6 天以前 91c82965b2d987452ca276e3a03b48c8dcda2ae9
src/views/mes/pd/project/detail/index.vue
@@ -9,22 +9,25 @@
import { useTabs } from '#/packages/effects/hooks/src';
import { MesPdProjectStatusEnum } from '#/packages/constants/src';
import { Card, Tabs } from 'ant-design-vue';
import { Card, message, Tabs } from 'ant-design-vue';
import {
  archivePdProject,
  getPdProject,
  getPdProjectApproveProcessList,
  publishPdProject,
  uploadPdProject,
} from '#/api/mes/pd/project';
import { useDescription } from '#/components/description';
import { ACTION_ICON, TableAction } from '#/adapter/vxe-table';
import { $t } from '#/locales';
import Form from '../modules/form.vue';
import PublishForm from '../modules/publish-form.vue';
import WorkflowActionForm from '../modules/workflow-action-form.vue';
import ReviewList from '../modules/drawing-review/review-list.vue';
import MaterialPanel from '../modules/material-panel.vue';
import TaskDraftBanner from '../modules/task-draft-banner.vue';
import DocumentAuditList from '../modules/document-audit-list.vue';
import DocumentList from '../modules/document-list.vue';
import ProcessSelectModal from '../modules/process-select-modal.vue';
import WorkflowTimeline from '../modules/workflow-timeline.vue';
import TaskDraftBanner from '../modules/task-draft-banner.vue';
import { useDetailSchema } from './data';
const route = useRoute();
@@ -35,37 +38,32 @@
const projectId = ref(0);
const project = ref<MesPdProjectApi.Project>({});
const activeTab = ref('workflow');
const workflowKey = ref(0);
const isDraft = computed(
  () => project.value.status === MesPdProjectStatusEnum.DRAFT,
const isPendingPublish = computed(
  () => project.value.status === MesPdProjectStatusEnum.PENDING_PUBLISH,
);
const isDesigning = computed(
  () => project.value.status === MesPdProjectStatusEnum.DESIGNING,
const isPendingUpload = computed(
  () => project.value.status === MesPdProjectStatusEnum.PENDING_UPLOAD,
);
const isReviewing = computed(
  () => project.value.status === MesPdProjectStatusEnum.REVIEWING,
const isPendingAudit = computed(
  () => project.value.status === MesPdProjectStatusEnum.PENDING_AUDIT,
);
const isApproved = computed(
  () => project.value.status === MesPdProjectStatusEnum.APPROVED,
const isPendingArchive = computed(
  () => project.value.status === MesPdProjectStatusEnum.PENDING_ARCHIVE,
);
const isApproving = computed(
  () => project.value.status === MesPdProjectStatusEnum.APPROVING,
);
const isArchived = computed(
  () => project.value.status === MesPdProjectStatusEnum.ARCHIVED,
);
const isFormEditable = computed(
  () =>
    !isArchived.value &&
    project.value.status !== MesPdProjectStatusEnum.CANCELLED &&
    (isDraft.value || isDesigning.value),
  () => isPendingPublish.value,
);
const materialFormType = computed<FormType>(() =>
  isDesigning.value ? 'update' : 'detail',
);
const showReviewTab = computed(
  () => isReviewing.value || isApproved.value || isArchived.value,
  isPendingPublish.value || isPendingUpload.value ? 'update' : 'detail',
);
const [Descriptions] = useDescription({
@@ -79,13 +77,8 @@
  destroyOnClose: true,
});
const [PublishModal, publishModalApi] = useVbenModal({
  connectedComponent: PublishForm,
  destroyOnClose: true,
});
const [WorkflowActionModal, workflowActionModalApi] = useVbenModal({
  connectedComponent: WorkflowActionForm,
const [ProcessModal, processModalApi] = useVbenModal({
  connectedComponent: ProcessSelectModal,
  destroyOnClose: true,
});
@@ -93,11 +86,10 @@
  loading.value = true;
  try {
    project.value = await getPdProject(projectId.value);
    workflowKey.value += 1;
    if (isDesigning.value) {
    if (isPendingUpload.value) {
      activeTab.value = 'material';
    } else if (isReviewing.value) {
      activeTab.value = 'review';
    } else if (isPendingAudit.value) {
      activeTab.value = 'audit';
    }
  } finally {
    loading.value = false;
@@ -113,12 +105,72 @@
  formModalApi.setData({ formType: 'update', id: projectId.value }).open();
}
function handlePublish() {
  publishModalApi.setData({ id: projectId.value }).open();
async function handlePublish() {
  const hideLoading = message.loading({ content: '发布中…', duration: 0 });
  try {
    await publishPdProject(projectId.value);
    message.success('任务已发布,进入待上传状态');
    loadProjectDetail();
  } finally {
    hideLoading();
  }
}
function handleWorkflowAction(action: 'approve' | 'archive' | 'submit-review') {
  workflowActionModalApi.setData({ id: projectId.value, action }).open();
async function handleUpload() {
  const hideLoading = message.loading({ content: '提交审核中…', duration: 0 });
  try {
    await uploadPdProject(projectId.value);
    message.success('已提交资料审核');
    tabs.closeCurrentTab();
    router.back();
  } finally {
    hideLoading();
  }
}
/** 提交审批 - 先获取流程列表 */
async function handleSubmit() {
  const hideLoading = message.loading({ content: '获取审批流程...', duration: 0 });
  try {
    const processList = await getPdProjectApproveProcessList();
    hideLoading();
    if (!processList || processList.length === 0) {
      message.warning('暂无可用审批流程,请先配置 BPM 流程');
      return;
    }
    // 打开流程选择弹窗
    processModalApi.setData({ id: projectId.value, processList }).open();
  } catch {
    hideLoading();
  }
}
/** 查看审批详情 */
function handleProcessDetail() {
  if (!project.value.processInstanceId) {
    message.warning('该项目尚未提交审批');
    return;
  }
  router.push({
    name: 'BpmProcessInstanceDetail',
    query: { id: project.value.processInstanceId },
  });
}
/** 提交审批成功后刷新详情 */
function handleSubmitSuccess() {
  loadProjectDetail();
}
async function handleArchive() {
  const hideLoading = message.loading({ content: '归档中…', duration: 0 });
  try {
    await archivePdProject(projectId.value);
    message.success('已归档');
    loadProjectDetail();
  } finally {
    hideLoading();
  }
}
onMounted(() => {
@@ -131,11 +183,10 @@
  <Page
    auto-content-height
    :loading="loading"
    :title="project.name || '设计任务详情'"
    :title="project.taskName || '设计任务详情'"
  >
    <FormModal @success="loadProjectDetail" />
    <PublishModal @success="loadProjectDetail" />
    <WorkflowActionModal @success="loadProjectDetail" />
    <ProcessModal @success="handleSubmitSuccess" />
    <template #extra>
      <TableAction
@@ -150,45 +201,46 @@
            label: $t('common.edit'),
            type: 'primary',
            icon: ACTION_ICON.EDIT,
            auth: ['mes:pd-project:update'],
            ifShow: isFormEditable,
            onClick: handleEdit,
          },
          {
            label: '发布任务',
            label: '发布',
            type: 'primary',
            auth: ['mes:pd-project:update'],
            ifShow: isDraft,
            ifShow: isPendingPublish,
            onClick: handlePublish,
          },
          {
            label: '提交审核',
            type: 'default',
            auth: ['mes:pd-project:submit-review'],
            ifShow: isDesigning,
            onClick: () => handleWorkflowAction('submit-review'),
            label: '确认上传',
            type: 'primary',
            ifShow: isPendingUpload,
            onClick: handleUpload,
          },
          {
            label: '审核通过',
            label: '提交审批',
            type: 'primary',
            auth: ['mes:pd-drawing-review:review'],
            ifShow: isReviewing,
            onClick: () => handleWorkflowAction('approve'),
            ifShow: isPendingAudit,
            onClick: handleSubmit,
          },
          {
            label: '查看审批',
            type: 'primary',
            ifShow: isApproving,
            onClick: handleProcessDetail,
          },
          {
            label: '归档',
            type: 'default',
            auth: ['mes:pd-project:archive'],
            ifShow: isApproved,
            onClick: () => handleWorkflowAction('archive'),
            ifShow: isPendingArchive,
            onClick: handleArchive,
          },
        ]"
      />
    </template>
    <TaskDraftBanner
      v-if="isDraft"
      :designer-name="project.designerName"
      v-if="isPendingPublish"
      :designer-name="project.chiefDesignerNickname"
      :product-name="project.productName"
      :version="project.version"
      @edit="handleEdit"
@@ -202,21 +254,20 @@
    <Card class="mt-4 min-h-[60%]">
      <Tabs v-model:active-key="activeTab">
        <Tabs.TabPane key="workflow" tab="流程进度" :force-render="true">
          <WorkflowTimeline :key="workflowKey" :project-id="projectId" />
          <WorkflowTimeline :status="project.status ?? 0" />
        </Tabs.TabPane>
        <Tabs.TabPane key="material" tab="设计资料" :force-render="true">
          <p v-if="isDraft" class="mb-3 text-sm text-amber-600">
        <Tabs.TabPane v-if="!isPendingAudit" key="material" tab="设计资料">
          <p v-if="isPendingPublish" class="mb-3 text-sm text-amber-600">
            请先发布任务后再上传设计资料
          </p>
          <MaterialPanel :form-type="materialFormType" :project-id="projectId" />
          <DocumentList
            :form-type="materialFormType"
            :project-id="projectId"
            :project-status="project.status"
          />
        </Tabs.TabPane>
        <Tabs.TabPane
          v-if="showReviewTab"
          key="review"
          tab="资料审核"
          :force-render="true"
        >
          <ReviewList form-type="detail" :project-id="projectId" />
        <Tabs.TabPane v-if="isPendingAudit" key="audit" tab="资料审核">
          <DocumentAuditList :project-id="projectId" @success="loadProjectDetail" />
        </Tabs.TabPane>
      </Tabs>
    </Card>