From db23574959907a941b1a2b4095a4a5fc1f920d0c Mon Sep 17 00:00:00 2001 From: andy <1042025947@qq.com> Date: Wed, 15 Jul 2026 15:32:27 +0800 Subject: [PATCH 1/5] =?UTF-8?q?=E8=B0=83=E6=95=B4=E6=9D=A1=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/biz/flowingAround/index.vue | 40 +++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/src/views/biz/flowingAround/index.vue b/src/views/biz/flowingAround/index.vue index cf8d556..34f31de 100644 --- a/src/views/biz/flowingAround/index.vue +++ b/src/views/biz/flowingAround/index.vue @@ -103,7 +103,7 @@ \ No newline at end of file diff --git a/src/components/SumbitDetailCard.vue b/src/components/SumbitDetailCard.vue new file mode 100644 index 0000000..ac2c1f6 --- /dev/null +++ b/src/components/SumbitDetailCard.vue @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/views/biz/device/index.vue b/src/views/biz/device/index.vue index 2ff0169..f89c3a1 100644 --- a/src/views/biz/device/index.vue +++ b/src/views/biz/device/index.vue @@ -63,15 +63,6 @@ - - - - - + + @@ -148,7 +145,6 @@ import { NButton, NSpace,NTag, NIcon, NUpload, useMessage, useDialog, type DataT import { SearchOutline, RefreshOutline, AddOutline, TrashOutline, CreateOutline, CloudUploadOutline, DownloadOutline } from '@vicons/ionicons5' import { deviceApi, type Device } from '@/api/device' -import { stationApi, type Station } from '@/api/station' import { dictDataApi } from '@/api/org' import {sectionApi, type Section} from '@/api/section' @@ -193,7 +189,8 @@ const defaultFormData: Device = { manufactureDate: undefined, workshopId: '', remark: '', - status:'' + status:0, + deviceFlag:'mes_equipment' } const formData = reactive({ ...defaultFormData }) @@ -201,6 +198,8 @@ const formData = reactive({ ...defaultFormData }) const deviceTypeList = ref<{ label: string; value: any ;class:any}[]>([]) const statusList = ref<{ label: string; value: any ;class:any}[]>([]) +const deviceFlagList = ref<{ label: string; value: any ;class:any}[]>([]) + // 表单校验规则 const formRules = { } @@ -248,7 +247,8 @@ async function loadData() { const res = await deviceApi.page({ page: pagination.page, pageSize: pagination.pageSize, - deviceCode:searchForm.deviceCode + deviceCode:searchForm.deviceCode, + deviceFlag:"mes_equipment" }) tableData.value = res.list pagination.itemCount = res.total @@ -297,12 +297,7 @@ function handleAdd() { // 编辑 function handleEdit(row: Device) { modalTitle.value = '编辑设备表' - console.log(row); - Object.assign(formData, row) - if (formData.manufactureDate && typeof formData.manufactureDate === 'string') { - formData.manufactureDate = new Date(formData.manufactureDate.replace(' ', 'T')).getTime() - } modalVisible.value = true } @@ -432,6 +427,10 @@ async function loadDictOptions() { const data = await dictDataApi.listByType("sys_status") statusList.value = data.map(d => ({ label: d.dictLabel, value: (Number(d.dictValue) || d.dictValue),class:d.listClass })) }catch {} + try { + const data = await dictDataApi.listByType("mes_device_flag") + deviceFlagList.value = data.map(d => ({ label: d.dictLabel, value: (Number(d.dictValue) || d.dictValue),class:d.listClass })) + }catch {} } diff --git a/src/views/biz/flowingAround/assingWork.vue b/src/views/biz/flowingAround/assingWork.vue index 5e92e3f..4fe2e80 100644 --- a/src/views/biz/flowingAround/assingWork.vue +++ b/src/views/biz/flowingAround/assingWork.vue @@ -7,7 +7,10 @@ - + @@ -17,12 +20,14 @@ import { ref, reactive, h, defineProps, onMounted, watch} from 'vue'; import { info } from '@/api/production' - const props = defineProps<{ +const props = defineProps<{ id: number; - num: number + num: number; + qcNumDisabled:boolean }>(); -const emit = defineEmits(['updateWidth']) +const emit = defineEmits(['updateWidth','updateQcNum']) + let pauseform = reactive({ id:'', @@ -38,6 +43,10 @@ async function loadData(){ } +function handleQcNumChange(){ + emit('updateQcNum', pauseform.qcNum) +} + watch(() => props.id, (val: number)=>{ loadData(); }) diff --git a/src/views/biz/flowingAround/index.vue b/src/views/biz/flowingAround/index.vue index cf8d556..1ec62ff 100644 --- a/src/views/biz/flowingAround/index.vue +++ b/src/views/biz/flowingAround/index.vue @@ -95,7 +95,16 @@ - + + @@ -109,6 +118,7 @@ import { SearchOutline, RefreshOutline, AddOutline, TrashOutline, CreateOutline, import { flowingAroundApi, type FlowingAround } from '@/api/flowingAround' import { dictDataApi } from '@/api/org' import AssingWorkVue from '@/views/biz/flowingAround/assingWork.vue' +import SubmitDetailPage from '@/components/SubmitDetailPage.vue' const message = useMessage() const dialog = useDialog() @@ -226,7 +236,7 @@ async function loadData() { } -let parentWidth = ref('width: 40%;') +let parentWidth = ref('width: 20%;') function handleUpdateWidth(width:string){ @@ -273,6 +283,8 @@ const modalCheckData = ref() const modalCheckTitle = ref('') //查看提交数据 function handleView(row: FlowingAround){ + console.log(row); + modalCheckTitle.value = '提交详情' modalCheckData.value = row modalCheckVisible.value = true diff --git a/src/views/biz/orderProcessPlan/board.vue b/src/views/biz/orderProcessPlan/board.vue index 4e7a7fe..1c1161a 100644 --- a/src/views/biz/orderProcessPlan/board.vue +++ b/src/views/biz/orderProcessPlan/board.vue @@ -402,7 +402,7 @@ const dispatchLoading = ref(false) const dispatchformRef = ref() const dispatchform = reactive({ id: '', name: '', beginTime: '', endTime: '', quantity: '', - list: [{ sectionId:'',deviceId:'',userId: '', quantity: '' }], + list: [{ sectionId:'',deviceList:'',userList: '', quantity: '' }], }) const dispatchrules = {} @@ -606,11 +606,13 @@ function disphand(process: ProcessPlanItemVO, order?: OrderProcessPlanVO) { dispatchform.beginTime = entity.beginTime dispatchform.endTime = entity.endTime dispatchform.quantity = entity.quantity - dispatchform.list = [{ sectionId:'',deviceId:'',userId: '', quantity: '' }] + dispatchform.orderItemId = entity.orderItemId + dispatchform.sort = entity.sort + dispatchform.list = [{ sectionId:'',deviceList:'',userList: '', quantity: '' }] } function addpgnum() { - dispatchform.list.push({ sectionId:'',deviceId:'',userId: '', quantity: '' }) + dispatchform.list.push({ sectionId:'',deviceList:'',userList: '', quantity: '' }) } function deletenum(index: number) { @@ -619,13 +621,17 @@ function deletenum(index: number) { function dispatchSubmit() { let total = 0 - dispatchform.list.forEach((n: any) => { total += Number(n.quantity) || 0 }) + dispatchform.list.forEach((n: any) => { + total += Number(n.quantity) || 0 + }) + dispatchformRef.value?.validate((v: boolean) => { if (v) return if (total !== Number(dispatchform.quantity)) { message.error('派工总数量需等于生产总数', { duration: 4000 }) return } + dispatchLoading.value = true orderProcessPlanApi.assignWork(dispatchform).then(() => { message.success('派工成功') diff --git a/src/views/biz/orderProcessPlan/pgitem.vue b/src/views/biz/orderProcessPlan/pgitem.vue index 718bbec..93754c2 100644 --- a/src/views/biz/orderProcessPlan/pgitem.vue +++ b/src/views/biz/orderProcessPlan/pgitem.vue @@ -27,19 +27,28 @@ = [ // { title: '关联生产订单ID', key: 'orderId' }, // { title: '关联工序计划ID', key: 'processId' }, // { title: '物料ID', key: 'itemId' }, + { title: '追溯码', key: 'traceCode',align: 'center' }, { title: '报检总数', key: 'totalQty',align: 'center' }, { title: '已检验数量', key: 'inspectQty',align: 'center' }, { title: '质检状态', key: 'status',align: 'center', @@ -508,12 +509,12 @@ const columns: DataTableColumns = [ { label: '查看详情', key: 'view' }, { 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 }, // 分割线 + // { 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' }, + // { type: 'divider' }, // 分割线 + // { label: '质检撤回', key: 'cancelQuality' }, ], // 下拉菜单项点击事件 onSelect: (key: string) => { @@ -524,15 +525,15 @@ const columns: DataTableColumns = [ case 'submitResultDetail': submitResultDetail(row) break - case 'submitBFResultDetail': - submitBFResultDetail(row) - break + // case 'submitBFResultDetail': + // submitBFResultDetail(row) + // break case 'queryResultDetail': queryResultDetail(row) break - case 'cancelQuality': - handleCancelQuality(row) - break + // case 'cancelQuality': + // handleCancelQuality(row) + // break } } }, { @@ -844,7 +845,7 @@ function submitResultDetail(row:any) { submitFlag.value = true - let path = `/qc/submitDetail/${row.qcNo}/${row.id}/${submitFlag.value}/${traceCodeShow.value}` + let path = `/qc/submitDetail/${row.qcNo}/${row.id}/${submitFlag.value}/${row.traceCode}` router.push(path) } diff --git a/src/views/biz/station/index.vue b/src/views/biz/station/index.vue index 4f01338..8c6b4ec 100644 --- a/src/views/biz/station/index.vue +++ b/src/views/biz/station/index.vue @@ -4,8 +4,8 @@ - - + + @@ -61,10 +61,10 @@ - - + + - + - + 导入说明 @@ -128,20 +128,24 @@ import { ref, reactive, h, onMounted } from 'vue' import { NButton, NSpace,NTag, NIcon, NUpload, useMessage, useDialog, type DataTableColumns, type UploadCustomRequestOptions } from 'naive-ui' import { SearchOutline, RefreshOutline, AddOutline, TrashOutline, CreateOutline, CloudUploadOutline, DownloadOutline } from '@vicons/ionicons5' -import { stationApi, type Station } from '@/api/station' +import { deviceApi, type Device } from '@/api/device' + import { dictDataApi } from '@/api/org' import {sectionApi, type Section} from '@/api/section' + const message = useMessage() const dialog = useDialog() +let sectionList = reactive<{label:string,value:any}[]>([]) + // 搜索表单 const searchForm = reactive({ - stationCode: null as string | null, + deviceCode: null as number | null, }) // 表格数据 -const tableData = ref([]) +const tableData = ref([]) const loading = ref(false) const selectedIds = ref([]) const pagination = reactive({ @@ -157,42 +161,48 @@ const modalVisible = ref(false) const modalTitle = ref('') const importModalVisible = ref(false) const formRef = ref() -const defaultFormData: Station = { - id:'', - stationCode: '', - stationName: '', - sectionId: undefined, - status:undefined, - remark:undefined +const defaultFormData: Device = { + id:"", + deviceCode: '', + deviceName: '', + deviceTypeId: undefined, + deviceType:"", + sectionId: "", + sectionName:"", + spec: '', + manufacturer: '', + manufactureDate: undefined, + workshopId: '', + remark: '', + status:0, + deviceFlag:'mes_station' } -const formData = reactive({ ...defaultFormData }) - -let sectionList = reactive<{label:string,value:any}[]>([]) +const formData = reactive({ ...defaultFormData }) // 字典选项(下拉框/单选框/复选框关联字典时使用) +const deviceTypeList = ref<{ label: string; value: any ;class:any}[]>([]) const statusList = ref<{ label: string; value: any ;class:any}[]>([]) +const deviceFlagList = ref<{ label: string; value: any ;class:any}[]>([]) // 表单校验规则 const formRules = { } // 表格列 -const columns: DataTableColumns = [ +const columns: DataTableColumns = [ { type: 'selection' }, - { title: '工位编码', key: 'stationCode' }, - { title: '工位名称', key: 'stationName' }, + { title: '工位编码', key: 'deviceCode' }, + { title: '工位名称', key: 'deviceName' }, { title: '所属工段', key: 'sectionName' }, - { title: '备注', key: 'remark' }, - { title: '启用状态', key: 'status', + { title: '状态', key: 'status', render:(row) =>{ const val = row.status const opt = statusList.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: 'createTime' }, +}, { title: '操作', key: 'actions', @@ -215,10 +225,11 @@ const columns: DataTableColumns = [ async function loadData() { loading.value = true try { - const res = await stationApi.page({ + const res = await deviceApi.page({ page: pagination.page, pageSize: pagination.pageSize, - stationCode: searchForm.stationCode || undefined, + deviceCode:searchForm.deviceCode, + deviceFlag:"mes_station" }) tableData.value = res.list pagination.itemCount = res.total @@ -235,7 +246,7 @@ function handleSearch() { // 重置 function handleReset() { - searchForm.stationCode = null + searchForm.deviceCode = null handleSearch() } @@ -259,14 +270,16 @@ function handleCheck(keys: Array) { // 新增 function handleAdd() { - modalTitle.value = '新增工位表' + modalTitle.value = '新增设备表' Object.assign(formData, defaultFormData) modalVisible.value = true } // 编辑 -function handleEdit(row: Station) { - modalTitle.value = '编辑工位表' +function handleEdit(row: Device) { + modalTitle.value = '编辑设备表' + console.log(row); + Object.assign(formData, row) modalVisible.value = true } @@ -275,12 +288,12 @@ function handleEdit(row: Station) { async function handleSubmit() { await formRef.value?.validate() try { - const submitData = { ...formData } as Station + const submitData = { ...formData } as Device if (submitData.id) { - await stationApi.update(submitData) + await deviceApi.update(submitData) message.success('修改成功') } else { - await stationApi.create(submitData) + await deviceApi.create(submitData) message.success('新增成功') } modalVisible.value = false @@ -291,7 +304,7 @@ async function handleSubmit() { } // 删除 -function handleDelete(row: Station) { +function handleDelete(row: Device) { dialog.warning({ title: '提示', content: '确定要删除该记录吗?', @@ -299,7 +312,7 @@ function handleDelete(row: Station) { negativeText: '取消', onPositiveClick: async () => { try { - await stationApi.delete([row.id!]) + await deviceApi.delete([row.id!]) message.success('删除成功') loadData() } catch (error) { @@ -318,7 +331,7 @@ function handleBatchDelete() { negativeText: '取消', onPositiveClick: async () => { try { - await stationApi.delete(selectedIds.value) + await deviceApi.delete(selectedIds.value) message.success('删除成功') selectedIds.value = [] loadData() @@ -334,12 +347,12 @@ async function handleExport() { try { const params: Record = {} if (selectedIds.value.length > 0) params.ids = selectedIds.value - if (searchForm.stationCode != null) params.stationCode = searchForm.stationCode - const blob = await stationApi.export(params) + if (searchForm.deviceCode != null) params.deviceCode = searchForm.deviceCode + const blob = await deviceApi.export(params) const url = window.URL.createObjectURL(blob) const link = document.createElement('a') link.href = url - link.download = '工位表数据.xlsx' + link.download = '设备表数据.xlsx' link.click() window.URL.revokeObjectURL(url) } catch (error) { @@ -350,11 +363,11 @@ async function handleExport() { // 下载导入模板 async function handleDownloadTemplate() { try { - const blob = await stationApi.downloadTemplate() + const blob = await deviceApi.downloadTemplate() const url = window.URL.createObjectURL(blob) const link = document.createElement('a') link.href = url - link.download = '工位表导入模板.xlsx' + link.download = '设备表导入模板.xlsx' link.click() window.URL.revokeObjectURL(url) } catch (error) { @@ -366,7 +379,7 @@ async function handleDownloadTemplate() { async function handleImportUpload({ file }: UploadCustomRequestOptions) { if (!file.file) return try { - const result = await stationApi.importData(file.file) + const result = await deviceApi.importData(file.file) if (result.fail > 0) { dialog.warning({ title: '导入结果', @@ -385,10 +398,19 @@ async function handleImportUpload({ file }: UploadCustomRequestOptions) { // 加载字典选项 async function loadDictOptions() { - try { - const data = await dictDataApi.listByType("sys_status") - statusList.value = data.map(d => ({ label: d.dictLabel, value: (Number(d.dictValue) || d.dictValue),class:d.listClass })) - }catch {} + try { + const data = await dictDataApi.listByType("device_type") + deviceTypeList.value = data.map(d => ({ label: d.dictLabel, value: (Number(d.dictValue) || d.dictValue),class:d.listClass })) + }catch {} + + try { + const data = await dictDataApi.listByType("sys_status") + statusList.value = data.map(d => ({ label: d.dictLabel, value: (Number(d.dictValue) || d.dictValue),class:d.listClass })) + }catch {} + try { + const data = await dictDataApi.listByType("mes_device_flag") + deviceFlagList.value = data.map(d => ({ label: d.dictLabel, value: (Number(d.dictValue) || d.dictValue),class:d.listClass })) + }catch {} } diff --git a/src/views/production/dispatchwork/index.vue b/src/views/production/dispatchwork/index.vue index 23dd5b8..2a13a94 100644 --- a/src/views/production/dispatchwork/index.vue +++ b/src/views/production/dispatchwork/index.vue @@ -496,6 +496,24 @@ const columns = [ key: 'processName', minWidth: 200 }, + { + align:'center', + title:"追溯类型", + key:"traceType", + render(row:any) { + const val = row.traceType + if(val == 1) return '-' + if(val == 2) return '追溯码' + if(val == 3) return '批次码' + }, + minWidth:80 + }, + // { + // align:'center', + // title:"追溯码/批次号", + // key:"traceCode", + // minWidth:200 + // }, { align:'center', title: '派工状态', @@ -557,6 +575,26 @@ const columns = [ key: 'reworkNum', minWidth: 150 }, + { + align:'center', + title:"是否质检", + key:"isQual", + minWidth:100, + render(row:any) { + const qual = row.isQual === 1 + return h(NTag, {type: qual ? 'error' : 'success', size: 'small'}, {default: () => (qual ? '是' : '否')}) + } + }, + { + align:'center', + title:"是否直接入库", + key:"isStorage", + minWidth:120, + render(row:any) { + const storage = row.isQual === 1 + return h(NTag, {type: storage ? 'error' : 'success', size: 'small'}, {default: () => (storage ? '是' : '否')}) + } + }, { align:'center', title: '完成数量', diff --git a/src/views/production/myassigtask/index.vue b/src/views/production/myassigtask/index.vue index a01aff3..1591f46 100644 --- a/src/views/production/myassigtask/index.vue +++ b/src/views/production/myassigtask/index.vue @@ -120,24 +120,20 @@ style="width: 400px" :mask-closable="false" > + + + - - - - - - - - - - - 取消 @@ -148,9 +144,10 @@ :disabled="pauseisedbtn" >保存 - - - + + + + @@ -174,7 +171,7 @@ import { // NGi, NTag, useMessage, - //useDialog, + useDialog, //type FormInst, } from 'naive-ui' @@ -191,8 +188,11 @@ import { } from '@/api/production' import PlmModelDrawer from '@/components/PlmModelDrawer.vue' import type { PlmModelOpenContext } from '@/api/plmModel' +import AssingWorkVue from '@/views/biz/flowingAround/assingWork.vue' +import { qualityTestingApi, type QualityTesting } from '@/api/qualityTesting' +import SumbitDetailCard from '@/components/SumbitDetailCard.vue' -//const dialog = useDialog() +const dialog = useDialog() const message = useMessage() @@ -431,7 +431,7 @@ const columns = [ align:'center', title: '操作', key: 'actions', - width: 100, + width: 250, fixed: 'right', render(row:any) { const buttons:any = [] @@ -442,7 +442,7 @@ const columns = [ type:'primary', ghost:true, onClick: () => { handlpause(row) } }, - { default: () => '报检'} + { default: () => '完工汇报'} )) } buttons.push(h(NButton, { @@ -452,6 +452,13 @@ const columns = [ onClick: () => openPlmModel(row), }, { default: () => '模型' })) + buttons.push(h(NButton, { + size: 'small', + type: 'info', + ghost: true, + onClick: ()=> cancelQuality(row) + }, { default: () => '质检撤回' })) + return buttons.length > 0 ? h(NSpace, {justify:'center'}, { default: () => buttons }) : '-' } } @@ -506,7 +513,9 @@ let gxobg = reactive({}) let pausemodal = ref(false) let pauseform = reactive({ id:'', - qcNum:'' + qcNum:'', + okData:undefined, + scrapData:undefined }) const pauseformRef = ref() @@ -542,13 +551,39 @@ function handlpause(n:any) { pauseformRef.value?.restoreValidation() pauseform.id = n.id //pauseform.qcNum = `${n.quantity}` - pauseform.qcNum = n.quantity-(n.completedQuantity ?? 0) + // pauseform.qcNum = n.quantity-(n.completedQuantity ?? 0) +} + +function checkPauseSumbit():boolean { + if(pauseform.id == null) { + message.error("参数id为空") + return false + } + + if(pauseform.qcNum == null || pauseform.qcNum == '') { + message.error("质检数量不能为空") + return false + } + + //检查合格数量和报废数量总和是不是等于提交总数 + const checkNum = pauseform.okData?.qty + pauseform.scrapData?.qty + + if(checkNum != pauseform.qcNum) { + message.error("汇报数量总和不等于提交数量") + return false + } + return true } function pauseSubmit() { - pauseformRef.value?.validate((v:any) => { - if(!v){ - pauseLoading.value = true + + var pass = checkPauseSumbit(); + + console.log(pass); + + if(!pass) return + + pauseLoading.value = true pauseisedbtn.value = true inspectio(Object.assign({},pauseform,{qcNum:pauseform.qcNum*1})).then(() => { message.success('操作成功!') @@ -561,11 +596,22 @@ function pauseSubmit() { }).catch(() => { pauseLoading.value = false pauseisedbtn.value = false - }) - } }) } +function handleUpdateQcNum(qcNum:number) { + pauseform.qcNum = qcNum +} + +function handleSubmitDetail(submitDetail:any){ + pauseform.okData = submitDetail.okData + pauseform.scrapData = submitDetail.scrapData + console.log(pauseform); + + + +} + // 加载字典选项 async function loadDictOptions() { try { @@ -588,10 +634,27 @@ async function loadDictOptions() { // } // }) // } -onMounted(() => { - - getlist() +function cancelQuality(row:any) { + dialog.warning({ + title: '提示', + content: '确定要撤回质检记录吗?', + positiveText: '确定', + negativeText: '取消', + onPositiveClick: async () => { + try { + await qualityTestingApi.cancel(row.id) + message.success('撤回成功') + getlist() + } catch (error) { + console.log("撤回失败"+error) + } + } + }) +} + +onMounted(() => { + getlist() loadDictOptions() }) From 45815cb6020efccaee8e11bf593a4b91134682f9 Mon Sep 17 00:00:00 2001 From: shaoleiliu-netizen123 <480188199@qq.com> Date: Fri, 17 Jul 2026 11:05:57 +0800 Subject: [PATCH 3/5] =?UTF-8?q?=E5=AE=8C=E5=B7=A5=E6=B1=87=E6=8A=A5?= =?UTF-8?q?=E8=B4=A8=E6=A3=80=E8=AF=A6=E6=83=85=20=E6=92=A4=E5=9B=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/qcResultDetail.ts | 7 + src/api/qualityTesting.ts | 6 +- src/api/submitLog.ts | 2 + src/components/SumbitDetailCard.vue | 41 +- src/views/biz/qualityTesting/detail.vue | 11 +- src/views/biz/qualityTesting/index.vue | 123 +++--- src/views/biz/qualityTesting/submitDetail.vue | 361 ++++-------------- src/views/biz/submitLog/index.vue | 42 +- src/views/production/myassigtask/index.vue | 155 ++++++-- 9 files changed, 349 insertions(+), 399 deletions(-) diff --git a/src/api/qcResultDetail.ts b/src/api/qcResultDetail.ts index ae8cd70..433fb0a 100644 --- a/src/api/qcResultDetail.ts +++ b/src/api/qcResultDetail.ts @@ -82,5 +82,12 @@ export const qcResultDetailApi = { // 下载导入模板 downloadTemplate() { return request({ url: `/biz/qcResultDetail/template`, method: 'get', responseType: 'blob' }) + }, + + selectlistByqcId(qcId:any) { + return request({ + url:`/biz/qcResultDetail/selectlistByqcId/${qcId}`, + method:'get' + }) } } \ No newline at end of file diff --git a/src/api/qualityTesting.ts b/src/api/qualityTesting.ts index 42bca4d..e038d50 100644 --- a/src/api/qualityTesting.ts +++ b/src/api/qualityTesting.ts @@ -73,8 +73,10 @@ export const qualityTestingApi = { return request({ url: '/mes/qc/partial', method: 'post', data }) }, //质检撤回 - cancel(id: number) { - return request({ url: `/mes/dispatch/revoke/${id}`, method: 'put' }) + cancel(data:{assingId:number,remark:string}) { + console.log(data); + + return request({ url: `/mes/dispatch/revoke`, method: 'put',data }) }, // 导出 diff --git a/src/api/submitLog.ts b/src/api/submitLog.ts index d01d31c..d95368c 100644 --- a/src/api/submitLog.ts +++ b/src/api/submitLog.ts @@ -22,6 +22,8 @@ export interface SubmitLog { assingStatus?: number + remark?: string + } // 派工工单汇报记录 API diff --git a/src/components/SumbitDetailCard.vue b/src/components/SumbitDetailCard.vue index ac2c1f6..2db2fbf 100644 --- a/src/components/SumbitDetailCard.vue +++ b/src/components/SumbitDetailCard.vue @@ -40,14 +40,14 @@ \ No newline at end of file diff --git a/src/views/biz/qualityTesting/detail.vue b/src/views/biz/qualityTesting/detail.vue index b635ee8..e7316b0 100644 --- a/src/views/biz/qualityTesting/detail.vue +++ b/src/views/biz/qualityTesting/detail.vue @@ -54,8 +54,8 @@ diff --git a/src/api/device.ts b/src/api/device.ts index ff636b2..ac2a6bb 100644 --- a/src/api/device.ts +++ b/src/api/device.ts @@ -8,16 +8,37 @@ export interface Device{ deviceTypeId:number, deviceType:string, sectionId:number, + sectionName?:string, spec:string, manufacturer:string, manufactureDate:string, workshopId:number, remark:string, status:number, + deviceFlag?:string, + /** 新代 SynFactory equipID */ + synEquipId?: number | null, createTime:string, updateTime:string } +export interface DeviceRealtimeVO { + deviceId?: number + deviceCode?: string + displayName: string + synEquipId: number + bound: boolean + connected?: number | null + cncStatus?: number | null + cncStatusText?: string + partCount?: number | null + mainProgram?: string | null + alarmCount?: number + alarmMessages?: string[] + dataTimestamp?: number + sectionName?: string +} + export const deviceApi = { @@ -25,6 +46,7 @@ export const deviceApi = { page:number, pageSize:number, deviceCode:any + deviceFlag?: string }) { return request({ url:"/biz/device/page", @@ -33,6 +55,21 @@ export const deviceApi = { }) }, + /** 设备机联网看板:MES名称 + 新代即时状态 */ + realtimeBoard(equipIds?: string | number[]) { + const params: Record = {} + if (Array.isArray(equipIds) && equipIds.length) { + params.equipIds = equipIds.join(',') + } else if (typeof equipIds === 'string' && equipIds) { + params.equipIds = equipIds + } + return request({ + url: '/biz/device/realtime-board', + method: 'get', + params + }) + }, + create(data:Device) { return request({ url:"/biz/device", diff --git a/src/api/orderProcessPlan.ts b/src/api/orderProcessPlan.ts index 9b0da35..35f9c32 100644 --- a/src/api/orderProcessPlan.ts +++ b/src/api/orderProcessPlan.ts @@ -64,6 +64,8 @@ export interface ProcessPlanItemVO { planId?: number + workOrderCode?: string + processCode?: string operNumber?: number @@ -442,5 +444,60 @@ export const orderProcessPlanApi = { }, + /** 委外第一步:获取可选工序 */ + getOutsourcingOptions(processPlanId: number) { + return request({ + url: `/biz/orderProcessPlan/outsourcing/options/${processPlanId}`, + method: 'get', + }) + }, + + /** 委外第二步:创建委外单 */ + createOutsourcing(data: OutsourcingCreate) { + return request({ + url: '/biz/orderProcessPlan/outsourcing', + method: 'post', + data, + }) + }, + +} + +/** 委外可选工序项 */ +export interface OutsourcingProcessOption { + planId?: number + workOrderCode?: string + processCode?: string + operNumber?: number + processName?: string + quantity?: number + outsource?: number + planStartTime?: string + planFinishTime?: string + current?: boolean +} + +/** 委外可选工序(第一步) */ +export interface OutsourcingOptions { + orderItemId?: number + mainCode?: string + materialCode?: string + materialName?: string + orderCode?: string + quantity?: number + currentProcessPlanId?: number + processList?: OutsourcingProcessOption[] +} + +/** 创建委外单(第二步) */ +export interface OutsourcingCreate { + processPlanId: number + supplierId?: number + supplierName: string + quantity: number + unitPrice?: number + planStartTime?: string + planEndTime?: string + remark?: string } diff --git a/src/api/outsourcing.ts b/src/api/outsourcing.ts new file mode 100644 index 0000000..be639fd --- /dev/null +++ b/src/api/outsourcing.ts @@ -0,0 +1,105 @@ +import { request } from '@/utils/request' + +/** 委外工单 */ +export interface Outsourcing { + id?: number + outsourceCode?: string + name?: string + code?: string + businessType?: number + businessId?: number + businessCode?: string + orderItemId?: number + quantity?: number + supplierId?: number + supplierName?: string + unitPrice?: number | string + totalAmount?: number | string + beginPreparationTime?: string + endPreparationTime?: string + beginTime?: string + endTime?: string + remark?: string + createTime?: string + createBy?: string + overdue?: number + /** 0草稿 1执行中 2已完成 3已关闭 */ + status?: number + /** 1正常 2紧急 3低 */ + priority?: number + issuedQuantity?: number | string + receivedQuantity?: number | string + qualifiedQuantity?: number | string +} + +export const OUTSOURCE_STATUS_MAP: Record = { + 0: { label: '草稿', type: 'default' }, + 1: { label: '执行中', type: 'info' }, + 2: { label: '已完成', type: 'success' }, + 3: { label: '已关闭', type: 'default' }, +} + +export const OUTSOURCE_PRIORITY_MAP: Record = { + 1: { label: '正常', type: 'info' }, + 2: { label: '紧急', type: 'error' }, + 3: { label: '低', type: 'default' }, +} + +export const outsourcingApi = { + page(params: { + page: number + pageSize: number + id?: number + name?: string + businessType?: number + outsourceCode?: string + supplierName?: string + status?: number + }) { + return request<{ list: Outsourcing[]; total: number; page: number; pageSize: number }>({ + url: '/biz/outsourcing/page', + method: 'get', + params, + }) + }, + + detail(id: number | string) { + return request({ url: `/biz/outsourcing/${id}`, method: 'get' }) + }, + + create(data: Outsourcing) { + return request({ url: '/biz/outsourcing', method: 'post', data }) + }, + + update(data: Outsourcing) { + return request({ url: '/biz/outsourcing', method: 'put', data }) + }, + + delete(ids: number[]) { + return request({ url: `/biz/outsourcing/${ids.join(',')}`, method: 'delete' }) + }, + + export(params?: { ids?: number[]; id?: number; name?: string; businessType?: number }) { + const p: Record = {} + if (params?.ids?.length) p.ids = params.ids.join(',') + if (params?.id != null) p.id = params.id + if (params?.name) p.name = params.name + if (params?.businessType != null) p.businessType = params.businessType + return request({ url: '/biz/outsourcing/export', method: 'get', params: p, responseType: 'blob' }) + }, + + importData(file: File) { + const formData = new FormData() + formData.append('file', file) + return request<{ success: number; fail: number; errors: string[] }>({ + url: '/biz/outsourcing/import', + method: 'post', + data: formData, + headers: { 'Content-Type': 'multipart/form-data' }, + }) + }, + + downloadTemplate() { + return request({ url: '/biz/outsourcing/template', method: 'get', responseType: 'blob' }) + }, +} diff --git a/src/router/index.ts b/src/router/index.ts index 4da2bfa..ff3851a 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -148,6 +148,24 @@ const routes: RouteRecordRaw[] = [ component: () => import('@/views/biz/orderProcessPlan/index.vue'), meta: { title: '工序计划', icon: 'ListOutline' } }, + { + path: 'biz/orderProcessPlan/board', + name: 'orderProcessPlanBoard', + component: () => import('@/views/biz/orderProcessPlan/board.vue'), + meta: { title: '工序计划看板', icon: 'ListOutline', activeMenu: '/biz/orderProcessPlan' } + }, + { + path: 'biz/device', + name: 'device', + component: () => import('@/views/biz/device/index.vue'), + meta: { title: '设备管理', icon: 'HardwareChipOutline' } + }, + { + path: 'biz/device/board', + name: 'deviceRealtimeBoard', + component: () => import('@/views/biz/device/board.vue'), + meta: { title: '设备状态看板', icon: 'GridOutline', activeMenu: '/biz/device' } + }, { path: 'biz/user', name: 'user', @@ -264,6 +282,12 @@ const routes: RouteRecordRaw[] = [ component: () => import('@/views/biz/flowingAround/index.vue'), meta: { title: '流转记录表', icon: 'ListOutline' } }, + { + path: 'biz/outsourcing', + name: 'outsourcing', + component: () => import('@/views/biz/outsourcing/index.vue'), + meta: { title: '工序委外', icon: 'ListOutline' } + }, { // 开发工具 path: 'tool/gen', diff --git a/src/utils/request.ts b/src/utils/request.ts index 2f5fe72..9a67eae 100644 --- a/src/utils/request.ts +++ b/src/utils/request.ts @@ -116,8 +116,8 @@ async function decryptResponseData(data: string): Promise { // 创建axios实例 // 后端 API 统一使用 /api 前缀 const service: AxiosInstance = axios.create({ - // baseURL:'/api', - baseURL: BASE_API, + baseURL:'/api', + //baseURL: BASE_API, timeout: 30000 }) diff --git a/src/views/biz/device/board.vue b/src/views/biz/device/board.vue new file mode 100644 index 0000000..13ea600 --- /dev/null +++ b/src/views/biz/device/board.vue @@ -0,0 +1,438 @@ + + + + + + + + 刷新 + + + 自动刷新 15s + 手动刷新 + + + + 返回设备管理 + + + + + + {{ list.length }} + 设备总数 + + + + {{ countByStatus(1) }} + 加工中 + + + + {{ countByStatus(0) }} + 闲置 + + + + {{ countByStatus(2) }} + 警报 + + + + {{ offlineCount }} + 离线 + + + + + + + + + + + + {{ item.displayName }} + + {{ item.deviceCode }} + · + {{ item.sectionName }} + 设备监控 + + + + + {{ item.cncStatusText || '未知' }} + + + + + + 当前程序 + {{ item.mainProgram || '—' }} + + + 累计产量 + {{ item.partCount ?? '—' }} + + + 通讯状态 + + + {{ item.connected === 1 ? '在线' : item.connected === 0 ? '离线' : '—' }} + + + + + 运行状态 + {{ item.cncStatusText || '—' }} + + + + + + {{ (item.alarmMessages || []).slice(0, 2).join(';') || `当前警报 ${item.alarmCount} 条` }} + + + + + + + + + + + + + diff --git a/src/views/biz/device/index.vue b/src/views/biz/device/index.vue index f89c3a1..ced75dd 100644 --- a/src/views/biz/device/index.vue +++ b/src/views/biz/device/index.vue @@ -29,6 +29,9 @@ 新增设备 + + 设备状态看板 + + + + + + {{ outsourceOptions.mainCode || '-' }} + {{ outsourceOptions.orderCode || '-' }} + {{ outsourceOptions.materialCode || '-' }} + {{ outsourceOptions.materialName || '-' }} + {{ outsourceOptions.quantity ?? '-' }} + + + + + + + + {{ proc.processName || '-' }} + 当前 + 已委外 + + + 工单号:{{ proc.workOrderCode || '-' }} + 工序号:{{ proc.operNumber ?? '-' }} + 数量:{{ proc.quantity ?? '-' }} + + + + + + + + + + + + 委外工序: + {{ selectedOutsourceProcess?.processName || '-' }} + + + 工单号: + {{ selectedOutsourceProcess?.workOrderCode || '-' }} + + + 物料: + {{ outsourceOptions?.materialName || '-' }} + + + 工序数量: + {{ selectedOutsourceProcess?.quantity ?? '-' }} + + + + + + + + + + + + + + + + + + + + + + + + + + + + 取消 + 上一步 + 下一步 + 确认创建 + + + + @@ -338,17 +526,18 @@ diff --git a/vite.config.ts b/vite.config.ts index 632bef7..1fa2d3a 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -16,14 +16,13 @@ export default defineConfig({ emptyOutDir: true }, server: { - // host: "192.168.5.231", host: true, port: 3000, proxy: { '/api': { //target:'http://192.168.6.107:8080', //'http://192.168.5.230:8888', - target:'http://192.168.5.230:8888', - //target:'http://192.168.5.200:8888', + //target:'http://192.168.5.230:8888', + target:'http://localhost:8888', changeOrigin: true }, '/druid': {