feat(mes): 新增库存物资记录编号字段及相关逻辑

pull/871/MERGE
YunaiV 2026-03-30 17:53:58 +08:00
parent e41d14bb67
commit 62f4c62e3d
3 changed files with 150 additions and 60 deletions

View File

@ -5,6 +5,7 @@ export interface WmSalesNoticeLineVO {
id: number
noticeId: number
itemId: number
materialStockId: number
itemCode: string
itemName: string
specification: string

View File

@ -13,9 +13,7 @@
<el-form-item label="通知单编号" prop="noticeCode">
<el-input v-model="formData.noticeCode" placeholder="请输入通知单编号">
<template #append>
<el-button @click="generateCode">
生成
</el-button>
<el-button @click="generateCode"> </el-button>
</template>
</el-input>
</el-form-item>
@ -45,6 +43,7 @@
value-format="x"
placeholder="请选择发货日期"
class="!w-1/1"
:disabled="isDetail"
/>
</el-form-item>
</el-col>
@ -74,16 +73,24 @@
</el-col>
</el-row>
</el-form>
<!-- 编辑时展示物料信息 -->
<template v-if="formType === 'update' && formData.id">
<!-- 非新建模式展示物料信息 -->
<template v-if="formData.id">
<el-divider content-position="center">物料信息</el-divider>
<SalesNoticeLineList :notice-id="formData.id" />
<SalesNoticeLineList :notice-id="formData.id" :form-type="formType" />
</template>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading" v-if="!isDetail">
<el-button v-if="isEditable" @click="submitForm" type="primary" :disabled="formLoading">
</el-button>
<el-button @click="dialogVisible = false"> </el-button>
<el-button
v-if="isEditable && formData.status === MesWmSalesNoticeStatusEnum.PREPARE"
@click="handleSubmit"
type="warning"
:disabled="formLoading"
>
</el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
@ -93,32 +100,34 @@ import { WmSalesNoticeApi, WmSalesNoticeVO } from '@/api/mes/wm/salesnotice'
import { AutoCodeRecordApi } from '@/api/mes/md/autocode/record'
import SalesNoticeLineList from './SalesNoticeLineList.vue'
import MdClientSelect from '@/views/mes/md/client/components/MdClientSelect.vue'
import { MesAutoCodeRuleCode } from '@/views/mes/utils/constants'
import { MesAutoCodeRuleCode, MesWmSalesNoticeStatusEnum } from '@/views/mes/utils/constants'
defineOptions({ name: 'SalesNoticeForm' })
const emit = defineEmits(['success'])
const { t } = useI18n()
const message = useMessage()
const message = useMessage() //
const dialogVisible = ref(false)
const formLoading = ref(false)
const formType = ref('')
const isDetail = computed(() => formType.value === 'detail')
const dialogVisible = ref(false) //
const formLoading = ref(false) //
const formType = ref<string>('create') // 表单的类型create / update / detail
const isEditable = computed(() => ['create', 'update'].includes(formType.value)) //
const isDetail = computed(() => formType.value === 'detail') //
const dialogTitle = computed(() => {
const titles = {
const titles: Record<string, string> = {
create: '新增发货通知单',
update: '修改发货通知单',
detail: '查看发货通知单'
}
return titles[formType.value] || t('action.' + formType.value)
return titles[formType.value] || formType.value
})
const formData = ref({
id: undefined,
id: undefined as number | undefined,
noticeCode: undefined,
noticeName: undefined,
salesOrderCode: undefined,
clientId: undefined,
salesDate: undefined,
status: undefined as number | undefined,
recipientName: undefined,
recipientTelephone: undefined,
recipientAddress: undefined,
@ -130,7 +139,8 @@ const formRules = reactive({
clientId: [{ required: true, message: '请选择客户', trigger: 'change' }],
salesDate: [{ required: true, message: '请选择发货日期', trigger: 'change' }]
})
const formRef = ref()
const formRef = ref() // Ref
const originalFormData = ref<string>('') //
/** 生成通知单编号 */
const generateCode = async () => {
@ -152,11 +162,11 @@ const open = async (type: string, id?: number) => {
formLoading.value = false
}
}
//
originalFormData.value = JSON.stringify(formData.value)
}
defineExpose({ open })
/** 提交表单 */
const emit = defineEmits(['success'])
/** 提交表单create/update 模式) */
const submitForm = async () => {
await formRef.value.validate()
formLoading.value = true
@ -164,20 +174,44 @@ const submitForm = async () => {
const data = formData.value as unknown as WmSalesNoticeVO
if (formType.value === 'create') {
const res = await WmSalesNoticeApi.createSalesNotice(data)
message.success(t('common.createSuccess'))
message.success('新增成功')
formData.value.id = res
formData.value.status = MesWmSalesNoticeStatusEnum.PREPARE
formType.value = 'update'
} else {
await WmSalesNoticeApi.updateSalesNotice(data)
message.success(t('common.updateSuccess'))
dialogVisible.value = false
message.success('修改成功')
}
//
originalFormData.value = JSON.stringify(formData.value)
emit('success')
} finally {
formLoading.value = false
}
}
/** 提交操作:表单修改过则先保存,再提交 */
const handleSubmit = async () => {
await formRef.value.validate()
try {
await message.confirm('确认提交该发货通知单?【提交后将不能修改】')
formLoading.value = true
// 1.
if (JSON.stringify(formData.value) !== originalFormData.value) {
const data = formData.value as unknown as WmSalesNoticeVO
await WmSalesNoticeApi.updateSalesNotice(data)
}
// 2.
await WmSalesNoticeApi.submitSalesNotice(formData.value.id!)
message.success('提交成功')
dialogVisible.value = false
emit('success')
} catch {
} finally {
formLoading.value = false
}
}
/** 重置表单 */
const resetForm = () => {
formData.value = {
@ -187,6 +221,7 @@ const resetForm = () => {
salesOrderCode: undefined,
clientId: undefined,
salesDate: undefined,
status: undefined,
recipientName: undefined,
recipientTelephone: undefined,
recipientAddress: undefined,
@ -194,4 +229,6 @@ const resetForm = () => {
}
formRef.value?.resetFields()
}
defineExpose({ open })
</script>

View File

@ -1,26 +1,43 @@
<!-- MES 发货通知单行列表子组件 -->
<template>
<div class="overflow-hidden">
<el-button type="primary" plain @click="openForm('create')" class="mb-10px">
<el-button v-if="isUpdate" type="primary" plain @click="openForm('create')" class="mb-10px">
<Icon icon="ep:plus" class="mr-5px" /> 添加物料
</el-button>
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true" border>
<el-table
v-loading="loading"
:data="list"
:stripe="true"
:show-overflow-tooltip="true"
border
:row-key="(row: any) => row.id"
>
<el-table-column label="物料编码" align="center" prop="itemCode" min-width="120" />
<el-table-column label="物料名称" align="center" prop="itemName" min-width="140" />
<el-table-column label="规格型号" align="center" prop="specification" min-width="120" />
<el-table-column label="单位" align="center" prop="unitMeasureName" width="80" />
<el-table-column label="批次号" align="center" prop="batchCode" min-width="120" />
<el-table-column label="发货数量" align="center" prop="quantity" width="100" />
<el-table-column label="批次号" align="center" prop="batchCode" min-width="120" />
<el-table-column label="是否检验" align="center" prop="oqcCheckFlag" width="90">
<template #default="scope">
<dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.oqcCheckFlag" />
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="remark" min-width="120" />
<el-table-column label="操作" align="center" width="120">
<el-table-column
v-if="isUpdate"
label="操作"
align="center"
width="120"
fixed="right"
>
<template #default="scope">
<el-button link type="primary" @click="openForm('update', scope.row.id)">编辑</el-button>
<el-button link type="danger" @click="handleDelete(scope.row.id)"></el-button>
<el-button v-if="isUpdate" link type="primary" @click="openForm('update', scope.row.id)">
编辑
</el-button>
<el-button v-if="isUpdate" link type="danger" @click="handleDelete(scope.row.id)">
删除
</el-button>
</template>
</el-table-column>
</el-table>
@ -33,7 +50,7 @@
</div>
<!-- 添加/编辑行弹窗 -->
<Dialog :title="dialogTitle" v-model="dialogVisible" width="700px">
<Dialog :title="dialogTitle" v-model="dialogVisible" width="960px">
<el-form
ref="formRef"
:model="formData"
@ -42,30 +59,41 @@
v-loading="formLoading"
>
<el-row>
<el-col :span="12">
<el-form-item label="物料" prop="itemId">
<MdItemSelect v-model="formData.itemId" placeholder="请选择物料" />
<el-col :span="8">
<el-form-item label="库存记录" prop="materialStockId">
<WmMaterialStockSelect
v-model="formData.materialStockId"
placeholder="请选择库存"
class="!w-1/1"
@change="handleStockChange"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="批次号" prop="batchCode">
<el-input v-model="formData.batchCode" placeholder="请输入批次号" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-col :span="8">
<el-form-item label="发货数量" prop="quantity">
<el-input-number
v-model="formData.quantity"
:precision="2"
:min="0.01"
:min="0"
:max="quantityMax"
controls-position="right"
class="!w-1/1"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-col :span="8">
<el-form-item label="批次号">
<el-input :model-value="formData.batchCode" disabled placeholder="选择库存后自动带出" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<el-form-item label="物料">
<MdItemSelect v-model="formData.itemId" disabled />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="是否检验" prop="oqcCheckFlag">
<el-switch v-model="formData.oqcCheckFlag" />
</el-form-item>
@ -89,17 +117,22 @@
<script setup lang="ts">
import { DICT_TYPE } from '@/utils/dict'
import { WmSalesNoticeLineApi, WmSalesNoticeLineVO } from '@/api/mes/wm/salesnotice/line'
import { WmMaterialStockVO } from '@/api/mes/wm/materialstock'
import WmMaterialStockSelect from '@/views/mes/wm/materialstock/components/WmMaterialStockSelect.vue'
import MdItemSelect from '@/views/mes/md/item/components/MdItemSelect.vue'
defineOptions({ name: 'SalesNoticeLineList' })
const props = defineProps<{
noticeId: number
formType: string
}>()
const { t } = useI18n()
const message = useMessage()
const isUpdate = computed(() => ['create', 'update'].includes(props.formType))
// ==================== ====================
const loading = ref(false)
const list = ref<WmSalesNoticeLineVO[]>([])
@ -137,31 +170,47 @@ const handleDelete = async (id: number) => {
const dialogVisible = ref(false)
const dialogTitle = ref('')
const formLoading = ref(false)
const formType = ref('')
const lineFormType = ref('')
const quantityMax = ref<number | undefined>(undefined)
const formData = ref({
id: undefined,
noticeId: undefined as number | undefined,
itemId: undefined,
batchCode: undefined,
quantity: undefined,
materialStockId: undefined as number | undefined,
itemId: undefined as number | undefined,
quantity: undefined as number | undefined,
batchId: undefined as number | undefined,
batchCode: undefined as string | undefined,
oqcCheckFlag: true,
remark: undefined
})
const formRules = reactive({
itemId: [{ required: true, message: '物料不能为空', trigger: 'change' }],
quantity: [
{ required: true, message: '发货数量不能为空', trigger: 'blur' },
{ type: 'number', min: 0.01, message: '发货数量必须大于0', trigger: 'blur' }
],
oqcCheckFlag: [{ required: true, message: '是否检验不能为空', trigger: 'change' }]
materialStockId: [{ required: true, message: '请选择库存记录', trigger: 'change' }],
quantity: [{ required: true, message: '发货数量不能为空', trigger: 'blur' }]
})
const formRef = ref()
/** 库存选中回调 —— 自动回填物料ID/批次/数量上限 */
const handleStockChange = (stock: WmMaterialStockVO | undefined) => {
if (!stock) {
formData.value.itemId = undefined
formData.value.batchId = undefined
formData.value.batchCode = undefined
formData.value.quantity = undefined
quantityMax.value = undefined
return
}
formData.value.itemId = stock.itemId
formData.value.batchId = stock.batchId
formData.value.batchCode = stock.batchCode
formData.value.quantity = stock.quantity
quantityMax.value = stock.quantity
}
/** 打开表单弹窗 */
const openForm = async (type: string, id?: number) => {
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
dialogTitle.value = type === 'create' ? '添加发货通知单行' : '修改发货通知单行'
lineFormType.value = type
resetForm()
if (id) {
formLoading.value = true
@ -179,7 +228,7 @@ const submitForm = async () => {
formLoading.value = true
try {
const data = { ...formData.value, noticeId: props.noticeId } as unknown as WmSalesNoticeLineVO
if (formType.value === 'create') {
if (lineFormType.value === 'create') {
await WmSalesNoticeLineApi.createSalesNoticeLine(data)
message.success(t('common.createSuccess'))
} else {
@ -198,12 +247,15 @@ const resetForm = () => {
formData.value = {
id: undefined,
noticeId: undefined,
materialStockId: undefined,
itemId: undefined,
batchCode: undefined,
quantity: undefined,
batchId: undefined,
batchCode: undefined,
oqcCheckFlag: true,
remark: undefined
}
quantityMax.value = undefined
formRef.value?.resetFields()
}