mirror of
https://codeup.aliyun.com/67762337eccfc218f6110e0e/vue/fe-manage.git
synced 2025-12-06 17:36:44 +08:00
feat(hooks): 添加媒体组件通用hook
- 创建 useMediaComponent hook 处理媒体组件公共逻辑 - 实现本地表单数据响应式拷贝与深度监听更新 - 提供表单字段更新方法并触发事件通知 - 定义文件基础URL常量便于统一管理 - 支持 dialogVideoForm 属性的双向绑定更新 - 集成 Vue Composition API 的 ref 和 watch 功能
This commit is contained in:
@@ -1,10 +1,13 @@
|
||||
<script setup>
|
||||
import { reactive, onMounted, ref, h, watch } from "vue";
|
||||
import { ElButton, ElInput, ElUpload } from "element-plus";
|
||||
import { reactive, onMounted, ref, h } from "vue";
|
||||
import { ElButton, ElInput, ElUpload, ElMessage } from "element-plus";
|
||||
import BasicTable from "@/components/BasicElTable/BasicTable.vue";
|
||||
import { getPageListByType } from "@/hooks/useCreateCourseMaps";
|
||||
import { getType, getMapsItem } from "@/hooks/useCreateCourseMaps";
|
||||
import { getPageListByType, getType, getMapsItem } from "@/hooks/useCreateCourseMaps";
|
||||
import apiCourseFile from "@/api/modules/courseFile";
|
||||
import { useRoute } from "vue-router";
|
||||
import Cookies from "vue-cookies";
|
||||
|
||||
const route = useRoute();
|
||||
const props = defineProps({
|
||||
resType: {
|
||||
type: Number,
|
||||
@@ -12,25 +15,45 @@ const props = defineProps({
|
||||
},
|
||||
});
|
||||
|
||||
// 响应式数据
|
||||
const tableData = ref([]);
|
||||
const loading = ref(false);
|
||||
const showDialog = ref(false);
|
||||
const fileList = ref([]);
|
||||
|
||||
// 表单数据
|
||||
const form = reactive({
|
||||
name: "",
|
||||
resType: props.resType,
|
||||
});
|
||||
let pagination = reactive({
|
||||
|
||||
// 分页配置
|
||||
const pagination = reactive({
|
||||
pageSize: 10,
|
||||
current: 1,
|
||||
total: 0,
|
||||
});
|
||||
|
||||
// 视频表单数据
|
||||
const dialogVideoForm = reactive({
|
||||
name: "",
|
||||
isDrag: false,
|
||||
completeSetup: 0,
|
||||
setupTage: "",
|
||||
});
|
||||
const loading = ref(false);
|
||||
const showDialog = ref(false);
|
||||
const emit = defineEmits(["chooseItem"]);
|
||||
|
||||
// 上传配置
|
||||
const uploadData = reactive({
|
||||
headers: {
|
||||
"XBOE-Access-Token": Cookies.get("token"),
|
||||
},
|
||||
data: {
|
||||
dir: "course",
|
||||
},
|
||||
actionUrl: process.env.VUE_APP_SYS_API + "/xboe/sys/xuploader/file/upload",
|
||||
});
|
||||
|
||||
// 表格列配置
|
||||
const columns = [
|
||||
{
|
||||
title: "序号",
|
||||
@@ -66,13 +89,7 @@ const columns = [
|
||||
type: "primary",
|
||||
size: "small",
|
||||
onClick: () => {
|
||||
emit("chooseItem", {
|
||||
...params.row,
|
||||
isDrag: false,
|
||||
completeSetup: 0,
|
||||
setupTage: "",
|
||||
resType: props.resType,
|
||||
});
|
||||
handleChooseItem(params.row);
|
||||
},
|
||||
},
|
||||
"选择"
|
||||
@@ -82,18 +99,36 @@ const columns = [
|
||||
},
|
||||
];
|
||||
|
||||
// 事件发射
|
||||
const emit = defineEmits(["chooseItem"]);
|
||||
|
||||
// 处理选择项目
|
||||
const handleChooseItem = (row) => {
|
||||
emit("chooseItem", {
|
||||
...row,
|
||||
isDrag: false,
|
||||
completeSetup: 0,
|
||||
setupTage: "",
|
||||
resType: props.resType,
|
||||
});
|
||||
};
|
||||
|
||||
// 分页改变处理
|
||||
const changePagination = (PAGINATION) => {
|
||||
pagination = PAGINATION;
|
||||
Object.assign(pagination, PAGINATION);
|
||||
getVideoList();
|
||||
};
|
||||
|
||||
// 获取视频列表
|
||||
const getVideoList = () => {
|
||||
loading.value = true;
|
||||
let paramsData = {
|
||||
const paramsData = {
|
||||
...form,
|
||||
pageSize: pagination.pageSize,
|
||||
pageIndex: pagination.current,
|
||||
self: true,
|
||||
};
|
||||
|
||||
getPageListByType(paramsData).then((res) => {
|
||||
loading.value = false;
|
||||
tableData.value = res.result.list;
|
||||
@@ -101,7 +136,8 @@ const getVideoList = () => {
|
||||
});
|
||||
};
|
||||
|
||||
const chooseItem = (type) => {
|
||||
// 选择项目处理
|
||||
const chooseItem = () => {
|
||||
showDialog.value = false;
|
||||
emit("chooseItem", {
|
||||
...dialogVideoForm,
|
||||
@@ -109,29 +145,81 @@ const chooseItem = (type) => {
|
||||
});
|
||||
};
|
||||
|
||||
const uploadData = reactive({
|
||||
headers: {
|
||||
"XBOE-Access-Token": Cookies.get("token"),
|
||||
},
|
||||
data: {
|
||||
dir: "course",
|
||||
},
|
||||
actionUrl: process.env.VUE_APP_SYS_API + "/xboe/sys/xuploader/file/upload",
|
||||
});
|
||||
|
||||
const fileList = ref([]);
|
||||
const uploadSuccess = (result) => {
|
||||
if (result.status === 200) {
|
||||
emit("chooseItem", {
|
||||
...dialogVideoForm,
|
||||
name: result.result.displayName,
|
||||
// 上传成功处理
|
||||
const handleUploadSuccess = (res, file) => {
|
||||
if (res.status === 200) {
|
||||
// 上传到课件库
|
||||
const routeQuery = route.query;
|
||||
const courseWare = {
|
||||
fileName: res.result.displayName,
|
||||
fileType: res.result.fileType,
|
||||
filePath: res.result.filePath,
|
||||
resType: props.resType,
|
||||
...result.result,
|
||||
orgId: routeQuery.orgId,
|
||||
orgName: routeQuery.orgName,
|
||||
duration: routeQuery.duration,
|
||||
remark: "课程中直接上传",
|
||||
};
|
||||
|
||||
apiCourseFile.saveUpload(courseWare).then((rs) => {
|
||||
if (rs.status === 200) {
|
||||
emit("chooseItem", {
|
||||
...dialogVideoForm,
|
||||
name: res.result.displayName,
|
||||
resType: props.resType,
|
||||
...rs.result,
|
||||
});
|
||||
fileList.value = [];
|
||||
} else {
|
||||
ElMessage.error(rs.message);
|
||||
}
|
||||
});
|
||||
fileList.value = [];
|
||||
}
|
||||
};
|
||||
|
||||
// 上传前处理
|
||||
const handleBeforeUpload = (file) => {
|
||||
if (file.name.lastIndexOf(".") === -1) {
|
||||
ElMessage({ message: `文件格式不正确!`, type: "error", offset: 100 });
|
||||
return false;
|
||||
}
|
||||
|
||||
let fileExtension = file.name.slice(file.name.lastIndexOf(".") + 1);
|
||||
fileExtension = fileExtension.toLowerCase();
|
||||
|
||||
// 校检文件类型
|
||||
if (getMapsItem(props.resType).fileType.join(",").indexOf(fileExtension) === -1) {
|
||||
ElMessage({
|
||||
message: `文件格式不正确, 请上传正确格式的${getMapsItem(props.resType).name}文件!`,
|
||||
type: "error",
|
||||
offset: 100,
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
// 校检文件大小
|
||||
if (getMapsItem(props.resType).uploadSize) {
|
||||
const isLt = file.size / 1024 / 1024 < getMapsItem(props.resType).uploadSize;
|
||||
if (!isLt) {
|
||||
ElMessage({
|
||||
message: `上传文件大小不能超过 ${getMapsItem(props.resType).uploadSize} !`,
|
||||
type: "error",
|
||||
offset: 100,
|
||||
});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (props.resType === 50) {
|
||||
dialogVideoForm.dir = "scorm";
|
||||
} else {
|
||||
dialogVideoForm.dir = "course";
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
// 生命周期
|
||||
onMounted(() => {
|
||||
getVideoList();
|
||||
});
|
||||
@@ -145,8 +233,9 @@ onMounted(() => {
|
||||
:action="uploadData.actionUrl"
|
||||
:headers="uploadData.headers"
|
||||
:data="uploadData.data"
|
||||
:on-success="uploadSuccess"
|
||||
:on-success="handleUploadSuccess"
|
||||
:file-list="fileList"
|
||||
:before-upload="handleBeforeUpload"
|
||||
>
|
||||
<el-button v-if="[10, 20, 40].includes(props.resType)" type="primary"
|
||||
>上传新{{ getType(props.resType) }}</el-button
|
||||
@@ -193,4 +282,4 @@ onMounted(() => {
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
34
src/hooks/useMediaComponent.js
Normal file
34
src/hooks/useMediaComponent.js
Normal file
@@ -0,0 +1,34 @@
|
||||
import { ref, watch } from "vue";
|
||||
|
||||
/**
|
||||
* 通用媒体组件hook,用于处理媒体组件的公共逻辑
|
||||
* @param {Object} props - 组件props
|
||||
* @param {Function} emit - 组件emit函数
|
||||
*/
|
||||
export function useMediaComponent(props, emit) {
|
||||
// Create a reactive copy of the prop for local modifications
|
||||
const localDialogVideoForm = ref({ ...props.dialogVideoForm });
|
||||
|
||||
// Watch for changes in the prop and update the local copy
|
||||
watch(
|
||||
() => props.dialogVideoForm,
|
||||
(newVal) => {
|
||||
Object.assign(localDialogVideoForm.value, newVal);
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
// Update form values and emit changes
|
||||
const updateFormValue = (field, value) => {
|
||||
localDialogVideoForm.value[field] = value;
|
||||
emit("update:dialogVideoForm", { ...localDialogVideoForm.value });
|
||||
};
|
||||
|
||||
const fileBaseUrl = "http://home.hzer.xyz:9960/upload";
|
||||
|
||||
return {
|
||||
localDialogVideoForm,
|
||||
updateFormValue,
|
||||
fileBaseUrl,
|
||||
};
|
||||
}
|
||||
@@ -66,6 +66,7 @@ const executeCourseOperation = (operationName, data) => {
|
||||
courseMetadata.chooseIndex = data;
|
||||
courseMetadata.selectionIndex = null;
|
||||
isPreview.value = false;
|
||||
chooseItemData.value = {};
|
||||
if (courseOperations[operationName]) {
|
||||
courseOperations[operationName](data);
|
||||
} else {
|
||||
|
||||
@@ -149,7 +149,6 @@ const renderIndexColumn = () => {
|
||||
// 渲染名称列
|
||||
const renderNameColumn = () => {
|
||||
return ({ record }) => {
|
||||
console.log(record);
|
||||
// 如果处于编辑状态,显示输入框和确认按钮
|
||||
if (record.isEdit) {
|
||||
return h(
|
||||
|
||||
Reference in New Issue
Block a user