Compare commits
4 Commits
fa3a7599d0
...
0542bb739e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0542bb739e | ||
|
|
cb67fc53a2 | ||
|
|
ea5fcea2fb | ||
|
|
18b4399789 |
@ -45,6 +45,8 @@ export interface OrderItem {
|
|||||||
|
|
||||||
starter?: number
|
starter?: number
|
||||||
|
|
||||||
|
mainCode?: string
|
||||||
|
|
||||||
orderCode?: string
|
orderCode?: string
|
||||||
|
|
||||||
routeCode?: string
|
routeCode?: string
|
||||||
|
|||||||
@ -88,6 +88,12 @@ export interface ProcessPlanItemVO {
|
|||||||
|
|
||||||
planFinishTime?: string
|
planFinishTime?: string
|
||||||
|
|
||||||
|
/** 计划开始(部分接口直接返回 beginTime) */
|
||||||
|
beginTime?: string
|
||||||
|
|
||||||
|
/** 计划结束(部分接口直接返回 endTime) */
|
||||||
|
endTime?: string
|
||||||
|
|
||||||
actualStartTime?: string | null
|
actualStartTime?: string | null
|
||||||
|
|
||||||
actualFinishTime?: string | null
|
actualFinishTime?: string | null
|
||||||
@ -242,9 +248,9 @@ export function processItemToEntity(
|
|||||||
|
|
||||||
orderItemId,
|
orderItemId,
|
||||||
|
|
||||||
beginTime: item.planStartTime,
|
beginTime: item.planStartTime || item.beginTime,
|
||||||
|
|
||||||
endTime: item.planFinishTime,
|
endTime: item.planFinishTime || item.endTime,
|
||||||
|
|
||||||
procurement: item.procurement,
|
procurement: item.procurement,
|
||||||
|
|
||||||
|
|||||||
@ -89,6 +89,10 @@ export interface KingdeeProcessRoute {
|
|||||||
planStartTime: string | null
|
planStartTime: string | null
|
||||||
/** 计划结束时间 yyyy-MM-dd HH:mm:ss */
|
/** 计划结束时间 yyyy-MM-dd HH:mm:ss */
|
||||||
planFinishTime: string | null
|
planFinishTime: string | null
|
||||||
|
/** 是否质检 1是 0否(后端按控制码推导后返回) */
|
||||||
|
qualityInspection?: number | null
|
||||||
|
/** 是否入库 1是 0否(后端:仅末序为 1) */
|
||||||
|
storageEntry?: number | null
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 解析工序名称,兼容旧字段及后端误映射 */
|
/** 解析工序名称,兼容旧字段及后端误映射 */
|
||||||
|
|||||||
@ -1,4 +1,8 @@
|
|||||||
import { normalizeKingdeeProcessRoute, type KingdeePrdMo, type KingdeeProcessRoute } from '@/api/orderProject'
|
import {
|
||||||
|
normalizeKingdeeProcessRoute,
|
||||||
|
type KingdeePrdMo,
|
||||||
|
type KingdeeProcessRoute,
|
||||||
|
} from '@/api/orderProject'
|
||||||
|
|
||||||
export type KingdeeMoTableRow = Omit<KingdeePrdMo, 'children'> & { processRoutes: KingdeeProcessRoute[] }
|
export type KingdeeMoTableRow = Omit<KingdeePrdMo, 'children'> & { processRoutes: KingdeeProcessRoute[] }
|
||||||
|
|
||||||
@ -11,6 +15,9 @@ export function mapKingdeeMoListToTableRows(data: KingdeePrdMo[]): KingdeeMoTabl
|
|||||||
...r,
|
...r,
|
||||||
planStartTime: r.planStartTime ?? null,
|
planStartTime: r.planStartTime ?? null,
|
||||||
planFinishTime: r.planFinishTime ?? null,
|
planFinishTime: r.planFinishTime ?? null,
|
||||||
|
// 质检/入库由后端查询金蝶时已写入,前端原样带出
|
||||||
|
qualityInspection: r.qualityInspection ?? null,
|
||||||
|
storageEntry: r.storageEntry ?? null,
|
||||||
}))
|
}))
|
||||||
return { ...rest, processRoutes: routes }
|
return { ...rest, processRoutes: routes }
|
||||||
})
|
})
|
||||||
|
|||||||
@ -54,7 +54,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, h, computed, defineProps, onMounted, watch, defineEmits} from 'vue'
|
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 { NButton, NSpace, NIcon, NTag, NDatePicker, NDataTable, useMessage, useDialog, type DataTableColumns } from 'naive-ui'
|
||||||
import { type KingdeePrdMo, type KingdeeProcessRoute } from '@/api/orderProject'
|
import { type KingdeePrdMo, type KingdeeProcessRoute, resolveProcessName } from '@/api/orderProject'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { CalendarOutline } from '@vicons/ionicons5'
|
import { CalendarOutline } from '@vicons/ionicons5'
|
||||||
|
|
||||||
@ -72,20 +72,27 @@ const props = defineProps({
|
|||||||
selectedId:{
|
selectedId:{
|
||||||
type: Number,
|
type: Number,
|
||||||
default: null
|
default: null
|
||||||
|
},
|
||||||
|
/** 父页面查询/重读数据时的加载状态 */
|
||||||
|
loading: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
kingdeeTableData.value = props.kingdeeTableData as KingdeeMoTableRow[]
|
kingdeeTableData.value = (props.kingdeeTableData as KingdeeMoTableRow[]) || []
|
||||||
})
|
})
|
||||||
|
|
||||||
watch(()=>props.kingdeeTableData,()=>{
|
watch(() => props.kingdeeTableData, () => {
|
||||||
kingdeeTableData.value = props.kingdeeTableData as KingdeeMoTableRow[]
|
kingdeeTableData.value = (props.kingdeeTableData as KingdeeMoTableRow[]) || []
|
||||||
},{ deep: true } )
|
}, { deep: true })
|
||||||
|
|
||||||
|
|
||||||
const kingdeeModalVisible = ref(false)
|
const kingdeeModalVisible = ref(false)
|
||||||
const kingdeeLoading = ref(false)
|
/** 子组件自身操作(保存/同步)的加载状态 */
|
||||||
|
const actionLoading = ref(false)
|
||||||
|
/** 表格与按钮共用:父级查询 loading 或本地操作 loading */
|
||||||
|
const kingdeeLoading = computed(() => props.loading || actionLoading.value)
|
||||||
/** 主表行:工序仅存 processRoutes,避免 children 触发树形重复行 */
|
/** 主表行:工序仅存 processRoutes,避免 children 触发树形重复行 */
|
||||||
type KingdeeMoTableRow = Omit<KingdeePrdMo, 'children'> & { processRoutes: KingdeeProcessRoute[] }
|
type KingdeeMoTableRow = Omit<KingdeePrdMo, 'children'> & { processRoutes: KingdeeProcessRoute[] }
|
||||||
const kingdeeTableData = ref<KingdeeMoTableRow[]>([])
|
const kingdeeTableData = ref<KingdeeMoTableRow[]>([])
|
||||||
@ -93,7 +100,7 @@ const kingdeeExpandedKeys = ref<Array<string | number>>([])
|
|||||||
// const kingdeeCurrentProjectId = ref<number | null>(null) // 记录当前正在查询的订单ID
|
// const kingdeeCurrentProjectId = ref<number | null>(null) // 记录当前正在查询的订单ID
|
||||||
const kingdeeTableMaxHeight = 'min(78vh, 720px)'
|
const kingdeeTableMaxHeight = 'min(78vh, 720px)'
|
||||||
const kingdeeMoScrollX = 1820
|
const kingdeeMoScrollX = 1820
|
||||||
const kingdeeProcessScrollX = 1360
|
const kingdeeProcessScrollX = 1540
|
||||||
|
|
||||||
const kingdeeMoColumns: DataTableColumns<KingdeeMoTableRow> = [
|
const kingdeeMoColumns: DataTableColumns<KingdeeMoTableRow> = [
|
||||||
{
|
{
|
||||||
@ -155,7 +162,12 @@ const kingdeeProcessColumns: DataTableColumns<KingdeeProcessRoute> = [
|
|||||||
return row.operNumber != null ? String(row.operNumber) : '-'
|
return row.operNumber != null ? String(row.operNumber) : '-'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ title: '工序名称', key: 'processProperty', width: 100, align: 'center' },
|
{
|
||||||
|
title: '工序名称', key: 'processName', width: 100, align: 'center',
|
||||||
|
render(row) {
|
||||||
|
return resolveProcessName(row) || '-'
|
||||||
|
}
|
||||||
|
},
|
||||||
{ title: '工序说明', key: 'operDescription', width: 140, ellipsis: { tooltip: true } },
|
{ title: '工序说明', key: 'operDescription', width: 140, ellipsis: { tooltip: true } },
|
||||||
{ title: '工作中心', key: 'workCenterName', width: 110, align: 'center', 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: 'departmentName', width: 110, align: 'center', ellipsis: { tooltip: true } },
|
||||||
@ -179,6 +191,28 @@ const kingdeeProcessColumns: DataTableColumns<KingdeeProcessRoute> = [
|
|||||||
},
|
},
|
||||||
{ title: '活动单位', key: 'activityUnit', width: 80, align: 'center' },
|
{ title: '活动单位', key: 'activityUnit', width: 80, align: 'center' },
|
||||||
{ title: '控制码', key: 'optCtrlCodeName', width: 120, align: 'center', ellipsis: { tooltip: true } },
|
{ title: '控制码', key: 'optCtrlCodeName', width: 120, align: 'center', ellipsis: { tooltip: true } },
|
||||||
|
{
|
||||||
|
title: '是否质检', key: 'qualityInspection', width: 88, align: 'center',
|
||||||
|
render(row) {
|
||||||
|
const yes = Number(row.qualityInspection) === 1
|
||||||
|
return h(NTag, { size: 'small', type: yes ? 'success' : 'default', bordered: false }, {
|
||||||
|
default: () => (yes ? '是' : '否'),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '是否入库', key: 'storageEntry', width: 88, align: 'center',
|
||||||
|
render(row) {
|
||||||
|
const yes = Number(row.storageEntry) === 1
|
||||||
|
return h(NTag, {
|
||||||
|
size: 'small',
|
||||||
|
type: yes ? 'warning' : 'default',
|
||||||
|
bordered: false,
|
||||||
|
}, {
|
||||||
|
default: () => (yes ? '是' : '否'),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@ -302,7 +336,7 @@ function handleGanttSchedule() {
|
|||||||
async function handleSyncOrderAndPlan() {
|
async function handleSyncOrderAndPlan() {
|
||||||
if (!props.selectedId) return
|
if (!props.selectedId) return
|
||||||
|
|
||||||
kingdeeLoading.value = true
|
actionLoading.value = true
|
||||||
try {
|
try {
|
||||||
// 恢复数据结构,将 processRoutes 转换为 children
|
// 恢复数据结构,将 processRoutes 转换为 children
|
||||||
const draftData = kingdeeTableData.value.map(mo => {
|
const draftData = kingdeeTableData.value.map(mo => {
|
||||||
@ -320,7 +354,7 @@ async function handleSyncOrderAndPlan() {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
// 错误拦截器已处理
|
// 错误拦截器已处理
|
||||||
} finally {
|
} finally {
|
||||||
kingdeeLoading.value = false
|
actionLoading.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -336,15 +370,8 @@ const reCrawlReorderForm = () => {
|
|||||||
positiveText: '确定',
|
positiveText: '确定',
|
||||||
negativeText: '取消',
|
negativeText: '取消',
|
||||||
onPositiveClick: () => {
|
onPositiveClick: () => {
|
||||||
kingdeeLoading.value = true
|
// 加载态由父组件 reCrawlReorderForm 的 kingdeeLoading 控制
|
||||||
try {
|
|
||||||
emit('reCrawlCallback', props.selectedId, true)
|
emit('reCrawlCallback', props.selectedId, true)
|
||||||
message.success('重启读取成功')
|
|
||||||
} catch (error) {
|
|
||||||
// 错误拦截器已处理
|
|
||||||
} finally {
|
|
||||||
kingdeeLoading.value = false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -356,7 +383,7 @@ const handleSaveDraft = () => {
|
|||||||
// // 暂存金蝶生产订单数据(草稿)
|
// // 暂存金蝶生产订单数据(草稿)
|
||||||
if (!props.selectedId) return
|
if (!props.selectedId) return
|
||||||
|
|
||||||
kingdeeLoading.value = true
|
actionLoading.value = true
|
||||||
try {
|
try {
|
||||||
const draftData = kingdeeTableData.value.map(mo => {
|
const draftData = kingdeeTableData.value.map(mo => {
|
||||||
const { processRoutes, ...rest } = mo
|
const { processRoutes, ...rest } = mo
|
||||||
@ -367,7 +394,7 @@ const handleSaveDraft = () => {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
// 错误拦截器已处理
|
// 错误拦截器已处理
|
||||||
} finally {
|
} finally {
|
||||||
kingdeeLoading.value = false
|
actionLoading.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,9 @@
|
|||||||
<!-- 搜索表单 -->
|
<!-- 搜索表单 -->
|
||||||
<div class="search-form">
|
<div class="search-form">
|
||||||
<n-form inline :model="searchForm" label-placement="left">
|
<n-form inline :model="searchForm" label-placement="left">
|
||||||
|
<n-form-item label="生产令号">
|
||||||
|
<n-input v-model:value="searchForm.productionCode" placeholder="请输入生产令号" clearable />
|
||||||
|
</n-form-item>
|
||||||
<n-form-item label="物料编码">
|
<n-form-item label="物料编码">
|
||||||
<n-input v-model:value="searchForm.code" placeholder="请输入物料编码" clearable />
|
<n-input v-model:value="searchForm.code" placeholder="请输入物料编码" clearable />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
@ -371,6 +374,7 @@
|
|||||||
<KingdeeVue
|
<KingdeeVue
|
||||||
:kingdeeTableData="kingdeeTableData"
|
:kingdeeTableData="kingdeeTableData"
|
||||||
:selectedId="kingdeeOrderOtemId"
|
:selectedId="kingdeeOrderOtemId"
|
||||||
|
:loading="kingdeeLoading"
|
||||||
@close-modal="kingdeeModalVisible = false"
|
@close-modal="kingdeeModalVisible = false"
|
||||||
@holdTemporarilyCallback="holdTemporarilySave"
|
@holdTemporarilyCallback="holdTemporarilySave"
|
||||||
@synchronizationCallback="synchronizationSave"
|
@synchronizationCallback="synchronizationSave"
|
||||||
@ -381,16 +385,18 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive, h, onMounted } from 'vue'
|
import { ref, reactive, h, computed, onMounted } from 'vue'
|
||||||
import { NButton, NSpace, NIcon, useMessage, useDialog, type UploadCustomRequestOptions} from 'naive-ui'
|
import { NButton, NSpace, NIcon, NTag, useMessage, useDialog, type UploadCustomRequestOptions} from 'naive-ui'
|
||||||
import { orderItemApi, type OrderItem } from '@/api/orderItem'
|
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 KingdeeVue from '@/views/biz/kingdee/index.vue'
|
import KingdeeVue from '@/views/biz/kingdee/index.vue'
|
||||||
|
|
||||||
import { type KingdeePrdMo, type KingdeeProcessRoute } from '@/api/orderProject'
|
import { type KingdeePrdMo } from '@/api/orderProject'
|
||||||
|
import { mapKingdeeMoListToTableRows, type KingdeeMoTableRow } from '@/utils/kingdeeSchedule'
|
||||||
import { userApi } from '@/api/system'
|
import { userApi } from '@/api/system'
|
||||||
|
import { dictDataApi } from '@/api/org'
|
||||||
|
|
||||||
const message = useMessage()
|
const message = useMessage()
|
||||||
const dialog = useDialog()
|
const dialog = useDialog()
|
||||||
@ -407,6 +413,7 @@ const hasPermission = (permission: string) => userStore.hasPermission(permission
|
|||||||
|
|
||||||
// 搜索表单
|
// 搜索表单
|
||||||
const searchForm = reactive<any>({
|
const searchForm = reactive<any>({
|
||||||
|
productionCode: '',
|
||||||
code: '',
|
code: '',
|
||||||
projectName: '',
|
projectName: '',
|
||||||
orderCode: '',
|
orderCode: '',
|
||||||
@ -466,25 +473,30 @@ const defaultFormData = {
|
|||||||
const formData = reactive<any>({ ...defaultFormData })
|
const formData = reactive<any>({ ...defaultFormData })
|
||||||
|
|
||||||
// 字典选项(下拉框/单选框/复选框关联字典时使用)
|
// 字典选项(下拉框/单选框/复选框关联字典时使用)
|
||||||
|
const workshopList = ref<{ label: string; value: any; class: any }[]>([])
|
||||||
|
|
||||||
// 表单校验规则
|
// 表单校验规则
|
||||||
const formRules = {
|
const formRules = {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 表格列
|
// 表格列(computed:字典异步加载后能触发表格重渲染)
|
||||||
const columns = [
|
const columns = computed(() => [
|
||||||
{
|
{
|
||||||
type: 'selection'
|
type: 'selection'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align:'center',
|
align:'center',
|
||||||
title: '产品名称',
|
title: '生产令号',
|
||||||
key: 'projectName',
|
key: 'productionCode',
|
||||||
// ellipsis: {
|
width: '140'
|
||||||
// tooltip: true
|
|
||||||
// }
|
|
||||||
minWidth: 150,
|
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
align:'center',
|
||||||
|
title: '订单编号',
|
||||||
|
key: 'orderCode',
|
||||||
|
width:"120"
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
align:'center',
|
align:'center',
|
||||||
title: '物料名称',
|
title: '物料名称',
|
||||||
@ -497,12 +509,7 @@ const columns = [
|
|||||||
key: 'code',
|
key: 'code',
|
||||||
width:"120"
|
width:"120"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
align:'center',
|
|
||||||
title: '订单编号',
|
|
||||||
key: 'orderCode',
|
|
||||||
width:"120"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
align:'center',
|
align:'center',
|
||||||
title: '工艺路线编码',
|
title: '工艺路线编码',
|
||||||
@ -513,43 +520,58 @@ const columns = [
|
|||||||
align:'center',
|
align:'center',
|
||||||
title: '生产车间',
|
title: '生产车间',
|
||||||
key: 'proWorkshop',
|
key: 'proWorkshop',
|
||||||
width:"120"
|
width:"120",
|
||||||
},
|
render(row: any) {
|
||||||
{
|
const val = row.proWorkshop
|
||||||
align:'center',
|
// 兼容存 dictValue 或车间名称(金蝶同步写入的是 WorkShopName)
|
||||||
title: '产品序列',
|
const opt = workshopList.value.find(o =>
|
||||||
key: 'sort',
|
o.value === val ||
|
||||||
width:"120"
|
String(o.value) === String(val) ||
|
||||||
|
o.label === val ||
|
||||||
|
String(o.label) === String(val)
|
||||||
|
)
|
||||||
|
if (!opt) return val ?? '-'
|
||||||
|
const tagType = opt.class && ['default', 'primary', 'info', 'success', 'warning', 'error'].includes(opt.class)
|
||||||
|
? opt.class
|
||||||
|
: 'info'
|
||||||
|
return h(NTag, { type: tagType, size: 'small' }, { default: () => opt.label })
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
// {
|
||||||
|
// align:'center',
|
||||||
|
// title: '产品序列',
|
||||||
|
// key: 'sort',
|
||||||
|
// width:"120"
|
||||||
|
// },
|
||||||
{
|
{
|
||||||
align:'center',
|
align:'center',
|
||||||
title: '生产数量',
|
title: '生产数量',
|
||||||
key: 'quantity',
|
key: 'quantity',
|
||||||
width:"120"
|
width:"120"
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
align:'center',
|
// align:'center',
|
||||||
title: '是否半成品',
|
// title: '是否半成品',
|
||||||
key: 'sfProduct',
|
// key: 'sfProduct',
|
||||||
width:"120"
|
// width:"120"
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
align:'center',
|
// align:'center',
|
||||||
title: '是否采购',
|
// title: '是否采购',
|
||||||
key: 'procurement',
|
// key: 'procurement',
|
||||||
width:"120"
|
// width:"120"
|
||||||
},
|
// },
|
||||||
{
|
{
|
||||||
align:'center',
|
align:'center',
|
||||||
title: '开始时间',
|
title: '开始时间',
|
||||||
key: 'beginTime',
|
key: 'beginTime',
|
||||||
width:"120"
|
width:"160"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align:'center',
|
align:'center',
|
||||||
title: '结束时间',
|
title: '结束时间',
|
||||||
key: 'endTime',
|
key: 'endTime',
|
||||||
width:"120"
|
width:"160"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align:'center',
|
align:'center',
|
||||||
@ -612,15 +634,15 @@ const columns = [
|
|||||||
{ default: () => '编辑'}
|
{ default: () => '编辑'}
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
if(hasPermission('biz:orderItem:assign')){
|
// if(hasPermission('biz:orderItem:assign')){
|
||||||
buttons.push(h(NButton, {
|
// buttons.push(h(NButton, {
|
||||||
size: 'small',
|
// size: 'small',
|
||||||
type:'success',
|
// type:'success',
|
||||||
ghost:true,
|
// ghost:true,
|
||||||
onClick: () => { disphand(row) } },
|
// onClick: () => { disphand(row) } },
|
||||||
{ default: () => '派工'}
|
// { default: () => '派工'}
|
||||||
))
|
// ))
|
||||||
}
|
// }
|
||||||
if(hasPermission('biz:orderItem:reorderForm')){
|
if(hasPermission('biz:orderItem:reorderForm')){
|
||||||
buttons.push(h(NButton, {
|
buttons.push(h(NButton, {
|
||||||
size: 'small',
|
size: 'small',
|
||||||
@ -644,7 +666,7 @@ const columns = [
|
|||||||
// ])
|
// ])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
])
|
||||||
|
|
||||||
//根据内容设置表格滚动条
|
//根据内容设置表格滚动条
|
||||||
let scrollX = ref(0)
|
let scrollX = ref(0)
|
||||||
@ -666,6 +688,7 @@ async function loadData() {
|
|||||||
const res = await orderItemApi.page({
|
const res = await orderItemApi.page({
|
||||||
page: pagination.page,
|
page: pagination.page,
|
||||||
pageSize: pagination.pageSize,
|
pageSize: pagination.pageSize,
|
||||||
|
productionCode: searchForm.productionCode || undefined,
|
||||||
code: searchForm.code,
|
code: searchForm.code,
|
||||||
projectName: searchForm.projectName,
|
projectName: searchForm.projectName,
|
||||||
orderCode: searchForm.orderCode,
|
orderCode: searchForm.orderCode,
|
||||||
@ -689,6 +712,7 @@ function handleSearch() {
|
|||||||
|
|
||||||
// 重置
|
// 重置
|
||||||
function handleReset() {
|
function handleReset() {
|
||||||
|
searchForm.productionCode = ''
|
||||||
searchForm.code = ''
|
searchForm.code = ''
|
||||||
searchForm.projectName = ''
|
searchForm.projectName = ''
|
||||||
searchForm.orderCode = ''
|
searchForm.orderCode = ''
|
||||||
@ -800,22 +824,14 @@ const kingdeeModalVisible = ref(false)
|
|||||||
const kingdeeModalTitle = ref('金蝶生产订单')
|
const kingdeeModalTitle = ref('金蝶生产订单')
|
||||||
const kingdeeLoading = ref(false)
|
const kingdeeLoading = ref(false)
|
||||||
|
|
||||||
type KingdeeMoTableRow = Omit<KingdeePrdMo, 'children'> & { processRoutes: KingdeeProcessRoute[] }
|
|
||||||
const kingdeeTableData = ref<KingdeeMoTableRow[]>([])
|
const kingdeeTableData = ref<KingdeeMoTableRow[]>([])
|
||||||
// const kingdeeExpandedKeys = ref<Array<string | number>>([])
|
// const kingdeeExpandedKeys = ref<Array<string | number>>([])
|
||||||
|
|
||||||
async function reCrawlReorderForm(id:number,reCrawl:Boolean){
|
async function reCrawlReorderForm(id:number,reCrawl:Boolean){
|
||||||
|
kingdeeLoading.value = true
|
||||||
try {
|
try {
|
||||||
const data = await orderItemApi.preCreationInfo(id, {reCrawl:reCrawl})
|
const data = await orderItemApi.preCreationInfo(id, {reCrawl:reCrawl})
|
||||||
kingdeeTableData.value = (Array.isArray(data) ? data : []).map((mo) => {
|
kingdeeTableData.value = mapKingdeeMoListToTableRows(Array.isArray(data) ? data : [])
|
||||||
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 {
|
} finally {
|
||||||
kingdeeLoading.value = false
|
kingdeeLoading.value = false
|
||||||
}
|
}
|
||||||
@ -829,9 +845,8 @@ async function handleReorderForm(row:OrderItem, reCrawl:Boolean){
|
|||||||
kingdeeOrderOtemId.value = row.id
|
kingdeeOrderOtemId.value = row.id
|
||||||
kingdeeModalTitle.value = `金蝶生产订单${row.code ? ` - ${row.code}` : ''}`
|
kingdeeModalTitle.value = `金蝶生产订单${row.code ? ` - ${row.code}` : ''}`
|
||||||
kingdeeModalVisible.value = true
|
kingdeeModalVisible.value = true
|
||||||
kingdeeLoading.value = true
|
kingdeeTableData.value = []
|
||||||
reCrawlReorderForm(row.id, false)
|
await reCrawlReorderForm(row.id, reCrawl)
|
||||||
kingdeeLoading.value = false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 暂存金蝶生产订单数据(草稿)
|
// 暂存金蝶生产订单数据(草稿)
|
||||||
@ -1102,6 +1117,7 @@ async function handleExport() {
|
|||||||
try {
|
try {
|
||||||
const params: Record<string, any> = {}
|
const params: Record<string, any> = {}
|
||||||
if (selectedIds.value.length > 0) params.ids = selectedIds.value
|
if (selectedIds.value.length > 0) params.ids = selectedIds.value
|
||||||
|
if (searchForm.productionCode) params.productionCode = searchForm.productionCode
|
||||||
if (searchForm.code) params.code = searchForm.code
|
if (searchForm.code) params.code = searchForm.code
|
||||||
if (searchForm.projectName) params.projectName = searchForm.projectName
|
if (searchForm.projectName) params.projectName = searchForm.projectName
|
||||||
if (searchForm.orderCode) params.orderCode = searchForm.orderCode
|
if (searchForm.orderCode) params.orderCode = searchForm.orderCode
|
||||||
@ -1159,6 +1175,10 @@ async function handleImportUpload({ file }: UploadCustomRequestOptions) {
|
|||||||
|
|
||||||
// 加载字典选项
|
// 加载字典选项
|
||||||
async function loadDictOptions() {
|
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 }))
|
||||||
|
} catch {}
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
|||||||
@ -190,6 +190,11 @@
|
|||||||
v-for="(proc, idx) in sortedProcessList(order.processList)"
|
v-for="(proc, idx) in sortedProcessList(order.processList)"
|
||||||
:key="proc.planId ?? idx"
|
:key="proc.planId ?? idx"
|
||||||
:process="proc"
|
: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"
|
:is-last="idx === (order.processList?.length ?? 0) - 1"
|
||||||
:can-edit="hasPermission('biz:orderItem:edit')"
|
:can-edit="hasPermission('biz:orderItem:edit')"
|
||||||
:can-assign="hasPermission('biz:orderItem:assign')"
|
:can-assign="hasPermission('biz:orderItem:assign')"
|
||||||
@ -246,6 +251,11 @@
|
|||||||
v-for="(proc, idx) in (detailData.processList)"
|
v-for="(proc, idx) in (detailData.processList)"
|
||||||
:key="proc.planId ?? idx"
|
:key="proc.planId ?? idx"
|
||||||
:process="proc"
|
: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"
|
:is-last="idx === (detailData.processList?.length ?? 0) - 1"
|
||||||
:can-edit="hasPermission('biz:orderItem:edit')"
|
:can-edit="hasPermission('biz:orderItem:edit')"
|
||||||
:can-assign="hasPermission('biz:orderItem:assign')"
|
:can-assign="hasPermission('biz:orderItem:assign')"
|
||||||
@ -329,6 +339,16 @@
|
|||||||
<span>{{dispatchform.quantity}}</span>
|
<span>{{dispatchform.quantity}}</span>
|
||||||
</n-gi>
|
</n-gi>
|
||||||
</n-grid>
|
</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-grid :cols="2">
|
||||||
<n-gi>
|
<n-gi>
|
||||||
<span class="pgClass">开始时间:</span>
|
<span class="pgClass">开始时间:</span>
|
||||||
@ -628,7 +648,7 @@ const dispatchmodal = ref(false)
|
|||||||
const dispatchLoading = ref(false)
|
const dispatchLoading = ref(false)
|
||||||
const dispatchformRef = ref()
|
const dispatchformRef = ref()
|
||||||
const dispatchform = reactive<any>({
|
const dispatchform = reactive<any>({
|
||||||
id: '', name: '', beginTime: '', endTime: '', quantity: '',workCenterName:'',proWorkshop:'',
|
id: '', name: '', beginTime: '', endTime: '', quantity: '',workCenterName:'',
|
||||||
list: [{ sectionId:'',deviceId:'', quantity: '' }],
|
list: [{ sectionId:'',deviceId:'', quantity: '' }],
|
||||||
})
|
})
|
||||||
const dispatchrules = {}
|
const dispatchrules = {}
|
||||||
@ -1063,13 +1083,20 @@ async function handleSubmit() {
|
|||||||
function disphand(process: ProcessPlanItemVO, order?: OrderProcessPlanVO) {
|
function disphand(process: ProcessPlanItemVO, order?: OrderProcessPlanVO) {
|
||||||
const entity = processItemToEntity(process, order?.orderItemId,order?.proWorkshop)
|
const entity = processItemToEntity(process, order?.orderItemId,order?.proWorkshop)
|
||||||
|
|
||||||
|
const planQty = Number(entity.quantity) || 0
|
||||||
|
const completedQty = Number(process.completedQty) || 0
|
||||||
|
const remainQty = Math.max(0, planQty - completedQty)
|
||||||
dispatchmodal.value = true
|
dispatchmodal.value = true
|
||||||
dispatchformRef.value?.restoreValidation()
|
dispatchformRef.value?.restoreValidation()
|
||||||
dispatchform.id = entity.id
|
dispatchform.id = entity.id
|
||||||
dispatchform.name = entity.name
|
dispatchform.name = entity.name
|
||||||
dispatchform.beginTime = entity.beginTime
|
// 工序计划时间优先,没有则用订单头 beginTime/endTime
|
||||||
dispatchform.endTime = entity.endTime
|
dispatchform.beginTime = entity.beginTime || order?.beginTime || ''
|
||||||
|
dispatchform.endTime = entity.endTime || order?.endTime || ''
|
||||||
|
// quantity 保持工序计划总数,提交时不能改掉计划数量
|
||||||
dispatchform.quantity = entity.quantity
|
dispatchform.quantity = entity.quantity
|
||||||
|
dispatchform.completedQty = completedQty
|
||||||
|
dispatchform.remainQty = remainQty
|
||||||
dispatchform.orderItemId = entity.orderItemId
|
dispatchform.orderItemId = entity.orderItemId
|
||||||
dispatchform.sort = entity.sort
|
dispatchform.sort = entity.sort
|
||||||
dispatchform.workCenterName = entity.workCenterName
|
dispatchform.workCenterName = entity.workCenterName
|
||||||
@ -1079,10 +1106,11 @@ function disphand(process: ProcessPlanItemVO, order?: OrderProcessPlanVO) {
|
|||||||
console.log(dispatchform)
|
console.log(dispatchform)
|
||||||
|
|
||||||
|
|
||||||
|
dispatchform.list = [{ sectionId: '', deviceId: '', userList: '', quantity: remainQty || '' }]
|
||||||
}
|
}
|
||||||
|
|
||||||
function addpgnum() {
|
function addpgnum() {
|
||||||
dispatchform.list.push({ sectionId:'',deviceId:'', quantity: '' })
|
dispatchform.list.push({ sectionId: '', deviceId: '', userList: '', quantity: '' })
|
||||||
}
|
}
|
||||||
|
|
||||||
function deletenum(index: number) {
|
function deletenum(index: number) {
|
||||||
@ -1094,15 +1122,24 @@ function dispatchSubmit() {
|
|||||||
dispatchform.list.forEach((n: any) => {
|
dispatchform.list.forEach((n: any) => {
|
||||||
total += Number(n.quantity) || 0
|
total += Number(n.quantity) || 0
|
||||||
})
|
})
|
||||||
|
const remainQty = Number(dispatchform.remainQty)
|
||||||
|
if (remainQty <= 0) {
|
||||||
|
message.warning('当前工序已全部完成,无需再派工')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
dispatchformRef.value?.validate((v: boolean) => {
|
dispatchformRef.value?.validate((errors: any) => {
|
||||||
if (v) return
|
// Naive UI:有 errors 表示校验失败
|
||||||
if (total !== Number(dispatchform.quantity)) {
|
if (errors) return
|
||||||
message.error('派工总数量需等于生产总数', { duration: 4000 })
|
if (total !== remainQty) {
|
||||||
|
message.error(`派工总数量需等于待派数量 ${remainQty}(计划 ${dispatchform.quantity},已完成 ${dispatchform.completedQty ?? 0})`, {
|
||||||
|
duration: 4000,
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatchLoading.value = true
|
dispatchLoading.value = true
|
||||||
|
// 提交时 quantity 仍传计划总数,避免把工序计划数量改成待派数
|
||||||
orderProcessPlanApi.assignWork(dispatchform).then(() => {
|
orderProcessPlanApi.assignWork(dispatchform).then(() => {
|
||||||
message.success('派工成功')
|
message.success('派工成功')
|
||||||
dispatchmodal.value = false
|
dispatchmodal.value = false
|
||||||
|
|||||||
@ -2,7 +2,13 @@
|
|||||||
<div class="process-card-wrap">
|
<div class="process-card-wrap">
|
||||||
<div class="process-card" :class="themeClass">
|
<div class="process-card" :class="themeClass">
|
||||||
<div class="card-head">
|
<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>
|
<n-tag size="small" :bordered="false" :type="statusTag.type">{{ statusTag.label }}</n-tag>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -39,22 +45,28 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card-flow">
|
<div class="card-flow">
|
||||||
|
<div class="flow-item">
|
||||||
|
<span>转入</span>
|
||||||
|
<strong>{{ process.transferInQty ?? 0 }}</strong>
|
||||||
|
</div>
|
||||||
<div class="flow-item">
|
<div class="flow-item">
|
||||||
<span>剩余物料</span>
|
<span>剩余物料</span>
|
||||||
<strong>{{ remainQty }}</strong>
|
<strong>{{ remainQty }}</strong>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flow-item">
|
<div class="flow-item">
|
||||||
<span>转下道</span>
|
<span>转出</span>
|
||||||
<strong>{{ process.transferOutQty ?? 0 }}</strong>
|
<strong>{{ process.transferOutQty ?? 0 }}</strong>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card-meta">
|
<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>{{ process.workOrderCode || '-' }}</em></div>
|
||||||
<div class="meta-line"><span>人员</span><em>{{ personnel }}</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>{{ 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>{{ planTimeText }}</em></div>
|
||||||
<div class="meta-line"><span>实际开始</span><em>{{ process.actualStartTime || '-' }}</em></div>
|
<div class="meta-line"><span>实际开始</span><em>{{ process.actualStartTime || '-' }}</em></div>
|
||||||
</div>
|
</div>
|
||||||
@ -110,6 +122,16 @@ import { PROCESS_STATUS_MAP, type ProcessPlanItemVO } from '@/api/orderProcessPl
|
|||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
process: ProcessPlanItemVO
|
process: ProcessPlanItemVO
|
||||||
|
/** 物料编码(订单头) */
|
||||||
|
materialCode?: string
|
||||||
|
/** 生产订单编号(订单头 orderCode) */
|
||||||
|
orderCode?: string
|
||||||
|
/** 订单计划开始(订单头 beginTime,工序无计划时间时回退) */
|
||||||
|
orderBeginTime?: string
|
||||||
|
/** 订单计划结束(订单头 endTime) */
|
||||||
|
orderEndTime?: string
|
||||||
|
/** 生产车间(订单头 proWorkshop) */
|
||||||
|
proWorkshop?: string
|
||||||
isLast?: boolean
|
isLast?: boolean
|
||||||
canEdit?: boolean
|
canEdit?: boolean
|
||||||
canAssign?: boolean
|
canAssign?: boolean
|
||||||
@ -171,15 +193,39 @@ const railColor = computed(() => {
|
|||||||
const personnel = computed(() => {
|
const personnel = computed(() => {
|
||||||
if (props.process.assignByName) return props.process.assignByName
|
if (props.process.assignByName) return props.process.assignByName
|
||||||
const list = props.process.assignWorkList
|
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 '-'
|
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 planTimeText = computed(() => {
|
||||||
const start = props.process.planStartTime
|
// 工序计划时间优先;没有则回退订单头 beginTime/endTime
|
||||||
const end = props.process.planFinishTime
|
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 '-'
|
||||||
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 || '-'
|
return start || end || '-'
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
@ -252,6 +298,29 @@ const planTimeText = computed(() => {
|
|||||||
white-space: nowrap;
|
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 {
|
.card-progress {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|||||||
@ -233,6 +233,16 @@
|
|||||||
<n-input v-model:value="dispatchform.quantity" disabled />
|
<n-input v-model:value="dispatchform.quantity" disabled />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
</n-gi>
|
</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-gi>
|
||||||
<n-form-item label="开始时间">
|
<n-form-item label="开始时间">
|
||||||
<n-input v-model:value="dispatchform.beginTime" disabled />
|
<n-input v-model:value="dispatchform.beginTime" disabled />
|
||||||
@ -816,6 +826,8 @@ let dispatchform = reactive<any>({
|
|||||||
endTime:'',
|
endTime:'',
|
||||||
userid:'',
|
userid:'',
|
||||||
quantity:'',
|
quantity:'',
|
||||||
|
completedQty: 0,
|
||||||
|
remainQty: 0,
|
||||||
list:[{
|
list:[{
|
||||||
userId:'',
|
userId:'',
|
||||||
quantity:''
|
quantity:''
|
||||||
@ -866,17 +878,22 @@ function deletenum(index:any) {
|
|||||||
|
|
||||||
function disphand(process: ProcessPlanItemVO, order?: OrderProcessPlanVO) {
|
function disphand(process: ProcessPlanItemVO, order?: OrderProcessPlanVO) {
|
||||||
const entity = processItemToEntity(process, order?.orderItemId)
|
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
|
dispatchmodal.value = true
|
||||||
dispatchformRef.value?.restoreValidation()
|
dispatchformRef.value?.restoreValidation()
|
||||||
dispatchform.id = entity.id
|
dispatchform.id = entity.id
|
||||||
dispatchform.name = entity.name
|
dispatchform.name = entity.name
|
||||||
dispatchform.beginTime = entity.beginTime
|
dispatchform.beginTime = entity.beginTime || order?.beginTime || ''
|
||||||
dispatchform.endTime = entity.endTime
|
dispatchform.endTime = entity.endTime || order?.endTime || ''
|
||||||
dispatchform.quantity = entity.quantity
|
dispatchform.quantity = entity.quantity
|
||||||
|
dispatchform.completedQty = completedQty
|
||||||
|
dispatchform.remainQty = remainQty
|
||||||
dispatchform.userid = ''
|
dispatchform.userid = ''
|
||||||
dispatchform.list = [{
|
dispatchform.list = [{
|
||||||
userId: '',
|
userId: '',
|
||||||
quantity: '',
|
quantity: remainQty || '',
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -885,10 +902,15 @@ function dispatchSubmit() {
|
|||||||
dispatchform.list.forEach((n:any) => {
|
dispatchform.list.forEach((n:any) => {
|
||||||
total = n.quantity*1+total
|
total = n.quantity*1+total
|
||||||
})
|
})
|
||||||
|
const remainQty = Number(dispatchform.remainQty)
|
||||||
|
if (remainQty <= 0) {
|
||||||
|
message.warning('当前工序已全部完成,无需再派工')
|
||||||
|
return
|
||||||
|
}
|
||||||
dispatchformRef.value?.validate((v:any) => {
|
dispatchformRef.value?.validate((v:any) => {
|
||||||
if(!v){
|
if(!v){
|
||||||
if(total != dispatchform.quantity){
|
if(total != remainQty){
|
||||||
message.error('派工总数量需等于生产总数',{
|
message.error(`派工总数量需等于待派数量 ${remainQty}(计划 ${dispatchform.quantity},已完成 ${dispatchform.completedQty ?? 0})`,{
|
||||||
duration:4000
|
duration:4000
|
||||||
})
|
})
|
||||||
}else{
|
}else{
|
||||||
|
|||||||
@ -151,6 +151,7 @@
|
|||||||
<KingdeeVue
|
<KingdeeVue
|
||||||
:kingdeeTableData="kingdeeTableData"
|
:kingdeeTableData="kingdeeTableData"
|
||||||
:selectedId="kingdeeCurrentProjectId"
|
:selectedId="kingdeeCurrentProjectId"
|
||||||
|
:loading="kingdeeLoading"
|
||||||
@close-modal="kingdeeModalVisible = false"
|
@close-modal="kingdeeModalVisible = false"
|
||||||
@holdTemporarilyCallback="handleSaveDraft"
|
@holdTemporarilyCallback="handleSaveDraft"
|
||||||
@synchronizationCallback="handleSyncOrderAndPlan"
|
@synchronizationCallback="handleSyncOrderAndPlan"
|
||||||
@ -194,7 +195,8 @@
|
|||||||
import { ref, reactive, h, computed, onMounted, watch } from 'vue'
|
import { ref, reactive, h, computed, onMounted, watch } from 'vue'
|
||||||
import { NButton, NSpace, NIcon, NTag, NDatePicker, NDataTable, NUpload, useMessage, useDialog, type DataTableColumns, type UploadCustomRequestOptions } from 'naive-ui'
|
import { NButton, NSpace, NIcon, NTag, NDatePicker, NDataTable, NUpload, useMessage, useDialog, type DataTableColumns, type UploadCustomRequestOptions } from 'naive-ui'
|
||||||
import { SearchOutline, RefreshOutline, AddOutline, TrashOutline, CreateOutline, CloudUploadOutline, DownloadOutline, EyeOutline, CalendarOutline } from '@vicons/ionicons5'
|
import { SearchOutline, RefreshOutline, AddOutline, TrashOutline, CreateOutline, CloudUploadOutline, DownloadOutline, EyeOutline, CalendarOutline } from '@vicons/ionicons5'
|
||||||
import { orderProjectApi, type OrderProject, type KingdeePrdMo, type KingdeeProcessRoute, normalizeKingdeeProcessRoute } from '@/api/orderProject'
|
import { orderProjectApi, type OrderProject, type KingdeePrdMo, type KingdeeProcessRoute } from '@/api/orderProject'
|
||||||
|
import { mapKingdeeMoListToTableRows } from '@/utils/kingdeeSchedule'
|
||||||
import { dictDataApi } from '@/api/org'
|
import { dictDataApi } from '@/api/org'
|
||||||
import { useUserStore } from '@/stores/user'
|
import { useUserStore } from '@/stores/user'
|
||||||
|
|
||||||
@ -660,21 +662,14 @@ function handleGanttSchedule() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function reCrawlReorderForm(id:number,reCrawl:Boolean){
|
async function reCrawlReorderForm(id:number,reCrawl:Boolean){
|
||||||
|
kingdeeLoading.value = true
|
||||||
try {
|
try {
|
||||||
const data = await orderProjectApi.getKingdeeOrder(id,{reCrawl:reCrawl})
|
const data = await orderProjectApi.getKingdeeOrder(id,{reCrawl:reCrawl})
|
||||||
kingdeeTableData.value = (Array.isArray(data) ? data : []).map((mo) => {
|
kingdeeTableData.value = mapKingdeeMoListToTableRows(Array.isArray(data) ? data : [])
|
||||||
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) {
|
if (kingdeeTableData.value.length === 0) {
|
||||||
message.info('未查询到金蝶生产订单数据')
|
message.info('未查询到金蝶生产订单数据')
|
||||||
|
} else if (reCrawl) {
|
||||||
|
message.success('重新读取成功')
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
kingdeeLoading.value = false
|
kingdeeLoading.value = false
|
||||||
|
|||||||
@ -20,7 +20,8 @@ export default defineConfig({
|
|||||||
port: 3000,
|
port: 3000,
|
||||||
proxy: {
|
proxy: {
|
||||||
'/api': {
|
'/api': {
|
||||||
target:'http://192.168.12.4:8888/',
|
target:'http://192.168.12.12:8888/', //'http://192.168.5.230:8888',
|
||||||
|
//target:'http://192.168.12.4:8888/',
|
||||||
//target:'http://192.168.12.230:8888',
|
//target:'http://192.168.12.230:8888',
|
||||||
//target:'http://192.168.5.230:8888',
|
//target:'http://192.168.5.230:8888',
|
||||||
//target:'http://192.168.5.232:8888/',
|
//target:'http://192.168.5.232:8888/',
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user