build / build (push) Successful in 2m0s
- types 增 DoneTask/CcRow 行契约与 api.done/cc;列表组件 tabs 扩 'done'|'cc' (done=我办理的节点+办理时间;cc=抄送节点+抄送时间;行详情跳转只用本行 bizId 构造) - ApprovalApi.done/cc + adapter 映射;页头文案更新 - 门禁:vue-tsc 18 零新增+build 绿(Stage S5/P3.5)
139 lines
4.8 KiB
Vue
139 lines
4.8 KiB
Vue
<script setup lang="ts">
|
||
/**
|
||
* 我的审批(/todo,P3.3):待我审批(中心 todo)+ 我提交的(本地办件)两页签。
|
||
* 完整办理=去壳任务页 iframe(FlowTaskEmbed);审批记录=token 只读抽屉(FlowRecordDrawer)。
|
||
*
|
||
* 宿主职责(P1-09):
|
||
* - open-task 换址请求带代际号——关闭/换件时废弃在途响应并清 taskUrl/选中 ID;
|
||
* - open-biz 只用与当前办件上下文一致的 bizId 构造 /apply-detail?id=,不照抄任意 URL。
|
||
*/
|
||
import { onBeforeUnmount, ref } from "vue";
|
||
import { useRouter } from "vue-router";
|
||
import { Message } from "view-ui-plus";
|
||
import FlowApprovalList from "@/components/flow-approval/FlowApprovalList.vue";
|
||
import FlowRecordDrawer from "@/components/flow-approval/FlowRecordDrawer.vue";
|
||
import FlowTaskEmbed from "@/components/flow-approval/FlowTaskEmbed.vue";
|
||
import svcFlowApprovalApi from "@/api/module/approvalAdapter";
|
||
|
||
const router = useRouter();
|
||
const listRef = ref<InstanceType<typeof FlowApprovalList> | null>(null);
|
||
|
||
// ===== 审批记录抽屉 =====
|
||
const recordVisible = ref(false);
|
||
const recordBizId = ref("");
|
||
|
||
function openRecord(bizId: string) {
|
||
recordBizId.value = bizId;
|
||
recordVisible.value = true;
|
||
}
|
||
|
||
// ===== 完整办理(去壳任务页) =====
|
||
const taskVisible = ref(false);
|
||
const taskUrl = ref("");
|
||
const taskTaskId = ref<number | string>("");
|
||
const taskBizId = ref<string | number>("");
|
||
/** 换址请求代际号:关闭/换件时 +1,晚到响应按代际丢弃(P1-09) */
|
||
let taskReqEpoch = 0;
|
||
|
||
async function openTask(payload: { bizId: string; taskId: number }) {
|
||
const epoch = ++taskReqEpoch;
|
||
taskBizId.value = payload.bizId;
|
||
taskTaskId.value = payload.taskId;
|
||
taskUrl.value = "";
|
||
taskVisible.value = true;
|
||
try {
|
||
const res: any = await svcFlowApprovalApi.taskPageUrl(payload.bizId, payload.taskId);
|
||
if (epoch !== taskReqEpoch) return; // 已关闭/已换件:废弃
|
||
const url = res?.pageUrl || "";
|
||
if (!url) {
|
||
Message.error("任务页地址获取失败");
|
||
taskVisible.value = false;
|
||
return;
|
||
}
|
||
taskUrl.value = url;
|
||
} catch (e: any) {
|
||
if (epoch !== taskReqEpoch) return;
|
||
Message.error(e?.msg || e?.message || "任务页地址获取失败");
|
||
taskVisible.value = false;
|
||
}
|
||
}
|
||
|
||
function onTaskClose() {
|
||
// 关闭即清上下文 + 废弃在途换址请求
|
||
taskReqEpoch++;
|
||
taskUrl.value = "";
|
||
taskTaskId.value = "";
|
||
taskBizId.value = "";
|
||
}
|
||
|
||
function onHandled() {
|
||
// 办理完成:刷新列表(本地 flow_status 由回调推进,前端只刷数据面)
|
||
listRef.value?.load();
|
||
}
|
||
|
||
/**
|
||
* open-biz:只用校验过的本办件 ID 构造 /apply-detail?id=(P1-09)。
|
||
* 消息 bizId 必须与打开任务页时锁定的办件上下文一致;缺失时用锁定上下文;绝不透传 bizUrl 路由。
|
||
*/
|
||
function onOpenBiz(payload: { bizId?: string | null; bizUrl?: string }) {
|
||
const msgBizId = payload.bizId != null ? String(payload.bizId) : "";
|
||
const ctxBizId = String(taskBizId.value || "");
|
||
if (!msgBizId && !ctxBizId) return;
|
||
if (msgBizId && ctxBizId && msgBizId !== ctxBizId) return; // 换件期间旧消息,作废
|
||
const applyId = Number(msgBizId || ctxBizId);
|
||
if (!Number.isInteger(applyId) || applyId <= 0) return;
|
||
taskVisible.value = false;
|
||
router.push(`/apply-detail?id=${applyId}`);
|
||
}
|
||
|
||
/** "我提交的"行查看详情(只用本行 id 构造路由) */
|
||
function openDetail(applyId: number) {
|
||
router.push(`/apply-detail?id=${applyId}`);
|
||
}
|
||
|
||
onBeforeUnmount(() => {
|
||
taskReqEpoch++;
|
||
});
|
||
</script>
|
||
|
||
<template>
|
||
<div class="page todo-page">
|
||
<div class="page-head">
|
||
<h2 class="page-title">我的审批</h2>
|
||
<span class="page-sub">「待我审批/我已审批/抄送我的」为流程中心数据(按本应用过滤);「我提交的」为本地办件</span>
|
||
</div>
|
||
<FlowApprovalList ref="listRef" :api="svcFlowApprovalApi" :tabs="['todo', 'my', 'done', 'cc']"
|
||
@open-record="openRecord" @open-task="openTask" @handled="onHandled"
|
||
@open-detail="openDetail" />
|
||
|
||
<FlowRecordDrawer v-model="recordVisible" :api="svcFlowApprovalApi" :biz-id="recordBizId" />
|
||
<FlowTaskEmbed v-model="taskVisible" :page-url="taskUrl" :task-id="taskTaskId" :biz-id="taskBizId"
|
||
@handled="onHandled" @open-biz="onOpenBiz" @close="onTaskClose" />
|
||
</div>
|
||
</template>
|
||
|
||
<style scoped>
|
||
.todo-page {
|
||
max-width: 1080px;
|
||
margin: 0 auto;
|
||
width: 100%;
|
||
box-sizing: border-box;
|
||
}
|
||
.page-head {
|
||
display: flex;
|
||
align-items: baseline;
|
||
gap: 12px;
|
||
flex-wrap: wrap;
|
||
margin-bottom: 12px;
|
||
}
|
||
.page-title {
|
||
font-size: 18px;
|
||
font-weight: 600;
|
||
margin: 0;
|
||
}
|
||
.page-sub {
|
||
font-size: 13px;
|
||
color: var(--sh-text-weak, #6b7280);
|
||
}
|
||
</style>
|