diff --git a/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/controller/admin/order/TsoOrderController.java b/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/controller/admin/order/TsoOrderController.java index 4bc22a6..ad8f1e7 100644 --- a/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/controller/admin/order/TsoOrderController.java +++ b/mes-module-chemmes/mes-module-chemmes-biz/src/main/java/com/ningxia/yunxi/chemmes/module/biz/controller/admin/order/TsoOrderController.java @@ -87,7 +87,7 @@ public class TsoOrderController { respPageResult.getList().forEach(item -> { AdminUserDO userEntity = userService.getUser(item.getSaleMan()); if (userEntity != null) { - item.setSaleManName(userEntity.getUsername()); + item.setSaleManName(userEntity.getNickname()); } }); } diff --git a/mes-module-infra/mes-module-infra-biz/src/main/java/com/ningxia/yunxi/chemmes/module/infra/framework/security/config/SecurityConfiguration.java b/mes-module-infra/mes-module-infra-biz/src/main/java/com/ningxia/yunxi/chemmes/module/infra/framework/security/config/SecurityConfiguration.java index 01ce55f..f0b5358 100644 --- a/mes-module-infra/mes-module-infra-biz/src/main/java/com/ningxia/yunxi/chemmes/module/infra/framework/security/config/SecurityConfiguration.java +++ b/mes-module-infra/mes-module-infra-biz/src/main/java/com/ningxia/yunxi/chemmes/module/infra/framework/security/config/SecurityConfiguration.java @@ -39,6 +39,10 @@ public class SecurityConfiguration { .antMatchers(adminSeverContextPath + "/**").anonymous(); // 文件读取 registry.antMatchers(buildAdminApi("/infra/file/*/get/**")).permitAll(); + + registry.antMatchers(buildAdminApi("/infra/file/upload")).permitAll(); + registry.antMatchers(buildAdminApi("/infra/file/uploadBatch")).permitAll(); + registry.antMatchers(buildAdminApi("/infra/file/uploadWatch")).permitAll(); } }; diff --git a/mes-module-infra/mes-module-infra-biz/src/main/java/com/ningxia/yunxi/chemmes/module/infra/service/logger/ApiAccessLogServiceImpl.java b/mes-module-infra/mes-module-infra-biz/src/main/java/com/ningxia/yunxi/chemmes/module/infra/service/logger/ApiAccessLogServiceImpl.java index baa44d1..0768352 100644 --- a/mes-module-infra/mes-module-infra-biz/src/main/java/com/ningxia/yunxi/chemmes/module/infra/service/logger/ApiAccessLogServiceImpl.java +++ b/mes-module-infra/mes-module-infra-biz/src/main/java/com/ningxia/yunxi/chemmes/module/infra/service/logger/ApiAccessLogServiceImpl.java @@ -2,9 +2,10 @@ package com.ningxia.yunxi.chemmes.module.infra.service.logger; import com.ningxia.yunxi.chemmes.framework.common.pojo.PageResult; import com.ningxia.yunxi.chemmes.framework.common.util.object.BeanUtils; +import com.ningxia.yunxi.chemmes.framework.tenant.core.aop.TenantIgnore; import com.ningxia.yunxi.chemmes.module.infra.api.logger.dto.ApiAccessLogCreateReqDTO; -import com.ningxia.yunxi.chemmes.module.infra.dal.dataobject.logger.ApiAccessLogDO; import com.ningxia.yunxi.chemmes.module.infra.controller.admin.logger.vo.apiaccesslog.ApiAccessLogPageReqVO; +import com.ningxia.yunxi.chemmes.module.infra.dal.dataobject.logger.ApiAccessLogDO; import com.ningxia.yunxi.chemmes.module.infra.dal.mysql.logger.ApiAccessLogMapper; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -27,6 +28,7 @@ public class ApiAccessLogServiceImpl implements ApiAccessLogService { private ApiAccessLogMapper apiAccessLogMapper; @Override + @TenantIgnore public void createApiAccessLog(ApiAccessLogCreateReqDTO createDTO) { ApiAccessLogDO apiAccessLog = BeanUtils.toBean(createDTO, ApiAccessLogDO.class); if (apiAccessLog.getResultMsg().length()>200){ diff --git a/mes-ui/mes-ui-admin-vue3/src/views/biz/tsoorder/OrderForm.vue b/mes-ui/mes-ui-admin-vue3/src/views/biz/tsoorder/OrderForm.vue index ea9fe21..268ef07 100644 --- a/mes-ui/mes-ui-admin-vue3/src/views/biz/tsoorder/OrderForm.vue +++ b/mes-ui/mes-ui-admin-vue3/src/views/biz/tsoorder/OrderForm.vue @@ -217,6 +217,7 @@

产品明细

+ 新增 @@ -272,13 +273,53 @@

附件信息

- -
- - 点击上传 + + + + 上传文件 - 支持格式:doc, docx, pdf, jpg, jpeg, png 单个文件不超过50MB -
+ + + + + + + + + + + +
@@ -331,6 +372,12 @@ const deptTreeRef = ref() const userList = ref([]) const userSelectLoading = ref(false) +// 文件上传相关 +const uploadRef = ref() +const uploadUrl = import.meta.env.VITE_UPLOAD_URL +const uploadHeaders = ref({}) +const uploadedFiles = ref>([]) + // 用途数据字典 const purposeOptions = ref([]) @@ -497,6 +544,24 @@ const open = async (type: string, id?: number) => { const rows = Array.isArray(rawItems) ? rawItems : (rawItems != null ? [rawItems] : []) productList.value = rows.length ? rows.map((r) => ({ ...r })) : [] + // 处理附件信息回显 + const rawAttFile = data?.attFile + if (rawAttFile) { + try { + const attFileArray = typeof rawAttFile === 'string' ? JSON.parse(rawAttFile) : rawAttFile + if (Array.isArray(attFileArray)) { + uploadedFiles.value = attFileArray.map((item: any) => ({ + id: item.filePath?.split('/').pop() || Date.now().toString(), + name: item.fileName, + uploadTime: item.uploadTime || '-', + url: item.filePath + })) + } + } catch (e) { + console.error('解析附件信息失败', e) + } + } + console.log('处理后productList:', productList.value) } finally { formLoading.value = false @@ -532,6 +597,16 @@ const submitForm = async () => { await formRef.value?.validate?.() formLoading.value = true + + // 将上传的文件列表同步到 formData.attFile + if (uploadedFiles.value.length > 0) { + formData.attFile = JSON.stringify(uploadedFiles.value.map(item => ({ + fileName: item.name, + filePath: item.url, + uploadTime: item.uploadTime + }))) + } + const data = { ...formData, items: productList.value, @@ -561,6 +636,16 @@ const submitAudit = async () => { await formRef.value?.validate?.() formLoading.value = true + + // 将上传的文件列表同步到 formData.attFile + if (uploadedFiles.value.length > 0) { + formData.attFile = JSON.stringify(uploadedFiles.value.map(item => ({ + fileName: item.name, + filePath: item.url, + uploadTime: item.uploadTime + }))) + } + const data = { ...formData, ordStatus: 2, @@ -580,6 +665,9 @@ const submitAudit = async () => { } const resetForm = () => { + // 清空附件列表 + uploadedFiles.value = [] + // 重置表单数据,确保每个字段都是正确的类型 formData.id = undefined formData.saleOrdNo = '自动生成' @@ -771,6 +859,59 @@ const validateProductList = () => { const removeProductItem = (index: number) => { productList.value.splice(index, 1) } +// 添加上传开始时间记录 +const uploadStartTime = ref>(new Map()) + +// 文件上传前记录开始时间 +const handleBeforeUpload = (file: any) => { + uploadStartTime.value.set(file.name, Date.now()) +} + +// 文件上传成功处理 +const handleUploadSuccess = (response: any, file: any, fileList: any) => { + if (response.code === 0) { + const fileUrl = response.data + // 计算上传耗时(秒) + const startTime = uploadStartTime.value.get(file.name) || Date.now() + const uploadDuration = ((Date.now() - startTime) / 1000).toFixed(2) + 's' + uploadStartTime.value.delete(file.name) + + const fileId = fileUrl.split('/').pop() || Date.now().toString() + + uploadedFiles.value.push({ + id: fileId, + name: file.name, + uploadTime: uploadDuration, // 显示上传耗时,如 "2.35s" + url: fileUrl + }) + // ... + } +} + +// 文件上传失败时清理开始时间 +const handleUploadError = (error: any, file: any, fileList: any) => { + uploadStartTime.value.delete(file.name) + message.error('文件上传失败:' + (error.message || '未知错误')) +} + +// 文件移除处理 +const handleRemoveFile = (file: any, fileList: any) => { + // 可以在这里添加删除服务器文件的逻辑 +} + +// 文件超出限制处理 +const handleExceed = (files: any, fileList: any) => { + message.warning(`最多只能上传10个文件`) +} + +// 删除已上传的文件 +const removeUploadedFile = (row: any) => { + const index = uploadedFiles.value.findIndex(item => item.id === row.id) + if (index > -1) { + uploadedFiles.value.splice(index, 1) + message.success('文件删除成功') + } +} diff --git a/mes-ui/mes-ui-admin-vue3/src/views/biz/tsoorder/index.vue b/mes-ui/mes-ui-admin-vue3/src/views/biz/tsoorder/index.vue index dbf4eda..1ef2561 100644 --- a/mes-ui/mes-ui-admin-vue3/src/views/biz/tsoorder/index.vue +++ b/mes-ui/mes-ui-admin-vue3/src/views/biz/tsoorder/index.vue @@ -101,7 +101,7 @@ - + - + @@ -157,6 +174,8 @@ + +