feat: 新增手动新增汇总弹窗组件 manual-detail.vue

- 使用 useVbenModal + useVbenForm 组合
- 集成 MaterialSelectModal 进行物料选择
- 支持物料、出库重量、单位、批次、备注字段
- 单位自动从物料信息带出
- 弹窗打开时重置表单
This commit is contained in:
zhouz
2026-07-22 09:56:04 +08:00
parent c03e1a97cc
commit e5e12fb799

View File

@@ -0,0 +1,150 @@
<script lang="ts" setup>
import { ref } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { useVbenForm } from '#/adapter/form';
import MaterialSelectModalComponent from '../../../base/materialbase/components/MaterialSelectModal.vue';
const emit = defineEmits(['confirm']);
/** 物料选择弹窗 */
const [MaterialSelectModal, materialSelectModalApi] = useVbenModal({
connectedComponent: MaterialSelectModalComponent,
});
/** 已选物料信息(不在表单中展示的额外字段) */
const selectedMaterial = ref<{
materialId: number;
materialName: string;
qtyUnitId: number;
qtyUnitName: string;
} | null>(null);
function openMaterialSelect() {
materialSelectModalApi.setData({ multiple: false }).open();
}
function handleMaterialSelect(rows: any[]) {
if (rows.length > 0) {
const row = rows[0];
selectedMaterial.value = {
materialId: row.materialId,
materialName: row.materialName,
qtyUnitId: row.baseUnitId || row.qtyUnitId,
qtyUnitName: row.baseUnitName || row.qtyUnitName || '',
};
formApi.setValues({
materialCode: row.materialCode,
qtyUnitName: selectedMaterial.value.qtyUnitName,
});
}
}
const [Form, formApi] = useVbenForm({
commonConfig: {
componentProps: {
class: 'w-full',
},
formItemClass: 'col-span-2',
labelWidth: 80,
},
layout: 'horizontal',
schema: [
{
fieldName: 'materialCode',
label: '物料',
rules: 'required',
component: 'Input',
componentProps: {
placeholder: '请选择物料',
readonly: true,
style: 'cursor: pointer',
onClick: openMaterialSelect,
},
},
{
fieldName: 'planQty',
label: '出库重量',
rules: 'required',
component: 'InputNumber',
componentProps: {
placeholder: '请输入出库重量',
min: 0,
precision: 2,
},
},
{
fieldName: 'qtyUnitName',
label: '单位',
component: 'Input',
componentProps: {
placeholder: '',
readonly: true,
disabled: true,
},
},
{
fieldName: 'pcsn',
label: '批次',
component: 'Input',
componentProps: {
placeholder: '请输入批次',
maxlength: 64,
},
},
{
fieldName: 'remark',
label: '备注',
component: 'Input',
componentProps: {
placeholder: '请输入备注',
maxlength: 500,
},
},
],
showDefaultActions: false,
});
const [Modal, modalApi] = useVbenModal({
width: 500,
async onConfirm() {
const { valid } = await formApi.validate();
if (!valid) {
return;
}
if (!selectedMaterial.value) {
return;
}
const values = await formApi.getValues();
emit('confirm', {
materialCode: values.materialCode,
materialId: selectedMaterial.value.materialId,
materialName: selectedMaterial.value.materialName,
planQty: values.planQty,
qtyUnitId: selectedMaterial.value.qtyUnitId,
qtyUnitName: selectedMaterial.value.qtyUnitName,
pcsn: values.pcsn,
remark: values.remark,
});
modalApi.close();
},
async onOpenChange(isOpen: boolean) {
if (!isOpen) {
selectedMaterial.value = null;
return;
}
// 弹窗打开时重置表单
selectedMaterial.value = null;
await formApi.resetForm();
},
});
</script>
<template>
<Modal title="手动新增汇总">
<Form class="mx-4" />
<MaterialSelectModal @select="handleMaterialSelect" />
</Modal>
</template>