WIP: fix(shipping): 使用资产价值快照价格确保发货与分解价格一致 #1
Loading…
x
Reference in New Issue
Block a user
No description provided.
Delete Branch "zuncle"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
修复改价后发货价格与分解价格不一致的问题:
问题: commit b9a40df 修复了 CancelOrder()(用户/管理员主动取消)的券退回逻辑, 去掉了 `AND status = 4` 条件,但遗漏了 order_timeout.go 中超时取消的 同一逻辑,导致次数卡包(game_pass_package)订单超时取消时金额券余额丢失。 根因: game_pass_package 下单时,金额券(type=1)通过 applyCouponToGamePassOrder() 直接扣减 balance_amount 并保持 status=1(有余额)或 status=2(用完), 不会设置 status=4(预扣中)。而 cancelExpiredOrder() 的 UPDATE 语句带有 `WHERE id = ? AND status = 4` 条件,导致匹配不到行,退券静默失败。 生产已确认影响:用户9110的券1690(订单28229)和券1532(订单26743) 因此bug各丢失10元余额。 修复: - 去掉 `AND status = 4` 条件,改为 `WHERE id = ?`,兼容所有券状态 - 新增幂等校验:先查 timeout_refund 流水是否已存在,防止重复退还 - 新增兜底逻辑:order_coupons 无记录时,从 user_coupon_ledger 流水 回推预扣金额,与 CancelOrder() 的修复方案完全对齐问题: 盈亏分析(GetUserProfitLossTrend)和用户画像(GetUserProfile)中的 "商品产出"与玩家消费排行榜(DashboardPlayerSpendingLeaderboard) 计算口径不一致,导致同一用户的商品产出差异巨大。 排行榜显示用户9110商品产出¥16,913.40,盈亏分析显示¥0.00。 差异点: 1. status条件: 盈亏用 status=1(仅待发货),排行榜用 status IN (1,3) 2. 价格回退链: 盈亏缺少 price_snapshot_cents 回退层级 3. 道具卡倍率: 盈亏未计算 reward_multiplier_x1000 4. void排除: 盈亏未排除 remark 含 void 的作废项 修复: - users_profit_loss.go: 商品产出查询完全对齐排行榜公式 - users_profile.go: 库存价值查询同步对齐 - 公式: COALESCE(value_cents, snapshot_cents, price, 0) * GREATEST(COALESCE(multiplier, 1000), 1000) / 1000 - 条件: status IN (1,3) AND remark NOT LIKE '%void%'1. Revenue 口径统一为 actual_amount(真实现金到账) - 优惠券(discount_amount)和积分(points_amount)是平台免费发放的营销补贴, 不算收入,改为展示字段 - 涉及: profit_metrics.go, dashboard_spending.go, users_profit_loss.go, dashboard_user_spending.go, activity_rankings_admin.go 2. Cost 口径统一为奖品库存价值 - 删除 finance service 中的积分成本扫描(Step 3)和优惠券成本扫描(Step 4) - 之前优惠券同时算在收入和成本两侧,导致利润被人为压低 - 涉及: query_user.go, query_activity.go 3. 统一 value_cents fallback chain - finance service 改为与排行榜一致的三级回退: COALESCE(NULLIF(value_cents,0), price_snapshot_cents, products.price, 0) - 涉及: query_user.go, query_activity.go 4. 活动盈亏收入统一到 finance service - 删除 dashboard_activity.go 自有的 revenue SQL(含比例分摊逻辑) - 收入和成本统一由 finance.Service.QueryActivityProfitLoss() 提供 - 修复日志明细 profit:道具卡倍率改用 ComputePrizeCostWithMultiplier 5. finance service 新增展示字段 - ProfitLossDetail 增加 CouponDiscount, PointsDiscount, GamePassValue - 不参与 Revenue/Cost/Profit 计算,仅供前端展示营销补贴明细 6. 修复对对碰次卡订单 discount_amount 数据污染 - matching_game_app.go 次卡下单时 DiscountAmount 错误设为活动全价 - 改为 0(次卡支付不涉及优惠券) - 附带历史数据修复 migration SQL 7. 排除已分解奖品的成本重复计算 - 用户可以把奖品分解成积分再兑换新商品,导致同一份价值被计算两次 - 所有库存查询增加排除条件: status=3 且 remark 含 redeemed_points 或 batch_redeemed - 涉及 6 个文件的库存成本/资产查询 8. 排行榜详情抽屉限定活动范围 - prize 查询增加 activity_id > 0 过滤,排除积分兑换/转入/合成等非活动产出 - 使排行榜与其详情抽屉口径一致 修改文件(12个): - internal/service/finance/profit_metrics.go - internal/service/finance/query_user.go - internal/service/finance/query_activity.go - internal/service/finance/types.go - internal/api/admin/dashboard_activity.go - internal/api/admin/dashboard_spending.go - internal/api/admin/dashboard_user_spending.go - internal/api/admin/users_profit_loss.go - internal/api/admin/users_profile.go - internal/api/admin/activity_rankings_admin.go - internal/api/activity/matching_game_app.go - migrations/20260325_fix_matching_gamepass_discount.sql问题背景: - 平台审核失败,原因:小程序页面未完整浏览即要求授权登录,属于登录规范不合规 - GET /api/app/products/:id 位于认证路由组,未登录用户访问返回 401, 触发前端全局拦截器弹出"账号登录已过期"弹窗 修改内容: 1. router.go: 将 GET /products/:id 从 appAuthApiRouter(认证组) 移至 appPublicApiRouter(公开组),允许未登录用户浏览商品详情 2. product.go: 针对公开端点增加安全加固 - 增加商品 ID 参数校验(ParseInt 错误和 id<=0) - 将兜底错误信息从 validation.Error(err) 改为通用提示 "商品信息获取失败",防止原始 DB 错误泄露给未认证请求 影响范围: - 仅影响 GET /api/app/products/:id 端点 - GET /api/app/products(商品列表)仍保留在认证组 - 该 handler 不依赖 JWT session 上下文,移至公开组后功能无变化 - 返回数据仅包含商品元信息(名称、图片、价格、库存),不含用户敏感数据Checkout
From your project repository, check out a new branch and test the changes.