对齐和都后端修改的id字段

This commit is contained in:
tzy 2026-08-03 16:01:35 +08:00
parent b19dffa3cf
commit b0493eca29
10 changed files with 252 additions and 68 deletions

View File

@ -51,7 +51,7 @@ export interface OrderItem {
routeCode?: string
proWorkshop?: string
workshopId?: number | null
}
export interface KingdeePrdMo {
@ -130,6 +130,11 @@ export const orderItemApi = {
startWork(id: number) {
return request({ url: `/biz/orderItem/${id}/startWork`, method: 'post' })
},
/** 按工艺路线编码查询工艺路线(含工序);可带 orderItemId 精确匹配 */
getRoute(params: { routeCode?: string; orderItemId?: number | string }) {
return request({ url: '/biz/orderItem/route', method: 'get', params })
},
//根据生产编号查询预生产订单
preCreation(data: any) {
return request({ url: '/biz/orderItem/preCreation', method: 'post', data })
@ -163,7 +168,7 @@ export const orderItemApi = {
projectName?: string
orderCode?: string
routeCode?: string
proWorkshop?: string
workshopId?: number | string
beginTime?: string
endTime?: string
}) {
@ -173,7 +178,7 @@ export const orderItemApi = {
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?.workshopId !== undefined && params?.workshopId !== null) p.workshopId = params.workshopId
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' })

View File

@ -38,6 +38,10 @@ export interface OrderProcessPlan {
storageEntry?: number
sectionId?: number | null
workshopId?: number | null
}
@ -70,9 +74,13 @@ export interface ProcessPlanItemVO {
operNumber?: number
workCenterName?: string
sectionId?: number | null
departmentName?: string
sectionName?: string | null
workshopId?: number | null
workshopName?: string | null
processName?: string
@ -132,8 +140,6 @@ export interface ProcessPlanItemVO {
assignWorkList?: AssignWorkItem[]
proWorkshop?: string
}
@ -156,7 +162,9 @@ export interface OrderProcessPlanVO {
routeCode?: string
proWorkshop?: string
workshopId?: number | null
workshopName?: string | null
beginTime?: string
@ -232,8 +240,6 @@ export function processItemToEntity(
orderItemId?: number,
proWorkshop?:string
): OrderProcessPlan {
return {
@ -265,10 +271,10 @@ export function processItemToEntity(
qualityInspection: item.qualityInspection,
storageEntry: item.storageEntry,
workCenterName:item.workCenterName,
proWorkshop
sectionId: item.sectionId ?? null,
workshopId: item.workshopId ?? null,
}
@ -284,13 +290,13 @@ export function toOrderProcessPlanPayload(data: Record<string, unknown>): OrderP
const displayKeys = [
'mainCode', 'materialCode', 'materialName', 'orderCode', 'routeCode', 'proWorkshop',
'mainCode', 'materialCode', 'materialName', 'orderCode', 'routeCode', 'workshopName',
'actualStartTime', 'actualEndTime', 'completedQty', 'orderStatus', 'currentProcessName',
'currentOperNumber', 'processList', 'planId', 'processName', 'processCode', 'operNumber',
'workCenterName', 'departmentName', 'operDescription', 'activityUnit', 'optCtrlCodeName',
'sectionName', 'workshopName', 'operDescription', 'activityUnit', 'optCtrlCodeName',
'activityQty', 'planStartTime', 'planFinishTime', 'actualFinishTime', 'transferInQty',

View File

@ -39,6 +39,10 @@ export const processRouteApi = {
return request({ url: '/biz/processRoute/page', method: 'get', params })
},
getByCode(code: string) {
return request({ url: `/biz/processRoute/code/${encodeURIComponent(code)}`, method: 'get' })
},
// 获取详情
detail(id: string) {
return request({ url: `/biz/processRoute/${id}`, method: 'get' })

View File

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

View File

@ -91,6 +91,31 @@
</n-card>
</div>
<!-- 工艺路线右侧抽屉 -->
<n-drawer v-model:show="routeDrawerVisible" :width="720" placement="right">
<n-drawer-content :title="routeDrawerTitle" closable>
<n-spin :show="routeDrawerLoading">
<template v-if="routeDetail">
<n-descriptions label-placement="left" :column="2" size="small" bordered class="route-desc">
<n-descriptions-item label="工艺路线编码">{{ routeDetail.routeCode || '-' }}</n-descriptions-item>
<n-descriptions-item label="工艺路线名称">{{ routeDetail.routeName || '-' }}</n-descriptions-item>
</n-descriptions>
<div class="route-steps-title">工序明细</div>
<n-data-table
size="small"
striped
:bordered="false"
:single-line="false"
:columns="routeStepColumns"
:data="routeDetail.stepList || []"
:max-height="520"
/>
</template>
<n-empty v-else-if="!routeDrawerLoading" description="未查询到工艺路线" />
</n-spin>
</n-drawer-content>
</n-drawer>
<!-- 新增/编辑弹窗 -->
<n-modal
v-model:show="modalVisible"
@ -178,8 +203,8 @@
</n-form-item>
</n-gi>
<n-gi>
<n-form-item label="生产车间" path="proWorkshop">
<n-input v-model:value="formData.proWorkshop" placeholder="生产车间" :disabled="!formData.id" />
<n-form-item label="生产车间" path="workshopId">
<n-input :value="resolveWorkshopLabel(formData.workshopId)" placeholder="生产车间" disabled />
</n-form-item>
</n-gi>
@ -379,9 +404,10 @@
<script setup lang="ts">
import { ref, reactive, h, computed, onMounted, type HTMLAttributes } from 'vue'
import { NButton, NSpace, NIcon, NTag, useMessage, useDialog, type UploadCustomRequestOptions, type TreeOption } from 'naive-ui'
import { NButton, NSpace, NIcon, NTag, useMessage, useDialog, type UploadCustomRequestOptions, type TreeOption, type DataTableColumns } from 'naive-ui'
import { SearchOutline, RefreshOutline, CreateOutline, PlayOutline, DocumentTextOutline } from '@vicons/ionicons5'
import { orderItemApi, type OrderItem } from '@/api/orderItem'
import { processRouteApi } from '@/api/processRoute'
import { useUserStore } from '@/stores/user'
import { VueDraggable } from 'vue-draggable-plus'
@ -390,7 +416,7 @@ import KingdeeVue from '@/views/biz/kingdee/index.vue'
import { type KingdeePrdMo } from '@/api/orderProject'
import { mapKingdeeMoListToTableRows, type KingdeeMoTableRow } from '@/utils/kingdeeSchedule'
import { userApi } from '@/api/system'
import { dictDataApi } from '@/api/org'
import { deptApi } from '@/api/org'
const message = useMessage()
const dialog = useDialog()
@ -411,7 +437,7 @@ const searchForm = reactive<any>({
projectName: '',
orderCode: '',
routeCode: '',
proWorkshop: '',
workshopId: null as number | null,
beginTime: null as number | null,
endTime: null as number | null,
})
@ -511,12 +537,111 @@ const defaultFormData = {
starter: '',
orderCode: '',
routeCode: '',
proWorkshop: '',
workshopId: null as number | null,
}
const formData = reactive<any>({ ...defaultFormData })
// //使
const workshopList = ref<{ label: string; value: any; class: any }[]>([])
/** 部门全量(用于工段/车间名称解析) */
const deptNameMap = ref<Record<string, string>>({})
function resolveWorkshopLabel(val: any) {
if (val === null || val === undefined || val === '') return ''
const opt = workshopList.value.find(o =>
o.value === val ||
String(o.value) === String(val) ||
o.label === val ||
String(o.label) === String(val)
)
return opt?.label ?? String(val)
}
function resolveDeptName(val: any) {
if (val === null || val === undefined || val === '') return '-'
return deptNameMap.value[String(val)] || String(val)
}
// 线
const routeDrawerVisible = ref(false)
const routeDrawerLoading = ref(false)
const routeDrawerTitle = ref('工艺路线')
const routeDetail = ref<{
routeCode?: string
routeName?: string
stepList?: any[]
} | null>(null)
const routeStepColumns: DataTableColumns<any> = [
{ title: '工序号', key: 'operNumber', width: 72, align: 'center' },
{ title: '工序名称', key: 'processName', width: 110, align: 'center', ellipsis: { tooltip: true } },
{ title: '工序说明', key: 'operDescription', minWidth: 140, ellipsis: { tooltip: true } },
{
title: '工段',
key: 'sectionId',
width: 100,
align: 'center',
ellipsis: { tooltip: true },
render(row) { return resolveDeptName(row.sectionId) }
},
{
title: '生产车间',
key: 'workshopId',
width: 100,
align: 'center',
ellipsis: { tooltip: true },
render(row) { return resolveDeptName(row.workshopId) }
},
{ title: '活动量', key: 'activityQty', width: 80, align: 'center' },
{ title: '活动单位', key: 'activityUnit', width: 80, align: 'center' },
{ title: '控制码', key: 'optCtrlCodeName', width: 100, align: 'center', ellipsis: { tooltip: true } },
{
title: '委外',
key: 'isOutsource',
width: 64,
align: 'center',
render(row) {
return Number(row.isOutsource) === 1 ? '是' : '否'
}
},
]
async function openRouteDrawer(row: any) {
const code = row?.routeCode
if (!code) {
message.warning('该订单无工艺路线编码')
return
}
routeDrawerTitle.value = `工艺路线 · ${code}`
routeDrawerVisible.value = true
routeDrawerLoading.value = true
routeDetail.value = null
try {
const data: any = await orderItemApi.getRoute({
routeCode: code,
orderItemId: row.id,
})
if (data) {
routeDetail.value = data
return
}
// 线退线
const master: any = await processRouteApi.getByCode(code)
if (master) {
routeDetail.value = {
routeCode: master.code,
routeName: master.name,
stepList: master.stepList || [],
}
} else {
message.warning('未查询到工艺路线')
}
} catch {
//
} finally {
routeDrawerLoading.value = false
}
}
//
const formRules = {
@ -557,16 +682,38 @@ const columns = computed(() => [
align:'center',
title: '工艺路线编码',
key: 'routeCode',
width:"120"
width:"140",
render(row: any) {
const code = row.routeCode
if (!code) return '-'
return h(
'a',
{
class: 'route-code-link',
href: 'javascript:;',
style: {
color: '#2080f0',
textDecoration: 'underline',
cursor: 'pointer',
},
onClick: (e: MouseEvent) => {
e.preventDefault()
e.stopPropagation()
openRouteDrawer(row)
},
},
code
)
}
},
{
align:'center',
title: '生产车间',
key: 'proWorkshop',
key: 'workshopId',
width:"120",
render(row: any) {
const val = row.proWorkshop
// dictValue WorkShopName
const val = row.workshopId
// id /稿
const opt = workshopList.value.find(o =>
o.value === val ||
String(o.value) === String(val) ||
@ -753,7 +900,7 @@ function handleReset() {
searchForm.projectName = ''
searchForm.orderCode = ''
searchForm.routeCode = ''
searchForm.proWorkshop = ''
searchForm.workshopId = null
searchForm.beginTime = null
searchForm.endTime = null
selectedProjectId.value = undefined
@ -793,14 +940,14 @@ let planList = ref<any>([])
planList.value = rps.planList ? rps.planList : []
formData.orderCode = rps.orderCode ?? ''
formData.routeCode = rps.routeCode ?? ''
formData.proWorkshop = rps.proWorkshop ?? ''
formData.workshopId = rps.workshopId ?? null
if (rps.quantity != null) formData.quantity = rps.quantity
})
}else{
planList.value.splice(0)
formData.orderCode = ''
formData.routeCode = ''
formData.proWorkshop = ''
formData.workshopId = null
}
}
@ -842,7 +989,7 @@ function xmselupdate(v:any,opt:any) {
formData.code = ''
formData.orderCode = ''
formData.routeCode = ''
formData.proWorkshop = ''
formData.workshopId = null
formData.projectName = opt.label
formData.projectCode = opt?.additionParams?.projectCode || ''
if(v){
@ -1176,7 +1323,7 @@ async function handleExport() {
if (searchForm.projectName) params.projectName = searchForm.projectName
if (searchForm.orderCode) params.orderCode = searchForm.orderCode
if (searchForm.routeCode) params.routeCode = searchForm.routeCode
if (searchForm.proWorkshop) params.proWorkshop = searchForm.proWorkshop
if (searchForm.workshopId) params.workshopId = searchForm.workshopId
if (searchForm.beginTime != null) params.beginTime = searchForm.beginTime
if (searchForm.endTime != null) params.endTime = searchForm.endTime
const blob = await orderItemApi.export(params)
@ -1227,18 +1374,26 @@ async function handleImportUpload({ file }: UploadCustomRequestOptions) {
}
}
//
async function loadDictOptions() {
// 使
async function loadWorkshopOptions() {
try {
const data = await dictDataApi.listByType('work_shop')
workshopList.value = data.map(d => ({ label: d.dictLabel, value: (Number(d.dictValue) || d.dictValue), class: d.listClass }))
const data = await deptApi.list()
const list = data || []
const map: Record<string, string> = {}
list.forEach((d: any) => {
if (d?.id != null) map[String(d.id)] = d.deptName || String(d.id)
})
deptNameMap.value = map
workshopList.value = list
.filter((d: any) => d.deptName && d.deptName.includes('车间'))
.map((d: any) => ({ label: d.deptName, value: d.id, class: 'info' }))
} catch {}
}
onMounted(() => {
loadProjectTree()
loadData()
loadDictOptions()
loadWorkshopOptions()
updateScrollX()
window.addEventListener('resize', updateScrollX)
@ -1289,4 +1444,19 @@ onMounted(() => {
.table-toolbar {
margin-bottom: 16px;
}
:deep(.route-code-link) {
color: #2080f0 !important;
cursor: pointer;
text-decoration: underline !important;
}
.route-desc {
margin-bottom: 16px;
}
.route-steps-title {
margin: 8px 0 12px;
font-weight: 600;
}
</style>

View File

@ -114,7 +114,7 @@
<div class="col-qty">{{ order.quantity ?? '-' }}</div>
<div class="col-mode">
<n-tag v-if="order.routeCode" size="tiny" :bordered="false">工艺型</n-tag>
<n-tag v-if="order.proWorkshop" size="tiny" type="info" :bordered="false">{{ order.proWorkshop }}</n-tag>
<n-tag v-if="order.workshopName" size="tiny" type="info" :bordered="false">{{ order.workshopName }}</n-tag>
</div>
<div class="col-kit">-</div>
<div class="col-flow" :class="{ 'flow-expanded': isExpanded(order) }">
@ -201,7 +201,7 @@
:order-code="order.orderCode"
:order-begin-time="order.beginTime"
:order-end-time="order.endTime"
:pro-workshop="order.proWorkshop"
:workshop-name="order.workshopName"
:is-last="idx === (order.processList?.length ?? 0) - 1"
:can-edit="hasPermission('biz:orderItem:edit')"
:can-assign="hasPermission('biz:orderItem:assign')"
@ -248,7 +248,7 @@
<n-descriptions-item label="物料">{{ detailData.materialName || '-' }}</n-descriptions-item>
<n-descriptions-item label="数量">{{ detailData.quantity ?? '-' }}</n-descriptions-item>
<n-descriptions-item label="工艺路线">{{ detailData.routeCode || '-' }}</n-descriptions-item>
<n-descriptions-item label="车间">{{ detailData.proWorkshop || '-' }}</n-descriptions-item>
<n-descriptions-item label="车间">{{ detailData.workshopName || '-' }}</n-descriptions-item>
<n-descriptions-item label="计划开工">{{ detailData.beginTime || '-' }}</n-descriptions-item>
<n-descriptions-item label="计划完工">{{ detailData.endTime || '-' }}</n-descriptions-item>
<n-descriptions-item label="订单状态">{{ lifeLabel(detailData) }}</n-descriptions-item>
@ -262,7 +262,7 @@
:order-code="detailData.orderCode"
:order-begin-time="detailData.beginTime"
:order-end-time="detailData.endTime"
:pro-workshop="detailData.proWorkshop"
:workshop-name="detailData.workshopName"
:is-last="idx === (detailData.processList?.length ?? 0) - 1"
:can-edit="hasPermission('biz:orderItem:edit')"
:can-assign="hasPermission('biz:orderItem:assign')"
@ -454,8 +454,8 @@
:key="i"
:obj="n"
:index="i"
:section="dispatchform.workCenterName"
:workShop="dispatchform.workShop"
:section-id="dispatchform.sectionId"
:workshop-id="dispatchform.workshopId"
listname="list"
@addhand="addpgnum"
@delehand="deletenum(i)"
@ -741,7 +741,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: '', sectionId: null as number | null, workshopId: null as number | null,
list: [{ sectionId:'',deviceId:'', quantity: '' }],
})
const dispatchrules = {}
@ -1247,7 +1247,7 @@ async function handleSubmit() {
}
function disphand(process: ProcessPlanItemVO, order?: OrderProcessPlanVO) {
const entity = processItemToEntity(process, order?.orderItemId,order?.proWorkshop)
const entity = processItemToEntity(process, order?.orderItemId)
const planQty = Number(entity.quantity) || 0
const completedQty = Number(process.completedQty) || 0
@ -1265,12 +1265,8 @@ function disphand(process: ProcessPlanItemVO, order?: OrderProcessPlanVO) {
dispatchform.remainQty = remainQty
dispatchform.orderItemId = entity.orderItemId
dispatchform.sort = entity.sort
dispatchform.workCenterName = entity.workCenterName
dispatchform.workShop = entity.proWorkshop
dispatchform.list = [{ sectionId:'',deviceId:'', quantity: '' }]
dispatchform.sectionId = entity.sectionId ?? process.sectionId ?? null
dispatchform.workshopId = entity.workshopId ?? process.workshopId ?? order?.workshopId ?? null
dispatchform.list = [{ sectionId: '', deviceId: '', quantity: remainQty || '' }]
}

View File

@ -65,7 +65,7 @@
<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>{{ workshopText }}</em></div>
<div class="meta-line"><span>工位</span><em>{{ process.workCenterName || '-' }}</em></div>
<div class="meta-line"><span>工位</span><em>{{ process.sectionName || '-' }}</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>
@ -130,8 +130,8 @@ const props = defineProps<{
orderBeginTime?: string
/** 订单计划结束(订单头 endTime */
orderEndTime?: string
/** 生产车间(订单头 proWorkshop */
proWorkshop?: string
/** 生产车间名称(订单头 workshopName */
workshopName?: string
isLast?: boolean
canEdit?: boolean
canAssign?: boolean
@ -204,7 +204,7 @@ const personnel = computed(() => {
})
const workshopText = computed(() => {
return props.process.departmentName || props.proWorkshop || '-'
return props.process.workshopName || props.workshopName || '-'
})
const deviceText = computed(() => {

View File

@ -608,7 +608,7 @@ const orderColumns: DataTableColumns<OrderProcessPlanVO> = [
},
{ title: '数量', key: 'quantity', width: 72, align: 'center' },
{ title: '工艺路线', key: 'routeCode', width: 108, align: 'center', ellipsis: { tooltip: true } },
{ title: '生产车间', key: 'proWorkshop', width: 108, align: 'center', ellipsis: { tooltip: true } },
{ title: '生产车间', key: 'workshopName', width: 108, align: 'center', ellipsis: { tooltip: true } },
{ title: '计划开工', key: 'beginTime', width: 168, align: 'center', ellipsis: { tooltip: true } },
{ title: '计划完工', key: 'endTime', width: 168, align: 'center', ellipsis: { tooltip: true } },
{ title: '实际开工', key: 'actualStartTime', width: 168, align: 'center', ellipsis: { tooltip: true }, render: (row) => row.actualStartTime || '-' },
@ -639,8 +639,8 @@ const processColumns: DataTableColumns<ProcessPlanItemVO> = [
{ title: '工序编码', key: 'processCode', width: 96, align: 'center', ellipsis: { tooltip: true } },
{ title: '工序名称', key: 'processName', width: 140, ellipsis: { tooltip: true } },
{ title: '工序说明', key: 'operDescription', width: 160, ellipsis: { tooltip: true } },
{ title: '工作中心', key: 'workCenterName', width: 112, align: 'center', ellipsis: { tooltip: true } },
{ title: '部门', key: 'departmentName', width: 112, align: 'center', ellipsis: { tooltip: true } },
{ title: '工作中心', key: 'sectionName', width: 112, align: 'center', ellipsis: { tooltip: true } },
{ title: '部门', key: 'workshopName', width: 112, align: 'center', ellipsis: { tooltip: true } },
{ title: '计划开工', key: 'planStartTime', width: 168, align: 'center', ellipsis: { tooltip: true } },
{ title: '计划完工', key: 'planFinishTime', width: 168, align: 'center', ellipsis: { tooltip: true } },
{ title: '实际开工', key: 'actualStartTime', width: 168, align: 'center', ellipsis: { tooltip: true }, render: (row) => row.actualStartTime || '-' },

View File

@ -94,8 +94,8 @@
listname:any
obj:any,
index:any
section:string
workShop: string
sectionId?: number | string | null
workshopId?: number | string | null
}>(), {
obj:{}
})
@ -153,12 +153,13 @@
})
}
//
// sectionId
async function loadSection() {
//section
const res = await sectionApi.list({sectionName:props.section,workShop:props.workShop})
const mesSection = res.MesSection;
const mesDevice = res.MesDevice
if (props.sectionId == null || props.sectionId === '') return
const res = await sectionApi.list({sectionId: props.sectionId})
const mesSection = res?.MesSection;
const mesDevice = res?.MesDevice || []
if (!mesSection) return
sectionList.push({
label:mesSection.deptName,

View File

@ -132,7 +132,7 @@ 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 { sectionApi, type Section } from '@/api/section'
import { dictDataApi } from '@/api/org'
import { deptApi, dictDataApi } from '@/api/org'
const message = useMessage()
const dialog = useDialog()
@ -401,11 +401,13 @@ async function handleImportUpload({ file }: UploadCustomRequestOptions) {
}
}
//
//
async function loadDictOptions() {
try {
const data = await dictDataApi.listByType('work_shop')
workshopList.value = data.map(d => ({ label: d.dictLabel, value: (Number(d.dictValue) || d.dictValue),class:d.listClass }))
const data = await deptApi.list()
workshopList.value = (data || [])
.filter(d => d.deptName && d.deptName.includes('车间'))
.map(d => ({ label: d.deptName, value: d.id, class: 'info' }))
}catch {}
try {