派工管理添加查询汇报详情功能

This commit is contained in:
shaoleiliu-netizen123 2026-06-03 13:07:40 +08:00
parent 3a7ffef12f
commit 8f2faf04b0
3 changed files with 272 additions and 61 deletions

View File

@ -71,5 +71,11 @@ export const submitLogApi = {
//汇报统计 //汇报统计
statistics(params?: {time?:string; type?:string}){ statistics(params?: {time?:string; type?:string}){
return request({url:'/mes/report/statistics',method:'get',params}) return request({url:'/mes/report/statistics',method:'get',params})
},
//按派工单id查询汇报
getByDispatch(dispatchId:number){
return request({url:`/mes/report/bydispatch/${dispatchId}`,method:"get"})
} }
} }

View File

@ -243,6 +243,21 @@ const formRules = {
// //
const columns: DataTableColumns<SubmitLog> = [ const columns: DataTableColumns<SubmitLog> = [
{ type: 'selection' }, { type: 'selection' },
{ title: '物料名称', key: 'materialName',align: 'center',
render(rowData, rowIndex) {
return rowData.materialName? rowData.materialName: '-'
},
},
{ title: '物料编码', key: 'materialCode',align: 'center',
render(rowData, rowIndex) {
return rowData.materialCode? rowData.materialCode: '-'
},
},
{ title: '物料数量', key: 'materialQty',align: 'center',
render(rowData, rowIndex) {
return rowData.materialQty? rowData.materialQty: '-'
},
},
{ title: '工序名称', key: 'processName',align: 'center' }, { title: '工序名称', key: 'processName',align: 'center' },
{ title: '工序编号', key: 'processCode',align: 'center' }, { title: '工序编号', key: 'processCode',align: 'center' },
{ title: '派工编号', key: 'assingCode',align: 'center' }, { title: '派工编号', key: 'assingCode',align: 'center' },

View File

@ -259,6 +259,76 @@
</template> </template>
</n-modal> </n-modal>
<!--查询汇报详情-->
<n-modal v-model:show="reportDetailVisible" preset="card" :title="reportDetailTitle" style="width: 800px">
<n-card hoverable style="margin-bottom: 12px" >
<template #header>
<div style="display:flex;justify-content:space-between;align-items:center;width:100%">
<span>主表信息</span>
<n-button text @click="infoIsCollapse = !infoIsCollapse">
<n-icon :component="infoIsCollapse ? ArrowDownOutline : ArrowUpOutline" />
</n-button>
</div>
</template>
<n-descriptions :column="3" bordered v-show="!infoIsCollapse">
<n-descriptions-item
v-for="item in mappedInfoList"
:key="item.key"
:label="item.label"
>
{{ formatDisplayValue(item.key, item.value) }}
</n-descriptions-item>
</n-descriptions>
</n-card>
<n-card title="汇报信息" hoverable style="margin-bottom: 12px" >
<div v-if="qualityTestings.length === 0" style="height:520px;display:flex;align-items:center;justify-content:center;color:#999">
暂无质检单据数据
</div>
<n-tabs
type="line"
animated
placement="left"
style="height: 520px"
v-else>
<n-tab-pane
v-for="item in qualityTestings"
:name="item.qcNo"
:tab="item.qcNo">
<n-card title="质检基础信息" style="margin-bottom:12px">
<n-descriptions :column="3">
<n-descriptions-item label="资源类型">{{formatDisplayValue("resourceType",item.resourceType) }}</n-descriptions-item>
<n-descriptions-item label="质检状态">{{formatDisplayValue("status",item.qcStatus) }}</n-descriptions-item>
<n-descriptions-item label="总数量">{{ item.totalQty }}</n-descriptions-item>
</n-descriptions>
</n-card>
<!--汇报表格-->
<n-card title="汇报列表">
<n-data-table
:columns="submitColumns"
:data="item.submitLogs"
:scroll-x="700"
max-height="320"
:pagination="{ pageSize:3 }"
>
<!--空数据提示插槽-->
<template #empty>
<div style="padding:40px;text-align:center;color:#999">
当前没有数据
</div>
</template>
</n-data-table>
</n-card>
</n-tab-pane>
</n-tabs>
</n-card>
</n-modal>
</div> </div>
</template> </template>
@ -273,6 +343,7 @@ import {
import { import {
NButton, NButton,
NDropdown,
NIcon, NIcon,
NSpace, NSpace,
NPagination, NPagination,
@ -283,14 +354,12 @@ import {
//useDialog, //useDialog,
type FormInst, type FormInst,
} from 'naive-ui' } from 'naive-ui'
import { import {
SearchOutline, SearchOutline, RefreshOutline, AddOutline, TrashOutline, CreateOutline, CloudUploadOutline, DownloadOutline,
RefreshOutline EllipsisHorizontalOutline, ArrowDownOutline, ArrowUpOutline
} from '@vicons/ionicons5' } from '@vicons/ionicons5'
import { useUserStore } from '@/stores/user' import { useUserStore } from '@/stores/user'
import { dictDataApi } from '@/api/org'
import { import {
disworlist, disworlist,
editdiswor, editdiswor,
@ -299,6 +368,9 @@ import {
//workload //workload
} from '@/api/production' } from '@/api/production'
import { submitLogApi } from '@/api/submitLog'
import { an } from 'vue-router/dist/router-CWoNjPRp.mjs'
//const dialog = useDialog() //const dialog = useDialog()
const message = useMessage() const message = useMessage()
@ -308,6 +380,40 @@ const userStore = useUserStore()
// //
const hasPermission = (permission: string) => userStore.hasPermission(permission) const hasPermission = (permission: string) => userStore.hasPermission(permission)
//
const qcResultTypeOptions = ref<{ label: string; value: any }[]>([])
//
const qcSourceTypeOptions = ref<{ label: string; value: any }[]>([])
//
const qcStatusOptions = ref<{ label: string; value: any }[]>([])
//
const qcAssingStatusOptions = ref<{ label: string; value: any }[]>([])
//
const infoIsCollapse = ref(false)
const reportDetailVisible = ref(false)
const reportDetailTitle = ref<string>('')
const mappedInfoList = ref<Array<{ label: string; key: string; value: any }>>([])
const qualityTestings = ref<any[]>([])
const submitColumns = ref([
{ title: "提交人", key: "sumbitUser" },
{ title: "提交时间", key: "submitCreateTime" },
{ title: "提交数量", key: "quantity" },
{ title: "单据状态", key: "submitStatus",
render: (row) => {
const val = row.submitStatus
const opt = qcResultTypeOptions.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 })
}
}
])
// ==================== ==================== // ==================== ====================
const searchForm = reactive({ const searchForm = reactive({
@ -491,52 +597,79 @@ const columns = [
width: 200, width: 200,
fixed: 'right', fixed: 'right',
render(row:any) { render(row:any) {
const buttons:any = [ return h('div',{ style: { display: 'flex', alignItems: 'center', gap: '8px', flexWrap: 'nowrap' } },[
h(NButton, { size: 'small', quaternary: true, onClick: () => handleEdit(row) }, {
default: () => [h(NIcon, null, { default: () => h(CreateOutline) }), ' 编辑']
}),
h(NDropdown, {
trigger:'click',
options:[
{label:"改派",key:'transfer'},
{type: 'divider' }, // 线
{label:'暂停',key:'pauseResume'},
{type: 'divider' }, // 线
{label:'查看汇报',key:'view'},
],
onSelect:(key:string)=>{
switch(key) {
case "transfer":
handlreass(row)
break
case "pauseResume":
handlpause(row)
break
case "view":
handleViewReport(row.id)
break
// h(NButton, { }
// size: 'small', }
// type:'warning', },{
// ghost:true, // /
// onClick: () => handleEdit(row) }, default: () => h(NButton, { size: 'small', quaternary: true }, {
// //{ default: () => [h(NIcon, null, { default: () => h(CreateOutline) }), ' ' ]} default: () => [h(NIcon, null, { default: () => h(EllipsisHorizontalOutline) })]
// { default: () => ''} })
// ) })
] ])
if(hasPermission('biz:assingWork:edit')){
buttons.push(h(NButton, { // const buttons:any = [
size: 'small', // ]
type:'primary',
ghost:true, // if(hasPermission('biz:assingWork:edit')){
onClick: () => { handleEdit(row) } }, // buttons.push(h(NButton, {
//{ default: () => [h(NIcon, null, { default: () => h(CreateOutline) }), ' ' ]} // size: 'small',
{ default: () => '编辑'} // type:'primary',
)) // ghost:true,
} // onClick: () => { handleEdit(row) } },
if(hasPermission('biz:assingWork:transfer')){ // //{ default: () => [h(NIcon, null, { default: () => h(CreateOutline) }), ' ' ]}
buttons.push(h(NButton, { // { default: () => ''}
size: 'small', // ))
type:'success', // }
ghost:true, // if(hasPermission('biz:assingWork:transfer')){
onClick: () => { handlreass(row) } }, // buttons.push(h(NButton, {
{ default: () => '改派'} // size: 'small',
)) // type:'success',
} // ghost:true,
if(hasPermission('biz:assingWork:pauseResume')){ // onClick: () => { handlreass(row) } },
buttons.push(h(NButton, { // { default: () => ''}
size: 'small', // ))
type:'warning', // }
ghost:true, // if(hasPermission('biz:assingWork:pauseResume')){
onClick:()=>{ handlpause(row) } // buttons.push(h(NButton, {
}, // size: 'small',
{ default: () => '暂停'} // type:'warning',
)) // ghost:true,
} // onClick:()=>{ handlpause(row) }
// },
// { default: () => ''}
// ))
// }
// buttons.push( // buttons.push(
// ) // )
return buttons.length > 0 ? h(NSpace, {justify:'center'}, { default: () => buttons }) : '-' // return buttons.length > 0 ? h(NSpace, {justify:'center'}, { default: () => buttons }) : '-'
} }
} }
] ]
@ -747,23 +880,80 @@ function pauseSubmit() {
}) })
} }
// function zantqy(row:any) { async function handleViewReport(id:number) {
// dialog.warning({ reportDetailTitle.value='汇报详情'
// title: '', reportDetailVisible.value = true
// content: `"${row.processName}"`,
// positiveText: '', const res = await submitLogApi.getByDispatch(id);
// negativeText: '',
// onPositiveClick: () => { mappedInfoList.value = [
// pauseresume({}).then(() => { {key:"materialCode",label:"物料编码",value:res.materialCode},
// message.success('!') {key:"materialName",label:"物料名称",value:res.materialName},
// getlist() {key:"materialQty",label:"物料数量",value:res.materialQty},
// }) {key:"processCode",label:"工序编号",value:res.processCode},
// } {key:"processName",label:"工序名称",value:res.processName},
// }) {key:"processQty",label:"生产总数",value:res.processQty},
// } {key:"assingCode",label:"派工编号",value:res.assingCode},
{key:"workerName",label:"派工人",value:res.workerName},
{key:"assingQty",label:"派工数量",value:res.assingQty}
]
qualityTestings.value = res.qualityTestings
}
function formatDisplayValue(key: string, value: any): string {
if (value === null || value === undefined) return '-'
//
switch (key) {
case 'resourceType': {
const sourceOpt = qcSourceTypeOptions.value.find(o => o.value === value || String(o.value) === String(value))
return sourceOpt ? sourceOpt.label : String(value)
}
case 'status': {
const statusOpt = qcStatusOptions.value.find(o => o.value === value || String(o.value) === String(value))
return statusOpt ? statusOpt.label : String(value)
}
case 'qcNo':
return value ? new Date(value).toLocaleString('zh-CN') : '-'
case 'inspectTime':
case 'createTime':
case 'updateTime':
return value ? new Date(value).toLocaleString('zh-CN') : '-'
default:
return String(value)
}
}
//
async function loadDictOptions() {
try {
const data = await dictDataApi.listByType('qc_result_type')
qcResultTypeOptions.value = data.map(d => ({ label: d.dictLabel, value: (Number(d.dictValue) || d.dictValue),class:d.listClass }))
}catch {}
try {
const data = await dictDataApi.listByType('source_type')
qcSourceTypeOptions.value = data.map(d => ({ label: d.dictLabel, value: (Number(d.dictValue) || d.dictValue),class:d.listClass }))
}catch {}
try {
const data = await dictDataApi.listByType('qc_status')
qcStatusOptions.value = data.map(d => ({ label: d.dictLabel, value: (Number(d.dictValue) || d.dictValue),class:d.listClass }))
}catch {}
try {
const data = await dictDataApi.listByType('assing_status')
qcAssingStatusOptions.value = data.map(d => ({ label: d.dictLabel, value: (Number(d.dictValue) || d.dictValue),class:d.listClass }))
}catch {}
}
onMounted(() => { onMounted(() => {
getlist() getlist()
loadDictOptions()
//workload() //workload()
}) })