feat(t16): 消息记录查看(列表+筛选+分页+详情+分发链路)
- ImMessageMapper: +selectMessagePage/+countMessages(动态条件+LIMIT/OFFSET,带时间窗分区裁剪) - DistQueueMapper: +selectByMsgKey(详情关联分发链路,LIMIT 100) - AdminController: GET /admin/messages(列表+筛选+分页,默认近7天已分发)+ /admin/messages/detail - messages.ftl/messages_detail.ftl: 列表+筛选+分页 / 详情+msg_body+dist_queue链路 - _macros.ftl: 侧边栏加消息记录导航 - 时间由Controller预格式化(FreeMarker对java.time支持不稳),msgTimeIso用纳秒精度匹配DB微秒 Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
<#--
|
||||
消息详情页
|
||||
基本信息(im_message 完整字段,时间由 Controller 预格式化)+ msg_body 原始 JSON + 分发链路(dist_queue)
|
||||
-->
|
||||
<#import "_macros.ftl" as m>
|
||||
<@m.layout active="messages" title="消息详情">
|
||||
<div style="margin-bottom:16px">
|
||||
<a href="${basePath}/admin/messages" class="btn btn-secondary btn-sm">← 返回列表</a>
|
||||
</div>
|
||||
|
||||
<#if msg??>
|
||||
<div style="background:#fff;border-radius:8px;padding:20px;box-shadow:0 1px 6px rgba(0,0,0,.07);margin-bottom:16px">
|
||||
<h3 style="font-size:15px;margin-bottom:14px">基本信息</h3>
|
||||
<table class="data-table" style="margin-bottom:0">
|
||||
<tbody>
|
||||
<tr><th style="width:140px">MsgKey</th><td>${msg.msgKey!}</td></tr>
|
||||
<tr><th>消息时间</th><td>${msgTimeStr!}</td></tr>
|
||||
<tr><th>租户</th><td>${msg.tenantId!}</td></tr>
|
||||
<tr><th>会话类型</th><td><#if msg.convType?? && msg.convType==1>C2C<#elseif msg.convType?? && msg.convType==2>群<#else>-</#if></td></tr>
|
||||
<tr><th>会话ID</th><td>${msg.convId!}</td></tr>
|
||||
<tr><th>发送方</th><td>${msg.fromAccount!}</td></tr>
|
||||
<tr><th>接收方</th><td>${msg.toAccount!}</td></tr>
|
||||
<tr><th>群ID</th><td>${msg.groupId!}</td></tr>
|
||||
<tr><th>消息类型</th><td>${msg.msgType!}</td></tr>
|
||||
<tr><th>来源</th><td>${msg.source!}</td></tr>
|
||||
<tr><th>跨租户</th><td><#if msg.isCrossTenant?? && msg.isCrossTenant>是<#else>否</#if></td></tr>
|
||||
<tr><th>分发状态</th><td>
|
||||
<#if msg.distStatus?? && msg.distStatus==1><span class="badge badge-ok">已分发</span>
|
||||
<#elseif msg.distStatus?? && msg.distStatus==0><span class="badge badge-warn">待分发</span>
|
||||
<#elseif msg.distStatus?? && msg.distStatus==2><span class="badge badge-no">失败</span>
|
||||
<#else>-</#if>
|
||||
</td></tr>
|
||||
<tr><th>入库时间</th><td>${msgCreatedStr!}</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div style="background:#fff;border-radius:8px;padding:20px;box-shadow:0 1px 6px rgba(0,0,0,.07);margin-bottom:16px">
|
||||
<h3 style="font-size:15px;margin-bottom:14px">消息体(msg_body)</h3>
|
||||
<pre style="background:#f6f8fa;padding:14px;border-radius:6px;overflow:auto;font-size:13px;max-height:400px;white-space:pre-wrap;word-break:break-all">${msg.msgBody!}</pre>
|
||||
</div>
|
||||
|
||||
<div style="background:#fff;border-radius:8px;padding:20px;box-shadow:0 1px 6px rgba(0,0,0,.07)">
|
||||
<h3 style="font-size:15px;margin-bottom:14px">分发链路(dist_queue,最多 100 条)</h3>
|
||||
<#if dists?has_content>
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr><th>ID</th><th>目标地址</th><th>租户</th><th>状态</th><th>重试</th><th>创建时间</th><th>更新时间</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<#list dists as d>
|
||||
<tr>
|
||||
<td>${d.id!}</td>
|
||||
<td class="muted" style="max-width:320px;word-break:break-all">${d.targetUrl!}</td>
|
||||
<td>${d.tenantId!}</td>
|
||||
<td>
|
||||
<#if d.status?? && d.status==0><span class="badge badge-warn">待分发</span>
|
||||
<#elseif d.status?? && d.status==1><span class="badge badge-warn">处理中</span>
|
||||
<#elseif d.status?? && d.status==2><span class="badge badge-ok">已分发</span>
|
||||
<#elseif d.status?? && d.status==3><span class="badge badge-no">死信</span>
|
||||
<#else>-</#if>
|
||||
</td>
|
||||
<td>${d.retryCount!}</td>
|
||||
<td>${d.createdStr!}</td>
|
||||
<td>${d.updatedStr!}</td>
|
||||
</tr>
|
||||
</#list>
|
||||
</tbody>
|
||||
</table>
|
||||
<#else>
|
||||
<div class="empty">无分发记录</div>
|
||||
</#if>
|
||||
</div>
|
||||
<#else>
|
||||
<div class="empty">消息不存在或参数缺失</div>
|
||||
</#if>
|
||||
</@m.layout>
|
||||
Reference in New Issue
Block a user