| | |
| | | <!-- |
| | | 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"> |
| | |
| | | <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 }" |
| | |
| | | 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, |
| | |
| | | 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; |
| | |
| | | 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" }); |
| | |
| | | }); |
| | | }; |
| | | |
| | | 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> |