| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- // 活动域 7 表 model(t_courses_activity / _signed / _user_discount / _user_discount_log /
- // _used_log / _request / _visit)——与 academic-model-ddl.sql「第二部分」逐列对齐。
- //
- // 业务主线(设计 §3.2,覆盖 9 个 SP):
- //
- // 活动方案(type 2 充值赠送/3 代金券/4 老带新) → 报名(signed, 状态机 0~4) → 赠送金额池(user_discount)
- // → 使用/退回流水(user_discount_log) → 老带新结算(used_log 写负值) → 优惠申请(request 审批) → 回访(visit)
- //
- // 字段注释五维口径:语义与单位 | 枚举全量取值 | 写入时机 | 主外键/关联语义 | 安全红线。
- package model
- import "time"
- // t_courses_activity.type 活动类型编码(1 试听为旧遗留,不参与 SP 逻辑)。
- const (
- ActivityTypeTrial int8 = 1 // 试听活动(旧遗留,不参与 SP 逻辑)
- ActivityTypeRecharge int8 = 2 // 充值赠送
- ActivityTypeVoucher int8 = 3 // 代金券
- ActivityTypeRecommend int8 = 4 // 老带新推荐
- )
- // t_courses_activity.status 活动状态编码(旧 COMMENT 自相矛盾,以 PHP 判断口径为准,设计 §11-5)。
- const (
- ActivityStatusDisabled int8 = 0 // 停用
- ActivityStatusEnabled int8 = 1 // 开启
- ActivityStatusEnded int8 = 2 // 已结束
- )
- // t_courses_activity_signed.status 报名状态机(0 取消报名 → 1 报名 → 2 参加活动 → 3 报课成交 / 4 过期)。
- const (
- ActivitySignedCancelled int32 = 0 // 取消报名(旧 DELETE+INSERT 幂等会清掉的行状态)
- ActivitySignedSigned int32 = 1 // 报名
- ActivitySignedAttended int32 = 2 // 参加活动(老带新结算后置为此态)
- ActivitySignedDeal int32 = 3 // 报课(成交)
- ActivitySignedExpired int32 = 4 // 过期不能使用
- )
- // t_courses_activity_request.approved 审批状态编码。
- const (
- ActivityRequestApprovedRejected int8 = -1 // 不通过
- ActivityRequestApprovedPending int8 = 0 // 未处理
- ActivityRequestApprovedPassed int8 = 1 // 通过
- )
- // t_courses_activity.toped 置顶标记编码。
- const (
- ActivityTopedNo int8 = 0 // 不置顶
- ActivityTopedYes int8 = 1 // 置顶(置顶有效至活动结束)
- )
- // CoursesActivity 活动表 t_courses_activity(充值赠送/代金券/老带新)。
- //
- // 作用域:institution_id + campus_id(campus_id=0 表示"机构所有**自营**校区",
- // 是 custom_refund/cleared_balance 的 `campus_id IN (x,0)` 判据来源,设计 §2「7.」)。
- type CoursesActivity struct {
- ID int64 `gorm:"column:id;primaryKey;autoIncrement" json:"id"` // 活动 ID(D3 自增)|枚举:无|写入:INSERT 自动|FK:被 signed/discount/used_log/request 引用|红线:报名表已落库后不得物理删除
- Type int8 `gorm:"index:idx_inst_campus_type_status,priority:3;column:type;not null;default:1" json:"type"` // 活动类型(1 试听/2 充值赠送/3 代金券/4 老带新推荐)|枚举:ActivityType*|写入:创建活动时|FK:无|红线:决定结算分支(type=3 一次全退、type=4 双边入账),运行期禁改
- Toped int8 `gorm:"column:toped;not null;default:0" json:"toped"` // 置顶(0 否/1 是,置顶有效至活动结束)|枚举:ActivityToped*|写入:后台编辑|FK:无|红线:仅展示序,不影响资金
- Thumbnail *string `gorm:"column:thumbnail;size:500" json:"thumbnail,omitempty"` // 缩略图 URL|枚举:无|写入:后台编辑|FK:无|红线:外部 URL,渲染需校验域名白名单
- SubjectID int32 `gorm:"column:subject_id;not null;default:0" json:"subjectId"` // 科目 ID(0 混合)|枚举:科目字典(跨域)|写入:创建活动时|FK:→ 教学域科目(无物理 FK)|红线:不参与金额计算
- GradeID int32 `gorm:"column:grade_id;not null;default:0" json:"gradeId"` // 年级 ID(0 混合)|枚举:年级字典(跨域)|写入:创建活动时|FK:→ 教学域年级|红线:同上
- InstitutionID int64 `gorm:"index:idx_inst_campus_type_status,priority:1;column:institution_id;not null;default:0" json:"institutionId"` // 机构 ID(原 schoolid;作用域列)|枚举:无|写入:创建活动时锁定|FK:→ t_institution|红线:scoping 强依赖,禁 0 值
- CampusID int64 `gorm:"index:idx_inst_campus_type_status,priority:2;column:campus_id;not null;default:0" json:"campusId"` // 校区 ID(原 campusid;0=机构所有自营校区;作用域列)|枚举:无|写入:创建活动时锁定|FK:→ t_campus|红线:0 的活动失效范围依赖自营判定(设计 §11-2)
- StartTime *time.Time `gorm:"index:idx_time,priority:1;column:start_time" json:"startTime,omitempty"` // 活动开始时间(datetime(3))|枚举:无|写入:创建/编辑|FK:无|红线:报名须校验时间窗(3110)
- EndTime *time.Time `gorm:"index:idx_time,priority:2;column:end_time" json:"endTime,omitempty"` // 活动结束时间(datetime(3))|枚举:无|写入:创建/编辑|FK:无|红线:须 >= start_time
- NumberMax int32 `gorm:"column:number_max;not null;default:0" json:"numberMax"` // 可报名人数(0=不限)|枚举:无|写入:创建/编辑|FK:无|红线:与 number_sign 比较须在事务内(防超卖,3141)
- NumberSign int32 `gorm:"column:number_sign;not null;default:0" json:"numberSign"` // 当前报名人数(报名+1/取消-1)|枚举:无|写入:signed_add/cancel(原子增减)|FK:无|红线:取消时下限保护(不得为负)
- Title *string `gorm:"column:title;size:500" json:"title,omitempty"` // 标题|枚举:无|写入:创建/编辑|FK:无|红线:用户输入,展示需转义
- Content *string `gorm:"column:content;type:longtext" json:"content,omitempty"` // 活动内容(HTML)|枚举:无|写入:创建/编辑|FK:无|红线:**富文本 XSS 风险**,输出须 sanitize
- Money string `gorm:"column:money;type:decimal(12,2);not null;default:0.00" json:"money"` // 金额/额度(元;充值赠送额/代金券面额/老带新奖励额)|枚举:无|写入:创建/编辑|FK:无|红线:报名时快照进 signed.activity_money,事后改活动不影响存量
- Status int8 `gorm:"index:idx_inst_campus_type_status,priority:4;column:status;not null;default:0" json:"status"` // 状态(0 停用/1 开启/2 已结束)|枚举:ActivityStatus*|写入:后台编辑/到期任务|FK:无|红线:与报名表 status 同名不同义(设计 §11-5),勿混用
- View int32 `gorm:"column:view;not null;default:0" json:"view"` // 浏览量(后台可见)|枚举:无|写入:详情页访问自增|FK:无|红线:非资金字段,可异步
- Memo *string `gorm:"column:memo;size:500" json:"memo,omitempty"` // 备注|枚举:无|写入:创建/编辑|FK:无|红线:脱敏
- CreateUserID *string `gorm:"column:create_user_id;size:26" json:"createUserId,omitempty"` // 创建人(ULID;原 create_userid)|枚举:无|写入:创建时|FK:→ t_user(逻辑)|红线:禁止旧 int id
- CreateTime time.Time `gorm:"column:create_time;not null;default:CURRENT_TIMESTAMP" json:"createTime"` // 创建时间(datetime(3))|枚举:无|写入:DB 默认|FK:无|红线:勿手改
- UpdatedAt time.Time `gorm:"column:updated_at;not null;default:CURRENT_TIMESTAMP" json:"updatedAt"` // 更新时间(datetime(3),ON UPDATE;新增列)|枚举:无|写入:DB 自动|FK:无|红线:勿手改
- }
- // TableName 指定表名。
- func (CoursesActivity) TableName() string { return "t_courses_activity" }
- // CoursesActivitySigned 活动报名/结算表 t_courses_activity_signed(UK(user_id, activity_id))。
- //
- // 幂等语义演进(设计 §1.5):旧 SP `signed_add` 用 DELETE+INSERT 保证"同一 user+activity 只留一条",
- // 目标态改为 `clause.OnConflict{DoUpdates: 覆盖 status/activity_money/recommend_user_id}` + UK 兜底。
- // institution_id/campus_id 为**冗余作用域列**(取活动上的值),便于 scoping 查询(迁移后一次性回填)。
- type CoursesActivitySigned struct {
- ID int64 `gorm:"column:id;primaryKey;autoIncrement" json:"id"` // 报名记录 ID(D3 自增)|枚举:无|写入:INSERT 自动|FK:无|红线:注销不等于删除(status=0 保留审计)
- ActivityID int64 `gorm:"uniqueIndex:uk_user_activity,priority:2;index:idx_activity_status,priority:1;column:activity_id;not null" json:"activityId"` // 活动 ID(原 activityid)|枚举:无|写入:报名时|FK:→ t_courses_activity.id|红线:UK 第 2 列,禁止改绑
- UserID string `gorm:"uniqueIndex:uk_user_activity,priority:1;index:idx_user_status,priority:1;column:user_id;size:26;not null" json:"userId"` // 报名用户(ULID;原 userid)|枚举:无|写入:报名时|FK:→ t_user(逻辑)|红线:UK 第 1 列,一活动一人一行
- InstitutionID int64 `gorm:"index:idx_inst_campus,priority:1;column:institution_id;not null;default:0" json:"institutionId"` // 机构 ID(冗余作用域列,取活动值;新增)|枚举:无|写入:报名时冗余|FK:→ t_institution|红线:不得与活动表值冲突(迁移回填后一次性冻结)
- CampusID int64 `gorm:"index:idx_inst_campus,priority:2;column:campus_id;not null;default:0" json:"campusId"` // 校区 ID(冗余作用域列,取活动 campus_id;新增)|枚举:无|写入:报名时冗余|FK:→ t_campus|红线:同上
- Status int32 `gorm:"index:idx_activity_status,priority:2;index:idx_user_status,priority:2;column:status;not null;default:0" json:"status"` // 报名状态(0 取消报名/1 报名/2 参加活动/3 报课成交/4 过期不能使用)|枚举:ActivitySigned*|写入:报名/结算/取消|FK:无|红线:状态机单向推进(2→1 仅取消路径);type=4 限一次判定按 dump 用**活动** status(§11-5)
- RechargeAmount string `gorm:"column:recharge_amount;type:decimal(12,2);not null;default:0.00" json:"rechargeAmount"` // 充值金额(元;copy_activity_discount_to_signed 回填)|枚举:无|写入:充值赠送结算/迁移重放|FK:无|红线:只读回填值,勿参与实时计算
- ActivityMoney string `gorm:"column:activity_money;type:decimal(12,2);not null;default:0.00" json:"activityMoney"` // 活动金额(元;报名时取 t_courses_activity.money 快照)|枚举:无|写入:报名时|FK:无|红线:取消报名时归零(status=0 同行清 0)
- ActivityMoneyUsed string `gorm:"column:activity_money_used;type:decimal(12,2);not null;default:0.00" json:"activityMoneyUsed"` // 已使用活动金额(元;老带新=已充值到账户)|枚举:无|写入:结算|FK:无|红线:取消报名时归零;与 used_log 累计须一致
- RecommendUserID *string `gorm:"column:recommend_user_id;size:26" json:"recommendUserId,omitempty"` // 推荐人(ULID;原 recommend_userid;0→NULL)|枚举:无|写入:报名时|FK:→ t_user(逻辑)|红线:双边入账的对手方,禁止自荐(业务校验)
- CreateUserID *string `gorm:"column:create_user_id;size:26" json:"createUserId,omitempty"` // 创建人(原 create_userid)|枚举:无|写入:报名时|FK:→ t_user(逻辑)|红线:禁止旧 int id
- CreateTime time.Time `gorm:"column:create_time;not null;default:CURRENT_TIMESTAMP" json:"createTime"` // 报名时间(datetime(3))|枚举:无|写入:DB 默认|FK:无|红线:勿手改(对账依据)
- Imgs *string `gorm:"column:imgs;size:255" json:"imgs,omitempty"` // 图片备注(JSON 字符串)|枚举:无|写入:报名时|FK:无|红线:含个人信息,输出按需裁剪
- Memo *string `gorm:"column:memo;size:500" json:"memo,omitempty"` // 备注|枚举:无|写入:报名/审核|FK:无|红线:脱敏
- RequestNo *string `gorm:"index:idx_request_no;column:request_no;size:100" json:"requestNo,omitempty"` // 申请单号(原 requestid)|枚举:无|写入:报名时|FK:弱关联 t_user_balance_request.biz_no|红线:字符串保留(非 int64 FK),勿 JOIN id
- ResponseUserID *string `gorm:"column:response_user_id;size:26" json:"responseUserId,omitempty"` // 审核人(ULID;原 response_userid;非空表示已审核通过→不可取消)|枚举:无|写入:审核动作|FK:→ t_user(逻辑)|红线:**取消报名的核心判据**(3107)
- ResponseTime *time.Time `gorm:"column:response_time" json:"responseTime,omitempty"` // 审核时间(datetime(3))|枚举:无|写入:审核动作|FK:无|红线:与 response_user_id 同事务写
- ResponseMsg *string `gorm:"column:response_msg;size:500" json:"responseMsg,omitempty"` // 审核意见|枚举:无|写入:审核动作|FK:无|红线:用户输入,展示转义
- }
- // TableName 指定表名。
- func (CoursesActivitySigned) TableName() string { return "t_courses_activity_signed" }
- // CoursesActivityUserDiscount 活动学生优惠表 t_courses_activity_user_discount(赠送金额池)。
- //
- // 语义:discount_amount = 赠送总额(**负数是减、正数是赠送**),discount_amount_used = 已使用;
- // 可用 = discount_amount − discount_amount_used(user_discount_usable 仅累加 >0 的行,设计 §3.2 #14)。
- type CoursesActivityUserDiscount struct {
- ID int64 `gorm:"column:id;primaryKey;autoIncrement" json:"id"` // 优惠账户 ID(D3 自增)|枚举:无|写入:INSERT 自动|FK:被 discount_log 引用|红线:资金池行,禁止物理删除(审计)
- ActivityID int64 `gorm:"index:idx_user_activity,priority:2;column:activity_id;not null" json:"activityId"` // 活动 ID(原 activityid)|枚举:无|写入:充值赠送入池时|FK:→ t_courses_activity.id|红线:决定赠送口径
- InstitutionID int64 `gorm:"index:idx_inst_campus_user,priority:1;column:institution_id;not null;default:0" json:"institutionId"` // 机构 ID(原 schoolid;作用域列)|枚举:无|写入:入池时锁定|FK:→ t_institution|红线:scoping 依赖,禁 0 值
- CampusID int64 `gorm:"index:idx_inst_campus_user,priority:2;column:campus_id;not null;default:0" json:"campusId"` // 校区 ID(原 campusid;0=机构所有自营校区)|枚举:无|写入:入池时锁定|FK:→ t_campus|红线:usable 汇总按此过滤
- UserID string `gorm:"index:idx_user_activity,priority:1;index:idx_inst_campus_user,priority:3;column:user_id;size:26;not null" json:"userId"` // 学生(ULID;原 userid)|枚举:无|写入:入池时|FK:→ t_user(逻辑)|红线:池归属人,禁止跨人使用
- BalanceRequestID *int64 `gorm:"column:balance_request_id" json:"balanceRequestId,omitempty"` // 来源充值/退费工单 ID(原 balance_requestid varchar(32) → 迁移 JOIN biz_no 重映射)|枚举:无|写入:入池时|FK:→ t_user_balance_request.id|红线:NULL=历史/手工入池,不得据此反推金额
- Income string `gorm:"column:income;type:decimal(12,2);not null;default:0.00" json:"income"` // 充值金额(元;触发赠送的充值额)|枚举:无|写入:入池时|FK:无|红线:审计口径列,只写不改
- DiscountAmount string `gorm:"column:discount_amount;type:decimal(12,2);not null;default:0.00" json:"discountAmount"` // 赠送金额(元;负数=扣减/正数=赠送)|枚举:无|写入:入池时|FK:无|红线:可用额=本列−已用,禁止直接改本列做消费
- DiscountAmountUsed string `gorm:"column:discount_amount_used;type:decimal(12,2);not null;default:0.00" json:"discountAmountUsed"` // 已使用赠送金额(元;<= discount_amount)|枚举:无|写入:使用/退回(原子增减)|FK:无|红线:须与 discount_log 累计一致(对账恒等式)
- CreateTime time.Time `gorm:"column:create_time;not null;default:CURRENT_TIMESTAMP" json:"createTime"` // 创建时间(datetime(3))|枚举:无|写入:DB 默认|FK:无|红线:勿手改
- }
- // TableName 指定表名。
- func (CoursesActivityUserDiscount) TableName() string { return "t_courses_activity_user_discount" }
- // CoursesActivityUserDiscountLog 活动学生优惠使用记录表 t_courses_activity_user_discount_log(只增)。
- //
- // 迁移说明:`courses_studentid`(旧 varchar(32) UUID)→ courses_student_id(int64 FK),
- // 同时保留 courses_student_no 旧 UUID 供迁移/对账(回填完成后可停用,设计 §2「10.」)。
- type CoursesActivityUserDiscountLog struct {
- ID int64 `gorm:"column:id;primaryKey;autoIncrement" json:"id"` // 流水 ID(D3 自增)|枚举:无|写入:INSERT 自动|FK:无|红线:只增不改(审计底线)
- ActivityUserDiscountID int64 `gorm:"index:idx_discount;column:activity_user_discount_id;not null" json:"activityUserDiscountId"` // 优惠账户 ID(原 activity_user_discountid)|枚举:无|写入:使用/退回时|FK:→ t_courses_activity_user_discount.id|红线:汇总须按本列分组核对
- CoursesStudentID *int64 `gorm:"index:idx_student;column:courses_student_id" json:"coursesStudentId,omitempty"` // 报课记录 ID(原 courses_studentid UUID → t_courses_student.id;未回填前 NULL)|枚举:无|写入:使用/退回时|FK:→ t_courses_student.id|红线:NULL 期间用 courses_student_no 回溯
- CoursesStudentNo *string `gorm:"index:idx_student_no;column:courses_student_no;size:32" json:"coursesStudentNo,omitempty"` // 报课记录旧单号(迁移期保留旧 UUID)|枚举:无|写入:迁移搬入|FK:弱关联 t_courses_student.biz_no|红线:回填完成后停用,禁止新写入
- DiscountAmountUsed string `gorm:"column:discount_amount_used;type:decimal(12,2);not null;default:0.00" json:"discountAmountUsed"` // 变动金额(元;负=消费/正=退回)|枚举:无|写入:使用/退回时|FK:无|红线:符号方向固定,退回按 ABS 等额回冲
- CreateTime time.Time `gorm:"column:create_time;not null;default:CURRENT_TIMESTAMP" json:"createTime"` // 使用时间(datetime(3))|枚举:无|写入:DB 默认|FK:无|红线:同秒多行用 id 排序(退回游标 DESC)
- Memo *string `gorm:"column:memo;size:500" json:"memo,omitempty"` // 备注(默认文案"使用充值赠送金额")|枚举:无|写入:使用/退回时|FK:无|红线:脱敏
- }
- // TableName 指定表名。
- func (CoursesActivityUserDiscountLog) TableName() string {
- return "t_courses_activity_user_discount_log"
- }
- // CoursesActivityUsedLog 老带新活动获得/使用记录表 t_courses_activity_used_log(只增)。
- //
- // 语义:老带新结算写**负值**(activity_money_used = −金额,表示"从活动池取出并充值到账户");
- // `copy_activity_discountLog_to_usedLog` 全量重放按 discount_log 原值写入(可能为正)。
- // 撤销前置校验:老带新有本表记录 → 不可取消报名(3108,设计 §3.2 #20)。
- type CoursesActivityUsedLog struct {
- ID int64 `gorm:"column:id;primaryKey;autoIncrement" json:"id"` // 记录 ID(D3 自增)|枚举:无|写入:INSERT 自动|FK:无|红线:只增不改
- ActivityID int64 `gorm:"index:idx_activity_user,priority:1;column:activity_id;not null" json:"activityId"` // 活动 ID(原 activityid)|枚举:无|写入:结算/重放|FK:→ t_courses_activity.id|红线:撤销校验按 (activity,user) 判存在
- UserID string `gorm:"index:idx_activity_user,priority:2;index:idx_user;column:user_id;size:26;not null" json:"userId"` // 参与用户(ULID;原 userid)|枚举:无|写入:结算/重放|FK:→ t_user(逻辑)|红线:与 signed.user_id 一致
- RecommendUserID *string `gorm:"column:recommend_user_id;size:26" json:"recommendUserId,omitempty"` // 推荐人(ULID;原 recommend_userid;0→NULL)|枚举:无|写入:结算|FK:→ t_user(逻辑)|红线:双边入账对手方
- OrderNo *string `gorm:"index:idx_order_no;column:order_no;size:100" json:"orderNo,omitempty"` // 订单号(原 orderid:老带新=报课信息 id;copy 重放=courses_studentid)|枚举:无|写入:结算/重放|FK:弱关联 t_courses_student.biz_no|红线:字符串保留,勿当 int64 FK
- ActivityMoneyUsed string `gorm:"column:activity_money_used;type:decimal(12,2);not null;default:0.00" json:"activityMoneyUsed"` // 活动金额变动(元;老带新结算=负值)|枚举:无|写入:结算/重放|FK:无|红线:符号方向 ★ 结算负值,重放可能正值(双跑重点比对)
- CreateTime time.Time `gorm:"column:create_time;not null;default:CURRENT_TIMESTAMP" json:"createTime"` // 创建时间(datetime(3))|枚举:无|写入:DB 默认|FK:无|红线:勿手改
- Memo *string `gorm:"column:memo;size:255" json:"memo,omitempty"` // 备注|枚举:无|写入:结算/重放|FK:无|红线:脱敏
- }
- // TableName 指定表名。
- func (CoursesActivityUsedLog) TableName() string { return "t_courses_activity_used_log" }
- // CoursesActivityRequest 活动优惠申请表 t_courses_activity_request(旧 UUID 主键 → int64 + biz_no)。
- //
- // 审批:approved −1 不通过 / 0 未处理 / 1 通过;`copy_activity_discount_to_signed` 只取
- // `approved=1 AND type=100`(设计 §3.6 #31)。
- type CoursesActivityRequest struct {
- ID int64 `gorm:"column:id;primaryKey;autoIncrement" json:"id"` // 申请 ID(D3 自增)|枚举:无|写入:INSERT 自动|FK:无|红线:对外单号是 biz_no
- BizNo string `gorm:"uniqueIndex:uk_biz_no;column:biz_no;size:32;not null" json:"bizNo"` // 业务单号(旧 UUID 原样保留;UNIQUE)|枚举:无|写入:申请时|FK:幂等/回滚锚点|红线:不可变
- ActivityID int64 `gorm:"index:idx_activity_user,priority:1;column:activity_id;not null" json:"activityId"` // 活动 ID(原 activityid)|枚举:无|写入:申请时|FK:→ t_courses_activity.id|红线:审批通过后不可改绑
- InstitutionID int64 `gorm:"index:idx_inst_campus_approved,priority:1;column:institution_id;not null;default:0" json:"institutionId"` // 适用机构 ID(原 schoolid;作用域列)|枚举:无|写入:申请时|FK:→ t_institution|红线:scoping 依赖
- CampusID int64 `gorm:"index:idx_inst_campus_approved,priority:2;column:campus_id;not null;default:0" json:"campusId"` // 适用校区 ID(原 campusid;作用域列)|枚举:无|写入:申请时|FK:→ t_campus|红线:同上
- UserID string `gorm:"index:idx_activity_user,priority:2;column:user_id;size:26;not null;default:''" json:"userId"` // 用户(ULID)|枚举:无|写入:申请时|FK:→ t_user(逻辑)|红线:与请求人可不同(代申请场景需审计)
- GiveAmount string `gorm:"column:give_amount;type:decimal(12,2);not null;default:0.00" json:"giveAmount"` // 优惠金额(元;旧 float(10,2))|枚举:无|写入:申请时|FK:无|红线:审批通过才入池,未通过不得预占
- Imgs *string `gorm:"column:imgs;type:longtext" json:"-"` // 图片备注(JSON 直存)|枚举:无|写入:申请时|FK:无|红线:**不外泄**(json:"-")
- Memo *string `gorm:"column:memo;type:longtext" json:"memo,omitempty"` // 备注|枚举:无|写入:申请/审批|FK:无|红线:用户输入,展示转义
- RequestUserID string `gorm:"column:request_user_id;size:26;not null;default:''" json:"requestUserId"` // 申请人(ULID)|枚举:无|写入:申请时|FK:→ t_user(逻辑)|红线:禁止旧 int id
- RequestTime *time.Time `gorm:"column:request_time" json:"requestTime,omitempty"` // 申请时间(datetime(3))|枚举:无|写入:提交时|FK:无|红线:只写一次
- ResponseUserID *string `gorm:"column:response_user_id;size:26" json:"responseUserId,omitempty"` // 审批人(ULID;0→NULL)|枚举:无|写入:审批动作|FK:→ t_user(逻辑)|红线:申请人不得自审(Service 校验)
- ResponseTime *time.Time `gorm:"column:response_time" json:"responseTime,omitempty"` // 审批时间(datetime(3))|枚举:无|写入:审批动作|FK:无|红线:与 approved 同事务
- ResponseMsg *string `gorm:"column:response_msg;type:longtext" json:"responseMsg,omitempty"` // 审批意见|枚举:无|写入:审批动作|FK:无|红线:用户输入,转义
- Approved int8 `gorm:"index:idx_inst_campus_approved,priority:3;column:approved;not null;default:0" json:"approved"` // 审批状态(-1 不通过/0 未处理/1 通过;原 aproved 错拼修正)|枚举:ActivityRequestApproved*|写入:审批动作|FK:无|红线:0→1 才可入池,重复审批幂等
- CreatedAt time.Time `gorm:"column:created_at;not null;default:CURRENT_TIMESTAMP" json:"createdAt"` // 创建时间(datetime(3))|枚举:无|写入:DB 默认|FK:无|红线:勿手改
- UpdatedAt time.Time `gorm:"column:updated_at;not null;default:CURRENT_TIMESTAMP" json:"updatedAt"` // 更新时间(datetime(3),ON UPDATE)|枚举:无|写入:DB 自动|FK:无|红线:勿手改
- }
- // TableName 指定表名。
- func (CoursesActivityRequest) TableName() string { return "t_courses_activity_request" }
- // CoursesActivityVisit 活动回访记录表 t_courses_activity_visit。
- //
- // 来源:旧库基本空表(AUTO_INCREMENT=1),字符集由 latin1 收敛 utf8mb4。
- type CoursesActivityVisit struct {
- ID int64 `gorm:"column:id;primaryKey;autoIncrement" json:"id"` // 回访 ID(D3 自增)|枚举:无|写入:INSERT 自动|FK:无|红线:只增不改
- ActivitySignedID *int64 `gorm:"index:idx_signed;column:activity_signed_id" json:"activitySignedId,omitempty"` // 报名记录 ID(原 activity_signedid)|枚举:无|写入:回访登记时|FK:→ t_courses_activity_signed.id|红线:NULL=历史脏数据,勿据此做业务判断
- CreateUserID *string `gorm:"column:create_user_id;size:26" json:"createUserId,omitempty"` // 回访人(ULID;原 create_userid)|枚举:无|写入:回访登记时|FK:→ t_user(逻辑)|红线:禁止旧 int id
- CreateTime time.Time `gorm:"column:create_time;not null;default:CURRENT_TIMESTAMP" json:"createTime"` // 回访时间(datetime(3))|枚举:无|写入:DB 默认/录入|FK:无|红线:勿手改
- Memo *string `gorm:"column:memo;size:500" json:"memo,omitempty"` // 回访内容|枚举:无|写入:回访登记时|FK:无|红线:含学员沟通内容,按权限裁剪输出
- }
- // TableName 指定表名。
- func (CoursesActivityVisit) TableName() string { return "t_courses_activity_visit" }
|