Files
tencent-im-util/src/main/resources/templates/sourceapp.ftl
T
yixiongandClaude 7b1385e160 feat(t14-s1s2): 数据迁移基础设施 + 用户迁移
T14 数据迁移工具 S1/S2 阶段:

S1 基础设施:
- source_app/migrate_task 建表 + 实体 + Mapper
- TencentImClient 双密钥 callApiAs(老应用拉取,不走主应用限流,审计记 migrate)
- 后台「老应用配置」页(CRUD + 测试连通)

S2 用户迁移:
- batchImport(multiaccount_import,每批≤100)
- MigrateService.migrateUsers(前缀转换+导入+映射+校验,幂等)
- 后台「数据迁移」页(上传清单文件/粘贴列表 + 任务记录)

联调通过:3用户清单→加sa前缀→腾讯导入OK→user_mapping→校验3/3/3。

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-09 11:12:25 +08:00

95 lines
4.6 KiB
Plaintext
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.
<#import "_macros.ftl" as m>
<@m.layout active="sourceapp" title="老应用配置">
<#if msg?has_content>
<div class="alert">
<#if msg=='saved'>保存成功
<#elseif msg=='toggled'>状态已切换
<#elseif msg=='test_ok'>✅ 连通成功(SDKAppId/密钥/sig 正确)
<#elseif msg=='test_sigfail'>❌ 连通失败:UserSig 错误(70003SDKAppId/密钥不匹配)
<#elseif msg=='test_fail'>❌ 连通失败(详见日志)
<#elseif msg=='sdkappid_required'>SDKAppID 必填
<#elseif msg=='tenant_required'>对应租户必填
<#elseif msg=='notfound'>老应用不存在
<#else>${msg}
</#if>
</div>
</#if>
<p class="muted">数据迁移源:每个老应用对应主应用一个租户(决定 UserID 前缀)。迁移时用其 SDKAppID/密钥调腾讯 API 拉取存量数据,加前缀后导入主应用。密钥仅本工具持有。</p>
<div style="margin-bottom:14px">
<button class="btn btn-success" onclick="document.getElementById('addModal').classList.add('show')"> 新增老应用</button>
</div>
<#if apps?has_content>
<table class="data-table">
<thead>
<tr>
<th>ID</th><th>应用名称</th><th>SDKAppID</th><th>密钥</th><th>对应租户</th>
<th>状态</th><th>操作</th>
</tr>
</thead>
<tbody>
<#list apps as a>
<tr>
<td>${a.id!}</td>
<td>${a.appName!}</td>
<td>${a.sdkAppId!}</td>
<td class="muted">••••••••</td>
<td>${a.tenantId!}</td>
<td>
<#if a.status?? && a.status == 1>
<span class="badge badge-ok">启用</span>
<#else>
<span class="badge badge-no">停用</span>
</#if>
</td>
<td>
<form method="post" action="${basePath}/admin/sourceapp/toggle" style="display:inline">
<input type="hidden" name="id" value="${a.id!}">
<#if a.status?? && a.status == 1>
<input type="hidden" name="status" value="0">
<button class="btn btn-sm btn-secondary">停用</button>
<#else>
<input type="hidden" name="status" value="1">
<button class="btn btn-sm btn-success">启用</button>
</#if>
</form>
<form method="post" action="${basePath}/admin/sourceapp/test" style="display:inline">
<input type="hidden" name="id" value="${a.id!}">
<button class="btn btn-sm btn-primary">测试连通</button>
</form>
</td>
</tr>
</#list>
</tbody>
</table>
<#else>
<div class="empty">暂无老应用配置,点击「新增老应用」添加</div>
</#if>
<div id="addModal" class="modal" onclick="if(event.target===this)this.classList.remove('show')">
<div class="modal-content">
<div class="modal-title">新增老应用</div>
<form method="post" action="${basePath}/admin/sourceapp/save">
<div class="modal-body">
<div class="form-group"><label>应用名称</label><input name="appName" required></div>
<div class="form-group"><label>SDKAppID(老应用)</label><input name="sdkAppId" required></div>
<div class="form-group"><label>SecretKey(老应用密钥)</label><input name="secretKey" required></div>
<div class="form-group">
<label>对应租户(决定 UserID 前缀)</label>
<select name="tenantId" required>
<option value="">请选择租户</option>
<#list tenants as t>
<option value="${t.tenantId!}">${t.tenantId!}${t.tenantName!},前缀 ${t.prefixCode!}</option>
</#list>
</select>
</div>
<div class="form-group"><label>备注</label><input name="remark" placeholder="如:原XX系统IM应用"></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" onclick="document.getElementById('addModal').classList.remove('show')">取消</button>
<button type="submit" class="btn btn-primary">保存</button>
</div>
</form>
</div>
</div>
</@m.layout>