Merge remote-tracking branch 'origin/dev_新疆_新高电力' into dev_新疆_新高电力
已修改8个文件
133 ■■■■■ 文件已修改
src/api/mdm/item/index.ts 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/mes/pro/workorder/bom/index.ts 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/basicData/mdm/components/select-dialog.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/basicData/mdm/components/select.vue 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mes/pro/task/modules/schedule-form.vue 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mes/qc/template/data.ts 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mes/qc/template/modules/item-form.vue 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mes/workbench/components/tabs/ProductIssueLineFormModal.vue 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/mdm/item/index.ts
@@ -53,6 +53,7 @@
  /** 物料分页查询参数 */
  export interface PageParams extends PageParam {
    excludeIds?: string;
    code?: string;
    name?: string;
    categoryId?: number;
src/api/mes/pro/workorder/bom/index.ts
@@ -60,3 +60,11 @@
    `/mes/pro/work-order-bom/item-list-by-work-order-id?workOrderId=${workOrderId}`,
  );
}
/** 查询生产任务所在工序的投入物料 */
export function getWorkOrderBomListByTaskId(taskId: number) {
  return requestClient.get<MesProWorkOrderBomApi.WorkOrderBom[]>(
    '/mes/pro/work-order-bom/list-by-task-id',
    { params: { taskId } },
  );
}
src/views/basicData/mdm/components/select-dialog.vue
@@ -27,6 +27,7 @@
const selectedRows = ref<MdmItemApi.Item[]>([]); // 已选物料列表
const preSelectedIds = ref<number[]>([]); // 预选物料编号列表
const categoryList = ref<MesMdItemTypeApi.ItemType[]>([]); // 分类列表缓存
const excludeIds = ref<number[]>([]);
const TAG_COLORS = ['green', 'orange', 'blue', 'purple', 'cyan', 'magenta', 'geekblue', 'volcano', 'gold', 'lime'] as const;
@@ -149,6 +150,7 @@
            pageNo: page.currentPage,
            pageSize: page.pageSize,
            ...formValues,
            excludeIds: excludeIds.value.length ? excludeIds.value.join(',') : undefined,
          });
        },
      },
