19 小时以前 46b2ae1c889e181ebe186de3758fc09804696029
src/views/mes/pro/workorder/modules/process-list.vue
@@ -5,11 +5,13 @@
import type { MesProWorkOrderApi } from '#/api/mes/pro/workorder';
import type { MesProWorkOrderProcessApi } from '#/api/mes/pro/workorder/process';
import { computed, ref, watch } from 'vue';
import { computed, nextTick, onUnmounted, ref, watch } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { MesProWorkOrderStatusEnum } from '@vben/constants';
import { IconifyIcon } from '@vben/icons';
import { useSortable } from '@vueuse/integrations/useSortable';
import { message, Tag } from 'ant-design-vue';
import { TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
@@ -45,6 +47,9 @@
const isCreateMode = computed(() => props.formType === 'create');
// 拖拽排序
const sortableInstance = ref<any>(null);
const [ProcessFormModal, processFormModalApi] = useVbenModal({
  connectedComponent: ProcessForm,
  destroyOnClose: true,
@@ -54,7 +59,7 @@
  gridOptions: {
    autoResize: true,
    border: true,
    columns: useProcessGridColumns(),
    columns: useProcessGridColumns(isEditable.value),
    data: [],
    minHeight: 240,
    pagerConfig: { enabled: false },
@@ -63,6 +68,50 @@
    toolbarConfig: { enabled: false },
  } as VxeTableGridOptions<MesProWorkOrderProcessApi.WorkOrderProcess>,
});
/** 初始化/销毁拖拽排序 */
async function initSortable() {
  destroySortable();
  if (!isEditable.value || list.value.length === 0) return;
  await nextTick();
  sortableInstance.value = useSortable(
    '.workorder-process-list .vxe-table--body-wrapper:not(.fixed-right--wrapper) .vxe-table--body tbody',
    list.value,
    {
      animation: 150,
      draggable: '.vxe-body--row',
      handle: '.drag-handle',
      onEnd: ({ newDraggableIndex, oldDraggableIndex }) => {
        if (
          newDraggableIndex !== undefined &&
          oldDraggableIndex !== undefined &&
          oldDraggableIndex !== newDraggableIndex
        ) {
          // 重新排序数组
          list.value.splice(
            newDraggableIndex,
            0,
            list.value.splice(oldDraggableIndex, 1)[0]!,
          );
          // 更新 sort 字段
          list.value.forEach((item, index) => {
            item.sort = index + 1;
          });
          gridApi.setGridOptions({ data: list.value });
          emit('processListChange', list.value);
        }
      },
    },
  );
}
/** 销毁拖拽排序实例 */
function destroySortable() {
  if (sortableInstance.value) {
    sortableInstance.value.stop?.();
    sortableInstance.value = null;
  }
}
/** 加载工序列表 */
async function getList() {
@@ -106,6 +155,8 @@
    }
    gridApi.setGridOptions({ data: list.value });
    emit('processListChange', list.value);
    // 初始化拖拽排序
    initSortable();
  } finally {
    gridApi.setLoading(false);
  }
@@ -135,25 +186,6 @@
    .open();
}
/** 删除工序 */
function handleDelete(row: MesProWorkOrderProcessApi.WorkOrderProcess) {
  if (isCreateMode.value) {
    // 新增模式:从列表删除
    const index = list.value.findIndex((item) => item.processId === row.processId);
    if (index > -1) {
      list.value.splice(index, 1);
      gridApi.setGridOptions({ data: list.value });
      emit('processListChange', list.value);
    }
  } else {
    // 编辑模式:调用接口删除
    deleteWorkOrderProcess(row.id!).then(() => {
      message.success($t('ui.actionMessage.deleteSuccess', [row.processName]));
      getList();
    });
  }
}
/** 新增/编辑成功回调 */
function handleFormSuccess(data: MesProWorkOrderProcessApi.WorkOrderProcess, isEdit: boolean) {
  if (isCreateMode.value) {
@@ -167,10 +199,40 @@
    }
    gridApi.setGridOptions({ data: list.value });
    emit('processListChange', list.value);
    initSortable();
  } else {
    getList();
  }
}
/** 删除工序 */
function handleDelete(row: MesProWorkOrderProcessApi.WorkOrderProcess) {
  if (isCreateMode.value) {
    // 新增模式:从列表删除
    const index = list.value.findIndex((item) => item.processId === row.processId);
    if (index > -1) {
      list.value.splice(index, 1);
      // 更新 sort 字段
      list.value.forEach((item, idx) => {
        item.sort = idx + 1;
      });
      gridApi.setGridOptions({ data: list.value });
      emit('processListChange', list.value);
      initSortable();
    }
  } else {
    // 编辑模式:调用接口删除
    deleteWorkOrderProcess(row.id!).then(() => {
      message.success($t('ui.actionMessage.deleteSuccess', [row.processName]));
      getList();
    });
  }
}
// 组件卸载时销毁排序实例
onUnmounted(() => {
  destroySortable();
});
// 监听产品/工单变化
watch(
@@ -183,7 +245,7 @@
</script>
<template>
  <div>
  <div class="workorder-process-list">
    <ProcessFormModal @success="handleFormSuccess" />
    <div v-if="isEditable" class="mb-3 flex items-center justify-start">
      <TableAction
@@ -197,6 +259,12 @@
      />
    </div>
    <Grid class="w-full" table-title="工序">
      <template #dragHandle>
        <IconifyIcon
          icon="ic:round-drag-indicator"
          class="drag-handle cursor-move text-xl text-gray-400"
        />
      </template>
      <template #keyFlag="{ row }">
        <Tag v-if="row.keyFlag" color="red">关键</Tag>
        <span v-else>-</span>