5 天以前 91c82965b2d987452ca276e3a03b48c8dcda2ae9
src/views/mes/pro/task/data.ts
@@ -1,14 +1,21 @@
import type { VbenFormApi, VbenFormSchema } from '#/adapter/form';
import type { VbenFormApi, VbenFormSchema } from '#/adapter/form';
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import { z } from '#/adapter/form';
import { getSimpleUserListByRoleCode } from '#/api/system/user';
import type { MesProTaskApi } from '#/api/mes/pro/task';
import type { MesProWorkOrderApi } from '#/api/mes/pro/workorder';
import type { Ref } from 'vue';
import { markRaw } from 'vue';
import { DICT_TYPE } from '@vben/constants';
import { getDictOptions } from '@vben/hooks';
import { message } from 'ant-design-vue';
import CrmCustomerSelect from '#/components/crm-customer-select.vue';
import { calculateTaskDuration } from '#/api/mes/pro/task';
import { getRangePickerDefaultProps } from '#/utils';
import { MdItemSelect } from '#/views/mes/md/item/components';
import { MdWorkstationSelect } from '#/views/mes/md/workstation/components';
@@ -125,15 +132,33 @@
      width: 80,
    },
    {
      field: 'status',
      title: '订单状态',
      width: 100,
      cellRender: {
        name: 'CellDict',
        props: { type: DICT_TYPE.MES_PRO_WORK_ORDER_STATUS },
      },
    },
    {
      field: 'productionStatus',
      title: '生产状态',
      width: 100,
      cellRender: {
        name: 'CellDict',
        props: { type: DICT_TYPE.ORDER_PRODUCTION_STATUS },
      },
    },
    {
      field: 'quantity',
      title: '订单数量',
      width: 100,
    },
    {
      field: 'quantityChanged',
      title: '调整数量',
      width: 100,
    },
    // {
    //   field: 'quantityChanged',
    //   title: '调整数量',
    //   width: 100,
    // },
    {
      field: 'quantityProduced',
      title: '已生产数量',
@@ -155,18 +180,10 @@
      width: 120,
      formatter: 'formatDate',
    },
    {
      field: 'status',
      title: '排产状态',
      width: 100,
      cellRender: {
        name: 'CellDict',
        props: { type: DICT_TYPE.MES_PRO_WORK_ORDER_STATUS },
      },
    },
    {
      title: '操作',
      width: 100,
      width: 160,
      fixed: 'right',
      slots: { default: 'actions' },
    },
@@ -279,7 +296,7 @@
        class: '!w-full',
        disabled: true,
        format: 'YYYY-MM-DD',
        valueFormat: 'x',
        valueFormat: 'YYYY-MM-DD',
      },
    },
    {
@@ -376,7 +393,7 @@
}
/** 生产任务新增/修改的表单 */
export function useTaskFormSchema(formApi?: VbenFormApi): VbenFormSchema[] {
export function useTaskFormSchema(formApi?: VbenFormApi, workOrderQuantity?: Ref<number | undefined>): VbenFormSchema[] {
  return [
    {
      fieldName: 'workstationId',
@@ -384,6 +401,7 @@
      component: markRaw(MdWorkstationSelect),
      componentProps: {
        placeholder: '请选择工作站',
        onChange: () => recalcDuration(formApi),
      },
      rules: 'selectRequired',
    },
@@ -391,11 +409,13 @@
      fieldName: 'quantity',
      label: '排产数量',
      component: 'InputNumber',
      description: () => workOrderQuantity?.value != null ? `订单数量:${workOrderQuantity.value}` : '',
      componentProps: {
        class: '!w-full',
        min: 0.01,
        placeholder: '请输入排产数量',
        precision: 2,
        onChange: () => recalcDuration(formApi),
      },
      rules: 'required',
    },
@@ -410,11 +430,17 @@
      component: 'DatePicker',
      componentProps: {
        class: '!w-full',
        placeholder: '请选择开始时间',
        placeholder: '请先选择工作站',
        showTime: true,
        valueFormat: 'x',
        // 开始时间变更:重新计算结束时间
        valueFormat: 'YYYY-MM-DD HH:mm:ss',
        onChange: () => recalcEndTime(formApi),
      },
      dependencies: {
        triggerFields: ['workstationId'],
        componentProps: (values) => ({
          disabled: !values.workstationId,
          placeholder: values.workstationId ? '请选择开始时间' : '请先选择工作站',
        }),
      },
      rules: 'required',
    },
@@ -440,8 +466,22 @@
        class: '!w-full',
        disabled: true,
        showTime: true,
        valueFormat: 'x',
        valueFormat: 'YYYY-MM-DD HH:mm:ss',
      },
    },
    {
      fieldName: 'assigneeUserIds',
      label: '报工人',
      component: 'ApiSelect',
      componentProps: {
        placeholder: '请选择报工人',
        api: getSimpleUserListByRoleCode,
        params: { code: 'production_submit_work' },
        labelField: 'nickname',
        valueField: 'id',
        mode: 'multiple',
      },
      rules: z.array(z.number()).min(1, '请选择报工人').default([]),
    },
    {
      fieldName: 'remark',
@@ -456,6 +496,24 @@
  ];
}
/** 选择工作站或修改数量后,自动计算生产时长 */
async function recalcDuration(formApi?: VbenFormApi) {
  if (!formApi) return;
  const values = await formApi.getValues();
  if (!values.workstationId || !values.quantity) return;
  try {
    const res = await calculateTaskDuration(values.workstationId, values.quantity);
    await formApi.setFieldValue('duration', res.duration);
    if (res.duration === 0) {
      message.warning('该工作站未绑定设备,或绑定设备未配置生产效率');
    }
    // 重新计算结束时间
    await recalcEndTime(formApi);
  } catch {
    // 计算失败不阻塞用户操作
  }
}
/** 计算结束时间:开始时间 + 生产时长(小时) */
async function recalcEndTime(formApi?: VbenFormApi) {
  if (!formApi) {
@@ -463,11 +521,12 @@
  }
  const values = await formApi.getValues();
  if (values.startTime && values.duration) {
    const start = Number(values.startTime);
    await formApi.setFieldValue(
      'endTime',
      start + values.duration * 3600 * 1000,
    );
    const start = new Date(values.startTime).getTime();
    const endTime = start + values.duration * 3600 * 1000;
    const pad = (n: number) => String(n).padStart(2, '0');
    const d = new Date(endTime);
    const formatted = `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;
    await formApi.setFieldValue('endTime', formatted);
  }
}