feat(msgcenter): 消息卡片直批入口——铃铛卡片与全部消息表格加同意/拒绝(msgType=2),弹窗拒绝意见必填、提交防重、成功标已读刷新
This commit is contained in:
@@ -142,6 +142,17 @@ class Base extends Abstract {
|
|||||||
return this.postRequest({ url });
|
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
|
* @memberof Basic
|
||||||
|
|||||||
+153
-18
@@ -48,6 +48,12 @@
|
|||||||
{{ item.title }}:{{ item.content }}
|
{{ item.title }}:{{ item.content }}
|
||||||
</span>
|
</span>
|
||||||
</h4>
|
</h4>
|
||||||
|
<span v-if="item.msgType === 2" class="approval-box">
|
||||||
|
<a href="javascript:;" class="approval-link approve"
|
||||||
|
@click="openApproval(item, 'approve')">同意</a>
|
||||||
|
<a href="javascript:;" class="approval-link reject"
|
||||||
|
@click="openApproval(item, 'reject')">拒绝</a>
|
||||||
|
</span>
|
||||||
<a v-if="item.jumpUrl" href="javascript:;" @click="onClickMsg(item)"
|
<a v-if="item.jumpUrl" href="javascript:;" @click="onClickMsg(item)"
|
||||||
title="查看详情">
|
title="查看详情">
|
||||||
<SvgIcon name="arrow-right" color="#bbbbbb" />
|
<SvgIcon name="arrow-right" color="#bbbbbb" />
|
||||||
@@ -271,6 +277,22 @@
|
|||||||
</template>
|
</template>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
||||||
|
<!-- 卡片直批弹窗(B3 §2):同意可选意见 / 拒绝意见必填;身份服务端取会话 -->
|
||||||
|
<Modal v-model="approval.visible" width="460" :mask-closable="false"
|
||||||
|
:title="approval.action === 'approve' ? '同意办理' : '拒绝办理'">
|
||||||
|
<div class="approval-body">
|
||||||
|
<p class="approval-title text-ellipsis">{{ approval.title || "确认办理该待办?" }}</p>
|
||||||
|
<Input v-model="approval.opinion" type="textarea" :rows="3" maxlength="200" show-word-limit
|
||||||
|
:placeholder="approval.action === 'approve' ? '审批意见(可选)' : '请输入拒绝意见(必填)'" />
|
||||||
|
</div>
|
||||||
|
<template #footer>
|
||||||
|
<Button type="primary" :loading="approval.submitting" @click="submitApproval">
|
||||||
|
{{ approval.action === "approve" ? "确认同意" : "确认拒绝" }}
|
||||||
|
</Button>
|
||||||
|
<Button @click="approval.visible = false">取消</Button>
|
||||||
|
</template>
|
||||||
|
</Modal>
|
||||||
|
|
||||||
<MenuBarModal ref="refMenuBarModal" />
|
<MenuBarModal ref="refMenuBarModal" />
|
||||||
<StatsBarModal ref="refStatsBarModal" />
|
<StatsBarModal ref="refStatsBarModal" />
|
||||||
<TeacherCopilotModal ref="refTeacherCopilotModal" />
|
<TeacherCopilotModal ref="refTeacherCopilotModal" />
|
||||||
@@ -478,27 +500,62 @@ const columns = ref<any[]>([
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "操作",
|
title: "操作",
|
||||||
width: 90,
|
width: 210,
|
||||||
align: "center",
|
align: "center",
|
||||||
render(h: any, params: any) {
|
render(h: any, params: any) {
|
||||||
if (!params.row.jumpUrl) return h("span", "—");
|
const row = params.row;
|
||||||
return h(
|
const nodes: any[] = [];
|
||||||
"a",
|
// 审批待办(msgType=2)直批入口:taskId 由服务端按 bizId 匹配定位;
|
||||||
{
|
// 无权限/已处理由后端返回文案,直批按钮不受跳转权限影响
|
||||||
attrs: { href: "javascript:;" },
|
if (row.msgType === 2 && row.msgId) {
|
||||||
on: {
|
nodes.push(
|
||||||
click: () => {
|
h(
|
||||||
if (params.row.isRead !== 1 && params.row.msgId) {
|
"a",
|
||||||
BaseApi.readMsgCenter(params.row.msgId);
|
{
|
||||||
params.row.isRead = 1;
|
attrs: { href: "javascript:;" },
|
||||||
unreadCount.value = Math.max(0, unreadCount.value - 1);
|
on: {
|
||||||
}
|
click: () => openApproval(row, "approve"),
|
||||||
window.open(params.row.jumpUrl, "_blank");
|
},
|
||||||
},
|
},
|
||||||
},
|
"同意"
|
||||||
},
|
),
|
||||||
"去处理"
|
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");
|
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() {
|
function resetMsgPage() {
|
||||||
refTablePage.value.reloadData();
|
refTablePage.value.reloadData();
|
||||||
}
|
}
|
||||||
@@ -697,6 +806,32 @@ function logout() {
|
|||||||
::v-deep .ivu-table td {
|
::v-deep .ivu-table td {
|
||||||
height: 32px;
|
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;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
|||||||
Reference in New Issue
Block a user