|
@@ -842,26 +842,35 @@ func (s *CourseService) ListScheduleRows(ctx context.Context, q ScheduleQuery) (
|
|
|
// 端点 51:结课响应装配(只读,不进结账事务)
|
|
// 端点 51:结课响应装配(只读,不进结账事务)
|
|
|
// ---------------------------------------------------------------------------
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
-// DivideGrantRow 单条分账入账明细(端点 51 的 `divide[]`)。
|
|
|
|
|
|
|
+// DivideGrantRow 单条分账入账明细(端点 51 的 `divide[]`)——**team-lead 裁决后的最终形状**
|
|
|
|
|
+// `[{userId, type, amount}]`。
|
|
|
//
|
|
//
|
|
|
-// 字段来源:
|
|
|
|
|
|
|
+// 字段来源(**逐字段列溯源**,契约 §3.4 ③):
|
|
|
|
|
+//
|
|
|
|
|
+// UserID ← t_user_divide_into_log.user_id(这笔上课的钱分给了谁)
|
|
|
|
|
+// Type ← t_user_divide_into_log.type(分成类型 1 一次付清 / 2 按课次)
|
|
|
|
|
+// Amount ← t_user_divide_into_log.money(本次入账金额)
|
|
|
|
|
+//
|
|
|
|
|
+// ⚠ **契约原 mock 的 `level` 与 `quota` 均不下发(团队裁决,2026-11-09)**:
|
|
|
|
|
+//
|
|
|
|
|
+// `level` —— `t_user_divide_into_log` **没有层级列**;`t_user_divide_into.layer` 是**当前**层级,
|
|
|
|
|
+// 不是"入账当时"的层级,拿当前值顶替历史值 = 「事后调整树结构 ⇒ 历史记录显示错」,
|
|
|
|
|
+// 属静默错,比字段缺失更难查。
|
|
|
|
|
+// `quota` —— 同上:节点 quota 事后可被 `update_quota` 改,日志里没留"当时额度";
|
|
|
|
|
+// 用当前值顶替即是伪造历史。
|
|
|
//
|
|
//
|
|
|
-// UserID ← t_user_divide_into_log.user_id(获得分成的用户)
|
|
|
|
|
-// Quota ← t_user_divide_into_log.money(入账金额;**该值就是入账当时的节点 quota**,
|
|
|
|
|
-// 见 model.UserDivideIntoLog.Money 注释"写入:上行分成时取节点 quota")
|
|
|
|
|
-// Amount ← t_user_divide_into_log.money(同上)
|
|
|
|
|
|
|
+// 为什么**不是**把整个数组删掉:它承载"这笔钱分给了谁、各多少"这个核心信息;
|
|
|
|
|
+// `level`/`quota` 只是附加维度,缺了不影响主信息。因此改为**补 `type`(有列)**、删两个无列字段。
|
|
|
|
|
+// 若产品确需"当时层级/当时额度":需在日志表加列并回填 = 迁移变更,另立需求(本批不做)。
|
|
|
//
|
|
//
|
|
|
-// ⚠ **契约的 `divide[].level` 不下发**:`t_user_divide_into_log` **没有层级列**
|
|
|
|
|
-// (只有 `type` = 分成类型 1 一次付清 / 2 按课次);层级 `t_user_divide_into.layer` 是**当前值**,
|
|
|
|
|
-// 不是"入账当时"的值,用它顶替会出现"历史明细显示今天的层级"(时间维度错位,比字段恒空更难查)。
|
|
|
|
|
-// 按契约 §3.4 ③「找不到列的一律不写」⇒ 删除该字段,并补 `userId` 以免数组元素无法区分。
|
|
|
|
|
-// 已登记偏差,待契约升版。
|
|
|
|
|
|
|
+// ⚠ 反模式提醒(团队明确禁止):为了让前端 mock 好看而给 `level` 填常量 1。
|
|
|
|
|
+// "字段有值、永远等于 1、没人能发现它是假的"是本类缺陷里最难查的一种。
|
|
|
type DivideGrantRow struct {
|
|
type DivideGrantRow struct {
|
|
|
- // UserID 获得分成的用户(ULID)。
|
|
|
|
|
|
|
+ // UserID 获得分成的用户(ULID,源列 `user_id`)。
|
|
|
UserID string
|
|
UserID string
|
|
|
- // Quota 本次分成额度(= 入账金额)。
|
|
|
|
|
- Quota money.Amount
|
|
|
|
|
- // Amount 本次入账金额。
|
|
|
|
|
|
|
+ // Type 分成类型(源列 `type`:1 一次付清 / 2 按课次)。
|
|
|
|
|
+ Type int32
|
|
|
|
|
+ // Amount 本次入账金额(源列 `money`)。
|
|
|
Amount money.Amount
|
|
Amount money.Amount
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -975,7 +984,7 @@ func (s *RecordViewService) FinishView(ctx context.Context, res *FinishRecordRes
|
|
|
}
|
|
}
|
|
|
view.Divide = append(view.Divide, DivideGrantRow{
|
|
view.Divide = append(view.Divide, DivideGrantRow{
|
|
|
UserID: logs[j].UserID,
|
|
UserID: logs[j].UserID,
|
|
|
- Quota: amount,
|
|
|
|
|
|
|
+ Type: int32(logs[j].Type),
|
|
|
Amount: amount,
|
|
Amount: amount,
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|