feat(p3.3): 应用内审批前端——flow-approval 组件族本地化 + /todo 我的审批页 + 详情审批卡片
build / build (push) Successful in 2m12s
build / build (push) Successful in 2m12s
- 从 Notice/front 复制 flow-approval 六件并本地修复(漂移登记组件 README,Notice 不回改):
· P0-04:四个写调用点(List 通过/驳回 + Card 通过/驳回)全部实际携带本行 bizId,
选中 bizId 随弹窗生命周期锁定/清理
· P0-05:删 useElementHeight/yh-* 平台布局依赖,本地 fa-* 样式(theme-base.css --sh-* 令牌)
· P0-06:types.ts 本地契约——增 my(行=ApplyVo 子集/FlowPage 完整元数据/状态 0=待提交
禁止当全部,全部用 -1 哨兵)、删 instances(不代理全校视角)、approve/reject 增 bizId 参
· P1-05:卡片轨迹不自取(详情页把 /progress 转换 TraceVo 经 props 传入);节点摘要取
active steps 节点名;MULTI_TASK 逐条列出本人待办各带动作,不默认 tasks[0];
未进流程(flowInstanceId 空)详情页不渲染卡片(显式决策)
· P1-09:FlowTaskEmbed 消息四条件(打开中+严格 origin+本 iframe+taskId/bizId 上下文一致),
换址重置高度;宿主换址请求带代际号,关闭/换件废弃在途响应并清上下文;
open-biz 只用与当前办件一致的 bizId 构造 /apply-detail?id=,不透传任意 URL
- ApprovalApi 类挂 svc.ts(todo/my/byBiz/approve/reject/recordUrl/taskPageUrl,写面
taskId/applyId 查询参数+opinion/edgeName JSON body 两形态区分)+ approvalAdapter.ts 唯一映射
- /todo 路由 + 顶部导航第三链接「我的审批」+ MyApprovals.vue(双页签+记录抽屉+完整办理)
- ApplyDetail 挂审批卡片(审批操作区)+ TraceVo 转换器
- 小屏基础响应式(drawer/modal 宽度自适应、列表横向滚动;1200px 全量适配不在本批)
- 门禁:vue-tsc(ts4.9 外挂兼容组合)错误数 HEAD=工作区=18 零新增(仓内 vue-tsc1.8+ts5.9
崩溃系历史遗留);vite build 绿(MyApprovals/approvalAdapter chunk 产出);
preview 冒烟:/todo 渲染完整(导航/页签/表格空态/API 失败优雅降级)、详情页无崩溃(Stage S4/P3.3)
This commit is contained in:
@@ -0,0 +1,138 @@
|
||||
<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']"
|
||||
@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>
|
||||
Reference in New Issue
Block a user