win
26696f4e80
x
2026-04-25 02:48:07 +08:00
45ea70760b
fix(dashboard): 修复产品动销排行时间范围筛选异常
...
修复产品动销排行接口在时间筛选上的两个问题:
1. parseRange 未处理 all,导致前端传入 all 时实际回落到默认分支,查询结果等同最近 7 天。
2. 产品动销排行原先按 activity_draw_logs.created_at 过滤时间,但销量/营收统计口径基于已支付订单,导致不同时间范围下结果失真,自定义区间与全部区间表现异常。
本次调整内容:
- 为 parseRange 增加 all 分支,返回从较早时间到当前时间的全量区间。
- OperationsProductPerformance 接口改为接收 start/end 参数,支持前端自定义时间范围透传。
- 将产品动销排行的时间过滤从 activity_draw_logs.created_at 改为 COALESCE(orders.paid_at, orders.created_at),并显式限定 orders.status = 2,使筛选口径与销量/营收统计保持一致。
修复后,全部、7天、30天和自定义时间范围将按支付时间维度返回更符合业务语义的产品动销排行结果。
2026-04-25 01:52:19 +08:00
e6e4214df4
fix(dashboard): 按有效抽奖口径修正产品动销排行
...
本次仅调整产品动销排行接口的后端统计逻辑,不改动活动盈亏分析页面与接口。
详细说明:
- 将销量从 activity_draw_logs 总条数改为有效抽奖次数,仅统计 orders.status = 2 的抽奖记录,避免把退款、取消等无效抽奖一并计入。
- 将营收统一改为“有效抽奖次数 × 活动单抽价格(price_draw)”,不再使用总日志数乘单价,确保产品动销排行内部次数与营收口径一致。
- 将成本从 price_snapshot_cents / products.price 的近似标价口径改为 products.cost_price 成本价口径,并继续保留 drop_quantity 与倍数卡 multiplier 的影响,避免利润长期被标价成本压低。
- 将盈亏与利润率统一为 Revenue - Cost 与 Profit / Revenue,使产品动销排行内部的销量、营收、成本、盈亏逻辑自洽。
- 将贡献率从按次数占比调整为按营收占比,更符合“营收贡献率”的业务含义。
本次未处理内容:
- 不修改活动盈亏分析的现有统计口径。
- 不修改前端卡片结构与活动盈亏分析页面。
已核对的业务结论:
- 活动 103 的产品动销排行 4696 次是最近 30 天有效抽奖次数;活动盈亏分析 5960 次是全量历史有效抽奖次数,两边差异来自时间范围而非当前产品动销排行次数公式。
2026-04-24 21:35:36 +08:00
win
400cd68d00
feat(game): 优化扫雷排行榜查询逻辑
2026-04-21 12:51:20 +08:00
471e21a68b
fix(activity): 修复复制活动时奖励快照时间写入异常
...
本次提交修复了管理端复制活动接口在复制奖励配置时写入零时间导致的 MySQL datetime 报错,并补齐了活动奖励复制过程遗漏的快照与业务字段,避免新活动复制后出现配置丢失或插入失败。
- 复制逻辑:在 CopyActivity 中完整复制 price_snapshot_cents、cost_snapshot_cents、price_snapshot_at、min_score、drop_quantity 等奖励字段
- 异常兜底:当历史奖励快照时间为空或为零值时,复制时自动回填为当前时间;当价格/成本快照缺失且存在商品 ID 时,回退读取当前商品价格与成本价
- 兼容历史数据:确保旧奖励配置即使未完整回填快照字段,也能被安全复制,不再因 0000-00-00 时间值触发插入失败
- 测试覆盖:补充活动复制场景测试,验证快照字段原样复制、缺失快照自动补齐,以及 min_score/drop_quantity 等字段不会在复制时丢失
2026-04-21 03:08:21 +08:00
0a397adf41
feat: 支持批量合成并收口不包邮运费规则
...
本次提交同时完成碎片批量合成与盒柜发货运费规则改造,减少用户重复操作,并确保不包邮商品在任何件数下都必须支付运费。
- 合成功能:新增批量合成接口与前端一键合成入口,按配方可合成上限批量消耗碎片并生成对应资产,同时补充批量合成测试
- 运费规则:后端新增统一运费判定逻辑,命中 category_id 14/15 的商品时整单强制收取运费,否则继续沿用少于 5 件收运费的旧规则
- 发货流程:新增运费检查接口,前端发货前先向后端确认是否需要支付运费,并根据“件数不足”或“包含不包邮商品”展示不同提示文案
- 接口校验:运费预下单与批量申请发货统一复用后端判定逻辑,避免前端规则被绕过
2026-04-21 02:06:56 +08:00
win
a96b1543f0
排行榜 扫雷
2026-04-20 15:53:31 +08:00
0e202fabd8
fix(dashboard): 统一玩家盈亏分析产出口径
...
将玩家盈亏趋势中的商品产出从当前资产快照估值,
调整为按用户、订单、抽奖日志链路聚合的商品成本口径。
这样可使商品产出与消费看板中的活动产出统计保持一致,
避免同一用户在两个面板中看到不同的商品产出口径。
同时保留积分、道具卡、优惠券三项当前分项展示,
避免接口结构调整后页面字段缺失或被误显示为 0。
2026-04-18 01:15:11 +08:00
1cf57657ca
feat(shipping): 发货列表返回收货地址信息
...
为用户发货分组接口补充 address 字段,在按批次聚合发货记录时一并收集 address_id,批量查询 user_addresses 并回填到 shipment 返回结果。
这样小程序发货列表卡片可以直接展示本次申请发货所选的联系人、手机号和详细地址,避免前端额外发起地址查询或依赖本地拼装。
2026-04-17 20:42:46 +08:00
5dc9f034c8
fix(dashboard): 修正活动奖品分析成本口径
...
活动奖品分析接口统一使用 products.cost_price 计算 prizeValue、cost 和 totalCost,避免误用售价导致成本统计偏差。
2026-04-14 23:07:32 +08:00
25dacc066a
fix(dashboard): 按订单链路修正用户消费成本统计
...
将玩家消费排行榜和用户消费详情中的产出成本口径从 user_inventory 快照值改为订单抽奖链路成本。
排行榜按 user_id + 活动分类聚合,详情按 user_id + activity_id 聚合,成本统一基于已支付订单对应的 draw log、奖励配置、商品成本价、掉落数量和翻倍道具卡补量规则计算,使列表、详情与活动盈亏页的业务口径保持一致。
2026-04-13 19:23:13 +08:00
c927f46cdd
fix(livestream): 统一直播间盈亏成本口径并消除转赠影响
...
将直播间统计从基于 user_inventory 当前持有状态和 remark 反推成本,改为基于 livestream_draw_logs 中奖事实直接关联 products.cost_price 计算成本。统一 /livestream/activities/:id/stats 与 /livestream/activities/:id/draw_logs 两个接口的营收、退款、成本和净利润口径,避免因转赠、remark 覆盖或订单行缺失导致统计失真,并补充针对转赠、退款、零订单和 product 回退场景的回归测试。
2026-04-12 21:23:36 +08:00
fb4b266bac
fix(channel): 统一渠道分析时间筛选范围
...
让渠道分析弹窗的概览卡片和趋势图共用同一时间筛选范围,
并将默认行为调整为历史全量展示。前端改为在未选择日期时
不再回退最近 12 天,后端新增统一时间窗口解析逻辑,使
overview 与 daily 在全量、指定区间和 days 模式下保持一致。
2026-04-09 17:51:42 +08:00
03214dddf2
fix(channel): align channel cost with draw-source attribution
...
Replace channel cost aggregation with draw-source based cost calculation
that follows activity profit-loss logic and keeps cost attribution on the
original ordering user's channel. Update channel stats tests to cover the
new cost path and related schema fields.
2026-04-09 17:04:30 +08:00
c7a6e1e017
fix(dashboard): 修正销售抽奖趋势自定义日期统计
...
修复 sales_draw_trend 自定义日期按 UTC 解析导致的统计偏差,并统一使用半开区间处理日维度边界,补充上海时区与单日范围回归测试。
2026-04-04 00:06:17 +08:00
6284966d3c
fix(dashboard): add paid amount to sales trend
2026-04-03 18:03:29 +08:00
25d32831ea
fix(livestream): 放宽待处理订单状态筛选
...
直播间 pending-orders 接口改为同时展示状态 2 和状态 3 且未发满奖励的订单,避免因为抖店同步把订单刷成已发货后页面看不到待处理订单。
2026-04-03 16:36:18 +08:00
38edc9f324
fix(user): align profile inventory stats with held assets
...
Count only status=1 inventory in the admin user profile so the profile inventory metrics match the held-assets inventory list semantics.
2026-04-02 23:35:18 +08:00
dd1034dda8
fix(finance): correct activity profit-loss cost aggregation
...
Use handler-specific activity profit/loss rules for the dashboard endpoints, counting cash, coupons, and game pass value against product cost_price. Fix missing extra reward cost aggregation and align activity logs with the same profit calculation semantics.
2026-04-02 22:27:45 +08:00
4353b0f053
fix(shipping): 反转运费规则为不满5件收运费,满5件包邮
...
- 运费预下单接口:< 5 件允许创建运费订单,>= 5 件拒绝
- 批量发货接口:< 5 件时强制校验已支付运费订单
- 单件发货接口:同样强制校验已支付运费订单
- 运费订单 remark 存入 inventory_ids JSON 用于关联
2026-03-31 21:08:33 +08:00
53e5d81fa8
fix(auth): 商品详情接口移至公开路由,修复未登录浏览触发登录弹窗
...
问题背景:
- 平台审核失败,原因:小程序页面未完整浏览即要求授权登录,属于登录规范不合规
- 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 上下文,移至公开组后功能无变化
- 返回数据仅包含商品元信息(名称、图片、价格、库存),不含用户敏感数据
2026-03-26 14:35:25 +08:00
58fd926b46
fix(finance): 统一收益统计口径,修复多处数据计算错误
...
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
2026-03-26 00:01:17 +08:00
be245c1476
feat(rewards): API 返回奖品参考价字段 price_snapshot_cents
...
rewards 接口的 rewardItem 新增 price_snapshot_cents 字段,
将数据库中的商品价格快照(分)暴露给前端用于展示参考价。
2026-03-25 22:01:28 +08:00
89be01f8e3
fix: 将商城和分类接口移至公开路由,支持未登录浏览
...
将 /store/items 和 /product_categories 从 appAuthApiRouter
移至 appPublicApiRouter,配合小程序端解决微信审核问题。
2026-03-24 17:11:05 +08:00
46b9555823
feat(fragment): 商品成本价 + 活动奖品单次产出数量
...
- products 表新增 cost_price 字段(成本价/分)
- activity_reward_settings 新增 drop_quantity(单次产出数量,默认1)
和 cost_snapshot_cents(成本价快照)
- 奖品创建/修改时自动快照成本价,drop_quantity 限制 1-100
- 抽奖发放逻辑按 drop_quantity 循环创建多个库存项
- 抽奖结果接口按 drop_quantity 返回多条 item,前端自动合并显示
- 抽奖记录接口返回 drop_quantity 字段
- 商品管理 API 全链路支持 cost_price
2026-03-23 22:26:06 +08:00
win
1f8f3f7fad
x
2026-03-21 19:00:28 +08:00
win
2a7b731484
feat(finance): implement Phase 1 core P&L service + wire into dashboard
...
- Add internal/service/finance/types.go: AssetType enum, param/result structs
- Add internal/service/finance/service.go: Service interface, read-only ctor
- Add internal/service/finance/query_user.go: QueryUserProfitLoss (4 fan-out scans)
- Add internal/service/finance/query_activity.go: QueryActivityProfitLoss (4 fan-out scans)
- Add internal/service/finance/service_test.go: 22 integration tests (all pass)
- Wire finance.Service into admin handler (admin.go)
- Replace dashboard_activity cost scan with finance.Service call (D-09: value_cents single source of truth)
- Revenue/gamepass/draw-count scans unchanged; response schema fully compatible
Co-Authored-By: claude-flow <ruv@ruv.net>
2026-03-21 18:38:33 +08:00
win
b99bcbd06f
docs(01-core-pnl-functions): create phase 1 plans
...
4 plans across 3 waves:
- 01-01 (wave 1): package scaffold — types.go, service.go, service_test.go
- 01-02 (wave 2): QueryUserProfitLoss — query_user.go + user integration tests
- 01-03 (wave 2, parallel): QueryActivityProfitLoss — query_activity.go + activity tests
- 01-04 (wave 3): phase verification — static checks + full test suite gate
Covers all 20 Phase 1 requirements: PNL-01..08, DIM-01..04, RET-01/03,
AST-01, QUA-01..05.
2026-03-21 17:27:58 +08:00
win
e78bbaaf76
docs(phase-1): add research and validation strategy
2026-03-21 17:17:56 +08:00
win
e0097f50c8
docs: gather phase 1 context
2026-03-21 17:09:14 +08:00
win
e3b0ab7cca
docs: create roadmap (2 phases)
2026-03-21 16:37:24 +08:00
win
4f3b9b8fa7
docs: define v1 requirements
2026-03-21 16:31:35 +08:00
win
9e3d893938
docs: complete project research
2026-03-21 16:28:48 +08:00
win
fd2c9e242e
chore: add project config
2026-03-21 16:19:29 +08:00
win
485798d551
docs: initialize project
2026-03-21 16:17:37 +08:00
win
5ede909be4
docs: map existing codebase
2026-03-21 16:01:32 +08:00
5b34972ee3
fix(dashboard): 盈亏分析CAST修复+视角改为平台视角(A-B)
...
1. CAST修复:
MySQL的 / 运算符返回DECIMAL类型,GORM无法将DECIMAL扫描进int64,
导致商品产出静默返回0。添加 CAST(... AS SIGNED) 与排行榜对齐。
2. 视角统一:
盈亏分析原为用户视角(B-A),排行榜为平台视角(A-B),同一用户
一个显示+¥12,130(用户赚了),一个显示-¥12,127(平台亏了),
造成管理员困惑。
修改:
- 净盈亏: Value-Cost → Cost-Value (A-B,平台盈利为正)
- 盈亏比: Value/Cost → Cost/Value (A/B,>1表示平台盈利)
- 趋势图每个数据点同步调整
2026-03-20 21:18:02 +08:00
fe3141e2b5
fix(dashboard): 盈亏分析商品产出对齐排行榜计算口径
...
问题:
盈亏分析(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%'
2026-03-20 21:02:21 +08:00
ddd66bf4e9
fix(dashboard): 修复盈亏分析商品产出只统计待发货库存的bug
...
问题:
盈亏分析(GetUserProfitLossTrend)和用户画像(GetUserProfile)中的
"商品产出"查询条件为 `ui.status = 1`,只统计了待发货/库存中的商品,
已发货/已兑换(status=3)的商品被完全排除。
示例:用户9110实际累计获得874件商品(价值¥16,279.40),但因为大部分
已发货(status=3),盈亏分析只显示商品产出¥12.50,全资产产出严重偏低。
而 dashboard_user_spending.go 中的同类查询正确使用了
`status IN (1, 3)`,说明此处是遗漏。
修复:
- users_profit_loss.go: 当前资产快照查询改为 `status IN (1, 3)`
- users_profile.go: 库存统计查询改为 `status IN (1, 3)`
- 与 dashboard_user_spending.go 的计算口径对齐
2026-03-20 20:39:50 +08:00
535106f158
fix(coupon): 修复订单超时取消时金额券未退还的bug
...
问题:
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() 的修复方案完全对齐
2026-03-20 20:32:30 +08:00
9cb4aaa511
fix(admin): 修复订单列表source_type=4/5显示未知的问题
...
- source_type=4: 区分购买次卡/次卡抽奖/一番赏
- source_type=5: 区分运费订单/直播间抽奖
2026-03-20 17:45:19 +08:00
win
a671fc14c6
运费
2026-03-20 00:57:17 +08:00
win
eaf4af4ba4
Merge remote-tracking branch 'origin/zuncle'
2026-03-19 22:37:56 +08:00
47c36b43cd
feat(fragment): add synthesis flow and fragment restrictions with tests
2026-03-19 16:26:36 +08:00
4ffd8e8326
fix: 修复过期优惠券仍可兑换/使用的漏洞
...
- store.go: 积分商城优惠券列表加 valid_end > now 过滤
- coupons_list.go: 修复 NULL valid_end 被错误排除,无截止日期券正确显示为有效
- activity_order_service.go: 过期/不可用券下单返回明确错误,不再静默跳过
- points_redeem_coupon_app.go: 积分兑换前校验模板 valid_end
- coupon_add.go: 发券前校验模板 valid_end,过期拒绝发放
2026-03-18 21:58:25 +08:00
9f7a7d29fb
fix(admin): 管理端取消订单改为调用 userSvc.CancelOrder,补充优惠券和积分退还逻辑
2026-03-18 21:12:46 +08:00
0722e515c4
feat(shipping): 新增管理端撤销发货功能
...
- 新增 AdminCancelShipping handler,支持批量撤销待发货记录(status=1→5)
- 事务内同步恢复 user_inventory.status=1 并清空 shipping_no
- 在 remark 记录操作人 adminID,保证审计可追溯
- 注册路由 POST /api/admin/shipping/orders/cancel
2026-03-18 20:11:37 +08:00
b9a40df5c5
fix(coupon): 修复订单取消时金额券未退还的bug
...
订单取消退券逻辑依赖 used_order_id 匹配,但金额券在下单时
不设置 used_order_id(仅在支付确认后设置),导致未支付订单
取消时 WHERE 条件匹配不到行,退券静默失败。
修复:去掉 used_order_id 条件,按券 ID 直接退还,增加幂等
校验和错误处理,兜底从流水回推预扣金额。
2026-03-17 21:15:33 +08:00
d1ee319f0e
feat(dashboard): 平台有效资产增加优惠券和次卡价值统计
...
- 新增优惠券总价值统计(关联system_coupons表)
- 新增次卡总价值统计(关联activities表price_draw)
- 使用Raw SQL执行复杂JOIN查询
2026-03-17 19:17:56 +08:00
win
8d8f660e34
Merge remote-tracking branch 'origin/zuncle'
2026-03-17 18:36:24 +08:00