zhangwencui
8 天以前 d171971461713d9d6d9ccb989fa2195d7d9ee1c6
物料同步到mes开关syncMes
已修改3个文件
563 ■■■■ 文件已修改
src/views/basicData/mdm/data.ts 405 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/basicData/mdm/modules/form.vue 128 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
vite.config.ts 30 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/basicData/mdm/data.ts
@@ -1,283 +1,294 @@
import type { VbenFormSchema } from '#/adapter/form';
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type { VbenFormSchema } from "#/adapter/form";
import type { VxeTableGridOptions } from "#/adapter/vxe-table";
import { CommonStatusEnum, DICT_TYPE } from '#/packages/constants/src';
import { getDictOptions } from '#/packages/effects/hooks/src';
import { CommonStatusEnum, DICT_TYPE } from "#/packages/constants/src";
import { getDictOptions } from "#/packages/effects/hooks/src";
import { z } from '#/adapter/form';
import { getUnitPage } from '#/api/mdm/unit';
import { getWarehouseSimpleList } from '#/api/erp/stock/warehouse';
import { z } from "#/adapter/form";
import { getUnitPage } from "#/api/mdm/unit";
import { getWarehouseSimpleList } from "#/api/erp/stock/warehouse";
/** 物料类型选项 */
export const ITEM_TYPE_OPTIONS = [
  { label: '原料', value: 1 },
  { label: '半成品', value: 2 },
  { label: '成品', value: 3 },
  { label: '辅料', value: 4 },
  { label: "原料", value: 1 },
  { label: "半成品", value: 2 },
  { label: "成品", value: 3 },
  { label: "辅料", value: 4 },
];
/** 物料类型映射 */
export const ITEM_TYPE_MAP: Record<number, string> = {
  1: '原料',
  2: '半成品',
  3: '成品',
  4: '辅料',
  1: "原料",
  2: "半成品",
  3: "成品",
  4: "辅料",
};
/** 物料类型颜色映射 */
export const ITEM_TYPE_COLOR_MAP: Record<number, string> = {
  1: 'green',
  2: 'orange',
  3: 'blue',
  4: 'purple',
  1: "green",
  2: "orange",
  3: "blue",
  4: "purple",
};
/** 新增/修改的表单 */
export function useFormSchema(): VbenFormSchema[] {
  return [
    {
      component: 'Input',
      fieldName: 'id',
      component: "Input",
      fieldName: "id",
      dependencies: {
        triggerFields: [''],
        triggerFields: [""],
        show: () => false,
      },
    },
    {
      component: 'Input',
      fieldName: 'code',
      label: '物料编码',
      component: "Input",
      fieldName: "code",
      label: "物料编码",
      componentProps: {
        placeholder: '请输入物料编码',
        placeholder: "请输入物料编码",
      },
      rules: 'required',
      rules: "required",
    },
    {
      component: 'Input',
      fieldName: 'name',
      label: '物料名称',
      component: "Input",
      fieldName: "name",
      label: "物料名称",
      componentProps: {
        placeholder: '请输入物料名称',
        placeholder: "请输入物料名称",
      },
      rules: 'required',
      rules: "required",
    },
    {
      component: 'RadioGroup',
      fieldName: 'itemType',
      label: '物料类型',
      component: "RadioGroup",
      fieldName: "itemType",
      label: "物料类型",
      componentProps: {
        options: ITEM_TYPE_OPTIONS,
        buttonStyle: 'solid',
        optionType: 'button',
        buttonStyle: "solid",
        optionType: "button",
      },
      rules: 'required',
      rules: "required",
    },
    {
      component: 'Input',
      fieldName: 'specification',
      label: '规格型号',
      component: "Input",
      fieldName: "specification",
      label: "规格型号",
      componentProps: {
        placeholder: '请输入规格型号',
        placeholder: "请输入规格型号",
      },
    },
    {
      component: 'ApiSelect',
      fieldName: 'unitMeasureId',
      label: '计量单位',
      rules: 'required',
      formItemClass: 'col-span-1',
      component: "ApiSelect",
      fieldName: "unitMeasureId",
      label: "计量单位",
      rules: "required",
      formItemClass: "col-span-1",
      componentProps: {
        placeholder: '请选择计量单位',
        placeholder: "请选择计量单位",
        allowClear: true,
        api: async () => {
          const res = await getUnitPage({ pageNo: 1, pageSize: 100, status: 0 });
          return res.list || [];
        },
        labelField: 'name',
        valueField: 'id',
        labelField: "name",
        valueField: "id",
      },
    },
    {
      component: 'ApiSelect',
      fieldName: 'unitMeasureId2',
      label: '辅单位1',
      formItemClass: 'col-span-1',
      component: "ApiSelect",
      fieldName: "unitMeasureId2",
      label: "辅单位1",
      formItemClass: "col-span-1",
      componentProps: {
        placeholder: '请选择辅单位1',
        placeholder: "请选择辅单位1",
        allowClear: true,
        api: async () => {
          const res = await getUnitPage({ pageNo: 1, pageSize: 100, status: 0 });
          return res.list || [];
        },
        labelField: 'name',
        valueField: 'id',
        labelField: "name",
        valueField: "id",
      },
    },
    {
      component: 'InputNumber',
      fieldName: 'unitMeasureRate1',
      label: '辅单位1换算比率',
      formItemClass: 'col-span-1',
      component: "InputNumber",
      fieldName: "unitMeasureRate1",
      label: "辅单位1换算比率",
      formItemClass: "col-span-1",
      componentProps: {
        class: '!w-full',
        class: "!w-full",
        min: 0,
        precision: 6,
        placeholder: '请输入换算比率',
        placeholder: "请输入换算比率",
      },
    },
    {
      component: 'ApiSelect',
      fieldName: 'unitMeasureId3',
      label: '辅单位2',
      formItemClass: 'col-span-1',
      component: "ApiSelect",
      fieldName: "unitMeasureId3",
      label: "辅单位2",
      formItemClass: "col-span-1",
      componentProps: {
        placeholder: '请选择辅单位2',
        placeholder: "请选择辅单位2",
        allowClear: true,
        api: async () => {
          const res = await getUnitPage({ pageNo: 1, pageSize: 100, status: 0 });
          return res.list || [];
        },
        labelField: 'name',
        valueField: 'id',
        labelField: "name",
        valueField: "id",
      },
    },
    {
      component: 'InputNumber',
      fieldName: 'unitMeasureRate2',
      label: '辅单位2换算比率',
      formItemClass: 'col-span-1',
      component: "InputNumber",
      fieldName: "unitMeasureRate2",
      label: "辅单位2换算比率",
      formItemClass: "col-span-1",
      componentProps: {
        class: '!w-full',
        class: "!w-full",
        min: 0,
        precision: 6,
        placeholder: '请输入换算比率',
        placeholder: "请输入换算比率",
      },
    },
    {
      component: 'ApiSelect',
      fieldName: 'warehouseId',
      label: '默认仓库',
      component: "ApiSelect",
      fieldName: "warehouseId",
      label: "默认仓库",
      componentProps: {
        placeholder: '请选择默认仓库',
        placeholder: "请选择默认仓库",
        allowClear: true,
        api: getWarehouseSimpleList,
        labelField: 'name',
        valueField: 'id',
        labelField: "name",
        valueField: "id",
      },
    },
    {
      component: 'Input',
      fieldName: 'barCode',
      label: '条码',
      component: "Input",
      fieldName: "barCode",
      label: "条码",
      componentProps: {
        placeholder: '请输入条码',
        placeholder: "请输入条码",
      },
    },
    {
      component: 'InputNumber',
      fieldName: 'purchasePrice',
      label: '采购价',
      component: "InputNumber",
      fieldName: "purchasePrice",
      label: "采购价",
      componentProps: {
        class: '!w-full',
        class: "!w-full",
        min: 0,
        precision: 2,
        placeholder: '请输入采购价',
        placeholder: "请输入采购价",
      },
    },
    {
      component: 'InputNumber',
      fieldName: 'salesPrice',
      label: '销售价',
      component: "InputNumber",
      fieldName: "salesPrice",
      label: "销售价",
      componentProps: {
        class: '!w-full',
        class: "!w-full",
        min: 0,
        precision: 2,
        placeholder: '请输入销售价',
        placeholder: "请输入销售价",
      },
    },
    {
      component: 'InputNumber',
      fieldName: 'costPrice',
      label: '成本价',
      component: "InputNumber",
      fieldName: "costPrice",
      label: "成本价",
      componentProps: {
        class: '!w-full',
        class: "!w-full",
        min: 0,
        precision: 2,
        placeholder: '请输入成本价',
        placeholder: "请输入成本价",
      },
    },
    {
      component: 'InputNumber',
      fieldName: 'safetyStock',
      label: '安全库存',
      component: "InputNumber",
      fieldName: "safetyStock",
      label: "安全库存",
      componentProps: {
        class: '!w-full',
        class: "!w-full",
        min: 0,
        precision: 2,
        placeholder: '请输入安全库存',
        placeholder: "请输入安全库存",
      },
    },
    {
      component: 'InputNumber',
      fieldName: 'minStock',
      label: '最低库存',
      component: "InputNumber",
      fieldName: "minStock",
      label: "最低库存",
      componentProps: {
        class: '!w-full',
        class: "!w-full",
        min: 0,
        precision: 2,
        placeholder: '请输入最低库存',
        placeholder: "请输入最低库存",
      },
    },
    {
      component: 'InputNumber',
      fieldName: 'maxStock',
      label: '最高库存',
      component: "InputNumber",
      fieldName: "maxStock",
      label: "最高库存",
      componentProps: {
        class: '!w-full',
        class: "!w-full",
        min: 0,
        precision: 2,
        placeholder: '请输入最高库存',
        placeholder: "请输入最高库存",
      },
    },
    {
      component: 'Switch',
      fieldName: 'isBatchManaged',
      label: '批次管理',
      component: "Switch",
      fieldName: "isBatchManaged",
      label: "批次管理",
      componentProps: {
        class: 'w-auto',
        checkedChildren: '是',
        unCheckedChildren: '否',
        class: "w-auto",
        checkedChildren: "是",
        unCheckedChildren: "否",
      },
      rules: z.boolean().default(true),
    },
    {
      component: 'InputNumber',
      fieldName: 'expiryDay',
      label: '有效期(天)',
      component: "Switch",
      fieldName: "syncMes",
      label: "同步到 MES",
      componentProps: {
        class: '!w-full',
        class: "w-auto",
        checkedChildren: "是",
        unCheckedChildren: "否",
      },
      rules: z.boolean().default(false),
    },
    {
      component: "InputNumber",
      fieldName: "expiryDay",
      label: "有效期(天)",
      componentProps: {
        class: "!w-full",
        min: 0,
        placeholder: '请输入有效期',
        placeholder: "请输入有效期",
      },
    },
    {
      component: 'RadioGroup',
      fieldName: 'status',
      label: '状态',
      component: "RadioGroup",
      fieldName: "status",
      label: "状态",
      componentProps: {
        options: getDictOptions(DICT_TYPE.COMMON_STATUS, 'number'),
        buttonStyle: 'solid',
        optionType: 'button',
        options: getDictOptions(DICT_TYPE.COMMON_STATUS, "number"),
        buttonStyle: "solid",
        optionType: "button",
      },
      rules: z.number().default(CommonStatusEnum.ENABLE),
    },
    {
      component: 'Textarea',
      fieldName: 'remark',
      label: '备注',
      formItemClass: 'col-span-2',
      component: "Textarea",
      fieldName: "remark",
      label: "备注",
      formItemClass: "col-span-2",
      componentProps: {
        placeholder: '请输入备注',
        placeholder: "请输入备注",
        rows: 3,
      },
    },
@@ -288,143 +299,143 @@
export function useGridFormSchema(): VbenFormSchema[] {
  return [
    {
      fieldName: 'code',
      label: '物料编码',
      component: 'Input',
      fieldName: "code",
      label: "物料编码",
      component: "Input",
      componentProps: {
        placeholder: '请输入物料编码',
        placeholder: "请输入物料编码",
        allowClear: true,
      },
    },
    {
      fieldName: 'name',
      label: '物料名称',
      component: 'Input',
      fieldName: "name",
      label: "物料名称",
      component: "Input",
      componentProps: {
        placeholder: '请输入物料名称',
        placeholder: "请输入物料名称",
        allowClear: true,
      },
    },
    {
      fieldName: 'itemType',
      label: '物料类型',
      component: 'Select',
      fieldName: "itemType",
      label: "物料类型",
      component: "Select",
      componentProps: {
        placeholder: '请选择物料类型',
        placeholder: "请选择物料类型",
        allowClear: true,
        options: ITEM_TYPE_OPTIONS,
      },
    },
    {
      fieldName: 'status',
      label: '状态',
      component: 'Select',
      fieldName: "status",
      label: "状态",
      component: "Select",
      componentProps: {
        placeholder: '请选择状态',
        placeholder: "请选择状态",
        allowClear: true,
        options: getDictOptions(DICT_TYPE.COMMON_STATUS, 'number'),
        options: getDictOptions(DICT_TYPE.COMMON_STATUS, "number"),
      },
    },
  ];
}
/** 列表的字段 */
export function useGridColumns(): VxeTableGridOptions['columns'] {
export function useGridColumns(): VxeTableGridOptions["columns"] {
  return [
    { type: 'checkbox', width: 40 },
    { type: "checkbox", width: 40 },
    {
      field: 'code',
      title: '物料编码',
      field: "code",
      title: "物料编码",
      minWidth: 120,
    },
    {
      field: 'name',
      title: '物料名称',
      field: "name",
      title: "物料名称",
      minWidth: 180,
    },
    {
      field: 'specification',
      title: '规格型号',
      field: "specification",
      title: "规格型号",
      minWidth: 150,
    },
    {
      field: 'unitMeasureName',
      title: '单位',
      field: "unitMeasureName",
      title: "单位",
      minWidth: 80,
    },
    {
      field: 'unitMeasureName2',
      title: '辅单位1',
      field: "unitMeasureName2",
      title: "辅单位1",
      minWidth: 80,
    },
    {
      field: 'unitMeasureRate1',
      title: '辅单位1换算比率',
      field: "unitMeasureRate1",
      title: "辅单位1换算比率",
      minWidth: 130,
    },
    {
      field: 'unitMeasureName3',
      title: '辅单位2',
      field: "unitMeasureName3",
      title: "辅单位2",
      minWidth: 80,
    },
    {
      field: 'unitMeasureRate2',
      title: '辅单位2换算比率',
      field: "unitMeasureRate2",
      title: "辅单位2换算比率",
      minWidth: 130,
    },
    {
      field: 'warehouseName',
      title: '默认仓库',
      field: "warehouseName",
      title: "默认仓库",
      minWidth: 100,
    },
    {
      field: 'itemType',
      title: '物料类型',
      field: "itemType",
      title: "物料类型",
      minWidth: 100,
      slots: { default: 'itemType' },
      slots: { default: "itemType" },
    },
    {
      field: 'purchasePrice',
      title: '采购价',
      field: "purchasePrice",
      title: "采购价",
      minWidth: 100,
      formatter: ({ cellValue }) => {
        return cellValue != null ? `¥${Number(cellValue).toFixed(2)}` : '';
        return cellValue != null ? `¥${Number(cellValue).toFixed(2)}` : "";
      },
    },
    {
      field: 'salesPrice',
      title: '销售价',
      field: "salesPrice",
      title: "销售价",
      minWidth: 100,
      formatter: ({ cellValue }) => {
        return cellValue != null ? `¥${Number(cellValue).toFixed(2)}` : '';
        return cellValue != null ? `¥${Number(cellValue).toFixed(2)}` : "";
      },
    },
    {
      field: 'isBatchManaged',
      title: '批次管理',
      field: "isBatchManaged",
      title: "批次管理",
      minWidth: 80,
      slots: { default: 'isBatchManaged' },
      slots: { default: "isBatchManaged" },
    },
    {
      field: 'status',
      title: '状态',
      field: "status",
      title: "状态",
      minWidth: 80,
      cellRender: {
        name: 'CellDict',
        name: "CellDict",
        props: { type: DICT_TYPE.COMMON_STATUS },
      },
    },
    {
      field: 'createTime',
      title: '创建时间',
      field: "createTime",
      title: "创建时间",
      minWidth: 180,
      formatter: 'formatDateTime',
      formatter: "formatDateTime",
    },
    {
      title: '操作',
      title: "操作",
      width: 180,
      fixed: 'right',
      slots: { default: 'actions' },
      fixed: "right",
      slots: { default: "actions" },
    },
  ];
}
}
src/views/basicData/mdm/modules/form.vue
@@ -1,80 +1,82 @@
<script lang="ts" setup>
import type { MdmItemApi } from '#/api/mdm/item';
  import type { MdmItemApi } from "#/api/mdm/item";
import { computed, ref } from 'vue';
  import { computed, ref } from "vue";
import { useVbenModal } from '#/packages/effects/common-ui/src';
  import { useVbenModal } from "#/packages/effects/common-ui/src";
import { message } from 'ant-design-vue';
  import { message } from "ant-design-vue";
import { useVbenForm } from '#/adapter/form';
import { createItem, getItem, updateItem } from '#/api/mdm/item';
import { $t } from '#/locales';
  import { useVbenForm } from "#/adapter/form";
  import { createItem, getItem, updateItem } from "#/api/mdm/item";
  import { $t } from "#/locales";
import { useFormSchema } from '../data';
  import { useFormSchema } from "../data";
defineOptions({ name: 'ItemForm' });
  defineOptions({ name: "ItemForm" });
const emit = defineEmits(['success']);
const formData = ref<MdmItemApi.Item>();
const getTitle = computed(() => {
  return formData.value?.id
    ? $t('ui.actionTitle.edit', ['物料'])
    : $t('ui.actionTitle.create', ['物料']);
});
  const emit = defineEmits(["success"]);
  const formData = ref<MdmItemApi.Item>();
  const getTitle = computed(() => {
    return formData.value?.id
      ? $t("ui.actionTitle.edit", ["物料"])
      : $t("ui.actionTitle.create", ["物料"]);
  });
const [Form, formApi] = useVbenForm({
  commonConfig: {
    componentProps: {
      class: 'w-full',
  const [Form, formApi] = useVbenForm({
    commonConfig: {
      componentProps: {
        class: "w-full",
      },
      labelWidth: 110,
    },
    labelWidth: 110,
  },
  layout: 'horizontal',
  schema: useFormSchema(),
  showDefaultActions: false,
  wrapperClass: 'grid-cols-2',
});
    layout: "horizontal",
    schema: useFormSchema(),
    showDefaultActions: false,
    wrapperClass: "grid-cols-2",
  });
const [Modal, modalApi] = useVbenModal({
  async onConfirm() {
    const { valid } = await formApi.validate();
    if (!valid) {
      return;
    }
    modalApi.lock();
    const data = (await formApi.getValues()) as MdmItemApi.Item;
    try {
      await (formData.value?.id ? updateItem(data) : createItem(data));
      await modalApi.close();
      emit('success');
      message.success($t('ui.actionMessage.operationSuccess'));
    } finally {
      modalApi.unlock();
    }
  },
  async onOpenChange(isOpen: boolean) {
    if (!isOpen) {
      formData.value = undefined;
      return;
    }
    const data = modalApi.getData<MdmItemApi.Item>();
    if (!data || !data.id) {
      return;
    }
    modalApi.lock();
    try {
      formData.value = await getItem(data.id);
      await formApi.setValues(formData.value);
    } finally {
      modalApi.unlock();
    }
  },
});
  const [Modal, modalApi] = useVbenModal({
    async onConfirm() {
      const { valid } = await formApi.validate();
      if (!valid) {
        return;
      }
      modalApi.lock();
      const data = (await formApi.getValues()) as MdmItemApi.Item;
      try {
        await (formData.value?.id ? updateItem(data) : createItem(data));
        await modalApi.close();
        emit("success");
        message.success($t("ui.actionMessage.operationSuccess"));
      } finally {
        modalApi.unlock();
      }
    },
    async onOpenChange(isOpen: boolean) {
      if (!isOpen) {
        formData.value = undefined;
        return;
      }
      const data = modalApi.getData<MdmItemApi.Item>();
      if (!data || !data.id) {
        return;
      }
      modalApi.lock();
      try {
        formData.value = await getItem(data.id);
        // 编辑回显时,syncMes 默认为 false
        await formApi.setValues({ ...formData.value, syncMes: false });
      } finally {
        modalApi.unlock();
      }
    },
  });
</script>
<template>
  <Modal class="w-[1000px]" :title="getTitle">
  <Modal class="w-[1000px]"
         :title="getTitle">
    <Form class="mx-4" />
  </Modal>
</template>
vite.config.ts
@@ -8,22 +8,8 @@
        enable: false,
      },
      optimizeDeps: {
        include: [
          "vue",
          "vue-router",
          "pinia",
          "ant-design-vue",
          "dayjs",
          "@vueuse/core",
          "axios",
        ],
        exclude: [
          "dhtmlx-gantt",
          "tinymce",
          "bpmn-js",
          "bpmn-js-properties-panel",
          "video.js",
        ],
        include: ["vue", "vue-router", "pinia", "ant-design-vue", "dayjs", "@vueuse/core", "axios"],
        exclude: ["dhtmlx-gantt", "tinymce", "bpmn-js", "bpmn-js-properties-panel", "video.js"],
      },
      build: {
        rollupOptions: {
@@ -32,11 +18,7 @@
              "vendor-vue": ["vue", "vue-router", "pinia"],
              "vendor-ui": ["ant-design-vue", "@vueuse/core"],
              "vendor-utils": ["dayjs", "axios", "@vee-validate/zod", "zod"],
              "vendor-editor": [
                "tinymce",
                "@tinymce/tinymce-vue",
                "@form-create/ant-design-vue",
              ],
              "vendor-editor": ["tinymce", "@tinymce/tinymce-vue", "@form-create/ant-design-vue"],
            },
          },
        },
@@ -44,13 +26,13 @@
      server: {
        allowedHosts: true,
        watch: {
          ignored: ['**/node_modules/**', '**/dist/**', '**/.git/**'],
          ignored: ["**/node_modules/**", "**/dist/**", "**/.git/**"],
        },
        proxy: {
          "/admin-api": {
            changeOrigin: true,
            rewrite: (path) => path.replace(/^\/admin-api/, ""),
            target: "http://192.168.0.226:48080/admin-api",
            rewrite: path => path.replace(/^\/admin-api/, ""),
            target: "http://192.168.0.244:48080/admin-api",
            ws: true,
          },
        },