From 8931cf0404272c33af7178b786eb00bd920b47db Mon Sep 17 00:00:00 2001 From: shaoleiliu-netizen123 <480188199@qq.com> Date: Wed, 3 Jun 2026 08:41:47 +0800 Subject: [PATCH 01/14] =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/biz/orderProject/index.vue | 38 +++++++++++--- src/views/biz/qualityTesting/index.vue | 58 +++++++++++++-------- src/views/biz/submitLog/index.vue | 30 ++++++----- src/views/production/dispatchwork/index.vue | 12 ++--- 4 files changed, 90 insertions(+), 48 deletions(-) diff --git a/src/views/biz/orderProject/index.vue b/src/views/biz/orderProject/index.vue index c0075fa..f331eb5 100644 --- a/src/views/biz/orderProject/index.vue +++ b/src/views/biz/orderProject/index.vue @@ -400,6 +400,8 @@ const formData = reactive({ ...defaultFormData }) // 字典选项(下拉框/单选框/复选框关联字典时使用) const sourceOptions = ref<{ label: string; value: any }[]>([]) const statusOptions = ref<{ label: string; value: any }[]>([]) +const prodTypeOptions = ref<{label: string; value:any} []>([]) + // 表单校验规则 const formRules = { @@ -419,11 +421,23 @@ const columns: DataTableColumns = [ { title: '项目来源', key: 'source', width: 110,align: 'center', render(row) { const val = row.source + console.log(sourceOptions.value); + const opt = sourceOptions.value.find(o => o.value === val || String(o.value) === String(val)) - return opt ? opt.label : (val ?? '-') + if (!opt) return val ?? '-' + + return h(NTag, { type: opt.class, size: 'small' }, { default: () => opt.label }) + } + }, + { title: '生产类型', key: 'prodType', width: 100 ,align: 'center', + render(row) { + const val = row.prodType + const opt = prodTypeOptions.value.find(o => o.value === val || String(o.value) === String(val)) + if (!opt) return val ?? '-' + + return h(NTag, { type: opt.class, size: 'small' }, { default: () => opt.label }) } }, - { title: '生产类型', key: 'prodType', width: 100 ,align: 'center'}, { title: 'BOM版本', key: 'bomVersion', width: 100 ,align: 'center'}, { title: '规格型号', key: 'specModel', width: 140, ellipsis: { tooltip: true } }, { title: '单位', key: 'unit', width: 70 ,align: 'center'}, @@ -434,7 +448,9 @@ const columns: DataTableColumns = [ render(row) { const val = row.status const opt = statusOptions.value.find(o => o.value === val || String(o.value) === String(val)) - return opt ? opt.label : (val ?? '-') + if (!opt) return val ?? '-' + + return h(NTag, { type: opt.class, size: 'small' }, { default: () => opt.label }) } }, { title: '计划完成日期', key: 'planFinishTime', width: 170 ,align: 'center'}, @@ -470,8 +486,9 @@ const columns: DataTableColumns = [ ] const pickMtrlStatusMap: Record = { - '0': '未领料', - '1': '已领料', + '1': '未领料', + '2': '待定', + '3': '已领料', } const kingdeeMoColumns: DataTableColumns = [ @@ -516,6 +533,8 @@ const kingdeeMoColumns: DataTableColumns = [ title: '领料状态', key: 'pickMtrlStatus', width: 90, align: 'center', render(row) { const val = row.pickMtrlStatus + console.log(val); + return val != null ? (pickMtrlStatusMap[String(val)] ?? val) : '-' } }, @@ -864,11 +883,16 @@ async function handleImportUpload({ file }: UploadCustomRequestOptions) { async function loadDictOptions() { try { const data = await dictDataApi.listByType('pro_source') - sourceOptions.value = data.map(d => ({ label: d.dictLabel, value: (Number(d.dictValue) || d.dictValue) })) + sourceOptions.value = data.map(d => ({ label: d.dictLabel, value: (Number(d.dictValue) || d.dictValue),class:d.listClass })) } catch {} try { const data = await dictDataApi.listByType('pro_status') - statusOptions.value = data.map(d => ({ label: d.dictLabel, value: (Number(d.dictValue) || d.dictValue) })) + statusOptions.value = data.map(d => ({ label: d.dictLabel, value: (Number(d.dictValue) || d.dictValue),class:d.listClass })) + } catch {} + + try { + const data = await dictDataApi.listByType("prod_type") + prodTypeOptions.value = data.map(d=>({label: d.dictLabel,value:(Number(d.dictValue) || d.dictValue),class:d.listClass})) } catch {} } diff --git a/src/views/biz/qualityTesting/index.vue b/src/views/biz/qualityTesting/index.vue index 766079a..6d86550 100644 --- a/src/views/biz/qualityTesting/index.vue +++ b/src/views/biz/qualityTesting/index.vue @@ -317,7 +317,7 @@ From 1b51d68a25779d137b26bd9eb55193be3c899ba1 Mon Sep 17 00:00:00 2001 From: shaoleiliu-netizen123 <480188199@qq.com> Date: Thu, 4 Jun 2026 14:49:19 +0800 Subject: [PATCH 06/14] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=B4=BE=E5=B7=A5?= =?UTF-8?q?=E5=89=8D=E7=AB=AF=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/qualityTesting.ts | 4 + src/views/biz/qualityTesting/index.vue | 110 +++++++++++++++++--- src/views/production/dispatchwork/index.vue | 16 +-- src/views/production/myassigtask/index.vue | 2 +- 4 files changed, 99 insertions(+), 33 deletions(-) diff --git a/src/api/qualityTesting.ts b/src/api/qualityTesting.ts index fd5d34d..42bca4d 100644 --- a/src/api/qualityTesting.ts +++ b/src/api/qualityTesting.ts @@ -68,6 +68,10 @@ export const qualityTestingApi = { submit(data: QcResultDetail[]) { return request({ url: '/mes/qc/judge', method: 'put', data }) }, + + submitBF(data: QcResultDetail[]) { + return request({ url: '/mes/qc/partial', method: 'post', data }) + }, //质检撤回 cancel(id: number) { return request({ url: `/mes/dispatch/revoke/${id}`, method: 'put' }) diff --git a/src/views/biz/qualityTesting/index.vue b/src/views/biz/qualityTesting/index.vue index 3d3c68d..29a26ea 100644 --- a/src/views/biz/qualityTesting/index.vue +++ b/src/views/biz/qualityTesting/index.vue @@ -312,12 +312,38 @@ - - + + + + +
+ + + +
+ + 点击或者拖动文件到该区域来上传 + + + 仅支持 PDF、DOC、DOCX,单文件最大10MB + +
+
+ + @@ -339,7 +365,7 @@ import { NButton, NSpace, NIcon, NUpload,NTag, useMessage, useDialog, type DataTableColumns, type UploadCustomRequestOptions, NDropdown } from 'naive-ui' -import { } from '@vicons/ionicons5' + import { SearchOutline, RefreshOutline, AddOutline, TrashOutline, CreateOutline, CloudUploadOutline, DownloadOutline, EllipsisHorizontalOutline, ArrowDownOutline, ArrowUpOutline @@ -391,6 +417,9 @@ const detailIsCollapse = ref(true) //提交判定明细 const submitDetailModalVisible = ref(false) const traceCodeShow = ref(false) +//提交明细/部分提交明细标识 +const submitFlag = ref() + const customOrderKeys = [ 'materialCode', @@ -522,6 +551,11 @@ const defaultFormDetailData:QcResultDetail = { handleAction: undefined, actionStatus: undefined } + +//提交附件 +const fileList = ref([]) +const uploadFiles = ref([]) + const formDetailOKData = reactive({ ...defaultFormDetailData, resultType: 1,handleAction:'下一道工序',actionStatus:1 }) const formDetailScrapData = reactive({ ...defaultFormDetailData,resultType: 2,handleAction:'报废次品',actionStatus:1 }) const formDetailReworkData = reactive({ ...defaultFormDetailData,resultType: 3,handleAction:'返工',actionStatus:1 }) @@ -567,6 +601,7 @@ const columns: DataTableColumns = [ // { title: '关联工序计划ID', key: 'processId' }, // { title: '物料ID', key: 'itemId' }, { title: '报检总数', key: 'totalQty',align: 'center' }, + { title: '已检验数量', key: 'inspectQty',align: 'center' }, { title: '质检状态', key: 'status',align: 'center', render(row) { const val = row.status @@ -606,8 +641,10 @@ const columns: DataTableColumns = [ options: [ { label: '查看详情', key: 'view' }, { type: 'divider' }, // 分割线 - { label: '提交判定明细', key: 'submitResultDetail' }, - { type: 'divider' }, // 分割线 + { label: '提交判定明细', key: 'submitResultDetail',show:row.status == 1 }, + { type: 'divider',show:row.status == 1 }, // 分割线 + { label: '提交部分判定明细', key: 'submitBFResultDetail',show:(row.status == 1 || row.status == 2) }, + { type: 'divider',show:(row.status == 1 || row.status == 2) }, // 分割线 { label: '查询判定明细', key: 'queryResultDetail' }, { type: 'divider' }, // 分割线 { label: '质检撤回', key: 'cancelQuality' }, @@ -621,6 +658,9 @@ const columns: DataTableColumns = [ case 'submitResultDetail': submitResultDetail(row) break + case 'submitBFResultDetail': + submitBFResultDetail(row) + break case 'queryResultDetail': queryResultDetail(row) break @@ -930,7 +970,7 @@ async function loadAssignWorkOrder() { } //提交判定明细 -async function submitResultDetail(row) { +function submitResultDetail(row) { Object.assign(formDetailOKData, reactive({ ...defaultFormDetailData, resultType: 1,handleAction:'下一道工序',actionStatus:1 })) Object.assign(formDetailScrapData, reactive({ ...defaultFormDetailData,resultType: 2,handleAction:'报废次品',actionStatus:1 })) Object.assign(formDetailReworkData, reactive({ ...defaultFormDetailData,resultType: 3,handleAction:'返工',actionStatus:1 })) @@ -938,6 +978,7 @@ async function submitResultDetail(row) { if (row.traceType != 1) { traceCodeShow.value = true } + submitFlag.value = true submitDetailModalVisible.value = true formDetailOKData.qcId = row.id formDetailScrapData.qcId = row.id @@ -946,18 +987,35 @@ async function submitResultDetail(row) { } async function handleSubmitResultDetail() { - try { - const submitParam = [formDetailOKData,formDetailScrapData,formDetailReworkData,formDetailConcessionData] - await qualityTestingApi.submit(submitParam) - message.success('提交成功') - }catch ( error) { - message.error('提交失败'+error) - } + const submitParam = [formDetailOKData,formDetailScrapData,formDetailReworkData,formDetailConcessionData] + submitFlag.value? await qualityTestingApi.submit(submitParam) : await qualityTestingApi.submitBF(submitParam) + + message.success('提交成功') submitDetailModalVisible.value = false loadData() } +//提交部分判定明细 +function submitBFResultDetail(row) { + Object.assign(formDetailOKData, reactive({ ...defaultFormDetailData, resultType: 1,handleAction:'下一道工序',actionStatus:1 })) + Object.assign(formDetailScrapData, reactive({ ...defaultFormDetailData,resultType: 2,handleAction:'报废次品',actionStatus:1 })) + Object.assign(formDetailReworkData, reactive({ ...defaultFormDetailData,resultType: 3,handleAction:'返工',actionStatus:1 })) + Object.assign(formDetailConcessionData, reactive({ ...defaultFormDetailData,resultType: 4,handleAction:'让步接收',actionStatus:1 })) + + if (row.traceType != 1) { + traceCodeShow.value = true + } + submitFlag.value = false + submitDetailModalVisible.value = true + formDetailOKData.qcId = row.id + formDetailScrapData.qcId = row.id + formDetailReworkData.qcId = row.id + formDetailConcessionData.qcId = row.id + +} + + //查询判定明细 function queryResultDetail(row) { let path = `detail/${row.id}`; @@ -983,6 +1041,24 @@ function handleCancelQuality(row) { }) } + +//上传附件 +const handleUploadChange = ({ file, fileList: list }: any) => { + uploadFiles.value = list.map(item => item.file) +} + +// 表单保存时调用 +const submitUpload = async (billId: number) => { + if (!uploadFiles.value.length) return + const formData = new FormData() + formData.append('billId', String(billId)) + uploadFiles.value.forEach(file => { + formData.append('files', file) + }) + console.log(uploadFiles); + +} + onMounted(() => { loadData() loadDictOptions() diff --git a/src/views/production/dispatchwork/index.vue b/src/views/production/dispatchwork/index.vue index 1b1f35f..c922db7 100644 --- a/src/views/production/dispatchwork/index.vue +++ b/src/views/production/dispatchwork/index.vue @@ -508,20 +508,6 @@ const columns = [ key: 'assingStatus', minWidth: 150, render(row:any) { - // let text = '' - // if(row.assingStatus == 1){ - // text = '待执行' - // }else if(row.assingStatus == 2){ - // text = '执行中' - // }else if(row.assingStatus == 3){ - // text = '质检中' - // }else if(row.assingStatus == 4){ - // text = '已汇报' - // }else if(row.assingStatus == 5){ - // text = '已关闭' - // } - - // return text const val = row.assingStatus const opt = qcAssingStatusOptions.value.find(o => o.value === val || String(o.value) === String(val)) if (!opt) return val ?? '-' @@ -626,7 +612,7 @@ const columns = [ } if(row.status == 2){ return h(NTag, { - type:'warning', + type:'error', size: 'small' }, { diff --git a/src/views/production/myassigtask/index.vue b/src/views/production/myassigtask/index.vue index 7ae28ff..15aa868 100644 --- a/src/views/production/myassigtask/index.vue +++ b/src/views/production/myassigtask/index.vue @@ -285,7 +285,7 @@ const columns = [ { align:'center', title: '工人名称', - key: 'stringUserName', + key: 'userName', minWidth: 200 }, { From 3e06241c9ce9b0f0992c6b42ed417db164341067 Mon Sep 17 00:00:00 2001 From: tzy <1042411602@qq.com> Date: Sat, 6 Jun 2026 11:14:24 +0800 Subject: [PATCH 07/14] =?UTF-8?q?=E7=BB=9F=E4=B8=80=E6=8E=92=E4=BA=A7?= =?UTF-8?q?=E5=90=8C=E6=AD=A5=E6=B5=81=E7=A8=8B,=E4=BF=AE=E5=A4=8DLOGO?= =?UTF-8?q?=E5=A4=B1=E6=95=88=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/orderItem.ts | 21 +- src/api/orderProject.ts | 41 +- src/layout/index.vue | 20 +- src/router/index.ts | 12 + src/stores/site.ts | 4 +- src/views/biz/orderItem/index.vue | 71 +- .../orderProject/components/GanttSchedule.vue | 666 +++++++++++++----- src/views/biz/orderProject/index.vue | 68 +- src/views/login/index.vue | 22 +- src/views/register/index.vue | 5 +- src/views/system/config/index.vue | 18 +- 11 files changed, 710 insertions(+), 238 deletions(-) diff --git a/src/api/orderItem.ts b/src/api/orderItem.ts index 18acab9..2674438 100644 --- a/src/api/orderItem.ts +++ b/src/api/orderItem.ts @@ -44,7 +44,12 @@ export interface OrderItem { assingWorkOperationTime?: string starter?: number + + orderCode?: string + routeCode?: string + + proWorkshop?: string } // 生产订单 API @@ -93,11 +98,23 @@ export const orderItemApi = { }, // 导出 - export(params?: { ids?: string[]; code?: string; projectId?: number; beginTime?: string; endTime?: string }) { + export(params?: { + ids?: string[] + code?: string + projectName?: string + orderCode?: string + routeCode?: string + proWorkshop?: string + beginTime?: string + endTime?: string + }) { const p: Record = {} if (params?.ids?.length) p.ids = params.ids.join(',') if (params?.code !== undefined && params?.code !== null) p.code = params.code - if (params?.projectId !== undefined && params?.projectId !== null) p.projectId = params.projectId + if (params?.projectName !== undefined && params?.projectName !== null) p.projectName = params.projectName + if (params?.orderCode !== undefined && params?.orderCode !== null) p.orderCode = params.orderCode + if (params?.routeCode !== undefined && params?.routeCode !== null) p.routeCode = params.routeCode + if (params?.proWorkshop !== undefined && params?.proWorkshop !== null) p.proWorkshop = params.proWorkshop if (params?.beginTime !== undefined && params?.beginTime !== null) p.beginTime = params.beginTime if (params?.endTime !== undefined && params?.endTime !== null) p.endTime = params.endTime return request({ url: `/biz/orderItem/export`, method: 'get', params: p, responseType: 'blob' }) diff --git a/src/api/orderProject.ts b/src/api/orderProject.ts index 7cea8aa..73244d3 100644 --- a/src/api/orderProject.ts +++ b/src/api/orderProject.ts @@ -69,18 +69,57 @@ export interface KingdeePrdMo { /** 金蝶工艺路线工序(树子节点) */ export interface KingdeeProcessRoute { + /** 工序号 FOperNumber */ operNumber: number | null + /** 工作中心 FWorkCenterId.FName */ workCenterName: string | null + /** 生产车间 FDepartmentId.FName */ departmentName: string | null - processProperty: string | null + /** 工序名称 FProcessProperty */ + processName: string | null + /** 工序说明 FOperDescription */ operDescription: string | null + /** 活动单位 FActivity1UnitID.FName */ activityUnit: string | null + /** 工序控制码 FOptCtrlCodeId.FName */ optCtrlCodeName: string | null + /** 活动量 FActivity1Qty */ activityQty: number | null + /** 计划开始时间 yyyy-MM-dd HH:mm:ss */ planStartTime: string | null + /** 计划结束时间 yyyy-MM-dd HH:mm:ss */ planFinishTime: string | null } +/** 解析工序名称,兼容旧字段及后端误映射 */ +export function resolveProcessName(route: Partial & { processProperty?: string | null }) { + const legacyName = typeof route.processProperty === 'string' ? route.processProperty.trim() : '' + const processName = route.processName?.trim() || legacyName || '' + const operDescription = route.operDescription?.trim() || '' + + if (processName) return processName + // 兼容:FProcessProperty 被写入 operDescription 而 processName 为空 + if (operDescription) return operDescription + return '' +} + +/** 归一化金蝶工序字段,保证 processName / operDescription 各归其位 */ +export function normalizeKingdeeProcessRoute( + route: KingdeeProcessRoute & { processProperty?: string | null } +): KingdeeProcessRoute { + const legacyName = typeof route.processProperty === 'string' ? route.processProperty.trim() : '' + const processName = route.processName?.trim() || legacyName || '' + const operDescription = route.operDescription?.trim() || '' + + if (processName) { + return { ...route, processName, operDescription: operDescription || null } + } + if (operDescription) { + return { ...route, processName: operDescription, operDescription: null } + } + return { ...route, processName: null, operDescription: null } +} + // 项目表 API export const orderProjectApi = { // 分页查询 diff --git a/src/layout/index.vue b/src/layout/index.vue index 681acb5..880415d 100644 --- a/src/layout/index.vue +++ b/src/layout/index.vue @@ -17,8 +17,11 @@ >