gaoluyang
2 天以前 b64a0deae5b5d33f9e20671a68936b27f0b9b00b
src/views/mes/workbench/components/tabs/ProductIssueTab.vue
@@ -3,7 +3,7 @@
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type { MesWmProductIssueApi } from '#/api/mes/wm/productissue';
import { h, markRaw, onBeforeUnmount, onMounted, ref, watch, nextTick } from 'vue';
import { computed, h, markRaw, onBeforeUnmount, onMounted, ref, watch, nextTick } from 'vue';
import {
  DICT_TYPE,
@@ -12,11 +12,11 @@
  MesWmProductIssueStatusEnum,
} from '@vben/constants';
import { IconifyIcon } from '@vben/icons';
import { getDictOptions } from '@vben/hooks';
import { Button, Divider, message, Popconfirm, Tag } from 'ant-design-vue';
import { Button, Divider, Empty, message, Popconfirm, Tag } from 'ant-design-vue';
import { useVbenForm } from '#/adapter/form';
import { useVbenModal } from '@vben/common-ui';
import { useVbenVxeGrid } from '#/adapter/vxe-table';
import { generateAutoCode } from '#/api/mes/md/autocode/record';
import {
@@ -29,7 +29,8 @@
} from '#/api/mes/wm/productissue';
import { MdWorkstationSelect } from '#/views/mes/md/workstation/components';
import { ProWorkOrderSelect } from '#/views/mes/pro/workorder/components';
import { $t } from '#/locales';
import ProductIssueFormModal from './ProductIssueFormModal.vue';
defineOptions({ name: 'WorkbenchProductIssueTab' });
@@ -38,6 +39,14 @@
  workstationId?: number;
  /** 当前工作站名称 */
  workstationName?: string;
  /** 当前选中的任务 ID */
  taskId?: number;
  /** 当前选中的任务编码 */
  taskCode?: string;
  /** 当前选中的任务名称 */
  taskName?: string;
  /** 当前选中的任务关联工单 ID */
  workOrderId?: number;
}>();
// --- 表单状态 ---
@@ -77,19 +86,29 @@
      rules: 'required',
    },
    {
      fieldName: 'taskId',
      label: '生产任务',
      component: 'Input',
      componentProps: {
        placeholder: '从选中任务自动带入',
        disabled: true,
      },
      rules: 'required',
    },
    {
      fieldName: 'workOrderId',
      label: '生产订单',
      component: markRaw(ProWorkOrderSelect),
      componentProps: {
        status: MesProWorkOrderStatusEnum.CONFIRMED,
        disabled: true,
      },
      rules: 'selectRequired',
    },
    {
      fieldName: 'workstationId',
      label: '工作站',
      component: markRaw(MdWorkstationSelect),
      componentProps: { placeholder: '请选择工作站' },
      componentProps: { placeholder: '从选中任务自动带入', disabled: true },
    },
    {
      fieldName: 'requiredTime',
@@ -129,7 +148,13 @@
  isCreating.value = true;
  editingId.value = undefined;
  await formApi.resetForm();
  // 预填工作站
  // 预填任务信息
  if (props.taskId) {
    await formApi.setFieldValue('taskId', props.taskId);
  }
  if (props.workOrderId) {
    await formApi.setFieldValue('workOrderId', props.workOrderId);
  }
  if (props.workstationId) {
    await formApi.setFieldValue('workstationId', props.workstationId);
  }
@@ -165,6 +190,11 @@
  formApi.resetForm();
}
/** 编辑领料单:打开编辑弹窗(仅草稿状态可编辑) */
function handleEditRow(row: MesWmProductIssueApi.ProductIssue) {
  editFormModalApi.setData({ id: row.id }).open();
}
/** 提交 */
async function handleSubmitRow(row: MesWmProductIssueApi.ProductIssue) {
  await submitProductIssue(row.id!);
@@ -190,6 +220,12 @@
const gridColumns: VxeTableGridOptions<MesWmProductIssueApi.ProductIssue>['columns'] = [
  { field: 'code', title: '领料单编号', minWidth: 150 },
  { field: 'name', title: '领料单名称', minWidth: 130 },
  {
    field: 'taskCode',
    title: '生产任务',
    minWidth: 130,
    formatter: ({ row }) => row.taskCode || props.taskCode || '',
  },
  { field: 'workOrderCode', title: '生产订单', minWidth: 130 },
  {
    field: 'requiredTime',
@@ -206,7 +242,7 @@
      props: { type: DICT_TYPE.MES_WM_PRODUCT_ISSUE_STATUS },
    },
  },
  { title: '操作', width: 200, fixed: 'right', slots: { default: 'actions' } },
  { title: '操作', width: 260, fixed: 'right', slots: { default: 'actions' } },
];
const gridHeight = ref(300);
@@ -224,7 +260,7 @@
          return await getProductIssuePage({
            pageNo: page.currentPage,
            pageSize: page.pageSize,
            workstationId: props.workstationId,
            taskId: props.taskId,
            ...formValues,
          });
        },
