feat(p3.5): 我的审批扩四页签——我已审批/抄送我的(行映射与漂移登记)
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)
This commit is contained in:
chenxing
2026-10-20 00:16:24 +08:00
parent 351a513547
commit d7d8789d1a
5 changed files with 141 additions and 9 deletions
+2
View File
@@ -16,6 +16,8 @@ export const svcFlowApprovalApi: FlowApprovalApi = {
approvalApi
.my(p?.page ?? 1, p?.size ?? 10, p?.flowStatus ?? null)
.send(),
done: (p) => approvalApi.done(p?.page ?? 1, p?.size ?? 10).send(),
cc: (p) => approvalApi.cc(p?.page ?? 1, p?.size ?? 10).send(),
byBiz: (bizId) => approvalApi.byBiz(Number(bizId)).send(),
trace: (bizId) => applyApi.progress(Number(bizId)).send(),
approve: (taskId, opinion, edgeName, bizId) =>
+8
View File
@@ -132,6 +132,14 @@ class ApprovalApi {
todo(page?: number, size?: number) {
return get(`${APPROVAL}/Todo`, { page, size });
}
/** 我已审批(P3.5;中心 done,过滤=签名方应用身份在中心侧) */
done(page?: number, size?: number) {
return get(`${APPROVAL}/Done`, { page, size });
}
/** 抄送我的(P3.5;中心 cc,同上) */
cc(page?: number, size?: number) {
return get(`${APPROVAL}/Cc`, { page, size });
}
/** 我提交的(本地办件;后端做 {total,list}→FlowPage 信封映射;flowStatus 空=全部) */
my(page?: number, size?: number, flowStatus?: number | null) {
return get(`${APPROVAL}/My`, { page, size, flowStatus: flowStatus ?? undefined });
@@ -23,6 +23,42 @@
</div>
</div>
<!-- 我已审批(P3.5,中心 done) -->
<div class="fa-tab-body" v-else-if="innerTab === 'done'">
<div class="fa-table-region">
<Table :columns="doneCols" :data="doneRows" :loading="loading" no-data-text="暂无已办记录">
<template #instStatus="{ row }">
<Tag :color="statusTag(row.instanceStatus)">{{ statusText(row.instanceStatus) }}</Tag>
</template>
<template #doneAction="{ row }">
<a class="fa-link" @click="emitOpenDetail(Number(row.bizId))">查看详情</a>
</template>
</Table>
</div>
<div class="fa-page" v-if="donePage.total > donePage.pageSize">
<Page :current="donePage.pageIndex" :page-size="donePage.pageSize"
:total="donePage.total" show-total @on-change="loadDone" />
</div>
</div>
<!-- 抄送我的(P3.5,中心 cc) -->
<div class="fa-tab-body" v-else-if="innerTab === 'cc'">
<div class="fa-table-region">
<Table :columns="ccCols" :data="ccRows" :loading="loading" no-data-text="暂无抄送记录">
<template #ccStatus="{ row }">
<Tag :color="statusTag(row.instanceStatus)">{{ statusText(row.instanceStatus) }}</Tag>
</template>
<template #ccAction="{ row }">
<a class="fa-link" @click="emitOpenDetail(Number(row.bizId))">查看详情</a>
</template>
</Table>
</div>
<div class="fa-page" v-if="ccPage.total > ccPage.pageSize">
<Page :current="ccPage.pageIndex" :page-size="ccPage.pageSize"
:total="ccPage.total" show-total @on-change="loadCc" />
</div>
</div>
<!-- 我提交的(本地办件) -->
<div class="fa-tab-body" v-else>
<div class="fa-filter">
@@ -93,15 +129,15 @@
*/
import { computed, onMounted, ref } from "vue";
import { Message } from "view-ui-plus";
import type { ByBizTask, FlowApprovalApi, FlowPage, MyApplyRow, TodoTask } from "./types";
import type { ByBizTask, CcRow, DoneTask, FlowApprovalApi, FlowPage, MyApplyRow, TodoTask } from "./types";
import { INSTANCE_STATUS_TAG, INSTANCE_STATUS_TEXT } from "./types";
const props = withDefaults(
defineProps<{
api: FlowApprovalApi;
tabs?: Array<"todo" | "my">;
tabs?: Array<"todo" | "my" | "done" | "cc">;
}>(),
{ tabs: () => ["todo", "my"] }
{ tabs: () => ["todo", "my", "done", "cc"] }
);
const emit = defineEmits<{
@@ -112,7 +148,7 @@ const emit = defineEmits<{
(e: "open-detail", applyId: number): void;
}>();
const innerTab = ref<"todo" | "my">(props.tabs[0] || "todo");
const innerTab = ref<"todo" | "my" | "done" | "cc">(props.tabs[0] || "todo");
const loading = ref(false);
const acting = ref(false);
@@ -120,6 +156,10 @@ const todoRows = ref<Array<TodoTask & { _summary: string }>>([]);
const todoPage = ref({ total: 0, pageIndex: 1, pageSize: 10 });
const myRows = ref<MyApplyRow[]>([]);
const myPage = ref({ total: 0, pageIndex: 1, pageSize: 10 });
const doneRows = ref<DoneTask[]>([]);
const donePage = ref({ total: 0, pageIndex: 1, pageSize: 10 });
const ccRows = ref<CcRow[]>([]);
const ccPage = ref({ total: 0, pageIndex: 1, pageSize: 10 });
/** -1=全部(本地哨兵;0 在 hall 语义里是"待提交",禁止当"全部"用) */
const myStatus = ref(-1);
@@ -134,7 +174,7 @@ const targetBizId = ref("");
const chosenOutlets = computed(() => targetTask.value?.outlets || []);
const TAB_LABELS: Record<string, string> = { todo: "待我审批", my: "我提交的" };
const TAB_LABELS: Record<string, string> = { todo: "待我审批", my: "我提交的", done: "我已审批", cc: "抄送我的" };
function tabLabel(t: string) {
return TAB_LABELS[t] || t;
}
@@ -147,6 +187,22 @@ const todoCols = [
{ title: "操作", slot: "action", width: 240, align: "center" },
];
const doneCols = [
{ title: "办件", key: "bizTitle", minWidth: 220, ellipsis: true, tooltip: true },
{ title: "办结状态", slot: "instStatus", minWidth: 100 },
{ title: "我办理的节点", key: "nodeName", minWidth: 130 },
{ title: "办理时间", key: "handleTime", minWidth: 170, render: fmtTime },
{ title: "操作", slot: "doneAction", width: 110, align: "center" },
];
const ccCols = [
{ title: "办件", key: "bizTitle", minWidth: 220, ellipsis: true, tooltip: true },
{ title: "办件状态", slot: "ccStatus", minWidth: 100 },
{ title: "抄送节点", key: "nodeName", minWidth: 130 },
{ title: "抄送时间", key: "sentTime", minWidth: 170, render: fmtTime },
{ title: "操作", slot: "ccAction", width: 110, align: "center" },
];
const myCols = [
{ title: "事项", key: "itemTitle", minWidth: 220, ellipsis: true, tooltip: true },
{ title: "状态", slot: "status", minWidth: 100 },
@@ -178,7 +234,7 @@ function parseSummary(task: TodoTask): string {
}
function switchTab(name: any) {
innerTab.value = String(name) as "todo" | "my";
innerTab.value = String(name) as "todo" | "my" | "done" | "cc";
load();
}
@@ -229,8 +285,44 @@ async function loadMy(page = 1) {
}
}
async function loadDone(page = 1) {
if (!props.api.done) {
doneRows.value = [];
return;
}
loading.value = true;
try {
const res: FlowPage<DoneTask> = await props.api.done({ page, size: donePage.value.pageSize });
donePage.value = { total: res.total ?? 0, pageIndex: res.pageIndex ?? page, pageSize: res.pageSize ?? donePage.value.pageSize };
doneRows.value = res.content || [];
} catch (e: any) {
Message.error(e?.msg || e?.message || "已办列表加载失败");
} finally {
loading.value = false;
}
}
async function loadCc(page = 1) {
if (!props.api.cc) {
ccRows.value = [];
return;
}
loading.value = true;
try {
const res: FlowPage<CcRow> = await props.api.cc({ page, size: ccPage.value.pageSize });
ccPage.value = { total: res.total ?? 0, pageIndex: res.pageIndex ?? page, pageSize: res.pageSize ?? ccPage.value.pageSize };
ccRows.value = res.content || [];
} catch (e: any) {
Message.error(e?.msg || e?.message || "抄送列表加载失败");
} finally {
loading.value = false;
}
}
function load() {
if (innerTab.value === "todo") loadTodo(1);
else if (innerTab.value === "done") loadDone(1);
else if (innerTab.value === "cc") loadCc(1);
else loadMy(1);
}
@@ -347,7 +439,7 @@ function reset() {
}
onMounted(load);
defineExpose({ load, loadTodo, loadMy });
defineExpose({ load, loadTodo, loadMy, loadDone, loadCc });
</script>
<style scoped>
+30
View File
@@ -46,6 +46,32 @@ export interface MyApplyRow {
finishTime?: string | null;
}
/** 我已办行(P3.5,中心 /oapi/flow/tasks/done;过滤=签名方应用,天然只含本应用办件) */
export interface DoneTask {
taskId: number;
instanceId: number;
bizTitle: string;
bizType: string;
bizId: string;
instanceStatus?: number | null;
nodeId: string;
nodeName: string;
handleTime?: string | null;
opinion?: string | null;
}
/** 抄送我行(P3.5,中心 /oapi/flow/cc;NOTIFY 落库,bizId 已回填本应用办件 ID) */
export interface CcRow {
ccId: number;
instanceId: number;
nodeId?: string | null;
nodeName?: string | null;
sentTime?: string | null;
bizTitle?: string | null;
bizId?: string | null;
instanceStatus?: number | null;
}
/** 出口:多出口节点办理时须选其一(选中值作为 approve 的 edgeName) */
export interface ByBizOutlet {
name: string;
@@ -115,6 +141,10 @@ export interface FlowApprovalApi {
todo(params?: { page?: number; size?: number }): any;
/** 我提交的分页(本地办件;flowStatus 可选,null=全部) */
my?(params?: { page?: number; size?: number; flowStatus?: number | null }): any;
/** 我已办分页(P3.5;中心按签名方应用过滤,前端不传 bizType) */
done?(params?: { page?: number; size?: number }): any;
/** 抄送我分页(P3.5;同上) */
cc?(params?: { page?: number; size?: number }): any;
/** 当前人在该办件上的待办 */
byBiz(bizId: string): any;
/** 审批轨迹(可缺省:传了卡片就不再自取) */
+2 -2
View File
@@ -100,9 +100,9 @@ onBeforeUnmount(() => {
<div class="page todo-page">
<div class="page-head">
<h2 class="page-title">我的审批</h2>
<span class="page-sub">「待我审批」为流程中心待办;「我提交的」为本人在大厅提交的办件</span>
<span class="page-sub">「待我审批/我已审批/抄送我的」为流程中心数据(按本应用过滤);「我提交的」为本地办件</span>
</div>
<FlowApprovalList ref="listRef" :api="svcFlowApprovalApi" :tabs="['todo', 'my']"
<FlowApprovalList ref="listRef" :api="svcFlowApprovalApi" :tabs="['todo', 'my', 'done', 'cc']"
@open-record="openRecord" @open-task="openTask" @handled="onHandled"
@open-detail="openDetail" />