feat(course): implement video selection and management features

- Added AddVideo component for video selection with preview and settings
- Implemented BasicTable component for displaying paginated data with custom rendering
- Created course file API module for managing course materials
- Enhanced dragTable component with edit, preview, and delete functionalities
- Added comprehensive styling utilities for margins, paddings, and dimensions
- Integrated video selection dialog in course creation workflow
- Added support for video drag-and-drop and completion rule configuration
- Implemented reusable course data management hook with icon support
- Added chapter and section management capabilities
- Enhanced course operation mapping for various content types
This commit is contained in:
陈昱达
2025-11-20 17:28:23 +08:00
parent 740ad58897
commit 8ebca12470
8 changed files with 1018 additions and 322 deletions

View File

@@ -0,0 +1,225 @@
<script setup>
import { reactive, onMounted, ref, h } from "vue";
import {
ElButton,
ElInput,
ElDialog,
ElForm,
ElFormItem,
ElRadioGroup,
ElRadio,
ElInputNumber,
} from "element-plus";
import BasicTable from "@/components/BasicElTable/BasicTable.vue";
import { getPageListByType } from "@/hooks/useCreateCourseMaps";
const tableData = ref([]);
const form = reactive({
name: "",
resType: 10,
});
let pagination = reactive({
pageSize: 10,
current: 1,
total: 0,
});
const dialogVideoForm = ref({
name: "",
isDrag: false,
completeSetup: 0,
setupTage: "",
});
const loading = ref(false);
const showDialog = ref(false);
const emit = defineEmits(["saveContent"]);
const columns = [
{
title: "序号",
render: (params) => {
return h("span", {}, params.index + 1);
},
},
{
title: "名称",
key: "name",
dataIndex: "name",
},
{
title: "创建人",
key: "sysCreateBy",
dataIndex: "sysCreateBy",
},
{
title: "创建时间",
key: "sysCreateTime",
dataIndex: "sysCreateTime",
},
{
title: "操作",
key: "action",
dataIndex: "action",
width: 150,
render: (params) => {
return h("div", [
h(
ElButton,
{
type: "primary",
size: "small",
onClick: () => {
console.log(params);
showDialog.value = true;
dialogVideoForm.value = {
...dialogVideoForm.value,
...params.row,
};
},
},
"选择"
),
]);
},
},
];
const changePagination = (PAGINATION) => {
pagination = PAGINATION;
getVideoList();
};
const getVideoList = () => {
loading.value = true;
let paramsData = {
...form,
pageSize: pagination.pageSize,
pageIndex: pagination.current,
self: true,
};
getPageListByType(paramsData).then((res) => {
loading.value = false;
tableData.value = res.result.list;
pagination.total = res.result.count;
});
};
const saveContent = (type) => {
showDialog.value = false;
emit("saveContent", {
...dialogVideoForm,
type: 10,
});
// postData.content=this.cware.content;
// this.cwareChange.content = deepClone(this.cware.content)
// if(this.cware.content.contentType==52){
// if(this.cware.linkInfo.url==''){
// this.$message.error("请填写外连URL地址");
// return;
// }
// postData.content.content=JSON.stringify(this.cware.linkInfo);
// this.cwareChange.linkInfo = deepClone(this.cware.linkInfo)
// }else if(this.cware.content.contentType==10 || this.cware.content.contentType==20){
// if(this.cware.curriculumData.url==''){
// this.$message.error("请选择课件");
// return;
// }
// postData.content.content=JSON.stringify(this.cware.curriculumData);
// this.cwareChange.curriculumData = deepClone(this.cware.curriculumData)
// }
};
onMounted(() => {
getVideoList();
});
</script>
<template>
<div class="add-video">
<div class="add-vide-header">
<div>
<el-button>上传新视频</el-button>
<span class="desc ml10">文件大小限制1G,支持的文件类型:mp4 </span>
</div>
<div>
<el-input
style="width: 150px"
placeholder="请输入视频名称"
v-model="form.name"
clearable
></el-input>
<el-button class="ml10" @click="getVideoList">查询</el-button>
</div>
</div>
<div class="mt10">
<BasicTable
:columns="columns"
:data="tableData"
:pagination="pagination"
@changePage="changePagination"
:loading="loading"
></BasicTable>
</div>
</div>
<el-dialog v-model="showDialog" title="视频">
<el-form>
<el-form-item label="视频名称">
<el-input v-model="dialogVideoForm.name"></el-input>
</el-form-item>
<video
controls
style="width: 100%; max-height: 400px"
class="mb10"
v-if="showDialog"
>
<source
:src="'http://home.hzer.xyz:9960/upload/' + dialogVideoForm.filePath"
type="video/mp4"
/>
您的浏览器不支持video
</video>
<el-form-item label="是否允许拖拽">
<el-radio-group v-model="dialogVideoForm.isDrag" size="small">
<el-radio :label="true" border></el-radio>
<el-radio :label="false" border></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="完成规则设置">
<el-radio-group v-model="dialogVideoForm.completeSetup">
<el-radio :label="0">默认(系统自动控制)</el-radio>
<el-radio :label="1"
>按进度
<el-input-number
:disabled="dialogVideoForm.completeSetup === 0"
v-model="dialogVideoForm.setupTage"
size="mini"
:min="0"
:max="100"
label="描述文字"
controls-position="right"
></el-input-number>
%</el-radio
>
</el-radio-group>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="saveContent(1)"> 保存 </el-button>
</div>
</template>
</el-dialog>
</template>
<style scoped lang="scss">
.add-video {
.add-vide-header {
display: flex;
justify-content: space-between;
.desc {
font-size: 12px;
color: #999;
}
}
}
</style>