@@ -261,77 +297,112 @@
  resizeObserver = null;
});
// 工作站变化时刷新列表
// 任务或工作站变化时刷新列表
watch(
  () => props.workstationId,
  () => [props.taskId, props.workstationId],
  () => gridApi.query(),
);
/** 是否已选中工作站和任务,未选中时不展示表格 */
const isReady = computed(() => !!props.taskId && !!props.workstationId);
/** 编辑弹窗 */
const [EditFormModal, editFormModalApi] = useVbenModal({
  connectedComponent: ProductIssueFormModal,
  destroyOnClose: true,
});
/** 编辑弹窗操作成功后刷新列表 */
function onEditSuccess() {
  gridApi.query();
}
</script>
<template>
  <div class="issue-tab">
    <!-- 顶部:表单 / 新建按钮 -->
    <div class="issue-tab__header">
      <div class="issue-tab__header-left">
        <IconifyIcon icon="lucide:clipboard-list" class="issue-tab__icon" />
        <span class="issue-tab__title">领料单</span>
        <Tag v-if="isCreating" color="blue">新建中</Tag>
    <!-- 未选中工作站或任务时显示提示 -->
    <div v-if="!isReady" class="issue-tab__empty">
      <Empty
        :image="Empty.PRESENTED_IMAGE_SIMPLE"
        description="请先在左侧选择工作站和任务"
      />
    </div>
    <template v-else>
      <!-- 顶部:表单 / 新建按钮 -->
      <div class="issue-tab__header">
        <div class="issue-tab__header-left">
          <IconifyIcon icon="lucide:clipboard-list" class="issue-tab__icon" />
          <span class="issue-tab__title">领料单</span>
          <Tag v-if="isCreating" color="blue">新建中</Tag>
        </div>
        <div class="issue-tab__header-actions">
          <template v-if="!isCreating">
            <Button type="primary" size="small" @click="handleCreate">
              <template #icon><IconifyIcon icon="lucide:plus" /></template>
              新建领料单
            </Button>
          </template>
          <template v-else>
            <Button type="primary" size="small" @click="handleSave">
              <template #icon><IconifyIcon icon="lucide:save" /></template>
              保存
            </Button>
            <Button size="small" @click="handleCancelEdit">取消</Button>
          </template>
        </div>
      </div>
      <div class="issue-tab__header-actions">
        <template v-if="!isCreating">
          <Button type="primary" size="small" @click="handleCreate">
            <template #icon><IconifyIcon icon="lucide:plus" /></template>
            新建领料单
          </Button>
        </template>
        <template v-else>
          <Button type="primary" size="small" @click="handleSave">
            <template #icon><IconifyIcon icon="lucide:save" /></template>
            保存
          </Button>
          <Button size="small" @click="handleCancelEdit">取消</Button>
        </template>
      <!-- 表单区域(仅新建时展示) -->
      <div v-if="isCreating" class="issue-tab__form">
        <Form />
      </div>
    </div>
    <!-- 表单区域(仅新建时展示) -->
    <div v-if="isCreating" class="issue-tab__form">
      <Form />
    </div>
      <Divider style="margin: 12px 0" />
    <Divider style="margin: 12px 0" />
      <!-- 底部:领料记录列表 -->
      <div ref="listRef" class="issue-tab__list">
        <Grid table-title="领料记录">
          <template #actions="{ row }">
            <Button
              v-if="row.status === MesWmProductIssueStatusEnum.PREPARE"
              type="link"
              size="small"
              @click="handleEditRow(row)"
            >
              编辑
            </Button>
            <Popconfirm
              v-if="row.status === MesWmProductIssueStatusEnum.PREPARE"
              title="确认提交?提交后不能修改"
              @confirm="handleSubmitRow(row)"
            >
              <Button type="link" size="small">提交</Button>
            </Popconfirm>
            <Popconfirm
              v-if="row.status === MesWmProductIssueStatusEnum.PREPARE"
              :title="`确认删除 ${row.code}?`"
              @confirm="handleDeleteRow(row)"
            >
              <Button type="link" size="small" danger>删除</Button>
            </Popconfirm>
            <Popconfirm
              v-if="
                row.status === MesWmProductIssueStatusEnum.APPROVING ||
                row.status === MesWmProductIssueStatusEnum.APPROVED
              "
              title="确认取消?取消后不可恢复"
              @confirm="handleCancelRow(row)"
            >
              <Button type="link" size="small" danger>取消</Button>
            </Popconfirm>
          </template>
        </Grid>
      </div>
    <!-- 底部:领料记录列表 -->
    <div ref="listRef" class="issue-tab__list">
      <Grid table-title="领料记录">
        <template #actions="{ row }">
          <Popconfirm
            v-if="row.status === MesWmProductIssueStatusEnum.PREPARE"
            title="确认提交?提交后不能修改"
            @confirm="handleSubmitRow(row)"
          >
            <Button type="link" size="small">提交</Button>
          </Popconfirm>
          <Popconfirm
            v-if="row.status === MesWmProductIssueStatusEnum.PREPARE"
            :title="`确认删除 ${row.code}?`"
            @confirm="handleDeleteRow(row)"
          >
            <Button type="link" size="small" danger>删除</Button>
          </Popconfirm>
          <Popconfirm
            v-if="
              row.status === MesWmProductIssueStatusEnum.APPROVING ||
              row.status === MesWmProductIssueStatusEnum.APPROVED
            "
            title="确认取消?取消后不可恢复"
            @confirm="handleCancelRow(row)"
          >
            <Button type="link" size="small" danger>取消</Button>
          </Popconfirm>
        </template>
      </Grid>
    </div>
    </template>
    <!-- 编辑弹窗 -->
    <EditFormModal @success="onEditSuccess" />
  </div>
</template>
@@ -386,4 +457,11 @@
  min-height: 0;
  overflow: hidden;
}
.issue-tab__empty {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}
</style>