From a7ae4db2fbcd64e82fca6b768599e1663f029955 Mon Sep 17 00:00:00 2001 From: chenxing Date: Mon, 28 Sep 2026 13:30:30 +0800 Subject: [PATCH] =?UTF-8?q?feat(msgcenter):=20=E6=B6=88=E6=81=AF=E5=8D=A1?= =?UTF-8?q?=E7=89=87=E7=9B=B4=E6=89=B9=E5=85=A5=E5=8F=A3=E2=80=94=E2=80=94?= =?UTF-8?q?=E9=93=83=E9=93=9B=E5=8D=A1=E7=89=87=E4=B8=8E=E5=85=A8=E9=83=A8?= =?UTF-8?q?=E6=B6=88=E6=81=AF=E8=A1=A8=E6=A0=BC=E5=8A=A0=E5=90=8C=E6=84=8F?= =?UTF-8?q?/=E6=8B=92=E7=BB=9D=EF=BC=88msgType=3D2=EF=BC=89=EF=BC=8C?= =?UTF-8?q?=E5=BC=B9=E7=AA=97=E6=8B=92=E7=BB=9D=E6=84=8F=E8=A7=81=E5=BF=85?= =?UTF-8?q?=E5=A1=AB=E3=80=81=E6=8F=90=E4=BA=A4=E9=98=B2=E9=87=8D=E3=80=81?= =?UTF-8?q?=E6=88=90=E5=8A=9F=E6=A0=87=E5=B7=B2=E8=AF=BB=E5=88=B7=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/BaseApi.ts | 11 +++ src/components/Header.vue | 171 ++++++++++++++++++++++++++++++++++---- 2 files changed, 164 insertions(+), 18 deletions(-) diff --git a/src/api/BaseApi.ts b/src/api/BaseApi.ts index 5ec43ac..e517d47 100644 --- a/src/api/BaseApi.ts +++ b/src/api/BaseApi.ts @@ -142,6 +142,17 @@ class Base extends Abstract { return this.postRequest({ url }); } + /** + * 消息卡片直批(B3 §2):同意/拒绝消息对应的审批待办。 + * 身份(operatorId/schId/operatorName)服务端取会话,前端只传消息定位与动作。 + * 返回 {ok, message}——ok=false 时 message 为可直接展示的文案。 + * @memberof Basic + */ + handleMsg(msgId: number, action: "approve" | "reject", opinion?: string) { + const url = path + "/msgCenter/handle"; + return this.postRequest({ url, data: { msgId, action, opinion } }); + } + /** * 修改密码 * @memberof Basic diff --git a/src/components/Header.vue b/src/components/Header.vue index e957729..956cc54 100644 --- a/src/components/Header.vue +++ b/src/components/Header.vue @@ -48,6 +48,12 @@ {{ item.title }}:{{ item.content }} + + 同意 + 拒绝 + @@ -271,6 +277,22 @@ + + +
+

{{ approval.title || "确认办理该待办?" }}

+ +
+ +
+ @@ -478,27 +500,62 @@ const columns = ref([ }, { title: "操作", - width: 90, + width: 210, align: "center", render(h: any, params: any) { - if (!params.row.jumpUrl) return h("span", "—"); - return h( - "a", - { - attrs: { href: "javascript:;" }, - on: { - click: () => { - if (params.row.isRead !== 1 && params.row.msgId) { - BaseApi.readMsgCenter(params.row.msgId); - params.row.isRead = 1; - unreadCount.value = Math.max(0, unreadCount.value - 1); - } - window.open(params.row.jumpUrl, "_blank"); + const row = params.row; + const nodes: any[] = []; + // 审批待办(msgType=2)直批入口:taskId 由服务端按 bizId 匹配定位; + // 无权限/已处理由后端返回文案,直批按钮不受跳转权限影响 + if (row.msgType === 2 && row.msgId) { + nodes.push( + h( + "a", + { + attrs: { href: "javascript:;" }, + on: { + click: () => openApproval(row, "approve"), + }, }, - }, - }, - "去处理" - ); + "同意" + ), + h("span", " "), + h( + "a", + { + attrs: { href: "javascript:;" }, + on: { + click: () => openApproval(row, "reject"), + }, + }, + "拒绝" + ) + ); + } + if (row.jumpUrl) { + if (nodes.length) nodes.push(h("span", " ")); + nodes.push( + h( + "a", + { + attrs: { href: "javascript:;" }, + on: { + click: () => { + if (row.isRead !== 1 && row.msgId) { + BaseApi.readMsgCenter(row.msgId); + row.isRead = 1; + unreadCount.value = Math.max(0, unreadCount.value - 1); + } + window.open(row.jumpUrl, "_blank"); + }, + }, + }, + "去处理" + ) + ); + } + if (!nodes.length) return h("span", "—"); + return h("span", nodes); }, }, ]); @@ -580,6 +637,58 @@ async function onClickMsg(item: any) { if (item.jumpUrl) window.open(item.jumpUrl, "_blank"); } +// ===== 卡片直批(B3 §2):同意/拒绝待办;operatorId/schId/operatorName 服务端取会话 ===== +const approval = reactive({ + visible: false, + msgId: 0, + action: "approve" as "approve" | "reject", + title: "", + opinion: "", + submitting: false, +}); + +function openApproval(item: any, action: "approve" | "reject") { + approval.msgId = item.msgId; + approval.action = action; + approval.title = item.title ? String(item.title) : ""; + approval.opinion = ""; + approval.visible = true; +} + +async function submitApproval() { + if (approval.submitting) return; + if (approval.action === "reject" && !approval.opinion.trim()) { + Notice.warning({ title: "拒绝必须填写意见", duration: 3 }); + return; + } + approval.submitting = true; + try { + const res: any = await BaseApi.handleMsg(approval.msgId, approval.action, approval.opinion.trim()); + if (res && res.ok) { + Notice.success({ title: "办理成功", duration: 3 }); + approval.visible = false; + markRowRead(approval.msgId); + } else { + Notice.warning({ title: (res && res.message) || "办理失败", duration: 5 }); + } + // 成功/失效/被他人处理等场景都同步刷新,让卡片状态跟上服务端 + reloadMsg(); + } catch (e) { + // flow-center 不可达等:降级为提示,不阻塞消息卡片其余功能 + Notice.error({ title: "流程中心暂不可用,请稍后重试", duration: 5 }); + } finally { + approval.submitting = false; + } +} + +function markRowRead(msgId: number) { + const row = userMsgList.value.find((m: any) => m.msgId === msgId); + if (row && row.isRead !== 1) { + row.isRead = 1; + unreadCount.value = Math.max(0, unreadCount.value - 1); + } +} + function resetMsgPage() { refTablePage.value.reloadData(); } @@ -697,6 +806,32 @@ function logout() { ::v-deep .ivu-table td { height: 32px; } + +/* 卡片直批(B3):待办消息行内「同意/拒绝」入口 */ +.approval-box { + margin-right: 6px; + white-space: nowrap; +} + +.approval-link { + margin-left: 8px; + font-size: 12px; + color: #577afb; +} + +.approval-link.reject { + color: #ed4014; +} + +.approval-body { + padding: 4px 2px; +} + +.approval-title { + margin-bottom: 10px; + color: #515a6e; + font-weight: 600; +}