feat(course): 添加文档类型资源支持

- 新增文档组件 DocComp.vue,支持 PDF 预览功能
- 在 createCourse.vue 中集成文档类型处理逻辑
- 更新 chooseFileList.vue 支持文档类型上传
- 重构音视频组件,提取公共逻辑至 useMediaComponent hook
- 统一文件路径前缀为 fileBaseUrl,替换硬编码地址
- 调整拖拽表格操作按钮样式及显示逻辑
- 添加 pdf-vue3 依赖用于 PDF 渲染支持
- TODO
- 上传文件目前缺少id 无法进行预览 这是一个问题!
This commit is contained in:
陈昱达
2025-11-24 16:06:54 +08:00
parent cc1af6a11e
commit 7d18bc73ea
9 changed files with 5228 additions and 97 deletions

View File

@@ -148,7 +148,7 @@ onMounted(() => {
:on-success="uploadSuccess"
:file-list="fileList"
>
<el-button v-if="[10, 20].includes(props.resType)" type="primary"
<el-button v-if="[10, 20, 40].includes(props.resType)" type="primary"
>上传新{{ getType(props.resType) }}</el-button
>
</el-upload>

View File

@@ -7,6 +7,7 @@ import {
ElRadio,
ElRadioGroup,
} from "element-plus";
defineOptions({
resType: 20,
});
@@ -27,27 +28,13 @@ const props = defineProps({
},
});
import { ref, watch } from "vue";
// 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 }
);
import { useMediaComponent } from "@/hooks/useMediaComponent";
// Emit updates to parent component
const emit = defineEmits(["update:dialogVideoForm"]);
// Update form values and emit changes
const updateFormValue = (field, value) => {
localDialogVideoForm.value[field] = value;
emit("update:dialogVideoForm", { ...localDialogVideoForm.value });
};
// 使用hook处理公共逻辑
const { localDialogVideoForm, updateFormValue, fileBaseUrl } =
useMediaComponent(props, emit);
</script>
<template>
@@ -64,7 +51,7 @@ const updateFormValue = (field, value) => {
style="width: 100%; max-height: 400px"
class="mb10"
:key="localDialogVideoForm.filePath"
:src="'http://home.hzer.xyz:9960/upload/' + localDialogVideoForm.filePath"
:src="fileBaseUrl + localDialogVideoForm.filePath"
>
您的浏览器不支持video
</audio>

View File

@@ -0,0 +1,114 @@
<script setup>
import apiCourseFile from "@/api/modules/courseFile";
import { onBeforeUnmount, onMounted, ref, watch } from "vue";
import PDF from "pdf-vue3";
defineOptions({
resType: 40,
});
const props = defineProps({
dialogVideoForm: {
type: Object,
default: () => ({
name: "",
filePath: "",
isDrag: true,
completeSetup: 0,
setupTage: 0,
}),
},
isPreview: {
type: Boolean,
default: false,
},
scrollToID: {
type: String,
default: "pdf-perView",
},
autoScroll: {
type: Boolean,
default: false,
},
});
import { useMediaComponent } from "@/hooks/useMediaComponent";
// Emit updates to parent component
const emit = defineEmits(["update:dialogVideoForm"]);
// 使用hook处理公共逻辑
const { localDialogVideoForm, updateFormValue, fileBaseUrl } =
useMediaComponent(props, emit);
// 添加响应式pdf路径变量
const pdfPath = ref("");
const loadPdfFile = () => {
console.log(localDialogVideoForm.value);
//检查当前是否是pdf如果是pdf那么就不需要再查询一次了
let fname = localDialogVideoForm.value.filePath;
if (fname && fname.indexOf(".pdf") > -1) {
localDialogVideoForm.value.pdfPath = localDialogVideoForm.value.filePath;
pdfPath.value = localDialogVideoForm.value.filePath;
console.log(123123);
} else {
apiCourseFile.detail(localDialogVideoForm.value.id).then((rs) => {
if (rs.status == 200) {
if (
rs.result.previewFilePath == "" &&
rs.result.filePath.indexOf("pdf") > -1
) {
pdfPath.value = rs.result.filePath;
} else {
pdfPath.value = rs.result.previewFilePath;
}
}
});
}
};
// 定义响应式数据
const currentPage = ref(0);
// 加载进度
const loadedRatio = ref(0);
const showProgress = ref(true);
// 定义 refs
const pdfRef = ref(null);
// PDF 加载处理
const loadPdfHandler = (e) => {
currentPage.value = 1; // 加载的时候先加载第一页
};
// 监听 loadedRatio 变化
watch(loadedRatio, (newVal) => {
// 直接使用loadedRatio控制进度条没有加载效果
if (newVal == 1) {
setTimeout(() => {
showProgress.value = false;
}, 500);
}
});
onMounted(() => {
loadPdfFile();
});
onBeforeUnmount(() => {});
</script>
<template>
<div class="pdf-perView" id="pdf-perView">
<div class="pdf-box" style="height: 505px; overflow: hidden">
<PDF
style="max-height: 500px; overflow: scroll"
ref="pdfRef"
:src="fileBaseUrl + pdfPath"
v-if="pdfPath"
@onComplete="loadPdfHandler"
></PDF>
</div>
</div>
</template>
<style scoped lang="scss"></style>

View File

@@ -75,26 +75,12 @@ const props = defineProps({
},
});
// 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 }
);
import { useMediaComponent } from "@/hooks/useMediaComponent";
// Emit updates to parent component
const emit = defineEmits(["update:dialogVideoForm"]);
// Update form values and emit changes
const updateFormValue = (field, value) => {
localDialogVideoForm.value[field] = value;
emit("update:dialogVideoForm", { ...localDialogVideoForm.value });
};
// 使用hook处理公共逻辑
const { localDialogVideoForm, updateFormValue } = useMediaComponent(props, emit);
const editor = ref(null);
@@ -157,4 +143,4 @@ watch(
</el-form>
</template>
<style scoped lang="scss"></style>
<style scoped lang="scss"></style>

View File

@@ -28,27 +28,13 @@ const props = defineProps({
},
});
import { ref, watch } from "vue";
// 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 }
);
import { useMediaComponent } from "@/hooks/useMediaComponent";
// Emit updates to parent component
const emit = defineEmits(["update:dialogVideoForm"]);
// Update form values and emit changes
const updateFormValue = (field, value) => {
localDialogVideoForm.value[field] = value;
emit("update:dialogVideoForm", { ...localDialogVideoForm.value });
};
// 使用hook处理公共逻辑
const { localDialogVideoForm, updateFormValue, fileBaseUrl } =
useMediaComponent(props, emit);
</script>
<template>
@@ -67,9 +53,7 @@ const updateFormValue = (field, value) => {
:key="localDialogVideoForm.filePath"
>
<source
:src="
'http://home.hzer.xyz:9960/upload/' + localDialogVideoForm.filePath
"
:src="fileBaseUrl + localDialogVideoForm.filePath"
type="video/mp4"
/>
您的浏览器不支持video