feat(mes): 新增工单类型过滤和批次编码处理逻辑

在生产工单精简列表接口中新增工单类型参数,支持根据工单类型过滤工单列表。同时,在外协发料单行的创建和更新中,新增批次编码字段,并实现根据批次编码自动解析批次 ID 的功能,提升数据处理的灵活性和准确性。
pull/871/MERGE
YunaiV 2026-03-31 23:22:23 +08:00
parent 8effbce819
commit ffb833d822
6 changed files with 136 additions and 40 deletions

View File

@ -81,7 +81,7 @@ export const ProWorkOrderApi = {
},
// 获得工单精简列表(下拉选项)
getWorkOrderSimpleList: async () => {
return await request.get({ url: `/mes/pro/work-order/simple-list` })
getWorkOrderSimpleList: async (type?: number) => {
return await request.get({ url: `/mes/pro/work-order/simple-list`, params: { type } })
}
}

View File

@ -29,6 +29,7 @@ defineOptions({ name: 'ProWorkOrderSelect' })
const props = withDefaults(
defineProps<{
modelValue?: number
type?: number
disabled?: boolean
clearable?: boolean
placeholder?: string
@ -73,8 +74,20 @@ const handleChange = (val: number | undefined) => {
}
/** 加载工单列表 */
onMounted(async () => {
allList.value = await ProWorkOrderApi.getWorkOrderSimpleList()
const loadData = async () => {
allList.value = await ProWorkOrderApi.getWorkOrderSimpleList(props.type)
filteredList.value = allList.value
}
/** 监听 type 变化重新加载 */
watch(
() => props.type,
() => {
loadData()
}
)
onMounted(() => {
loadData()
})
</script>

View File

@ -1,6 +1,5 @@
<!-- MES 外协发料单明细表单弹窗 -->
<template>
<!-- TODO @AI每行 3 改下 -->
<Dialog :title="dialogTitle" v-model="dialogVisible" width="960px">
<el-form
ref="formRef"
@ -9,31 +8,66 @@
label-width="110px"
v-loading="formLoading"
>
<!-- TODO @AI库存物资的选择参考别的模块选择 WmMaterialStockSelect然后选择它后设置到下面的字段这些字段要 disabled你参考下别的模块 -->
<el-form-item label="物料" prop="itemId" required>
<MdItemSelect v-model="formData.itemId" disabled />
</el-form-item>
<el-form-item label="发料仓库" prop="warehouseId" required>
<WmWarehouseSelect v-model="formData.warehouseId" />
</el-form-item>
<el-form-item label="库区" prop="locationId" v-if="formData.warehouseId">
<WmWarehouseLocationSelect
v-model="formData.locationId"
:warehouse-id="formData.warehouseId"
/>
</el-form-item>
<el-form-item label="库位" prop="areaId" v-if="formData.locationId">
<WmWarehouseAreaSelect v-model="formData.areaId" :location-id="formData.locationId" />
</el-form-item>
<el-form-item label="数量" prop="quantity" required>
<el-input-number
v-model="formData.quantity"
:precision="2"
:min="0"
controls-position="right"
class="!w-1/1"
/>
</el-form-item>
<el-row>
<el-col :span="8">
<el-form-item label="库存记录" prop="materialStockId">
<WmMaterialStockSelect
v-model="formData.materialStockId"
:item-id="formData.itemId"
@change="handleStockChange"
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="物料" prop="itemId">
<MdItemSelect v-model="formData.itemId" disabled />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="数量" prop="quantity">
<el-input-number
v-model="formData.quantity"
:precision="2"
:min="0"
:max="quantityMax"
controls-position="right"
class="!w-1/1"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<el-form-item label="发料仓库" prop="warehouseId">
<WmWarehouseSelect v-model="formData.warehouseId" disabled />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="库区" prop="locationId">
<WmWarehouseLocationSelect
v-model="formData.locationId"
:warehouse-id="formData.warehouseId"
disabled
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="库位" prop="areaId">
<WmWarehouseAreaSelect
v-model="formData.areaId"
:location-id="formData.locationId"
disabled
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<el-form-item label="批次号">
<el-input :model-value="formData.batchCode" disabled />
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
@ -47,7 +81,9 @@ import {
WmOutsourceIssueDetailApi,
WmOutsourceIssueDetailVO
} from '@/api/mes/wm/outsourceissue/detail'
import { WmMaterialStockVO } from '@/api/mes/wm/materialstock'
import MdItemSelect from '@/views/mes/md/item/components/MdItemSelect.vue'
import WmMaterialStockSelect from '@/views/mes/wm/materialstock/components/WmMaterialStockSelect.vue'
import WmWarehouseSelect from '@/views/mes/wm/warehouse/components/WmWarehouseSelect.vue'
import WmWarehouseLocationSelect from '@/views/mes/wm/warehouse/components/WmWarehouseLocationSelect.vue'
import WmWarehouseAreaSelect from '@/views/mes/wm/warehouse/components/WmWarehouseAreaSelect.vue'
@ -68,23 +104,48 @@ const dialogTitle = ref('') // 弹窗的标题
const formLoading = ref(false) //
const formType = ref('') // 表单的类型create / update
const currentLineId = ref<number>() // ID
const quantityMax = ref<number | undefined>(undefined) //
const formRef = ref() // Ref
const formData = ref({
id: undefined as number | undefined,
lineId: undefined as number | undefined,
issueId: undefined as number | undefined,
itemId: undefined as number | undefined,
materialStockId: undefined as number | undefined,
quantity: undefined as number | undefined,
batchId: undefined as number | undefined,
batchCode: undefined as string | undefined,
warehouseId: undefined as number | undefined,
locationId: undefined as number | undefined,
areaId: undefined as number | undefined
})
const formRules = reactive({
itemId: [{ required: true, message: '物料不能为空', trigger: 'change' }],
warehouseId: [{ required: true, message: '发料仓库不能为空', trigger: 'change' }],
materialStockId: [{ required: true, message: '请选择库存记录', trigger: 'change' }],
quantity: [{ required: true, message: '数量不能为空', trigger: 'blur' }]
})
/** 库存选中回调 —— 自动回填仓库/库区/库位/批次/数量 */
const handleStockChange = (stock: WmMaterialStockVO | undefined) => {
if (!stock) {
formData.value.warehouseId = undefined
formData.value.locationId = undefined
formData.value.areaId = undefined
formData.value.batchId = undefined
formData.value.batchCode = undefined
formData.value.quantity = undefined
quantityMax.value = undefined
return
}
formData.value.warehouseId = stock.warehouseId
formData.value.locationId = stock.locationId
formData.value.areaId = stock.areaId
formData.value.batchId = stock.batchId
formData.value.batchCode = stock.batchCode
formData.value.quantity = stock.quantity
quantityMax.value = stock.quantity
}
/** 打开弹窗 */
const open = async (type: string, lineId: number, itemId?: number, detailId?: number) => {
dialogVisible.value = true
@ -140,11 +201,15 @@ const resetForm = () => {
lineId: undefined,
issueId: undefined,
itemId: undefined,
materialStockId: undefined,
quantity: undefined,
batchId: undefined,
batchCode: undefined,
warehouseId: undefined,
locationId: undefined,
areaId: undefined
}
quantityMax.value = undefined
formRef.value?.resetFields()
}
</script>

View File

@ -46,11 +46,13 @@
</el-row>
<el-row>
<el-col :span="8">
<!-- TODO @AIworkorderType 需要过滤下 type对齐后端应该也要校验下类型 -->
<!-- TODO @AIoutsourcereceipt 也有类似的问题 -->
<el-form-item label="外协工单" prop="workOrderId">
<!-- TODO @AIchange 的事件设置到 vendorId -->
<ProWorkOrderSelect v-model="formData.workOrderId" :disabled="isHeaderReadonly" />
<ProWorkOrderSelect
v-model="formData.workOrderId"
:type="MesProWorkOrderTypeEnum.OUTSOURCE"
:disabled="isHeaderReadonly"
@change="handleWorkOrderChange"
/>
</el-form-item>
</el-col>
<el-col :span="8">
@ -106,7 +108,8 @@ import { AutoCodeRecordApi } from '@/api/mes/md/autocode/record'
import MdVendorSelect from '@/views/mes/md/vendor/components/MdVendorSelect.vue'
import ProWorkOrderSelect from '@/views/mes/pro/workorder/components/ProWorkOrderSelect.vue'
import OutsourceIssueLineList from './OutsourceIssueLineList.vue'
import { MesAutoCodeRuleCode, MesWmOutsourceIssueStatusEnum } from '@/views/mes/utils/constants'
import { ProWorkOrderVO } from '@/api/mes/pro/workorder'
import { MesAutoCodeRuleCode, MesWmOutsourceIssueStatusEnum, MesProWorkOrderTypeEnum } from '@/views/mes/utils/constants'
defineOptions({ name: 'OutsourceIssueForm' })
const emit = defineEmits(['success'])
@ -155,6 +158,11 @@ const generateCode = async () => {
)
}
/** 工单选中回调 —— 自动回填供应商 */
const handleWorkOrderChange = (workOrder: ProWorkOrderVO | undefined) => {
formData.value.vendorId = workOrder?.vendorId ?? undefined
}
/** 打开弹窗 */
const open = async (type: string, id?: number) => {
dialogVisible.value = true

View File

@ -33,7 +33,7 @@
<el-table-column label="单位" align="center" prop="unitMeasureName" width="80" />
<el-table-column label="领料数量" align="center" prop="quantity" width="100" />
<el-table-column label="批次号" align="center" prop="batchCode" min-width="120" />
<!-- TODO @AI增加备注 -->
<el-table-column label="备注" align="center" prop="remark" min-width="150" show-overflow-tooltip />
<el-table-column
v-if="isUpdate || isStock"
label="操作"
@ -88,7 +88,6 @@
/>
</el-form-item>
</el-col>
<!-- TODO @AIbatchCode 查询 batchIdfillBatchId后端对齐下 -->
<el-col :span="8">
<el-form-item label="批次号" prop="batchCode">
<el-input v-model="formData.batchCode" placeholder="请输入批次号" />

View File

@ -32,8 +32,12 @@
</el-col>
<el-col :span="8">
<el-form-item label="外协工单" prop="workOrderId">
<!-- DONE @芋艿外协工单后续在处理这里是有个过滤条件的AI 未修复原因标注为后续处理需人工介入 -->
<ProWorkOrderSelect v-model="formData.workOrderId" :disabled="isHeaderReadonly" />
<ProWorkOrderSelect
v-model="formData.workOrderId"
:type="MesProWorkOrderTypeEnum.OUTSOURCE"
:disabled="isHeaderReadonly"
@change="handleWorkOrderChange"
/>
</el-form-item>
</el-col>
</el-row>
@ -89,9 +93,11 @@
<script setup lang="ts">
import { generateRandomStr } from '@/utils'
import { WmOutsourceReceiptApi, WmOutsourceReceiptVO } from '@/api/mes/wm/outsourcereceipt'
import { ProWorkOrderVO } from '@/api/mes/pro/workorder'
import MdVendorSelect from '@/views/mes/md/vendor/components/MdVendorSelect.vue'
import ProWorkOrderSelect from '@/views/mes/pro/workorder/components/ProWorkOrderSelect.vue'
import OutsourceReceiptLineList from './OutsourceReceiptLineList.vue'
import { MesProWorkOrderTypeEnum } from '@/views/mes/utils/constants'
defineOptions({ name: 'OutsourceReceiptForm' })
@ -135,6 +141,11 @@ const generateCode = () => {
formData.value.code = 'OR' + generateRandomStr(10)
}
/** 工单选中回调 —— 自动回填供应商 */
const handleWorkOrderChange = (workOrder: ProWorkOrderVO | undefined) => {
formData.value.vendorId = workOrder?.vendorId ?? undefined
}
/** 打开弹窗 */
const open = async (type: string, id?: number) => {
dialogVisible.value = true