yml2213
|
aa052d420a
|
fix(dlc): 更新暗影哥特、黑色上衣与浪漫天命的商品编码
- 同步上游 DLC (聚鑫源) 最新 GoodID 映射:
- suit_shadow_gothic: 6a13aa55e3bce430aca29b01
- top_black_elite_trainer: 6a13aaeae3bce430aca29b03
- suit_romantic_destiny: 6a13ab21e3bce430aca29b04
- 更新 delivery_helpers 缺省兜底映射表与 sync_product_images 常量
- 更新 provider_test 单元测试断言与 docs/商品目录.md 文档
- 验证方式:go test 单元测试通过,go vet 校验通过
|
2026-10-10 18:14:46 +08:00 |
|
yml2213
|
e293cebaf5
|
feat(rock): 发货记录表格新增时间与备注列并支持上报失效联动
- 做了什么:
1. 数据库新增 013_rock_tokens_remark.sql 迁移,rock_tokens 表补充 remark 字段并在 ListTokens 中支持备注模糊检索;
2. 后端扩展 UpdateTokenRemark、MarkTokenAbnormal 接口,同时优化 ResetMismatchToken 支持 mismatch 与 abnormal 状态的解冻重置;
3. 前端 RockTokenTable 新增「流转时间」列(入库/绑错/发货/绑定/提货)与「备注」列(TokenRemarkCell 浮窗快捷预设选择与自定义输入);
4. 快捷选择「已上报」或点击「上报失效」自动将链接标记为 abnormal 作废,从可用库存池中剔除,防止被新订单领走;
5. 优化操作列与顶部筛选栏:mismatch 增加「上报失效」与警示重置;abnormal 状态明确显示已失效并提供强制恢复;筛选栏新增「已上报失效」Tab。
- 为什么:
解决绑定错误上报 0868 上游后无法记录备注、且原「解冻重置」容易误将已作废卡密放回可用库存池导致后续订单报错的问题。
- 验证方式:
1. 后端单元测试 TestRockService_TokenRemarkAndAbnormal 与 TestRock 测试集通过;
2. make fmt、go vet 通过;
3. 前端 oxlint 检查通过 (0 errors, 0 warnings),npm run build 生产构建通过。
|
2026-10-08 20:13:25 +08:00 |
|
 yml2213andCursor