@@ -184,11 +186,12 @@
/** 打开物料选择弹窗 */
async function openModal(
  selectedIds?: number[],
  options?: { multiple?: boolean },
  options?: { multiple?: boolean; excludeIds?: number[] },
) {
  open.value = true;
  multiple.value = options?.multiple ?? true;
  preSelectedIds.value = selectedIds || [];
  excludeIds.value = options?.excludeIds || [];
  await nextTick();
  gridApi.setGridOptions({
    columns: useMdmItemSelectGridColumns(multiple.value),
src/views/basicData/mdm/components/select.vue
@@ -20,6 +20,7 @@
    modelValue?: number;
    placeholder?: string;
    label?: string;
    excludeIds?: number[];
  }>(),
  {
    allowClear: true,
@@ -88,7 +89,7 @@
  const selectedIds = (
    props.modelValue === null ? [] : [props.modelValue]
  ) as number[];
  dialogRef.value?.open(selectedIds, { multiple: false });
  dialogRef.value?.open(selectedIds, { multiple: false, excludeIds: props.excludeIds });
}
/** 回填选中的物料 */
src/views/mes/pro/task/modules/schedule-form.vue
@@ -6,17 +6,16 @@
import { useVbenModal } from '@vben/common-ui';
import { Button, Card, message, Popconfirm, Steps } from 'ant-design-vue';
import { Card, message, Steps } from 'ant-design-vue';
import { useVbenForm } from '#/adapter/form';
import { getRouteProcessListByProduct } from '#/api/mes/pro/route/process';
import { finishWorkOrder, getWorkOrder } from '#/api/mes/pro/workorder';
import { getWorkOrder } from '#/api/mes/pro/workorder';
import { getWorkOrderProcessListByWorkOrderId } from '#/api/mes/pro/workorder/process';
import { useScheduleFormSchema } from '../data';
import TaskList from './task-list.vue';
const emit = defineEmits(['success']);
const formType = ref<'detail' | 'schedule'>('schedule');
const workOrder = ref<MesProWorkOrderApi.WorkOrder>(); // 当前订单详情
/** 排产工序列表 */
@@ -63,22 +62,6 @@
  routeProcessList.value = [...woProcesses].toSorted(
    (a, b) => (a.sort ?? 0) - (b.sort ?? 0),
  );
}
/** 完成订单 */
async function handleFinish() {
  if (!workOrder.value?.id) {
    return;
  }
  modalApi.lock();
  try {
    await finishWorkOrder(workOrder.value.id);
    message.success('订单已完成');
    await modalApi.close();
    emit('success');
  } finally {
    modalApi.unlock();
  }
}
const [Modal, modalApi] = useVbenModal({
@@ -150,22 +133,6 @@
          />
        </Card>
      </template>
    </template>
    <template #prepend-footer>
      <div class="flex flex-auto items-center gap-2">
        <template v-if="formType === 'schedule'">
          <Popconfirm
            v-if="routeProcessList.length > 0"
            title="确认要完成该订单吗?完成后订单下所有任务将标记为已完成。"
            @confirm="handleFinish"
          >
            <Button type="primary">完成</Button>
          </Popconfirm>
          <span v-else class="text-gray-400 text-sm">
            当前订单未配置工序,请先在工单中维护工序信息后再完成
          </span>
        </template>
      </div>
    </template>
  </Modal>
</template>
src/views/mes/qc/template/data.ts
@@ -17,7 +17,7 @@
import { z } from '#/adapter/form';
import { generateAutoCode } from '#/api/mes/md/autocode/record';
import { getItemPage } from '#/api/mdm/item';
import { MdmItemSelect } from '#/views/basicData/mdm/components';
import { MdUnitMeasureSelect } from '#/views/mes/md/unitmeasure/components';
import { QcIndicatorSelect } from '#/views/mes/qc/indicator/components';
@@ -408,7 +408,7 @@
}
/** 产品关联子表的表单 */
export function useItemFormSchema(): VbenFormSchema[] {
export function useItemFormSchema(excludeIds: number[] = []): VbenFormSchema[] {
  return [
    {
      fieldName: 'id',
@@ -421,19 +421,11 @@
    {
      fieldName: 'itemId',
      label: '产品物料',
      component: 'ApiSelect',
      component: markRaw(MdmItemSelect),
      componentProps: {
        placeholder: '请选择产品物料',
        allowClear: true,
        showSearch: true,
        api: getItemPage,
        resultField: 'list',
        labelField: 'name',
        valueField: 'id',
        optionRender: (option: any) => {
          const item = option.data;
          return `${item.code} - ${item.name}`;
        },
        excludeIds,
      },
      formItemClass: 'col-span-3',
      rules: 'required',
src/views/mes/qc/template/modules/item-form.vue
@@ -11,6 +11,7 @@
import {
  createTemplateItem,
  getTemplateItem,
  getTemplateItemPage,
  updateTemplateItem,
} from '#/api/mes/qc/template/item';
import { $t } from '#/locales';
@@ -74,14 +75,26 @@
      MesQcTemplateItemApi.TemplateItem & { templateId: number }
    >();
    templateId.value = data.templateId;
    if (!data?.id) {
      return;
    }
    modalApi.lock();
    try {
      formData.value = await getTemplateItem(data.id);
      formData.value = data.id ? await getTemplateItem(data.id) : undefined;
      const boundItems: MesQcTemplateItemApi.TemplateItem[] = [];
      let pageNo = 1;
      const pageSize = 200;
      let total: number;
      do {
        const page = await getTemplateItemPage({ templateId: data.templateId, pageNo, pageSize });
        boundItems.push(...page.list);
        total = page.total;
        pageNo++;
        if (page.list.length === 0) break;
      } while (boundItems.length < total);
      const excludeIds = boundItems
        .filter(item => item.id !== data.id && item.itemId != null)
        .map(item => item.itemId!);
      await formApi.updateSchema(useItemFormSchema(excludeIds));
      // 设置到 values
      await formApi.setValues(formData.value);
      if (formData.value) await formApi.setValues(formData.value);
    } finally {
      modalApi.unlock();
    }
src/views/mes/workbench/components/tabs/ProductIssueLineFormModal.vue
@@ -2,19 +2,20 @@
import type { VbenFormSchema } from '#/adapter/form';
import type { MesWmProductIssueLineApi } from '#/api/mes/wm/productissue/line';
import { computed, markRaw, ref } from 'vue';
import { computed, ref } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { message } from 'ant-design-vue';
import { useVbenForm } from '#/adapter/form';
import { getWorkOrderBomListByTaskId } from '#/api/mes/pro/workorder/bom';
import { getProductIssue } from '#/api/mes/wm/productissue';
import {
  createProductIssueLine,
  getProductIssueLine,
  updateProductIssueLine,
} from '#/api/mes/wm/productissue/line';
import { MdItemSelect } from '#/views/mes/md/item/components';
const emit = defineEmits(['success']);
const formData = ref<MesWmProductIssueLineApi.ProductIssueLine>();
@@ -25,13 +26,18 @@
});
/** 物料行表单 schema */
function buildLineFormSchema(): VbenFormSchema[] {
function buildLineFormSchema(options: { label: string; value: number }[] = []): VbenFormSchema[] {
  return [
    {
      fieldName: 'itemId',
      label: '产品物料',
      component: markRaw(MdItemSelect),
      componentProps: { placeholder: '请选择产品物料' },
      component: 'Select',
      componentProps: {
        options,
        showSearch: true,
        optionFilterProp: 'label',
        placeholder: options.length ? '请选择当前工序物料' : '请先维护当前工序投入物料',
      },
      rules: 'selectRequired',
    },
    {
@@ -91,14 +97,26 @@
    }
    const data = modalApi.getData<{ id?: number; issueId: number }>();
    issueId.value = data.issueId;
    if (!data.id) {
      await formApi.resetForm();
      return;
    }
    modalApi.lock();
    try {
      formData.value = await getProductIssueLine(data.id);
      await formApi.setValues(formData.value);
      const issue = await getProductIssue(data.issueId);
      const boms = issue.taskId ? await getWorkOrderBomListByTaskId(issue.taskId) : [];
      const optionMap = new Map<number, { label: string; value: number }>();
      for (const item of boms) {
        if (item.itemId != null) {
          optionMap.set(item.itemId, {
            value: item.itemId,
            label: `${item.itemCode ?? ''} ${item.itemName ?? ''}`.trim(),
          });
        }
      }
      const options = [...optionMap.values()];
      await formApi.updateSchema(buildLineFormSchema(options));
      await formApi.resetForm();
      if (data.id) {
        formData.value = await getProductIssueLine(data.id);
        await formApi.setValues(formData.value);
      }
    } finally {
      modalApi.unlock();
    }