yyb
2026-05-21 eb322fd6b88273f1dada1f850f4473d5f054dd66
src/pages/oa/ApproveManage/approve-list/approve.vue
@@ -1,17 +1,22 @@
<!--
  OA / 审批管理 / 审批处理
  路由:/pages/oa/ApproveManage/approve-list/approve
  差旅/费用报销使用报销详情 + 审批列表 approve 接口
-->
<template>
  <view class="oa-detail-page">
    <PageHeader title="审批处理"
    <PageHeader :title="pageTitle"
                @back="goBack" />
    <scroll-view v-if="row"
    <scroll-view v-if="displayReady"
                 class="oa-detail-scroll"
                 scroll-y
                 :show-scrollbar="false">
      <ApproveInstanceDetailBody :row="row"
      <ReimburseInstanceDetailBody v-if="isReimburse"
                                 :reimburse-row="reimburseRow"
                                 :module-key="detailModuleKey" />
      <ApproveInstanceDetailBody v-else
                                 :row="row"
                                 :module-key="detailModuleKey" />
      <view class="section-card opinion-card">
@@ -32,10 +37,10 @@
    <view v-else
          class="oa-empty">
      <up-empty mode="data"
                text="未获取到审批数据" />
                :text="loading ? '加载中' : '未获取到审批数据'" />
    </view>
    <view v-if="row"
    <view v-if="displayReady"
          class="oa-page-footer">
      <text class="oa-footer-btn btn-default"
            :class="{ 'is-disabled': submitting }"
@@ -55,6 +60,7 @@
  import { onLoad } from "@dcloudio/uni-app";
  import PageHeader from "@/components/PageHeader.vue";
  import ApproveInstanceDetailBody from "./_components/ApproveInstanceDetailBody.vue";
  import ReimburseInstanceDetailBody from "../../ReimburseManage/_components/ReimburseInstanceDetailBody.vue";
  import { approveApprovalInstance } from "@/api/oa/approvalInstance.js";
  import {
    buildApproveInstanceDto,
@@ -62,16 +68,44 @@
    loadInstanceRow,
  } from "../../_utils/approveListUtils.js";
  import { inferModuleKeyFromRow } from "../../_utils/approvalModuleApplyExtras.js";
  import {
    inferReimburseModuleKeyFromInstance,
    isReimburseApprovalInstance,
    loadReimburseDetailForInstance,
  } from "../../_utils/reimburseApproveBridge.js";
  import { getApprovalModuleConfig } from "../../_utils/approvalModuleRegistry.js";
  const instanceId = ref("");
  const row = ref(null);
  const detailModuleKey = computed(() => inferModuleKeyFromRow(row.value));
  const reimburseRow = ref(null);
  const loading = ref(false);
  const approveOpinion = ref("");
  const submitting = ref(false);
  const goBack = () => {
    uni.navigateBack();
  };
  const isReimburse = computed(() => isReimburseApprovalInstance(row.value));
  const detailModuleKey = computed(() => {
    if (isReimburse.value) {
      return (
        reimburseRow.value?.moduleKey ||
        inferReimburseModuleKeyFromInstance(row.value)
      );
    }
    return inferModuleKeyFromRow(row.value);
  });
  const pageTitle = computed(() => {
    if (isReimburse.value) {
      const label = getApprovalModuleConfig(detailModuleKey.value)?.label || "报销";
      return `${label}审批`;
    }
    return "审批处理";
  });
  const displayReady = computed(() =>
    isReimburse.value ? Boolean(reimburseRow.value) : Boolean(row.value)
  );
  const goBack = () => uni.navigateBack();
  const submitApprove = uiResult => {
    if (!row.value?.id || submitting.value) return;
@@ -99,7 +133,7 @@
          const prevRoute = pages[pages.length - 2]?.route || "";
          const delta = prevRoute.includes("approve-list/detail") ? 2 : 1;
          uni.navigateBack({ delta });
        }, 300);
        }, 400);
      })
      .catch(() => {
        uni.showToast({ title: "审批操作失败", icon: "none" });
@@ -109,56 +143,38 @@
      });
  };
  onLoad(options => {
  onLoad(async options => {
    if (!options?.id) {
      uni.showToast({ title: "缺少审批 ID", icon: "none" });
      setTimeout(goBack, 500);
      return;
    }
    instanceId.value = options.id;
    const cached = loadInstanceRow(options.id);
    if (!cached) {
      uni.showToast({ title: "请从列表进入审批", icon: "none" });
      uni.showToast({ title: "请从列表进入", icon: "none" });
      setTimeout(goBack, 500);
      return;
    }
    if (!canApproveInstance(cached)) {
      uni.showToast({ title: "当前审批不可处理", icon: "none" });
      uni.showToast({ title: "当前审批无需您处理", icon: "none" });
      setTimeout(goBack, 500);
      return;
    }
    row.value = cached;
    if (isReimburseApprovalInstance(cached)) {
      loading.value = true;
      try {
        const { reimburseRow: mapped } = await loadReimburseDetailForInstance(cached);
        reimburseRow.value = mapped;
      } catch {
        uni.showToast({ title: "加载报销详情失败", icon: "none" });
      } finally {
        loading.value = false;
      }
    }
  });
</script>
<style scoped lang="scss">
  @import "../../_styles/oa-approval-list.scss";
  $primary: #2979ff;
  .opinion-card {
    margin-top: 10px;
    background: #fff;
    border-radius: 12px;
    overflow: hidden;
    box-shadow: 0 2px 12px rgba(31, 45, 61, 0.05);
  }
  .section-head {
    padding: 12px 16px;
    border-bottom: 1px solid #f2f4f7;
  }
  .section-title {
    font-size: 15px;
    font-weight: 600;
    color: #1f2d3d;
    padding-left: 10px;
    border-left: 3px solid $primary;
    line-height: 1.2;
  }
  .opinion-wrap {
    padding: 12px 16px 16px;
  }
</style>