Files
UserhomeFront/src/components/MsgApprovalModal.vue
T
chenxing 0f7101983e feat(msgcenter): /msg 换真实数据——服务端筛选+滚动分页、铃铛直跳、unreadCount 上提 store、WS 通知带应用名
- views/msg/index.vue:数据层整体替换(msgType 0/1/2 映射、isRead 1=已读、fmtTime 重写绝对时间);列表走 msgCenter/list 服务端筛选(msgType/appKey/isRead/keyword 防抖 300ms),滚动到底追加下一页,切视图/搜索重置第 1 页;左栏分类计数走 summary(旧版 UserMsg 缺字段降级显示 —),应用清单取 store 应用列表、计数同源 todos;点击卡片标已读、全部已读、去处理(showJump/jumpUrl)、审批直批(共享弹窗);失败态有重试;WS 新消息经 mittBus 自刷新
- components/Header.vue:铃铛直跳 /msg(移除 Poptip 浮层与 900 宽 Modal 及 columns/tableApi 死代码);unreadCount 上提 pinia store(角标与 /msg、LeftMenu 同源);WS Notice.info 标题带应用名(appKey 匹配 store 应用列表,缺失回退类型标签);壁纸/LOGO Modal 不动
- components/MsgApprovalModal.vue(新增):审批直批弹窗抽共享组件,逻辑照抄原 Header 内联实现(同意可选意见/拒绝必填校验/三种失败反馈)
- components/LeftMenu.vue:「消息」入口(url=/msg)未读角标(读 store,红底白字胶囊)
- store/index.ts:unreadCount + setUnreadCount/incUnread/decUnread
- api/BaseApi.ts:getMsgCenterList 参数类型放宽(服务端筛选项);getMsgCenterSummary 返回类型补分类计数字段(可缺省)
- assets/styles/header.scss:删除消息浮层死样式 .message-wrap 段
2026-09-30 12:37:30 +08:00

90 lines
3.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<!-- 消息卡片直批弹窗(B3 §2,消息对接 2026-09-30 抽共享):同意可选意见 / 拒绝意见必填;
身份(operatorId/schId/operatorName)服务端取会话。Header 铃铛域已无直批入口,
本组件供 /msg 消息中心页使用,逻辑照抄原 Header 内联实现。 -->
<Modal :model-value="visible" width="460" :mask-closable="false"
:title="action === 'approve' ? '同意办理' : '拒绝办理'" @on-cancel="close">
<div class="approval-body">
<p class="approval-title text-ellipsis">{{ title || "确认办理该待办?" }}</p>
<Input v-model="opinion" type="textarea" :rows="3" maxlength="200" show-word-limit
:placeholder="action === 'approve' ? '审批意见(可选)' : '请输入拒绝意见(必填)'" />
</div>
<template #footer>
<Button type="primary" :loading="submitting" @click="submit">
{{ action === "approve" ? "确认同意" : "确认拒绝" }}
</Button>
<Button @click="close">取消</Button>
</template>
</Modal>
</template>
<script lang="ts" setup>
import { ref, watch } from "vue";
import { Notice } from "view-ui-plus";
import BaseApi from "@/api/BaseApi";
/**
* 审批直批弹窗(msgCenter/handle 代理)。
* 父组件 open({msgId, title, action}) 打开;成功(后端 ok)后 emit("handled", msgId),
* 失败/已被处理等场景只弹后端文案,不关弹窗(成功/失败/已被处理三种场景都有反馈)。
*/
const emit = defineEmits<{ (e: "handled", msgId: number): void }>();
const visible = ref(false);
const msgId = ref(0);
const title = ref("");
const action = ref<"approve" | "reject">("approve");
const opinion = ref("");
const submitting = ref(false);
function open(row: { msgId: number; title?: string }, act: "approve" | "reject") {
msgId.value = row.msgId;
action.value = act;
title.value = row.title ? String(row.title) : "";
opinion.value = "";
submitting.value = false;
visible.value = true;
}
function close() {
visible.value = false;
}
async function submit() {
if (submitting.value) return;
if (action.value === "reject" && !opinion.value.trim()) {
Notice.warning({ title: "拒绝必须填写意见", duration: 3 });
return;
}
submitting.value = true;
try {
const res: any = await BaseApi.handleMsg(msgId.value, action.value, opinion.value.trim());
if (res && res.ok) {
Notice.success({ title: "办理成功", duration: 3 });
visible.value = false;
emit("handled", msgId.value);
} else {
Notice.warning({ title: (res && res.message) || "办理失败", duration: 5 });
}
} catch (e) {
// flow-center 不可达等:降级为提示,不阻塞消息卡片其余功能
Notice.error({ title: "流程中心暂不可用,请稍后重试", duration: 5 });
} finally {
submitting.value = false;
}
}
defineExpose({ open });
</script>
<style scoped lang="scss">
.approval-body {
.approval-title {
font-size: 14px;
font-weight: 500;
color: #2c3138;
margin-bottom: 12px;
}
}
</style>