fix: 完成商务迁移复核与接口优化并清理历史资料
This commit is contained in:
@@ -23,7 +23,7 @@ Kra 管理后台由 Kratos 应用承载生命周期,Gin 提供兼容管理端
|
||||
| 目录 | 职责 |
|
||||
|---|---|
|
||||
| `internal/server` | Gin 路由、中间件和 Kratos transport 生命周期 |
|
||||
| `internal/service` | HTTP DTO 与领域对象转换、用例编排 |
|
||||
| `internal/service` | HTTP 输入校验、DTO 与领域对象转换 |
|
||||
| `internal/biz` | 领域对象、业务规则和仓储接口 |
|
||||
| `internal/data` | GORM、MySQL、Redis 和本地文件存储实现 |
|
||||
| `web` | Vue 3 管理端 |
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
# 当前接口审查(2026-11-04)
|
||||
|
||||
## 范围
|
||||
|
||||
以 `internal/routecatalog/catalog.go` 与实际 Gin 注册为基线:共 **252** 个接口,其中商务 **55** 个(包括 4 个找回密码接口),原生框架 **197** 个。公开接口 15 个,其余 237 个均检查认证入口;分别在空前缀和 `/api` 前缀下执行未登录请求,共 **474** 项认证回归。
|
||||
|
||||
路由完整性与鉴权检查覆盖全部入口。按领域审查商务查询、权限范围、输入/排序/分页、写入事务、导出和定时任务,以及原生认证、权限、上传、支付、集成配置和审计的公共处理。真实外部支付、短信发送、OA 审批和所有原生管理写操作未在共享测试数据上逐一执行,不能将路由覆盖等同于这些外部流程全量验收。
|
||||
|
||||
## 本轮修复
|
||||
|
||||
| 问题 | 修改与回归 |
|
||||
|---|---|
|
||||
| 渠道激活只按商务账号名授权,跨平台同名可能串数据 | 列表和流水明细均按已通过绑定的“平台+账号”匹配;测试同名异平台、无绑定、管理员及状态范围 |
|
||||
| 日期只传一端时被忽略,统计结果悄悄回到默认区间 | 商务列表、注册/充值、渠道/游戏统计、区服分析及排行榜统一拒绝不完整/非法/倒置范围;合法默认与单日保留 |
|
||||
| 审计写入无 deadline,数据库异常可能拖住退出 | 每批写入限时 2 秒,Close 最多等 5 秒;关闭后拒绝入队,测试阻塞写入被取消 |
|
||||
| 证书的 content/path/file 别名未脱敏 | 配置读回、掩码提交合并与审计共享识别;覆盖内联证书、密钥、PKCS12、嵌套字段和普通 content 字段 |
|
||||
| 支付测试的结构化步骤消息透传适配器原始错误 | HTTP 返回安全错误和步骤信息,服务端保留诊断;避免 URL、凭据、SQL 经 data 字段泄露 |
|
||||
| 已有错误弹窗时 401 回调被丢弃 | 会话失效立即清理并跳转,不依赖弹窗确认;旧请求不覆盖新令牌或注销新会话;真实 Chrome 验证 |
|
||||
| Swagger 的环境判定与启动日志不同,空环境默认开放 | 配置统一判定,仅显式 dev/development/test/local 开放;启动地址和路由一致,包含缺省及 qa/uat 测试 |
|
||||
| 媒体分类保存原名会把自身当重复记录 | 重名检查排除当前 ID,仍拒绝其他同名分类;媒体重命名缺失记录映射领域 NotFound |
|
||||
| 偏好对比脚本在 HTTP 恢复失败时跳过数据库恢复 | 双层 finally 确保尝试恢复原行和更新时间 |
|
||||
|
||||
本次提交也包含此前完成但尚未提交的迁移任务、SQL 修正、查询索引、性能优化及页面修复。性能和统计口径见 [商务验收](sw6-to-kra/validation.md)。
|
||||
|
||||
## 验证结果与数据漂移
|
||||
|
||||
- `make generate`、`go test ./...`、`go vet ./...`、服务构建通过;Wire 由工具重新生成。
|
||||
- 独立 MySQL 5.7 的 5 组测试通过:预警并发去重、渠道并发创建、注册 CAST 索引、区服时间索引、查询索引幂等及冲突拒绝。
|
||||
- 前端完整 ESLint 和生产构建通过;构建仍提示大分块及第三方 BigInt 目标兼容告警,没有把告警视为旧浏览器兼容验证。Chrome 实测覆盖另一个错误弹窗已打开时的 401 清理和跳转。
|
||||
- 新旧真实读取共 75 组:管理员 36,绑定三级 21,专用一级/二级/三级各 6。**73 组相等,2 组预警列表因数据快照不同而不等**,失败原始报告已保留。
|
||||
- 漂移核实:sw8 的预警在 **2026-11-04 14:00** 被更新,当前 480 条;sw9 为原快照 478 条,其中 55 个同 ID 记录的时间已不同。本机旧服务配置仍关闭调度,未从其日志确认更新来源;没有覆盖、删除或回写 sw8 的新记录。
|
||||
- 使用之前保存的同参数 sw8 快照重新核对当前 sw9 的完整预警列表,通过;报告明确 `source_capture_reused=true`。这证明当前列表符合该快照,不代表两库当前内容相等。
|
||||
- 新版已启动在日常 8000;8 组工作台、排行榜、激活第二页、偏好和任务注册结果与验证实例一致。
|
||||
|
||||
本轮原始报告位于仓库外 `D:/Users/Yvan/backups/sw9/20261104_rehearsal/review_20261104/`。此前完整写入/导出/重建及恢复证据见 [历史综合索引](sw6-to-kra/sw8-sw9-recheck-summary-2026-11-04.json)。本机无可用 CGO 编译环境,未运行 `-race`,不宣称竞态检测通过。
|
||||
|
||||
## 保留的框架风险与验证边界
|
||||
|
||||
旧审查材料中尚未消除的内容移到这里,避免删除历史文档时丢失问题。它们不属于“已修复”清单:
|
||||
|
||||
| 范围 | 当前边界 |
|
||||
|---|---|
|
||||
| 媒体并发 | 删除只有进程内互斥,秒传复用创建与删除缺少统一的跨实例引用锁;长时间合并仍受陈旧会话清理宽限影响,需要独立并发/故障方案 |
|
||||
| 配置保存 | storage、email 和配置文件分步持久化,中途失败可能形成部分成功;尚无跨存储的原子提交/补偿流程 |
|
||||
| 历史支付订单 | 请求指纹严格匹配;缺少旧指纹样本的幂等重放验证,不直接放宽金额、业务身份的冲突检查 |
|
||||
| 错误协议 | 框架仍有裸错误与字符串拼接、响应净化规则;此次堵住支付测试 data 泄露,但未统一全框架 typed error 协议 |
|
||||
| 认证与前端路由 | token 仍由既有 localStorage 方案保存,登录与守卫仍各有动态路由注册;改成仅 HttpOnly cookie 或统一注册需要独立兼容设计 |
|
||||
| 调度启动 | 永久非法 cron 会保持旧计划并继续启动重试;数据库读失败不清空既有计划,但固定重试间隔仍可改成有界退避 |
|
||||
| 审计可读性 | 一些通用 key/序列号字段仍被旧脱敏策略掩盖;未为恢复可读性而放宽密钥保护 |
|
||||
|
||||
## 文档与脚本清理
|
||||
|
||||
104 份阶段报告、重复 JSON、旧目录审查和独立菜单 SQL,以及 26 个旧脚本已逐文件复制到仓库外并校验 SHA-256 后移除。保留统一迁移 SQL、业务口径、综合验收索引和 14 个当前验证工具,补充维护入口与脚本说明。
|
||||
|
||||
真实本地配置 `configs/config.yaml`、私有运行数据,以及其他会话的 V2 估算和 outputs 成果不纳入本次提交。未推送远端。
|
||||
@@ -0,0 +1,9 @@
|
||||
# 文档入口
|
||||
|
||||
- [商务迁移](sw6-to-kra/README.md):统一 SQL、业务口径、接口与任务验收。
|
||||
- [当前接口审查](API_REVIEW.md):此次修复、验证范围及保留的技术风险。
|
||||
- [后台说明](ADMIN_BACKEND.md)、[支付接入](PAYMENT.md)、[短信接入](SMS_INTEGRATION.md)。
|
||||
- [OA 迁移计划](OA_MIGRATION_PLAN.md):独立 OA 工作的设计材料,不是当前商务迁移的完成证明。
|
||||
- [验证脚本](../scripts/README.md):保留工具的用途和私有输入约定。
|
||||
|
||||
历史阶段记录已归档到仓库外;后续将最新结果更新到对应维护文档,不再每个接口生成一份日期报告。其他会话生成的商务 V2 估算及表格保持原状,本次清理和提交不包含这些文件。
|
||||
@@ -1,78 +0,0 @@
|
||||
# 代码审查问题清单(internal + pkg)
|
||||
|
||||
- 审查日期:2026-08-27 ~ 2026-08-28,共十一轮全量审查。第十一轮(2026-08-28):核查第十轮划线项(22 项)+ 全新视角回归审查;`go build ./...` 编译验证通过
|
||||
- 文档结构:只保留待修复问题,按**类型**归类;每条标注发现轮次与处置状态(专项待修/待修);已修复并经复查确认的、经评估决定保留的、用户决策不修的直接删除
|
||||
- gva/ 目录是遗留参考库(独立 module 不参与 kra 编译),不在审查范围
|
||||
- 依赖方向合规:pkg 无 import internal;integration 不 import data/service;data 不 import integration/payment;无循环依赖
|
||||
- 第十一轮总评:核心分层契约、日志防循环、CleanupStale 顺序反转、调度器重试、微文件合并等历轮修复验收干净;当前风险集中在**边缘入口的防护不对称**——公开写接口无治理、TTL 语义错位、停机路径无超时、前端凭证存储薄弱
|
||||
|
||||
---
|
||||
|
||||
## 一、安全与正确性缺陷
|
||||
|
||||
### 专项设计待修(用户已确认需专项处理)
|
||||
|
||||
| # | 问题 | 位置 | 状态 |
|
||||
|---|------|------|------|
|
||||
| ~~V-39~~ | ~~公开无限流写接口 `/sysError/createSysError`~~:已移入鉴权路由组、纳入安全限流,并限制 `Info` 最大长度 | ~~server/router/audit.go;middleware/rate_limit.go;service/dto/audit.go~~ | ~~十一轮~~ |
|
||||
| V-33 | 支付指纹严格相等校验对存量订单幂等重放的冲突风险(initialized/pending 存量订单重放报参数冲突而非幂等短路)——修复需兼容旧指纹、区分订单状态、覆盖并发重放,直接放宽会削弱防篡改 | biz/payment/payment.go:645-657 | 十轮发现,专项 |
|
||||
| V-24 | Delete↔Create 竞态窗口仍开(锁仅覆盖 Delete,秒传/上传/Complete 的 CreateMedia 路径不持锁);多副本需数据库/分布式锁 | biz/system/media.go:50,111-143;media_upload.go:100-107,262 | 八轮发现,专项 |
|
||||
| V-13b | swagger:空 env fail-open(gin.go:68 仍注册);gin 白名单 vs main.go 黑名单双清单不一致(qa/uat 时日志谎报);env 门禁零测试——需统一单一判定函数+环境矩阵测试 | server/gin.go:64-70;cmd/main.go:105-126,171 | 七轮发现,专项 |
|
||||
| V-27 | redis_list 仍按下标回退(configuration.go:439-441,database_list 已修✓);别名匹配失败时哨兵字面量落盘无拒绝校验——需重新定义配置项稳定标识与密钥继承规则 | internal/initialize/configuration.go:427-446 | 九轮发现,专项 |
|
||||
| V-20 | 前端 token 拼入 URL(完整 JWT 拼二维码 URL)——需后端一次性短时效票据+扫码协议迁移 | web/src/components/upload/QR-code.vue:55 | 六轮发现,专项 |
|
||||
| V-15 | **envelope 净化剩余三洞**(全角冒号已修✓——response.go:53 分隔符已扩 ["失败:","失败:"]):① 17 处无冒号/紧贴拼接调用截断不可命中(api.go:137,156、authority.go 9 处、menu.go:170,178,198、user.go:150),非黑名单错误原样透出;② **CodeError data 通道完全无净化**——payment TestProvider Stages[].Message 原始 err 随 data 到前端;③ 净化静默无日志("不泄露也不可排障")。另有误伤:宽泛词 marker+约 45 处截断吞 biz 可读提示——需统一错误模型+结构化 Data 脱敏+日志策略 | server/httpx/response.go:32-59;data/payment/payment.go:79-139 | 六轮发现,专项 |
|
||||
| V-19 | **证书别名缺口仍在(三层同源✓但键表未补别名——"已纳入键表"声称不实)**:app_cert_content/root_cert_content/pkcs12_content/cert_content/key_content/cert_path 等仍不命中 IsIntegrationSecretKey(后缀表无 *_content/*_path 项,integration_config.go:402-413)→ API 直连提交明文落库并回显,日志 resp_data 同泄;修法:剥后缀匹配词干或显式枚举(勿用裸 content/path 后缀防误伤) | biz/integration/integration_config.go:402-413,329-332,427-435 | 六轮发现,十轮部分+十一轮复核未闭合 |
|
||||
| ~~V-30~~ | ~~douyin `platform_serial_no` required 标记与别名校验不一致~~:字段已标记 required,支付 required 校验同时识别 `platform_cert_serial` 别名 | ~~biz/integration/integration_config_definition.go;integration_config.go~~ | ~~十一轮复核~~ |
|
||||
| V-38 | 媒体域裸错误(ErrMediaTooLarge/ErrUploadSessionNotFound)vs AGENTS typed errors 契约——需连同错误码表与 HTTP 映射一起迁移 | biz/system/media.go:52、media_upload.go:21 | 十轮发现,专项 |
|
||||
|
||||
### 待修(正确性缺陷)
|
||||
|
||||
| # | 问题 | 位置 | 状态 |
|
||||
|---|------|------|------|
|
||||
| ~~V-40~~ | ~~上传会话 TTL 未按最后活动时间刷新~~:每次分片写入后同步更新上传会话 `updated_at` | ~~data/system/media_upload.go~~ | ~~十一轮~~ |
|
||||
| V-41 | (新发现,中低)merging 仅 1h 宽限(data:129),远程存储 Compose 超 1h 的合法合并被清理并整体失败(有回滚无泄漏,功能误杀) | data/system/media_upload.go:129 | 十一轮 |
|
||||
| V-42 | **(新发现,中)dataScopeAuditWriter.Close 无超时且 MySQL DSN 无网络超时**:Close 无限期 `<-w.done`(:67-73)、flush 用 context.Background 无 deadline(:88)、DSN 无 readTimeout/writeTimeout(config.yaml:9,15)——DB 故障时 cleanup 链(data.go:191-198 先 auditLog.Close 后关 DB)被挂起 flush 永久阻塞,进程无法优雅退出 | data/data_scope_audit.go:67-73,88;configs/config.yaml:9,15 | 十一轮 |
|
||||
| V-43 | **(新发现,中)前端 token 存 localStorage(7 天长期凭证 XSS 可窃)+ 401 登出回调可被并发弹窗吞掉**(application/index.vue:16 已有弹窗时 show-error 被忽略、handleClose 置 null cb 不执行 → 401 后 token 残留循环) | web/src/pinia/modules/user.js:23;components/application/index.vue:16;utils/request.js:231-241 | 十一轮 |
|
||||
| ~~V-44~~ | ~~V-36 词表收窄导致“导出token无效或已过期”不再命中~~:已补充 `token无效` 匹配 | ~~middleware/error_audit.go~~ | ~~十一轮~~ |
|
||||
| ~~V-45~~ | ~~sysError 写路径失败无日志~~:创建失败时已记录结构化错误日志 | ~~server/handler/audit.go~~ | ~~十一轮~~ |
|
||||
| V-46 | (新发现,低)调度器启动重试无上限无退避:永久性错误(cron 解析失败整批 return err,task_scheduler.go:204-207)会每 5s 重试永不成功+刷 Warn 日志(约 720 条/小时)——需区分永久/暂时性错误 | worker/task_scheduler.go:93-112,204-207 | 十一轮(V-35 修复残留) |
|
||||
| V-47 | (新发现,低)PersistRuntimeConfig 三段写非原子(先 storage 再 email 再 config,任一失败返回)——前面已写的集成配置与未替换的 runtime 出现不一致窗口 | data/initialization_backend.go:74-83 | 十一轮 |
|
||||
| V-31 残留 | UpdateMediaName 仍透传 gorm 原文(404 语义丢失) | data/system/media.go:125-127 | 九轮,部分修复 |
|
||||
|
||||
## 二、死代码与碎屑
|
||||
|
||||
| # | 问题 | 位置 | 状态 |
|
||||
|---|------|------|------|
|
||||
| Z-15 | 软删字段死重量(4 个 PO 的 DeletedAt+索引在删除路径全 Unscoped 后成死配置)——存量表结构清理需迁移与回滚策略,待数据库迁移窗口 | data/system/media.go:16,34;media_upload.go:17,35,104 | 九轮,专项 |
|
||||
| Z-9 | audit.go:76/83 ctxRespTextKey/ctxRespTruncatedKey 消费分支生产链路不可达(后置键);access_log 先对截断体完整脱敏再覆盖(白做功)——需连同响应捕获链路整体重构 | server/middleware/audit.go:76-85;access_log.go:110-121 | 八轮,专项 |
|
||||
| Z-13 残留 | cors.go:13-14 逗号空格、audit.go:104 单行 13 字段、audit.go:46-47 空 else-if——纯格式问题(用户评估:格式化工具统一处理) | server/middleware/ | 八轮,评估暂缓 |
|
||||
| Z-17 | scanUpload.vue 空 catch 吞路由就绪异常——需统一前端错误上报 | web/src/view/media/scanUpload.vue:115-116 | 九轮,专项 |
|
||||
| Z-22 | (新发现)Z-19 清理后前端死代码残留:image.js:32-35 空 if 块+未使用 newImgSize;global.js:51,54 未使用 allKeys+悬空比较表达式;另 3 处已注释 console 代码(cropper.vue:198、upload.vue:363、menus.vue:302) | web/src/utils/image.js:32-35;core/global.js:51,54 | 十一轮 |
|
||||
| ~~Z-23~~ | ~~douyin 别名分支放错校验器~~:已移除通信校验器中的不可达分支,别名逻辑归入支付校验器 | ~~biz/integration/integration_config.go~~ | ~~十一轮~~ |
|
||||
| Z-24 | (新发现)秒传分支变量名 `copy` 遮蔽内置函数(可读性) | biz/system/media_upload.go:100 | 十一轮 |
|
||||
|
||||
## 三、重复实现 / 双轨残留
|
||||
|
||||
| # | 问题 | 位置 | 状态 |
|
||||
|---|------|------|------|
|
||||
| Y-7 | 掩码三套实现+键表多层漂移(data Secret∪IsIntegrationSecretKey / service 仅后者 / redact.go 第四张表);哨兵双轨(****** vs ***)——需先定义跨层协议(专项) | data/integration:225-245;service/integration:69-96;redact.go:18-27 | 九轮,专项 |
|
||||
| Y-12 | **(新发现,中低)redact 键表误伤非机密标识符,审计记录失去回放价值**:redact.go:22 精确项 "key"、:24-25 platformserialno/webhookid 是序列号/ID 非秘密——实证误伤 dto/menu.go:26,90(菜单路由 key)、dto/media.go:15,76(存储 key)、settings.go:45,56,117、version.go:39,这些写接口的操作审计响应中 key 全为 `***`,菜单/媒体/设置类审计基本无法回放排障(安全无泄漏,可用性受损) | server/middleware/redact.go:22,24-25;dto/menu.go:26 等 | 十一轮 |
|
||||
| Y-5 | 集成配置校验双重执行(biz 层对掩码值总通过半失效)——用户评估:分层防线保留 | biz/integration:122-129 | 八轮,评估保留 |
|
||||
| Y-2 剩余 | capture.go JSON 成功路径先 marshal 后判超限(超长白做)——用户评估:安全优先保留现状 | middleware/capture.go:49-76 | 六轮,评估保留 |
|
||||
| Y-10 | 前端两套动态路由注册逻辑(登录整树 vs 守卫扁平化+redirect)——需先补路由矩阵测试 | web/src/pinia/modules/user.js:85-87;permission.js:78-146 | 十轮,专项 |
|
||||
|
||||
## 四、文档漂移
|
||||
|
||||
| # | 问题 | 位置 | 状态 |
|
||||
|---|------|------|------|
|
||||
| F-37 | **CLAUDE.md:19 integration 描述仍为 "(cache, email, payment, storage)" 4 项("已同步"声称不实——实际目录 8 个模块,AGENTS.md 版本已含全部)** | CLAUDE.md:19 | 十轮发现,声称不实 |
|
||||
| F-39 | (新,微)根 README.md:7-18 目录树缺 internal/{integration,modules,paymentkit,routecatalog,logging,utils} 与 pkg/(AGENTS.md 为权威无错,README 属简化版) | README.md:7-18 | 十一轮 |
|
||||
|
||||
## 处置建议(按优先级)
|
||||
|
||||
1. **V-39 公开写接口治理**(限流覆盖/长度 binding/或移入鉴权组——安全优先)+ **V-44/V-45 ErrorAudit 噪音与盲区**(词表补导出 token 文案或改 4xx;CreateError 失败补日志)
|
||||
2. **V-40 TTL 改活动时间**(UpsertChunk touch 会话 updated_at——一行修复)+ **V-42 Close/DSN 超时** + **V-46 重试上限/退避**
|
||||
3. **V-19 键表补别名**(剥后缀匹配词干——一处三层受益;连带 Z-23 死分支归位)+ **V-30 douyin required**(通用循环感知别名后置 true)
|
||||
4. **V-43 前端凭证**(401 回调修复+token 存储评估)+ **F-37 一行同步**(本轮声称不实项)
|
||||
5. **V-41/V-47/V-31 残留 + Z-22/23/24 碎屑 + Y-12 redact 误伤面收敛**(与 Y-7 专项一并设计)
|
||||
6. **专项批次**:V-15 错误模型统一、V-33 指纹兼容窗口、V-24 分布式锁、V-13b 单一判定函数、V-27 稳定标识、V-20 短时票据、V-38 错误码迁移、Z-15 迁移窗口、Z-9 响应链重构、Y-7 跨层协议、Y-10 路由矩阵
|
||||
@@ -0,0 +1,28 @@
|
||||
# 商务迁移维护入口
|
||||
|
||||
旧 Java 商务使用测试库 **sw8**,当前 Go 商务使用 **sw9**。两库来自相同线上副本;未执行正式库 sw6 迁移。
|
||||
|
||||
## 执行顺序
|
||||
|
||||
1. 准备完整业务副本及 SQL 要求的 26 张框架源表,保存数据库备份。
|
||||
2. 在 [统一迁移 SQL](sw_to_kra_migrate.sql) 开头修改 `USE`,当前为 `USE sw9`。用支持 `DELIMITER` 的客户端在同一连接执行,遇错停止。
|
||||
3. 启动当前 Go 版本,执行版本迁移,补齐业务锁、密码重置表、附件引用和查询索引。大表首次建索引需要等待完成。
|
||||
4. 配置主库和 `lx`、`hw`、`yq`、`oa` 数据源。配置和凭据保存在仓库外;数据库连接信息不写入本目录。
|
||||
5. 对照 [验收记录](validation.md) 与 [验证脚本说明](../../scripts/README.md) 复核接口和任务。迁入计划默认停用,启用前应确认业务所需运行时段。
|
||||
|
||||
SQL 自动区分首次迁移、已完成迁移的菜单调整和异常中间状态;不会对完成迁移的库重新导入账号。重复执行及旧表已归档/清理的路径均有演练记录。
|
||||
|
||||
当前 SQL v5 按 LF 规范化 SHA-256:
|
||||
`07e2c8395b6f43f064fe973407f374a962b39d07474bfba68aeb2b3c5ffe8bf2`。
|
||||
|
||||
## 维护材料
|
||||
|
||||
- [验收与性能记录](validation.md):数据、任务、已知契约差异和性能基线。
|
||||
- [历史逐接口验收索引](sw8-sw9-recheck-summary-2026-11-04.json):63 项旧契约及 230 项检查;时间点为最近一次完整写入演练,不代表以后每轮都重跑写操作。
|
||||
- [原生系统接口与旧别名](system-api-audit.md)、[附件引用转换](alert-attachment-migration.md)。
|
||||
- 各域 `*-source-notes.md`:长期保留的查询、权限和统计口径。
|
||||
- [当前接口审查](../API_REVIEW.md):此次修复、测试范围与需继续验证的框架边界。
|
||||
|
||||
SQL 生成器位于旧仓库 `script/sql/sw6_to_kra/build_sw7_migration.py`。修改生成器后同步本目录统一 SQL,并重新核对散列及迁移结果;不要恢复分阶段 SQL 补丁。
|
||||
|
||||
阶段报告、重复 JSON、旧 sw7 冒烟脚本已归档到本机仓库外 `D:/Users/Yvan/backups/sw9/20261104_rehearsal/cleanup-archive/`。该目录以及相邻的运行配置、原始响应、分区备份不纳入 Git。历史索引中 `reports` 项的文件名可在归档内查找。
|
||||
@@ -1,44 +0,0 @@
|
||||
{
|
||||
"scope": "当前 sw7 运行实例,只读请求;OA 未接入场景明确返回 available=false。完整 OA 与流水数据通过两个隔离数据库的 TCP HTTP 测试。",
|
||||
"checks": [
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/sw/promoteActivePool/bindList?pageNum=1&pageSize=10",
|
||||
"http": 200,
|
||||
"code": 0,
|
||||
"msg": "成功",
|
||||
"passed": true,
|
||||
"total": 0,
|
||||
"available": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/sw/promoteActivePool/bindList?platformNames=lx,hw&statuses=reached",
|
||||
"http": 200,
|
||||
"code": 0,
|
||||
"msg": "成功",
|
||||
"passed": true,
|
||||
"total": 0,
|
||||
"available": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/sw/promoteActivePool/bindList?statuses=%E5%B7%B2%E8%BE%BE%E6%A0%87&busierAccount=does-not-exist",
|
||||
"http": 200,
|
||||
"code": 0,
|
||||
"msg": "成功",
|
||||
"passed": true,
|
||||
"total": 0,
|
||||
"available": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/sw/promoteActivePool/bindSpendDetail?id=0",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "绑定记录不存在",
|
||||
"passed": true
|
||||
}
|
||||
],
|
||||
"passed": true
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"method": "真实 Chrome,受控 OA 和流水响应,无写入",
|
||||
"passed": true,
|
||||
"rejectedHidesFlow": true,
|
||||
"pendingShowsReasonWithoutFakeTotal": true,
|
||||
"reachedCutoffDisplayed": true,
|
||||
"exactLargeAmount": true,
|
||||
"filtersAndReset": true,
|
||||
"unavailableSourceNotice": true,
|
||||
"pageErrors": []
|
||||
}
|
||||
@@ -1,123 +0,0 @@
|
||||
{
|
||||
"scope": "既有 sw7,只读查询及必然拒绝的无效写请求;正向流转另用隔离 SQLite 和 TCP HTTP 测试",
|
||||
"base_url": "http://127.0.0.1:18000",
|
||||
"checks": [
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/sw/alertRecord/list?pageNum=1&pageSize=10",
|
||||
"http": 200,
|
||||
"code": 0,
|
||||
"msg": "成功",
|
||||
"passed": true,
|
||||
"total": 0,
|
||||
"available": true,
|
||||
"status_count": {}
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/sw/alertRecord/list?platformCodes=lx,hw&status=5",
|
||||
"http": 200,
|
||||
"code": 0,
|
||||
"msg": "成功",
|
||||
"passed": true,
|
||||
"total": 0,
|
||||
"available": true,
|
||||
"status_count": {}
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/sw/alertRule/ruleTypes",
|
||||
"http": 200,
|
||||
"code": 0,
|
||||
"msg": "成功",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/sw/business/list?pageNum=1&pageSize=500",
|
||||
"http": 200,
|
||||
"code": 0,
|
||||
"msg": "成功",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/sw/alertRecord/list?businessId=10007",
|
||||
"http": 200,
|
||||
"code": 0,
|
||||
"msg": "成功",
|
||||
"passed": true,
|
||||
"total": 0,
|
||||
"available": false,
|
||||
"status_count": {}
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/sw/alertRecord/list?businessId=10001",
|
||||
"http": 200,
|
||||
"code": 0,
|
||||
"msg": "成功",
|
||||
"passed": true,
|
||||
"total": 0,
|
||||
"available": true,
|
||||
"status_count": {}
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/sw/alertRecord/detail/0",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "预警记录参数不正确",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/sw/alertRecord/startProcess",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "预警记录参数不正确",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/sw/alertRecord/submitAudit",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "预警记录参数不正确",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/sw/alertRecord/approve",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "预警记录参数不正确",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/sw/alertRecord/reject",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "预警记录参数不正确",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/sw/alertRecord/reProcess",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "预警记录参数不正确",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/sw/alertRecord/addNote",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "预警记录参数不正确",
|
||||
"passed": true
|
||||
}
|
||||
],
|
||||
"passed": true
|
||||
}
|
||||
@@ -1,116 +0,0 @@
|
||||
{
|
||||
"method": "真实 Chrome 渲染;受控身份、预警数据、写接口和图片上传;未修改真实业务数据",
|
||||
"results": [
|
||||
{
|
||||
"level": 0,
|
||||
"stateButtons": [
|
||||
{
|
||||
"status": 1,
|
||||
"label": "处理"
|
||||
},
|
||||
{
|
||||
"status": 2,
|
||||
"label": "继续处理"
|
||||
},
|
||||
{
|
||||
"status": 3,
|
||||
"label": "查看"
|
||||
},
|
||||
{
|
||||
"status": 4,
|
||||
"label": "重新处理"
|
||||
},
|
||||
{
|
||||
"status": 5,
|
||||
"label": "查看"
|
||||
}
|
||||
],
|
||||
"passed": true,
|
||||
"pageErrors": []
|
||||
},
|
||||
{
|
||||
"level": 1,
|
||||
"stateButtons": [
|
||||
{
|
||||
"status": 1,
|
||||
"label": "处理"
|
||||
},
|
||||
{
|
||||
"status": 2,
|
||||
"label": "继续处理"
|
||||
},
|
||||
{
|
||||
"status": 3,
|
||||
"label": "审核"
|
||||
},
|
||||
{
|
||||
"status": 4,
|
||||
"label": "重新处理"
|
||||
},
|
||||
{
|
||||
"status": 5,
|
||||
"label": "查看"
|
||||
}
|
||||
],
|
||||
"passed": true,
|
||||
"workflowAndAttachments": true,
|
||||
"pasteDropAndRemove": true,
|
||||
"pageErrors": []
|
||||
},
|
||||
{
|
||||
"level": 2,
|
||||
"stateButtons": [
|
||||
{
|
||||
"status": 1,
|
||||
"label": "处理"
|
||||
},
|
||||
{
|
||||
"status": 2,
|
||||
"label": "继续处理"
|
||||
},
|
||||
{
|
||||
"status": 3,
|
||||
"label": "查看"
|
||||
},
|
||||
{
|
||||
"status": 4,
|
||||
"label": "重新处理"
|
||||
},
|
||||
{
|
||||
"status": 5,
|
||||
"label": "查看"
|
||||
}
|
||||
],
|
||||
"passed": true,
|
||||
"statusCardsAndUnavailable": true,
|
||||
"pageErrors": []
|
||||
},
|
||||
{
|
||||
"level": 3,
|
||||
"stateButtons": [
|
||||
{
|
||||
"status": 1,
|
||||
"label": "处理"
|
||||
},
|
||||
{
|
||||
"status": 2,
|
||||
"label": "继续处理"
|
||||
},
|
||||
{
|
||||
"status": 3,
|
||||
"label": "查看"
|
||||
},
|
||||
{
|
||||
"status": 4,
|
||||
"label": "重新处理"
|
||||
},
|
||||
{
|
||||
"status": 5,
|
||||
"label": "查看"
|
||||
}
|
||||
],
|
||||
"passed": true,
|
||||
"pageErrors": []
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
{
|
||||
"scope": "既有 sw7;查询和拒绝无效写请求,未创建真实规则",
|
||||
"schema_before": {
|
||||
"column_type": "decimal(7,2)",
|
||||
"rule_rows": 0
|
||||
},
|
||||
"schema_after": "decimal(7,2)",
|
||||
"checks": [
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/sw/alertRule/list?pageNum=1&pageSize=10",
|
||||
"code": 0,
|
||||
"msg": "成功",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/sw/alertRule/ruleTypes",
|
||||
"code": 0,
|
||||
"msg": "成功",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/sw/alertRule/add",
|
||||
"code": 7,
|
||||
"msg": "预警规则参数不正确",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"method": "PUT",
|
||||
"path": "/sw/alertRule/toggle/0?enabled=1",
|
||||
"code": 7,
|
||||
"msg": "预警规则参数不正确",
|
||||
"passed": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
{
|
||||
"method": "真实 Chrome 渲染,受控角色及规则数据;不写真实规则",
|
||||
"results": [
|
||||
{
|
||||
"level": 0,
|
||||
"createButton": 1,
|
||||
"editButton": 1,
|
||||
"passed": true,
|
||||
"pageErrors": []
|
||||
},
|
||||
{
|
||||
"level": 1,
|
||||
"createButton": 1,
|
||||
"editButton": 1,
|
||||
"passed": true,
|
||||
"metricFields": true,
|
||||
"pageErrors": []
|
||||
},
|
||||
{
|
||||
"level": 2,
|
||||
"createButton": 0,
|
||||
"editButton": 0,
|
||||
"passed": true,
|
||||
"pageErrors": []
|
||||
},
|
||||
{
|
||||
"level": 3,
|
||||
"createButton": 0,
|
||||
"editButton": 0,
|
||||
"passed": true,
|
||||
"pageErrors": []
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
{
|
||||
"scope": "真实 sw7 会话,只读请求;完整统计及权限口径另由隔离 TCP HTTP 测试验证。",
|
||||
"checks": [
|
||||
{
|
||||
"path": "/sw/channelData/list?sourceDb=lx,hw,yq&pageNum=1&pageSize=10",
|
||||
"http": 200,
|
||||
"code": 0,
|
||||
"msg": "成功",
|
||||
"passed": true,
|
||||
"available": false,
|
||||
"total": 0,
|
||||
"begin": "2026-11-04",
|
||||
"end": "2026-11-04"
|
||||
},
|
||||
{
|
||||
"path": "/sw/channelData/list?beginTime=bad&endTime=2026-11-04",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "统计周期格式错误,应为 yyyy-MM-dd",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"path": "/sw/channelData/list?beginTime=2026-11-05&endTime=2026-11-04",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "统计开始日期不能晚于结束日期",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"path": "/sw/gameData/list?sourceDb=lx,hw,yq&pageNum=1&pageSize=10",
|
||||
"http": 200,
|
||||
"code": 0,
|
||||
"msg": "成功",
|
||||
"passed": true,
|
||||
"available": false,
|
||||
"total": 0,
|
||||
"begin": "2026-11-04",
|
||||
"end": "2026-11-04"
|
||||
},
|
||||
{
|
||||
"path": "/sw/gameData/list?beginTime=bad&endTime=2026-11-04",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "统计周期格式错误,应为 yyyy-MM-dd",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"path": "/sw/gameData/list?beginTime=2026-11-05&endTime=2026-11-04",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "统计开始日期不能晚于结束日期",
|
||||
"passed": true
|
||||
}
|
||||
],
|
||||
"passed": true
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
{
|
||||
"method": "真实 Chrome 渲染,受控业务数据;未写入真实数据",
|
||||
"reports": [
|
||||
{
|
||||
"kind": "channel",
|
||||
"passed": true,
|
||||
"fullSummaryAcrossPages": true,
|
||||
"filtersResetPage": true,
|
||||
"platformAndGameFilters": true,
|
||||
"noInventedExport": true,
|
||||
"missingDataNotZero": true,
|
||||
"pageErrors": []
|
||||
},
|
||||
{
|
||||
"kind": "game",
|
||||
"passed": true,
|
||||
"fullSummaryAcrossPages": true,
|
||||
"filtersResetPage": true,
|
||||
"platformAndGameFilters": true,
|
||||
"noInventedExport": true,
|
||||
"missingDataNotZero": true,
|
||||
"pageErrors": []
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -25,4 +25,5 @@
|
||||
- 使用聚合查询和批量资料查询代替逐行查询,不改变业务口径。日期非法或倒置返回明确错误。
|
||||
- 隔离 TCP HTTP 和仓储测试覆盖全量汇总与分页、跨平台同号、官方/孤立渠道、根渠道树去重、类型交集、历史游戏名过滤、当前资料展示、偏好切换及空范围。
|
||||
- 领域测试覆盖大金额精确排序、分母和人数上限。前端检查筛选回第一页、30 天默认值、汇总不随分页变化、缺数据提示、没有额外导出入口。
|
||||
- 真实 sw7 库只做只读请求;当前缺少完整业务报表,最终旧库复制与同源数据比较仍未开始。
|
||||
|
||||
当前验证状态统一见 [验收与性能记录](validation.md),不再维护阶段性运行报告。
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
{
|
||||
"method": "真实 Chrome 渲染;受控身份和业务数据,权限页签与状态操作核对",
|
||||
"results": [
|
||||
{
|
||||
"level": 0,
|
||||
"bindingTab": false,
|
||||
"editButtons": 0,
|
||||
"passed": true,
|
||||
"bindingCalls": 0,
|
||||
"pageErrors": []
|
||||
},
|
||||
{
|
||||
"level": 1,
|
||||
"bindingTab": false,
|
||||
"editButtons": 0,
|
||||
"passed": true,
|
||||
"sdkDetailReadonly": true,
|
||||
"bindingCalls": 0,
|
||||
"pageErrors": []
|
||||
},
|
||||
{
|
||||
"level": 2,
|
||||
"bindingTab": false,
|
||||
"editButtons": 0,
|
||||
"passed": true,
|
||||
"sdkDetailReadonly": true,
|
||||
"bindingCalls": 0,
|
||||
"pageErrors": []
|
||||
},
|
||||
{
|
||||
"level": 3,
|
||||
"bindingTab": true,
|
||||
"editButtons": 0,
|
||||
"passed": true,
|
||||
"normalUnbind": 1,
|
||||
"rejectedUnbind": 0,
|
||||
"pendingUnbind": 0,
|
||||
"rejectedDetail": 1,
|
||||
"rejectedChannelsDisabled": true,
|
||||
"pendingChannelsDisabled": true,
|
||||
"channelFilters": true,
|
||||
"rejectDrawerInViewport": true,
|
||||
"bindingCalls": 1,
|
||||
"pageErrors": []
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
{
|
||||
"scope": "当前 sw7 实际登录会话;只读查询和无效创建。完整查询、偏好、游戏分布及源库创建已在隔离数据库通过 TCP HTTP 验证。",
|
||||
"checks": [
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/sw/promote/list?pageNum=1&pageSize=10",
|
||||
"http": 200,
|
||||
"code": 0,
|
||||
"msg": "成功",
|
||||
"passed": true,
|
||||
"total": 0,
|
||||
"available": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/sw/promote/list?sourceDb=lx,hw&lockStatus=-1&promoteLevel=1",
|
||||
"http": 200,
|
||||
"code": 0,
|
||||
"msg": "成功",
|
||||
"passed": true,
|
||||
"total": 0,
|
||||
"available": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/sw/promote/list?busierAccount=does-not-exist",
|
||||
"http": 200,
|
||||
"code": 0,
|
||||
"msg": "成功",
|
||||
"passed": true,
|
||||
"total": 0,
|
||||
"available": true
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/sw/promote/bindOptions?sourceDb=lx",
|
||||
"http": 200,
|
||||
"code": 0,
|
||||
"msg": "成功",
|
||||
"passed": true,
|
||||
"rows": 17
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/sw/promote/bindOptions?sourceDb=hw",
|
||||
"http": 200,
|
||||
"code": 0,
|
||||
"msg": "成功",
|
||||
"passed": true,
|
||||
"rows": 20
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/sw/promote/bindOptions?sourceDb=yq",
|
||||
"http": 200,
|
||||
"code": 0,
|
||||
"msg": "成功",
|
||||
"passed": true,
|
||||
"rows": 20
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/sw/promote/game-distribution?sourceDb=lx&promoteId=0",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "渠道查询参数不正确",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/sw/promote/game-distribution?sourceDb=lx&promoteId=1",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "渠道数据尚未接入",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/sw/promote",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "请选择有效的游戏商务绑定",
|
||||
"passed": true
|
||||
}
|
||||
],
|
||||
"passed": true
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
{
|
||||
"method": "真实 Chrome 渲染;受控页面数据、身份及平台创建响应,不创建真实平台渠道",
|
||||
"passed": true,
|
||||
"level": 1,
|
||||
"noEditEntry": true,
|
||||
"createAllowedForUpperBusiness": true,
|
||||
"platformSwitchClearsBinding": true,
|
||||
"crossPlatformSameID": true,
|
||||
"zeroGameCountClickable": true,
|
||||
"missingMetricsVisible": true,
|
||||
"sourceDatabaseCreatePayload": true,
|
||||
"portraitPending": false,
|
||||
"pageErrors": []
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
{
|
||||
"scope": "当前 sw7 登录会话,只读检查;完整累计、分层、日期与权限在隔离 TCP HTTP 中验证。",
|
||||
"checks": [
|
||||
{
|
||||
"path": "/sw/promote/list?pageNum=1&pageSize=1",
|
||||
"http": 200,
|
||||
"code": 0,
|
||||
"msg": "成功",
|
||||
"passed": true,
|
||||
"available": false
|
||||
},
|
||||
{
|
||||
"path": "/sw/promote/portrait?sourceDb=lx&promoteId=1&period=total",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "渠道数据尚未接入",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"path": "/sw/promote/portrait?sourceDb=lx&promoteId=0",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "渠道查询参数不正确",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"path": "/sw/promote/portrait?sourceDb=invalid&promoteId=1",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "所属平台不正确",
|
||||
"passed": true
|
||||
}
|
||||
],
|
||||
"passed": true
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
{
|
||||
"method": "真实 Chrome,画像、游戏与预警数据为受控响应,不改业务数据",
|
||||
"passed": true,
|
||||
"activeMetric": true,
|
||||
"totalNoComparison": true,
|
||||
"canonicalLast7": true,
|
||||
"fourPayTiers": true,
|
||||
"gameDrawer": true,
|
||||
"platformAndChannelAlertFilter": true,
|
||||
"crossPlatformSameID": true,
|
||||
"unavailableIsNotZero": true,
|
||||
"pageErrors": []
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
# 渠道画像迁移核对
|
||||
|
||||
已实现 `GET /sw/promote/portrait` 及渠道列表画像入口,来源为旧 `PromotePortraitServiceImpl`、`ChannelProfileDrawer.vue`、日汇总/身份键和支付 Mapper。完整业务库数据仍待最终复制验收。
|
||||
|
||||
## 数据范围与基本资料
|
||||
|
||||
@@ -29,4 +28,4 @@
|
||||
- 旧关联预警误将渠道 ID 传入 businessId;新页面使用 targetPromoteId 与 platformCodes,并继续由预警接口执行查看者数据范围隔离。
|
||||
- 小R/免费区间文案按实际后端 >0 / ≤0 调整,避免把小于一元的付费玩家误解为免费。
|
||||
|
||||
验证覆盖领域规则、真实仓储查询、隔离数据库 TCP HTTP、浏览器完整交互及当前 sw7 只读接口。详见 `channel-portrait-http-2026-11-03.json` 与 `channel-portrait-page-2026-11-03.json`;全量 Go 测试与前端构建通过。
|
||||
当前验证状态统一见 [验收与性能记录](validation.md),不再维护阶段性运行报告。
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
# 渠道列表与新增渠道:源码核对记录
|
||||
|
||||
以下是实现核对契约,源码基线与 `implementation.md` 一致。列表、新增、绑定选项、游戏分布及渠道画像已接入并验证;报表构建任务及完整数据验收仍未完成。
|
||||
|
||||
## 页面
|
||||
|
||||
@@ -12,7 +11,7 @@
|
||||
- 状态筛选及列使用 `lockStatus`:0 正常、-1 已锁定、-2 解除合作,与渠道审批字段 `status` 不同。
|
||||
- “添加渠道”只按按钮权限判断,旧代码没有额外要求三级商务。游戏商务下拉随平台变化加载,选项取平台商务 ID 并去重。
|
||||
- 新增字段:平台、游戏商务、推广类型、渠道账号、密码。账号为 `[\u4e00-\u9fa5a-zA-Z0-9]{4,30}`,提交前 trim;密码原值保留,按 Java UTF-16 长度 6–15 校验。
|
||||
- 推广游戏与画像均是右侧抽屉,必须同时传 `sourceDb` 与渠道 ID。游戏抽屉调用 `/system/promote/game-distribution`,累计口径,列为游戏、玩家数量、充值金额。画像尚待迁移,不能宣称渠道整个菜单完成。
|
||||
- 推广游戏与画像均是右侧抽屉,必须同时传 `sourceDb` 与渠道 ID。游戏抽屉调用 `/system/promote/game-distribution`,累计口径,列为游戏、玩家数量、充值金额。画像已迁移。
|
||||
|
||||
## 列表权限和查询
|
||||
|
||||
@@ -35,7 +34,6 @@
|
||||
- `totalPayAmount`:`tab_spend.pay_status=1` 累计 `pay_amount`,不按身份证去重,也没有日期上限。
|
||||
- 关闭包含下级、层级为空或 >=3:只统计当前渠道。二级:本级与 `parent_id=当前ID AND promote_level=3`。一级:本级与同平台 `top_promote_id=当前ID OR parent_id=当前ID`。
|
||||
- 注意一级旧加载函数还会加载第二跳子渠道,但最终 `PromotePortraitScopeHelper` 再按 top/parent 条件过滤;不能仅看加载函数就扩大最终统计集合。
|
||||
- 当前 sw7 缺业务表,列表本体及各指标要明确表示未接入,不能伪造真实零。
|
||||
|
||||
## 源平台创建事务
|
||||
|
||||
@@ -53,3 +51,5 @@
|
||||
游戏分布依赖 `PromotePortraitServiceImpl.buildGameDistribution`、`SwReportDayQueryServiceImpl` 和日汇总/身份键 Mapper。当前实现只列根渠道已通过的游戏,用同渠道统计树读取日汇总:人数对 metric=1 的 identity_key 去重,dedup_mode 随偏好;金额固定 dedup_mode=0。累计起点从当前人数模式的最早日汇总取得,缺失则使用上海当天,即使模式 0 有更早数据也不改写该起点。截止上海当天,排除未来日期。先将金额保留两位再按金额降序、游戏 ID 升序排列。
|
||||
|
||||
完整渠道画像已接入,规则及验证见 `channel-portrait-source-notes.md`。报表汇总任务、预警生成任务和最终实库验收仍属于后续范围。
|
||||
|
||||
当前验证状态统一见 [验收与性能记录](validation.md),不再维护阶段性运行报告。
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
{
|
||||
"scope": "既有 sw7 系统库;渠道表尚未接入。完整数据与跨平台范围通过隔离数据库 HTTP/仓储测试。",
|
||||
"checks": [
|
||||
{
|
||||
"path": "/sw/business/10001/promotes",
|
||||
"code": 0,
|
||||
"available": true,
|
||||
"total": 0,
|
||||
"rows": 0,
|
||||
"elapsed_ms": 14
|
||||
},
|
||||
{
|
||||
"path": "/sw/business/10007/promotes",
|
||||
"code": 0,
|
||||
"available": false,
|
||||
"total": 0,
|
||||
"rows": 0,
|
||||
"elapsed_ms": 15
|
||||
},
|
||||
{
|
||||
"path": "/sw/business/10007/promotes?sourceDb=hw&platformBusierId=14",
|
||||
"code": 0,
|
||||
"available": false,
|
||||
"total": 0,
|
||||
"rows": 0,
|
||||
"elapsed_ms": 33
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,133 +0,0 @@
|
||||
{
|
||||
"base_url": "http://127.0.0.1:18000",
|
||||
"checks": [
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/sw/business/list?pageNum=1&pageSize=500",
|
||||
"http": 200,
|
||||
"code": 0,
|
||||
"msg": "成功",
|
||||
"elapsed_ms": 184,
|
||||
"passed": true,
|
||||
"total": 45,
|
||||
"rows": 45
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/sw/business/list?pageNum=2&pageSize=10",
|
||||
"http": 200,
|
||||
"code": 0,
|
||||
"msg": "成功",
|
||||
"elapsed_ms": 43,
|
||||
"passed": true,
|
||||
"total": 45,
|
||||
"rows": 10
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/sw/business/10001",
|
||||
"http": 200,
|
||||
"code": 0,
|
||||
"msg": "成功",
|
||||
"elapsed_ms": 19,
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/sw/business/list?userName=admin",
|
||||
"http": 200,
|
||||
"code": 0,
|
||||
"msg": "成功",
|
||||
"elapsed_ms": 22,
|
||||
"passed": true,
|
||||
"total": 1,
|
||||
"rows": 1
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/sw/business/10007/bindPlatform",
|
||||
"http": 200,
|
||||
"code": 0,
|
||||
"msg": "成功",
|
||||
"elapsed_ms": 25,
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/sw/user/preference",
|
||||
"http": 200,
|
||||
"code": 0,
|
||||
"msg": "成功",
|
||||
"elapsed_ms": 94,
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/sw/business/bindPlatform?pageNum=1&pageSize=10",
|
||||
"http": 200,
|
||||
"code": 0,
|
||||
"msg": "成功",
|
||||
"elapsed_ms": 22,
|
||||
"passed": true,
|
||||
"total": 58,
|
||||
"rows": 10
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/sw/business/bindPlatform?sourceDb=lx,hw&status=0&pageSize=2",
|
||||
"http": 200,
|
||||
"code": 0,
|
||||
"msg": "成功",
|
||||
"elapsed_ms": 23,
|
||||
"passed": true,
|
||||
"total": 37,
|
||||
"rows": 2
|
||||
},
|
||||
{
|
||||
"method": "PUT",
|
||||
"path": "/sw/user/preference",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "偏好参数不能为空",
|
||||
"elapsed_ms": 424,
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/sw/business",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "商务账号参数不正确",
|
||||
"elapsed_ms": 471,
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"method": "PUT",
|
||||
"path": "/sw/business",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "商务账号参数不正确",
|
||||
"elapsed_ms": 335,
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/sw/business/bindPlatform",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "商务账号参数不正确",
|
||||
"elapsed_ms": 521,
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"method": "DELETE",
|
||||
"path": "/sw/business/bindPlatform",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "商务账号参数不正确",
|
||||
"elapsed_ms": 272,
|
||||
"passed": true
|
||||
}
|
||||
],
|
||||
"passed": true
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
{
|
||||
"date": "2026-11-03",
|
||||
"timezone": "Asia/Shanghai",
|
||||
"base_url": "http://127.0.0.1:18000",
|
||||
"database_scope": "沿用已配置的 sw7 系统迁移测试库;未复制或迁移旧正式数据库",
|
||||
"authentication": "通过本地服务验证码及账号密码正常登录后,携带 JWT 请求;凭据和令牌不记录在报告中",
|
||||
"observed_failure": "原 8000 实例日志:Error 1146,sw7.tab_promote 不存在导致商务列表返回商务数据访问失败",
|
||||
"fix": "基础商务资料和已通过绑定数继续返回;有绑定但渠道表未接入时 promoteCount 为 null;完整业务库仍按原口径计算真实渠道数",
|
||||
"checks": [
|
||||
{
|
||||
"path": "/health",
|
||||
"http": 200,
|
||||
"elapsed_ms": 64
|
||||
},
|
||||
{
|
||||
"path": "/sw/business/list?pageNum=1&pageSize=10",
|
||||
"http": 200,
|
||||
"elapsed_ms": 36,
|
||||
"code": 0,
|
||||
"msg": "成功",
|
||||
"total": 45,
|
||||
"rows": 10,
|
||||
"unavailable_promote_counts": 1
|
||||
},
|
||||
{
|
||||
"path": "/sw/business/list?pageNum=2&pageSize=10",
|
||||
"http": 200,
|
||||
"elapsed_ms": 46,
|
||||
"code": 0,
|
||||
"msg": "成功",
|
||||
"total": 45,
|
||||
"rows": 10,
|
||||
"unavailable_promote_counts": 5
|
||||
},
|
||||
{
|
||||
"path": "/sw/business/list?userName=admin&pageNum=1&pageSize=10",
|
||||
"http": 200,
|
||||
"elapsed_ms": 32,
|
||||
"code": 0,
|
||||
"msg": "成功",
|
||||
"total": 1,
|
||||
"rows": 1,
|
||||
"unavailable_promote_counts": 0
|
||||
},
|
||||
{
|
||||
"path": "/sw/business/10001",
|
||||
"http": 200,
|
||||
"elapsed_ms": 33,
|
||||
"code": 0,
|
||||
"msg": "成功"
|
||||
},
|
||||
{
|
||||
"path": "/sw/user/preference",
|
||||
"http": 200,
|
||||
"elapsed_ms": 103,
|
||||
"code": 0,
|
||||
"msg": "成功"
|
||||
}
|
||||
],
|
||||
"limits": [
|
||||
"验证实例与 GoLand 的 8000 进程独立;GoLand 必须重新运行才能使用新代码",
|
||||
"本次未验证完整渠道数据,完整旧库复制和最终一致性核对仍待迁移结束后确认"
|
||||
]
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
# 商务功能迁移执行记录
|
||||
|
||||
## 基线与方法
|
||||
|
||||
- 旧后端:`D:/Users/Yvan/projects/yzyz/sw`,`main`,`f9a5e3a90`。
|
||||
- 框架基线:`d31082f4a7816d4c83544b8f54e6f42a3b2132b1`。
|
||||
- 旧前端:`D:/Users/Yvan/projects/yzyz/sw/web`,`dev/dev1.0`,`ba284011c87fd3d5730e0e3dceffb14a7389730c`。
|
||||
- 新实现分支:`codex/sw-business-migration`。
|
||||
|
||||
按基线至当前版本的最终差异提取功能,以当前 Java 实现、实际调用的前端接口和 SQL 为核对依据。提交记录用于解释修复和撤销,不逐提交搬运。旧前端中未接入的 mock、废弃接口不能作为已实现业务迁移。
|
||||
|
||||
沿用现有迁移 SQL 的 `/sw/` 路由与 `view/sw/` 菜单组件路径。认证、响应信封、权限、表格及图表采用 Kra;业务字段、统计口径、状态流转、可见范围保留旧实现。登录页、系统名称和品牌资源来自旧商务。新增代码注释与提交信息使用中文。
|
||||
|
||||
用户补充:允许直接优化旧接口、SQL 和逻辑。优化时记录行为差异并验证业务结果;各批实现必须实际请求 HTTP 接口,不能只以单元测试和构建作为完成依据。
|
||||
|
||||
2026-11-04 用户调整验证要求:后续不需要检查页面交互,只验证接口并继续迁移,包括工作台/仪表盘。后续保留旧页面源码核对、接口实测、数据断言和构建检查,不再执行 Chrome 交互验收。
|
||||
|
||||
用户再次指出页面偏差后,明确按旧前端实际页面核对入口,不能从后端接口推断 UI 功能。详见 `page-parity.md`。商务列表已移除错误增加的编辑入口,恢复“绑定列表”名称及仅三级显示规则,并对齐按审核状态显示行操作。
|
||||
|
||||
用户已有的 `configs/config.yaml` 修改与迁移 SQL 保留。未经最后阶段的数据库确认,不连接、复制或修改用户的旧数据库。
|
||||
|
||||
## 依赖顺序与完成标准
|
||||
|
||||
| 阶段 | 范围 | 状态 |
|
||||
| --- | --- | --- |
|
||||
| 1 | 商务用户字段、层级与角色、账号资料和审核、偏好、登录及找回密码 | 进行中 |
|
||||
| 2 | 平台绑定、商务/渠道可见范围、外部平台与 OA 数据源、商务列表及抽屉 | 进行中;绑定、旗下渠道、商务/SDK 画像、OA 激活只读接口已接入;外部数据源及审核实库联调待完成 |
|
||||
| 3 | 预警规则、记录与状态机、操作日志、附件、消息、任务注册与调度 | 进行中;规则、记录和工作流已接入;任务待迁移,消息盒子已确认属于未改动框架代码 |
|
||||
| 4 | 渠道列表及新增、渠道激活、推广游戏等业务接口与页面 | 功能已接入;包含渠道画像,完整业务数据和源平台联调仍待最终验收 |
|
||||
| 5 | 日汇总构建、充值/注册明细、渠道/游戏/区服报表、排行、画像与仪表盘 | 进行中;画像、明细及导出、各报表/排行榜、工作台和两类汇总构建已接入,预警检测任务与最终实库验收待完成 |
|
||||
| 6 | 静态接口核对、后端测试、前端构建和页面验证 | 随阶段推进,最终全量复核 |
|
||||
| 7 | 用户确认源数据库,复制至隔离库,执行迁移,启动并逐接口核对数据 | 未开始,必须等待用户确认 |
|
||||
|
||||
每项完成需覆盖 DTO → service → biz → data、路由目录、权限、菜单页面和有意义的行为测试。只有真实实现并通过验证的项才标为完成。整项目标在实库验证之前保持未完成。
|
||||
|
||||
## 已核实的业务约束
|
||||
|
||||
- 超管创建一级商务,一级创建二级,二级创建三级;三级不能创建下级。层级与祖先链由服务器生成。
|
||||
- 新增子商务最终版本默认正常,不采用残留注释中的“默认待审核”。
|
||||
- 一/二级商务列表只显示下级树,不显示自己;三级列表为空。报表使用独立渠道可见范围,不能套用 Kra 的部门过滤替代。
|
||||
- `includeSubPromote` 与 `idcardDedup` 无记录或数据库值非零时均为开启,新增账号同时初始化开启。
|
||||
- SDK 商务绑定数量仅计算已通过记录;渠道计数依照当前直属渠道算法,跨平台 ID 不能混用。
|
||||
- 用户审核状态有正常、停用、驳回、待审核四种,须保留 `business_status`,不能压成 `enable` 后丢失含义。
|
||||
- 金额查询固定不做身份证去重;人数查询遵守全局偏好。
|
||||
- SQL 已建立用户、角色、文件等 ID 映射;平台实体及业务主键保留。迁移验收应按映射比较,不能直接比较所有原始 ID。
|
||||
|
||||
## 验证记录
|
||||
|
||||
- 已落地商务用户七个扩展字段的存取及增量补列;登录和既有会话同时检查商务审核状态。
|
||||
- 已落地全局偏好 GET/PUT、当前用户隔离、缺省开启、显式关闭及幂等写入;Kra 顶栏增加统计口径入口。
|
||||
- 已落地商务列表、查询资料、新增子商务、部分编辑和审核状态,以及 Kra 风格 `BusinessList` 页面。层级及角色由服务端按原角色 ID 映射分配;账号、角色、偏好在同一事务创建。列表按平台与商务组合键统计直属一级渠道和已通过绑定。
|
||||
- 商务、SDK 商务和渠道画像已接入;其余报表及任务继续迁移。后端导出等接口另按源码核对,不能据此给旧页面增加不存在的按钮;最终仍需完整数据源验收。
|
||||
- 已接入绑定列表、指定商务已通过绑定详情、提交绑定及解绑四个接口,页面恢复仅三级可见的“绑定列表”页签及只读详情抽屉。绑定流程保持三级限制、平台验密、OA 待审核及驳回重提规则;新增键锁表 `sys_business_binding_locks`,串行处理同一平台商务的并发绑定。
|
||||
- 已恢复旧登录页的图片、文案、布局及记住账号功能,系统名称统一为“遨游龙翔游戏平台”。找回密码四个匿名接口位于 `/sw/auth/forgot-password/`,保留账号/手机号检查、60 秒发码限制、两分钟验证码、十分钟凭证、6–15 位密码及失败五次吊销等规则。
|
||||
- 找回密码采用同库事务保存验证码摘要和一次性凭证,并原子执行改密/消费凭证;新增 `sys_business_password_codes`、`sys_business_password_resets`。更新密码版本使旧 JWT 失效。短信复用 Kra 集成配置,`SW_PASSWORD_RESET_SMS_PROVIDER` 默认 `tencent`,也支持 `aliyun`;模板和通道凭据在对应集成配置中维护。
|
||||
- 旗下渠道接口 `/sw/business/:userId/promotes` 和两处抽屉入口已接入:先校验商务可见范围,再按已通过绑定的 `(source_db, platform_busier_id)` 查询直属一级渠道;按渠道 ID、平台稳定分页。实际 sw7 请求与隔离完整数据 HTTP/仓储测试均通过,浏览器确认绑定入口同时携带平台和平台商务 ID,未通过绑定禁用该入口。
|
||||
- 平台数据源通过 Kra 的 `data.database_list` 复用连接,别名为 `lx` / `hw` / `yq`。旧密码算法支持三种格式,兼容盐通过环境变量 `SW_SDK_AUTH_CODE`、`SW_SDK_MIGRATE_AUTH_CODE` 提供,取值应与旧 `XiguPasswordUtils` 对应常量一致;`SW_SDK_TABLE_PREFIX` 缺省为 `sys_`。真实连接凭据和盐不写进新仓库。完整平台库验密仍需部署配置后联调。
|
||||
- 已生成 `source-inventory.json`:现有 SQL 的 63 个接口契约、279 个变更源文件及额外找回密码控制器。此清单是范围索引,不代表已完成实现。
|
||||
- 已执行 `make generate`、相关 Go 测试、变更前端 ESLint 和生产构建。构建存在原 `arcdash` 依赖的 BigInt 浏览器目标警告。
|
||||
- 第一批提交 `ce4b54a` 后 `go test ./...` 全量通过;第二批账号功能的 biz/data/service/modules/server/cmd 检查及前端生产构建通过。
|
||||
- 用户反馈实际商务列表失败后,定位为 sw7 缺少 `tab_promote`。已解耦基础列表与渠道统计:有绑定且渠道表缺失时返回 `promoteCount: null`,界面显示“未接入”,无绑定账号仍为真实零。新增通过真实 TCP 请求的 HTTP 回归测试,覆盖系统数据库及完整渠道表两种场景。
|
||||
- 已通过正常验证码登录取得测试会话,并在修复后的独立 18000 实例连接同一 sw7 执行 HTTP 请求。列表总数 45,分页、账号筛选、资料和偏好查询全部成功。详见 `http-verification-2026-11-03.json`。8000 为用户 GoLand 旧二进制,需重新运行才加载源码修复。
|
||||
- 绑定批次通过 13 项真实 HTTP 检查:商务 45 条、绑定 58 条、平台与审核筛选、详情、偏好查询和写请求校验,结果见 `http-business-bindings-2026-11-03.json`;`scripts/sw_http_smoke.py` 可复用且不记录令牌。真实库不制造测试商务或发起实际平台绑定。新增、修改、偏好关闭、提交绑定及解绑的正向流程已用独立 SQLite 数据库通过实际 TCP HTTP 测试;平台验密外部边界使用测试替身,密码算法另用固定向量验证。
|
||||
- 登录/找回密码批次 `go test ./...` 全量通过,前端 ESLint 和生产构建通过。Chrome 已检查桌面/移动登录页及三步找回流程(短信接口受控替身);完整找回密码链路已通过匿名 TCP HTTP + SQLite 测试,覆盖错误验证码后重试、原子消费、改密版本更新和凭证重放拒绝。实际运行实例四个匿名接口校验与既有 13 项商务 HTTP 回归全部通过,未发送真实短信或修改真实用户密码。
|
||||
- 预警规则七个接口及 Kra 页面已接入。一级商务管理自己的规则,二/三级读取所属一级的规则,超管可管理全部;启停、软删除、监控指标与原校验一致。分类选项来自历史预警记录,删除规则不会丢失历史分类。编辑不覆盖独立的启停/删除状态,省略的可选指标字段沿用旧值。
|
||||
- 新增预警表缺表建表迁移,保留既有表;阈值列支持原页面 9999% 上限。当前 sw7 启动前后均为 `decimal(7,2)`,没有改动既有规则数据。触发检测任务和记录去重写入尚未迁移,不作为规则页面完成范围。
|
||||
- 规则批次通过 biz/data/service/cmd/server/modules 检查、前端 ESLint 与生产构建;隔离 SQLite + TCP HTTP 测试覆盖新增、编辑、启停、软删除、历史分类和跨商务权限。`alert-rules-http-2026-11-03.json` 记录真实 sw7 查询与无效写请求,`alert-rules-page-2026-11-03.json` 记录四级角色入口与指标表单联动;可复用脚本为 `scripts/sw_alert_rules_smoke.cjs`。
|
||||
- 预警记录八个接口与列表、处理抽屉已接入。列表、详情和写入同时按所属一级商务及本人/下级的已通过绑定隔离,渠道键包含平台,保留停用一级渠道的历史预警。`businessId` 筛选取指定商务渠道范围与查看范围的交集,不误用预警归属一级字段。状态汇总仅随范围、平台和指定渠道变化,不受名称、分类、指标及列表状态筛选影响。
|
||||
- 完整工作流为未处理→处理中→待审核→已处理,或待审核→审核驳回→处理中后重新提交。审核只允许一级商务,超管等级为零时也不能审核。状态条件在带权限条件的行锁事务中检查,状态日志及可选备注共同提交;独立备注不改状态,保留原接口允许已关闭记录追加备注的行为(旧页面只读态仍不展示备注编辑区)。
|
||||
- 备注图片复用 Kra 上传接口,支持选取、拖拽、粘贴、暂存预览和移除;添加备注时才上传。修复旧前后端矛盾:先要求非空备注再上传,部分上传或备注失败重试时复用已上传结果。历史数字附件批量查询新文件表,URL 附件保持原值,异常 JSON 视为空附件;记录/规则/日志大 ID 使用字符串响应,避免浏览器精度丢失。
|
||||
- 补充 `202611030007_business_alert_attachments`,针对原 SQL 遗留的日志数字附件做文件 ID 映射。只转换与 `bak_sw2kra_20261103_sys_alert_operation_log` 备份相符的旧日志,新日志、URL 或已变化引用不改动;缺失旧文件不解释为同号新文件,原引用保留在备份。详见 `alert-attachment-migration.md`。
|
||||
- 预警记录批次全量 `go test ./...`、前端 ESLint 与生产构建通过。隔离 SQLite + 实际 TCP HTTP 覆盖全部处理动作、驳回重提、跨商务/平台拒绝、大 ID、附件读取与缺表场景;仓储测试覆盖日志失败回滚与重复请求。MySQL 行锁的真实并发验证留待最终隔离旧库验收。`alert-records-http-2026-11-03.json` 记录当前 sw7 的真实会话请求;当前预警零条,未创建真实预警或上传文件。原商务 45 条、绑定 58 条的 HTTP 回归继续通过。
|
||||
- `alert-records-page-2026-11-03.json` 记录真实 Chrome 下四个等级、五种状态的入口检查,以及完整抽屉流程、附件延迟上传、状态卡片筛选、缺渠道数据提示。浏览器业务数据、处理写入和上传使用受控替身;正向服务端行为另由前述 TCP HTTP 测试覆盖。
|
||||
- 渠道激活 `/sw/promoteActivePool/bindList` 和 `/sw/promoteActivePool/bindSpendDetail` 及旧同名页面已接入。OA 连接复用 `data.database_list` 中别名 `oa` 的共享客户端;只读 `sys_promote_active_pool_bind`,不创建或修改 OA 表。普通商务按本人已通过绑定的账号集合匹配 OA 认领,不包含下级,超管不限;保持旧实现按账号匹配的规则。
|
||||
- 激活流水从主库 `tab_spend` 按游戏汇总,成功支付、同平台、绑定开始(含)到达标/解绑截止(含);渠道树包含本级、直属子级及 `top_promote_id` 匹配项,不依赖全局下级/身份证偏好。达标时间优先于解绑时间,进行中没有结束上限。使用 EXISTS 避免重复渠道行导致金额翻倍,金额及大 ID 以字符串返回,计算和页面格式化避免浮点精度丢失。
|
||||
- 激活批次通过全量 `go test ./...`、ESLint 和生产构建,以及主库/OA 两个隔离数据库的实际 TCP HTTP 测试。`activation-http-2026-11-03.json` 记录当前真实会话请求(OA 未接入,明确 available=false);`activation-page-2026-11-03.json` 核对旧页面列、五种状态入口、筛选重置、达标截止与大金额。待审核可以打开流水入口但显示原接口“审核通过后可查看”,已驳回不显示入口;明细读取失败不展示伪造零流水。
|
||||
- 已对框架基线至 main 的 Git 差异核实:`SysMessageController` 与 `SysMessageServiceImpl` 未变更,旧导航栏消息入口也被注释,因此不新增商务消息 UI。SW 主库写入待审绑定后由外部 OA 审核,并没有需要照搬的 SW 内部 OA 同步任务;最终联调仍须核对 OA 连接目标及商务用户 ID 映射,不能把隔离替身测试当成外部审核验收。
|
||||
- 渠道列表、可用绑定、新增渠道、推广游戏分布四个接口及对应 Kra 页面已接入。列表读取本人及全部下级的正常绑定,超管默认不限;指定商务用户只取该用户本人的绑定。商务账号关键词同时匹配平台账号和 SW 登录名,保留 Java 文字子串语义,不把 `%` 变成通配符。渠道状态筛选使用锁定状态字段。
|
||||
- 渠道列表游戏数仅统计当前渠道已通过申请的去重游戏;玩家数和成功充值额按原渠道树及全局偏好汇总。身份证去重跨整棵统计树进行,空证件不计入,末尾 X/x 归一。指标按平台/渠道组合批量查询;缺失指标单独返回 null,已有指标继续显示。真实 TCP HTTP 回归发现并修复 `idcard` 列映射错误,增加存储字段与实际返回人数断言。
|
||||
- 游戏分布只列当前渠道已通过的推广游戏,读取 `tab_sw_report_day` / `tab_sw_report_day_key`,人数按当前去重模式去重,金额固定模式 0。累计起点保留旧实现从当前人数口径的最早日汇总取得、缺省当天的规则,截止上海当天;不能与列表原始注册/充值口径混用。金额先保留两位再排序,同金额按游戏 ID。
|
||||
- 新增渠道由 biz 决定一级、待审核 `-3`、默认注册类型和七天结算周期;data 在对应源平台库同事务写渠道、结算记录、商务渠道关系。密码复用旧 cmf 格式和 `SW_SDK_AUTH_CODE`。MySQL 创建使用固定连接持有账号命名锁直到事务提交,商务关系在行锁内追加;命名锁的真实并发验证留待最终隔离平台库联调。没有创建真实平台测试渠道,也没有伪造主库同步副本。
|
||||
- 渠道批次通过全量 Go 检查、前端 ESLint/生产构建、独立主库和源平台 SQLite 的 TCP HTTP 验证。`channel-http-2026-11-03.json` 记录实际 sw7 会话请求,当前主库渠道数据未接入,lx/hw/yq 正常绑定选项分别为 17/20/20 条。`channel-page-2026-11-03.json` 核对一级商务新增入口、平台切换清空绑定、跨平台同号、零游戏数入口、缺失指标提示及新增提交参数。画像入口继续随画像用例迁移,当前不将整个渠道菜单标为完成。
|
||||
- 核对剩余用户接口的基线差异及 Kra 原生能力,记录于 `system-api-audit.md`;保留历史别名未注册、Excel 协议未兼容等差异,不把能力对应表当成接口兼容完成证明。商务页面仍不增加原页面没有的编辑/删除/导入/导出入口。
|
||||
- 修复原生用户启停只更新 enable、商务状态不同步的问题:由 biz 决定状态联动,在 data 行锁事务中一起写入;未启用时保留待审/驳回,个人资料请求不能自行解除管理员限制。当前 45 个真实用户只读检查未发现已有冲突,没有批量更新真实账号;正常启停、审核状态保留、失败回滚和越权通过隔离 HTTP/仓储/领域测试。全量 Go 测试通过,实际服务检查记录为 `user-status-http-2026-11-03.json`。
|
||||
- 新增 `/sw/business/:userId/portrait` 与 `/sw/business/bindPlatform/portrait`。补齐商务列表画像、正常绑定画像和只读 SDK 详情平台入口,共用 Kra 风格抽屉,包含基本资料、五个时间周期、四项指标、可交互趋势、注册/充值 TOP 5 及独立分页的关联预警。SVG 图表使用 Kra 主题变量,无新增图表依赖,支持键盘数据点和负金额。
|
||||
- 普通商务基本资料来自新系统用户,SDK 资料来自对应平台库,父级分别按 SW parent_id 和平台 commerce1/commerce2 解析。SDK 状态 0 仍是待审核,不能当作 SW 正常;关联预警/旗下渠道使用打开时的 SW 用户 ID,平台商务 ID 只作为绑定筛选。保留旧 SDK 画像关联预警按商务及平台的实际范围。
|
||||
- 画像日指标与日趋势读取汇总/身份键表,模式 0 人数带平台前缀、模式 1 跨平台身份证去重,金额固定模式 0。付费率分母为活跃人数,人均充值分母为注册人数;上期活跃为零时付费率对照和百分点差为 null。今日/昨日趋势读原始主账号与成功支付、补齐 24 小时;MySQL 保留原 HOUR(FROM_UNIXTIME) 会话时区语义。注册 TOP 5 在渠道树内 COUNT DISTINCT;人数上限在排序截取前应用。
|
||||
- 画像批次通过领域/存储/双库实际 TCP HTTP 测试、全量 Go 检查和前端 ESLint/构建;验证月末/闰月对比、四舍五入与负零、去重切换、金额稳定、原始小时口径、父级状态、跨商务拒绝及缺表。`portrait-http-2026-11-03.json` 为真实会话检查:无绑定返回零指标及完整趋势,有绑定缺表保留基本资料并明确未知。`portrait-page-2026-11-03.json` 核对三个入口、周期切换、交互图表、两个 ID 范畴和缺数据提示。
|
||||
- 当前没有执行最终旧数据库复制与迁移验收。
|
||||
- 渠道画像 `/sw/promote/portrait` 与列表入口已接入,包含基本资料、累计/当期指标、趋势、四档付费分层、关联预警及推广游戏抽屉。复用画像统计并增加经过校验的单渠道树范围、无对照期分支;渠道第四项保持活跃玩家。分层成员取累计注册身份,金额按历史成功支付及原始付款账号/身份证口径,保持无日期过滤,不能误复用指标周期过滤。
|
||||
- 修复旧渠道页面两处参数错配:近7/30天改发 last7/last30,关联预警改发 targetPromoteId 而不是 businessId。领域、存储和隔离 TCP HTTP 覆盖分层边界、子账号与跨平台、模式切换、累计无环比、原始小时趋势和缺数据;浏览器验证入口、正确参数、四档分层及游戏抽屉。全量 Go、ESLint/构建通过;当前真实会话请求记录于 `channel-portrait-http-2026-11-03.json`,仍未复制实际旧业务库。
|
||||
- 注册/充值明细、两个 XLSX 导出及游戏下拉共五个接口已接入。注册保留 puid=0、同平台玩家全部历史成功充值;充值合计只算成功单,不随列表状态改变。渠道精确匹配、商务文字筛选、官方/未知渠道和跨平台同号均按旧口径处理。
|
||||
- 修复注册游戏关联跨平台、超过200个渠道后放宽筛选的问题,批量补充当前页资料。导出超过10000条提前拒绝,保留数字/文本类型及原字段顺序。页面使用 Kra 表格、筛选、日期控件与下载,保留近30天默认显示和大额行高亮;注册导出权限与接口一致。
|
||||
- 明细批次通过全量 Go、前端 ESLint/构建、隔离 TCP HTTP、工作簿内容校验和浏览器筛选/下载。真实 sw7 请求及空查询工作簿验证记录见 `ledger-http-2026-11-04.json`、`ledger-page-2026-11-04.json`,没有导出或修改真实业务行;详细边界见 `ledger-source-notes.md`。
|
||||
- 渠道/游戏统计两个接口与 Kra 页面已接入,保留游戏筛选、渠道账号/类型筛选、平台、日期、排序、分页及全量汇总。金额固定模式 0,人数按当前身份证偏好;游戏汇总累加各游戏,渠道超管汇总全局去重、普通商务累加可见渠道,不互相替代。渠道模糊匹配扩到可见同树渠道,并保持类型交集;超管全平台范围包含官方和历史孤立渠道。
|
||||
- 统计批次通过全量 Go、隔离数据库真实 TCP HTTP、领域/仓储测试、ESLint/生产构建;真实 sw7 请求和 Chrome 检查见 `analytics-http-2026-11-04.json`、`analytics-page-2026-11-04.json`。分页不改变汇总,缺表明确未接入;非法日期/倒置周期明确报错。没有添加旧统计页面不存在的导出按钮。详细口径与优化见 `analytics-source-notes.md`。
|
||||
- 区服列表与区服选项接口、Kra 区服分析页面已接入。统计按平台+游戏+区服编号分组,人数区服内去重、金额固定模式 0;页尾汇总全部筛选行。游戏必选,选项按当前游戏名,报表按历史游戏名,区服编号保留前导零。
|
||||
- 区服批次通过全量 Go、隔离数据库真实 TCP HTTP、前端 ESLint/构建和真实 sw7 只读接口请求,结果见 `server-analysis-http-2026-11-04.json`。覆盖跨平台同号、全量汇总、零行处理、偏好切换、资料补全及缺表;按用户新要求未执行页面交互检查。最终旧库验收仍未开始。
|
||||
- 工作台四个接口及 Kra 仪表盘业务区域已接入:六项指标、注册/充值 TOP10、未登录 TOP10、最低充值 TOP10 和已有预警的最新五条轮播。保留 Kra 欢迎区域、快捷入口与公告,平台和周期按旧页面设置;请求失败清空旧结果并提示,不能显示其他平台的缓存值。
|
||||
- 工作台保留本月对上月同日(截断月末)、模式 0 跨平台 ID 隔离、渠道树注册去重、金额固定模式 0、活跃渠道按自身注册/正充值计数、最低榜含零一级渠道,以及未登录回退创建时间和 99999 哨兵值。详见 `workbench-source-notes.md`。
|
||||
- 工作台批次全量 Go、隔离 TCP HTTP、领域/仓储测试、前端 ESLint/构建通过;真实 sw7 请求记录见 `workbench-http-2026-11-04.json`。缺业务表时六卡返回 null、榜单明确报未接入。未执行页面交互检查或最终旧库复制。
|
||||
- 独立排行榜渠道、商务、游戏三个接口和 Kra 页面已接入,各有注册/充值/付费率/活跃 TOP20,保留平台、维度独立日期记忆、近 7 天默认周期和等长上期。付费率用百分点差,其余用百分比环比。商务按直属下级展示、合并其整个下级绑定树,再累加各渠道人数;三级不展示商务排行。
|
||||
- 排行批次全量 Go、隔离 TCP HTTP、领域/仓储测试、前端 ESLint/构建、真实 sw7 接口检查通过,见 `ranking-http-2026-11-04.json` 与 `ranking-source-notes.md`。当前 SQL 清单 63 个目标接口中 51 个已注册;其余 12 个均为 `SysUser` 历史系统别名,详见 `system-api-audit.md`,不能将接口注册数量当作全迁移完成证明。汇总和预警任务、最终旧库迁移验收仍待完成。
|
||||
- 已迁移日汇总/区服汇总的今日、昨日、按日期回跑六个任务方法,复用 Kra 原生任务创建、手动触发、执行日志和取消机制。汇总和身份键同事务替换,按报表类型与日期持有数据库行锁;增加 `202611040008_business_report_build_locks`。只注册方法,不自动新建或启用计划。当前真实 sw7 的 7 个导入任务均保持禁用。
|
||||
- 汇总领域/仓储测试和原生任务实际 TCP HTTP 测试通过,覆盖账号/身份证双口径、主/子账号差异、无平台登录歧义、原始账号新增付费交集、自然日格式、幂等回跑及写入失败回滚。全量 Go 通过;真实服务方法和禁用状态验证见 `report-build-http-2026-11-04.json`。未触发实际 sw7 的数据重建;完整源库重跑比较仍留待最终阶段。
|
||||
- 用户反馈仅排行榜图标可显示,定位为原 SQL 直接复制 RuoYi SVG 名称。已修正原 SQL 首次迁移和重复执行分支,模块菜单改用统一的 14 项有效 Kra 图标;新增 `202611040009_business_menu_icons` 修复已迁移库,单独补丁为 `menu-icon-repair.sql`。仅替换旧迁移值,保留其他自定义图标。
|
||||
- 14 个图标都已通过本地已安装组件的 SVG 输出验证;实际 8000 和 18000 菜单接口全部返回正确图标,见 `menu-icons-components-2026-11-04.json`、`menu-icons-live-http-2026-11-04.json`、`menu-icons-http-2026-11-04.json`。这次按用户明确要求修改原迁移 SQL,原有暂存内容继续保留;未执行整个旧库迁移脚本。
|
||||
@@ -1,86 +0,0 @@
|
||||
{
|
||||
"scope": "真实 sw7 会话,只读查询;导出使用确定为空的商务筛选,仅校验表头工作簿,不导出真实业务行。",
|
||||
"checks": [
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/sw/register/list?sourceDb=lx,hw,yq",
|
||||
"http": 200,
|
||||
"code": 0,
|
||||
"msg": "成功",
|
||||
"passed": true,
|
||||
"total": 0,
|
||||
"available": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/sw/register/list?busierAccount=__kra_empty_export_probe_20261104__",
|
||||
"http": 200,
|
||||
"code": 0,
|
||||
"msg": "成功",
|
||||
"passed": true,
|
||||
"total": 0,
|
||||
"available": true
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/sw/register/export",
|
||||
"http": 200,
|
||||
"xlsx": true,
|
||||
"worksheet_rows": 1,
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/sw/register/export",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "明细数据尚未接入,无法导出",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/sw/spend/list?sourceDb=lx,hw,yq",
|
||||
"http": 200,
|
||||
"code": 0,
|
||||
"msg": "成功",
|
||||
"passed": true,
|
||||
"total": 0,
|
||||
"available": false
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/sw/spend/list?busierAccount=__kra_empty_export_probe_20261104__",
|
||||
"http": 200,
|
||||
"code": 0,
|
||||
"msg": "成功",
|
||||
"passed": true,
|
||||
"total": 0,
|
||||
"available": true
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/sw/spend/export",
|
||||
"http": 200,
|
||||
"xlsx": true,
|
||||
"worksheet_rows": 1,
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/sw/spend/export",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "明细数据尚未接入,无法导出",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/sw/register/list?beginRegisterTime=bad&endRegisterTime=2026-11-04",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "明细查询参数不正确",
|
||||
"passed": true
|
||||
}
|
||||
],
|
||||
"passed": true
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
{
|
||||
"method": "真实 Chrome,列表数据受控;导出使用真实服务的空筛选生成 XLSX,不读取业务数据。",
|
||||
"reports": [
|
||||
{
|
||||
"kind": "register",
|
||||
"passed": true,
|
||||
"defaultThirtyDays": true,
|
||||
"gameNameSelection": true,
|
||||
"exactAmountOrSuccessSummary": true,
|
||||
"xlsxDownload": true,
|
||||
"exportKeepsFilters": true,
|
||||
"failedQueryClearsOldData": true,
|
||||
"pageErrors": []
|
||||
},
|
||||
{
|
||||
"kind": "spend",
|
||||
"passed": true,
|
||||
"defaultThirtyDays": true,
|
||||
"gameNameSelection": true,
|
||||
"exactAmountOrSuccessSummary": true,
|
||||
"xlsxDownload": true,
|
||||
"exportKeepsFilters": true,
|
||||
"failedQueryClearsOldData": true,
|
||||
"pageErrors": []
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -31,6 +31,6 @@
|
||||
- 保留原 VO 导出字段顺序,包括没有中文 ExcelProperty 的辅助字段;时间保留 Unix 秒,状态/方式保留原代码。
|
||||
- 数值直接写入数值 XML,不先转 float64;账号、订单号等强制文本,保留前导零并避免当作公式。
|
||||
- 页面按旧模板提供筛选、游戏远程下拉、日期快捷项、排序、分页、导出;充值金额≥5000的行高亮。查询失败会清除旧行和旧合计。
|
||||
- 游戏下拉的默认/批量 limit 行为沿用旧接口;区服分析的 servers/list 尚待后续实现,不能因 games 可用而标记整个区服页面完成。
|
||||
- 游戏下拉的默认/批量 limit 行为沿用旧接口;区服分析的 servers/list 现已完成迁移。
|
||||
|
||||
验证:领域/存储测试,实际 TCP HTTP 与 XLSX 内容校验,真实 sw7 的只读查询及确定空查询导出,Chrome 筛选/下载回归。见 `ledger-http-2026-11-04.json`、`ledger-page-2026-11-04.json`。未修改真实业务数据,最终旧库复制和数据比对尚未开始。
|
||||
当前验证状态统一见 [验收与性能记录](validation.md),不再维护阶段性运行报告。
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"method": "真实 Chrome 渲染;找回密码接口使用受控响应,不发送真实短信",
|
||||
"title": "遨游龙翔游戏平台",
|
||||
"actions": [
|
||||
"check",
|
||||
"send-code",
|
||||
"verify-code",
|
||||
"reset"
|
||||
],
|
||||
"pageErrors": [],
|
||||
"passed": true
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
-- 已完成迁移的 Kra 数据库可单独执行;仅更新商务菜单的旧图标值。
|
||||
START TRANSACTION;
|
||||
-- RuoYi SVG 名称转换为 Kra 已注册图标;只修复旧值,保留后续自定义选择。
|
||||
UPDATE sys_base_menus SET icon=CASE name
|
||||
WHEN 'sw_BusMgmt' THEN 'Briefcase'
|
||||
WHEN 'sw_BusinessList' THEN 'UserFilled'
|
||||
WHEN 'sw_ChannelList' THEN 'Connection'
|
||||
WHEN 'sw_ChannelActivationList' THEN 'CircleCheck'
|
||||
WHEN 'sw_DataAnalysis' THEN 'DataAnalysis'
|
||||
WHEN 'sw_ChannelDataStatistics' THEN 'Histogram'
|
||||
WHEN 'sw_RechargeDetails' THEN 'Money'
|
||||
WHEN 'sw_RegistrationDetails' THEN 'User'
|
||||
WHEN 'sw_GameAnalytics' THEN 'TrendCharts'
|
||||
WHEN 'sw_ServerAnalysis' THEN 'Monitor'
|
||||
WHEN 'sw_RankingAnalysis' THEN 'Star'
|
||||
WHEN 'sw_AlertCenter' THEN 'Bell'
|
||||
WHEN 'sw_AlertList' THEN 'Warning'
|
||||
WHEN 'sw_AlertRules' THEN 'Setting'
|
||||
ELSE icon END
|
||||
WHERE name IN ('sw_BusMgmt','sw_BusinessList','sw_ChannelList','sw_ChannelActivationList','sw_DataAnalysis','sw_ChannelDataStatistics','sw_RechargeDetails','sw_RegistrationDetails','sw_GameAnalytics','sw_ServerAnalysis','sw_RankingAnalysis','sw_AlertCenter','sw_AlertList','sw_AlertRules')
|
||||
AND (icon IS NULL OR icon IN ('', 'category', 'email', 'chart', 'company', 'international', 'color', 'dict', 'cascader', 'education', 'excel', 'star', 'process-definition', 'documentation', 'example', 'data-analysis', 'user', 'money', 'warn'));
|
||||
COMMIT;
|
||||
@@ -1,76 +0,0 @@
|
||||
{
|
||||
"method": "本地已安装组件的 SSR SVG 验证,包含首次/重复迁移 SQL 与模块定义一致性检查",
|
||||
"icons": [
|
||||
{
|
||||
"name": "sw_BusMgmt",
|
||||
"icon": "Briefcase",
|
||||
"svgRendered": true
|
||||
},
|
||||
{
|
||||
"name": "sw_BusinessList",
|
||||
"icon": "UserFilled",
|
||||
"svgRendered": true
|
||||
},
|
||||
{
|
||||
"name": "sw_ChannelList",
|
||||
"icon": "Connection",
|
||||
"svgRendered": true
|
||||
},
|
||||
{
|
||||
"name": "sw_ChannelActivationList",
|
||||
"icon": "CircleCheck",
|
||||
"svgRendered": true
|
||||
},
|
||||
{
|
||||
"name": "sw_DataAnalysis",
|
||||
"icon": "DataAnalysis",
|
||||
"svgRendered": true
|
||||
},
|
||||
{
|
||||
"name": "sw_ChannelDataStatistics",
|
||||
"icon": "Histogram",
|
||||
"svgRendered": true
|
||||
},
|
||||
{
|
||||
"name": "sw_RechargeDetails",
|
||||
"icon": "Money",
|
||||
"svgRendered": true
|
||||
},
|
||||
{
|
||||
"name": "sw_RegistrationDetails",
|
||||
"icon": "User",
|
||||
"svgRendered": true
|
||||
},
|
||||
{
|
||||
"name": "sw_GameAnalytics",
|
||||
"icon": "TrendCharts",
|
||||
"svgRendered": true
|
||||
},
|
||||
{
|
||||
"name": "sw_ServerAnalysis",
|
||||
"icon": "Monitor",
|
||||
"svgRendered": true
|
||||
},
|
||||
{
|
||||
"name": "sw_RankingAnalysis",
|
||||
"icon": "Star",
|
||||
"svgRendered": true
|
||||
},
|
||||
{
|
||||
"name": "sw_AlertCenter",
|
||||
"icon": "Bell",
|
||||
"svgRendered": true
|
||||
},
|
||||
{
|
||||
"name": "sw_AlertList",
|
||||
"icon": "Warning",
|
||||
"svgRendered": true
|
||||
},
|
||||
{
|
||||
"name": "sw_AlertRules",
|
||||
"icon": "Setting",
|
||||
"svgRendered": true
|
||||
}
|
||||
],
|
||||
"passed": true
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
{
|
||||
"baseURL": "http://127.0.0.1:18000",
|
||||
"menuCount": 14,
|
||||
"checks": [
|
||||
{
|
||||
"name": "sw_BusMgmt",
|
||||
"icon": "Briefcase",
|
||||
"expected": "Briefcase",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "sw_BusinessList",
|
||||
"icon": "UserFilled",
|
||||
"expected": "UserFilled",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "sw_ChannelList",
|
||||
"icon": "Connection",
|
||||
"expected": "Connection",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "sw_ChannelActivationList",
|
||||
"icon": "CircleCheck",
|
||||
"expected": "CircleCheck",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "sw_DataAnalysis",
|
||||
"icon": "DataAnalysis",
|
||||
"expected": "DataAnalysis",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "sw_ChannelDataStatistics",
|
||||
"icon": "Histogram",
|
||||
"expected": "Histogram",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "sw_RechargeDetails",
|
||||
"icon": "Money",
|
||||
"expected": "Money",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "sw_RegistrationDetails",
|
||||
"icon": "User",
|
||||
"expected": "User",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "sw_GameAnalytics",
|
||||
"icon": "TrendCharts",
|
||||
"expected": "TrendCharts",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "sw_ServerAnalysis",
|
||||
"icon": "Monitor",
|
||||
"expected": "Monitor",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "sw_RankingAnalysis",
|
||||
"icon": "Star",
|
||||
"expected": "Star",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "sw_AlertCenter",
|
||||
"icon": "Bell",
|
||||
"expected": "Bell",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "sw_AlertList",
|
||||
"icon": "Warning",
|
||||
"expected": "Warning",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "sw_AlertRules",
|
||||
"icon": "Setting",
|
||||
"expected": "Setting",
|
||||
"passed": true
|
||||
}
|
||||
],
|
||||
"passed": true
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
{
|
||||
"baseURL": "http://127.0.0.1:8000",
|
||||
"menuCount": 14,
|
||||
"checks": [
|
||||
{
|
||||
"name": "sw_BusMgmt",
|
||||
"icon": "Briefcase",
|
||||
"expected": "Briefcase",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "sw_BusinessList",
|
||||
"icon": "UserFilled",
|
||||
"expected": "UserFilled",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "sw_ChannelList",
|
||||
"icon": "Connection",
|
||||
"expected": "Connection",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "sw_ChannelActivationList",
|
||||
"icon": "CircleCheck",
|
||||
"expected": "CircleCheck",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "sw_DataAnalysis",
|
||||
"icon": "DataAnalysis",
|
||||
"expected": "DataAnalysis",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "sw_ChannelDataStatistics",
|
||||
"icon": "Histogram",
|
||||
"expected": "Histogram",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "sw_RechargeDetails",
|
||||
"icon": "Money",
|
||||
"expected": "Money",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "sw_RegistrationDetails",
|
||||
"icon": "User",
|
||||
"expected": "User",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "sw_GameAnalytics",
|
||||
"icon": "TrendCharts",
|
||||
"expected": "TrendCharts",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "sw_ServerAnalysis",
|
||||
"icon": "Monitor",
|
||||
"expected": "Monitor",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "sw_RankingAnalysis",
|
||||
"icon": "Star",
|
||||
"expected": "Star",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "sw_AlertCenter",
|
||||
"icon": "Bell",
|
||||
"expected": "Bell",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "sw_AlertList",
|
||||
"icon": "Warning",
|
||||
"expected": "Warning",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"name": "sw_AlertRules",
|
||||
"icon": "Setting",
|
||||
"expected": "Setting",
|
||||
"passed": true
|
||||
}
|
||||
],
|
||||
"passed": true
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
# 商务菜单图标修复
|
||||
|
||||
旧 SQL 使用 `COALESCE(n.icon,'')` 原样迁移 RuoYi 图标名。实际菜单接口返回 category/email/chart/international 等,Kra 未注册这些图标;star 恰好对应 Element Plus 的 Star。
|
||||
|
||||
Kra 的 `web/src/core/global.js` 注册全部 `@element-plus/icons-vue` 导出组件,以及仓库本地 SVG。现在明确使用组件导出名,避免依赖旧 SVG 文件或大小写猜测。
|
||||
|
||||
| 菜单 | Kra 图标 |
|
||||
| --- | --- |
|
||||
| 商务管理 / 商务列表 | Briefcase / UserFilled |
|
||||
| 渠道列表 / 渠道激活 | Connection / CircleCheck |
|
||||
| 数据分析 / 渠道数据统计 | DataAnalysis / Histogram |
|
||||
| 充值明细 / 注册明细 | Money / User |
|
||||
| 游戏数据 / 区服分析 | TrendCharts / Monitor |
|
||||
| 排行榜 | Star |
|
||||
| 预警中心 / 预警列表 / 预警规则 | Bell / Warning / Setting |
|
||||
|
||||
首次迁移按旧菜单 path 映射;重复执行分支和 `202611040009_business_menu_icons` 修复已迁移库。仅替换原迁移、早期模块默认图标或空值,其他自定义图标保留。无需完整重跑数据库迁移,独立 SQL 补丁见 `menu-icon-repair.sql`。
|
||||
|
||||
`scripts/sw_menu_icons_verify.cjs` 检查当前安装的真实组件、SVG 输出、模块定义和 SQL 两条分支的一致性。实际 8000/18000 菜单接口均已通过 14 项检查;没有进行浏览器交互检查。刷新页面重新加载菜单后生效。
|
||||
@@ -1,200 +0,0 @@
|
||||
# 旧商务页面功能核对
|
||||
|
||||
以旧前端 `dev/dev1.0` 的实际模板、事件处理和接口调用为准,不因为后端存在某个接口就向页面增加入口。页面样式采用 Kra;名称、业务可见条件和交互沿用旧商务。只有完成页面、接口和实际验证后才标为整个菜单完成。
|
||||
|
||||
## 商务列表与绑定列表
|
||||
|
||||
来源:`sw/web/src/views/BusMgmt/BusinessList.vue`,以及该目录下实际引用的抽屉组件。前端基线 `ba284011c87fd3d5730e0e3dceffb14a7389730c`。
|
||||
|
||||
| 旧页面行为 | 新页面状态 |
|
||||
| --- | --- |
|
||||
| 商务列表没有编辑按钮;操作列为画像 | 已对齐,商务画像及对应抽屉已接入 |
|
||||
| 第二个页签名为“绑定列表”,仅 `level=3` 显示 | 已对齐;超管、一级、二级均隐藏且不会加载绑定列表 |
|
||||
| 商务列表筛选:商务名称、商务账号、等级、状态 | 已实现 |
|
||||
| 添加子商务:账号、密码、姓名、手机号、QQ;展示等级/所属商务 | 已实现;已移除原页面没有的邮箱和编辑审核表单 |
|
||||
| SDK商务数量可点击,零数量也能打开详情 | 已对齐 |
|
||||
| SDK商务绑定详情是只读抽屉,上级可以查看;列为平台、ID、游戏商务账号、审核状态、绑定日期 | 已对齐,平台点击可进入游戏商务画像 |
|
||||
| 商务列表列名“旗下渠道数”,点击进入旗下渠道抽屉 | 已对齐,抽屉显示序号、渠道名称、所属平台及分页 |
|
||||
| 注册日期、绑定日期显示年月日 | 已对齐 |
|
||||
| 绑定状态正常:画像、解绑;驳回:查看驳回;待审核:无操作 | 已对齐,画像只出现在正常绑定行 |
|
||||
| 查看驳回打开审核详情,展示申请商务、平台、账号、状态、申请/审核时间、审核人和审核意见 | 已实现 |
|
||||
| 添加绑定、解除绑定确认使用右侧抽屉 | 已对齐 |
|
||||
| 绑定列表点击旗下渠道数时,仅正常状态可查看并携带平台/平台商务筛选 | 已实现并通过浏览器参数核对 |
|
||||
| 全局偏好变化刷新商务/绑定数据 | 已接入 Kra 页面刷新机制 |
|
||||
|
||||
“仅三级可见”是旧页面页签规则。旧 Java 绑定查询接口仍支持超管全量、一级/二级查询下级,SDK 详情接口允许上级查看下级;这些接口的数据范围不能因页签隐藏而一并误删。
|
||||
|
||||
目前 sw7 是系统数据演练库,缺少 `tab_promote`。有绑定但渠道表未接入的数量明确返回空值并展示“未接入”,不当作零;完整数据环境继续计算真实数量。
|
||||
|
||||
## 验证
|
||||
|
||||
- `business-page-parity-2026-11-03.json`:真实 Chrome 渲染、受控身份/业务数据,检查四个等级的页签和按钮,以及三种审核状态的行操作;无页面运行时错误。
|
||||
- `http-business-bindings-2026-11-03.json`:真实运行实例及已有 sw7 测试数据的 HTTP 验证。
|
||||
- 旗下渠道已通过仓储与实际 HTTP 回归,覆盖已通过绑定、直属一级、跨平台同号和稳定分页;sw7 缺渠道数据时明确返回 `available=false`。
|
||||
- 商务、SDK 商务和渠道画像已通过接口及浏览器验证;真实业务库数值仍待最终验收。
|
||||
|
||||
## 商务与游戏商务画像
|
||||
|
||||
来源:旧 `BusinessProfileDrawer.vue` 及 `BusinessList.vue` 的实际入口、`handleProfileOpenChannels` 参数传递。
|
||||
|
||||
| 旧页面行为 | 新页面状态 |
|
||||
| --- | --- |
|
||||
| 商务列表画像、正常绑定行画像、只读 SDK 详情平台入口 | 三个入口已接入,并分别验证一级与三级身份 |
|
||||
| 基本资料、上级商务、注册时间、状态、一级渠道数、本月新增 | 已实现;SDK 父级来自 commerce1/commerce2,SDK 状态 0 展示待审核 |
|
||||
| 今日、昨日、近7天、近30天、本月 | 已实现,周期和对照区间由后端统一计算 |
|
||||
| 注册玩家、充值金额、付费率、人均充值及环比 | 已实现,付费率使用百分点差并保留无对照期时的 null |
|
||||
| 注册、充值趋势及 TOP 5 | 已实现;使用 Kra 主题样式,图表支持鼠标与键盘查看数据点 |
|
||||
| 关联预警独立分页,不随指标周期改变查询范围 | 已实现,按 SW businessId 与平台过滤 |
|
||||
| 画像“旗下渠道”继续打开直属渠道抽屉 | 已对照父组件处理函数;传入 SW 用户 ID,SDK 场景附带平台和平台商务 ID |
|
||||
| 缺业务数据与没有业务数据 | 分别显示未接入与真实零,避免未知指标显示为零 |
|
||||
|
||||
验证:`portrait-http-2026-11-03.json`、`portrait-page-2026-11-03.json` 及隔离双库 TCP HTTP 测试。完整平台资料与真实业务数值仍待最终实库联调。
|
||||
|
||||
## 其他页面
|
||||
|
||||
渠道统计、游戏数据、区服分析和排行榜,均需在各自实现前逐项提取旧模板的筛选项、列、按钮、抽屉、权限和跳转。数据库菜单清单或后端接口清单只能用于交叉核对,不能替代页面核对。
|
||||
|
||||
## 注册与充值明细
|
||||
|
||||
来源:旧 `RegistrationDetails.vue`、`RechargeDetails.vue`,查询及导出边界见 `ledger-source-notes.md`。
|
||||
|
||||
| 旧页面行为 | 新页面状态 |
|
||||
| --- | --- |
|
||||
| 平台、商务账号、玩家ID、精确渠道账号、游戏名称与日期筛选 | 已实现;游戏选项按平台查询并按名称选择 |
|
||||
| 页面默认含今日近30天,后台不传日期默认截至昨日7天 | 分别保留;日期快捷为今日/昨日/本周/本月 |
|
||||
| 注册列没有独立 ID 与角色名称,包含累计充值 | 已对齐;累计充值按同平台玩家全部历史成功支付 |
|
||||
| 充值包含订单、区服、角色、方式、状态及成功支付合计 | 已实现;合计不跟随失败/处理中状态筛选改变口径 |
|
||||
| 时间、金额服务端排序 | 已实现;不提供后台不支持的充值 ID 排序 |
|
||||
| 充值≥5000的行高亮 | 已保留 |
|
||||
| 导出当前筛选数据,最多10000条 | 已实现 XLSX;注册按钮改用正确的注册导出权限 |
|
||||
| 缺业务数据或查询失败 | 明确提示,清除旧行与旧合计,不导出假空业务数据 |
|
||||
|
||||
验证:`ledger-http-2026-11-04.json`、`ledger-page-2026-11-04.json`,实际 TCP HTTP、工作簿内容检查及全量 Go/前端构建。真实服务导出验证仅使用确定无匹配数据的筛选。
|
||||
|
||||
## 预警规则
|
||||
|
||||
来源:`sw/web/src/views/AlertCenter/AlertRules.vue` 及其规则编辑组件;规则触发提示同时核对最终 `AlertRecordCreationService`,旧页面“每天一次”提示已失效。
|
||||
|
||||
| 旧页面行为 | 新页面状态 |
|
||||
| --- | --- |
|
||||
| 按监控指标、规则名称筛选 | 已实现 |
|
||||
| 列为启用状态、规则名称、规则类型、描述、创建人、作用范围、操作 | 已实现;类型显示预警颜色,范围固定一级渠道 |
|
||||
| 一级商务和超管可新建、编辑、删除、启停;二/三级只读 | 已实现,后端同时校验归属,真实 Chrome 检查四级角色 |
|
||||
| 新建/编辑右侧抽屉,类型为自由文本 | 已实现 |
|
||||
| 注册/充值展示周期、方向、阈值;登录展示未登录天数 | 已实现,浏览器验证切换字段及提交参数 |
|
||||
| 删除需要确认 | 已实现,后端软删除 |
|
||||
| 预警触发去重说明 | 按最终后端描述平台、渠道、类型的未关闭记录去重;生成任务仍待迁移 |
|
||||
|
||||
验证:`alert-rules-http-2026-11-03.json`、`alert-rules-page-2026-11-03.json`,以及隔离数据的真实 TCP HTTP 生命周期测试。预警检测与生成任务仍待迁移。
|
||||
|
||||
## 预警列表与处理抽屉
|
||||
|
||||
来源:`sw/web/src/views/AlertCenter/AlertList.vue`、`components/AlertHandleDialog.vue`,并核对最终 `SysAlertRecordServiceImpl` 和 `SysAlertOperationLogServiceImpl`。
|
||||
|
||||
| 旧页面行为 | 新页面状态 |
|
||||
| --- | --- |
|
||||
| 顶部五种状态卡片,点击筛选、再次点击取消 | 已实现;状态卡片统计保留原后端口径 |
|
||||
| 平台默认全选;规则名称、类型、状态、归属商务筛选 | 已实现;平台取消全选时清空列表,不误查询全部 |
|
||||
| 所属平台、触发时间、规则名称、类型、预警对象、归属商务、内容、状态、操作 | 已实现,触发时间按月日时分显示 |
|
||||
| 行操作按五种状态显示处理、继续处理、审核/查看、重新处理、查看 | 已实现;待审核仅一级显示审核,等级为零的超管显示查看 |
|
||||
| 右侧处理/详情抽屉展示摘要与不可删除的操作记录 | 已实现,日志按时间、ID 倒序,动作编码映射中文 |
|
||||
| 只读态隐藏备注与写入按钮 | 已实现;详情最新状态与服务端 canAudit 同时决定可操作性 |
|
||||
| 开始、提交、驳回、重新处理需要确认;审核通过直接提交 | 已对齐 |
|
||||
| 操作成功刷新详情与列表,抽屉保持打开 | 已实现,状态变化后按钮和只读态同步更新 |
|
||||
| 图片选取、拖拽、粘贴、预览、移除,添加备注时才上传 | 已实现;失败重试复用已上传结果,暂存图片阻止直接流转 |
|
||||
| 旧页面允许只选图片,后端要求非空备注 | 按原后端契约提前校验备注,避免先上传后失败 |
|
||||
| 缺渠道表无法判断可见范围 | 返回 available=false,卡片显示未接入,不把未知范围当成真实零 |
|
||||
|
||||
验证:`alert-records-http-2026-11-03.json`、`alert-records-page-2026-11-03.json`;后端完整状态流转通过独立 SQLite 和真实 TCP HTTP 测试,浏览器核对四个等级和五种状态的入口。预警检测/生成任务仍未接入,不因列表和工作流完成而宣称整个预警链路完成。
|
||||
|
||||
## 登录页
|
||||
|
||||
已从旧 `login.vue` 复用登录模板和样式,复制原品牌图片,适配 Kra 登录接口;保持记住账号而不存密码、验证码、三步找回密码和原文案。系统标题、侧栏标识及页脚已同步旧商务名称。`login-page-verification-2026-11-03.json` 记录 Chrome 的流程验证,短信接口为测试替身,不向真实手机发码。
|
||||
|
||||
## 渠道激活
|
||||
|
||||
来源:`sw/web/src/views/BusMgmt/ChannelActivationList.vue`,最终 `PromoteActivePoolBindServiceImpl` 与独立 OA 查询适配器。
|
||||
|
||||
| 旧页面行为 | 新页面状态 |
|
||||
| --- | --- |
|
||||
| 平台默认全选,渠道账号与绑定商务筛选,查询/重置 | 已实现;没有额外增加旧模板不存在的状态筛选 |
|
||||
| 列为平台、渠道名称、绑定商务、绑定日期、解绑时间、累计流水金额、状态、操作 | 已实现,日期按年月日显示,金额保留两位小数 |
|
||||
| 已驳回无流水明细按钮,其余状态均显示 | 已实现;待审核按原接口提示“审核通过后可查看” |
|
||||
| 流水使用居中弹窗,显示平台、渠道、绑定期间、游戏汇总和总额 | 已实现 |
|
||||
| 普通商务仅看本人认领,超管看全部 | 已实现,和预警的下级树范围分开;在隔离双库 HTTP 测试中验证 |
|
||||
| 达标/解绑后的流水截止时间 | 保持最终后端计算,并修正旧弹窗达标状态仍显示“起”的文案,显示实际截止日期 |
|
||||
| 明细加载失败 | 明确展示原因,不保留预填金额冒充成功读取的明细 |
|
||||
| OA 未接入 | 明确显示未接入;不回退到主库同名表 |
|
||||
|
||||
验证:`activation-http-2026-11-03.json`、`activation-page-2026-11-03.json`,以及独立主库/OA 两个 SQLite 数据库的真实 TCP HTTP 测试。未修改实际 OA 数据。
|
||||
|
||||
## 渠道列表、新增与推广游戏
|
||||
|
||||
来源及统计规则详见 `channel-source-notes.md`。页面保持旧 `ChannelList.vue`、`AddChannelDrawer.vue`、`ChannelGameDrawer.vue` 的实际功能。
|
||||
|
||||
| 旧页面行为 | 新页面状态 |
|
||||
| --- | --- |
|
||||
| 平台、商务账号、渠道关键词、层级、类型、锁定状态筛选 | 已实现;修正旧“账号/负责人姓名”占位文案,按实际后端只查询账号 |
|
||||
| 列表类型个人/公会;新增类型个人/企业 | 按两处实际模板分别保留 |
|
||||
| 渠道信息、归属商务、上级/负责人、推广游戏、玩家、累计充值、锁定状态 | 已实现;缺失指标明确显示未接入 |
|
||||
| 没有编辑入口,行操作为画像 | 已对齐,渠道画像入口及完整抽屉已接入 |
|
||||
| 添加渠道按按钮权限,不额外限制三级 | 已实现并用一级浏览器身份核对,上级可选择下级正常绑定 |
|
||||
| 切换平台清空游戏商务并重新加载、按平台商务 ID 去重 | 已实现,防止旧请求覆盖新平台选项 |
|
||||
| 添加成功后关闭抽屉、刷新第一页,允许同步延迟 | 已实现,保持源平台创建及同步延迟提示 |
|
||||
| 游戏数量零也可打开抽屉;必须携带平台和渠道 ID | 已实现并用跨平台同号与零游戏行验证 |
|
||||
| 游戏分布显示累计玩家数、充值金额 | 已实现,实际取日汇总/身份键数据,独立于列表原始累计指标 |
|
||||
| 全局偏好变化刷新页面 | 复用 Kra 全局 reload,后端每次请求读取当前偏好 |
|
||||
|
||||
验证:`channel-http-2026-11-03.json`、`channel-page-2026-11-03.json`,以及实际 TCP HTTP + 隔离主库/平台库。画像新增验证见下表,完整真实数据仍待最终验收。
|
||||
|
||||
## 渠道画像
|
||||
|
||||
来源及计算规则见 `channel-portrait-source-notes.md`。
|
||||
|
||||
| 旧页面行为 | 新页面状态 |
|
||||
| --- | --- |
|
||||
| 基本资料、上级渠道、注册与最后登录时间、推广游戏数 | 已实现,一级不显示上级,其余读取同平台当前上级账号 |
|
||||
| 今日、昨日、近7天、近30天、累计 | 已实现;修正旧 7d/30d 参数错配,发送 last7/last30 |
|
||||
| 注册玩家、充值金额、付费率、活跃玩家 | 已实现;累计模式无环比值 |
|
||||
| 两个趋势图与四档付费分层 | 已实现,复用 Kra 主题图表和进度条,分层按累计身份与历史成功支付 |
|
||||
| 推广游戏数点击打开游戏分布 | 已实现,携带同一平台和渠道 ID,始终累计口径 |
|
||||
| 关联预警分页 | 已实现;修复旧页面误传 businessId,改为平台+targetPromoteId |
|
||||
| 缺业务表 | 保留能读取的基本资料,明确提示未接入,不生成假零分层 |
|
||||
|
||||
验证:`channel-portrait-http-2026-11-03.json`、`channel-portrait-page-2026-11-03.json`、隔离数据真实 TCP HTTP 和完整 Go/前端构建检查。
|
||||
|
||||
## 渠道统计与游戏分析
|
||||
|
||||
来源及统计细节见 `analytics-source-notes.md`。
|
||||
|
||||
| 旧页面行为 | 新页面状态 |
|
||||
| --- | --- |
|
||||
| 平台默认全选,游戏多选、日期近 30 天,搜索/查询 | 已实现,查询和筛选回到第一页 |
|
||||
| 渠道另有账号模糊、个人/公会类型筛选 | 已实现,文案明确按账号匹配 |
|
||||
| 渠道顶部渠道数、注册、金额、付费率四卡片 | 已实现,使用全量后端汇总,与当前分页无关 |
|
||||
| 渠道表平台、渠道、归属商务、注册/活跃/充值人数、新付费、金额和付费率 | 已实现,沿用 Kra 表格样式 |
|
||||
| 游戏表平台、游戏、注册/活跃/付费人数、新付费、金额、付费率、ARPU、ARPPU | 已实现,游戏 ID 无无效排序箭头 |
|
||||
| 游戏表尾汇总来自全部筛选结果 | 已实现,跨页保留全量 summary;渠道页使用顶部卡片 |
|
||||
| 列排序和分页 | 已实现,服务器排序,同值增加平台/ID 保证稳定 |
|
||||
| 旧页面无导出接口/按钮 | 不增加导出入口 |
|
||||
| 缺报表数据 | 明确显示未接入,清空过期汇总,指标不伪造零 |
|
||||
|
||||
验证:`analytics-http-2026-11-04.json`、`analytics-page-2026-11-04.json`;Chrome 使用受控业务数据,完整计算和权限使用隔离数据库的真实 TCP HTTP 验证。
|
||||
|
||||
## 区服分析
|
||||
|
||||
按旧 `ServerAnalysis.vue` 源码迁移平台多选、游戏多选、区服单选、近 30 天默认日期、首个游戏自动查询、列排序/分页及全量汇总;沿用 Kra 控件,没有新增导出入口。切换平台清空游戏/区服,切换游戏清空区服,过期异步请求不覆盖新选项。统计字段保持所属平台、区服编号/名称、开服日期、新增注册、活跃玩家、充值金额、付费玩家和 ARPU。
|
||||
|
||||
接口通过真实 sw7 请求及隔离数据库 TCP HTTP 验证,前端 ESLint/生产构建通过。按用户 2026-11-04 新要求,此后只检查接口,不再检查页面交互。详见 `server-analysis-source-notes.md`。
|
||||
|
||||
## 工作台 / Kra 仪表盘
|
||||
|
||||
直接核对旧 `views/index.vue`,在原 Kra 仪表盘中加入六项商务指标、平台多选、注册/充值两组横向榜图、未登录/最低充值两组榜表,以及最新五条待处理预警的四秒轮播和查看全部入口。注册/最高充值默认今日,最低充值默认近 30 天;每个榜单单独切换周期。保留 Kra 欢迎、快捷入口和公告,使用 Kra 卡片、颜色与 Element Plus 控件。没有移植旧页面的自定义图表样式。
|
||||
|
||||
四个工作台接口和已有预警接口负责真实业务数据;接口缺表或错误明确提示,不将空选择、未接入和真实零混淆。按用户要求仅做接口实测、数据断言和构建,未做页面交互检查。
|
||||
|
||||
## 独立排行榜
|
||||
|
||||
按旧 `RankingAnalysis.vue` 保留渠道/商务/游戏三个页签、平台多选(空选表示全部)、各维度独立记忆的日期、默认近 7 天,以及注册/充值/付费率/活跃四组 TOP20。不足 20 条显示占位符,旧请求不覆盖新维度。界面采用 Kra 表格和配色;付费率的环比文案明确为百分点,修复旧页面将百分点也显示成百分比的歧义。没有额外增加分页、游戏选择或导出入口。
|
||||
|
||||
接口实测、隔离数据 HTTP、全量 Go 和前端构建通过。按用户要求未检查页面交互。详见 `ranking-source-notes.md`。
|
||||
@@ -1,38 +0,0 @@
|
||||
{
|
||||
"scope": "运行实例匿名接口校验;不发送短信、不修改真实用户密码",
|
||||
"base_url": "http://127.0.0.1:18000",
|
||||
"checks": [
|
||||
{
|
||||
"action": "check",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "账号不存在或未注册",
|
||||
"elapsed_ms": 3097,
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"action": "send-code",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "商务账号参数不正确",
|
||||
"elapsed_ms": 314,
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"action": "verify-code",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "商务账号参数不正确",
|
||||
"elapsed_ms": 85,
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"action": "reset",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "商务账号参数不正确",
|
||||
"elapsed_ms": 224,
|
||||
"passed": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
{
|
||||
"scope": "真实 sw7 登录会话,只读请求;有绑定但业务表未接入时不伪造零,无绑定时验证真实空画像。完整指标和 SDK 基本信息通过隔离双库 TCP HTTP 测试。",
|
||||
"checks": [
|
||||
{
|
||||
"path": "/sw/business/list?pageNum=1&pageSize=500",
|
||||
"http": 200,
|
||||
"code": 0,
|
||||
"msg": "成功",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"path": "/sw/business/10001/portrait?sourceDbList=lx,hw,yq&period=today",
|
||||
"http": 200,
|
||||
"code": 0,
|
||||
"msg": "成功",
|
||||
"passed": true,
|
||||
"available": true,
|
||||
"promote_count": 0,
|
||||
"register_points": 24,
|
||||
"pay_points": 24
|
||||
},
|
||||
{
|
||||
"path": "/sw/business/10001/portrait?sourceDbList=lx&period=thisMonth",
|
||||
"http": 200,
|
||||
"code": 0,
|
||||
"msg": "成功",
|
||||
"passed": true,
|
||||
"available": true,
|
||||
"promote_count": 0,
|
||||
"register_points": 3,
|
||||
"pay_points": 3
|
||||
},
|
||||
{
|
||||
"path": "/sw/business/10004/portrait?sourceDbList=lx,hw,yq&period=last7",
|
||||
"http": 200,
|
||||
"code": 0,
|
||||
"msg": "成功",
|
||||
"passed": true,
|
||||
"available": false,
|
||||
"promote_count": null,
|
||||
"register_points": 0,
|
||||
"pay_points": 0
|
||||
},
|
||||
{
|
||||
"path": "/sw/business/10001/portrait",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "请选择所属平台后查看数据",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"path": "/sw/business/bindPlatform/portrait?sourceDb=lx&platformBusierId=0",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "商务账号参数不正确",
|
||||
"passed": true
|
||||
}
|
||||
],
|
||||
"passed": true
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
{
|
||||
"method": "真实 Chrome 渲染;业务接口使用受控数据。验证三个入口、时间切换、交互图表、SDK 状态、SW 用户 ID 与平台 ID 分离、缺数据提示。",
|
||||
"results": [
|
||||
{
|
||||
"level": 1,
|
||||
"passed": true,
|
||||
"entry": "商务列表与只读 SDK 详情",
|
||||
"pageErrors": []
|
||||
},
|
||||
{
|
||||
"level": 3,
|
||||
"passed": true,
|
||||
"entry": "三级绑定列表正常行",
|
||||
"pageErrors": []
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
# 商务与 SDK 商务画像源码核对
|
||||
|
||||
状态:两种画像接口、三个页面入口及报表读取已实现并通过隔离 HTTP、真实会话和浏览器验证。完整平台数据源与最终旧库数据验收仍未完成。账号状态联动已在 `fc17b38` 完成。
|
||||
两种画像接口、三个页面入口及报表读取已实现。接口、平台数据源及账号状态验证统一见 `validation.md`。
|
||||
|
||||
## 范围与入口
|
||||
|
||||
@@ -40,4 +40,4 @@
|
||||
|
||||
沿用 DTO → service → biz → data,金额用精确计算,页面采用 Kra 图表/表格风格。不要在 stats 缺表时伪造零;没有任何绑定是已知空范围,可返回真实零和零趋势,有绑定但渠道/汇总未接入时保留可读取基本信息并明确未知指标。
|
||||
|
||||
当前真实测试库仍缺完整业务表、平台/OA 别名尚未配齐。正向指标和权限测试继续用隔离数据与真实 TCP HTTP,真实 18000 实例用现有会话验证查询和缺数据场景。最终仍需用户确认旧库后复制验收。
|
||||
当前验证状态统一见 [验收与性能记录](validation.md),不再维护阶段性运行报告。
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
{
|
||||
"scope": "真实 sw7 会话;当前缺业务表,只读验证输入与未接入提示。正向排行和权限通过隔离 TCP HTTP 测试。",
|
||||
"checks": [
|
||||
{
|
||||
"path": "/sw/rank/channel?sourceDb=lx,hw,yq",
|
||||
"http": 200,
|
||||
"code": 0,
|
||||
"msg": "成功",
|
||||
"passed": true,
|
||||
"available": false
|
||||
},
|
||||
{
|
||||
"path": "/sw/rank/channel?beginTime=bad&endTime=2026-11-04",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "统计周期格式错误,应为 yyyy-MM-dd",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"path": "/sw/rank/channel?beginTime=2026-11-05&endTime=2026-11-04",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "统计开始日期不能晚于结束日期",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"path": "/sw/rank/business?sourceDb=lx,hw,yq",
|
||||
"http": 200,
|
||||
"code": 0,
|
||||
"msg": "成功",
|
||||
"passed": true,
|
||||
"available": false
|
||||
},
|
||||
{
|
||||
"path": "/sw/rank/business?beginTime=bad&endTime=2026-11-04",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "统计周期格式错误,应为 yyyy-MM-dd",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"path": "/sw/rank/business?beginTime=2026-11-05&endTime=2026-11-04",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "统计开始日期不能晚于结束日期",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"path": "/sw/rank/game?sourceDb=lx,hw,yq",
|
||||
"http": 200,
|
||||
"code": 0,
|
||||
"msg": "成功",
|
||||
"passed": true,
|
||||
"available": false
|
||||
},
|
||||
{
|
||||
"path": "/sw/rank/game?beginTime=bad&endTime=2026-11-04",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "统计周期格式错误,应为 yyyy-MM-dd",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"path": "/sw/rank/game?beginTime=2026-11-05&endTime=2026-11-04",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "统计开始日期不能晚于结束日期",
|
||||
"passed": true
|
||||
}
|
||||
],
|
||||
"passed": true
|
||||
}
|
||||
@@ -8,9 +8,9 @@
|
||||
- 商务榜超管列出一/二/三级商务,普通商务看直属下级,三级空榜。每个被展示商务的数据来自本人及全部下级的正常绑定渠道。一次关系查询展开目标、下级、绑定、渠道,代替旧每个目标单独查询下级的 N+1;查询条件保持各目标自己的祖先路径范围。
|
||||
- 商务人数累加各渠道人数,不做跨渠道全局去重;金额累加同一组渠道。逐渠道保留 Java int 上限,商务总数采用 int64 避免旧 int 溢出。祖先与下级可以分别上榜;不是互斥分区。
|
||||
- 注册、充值、活跃只展示正值;付费率只要求活跃大于 0,保留 0% 行。金额固定模式 0,人数取当前偏好。
|
||||
- 注册/充值/活跃环比需要上期正值,否则为 null;付费率只要求上期存在行,上期活跃为零按 0% 比较,结果为百分点差。金额展示先保留两位,金额环比用未舍入汇总,与旧服务一致。
|
||||
- 2026-11-04 按用户要求,四榜环比统一为 `(本期值 - 上期值) / 上期值 × 100%`。上期没有有效数据或为零时为 null;本期付费率降到零且上期为正时为 -100%。付费率原来的百分点差已改为相对增幅,这是迁移后明确采用的新口径。金额展示先保留两位,金额环比用未舍入汇总,与旧服务一致。
|
||||
- 环比保留两位,绝对值小于 0.01 为持平。数值排序用精确有理数,同值追加平台/ID 稳定排序,截取后连续编号。
|
||||
- 源码还核对了空平台含义:独立排行榜空选表示全部,区别于工作台必须选平台。非法/倒置日期明确拒绝。缺报表时 available=false 和空数组,不伪造零指标或空查询成功。
|
||||
- 当前菜单名称、父级和路径已通过实际菜单接口核实,仍为 `sw_DataAnalysis` 下 `sw_RankingAnalysis` / `RankingAnalysis`。
|
||||
|
||||
已通过全量 Go、领域/仓储测试、独立 SQLite 的真实 TCP HTTP、ESLint/生产构建、真实 sw7 只读请求。没有页面交互检查,也没有进行最终旧库复制或同源比较。
|
||||
当前验证状态统一见 [验收与性能记录](validation.md),不再维护阶段性运行报告。
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
{
|
||||
"scope": "真实 sw7 会话,只读任务接口;正向创建和触发通过隔离数据库原生任务 HTTP 测试。",
|
||||
"registeredMethods": [
|
||||
"swReportDayBackfillTask",
|
||||
"swReportDayTodayTask",
|
||||
"swReportDayYesterdayTask",
|
||||
"swReportServerDayBackfillTask",
|
||||
"swReportServerDayTodayTask",
|
||||
"swReportServerDayYesterdayTask"
|
||||
],
|
||||
"importedTasks": 7,
|
||||
"enabledImportedTasks": 0,
|
||||
"passed": true
|
||||
}
|
||||
@@ -24,4 +24,4 @@
|
||||
|
||||
领域与存储测试覆盖身份/账号规则、重复构建、自然日筛选和身份明细写失败后的原子回滚。真实 TCP HTTP 使用隔离数据库和 Kra 原生任务创建、手动触发、执行日志,核对两种报表实际落库且任务仍为禁用。
|
||||
|
||||
全量 Go 测试通过。当前真实 sw7 仅查询注册方法和计划状态,7 个导入任务均禁用。没有在真实 sw7 重建报表,也没有开始最终旧数据库复制与同源结果比较;MySQL 并发锁效果须在最终隔离旧库联调中验证。
|
||||
当前验证状态统一见 [验收与性能记录](validation.md),不再维护阶段性运行报告。
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
{
|
||||
"scope": "真实 sw7 会话只读检查,当前缺少业务报表和游戏区服表;未创建实际业务数据。",
|
||||
"checks": [
|
||||
{
|
||||
"endpoint": "list",
|
||||
"query": {},
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "请选择游戏",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"endpoint": "servers",
|
||||
"query": {},
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "请选择游戏",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"endpoint": "list",
|
||||
"query": {
|
||||
"gameName": "隔离核验不存在游戏",
|
||||
"sourceDb": "lx,hw,yq"
|
||||
},
|
||||
"http": 200,
|
||||
"code": 0,
|
||||
"msg": "成功",
|
||||
"passed": true,
|
||||
"available": false,
|
||||
"total": 0
|
||||
},
|
||||
{
|
||||
"endpoint": "list",
|
||||
"query": {
|
||||
"gameName": "x",
|
||||
"beginTime": "bad",
|
||||
"endTime": "2026-11-04"
|
||||
},
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "统计周期格式错误,应为 yyyy-MM-dd",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"endpoint": "list",
|
||||
"query": {
|
||||
"gameName": "x",
|
||||
"beginTime": "2026-11-05",
|
||||
"endTime": "2026-11-04"
|
||||
},
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "统计开始日期不能晚于结束日期",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"endpoint": "servers",
|
||||
"query": {
|
||||
"gameName": "隔离核验不存在游戏",
|
||||
"sourceDb": "lx"
|
||||
},
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "游戏或区服数据尚未接入",
|
||||
"passed": true
|
||||
}
|
||||
],
|
||||
"passed": true
|
||||
}
|
||||
@@ -13,4 +13,4 @@
|
||||
- 缺任一必要业务表时明确未接入,summary 为 null;不能混用不存在区服和缺表错误。未知开服时间保持 null。
|
||||
- 后端默认上海当天,前端默认近 30 天;非法日期/倒置周期明确拒绝。页长沿用最大 500。
|
||||
|
||||
已通过领域/仓储测试、独立数据库真实 TCP HTTP、全量 Go、ESLint/生产构建与真实 sw7 接口只读请求。用户已明确不需要页面交互检查;没有执行旧数据库复制或最终同源比对。
|
||||
当前验证状态统一见 [验收与性能记录](validation.md),不再维护阶段性运行报告。
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,558 @@
|
||||
{
|
||||
"date": "2026-11-04",
|
||||
"sourceDatabase": "sw8",
|
||||
"targetDatabase": "sw9",
|
||||
"ports": {
|
||||
"legacy": 18080,
|
||||
"newRecheck": 19002,
|
||||
"newDevelopment": 8000
|
||||
},
|
||||
"businessContractsVerified": 51,
|
||||
"legacyFrameworkAliasesReplaced": 12,
|
||||
"readComparisonCases": 104,
|
||||
"businessTasksMigrated": 7,
|
||||
"businessTasksEnabled": 0,
|
||||
"checks": 230,
|
||||
"reports": [
|
||||
{
|
||||
"file": "sw8-sw9-recheck-account-create-2026-11-04.json",
|
||||
"checks": 10,
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"file": "sw8-sw9-recheck-account-write-2026-11-04.json",
|
||||
"checks": 21,
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"file": "sw8-sw9-recheck-admin-2026-11-04.json",
|
||||
"checks": 36,
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"file": "sw8-sw9-recheck-exports-2026-11-04.json",
|
||||
"checks": 2,
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"file": "sw8-sw9-recheck-level3-2026-11-04.json",
|
||||
"checks": 15,
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"file": "sw8-sw9-recheck-pagination-2026-11-04.json",
|
||||
"checks": 19,
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"file": "sw8-sw9-recheck-preference-matrix-2026-11-04-sub0-dedup0.json",
|
||||
"checks": 4,
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"file": "sw8-sw9-recheck-preference-matrix-2026-11-04-sub0-dedup1.json",
|
||||
"checks": 4,
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"file": "sw8-sw9-recheck-preference-matrix-2026-11-04-sub1-dedup0.json",
|
||||
"checks": 4,
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"file": "sw8-sw9-recheck-preference-matrix-2026-11-04-sub1-dedup1.json",
|
||||
"checks": 4,
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"file": "sw8-sw9-recheck-preference-matrix-2026-11-04.json",
|
||||
"checks": 14,
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"file": "sw8-sw9-recheck-sdk-write-2026-11-04.json",
|
||||
"checks": 35,
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"file": "sw8-sw9-recheck-task-validation-2026-11-04.json",
|
||||
"checks": 8,
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"file": "sw8-sw9-recheck-tasks-2026-11-04.json",
|
||||
"checks": 7,
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"file": "sw8-sw9-recheck-testlevel1-2026-11-04.json",
|
||||
"checks": 6,
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"file": "sw8-sw9-recheck-testlevel2-2026-11-04.json",
|
||||
"checks": 6,
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"file": "sw8-sw9-recheck-testlevel3-2026-11-04.json",
|
||||
"checks": 6,
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"file": "sw8-sw9-recheck-write-2026-11-04.json",
|
||||
"checks": 29,
|
||||
"passed": true
|
||||
}
|
||||
],
|
||||
"coverage": [
|
||||
{
|
||||
"method": "GET",
|
||||
"source_path": "/system/user/preference",
|
||||
"target_path": "/sw/user/preference",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-admin-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "PUT",
|
||||
"source_path": "/system/user/preference",
|
||||
"target_path": "/sw/user/preference",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-preference-matrix-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"source_path": "/system/promote/list",
|
||||
"target_path": "/sw/promote/list",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-admin-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"source_path": "/system/promote/portrait",
|
||||
"target_path": "/sw/promote/portrait",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-admin-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"source_path": "/system/promote/game-distribution",
|
||||
"target_path": "/sw/promote/game-distribution",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-admin-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"source_path": "/system/promote/bindOptions",
|
||||
"target_path": "/sw/promote/bindOptions",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-admin-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"source_path": "/system/promote",
|
||||
"target_path": "/sw/promote",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-sdk-write-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"source_path": "/system/promoteActivePool/bindList",
|
||||
"target_path": "/sw/promoteActivePool/bindList",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-admin-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"source_path": "/system/promoteActivePool/bindSpendDetail",
|
||||
"target_path": "/sw/promoteActivePool/bindSpendDetail",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-admin-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"source_path": "/system/workbench/summary",
|
||||
"target_path": "/sw/workbench/summary",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-admin-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"source_path": "/system/workbench/registerTop",
|
||||
"target_path": "/sw/workbench/registerTop",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-admin-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"source_path": "/system/workbench/payRank",
|
||||
"target_path": "/sw/workbench/payRank",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-admin-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"source_path": "/system/workbench/unloginTop",
|
||||
"target_path": "/sw/workbench/unloginTop",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-admin-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"source_path": "/system/rank/channel",
|
||||
"target_path": "/sw/rank/channel",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-admin-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"source_path": "/system/rank/business",
|
||||
"target_path": "/sw/rank/business",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-admin-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"source_path": "/system/rank/game",
|
||||
"target_path": "/sw/rank/game",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-admin-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"source_path": "/system/gameData/list",
|
||||
"target_path": "/sw/gameData/list",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-admin-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"source_path": "/system/channelData/list",
|
||||
"target_path": "/sw/channelData/list",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-admin-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"source_path": "/system/register/list",
|
||||
"target_path": "/sw/register/list",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-admin-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"source_path": "/system/register/export",
|
||||
"target_path": "/sw/register/export",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-exports-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"source_path": "/system/spend/list",
|
||||
"target_path": "/sw/spend/list",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-admin-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"source_path": "/system/spend/export",
|
||||
"target_path": "/sw/spend/export",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-exports-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"source_path": "/system/serverAnalysis/games",
|
||||
"target_path": "/sw/serverAnalysis/games",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-admin-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"source_path": "/system/serverAnalysis/servers",
|
||||
"target_path": "/sw/serverAnalysis/servers",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-admin-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"source_path": "/system/serverAnalysis/list",
|
||||
"target_path": "/sw/serverAnalysis/list",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-admin-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"source_path": "/system/alertRule/list",
|
||||
"target_path": "/sw/alertRule/list",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-admin-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"source_path": "/system/alertRule/ruleTypes",
|
||||
"target_path": "/sw/alertRule/ruleTypes",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-admin-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"source_path": "/system/alertRule/{id}",
|
||||
"target_path": "/sw/alertRule/:id",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-admin-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"source_path": "/system/alertRule/add",
|
||||
"target_path": "/sw/alertRule/add",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-write-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "PUT",
|
||||
"source_path": "/system/alertRule/edit",
|
||||
"target_path": "/sw/alertRule/edit",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-write-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "DELETE",
|
||||
"source_path": "/system/alertRule/{id}",
|
||||
"target_path": "/sw/alertRule/:id",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-write-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "PUT",
|
||||
"source_path": "/system/alertRule/toggle/{id}",
|
||||
"target_path": "/sw/alertRule/toggle/:id",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-write-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"source_path": "/system/alertRecord/list",
|
||||
"target_path": "/sw/alertRecord/list",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-admin-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"source_path": "/system/alertRecord/detail/{id}",
|
||||
"target_path": "/sw/alertRecord/detail/:id",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-admin-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"source_path": "/system/alertRecord/startProcess",
|
||||
"target_path": "/sw/alertRecord/startProcess",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-write-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"source_path": "/system/alertRecord/submitAudit",
|
||||
"target_path": "/sw/alertRecord/submitAudit",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-write-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"source_path": "/system/alertRecord/approve",
|
||||
"target_path": "/sw/alertRecord/approve",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-write-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"source_path": "/system/alertRecord/reject",
|
||||
"target_path": "/sw/alertRecord/reject",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-write-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"source_path": "/system/alertRecord/reProcess",
|
||||
"target_path": "/sw/alertRecord/reProcess",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-write-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"source_path": "/system/alertRecord/addNote",
|
||||
"target_path": "/sw/alertRecord/addNote",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-write-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"source_path": "/system/user/list",
|
||||
"target_path": "/sw/business/list",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-admin-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"source_path": "/system/user/{userId}/promotes",
|
||||
"target_path": "/sw/business/:userId/promotes",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-admin-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"source_path": "/system/user/{userId}/portrait",
|
||||
"target_path": "/sw/business/:userId/portrait",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-admin-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"source_path": "/system/user/{userId}/bindPlatform",
|
||||
"target_path": "/sw/business/:userId/bindPlatform",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-admin-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"source_path": "/system/user/bindPlatform",
|
||||
"target_path": "/sw/business/bindPlatform",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-sdk-write-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"source_path": "/system/user/bindPlatform",
|
||||
"target_path": "/sw/business/bindPlatform",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-admin-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"source_path": "/system/user/bindPlatform/portrait",
|
||||
"target_path": "/sw/business/bindPlatform/portrait",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-admin-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "DELETE",
|
||||
"source_path": "/system/user/bindPlatform",
|
||||
"target_path": "/sw/business/bindPlatform",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-sdk-write-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"source_path": "/system/user/export",
|
||||
"target_path": "/sw/business/export",
|
||||
"status": "native_framework_replacement",
|
||||
"note": "not a legacy wire-protocol alias"
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"source_path": "/system/user/importData",
|
||||
"target_path": "/sw/business/importData",
|
||||
"status": "native_framework_replacement",
|
||||
"note": "not a legacy wire-protocol alias"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"source_path": "/system/user/",
|
||||
"target_path": "/sw/business",
|
||||
"status": "native_framework_replacement",
|
||||
"note": "not a legacy wire-protocol alias"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"source_path": "/system/user/{userId}",
|
||||
"target_path": "/sw/business/:userId",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-admin-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"source_path": "/system/user",
|
||||
"target_path": "/sw/business",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-account-create-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "PUT",
|
||||
"source_path": "/system/user",
|
||||
"target_path": "/sw/business",
|
||||
"status": "verified",
|
||||
"evidence": "sw8-sw9-recheck-account-write-2026-11-04.json"
|
||||
},
|
||||
{
|
||||
"method": "DELETE",
|
||||
"source_path": "/system/user/{userIds}",
|
||||
"target_path": "/sw/business/:userIds",
|
||||
"status": "native_framework_replacement",
|
||||
"note": "not a legacy wire-protocol alias"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"source_path": "/system/user/optionselect",
|
||||
"target_path": "/sw/business/optionselect",
|
||||
"status": "native_framework_replacement",
|
||||
"note": "not a legacy wire-protocol alias"
|
||||
},
|
||||
{
|
||||
"method": "PUT",
|
||||
"source_path": "/system/user/resetPwd",
|
||||
"target_path": "/sw/business/resetPwd",
|
||||
"status": "native_framework_replacement",
|
||||
"note": "not a legacy wire-protocol alias"
|
||||
},
|
||||
{
|
||||
"method": "PUT",
|
||||
"source_path": "/system/user/changeStatus",
|
||||
"target_path": "/sw/business/changeStatus",
|
||||
"status": "native_framework_replacement",
|
||||
"note": "not a legacy wire-protocol alias"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"source_path": "/system/user/unlock/{userId}",
|
||||
"target_path": "/sw/business/unlock/:userId",
|
||||
"status": "native_framework_replacement",
|
||||
"note": "not a legacy wire-protocol alias"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"source_path": "/system/user/authRole/{userId}",
|
||||
"target_path": "/sw/business/authRole/:userId",
|
||||
"status": "native_framework_replacement",
|
||||
"note": "not a legacy wire-protocol alias"
|
||||
},
|
||||
{
|
||||
"method": "PUT",
|
||||
"source_path": "/system/user/authRole",
|
||||
"target_path": "/sw/business/authRole",
|
||||
"status": "native_framework_replacement",
|
||||
"note": "not a legacy wire-protocol alias"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"source_path": "/system/user/deptTree",
|
||||
"target_path": "/sw/business/deptTree",
|
||||
"status": "native_framework_replacement",
|
||||
"note": "not a legacy wire-protocol alias"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"source_path": "/system/user/list/dept/{deptId}",
|
||||
"target_path": "/sw/business/list/dept/:deptId",
|
||||
"status": "native_framework_replacement",
|
||||
"note": "not a legacy wire-protocol alias"
|
||||
}
|
||||
],
|
||||
"explicitDifferences": [
|
||||
"Pay-rate ranking uses user-requested relative percentage growth instead of percentage-point change.",
|
||||
"Only the creation times of three explicitly identified HTTP-created test users are excluded; original migrated users remain strict.",
|
||||
"Legacy MyBatis returns page one on an out-of-range page; new service returns an empty page. Valid pages match.",
|
||||
"Disabled/pending/rejected users cannot use existing sessions in the new service; old service permits this."
|
||||
],
|
||||
"passed": true
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,7 @@
|
||||
|
||||
## 商务新增与改动
|
||||
|
||||
`SysUserController` 的 Git 差异主要是商务列表语义、添加子商务,以及直属渠道、平台绑定和两种商务画像。用户列表查询新增商务树、姓名/等级过滤、直属渠道与正常绑定数量;添加子商务新增层级、归属与偏好初始化。当前列表、子商务、偏好和平台绑定已迁移;商务/平台商务画像仍未完成。
|
||||
`SysUserController` 的 Git 差异主要是商务列表语义、添加子商务,以及直属渠道、平台绑定和两种商务画像。用户列表查询新增商务树、姓名/等级过滤、直属渠道与正常绑定数量;添加子商务新增层级、归属与偏好初始化。当前列表、子商务、偏好、平台绑定及两种商务画像均已迁移;2026-11-04 已完成 sw8/sw9 同源接口核对。
|
||||
|
||||
原用户控制器中的以下方法在基线前已经存在,旧 `BusMgmt/BusinessList.vue` 没有为它们增加实际操作入口。新商务页面不据此增加编辑、删除、导入、导出、角色分配等按钮。
|
||||
|
||||
@@ -39,4 +39,12 @@
|
||||
|
||||
隔离 TCP HTTP 测试覆盖原生启停后商务接口返回状态、待审/驳回资料编辑、自行启用被拒绝和不存在用户;仓储测试覆盖失败回滚与越权。现有鉴权测试继续检查停用/待审/驳回会拒绝密码登录和已有会话。
|
||||
|
||||
当前 sw7 的 45 个用户已做只读一致性检查,未发现 enable 与 business_status 冲突,因此没有批量改写真实账号。
|
||||
sw8/sw9 的账号状态及原密码保留情况见 `validation.md`。
|
||||
|
||||
## 2026-11-04 实库复核
|
||||
|
||||
SQL 的 63 项契约已逐项归类:51 项商务接口完成真实 HTTP 核对,12 项本页所列旧框架别名由 Kra 原生能力承接,不宣称旧 Excel/Redis 解锁等协议兼容。详见 `sw8-sw9-recheck-summary-2026-11-04.json`。
|
||||
|
||||
真实状态写入验证确认:旧系统停用、待审、驳回后已签发会话仍可访问偏好;新系统会拒绝这些会话。该安全差异保留,恢复正常后旧令牌重新可用。
|
||||
|
||||
原库一级商务角色没有 `system:promote:add` 权限,新库保持同一授权限制。新增渠道的正向实测使用管理员,未擅自扩大角色权限。
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
{
|
||||
"scope": "真实 sw7 登录会话,只读检查;未启停任何真实账号。正向启停和审核状态保留由隔离 TCP HTTP 测试覆盖。",
|
||||
"checks": [
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/user/getUserList",
|
||||
"http": 200,
|
||||
"code": 0,
|
||||
"msg": "获取成功",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/sw/business/list?pageNum=1&pageSize=500",
|
||||
"http": 200,
|
||||
"code": 0,
|
||||
"msg": "成功",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"method": "PUT",
|
||||
"path": "/user/setUserInfo",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "ID值不能为空",
|
||||
"passed": true
|
||||
}
|
||||
],
|
||||
"native_total": 45,
|
||||
"business_total": 45,
|
||||
"checked_users": 45,
|
||||
"inconsistent_states": 0,
|
||||
"response_mismatches": 0,
|
||||
"passed": true
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
# 商务迁移验收与性能记录
|
||||
|
||||
核验日期:2026-11-04。Java → sw8,Go → sw9。原始响应与备份位于仓库外 `D:/Users/Yvan/backups/sw9/20261104_rehearsal/`。
|
||||
|
||||
## 迁移与接口
|
||||
|
||||
- SQL v5 在独立 MySQL 5.7 完成 52 项备份检查、24 项迁移检查;首次执行、重复执行、异常账本拒绝、旧表归档后执行均通过。45 个原用户密码哈希逐字节保留。
|
||||
- 全量旧契约 63 项:51 项商务接口已实测(33 读取、18 写入/导出);12 项旧框架别名由原生功能承接,不能视为旧协议兼容。
|
||||
- 最近完整演练共 230 项检查:104 组读取、两个 Excel 逐单元格、账号创建/编辑/状态、规则增删改/启停、预警状态流转/备注、SDK 绑定/重提/解绑、创建渠道和任务配置。
|
||||
- 日报与区服报表真实重建后,68,857 行逻辑数据一致,随后恢复原分区;预警实际任务两边生成 480 条后恢复原 478 条。
|
||||
- 恢复后的两库均为用户 48、平台绑定 58、规则 5、预警 478、预警日志 313。增加的 3 个层级账号为获授权保留的测试账号。
|
||||
- SDK 写入使用本机独立平台夹具,OA 审批使用受控夹具;没有宣称真实第三方审核或线上支付已验收。
|
||||
|
||||
详细旧契约清单保留在 [综合索引](sw8-sw9-recheck-summary-2026-11-04.json)。本轮新增审查及运行结果见 [接口审查](../API_REVIEW.md)。
|
||||
|
||||
## 明确保留的差异
|
||||
|
||||
1. 付费率榜单按用户要求统一 `%`,变化率为 `(本期-上期)/上期×100%`,上期为零返回无可比值;不是百分点差。
|
||||
2. 仅三个分别创建的测试账号允许创建时刻不同,原迁移用户时间严格比较。
|
||||
3. 超出末页时新接口返回空页;旧 MyBatis 会回到第一页。有效页码和总数保持相同。
|
||||
4. 新服务立即拒绝停用、待审、驳回用户的已有会话;旧服务未做这项检查。
|
||||
5. 本轮修正渠道激活的跨平台同名账号访问:本人已通过绑定的“平台+账号”才有权限。列表及流水明细使用同一规则。
|
||||
6. 日期范围只传一端、倒置或非法时返回参数错误;不再静默忽略筛选。
|
||||
|
||||
## 定时任务
|
||||
|
||||
7 条实际商务计划及 7 个方法均迁移,cron、秒字段、上海时区、回跑参数与超时/重试配置已经逐条核对。
|
||||
|
||||
| 方法 | 周期 | 测试库状态 |
|
||||
|---|---|---|
|
||||
| swReportDayYesterdayTask | 每日 01:00 | 停用 |
|
||||
| swReportServerDayYesterdayTask | 每日 01:05 | 停用 |
|
||||
| swReportDayTodayTask | 每 5 分钟,第 40 秒 | 停用 |
|
||||
| swReportServerDayTodayTask | 每 5 分钟 | 停用 |
|
||||
| swReportDayBackfillTask | 每 60 秒,原配置停用 | 停用 |
|
||||
| swReportServerDayBackfillTask | 每 60 秒,原配置停用 | 停用 |
|
||||
| alertTriggerTask | 每 30 分钟 | 停用 |
|
||||
|
||||
新库未开启自动执行;框架自带 ClearDB、CleanStaleUploads 另行保留。旧工程的演示、分片、MapReduce 示例没有实际商务计划,不属于漏迁。方法超时后仍未退出时禁止重复执行,同分区报表和预警写入有事务锁及去重测试。
|
||||
|
||||
## 已完成的性能优化
|
||||
|
||||
同一 sw9 副本的多轮中位耗时,单位 ms;首次冷读与负载变化会有波动。数据统计近 30 天,排行榜近 7 天。
|
||||
|
||||
| 接口 | 优化前 | 优化后 |
|
||||
|---|---:|---:|
|
||||
| 渠道列表 | 175 | 108 |
|
||||
| 渠道数据统计 | 3839 | 1110 |
|
||||
| 充值明细 | 216 | 113 |
|
||||
| 注册明细 | 139 | 88 |
|
||||
| 游戏数据 | 859 | 453 |
|
||||
| 区服分析 | 3012 | 42 |
|
||||
| 渠道排行榜 | 863 | 483 |
|
||||
| 商务排行榜 | 5048 | 325 |
|
||||
| 游戏排行榜 | 631 | 229 |
|
||||
| 工作台汇总 | 75 | 42 |
|
||||
| 工作台最低充值榜 | 1509 | 171 |
|
||||
| 工作台未登录榜 | 224 | 158 |
|
||||
| 工作台近 7 天注册榜 | 92 | 74 |
|
||||
| 工作台近 7 天充值榜 | 147 | 53 |
|
||||
|
||||
优化包括分页主键后回表、按原渠道预聚合、取消相关子查询、合并汇总查询、限制并发为 2、只加载 TOP10 名称,以及关闭 SQL 日志时避免参数展开。61 组业务列表/排行榜和 52 组工作台数据逐字段相等,另有日常 8080 接口调用检查。
|
||||
|
||||
新增版本 `202611040013_business_query_indexes` 已在 sw9 应用 7 个查询索引,累计 27 个迁移版本;注册转换列索引和区服创角时间索引亦已存在。查询优化不改变用户权限和统计口径。
|
||||
|
||||
## 页面
|
||||
|
||||
渠道激活页不再在发起分页请求时清零 total;排行榜与仪表盘四榜并排、付费率用百分比、头部两项偏好直接勾选;三级商务保留商务列表/绑定列表切换。完整页面检查脚本仍保留,运行截图和带业务数据的响应仅存仓库外。
|
||||
@@ -1,84 +0,0 @@
|
||||
{
|
||||
"scope": "真实 sw7 会话;当前缺业务表,只读验证输入与未接入提示。正向六卡、榜单与权限通过隔离 TCP HTTP 测试。",
|
||||
"checks": [
|
||||
{
|
||||
"path": "/sw/workbench/summary?",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "请选择所属平台后查看数据",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"path": "/sw/workbench/summary?sourceDbList=lx,hw,yq",
|
||||
"http": 200,
|
||||
"code": 0,
|
||||
"msg": "成功",
|
||||
"passed": true,
|
||||
"available": false
|
||||
},
|
||||
{
|
||||
"path": "/sw/workbench/registerTop?",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "请选择所属平台后查看数据",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"path": "/sw/workbench/registerTop?sourceDbList=lx,hw,yq",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "工作台所需业务数据尚未接入",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"path": "/sw/workbench/registerTop?sourceDbList=lx&period=invalid",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "时间维度无效,应为 today/yesterday/last7/last30",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"path": "/sw/workbench/payRank?",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "请选择所属平台后查看数据",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"path": "/sw/workbench/payRank?sourceDbList=lx,hw,yq",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "工作台所需业务数据尚未接入",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"path": "/sw/workbench/payRank?sourceDbList=lx&period=invalid",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "时间维度无效,应为 today/yesterday/last7/last30",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"path": "/sw/workbench/payRank?sourceDbList=lx,hw,yq&order=asc&period=last30",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "工作台所需业务数据尚未接入",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"path": "/sw/workbench/unloginTop?",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "请选择所属平台后查看数据",
|
||||
"passed": true
|
||||
},
|
||||
{
|
||||
"path": "/sw/workbench/unloginTop?sourceDbList=lx,hw,yq",
|
||||
"http": 200,
|
||||
"code": 7,
|
||||
"msg": "工作台所需业务数据尚未接入",
|
||||
"passed": true
|
||||
}
|
||||
],
|
||||
"passed": true
|
||||
}
|
||||
@@ -22,5 +22,5 @@
|
||||
- 仪表盘直接调用四个接口,并复用已有预警列表查询 status=1/pageSize=5,实现原最新五条轮播。Kra 快捷入口和公告保留。
|
||||
- 聚合、资料查询批量执行,未对每个渠道发起独立 SQL。注册榜不依赖金额表,未登录榜不依赖报表,缺少必要表返回明确不可用。
|
||||
- 六卡扩展 available=false 并返回 null 值;榜单保留数组成功协议,缺表返回业务错误,避免把未知榜单当作真实空榜。
|
||||
- 全量 Go、隔离数据库真实 TCP HTTP、前端 ESLint/构建通过;测试覆盖月末对照、零分母、大金额、TOP10、身份去重、下级偏好、负金额/零渠道、未登录回退和跨商务拒绝。实际 sw7 只读结果见 `workbench-http-2026-11-04.json`。
|
||||
- 按用户要求不检查页面交互。当前没有复制旧业务库,最终同源验收尚未开始。
|
||||
|
||||
当前验证状态统一见 [验收与性能记录](validation.md),不再维护阶段性运行报告。
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
# `` 到 `pkg` 复用性审查
|
||||
|
||||
审查原则:公共包只提供跨模块稳定的机制、协议或无状态纯函数;不能依赖
|
||||
`app/*/internal`,也不承载 system 的业务表、用例、provider 客户端或运行时
|
||||
配置。
|
||||
|
||||
## 已抽取到 `pkg`
|
||||
|
||||
| 能力 | 公共位置 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| HTTP JSON 响应契约 | `pkg/httpx` | `Response`、`PageResult`、状态码和 Gin 响应助手;`server/httpx/response.go` 仅保留 system 适配。 |
|
||||
| protobuf JSON 局部合并 | `pkg/protoutil` | 与业务无关的字段归一化和局部反序列化;初始化直接使用公共包。 |
|
||||
| 支付 provider/mode 标识 | `pkg/paymentkit` | provider 常量、支持列表、金额/签名/JSON 等跨模块协议;`biz/payment` 与 `biz/integration` 直接复用。 |
|
||||
| 支付回调 ACK | `pkg/paymentkit` | 回调应答、失败包装和默认 provider 应答;具体渠道 SDK 留在 `internal/integration/payment`。 |
|
||||
| WebSocket 通用收发 | `pkg/websocket` | Melody 的连接、事件、点对点发送、广播和会话查询封装;`internal/integration` 管理配置与生命周期。 |
|
||||
| 消息队列 | `pkg/mq` | Broker 无关的发布、订阅、JSON 和 QoS 接口;EMQX/Paho 与 RabbitMQ/AMQP 客户端由 `internal/integration` 管理。 |
|
||||
| 模块、任务和迁移协议 | `pkg/module`、`pkg/task`、`pkg/database/migration` | 供不同业务模块注册贡献,不带 system 业务语义。 |
|
||||
|
||||
## system 内部保留边界
|
||||
|
||||
- `app`:运行时组合根,汇总依赖注入后的路由和任务贡献。
|
||||
- `modules`:静态模块 catalog,汇总各模块迁移、菜单、API 和默认任务。
|
||||
- `modules/system`:system 模块的 Definition,声明系统表迁移。
|
||||
- `modules/integration`:integration 配置迁移和管理面贡献。
|
||||
- `modules/task`:定时任务迁移和默认任务贡献。
|
||||
- `modules/payment`:payment 模块的 Definition,声明支付迁移和支付管理面。
|
||||
- `biz/system`:用户、权限、菜单、审计、媒体和系统配置等系统领域模型与用例。
|
||||
- `biz/payment`:支付订单、支付流程、支付接口和支付日志。
|
||||
- `biz/integration`:支付/消息队列/WebSocket 集成配置定义与校验。
|
||||
- `biz/task`:定时任务模型、任务用例和任务注册协议。
|
||||
- `conf`:system 配置 proto、运行时快照和生成代码。
|
||||
- `data`:共享数据库生命周期与配置 watcher;PO/仓储按 `system`、`integration`、`task`、`payment` 子包隔离;后台 JWT claims 与签发/解析位于 `data/system/token.go`。
|
||||
- `initialize`:首次安装、配置迁移、种子编排和运行时重载。
|
||||
- `integration`:Redis、邮件、存储、支付、WebSocket、EMQX 和 RabbitMQ 的 provider 生命周期。
|
||||
- `routecatalog`:HTTP 公开性、操作审计、请求体策略和 API 分组/说明的统一目录。
|
||||
- `service`:HTTP DTO(`service/dto`)、DTO 与 DO 转换和应用服务。
|
||||
- `server`:Gin 生命周期;handler、middleware、router、HTTP 适配按子包维护。
|
||||
- `worker`:任务调度、执行器、SSE 订阅及其并发状态。
|
||||
|
||||
这些代码都带有 system 的 API、配置、数据表或生命周期语义,不应为了减少
|
||||
文件数量搬到 `pkg`。
|
||||
|
||||
## 目录分类约定
|
||||
|
||||
```text
|
||||
internal/
|
||||
app/ # 应用组合根
|
||||
modules/ # 静态 catalog、业务模块定义及其模块级贡献
|
||||
biz/
|
||||
system/ # 系统领域
|
||||
payment/ # 支付领域
|
||||
integration/# 集成配置领域
|
||||
task/ # 定时任务领域
|
||||
config/ # Viper 配置、快照和热更新
|
||||
global/ # 进程级共享资源入口
|
||||
data/
|
||||
system/ # 系统表与系统仓储,含后台 JWT token.go
|
||||
integration/# 集成配置表与仓储
|
||||
task/ # 定时任务表与仓储
|
||||
payment/ # 支付表与仓储
|
||||
initialize/ # 首次安装和配置编排
|
||||
integration/ # 外部 I/O provider
|
||||
server/ # Gin 生命周期,内部按 handler/middleware/router/httpx 分类
|
||||
service/ # 应用服务;DTO 集中在 dto 子包
|
||||
worker/ # 任务运行时
|
||||
```
|
||||
|
||||
技术角色使用子目录表达,子目录内部使用资源名,例如 `handler/payment.go`、
|
||||
`router/payment.go`、`dto/payment.go`。只有少量代码且没有独立边界时不建立
|
||||
新包;同一角色文件较多时也不应全部堆在父目录。
|
||||
|
||||
## 暂不抽取的候选
|
||||
|
||||
1. token cookie 名称、SameSite 和反向代理策略:目前是 system 认证策略。
|
||||
2. operation-audit 脱敏和请求采集:包含 system context key 与审计字段。
|
||||
3. biz 查询选项和错误:当前绑定 system 的领域接口及 API reason。
|
||||
|
||||
只有当其他模块出现相同、稳定且不带 system 语义的契约时,才新增公共包;不要
|
||||
直接把单个 system 类型搬到 `pkg`。
|
||||
|
||||
## 验证
|
||||
|
||||
```text
|
||||
go test ./...
|
||||
```
|
||||
|
||||
当前全仓测试通过,且未发现对已删除旧路径的 Go import。
|
||||
@@ -1,63 +0,0 @@
|
||||
# `internal` 目录结构优化结论
|
||||
|
||||
参考 Go Kratos 的分层方式,顶层保留 `app`、`modules`、`biz`、`config`、`global`、
|
||||
`data`、`initialize`、`integration`、`security`、`server`、`service`、`worker` 等
|
||||
稳定职责。目录不是越少越好:同一技术角色文件较多时,应在所属层下分组,避免
|
||||
一个目录堆积几十个文件。
|
||||
|
||||
## 当前结构
|
||||
|
||||
```text
|
||||
internal/
|
||||
app/ # 应用组合根
|
||||
modules/ # 静态 catalog 和模块定义
|
||||
modules/payment/ # payment 模块定义
|
||||
biz/ # DO、usecase、repo interface
|
||||
config/ # Viper 配置、快照和热更新
|
||||
global/ # 进程级共享资源
|
||||
data/ # PO、repo、数据库和迁移
|
||||
initialize/ # 首次安装和配置编排
|
||||
integration/ # 外部 I/O provider
|
||||
security/ # JWT 和安全实现
|
||||
server/
|
||||
handler/ # Gin handler,按资源命名
|
||||
middleware/ # 认证、审计、限流、恢复等中间件
|
||||
router/ # 各资源路由及 Routes 聚合
|
||||
httpx/ # system HTTP 响应和 cookie 适配
|
||||
service/
|
||||
dto/ # HTTP 请求、响应和查询 DTO,按模块命名
|
||||
worker/ # 任务运行时
|
||||
```
|
||||
|
||||
## 本次调整
|
||||
|
||||
- DTO 从 `service` 根目录归档到 `service/dto`。
|
||||
- handler、middleware、router、HTTP helper 分别归档到 `server` 子包。
|
||||
- 子目录内文件直接使用资源名,例如 `handler/payment.go`、
|
||||
`router/payment.go`、`dto/payment.go`,不保留重复角色前缀。
|
||||
- Wire 直接装配 `handler.ProviderSet` 和 `router.ProviderSet`,server 根目录只
|
||||
负责 Gin/Swagger 生命周期。
|
||||
- `security/adminauth/token.go` 合并为 `security/token.go`;单文件子包没有
|
||||
独立边界时不继续拆分。
|
||||
- 删除只转发 `pkg/protoutil` 的 `utils/configutil`。
|
||||
|
||||
## `internal/app` 为什么只保留应用组合
|
||||
|
||||
`modules/catalog.go` 是静态模块注册点,负责按依赖顺序汇总各模块
|
||||
`Definition()`;`app/runtime.go` 只负责任务注册和依赖注入后的路由组合。
|
||||
这样模块定义不再和应用组合逻辑混在一起,也不能误并入 `biz`、`service` 或
|
||||
`data`。
|
||||
|
||||
Catalog 只能自动汇总静态模块贡献;新增模块若提供运行时路由或依赖型任务,仍需
|
||||
在 cmd/Wire 中显式注册。
|
||||
|
||||
## 其他目录审查
|
||||
|
||||
- `data` 与 `integration` 已按仓储或 provider 分类,边界和生命周期明确。
|
||||
- `biz`、`service` 根目录采用一资源一文件;进一步拆成资源子包会改变 Go 包
|
||||
边界并容易引入循环依赖,本次不做纯视觉拆分。
|
||||
- `security` 当前只有一个文件,但安全实现是明确的依赖边界,后续认证机制也会
|
||||
在此扩展,因此保留顶层包。
|
||||
|
||||
新增目录应至少满足独立依赖方向、状态生命周期或稳定技术角色之一。不要回到
|
||||
一文件一目录,也不要为了减少目录数量把大量不同角色重新铺平。
|
||||
Reference in New Issue
Block a user