修改派工工单汇报信息 质检信息

This commit is contained in:
shaoleiliu-netizen123 2026-07-28 14:19:55 +08:00
parent 69e5e45478
commit c0832186b1
13 changed files with 428 additions and 72 deletions

View File

@ -126,6 +126,8 @@ export interface ProcessPlanItemVO {
assignWorkList?: AssignWorkItem[]
proWorkshop?: string
}
@ -224,6 +226,8 @@ export function processItemToEntity(
orderItemId?: number,
proWorkshop?:string
): OrderProcessPlan {
return {
@ -256,7 +260,9 @@ export function processItemToEntity(
storageEntry: item.storageEntry,
workCenterName:item.workCenterName
workCenterName:item.workCenterName,
proWorkshop
}

View File

@ -103,5 +103,10 @@ export const qualityTestingApi = {
// 下载导入模板
downloadTemplate() {
return request({ url: `/biz/qualityTesting/template`, method: 'get', responseType: 'blob' })
},
//加载质检单
loadQualityTestingList(assingId:number) {
return request({url:`/mes/qc/loadQualityTestingList/${assingId}`,method:'get'})
}
}

View File

@ -68,7 +68,7 @@ export const sectionApi = {
})
},
list(params:{sectionName:string}) {
list(params:{sectionName:string,workShop:string}) {
return request({
url:"/biz/section/listBySectionName",
method:"get",

View File

@ -87,5 +87,15 @@ export const submitLogApi = {
//按派工单id查询汇报
getByDispatch(dispatchId:number){
return request({url:`/mes/report/bydispatch/${dispatchId}`,method:"get"})
},
//根据工序Id查询汇报
getProcessReportDetail(processId:number){
return request({url:`/mes/report/submitLogToProcess/${processId}`,method:"get"})
},
//加载汇报列表
loadSumbitLog(assingId?:number){
return request({url:`/mes/report/loadSumbitLog/${assingId}`,method:'get'})
}
}

View File

@ -289,18 +289,18 @@ const routes: RouteRecordRaw[] = [
component: () => import('@/views/biz/outsourcing/index.vue'),
meta: { title: '工序委外', icon: 'ListOutline' }
},
{
path: 'biz/tool',
name: 'tool',
component: () => import('@/views/biz/tool/index.vue'),
meta: { title: '刀具管理', icon: 'ToolOutline' }
},
{
path: 'biz/tool/usage',
name: 'toolUsage',
component: () => import('@/views/biz/tool/usage.vue'),
meta: { title: '刀具使用记录', icon: 'ToolOutline', activeMenu: '/biz/tool' }
},
// {
// path: 'biz/tool',
// name: 'tool',
// component: () => import('@/views/biz/tool/index.vue'),
// meta: { title: '刀具管理', icon: 'ToolOutline' }
// },
// {
// path: 'biz/tool/usage',
// name: 'toolUsage',
// component: () => import('@/views/biz/tool/usage.vue'),
// meta: { title: '刀具使用记录', icon: 'ToolOutline', activeMenu: '/biz/tool' }
// },
{
path: 'biz/errorNotification',
name: 'errorNotification',

View File

@ -353,6 +353,7 @@
:obj="n"
:index="i"
:section="dispatchform.workCenterName"
:workShop="dispatchform.workShop"
listname="list"
@addhand="addpgnum"
@delehand="deletenum(i)"
@ -531,10 +532,28 @@
<!-- 汇报详情弹窗 -->
<n-modal v-model:show="submitLogModalVisible" preset="card" title="导入工序计划" style="width: 500px">
<n-modal v-model:show="submitLogModalVisible" preset="card" title="工序汇报详情" style="width: 2000px">
<ReportDetailPage
:planId="processId"
/>
<template #footer>
<n-space justify="end">
<n-button size="small" @click="submitLogModalVisible = false">取消</n-button>
</n-space>
</template>
</n-modal>
<n-modal v-model:show="submitModalVisible" preset="card" title="工单汇报详情" style="width: 500px">
<OrderReportDetailPage
:orderId="orderId"
/>
<template #footer>
<n-space justify="end">
<n-button size="small" @click="submitLogModalVisible = false">取消</n-button>
</n-space>
</template>
</n-modal>
</div>
</template>
@ -550,7 +569,7 @@ import {
AddOutline, RemoveOutline, SearchOutline, RefreshOutline, CloudUploadOutline,
DownloadOutline, ChevronDownOutline, CheckmarkCircleOutline, CheckmarkCircle,
EllipseOutline, TimeOutline, PrintOutline, SyncOutline, PeopleOutline,
GitBranchOutline, CloseCircleOutline, LockClosedOutline, TrashOutline,
GitBranchOutline, CloseCircleOutline, LockClosedOutline, TrashOutline, EyeSharp,
} from '@vicons/ionicons5'
import {
orderProcessPlanApi,
@ -568,8 +587,8 @@ import ProcessCard from './components/ProcessCard.vue'
import PlmModelDrawer from '@/components/PlmModelDrawer.vue'
import type { PlmModelOpenContext } from '@/api/plmModel'
import Pgitem from './pgitem.vue'
import { submitLogApi } from '@/api/submitLog.ts'
import ReportDetailPage from "@/views/biz/orderProcessPlan/components/ReportDetail.vue";
import OrderReportDetailPage from "@/views/biz/orderProcessPlan/components/OrderReportDetail.vue";
const message = useMessage()
@ -609,7 +628,7 @@ const dispatchmodal = ref(false)
const dispatchLoading = ref(false)
const dispatchformRef = ref()
const dispatchform = reactive<any>({
id: '', name: '', beginTime: '', endTime: '', quantity: '',workCenterName:'',
id: '', name: '', beginTime: '', endTime: '', quantity: '',workCenterName:'',proWorkshop:'',
list: [{ sectionId:'',deviceId:'', quantity: '' }],
})
const dispatchrules = {}
@ -617,6 +636,7 @@ const dispatchrules = {}
const importModalVisible = ref(false)
const plmModelDrawerRef = ref<InstanceType<typeof PlmModelDrawer> | null>(null)
const submitModalVisible = ref<Boolean>(false)
const outsourceModalVisible = ref(false)
const outsourceOptionsLoading = ref(false)
@ -659,13 +679,14 @@ function openPlmModel(order: OrderProcessPlanVO, process?: ProcessPlanItemVO) {
//
const submitLogModalVisible = ref<Boolean>(false)
const processId = ref<number | null>(null)
//
function openDetailModel(order:ProcessPlanItemVO,procces?:OrderProcessPlanVO) {
function openDetailModel(order:ProcessPlanItemVO,process?:OrderProcessPlanVO) {
// submitLogModalVisible.value = true
// const processId = procces.planId
submitLogModalVisible.value = true
console.log(process.planId)
processId.value = process.planId
}
@ -704,6 +725,7 @@ const moreOptions = [
{ label: '创建返工单', key: 'createRework', icon: dropdownIcon(SyncOutline) },
{ label: '创建工序委外', key: 'createOutsource', icon: dropdownIcon(PeopleOutline) },
{ label: '拆分工单', key: 'splitWorkOrder', icon: dropdownIcon(GitBranchOutline) },
{ label: '汇报详情', key: 'reportDetailView', icon: dropdownIcon(EyeSharp) },
],
},
{
@ -858,6 +880,11 @@ function onMoreSelect(key: string, order: OrderProcessPlanVO) {
openOutsource(order)
return
}
if (key === 'reportDetailView') {
openReportDetail(order)
return;
}
const labels: Record<string, string> = {
print: '打印',
createRework: '创建返工单',
@ -1034,7 +1061,7 @@ async function handleSubmit() {
}
function disphand(process: ProcessPlanItemVO, order?: OrderProcessPlanVO) {
const entity = processItemToEntity(process, order?.orderItemId)
const entity = processItemToEntity(process, order?.orderItemId,order?.proWorkshop)
dispatchmodal.value = true
dispatchformRef.value?.restoreValidation()
@ -1046,8 +1073,11 @@ function disphand(process: ProcessPlanItemVO, order?: OrderProcessPlanVO) {
dispatchform.orderItemId = entity.orderItemId
dispatchform.sort = entity.sort
dispatchform.workCenterName = entity.workCenterName
dispatchform.workShop = entity.proWorkshop
dispatchform.list = [{ sectionId:'',deviceId:'', quantity: '' }]
console.log(dispatchform)
}
@ -1120,6 +1150,14 @@ async function handleImportUpload({ file }: UploadCustomRequestOptions) {
loadData()
}
const orderId = ref<number>(null)
function openReportDetail(order) {
submitModalVisible.value = true
orderId.value = order.id
}
onMounted(loadData)
</script>

View File

@ -84,7 +84,7 @@
>委外</n-button>
<n-button
size="tiny"
quaternary
type="info"
ghost
@click="emit('submitDetail', process)"
>汇报</n-button>

View File

@ -0,0 +1,295 @@
<script setup lang="ts">
import { submitLogApi } from '@/api/submitLog'
import {h, onMounted, ref} from "vue";
import {DataTableColumns, NButton, NDataTable, NSpace, NTag} from "naive-ui";
import type {AssingWork} from "@/api/production.ts";
import { dictDataApi } from "@/api/org";
import {AssingWorkDetail} from "@/api/AssingWorkDetail.ts";
const props = defineProps<{
planId: number
}>()
const tableLoading = ref<Boolean>(false)
const AssingWorkTableData = ref<AssingWork[]>([])
//Id
async function loadReportDetail() {
try {
const res = await submitLogApi.getProcessReportDetail(props.planId)
AssingWorkTableData.value = res
} catch (error) {
console.error('加载汇报详情失败', error)
}
}
const qcAssingStatusOptions = ref<{ label: string; value: any;class:any }[]>([])
const submitStatusOptions = ref<{ label: string; value: any;class:any }[]>([])
const AssingWorkExpandedKeys = ref<Array<string |number>>([])
const AssingWorkColumns :DataTableColumns<AssingWork> = [
{
type:"expand",
expandable:()=>true,
renderExpand:(row) => renderAssingWorkExpand(row)
},
{
align:"center",
title:"物料名称",
key:"materialName",
minWidth:150,
render(row:any) {
var opt = row.materialName
if(opt) return opt
return '-'
}
},
{
align:"center",
title:"物料编码",
key:"materialCode",
minWidth:150,
render(row:any) {
var opt = row.materialCode
if(opt) return opt
return '-'
}
},
{
align:"center",
title:"派工编号",
key:"assingCode",
minWidth:150
},
{
align:'center',
title: '工序名称',
key: 'processName',
minWidth: 200
},
{
align:'center',
title: '工序编号',
key: 'processCode',
minWidth: 200
},
{
align:'center',
title: '派工状态',
key: 'assingStatus',
minWidth: 150,
render(row:any) {
const val = row.assingStatus
const opt = qcAssingStatusOptions.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 })
}
//0 1 2+34
},
{
align:'center',
title: '工段名称',
key: 'sectionName',
minWidth: 200
},
{
align:'center',
title: '工位名称',
key: 'deviceName',
minWidth: 200
},
{
align:'center',
title: '数量',
minWidth: 100,
key: 'quantity'
},
{
align:'center',
title: '是否返工',
key: 'rework',
minWidth: 100,
render(row:any) {
const quit = row.rework === 1
return h(NTag, {type: quit ? 'error' : 'success', size: 'small'}, {default: () => (quit ? '是' : '否')})
}
},
{
align:'center',
title: '返工次数',
key: 'reworkNum',
minWidth: 150
},
{
align:'center',
title: '完成数量',
key: 'completedQuantity',
minWidth: 150
},
{
align:'center',
title: '完成时间',
key: 'completedTime',
minWidth: 180
},
{
align:'center',
title: '工序状态',
key: 'status',
minWidth: 100,
render(row:any) {
if(row.status == 0){
return h(NTag, {
type:'success',
size: 'small'
},
{
default: () => '启用'
}
)
}
if(row.status == 1){
return h(NTag, {
type:'warning',
size: 'small'
},
{
default: () => '已暂停'
}
)
}
if(row.status == 2){
return h(NTag, {
type:'warning',
size: 'small'
},
{
default: () => '已改派'
}
)
}
return '-'
}
}
]
function RowKey(row:AssingWork) {
return row.id
}
const expandDataMap = new Map<number, any[]>()
const loadingRowIds = ref<Set<number>>(new Set())
function renderAssingWorkExpand(row: AssingWork) {
// 1.
if (!expandDataMap.has(row.id)) {
expandDataMap.set(row.id, [])
loadingRowIds.value.add(row.id)
//
expandDataMap.set(row.id, row.submitLogList)
loadingRowIds.value.delete(row.id)
}
// 2.
if (loadingRowIds.value.has(row.id)) {
return h('div', { style: 'padding:12px' }, '加载中...')
}
const tableData = expandDataMap.get(row.id)!
return h('div', { style: 'padding: 0 16px 12px' }, [
h(NDataTable, {
columns: AssingWorkDetailColums,
data: tableData,
rowKey: DetailRowKey,
size: 'small',
bordered: true,
striped: true,
scrollX: 600
})
])
}
function DetailRowKey(row:any) {
return row.id
}
const AssingWorkDetailColums:DataTableColumns<AssingWorkDetail> = [
{
align:"center",
title:"数量",
key:"quantity",
width:150
},
{
align:"center",
title:"汇报状态",
key:"submitStatus",
render: (row) => {
const val = row.submitStatus
const opt = submitStatusOptions.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: 'remark',align: 'center' },
{
align:"center",
title:"操作人",
key:"userName",
width:150
},
{
align:"center",
title:"创建时间",
key:"createTime",
width:150
},
]
//
async function loadDictOptions() {
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 {}
try {
const data = await dictDataApi.listByType('submit_status')
submitStatusOptions.value = data.map(d => ({ label: d.dictLabel, value: (Number(d.dictValue) || d.dictValue),class:d.listClass }))
}catch {}
}
onMounted(async () => {
loadReportDetail()
loadDictOptions()
})
</script>
<template>
<div>
<n-card>
<n-scrollbar x-scrollable>
<n-data-table
v-model:expanded-row-keys="AssingWorkExpandedKeys"
:columns="AssingWorkColumns"
:data="AssingWorkTableData"
:loading="tableLoading"
:scroll-x="600"
:max-height="1000"
size="small"
style="margin-bottom:15px"
:row-key="RowKey"
/>
</n-scrollbar>
</n-card>
</div>
</template>
<style scoped>
</style>

View File

@ -95,6 +95,7 @@
obj:any,
index:any
section:string
workShop: string
}>(), {
obj:{}
})
@ -155,23 +156,23 @@
//
async function loadSection() {
//section
const res = await sectionApi.list({sectionName:props.section})
const res = await sectionApi.list({sectionName:props.section,workShop:props.workShop})
const mesSection = res.MesSection;
const mesDevice = res.MesDevice
console.log(mesSection);
sectionList.push({
label:mesSection.sectionName,
value:mesSection.id
})
props.obj.sectionId = mesSection.id
})
props.obj.sectionId = mesSection.id
deviceList.value = mesDevice.map((n:any)=>{
return {
label:n.deviceName,
value:n.id+''
}
})
})
}
// function searchSection(sectionId?:number){

View File

@ -11,17 +11,20 @@
</n-button>
</n-space>
</div>
<n-data-table
v-model:expanded-row-keys="AssingWorkExpandedKeys"
:columns="AssingWorkColumns"
:data="AssingWorkTableData"
:loading="tableLoading"
:row-key="RowKey"
:scroll-x="600"
:max-height="1000"
size="small"
style="margin-bottom:15px"
/>
<n-scrollbar x-scrollable>
<n-data-table
v-model:expanded-row-keys="AssingWorkExpandedKeys"
:columns="AssingWorkColumns"
:data="AssingWorkTableData"
:loading="tableLoading"
:row-key="RowKey"
:scroll-x="600"
:max-height="1000"
size="small"
style="margin-bottom:15px"
/>
</n-scrollbar>
<div class="pagination-container" style="display: flex; justify-content: flex-end; margin-top: 12px">
<n-pagination
v-model:page="pagination.page"
@ -43,12 +46,12 @@
<div>
<SubmitLogInfoPage
v-if="baseInfo.logOrQuality === 'log'"
:submitLogList="submitLogList"
:assingId="assingId"
:baseInfo="baseInfo"
/>
<QualityInfoPage
v-if="baseInfo.logOrQuality === 'Quality'"
:qualityTestingList="qualityList"
:assingId="assingId"
:baseInfo="baseInfo"
/>
</div>
@ -506,10 +509,11 @@ async function loadDictOptions() {
}
//
const assingId = ref<number>(null)
function handleReportRecords(row:any) {
showQcReport.value = true
reportTitle.value = "汇报信息"
submitLogList.value = row.submitLogList
assingId.value = row.id
baseInfo.value = {...row}
baseInfo.value.logOrQuality = "log"
}
@ -520,8 +524,7 @@ function handleReportRecords(row:any) {
function handleQualityRecords(row:any) {
showQcReport.value = true
reportTitle.value = "质检信息"
qualityList.value = row.qualityTestingList
console.log(qualityList.value)
assingId.value = row.id
baseInfo.value = {...row}
baseInfo.value.logOrQuality = "Quality"
}

View File

@ -27,7 +27,7 @@
<n-data-table
:columns="reportRecordsColums"
size="small"
:data="props.qualityTestingList"
:data="qualityTestingList"
remote
:scroll-x="600"
/>
@ -39,11 +39,11 @@ import { NCard, NDataTable, NGi,NTag, NGrid,DataTableColumns} from "naive-ui";
import {onMounted, ref,h} from "vue";
import { dictDataApi } from '@/api/org'
import {QualityTesting} from "@/api/qualityTesting.ts";
import {QualityTesting,qualityTestingApi} from "@/api/qualityTesting.ts";
const props =defineProps(
{
qualityTestingList:Object,
assingId:Object,
baseInfo:Object
}
)
@ -91,9 +91,15 @@ async function loadDictOptions() {
}
const qualityTestingList = ref<QualityTesting[]>([])
async function loadQualityTestingList() {
const res = await qualityTestingApi.loadQualityTestingList(props.assingId)
qualityTestingList.value = res
}
onMounted(()=>{
loadDictOptions()
loadQualityTestingList()
})
</script>
<style scoped>

View File

@ -27,7 +27,7 @@
<n-data-table
:columns="reportRecordsColums"
size="small"
:data="props.submitLogList"
:data="submitLogList"
remote
:scroll-x="600"
/>
@ -38,11 +38,11 @@
import { NCard, NDataTable, NGi,NTag, NGrid,DataTableColumns} from "naive-ui";
import {onMounted, ref,h} from "vue";
import { dictDataApi } from '@/api/org'
import { SubmitLog } from '@/api/submitLog'
import { SubmitLog,submitLogApi} from '@/api/submitLog'
const props =defineProps(
{
submitLogList:Object,
assingId:Number,
baseInfo:Object
}
)
@ -64,7 +64,8 @@ const reportRecordsColums:DataTableColumns<SubmitLog> = [
return h(NTag, { type: opt.class, size: 'small' }, { default: () => opt.label })
}
}
},
{ title: '汇报时间', key: 'createTime',align: 'center' },
]
//
@ -75,10 +76,16 @@ async function loadDictOptions() {
}catch {}
}
//
const submitLogList = ref<SubmitLog[]>([])
async function load() {
const res = await submitLogApi.loadSumbitLog(props.assingId)
submitLogList.value = res
}
onMounted(()=>{
loadDictOptions()
load()
})
</script>
<style scoped>

View File

@ -280,19 +280,6 @@ const pagination = reactive({
const plmModelDrawerRef = ref<InstanceType<typeof PlmModelDrawer> | null>(null)
function openPlmModel(row: Record<string, unknown>) {
console.log(row);
const ctx: PlmModelOpenContext = {
orderItemId: row.orderItemId as string | number,
dispatchId: row.id as number | string,
materialCode: row.materialCode as string | undefined,
materialName: row.materialName as string | undefined,
drawingNo: (row.drawingNo as string | undefined) || (row.materialCode as string | undefined),
title: `三维模型 · ${row.processName || row.materialName || ''}`,
}
plmModelDrawerRef.value?.open(ctx)
}
const columns = [
// {
@ -541,9 +528,7 @@ const columns = [
]
function dropdownIcon(icon: Component) {
return () => h(NIcon, null, { default: () => h(icon) })
}
//