From 559c341ee15f9f06131bd802f15497da3fa1e637 Mon Sep 17 00:00:00 2001 From: liutao <790864623@qq.com> Date: Tue, 24 Mar 2026 11:23:25 +0800 Subject: [PATCH] =?UTF-8?q?esop=E6=96=87=E4=BB=B6=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/mes/esopFile/index.ts | 85 ++++++++++ src/locales/en.ts | 63 ++++++++ src/locales/zh-CN.ts | 61 ++++++++ src/utils/dict.ts | 2 + src/views/mes/calholiday/index.vue | 21 ++- src/views/mes/esopFile/FileForm.vue | 228 +++++++++++++++++++++++++++ src/views/mes/esopFile/index.vue | 234 ++++++++++++++++++++++++++++ src/views/mes/esopFile/useUpload.ts | 117 ++++++++++++++ 8 files changed, 803 insertions(+), 8 deletions(-) create mode 100644 src/api/mes/esopFile/index.ts create mode 100644 src/views/mes/esopFile/FileForm.vue create mode 100644 src/views/mes/esopFile/index.vue create mode 100644 src/views/mes/esopFile/useUpload.ts diff --git a/src/api/mes/esopFile/index.ts b/src/api/mes/esopFile/index.ts new file mode 100644 index 00000000..dc61322a --- /dev/null +++ b/src/api/mes/esopFile/index.ts @@ -0,0 +1,85 @@ +import request from '@/config/axios' + +// esop文件表库 VO +export interface FileVO { + id: number // id + configId: number // 配置编号 + code: string // 文件编码 + name: string // 文件名 + path: string // 文件路径 + url: string // 文件 URL + type: string // 文件类型 + class: string // 文件分类 + status: number // 文件状态 + size: number // 文件大小 +} +// 文件预签名地址 Response VO +export interface FilePresignedUrlRespVO { + // 文件配置编号 + configId: number + // 文件上传 URL + uploadUrl: string + // 文件 URL + url: string +} + +export enum ApiUrl{ + '/admin-api/mes/esop/file/create' +} + +// esop文件表库 API +export const FileApi = { + // 查询esop文件表库分页 + getFilePage: async (params: any) => { + return await request.get({ url: `/esop/file/page`, params }) + }, + + + // 查询esop文件表库详情 + getFile: async (id: number) => { + return await request.get({ url: `/esop/file/get?id=` + id }) + }, + + // 新增esop文件表库 + createFile: async (data: FileVO) => { + return await request.post({ url: `/esop/file/create`, data }) + }, + + // 修改esop文件表库 + updateFile: async (data: FileVO) => { + return await request.put({ url: `/esop/file/update`, data }) + }, + + // 删除esop文件表库 + deleteFile: async (id: number) => { + return await request.delete({ url: `/esop/file/delete?id=` + id }) + }, + + // 导出esop文件表库 Excel + exportFile: async (params) => { + return await request.download({ url: `/esop/file/export-excel`, params }) + }, + // 获取文件编码 + generateCode: async () => { + return await request.get({ url: `/esop/file/generate`}) + }, + +} + +// 获取文件预签名地址 +export const getFilePresignedUrl = (path: string) => { + return request.get({ + url: '/infra/file/presigned-url', + params: { path } + }) +} + +// 创建文件 +export const createFile = (data: any) => { + return request.post({ url: '/esop/file/create', data }) +} + +// 上传文件 +export const updateFile = (data: any) => { + return request.upload({ url: '/esop/file/create', data }) +} diff --git a/src/locales/en.ts b/src/locales/en.ts index f3635b38..b87650a0 100644 --- a/src/locales/en.ts +++ b/src/locales/en.ts @@ -2069,6 +2069,69 @@ export default { validatorNameRequired: 'Unit name can not be empty', validatorStatusRequired: 'Unit status can not be empty', validatorPrimaryFlagRequired: 'Primary unit flag can not be empty' + }, + CalHoliday: { + setWorkingDays: 'set working days', + setHoliday: 'set holiday', + lastMonth:'last month', + today:'today', + nextMonth:'next month', + work:'work', + rest:'rest', + searchDateStartPlaceholder: '开始日期', + searchDateEndPlaceholder: '结束日期', + searchTypeLabel: '类型', + searchTypePlaceholder: '请选择类型', + searchRemarkLabel: '备注', + searchRemarkPlaceholder: '请输入备注', + searchButtonText: '搜索', + resetButtonText: '重置', + addButtonText: '新增', + exportButtonText: '导出' + }, + + EsopFile: { + moduleName: 'File Management', + searchCodeLabel: 'File Code', + searchCodePlaceholder: 'Please enter file code', + searchFileNameLabel: 'File_Name', + searchFileNamePlaceholder: 'Please enter file name', + searchClassificationLabel: 'File Classification', + searchClassificationPlaceholder: 'Please select file Classification', + searchStatusLabel: 'File Status', + searchStatusPlaceholder: 'Please select file status', + searchButtonText: 'Search', + resetButtonText: 'Reset', + uploadButtonText: 'Upload', + exportButtonText: 'Export', + tableCodeColumn: 'File Code', + tableNameColumn: 'File Name', + tableClassificationColumn: 'File Classification', + tableTypeColumn: 'File Type', + tableStatusColumn: 'File Status', + tableCreatorNameColumn: 'Uploader', + tableCreateTimeColumn: 'Upload Time', + tableOperateColumn: 'Operation', + tableEditAction: 'Edit', + tableDownloadAction: 'Download', + tableDeleteAction: 'Delete', + dialogFileNameLabel: 'File Name', + dialogFileNamePlaceholder: 'Please enter file name', + dialogClassificationLabel: 'File Classification', + dialogClassificationPlaceholder: 'Please select file classification', + dialogStatusLabel: 'File Status', + dialogCancelButton: 'Cancel', + dialogSubmitButton: 'Confirm', + messageOne: 'Tip: Only ', + messageTwo: ' format files are allowed to be imported!', + messageThree: ' Drag the file to this area, or ', + messageFour: ' click to upload', + validatorCodeRequired: 'File code can not be empty', + validatorNameRequired: 'File name can not be empty', + validatorClassificationRequired: 'File classification can not be empty', + validatorTypeRequired: 'File type can not be empty', + validatorStatusRequired: 'File status can not be empty' + } }, diff --git a/src/locales/zh-CN.ts b/src/locales/zh-CN.ts index 19048918..0a50671b 100644 --- a/src/locales/zh-CN.ts +++ b/src/locales/zh-CN.ts @@ -2875,7 +2875,66 @@ export default { validatorNameRequired: '单位名称不能为空', validatorStatusRequired: '单位状态不能为空', validatorPrimaryFlagRequired: '是否主单位不能为空' + }, + //假日管理 + CalHoliday: { + setWorkingDays: '设置工作日', + setHoliday: '设置休息日', + lastMonth:'上个月', + today:'今天', + nextMonth:'下个月', + work:'班', + rest:'休', + searchDateStartPlaceholder: '开始日期', + searchDateEndPlaceholder: '结束日期', + searchTypeLabel: '类型', + searchTypePlaceholder: '请选择类型', + searchRemarkLabel: '备注', + searchRemarkPlaceholder: '请输入备注', + searchButtonText: '搜索', + resetButtonText: '重置', + addButtonText: '新增', + exportButtonText: '导出' + }, + //esop文件管理 + EsopFile: { + searchFileNameLabel: '文件名称', + searchFileNamePlaceholder: '请输入文件名', + searchClassificationLabel: '文件分类', + searchClassificationPlaceholder: '请选择文件分类', + searchStatusLabel: '文件状态', + searchStatusPlaceholder: '请选择文件状态', + searchButtonText: '搜索', + resetButtonText: '重置', + uploadButtonText: '文件上传', + addButtonText: '新增', + exportButtonText: '导出', + tableCodeColumn:'文件编码', + tableNameColumn: '文件名称', + tableClassificationColumn: '文件分类', + tableTypeColumn: '文件类型', + tableStatusColumn: '文件状态', + tableCreatorNameColumn: '上传人', + tableCreateTimeColumn: '上传时间', + tableOperateColumn: '操作', + tableEditAction: '编辑', + tableDownloadAction:'下载', + tableDeleteAction: '删除', + dialogFileNameLabel: '文件名', + dialogFileNamePlaceholder: '请输入文件名', + dialogClassificationLabel: '文件分类', + dialogClassificationPlaceholder: '请选择文件分类', + dialogStatusLabel: '文件状态', + dialogCancelButton: '取 消', + dialogSubmitButton: '确 定', + messageOne:'提示:仅允许导入 ', + messageTwo:' 格式文件!', + messageThree:' 将文件拖到此处,或', + messageFour:'点击上传', + validatorNameRequired: '文件名不能为空', + validatorStatusRequired: '文件状态不能为空' } + }, ProductionPlan: { Task: { @@ -4221,6 +4280,8 @@ export default { messageDeviceNoParams: '该设备下没有参数', messageFetchChartFailed: '获取图表数据失败' } + + } } } diff --git a/src/utils/dict.ts b/src/utils/dict.ts index 2d3cc806..1b5589e4 100644 --- a/src/utils/dict.ts +++ b/src/utils/dict.ts @@ -266,6 +266,8 @@ export enum DICT_TYPE { MOLD_GET_STATUS = "mold_get_status", MES_PRE_PRODUCTION = "mes_pre_production", MES_ZJ_PRODUCT = "mes_zj_product", + FILE_STATUS = "file_status", + Classification = "classification", //====iot IOT_SIEMENS_TYPE = "iot_siemens_type", IOT_MODBUS_TYPE = "iot_modbus_type", diff --git a/src/views/mes/calholiday/index.vue b/src/views/mes/calholiday/index.vue index 928a562c..118cdaf9 100644 --- a/src/views/mes/calholiday/index.vue +++ b/src/views/mes/calholiday/index.vue @@ -22,33 +22,33 @@ type="primary" size="small" @click="handleWorkday(date)" - >设置工作日 + >{{ t('FactoryModeling.CalHoliday.setWorkingDays') }} 设置休息日 + >{{ t('FactoryModeling.CalHoliday.setHoliday') }} - 上个月 + {{ t('FactoryModeling.CalHoliday.lastMonth') }} - 今天 + {{ t('FactoryModeling.CalHoliday.today') }} - 下个月 + {{ t('FactoryModeling.CalHoliday.nextMonth') }} @@ -64,8 +64,8 @@ - - + {{ t('FactoryModeling.CalHoliday.work') }} + {{ t('FactoryModeling.CalHoliday.rest') }} @@ -138,21 +138,26 @@ const loadMonthData = () => { // 原按钮的事件处理 const handleOriginalPrevMonth = () => { + queryParams.theDay = dayjs(currentDate.value).format('YYYY-MM-DD'); currentDate.value = dayjs(currentDate.value) .subtract(1, 'month') .toDate() loadMonthData() + getList() } const handleOriginalNextMonth = () => { + queryParams.theDay = dayjs(currentDate.value).format('YYYY-MM-DD'); currentDate.value = dayjs(currentDate.value) .add(1, 'month') .toDate() loadMonthData() + getList() } const handleOriginalToday = () => { - currentDate.value = new Date() + currentDate.value = new Date(); + queryParams.theDay = dayjs(currentDate.value).format('YYYY-MM-DD'); loadMonthData() } diff --git a/src/views/mes/esopFile/FileForm.vue b/src/views/mes/esopFile/FileForm.vue new file mode 100644 index 00000000..6da59b3a --- /dev/null +++ b/src/views/mes/esopFile/FileForm.vue @@ -0,0 +1,228 @@ + + diff --git a/src/views/mes/esopFile/index.vue b/src/views/mes/esopFile/index.vue new file mode 100644 index 00000000..a8266a08 --- /dev/null +++ b/src/views/mes/esopFile/index.vue @@ -0,0 +1,234 @@ + + + diff --git a/src/views/mes/esopFile/useUpload.ts b/src/views/mes/esopFile/useUpload.ts new file mode 100644 index 00000000..5276ae76 --- /dev/null +++ b/src/views/mes/esopFile/useUpload.ts @@ -0,0 +1,117 @@ +import * as FileApi from '@/api/mes/esopFile' +import CryptoJS from 'crypto-js' +import { UploadRawFile, UploadRequestOptions } from 'element-plus/es/components/upload/src/upload' +import axios from 'axios' + +/** + * 获得上传 URL + */ +export const getUploadUrl = (): string => { + return import.meta.env.VITE_BASE_URL + import.meta.env.VITE_API_URL + '/esop/file/create' +} + +export const useUpload = () => { + // 后端上传地址 + const uploadUrl = getUploadUrl() + // 是否使用前端直连上传 + const isClientUpload = UPLOAD_TYPE.CLIENT === import.meta.env.VITE_UPLOAD_TYPE + // 重写ElUpload上传方法 + const httpRequest = async (options: UploadRequestOptions) => { + // 模式一:前端上传 + if (isClientUpload) { + const fileName = await generateFileName(options.file) + const presignedInfo = await FileApi.getFilePresignedUrl(fileName) + return axios + .put(presignedInfo.uploadUrl, options.file, { + headers: { + 'Content-Type': options.file.type + } + }) + .then(() => { + const fileVo = createFile(presignedInfo, fileName, options.file) + return { + code: 0, + status: 0, + data: { + fileName: fileVo.path, + fileUrl: fileVo.url + }, + msg: '' + } + }) + } else { + const fileVo = { + file: options.file, + code: options.data.params.code, + name: options.data.params.name, + type: options.data.params.type, + classification: options.data.params.classification, + status: options.data.params.status, + } + // 模式二:后端上传 + // 重写 el-upload httpRequest 文件上传成功会走成功的钩子,失败走失败的钩子 + return new Promise((resolve, reject) => { + FileApi.updateFile(fileVo) + .then((res) => { + if (res.code === 0) { + resolve(res) + } else { + reject(res) + } + }) + .catch((res) => { + reject(res) + }) + }) + } + } + + return { + uploadUrl, + httpRequest + } +} + +/** + * 创建文件信息 + * @param vo 文件预签名信息 + * @param name 文件名称 + * @param file 文件 + */ +function createFile(vo: FileApi.FilePresignedUrlRespVO, name: string, file: UploadRawFile) { + const fileVo = { + configId: vo.configId, + url: vo.url, + path: name, + name: file.name, + type: file.type, + size: file.size + } + FileApi.createFile(fileVo) + return fileVo +} + +/** + * 生成文件名称(使用算法SHA256) + * @param file 要上传的文件 + */ +async function generateFileName(file: UploadRawFile) { + // 读取文件内容 + const data = await file.arrayBuffer() + const wordArray = CryptoJS.lib.WordArray.create(data) + // 计算SHA256 + const sha256 = CryptoJS.SHA256(wordArray).toString() + // 拼接后缀 + const ext = file.name.substring(file.name.lastIndexOf('.')) + return `${sha256}${ext}` +} + +/** + * 上传类型 + */ +enum UPLOAD_TYPE { + // 客户端直接上传(只支持S3服务) + CLIENT = 'client', + // 客户端发送到后端上传 + SERVER = 'server' +}