云
7 小时以前 5d321660a2f1a4b8756f816283e96481a8c934e4
src/views/mes/pro/batch/data.ts
@@ -16,14 +16,68 @@
/** 未绑定托盘下拉选项 */
export interface PalletOption {
  disabled?: boolean;
  itemCode?: string;
  itemId?: number;
  itemName?: string;
  label: string;
  value: number;
}
export type TonBagOption = PalletOption;
/** 绑定类型(托盘/吨袋互斥,编辑补录时按已有绑定锁定其中一方) */
export type BindingMode = 'pallet' | 'tonBag';
/** 托盘、吨袋下拉的交互事件(支持远程搜索与滚动分页加载) */
export interface BindingSelectHandlers {
  onChange?: (ids: number[]) => void;
  onPopupScroll?: (event: Event) => void;
  onSearch?: (keyword: string) => void;
}
/**
 * 刷新托盘选项禁用态。
 *
 * 下拉已改为分页加载,选项数组本身就是渲染数据源,因此禁用态直接写到选项对象上,
 * 每次加载新一页或表单值变化时重算,避免依赖机制里做数组映射导致新加载的数据被旧快照覆盖。
 */
export function applyPalletOptionState(
  options: PalletOption[],
  values: Record<string, any>,
  existingBinding?: BindingMode,
) {
  options.forEach((option) => {
    option.disabled =
      existingBinding === 'tonBag' ||
      !!values.tonBagIds?.length ||
      !option.itemId ||
      (!!values.itemId && option.itemId !== values.itemId);
  });
}
/** 刷新吨袋选项禁用态,规则与 {@link applyPalletOptionState} 对称 */
export function applyTonBagOptionState(
  options: TonBagOption[],
  values: Record<string, any>,
  existingBinding?: BindingMode,
) {
  options.forEach((option) => {
    option.disabled =
      existingBinding === 'pallet' ||
      !!values.palletIds?.length ||
      (!!values.itemId && option.itemId !== values.itemId);
  });
}
/** 新增/修改的表单 */
export function useFormSchema(
  formType: FormType,
  palletOptions: PalletOption[] = [],
  palletHandlers: BindingSelectHandlers = {},
  tonBagOptions: TonBagOption[] = [],
  tonBagHandlers: BindingSelectHandlers = {},
  existingBinding?: BindingMode,
): VbenFormSchema[] {
  const disabled = formType === 'detail';
  return [
@@ -132,6 +186,18 @@
      rules: 'selectRequired',
    },
    {
      fieldName: 'itemId', component: 'Input',
      dependencies: { triggerFields: [''], show: () => false },
    },
    {
      fieldName: 'itemName', label: '品种名称', component: 'Input',
      componentProps: { disabled: true, placeholder: '选择托盘或吨袋后自动带入' },
    },
    {
      fieldName: 'itemCode', label: '品种编码', component: 'Input',
      componentProps: { disabled: true, placeholder: '选择托盘或吨袋后自动带入' },
    },
    {
      fieldName: 'palletIds',
      label: '绑定托盘',
      component: 'Select',
@@ -139,17 +205,59 @@
        allowClear: true,
        disabled,
        maxTagCount: 3,
        dropdownMatchSelectWidth: false,
        dropdownStyle: { minWidth: '360px', maxWidth: 'calc(100vw - 32px)' },
        mode: 'multiple',
        optionFilterProp: 'label',
        options: palletOptions,
        placeholder: '请选择托盘(可不选)',
        filterOption: false,
        ...palletHandlers,
        placeholder: '请选择相同品种的托盘',
        showSearch: true,
      },
      dependencies: {
        triggerFields: [''],
        triggerFields: ['itemId', 'tonBagIds'],
        show: () => formType !== 'detail',
        componentProps: (values) => {
          applyPalletOptionState(palletOptions, values, existingBinding);
          return {
            options: palletOptions,
            disabled: disabled || existingBinding === 'tonBag' || !!values.tonBagIds?.length,
          };
        },
      },
      help: '绑定后批次直接进入生产中:托盘生成正式托盘码,托盘下未录批次的袋码自动级联录入本批次(袋码品种须一致);编辑时仅需勾选新增托盘,已绑定的不可解绑',
      help: '只能绑定相同品种的托盘,品种信息自动带入;缺少品种的托盘请先装袋。绑定后批次直接进入生产中:托盘生成正式托盘码,托盘下未录批次的袋码自动级联录入本批次(袋码品种须一致);编辑时仅需勾选新增托盘,已绑定的不可解绑',
    },
    {
      fieldName: 'tonBagIds',
      label: '绑定吨袋',
      component: 'Select',
      componentProps: {
        allowClear: true,
        disabled,
        maxTagCount: 3,
        dropdownMatchSelectWidth: false,
        dropdownStyle: { minWidth: '380px', maxWidth: 'calc(100vw - 32px)' },
        mode: 'multiple',
        optionFilterProp: 'label',
        options: tonBagOptions,
        filterOption: false,
        ...tonBagHandlers,
        placeholder: '请选择相同品种的吨袋',
        showSearch: true,
      },
      dependencies: {
        triggerFields: ['itemId', 'palletIds'],
        show: () => formType !== 'detail',
        componentProps: (values) => {
          applyTonBagOptionState(tonBagOptions, values, existingBinding);
          return {
            options: tonBagOptions,
            disabled: disabled || existingBinding === 'pallet' || !!values.palletIds?.length,
          };
        },
      },
      help: '仅可绑定计量单位为吨、无托盘且未录入批次的袋码;与绑定托盘互斥。编辑时仅选择新增吨袋,已绑定的不可解绑',
    },
    {
      fieldName: 'remark',
@@ -168,6 +276,7 @@
/** 列表的搜索表单 */
export function useGridFormSchema(): VbenFormSchema[] {
  return [
    { fieldName: 'businessCode', label: '业务码', component: 'Input', componentProps: { allowClear: true, placeholder: '请输入作业扫码业务码' } },
    {
      fieldName: 'code',
      label: '批次号',
@@ -237,6 +346,7 @@
/** 列表的字段 */
export function useGridColumns(): VxeTableGridOptions<MesProBatchApi.Batch>['columns'] {
  return [
    { field: 'businessCode', title: '业务码(作业扫码)', minWidth: 210 },
    {
      field: 'code',
      title: '批次号',
@@ -244,6 +354,8 @@
      minWidth: 200,
      slots: { default: 'code' },
    },
    { field: 'itemName', title: '品种名称', minWidth: 150 },
    { field: 'itemCode', title: '品种编码', minWidth: 150 },
    {
      field: 'lineName',
      title: '加工单位',