2 天以前 46624ce480a3c14da21f39cc4ad5f7eecea2bb1e
src/views/mes/pro/bagCode/modules/generate-form.vue
@@ -1,6 +1,9 @@
<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";
@@ -8,26 +11,91 @@
  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[] {
    return [
    const schema: VbenFormSchema[] = [
      {
        fieldName: "count",
        label: "生成袋数",
        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: "请输入需要生成的袋码数量",
          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",
@@ -35,8 +103,40 @@
          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({
@@ -55,12 +155,30 @@
    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;
        await generateBagCodes(values);
        message.success(`已成功生成 ${values.count} 条袋码`);
        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 {
@@ -71,6 +189,18 @@
      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();
@@ -82,5 +212,12 @@
<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>