|
fcbd7715c7
|
fix(rock): 按链接签名时间提前刷新二维码,扫码查询改为 5 秒
腾讯活动链接大约 10 分钟后签名过期。从链接 timestamp 起满 8 分钟就换新码,避免买家扫到失效二维码。
Co-authored-by: Cursor <cursoragent@cursor.com>
|
2026-10-07 09:49:26 +08:00 |
|
yml2213
|
8cc5d42d53
|
feat(admin): 平台商户成员管理改用抽屉,消除商户视角切换与全局状态污染
- 交互重构:在「平台商户」与「平台账号」点击成员管理时,不再跳转路由或改写 localStorage.merchant_id,改为滑出 MerchantMembersDrawer 抽屉
- 抽屉能力:支持查看指定商户成员列表、新增成员(新建账号或关联已有账号)、修改角色与启用状态、移除成员
- 顶栏清理:彻底移除顶栏右上角的「当前商户:xxx」标签与「退出商户视角」按钮,超管登录自动清理任何残留上下文
- 后端补齐:新增平台专属 /api/platform/merchants/:id/members 与 roles 接口,平台操作不再依赖 X-Merchant-ID
- 验证:tsc -b && vite build 成功;全量 go test ./... 包含路由与鉴权回归测试 100% 通过
|
2026-10-06 21:13:37 +08:00 |
|
yml2213
|
3ec7febb8c
|
refactor(security): 简化为单主密钥架构,废弃离线重加密与冗余警告
- 废弃 DATA_ENCRYPTION_KEY 独立要求,敏感数据加密默认统一由 JWT_SECRET 派生
- 移除 cmd/reencrypt_secrets 离线全表重加密脚本与 docs/密钥轮换说明.md,避免生产原地 UPDATE 高危反模式
- 精简 Config.SecurityWarnings,不再刷屏 DATA_ENCRYPTION_KEY 未显式配置警告,保持启动日志干净
- 更新 .env.example、README.md 与项目分析文档说明
- 验证:make lint 与 make test 全量测试 100% 通过
|
2026-10-06 20:54:00 +08:00 |
|
yml2213
|
663d7e1e9f
|
fix(admin): 商户筛选下拉改用不分页的精简接口
自查新做的下游订单页时发现的问题:商户筛选下拉调用
/api/platform/merchants?size=200,而分页查询会把 >100 的 size 静默降级为 20
(service.normalizePage),因此商户超过 20 家时下拉里会少一批商户,界面不报任何错。
- 新增 service.ListMerchantOptions:不分页返回全部启用商户的精简信息
(id/code/name),独立于分页的 ListMerchants
- 新增 GET /api/platform/merchant-options
- 前端改用该接口;types 增加 MerchantOption,api 增加 merchantOptions()
测试:
- TestListMerchantOptionsReturnsAllActiveMerchants:造 25 家启用 + 1 家禁用,
断言返回数量与库中启用数一致、必须超过分页上限、且不含已禁用商户
- TestListMerchantsClampsOversizedPageSize:钉住「size=200 实际只返回 20 条,
而 total 反映真实总数」这一事实,即上面接口存在的理由
|
2026-10-06 20:44:48 +08:00 |
|
yml2213
|
e692790aa7
|
fix(admin): 平台路由不再依赖商户上下文,消除管理端被残留上下文锁死
问题:Tenant 中间件挂在整个已登录分组上,包括 /api/platform/*。管理员
localStorage 里一旦残留一个已禁用/已删除的商户 ID,ResolveMerchantForAdmin 就会对
所有请求返回 403——连"去把它改回来"的平台页面都打不开,整个管理端被锁死。
判断依据:逐条核对 35 条 /platform/* 路由与 13 个平台侧 handler,租户依赖为 0。
平台接口本身就是跨商户的,商户上下文对它们没有意义。
- router:平台分组从租户中间件里摘出,只挂 Auth + RequireRole(admin);
商户侧分组保持 Tenant 不变,单商户隔离语义一点没动
- 搬迁后逐条比对路由集合:平台 35 条、商户侧全部一致
- request.ts:对 /platform/* 以及管理员的 /dashboard 不再发送 X-Merchant-ID,
作为第二道防线(后者后端本就按角色忽略商户,带上只会引入 403 风险)
回归测试:新增 TestPlatformRoutesIgnoreStaleMerchantContext(无上下文 / 残留不存在的
商户两种情形都必须 200)与 TestMerchantRoutesStillRejectStaleContext(商户侧仍须 403)。
已实测这两个用例在未修复时会失败,报 403「当前账号无权访问该商户」/「商户不存在或已禁用」。
实测(无效商户上下文下):/api/platform/orders → 200 total=37;
/api/platform/merchants、rock/config、product-catalog → 200;/api/merchant/orders → 403。
|
2026-10-06 20:39:57 +08:00 |
|
yml2213
|
8c12d1d448
|
fix(admin): 超管看不到下游订单——新增平台侧跨商户订单视图
问题:管理员首页 Dashboard 显示平台总量(37 单,跨全部商户),点进「发货订单」
却只有 29 单,两个数字互相矛盾且界面上没有任何解释。
根因是「平台管理员」在两套接口里语义不同:
- /api/dashboard:isPlatformAdmin 只看 JWT 角色 → 平台视角,跨商户聚合
- /api/merchant/*:Tenant 中间件强制落到单个 merchant_id → 商户成员视角。
管理员唯一的成员关系是自营商户,于是被静默框定在商户 1
且 34 条 /platform/* 路由中没有任何订单入口,前端也没有商户切换器或上下文提示。
修复(不改动商户侧隔离语义):
- 新增 GET /api/platform/orders,support 按商户/状态/来源/关键字筛选,缺省为全部商户
- Service 抽出共用的 orderFilters 集中校验,ListOrders 与 ListPlatformOrders 并行;
ListOrders 仍强制单商户,避免新增平台路径时顺手放宽商户侧可见范围
- FulfillmentOrder 增加 Merchant 关联字段,仅平台侧 Preload,商户侧响应结构不变
- 前端新增「下游订单(全部商户)」页与菜单项,「发货订单」更名为「发货订单(当前商户)」
- README 补充两个订单入口的说明,避免后来者重踩
验证:单测覆盖跨商户可见性、按商户筛选、筛选校验、以及商户侧隔离不回归;
实测新接口返回 37 单(自营 29 + 测试商户 8)且带商户信息,商户侧仍为 29 单且无 merchant 字段。
|
2026-10-06 20:28:41 +08:00 |
|
yml2213
|
e56a5ea469
|
refactor(time): 不再全局改写 time.Local,业务时间统一走显式时区
main.go 原本在启动时执行 time.Local = timeutil.Location(),靠隐式改写进程全局
状态把时间钉在 +08:00。副作用是任何跑在这行之前的代码都处于另一个时区,且依赖
关系完全不可见。
- 移除该全局赋值,业务时间全部走 timeutil 的显式时区
- rock_snapshot.parseRockTime 是唯一真实依赖,且是会出事的那一处:上游返回不带
偏移的北京时间墙面时间,用 time.Local 解析会在 TZ≠+08:00 时整体偏移 8 小时,
把「本次新绑定」误判为「历史残留」而放回库存,直接造成重复发货。
改为 timeutil.Location() 并补回归测试
- 有一点无法绕开:pgx 会把 timestamptz 解码到 time.Local,所以接口 JSON 的时间
偏移仍由进程时区决定。新增 timeutil.LocalZoneNotice(),启动时把不一致显式告警,
交由运维用 TZ=Asia/Shanghai 声明(Docker 部署已内置),而不是靠代码偷偷改全局
- 测试时间基线改用业务时区,避免随宿主机 TZ 漂移
验证:全量测试在默认时区、TZ=UTC、TZ=America/New_York 三种环境下均通过;
实测 TZ=UTC 启动打印时区提示,业务时区下静默。
|
2026-10-06 19:58:34 +08:00 |
|
yml2213
|
a47b61a98d
|
refactor(sign): 抽取公共签名原语 signutil,三套签名串格式保持不变
商户侧 /api/client/v1、源头侧 /api/open/v1 与乐玩开放平台各有一套签名实现,
其中语义完全一致的部分重复了多份,任一处修复都容易漏改另外两处。
- 新增 internal/pkg/signutil,只收敛四类一致性原语:HMAC-SHA256→hex、
body SHA256 摘要、时间戳偏差校验、常数时间比较
- 中间件与 lewan 改为调用该包,删除 middleware 里重复的 hmacSHA256Hex 与 abs64
- 刻意不统一「签名串构造」:三者拼接方式是对外契约且互不相同
(商户:字典序 & + body 摘要;源头:字典序 & + body 原文;乐玩:换行 6 行),
强行合并会直接改变握手结果
- 保留各处原有细节语义:商户侧十六进制签名大小写不敏感、乐玩签名原样比较、
VerifyWebhook 在 allowedSkew<=0 时仍要求时间戳可解析
验证:三套方案既有端到端测试全部通过(含乐玩官方测试向量、大写签名、重放拒绝);
新增 signutil 已知向量与偏差/比较边界测试,以及 VerifyWebhook 边界语义测试。
|
2026-10-06 19:53:55 +08:00 |
|
yml2213
|
5ed36c724f
|
refactor(fulfillment): 按职责拆分 fulfillment.go(640 → 最大 235 行)
纯文件级移动,无行为变更,沿用既有的 fulfillment_<aspect>.go 命名约定:
- fulfillment.go 结构体、构造函数、上游钩子、CanFulfill、orderCallbackData
- fulfillment_create.go 下单类型定义、CreateManualOrder、CreateOrder
- fulfillment_testorder.go 联调测试订单
- fulfillment_update.go 履约结果更新
- fulfillment_cancel.go 取消订单(含上游联动取消)
校验:拆分前后 19 个 func/type 声明完全一致(无缺失、无多出、无重复)。
|
2026-10-06 19:50:13 +08:00 |
|
yml2213
|
7f984b0f4e
|
fix(security): 告警渠道 webhook 与 Bark Device Key 响应脱敏
AlertNotifyChannel.Config 原先以真值返回。钉钉/飞书/企微的 webhook URL 与 Bark
的 device key 本身就是凭据,泄露即可直接向对应群或设备推送消息,而列表接口对
具备 recharge:manage 的商户成员可见。
- 新增 service.MaskAlertChannel(s):在 HTTP 响应层脱敏,只保留密钥末 4 位。
webhook 保留域名与路径以便辨认是哪一台机器人(钉钉/企微的 token 在查询串,
飞书的 uuid 在路径末段),Server 属主机地址不遮蔽
- UpdateAlertChannel 识别回传的脱敏占位值并沿用库中真实密钥,使「只改名称/开关」
不会被掩码覆盖;填写新值则正常替换
- 脱敏刻意不放在 service 层:CheckLowBalanceAndNotify 复用 ListAlertChannels
的结果真正去发消息,在那一层脱敏会直接打断告警发送
- 前端表单补充说明文案
验证:新增 6 组测试,覆盖脱敏规则、三种机器人 URL 形态、脱敏结果仍能通过校验、
掩码回传不覆盖真实密钥,以及「service 层必须返回真值」这条关键边界。
|
2026-10-06 19:49:11 +08:00 |
|
yml2213
|
44ec142395
|
style: 清理 gofmt 偏差
纯对齐与行尾空行调整,无逻辑变更。gofmt -l 现输出为空,
配合 make fmt 可将格式检查直接纳入 CI。
|
2026-10-06 19:43:43 +08:00 |
|
yml2213
|
ae71bc99b8
|
refactor(handler): 按业务域拆分 merchant.go(847 → 最大 182 行)
纯文件级移动,无行为变更:
- merchant.go 结构体、构造函数与跨域共用辅助(mapKeys/pageParams)
- merchant_product.go 商品目录与分配
- merchant_order.go 订单、人工/测试下单与发货链接
- merchant_wallet.go 钱包、积分流水与管理员调账
- merchant_api_client.go API 客户端与回调订阅
- merchant_member.go 成员与角色
- merchant_platform.go 平台侧租户管理
校验:与 HEAD 的声明行 diff 为空,MerchantHandler 方法数 41 → 41。
|
2026-10-06 19:43:13 +08:00 |
|
yml2213
|
24fa6a97a0
|
refactor(delivery): 按职责拆分 delivery.go(1162 → 最大 249 行)
纯文件级移动,无行为变更:
- delivery.go 常量、DeliveryService 结构、构造与依赖注入
- delivery_types.go 对外 DTO 与 deliveryHTTPError
- delivery_provider.go 渠道取消/同步与 result_data 维护
- delivery_query.go 订单查询与发货状态构建
- delivery_bind.go 绑定与绑定结果查询
- delivery_submit.go 提交发货与提交阶段状态机
- deliveryGoodID 并入 delivery_helpers.go,链接管理并入 delivery_link.go
校验:拆分前后 55 个 func/type/const 声明完全一致(无缺失、无多出、无重复)。
|
2026-10-06 19:43:05 +08:00 |
|
yml2213
|
80e2bbf875
|
fix(rock): 上游地址改为以数据库配置为准,并消除 baseURL 数据竞争
GetConfig 从不把 rock_configs.base_url 回写到客户端,main.go 又硬编码了
https://0666.pro,导致后台改上游地址「保存那一刻生效、进程重启后失效」,
数据库里的值被静默忽略且无任何提示。
- 新增 model.RockDefaultBaseURL 统一默认值来源
- 新增 RockService.ApplyConfigToClient,启动时把 DB 地址同步到客户端
- UpdateConfig 改用 client.SetBaseURL 立即生效,不再直接写字段
- RockClient.baseURL 原为裸字段,被 HTTP 请求线程与库存巡检 goroutine 并发
读写(数据竞争),改为 sync.RWMutex 保护并新增 BaseURL/SetBaseURL
- ClaimTokens/RefreshToken/RedeemSkin 的 Origin/Referer 跟随配置地址
- 空值回落默认地址,末尾斜杠自动裁剪
为保持该提交可编译,同一次改动把 rock_service.go(1177 行)按域拆分为
8 个文件(最大 221 行):rock_service / rock_bindlink / rock_stock /
rock_assign / rock_bindcheck / rock_redeem / rock_recover / rock_snapshot。
35 个声明块全部有归属,无遗漏无重复;迁移文件 012 受 checksum 保护故未改动。
验证:TestRockServiceBaseURLFromConfig 覆盖「改地址→立即生效→重启→仍生效」;
并发用例在 -race 下通过;全量测试通过。
|
2026-10-06 19:42:58 +08:00 |
|
yml2213
|
d423fc652c
|
chore(build): 新增 make test/lint/fmt 并修复 testdb 连接串缺陷
- make test 自动拉起并等待 PostgreSQL 就绪;测试用临时 schema 隔离,不污染开发库
- 新增 make test-db / lint / fmt
- 修复 testdb.withSearchPath:原实现用 url.Values.Encode() 重编码整个查询串,
把 TimeZone=Asia/Shanghai 变成 Asia%2FShanghai,pgx 原样传给服务端后报
"unknown time zone Asia%2FShanghai",导致数据库起来后集成测试依然全挂。
改为只追加 search_path,并补测试锁定该行为。
|
2026-10-06 19:42:49 +08:00 |
|
yml2213
|
d821fe13df
|
fix(security): 分离 JWT 与数据加密密钥并新增启动安全体检
.env 中 JWT_SECRET 仍逐字节等于 .env.example 的示例值,且 DATA_ENCRYPTION_KEY
未设置、按 config.go 的回退逻辑实际等于 JWT_SECRET。任何见过仓库的人都能伪造
管理员 JWT,并解密库中全部 API Client / 回调密钥密文。
- JWT_SECRET 与 DATA_ENCRYPTION_KEY 改为各自独立的强随机值
- 新增 Config.SecurityWarnings():示例密钥 / 未分离 / release 下开调试日志均告警
- 新增 cmd/reencrypt_secrets:默认只预演,-apply 才写库;幂等,坏数据不中断整轮
- 新增 docs/密钥轮换说明.md;.gitignore 忽略 .env.bak*
- release 模式下关闭 OPEN_API_DEBUG
|
2026-10-06 19:42:42 +08:00 |
|
 yml2213andCursor
|
a2c4eb59b6
|
fix(dlc): 发货重试不再改写订单号
代练仓按原单号回查能不能发货。随机后缀查不到,正式单会失败。已有队列时应续发原单,不能换号。
Co-authored-by: Cursor <cursoragent@cursor.com>
|
2026-10-06 18:45:08 +08:00 |
|
 yml2213andCursor
|
c85b9f4173
|
feat(rock): 同一提货号过期后重取二维码
轮询绑定时向 0666 换一条新的活动链接,提货号不变。下游只展示返回的链接。
Co-authored-by: Cursor <cursoragent@cursor.com>
|
2026-10-06 18:08:27 +08:00 |
|
 yml2213andCursor
|
4b8fc76f36
|
feat(rock): 绑定错误可直接改买家 UID,提货号继续留在原订单
Co-authored-by: Cursor <cursoragent@cursor.com>
|
2026-10-06 17:47:02 +08:00 |
|
 yml2213andCursor
|
0967ecc5db
|
feat(rock): 库存列表直接显示 0666 编号和完整提取码
本地序号和上游编号不是同一个,按 0666 上的编号就能对上库存和兑换记录。
Co-authored-by: Cursor <cursoragent@cursor.com>
|
2026-10-06 11:49:47 +08:00 |
|
yml2213
|
3741f5ae73
|
feat(rock): 实现方案B智能自愈,支持买家手滑填错UID时确认为扫码角色UID自愈绑定
|
2026-10-06 11:04:44 +08:00 |
|
 yml2213andCursor
|
717392b195
|
feat(rock): 未扫码绑定的使用中链接可释放回库存
历史残留绑定不再占住提货链接,退款后可以把还没扫上的库存分给下一单。
Co-authored-by: Cursor <cursoragent@cursor.com>
|
2026-10-05 22:13:17 +08:00 |
|
 yml2213andCursor
|
4c68103217
|
feat(routing): 渠道配置页把 Rock 作为独立履约策略展示
最新的 Rock 商品之前被算进第一平台,配置里也无法单独选择 Rock 库存池。
Co-authored-by: Cursor <cursoragent@cursor.com>
|
2026-10-05 21:15:20 +08:00 |
|
 yml2213andCursor
|
8c43fb4569
|
fix(delivery): 将第一平台发货出站超时调到 30 秒
常态提交约 11 秒,15 秒上限会在上游偶发变慢时提前断开,可能把仍在处理的订单记成失败。
Co-authored-by: Cursor <cursoragent@cursor.com>
|
2026-10-05 19:57:07 +08:00 |
|
yml2213
|
4f23ae389d
|
fix(rock): 补充买家更新UID时Token期望UID同步更新,保障自建发货页重入一致性
|
2026-10-05 19:31:43 +08:00 |
|
yml2213
|
9e260059ee
|
feat(rock): 关联业务工单升级为双单号清晰展示(系统工单号 + 创建商户单号)
1. 后端批量反查商户单号:在 RockService.ListTokens 中支持批量反查关联订单创建时由调用方传入的 ClientOrderNo(商户单号),并拓展支持通过商户单号进行全局关键词模糊搜索;
2. 管理后台双单号排版升级:在 Rock 管理表格中将「关联业务工单」升级为双行呈现——第一行高亮展示内部统一系统工单号 (FO2026...),第二行辅助展示外部电商/商户原始单号 (如 test4 / 拼多多单号),两行均支持一键独立复制;
3. 单元测试全覆盖:补充商户单号自动挂载关联与按商户单号模糊检索的自动化单测,确保对单溯源精准无误。
|
2026-10-05 19:18:52 +08:00 |
|
yml2213
|
5c3fd92738
|
fix(delivery): 提货详情页自动回填 Rock 绑定的游戏角色名与区服
1. 解决提货页历史已交付订单缺失角色名的问题:在 buildDeliveryState 中新增自动回溯机制,若订单 ResultData 缺失角色名或区服,自动从关联的 rock_tokens 表提取 actual_role_name 与 actual_channel;
2. 自动修正并持久化:回填成功后自动修补至 fulfillment_orders.result_data,确保后续无需重复反查,提货页与凭据大图立即可见真实游戏昵称。
|
2026-10-05 19:03:50 +08:00 |
|
yml2213
|
bf3f3a3626
|
feat(delivery-voucher): 优化发货凭据为一键复制深海蓝高清图并补齐商品本地图片
1. 管理后台 Rock 表格优化:将原「官方发货凭证(FulfillId)」列升级为「发货结果图片」列,提供一键「复制结果图」与「高清预览」Modal,点击即可自动生成凭据大图并直接写入剪贴板(支持在微信/QQ客服聊天框中直接 Ctrl+V 粘贴图片);
2. 商品图片本地缓存与展示修复:从官方 HAR 提取黑色 ROCK 长袖 T 恤与蓝色运动服上衣高清立绘(rock_black_tshirt.webp / rock_blue_sportswear.webp),优化 productImage 自动识别与 Delivery 提货页图片自适应居中,彻底消除灰色占位块;
3. 标杆级发货凭据绘制重构:参考腾讯官方电竞风格设计,重构 640x960 视网膜双倍高清 Canvas 凭据绘制(深海蓝微光渐变背景、顶部微光加粗「兑换成功」、正圆形双层光环立绘、详细角色区服参数对齐、底部翡翠绿发光胶囊按钮),全方位超越 0666 官方粗糙原图;
4. 履约结果字段持久化:后端发货成功后同步持久化角色名、游戏大区与 UID 至 fulfillment_orders 结果报文,确保提货页区服与角色信息完整呈现。
|
2026-10-05 18:52:41 +08:00 |
|
yml2213
|
78e2fe4c6a
|
fix(delivery): 禁用Rock二次生成二维码并治理上游110001频控报错
1. 业务防乱(专属通道锁定):提货页面一旦生成二维码后,直接禁用'重新生成二维码'按钮并锁定游戏UID输入框,杜绝Token浪费与绑定混乱;
2. 频控治理(前端3秒冷却):手动点击'检查扫码状态'增加3秒倒计时防抖冷却,且对'过于频繁/110001'错误进行平滑提示,不再触发大红报错;
3. 频控治理(后端瞬时防抖与软降级):RockService增加800ms内存并发安全防抖缓存,当上游返回110001时自动优雅降级返回等待扫码状态,不抛出HTTP 400错误。
|
2026-10-05 18:25:35 +08:00 |
|
yml2213
|
08a0e74cd0
|
fix(rock): 修复空闲库存为0时误将已分配订单判定为补货中并拦截发货的严重漏洞
1. 根因修复(状态机死锁):当一笔订单分配了池中最后一个可用Token后,空闲库存降为0。原PrepareDelivery仅检查AvailableStock<=0,导致已锁定Token的订单在发货校验时被误判为'库存补充中'并硬性拦截发货;
2. 逻辑重构:PrepareDelivery增加已预占Token识别,若当前订单已持有using或bound状态的专属Token,直接豁免空闲库存校验,放行扫码与发货;
3. 协议对齐:在ClaimTokens与RefreshToken中补全Origin与Referer请求头;
4. 单元测试与方案文档:新增TestRockProvider_PrepareDelivery_ZeroStockWithAssignedToken用例,5项Rock专项单测与全量Service测试100%全绿通过,方案文档追加7.5节证据与复盘记录。
|
2026-10-05 18:19:40 +08:00 |
|
yml2213
|
83870843ed
|
fix(rock): 修复兑换发货401未鉴权错误与买家角色名提取解析
1. 根因修复(兑换发货鉴权):对比原生平台发货抓包证实 POST /api/redeem/:id 必须携带 Authorization: Bearer <token>,Origin 及 Referer 头,补齐相关请求头彻底杜绝 401 报错;
2. 根因修复(角色昵称解析):逆向解构 0666.pro 响应报文,将角色名提取从错误的 binding.role_name 切换为 token.bound_account,消除提货页角色名显示为 '-' 的问题;
3. 协议对齐(响应结构重构):将 RockRedeemResponse 与真实上游返回对齐(包含 token 与 status 结构),剔除臆想的 delivery 字段;
4. 单元测试与方案文档:更新单测覆盖鉴权与字段映射断言,在方案文档 7.4 节录入实测抓包报文镜像比对表。
|
2026-10-05 16:30:18 +08:00 |
|
yml2213
|
7e5cbaf65e
|
fix(rock): 兼容 0666.pro 接口 points 字段字符串与数值自适应解析
1. 新增 FlexibleFloat64 类型,解决上游 /api/me 响应中 points 为字符串(如 '8271.2')导致反序列化失败的问题;
2. 服务层与数据库快照存储统一调用 Float64() 保持类型严谨;
3. 单元测试补充真实上游字符串响应场景并全绿通过。
|
2026-10-05 15:42:00 +08:00 |
|
yml2213
|
611c658a8a
|
fix(merchant-products): 严格锁定商品价格与库存编辑权限,仅对平台超级管理员开放
1. 前端 ProductsTab 增加 canEditPricing={isAdmin} 显式权限透传,仅超级管理员可见【编辑】按钮,普通分销商/商户完全隐藏;
2. 后端 UpdateProduct 接口补充 middleware.GetRole(c) != model.RoleAdmin 强校验,普通分销商发起请求直接 403 阻断;
3. 保障平台商品进货成本与对外积分售价的权威性,杜绝下游分销商私自篡改价格与库存风险。
|
2026-10-05 15:14:33 +08:00 |
|
yml2213
|
0dff9d892e
|
feat(merchant-products): 开放商品编辑功能,支持超级管理员与商户修改售价积分、成本价与库存模式
1. 后端 Handler 新增 UpdateProduct 方法,并在 /api/merchant/products/:id 注册 PATCH 路由,支持修改商品显示名称、对外售价积分、成本价与库存;
2. 前端商户中心 merchantApi 扩充 updateProduct 接口对接;
3. 商品列表(ProductsTab)操作列新增【编辑】按钮与模态框,提供商品名称、对外售价(积分)、成本价(积分)、无限库存/指定限量模式及上架状态编辑功能;
4. 修复超级管理员在自营或商户商品列表中无法自由调价与调整库存的交互缺失问题。
|
2026-10-05 15:10:21 +08:00 |
|
yml2213
|
ef7f67dd0c
|
feat(fulfillment): 接入Rock发货平台(0666.pro)代理履约、通用库存池与UID强一致风控
1. 数据库新增 012_rock_fulfillment 迁移,创建 rock_configs 配置表与 rock_tokens 通用库存表,补齐黑色ROCK长袖T恤与蓝色运动服上衣商品目录;
2. 封装 RockClient 与 RockService,实现 0666.pro 平台 Bearer Token 极简连通校验、批量采购50个入库、水位监控巡检与自动补货;
3. 新增 RockProvider 实现标准履约路由,引入 Anti-Ghost 旧绑定基线比对与 UID 强一致门禁,扫错号硬阻断并记录为 mismatch 状态;
4. 针对黑色ROCK与蓝色运动服实现动态发货(绑定后发货前动态选择 skin),并提取腾讯官方发货流水号 fulfillId 对账;
5. 新增全局自动发货总开关(Kill Switch),支持一键软熔断降级转人工接单处理;
6. 前端新增 PlatformRock 管理大屏,提供总开关切换、Token配置与连通测试、库存监控、一键补货及错单解冻重置。
|
2026-10-05 14:56:11 +08:00 |
|
yml2213
|
46ec3574ae
|
fix(delivery): 治理上游 BFF 单 IP 频控限流与高频轮询雪崩问题
1. 透传分布式客户端 IP(X-Forwarded-For):signProxy 发包自动透传客户端 IP 与订单散列 IP,穿透上游 Nginx 限流层,避免生产服务器单出口 IP(124.223.12.34)被全盘限流(HTTP 429);
2. 频控限流立即避让禁止盲目重试:429 与“请求过于频繁”明确判定为不可重试错误,signProxy 立即返回,消除 8.2 秒长挂与 3 倍放大重试流量;
3. 优化轮询频次与频控冷却:accountBound 未扫码缓存 TTL 提升至 5 秒(削减 60% 轮询 QPS),遭遇频控时拉长缓存避让至 15 秒并由前端平滑等待,给上游充分恢复窗口。
|
2026-09-18 19:52:53 +08:00 |
|
yml2213
|
af0822949d
|
fix(delivery): 修复 DLC 正式下单重复提交与发货并发冲突问题
1. DLC 正式下单接口禁用传输层自动重试:/public/users/orders 属于非幂等状态变更接口,发生频控或抖动时由上层回调与状态同步接管,严禁盲目原单号重试导致上游抛出“该子订单已处理,请勿重复提交”;
2. 扩充队列防重与已有记录识别:识别上游“该订单已有发货记录/已处理”错误,重新建队时自动追加独立重试单号(_xxxx)并透传至正式下单,避免单号污染冲突;
3. 上游回调支持重试单号兼容:HandleShipNotify 在精准匹配未命中时,自动按下划线前缀匹配主订单号(FO..._xxxx -> FO...),保障重试单回调正常交付;
4. 加强提交并发锁防护:在 35 秒活跃执行窗口内对 in_progress 阶段实行严格并发互斥,避免上游 Webhook 提前推回失败状态导致后续重试穿透产生并发打架;提单失败时显式重置 provider_order_stage 释放锁。
|
2026-09-18 16:19:37 +08:00 |
|
yml2213
|
40194fa7e5
|
fix(delivery): 增加绑定缓存防频控、发货队列防重试死锁、终止无效回调重试
|
2026-09-18 15:26:09 +08:00 |
|
yml2213
|
ec76844da8
|
feat(log): 全面重构日志系统,支持日志级别、去除ANSI乱码并抑制高频轮询
|
2026-09-18 15:04:38 +08:00 |
|
yml2213
|
20bde97d7a
|
fix(delivery): add transient retry, fix queue deadlock, and gate delivery submit by scan auth
|
2026-09-18 14:49:54 +08:00 |
|
 yml2213andCursor
|
848d3da809
|
fix(delivery): 绑定失败回退 DLC,并补齐乐玩角色名展示
乐玩写接口失败时清除渠道锁定改试 DLC;免扫码/查绑/提交路径回传 role_name 与 game_channel。
Co-authored-by: Cursor <cursoragent@cursor.com>
|
2026-09-15 12:39:53 +08:00 |
|
 yml2213andCursor
|
6c41834274
|
fix(delivery): 乐玩不可用时回退 DLC,避免提交 UID 绑定失败
legacy 双渠道配置升为 priority;显式 lewan 且具备 DLC 时允许回退,缓解 LEWAN_* 未注入导致的 bind 失败。
Co-authored-by: Cursor <cursoragent@cursor.com>
|
2026-09-15 11:51:32 +08:00 |
|
 yml2213andCursor
|
6dc2375a79
|
chore(catalog): 清理 LEWAN_ 列表过滤与商品图 UUID 历史回退
商品列表不再过滤镜像 SKU;图片只按英文 SKU 解析,修正 DLC 预设文案。
Co-authored-by: Cursor <cursoragent@cursor.com>
|
2026-09-14 20:33:42 +08:00 |
|
 yml2213andCursor
|
c2d8228512
|
fix(delivery): 硬化自动发货可靠性,避免双发与无限 Webhook 重试
恢复 ship_failed 可重试 UI;DLC 断点续传 queue;乐玩未绑定禁止进 delivering;Webhook 原子 nonce 与业务拒绝回 200。
Co-authored-by: Cursor <cursoragent@cursor.com>
|
2026-09-14 20:13:29 +08:00 |
|
 yml2213andCursor
|
df1a170d44
|
refactor(catalog): 废弃 LEWAN_ 镜像,统一英文 SKU 与积分价,商品图按 SKU 缓存
对外目录只保留英文主 sku;迁移硬删镜像并校准 1元=100积分;发货页/凭证优先使用 local {sku}.webp。
Co-authored-by: Cursor <cursoragent@cursor.com>
|
2026-09-14 20:00:26 +08:00 |
|
yml2213
|
bf9614569e
|
feat: 优化发货凭证与字段兼容,隐藏内部积分展示并增强DLC角色解析
|
2026-09-14 17:37:53 +08:00 |
|
yml2213
|
5f642eb7a6
|
feat: 优化发货交付页面与凭据生成,支持一键复制结果图片及官方商品图片本地缓存
- 交付界面重构:隐藏内部订单号、流水号与发货渠道,展示聚焦于买家游戏UID、角色名与交付时间
- 发货结果凭据生成:采用 Canvas 生成高清发货存证图,优化存证说明文案与自适应排版
- 一键复制图片:支持直接将结果凭证图片写入系统剪贴板,方便客服在聊天窗口快捷粘贴
- 官方图片本地化缓存:全量下载乐玩商品官方主图并建立本地持久化路由,规避外部源站跨域及破损问题
- 修复乐玩渠道角色UID提取与履约状态幂等回填逻辑
|
2026-09-14 17:19:12 +08:00 |
|
 yml2213andCursor
|
f7f48d0feb
|
功能:接入乐玩开放平台双渠道路由,并修复渠道锁定与 Webhook 可靠性
在保持 DLC 默认零破坏的前提下,支持 priority/仅乐玩/仅 DLC 履约策略与后台 GUI 配置;同步补齐 Prepare 渠道落库、乐玩订单取消、Webhook 验签与失败重试。
Co-authored-by: Cursor <cursoragent@cursor.com>
|
2026-09-11 15:48:03 +08:00 |
|