<script lang="ts" setup>
|
import type { VbenFormSchema } from "#/adapter/form";
|
import type { MdmItemApi } from "#/api/mdm/item";
|
import type { MesProBagCodeApi } from "#/api/mes/pro/bagCode";
|
|
import { computed, markRaw, ref } from "vue";
|
|
import { useVbenModal } from "@vben/common-ui";
|
|
import { message } from "ant-design-vue";
|
|
import { useVbenForm } from "#/adapter/form";
|
import { generateBagCodes } from "#/api/mes/pro/bagCode";
|
import { getUnit } from "#/api/mdm/unit";
|
import { MdmItemSelect } from "#/views/basicData/mdm/components";
|
|
defineOptions({ name: "MesProBagCodeGenerateForm" });
|
|
const emit = defineEmits(["success"]);
|
|
// 所选品种主计量单位类型:48千克/100千克 -> 每托 N 袋;吨 -> 无托盘直接输袋码数
|
const unitType = ref("");
|
const kgPerPallet = ref<number | null>(null);
|
const isTon = ref(false);
|
const unitTypeError = ref(false);
|
const palletCountVal = ref<number | null>(null);
|
const bagCountVal = ref<number | null>(null);
|
|
/** 换算/配置提示文案 */
|
const tipText = computed(() => {
|
if (unitTypeError.value) {
|
return "该品种主计量单位未配置类型(仅支持 48千克/100千克/吨),请先前往「计量单位」维护后重试";
|
}
|
if (!unitType.value) {
|
return "";
|
}
|
if (isTon.value) {
|
return `计量单位类型为「吨」:不生成托盘,袋码仅绑定生产批次${
|
bagCountVal.value ? `,将生成 ${bagCountVal.value} 个袋码` : ""
|
}`;
|
}
|
const per = kgPerPallet.value ?? 0;
|
const count = palletCountVal.value ?? 0;
|
return `计量单位类型为「${unitType.value}」:每托 ${per} 袋${
|
count > 0
|
? ` × ${count} 托 = ${per * count} 个袋码,将自动生成 ${count} 个托盘并绑定`
|
: ",请输入托盘数"
|
}`;
|
});
|
|
function buildSchema(): VbenFormSchema[] {
|
const schema: VbenFormSchema[] = [
|
{
|
fieldName: "itemId",
|
label: "品种",
|
component: markRaw(MdmItemSelect),
|
componentProps: {
|
placeholder: "请选择品种(产品品种)",
|
onChange: handleItemChange,
|
},
|
rules: "selectRequired",
|
},
|
];
|
if (kgPerPallet.value) {
|
schema.push({
|
fieldName: "palletCount",
|
label: "托盘数",
|
component: "InputNumber",
|
componentProps: {
|
class: "!w-full",
|
min: 1,
|
placeholder: "请输入托盘数(系统自动生成托盘并均分绑定袋码)",
|
precision: 0,
|
onChange: (value: number | string) => {
|
palletCountVal.value = Number(value) || null;
|
},
|
},
|
rules: "required",
|
});
|
}
|
if (isTon.value) {
|
schema.push({
|
fieldName: "bagCount",
|
label: "袋码数",
|
component: "InputNumber",
|
componentProps: {
|
class: "!w-full",
|
min: 1,
|
placeholder: "请输入袋码数(吨品种无托盘,袋码仅绑定批次)",
|
precision: 0,
|
onChange: (value: number | string) => {
|
bagCountVal.value = Number(value) || null;
|
},
|
},
|
rules: "required",
|
});
|
}
|
schema.push({
|
fieldName: "remark",
|
label: "备注",
|
component: "Textarea",
|
componentProps: {
|
placeholder: "请输入备注",
|
rows: 2,
|
},
|
});
|
return schema;
|
}
|
|
/** 选择品种后读取主计量单位类型,动态切换托盘数/袋码数输入 */
|
async function handleItemChange(item?: MdmItemApi.Item) {
|
unitType.value = "";
|
kgPerPallet.value = null;
|
isTon.value = false;
|
unitTypeError.value = false;
|
palletCountVal.value = null;
|
bagCountVal.value = null;
|
if (item?.unitMeasureId) {
|
try {
|
const unit = await getUnit(item.unitMeasureId);
|
const type = (unit?.type ?? "").trim();
|
unitType.value = type;
|
if (type === "吨") {
|
isTon.value = true;
|
} else {
|
const matcher = /^(\d{1,5})千克$/.exec(type);
|
if (matcher) {
|
kgPerPallet.value = Number(matcher[1]);
|
} else {
|
unitTypeError.value = true;
|
}
|
}
|
} catch {
|
unitTypeError.value = true;
|
}
|
} else if (item) {
|
unitTypeError.value = true;
|
}
|
await formApi.setState({ schema: buildSchema() });
|
}
|
|
const [Form, formApi] = useVbenForm({
|
commonConfig: {
|
componentProps: {
|
class: "w-full",
|
},
|
labelWidth: 100,
|
},
|
layout: "horizontal",
|
schema: [],
|
showDefaultActions: false,
|
});
|
|
const [Modal, modalApi] = useVbenModal({
|
async onConfirm() {
|
const { valid } = await formApi.validate();
|
if (!valid) return;
|
if (unitTypeError.value) {
|
message.warning(tipText.value);
|
return;
|
}
|
modalApi.lock();
|
try {
|
const values =
|
(await formApi.getValues()) as MesProBagCodeApi.GenerateParams;
|
const data: MesProBagCodeApi.GenerateParams = {
|
itemId: values.itemId,
|
remark: values.remark,
|
};
|
if (isTon.value) {
|
data.bagCount = values.bagCount;
|
} else {
|
data.palletCount = values.palletCount;
|
}
|
const result = await generateBagCodes(data);
|
message.success(
|
`已成功生成 ${result.totalCount} 条袋码` +
|
(result.palletIds?.length
|
? `,并自动生成 ${result.palletIds.length} 个托盘`
|
: ""),
|
);
|
emit("success");
|
await modalApi.close();
|
} finally {
|
modalApi.unlock();
|
}
|
},
|
async onOpenChange(isOpen: boolean) {
|
if (!isOpen) return;
|
modalApi.lock();
|
try {
|
unitType.value = "";
|
kgPerPallet.value = null;
|
isTon.value = false;
|
unitTypeError.value = false;
|
palletCountVal.value = null;
|
bagCountVal.value = null;
|
await formApi.setValues({
|
itemId: undefined,
|
palletCount: undefined,
|
bagCount: undefined,
|
remark: undefined,
|
});
|
await formApi.setState({ schema: buildSchema() });
|
} finally {
|
modalApi.unlock();
|
}
|
},
|
});
|
</script>
|
|
<template>
|
<Modal title="生成袋码数据包" class="w-2/5">
|
<Form class="mx-4" />
|
<div
|
v-if="tipText"
|
class="mx-4 mb-2 rounded bg-gray-50 px-3 py-2 text-sm"
|
:class="unitTypeError ? 'text-red-500' : 'text-gray-500'"
|
>
|
{{ tipText }}
|
</div>
|
</Modal>
|
</template>
|