优化工序计划派工待派数量与卡片信息展示
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
4c974947af
commit
18b4399789
@ -88,6 +88,12 @@ export interface ProcessPlanItemVO {
|
||||
|
||||
planFinishTime?: string
|
||||
|
||||
/** 计划开始(部分接口直接返回 beginTime) */
|
||||
beginTime?: string
|
||||
|
||||
/** 计划结束(部分接口直接返回 endTime) */
|
||||
endTime?: string
|
||||
|
||||
actualStartTime?: string | null
|
||||
|
||||
actualFinishTime?: string | null
|
||||
@ -238,9 +244,9 @@ export function processItemToEntity(
|
||||
|
||||
orderItemId,
|
||||
|
||||
beginTime: item.planStartTime,
|
||||
beginTime: item.planStartTime || item.beginTime,
|
||||
|
||||
endTime: item.planFinishTime,
|
||||
endTime: item.planFinishTime || item.endTime,
|
||||
|
||||
procurement: item.procurement,
|
||||
|
||||
|
||||
@ -190,6 +190,11 @@
|
||||
v-for="(proc, idx) in sortedProcessList(order.processList)"
|
||||
:key="proc.planId ?? idx"
|
||||
:process="proc"
|
||||
:material-code="order.materialCode"
|
||||
:order-code="order.orderCode"
|
||||
:order-begin-time="order.beginTime"
|
||||
:order-end-time="order.endTime"
|
||||
:pro-workshop="order.proWorkshop"
|
||||
:is-last="idx === (order.processList?.length ?? 0) - 1"
|
||||
:can-edit="hasPermission('biz:orderItem:edit')"
|
||||
:can-assign="hasPermission('biz:orderItem:assign')"
|
||||
@ -246,6 +251,11 @@
|
||||
v-for="(proc, idx) in (detailData.processList)"
|
||||
:key="proc.planId ?? idx"
|
||||
:process="proc"
|
||||
:material-code="detailData.materialCode"
|
||||
:order-code="detailData.orderCode"
|
||||
:order-begin-time="detailData.beginTime"
|
||||
:order-end-time="detailData.endTime"
|
||||
:pro-workshop="detailData.proWorkshop"
|
||||
:is-last="idx === (detailData.processList?.length ?? 0) - 1"
|
||||
:can-edit="hasPermission('biz:orderItem:edit')"
|
||||
:can-assign="hasPermission('biz:orderItem:assign')"
|
||||
@ -329,6 +339,16 @@
|
||||
<span>{{dispatchform.quantity}}</span>
|
||||
</n-gi>
|
||||
</n-grid>
|
||||
<n-grid :cols="2">
|
||||
<n-gi>
|
||||
<span class="pgClass">已完成:</span>
|
||||
<span>{{dispatchform.completedQty ?? 0}}</span>
|
||||
</n-gi>
|
||||
<n-gi>
|
||||
<span class="pgClass">本次待派:</span>
|
||||
<span style="color: #2080f0; font-weight: 600">{{dispatchform.remainQty}}</span>
|
||||
</n-gi>
|
||||
</n-grid>
|
||||
<n-grid :cols="2">
|
||||
<n-gi>
|
||||
<span class="pgClass">开始时间:</span>
|
||||
@ -610,7 +630,9 @@ const dispatchLoading = ref(false)
|
||||
const dispatchformRef = ref()
|
||||
const dispatchform = reactive<any>({
|
||||
id: '', name: '', beginTime: '', endTime: '', quantity: '', workCenterName: '',
|
||||
list: [{ sectionId:'',deviceId:'', quantity: '' }],
|
||||
completedQty: 0,
|
||||
remainQty: 0,
|
||||
list: [{ sectionId: '', deviceId: '', userList: '', quantity: '' }],
|
||||
})
|
||||
const dispatchrules = {}
|
||||
|
||||
@ -1036,23 +1058,28 @@ async function handleSubmit() {
|
||||
function disphand(process: ProcessPlanItemVO, order?: OrderProcessPlanVO) {
|
||||
const entity = processItemToEntity(process, order?.orderItemId)
|
||||
|
||||
const planQty = Number(entity.quantity) || 0
|
||||
const completedQty = Number(process.completedQty) || 0
|
||||
const remainQty = Math.max(0, planQty - completedQty)
|
||||
dispatchmodal.value = true
|
||||
dispatchformRef.value?.restoreValidation()
|
||||
dispatchform.id = entity.id
|
||||
dispatchform.name = entity.name
|
||||
dispatchform.beginTime = entity.beginTime
|
||||
dispatchform.endTime = entity.endTime
|
||||
// 工序计划时间优先,没有则用订单头 beginTime/endTime
|
||||
dispatchform.beginTime = entity.beginTime || order?.beginTime || ''
|
||||
dispatchform.endTime = entity.endTime || order?.endTime || ''
|
||||
// quantity 保持工序计划总数,提交时不能改掉计划数量
|
||||
dispatchform.quantity = entity.quantity
|
||||
dispatchform.completedQty = completedQty
|
||||
dispatchform.remainQty = remainQty
|
||||
dispatchform.orderItemId = entity.orderItemId
|
||||
dispatchform.sort = entity.sort
|
||||
dispatchform.workCenterName = entity.workCenterName
|
||||
dispatchform.list = [{ sectionId:'',deviceId:'', quantity: '' }]
|
||||
|
||||
|
||||
dispatchform.list = [{ sectionId: '', deviceId: '', userList: '', quantity: remainQty || '' }]
|
||||
}
|
||||
|
||||
function addpgnum() {
|
||||
dispatchform.list.push({ sectionId:'',deviceId:'', quantity: '' })
|
||||
dispatchform.list.push({ sectionId: '', deviceId: '', userList: '', quantity: '' })
|
||||
}
|
||||
|
||||
function deletenum(index: number) {
|
||||
@ -1064,15 +1091,24 @@ function dispatchSubmit() {
|
||||
dispatchform.list.forEach((n: any) => {
|
||||
total += Number(n.quantity) || 0
|
||||
})
|
||||
const remainQty = Number(dispatchform.remainQty)
|
||||
if (remainQty <= 0) {
|
||||
message.warning('当前工序已全部完成,无需再派工')
|
||||
return
|
||||
}
|
||||
|
||||
dispatchformRef.value?.validate((v: boolean) => {
|
||||
if (v) return
|
||||
if (total !== Number(dispatchform.quantity)) {
|
||||
message.error('派工总数量需等于生产总数', { duration: 4000 })
|
||||
dispatchformRef.value?.validate((errors: any) => {
|
||||
// Naive UI:有 errors 表示校验失败
|
||||
if (errors) return
|
||||
if (total !== remainQty) {
|
||||
message.error(`派工总数量需等于待派数量 ${remainQty}(计划 ${dispatchform.quantity},已完成 ${dispatchform.completedQty ?? 0})`, {
|
||||
duration: 4000,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
dispatchLoading.value = true
|
||||
// 提交时 quantity 仍传计划总数,避免把工序计划数量改成待派数
|
||||
orderProcessPlanApi.assignWork(dispatchform).then(() => {
|
||||
message.success('派工成功')
|
||||
dispatchmodal.value = false
|
||||
|
||||
@ -2,7 +2,13 @@
|
||||
<div class="process-card-wrap">
|
||||
<div class="process-card" :class="themeClass">
|
||||
<div class="card-head">
|
||||
<span class="card-title">{{ process.processName || '-' }}</span>
|
||||
<div class="card-title-block">
|
||||
<span class="card-title">
|
||||
<em v-if="process.operNumber != null" class="card-oper">{{ process.operNumber }}</em>
|
||||
{{ process.processName || '-' }}
|
||||
</span>
|
||||
<span v-if="materialCode" class="card-material">{{ materialCode }}</span>
|
||||
</div>
|
||||
<n-tag size="small" :bordered="false" :type="statusTag.type">{{ statusTag.label }}</n-tag>
|
||||
</div>
|
||||
|
||||
@ -39,22 +45,28 @@
|
||||
</div>
|
||||
|
||||
<div class="card-flow">
|
||||
<div class="flow-item">
|
||||
<span>转入</span>
|
||||
<strong>{{ process.transferInQty ?? 0 }}</strong>
|
||||
</div>
|
||||
<div class="flow-item">
|
||||
<span>剩余物料</span>
|
||||
<strong>{{ remainQty }}</strong>
|
||||
</div>
|
||||
|
||||
<div class="flow-item">
|
||||
<span>转下道</span>
|
||||
<span>转出</span>
|
||||
<strong>{{ process.transferOutQty ?? 0 }}</strong>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-meta">
|
||||
<div class="meta-line"><span>生产订单</span><em>{{ orderCode || '-' }}</em></div>
|
||||
<div class="meta-line"><span>工单号</span><em>{{ process.workOrderCode || '-' }}</em></div>
|
||||
<div class="meta-line"><span>人员</span><em>{{ personnel }}</em></div>
|
||||
<div class="meta-line"><span>车间</span><em>{{ process.departmentName || '-' }}</em></div>
|
||||
<div class="meta-line"><span>车间</span><em>{{ workshopText }}</em></div>
|
||||
<div class="meta-line"><span>工位</span><em>{{ process.workCenterName || '-' }}</em></div>
|
||||
<div class="meta-line"><span>设备</span><em>-</em></div>
|
||||
<div class="meta-line"><span>设备</span><em>{{ deviceText }}</em></div>
|
||||
<div class="meta-line"><span>计划时间</span><em>{{ planTimeText }}</em></div>
|
||||
<div class="meta-line"><span>实际开始</span><em>{{ process.actualStartTime || '-' }}</em></div>
|
||||
</div>
|
||||
@ -110,6 +122,16 @@ import { PROCESS_STATUS_MAP, type ProcessPlanItemVO } from '@/api/orderProcessPl
|
||||
|
||||
const props = defineProps<{
|
||||
process: ProcessPlanItemVO
|
||||
/** 物料编码(订单头) */
|
||||
materialCode?: string
|
||||
/** 生产订单编号(订单头 orderCode) */
|
||||
orderCode?: string
|
||||
/** 订单计划开始(订单头 beginTime,工序无计划时间时回退) */
|
||||
orderBeginTime?: string
|
||||
/** 订单计划结束(订单头 endTime) */
|
||||
orderEndTime?: string
|
||||
/** 生产车间(订单头 proWorkshop) */
|
||||
proWorkshop?: string
|
||||
isLast?: boolean
|
||||
canEdit?: boolean
|
||||
canAssign?: boolean
|
||||
@ -171,15 +193,39 @@ const railColor = computed(() => {
|
||||
const personnel = computed(() => {
|
||||
if (props.process.assignByName) return props.process.assignByName
|
||||
const list = props.process.assignWorkList
|
||||
if (list?.length) return `${list.length} 人派工`
|
||||
if (list?.length) {
|
||||
const names = list
|
||||
.map((a: any) => a.userName || a.userId)
|
||||
.filter(Boolean)
|
||||
if (names.length) return names.join('、')
|
||||
return `${list.length} 人派工`
|
||||
}
|
||||
return '-'
|
||||
})
|
||||
|
||||
const workshopText = computed(() => {
|
||||
return props.process.departmentName || props.proWorkshop || '-'
|
||||
})
|
||||
|
||||
const deviceText = computed(() => {
|
||||
const list = props.process.assignWorkList as any[] | undefined
|
||||
if (!list?.length) return '-'
|
||||
const devices = list
|
||||
.map((a) => a.deviceName || a.deviceId)
|
||||
.filter(Boolean)
|
||||
return devices.length ? [...new Set(devices)].join('、') : '-'
|
||||
})
|
||||
|
||||
const planTimeText = computed(() => {
|
||||
const start = props.process.planStartTime
|
||||
const end = props.process.planFinishTime
|
||||
// 工序计划时间优先;没有则回退订单头 beginTime/endTime
|
||||
const start = props.process.planStartTime || props.process.beginTime || props.orderBeginTime
|
||||
const end = props.process.planFinishTime || props.process.endTime || props.orderEndTime
|
||||
if (!start && !end) return '-'
|
||||
if (start && end) return `${start.slice(0, 16)} ~ ${end.slice(11, 16)}`
|
||||
if (start && end) {
|
||||
const startText = start.length >= 16 ? start.slice(0, 16) : start
|
||||
const endText = end.length >= 16 ? end.slice(11, 16) : end
|
||||
return `${startText} ~ ${endText}`
|
||||
}
|
||||
return start || end || '-'
|
||||
})
|
||||
</script>
|
||||
@ -252,6 +298,29 @@ const planTimeText = computed(() => {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.card-oper {
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
margin-right: 4px;
|
||||
opacity: 0.95;
|
||||
}
|
||||
|
||||
.card-title-block {
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.card-material {
|
||||
font-size: 11px;
|
||||
font-weight: 500;
|
||||
opacity: 0.85;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.card-progress {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
@ -233,6 +233,16 @@
|
||||
<n-input v-model:value="dispatchform.quantity" disabled />
|
||||
</n-form-item>
|
||||
</n-gi>
|
||||
<n-gi>
|
||||
<n-form-item label="已完成">
|
||||
<n-input :value="String(dispatchform.completedQty ?? 0)" disabled />
|
||||
</n-form-item>
|
||||
</n-gi>
|
||||
<n-gi>
|
||||
<n-form-item label="本次待派">
|
||||
<n-input :value="String(dispatchform.remainQty ?? 0)" disabled />
|
||||
</n-form-item>
|
||||
</n-gi>
|
||||
<n-gi>
|
||||
<n-form-item label="开始时间">
|
||||
<n-input v-model:value="dispatchform.beginTime" disabled />
|
||||
@ -816,6 +826,8 @@ let dispatchform = reactive<any>({
|
||||
endTime:'',
|
||||
userid:'',
|
||||
quantity:'',
|
||||
completedQty: 0,
|
||||
remainQty: 0,
|
||||
list:[{
|
||||
userId:'',
|
||||
quantity:''
|
||||
@ -866,17 +878,22 @@ function deletenum(index:any) {
|
||||
|
||||
function disphand(process: ProcessPlanItemVO, order?: OrderProcessPlanVO) {
|
||||
const entity = processItemToEntity(process, order?.orderItemId)
|
||||
const planQty = Number(entity.quantity) || 0
|
||||
const completedQty = Number(process.completedQty) || 0
|
||||
const remainQty = Math.max(0, planQty - completedQty)
|
||||
dispatchmodal.value = true
|
||||
dispatchformRef.value?.restoreValidation()
|
||||
dispatchform.id = entity.id
|
||||
dispatchform.name = entity.name
|
||||
dispatchform.beginTime = entity.beginTime
|
||||
dispatchform.endTime = entity.endTime
|
||||
dispatchform.beginTime = entity.beginTime || order?.beginTime || ''
|
||||
dispatchform.endTime = entity.endTime || order?.endTime || ''
|
||||
dispatchform.quantity = entity.quantity
|
||||
dispatchform.completedQty = completedQty
|
||||
dispatchform.remainQty = remainQty
|
||||
dispatchform.userid = ''
|
||||
dispatchform.list = [{
|
||||
userId: '',
|
||||
quantity: '',
|
||||
quantity: remainQty || '',
|
||||
}]
|
||||
}
|
||||
|
||||
@ -885,10 +902,15 @@ function dispatchSubmit() {
|
||||
dispatchform.list.forEach((n:any) => {
|
||||
total = n.quantity*1+total
|
||||
})
|
||||
const remainQty = Number(dispatchform.remainQty)
|
||||
if (remainQty <= 0) {
|
||||
message.warning('当前工序已全部完成,无需再派工')
|
||||
return
|
||||
}
|
||||
dispatchformRef.value?.validate((v:any) => {
|
||||
if(!v){
|
||||
if(total != dispatchform.quantity){
|
||||
message.error('派工总数量需等于生产总数',{
|
||||
if(total != remainQty){
|
||||
message.error(`派工总数量需等于待派数量 ${remainQty}(计划 ${dispatchform.quantity},已完成 ${dispatchform.completedQty ?? 0})`,{
|
||||
duration:4000
|
||||
})
|
||||
}else{
|
||||
|
||||
Loading…
Reference in New Issue
Block a user