<template> <div class="operate"> <el-form ref="ruleForm" :model="form" :rules="rules" class="dialogForm" :label-width="90" :disabled="opts.type === 'view'"> <el-row :gutter="20"> <el-col :span="24"> <el-form-item label="分类编号:" prop="typeCode"> <el-input v-model="form.typeCode" type="text" placeholder="请输入分类编号" /> </el-form-item> </el-col> </el-row> <el-row :gutter="20"> <el-col :span="24"> <el-form-item label="分类名称:" prop="typeName"> <el-input v-model="form.typeName" type="text" placeholder="请输入分类名称" /> </el-form-item> </el-col> </el-row> <el-row :gutter="20"> <el-col :span="24"> <el-form-item label="分类描述:" prop="remark"> <el-input v-model="form.remark" type="textarea" placeholder="请输入分类描述" resize="none" :rows="4" /> </el-form-item> </el-col> </el-row> <el-row :gutter="20"> <el-col :span="24"> <el-form-item label="封面:" prop="cover"> <div class="upload"> <el-upload class="avatar-uploader" action="/system/upload" :headers="uploadHeader" :before-upload="rawFile => beforeUpload(rawFile, ['.png', '.jpg', '.jpeg'])" :on-success="response => onSuccess(response, 'cover')" :on-error="(error, uploadFile, uploadFiles) => onError(error, uploadFile, uploadFiles)" :show-file-list="false" accept=".jpg, .png, .jpeg, .svg, .gif" :disabled="opts.type === 'view' || !!form.cover" > <div class="img" v-if="form.cover"> <img :src="form.cover" class="avatar" /> <div class="mask" v-if="opts.type !== 'view'"> <el-icon class="icon" :size="20" @click="removeFile('cover')"><Delete /></el-icon> </div> </div> <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon> </el-upload> </div> </el-form-item> </el-col> </el-row> </el-form> </div> </template> <script setup> import { reactive, onMounted } from 'vue'; import { inheritAttr } from '@/utils/v3'; import { required } from '@/utils/validate-helper'; import uploadHeader from '@/utils/getUploadHeader'; import { documentTypeAdd, documentTypeEdit, documentTypeDetail } from '@/api/document/dataClassify'; import { getFileLIst } from '@/api/system/file'; const methed = { add: documentTypeAdd, edit: documentTypeEdit, }; const { proxy } = getCurrentInstance(); const props = defineProps({ curRow: { type: Object, default: () => ({}), }, opts: { type: Object, default: () => ({}), }, }); const { curRow, opts } = props; const emit = defineEmits(['close']); const form = reactive({ typeCode: '', typeName: '', remark: '', cover: '', sysFileSaveRequestList: [], }); const rules = reactive({ typeCode: required('分类编号'), typeName: required('分类名称'), remark: required('分类描述'), }); const submit = () => { proxy.$refs.ruleForm.validate(async (valid, fields) => { if (valid) { let api = methed[opts.type]; if (!api) return; const params = JSON.parse(JSON.stringify(form)); if (opts.type === 'add') { params.parentId = curRow.id; } else if (opts.type === 'edit') { params.id = curRow.id; } const res = await api(params); if (res?.code !== 200) return; proxy.$modal.msgSuccess('操作成功'); emit('close', opts); } else { console.log('error submit!', fields); } }); }; const beforeUpload = rawFile => { console.log(rawFile); if (rawFile.name.length > 50) { proxy.$modal.msgError(`文件名称过长(50个字符以内),请先修改再上传!`); return false; } return true; }; const onSuccess = (response, prop) => { console.log(response); const { data } = response; form[prop] = data.url; form.sysFileSaveRequestList = [{ ...data, refType: 'document_type_cover' }]; // nextTick(() => { // proxy.$refs.ruleForm.validateField(prop) // }) }; const onError = (error, uploadFile, uploadFiles) => { console.log(error, uploadFile, uploadFiles); }; const removeFile = prop => { proxy.$modal .confirm('是否确认删除?') .then(async () => { form[prop] = ''; form.sysFileSaveRequestList = []; nextTick(() => { proxy.$refs.ruleForm.validateField(prop); }); }) .catch(() => {}); }; const getDetail = async () => { const res = await documentTypeDetail(curRow.id); if (res?.code !== 200) rteturn; inheritAttr(res.data, form); getFileInfo(res.data.id, 'document_type_cover', data => { if (!data.length) return; const fileInfo = data[0]; form.cover = fileInfo.url; form.sysFileSaveRequestList = [{ ...fileInfo, refType: 'document_type_cover' }]; }); }; const getFileInfo = async (id, refType, callback) => { const res = await getFileLIst({ refId: id, refType }); if (res?.code !== 200) return; callback && callback(res.data); }; onMounted(() => { if (['view', 'edit'].includes(opts.type)) getDetail(); }); defineExpose({ submit, }); </script> <style lang="scss" scoped> .upload { position: relative; .fileName { position: absolute; left: 0; top: 30px; white-space: nowrap; display: flex; align-items: center; .del { flex-shrink: 0; color: #f56c6c; cursor: pointer; margin-left: 10px; } } } .img { position: relative; width: 178px; height: 178px; img { width: 100%; height: 100%; } .mask { position: absolute; left: 0; right: 0; top: 0; bottom: 0; background-color: rgba(0, 0, 0, 0.5); display: none; .icon { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: #fff; } } &:hover { .mask { display: block; } } } </style>