系统消息:按通知自身内容决定入口和文案,不再一律显示"前往安全设置"
用户实机测试反馈:系统消息列表里每条通知底部都是同一个"前往安全设置"按钮,点进去跟通知内容毫不 相关;正文还直接显示 "group.settings.updated" 这种原始事件码。查证后两个问题性质不同: 入口按钮(前端问题,已修):原来无条件对所有通知渲染同一个按钮、固定跳 security 页。改为按通知 自己的 action 字段决定——action.topic 是 grp 开头的进对应群聊设置页,好友申请类(action.type 为 friend_request)进"新朋友"页,带 device/ip 的安全类才进安全设置页,都不匹配就不显示按钮。 注意 action.topic 不能直接当群用:好友申请通知的 action 里带的是 p2p 会话 topic (db/mysql/tenant_adapter.go:8643),所以判断加了 grp 前缀检查。跳转目标都核对过在 tinode-web.jsx 的路由白名单里(friend-requests / group-settings),没有凭空造路由名。 正文文案(后端问题,前端只做兜底):后端多处把机器码直接当 summary 写进通知——群事件统一写 summary=event.EventType(im_group_events.go:42-44,7 种群事件还共用同一个 title"群聊动态"), 好友申请处理结果写 summary=status(im_http.go:5956 等,值就是 "accepted"/"rejected")。前端加 了一层兜底:summary 命中"纯小写字母数字点下划线"这种机器码特征时,按已知码翻译成中文,翻译不了 就退回通用文案;后端以后补上真正的文案会自动优先使用,不会被兜底覆盖。这条已记入后端问题清单。 实机验证:两条群通知正文由 "group.settings.updated" 变为"群设置有更新"、按钮变为"查看群聊"且 点击后正确进入 grpXDkK5cbXoK0 的群聊设置页;两条好友通知正文由 "accepted" 变为"对方已通过你的 好友申请",不再显示无关的安全设置按钮。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
3bdb0bf40f
commit
8225848493
@@ -10,7 +10,14 @@ import { topicDisplayName } from '../lib/utils.js';
|
||||
// Must go through setUrlSidePanel (not a bare navigateTo(view), which replaces the whole hash) so
|
||||
// switching panels from "messages-home" doesn't silently drop path[1] -- the currently open
|
||||
// conversation topic, which coexists with this panel in the split view once a chat is selected.
|
||||
const navigate = view => HashNavigation.navigateTo(HashNavigation.setUrlSidePanel(window.location.hash, view));
|
||||
// `topic` 可选:系统消息里的群事件通知需要带着群 topic 跳进对应群聊设置页,写法与
|
||||
// group-management-view.jsx 的同名辅助函数保持一致(不带 topic 时显式清掉,避免把上一个页面
|
||||
// 残留的 topic 参数带进不相关的页面)。
|
||||
const navigate = (view, topic) => {
|
||||
let hash = HashNavigation.setUrlSidePanel(window.location.hash, view);
|
||||
hash = topic ? HashNavigation.addUrlParam(hash, 'topic', topic) : HashNavigation.removeUrlParam(hash, 'topic');
|
||||
HashNavigation.navigateTo(hash);
|
||||
};
|
||||
|
||||
// Was a hardcoded FREQUENT_CONTACTS mock (5 fake names, always clicking through to the same
|
||||
// direct-message-view.jsx demo regardless of which avatar was tapped -- confirmed independently by
|
||||
@@ -281,6 +288,33 @@ function MessageActions() {
|
||||
</div>;
|
||||
}
|
||||
|
||||
// 系统通知的 summary 在多处后端代码里被直接填成机器码而不是人话:群事件统一写
|
||||
// summary=event.EventType(server/im_group_events.go:42-44,所有群事件共用 title="群聊动态"),
|
||||
// 好友申请处理结果写 summary=status(server/im_http.go:5956 与 db/mysql/tenant_adapter.go:8643,8700,
|
||||
// 值就是 "accepted"/"rejected")。已记入后端问题清单,在后端给出可读文案之前前端按已知码兜底翻译。
|
||||
const NOTIFICATION_TEXT = {
|
||||
'group.member.joined': '有成员加入了群聊',
|
||||
'group.member.left': '有成员退出了群聊',
|
||||
'group.member.updated': '群成员资料有更新',
|
||||
'group.mute.updated': '群禁言设置有变更',
|
||||
'group.owner.transferred': '群主已转让',
|
||||
'group.role.updated': '群成员角色有变更',
|
||||
'group.settings.updated': '群设置有更新',
|
||||
accepted: '对方已通过你的好友申请',
|
||||
rejected: '对方拒绝了你的好友申请'
|
||||
};
|
||||
|
||||
// 机器码判定:纯 ASCII 且只由小写字母/数字/点/下划线/连字符组成("accepted"、
|
||||
// "group.settings.updated" 这类),正常中文文案不会命中。
|
||||
const MACHINE_CODE = /^[a-z0-9._-]+$/;
|
||||
|
||||
function systemNotificationText(item) {
|
||||
const summary = (item.summary || '').trim();
|
||||
// 后端给了真正的文案就直接用;只有当它是机器码时才走兜底,避免把未来后端补上的正常文案盖掉。
|
||||
if (summary && !MACHINE_CODE.test(summary)) return summary;
|
||||
return NOTIFICATION_TEXT[summary] || NOTIFICATION_TEXT[item.event_type] || '您有一条新的系统通知。';
|
||||
}
|
||||
|
||||
function SystemMessages({authenticated}) {
|
||||
const [items, setItems] = React.useState([]);
|
||||
const [loading, setLoading] = React.useState(true);
|
||||
@@ -313,9 +347,19 @@ function SystemMessages({authenticated}) {
|
||||
<time>{new Date(item.created_at).toLocaleString('zh-CN')}</time>
|
||||
<div className="system-notification-card">
|
||||
<header><h2>{item.title}</h2>{!item.read_at ? <span>新</span> : null}</header>
|
||||
<p>{item.summary}</p>
|
||||
<p>{systemNotificationText(item)}</p>
|
||||
{item.action && item.action.device ? <dl><div><dt>设备:</dt><dd>{item.action.device}</dd></div>{item.action.ip ? <div><dt>IP地址:</dt><dd>{item.action.ip}</dd></div> : null}</dl> : null}
|
||||
<button type="button" className="system-security-link" onClick={e => { e.stopPropagation(); navigate(authenticated ? 'security' : 'identity-check'); }}>前往安全设置 <Icon>chevron_right</Icon></button>
|
||||
{/* 入口按通知自身的 action 决定,不再对所有通知一律显示"前往安全设置"。注意 action.topic
|
||||
不能直接当成群:好友申请类通知的 action 里带的是 p2p 会话 topic
|
||||
(db/mysql/tenant_adapter.go:8643),只有 grp 前缀才是真的群。都不匹配时不显示按钮,
|
||||
避免把人导到跟这条通知无关的页面。 */}
|
||||
{item.action && typeof item.action.topic === 'string' && item.action.topic.startsWith('grp') ?
|
||||
<button type="button" className="system-security-link" onClick={e => { e.stopPropagation(); navigate('group-settings', item.action.topic); }}>查看群聊 <Icon>chevron_right</Icon></button> :
|
||||
item.action && item.action.type === 'friend_request' ?
|
||||
<button type="button" className="system-security-link" onClick={e => { e.stopPropagation(); navigate('friend-requests'); }}>查看新朋友 <Icon>chevron_right</Icon></button> :
|
||||
item.action && (item.action.device || item.action.ip) ?
|
||||
<button type="button" className="system-security-link" onClick={e => { e.stopPropagation(); navigate(authenticated ? 'security' : 'identity-check'); }}>前往安全设置 <Icon>chevron_right</Icon></button> :
|
||||
null}
|
||||
<footer>保持警惕<br />即时通讯安全团队</footer>
|
||||
</div>
|
||||
</article>)}
|
||||
|
||||
Reference in New Issue
Block a user