|
@@ -0,0 +1,958 @@
|
|
|
|
|
+-- ============================================================================
|
|
|
|
|
+-- 目标态 academic(教务)域 数据模型 DDL(v0.1 Proposed)
|
|
|
|
|
+-- 产出:P1-06 教务域 Go 重写 · 阶段 2 架构设计(2026-11-09)
|
|
|
|
|
+-- 配套:03-migration/academic-domain-design.md(§2 映射总表 / §3 SP 映射 / §11 待明确)
|
|
|
|
|
+--
|
|
|
|
|
+-- 定位:academic 域**目标态运行态**表结构 —— 新 Go 后端(internal/academic)直接读写的表。
|
|
|
|
|
+-- 与既有 DDL 的分工(三套并存,不可混用):
|
|
|
|
|
+-- · 02-data-model/core-model-ddl.sql 机构/身份/org/审计 13 表(已落地,本文件不重复)
|
|
|
|
|
+-- · 02-data-model/unified-identity-ddl.sql 迁移源"清洗视图"(int 自增,仅迁移工具读取)
|
|
|
|
|
+-- · 本文件 academic-model-ddl.sql academic 目标态 27 表(本文件)
|
|
|
|
|
+--
|
|
|
|
|
+-- 设计依据:
|
|
|
|
|
+-- · 03-migration/stage0/finance-sp-behavior-spec.md(31 SP 行为规格)
|
|
|
|
|
+-- · 02-data-model/backend-model-field-spec.md §4(财务表字段方向 + 收敛规则)
|
|
|
|
|
+-- · 03-migration/stage0/schema-reconciliation-report.md(P0-11 双侧字段级对比)
|
|
|
|
|
+-- · 01-architecture/backend-technical-architecture.md §3(命名/类型/作用域/指针化)
|
|
|
|
|
+-- · 旧库实表结构:yuansiwei_finance.sql(44 表 dump,只取本域 27 表)
|
|
|
|
|
+--
|
|
|
|
|
+-- 统一约定(对齐 core-model-ddl.sql):
|
|
|
|
|
+-- · 字符集 utf8mb4 / COLLATE utf8mb4_general_ci;ENGINE=InnoDB;ROW_FORMAT=Dynamic
|
|
|
|
|
+-- · **不建物理外键**(应用层 Repository 强制作用域 + Service 事务保证),仅保留索引
|
|
|
|
|
+-- · 时间列 datetime(3)(毫秒);业务时间列沿用旧列名(create_time / start_time ...)
|
|
|
|
|
+-- · 金额列 **decimal(12,2)**(旧 float(10,2/3) / double(10,3) / decimal(10,3) 全收敛,P0-11 规则 2)
|
|
|
|
|
+-- · 列名 snake_case(旧 userid→user_id / schoolid→institution_id / campusid→campus_id /
|
|
|
|
|
+-- create_userid→create_user_id / logid→log_id / activityid→activity_id / ...
|
|
|
|
|
+-- 唯一例外:**表名保持 t_xxx 原样**,不做 t_→t_academic_ 前缀,降低迁移与对账成本)
|
|
|
|
|
+-- · 拼写修正:frosen→frozen、aproved→approved(本文件不涉 frosen,t_user_money_summary* 未纳入)
|
|
|
|
|
+--
|
|
|
|
|
+-- 主键铁律(D1/D2/D3,2026-11-06 拍板):
|
|
|
|
|
+-- · 引用人列 = canonical_user_id VARCHAR(26)(ULID)—— 本域所有 user_id / student_id /
|
|
|
|
|
+-- teacher_id / recommend_user_id / create_user_id / request_user_id / response_user_id
|
|
|
|
|
+-- · 机构/校区列 = institution_id / campus_id BIGINT(int64)
|
|
|
|
|
+-- · 业务明细/日志/关系表主键 = BIGINT AUTO_INCREMENT(int64,D3)
|
|
|
|
|
+-- · 纯汇总/自然键表(t_user_expense / t_user_divide_into)= 自然键(user_id)作主键
|
|
|
|
|
+--
|
|
|
|
|
+-- 旧 UUID 主键的处置(**关键迁移决策**,详见设计 §2.2):
|
|
|
|
|
+-- 旧库 7 张表主键为 varchar(32) UUID(t_order_pay / t_payment_log / t_user_balance_request /
|
|
|
|
|
+-- t_expenditure_log / t_courses_student / t_courses_record / t_courses_record_student)。
|
|
|
|
|
+-- 目标态一律 int64 自增主键 + **biz_no varchar(32) UNIQUE 保留旧 UUID**:
|
|
|
|
|
+-- - 迁移幂等(重跑按 biz_no 去重)
|
|
|
|
|
+-- - 旧表间引用列(t_courses_activity_signed.requestid、user_discount.balance_requestid、
|
|
|
|
|
+-- courses_student. activityid 逗号串 …)由迁移脚本 JOIN biz_no 重映射为 int64 外键
|
|
|
|
|
+-- - 割接期双写/回滚可反查
|
|
|
|
|
+--
|
|
|
|
|
+-- 执行顺序:第一部分 → 第五部分(无物理外键,顺序不强制;按资金→活动→分账→课程→课酬排列便于阅读)
|
|
|
|
|
+-- 建表:DDL 先行纪律 + main.go AutoMigrate 守卫(model.AllTables());本文件为结构权威,
|
|
|
|
|
+-- AutoMigrate 只补不删(列变更须同步本文件 + models.go + backend-model-field-spec.md 三处)
|
|
|
|
|
+-- ============================================================================
|
|
|
|
|
+
|
|
|
|
|
+SET NAMES utf8mb4;
|
|
|
|
|
+SET FOREIGN_KEY_CHECKS = 0;
|
|
|
|
|
+
|
|
|
|
|
+-- ============================================================================
|
|
|
|
|
+-- 第一部分:资金账户与流水(6 表)
|
|
|
|
|
+-- 覆盖 SP:recharge / school_recharge / school_expenditure / school_refund /
|
|
|
|
|
+-- get_refundable_amount / school_transfer_expenditure / baddebt /
|
|
|
|
|
+-- cancel_recharge_activity / custom_refund / school_cleared_balance / school_spend
|
|
|
|
|
+-- ============================================================================
|
|
|
|
|
+
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+-- 1. t_user_expense(用户费用·**全局维度**账户,自然键 user_id)
|
|
|
|
|
+-- 迁移源:t_user_expense(PK userid int,float 金额)
|
|
|
|
|
+-- 说明:全局账本,**无 institution_id/campus_id**(跨机构共享的钱包视图),不继承 BaseRepo;
|
|
|
|
|
+-- 作用域校验在 Service 层经 MembershipChecker 完成(设计 §1.7)。
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+DROP TABLE IF EXISTS `t_user_expense`;
|
|
|
|
|
+CREATE TABLE `t_user_expense` (
|
|
|
|
|
+ `user_id` VARCHAR(26) NOT NULL COMMENT '用户ID(canonical_user_id ULID,原 userid int → t_legacy_mapping.legacy_academic_user_id 重映射)',
|
|
|
|
|
+ `balance` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '用户余额(±数,负数为欠费部分;旧 float(10,3) −> decimal(12,2))',
|
|
|
|
|
+ `spend` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '上课消费的课费单价之和(spend SP 只加此列,不动 balance)',
|
|
|
|
|
+ `total_income` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '总充值(充值+/退费-/清零不动)',
|
|
|
|
|
+ `total_expenditure` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '总消费(报课学费之和+历史欠费;消费+/退费-/转结双向调整)',
|
|
|
|
|
+ `total_recommended_amount` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '累计推荐金额(老带新双边入账累加)',
|
|
|
|
|
+ `special_expenses` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '特殊费用(充值活动后提前退费/坏账/清零时累加)',
|
|
|
|
|
+ PRIMARY KEY (`user_id`)
|
|
|
|
|
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='用户费用表(全局账户·自然键·金额 decimal(12,2))' ROW_FORMAT=Dynamic;
|
|
|
|
|
+
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+-- 2. t_user_expense_school(用户费用·**校区维度**账户,UK(user_id, institution_id, campus_id))
|
|
|
|
|
+-- 迁移源:t_user_expense_school(id int AI + userid/schoolid/campusid,decimal(10,3))
|
|
|
|
|
+-- 说明:多租户表(带 institution_id/campus_id)→ Repository 继承 BaseRepo 强制 scoping,
|
|
|
|
|
+-- 跨作用域访问 → 1004。旧库**无唯一键**(仅 PK id),目标态补 UK 防重复账户(SP 里
|
|
|
|
|
+-- "COUNT>0 则 UPDATE 否则 INSERT" 的 UPSERT 语义迁到 Go 后依赖该唯一键 + OnConflict)。
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+DROP TABLE IF EXISTS `t_user_expense_school`;
|
|
|
|
|
+CREATE TABLE `t_user_expense_school` (
|
|
|
|
|
+ `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '账户记录ID(D3 自增)',
|
|
|
|
|
+ `user_id` VARCHAR(26) NOT NULL COMMENT '用户ID(canonical_user_id ULID,原 userid)',
|
|
|
|
|
+ `institution_id` BIGINT NOT NULL COMMENT '机构ID(原 schoolid → institution_id;作用域列)',
|
|
|
|
|
+ `campus_id` BIGINT NOT NULL DEFAULT 0 COMMENT '校区ID(原 campusid;作用域列,0=机构级)',
|
|
|
|
|
+ `balance` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '校区余额(±数,负数为欠费)',
|
|
|
|
|
+ `spend` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '上课消费课费单价之和',
|
|
|
|
|
+ `total_income` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '校区总充值',
|
|
|
|
|
+ `total_expenditure` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '校区总消费',
|
|
|
|
|
+ `total_recommended_amount` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '校区累计推荐金额',
|
|
|
|
|
+ `special_expenses` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '校区特殊费用(坏账/清零/提前退费)',
|
|
|
|
|
+ PRIMARY KEY (`id`),
|
|
|
|
|
+ UNIQUE KEY `uk_user_inst_campus` (`user_id`, `institution_id`, `campus_id`),
|
|
|
|
|
+ KEY `idx_inst_campus` (`institution_id`, `campus_id`),
|
|
|
|
|
+ KEY `idx_campus_balance` (`campus_id`, `balance`)
|
|
|
|
|
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='用户费用表(校区账户·多租户·UK(user,institution,campus))' ROW_FORMAT=Dynamic;
|
|
|
|
|
+
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+-- 3. t_user_expense_log(费用变更流水,**只增不改**)
|
|
|
|
|
+-- 迁移源:t_user_expense_log(id int AI,type int,logid varchar(32),decimal(10,3))
|
|
|
|
|
+-- type 编码(规格 §1.1,**权威口径见设计 §10.2**):
|
|
|
|
|
+-- 100 充值 / 101·201 课程消费(校区) / 104·105·204·205 课程消费(学校) /
|
|
|
|
|
+-- 106 转结出 / 206 转结入 / 107 老带新推荐 / 108 坏账处理 / 200 历史扣费 /
|
|
|
|
|
+-- 207 余额退费 / 208 余额清零 / 209 取消充值活动
|
|
|
|
|
+-- 幂等键:request_id + type 唯一(MySQL 唯一键对 NULL 放行 → 历史数据 request_id NULL 安全);
|
|
|
|
|
+-- Go 侧写入撞键即视为重复请求,返回首次结果(设计 §1.5)。
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+DROP TABLE IF EXISTS `t_user_expense_log`;
|
|
|
|
|
+CREATE TABLE `t_user_expense_log` (
|
|
|
|
|
+ `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '流水ID(D3 自增)',
|
|
|
|
|
+ `user_id` VARCHAR(26) NOT NULL COMMENT '用户ID(canonical_user_id ULID,原 userid)',
|
|
|
|
|
+ `type` INT NOT NULL DEFAULT 0 COMMENT '类型编码(100充值/107老带新/108坏账/200历史扣费/201·101·104·105·204·205课程消费/206转结入/106转结出/207退费/208清零/209取消充值活动)',
|
|
|
|
|
+ `log_id` VARCHAR(64) DEFAULT NULL COMMENT '业务单号(原 logid:报课id/缴费申请id/结课申请id/充值单号;无则为 NULL)',
|
|
|
|
|
+ `request_id` VARCHAR(64) DEFAULT NULL COMMENT '幂等请求号(原 SP inputRequestid;NULL=历史数据;与 type 组唯一键)',
|
|
|
|
|
+ `money` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '变更金额(正负号表方向;转结 106=+金额 / 206=金额,见 §11 漂移项)',
|
|
|
|
|
+ `balance_after` DECIMAL(12,2) DEFAULT NULL COMMENT '变更后校区余额快照(新增列,便于对账与双跑比对;历史行 NULL)',
|
|
|
|
|
+ `create_user_id` VARCHAR(26) DEFAULT NULL COMMENT '创建人(canonical_user_id ULID;原 create_userid int,0/系统 → NULL)',
|
|
|
|
|
+ `create_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
|
|
|
|
+ `remark` VARCHAR(1000) DEFAULT NULL COMMENT '备注(原 text → varchar(1000),旧数据超长截断记录见迁移报告)',
|
|
|
|
|
+ PRIMARY KEY (`id`),
|
|
|
|
|
+ UNIQUE KEY `uk_request_type` (`request_id`, `type`),
|
|
|
|
|
+ KEY `idx_user_time` (`user_id`, `create_time`),
|
|
|
|
|
+ KEY `idx_user_type` (`user_id`, `type`),
|
|
|
|
|
+ KEY `idx_log_id` (`log_id`)
|
|
|
|
|
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='用户费用变更流水表(只增不改·幂等键 request_id+type)' ROW_FORMAT=Dynamic;
|
|
|
|
|
+
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+-- 4. t_user_balance_request(余额变更申请/审批 · 充值/退费/坏账/取消活动/转结 的工单)
|
|
|
|
|
+-- 迁移源:t_user_balance_request(PK id varchar(32) UUID → int64 + biz_no)
|
|
|
|
|
+-- type 编码:100 普通充值 / 101 坏账 / 202 退费 / 203 取消充值活动 / 300 转结
|
|
|
|
|
+-- approved:-2 取消 / -1 不通过 / 0 未处理 / 1 已通过(原 aproved 错拼修正)
|
|
|
|
|
+-- 说明:审批"通过"动作才是资金变动触发点(Service 在同一事务内先更新工单再调资金方法,
|
|
|
|
|
+-- 或先调资金方法再回写工单——**设计取后者并加幂等 request_id**,见设计 §3 备注)。
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+DROP TABLE IF EXISTS `t_user_balance_request`;
|
|
|
|
|
+CREATE TABLE `t_user_balance_request` (
|
|
|
|
|
+ `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '工单ID(D3 自增)',
|
|
|
|
|
+ `biz_no` VARCHAR(32) NOT NULL COMMENT '业务单号(旧 UUID 主键原样保留,UNIQUE,迁移幂等键)',
|
|
|
|
|
+ `type` INT NOT NULL DEFAULT 100 COMMENT '类型(100普通充值/101坏账/202退费/203取消充值活动/300转结)',
|
|
|
|
|
+ `user_id` VARCHAR(26) NOT NULL DEFAULT '' COMMENT '用户ID(canonical_user_id ULID,原 userid)',
|
|
|
|
|
+ `institution_id` BIGINT NOT NULL DEFAULT 0 COMMENT '机构ID(原 schoolid;作用域列)',
|
|
|
|
|
+ `campus_id` BIGINT NOT NULL DEFAULT 0 COMMENT '校区ID(原 campusid;作用域列)',
|
|
|
|
|
+ `to_institution_id` BIGINT DEFAULT NULL COMMENT '转入机构ID(仅 type=300 转结使用,新增列)',
|
|
|
|
|
+ `to_campus_id` BIGINT DEFAULT NULL COMMENT '转入校区ID(仅 type=300 转结使用,新增列)',
|
|
|
|
|
+ `money` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '金额(旧 decimal(10,3) 收敛)',
|
|
|
|
|
+ `transfer_accounts_type` TINYINT NOT NULL DEFAULT 0 COMMENT '收款方式(0无/1现金/2微信/3支付宝)',
|
|
|
|
|
+ `transfer_accounts_time` DATETIME(3) DEFAULT NULL COMMENT '收款时间',
|
|
|
|
|
+ `order_no` VARCHAR(50) DEFAULT NULL COMMENT '交易单号(原 orderid)',
|
|
|
|
|
+ `request_user_id` VARCHAR(26) NOT NULL DEFAULT '' COMMENT '申请人(canonical_user_id ULID,原 request_userid)',
|
|
|
|
|
+ `request_time` DATETIME(3) DEFAULT NULL COMMENT '申请时间',
|
|
|
|
|
+ `response_user_id` VARCHAR(26) DEFAULT NULL COMMENT '审批人(canonical_user_id ULID,原 response_userid;0→NULL)',
|
|
|
|
|
+ `response_time` DATETIME(3) DEFAULT NULL COMMENT '审批时间',
|
|
|
|
|
+ `response_msg` VARCHAR(1000) DEFAULT NULL COMMENT '审批意见',
|
|
|
|
|
+ `approved` TINYINT NOT NULL DEFAULT 0 COMMENT '审批状态(-2取消/-1不通过/0未处理/1已通过;原 aproved 错拼修正)',
|
|
|
|
|
+ `item` VARCHAR(1000) DEFAULT NULL COMMENT '项目(报课/充值课程说明)',
|
|
|
|
|
+ `imgs` LONGTEXT DEFAULT NULL COMMENT '凭证图片(JSON 字符串,GORM *string 直存)',
|
|
|
|
|
+ `remark` VARCHAR(1000) DEFAULT NULL COMMENT '备注',
|
|
|
|
|
+ `created_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
|
|
|
|
+ `updated_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间',
|
|
|
|
|
+ PRIMARY KEY (`id`),
|
|
|
|
|
+ UNIQUE KEY `uk_biz_no` (`biz_no`),
|
|
|
|
|
+ KEY `idx_user` (`user_id`),
|
|
|
|
|
+ KEY `idx_inst_campus_approved` (`institution_id`, `campus_id`, `approved`),
|
|
|
|
|
+ KEY `idx_type_approved` (`type`, `approved`)
|
|
|
|
|
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='余额变更申请表(充值/退费/坏账/取消活动/转结 工单·审批驱动)' ROW_FORMAT=Dynamic;
|
|
|
|
|
+
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+-- 5. t_order_pay(支付订单,旧 UUID 主键 → int64 + biz_no)
|
|
|
|
|
+-- 迁移源:t_order_pay(PK id varchar(32) UUID,pay_money float(10,2))
|
|
|
|
|
+-- 说明:本期仅承接"创建/取消/回调"三动作(Go 侧重写 PayController 的 Addpaymentorder /
|
|
|
|
|
+-- Cancelpaymentorder + NotifyController 回调),支付通道(JSAPI/W02 银联)适配层 P1。
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+DROP TABLE IF EXISTS `t_order_pay`;
|
|
|
|
|
+CREATE TABLE `t_order_pay` (
|
|
|
|
|
+ `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '订单ID(D3 自增)',
|
|
|
|
|
+ `biz_no` VARCHAR(32) NOT NULL COMMENT '业务单号(旧 UUID 主键原样保留,UNIQUE,对外暴露给前端/支付网关)',
|
|
|
|
|
+ `status` TINYINT NOT NULL DEFAULT 0 COMMENT '状态(-2失败/-1取消/0未支付/1成功)',
|
|
|
|
|
+ `type` VARCHAR(100) DEFAULT NULL COMMENT '订单类型(充值/报课 …,旧 type 字符串原样)',
|
|
|
|
|
+ `institution_id` BIGINT DEFAULT NULL COMMENT '机构ID(原 schoolid;作用域列)',
|
|
|
|
|
+ `campus_id` BIGINT DEFAULT NULL COMMENT '校区ID(原 campusid;作用域列)',
|
|
|
|
|
+ `user_id` VARCHAR(26) DEFAULT NULL COMMENT '付款用户(canonical_user_id ULID,原 userid)',
|
|
|
|
|
+ `pay_order` VARCHAR(50) DEFAULT NULL COMMENT '交易单号(第三方流水号)',
|
|
|
|
|
+ `pay_type` VARCHAR(10) DEFAULT NULL COMMENT '支付方式(JSAPI 微信 / W02 银联 AllinPay)',
|
|
|
|
|
+ `pay_account` VARCHAR(100) DEFAULT NULL COMMENT '支付平台用户标识(原 pay_acct,openid/卡号)',
|
|
|
|
|
+ `pay_money` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '交易金额(旧 float(10,2) 收敛)',
|
|
|
|
|
+ `pay_time` DATETIME(3) DEFAULT NULL COMMENT '支付时间',
|
|
|
|
|
+ `pay_return_data` LONGTEXT DEFAULT NULL COMMENT '支付返回数据(JSON 字符串,*string 直存;含敏感信息,API 层不外泄)',
|
|
|
|
|
+ `create_user_id` VARCHAR(26) DEFAULT NULL COMMENT '下单人(canonical_user_id ULID;家长代付场景≠user_id)',
|
|
|
|
|
+ `create_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
|
|
|
|
+ `remark` VARCHAR(500) DEFAULT NULL COMMENT '用户备注',
|
|
|
|
|
+ PRIMARY KEY (`id`),
|
|
|
|
|
+ UNIQUE KEY `uk_biz_no` (`biz_no`),
|
|
|
|
|
+ KEY `idx_user_create` (`user_id`, `create_time`),
|
|
|
|
|
+ KEY `idx_status` (`status`),
|
|
|
|
|
+ KEY `idx_pay_order` (`pay_order`)
|
|
|
|
|
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='支付订单表(旧 UUID→int64+biz_no·充值/报课支付)' ROW_FORMAT=Dynamic;
|
|
|
|
|
+
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+-- 6. t_payment_log(支付网关回调日志,只增;旧 UUID 主键 → int64 + biz_no)
|
|
|
|
|
+-- 迁移源:t_payment_log(PK id varchar(100) 对外订单号;PHP 全仓 0 引用 → 旧支付网关遗留)
|
|
|
|
|
+-- 说明:本期**纳管为只读历史**(迁移保留,不新增写入);新支付回调日志统一写 t_audit_log
|
|
|
|
|
+-- + t_order_pay.pay_return_data。是否重建新通道日志表见设计 §11-9。
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+DROP TABLE IF EXISTS `t_payment_log`;
|
|
|
|
|
+CREATE TABLE `t_payment_log` (
|
|
|
|
|
+ `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '日志ID(D3 自增)',
|
|
|
|
|
+ `biz_no` VARCHAR(100) NOT NULL COMMENT '对外订单号(旧主键原样保留,UNIQUE)',
|
|
|
|
|
+ `user_id` VARCHAR(26) DEFAULT NULL COMMENT '用户ID(canonical_user_id ULID)',
|
|
|
|
|
+ `order_id` BIGINT DEFAULT NULL COMMENT '订单ID(原 order_id int → t_order_pay.id;迁移期 NULL 待回填)',
|
|
|
|
|
+ `payment_type` INT NOT NULL DEFAULT 0 COMMENT '支付网关类型(旧 int 编码原样)',
|
|
|
|
|
+ `receive_time` DATETIME(3) DEFAULT NULL COMMENT '收到支付消息时间',
|
|
|
|
|
+ `return_data` LONGTEXT DEFAULT NULL COMMENT '网关原始数据(JSON 字符串)',
|
|
|
|
|
+ `create_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '生成时间',
|
|
|
|
|
+ `result` INT NOT NULL DEFAULT 0 COMMENT '处理结果(旧编码原样)',
|
|
|
|
|
+ PRIMARY KEY (`id`),
|
|
|
|
|
+ UNIQUE KEY `uk_biz_no` (`biz_no`),
|
|
|
|
|
+ KEY `idx_order` (`order_id`),
|
|
|
|
|
+ KEY `idx_user` (`user_id`),
|
|
|
|
|
+ KEY `idx_result` (`result`)
|
|
|
|
|
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='支付网关日志表(只读历史·P2 不新增写入)' ROW_FORMAT=Dynamic;
|
|
|
|
|
+
|
|
|
|
|
+-- ============================================================================
|
|
|
|
|
+-- 第二部分:活动(7 表)
|
|
|
|
|
+-- 覆盖 SP:use_activity_recharge / refund_activity_recharge / user_discount_usable /
|
|
|
|
|
+-- user_discount_use / user_discount_refund / user_discount_refund_user_activity /
|
|
|
|
|
+-- use_activity_recommend / signed_add / signed_cancel
|
|
|
|
|
+-- ============================================================================
|
|
|
|
|
+
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+-- 7. t_courses_activity(活动方案)
|
|
|
|
|
+-- 迁移源:t_courses_activity(id int AI;money float(10,2))
|
|
|
|
|
+-- type:2 充值赠送 / 3 代金券 / 4 老带新推荐(1 试听活动为旧遗留,不参与 SP 逻辑)
|
|
|
|
|
+-- status:0 停用 / 1 开启 / 2 已结束(旧 COMMENT 自相矛盾,以 PHP 判断口径为准,见 §11-5)
|
|
|
|
|
+-- campus_id=0 表示"机构所有自营校区"(custom_refund/cleared_balance 的 campusid IN (x,0) 判据)
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+DROP TABLE IF EXISTS `t_courses_activity`;
|
|
|
|
|
+CREATE TABLE `t_courses_activity` (
|
|
|
|
|
+ `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '活动ID(D3 自增)',
|
|
|
|
|
+ `type` TINYINT NOT NULL DEFAULT 1 COMMENT '活动类型(1试听/2充值赠送/3代金券/4老带新推荐)',
|
|
|
|
|
+ `toped` TINYINT NOT NULL DEFAULT 0 COMMENT '置顶(0否/1是,置顶有效至活动结束)',
|
|
|
|
|
+ `thumbnail` VARCHAR(500) DEFAULT NULL COMMENT '缩略图 URL',
|
|
|
|
|
+ `subject_id` INT NOT NULL DEFAULT 0 COMMENT '科目ID(0混合)',
|
|
|
|
|
+ `grade_id` INT NOT NULL DEFAULT 0 COMMENT '年级ID(0混合)',
|
|
|
|
|
+ `institution_id` BIGINT NOT NULL DEFAULT 0 COMMENT '机构ID(原 schoolid;作用域列)',
|
|
|
|
|
+ `campus_id` BIGINT NOT NULL DEFAULT 0 COMMENT '校区ID(原 campusid;0=机构所有自营校区;作用域列)',
|
|
|
|
|
+ `start_time` DATETIME(3) DEFAULT NULL COMMENT '活动开始时间',
|
|
|
|
|
+ `end_time` DATETIME(3) DEFAULT NULL COMMENT '活动结束时间',
|
|
|
|
|
+ `number_max` INT NOT NULL DEFAULT 0 COMMENT '可报名人数(0=不限)',
|
|
|
|
|
+ `number_sign` INT NOT NULL DEFAULT 0 COMMENT '当前报名人数(报名+1/取消-1)',
|
|
|
|
|
+ `title` VARCHAR(500) DEFAULT NULL COMMENT '标题',
|
|
|
|
|
+ `content` LONGTEXT DEFAULT NULL COMMENT '活动内容(HTML)',
|
|
|
|
|
+ `money` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '金额/额度(充值赠送额/代金券面额/老带新奖励额;旧 float(10,2))',
|
|
|
|
|
+ `status` TINYINT NOT NULL DEFAULT 0 COMMENT '状态(0停用/1开启/2已结束)',
|
|
|
|
|
+ `view` INT NOT NULL DEFAULT 0 COMMENT '浏览量(后台可见)',
|
|
|
|
|
+ `memo` VARCHAR(500) DEFAULT NULL COMMENT '备注',
|
|
|
|
|
+ `create_user_id` VARCHAR(26) DEFAULT NULL COMMENT '创建人(canonical_user_id ULID,原 create_userid)',
|
|
|
|
|
+ `create_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
|
|
|
|
+ `updated_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间(新增列)',
|
|
|
|
|
+ PRIMARY KEY (`id`),
|
|
|
|
|
+ KEY `idx_inst_campus_type_status` (`institution_id`, `campus_id`, `type`, `status`),
|
|
|
|
|
+ KEY `idx_time` (`start_time`, `end_time`)
|
|
|
|
|
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='活动表(充值赠送/代金券/老带新)' ROW_FORMAT=Dynamic;
|
|
|
|
|
+
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+-- 8. t_courses_activity_signed(活动报名/结算记录,UK(user_id, activity_id) 由业务保证)
|
|
|
|
|
+-- 迁移源:t_courses_activity_signed(id int AI;decimal(10,3))
|
|
|
|
|
+-- status:0 取消报名 / 1 报名 / 2 参加活动 / 3 报课(成交) / 4 过期不能使用
|
|
|
|
|
+-- 关键:signed_add 用 **DELETE+INSERT 幂等**(同一 user+activity 只留一条,含 status=0 的旧行被清);
|
|
|
|
|
+-- 目标态改为 OnConflict(更新) 语义,保留唯一键 uk_user_activity 兜底(设计 §1.6)。
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+DROP TABLE IF EXISTS `t_courses_activity_signed`;
|
|
|
|
|
+CREATE TABLE `t_courses_activity_signed` (
|
|
|
|
|
+ `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '报名记录ID(D3 自增)',
|
|
|
|
|
+ `activity_id` BIGINT NOT NULL COMMENT '活动ID(原 activityid,→ t_courses_activity.id)',
|
|
|
|
|
+ `user_id` VARCHAR(26) NOT NULL COMMENT '报名用户(canonical_user_id ULID,原 userid)',
|
|
|
|
|
+ `institution_id` BIGINT NOT NULL DEFAULT 0 COMMENT '机构ID(冗余作用域列,便于 scoping;新增)',
|
|
|
|
|
+ `campus_id` BIGINT NOT NULL DEFAULT 0 COMMENT '校区ID(冗余作用域列,取活动 campus_id;新增)',
|
|
|
|
|
+ `status` INT NOT NULL DEFAULT 0 COMMENT '状态(0取消报名/1报名/2参加活动/3报课成交/4过期不能使用)',
|
|
|
|
|
+ `recharge_amount` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '充值金额(copy_activity_discount_to_signed 回填)',
|
|
|
|
|
+ `activity_money` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '活动金额(报名时取 t_courses_activity.money)',
|
|
|
|
|
+ `activity_money_used` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '已使用活动金额(老带新=已充值到账户)',
|
|
|
|
|
+ `recommend_user_id` VARCHAR(26) DEFAULT NULL COMMENT '推荐人(canonical_user_id ULID,原 recommend_userid;0→NULL)',
|
|
|
|
|
+ `create_user_id` VARCHAR(26) DEFAULT NULL COMMENT '创建人(原 create_userid)',
|
|
|
|
|
+ `create_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '报名时间',
|
|
|
|
|
+ `imgs` VARCHAR(255) DEFAULT NULL COMMENT '图片备注(JSON 字符串)',
|
|
|
|
|
+ `memo` VARCHAR(500) DEFAULT NULL COMMENT '备注',
|
|
|
|
|
+ `request_no` VARCHAR(100) DEFAULT NULL COMMENT '申请单号(原 requestid,关联 t_user_balance_request.biz_no)',
|
|
|
|
|
+ `response_user_id` VARCHAR(26) DEFAULT NULL COMMENT '审核人(canonical_user_id ULID,原 response_userid;>0 表示已审核通过→不可取消)',
|
|
|
|
|
+ `response_time` DATETIME(3) DEFAULT NULL COMMENT '审核时间',
|
|
|
|
|
+ `response_msg` VARCHAR(500) DEFAULT NULL COMMENT '审核意见',
|
|
|
|
|
+ PRIMARY KEY (`id`),
|
|
|
|
|
+ UNIQUE KEY `uk_user_activity` (`user_id`, `activity_id`),
|
|
|
|
|
+ KEY `idx_activity_status` (`activity_id`, `status`),
|
|
|
|
|
+ KEY `idx_user_status` (`user_id`, `status`),
|
|
|
|
|
+ KEY `idx_inst_campus` (`institution_id`, `campus_id`),
|
|
|
|
|
+ KEY `idx_request_no` (`request_no`)
|
|
|
|
|
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='活动报名/结算表(UK user+activity·status 状态机)' ROW_FORMAT=Dynamic;
|
|
|
|
|
+
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+-- 9. t_courses_activity_user_discount(活动学生优惠账户 = 赠送金额池)
|
|
|
|
|
+-- 迁移源:t_courses_activity_user_discount(id int AI;float(10,2)/float(10,3))
|
|
|
|
|
+-- 语义:discount_amount=赠送总额(负数是减、正数是赠送),discount_amount_used=已使用;
|
|
|
|
|
+-- 可用 = discount_amount - discount_amount_used(user_discount_usable 汇总裁剪口径:
|
|
|
|
|
+-- 仅累加 discount_amount > discount_amount_used 的行)
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+DROP TABLE IF EXISTS `t_courses_activity_user_discount`;
|
|
|
|
|
+CREATE TABLE `t_courses_activity_user_discount` (
|
|
|
|
|
+ `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '优惠账户ID(D3 自增)',
|
|
|
|
|
+ `activity_id` BIGINT NOT NULL COMMENT '活动ID(原 activityid)',
|
|
|
|
|
+ `institution_id` BIGINT NOT NULL DEFAULT 0 COMMENT '机构ID(原 schoolid;作用域列)',
|
|
|
|
|
+ `campus_id` BIGINT NOT NULL DEFAULT 0 COMMENT '校区ID(原 campusid;0=机构所有自营校区)',
|
|
|
|
|
+ `user_id` VARCHAR(26) NOT NULL COMMENT '学生(canonical_user_id ULID,原 userid)',
|
|
|
|
|
+ `balance_request_id` BIGINT DEFAULT NULL COMMENT '来源充值/退费工单ID(原 balance_requestid varchar(32) → t_user_balance_request.id)',
|
|
|
|
|
+ `income` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '充值金额(触发赠送的充值额)',
|
|
|
|
|
+ `discount_amount` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '赠送金额(负数减/正数赠送)',
|
|
|
|
|
+ `discount_amount_used` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '已使用赠送金额(<=discount_amount)',
|
|
|
|
|
+ `create_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
|
|
|
|
+ PRIMARY KEY (`id`),
|
|
|
|
|
+ KEY `idx_user_activity` (`user_id`, `activity_id`),
|
|
|
|
|
+ KEY `idx_inst_campus_user` (`institution_id`, `campus_id`, `user_id`)
|
|
|
|
|
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='活动学生优惠表(赠送金额池·可用=总额-已用)' ROW_FORMAT=Dynamic;
|
|
|
|
|
+
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+-- 10. t_courses_activity_user_discount_log(赠送金额使用流水,只增)
|
|
|
|
|
+-- 迁移源:t_courses_activity_user_discount_log(id int AI;discount_amount_used float(10,3) 负=消费 正=退回)
|
|
|
|
|
+-- courses_student_id:旧 varchar(32) UUID(报课信息 id)→ int64 FK(t_courses_student.id),
|
|
|
|
|
+-- 同时保留 courses_student_no 旧 UUID 供迁移与对账。
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+DROP TABLE IF EXISTS `t_courses_activity_user_discount_log`;
|
|
|
|
|
+CREATE TABLE `t_courses_activity_user_discount_log` (
|
|
|
|
|
+ `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '流水ID(D3 自增)',
|
|
|
|
|
+ `activity_user_discount_id` BIGINT NOT NULL COMMENT '优惠账户ID(原 activity_user_discountid → t_courses_activity_user_discount.id)',
|
|
|
|
|
+ `courses_student_id` BIGINT DEFAULT NULL COMMENT '报课记录ID(原 courses_studentid varchar(32) UUID → t_courses_student.id;未回填前 NULL)',
|
|
|
|
|
+ `courses_student_no` VARCHAR(32) DEFAULT NULL COMMENT '报课记录旧单号(迁移期间保留旧 UUID,回填完成后可停用)',
|
|
|
|
|
+ `discount_amount_used` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '变动金额(负=消费/正=退回)',
|
|
|
|
|
+ `create_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '使用时间',
|
|
|
|
|
+ `memo` VARCHAR(500) DEFAULT NULL COMMENT '备注',
|
|
|
|
|
+ PRIMARY KEY (`id`),
|
|
|
|
|
+ KEY `idx_discount` (`activity_user_discount_id`),
|
|
|
|
|
+ KEY `idx_student` (`courses_student_id`),
|
|
|
|
|
+ KEY `idx_student_no` (`courses_student_no`)
|
|
|
|
|
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='活动学生优惠使用记录表(负=消费/正=退回)' ROW_FORMAT=Dynamic;
|
|
|
|
|
+
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+-- 11. t_courses_activity_used_log(活动金额获得/使用记录,只增)
|
|
|
|
|
+-- 迁移源:t_courses_activity_used_log(id int AI;activity_money_used decimal(10,3))
|
|
|
|
|
+-- 语义:老带新结算写 **负值**(activity_money_used = -金额,表示"从活动池取出并充值到账户");
|
|
|
|
|
+-- copy_activity_discountLog_to_usedLog 全量重放时按 discount_log 原值写入(可能为正)。
|
|
|
|
|
+-- 撤销充值活动前置校验:老带新有本表记录 → 不可取消(signed_cancel)。
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+DROP TABLE IF EXISTS `t_courses_activity_used_log`;
|
|
|
|
|
+CREATE TABLE `t_courses_activity_used_log` (
|
|
|
|
|
+ `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '记录ID(D3 自增)',
|
|
|
|
|
+ `activity_id` BIGINT NOT NULL COMMENT '活动ID(原 activityid)',
|
|
|
|
|
+ `user_id` VARCHAR(26) NOT NULL COMMENT '参与用户(canonical_user_id ULID,原 userid)',
|
|
|
|
|
+ `recommend_user_id` VARCHAR(26) DEFAULT NULL COMMENT '推荐人(canonical_user_id ULID,原 recommend_userid;0→NULL)',
|
|
|
|
|
+ `order_no` VARCHAR(100) DEFAULT NULL COMMENT '订单号(原 orderid:老带新=报课信息 id;copy 重放=courses_studentid)',
|
|
|
|
|
+ `activity_money_used` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '活动金额变动(老带新结算=负值)',
|
|
|
|
|
+ `create_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
|
|
|
|
+ `memo` VARCHAR(255) DEFAULT NULL COMMENT '备注',
|
|
|
|
|
+ PRIMARY KEY (`id`),
|
|
|
|
|
+ KEY `idx_activity_user` (`activity_id`, `user_id`),
|
|
|
|
|
+ KEY `idx_user` (`user_id`),
|
|
|
|
|
+ KEY `idx_order_no` (`order_no`)
|
|
|
|
|
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='老带新活动获得/使用记录表(结算写负值)' ROW_FORMAT=Dynamic;
|
|
|
|
|
+
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+-- 12. t_courses_activity_request(活动优惠申请/审批,旧 UUID 主键 → int64 + biz_no)
|
|
|
|
|
+-- 迁移源:t_courses_activity_request(PK id varchar(32) UUID;give_amount float(10,2))
|
|
|
|
|
+-- approved:-1 不通过 / 0 未处理 / 1 通过
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+DROP TABLE IF EXISTS `t_courses_activity_request`;
|
|
|
|
|
+CREATE TABLE `t_courses_activity_request` (
|
|
|
|
|
+ `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '申请ID(D3 自增)',
|
|
|
|
|
+ `biz_no` VARCHAR(32) NOT NULL COMMENT '业务单号(旧 UUID 主键原样保留,UNIQUE)',
|
|
|
|
|
+ `activity_id` BIGINT NOT NULL COMMENT '活动ID(原 activityid)',
|
|
|
|
|
+ `institution_id` BIGINT NOT NULL DEFAULT 0 COMMENT '适用机构ID(原 schoolid;作用域列)',
|
|
|
|
|
+ `campus_id` BIGINT NOT NULL DEFAULT 0 COMMENT '适用校区ID(原 campusid;作用域列)',
|
|
|
|
|
+ `user_id` VARCHAR(26) NOT NULL DEFAULT '' COMMENT '用户ID(canonical_user_id ULID)',
|
|
|
|
|
+ `give_amount` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '优惠金额(旧 float(10,2))',
|
|
|
|
|
+ `imgs` LONGTEXT DEFAULT NULL COMMENT '图片备注(JSON 字符串)',
|
|
|
|
|
+ `memo` LONGTEXT DEFAULT NULL COMMENT '备注',
|
|
|
|
|
+ `request_user_id` VARCHAR(26) NOT NULL DEFAULT '' COMMENT '申请人(canonical_user_id ULID)',
|
|
|
|
|
+ `request_time` DATETIME(3) DEFAULT NULL COMMENT '申请时间',
|
|
|
|
|
+ `response_user_id` VARCHAR(26) DEFAULT NULL COMMENT '审批人(canonical_user_id ULID;0→NULL)',
|
|
|
|
|
+ `response_time` DATETIME(3) DEFAULT NULL COMMENT '审批时间',
|
|
|
|
|
+ `response_msg` LONGTEXT DEFAULT NULL COMMENT '审批意见',
|
|
|
|
|
+ `approved` TINYINT NOT NULL DEFAULT 0 COMMENT '审批状态(-1不通过/0未处理/1通过)',
|
|
|
|
|
+ `created_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
|
|
|
|
+ `updated_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间',
|
|
|
|
|
+ PRIMARY KEY (`id`),
|
|
|
|
|
+ UNIQUE KEY `uk_biz_no` (`biz_no`),
|
|
|
|
|
+ KEY `idx_activity_user` (`activity_id`, `user_id`),
|
|
|
|
|
+ KEY `idx_inst_campus_approved` (`institution_id`, `campus_id`, `approved`)
|
|
|
|
|
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='活动优惠申请表(旧 UUID→int64+biz_no)' ROW_FORMAT=Dynamic;
|
|
|
|
|
+
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+-- 13. t_courses_activity_visit(活动回访记录)
|
|
|
|
|
+-- 迁移源:t_courses_activity_visit(id int AI,AUTO_INCREMENT=1 基本空表,latin1 → utf8mb4)
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+DROP TABLE IF EXISTS `t_courses_activity_visit`;
|
|
|
|
|
+CREATE TABLE `t_courses_activity_visit` (
|
|
|
|
|
+ `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '回访ID(D3 自增)',
|
|
|
|
|
+ `activity_signed_id` BIGINT DEFAULT NULL COMMENT '报名记录ID(原 activity_signedid → t_courses_activity_signed.id)',
|
|
|
|
|
+ `create_user_id` VARCHAR(26) DEFAULT NULL COMMENT '回访人(canonical_user_id ULID,原 create_userid)',
|
|
|
|
|
+ `create_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '回访时间',
|
|
|
|
|
+ `memo` VARCHAR(500) DEFAULT NULL COMMENT '回访内容',
|
|
|
|
|
+ PRIMARY KEY (`id`),
|
|
|
|
|
+ KEY `idx_signed` (`activity_signed_id`)
|
|
|
|
|
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='活动回访记录表' ROW_FORMAT=Dynamic;
|
|
|
|
|
+
|
|
|
|
|
+-- ============================================================================
|
|
|
|
|
+-- 第三部分:分账(2 表,Nested Set 左右值树)
|
|
|
|
|
+-- 覆盖 SP:divide_into_add / divide_into_log_add / divide_into_log_delete / divide_into_update_quota
|
|
|
|
|
+-- ============================================================================
|
|
|
|
|
+
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+-- 14. t_user_divide_into(分账树节点,Nested Set,自然键 user_id)
|
|
|
|
|
+-- 迁移源:t_user_divide_into(PK userid;quota/total_income/total_income_payed float(10,2))
|
|
|
|
|
+-- 语义:一人一节点(PK user_id);root_user_id 标识所属树;left_val/right_val 为嵌套集区间;
|
|
|
|
|
+-- layer 为层级(根=1)。下线 quota 不得超过上线(update_quota 级联约束)。
|
|
|
|
|
+-- ⚠️ 此表**无 institution_id/campus_id**(旧库为全局推广体系)→ 不继承 BaseRepo,
|
|
|
|
|
+-- 访问控制由 Handler 角色白名单(super_admin/academic)+ 显式数据范围参数保证(设计 §1.7)。
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+DROP TABLE IF EXISTS `t_user_divide_into`;
|
|
|
|
|
+CREATE TABLE `t_user_divide_into` (
|
|
|
|
|
+ `user_id` VARCHAR(26) NOT NULL COMMENT '节点用户(canonical_user_id ULID,原 userid,主键)',
|
|
|
|
|
+ `type` TINYINT NOT NULL DEFAULT 1 COMMENT '分成类型(1一次付清/2按课次)',
|
|
|
|
|
+ `quota` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '分成额度(每次分成金额)',
|
|
|
|
|
+ `total_income` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '分成总收入(累积)',
|
|
|
|
|
+ `total_income_payed` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '已支付的分成收入',
|
|
|
|
|
+ `root_user_id` VARCHAR(26) DEFAULT NULL COMMENT '树根用户(原 root_userid;自身为根时=user_id)',
|
|
|
|
|
+ `parent_user_id` VARCHAR(26) DEFAULT NULL COMMENT '上级用户(原 parent_userid;根为 NULL)',
|
|
|
|
|
+ `left_val` INT NOT NULL DEFAULT 1 COMMENT '左值(Nested Set)',
|
|
|
|
|
+ `right_val` INT NOT NULL DEFAULT 2 COMMENT '右值(Nested Set)',
|
|
|
|
|
+ `layer` INT NOT NULL DEFAULT 1 COMMENT '层级(根=1)',
|
|
|
|
|
+ `created_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
|
|
|
|
+ `updated_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间',
|
|
|
|
|
+ PRIMARY KEY (`user_id`),
|
|
|
|
|
+ KEY `idx_root` (`root_user_id`),
|
|
|
|
|
+ KEY `idx_parent` (`parent_user_id`),
|
|
|
|
|
+ KEY `idx_root_left_right` (`root_user_id`, `left_val`, `right_val`)
|
|
|
|
|
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='用户分账表(Nested Set 左右值树·一人一节点)' ROW_FORMAT=Dynamic;
|
|
|
|
|
+
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+-- 15. t_user_divide_into_log(分账明细,只增)
|
|
|
|
|
+-- 迁移源:t_user_divide_into_log(id int AI;type tinyint ZEROFILL;money float(10,2))
|
|
|
|
|
+-- 去重幂等(divide_into_log_add 口径):
|
|
|
|
|
+-- type=1(一次付清):同 user+student 只生成一条(不区分 order);
|
|
|
|
|
+-- type=2(按课次) :同 user+student+order_no 只生成一条。
|
|
|
|
|
+-- log_delete 语义:学生已有首次扣费上课记录 → 改 order_no 为首次 record(保留分成);
|
|
|
|
|
+-- 否则回滚 total_income 并物理删除该行(设计 §3-4.3)。
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+DROP TABLE IF EXISTS `t_user_divide_into_log`;
|
|
|
|
|
+CREATE TABLE `t_user_divide_into_log` (
|
|
|
|
|
+ `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '分成记录ID(D3 自增)',
|
|
|
|
|
+ `type` TINYINT NOT NULL DEFAULT 1 COMMENT '分成类型(1一次付清/2按课次)',
|
|
|
|
|
+ `user_id` VARCHAR(26) NOT NULL COMMENT '获得分成的用户(canonical_user_id ULID,原 userid)',
|
|
|
|
|
+ `student_id` VARCHAR(26) NOT NULL COMMENT '报课学生(canonical_user_id ULID,原 studentid)',
|
|
|
|
|
+ `order_no` VARCHAR(50) DEFAULT NULL COMMENT '订单号(原 orderid:type=2 时=上课记录 id)',
|
|
|
|
|
+ `money` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '分成金额(旧 float(10,2))',
|
|
|
|
|
+ `create_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
|
|
|
|
+ `remark` LONGTEXT DEFAULT NULL COMMENT '备注',
|
|
|
|
|
+ PRIMARY KEY (`id`),
|
|
|
|
|
+ KEY `idx_user_student_type` (`user_id`, `student_id`, `type`),
|
|
|
|
|
+ KEY `idx_student_order` (`student_id`, `order_no`),
|
|
|
|
|
+ KEY `idx_create_time` (`create_time`)
|
|
|
|
|
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='分账明细表(type1 per student / type2 per order 幂等)' ROW_FORMAT=Dynamic;
|
|
|
|
|
+
|
|
|
|
|
+-- ============================================================================
|
|
|
|
|
+-- 第四部分:课程 / 班级 / 排班 / 打卡(6 表)
|
|
|
|
|
+-- 覆盖 SP:courses_student_counteract_arrears_course / courses_update / courses_update_campusid
|
|
|
|
|
+-- 说明:排班与打卡**无 SP 覆盖**(旧 PHP modules/courses 业务逻辑),本部分表为本期
|
|
|
|
|
+-- "排班生成 + 上课打卡 + 结束扣课时" 最小闭环的运行态载体(设计 §11-3 盘点结论)。
|
|
|
|
|
+-- ============================================================================
|
|
|
|
|
+
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+-- 16. t_courses(课程模板:价格/次数/周规则/时长)
|
|
|
|
|
+-- 迁移源:t_courses(id int AI;original_cost/real_price/discount_cash float(10,3);week varchar(50))
|
|
|
|
|
+-- week 语义:'-1' 全部周 / '0' 周日 / '1..6' / 多值逗号分隔(字符串保留,不做位图化,保迁移稳定)
|
|
|
|
|
+-- status:0 未发布 / 1 发布未开始 / 2 进行中 / 3 已结束
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+DROP TABLE IF EXISTS `t_courses`;
|
|
|
|
|
+CREATE TABLE `t_courses` (
|
|
|
|
|
+ `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '课程ID(D3 自增)',
|
|
|
|
|
+ `subject_id` INT NOT NULL DEFAULT 0 COMMENT '科目ID(0混合科)',
|
|
|
|
|
+ `grade_id` INT NOT NULL DEFAULT 0 COMMENT '年级ID(0混合年级)',
|
|
|
|
|
+ `type` INT NOT NULL DEFAULT 1 COMMENT '类型(1000集体班/2000VIP…)',
|
|
|
|
|
+ `institution_id` BIGINT NOT NULL DEFAULT 0 COMMENT '机构ID(原 schoolid;作用域列)',
|
|
|
|
|
+ `campus_id` BIGINT NOT NULL DEFAULT 0 COMMENT '校区ID(原 campusid;作用域列)',
|
|
|
|
|
+ `classify_id` BIGINT NOT NULL DEFAULT 0 COMMENT '课程分类ID(原 classifyid → t_courses_classify.id)',
|
|
|
|
|
+ `status` INT NOT NULL DEFAULT 1 COMMENT '状态(0未发布/1发布未开始/2进行中/3已结束)',
|
|
|
|
|
+ `name` VARCHAR(500) NOT NULL COMMENT '课程名称',
|
|
|
|
|
+ `number` INT NOT NULL DEFAULT 0 COMMENT '上课次数(课次)',
|
|
|
|
|
+ `duration` DECIMAL(5,1) NOT NULL DEFAULT 0.0 COMMENT '单节课时长(课时,1 位小数,保留旧精度)',
|
|
|
|
|
+ `week` VARCHAR(50) NOT NULL DEFAULT '-1' COMMENT '周规则(-1全部/0周日/1-6/多值逗号分隔)',
|
|
|
|
|
+ `start_time` DATETIME(3) DEFAULT NULL COMMENT '课程开始时间',
|
|
|
|
|
+ `end_time` DATETIME(3) DEFAULT NULL COMMENT '课程结束时间',
|
|
|
|
|
+ `address` LONGTEXT DEFAULT NULL COMMENT '上课地址',
|
|
|
|
|
+ `original_cost` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '原价(元;旧 float(10,3)→2 位收敛)',
|
|
|
|
|
+ `real_price` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '实价(元)',
|
|
|
|
|
+ `discount_cash` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '现金折扣(元)',
|
|
|
|
|
+ `discount_ratio` INT NOT NULL DEFAULT 0 COMMENT '折扣率(百分比数字部分)',
|
|
|
|
|
+ `remark` LONGTEXT DEFAULT NULL COMMENT '备注',
|
|
|
|
|
+ `max_people` INT NOT NULL DEFAULT 0 COMMENT '最多人数(0 时由 courses_update 从 classify 继承)',
|
|
|
|
|
+ `update_user_id` VARCHAR(26) DEFAULT NULL COMMENT '最后修改人(canonical_user_id ULID,原 update_userid)',
|
|
|
|
|
+ `update_time` DATETIME(3) DEFAULT NULL COMMENT '最后修改时间',
|
|
|
|
|
+ `created_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
|
|
|
|
+ PRIMARY KEY (`id`),
|
|
|
|
|
+ KEY `idx_inst_campus_status` (`institution_id`, `campus_id`, `status`),
|
|
|
|
|
+ KEY `idx_classify` (`classify_id`),
|
|
|
|
|
+ KEY `idx_subject_grade` (`subject_id`, `grade_id`)
|
|
|
|
|
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='课程信息表(课程模板·周规则+次数+价格)' ROW_FORMAT=Dynamic;
|
|
|
|
|
+
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+-- 17. t_courses_classify(课程分类:班级类型/单价/人数区间 + 课酬方案绑定)
|
|
|
|
|
+-- 迁移源:t_courses_classify(id int AI;unit_price float(10,3))
|
|
|
|
|
+-- class_type:1000 集体班 / 1001 小班 …(与 t_course_payment_detail.class_type 对应)
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+DROP TABLE IF EXISTS `t_courses_classify`;
|
|
|
|
|
+CREATE TABLE `t_courses_classify` (
|
|
|
|
|
+ `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '分类ID(D3 自增)',
|
|
|
|
|
+ `institution_id` BIGINT NOT NULL DEFAULT 0 COMMENT '机构ID(原 schoolid;作用域列)',
|
|
|
|
|
+ `campus_id` BIGINT NOT NULL DEFAULT 0 COMMENT '校区ID(原 campusid;作用域列)',
|
|
|
|
|
+ `class_type` INT NOT NULL DEFAULT 1000 COMMENT '班级类型(1000集体班/1001小班…)',
|
|
|
|
|
+ `course_payment_id` BIGINT NOT NULL DEFAULT 0 COMMENT '课酬方案ID(原 course_paymentid → t_course_payment.id)',
|
|
|
|
|
+ `grade_id` INT NOT NULL DEFAULT 0 COMMENT '年级ID(0混合)',
|
|
|
|
|
+ `subject_id` INT NOT NULL DEFAULT 0 COMMENT '科目ID(0混合)',
|
|
|
|
|
+ `name` VARCHAR(500) NOT NULL COMMENT '分类名称',
|
|
|
|
|
+ `unit_price` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '单价(一次课价格)',
|
|
|
|
|
+ `min_people` INT NOT NULL DEFAULT 1 COMMENT '最少人数',
|
|
|
|
|
+ `max_people` INT NOT NULL DEFAULT 1000 COMMENT '最多人数',
|
|
|
|
|
+ PRIMARY KEY (`id`),
|
|
|
|
|
+ KEY `idx_payment` (`course_payment_id`),
|
|
|
|
|
+ KEY `idx_inst_campus` (`institution_id`, `campus_id`)
|
|
|
|
|
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='课程分类表(班级类型/单价/人数区间)' ROW_FORMAT=Dynamic;
|
|
|
|
|
+
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+-- 18. t_courses_class(课程-班级-老师-课表规则关系 = **排班规则**)
|
|
|
|
|
+-- 迁移源:t_courses_class(id int AI;standard_lesson_cost/lesson_cost/discount_cash float(10,3))
|
|
|
|
|
+-- 语义:一门课在某班由某老师按 week + 上课起止时分 排课;finished_number 已上课量。
|
|
|
|
|
+-- ⚠️ start_time/end_time 旧库为"时分"(date 部分无意义);目标态保留 datetime(3) 以兼容旧数据,
|
|
|
|
|
+-- 新写入统一以 1970-01-01 日期 + 时分(迁移与写入规则见 §11-3)。
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+DROP TABLE IF EXISTS `t_courses_class`;
|
|
|
|
|
+CREATE TABLE `t_courses_class` (
|
|
|
|
|
+ `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '关系ID(D3 自增)',
|
|
|
|
|
+ `status` INT NOT NULL DEFAULT 1 COMMENT '状态(1进行中/2结束)',
|
|
|
|
|
+ `courses_id` BIGINT NOT NULL COMMENT '课程ID(原 coursesid → t_courses.id)',
|
|
|
|
|
+ `class_id` BIGINT NOT NULL COMMENT '班级ID(原 classid;旧库为外部班级体系 id,本期仅存值)',
|
|
|
|
|
+ `teacher_id` VARCHAR(26) DEFAULT NULL COMMENT '老师(canonical_user_id ULID,原 teacherid;0→NULL)',
|
|
|
|
|
+ `institution_id` BIGINT NOT NULL DEFAULT 0 COMMENT '机构ID(原 schoolid;作用域列)',
|
|
|
|
|
+ `campus_id` BIGINT NOT NULL DEFAULT 0 COMMENT '校区ID(原 campusid;作用域列)',
|
|
|
|
|
+ `standard_lesson_cost` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '课程标准单价',
|
|
|
|
|
+ `number` INT NOT NULL DEFAULT 0 COMMENT '开课总量(课次)',
|
|
|
|
|
+ `lesson_cost` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '一次课的课费',
|
|
|
|
|
+ `discount_cash` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '课程优惠(元)',
|
|
|
|
|
+ `finished_number` INT NOT NULL DEFAULT 0 COMMENT '已上课量',
|
|
|
|
|
+ `confirm` TINYINT NOT NULL DEFAULT 0 COMMENT '是否确认(0未确认/1确认)',
|
|
|
|
|
+ `week` VARCHAR(50) NOT NULL DEFAULT '-1' COMMENT '周规则(-1全部/0周日/1-6/多值逗号分隔)',
|
|
|
|
|
+ `start_time` DATETIME(3) DEFAULT NULL COMMENT '上课时间(时分;旧 NOT NULL,目标态放宽)',
|
|
|
|
|
+ `end_time` DATETIME(3) DEFAULT NULL COMMENT '下课时间(时分)',
|
|
|
|
|
+ `address` LONGTEXT DEFAULT NULL COMMENT '上课地址',
|
|
|
|
|
+ `remark` LONGTEXT DEFAULT NULL COMMENT '备注',
|
|
|
|
|
+ `created_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
|
|
|
|
+ PRIMARY KEY (`id`),
|
|
|
|
|
+ KEY `idx_courses` (`courses_id`),
|
|
|
|
|
+ KEY `idx_teacher` (`teacher_id`),
|
|
|
|
|
+ KEY `idx_class` (`class_id`),
|
|
|
|
|
+ KEY `idx_inst_campus` (`institution_id`, `campus_id`)
|
|
|
|
|
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='课程班级关系表(排班规则:周+时分+老师)' ROW_FORMAT=Dynamic;
|
|
|
|
|
+
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+-- 19. t_courses_student(学生报课信息 = 学费账户/课次账户;旧 UUID 主键 → int64 + biz_no)
|
|
|
|
|
+-- 迁移源:t_courses_student(PK id varchar(32) UUID;多列 decimal(10,3);activityid varchar(200))
|
|
|
|
|
+-- 语义:应收 receivable / 实收 net_receipts / 欠费 unpaid / 单课费 lesson_cost / 总次数 number /
|
|
|
|
|
+-- 已上 finished_number / 剩余费用 remainder_cost / 剩余应收 remainder_receivable / 坏账 bad_debt。
|
|
|
|
|
+-- confirm_discount_userid=0 表示"不可充值"(业务语义,见字段规范 §4.2)。
|
|
|
|
|
+-- ⚠️ activityid 旧为"多活动英文逗号串":目标态保留 activity_ids varchar(200) 原样,
|
|
|
|
|
+-- 不做规范化拆表(保结构稳定、迁移映射简单,设计 §2.3)。
|
|
|
|
|
+-- ⚠️ 该表同时是"报课订单"载体:user_discount_log.courses_student_id / activity_used_log.order_no
|
|
|
|
|
+-- 均指向本表;旧 UUID 必须保留在 biz_no。
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+DROP TABLE IF EXISTS `t_courses_student`;
|
|
|
|
|
+CREATE TABLE `t_courses_student` (
|
|
|
|
|
+ `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '报课记录ID(D3 自增)',
|
|
|
|
|
+ `biz_no` VARCHAR(32) NOT NULL COMMENT '业务单号(旧 UUID 主键原样保留,UNIQUE)',
|
|
|
|
|
+ `courses_id` BIGINT NOT NULL COMMENT '课程ID(原 coursesid)',
|
|
|
|
|
+ `class_id` BIGINT NOT NULL DEFAULT 0 COMMENT '班级ID(原 classid)',
|
|
|
|
|
+ `institution_id` BIGINT NOT NULL DEFAULT 0 COMMENT '机构ID(原 schoolid;作用域列)',
|
|
|
|
|
+ `campus_id` BIGINT NOT NULL DEFAULT 0 COMMENT '校区ID(原 campusid;作用域列)',
|
|
|
|
|
+ `student_id` VARCHAR(26) NOT NULL COMMENT '学生(canonical_user_id ULID,原 studentid)',
|
|
|
|
|
+ `type` TINYINT NOT NULL DEFAULT 1 COMMENT '上课类型(1正常/2插班)',
|
|
|
|
|
+ `status` TINYINT NOT NULL DEFAULT 1 COMMENT '状态(1正常/2结束)',
|
|
|
|
|
+ `receivable` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '应收',
|
|
|
|
|
+ `net_receipts` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '实收(学生实际缴纳)',
|
|
|
|
|
+ `unpaid` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '欠费(未支付费用)',
|
|
|
|
|
+ `lesson_cost` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '一节课的费用',
|
|
|
|
|
+ `number` INT NOT NULL DEFAULT 0 COMMENT '总课次',
|
|
|
|
|
+ `finished_number` INT NOT NULL DEFAULT 0 COMMENT '已上课次',
|
|
|
|
|
+ `discount_cash` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '现金折扣(元)',
|
|
|
|
|
+ `activity_ids` VARCHAR(200) DEFAULT NULL COMMENT '报课使用的活动ID(英文逗号分隔,原 activityid)',
|
|
|
|
|
+ `give_number` INT NOT NULL DEFAULT 0 COMMENT '赠送课次',
|
|
|
|
|
+ `give_cost` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '使用的赠送金额(元)',
|
|
|
|
|
+ `changing_course_number` INT NOT NULL DEFAULT 0 COMMENT '调课次数',
|
|
|
|
|
+ `remainder_number` INT NOT NULL DEFAULT 0 COMMENT '剩余课次',
|
|
|
|
|
+ `remainder_cost` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '剩余费用(缴费扣除每次课费后余额)',
|
|
|
|
|
+ `remainder_receivable` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '剩余应收',
|
|
|
|
|
+ `bad_debt` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '坏账',
|
|
|
|
|
+ `confirm_discount_user_id` VARCHAR(26) DEFAULT NULL COMMENT '确认学生折扣的操作人(原 confirm_discount_userid;0/NULL=不可充值)',
|
|
|
|
|
+ `confirm_time` DATETIME(3) DEFAULT NULL COMMENT '确认时间',
|
|
|
|
|
+ `recommender_user_id` VARCHAR(26) DEFAULT NULL COMMENT '推荐人(原 recommender_userid)',
|
|
|
|
|
+ `recommender_time` DATETIME(3) DEFAULT NULL COMMENT '推荐时间',
|
|
|
|
|
+ `create_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
|
|
|
|
+ `remark` LONGTEXT DEFAULT NULL COMMENT '备注',
|
|
|
|
|
+ PRIMARY KEY (`id`),
|
|
|
|
|
+ UNIQUE KEY `uk_biz_no` (`biz_no`),
|
|
|
|
|
+ KEY `idx_student_status` (`student_id`, `status`),
|
|
|
|
|
+ KEY `idx_courses` (`courses_id`),
|
|
|
|
|
+ KEY `idx_inst_campus` (`institution_id`, `campus_id`),
|
|
|
|
|
+ KEY `idx_unpaid` (`student_id`, `unpaid`)
|
|
|
|
|
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='学生报课信息表(学费/课次账户·旧 UUID→biz_no)' ROW_FORMAT=Dynamic;
|
|
|
|
|
+
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+-- 20. t_courses_record(上课记录/课表实例 = **排班实例**;旧 UUID 主键 → int64 + biz_no)
|
|
|
|
|
+-- 迁移源:t_courses_record(PK id varchar(32) UUID;income/teacher_reward float)
|
|
|
|
|
+-- status:0 未开始 / 1 正在进行 / 2 已结束
|
|
|
|
|
+-- 语义:开始上课写 actual_start_time;结束上课写 actual_end_time + income + teacher_reward,
|
|
|
|
|
+-- 并联动 t_courses_record_student / 余额 spend / 分账 / 课酬(设计 §7.3 流程外延)。
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+DROP TABLE IF EXISTS `t_courses_record`;
|
|
|
|
|
+CREATE TABLE `t_courses_record` (
|
|
|
|
|
+ `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '上课记录ID(D3 自增)',
|
|
|
|
|
+ `biz_no` VARCHAR(32) NOT NULL COMMENT '业务单号(旧 UUID 主键原样保留,UNIQUE)',
|
|
|
|
|
+ `courses_id` BIGINT NOT NULL COMMENT '课程ID(原 coursesid)',
|
|
|
|
|
+ `class_id` BIGINT NOT NULL COMMENT '班级ID(原 classid)',
|
|
|
|
|
+ `teacher_id` VARCHAR(26) DEFAULT NULL COMMENT '老师(canonical_user_id ULID,原 teacherid)',
|
|
|
|
|
+ `institution_id` BIGINT NOT NULL DEFAULT 0 COMMENT '机构ID(原 schoolid;作用域列)',
|
|
|
|
|
+ `campus_id` BIGINT NOT NULL DEFAULT 0 COMMENT '校区ID(原 campusid;作用域列)',
|
|
|
|
|
+ `status` INT NOT NULL DEFAULT 0 COMMENT '状态(0未开始/1正在进行/2已结束)',
|
|
|
|
|
+ `changing_course` TINYINT NOT NULL DEFAULT 0 COMMENT '是否调课(1调课)',
|
|
|
|
|
+ `student_changing_course` INT NOT NULL DEFAULT 0 COMMENT '单学生调课数',
|
|
|
|
|
+ `transfer_student` TINYINT NOT NULL DEFAULT 0 COMMENT '是否有插班生(1有)',
|
|
|
|
|
+ `original_record_no` VARCHAR(32) DEFAULT NULL COMMENT '原上课记录单号(原 original_recordid UUID)',
|
|
|
|
|
+ `start_time` DATETIME(3) DEFAULT NULL COMMENT '上课时间',
|
|
|
|
|
+ `end_time` DATETIME(3) DEFAULT NULL COMMENT '下课时间',
|
|
|
|
|
+ `address` LONGTEXT DEFAULT NULL COMMENT '上课地点',
|
|
|
|
|
+ `actual_start_time` DATETIME(3) DEFAULT NULL COMMENT '实际上课时间',
|
|
|
|
|
+ `actual_end_time` DATETIME(3) DEFAULT NULL COMMENT '实际下课时间',
|
|
|
|
|
+ `student_number` INT NOT NULL DEFAULT 0 COMMENT '上课人数',
|
|
|
|
|
+ `income` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '课程收入(元)',
|
|
|
|
|
+ `teacher_reward` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '老师课酬',
|
|
|
|
|
+ `teacher_reward_type` TINYINT NOT NULL DEFAULT 1 COMMENT '课酬结算方式(1正常/2按原课程老师课酬无最低课酬)',
|
|
|
|
|
+ `expect_student_ids` VARCHAR(500) DEFAULT NULL COMMENT '要求上课的学生 id 列表(逗号分隔,原 expect_studentids)',
|
|
|
|
|
+ `remark` LONGTEXT DEFAULT NULL COMMENT '备注',
|
|
|
|
|
+ `created_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
|
|
|
|
+ PRIMARY KEY (`id`),
|
|
|
|
|
+ UNIQUE KEY `uk_biz_no` (`biz_no`),
|
|
|
|
|
+ KEY `idx_courses_start` (`courses_id`, `start_time`),
|
|
|
|
|
+ KEY `idx_teacher_start` (`teacher_id`, `start_time`),
|
|
|
|
|
+ KEY `idx_inst_campus` (`institution_id`, `campus_id`),
|
|
|
|
|
+ KEY `idx_status` (`status`)
|
|
|
|
|
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='课程记录(课表/排班实例·旧 UUID→biz_no)' ROW_FORMAT=Dynamic;
|
|
|
|
|
+
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+-- 21. t_courses_record_student(学生上课记录 = **打卡/考勤/扣课时**;旧 UUID 主键 → int64 + biz_no)
|
|
|
|
|
+-- 迁移源:t_courses_record_student(PK id varchar(32) UUID;cost/give_cost/teacher_reward float(10,3))
|
|
|
|
|
+-- type:1 正常 / 2 插班 / 3 赠送;pay:1 已支付
|
|
|
|
|
+-- 语义:一次打卡 = 一行;cost 为本次扣除课费;give_cost 为本次使用的赠送金额;
|
|
|
|
|
+-- divide_into_log_delete 用本表"首次 cost>0 且 end_time 非空"的记录判定分成归属。
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+DROP TABLE IF EXISTS `t_courses_record_student`;
|
|
|
|
|
+CREATE TABLE `t_courses_record_student` (
|
|
|
|
|
+ `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '记录ID(D3 自增)',
|
|
|
|
|
+ `biz_no` VARCHAR(32) NOT NULL COMMENT '业务单号(旧 UUID 主键原样保留,UNIQUE)',
|
|
|
|
|
+ `courses_id` BIGINT NOT NULL COMMENT '课程ID(原 coursesid)',
|
|
|
|
|
+ `class_id` BIGINT NOT NULL DEFAULT 0 COMMENT '班级ID(原 classid)',
|
|
|
|
|
+ `institution_id` BIGINT NOT NULL DEFAULT 0 COMMENT '机构ID(原 schoolid;作用域列)',
|
|
|
|
|
+ `campus_id` BIGINT NOT NULL DEFAULT 0 COMMENT '校区ID(原 campusid;作用域列)',
|
|
|
|
|
+ `record_id` BIGINT NOT NULL COMMENT '上课记录ID(原 recordid UUID → t_courses_record.id)',
|
|
|
|
|
+ `student_id` VARCHAR(26) NOT NULL COMMENT '学生(canonical_user_id ULID,原 studentid)',
|
|
|
|
|
+ `type` INT NOT NULL DEFAULT 1 COMMENT '上课类型(1正常/2插班/3赠送)',
|
|
|
|
|
+ `start_time` DATETIME(3) NOT NULL COMMENT '上课时间',
|
|
|
|
|
+ `end_time` DATETIME(3) DEFAULT NULL COMMENT '下课时间',
|
|
|
|
|
+ `cost` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '本次课程费用(扣课时金额)',
|
|
|
|
|
+ `give_cost` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '本次使用的赠送金额',
|
|
|
|
|
+ `teacher_reward` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '本次课老师课酬',
|
|
|
|
|
+ `pay` TINYINT NOT NULL DEFAULT 0 COMMENT '是否已支付(0未/1已支付)',
|
|
|
|
|
+ `remark` LONGTEXT DEFAULT NULL COMMENT '备注',
|
|
|
|
|
+ PRIMARY KEY (`id`),
|
|
|
|
|
+ UNIQUE KEY `uk_biz_no` (`biz_no`),
|
|
|
|
|
+ KEY `idx_record` (`record_id`),
|
|
|
|
|
+ KEY `idx_student_time` (`student_id`, `start_time`),
|
|
|
|
|
+ KEY `idx_inst_campus` (`institution_id`, `campus_id`)
|
|
|
|
|
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='课程上课记录(打卡/考勤/扣课时·旧 UUID→biz_no)' ROW_FORMAT=Dynamic;
|
|
|
|
|
+
|
|
|
|
|
+-- ============================================================================
|
|
|
|
|
+-- 第五部分:课酬与支出(6 表)
|
|
|
|
|
+-- 覆盖 SP:course_payment_detail_get_teacher_detail(多级回退匹配)
|
|
|
|
|
+-- ============================================================================
|
|
|
|
|
+
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+-- 22. t_course_payment(课酬方案,机构/校区级,按生效日期取最新)
|
|
|
|
|
+-- 迁移源:t_course_payment(id int AI;actived bit(1))
|
|
|
|
|
+-- 匹配规则(SP 两级回退):campus_id 命中机构+校区 → 回退 campus_id=0(机构级)。
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+DROP TABLE IF EXISTS `t_course_payment`;
|
|
|
|
|
+CREATE TABLE `t_course_payment` (
|
|
|
|
|
+ `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '方案ID(D3 自增)',
|
|
|
|
|
+ `institution_id` BIGINT NOT NULL DEFAULT 0 COMMENT '机构ID(原 schoolid;0=所有机构;作用域列)',
|
|
|
|
|
+ `campus_id` BIGINT NOT NULL DEFAULT 0 COMMENT '校区ID(原 campusid;0=机构所有校区)',
|
|
|
|
|
+ `name` VARCHAR(200) DEFAULT NULL COMMENT '方案名称',
|
|
|
|
|
+ `effect_date` DATETIME(3) DEFAULT NULL COMMENT '生效日期(取 effect_date<=当前 最新一条)',
|
|
|
|
|
+ `actived` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否生效(bit(1)→tinyint(1)/bool)',
|
|
|
|
|
+ `create_user_id` VARCHAR(26) DEFAULT NULL COMMENT '创建人(canonical_user_id ULID,原 create_userid)',
|
|
|
|
|
+ `create_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
|
|
|
|
+ `memo` LONGTEXT DEFAULT NULL COMMENT '备注',
|
|
|
|
|
+ PRIMARY KEY (`id`),
|
|
|
|
|
+ KEY `idx_inst_campus_actived_effect` (`institution_id`, `campus_id`, `actived`, `effect_date`)
|
|
|
|
|
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='课酬方案表(机构/校区级·按生效日期取最新)' ROW_FORMAT=Dynamic;
|
|
|
|
|
+
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+-- 23. t_course_payment_detail(课酬明细规则;三级回退匹配)
|
|
|
|
|
+-- 迁移源:t_course_payment_detail(id int AI;percentage/min_payment/max_payment/reward float(10,1);
|
|
|
|
|
+-- teacher_exp_min/max float(10,3);teacher_cert bit(1))
|
|
|
|
|
+-- grade_id / subject_id 支持 -1 通配(匹配逻辑保留旧口径,见设计 §3-5.2)
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+DROP TABLE IF EXISTS `t_course_payment_detail`;
|
|
|
|
|
+CREATE TABLE `t_course_payment_detail` (
|
|
|
|
|
+ `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '明细ID(D3 自增)',
|
|
|
|
|
+ `course_payment_id` BIGINT NOT NULL COMMENT '课酬方案ID(原 course_paymentid)',
|
|
|
|
|
+ `grade_id` INT NOT NULL DEFAULT -1 COMMENT '年级ID(-1所有/0混合)',
|
|
|
|
|
+ `subject_id` INT NOT NULL DEFAULT -1 COMMENT '科目ID(-1所有/0混合)',
|
|
|
|
|
+ `class_type` INT NOT NULL DEFAULT 0 COMMENT '班级类型(对应 t_courses_classify.class_type)',
|
|
|
|
|
+ `classify_id` BIGINT NOT NULL DEFAULT 0 COMMENT '课程分类ID(原 classifyid;个人配置维度)',
|
|
|
|
|
+ `teacher_id` VARCHAR(26) DEFAULT NULL COMMENT '老师(canonical_user_id ULID,原 teacherid;NULL/空=通用规则)',
|
|
|
|
|
+ `name` VARCHAR(300) DEFAULT NULL COMMENT '计算方式名称',
|
|
|
|
|
+ `percentage` DECIMAL(5,1) NOT NULL DEFAULT 0.0 COMMENT '课酬比例(百分比数字部分)',
|
|
|
|
|
+ `min_payment` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '最低课酬标准(元)',
|
|
|
|
|
+ `max_payment` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '最高课酬标准(元)',
|
|
|
|
|
+ `reward` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '额外课酬(元)',
|
|
|
|
|
+ `teacher_cert` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否持证(bit(1)→tinyint(1)/bool)',
|
|
|
|
|
+ `teacher_exp_min` DECIMAL(6,2) NOT NULL DEFAULT 0.00 COMMENT '教龄下限(年)',
|
|
|
|
|
+ `teacher_exp_max` DECIMAL(6,2) NOT NULL DEFAULT 0.00 COMMENT '教龄上限(年)',
|
|
|
|
|
+ `actived` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否生效(bit(1)→tinyint(1)/bool)',
|
|
|
|
|
+ `memo` LONGTEXT DEFAULT NULL COMMENT '备注',
|
|
|
|
|
+ PRIMARY KEY (`id`),
|
|
|
|
|
+ KEY `idx_payment` (`course_payment_id`),
|
|
|
|
|
+ KEY `idx_teacher_classify` (`teacher_id`, `class_type`, `classify_id`),
|
|
|
|
|
+ KEY `idx_cert_exp` (`teacher_cert`, `teacher_exp_min`, `teacher_exp_max`)
|
|
|
|
|
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='课酬明细规则表(个人→持证通用→无证通用 三级回退)' ROW_FORMAT=Dynamic;
|
|
|
|
|
+
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+-- 24. t_teacher_information(教师扩展:资格证 + 教龄)
|
|
|
|
|
+-- 迁移源:t_teacher_information(PK teacherid int;teacher_cert bit(1);teacher_exp date)
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+DROP TABLE IF EXISTS `t_teacher_information`;
|
|
|
|
|
+CREATE TABLE `t_teacher_information` (
|
|
|
|
|
+ `teacher_id` VARCHAR(26) NOT NULL COMMENT '老师(canonical_user_id ULID,原 teacherid,主键)',
|
|
|
|
|
+ `teacher_cert` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '教师资格证(bit(1)→tinyint(1)/bool;0无/1有)',
|
|
|
|
|
+ `teacher_exp` DATE DEFAULT NULL COMMENT '教龄起算日(date)',
|
|
|
|
|
+ `created_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
|
|
|
|
+ `updated_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间',
|
|
|
|
|
+ PRIMARY KEY (`teacher_id`)
|
|
|
|
|
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='教师扩展信息表(资格证/教龄)' ROW_FORMAT=Dynamic;
|
|
|
|
|
+
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+-- 25. t_teacher_courses_percentage(老师课酬提成/固定课酬,UK(type, teacher_id))
|
|
|
|
|
+-- 迁移源:t_teacher_courses_percentage(id int AI;多列 float + *_extend 字符串/文本扩展)
|
|
|
|
|
+-- 说明:*_extend 为 JSON/逗号扩展串(按年级/科目分档),目标态**原样保留字符串**不结构化
|
|
|
|
|
+-- (保结构稳定;解析在 Service 层,见 §11-3 待补盘点)。
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+DROP TABLE IF EXISTS `t_teacher_courses_percentage`;
|
|
|
|
|
+CREATE TABLE `t_teacher_courses_percentage` (
|
|
|
|
|
+ `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '记录ID(D3 自增)',
|
|
|
|
|
+ `type` INT NOT NULL DEFAULT 1000 COMMENT '课程类型(class_type)',
|
|
|
|
|
+ `payment_method` TINYINT NOT NULL DEFAULT 1 COMMENT '结算方式(1提成结算/2现金结算)',
|
|
|
|
|
+ `teacher_id` VARCHAR(26) NOT NULL COMMENT '老师(canonical_user_id ULID,原 teacherid)',
|
|
|
|
|
+ `percentage` INT NOT NULL DEFAULT 0 COMMENT '提成比例(%)',
|
|
|
|
|
+ `cost` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '一次课课酬',
|
|
|
|
|
+ `added_cost` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '额外费用(比例基础上追加)',
|
|
|
|
|
+ `percentage_extend` VARCHAR(500) DEFAULT NULL COMMENT '提成比例扩展(原样保留)',
|
|
|
|
|
+ `cost_extend` VARCHAR(500) DEFAULT NULL COMMENT '固定课酬扩展(原样保留)',
|
|
|
|
|
+ `max_reward` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '最大课酬(一次课)',
|
|
|
|
|
+ `max_reward_extend` LONGTEXT DEFAULT NULL COMMENT '最大课酬扩展(按年级分档)',
|
|
|
|
|
+ `min_reward` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '最小课酬(一次课)',
|
|
|
|
|
+ `min_reward_extend` VARCHAR(500) DEFAULT NULL COMMENT '最小课酬扩展(原样保留)',
|
|
|
|
|
+ `effective_date` DATE DEFAULT NULL COMMENT '课酬生效日期',
|
|
|
|
|
+ `created_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
|
|
|
|
+ `updated_at` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间',
|
|
|
|
|
+ PRIMARY KEY (`id`),
|
|
|
|
|
+ UNIQUE KEY `uk_type_teacher` (`type`, `teacher_id`)
|
|
|
|
|
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='老师课酬提成表(提成/固定两制·UK type+teacher)' ROW_FORMAT=Dynamic;
|
|
|
|
|
+
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+-- 26. t_expenditure(收支类型字典,自引用树)
|
|
|
|
|
+-- 迁移源:t_expenditure(id int AI;type 1支出/2收入;parentid)
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+DROP TABLE IF EXISTS `t_expenditure`;
|
|
|
|
|
+CREATE TABLE `t_expenditure` (
|
|
|
|
|
+ `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '类型ID(D3 自增)',
|
|
|
|
|
+ `type` INT NOT NULL DEFAULT 1 COMMENT '类型(1支出/2收入)',
|
|
|
|
|
+ `parent_id` BIGINT NOT NULL DEFAULT 0 COMMENT '父类型ID(原 parentid;0=顶级)',
|
|
|
|
|
+ `name` VARCHAR(500) NOT NULL COMMENT '名称',
|
|
|
|
|
+ `remark` LONGTEXT DEFAULT NULL COMMENT '备注',
|
|
|
|
|
+ `institution_id` BIGINT NOT NULL DEFAULT 0 COMMENT '机构ID(新增作用域列;0=平台通用字典)',
|
|
|
|
|
+ PRIMARY KEY (`id`),
|
|
|
|
|
+ KEY `idx_parent` (`parent_id`),
|
|
|
|
|
+ KEY `idx_inst_type` (`institution_id`, `type`)
|
|
|
|
|
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='收支类型字典表(自引用树·支出/收入)' ROW_FORMAT=Dynamic;
|
|
|
|
|
+
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+-- 27. t_expenditure_log(收支记录,旧 UUID 主键 → int64 + biz_no)
|
|
|
|
|
+-- 迁移源:t_expenditure_log(PK id varchar(32) UUID;cost float(10,3);year year/month tinyint)
|
|
|
|
|
+-- 说明:year/month 为报表分桶冗余列,目标态保留(避免月度报表改 SQL)。
|
|
|
|
|
+-- ----------------------------------------------------------------------------
|
|
|
|
|
+DROP TABLE IF EXISTS `t_expenditure_log`;
|
|
|
|
|
+CREATE TABLE `t_expenditure_log` (
|
|
|
|
|
+ `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '记录ID(D3 自增)',
|
|
|
|
|
+ `biz_no` VARCHAR(32) NOT NULL COMMENT '业务单号(旧 UUID 主键原样保留,UNIQUE)',
|
|
|
|
|
+ `institution_id` BIGINT NOT NULL DEFAULT 0 COMMENT '机构ID(原 schoolid;作用域列)',
|
|
|
|
|
+ `campus_id` BIGINT NOT NULL DEFAULT 0 COMMENT '校区ID(原 campusid;作用域列)',
|
|
|
|
|
+ `expenditure_id` BIGINT NOT NULL DEFAULT 0 COMMENT '收支类型ID(原 expenditureid → t_expenditure.id)',
|
|
|
|
|
+ `cost` DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT '费用(元;旧 float(10,3) 收敛)',
|
|
|
|
|
+ `create_user_id` VARCHAR(26) DEFAULT NULL COMMENT '创建人(canonical_user_id ULID,原 create_userid)',
|
|
|
|
|
+ `create_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
|
|
|
|
+ `year` SMALLINT DEFAULT NULL COMMENT '收支年份(报表分桶冗余列,原 year)',
|
|
|
|
|
+ `month` TINYINT DEFAULT NULL COMMENT '收支月份(报表分桶冗余列,原 month)',
|
|
|
|
|
+ `remark` LONGTEXT DEFAULT NULL COMMENT '备注',
|
|
|
|
|
+ `imgs` LONGTEXT DEFAULT NULL COMMENT '图片地址(JSON 字符串)',
|
|
|
|
|
+ PRIMARY KEY (`id`),
|
|
|
|
|
+ UNIQUE KEY `uk_biz_no` (`biz_no`),
|
|
|
|
|
+ KEY `idx_inst_campus_time` (`institution_id`, `campus_id`, `create_time`),
|
|
|
|
|
+ KEY `idx_expenditure` (`expenditure_id`),
|
|
|
|
|
+ KEY `idx_year_month` (`year`, `month`)
|
|
|
|
|
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='收支记录表(旧 UUID→int64+biz_no)' ROW_FORMAT=Dynamic;
|
|
|
|
|
+
|
|
|
|
|
+SET FOREIGN_KEY_CHECKS = 1;
|
|
|
|
|
+
|
|
|
|
|
+-- ============================================================================
|
|
|
|
|
+-- 未纳入目标态的表(旧库 44 表中本域 30 表的处置说明)
|
|
|
|
|
+-- ============================================================================
|
|
|
|
|
+-- 【P2 暂不建(本期不承载业务,迁移期只归档,见设计 §11)】
|
|
|
|
|
+-- · t_user_money_summary / t_user_money_summary_school
|
|
|
|
|
+-- —— PHP 全仓 0 引用(grep 实测 count=0),实际未使用的汇总表;
|
|
|
|
|
+-- 目标态用视图/实时聚合替代,不建冗余汇总表(§11-8)。
|
|
|
|
|
+-- · t_user_balance_log
|
|
|
|
|
+-- —— 仅 UserBalanceLogHelper 存在、业务无调用点;已被 t_user_expense_log 取代(§11-9)。
|
|
|
|
|
+-- · t_courses_classify_edit_log / t_courses_record_student_copy / t_course_payment_detail_copy
|
|
|
|
|
+-- —— 备份/编辑留痕副本表,迁移后由 t_audit_log 覆盖。
|
|
|
|
|
+-- · tmp_replace_userid
|
|
|
|
|
+-- —— 一次性临时表。
|
|
|
|
|
+-- 【P2 待补盘点后建(课程域深水区,本期只做最小闭环)】
|
|
|
|
|
+-- · t_courses_change_student(调课)/ t_courses_closure_request(结课申请)/
|
|
|
|
|
+-- t_courses_other_request(课程其他申请)/ t_courses_record_send_msg_log(上课通知)/
|
|
|
|
|
+-- t_student_archives(学员档案)/ t_student_test_paper_achievement(测评成绩)
|
|
|
|
|
+-- · t_wechat_send_log(跨域,归 teaching/notification)
|
|
|
|
|
+-- · t_help / t_menu(平台级配置,归 org 域)
|
|
|
|
|
+-- ============================================================================
|
|
|
|
|
+
|
|
|
|
|
+-- ============================================================================
|
|
|
|
|
+-- ERD(ASCII,27 表关系主干)
|
|
|
|
|
+-- ============================================================================
|
|
|
|
|
+--
|
|
|
|
|
+-- 【资金】
|
|
|
|
|
+-- t_user_expense(user_id PK) 1──────────────────* t_user_expense_school(id PK, UK user+inst+campus)
|
|
|
|
|
+-- │ │
|
|
|
|
|
+-- │ user_id │ user_id
|
|
|
|
|
+-- └──────────────┬─────────────────────────────────────┘
|
|
|
|
|
+-- ▼
|
|
|
|
|
+-- t_user_expense_log(id PK)
|
|
|
|
|
+-- · type 编码 20+ 种(100/106/107/108/206/207/208/209…)
|
|
|
|
|
+-- · request_id + type 唯一 = 幂等键
|
|
|
|
|
+-- ▲
|
|
|
|
|
+-- t_user_balance_request(id PK, biz_no UK) ─── approved=1 触发资金方法 ──┘
|
|
|
|
|
+-- │ biz_no
|
|
|
|
|
+-- ▼
|
|
|
|
|
+-- t_order_pay(id PK, biz_no UK) t_payment_log(biz_no UK, 只读历史)
|
|
|
|
|
+--
|
|
|
|
|
+-- 【活动】 t_courses_activity(id PK)
|
|
|
|
|
+-- │ 1
|
|
|
|
|
+-- ├────* t_courses_activity_signed(id PK, UK user+activity) ── status 状态机 0/1/2/3/4
|
|
|
|
|
+-- ├────* t_courses_activity_user_discount(id PK) ── 赠送金额池
|
|
|
|
|
+-- │ │ 1
|
|
|
|
|
+-- │ └──* t_courses_activity_user_discount_log(id PK) ── 负=消费/正=退回
|
|
|
|
|
+-- ├────* t_courses_activity_used_log(id PK) ── 老带新结算(负值)
|
|
|
|
|
+-- ├────* t_courses_activity_request(id PK, biz_no UK)
|
|
|
|
|
+-- └────* t_courses_activity_visit(id PK, activity_signed_id)
|
|
|
|
|
+--
|
|
|
|
|
+-- 【分账】 t_user_divide_into(user_id PK, Nested Set: root_user_id/left_val/right_val/layer)
|
|
|
|
|
+-- │ 1
|
|
|
|
|
+-- └────* t_user_divide_into_log(id PK) · type=1 per student / type=2 per order
|
|
|
|
|
+--
|
|
|
|
|
+-- 【课程】 t_courses_classify(id PK) 1────* t_courses(id PK) 1────* t_courses_class(id PK) ← 排班规则
|
|
|
|
|
+-- │1 │1
|
|
|
|
|
+-- ├────* t_courses_student(id PK, biz_no UK) ← 报课/学费账户
|
|
|
|
|
+-- └────* t_courses_record(id PK, biz_no UK) ← 排班实例
|
|
|
|
|
+-- │1
|
|
|
|
|
+-- └──* t_courses_record_student(id PK, biz_no UK) ← 打卡
|
|
|
|
|
+--
|
|
|
|
|
+-- 【课酬】 t_course_payment(id PK) 1────* t_course_payment_detail(id PK)
|
|
|
|
|
+-- t_teacher_information(teacher_id PK) t_teacher_courses_percentage(id PK, UK type+teacher)
|
|
|
|
|
+-- 提供 get_teacher_detail 的输入(教龄/持证/个人配置/通用档)
|
|
|
|
|
+--
|
|
|
|
|
+-- 【支出】 t_expenditure(id PK, 自引用 parent_id) 1────* t_expenditure_log(id PK, biz_no UK)
|
|
|
|
|
+--
|
|
|
|
|
+-- 关系基线(无物理 FK,全部应用层保证):
|
|
|
|
|
+-- · 所有 *_id 引用 canonical_user_id 的列 = VARCHAR(26) ULID;机构/校区 = BIGINT
|
|
|
|
|
+-- · 旧 UUID 主键表(7 张)保留 biz_no UNIQUE,迁移/回滚/割接双跑的对账锚点
|
|
|
|
|
+-- · 多租户表(带 institution_id/campus_id)= _school / activity* / courses* / payroll / expenditure*;
|
|
|
|
|
+-- Repository 强制 BaseRepo.Scoping(跨作用域 → 1004)
|
|
|
|
|
+-- · 无作用域表 = t_user_expense(全局钱包)/ t_user_divide_into*(全局推广体系)
|
|
|
|
|
+-- → 不继承 BaseRepo,作用域断言在 Service 层(见设计 §1.7)
|
|
|
|
|
+-- ============================================================================
|
|
|
|
|
+
|
|
|
|
|
+-- ============================================================================
|
|
|
|
|
+-- 迁移落点调整(对 03-migration/stage0/migration-mapping.sql 的影响,T5 执行)
|
|
|
|
|
+-- ============================================================================
|
|
|
|
|
+-- 1. 本域 27 表 INSERT...SELECT 全部经 t_legacy_mapping 重映射用户列:
|
|
|
|
|
+-- `JOIN t_legacy_mapping lm ON lm.legacy_academic_user_id = 旧.userid`
|
|
|
|
|
+-- 取 lm.canonical_user_id 落 user_id/student_id/teacher_id/…(ADR-013:旧 int 只进映射表)。
|
|
|
|
|
+-- 2. schoolid → institution_id、campusid → campus_id 直改列名(值不变,1:1)。
|
|
|
|
|
+-- 3. 旧 varchar(32) UUID 主键 → biz_no 原样搬;新 id 由自增生成。
|
|
|
|
|
+-- 4. 表间 UUID 引用列重映射:
|
|
|
|
|
+-- · t_courses_activity_signed.requestid → request_no(保留字符串,指向 t_user_balance_request.biz_no)
|
|
|
|
|
+-- · t_courses_activity_user_discount.balance_requestid → balance_request_id(VARCHAR→BIGINT,
|
|
|
|
|
+-- JOIN t_user_balance_request ON biz_no)
|
|
|
|
|
+-- · t_courses_activity_user_discount_log.courses_studentid → courses_student_id(JOIN t_courses_student ON biz_no)
|
|
|
|
|
+-- · t_courses_record_student.recordid → record_id(JOIN t_courses_record ON biz_no)
|
|
|
|
|
+-- · t_courses_activity_used_log.orderid → order_no(保留字符串:老带新=报课 biz_no,copy 重放=courses_studentid)
|
|
|
|
|
+-- 5. 金额列 float(10,2/3)/double(10,3)/decimal(10,3) → decimal(12,2):`ROUND(x,2)`。
|
|
|
|
|
+-- **3 位小数的舍入差异须逐表出 diff 台账**(行数 / 前 20 行明细 / 差额绝对值合计),
|
|
|
|
|
+-- 超阈值(> 0.01 × 行数)升级人工核对(§11-7)。
|
|
|
|
|
+-- 6. bit(1)(actived/teacher_cert)→ tinyint(1):`IF(x=1,1,0)`。
|
|
|
|
|
+-- 7. 时间 datetime(0) → datetime(3):`DATE_FORMAT` 补 `.000`(或直迁,MySQL 自动补 000)。
|
|
|
|
|
+-- 8. 冗余列回填(迁移后一次性):
|
|
|
|
|
+-- · t_courses_activity_signed.institution_id/campus_id ← JOIN t_courses_activity
|
|
|
|
|
+-- · t_user_expense_log.balance_after 保持 NULL(历史无快照,双跑仅比新写入行)
|
|
|
|
|
+-- 9. 索引重建:本文件索引为运行态口径;迁移期可先 `ALTER TABLE ... DISABLE KEYS` 批量导入后重建。
|
|
|
|
|
+-- ============================================================================
|
|
|
|
|
+
|
|
|
|
|
+-- 执行顺序:1..27(无物理外键,顺序不强制;按 资金→活动→分账→课程→课酬/支出 排列)
|
|
|
|
|
+-- 验证(建表后 information_schema 逐列核对,对齐门禁 §4):
|
|
|
|
|
+-- · 所有 user_id/student_id/teacher_id/create_user_id/request_user_id/response_user_id/
|
|
|
|
|
+-- recommend_user_id/confirm_discount_user_id/recommender_user_id = varchar(26)
|
|
|
|
|
+-- · 所有 institution_id/campus_id = bigint
|
|
|
|
|
+-- · 所有金额列(balance/spend/total_*/special_expenses/money/cost/receivable/unpaid/…)
|
|
|
|
|
+-- = decimal(12,2) —— 例外(精度保留):t_courses.duration decimal(5,1)、
|
|
|
|
|
+-- t_course_payment_detail.percentage decimal(5,1)、teacher_exp_min/max decimal(6,2)
|
|
|
|
|
+-- · 所有时间列 = datetime(3)(例外:t_teacher_information.teacher_exp / effective_date = date)
|
|
|
|
|
+-- · 字符集全部 utf8mb4 / utf8mb4_general_ci;ROW_FORMAT=Dynamic
|
|
|
|
|
+-- · 7 张旧 UUID 表 biz_no 均为 VARCHAR(32) NOT NULL + UNIQUE
|
|
|
|
|
+-- ============================================================================
|