|
|
@@ -1,7 +1,7 @@
|
|
|
<script lang="ts" setup>
|
|
|
import { saveTrainingInformation, updateTrainingInformation } from '@/api/production-education-training-plan-dept';
|
|
|
import { ref, reactive, onMounted, watch, shallowRef, computed } from 'vue';
|
|
|
- import { UploadFilled, Plus } from '@element-plus/icons-vue';
|
|
|
+ import { UploadFilled, Plus, Delete, Download, ZoomIn } from '@element-plus/icons-vue';
|
|
|
import { TRAINING_FORM_RULES } from '../configs/form';
|
|
|
import { queryUserGroupPage } from '@/api/system/person-group';
|
|
|
import type { FileItem } from '@/components/UploadFiles/types';
|
|
|
@@ -9,7 +9,7 @@
|
|
|
import { Editor, Toolbar } from '@wangeditor/editor-for-vue';
|
|
|
// @ts-ignore: missing type declarations for CSS side-effect import
|
|
|
import '@wangeditor/editor/dist/css/style.css';
|
|
|
- import { ElMessage } from 'element-plus';
|
|
|
+ import { ElMessage, UploadRawFile } from 'element-plus';
|
|
|
|
|
|
import { debounce } from 'lodash-es';
|
|
|
|
|
|
@@ -70,17 +70,19 @@
|
|
|
try {
|
|
|
const basePayload = {
|
|
|
...form,
|
|
|
+ petpiId: props.currentId,
|
|
|
+ courseImg: form.courseImg[0],
|
|
|
// responsibleDeptIds: form.responsibleDeptIds.toString()
|
|
|
};
|
|
|
-
|
|
|
+ console.log('提交的表单数据:', basePayload);
|
|
|
if (isCreateMode.value) {
|
|
|
- // await saveTrainingInformation(basePayload);
|
|
|
+ await saveTrainingInformation(basePayload);
|
|
|
ElMessage.success('创建成功');
|
|
|
} else if (isEditMode.value && props.currentId) {
|
|
|
- // await updateTrainingInformation({
|
|
|
- // id: props.currentId,
|
|
|
- // ...basePayload,
|
|
|
- // });
|
|
|
+ await updateTrainingInformation({
|
|
|
+ id: props.currentId,
|
|
|
+ ...basePayload,
|
|
|
+ });
|
|
|
ElMessage.success('保存成功');
|
|
|
}
|
|
|
} catch (e) {
|
|
|
@@ -125,10 +127,6 @@
|
|
|
return isAllowedType && isLt20M;
|
|
|
};
|
|
|
|
|
|
- const handleExceed = () => {
|
|
|
- ElMessage.warning('只能上传一个文件,请先删除当前文件再上传!');
|
|
|
- };
|
|
|
-
|
|
|
const handleEditorCreated = (editor: any) => {
|
|
|
editorRef.value = editor;
|
|
|
};
|
|
|
@@ -136,57 +134,108 @@
|
|
|
const handleEditorChange = () => {
|
|
|
// 编辑器内容变化时的处理
|
|
|
};
|
|
|
- const handleImageUploadSuccess = (response: any, file: any, fileList: any[]) => {
|
|
|
- console.log('图片上传成功:', response, file, fileList);
|
|
|
- form.courseImg = fileList;
|
|
|
+ const handleImageUploadChange = (response: any, file: any) => {
|
|
|
+ form.courseImg = [response];
|
|
|
+ };
|
|
|
+
|
|
|
+ const courseImgRef = ref();
|
|
|
+ const handleImageExceed = (files: any[]) => {
|
|
|
+ console.log(files);
|
|
|
+ courseImgRef.value!.clearFiles(); // 清空文件列表
|
|
|
+ const file = files[0] as UploadRawFile;
|
|
|
+ courseImgRef.value!.handleStart(file); // 手动触发上传
|
|
|
+ form.courseImg = files[0];
|
|
|
+ };
|
|
|
+
|
|
|
+ const dialogVisible = ref(false);
|
|
|
+ const dialogImageUrl = ref('');
|
|
|
+ const handlePictureCardPreview = (file: any) => {
|
|
|
+ dialogImageUrl.value = file.url;
|
|
|
+ dialogVisible.value = true;
|
|
|
+ };
|
|
|
+
|
|
|
+ const handleImageRemove = (file: any) => {
|
|
|
+ console.log('图片被移除:', file, fileList.value);
|
|
|
+ // console.log('图片被移除:', file, fileList.value);
|
|
|
+ // form.courseImg = fileList.value.filter((item) => item.uid !== file.uid);
|
|
|
+ };
|
|
|
+ const validateImage = (file) => {
|
|
|
+ const validMIME = [
|
|
|
+ 'image/jpeg',
|
|
|
+ 'image/png',
|
|
|
+ 'image/gif',
|
|
|
+ 'image/bmp',
|
|
|
+ 'image/webp',
|
|
|
+ 'image/svg+xml',
|
|
|
+ 'image/tiff',
|
|
|
+ 'image/heic',
|
|
|
+ 'image/heif',
|
|
|
+ 'image/avif',
|
|
|
+ ];
|
|
|
+
|
|
|
+ if (!validMIME.includes(file.type)) {
|
|
|
+ ElMessage.error('仅支持图片文件(JPEG/PNG/GIF/BMP/WEBP/SVG/TIFF/HEIC/AVIF等)');
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!validMIME.includes(file.type)) {
|
|
|
+ ElMessage.error('仅支持JPG/PNG格式图片');
|
|
|
+ return false; // 阻止上传
|
|
|
+ }
|
|
|
+
|
|
|
+ // 可选:添加文件大小限制
|
|
|
+ const maxSize = 5 * 1024 * 1024; // 5MB
|
|
|
+ if (file.size > maxSize) {
|
|
|
+ ElMessage.error('图片大小不能超过5MB');
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ return true; // 验证通过
|
|
|
};
|
|
|
-const handleImageRemove = (file: any, fileList: any[]) => {
|
|
|
- console.log('图片被移除:', file, fileList);
|
|
|
- form.courseImg = fileList;
|
|
|
-}
|
|
|
|
|
|
-const handleFileChange = (file, fileList) => {
|
|
|
+ // 文件选择更新
|
|
|
+ const courseContentUpload = ref();
|
|
|
+ const handleFileExceed = (files) => {
|
|
|
+ courseContentUpload.value!.clearFiles(); // 清空文件列表
|
|
|
+ const file = files[0] as UploadRawFile;
|
|
|
+ if (!beforeUpload(file)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ courseContentUpload.value!.handleStart(file); // 手动触发上传
|
|
|
+ };
|
|
|
+ // 课程内容文件上传
|
|
|
+ const handleFileChange = (file, fileList) => {
|
|
|
// 1. 验证文件类型和大小
|
|
|
const allowedTypes = [
|
|
|
- 'application/rar',
|
|
|
- 'application/zip',
|
|
|
- 'application/msword',
|
|
|
- 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
|
- 'application/pdf',
|
|
|
- 'video/mp4'
|
|
|
+ 'application/rar',
|
|
|
+ 'application/zip',
|
|
|
+ 'application/msword',
|
|
|
+ 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
|
+ 'application/pdf',
|
|
|
+ 'video/mp4',
|
|
|
];
|
|
|
-
|
|
|
+
|
|
|
if (!allowedTypes.includes(file.raw.type)) {
|
|
|
- ElMessage.error('不支持的文件格式');
|
|
|
- return;
|
|
|
+ ElMessage.error('不支持的文件格式');
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
if (file.raw.size > 20 * 1024 * 1024) {
|
|
|
- ElMessage.error('文件大小不能超过20MB');
|
|
|
- return;
|
|
|
+ ElMessage.error('文件大小不能超过20MB');
|
|
|
+ return;
|
|
|
}
|
|
|
-
|
|
|
+ console.log(file, fileList);
|
|
|
// 2. 关键修改:强制覆盖旧文件
|
|
|
- fileList.value = [file.raw]; // 直接替换为新文件
|
|
|
-
|
|
|
- // 3. 生成文件信息JSON
|
|
|
- fileInfo.value = {
|
|
|
- fileName: file.raw.name,
|
|
|
- fileSize: `${(file.raw.size / (1024 * 1024)).toFixed(2)} MB`,
|
|
|
- fileType: file.raw.type,
|
|
|
- lastModified: new Date(file.raw.lastModified).toLocaleString(),
|
|
|
- rawFile: file.raw
|
|
|
- };
|
|
|
-}
|
|
|
-
|
|
|
- const handleUploadSignsUploadSuccess = async (item:any, fileList) => {
|
|
|
+ fileList.value = [file.raw]; // 直接替换为新文件
|
|
|
+ form.courseContent = file; // 更新表单数据
|
|
|
+ };
|
|
|
+
|
|
|
+ const handleUploadSignsUploadSuccess = async (item: any, fileList) => {
|
|
|
// const attachment = await formatAttachmentList(fileList);
|
|
|
// item.attachment = attachment;
|
|
|
-
|
|
|
// form.courseImg = [...signRecords.value.level1, ...signRecords.value.level2, ...signRecords.value.level3];
|
|
|
};
|
|
|
|
|
|
-
|
|
|
// 文件上传
|
|
|
const handleUploadSuccess = (files: FileItem[]) => {
|
|
|
console.log('上传成功的文件列表:', files);
|
|
|
@@ -244,6 +293,7 @@ const handleFileChange = (file, fileList) => {
|
|
|
<el-select
|
|
|
v-model="form.groupOfParticipants"
|
|
|
multiple
|
|
|
+ filterable
|
|
|
placeholder="请选择培训责任部门责任人所在分组,多选"
|
|
|
clearable
|
|
|
:disabled="isViewMode"
|
|
|
@@ -287,16 +337,15 @@ const handleFileChange = (file, fileList) => {
|
|
|
</el-form-item>
|
|
|
|
|
|
<el-form-item label="课程内容:" prop="courseContent">
|
|
|
- <!-- <UploadFiles label="上传文件" :maxCount="1" :file-list="form.courseImg" :disabled="isViewMode"
|
|
|
- accept=".rar,.zip,.doc,.docx,.pdf,.mp4" desc="支持格式:.rar .zip .doc .docx .pdf .mp4 ,单个文件不能超过20MB"
|
|
|
- :allow-all-file-types="true" @uploadSuccess="handleUploadSuccess" /> -->
|
|
|
<el-upload
|
|
|
action=""
|
|
|
+ ref="courseContentUpload"
|
|
|
:auto-upload="false"
|
|
|
:on-change="handleFileChange"
|
|
|
accept=".rar, .zip, .doc, .docx, .pdf, .mp4"
|
|
|
:file-list="fileList"
|
|
|
:limit="1"
|
|
|
+ :on-exceed="handleFileExceed"
|
|
|
>
|
|
|
<el-button type="default" :disabled="isViewMode">
|
|
|
<el-icon style="margin-right: 6px">
|
|
|
@@ -318,21 +367,18 @@ const handleFileChange = (file, fileList) => {
|
|
|
</el-form-item>
|
|
|
|
|
|
<el-form-item label="课程图片:" prop="courseImg">
|
|
|
- <UploadFiles
|
|
|
- accept=".jpeg,.jpg,.png,.svg"
|
|
|
- label="上传文件"
|
|
|
- :fileList="form.courseImg"
|
|
|
- @upload-success="(fileList) => handleUploadSignsUploadSuccess(item, fileList)"
|
|
|
- />
|
|
|
- <!-- <el-upload
|
|
|
+ <el-upload
|
|
|
class="image-uploader"
|
|
|
+ ref="courseImgRef"
|
|
|
action="#"
|
|
|
- :file-list="form.courseContent"
|
|
|
+ :file-list="form.courseImg"
|
|
|
:disabled="isViewMode"
|
|
|
+ :auto-upload="false"
|
|
|
:limit="1"
|
|
|
- accept=".jpg,.png,.jpeg"
|
|
|
- :on-success="handleImageUploadSuccess"
|
|
|
- :on-remove="handleImageRemove"
|
|
|
+ accept="image/*"
|
|
|
+ :on-change="handleImageUploadChange"
|
|
|
+ :on-exceed="handleImageExceed"
|
|
|
+ :before-upload="validateImage"
|
|
|
list-type="picture-card"
|
|
|
>
|
|
|
<el-icon>
|
|
|
@@ -342,9 +388,20 @@ const handleFileChange = (file, fileList) => {
|
|
|
<template #tip>
|
|
|
<div class="el-upload__tip"> 支持格式:.jpg .png .jpeg,单个文件不能超过300k,设置一个默认图片。 </div>
|
|
|
</template>
|
|
|
- </el-upload> -->
|
|
|
-
|
|
|
-
|
|
|
+ <template #file="{ file }">
|
|
|
+ <div>
|
|
|
+ <img class="el-upload-list__item-thumbnail courseImg" :src="file.url" alt="" />
|
|
|
+ <span class="el-upload-list__item-actions">
|
|
|
+ <span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)">
|
|
|
+ <el-icon><zoom-in /></el-icon>
|
|
|
+ </span>
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-upload>
|
|
|
+ <el-dialog v-model="dialogVisible">
|
|
|
+ <img w-full :src="dialogImageUrl" alt="Preview Image" />
|
|
|
+ </el-dialog>
|
|
|
</el-form-item>
|
|
|
</el-form>
|
|
|
|
|
|
@@ -396,7 +453,22 @@ const handleFileChange = (file, fileList) => {
|
|
|
background-color: #f5f7fa;
|
|
|
border-radius: 4px;
|
|
|
}
|
|
|
-
|
|
|
+ :deep(.el-upload-list__item) {
|
|
|
+ // margin: 10px 0;
|
|
|
+ border-radius: 8px;
|
|
|
+ border: 1px solid #e1e1e1;
|
|
|
+ background-color: #f9fafb;
|
|
|
+ }
|
|
|
+ :deep(.el-upload-list__item .el-icon--close) {
|
|
|
+ display: inline-block !important;
|
|
|
+ opacity: 1 !important;
|
|
|
+ }
|
|
|
+ .courseImg {
|
|
|
+ width: 78px;
|
|
|
+ height: 78px;
|
|
|
+ object-fit: cover;
|
|
|
+ border-radius: 4px;
|
|
|
+ }
|
|
|
pre {
|
|
|
white-space: pre-wrap;
|
|
|
}
|