调整预生产接口

This commit is contained in:
andy 2026-06-09 10:30:07 +08:00
parent 57c7eb92eb
commit 11ce22d245
5 changed files with 730 additions and 211 deletions

View File

@ -52,6 +52,48 @@ export interface OrderItem {
proWorkshop?: string proWorkshop?: string
} }
export interface KingdeePrdMo {
productionOrderNo: string
billNo: string
workShopName: string
materialCode: string
quantity: number | null
specModel: string | null
unit: string | null
materialName: string | null
routingNo: string | null
planStartTime: string | null
planFinishTime: string | null
pickMtrlStatus: string | null
children: KingdeeProcessRoute[]
}
/** 金蝶工艺路线工序(树子节点) */
export interface KingdeeProcessRoute {
/** 工序号 FOperNumber */
operNumber: number | null
/** 工作中心 FWorkCenterId.FName */
workCenterName: string | null
/** 生产车间 FDepartmentId.FName */
departmentName: string | null
/** 工序名称 FProcessProperty */
processName: string | null
/** 工序说明 FOperDescription */
operDescription: string | null
/** 活动单位 FActivity1UnitID.FName */
activityUnit: string | null
/** 工序控制码 FOptCtrlCodeId.FName */
optCtrlCodeName: string | null
/** 活动量 FActivity1Qty */
activityQty: number | null
/** 计划开始时间 yyyy-MM-dd HH:mm:ss */
planStartTime: string | null
/** 计划结束时间 yyyy-MM-dd HH:mm:ss */
planFinishTime: string | null
}
// 生产订单 API // 生产订单 API
export const orderItemApi = { export const orderItemApi = {
// 分页查询 // 分页查询
@ -86,6 +128,11 @@ export const orderItemApi = {
preCreation(data: any) { preCreation(data: any) {
return request({ url: '/biz/orderItem/preCreation', method: 'post', data }) return request({ url: '/biz/orderItem/preCreation', method: 'post', data })
}, },
//根据生产编号查询预生产订单
preCreationInfo(id: number, params:any) {
debugger;
return request({ url: `/biz/orderItem/preCreation/${id}`, method: 'get', params})
},
//查询项目名称 //查询项目名称
xmoptions(params: any) { xmoptions(params: any) {
@ -96,6 +143,10 @@ export const orderItemApi = {
wloptions(params: any) { //projectId wloptions(params: any) { //projectId
return request({ url: '/biz/orderItem/options', method: 'get', params }) return request({ url: '/biz/orderItem/options', method: 'get', params })
}, },
holdTemporarilySave(id: number, data: KingdeePrdMo[]){
return request({ url: `/biz/orderItem/kingdee/temporarily/save/${id}`, method: 'post', data })
},
// 导出 // 导出
export(params?: { export(params?: {

View File

@ -175,8 +175,8 @@ export const orderProjectApi = {
}, },
// 查询金蝶生产订单 (支持优先读取本地暂存) // 查询金蝶生产订单 (支持优先读取本地暂存)
getKingdeeOrder(id: number) { getKingdeeOrder(id: number, params:any) {
return request<KingdeePrdMo[]>({ url: `/biz/orderProject/kingdee/order/${id}`, method: 'get' }) return request<KingdeePrdMo[]>({ url: `/biz/orderProject/kingdee/order/${id}`, method: 'get', params })
}, },
// 暂存金蝶生产订单数据(草稿) // 暂存金蝶生产订单数据(草稿)

View File

@ -0,0 +1,458 @@
<template>
<div class="kingdee-toolbar">
<n-space>
<n-button
size="small"
:disabled="kingdeeLoading || !kingdeeTableData.length"
@click="kingdeeToggleExpandAll"
>
{{ kingdeeAllExpanded ? '全部收起' : '全部展开' }}
</n-button>
<n-button
size="small"
type="primary"
:disabled="kingdeeLoading || !kingdeeTableData.length"
@click="handleGanttSchedule"
>
<template #icon><n-icon><CalendarOutline /></n-icon></template>
甘特图排产
</n-button>
</n-space>
</div>
<n-data-table
v-model:expanded-row-keys="kingdeeExpandedKeys"
:columns="kingdeeMoColumns"
:data="kingdeeTableData"
:loading="kingdeeLoading"
:row-key="kingdeeMoRowKey"
:scroll-x="kingdeeMoScrollX"
:max-height="kingdeeTableMaxHeight"
:row-class-name="kingdeeMoRowClassName"
size="small"
style="margin-bottom:15px"
/>
<div style="margin-bottom: 1px;">
<!-- <template #footer> -->
<n-space justify="end">
<n-button type="error" :disabled="kingdeeLoading" @click="reCrawlReorderForm">
重新读取数据
</n-button>
<n-button type="primary" :disabled="kingdeeLoading" @click="handleSaveDraft">
保存草稿
</n-button>
<n-button type="info" :disabled="kingdeeLoading" @click="handleSyncOrderAndPlan">
同步订单计划
</n-button>
<n-button @click="$emit('close-modal')">关闭</n-button>
</n-space>
<!-- </template> -->
</div>
</template>
<script setup lang="ts">
import { ref, h, computed, defineProps, onMounted, watch, defineEmits} from 'vue'
import { NButton, NSpace, NIcon, NTag, NDatePicker, NDataTable, useMessage, useDialog, type DataTableColumns } from 'naive-ui'
import { type KingdeePrdMo, type KingdeeProcessRoute } from '@/api/orderProject'
import { useRouter } from 'vue-router'
import { CalendarOutline } from '@vicons/ionicons5'
const emit = defineEmits(['holdTemporarilyCallback', "synchronizationCallback","reCrawlCallback"])
const dialog = useDialog()
const message = useMessage()
const router = useRouter()
const props = defineProps({
kingdeeTableData: {
type: Array,
default: () => []
},
selectedId:{
type: Number,
default: null
}
})
onMounted(() => {
kingdeeTableData.value = props.kingdeeTableData as KingdeeMoTableRow[]
})
watch(()=>props.kingdeeTableData,()=>{
kingdeeTableData.value = props.kingdeeTableData as KingdeeMoTableRow[]
},{ deep: true } )
const kingdeeModalVisible = ref(false)
const kingdeeLoading = ref(false)
/** 主表行:工序仅存 processRoutes避免 children 触发树形重复行 */
type KingdeeMoTableRow = Omit<KingdeePrdMo, 'children'> & { processRoutes: KingdeeProcessRoute[] }
const kingdeeTableData = ref<KingdeeMoTableRow[]>([])
const kingdeeExpandedKeys = ref<Array<string | number>>([])
// const kingdeeCurrentProjectId = ref<number | null>(null) // ID
const kingdeeTableMaxHeight = 'min(78vh, 720px)'
const kingdeeMoScrollX = 1820
const kingdeeProcessScrollX = 1360
const kingdeeMoColumns: DataTableColumns<KingdeeMoTableRow> = [
{
type: 'expand',
expandable: () => true,
renderExpand: (row) => renderKingdeeExpand(row),
},
{
title: '类型', key: 'rowType', width: 96, align: 'center',
render() {
return h(NTag, { size: 'small', type: 'info', bordered: false }, { default: () => '生产订单' })
}
},
{ title: '单据编号', key: 'billNo', width: 120, align: 'center', ellipsis: { tooltip: true } },
{ title: '生产令号', key: 'productionOrderNo', width: 130, align: 'center', ellipsis: { tooltip: true } },
{ title: '工艺路线', key: 'routingNo', width: 110, align: 'center', ellipsis: { tooltip: true } },
{ title: '物料编码', key: 'materialCode', width: 180, ellipsis: { tooltip: true } },
{ title: '物料名称', key: 'materialName', width: 160, ellipsis: { tooltip: true } },
{
title: '数量', key: 'quantity', width: 90, align: 'center',
render(row) {
return formatKingdeeQty(row.quantity)
}
},
{ title: '生产车间', key: 'workShopName', width: 100, align: 'center', ellipsis: { tooltip: true } },
{ title: '规格型号', key: 'specModel', width: 110, align: 'center', ellipsis: { tooltip: true } },
{ title: '单位', key: 'unit', width: 60, align: 'center' },
{
title: '计划开工', key: 'planStartTime', width: 180, align: 'center',
render(row) {
return renderKingdeePlanPickerMo(row, 'planStartTime')
}
},
{
title: '计划完工', key: 'planFinishTime', width: 180, align: 'center',
render(row) {
return renderKingdeePlanPickerMo(row, 'planFinishTime')
}
},
{
title: '领料状态', key: 'pickMtrlStatus', width: 90, align: 'center',
render(row) {
const val = row.pickMtrlStatus
return val != null ? (pickMtrlStatusMap[String(val)] ?? val) : '-'
}
},
]
const kingdeeProcessColumns: DataTableColumns<KingdeeProcessRoute> = [
{
title: '类型', key: 'rowType', width: 72, align: 'center',
render() {
return h(NTag, { size: 'small', type: 'warning', bordered: false }, { default: () => '工序' })
}
},
{
title: '工序号', key: 'operNumber', width: 80, align: 'center',
render(row) {
return row.operNumber != null ? String(row.operNumber) : '-'
}
},
{ title: '工序名称', key: 'processProperty', width: 100, align: 'center' },
{ title: '工序说明', key: 'operDescription', width: 140, ellipsis: { tooltip: true } },
{ title: '工作中心', key: 'workCenterName', width: 110, align: 'center', ellipsis: { tooltip: true } },
{ title: '生产车间', key: 'departmentName', width: 110, align: 'center', ellipsis: { tooltip: true } },
{
title: '计划开始时间', key: 'planStartTime', width: 180, align: 'center',
render(row) {
return renderKingdeePlanPicker(row, 'planStartTime')
}
},
{
title: '计划结束时间', key: 'planFinishTime', width: 180, align: 'center',
render(row) {
return renderKingdeePlanPicker(row, 'planFinishTime')
}
},
{
title: '活动量', key: 'activityQty', width: 90, align: 'center',
render(row) {
return formatKingdeeQty(row.activityQty)
}
},
{ title: '活动单位', key: 'activityUnit', width: 80, align: 'center' },
{ title: '控制码', key: 'optCtrlCodeName', width: 120, align: 'center', ellipsis: { tooltip: true } },
]
const kingdeeAllExpanded = computed(() => {
const total = kingdeeTableData.value.length
if (!total) return false
return kingdeeExpandedKeys.value.length >= total
})
const pickMtrlStatusMap: Record<string, string> = {
'1': '未领料',
'2': '待定',
'3': '已领料',
}
function kingdeeMoRowClassName() {
return 'kingdee-mo-row'
}
function formatDateTime(ts: number) {
const d = new Date(ts)
const pad = (n: number) => String(n).padStart(2, '0')
return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`
}
function parseKingdeePlanTime(val: string | number | null | undefined): number | null {
if (val == null || val === '') return null
if (typeof val === 'number') return val
const ts = new Date(val.replace(' ', 'T')).getTime()
return Number.isNaN(ts) ? null : ts
}
function renderKingdeePlanPicker(row: KingdeeProcessRoute, field: 'planStartTime' | 'planFinishTime') {
return h(NDatePicker, {
value: parseKingdeePlanTime(row[field]),
type: 'datetime',
clearable: true,
size: 'small',
style: { width: '100%' },
onUpdateValue: (val: number | null) => {
row[field] = val != null ? formatDateTime(val) : null
},
})
}
function renderKingdeePlanPickerMo(row: KingdeeMoTableRow, field: 'planStartTime' | 'planFinishTime') {
return h(NDatePicker, {
value: parseKingdeePlanTime(row[field]),
type: 'datetime',
clearable: true,
size: 'small',
style: { width: '100%' },
onUpdateValue: (val: number | null) => {
row[field] = val != null ? formatDateTime(val) : null
},
})
}
function formatKingdeeQty(val: number | null | undefined) {
return val != null ? Number(val).toFixed(3) : '-'
}
function kingdeeMoRowKey(row: KingdeeMoTableRow) {
return `mo-${row.productionOrderNo}-${row.billNo}`
}
function kingdeeToggleExpandAll() {
if (kingdeeAllExpanded.value) {
kingdeeExpandedKeys.value = []
} else {
kingdeeExpandedKeys.value = kingdeeTableData.value.map(kingdeeMoRowKey)
}
}
function renderKingdeeExpand(row: KingdeeMoTableRow) {
const routes = getKingdeeRoutes(row)
if (!routes.length) {
return h('div', { class: 'kingdee-expand-empty' }, '暂无工艺路线工序')
}
return h('div', { class: 'kingdee-expand-wrap' }, [
h(NDataTable, {
class: 'kingdee-process-table',
columns: kingdeeProcessColumns,
data: routes,
rowKey: kingdeeProcessRowKey,
size: 'small',
bordered: true,
striped: true,
scrollX: kingdeeProcessScrollX,
}),
])
}
function getKingdeeRoutes(mo: KingdeeMoTableRow) {
return mo.processRoutes
}
function kingdeeProcessRowKey(row: KingdeeProcessRoute) {
return `route-${row.operNumber}-${row.workCenterName}-${row.operDescription}`
}
//
function handleGanttSchedule() {
// ID sessionStorage使
sessionStorage.setItem('gantt_schedule_data', JSON.stringify(kingdeeTableData.value))
if (props.selectedId) {
sessionStorage.setItem('gantt_project_id', String(props.selectedId))
}
//
router.push('/biz/orderProject/gantt')
}
//
async function handleSyncOrderAndPlan() {
if (!props.selectedId) return
kingdeeLoading.value = true
try {
// processRoutes children
const draftData = kingdeeTableData.value.map(mo => {
const { processRoutes, ...rest } = mo
return { ...rest, children: processRoutes } as KingdeePrdMo
})
emit('synchronizationCallback', props.selectedId, draftData)
message.success('同步订单计划成功')
kingdeeModalVisible.value = false
} catch (error) {
//
} finally {
kingdeeLoading.value = false
}
}
const reCrawlReorderForm = () => {
// // 稿
if (!props.selectedId) return
dialog.warning({
title: '提示',
content: '重启读取会导致当前页面数据全部重置, 确定需要重新读取吗?',
positiveText: '确定',
negativeText: '取消',
onPositiveClick: () => {
kingdeeLoading.value = true
try {
emit('reCrawlCallback', props.selectedId, true)
message.success('重启读取成功')
} catch (error) {
//
} finally {
kingdeeLoading.value = false
}
}
})
}
const handleSaveDraft = () => {
// // 稿
if (!props.selectedId) return
kingdeeLoading.value = true
try {
const draftData = kingdeeTableData.value.map(mo => {
const { processRoutes, ...rest } = mo
return { ...rest, children: processRoutes } as KingdeePrdMo
})
emit('holdTemporarilyCallback', props.selectedId, draftData)
message.success('草稿保存成功')
} catch (error) {
//
} finally {
kingdeeLoading.value = false
}
}
// // 稿
// async function handleSaveDraft() {
// if (!kingdeeCurrentProjectId) return
// kingdeeLoading.value = true
// try {
// // processRoutes children
// const draftData = kingdeeTableData.value.map(mo => {
// const { processRoutes, ...rest } = mo
// return { ...rest, children: processRoutes } as KingdeePrdMo
// })
// emit('holdTemporarilyCallback', { id:kingdeeCurrentProjectId, data:draftData })
// // await orderProjectApi.saveKingdeeOrderDraft(kingdeeCurrentProjectId.value, draftData)
// // message.success('稿')
// } catch (error) {
// //
// } finally {
// kingdeeLoading.value = false
// }
// }
</script>
<style scoped>
.search-form {
margin-bottom: 16px;
}
.table-toolbar {
margin-bottom: 16px;
}
.kingdee-toolbar {
margin-bottom: 12px;
}
:deep(.kingdee-modal .n-card) {
max-height: 94vh;
display: flex;
flex-direction: column;
}
:deep(.kingdee-modal .n-card__content) {
flex: 1;
min-height: 0;
overflow: hidden;
}
:deep(.kingdee-mo-row td) {
background-color: rgba(32, 128, 240, 0.06) !important;
font-weight: 500;
}
:deep(.kingdee-mo-row:hover td) {
background-color: rgba(32, 128, 240, 0.1) !important;
}
.kingdee-expand-wrap {
margin: 4px 8px 8px 36px;
padding: 12px 14px 14px;
border: 1px solid var(--n-border-color);
border-left: 4px solid #18a058;
border-radius: 6px;
background: var(--n-action-color);
}
:deep(.kingdee-process-table .n-data-table-th) {
background: rgba(24, 160, 88, 0.12) !important;
}
:deep(.kingdee-process-table .n-data-table-td) {
background-color: var(--n-color) !important;
}
:deep(.kingdee-process-table .n-data-table-tr--striped .n-data-table-td) {
background-color: var(--n-action-color) !important;
}
.kingdee-expand-empty {
margin: 4px 8px 8px 36px;
padding: 12px 14px;
font-size: 13px;
color: var(--n-text-color-3);
border: 1px dashed var(--n-border-color);
border-radius: 6px;
background: var(--n-action-color);
}
</style>

View File

@ -34,7 +34,7 @@
<!-- 工具栏 --> <!-- 工具栏 -->
<div class="table-toolbar"> <div class="table-toolbar">
<n-space> <n-space>
<n-button <!--<n-button
size="small" size="small"
type="primary" type="primary"
@click="handleAdd" @click="handleAdd"
@ -42,15 +42,15 @@
<template #icon><n-icon><AddOutline /></n-icon></template> <template #icon><n-icon><AddOutline /></n-icon></template>
新增/补单 新增/补单
</n-button> </n-button>
<!-- <n-button @click="importModalVisible = true"> <n-button @click="importModalVisible = true">
<template #icon><n-icon><CloudUploadOutline /></n-icon></template> <template #icon><n-icon><CloudUploadOutline /></n-icon></template>
导入 导入
</n-button> </n-button>
<n-button @click="handleExport"> <n-button @click="handleExport">
<template #icon><n-icon><DownloadOutline /></n-icon></template> <template #icon><n-icon><DownloadOutline /></n-icon></template>
导出{{ selectedIds.length > 0 ? `(${selectedIds.length})` : '' }} 导出{{ selectedIds.length > 0 ? `(${selectedIds.length})` : '' }}
</n-button> --> </n-button>
<!-- <n-button type="error" :disabled="selectedIds.length === 0" @click="handleBatchDelete"> <n-button type="error" :disabled="selectedIds.length === 0" @click="handleBatchDelete">
<template #icon><n-icon><TrashOutline /></n-icon></template> <template #icon><n-icon><TrashOutline /></n-icon></template>
删除 删除
</n-button> --> </n-button> -->
@ -117,16 +117,11 @@
</n-form-item> </n-form-item>
</n-gi> --> </n-gi> -->
<n-gi> <n-gi>
<n-form-item label="项目名称" path="projectCode"> <n-form-item label="项目名称" path="project">
<!-- <n-input v-if="formData.id" v-model:value="formData.projectName" disabled placeholder="请选择项目名称" />
-->
<n-input v-if="formData.id" v-model:value="formData.projectName" disabled placeholder="请选择项目" /> <n-input v-if="formData.id" v-model:value="formData.projectName" disabled placeholder="请选择项目" />
<!--@search="xmhand"-->
<n-select <n-select
v-else v-else
v-model:value="formData.projectCode" v-model:value="formData.projectId"
filterable filterable
placeholder="请选择项目" placeholder="请选择项目"
:options="xmlist" :options="xmlist"
@ -350,77 +345,39 @@
</n-space> </n-space>
</template> </template>
</n-modal> </n-modal>
<!-- 导入弹窗 --> <n-modal
<!-- <n-modal v-model:show="importModalVisible" preset="card" title="导入生产订单" style="width: 500px"> v-model:show="kingdeeModalVisible"
<n-space vertical> preset="card"
<n-alert type="info"> :title="kingdeeModalTitle"
<template #header>导入说明</template> class="kingdee-modal"
<ul style="margin: 0; padding-left: 16px; line-height: 1.8"> :style="{ width: '96vw', maxWidth: '1920px' }"
<li>请先下载导入模板按模板格式填写数据</li> :content-style="{ padding: '16px 24px', minHeight: '72vh' }"
<li>支持 .xlsx .xls 格式</li> :mask-closable="false"
</ul> :closable="true"
</n-alert> :close-on-esc="false"
<n-space> >
<n-button type="primary" @click="handleDownloadTemplate"> <KingdeeVue
<template #icon><n-icon><DownloadOutline /></n-icon></template> :kingdeeTableData="kingdeeTableData"
下载模板 :selectedId="kingdeeOrderOtemId"
</n-button> @close-modal="kingdeeModalVisible = false"
</n-space> @holdTemporarilyCallback="holdTemporarilySave"
<n-upload :max="1" accept=".xlsx,.xls" :show-file-list="true" :custom-request="handleImportUpload"> @synchronizationCallback="synchronizationSave"
<n-upload-dragger> @reCrawlCallback="reCrawlReorderForm"/>
<div style="margin-bottom: 12px"> </n-modal>
<n-icon size="48" :depth="3"><CloudUploadOutline /></n-icon>
</div>
<n-text style="font-size: 16px">点击或拖拽文件到此处上传</n-text>
<n-p depth="3" style="margin: 8px 0 0 0">支持 .xlsx .xls 格式</n-p>
</n-upload-dragger>
</n-upload>
</n-space>
<template #footer>
<n-button @click="importModalVisible = false">关闭</n-button>
</template>
</n-modal> -->
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { import { ref, reactive, h, onMounted } from 'vue'
ref, import { NButton, NSpace, NIcon, useMessage, useDialog, type UploadCustomRequestOptions} from 'naive-ui'
reactive, import { orderItemApi, type OrderItem } from '@/api/orderItem'
h,
onMounted
} from 'vue'
import {
NButton,
NSpace,
NIcon,
//NUpload,
useMessage,
useDialog,
//type DataTableColumns,
type UploadCustomRequestOptions
} from 'naive-ui'
import {
SearchOutline,
RefreshOutline,
AddOutline,
//TrashOutline,
//CreateOutline,
// CloudUploadOutline,
// DownloadOutline
} from '@vicons/ionicons5'
import {
orderItemApi,
type OrderItem
} from '@/api/orderItem'
import { useUserStore } from '@/stores/user' import { useUserStore } from '@/stores/user'
import { VueDraggable } from 'vue-draggable-plus' import { VueDraggable } from 'vue-draggable-plus'
// import Gxitem from './gxitem.vue' import KingdeeVue from '@/views/biz/kingdee/index.vue'
import { type KingdeePrdMo, type KingdeeProcessRoute } from '@/api/orderProject'
import { userApi } from '@/api/system' import { userApi } from '@/api/system'
const message = useMessage() const message = useMessage()
@ -632,19 +589,18 @@ const columns = [
align:'center', align:'center',
title: '操作', title: '操作',
key: 'actions', key: 'actions',
width: 140, width: 190,
fixed: 'right', fixed: 'right',
render(row:any) { render(row:any) {
const buttons:any = [] const buttons:any = []
if(hasPermission('biz:orderItem:edit')){ if(hasPermission('biz:orderItem:edit')){
buttons.push(h(NButton, { buttons.push(h(NButton, {
size: 'small', size: 'small',
type:'primary', type:'primary',
ghost:true, ghost:true,
onClick: () => { handleEdit(row) } }, onClick: () => { handleEdit(row) } },
//{ default: () => [h(NIcon, null, { default: () => h(CreateOutline) }), ' ' ]}
{ default: () => '编辑'} { default: () => '编辑'}
)) ))
} }
@ -657,6 +613,15 @@ const columns = [
{ default: () => '派工'} { default: () => '派工'}
)) ))
} }
if(hasPermission('biz:orderItem:reorderForm')){
buttons.push(h(NButton, {
size: 'small',
type:'info',
ghost:true,
onClick: () => handleReorderForm(row, false) }, //, disabled: row.starter !==1
{ default: () => '补单'}
))
}
return buttons.length > 0 ? h(NSpace, {justify:'center'}, { default: () => buttons }) : '-' return buttons.length > 0 ? h(NSpace, {justify:'center'}, { default: () => buttons }) : '-'
@ -779,31 +744,14 @@ let xmlist = ref<any>([])
let xmloading = ref(false) let xmloading = ref(false)
function xmhand() { async function xmhand() {
xmloading.value = true xmloading.value = true
orderItemApi.xmoptions({ xmlist.value = await orderItemApi.xmoptions({});
// page: 1, xmloading.value = false
// pageSize: 100,
// username: v,
}).then((rps:any) =>{
if(rps && rps.length > 0){
xmlist.value = rps.map((n:any) => {
return {
label:n.label,
value:n.value+''
}
})
}
xmloading.value = false
}).catch(() => {
xmloading.value = false
})
} }
let wllist = ref<any>([]) let wllist = ref<any>([])
function xmselupdate(v:any,opt:any) { function xmselupdate(v:any,opt:any) {
// console.log(v,'sle')
// console.log(opt,'opt')
planList.value.splice(0) planList.value.splice(0)
wllist.value.splice(0) wllist.value.splice(0)
formData.code = '' formData.code = ''
@ -811,6 +759,7 @@ function xmselupdate(v:any,opt:any) {
formData.routeCode = '' formData.routeCode = ''
formData.proWorkshop = '' formData.proWorkshop = ''
formData.projectName = opt.label formData.projectName = opt.label
formData.projectCode = opt?.additionParams?.projectCode || ''
if(v){ if(v){
wlhand(opt.value) wlhand(opt.value)
} }
@ -819,29 +768,73 @@ function xmselupdate(v:any,opt:any) {
// //
let wlloading = ref(false) let wlloading = ref(false)
function wlhand(v:any) { async function wlhand(v:any) {
wlloading.value = true wlloading.value = true
orderItemApi.wloptions({ wllist.value = await orderItemApi.wloptions({projectId:v });
projectId:v wlloading.value = false
// page: 1,
// pageSize: 100,
// username: v
}).then((rps:any) =>{
if(rps && rps.length > 0){
wllist.value = rps.map((n:any) => {
return {
label:n.label,
value:n.value+''
}
})
}
console.log(yglist.value,'12')
wlloading.value = false
}).catch(() => {
wlloading.value = false
})
} }
const kingdeeOrderOtemId = ref<number | null>(null) // ID
const kingdeeModalVisible = ref(false)
const kingdeeModalTitle = ref('金蝶生产订单')
const kingdeeLoading = ref(false)
type KingdeeMoTableRow = Omit<KingdeePrdMo, 'children'> & { processRoutes: KingdeeProcessRoute[] }
const kingdeeTableData = ref<KingdeeMoTableRow[]>([])
// const kingdeeExpandedKeys = ref<Array<string | number>>([])
async function reCrawlReorderForm(id:number,reCrawl:Boolean){
try {
const data = await orderItemApi.preCreationInfo(id, {reCrawl:reCrawl})
kingdeeTableData.value = (Array.isArray(data) ? data : []).map((mo) => {
const { children, ...rest } = mo
const routes = [...(children ?? [])].sort((a, b) => (a.operNumber ?? 0) - (b.operNumber ?? 0)).map((r) => ({
...r,
planStartTime: r.planStartTime ?? null,
planFinishTime: r.planFinishTime ?? null,
}))
return { ...rest, processRoutes: routes }
})
} finally {
kingdeeLoading.value = false
}
}
async function handleReorderForm(row:OrderItem, reCrawl:Boolean){
if (!row.id) {
message.warning('缺少物料订单ID无法查询')
return
}
kingdeeOrderOtemId.value = row.id
kingdeeModalTitle.value = `金蝶生产订单${row.code ? ` - ${row.code}` : ''}`
kingdeeModalVisible.value = true
kingdeeLoading.value = true
reCrawlReorderForm(row.id, false)
kingdeeLoading.value = false
}
// 稿
async function holdTemporarilySave(id: number, data: KingdeePrdMo[]) {
try {
// processRoutes children
await orderItemApi.holdTemporarilySave(id, data)
} catch (error) {
//
}
}
//
async function synchronizationSave(id: number, data: KingdeePrdMo[]) {
try {
// processRoutes children
await orderItemApi.synchronizationSave(id, data)
} catch (error) {
//
}
}
// //
function handleEdit(row: OrderItem) { function handleEdit(row: OrderItem) {
modalTitle.value = '编辑生产订单' modalTitle.value = '编辑生产订单'

View File

@ -148,48 +148,13 @@
:closable="false" :closable="false"
:close-on-esc="false" :close-on-esc="false"
> >
<div class="kingdee-toolbar"> <KingdeeVue
<n-space> :kingdeeTableData="kingdeeTableData"
<n-button :selectedId="kingdeeCurrentProjectId"
size="small" @close-modal="kingdeeModalVisible = false"
:disabled="kingdeeLoading || !kingdeeTableData.length" @holdTemporarilyCallback="handleSaveDraft"
@click="kingdeeToggleExpandAll" @synchronizationCallback="handleSyncOrderAndPlan"
> @reCrawlCallback="reCrawlReorderForm"/>
{{ kingdeeAllExpanded ? '全部收起' : '全部展开' }}
</n-button>
<n-button
size="small"
type="primary"
:disabled="kingdeeLoading || !kingdeeTableData.length"
@click="handleGanttSchedule"
>
<template #icon><n-icon><CalendarOutline /></n-icon></template>
甘特图排产
</n-button>
</n-space>
</div>
<n-data-table
v-model:expanded-row-keys="kingdeeExpandedKeys"
:columns="kingdeeMoColumns"
:data="kingdeeTableData"
:loading="kingdeeLoading"
:row-key="kingdeeMoRowKey"
:scroll-x="kingdeeMoScrollX"
:max-height="kingdeeTableMaxHeight"
:row-class-name="kingdeeMoRowClassName"
size="small"
/>
<template #footer>
<n-space justify="end">
<n-button type="info" :disabled="kingdeeLoading" @click="handleSyncOrderAndPlan">
同步订单计划
</n-button>
<n-button type="primary" :disabled="kingdeeLoading" @click="handleSaveDraft">
保存草稿
</n-button>
<n-button @click="kingdeeModalVisible = false">关闭</n-button>
</n-space>
</template>
</n-modal> </n-modal>
<!-- 导入弹窗 --> <!-- 导入弹窗 -->
@ -235,6 +200,9 @@ import { useUserStore } from '@/stores/user'
import { useRouter, useRoute } from 'vue-router' import { useRouter, useRoute } from 'vue-router'
import KingdeeVue from '@/views/biz/kingdee/index.vue'
const message = useMessage() const message = useMessage()
const dialog = useDialog() const dialog = useDialog()
const userStore = useUserStore() const userStore = useUserStore()
@ -451,7 +419,7 @@ const columns: DataTableColumns<OrderProject> = [
const buttons = [] const buttons = []
if (hasPermission('biz:orderProject:getKingdeeOrder')) { if (hasPermission('biz:orderProject:getKingdeeOrder')) {
buttons.push( buttons.push(
h(NButton, { size: 'small', quaternary: true, type: 'info', onClick: () => handleKingdeeQuery(row) }, { h(NButton, { size: 'small', quaternary: true, type: 'info', onClick: () => handleKingdeeQuery(row, false) }, {
default: () => [h(NIcon, null, { default: () => h(EyeOutline) }), ' 预生产查询'] default: () => [h(NIcon, null, { default: () => h(EyeOutline) }), ' 预生产查询']
}) })
) )
@ -691,8 +659,29 @@ function handleGanttSchedule() {
router.push('/biz/orderProject/gantt') router.push('/biz/orderProject/gantt')
} }
async function reCrawlReorderForm(id:number,reCrawl:Boolean){
try {
const data = await orderProjectApi.getKingdeeOrder(id,{reCrawl:reCrawl})
kingdeeTableData.value = (Array.isArray(data) ? data : []).map((mo) => {
const { children, ...rest } = mo
const routes = [...(children ?? [])]
.sort((a, b) => (a.operNumber ?? 0) - (b.operNumber ?? 0))
.map((r) => normalizeKingdeeProcessRoute({
...r,
planStartTime: r.planStartTime ?? null,
planFinishTime: r.planFinishTime ?? null,
}))
return { ...rest, processRoutes: routes }
})
if (kingdeeTableData.value.length === 0) {
message.info('未查询到金蝶生产订单数据')
}
} finally {
kingdeeLoading.value = false
}
}
// //
async function handleKingdeeQuery(row: OrderProject) { async function handleKingdeeQuery(row: OrderProject,reCrawl:Boolean) {
if (!row.id) { if (!row.id) {
message.warning('缺少项目ID无法查询') message.warning('缺少项目ID无法查询')
return return
@ -703,70 +692,98 @@ async function handleKingdeeQuery(row: OrderProject) {
kingdeeLoading.value = true kingdeeLoading.value = true
kingdeeTableData.value = [] kingdeeTableData.value = []
kingdeeExpandedKeys.value = [] kingdeeExpandedKeys.value = []
try { reCrawlReorderForm(row.id,reCrawl)
const data = await orderProjectApi.getKingdeeOrder(row.id) // try {
kingdeeTableData.value = (Array.isArray(data) ? data : []).map((mo) => { // const data = await orderProjectApi.getKingdeeOrder(row.id)
const { children, ...rest } = mo // kingdeeTableData.value = (Array.isArray(data) ? data : []).map((mo) => {
const routes = [...(children ?? [])] // const { children, ...rest } = mo
.sort((a, b) => (a.operNumber ?? 0) - (b.operNumber ?? 0)) // const routes = [...(children ?? [])]
.map((r) => normalizeKingdeeProcessRoute({ // .sort((a, b) => (a.operNumber ?? 0) - (b.operNumber ?? 0))
...r, // .map((r) => normalizeKingdeeProcessRoute({
planStartTime: r.planStartTime ?? null, // ...r,
planFinishTime: r.planFinishTime ?? null, // planStartTime: r.planStartTime ?? null,
})) // planFinishTime: r.planFinishTime ?? null,
return { ...rest, processRoutes: routes } // }))
}) // return { ...rest, processRoutes: routes }
if (kingdeeTableData.value.length === 0) { // })
message.info('未查询到金蝶生产订单数据') // if (kingdeeTableData.value.length === 0) {
} // message.info('')
} finally { // }
kingdeeLoading.value = false // } finally {
} // kingdeeLoading.value = false
// }
} }
// 稿
async function handleSaveDraft() {
if (!kingdeeCurrentProjectId.value) return
kingdeeLoading.value = true // 稿
// async function holdTemporarilyCallback(id: number, data: KingdeePrdMo[]) {
// await orderProjectApi.saveKingdeeOrderDraft(id, data)
// }
// 稿
async function handleSaveDraft(id: number, data: KingdeePrdMo[]) {
try { try {
// processRoutes children // processRoutes children
const draftData = kingdeeTableData.value.map(mo => { await orderProjectApi.saveKingdeeOrderDraft(id, data)
const { processRoutes, ...rest } = mo
return { ...rest, children: processRoutes } as KingdeePrdMo
})
await orderProjectApi.saveKingdeeOrderDraft(kingdeeCurrentProjectId.value, draftData)
message.success('草稿保存成功')
} catch (error) { } catch (error) {
// //
} finally { }
kingdeeLoading.value = false
}
} }
// //
async function handleSyncOrderAndPlan() { async function handleSyncOrderAndPlan(id: number, data: KingdeePrdMo[]) {
if (!kingdeeCurrentProjectId.value) return
kingdeeLoading.value = true
try { try {
// processRoutes children // processRoutes children
const draftData = kingdeeTableData.value.map(mo => { await orderProjectApi.saveKingdeeOrderAndPlan(id, data)
const { processRoutes, ...rest } = mo
return { ...rest, children: processRoutes } as KingdeePrdMo
})
await orderProjectApi.saveKingdeeOrderAndPlan(kingdeeCurrentProjectId.value, draftData)
message.success('同步订单计划成功')
kingdeeModalVisible.value = false
} catch (error) { } catch (error) {
// //
} finally { }
kingdeeLoading.value = false
}
} }
// // 稿
// async function handleSaveDraft() {
// if (!kingdeeCurrentProjectId.value) return
// kingdeeLoading.value = true
// try {
// // processRoutes children
// const draftData = kingdeeTableData.value.map(mo => {
// const { processRoutes, ...rest } = mo
// return { ...rest, children: processRoutes } as KingdeePrdMo
// })
// await orderProjectApi.saveKingdeeOrderDraft(kingdeeCurrentProjectId.value, draftData)
// message.success('稿')
// } catch (error) {
// //
// } finally {
// kingdeeLoading.value = false
// }
// }
//
// async function handleSyncOrderAndPlan() {
// if (!kingdeeCurrentProjectId.value) return
// kingdeeLoading.value = true
// try {
// // processRoutes children
// const draftData = kingdeeTableData.value.map(mo => {
// const { processRoutes, ...rest } = mo
// return { ...rest, children: processRoutes } as KingdeePrdMo
// })
// await orderProjectApi.saveKingdeeOrderAndPlan(kingdeeCurrentProjectId.value, draftData)
// message.success('')
// kingdeeModalVisible.value = false
// } catch (error) {
// //
// } finally {
// kingdeeLoading.value = false
// }
// }
// //
function handleDelete(row: OrderProject) { function handleDelete(row: OrderProject) {
dialog.warning({ dialog.warning({