| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351 |
- <template>
- <BasicModal
- v-bind="$attrs"
- @register="registerModal"
- @ok="handleSubmit"
- title="图纸管理"
- width="900px"
- :min-height="600"
- :max-height="1000"
- scrollable
- centered
- destroyOnClose
- :bodyStyle="{ padding: '20px' }"
- >
- <a-form
- ref="formRef"
- :model="formData"
- :rules="formRules"
- layout="horizontal"
- :label-col="{ span: 4 }"
- :wrapper-col="{ span: 20 }"
- >
- <div class="edit-container">
- <div class="mine-base-info">
- <!-- 添加 key 强制重新渲染 -->
- <a-form-item
- v-for="schema in visibleFormSchemas"
- :key="schema.field + formKey"
- :name="schema.field"
- :label="schema.label"
- :rules="schema.rules"
- >
- <!-- Upload 组件特殊处理 -->
- <template v-if="schema.component === 'Upload'">
- <a-upload
- v-model:file-list="formData[schema.field]"
- v-bind="schema.componentProps"
- @change="(info) => handleUploadChange(info, schema.field)"
- :customRequest="handleCustomUpload"
- :maxCount="1"
- >
- <a-button>
- <template #icon><UploadOutlined /></template>
- 上传文件
- </a-button>
- </a-upload>
- </template>
- <!-- 其他组件动态渲染 -->
- <template v-else>
- <component
- :is="getComponent(schema.component)"
- :value="formData[schema.field]"
- @update:value="handleUpdateValue(schema.field, $event)"
- @change="(val) => handleComponentChange(schema.field, val, schema)"
- v-bind="schema.componentProps"
- :placeholder="`请输入${schema.label}`"
- style="width: 100%"
- />
- </template>
- </a-form-item>
- </div>
- </div>
- </a-form>
- </BasicModal>
- </template>
- <script setup lang="ts">
- import { ref, computed, nextTick } from 'vue';
- import { BasicModal, useModalInner } from '/@/components/Modal';
- import { mapEditForm } from '../cad.data';
- import { Select, Input, message } from 'ant-design-vue';
- import { UploadOutlined } from '@ant-design/icons-vue';
- import MineCascader from '/@/components/Form/src/jeecg/components/MineCascader/MineCascader.vue';
- import type { FormInstance } from 'ant-design-vue/es/form';
- import { uploadFile, updateMineFile, addMineFile } from '../cad.api';
- import type { UploadChangeParam, UploadFile } from 'ant-design-vue/es/upload/interface';
- import dayjs from 'dayjs';
- import { useMineDepartmentStore } from '/@/store/modules/mine';
- // 表单 key(用于强制重新渲染)
- const formKey = ref(0);
- // 标识当前是否为新增模式
- const isAddMode = ref(false);
- // 组件映射表(Upload 单独处理)
- const componentMap: Record<string, any> = {
- Input,
- Select,
- InputTextArea: Input.TextArea,
- MineCascader,
- };
- // 定义事件发射
- const emit = defineEmits(['success']);
- // 表单实例
- const formRef = ref<FormInstance>();
-
- // 表单数据
- const formData = ref({
- id: '',
- mineCode: '',
- mineName: '',
- fileName: '',
- fileType: '',
- fileAttach: [] as any[],
- remark: '',
- filePath: '',
- createTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
- });
-
- // 获取部门信息
- const mineStore = useMineDepartmentStore();
- // 表单规则
- const formRules = computed(() => {
- const rules: Record<string, any> = {};
- mapEditForm.forEach((item) => {
- if (item.rules) {
- rules[item.field] = item.rules;
- }
- });
- return rules;
- });
- const visibleFormSchemas = computed(() => {
- // 定义新增模式下允许显示的字段
- const allowedFieldsInAddMode = ['mineCode', 'fileName', 'fileType', 'fileAttach' , 'remark'];
- const allowedFieldsInEditMode = ['mineCode', 'fileName', 'fileType', 'fileAttach', 'remark'];
-
- return mapEditForm.filter(item => {
- // 1. 基础隐藏逻辑
- if (item.ifShow === false || item.show === false) {
- return false;
- }
-
- // 2. 如果是新增模式,只保留允许显示的字段
- if (isAddMode.value) {
- return allowedFieldsInAddMode.includes(item.field);
- }
-
- return allowedFieldsInEditMode.includes(item.field);;
- });
- });
- // 获取组件
- const getComponent = (componentName: string) => {
- return componentMap[componentName] || Input;
- };
- // 处理值更新
- const handleUpdateValue = (field: string, value: any) => {
- formData.value[field as keyof typeof formData.value] = value;
- };
- const handleComponentChange = (field: string, value: any, schema: any) => {
- console.log(`字段 ${field} 触发 change 事件,新值为:`, schema, value);
-
- if (field === 'mineCode') {
- if (value) {
- const depart = mineStore.findDepartById(value, mineStore.getDepartTree);
- if (depart) {
- // 同步更新 formData 中的 mineName
- formData.value.mineName = depart.departName;
- console.log('自动填充矿区名称:', depart.departName);
- } else {
- // 如果没找到,可能数据还没加载完,或者 ID 无效
- console.warn('未找到对应的矿区名称');
- formData.value.mineName = '';
- }
- } else {
- // 如果清空了选择,也清空名称
- formData.value.mineName = '';
- }
- }
-
- };
- /**
- * 自定义上传请求
- * 使用 defHttp 封装的 uploadFile 接口
- */
- const handleCustomUpload = async (options: any) => {
- const { file, onSuccess, onError } = options;
-
- // 构建 FormData
- const formDataObj = new FormData();
- formDataObj.append('file', file);
- // 添加其他参数
- // formDataObj.append('biz', 'cadFile');
- try {
- // 调用上传接口
- const res = await uploadFile(formDataObj);
- if (res&& res.success && res.message) {
- // 成功回调,将后端返回的路径挂载到 file 对象上,方便后续提交或展示
- formData.value.filePath = res.message;
- const uploadedFileItem = {
- uid: file.uid || Date.now(), // 唯一标识
- name: file.name, // 文件名
- status: 'done', // 状态:完成
- url: res.message, // 预览地址(如果有)
- response: res // 原始响应
- };
-
- // 更新表单中的 fileAttach 数组,触发视图更新
- formData.value.fileAttach = [uploadedFileItem];
- onSuccess(res, file);
- } else {
- throw new Error(`${res.message}`);
- }
- } catch (err: any) {
- console.error('上传错误:', err);
- message.error(err.message || '文件上传失败');
- onError(err);
- }
- };
- /**
- * 上传状态改变处理
- * @param info 上传信息
- * @param field 当前绑定的表单字段名
- */
- const handleUploadChange = async (info: UploadChangeParam, field: string) => {
- const { fileList } = info;
- // const status = info.file.status;
-
- // // 1. 更新文件列表显示
- // // formData.value[field as keyof typeof formData.value] = fileList;
- // // 2. 如果上传成功,提取 filePath 并存储
-
- // if (info.file.status === 'done') {
- // const response = info.file.response;
- // // 假设后端返回的 message 就是我们要的 filePath
- // const filePath = response?.message;
-
- // if (filePath) {
- // const currentFile = fileList[fileList.length - 1];
- // if(currentFile) {
- // currentFile.customPath = filePath;
- // }
-
- // message.success(`${info.file.name} 文件上传成功`);
- // }
- // } else if (info.file.status === 'error') {
- // message.error(`${info.file.name} 文件上传失败`);
- // }
- };
- // 注册模态框并初始化数据
- const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
- setModalProps({ confirmLoading: false });
- // 先重置 formKey 强制重新渲染
- formKey.value++;
- // 如果没有data或者id为空则为新增模式
- isAddMode.value = !data || !data.id;
-
- // 重置表单数据
- await nextTick();
- formData.value = {
- id: '',
- mineCode: '',
- mineName: '',
- fileName: '',
- fileType: '',
- fileAttach: [],
- filePath: '',
- remark: '',
- createTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
- };
- // 编辑模式时填充现有数据
- if (data && !isAddMode.value) {
- const record = data;
- // 处理文件回显
- let fileList: UploadFile[] = [];
- if (record.filePath) {
- const originalFileName = record.filePath.split('/').pop() || record.filePath.split('\\').pop() || '已上传文件';
- // 后端返回了 filePath,构造一个 fake file 对象用于展示
- fileList = [{
- uid: '-1',
- name: originalFileName,
- status: 'done',
- url: record.filePath,
- response: { message: record.filePath }
- } as UploadFile];
- }
-
- // 使用 nextTick 确保数据填充后视图更新
- await nextTick();
- formData.value = {
- id: record.id || '',
- mineCode: record.mineCode || '',
- mineName: record.mineName || '',
- fileName: record.fileName || '',
- fileType: record.fileType || '',
- fileAttach: fileList || [],
- filePath: record.filePath || '',
- remark: record.remark || '',
- createTime: record.createTime || dayjs().format('YYYY-MM-DD HH:mm:ss'),
- };
-
- }
- });
- // 提交表单处理
- async function handleSubmit() {
- try {
- if (!formRef.value) return;
- await formRef.value.validate();
- setModalProps({ confirmLoading: true });
-
- // 构造提交数据
- const submitData = {
- ...formData.value,
- };
- submitData.createTime = dayjs().format('YYYY-MM-DD HH:mm:ss');
- delete submitData.fileAttach;
- // 调用更新接口
- await updateMineFile(submitData);
- if (isAddMode.value) {
- await addMineFile(submitData);
- } else {
- await updateMineFile(submitData);
- }
-
- message.success(isAddMode.value ? '新增成功' : '修改成功');
- emit('success',true);
- closeModal();
- } catch (error: any) {
- console.error('提交失败:', error);
- message.error(error.message || '操作失败,请检查必填项');
- } finally {
- setModalProps({ confirmLoading: false });
- }
- }
- </script>
- <style scoped>
- .mine-base-info {
- padding: 12px 16px;
- border: 1px solid #cad2e0;
- border-radius: 5px;
- background-color: #f8f9fc;
- }
- </style>
|