新增支付宝连接沙箱模拟支付(暂不可用

This commit was merged in pull request #35.
This commit is contained in:
2026-06-24 04:59:32 +08:00
parent 4481819eba
commit 2251f31524
42 changed files with 2571 additions and 991 deletions
@@ -1,86 +0,0 @@
-- V10: 团课预约业务场景测试数据
-- 测试场景:
-- 1. 用户A刚刚注册,在没有任何会员卡的情况下申请团课预约
-- 2. 用户B已有时长卡,但已经过期
-- 3. 会员C有时长卡,未过期
-- 4. 会员D有次数卡,但次数卡耗尽次数
-- 5. 会员E有次数卡,且次数充足
-- 6. 会员F有储值卡,但余额不足以支付其预约的团课
-- 7. 会员G有储值卡,余额充足
-- ============================================
-- 1. 创建测试会员用户 (A-G)
-- ============================================
INSERT INTO member_user (member_no, nickname, phone, gender, is_deleted, created_at, updated_at) VALUES
('MEM_TEST_A', '用户A_无卡新用户', '13800001001', 1, false, '2026-06-02 10:00:00', '2026-06-02 10:00:00'),
('MEM_TEST_B', '用户B_过期时长卡', '13800001002', 1, false, '2026-05-01 10:00:00', '2026-05-01 10:00:00'),
('MEM_TEST_C', '会员C_有效时长卡', '13800001003', 2, false, '2026-05-01 10:00:00', '2026-05-01 10:00:00'),
('MEM_TEST_D', '会员D_次数用尽', '13800001004', 1, false, '2026-05-01 10:00:00', '2026-05-01 10:00:00'),
('MEM_TEST_E', '会员E_次数充足', '13800001005', 2, false, '2026-05-01 10:00:00', '2026-05-01 10:00:00'),
('MEM_TEST_F', '会员F_储值卡余额不足', '13800001006', 1, false, '2026-05-01 10:00:00', '2026-05-01 10:00:00'),
('MEM_TEST_G', '会员G_储值卡余额充足', '13800001007', 2, false, '2026-05-01 10:00:00', '2026-05-01 10:00:00');
-- ============================================
-- 2. 团课课程测试数据(用于预约测试)
-- ============================================
-- 团课A: 收费类型为次数卡(点卡额度=1)
INSERT INTO group_course (course_name, coach_id, course_type, start_time, end_time, max_members, current_members, status, location, description, point_card_amount, stored_value_amount, create_by, created_at, updated_at) VALUES
('燃脂搏击_次数卡课程', 102, 2, '2026-06-10 19:30:00', '2026-06-10 20:30:00', 20, 0, '0', '综合训练区', '高强度间歇训练,配合音乐快速燃脂,消耗1次', 1, 0.00, 'admin', '2026-06-01 10:00:00', '2026-06-01 10:00:00');
-- 团课B: 收费类型为储值卡(储值额度=50.00)
INSERT INTO group_course (course_name, coach_id, course_type, start_time, end_time, max_members, current_members, status, location, description, point_card_amount, stored_value_amount, create_by, created_at, updated_at) VALUES
('高端普拉提_储值卡课程', 103, 1, '2026-06-11 19:00:00', '2026-06-11 20:00:00', 15, 0, '0', '普拉提教室', '精准训练核心肌群,消耗储值50元', 0, 20.00, 'admin', '2026-06-01 10:00:00', '2026-06-01 10:00:00');
-- ============================================
-- 3. 会员卡类型定义
-- ============================================
INSERT INTO member_card (member_card_name, member_card_type, member_card_price, member_card_validity_days, member_card_total_times, member_card_amount, member_card_status, extra_config, created_at, updated_at) VALUES
('30天时长卡', 'TIME_CARD', 299.00, 30, NULL, NULL, 1, '{}', '2026-01-01 00:00:00', '2026-01-01 00:00:00'),
('10次卡', 'COUNT_CARD', 499.00, NULL, 10, NULL, 1, '{}', '2026-01-01 00:00:00', '2026-01-01 00:00:00'),
('储值卡500', 'STORED_VALUE_CARD', 500.00, NULL, NULL, 500.00, 1, '{}', '2026-01-01 00:00:00', '2026-01-01 00:00:00');
-- ============================================
-- 4. 会员卡记录测试数据
-- ============================================
-- 场景2: 用户B - 时长卡已过期 (expire_time < 当前时间)
-- 购买于30天前,有效期30天,现已过期
INSERT INTO member_card_record (member_id, member_card_id, status, remaining_times, remaining_amount, expire_time, purchase_time, version, card_composition, created_at, updated_at) VALUES
((SELECT id FROM member_user WHERE member_no = 'MEM_TEST_B'), (SELECT member_card_id FROM member_card WHERE member_card_name = '30天时长卡'), 'EXPIRED', 0, 0.00, '2026-05-31 23:59:59', '2026-05-01 10:00:00', 0, '{}', '2026-05-01 10:00:00', '2026-06-02 10:00:00');
-- 场景3: 会员C - 时长卡未过期 (expire_time > 当前时间)
-- 购买于今天,有效期30天,还有30天有效期
INSERT INTO member_card_record (member_id, member_card_id, status, remaining_times, remaining_amount, expire_time, purchase_time, version, card_composition, created_at, updated_at) VALUES
((SELECT id FROM member_user WHERE member_no = 'MEM_TEST_C'), (SELECT member_card_id FROM member_card WHERE member_card_name = '30天时长卡'), 'ACTIVE', 0, 0.00, '2026-07-02 23:59:59', '2026-06-02 10:00:00', 0, '{}', '2026-06-02 10:00:00', '2026-06-02 10:00:00');
-- 场景4: 会员D - 次数卡耗尽 (remaining_times = 0)
INSERT INTO member_card_record (member_id, member_card_id, status, remaining_times, remaining_amount, expire_time, purchase_time, version, card_composition, created_at, updated_at) VALUES
((SELECT id FROM member_user WHERE member_no = 'MEM_TEST_D'), (SELECT member_card_id FROM member_card WHERE member_card_name = '10次卡'), 'ACTIVE', 0, 0.00, '2026-12-31 23:59:59', '2026-05-01 10:00:00', 0, '{}', '2026-05-01 10:00:00', '2026-06-02 10:00:00');
-- 场景5: 会员E - 次数卡充足 (remaining_times >= point_card_amount)
INSERT INTO member_card_record (member_id, member_card_id, status, remaining_times, remaining_amount, expire_time, purchase_time, version, card_composition, created_at, updated_at) VALUES
((SELECT id FROM member_user WHERE member_no = 'MEM_TEST_E'), (SELECT member_card_id FROM member_card WHERE member_card_name = '10次卡'), 'ACTIVE', 5, 0.00, '2026-12-31 23:59:59', '2026-05-01 10:00:00', 0, '{}', '2026-05-01 10:00:00', '2026-06-02 10:00:00');
-- 场景6: 会员F - 储值卡余额不足 (remaining_amount < stored_value_amount of course)
-- 团课B收费50元,但会员F储值卡只有30元
INSERT INTO member_card_record (member_id, member_card_id, status, remaining_times, remaining_amount, expire_time, purchase_time, version, card_composition, created_at, updated_at) VALUES
((SELECT id FROM member_user WHERE member_no = 'MEM_TEST_F'), (SELECT member_card_id FROM member_card WHERE member_card_name = '储值卡500'), 'ACTIVE', 0, 30.00, '2027-06-02 23:59:59', '2026-05-01 10:00:00', 0, '{}', '2026-05-01 10:00:00', '2026-06-02 10:00:00');
-- 场景7: 会员G - 储值卡余额充足 (remaining_amount >= stored_value_amount of course)
INSERT INTO member_card_record (member_id, member_card_id, status, remaining_times, remaining_amount, expire_time, purchase_time, version, card_composition, created_at, updated_at) VALUES
((SELECT id FROM member_user WHERE member_no = 'MEM_TEST_G'), (SELECT member_card_id FROM member_card WHERE member_card_name = '储值卡500'), 'ACTIVE', 0, 200.00, '2027-06-02 23:59:59', '2026-05-01 10:00:00', 0, '{}', '2026-05-01 10:00:00', '2026-06-02 10:00:00');
-- ============================================
-- 5. 测试场景说明
-- ============================================
-- 场景1: 用户A无会员卡 -> 预约团课时应提示"无可用会员卡"
-- 场景2: 用户B时长卡已过期 -> 预约团课时应提示"会员卡已过期"
-- 场景3: 会员C时长卡有效 -> 可以正常预约次数卡团课
-- 场景4: 会员D次数为0 -> 预约团课时应提示"剩余次数不足"
-- 场景5: 会员E次数充足 -> 可以正常预约次数卡团课
-- 场景6: 会员F储值卡余额30元,团课需50元 -> 预约时应提示"余额不足"
-- 场景7: 会员G储值卡余额200元,团课需50元 -> 可以正常预约储值卡团课
@@ -1,116 +0,0 @@
-- V11: 团课预约取消业务场景测试数据
-- 测试场景:
-- 1. 用户张三使用时长卡预约了团课,需要取消预约
-- 2. 用户李四使用次数卡预约了团课,需要取消预约
-- 3. 用户王五使用储值卡预约了团课,需要取消预约
-- ============================================
-- 1. 创建测试会员用户 (张三、李四、王五)
-- ============================================
INSERT INTO member_user (member_no, nickname, phone, gender, is_deleted, created_at, updated_at) VALUES
('MEM_TEST_ZHANG', '张三_时长卡用户', '13800002001', 1, false, '2026-06-02 10:00:00', '2026-06-02 10:00:00'),
('MEM_TEST_LI', '李四_次数卡用户', '13800002002', 1, false, '2026-06-02 10:00:00', '2026-06-02 10:00:00'),
('MEM_TEST_WANG', '王五_储值卡用户', '13800002003', 2, false, '2026-06-02 10:00:00', '2026-06-02 10:00:00');
-- ============================================
-- 2. 确保会员卡类型已存在(如果不存在则创建)
-- ============================================
-- 时长卡类型(30天)
INSERT INTO member_card (member_card_name, member_card_type, member_card_price, member_card_validity_days, member_card_total_times, member_card_amount, member_card_status, extra_config, created_at, updated_at)
SELECT '30天时长卡', 'TIME_CARD', 299.00, 30, NULL, NULL, 1, '{}', '2026-01-01 00:00:00', '2026-01-01 00:00:00'
WHERE NOT EXISTS (SELECT 1 FROM member_card WHERE member_card_name = '30天时长卡');
-- 次数卡类型(10次)
INSERT INTO member_card (member_card_name, member_card_type, member_card_price, member_card_validity_days, member_card_total_times, member_card_amount, member_card_status, extra_config, created_at, updated_at)
SELECT '10次卡', 'COUNT_CARD', 499.00, NULL, 10, NULL, 1, '{}', '2026-01-01 00:00:00', '2026-01-01 00:00:00'
WHERE NOT EXISTS (SELECT 1 FROM member_card WHERE member_card_name = '10次卡');
-- 储值卡类型(500元)
INSERT INTO member_card (member_card_name, member_card_type, member_card_price, member_card_validity_days, member_card_total_times, member_card_amount, member_card_status, extra_config, created_at, updated_at)
SELECT '储值卡500', 'STORED_VALUE_CARD', 500.00, NULL, NULL, 500.00, 1, '{}', '2026-01-01 00:00:00', '2026-01-01 00:00:00'
WHERE NOT EXISTS (SELECT 1 FROM member_card WHERE member_card_name = '储值卡500');
-- ============================================
-- 3. 为测试用户分配会员卡
-- ============================================
-- 张三:时长卡(有效期内)
INSERT INTO member_card_record (member_id, member_card_id, status, remaining_times, remaining_amount, expire_time, purchase_time, version, card_composition, created_at, updated_at) VALUES
((SELECT id FROM member_user WHERE member_no = 'MEM_TEST_ZHANG'),
(SELECT member_card_id FROM member_card WHERE member_card_name = '30天时长卡'),
'ACTIVE', 0, 0.00, '2026-07-02 23:59:59', '2026-06-02 10:00:00', 0, '{}', '2026-06-02 10:00:00', '2026-06-02 10:00:00');
-- 李四:次数卡(剩余5次)
INSERT INTO member_card_record (member_id, member_card_id, status, remaining_times, remaining_amount, expire_time, purchase_time, version, card_composition, created_at, updated_at) VALUES
((SELECT id FROM member_user WHERE member_no = 'MEM_TEST_LI'),
(SELECT member_card_id FROM member_card WHERE member_card_name = '10次卡'),
'ACTIVE', 5, 0.00, '2026-12-31 23:59:59', '2026-05-01 10:00:00', 0, '{}', '2026-05-01 10:00:00', '2026-06-02 10:00:00');
-- 王五:储值卡(余额200元)
INSERT INTO member_card_record (member_id, member_card_id, status, remaining_times, remaining_amount, expire_time, purchase_time, version, card_composition, created_at, updated_at) VALUES
((SELECT id FROM member_user WHERE member_no = 'MEM_TEST_WANG'),
(SELECT member_card_id FROM member_card WHERE member_card_name = '储值卡500'),
'ACTIVE', 0, 200.00, '2027-06-02 23:59:59', '2026-05-01 10:00:00', 0, '{}', '2026-05-01 10:00:00', '2026-06-02 10:00:00');
-- ============================================
-- 4. 创建用于取消预约测试的团课
-- ============================================
-- 团课X: 时长卡可用课程(使用次数卡支付,时长卡会员可预约)
INSERT INTO group_course (course_name, coach_id, course_type, start_time, end_time, max_members, current_members, status, location, description, point_card_amount, stored_value_amount, create_by, created_at, updated_at) VALUES
('晚间瑜伽_取消测试', 101, 1, '2026-06-15 19:00:00', '2026-06-15 20:00:00', 20, 0, '0', '瑜伽教室', '适合所有级别的瑜伽课程,用于测试取消预约功能', 1, 30.00, 'admin', '2026-06-02 10:00:00', '2026-06-02 10:00:00');
-- ============================================
-- 5. 创建已预约的记录(状态为0-已预约)
-- ============================================
-- 张三使用时长卡预约团课(状态:已预约)
INSERT INTO group_course_booking (course_id, member_id, member_card_id, booking_time, status, course_name, course_start_time, course_end_time, location, created_at, updated_at) VALUES
((SELECT id FROM group_course WHERE course_name = '晚间瑜伽_取消测试'),
(SELECT id FROM member_user WHERE member_no = 'MEM_TEST_ZHANG'),
(SELECT id FROM member_card_record WHERE member_id = (SELECT id FROM member_user WHERE member_no = 'MEM_TEST_ZHANG')),
'2026-06-02 11:00:00', '0', '晚间瑜伽_取消测试', '2026-06-15 19:00:00', '2026-06-15 20:00:00', '瑜伽教室',
'2026-06-02 11:00:00', '2026-06-02 11:00:00');
-- 李四使用次数卡预约团课(状态:已预约)
INSERT INTO group_course_booking (course_id, member_id, member_card_id, booking_time, status, course_name, course_start_time, course_end_time, location, created_at, updated_at) VALUES
((SELECT id FROM group_course WHERE course_name = '晚间瑜伽_取消测试'),
(SELECT id FROM member_user WHERE member_no = 'MEM_TEST_LI'),
(SELECT id FROM member_card_record WHERE member_id = (SELECT id FROM member_user WHERE member_no = 'MEM_TEST_LI')),
'2026-06-02 11:30:00', '0', '晚间瑜伽_取消测试', '2026-06-15 19:00:00', '2026-06-15 20:00:00', '瑜伽教室',
'2026-06-02 11:30:00', '2026-06-02 11:30:00');
-- 王五使用储值卡预约团课(状态:已预约)
INSERT INTO group_course_booking (course_id, member_id, member_card_id, booking_time, status, course_name, course_start_time, course_end_time, location, created_at, updated_at) VALUES
((SELECT id FROM group_course WHERE course_name = '晚间瑜伽_取消测试'),
(SELECT id FROM member_user WHERE member_no = 'MEM_TEST_WANG'),
(SELECT id FROM member_card_record WHERE member_id = (SELECT id FROM member_user WHERE member_no = 'MEM_TEST_WANG')),
'2026-06-02 12:00:00', '0', '晚间瑜伽_取消测试', '2026-06-15 19:00:00', '2026-06-15 20:00:00', '瑜伽教室',
'2026-06-02 12:00:00', '2026-06-02 12:00:00');
-- ============================================
-- 6. 更新团课当前预约人数
-- ============================================
UPDATE group_course
SET current_members = current_members + 3
WHERE course_name = '晚间瑜伽_取消测试';
-- ============================================
-- 测试数据说明
-- ============================================
-- 用户信息:
-- 张三 (MEM_TEST_ZHANG): 13800002001 - 持有有效期内的时长卡
-- 李四 (MEM_TEST_LI): 13800002002 - 持有次数卡(剩余5次)
-- 王五 (MEM_TEST_WANG): 13800002003 - 持有储值卡(余额200元)
-- 测试场景:
-- 1. 张三使用时长卡预约了团课 -> 取消预约 -> 应恢复时长卡状态,释放课程名额
-- 2. 李四使用次数卡预约了团课 -> 取消预约 -> 应返还扣除的次数,释放课程名额
-- 3. 王五使用储值卡预约了团课 -> 取消预约 -> 应返还扣除的金额,释放课程名额
-- 预约记录状态说明:
-- status = '0' 表示已预约
-- status = '1' 表示已取消(取消后应更新为此状态)
@@ -1,58 +0,0 @@
-- V12: 团课预约时间冲突测试数据
-- 测试场景:会员预约两个时间重叠的团课时,系统应检测到时间冲突并拒绝预约
-- ============================================
-- 1. 创建测试会员
-- ============================================
INSERT INTO member_user (member_no, nickname, phone, gender, is_deleted, created_at, updated_at) VALUES
('MEM_TIME_CONFLICT', '时间冲突测试会员', '13800009999', 1, false, '2026-06-02 10:00:00', '2026-06-02 10:00:00');
-- ============================================
-- 2. 创建时间冲突的团课
-- ============================================
-- 团课A: 6月15日 13:00 - 15:00
INSERT INTO group_course (course_name, coach_id, course_type, start_time, end_time, max_members, current_members, status, location, description, point_card_amount, stored_value_amount, create_by, created_at, updated_at) VALUES
('时间冲突测试_A_13点-15点', 102, 2, '2026-06-15 13:00:00', '2026-06-15 15:00:00', 20, 0, '0', '综合训练区', '测试用团课A,用于验证时间冲突检测', 1, 0.00, 'admin', '2026-06-02 10:00:00', '2026-06-02 10:00:00');
-- 团课B: 6月15日 14:00 - 16:00 (与团课A时间重叠)
INSERT INTO group_course (course_name, coach_id, course_type, start_time, end_time, max_members, current_members, status, location, description, point_card_amount, stored_value_amount, create_by, created_at, updated_at) VALUES
('时间冲突测试_B_14点-16点', 103, 1, '2026-06-15 14:00:00', '2026-06-15 16:00:00', 15, 0, '0', '普拉提教室', '测试用团课B,与团课A时间重叠(14:00-15:00', 1, 0.00, 'admin', '2026-06-02 10:00:00', '2026-06-02 10:00:00');
-- 团课C: 6月15日 10:00 - 12:00 (不冲突,作为对照)
INSERT INTO group_course (course_name, coach_id, course_type, start_time, end_time, max_members, current_members, status, location, description, point_card_amount, stored_value_amount, create_by, created_at, updated_at) VALUES
('时间冲突测试_C_10点-12点', 101, 1, '2026-06-15 10:00:00', '2026-06-15 12:00:00', 15, 0, '0', '瑜伽教室', '测试用团课C,与团课A/B不冲突', 1, 0.00, 'admin', '2026-06-02 10:00:00', '2026-06-02 10:00:00');
-- ============================================
-- 3. 会员卡记录(用于预约)
-- ============================================
-- 为时间冲突测试会员创建有效次数卡
INSERT INTO member_card_record (member_id, member_card_id, status, remaining_times, remaining_amount, expire_time, purchase_time, version, card_composition, created_at, updated_at) VALUES
((SELECT id FROM member_user WHERE member_no = 'MEM_TIME_CONFLICT'), (SELECT member_card_id FROM member_card WHERE member_card_name = '10次卡'), 'ACTIVE', 10, 0.00, '2026-12-31 23:59:59', '2026-06-02 10:00:00', 0, '{}', '2026-06-02 10:00:00', '2026-06-02 10:00:00');
-- ============================================
-- 4. 测试场景说明
-- ============================================
--
-- 测试步骤:
-- 1. 使用会员 MEM_TIME_CONFLICT 预约团课A (course_name='时间冲突测试_A_13点-15点')
-- → 预期:预约成功
--
-- 2. 使用会员 MEM_TIME_CONFLICT 预约团课B (course_name='时间冲突测试_B_14点-16点')
-- → 预期:预约失败,提示时间冲突(14:00-15:00与已预约的团课A重叠)
--
-- 3. 使用会员 MEM_TIME_CONFLICT 预约团课C (course_name='时间冲突测试_C_10点-12点')
-- → 预期:预约成功(与团课A时间不冲突)
--
-- 时间冲突判断逻辑:
-- 新课程开始时间 < 已预约课程结束时间 AND 新课程结束时间 > 已预约课程开始时间
-- 即:newStartTime < existingEndTime AND newEndTime > existingStartTime
--
-- 本测试数据中的时间关系:
-- - 团课A: 13:00 - 15:00
-- - 团课B: 14:00 - 16:00
-- → 14:00 < 15:00 AND 16:00 > 13:00 → 冲突
-- - 团课C: 10:00 - 12:00
-- → 10:00 < 15:00 AND 12:00 > 13:00 → 12:00 > 13:00 不成立 → 不冲突
@@ -0,0 +1,342 @@
-- ============================================================
-- V13: 整合所有测试数据(基于 2026-06-16 17:13
-- 说明: 系统初始数据由 V2 处理,本文件仅包含业务测试数据
-- 所有时间相关字段已更新为基于 2026-06-16
-- ============================================================
-- ============================================================
-- Section B: 团课类型数据(来源 V15)
-- ============================================================
INSERT INTO group_course_type (type_name, base_difficulty, description, category) VALUES
('慢走/椭圆机轻松模式', 1, '几乎无难度,适合所有人', '基础有氧与热身'),
('固定自行车(低阻力)', 2, '注意座椅高度调节即可', '基础有氧与热身'),
('跑步机慢跑', 3, '需要基本协调性,膝盖有压力', '基础有氧与热身'),
('跳绳(连续基础跳)', 3, '需要手脚配合,心肺要求明显', '基础有氧与热身'),
('坐姿腿屈伸/腿弯举', 2, '很容易找到发力感', '固定器械训练'),
('坐姿推胸机', 3, '需注意肩胛后收,避免耸肩', '固定器械训练'),
('高位下拉(坐姿)', 3, '需控制不要过度后仰', '固定器械训练'),
('史密斯机深蹲', 4, '轨迹固定,但需保持核心稳定', '固定器械训练'),
('蝴蝶机夹胸', 3, '易用肘关节代偿,需锁定肩关节', '固定器械训练'),
('平板支撑', 3, '耐力考验,技巧低', '自重基础动作'),
('跪姿俯卧撑', 3, '上肢力量较弱者首选', '自重基础动作'),
('标准俯卧撑', 5, '需核心收紧,身体成直线', '自重基础动作'),
('引体向上(弹力带辅助)', 6, '背部和手臂力量要求高', '自重基础动作'),
('标准引体向上', 8, '力量-体重比极高,多数男性无法完成1次', '自重基础动作'),
('徒手深蹲', 3, '注意膝盖方向与背部直立', '自重基础动作'),
('单腿深蹲(手枪蹲)', 8, '需要极高下肢力量、柔韧性和平衡', '自重基础动作'),
('哑铃二头弯举', 4, '容易晃动借力,但较安全', '自由重量杠铃/哑铃'),
('哑铃侧平举', 5, '极易用斜方肌代偿,真正练到三角肌中束很难', '自由重量杠铃/哑铃'),
('杠铃卧推', 7, '肩关节压力大,起桥、沉肩、稳定手腕均有技巧,有压伤风险', '自由重量杠铃/哑铃'),
('杠铃深蹲(颈后)', 8, '全身协调性、核心抗压、杠位放置、呼吸模式,学习曲线陡峭', '自由重量杠铃/哑铃'),
('传统硬拉', 9, '风险极高,需要精确的脊柱中立、髋铰链、背阔肌收紧,错误时伤腰', '自由重量杠铃/哑铃'),
('高翻/抓举(奥运举重)', 10, '需要爆发力、柔韧、精准衔接,非数月训练不能掌握', '自由重量杠铃/哑铃'),
('波比跳(标准版)', 6, '连续做时心肺压力极大', '高强度与爆发力'),
('冲刺跑(短跑)', 7, '对腘绳肌和脚踝爆发力要求高', '高强度与爆发力'),
('跳箱(合理高度)', 6, '需要落地缓冲技巧', '高强度与爆发力'),
('负重雪橇推', 6, '主要考验腿部耐力和意志力', '高强度与爆发力'),
('双力臂(引体向上后翻腕上杠)', 9, '需要爆发引体 + 极高相对力量', '高强度与爆发力'),
('静态拉伸(坐姿体前屈)', 2, '无风险,但需要坚持', '柔韧与平衡类'),
('瑜伽下犬式', 3, '常见,但需背部与手臂对齐', '柔韧与平衡类'),
('单腿罗马尼亚硬拉(徒手)', 6, '极考验平衡和髋稳定', '柔韧与平衡类'),
('全深蹲(脚跟贴地,亚洲蹲)', 5, '踝关节灵活度限制多数人', '柔韧与平衡类'),
('竖叉/横叉', 8, '需要数月甚至数年拉伸', '柔韧与平衡类'),
('瑜伽入门', 2, '适合初学者的瑜伽课程,注重基础体式', '柔韧与平衡类'),
('瑜伽进阶', 5, '针对有一定基础的学员,包含更复杂体式', '柔韧与平衡类'),
('普拉提', 4, '注重核心力量和身体控制', '柔韧与平衡类'),
('动感单车', 4, '高强度有氧运动,节奏感强', '基础有氧与热身'),
('搏击操', 5, '结合拳击动作的有氧运动', '高强度与爆发力'),
('HIIT训练', 7, '高强度间歇训练,对心肺要求极高', '高强度与爆发力'),
('核心训练', 4, '针对核心肌群的专项训练', '自重基础动作');
-- ============================================================
-- Section C: 团课标签数据(来源 V16)
-- ============================================================
INSERT INTO course_label (label_name, color, description) VALUES
('适合新手', '#52c41a', '适合健身初学者'),
('中级过渡', '#faad14', '适合有一定基础的学员'),
('高级进阶', '#f5222d', '适合高级学员'),
('减脂塑形', '#722ed1', '有助于减脂塑形'),
('增肌强化', '#13c2c2', '有助于增肌强化'),
('柔韧性训练', '#eb2f96', '注重柔韧性提升'),
('核心训练', '#1890ff', '注重核心力量'),
('心肺训练', '#fa8c16', '提升心肺功能'),
('低冲击', '#52c41a', '低冲击运动,适合关节保护'),
('高强度', '#f5222d', '高强度间歇训练'),
('团体互动', '#722ed1', '注重团队协作'),
('私教推荐', '#13c2c2', '私教推荐课程'),
('热门课程', '#ff1493', '人气较高的课程'),
('新课上线', '#00ced1', '新上线的课程');
-- ============================================================
-- Section D: 会员卡类型(来源 V10 / V11,已去重合并)
-- ============================================================
INSERT INTO member_card (member_card_name, member_card_type, member_card_price, member_card_validity_days, member_card_total_times, member_card_amount, member_card_status, extra_config, created_at, updated_at) VALUES
('30天时长卡', 'TIME_CARD', 299.00, 30, NULL, NULL, 1, '{}', '2026-01-01 00:00:00', '2026-01-01 00:00:00'),
('10次卡', 'COUNT_CARD', 499.00, NULL, 10, NULL, 1, '{}', '2026-01-01 00:00:00', '2026-01-01 00:00:00'),
('储值卡500', 'STORED_VALUE_CARD', 500.00, NULL, NULL, 500.00, 1, '{}', '2026-01-01 00:00:00', '2026-01-01 00:00:00');
-- ============================================================
-- Section E: 测试会员(来源 V10 / V11 / V12 / V14
-- ============================================================
-- E1: 数据统计测试会员(V14,显式 ID 1001-1012
INSERT INTO member_user (id, member_no, nickname, phone, created_at, updated_at, is_deleted) VALUES
(1001, 'M20260616001', '张三', '13800138001', '2026-06-16 08:00:00', '2026-06-16 08:00:00', false),
(1002, 'M20260616002', '李四', '13800138002', '2026-06-16 09:00:00', '2026-06-16 09:00:00', false),
(1003, 'M20260615003', '王五', '13800138003', '2026-06-15 10:00:00', '2026-06-15 10:00:00', false),
(1004, 'M20260614004', '赵六', '13800138004', '2026-06-14 11:00:00', '2026-06-14 11:00:00', false),
(1005, 'M20260616005', '钱七', '13800138005', '2026-06-16 08:00:00', '2026-06-16 08:00:00', false),
(1006, 'M20260616006', '孙八', '13800138006', '2026-06-16 09:00:00', '2026-06-16 09:00:00', false),
(1007, 'M20260616007', '周九', '13800138007', '2026-06-16 10:00:00', '2026-06-16 10:00:00', false),
(1008, 'M20260613008', '吴十', '13800138008', '2026-06-13 14:00:00', '2026-06-13 14:00:00', false),
(1009, 'M20260612009', '郑十一', '13800138009', '2026-06-12 15:00:00', '2026-06-12 15:00:00', false),
(1010, 'M20260611010', '王十二', '13800138010', '2026-06-11 16:00:00', '2026-06-11 16:00:00', false),
(1011, 'M20260610011', '陈十三', '13800138011', '2026-06-10 17:00:00', '2026-06-10 17:00:00', false),
(1012, 'M20260609012', '刘十四', '13800138012', '2026-06-09 18:00:00', '2026-06-09 18:00:00', false);
-- E2: 预约场景测试会员(V10: A-G)
INSERT INTO member_user (member_no, nickname, phone, gender, is_deleted, created_at, updated_at) VALUES
('MEM_TEST_A', '用户A_无卡新用户', '13800001001', 1, false, '2026-06-16 10:00:00', '2026-06-16 10:00:00'),
('MEM_TEST_B', '用户B_过期时长卡', '13800001002', 1, false, '2026-06-15 10:00:00', '2026-06-15 10:00:00'),
('MEM_TEST_C', '会员C_有效时长卡', '13800001003', 2, false, '2026-06-15 10:00:00', '2026-06-15 10:00:00'),
('MEM_TEST_D', '会员D_次数用尽', '13800001004', 1, false, '2026-06-15 10:00:00', '2026-06-15 10:00:00'),
('MEM_TEST_E', '会员E_次数充足', '13800001005', 2, false, '2026-06-15 10:00:00', '2026-06-15 10:00:00'),
('MEM_TEST_F', '会员F_储值卡余额不足', '13800001006', 1, false, '2026-06-15 10:00:00', '2026-06-15 10:00:00'),
('MEM_TEST_G', '会员G_储值卡余额充足', '13800001007', 2, false, '2026-06-15 10:00:00', '2026-06-15 10:00:00');
-- E3: 取消预约测试会员(V11: 张三/李四/王五)
INSERT INTO member_user (member_no, nickname, phone, gender, is_deleted, created_at, updated_at) VALUES
('MEM_TEST_ZHANG', '张三_时长卡用户', '13800002001', 1, false, '2026-06-15 10:00:00', '2026-06-15 10:00:00'),
('MEM_TEST_LI', '李四_次数卡用户', '13800002002', 1, false, '2026-06-15 10:00:00', '2026-06-15 10:00:00'),
('MEM_TEST_WANG', '王五_储值卡用户', '13800002003', 2, false, '2026-06-15 10:00:00', '2026-06-15 10:00:00');
-- E4: 时间冲突测试会员(V12)
INSERT INTO member_user (member_no, nickname, phone, gender, is_deleted, created_at, updated_at) VALUES
('MEM_TIME_CONFLICT', '时间冲突测试会员', '13800009999', 1, false, '2026-06-15 10:00:00', '2026-06-15 10:00:00');
-- ============================================================
-- Section F: 会员卡记录
-- ============================================================
-- F1: V10 预约场景 - 6条会员卡记录
INSERT INTO member_card_record (member_id, member_card_id, status, remaining_times, remaining_amount, expire_time, purchase_time, version, card_composition, created_at, updated_at) VALUES
((SELECT id FROM member_user WHERE member_no = 'MEM_TEST_B'), (SELECT member_card_id FROM member_card WHERE member_card_name = '30天时长卡'), 'EXPIRED', 0, 0.00, '2026-06-15 23:59:59', '2026-05-16 10:00:00', 0, '{}', '2026-05-16 10:00:00', '2026-06-16 10:00:00');
INSERT INTO member_card_record (member_id, member_card_id, status, remaining_times, remaining_amount, expire_time, purchase_time, version, card_composition, created_at, updated_at) VALUES
((SELECT id FROM member_user WHERE member_no = 'MEM_TEST_C'), (SELECT member_card_id FROM member_card WHERE member_card_name = '30天时长卡'), 'ACTIVE', 0, 0.00, '2026-07-16 23:59:59', '2026-06-16 10:00:00', 0, '{}', '2026-06-16 10:00:00', '2026-06-16 10:00:00');
INSERT INTO member_card_record (member_id, member_card_id, status, remaining_times, remaining_amount, expire_time, purchase_time, version, card_composition, created_at, updated_at) VALUES
((SELECT id FROM member_user WHERE member_no = 'MEM_TEST_D'), (SELECT member_card_id FROM member_card WHERE member_card_name = '10次卡'), 'ACTIVE', 0, 0.00, '2026-12-31 23:59:59', '2026-05-16 10:00:00', 0, '{}', '2026-05-16 10:00:00', '2026-06-16 10:00:00');
INSERT INTO member_card_record (member_id, member_card_id, status, remaining_times, remaining_amount, expire_time, purchase_time, version, card_composition, created_at, updated_at) VALUES
((SELECT id FROM member_user WHERE member_no = 'MEM_TEST_E'), (SELECT member_card_id FROM member_card WHERE member_card_name = '10次卡'), 'ACTIVE', 5, 0.00, '2026-12-31 23:59:59', '2026-05-16 10:00:00', 0, '{}', '2026-05-16 10:00:00', '2026-06-16 10:00:00');
INSERT INTO member_card_record (member_id, member_card_id, status, remaining_times, remaining_amount, expire_time, purchase_time, version, card_composition, created_at, updated_at) VALUES
((SELECT id FROM member_user WHERE member_no = 'MEM_TEST_F'), (SELECT member_card_id FROM member_card WHERE member_card_name = '储值卡500'), 'ACTIVE', 0, 30.00, '2027-06-16 23:59:59', '2026-05-16 10:00:00', 0, '{}', '2026-05-16 10:00:00', '2026-06-16 10:00:00');
INSERT INTO member_card_record (member_id, member_card_id, status, remaining_times, remaining_amount, expire_time, purchase_time, version, card_composition, created_at, updated_at) VALUES
((SELECT id FROM member_user WHERE member_no = 'MEM_TEST_G'), (SELECT member_card_id FROM member_card WHERE member_card_name = '储值卡500'), 'ACTIVE', 0, 200.00, '2027-06-16 23:59:59', '2026-05-16 10:00:00', 0, '{}', '2026-05-16 10:00:00', '2026-06-16 10:00:00');
-- F2: V11 取消预约场景 - 3条
INSERT INTO member_card_record (member_id, member_card_id, status, remaining_times, remaining_amount, expire_time, purchase_time, version, card_composition, created_at, updated_at) VALUES
((SELECT id FROM member_user WHERE member_no = 'MEM_TEST_ZHANG'), (SELECT member_card_id FROM member_card WHERE member_card_name = '30天时长卡'), 'ACTIVE', 0, 0.00, '2026-07-16 23:59:59', '2026-06-16 10:00:00', 0, '{}', '2026-06-16 10:00:00', '2026-06-16 10:00:00'),
((SELECT id FROM member_user WHERE member_no = 'MEM_TEST_LI'), (SELECT member_card_id FROM member_card WHERE member_card_name = '10次卡'), 'ACTIVE', 5, 0.00, '2026-12-31 23:59:59', '2026-05-16 10:00:00', 0, '{}', '2026-05-16 10:00:00', '2026-06-16 10:00:00'),
((SELECT id FROM member_user WHERE member_no = 'MEM_TEST_WANG'), (SELECT member_card_id FROM member_card WHERE member_card_name = '储值卡500'), 'ACTIVE', 0, 200.00, '2027-06-16 23:59:59', '2026-05-16 10:00:00', 0, '{}', '2026-05-16 10:00:00', '2026-06-16 10:00:00');
-- F3: V12 时间冲突场景 - 1条
INSERT INTO member_card_record (member_id, member_card_id, status, remaining_times, remaining_amount, expire_time, purchase_time, version, card_composition, created_at, updated_at) VALUES
((SELECT id FROM member_user WHERE member_no = 'MEM_TIME_CONFLICT'), (SELECT member_card_id FROM member_card WHERE member_card_name = '10次卡'), 'ACTIVE', 10, 0.00, '2026-12-31 23:59:59', '2026-06-16 10:00:00', 0, '{}', '2026-06-16 10:00:00', '2026-06-16 10:00:00');
-- ============================================================
-- Section G: 团课课程(来源 V7 / V10 / V11 / V12 / V14
-- ============================================================
-- G1: V7 - 7种场景团课
INSERT INTO group_course (course_name, coach_id, course_type, start_time, end_time, max_members, current_members, status, location, cover_image, description, create_by, created_at, updated_at) VALUES
('极速燃脂单车', 104, 2, '2026-06-17 16:45:00', '2026-06-17 20:20:00', 25, 0, 0, '单车房', '/images/spinning.jpg', '跟随音乐节奏变换阻力和速度,体验爬坡与冲刺的快感。', 'admin', '2026-06-15 11:00:00', '2026-06-15 11:00:00'),
('清晨流瑜伽', 101, 1, '2026-06-20 09:00:00', '2026-06-20 10:30:00', 15, 5, 0, 'A座3楼瑜伽教室', '/images/yoga_flow.jpg', '适合有一定基础的学员,通过流畅的体式连接呼吸。', 'admin', '2026-06-15 10:00:00', '2026-06-15 10:00:00'),
('燃脂搏击', 102, 2, '2026-06-18 18:30:00', '2026-06-18 19:30:00', 20, 20, 0, '综合训练区', '/images/kickboxing.jpg', '高强度间歇训练,名额已满。', 'coach_zhang', '2026-06-15 14:30:00', '2026-06-15 14:30:00'),
('哈他瑜伽', 101, 1, '2026-06-16 17:45:00', '2026-06-16 18:50:00', 12, 3, 0, '瑜伽教室B', '/images/hatha_yoga.jpg', '基础哈他瑜伽,距开始不足30分钟,已停止预约。', 'coach_li', '2026-06-16 08:00:00', '2026-06-16 08:00:00'),
('周末冥想修复', 101, 1, '2026-06-28 15:00:00', '2026-06-28 16:00:00', 12, 3, 1, '冥想室', '/images/meditation.jpg', '通过呼吸和正念冥想,该课程已被取消。', 'coach_wang', '2026-06-10 08:00:00', '2026-06-10 08:00:00'),
('蜜桃臀塑造', 103, 3, '2026-06-10 19:00:00', '2026-06-10 20:00:00', 10, 8, 2, '私教专区', '/images/glute.jpg', '针对性训练臀部肌肉群,课程已结束。', 'coach_li', '2026-05-30 09:15:00', '2026-05-30 09:15:00'),
('午间冥想放松', 101, 1, '2026-06-12 12:00:00', '2026-06-12 13:00:00', 15, 6, 2, '冥想室', '/images/meditation_noon.jpg', '午间冥想课程,已结束。', 'admin', '2026-06-05 09:00:00', '2026-06-05 09:00:00');
-- G2: V10 预约场景
INSERT INTO group_course (course_name, coach_id, course_type, start_time, end_time, max_members, current_members, status, location, description, point_card_amount, stored_value_amount, create_by, created_at, updated_at) VALUES
('燃脂搏击_次数卡课程', 102, 2, '2026-06-18 19:30:00', '2026-06-18 20:30:00', 20, 0, 0, '综合训练区', '消耗1次', 1, 0.00, 'admin', '2026-06-15 10:00:00', '2026-06-15 10:00:00'),
('高端普拉提_储值卡课程', 103, 1, '2026-06-19 19:00:00', '2026-06-19 20:00:00', 15, 0, 0, '普拉提教室', '消耗储值20元', 0, 20.00, 'admin', '2026-06-15 10:00:00', '2026-06-15 10:00:00');
-- G3: V11 取消预约场景
INSERT INTO group_course (course_name, coach_id, course_type, start_time, end_time, max_members, current_members, status, location, description, point_card_amount, stored_value_amount, create_by, created_at, updated_at) VALUES
('晚间瑜伽_取消测试', 101, 1, '2026-06-19 19:00:00', '2026-06-19 20:00:00', 20, 0, 0, '瑜伽教室', '用于测试取消预约功能', 1, 30.00, 'admin', '2026-06-15 10:00:00', '2026-06-15 10:00:00');
-- G4: V12 时间冲突场景
INSERT INTO group_course (course_name, coach_id, course_type, start_time, end_time, max_members, current_members, status, location, description, point_card_amount, stored_value_amount, create_by, created_at, updated_at) VALUES
('时间冲突测试_A_13点-15点', 102, 2, '2026-06-18 13:00:00', '2026-06-18 15:00:00', 20, 0, 0, '综合训练区', '测试用团课A', 1, 0.00, 'admin', '2026-06-15 10:00:00', '2026-06-15 10:00:00'),
('时间冲突测试_B_14点-16点', 103, 1, '2026-06-18 14:00:00', '2026-06-18 16:00:00', 15, 0, 0, '普拉提教室', '与团课A时间重叠', 1, 0.00, 'admin', '2026-06-15 10:00:00', '2026-06-15 10:00:00'),
('时间冲突测试_C_10点-12点', 101, 1, '2026-06-18 10:00:00', '2026-06-18 12:00:00', 15, 0, 0, '瑜伽教室', '与A/B不冲突', 1, 0.00, 'admin', '2026-06-15 10:00:00', '2026-06-15 10:00:00');
-- G5: V14 数据统计场景(今天)
INSERT INTO group_course (id, course_name, coach_id, course_type, start_time, end_time, max_members, current_members, status, location, cover_image, description, created_at, updated_at) VALUES
(3001, '瑜伽入门', 1, 1, '2026-06-16 08:00:00', '2026-06-16 09:00:00', 20, 15, 0, '健身房A区', 'https://example.com/yoga.jpg', '适合初学者的瑜伽课程', '2026-06-15 10:00:00', '2026-06-15 10:00:00'),
(3002, '动感单车', 2, 2, '2026-06-16 09:30:00', '2026-06-16 10:30:00', 25, 20, 0, '健身房B区', 'https://example.com/spinning.jpg', '高强度有氧运动', '2026-06-15 11:00:00', '2026-06-15 11:00:00'),
(3003, '普拉提', 3, 1, '2026-06-16 14:00:00', '2026-06-16 15:00:00', 15, 10, 0, '健身房C区', 'https://example.com/pilates.jpg', '核心力量训练', '2026-06-15 12:00:00', '2026-06-15 12:00:00');
-- ============================================================
-- Section H: 团课预约记录
-- ============================================================
-- H1: V11 取消预约测试
INSERT INTO group_course_booking (course_id, member_id, member_card_id, booking_time, status, course_name, course_start_time, course_end_time, location, created_at, updated_at) VALUES
((SELECT id FROM group_course WHERE course_name = '晚间瑜伽_取消测试'), (SELECT id FROM member_user WHERE member_no = 'MEM_TEST_ZHANG'), (SELECT id FROM member_card_record WHERE member_id = (SELECT id FROM member_user WHERE member_no = 'MEM_TEST_ZHANG')), '2026-06-16 11:00:00', '0', '晚间瑜伽_取消测试', '2026-06-19 19:00:00', '2026-06-19 20:00:00', '瑜伽教室', '2026-06-16 11:00:00', '2026-06-16 11:00:00'),
((SELECT id FROM group_course WHERE course_name = '晚间瑜伽_取消测试'), (SELECT id FROM member_user WHERE member_no = 'MEM_TEST_LI'), (SELECT id FROM member_card_record WHERE member_id = (SELECT id FROM member_user WHERE member_no = 'MEM_TEST_LI')), '2026-06-16 11:30:00', '0', '晚间瑜伽_取消测试', '2026-06-19 19:00:00', '2026-06-19 20:00:00', '瑜伽教室', '2026-06-16 11:30:00', '2026-06-16 11:30:00'),
((SELECT id FROM group_course WHERE course_name = '晚间瑜伽_取消测试'), (SELECT id FROM member_user WHERE member_no = 'MEM_TEST_WANG'), (SELECT id FROM member_card_record WHERE member_id = (SELECT id FROM member_user WHERE member_no = 'MEM_TEST_WANG')), '2026-06-16 12:00:00', '0', '晚间瑜伽_取消测试', '2026-06-19 19:00:00', '2026-06-19 20:00:00', '瑜伽教室', '2026-06-16 12:00:00', '2026-06-16 12:00:00');
UPDATE group_course SET current_members = current_members + 3 WHERE course_name = '晚间瑜伽_取消测试';
-- H2: V14 数据统计预约 - 今天(6月16日)
INSERT INTO group_course_booking (id, member_id, member_card_id, course_id, booking_time, status, created_at, updated_at) VALUES
(4001, 1001, 1, 3001, '2026-06-16 08:00:00', '2', '2026-06-15 20:00:00', '2026-06-16 08:30:00'),
(4002, 1002, 2, 3001, '2026-06-16 08:00:00', '2', '2026-06-15 21:00:00', '2026-06-16 08:30:00'),
(4003, 1003, 3, 3001, '2026-06-16 08:00:00', '3', '2026-06-15 22:00:00', '2026-06-16 09:00:00'),
(4004, 1004, 4, 3002, '2026-06-16 09:30:00', '2', '2026-06-15 19:00:00', '2026-06-16 09:30:00'),
(4005, 1005, 5, 3002, '2026-06-16 09:30:00', '1', '2026-06-15 20:30:00', '2026-06-16 09:00:00'),
(4006, 1006, 6, 3002, '2026-06-16 09:30:00', '2', '2026-06-15 21:30:00', '2026-06-16 09:30:00'),
(4007, 1007, 7, 3003, '2026-06-16 14:00:00', '2', '2026-06-15 22:30:00', '2026-06-16 14:00:00'),
(4008, 1008, 8, 3003, '2026-06-16 14:00:00', '3', '2026-06-16 08:00:00', '2026-06-16 14:00:00'),
(4009, 1009, 9, 3003, '2026-06-16 14:00:00', '2', '2026-06-16 09:00:00', '2026-06-16 14:00:00'),
(4010, 1010, 10, 3001, '2026-06-16 08:00:00', '2', '2026-06-16 07:00:00', '2026-06-16 08:00:00'),
(4011, 1011, 11, 3002, '2026-06-16 09:30:00', '1', '2026-06-16 08:30:00', '2026-06-16 09:00:00'),
(4012, 1012, 12, 3003, '2026-06-16 14:00:00', '2', '2026-06-16 10:00:00', '2026-06-16 14:00:00');
-- H3: V14 数据统计预约 - 昨天(6月15日)
INSERT INTO group_course_booking (id, member_id, member_card_id, course_id, booking_time, status, created_at, updated_at) VALUES
(4013, 1001, 1, 3001, '2026-06-15 08:00:00', '2', '2026-06-14 20:00:00', '2026-06-15 08:30:00'),
(4014, 1002, 2, 3001, '2026-06-15 08:00:00', '2', '2026-06-14 21:00:00', '2026-06-15 08:30:00'),
(4015, 1003, 3, 3002, '2026-06-15 09:30:00', '3', '2026-06-14 22:00:00', '2026-06-15 09:30:00'),
(4016, 1004, 4, 3002, '2026-06-15 09:30:00', '2', '2026-06-14 19:00:00', '2026-06-15 09:30:00'),
(4017, 1005, 5, 3003, '2026-06-15 14:00:00', '1', '2026-06-14 20:30:00', '2026-06-15 13:00:00'),
(4018, 1006, 6, 3003, '2026-06-15 14:00:00', '2', '2026-06-14 21:30:00', '2026-06-15 14:00:00');
-- H4: V14 数据统计预约 - 前天(6月14日)
INSERT INTO group_course_booking (id, member_id, member_card_id, course_id, booking_time, status, created_at, updated_at) VALUES
(4019, 1001, 1, 3002, '2026-06-14 09:30:00', '2', '2026-06-13 20:00:00', '2026-06-14 09:30:00'),
(4020, 1002, 2, 3002, '2026-06-14 09:30:00', '2', '2026-06-13 21:00:00', '2026-06-14 09:30:00'),
(4021, 1003, 3, 3003, '2026-06-14 14:00:00', '2', '2026-06-13 22:00:00', '2026-06-14 14:00:00'),
(4022, 1004, 4, 3003, '2026-06-14 14:00:00', '3', '2026-06-13 19:00:00', '2026-06-14 14:00:00');
-- ============================================================
-- Section I: 签到记录(来源 V14,基于 2026-06-16
-- ============================================================
INSERT INTO sign_in_record (id, member_id, sign_in_time, sign_in_type, sign_in_status, source, is_delete) VALUES
(2001, 1001, '2026-06-16 08:00:00', 'QR_CODE', 'SUCCESS', 'MINI_PROGRAM', false),
(2002, 1002, '2026-06-16 08:15:00', 'MANUAL', 'SUCCESS', 'PC_BACKEND', false),
(2003, 1003, '2026-06-16 08:30:00', 'FACE', 'SUCCESS', 'MINI_PROGRAM', false),
(2004, 1004, '2026-06-16 09:00:00', 'QR_CODE', 'SUCCESS', 'MINI_PROGRAM', false),
(2005, 1005, '2026-06-16 09:15:00', 'MANUAL', 'SUCCESS', 'PC_BACKEND', false),
(2006, 1006, '2026-06-16 09:30:00', 'QR_CODE', 'SUCCESS', 'MINI_PROGRAM', false),
(2007, 1007, '2026-06-16 10:00:00', 'FACE', 'SUCCESS', 'MINI_PROGRAM', false),
(2008, 1008, '2026-06-16 10:15:00', 'QR_CODE', 'SUCCESS', 'MINI_PROGRAM', false),
(2009, 1009, '2026-06-16 10:30:00', 'MANUAL', 'SUCCESS', 'PC_BACKEND', false),
(2010, 1010, '2026-06-16 11:00:00', 'QR_CODE', 'SUCCESS', 'MINI_PROGRAM', false),
(2011, 1011, '2026-06-16 11:15:00', 'FACE', 'FAIL', 'MINI_PROGRAM', false),
(2012, 1012, '2026-06-16 11:30:00', 'MANUAL', 'SUCCESS', 'PC_BACKEND', false);
INSERT INTO sign_in_record (id, member_id, sign_in_time, sign_in_type, sign_in_status, source, is_delete) VALUES
(2013, 1001, '2026-06-15 07:30:00', 'QR_CODE', 'SUCCESS', 'MINI_PROGRAM', false),
(2014, 1002, '2026-06-15 08:00:00', 'MANUAL', 'SUCCESS', 'PC_BACKEND', false),
(2015, 1003, '2026-06-15 08:30:00', 'FACE', 'SUCCESS', 'MINI_PROGRAM', false),
(2016, 1004, '2026-06-15 09:00:00', 'QR_CODE', 'SUCCESS', 'MINI_PROGRAM', false),
(2017, 1005, '2026-06-15 09:30:00', 'MANUAL', 'SUCCESS', 'PC_BACKEND', false),
(2018, 1006, '2026-06-15 10:00:00', 'QR_CODE', 'SUCCESS', 'MINI_PROGRAM', false),
(2019, 1007, '2026-06-15 10:30:00', 'FACE', 'SUCCESS', 'MINI_PROGRAM', false),
(2020, 1008, '2026-06-15 11:00:00', 'QR_CODE', 'SUCCESS', 'MINI_PROGRAM', false);
INSERT INTO sign_in_record (id, member_id, sign_in_time, sign_in_type, sign_in_status, source, is_delete) VALUES
(2021, 1001, '2026-06-14 07:00:00', 'QR_CODE', 'SUCCESS', 'MINI_PROGRAM', false),
(2022, 1002, '2026-06-14 07:30:00', 'MANUAL', 'SUCCESS', 'PC_BACKEND', false),
(2023, 1003, '2026-06-14 08:00:00', 'FACE', 'FAIL', 'MINI_PROGRAM', false),
(2024, 1004, '2026-06-14 08:30:00', 'QR_CODE', 'SUCCESS', 'MINI_PROGRAM', false),
(2025, 1005, '2026-06-14 09:00:00', 'MANUAL', 'SUCCESS', 'PC_BACKEND', false);
-- ============================================================
-- Section J: 团课推荐测试数据(来源 V18,基于 2026-06-16
-- ============================================================
INSERT INTO group_course_recommend (course_id, recommend_title, recommend_content, recommend_reason, priority, is_active, create_by, created_at, updated_at) VALUES
((SELECT id FROM group_course WHERE course_name = '极速燃脂单车'), '本周热门推荐', '极速燃脂单车课程,跟随音乐节奏变换阻力和速度,体验爬坡与冲刺的快感,一节课消耗800大卡!', '教练专业,课程内容丰富,深受学员喜爱,燃脂效果显著', 20, true, 'admin', '2026-06-16 10:00:00', '2026-06-16 10:00:00');
INSERT INTO group_course_recommend (course_id, recommend_title, recommend_content, recommend_reason, priority, is_active, create_by, created_at, updated_at) VALUES
((SELECT id FROM group_course WHERE course_name = '清晨流瑜伽'), '新手友好推荐', '清晨流瑜伽课程,适合有一定基础的学员,通过流畅的体式连接呼吸,唤醒身体能量。', '适合新手入门,教练耐心指导,课程节奏适中', 15, true, 'admin', '2026-06-16 11:00:00', '2026-06-16 11:00:00');
INSERT INTO group_course_recommend (course_id, recommend_title, recommend_content, recommend_reason, priority, is_active, create_by, created_at, updated_at) VALUES
((SELECT id FROM group_course WHERE course_name = '燃脂搏击'), '高强度燃脂', '燃脂搏击课程,高强度间歇训练,配合音乐快速燃脂,释放压力。', '高强度训练,适合进阶学员,快速燃脂塑形', 10, false, 'admin', '2026-06-16 12:00:00', '2026-06-16 12:00:00');
INSERT INTO group_course_recommend (course_id, recommend_title, recommend_content, recommend_reason, priority, is_active, create_by, created_at, updated_at) VALUES
((SELECT id FROM group_course WHERE course_name = '哈他瑜伽'), '基础瑜伽推荐', '基础哈他瑜伽课程,适合所有级别学员,通过基础体式练习提升身体柔韧性和平衡能力。', '零基础友好,适合所有健身水平,放松身心', 12, true, 'coach_li', '2026-06-16 13:00:00', '2026-06-16 13:00:00');
INSERT INTO group_course_recommend (course_id, recommend_title, recommend_content, recommend_reason, priority, is_active, create_by, created_at, updated_at) VALUES
((SELECT id FROM group_course WHERE course_name = '蜜桃臀塑造'), '塑形热门课程', '蜜桃臀塑造课程,针对性训练臀部肌肉群,打造完美曲线。', '专业私教指导,动作标准,效果显著,深受女性学员喜爱', 18, true, 'coach_li', '2026-06-10 09:15:00', '2026-06-10 09:15:00');
INSERT INTO group_course_recommend (course_id, recommend_title, recommend_content, recommend_reason, priority, is_active, create_by, created_at, updated_at) VALUES
((SELECT id FROM group_course WHERE course_name = '午间冥想放松'), '午间放松推荐', '午间冥想放松课程,通过呼吸和正念冥想,深度放松身心,缓解工作压力。', '适合上班族,午间放松充电,提升下午工作效率', 8, true, 'admin', '2026-06-12 09:00:00', '2026-06-12 09:00:00');
INSERT INTO group_course_recommend (course_id, recommend_title, recommend_content, recommend_reason, priority, is_active, create_by, created_at, updated_at) VALUES
((SELECT id FROM group_course WHERE course_name = '极速燃脂单车'), '减脂首选课程', '想要快速减脂?极速燃脂单车是你的最佳选择!专业教练带领,科学训练计划。', '减脂效果最佳,课程强度适中,适合想要快速瘦身的学员', 16, true, 'coach_zhang', '2026-06-16 14:00:00', '2026-06-16 14:00:00');
INSERT INTO group_course_recommend (course_id, recommend_title, recommend_content, recommend_reason, priority, is_active, create_by, created_at, updated_at) VALUES
((SELECT id FROM group_course WHERE course_name = '清晨流瑜伽'), '晨练优选', '清晨流瑜伽,唤醒身体能量,开启活力一天!适合晨练爱好者。', '晨练最佳选择,提升身体活力,改善精神状态', 14, true, 'coach_wang', '2026-06-16 15:00:00', '2026-06-16 15:00:00');
INSERT INTO group_course_recommend (course_id, recommend_title, recommend_content, recommend_reason, priority, is_active, create_by, created_at, updated_at) VALUES
((SELECT id FROM group_course WHERE course_name = '哈他瑜伽'), '身心平衡推荐', '哈他瑜伽课程,通过体式练习和呼吸控制,达到身心平衡,提升整体健康水平。', '改善身体柔韧性,增强核心力量,提升身体协调性', 11, true, 'coach_li', '2026-06-16 16:00:00', '2026-06-16 16:00:00');
INSERT INTO group_course_recommend (course_id, recommend_title, recommend_content, recommend_reason, priority, is_active, create_by, created_at, updated_at) VALUES
((SELECT id FROM group_course WHERE course_name = '午间冥想放松'), '职场减压课程', '午间冥想放松,专为职场人士设计,快速缓解工作压力,提升工作状态。', '职场减压首选,课程时间短,效果显著', 9, false, 'admin', '2026-06-12 10:00:00', '2026-06-12 10:00:00');
-- ============================================================
-- Section K: 统计说明
-- ============================================================
-- 今日(2026-06-16)统计预期:
-- 新增会员: 3 (1005, 1006, 1007)
-- 签到会员: 12
-- 预约总数: 12 (4001-4012),取消: 2,出席: 8,缺席: 2
-- 签到总数: 12,成功: 11,失败: 1
-- ============================================================
-- Section L: 测试场景汇总
-- ============================================================
-- 1. V7 团课预约场景:
-- - 极速燃脂单车: 明天,0人,可预约
-- - 清晨流瑜伽: 6月20日,5/15人,可预约
-- - 燃脂搏击: 6月18日,满员,不可预约
-- - 哈他瑜伽: 今天17:45,距开始<30min,不可预约
-- - 周末冥想修复: 6月28日,已取消(status=1)
-- - 蜜桃臀塑造: 6月10日,已结束(status=2)
-- - 午间冥想放松: 6月12日,已结束(status=2)
--
-- 2. V10 会员卡预约资格校验:
-- - 用户A: 无会员卡 → "无可用会员卡"
-- - 用户B: 时长卡过期 → "会员卡已过期"
-- - 会员C: 时长卡有效 → 可正常预约
-- - 会员D: 次数为0 → "剩余次数不足"
-- - 会员E: 次数充足 → 可正常预约
-- - 会员F: 储值卡30元,课程需20元 → 可正常预约
-- - 会员G: 储值卡200元,课程需20元 → 可正常预约
--
-- 3. V11 取消预约:
-- - 张三(时长卡)、李四(次数卡)、王五(储值卡) 预约了晚间瑜伽_取消测试
-- - 取消后应恢复对应卡状态,释放课程名额
--
-- 4. V12 时间冲突检测:
-- - 团课A: 6/18 13:00-15:00, 团课B: 6/18 14:00-16:00 → 时间重叠
-- - 团课C: 6/18 10:00-12:00 → 与A/B不冲突
--
-- 5. V14 数据统计:
-- - 3天签到/预约数据,覆盖今日/昨日/前日
--
-- 6. V18 团课推荐:
-- - 10条推荐记录,覆盖不同优先级和启用状态
@@ -1,99 +0,0 @@
-- ============================================
-- 签到记录表(sign_in_record
-- ============================================
-- Step 1: 创建 sign_in_record 表
CREATE TABLE IF NOT EXISTS sign_in_record (
-- ========== 主键和基础字段 ==========
id BIGSERIAL PRIMARY KEY, -- 自增主键
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 记录创建时间
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 记录更新时间
-- ========== 会员相关字段 ==========
member_id BIGINT NOT NULL, -- 会员ID,关联member_user表
member_card_id BIGINT, -- 签到时使用的会员卡ID
-- ========== 签到核心字段 ==========
sign_in_time TIMESTAMP NOT NULL, -- 签到入场时间
sign_in_type VARCHAR(20) NOT NULL, -- 签到方式:QR_CODE-扫码签到,MANUAL-手动签到,FACE-人脸识别
sign_in_status VARCHAR(20) NOT NULL DEFAULT 'SUCCESS', -- 签到状态:SUCCESS-成功,FAILED-失败
-- ========== 验证和错误信息 ==========
verification_details TEXT, -- JSONB格式,存储会员卡验证时的快照数据
fail_reason VARCHAR(500), -- 失败时的具体原因文案
-- ========== 操作人信息 ==========
operator_id BIGINT, -- 操作人ID(前台人员),自助签到时为NULL
operator_name VARCHAR(100), -- 操作人姓名冗余
-- ========== 设备和环境信息 ==========
device_info VARCHAR(200), -- 签到设备标识或型号
ip_address VARCHAR(50), -- 客户端IP地址
source VARCHAR(20) NOT NULL, -- 签到来源:MINI_PROGRAM-小程序扫码,PC_BACKEND-后台管理端
-- ========== 软删除字段 ==========
is_delete BOOLEAN DEFAULT FALSE -- 软删除标识:false-未删除,true-已删除
);
-- Step 2: 创建索引
-- 会员ID索引(加速按会员查询签到记录)
CREATE INDEX IF NOT EXISTS idx_sign_in_record_member_id ON sign_in_record(member_id);
-- 签到时间索引(加速按时间范围查询)
CREATE INDEX IF NOT EXISTS idx_sign_in_record_sign_in_time ON sign_in_record(sign_in_time);
-- 签到状态索引(加速按状态筛选)
CREATE INDEX IF NOT EXISTS idx_sign_in_record_sign_in_status ON sign_in_record(sign_in_status);
-- 会员卡ID索引(加速按会员卡查询)
CREATE INDEX IF NOT EXISTS idx_sign_in_record_member_card_id ON sign_in_record(member_card_id);
-- 操作人ID索引(加速按操作人查询)
CREATE INDEX IF NOT EXISTS idx_sign_in_record_operator_id ON sign_in_record(operator_id);
-- 签到来源索引(加速按来源统计)
CREATE INDEX IF NOT EXISTS idx_sign_in_record_source ON sign_in_record(source);
-- 软删除索引(加速查询未删除的记录)
CREATE INDEX IF NOT EXISTS idx_sign_in_record_is_delete ON sign_in_record(is_delete);
-- 复合索引:会员ID + 签到时间(加速会员签到历史查询)
CREATE INDEX IF NOT EXISTS idx_sign_in_record_member_time ON sign_in_record(member_id, sign_in_time);
-- 复合索引:签到状态 + 签到时间(加速统计数据查询)
CREATE INDEX IF NOT EXISTS idx_sign_in_record_status_time ON sign_in_record(sign_in_status, sign_in_time);
-- 复合索引:签到日期(用于每日统计,使用表达式索引)
CREATE INDEX IF NOT EXISTS idx_sign_in_record_sign_in_date ON sign_in_record(DATE(sign_in_time));
-- Step 3: 添加外键约束(可选,根据业务需求决定)
-- 注意:如果member_user表使用了软删除,外键约束可能需要谨慎使用
-- ALTER TABLE sign_in_record
-- ADD CONSTRAINT fk_sign_in_record_member
-- FOREIGN KEY (member_id) REFERENCES member_user(id) ON DELETE SET NULL;
-- Step 4: 添加注释
COMMENT ON TABLE sign_in_record IS '会员到店签到记录表';
COMMENT ON COLUMN sign_in_record.id IS '自增主键';
COMMENT ON COLUMN sign_in_record.created_at IS '记录创建时间';
COMMENT ON COLUMN sign_in_record.updated_at IS '记录更新时间';
COMMENT ON COLUMN sign_in_record.member_id IS '会员ID,关联member_user表';
COMMENT ON COLUMN sign_in_record.member_card_id IS '签到时使用的会员卡ID';
COMMENT ON COLUMN sign_in_record.sign_in_time IS '签到入场时间';
COMMENT ON COLUMN sign_in_record.sign_in_type IS '签到方式:QR_CODE-扫码签到,MANUAL-手动签到,FACE-人脸识别';
COMMENT ON COLUMN sign_in_record.sign_in_status IS '签到状态:SUCCESS-成功,FAILED-失败';
COMMENT ON COLUMN sign_in_record.verification_details IS 'JSON格式,存储会员卡验证时的快照数据(包含卡类型、剩余次数/金额、有效期等)';
COMMENT ON COLUMN sign_in_record.fail_reason IS '失败时的具体原因文案';
COMMENT ON COLUMN sign_in_record.operator_id IS '操作人ID(前台人员),自助签到时为NULL';
COMMENT ON COLUMN sign_in_record.operator_name IS '操作人姓名冗余(避免关联查询)';
COMMENT ON COLUMN sign_in_record.device_info IS '签到设备标识或型号';
COMMENT ON COLUMN sign_in_record.ip_address IS '客户端IP地址';
COMMENT ON COLUMN sign_in_record.source IS '签到来源:MINI_PROGRAM-小程序扫码,PC_BACKEND-后台管理端';
COMMENT ON COLUMN sign_in_record.is_delete IS '软删除标识:false-未删除,true-已删除';
@@ -1,120 +0,0 @@
-- 数据统计模块测试数据
-- 用于测试会员、预约、签到统计接口
-- 插入测试会员数据
INSERT INTO member_user (id, member_no, nickname, phone, created_at, updated_at, is_deleted) VALUES
(1001, 'M20260601001', '张三', '13800138001', '2026-06-01 08:00:00', '2026-06-01 08:00:00', false),
(1002, 'M20260601002', '李四', '13800138002', '2026-06-01 09:00:00', '2026-06-01 09:00:00', false),
(1003, 'M20260602003', '王五', '13800138003', '2026-06-02 10:00:00', '2026-06-02 10:00:00', false),
(1004, 'M20260603004', '赵六', '13800138004', '2026-06-03 11:00:00', '2026-06-03 11:00:00', false),
(1005, 'M20260609005', '钱七', '13800138005', '2026-06-09 08:00:00', '2026-06-09 08:00:00', false),
(1006, 'M20260609006', '孙八', '13800138006', '2026-06-09 09:00:00', '2026-06-09 09:00:00', false),
(1007, 'M20260609007', '周九', '13800138007', '2026-06-09 10:00:00', '2026-06-09 10:00:00', false),
(1008, 'M20260604008', '吴十', '13800138008', '2026-06-04 14:00:00', '2026-06-04 14:00:00', false),
(1009, 'M20260605009', '郑十一', '13800138009', '2026-06-05 15:00:00', '2026-06-05 15:00:00', false),
(1010, 'M20260606010', '王十二', '13800138010', '2026-06-06 16:00:00', '2026-06-06 16:00:00', false),
(1011, 'M20260607011', '陈十三', '13800138011', '2026-06-07 17:00:00', '2026-06-07 17:00:00', false),
(1012, 'M20260608012', '刘十四', '13800138012', '2026-06-08 18:00:00', '2026-06-08 18:00:00', false)
ON CONFLICT (id) DO NOTHING;
-- 插入测试签到记录数据 (今天的数据)
INSERT INTO sign_in_record (id, member_id, sign_in_time, sign_in_type, sign_in_status, source, is_delete) VALUES
(2001, 1001, '2026-06-09 08:00:00', 'QR_CODE', 'SUCCESS', 'MINI_PROGRAM', false),
(2002, 1002, '2026-06-09 08:15:00', 'MANUAL', 'SUCCESS', 'PC_BACKEND', false),
(2003, 1003, '2026-06-09 08:30:00', 'FACE', 'SUCCESS', 'MINI_PROGRAM', false),
(2004, 1004, '2026-06-09 09:00:00', 'QR_CODE', 'SUCCESS', 'MINI_PROGRAM', false),
(2005, 1005, '2026-06-09 09:15:00', 'MANUAL', 'SUCCESS', 'PC_BACKEND', false),
(2006, 1006, '2026-06-09 09:30:00', 'QR_CODE', 'SUCCESS', 'MINI_PROGRAM', false),
(2007, 1007, '2026-06-09 10:00:00', 'FACE', 'SUCCESS', 'MINI_PROGRAM', false),
(2008, 1008, '2026-06-09 10:15:00', 'QR_CODE', 'SUCCESS', 'MINI_PROGRAM', false),
(2009, 1009, '2026-06-09 10:30:00', 'MANUAL', 'SUCCESS', 'PC_BACKEND', false),
(2010, 1010, '2026-06-09 11:00:00', 'QR_CODE', 'SUCCESS', 'MINI_PROGRAM', false),
(2011, 1011, '2026-06-09 11:15:00', 'FACE', 'FAIL', 'MINI_PROGRAM', false),
(2012, 1012, '2026-06-09 11:30:00', 'MANUAL', 'SUCCESS', 'PC_BACKEND', false)
ON CONFLICT (id) DO NOTHING;
-- 插入测试签到记录数据 (昨天的数据)
INSERT INTO sign_in_record (id, member_id, sign_in_time, sign_in_type, sign_in_status, source, is_delete) VALUES
(2013, 1001, '2026-06-08 07:30:00', 'QR_CODE', 'SUCCESS', 'MINI_PROGRAM', false),
(2014, 1002, '2026-06-08 08:00:00', 'MANUAL', 'SUCCESS', 'PC_BACKEND', false),
(2015, 1003, '2026-06-08 08:30:00', 'FACE', 'SUCCESS', 'MINI_PROGRAM', false),
(2016, 1004, '2026-06-08 09:00:00', 'QR_CODE', 'SUCCESS', 'MINI_PROGRAM', false),
(2017, 1005, '2026-06-08 09:30:00', 'MANUAL', 'SUCCESS', 'PC_BACKEND', false),
(2018, 1006, '2026-06-08 10:00:00', 'QR_CODE', 'SUCCESS', 'MINI_PROGRAM', false),
(2019, 1007, '2026-06-08 10:30:00', 'FACE', 'SUCCESS', 'MINI_PROGRAM', false),
(2020, 1008, '2026-06-08 11:00:00', 'QR_CODE', 'SUCCESS', 'MINI_PROGRAM', false)
ON CONFLICT (id) DO NOTHING;
-- 插入测试签到记录数据 (前天的数据)
INSERT INTO sign_in_record (id, member_id, sign_in_time, sign_in_type, sign_in_status, source, is_delete) VALUES
(2021, 1001, '2026-06-07 07:00:00', 'QR_CODE', 'SUCCESS', 'MINI_PROGRAM', false),
(2022, 1002, '2026-06-07 07:30:00', 'MANUAL', 'SUCCESS', 'PC_BACKEND', false),
(2023, 1003, '2026-06-07 08:00:00', 'FACE', 'FAIL', 'MINI_PROGRAM', false),
(2024, 1004, '2026-06-07 08:30:00', 'QR_CODE', 'SUCCESS', 'MINI_PROGRAM', false),
(2025, 1005, '2026-06-07 09:00:00', 'MANUAL', 'SUCCESS', 'PC_BACKEND', false)
ON CONFLICT (id) DO NOTHING;
-- 插入测试团课数据
INSERT INTO group_course (id, course_name, coach_id, course_type, start_time, end_time, max_members, current_members, status, location, cover_image, description, created_at, updated_at) VALUES
(3001, '瑜伽入门', 1, 1, '2026-06-09 08:00:00', '2026-06-09 09:00:00', 20, 15, 0, '健身房A区', 'https://example.com/yoga.jpg', '适合初学者的瑜伽课程', '2026-06-01 10:00:00', '2026-06-01 10:00:00'),
(3002, '动感单车', 2, 2, '2026-06-09 09:30:00', '2026-06-09 10:30:00', 25, 20, 0, '健身房B区', 'https://example.com/spinning.jpg', '高强度有氧运动', '2026-06-01 11:00:00', '2026-06-01 11:00:00'),
(3003, '普拉提', 3, 1, '2026-06-09 14:00:00', '2026-06-09 15:00:00', 15, 10, 0, '健身房C区', 'https://example.com/pilates.jpg', '核心力量训练', '2026-06-01 12:00:00', '2026-06-01 12:00:00')
ON CONFLICT (id) DO NOTHING;
-- 插入测试团课预约数据 (今天的数据)
INSERT INTO group_course_booking (id, member_id, member_card_id, course_id, booking_time, status, created_at, updated_at) VALUES
(4001, 1001, 1, 3001, '2026-06-09 08:00:00', '2', '2026-06-08 20:00:00', '2026-06-09 08:30:00'),
(4002, 1002, 2, 3001, '2026-06-09 08:00:00', '2', '2026-06-08 21:00:00', '2026-06-09 08:30:00'),
(4003, 1003, 3, 3001, '2026-06-09 08:00:00', '3', '2026-06-08 22:00:00', '2026-06-09 09:00:00'),
(4004, 1004, 4, 3002, '2026-06-09 09:30:00', '2', '2026-06-08 19:00:00', '2026-06-09 09:30:00'),
(4005, 1005, 5, 3002, '2026-06-09 09:30:00', '1', '2026-06-08 20:30:00', '2026-06-09 09:00:00'),
(4006, 1006, 6, 3002, '2026-06-09 09:30:00', '2', '2026-06-08 21:30:00', '2026-06-09 09:30:00'),
(4007, 1007, 7, 3003, '2026-06-09 14:00:00', '2', '2026-06-08 22:30:00', '2026-06-09 14:00:00'),
(4008, 1008, 8, 3003, '2026-06-09 14:00:00', '3', '2026-06-09 08:00:00', '2026-06-09 14:00:00'),
(4009, 1009, 9, 3003, '2026-06-09 14:00:00', '2', '2026-06-09 09:00:00', '2026-06-09 14:00:00'),
(4010, 1010, 10, 3001, '2026-06-09 08:00:00', '2', '2026-06-09 07:00:00', '2026-06-09 08:00:00'),
(4011, 1011, 11, 3002, '2026-06-09 09:30:00', '1', '2026-06-09 08:30:00', '2026-06-09 09:00:00'),
(4012, 1012, 12, 3003, '2026-06-09 14:00:00', '2', '2026-06-09 10:00:00', '2026-06-09 14:00:00')
ON CONFLICT (id) DO NOTHING;
-- 插入测试团课预约数据 (昨天的数据)
INSERT INTO group_course_booking (id, member_id, member_card_id, course_id, booking_time, status, created_at, updated_at) VALUES
(4013, 1001, 1, 3001, '2026-06-08 08:00:00', '2', '2026-06-07 20:00:00', '2026-06-08 08:30:00'),
(4014, 1002, 2, 3001, '2026-06-08 08:00:00', '2', '2026-06-07 21:00:00', '2026-06-08 08:30:00'),
(4015, 1003, 3, 3002, '2026-06-08 09:30:00', '3', '2026-06-07 22:00:00', '2026-06-08 09:30:00'),
(4016, 1004, 4, 3002, '2026-06-08 09:30:00', '2', '2026-06-07 19:00:00', '2026-06-08 09:30:00'),
(4017, 1005, 5, 3003, '2026-06-08 14:00:00', '1', '2026-06-07 20:30:00', '2026-06-08 13:00:00'),
(4018, 1006, 6, 3003, '2026-06-08 14:00:00', '2', '2026-06-07 21:30:00', '2026-06-08 14:00:00')
ON CONFLICT (id) DO NOTHING;
-- 插入测试团课预约数据 (前天的数据)
INSERT INTO group_course_booking (id, member_id, member_card_id, course_id, booking_time, status, created_at, updated_at) VALUES
(4019, 1001, 1, 3002, '2026-06-07 09:30:00', '2', '2026-06-06 20:00:00', '2026-06-07 09:30:00'),
(4020, 1002, 2, 3002, '2026-06-07 09:30:00', '2', '2026-06-06 21:00:00', '2026-06-07 09:30:00'),
(4021, 1003, 3, 3003, '2026-06-07 14:00:00', '2', '2026-06-06 22:00:00', '2026-06-07 14:00:00'),
(4022, 1004, 4, 3003, '2026-06-07 14:00:00', '3', '2026-06-06 19:00:00', '2026-06-07 14:00:00')
ON CONFLICT (id) DO NOTHING;
-- 预期统计结果 (今日):
-- 会员统计:
-- 新增会员: 3 (1005, 1006, 1007)
-- 活跃会员: 12 (所有会员今日或近期有活动)
-- 总会员数: 12
-- 签到会员: 12
-- 预约会员: 9
-- 取消会员: 2
-- 预约统计:
-- 总预约: 12
-- 取消: 2
-- 出席: 8
-- 缺席: 2
-- 出席率: 8/10 = 80%
-- 取消率: 2/12 = 16.67%
-- 签到统计:
-- 总签到: 12
-- 成功: 11
-- 失败: 1
-- 成功率: 11/12 = 91.67%
-- 类型分布: QR_CODE=5, MANUAL=4, FACE=3
@@ -1,43 +0,0 @@
-- ============================================
-- 团课推荐测试数据
-- ============================================
-- 推荐数据1: 极速燃脂单车 - 高优先级推荐(热门课程)
INSERT INTO group_course_recommend (course_id, recommend_title, recommend_content, recommend_reason, priority, is_active, create_by, created_at, updated_at) VALUES
(1, '本周热门推荐', '极速燃脂单车课程,跟随音乐节奏变换阻力和速度,体验爬坡与冲刺的快感,一节课消耗800大卡!', '教练专业,课程内容丰富,深受学员喜爱,燃脂效果显著', 20, true, 'admin', '2026-06-15 10:00:00', '2026-06-15 10:00:00');
-- 推荐数据2: 清晨流瑜伽 - 中等优先级推荐(适合新手)
INSERT INTO group_course_recommend (course_id, recommend_title, recommend_content, recommend_reason, priority, is_active, create_by, created_at, updated_at) VALUES
(2, '新手友好推荐', '清晨流瑜伽课程,适合有一定基础的学员,通过流畅的体式连接呼吸,唤醒身体能量。', '适合新手入门,教练耐心指导,课程节奏适中', 15, true, 'admin', '2026-06-15 11:00:00', '2026-06-15 11:00:00');
-- 推荐数据3: 燃脂搏击 - 低优先级推荐(满员课程,已禁用)
INSERT INTO group_course_recommend (course_id, recommend_title, recommend_content, recommend_reason, priority, is_active, create_by, created_at, updated_at) VALUES
(3, '高强度燃脂', '燃脂搏击课程,高强度间歇训练,配合音乐快速燃脂,释放压力。', '高强度训练,适合进阶学员,快速燃脂塑形', 10, false, 'admin', '2026-06-15 12:00:00', '2026-06-15 12:00:00');
-- 推荐数据4: 哈他瑜伽 - 中等优先级推荐(基础课程)
INSERT INTO group_course_recommend (course_id, recommend_title, recommend_content, recommend_reason, priority, is_active, create_by, created_at, updated_at) VALUES
(4, '基础瑜伽推荐', '基础哈他瑜伽课程,适合所有级别学员,通过基础体式练习提升身体柔韧性和平衡能力。', '零基础友好,适合所有健身水平,放松身心', 12, true, 'coach_li', '2026-06-15 13:00:00', '2026-06-15 13:00:00');
-- 推荐数据5: 蜜桃臀塑造 - 高优先级推荐(热门课程,但课程已结束)
INSERT INTO group_course_recommend (course_id, recommend_title, recommend_content, recommend_reason, priority, is_active, create_by, created_at, updated_at) VALUES
(6, '塑形热门课程', '蜜桃臀塑造课程,针对性训练臀部肌肉群,打造完美曲线。', '专业私教指导,动作标准,效果显著,深受女性学员喜爱', 18, true, 'coach_li', '2026-05-25 09:15:00', '2026-05-25 09:15:00');
-- 推荐数据6: 午间冥想放松 - 低优先级推荐(放松课程)
INSERT INTO group_course_recommend (course_id, recommend_title, recommend_content, recommend_reason, priority, is_active, create_by, created_at, updated_at) VALUES
(7, '午间放松推荐', '午间冥想放松课程,通过呼吸和正念冥想,深度放松身心,缓解工作压力。', '适合上班族,午间放松充电,提升下午工作效率', 8, true, 'admin', '2026-05-25 09:00:00', '2026-05-25 09:00:00');
-- 推荐数据7: 极速燃脂单车 - 第二个推荐(不同角度推荐)
INSERT INTO group_course_recommend (course_id, recommend_title, recommend_content, recommend_reason, priority, is_active, create_by, created_at, updated_at) VALUES
(1, '减脂首选课程', '想要快速减脂?极速燃脂单车是你的最佳选择!专业教练带领,科学训练计划。', '减脂效果最佳,课程强度适中,适合想要快速瘦身的学员', 16, true, 'coach_zhang', '2026-06-15 14:00:00', '2026-06-15 14:00:00');
-- 推荐数据8: 清晨流瑜伽 - 第二个推荐(不同角度推荐)
INSERT INTO group_course_recommend (course_id, recommend_title, recommend_content, recommend_reason, priority, is_active, create_by, created_at, updated_at) VALUES
(2, '晨练优选', '清晨流瑜伽,唤醒身体能量,开启活力一天!适合晨练爱好者。', '晨练最佳选择,提升身体活力,改善精神状态', 14, true, 'coach_wang', '2026-06-15 15:00:00', '2026-06-15 15:00:00');
-- 推荐数据9: 哈他瑜伽 - 第二个推荐(不同角度推荐)
INSERT INTO group_course_recommend (course_id, recommend_title, recommend_content, recommend_reason, priority, is_active, create_by, created_at, updated_at) VALUES
(4, '身心平衡推荐', '哈他瑜伽课程,通过体式练习和呼吸控制,达到身心平衡,提升整体健康水平。', '改善身体柔韧性,增强核心力量,提升身体协调性', 11, true, 'coach_li', '2026-06-15 16:00:00', '2026-06-15 16:00:00');
-- 推荐数据10: 午间冥想放松 - 第二个推荐(不同角度推荐,已禁用)
INSERT INTO group_course_recommend (course_id, recommend_title, recommend_content, recommend_reason, priority, is_active, create_by, created_at, updated_at) VALUES
(7, '职场减压课程', '午间冥想放松,专为职场人士设计,快速缓解工作压力,提升工作状态。', '职场减压首选,课程时间短,效果显著', 9, false, 'admin', '2026-05-25 10:00:00', '2026-05-25 10:00:00');
@@ -0,0 +1,9 @@
-- ============================================
-- V20: 为 member_user 表添加 deleted_at 字段
-- 原因:BaseEntity 已映射该字段,但 member_user 表缺失
-- ============================================
ALTER TABLE member_user
ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMP;
COMMENT ON COLUMN member_user.deleted_at IS '软删除时间';
@@ -0,0 +1,9 @@
-- ============================================
-- V21: 为 member_card_transactions 表添加 updated_at 字段
-- 原因:MemberCardTransaction 继承 BaseEntity 已映射该字段,但表缺失
-- ============================================
ALTER TABLE member_card_transactions
ADD COLUMN IF NOT EXISTS updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;
COMMENT ON COLUMN member_card_transactions.updated_at IS '更新时间';
@@ -0,0 +1,100 @@
-- ============================================
-- V22: 新增业务模块权限
-- 描述: 为会员、会员卡、团课、签到、数据统计、员工管理等业务模块创建权限
-- ============================================
-- ============================================
-- 会员管理权限
-- ============================================
INSERT INTO sys_permission (permission_name, permission_code, resource, action, description, status, create_by, update_by, created_at, updated_at) VALUES
('会员查看', 'business:member:view', '/api/admin/members', 'GET', '查看会员列表及详情', 1, 'system', 'system', NOW(), NOW()),
('会员编辑', 'business:member:edit', '/api/admin/member', 'PUT', '编辑会员信息', 1, 'system', 'system', NOW(), NOW()),
('会员手机修改', 'business:member:phone', '/api/admin/member/phone', 'POST', '管理员修改会员手机号', 1, 'system', 'system', NOW(), NOW());
-- ============================================
-- 会员卡管理权限
-- ============================================
INSERT INTO sys_permission (permission_name, permission_code, resource, action, description, status, create_by, update_by, created_at, updated_at) VALUES
('会员卡查看', 'business:memberCard:view', '/api/member-cards', 'GET', '查看会员卡列表及详情', 1, 'system', 'system', NOW(), NOW()),
('会员卡创建', 'business:memberCard:create', '/api/member-cards', 'POST', '创建会员卡类型', 1, 'system', 'system', NOW(), NOW()),
('会员卡编辑', 'business:memberCard:edit', '/api/member-cards', 'PUT', '编辑会员卡类型', 1, 'system', 'system', NOW(), NOW()),
('会员卡删除', 'business:memberCard:delete', '/api/member-cards', 'DELETE', '删除会员卡类型', 1, 'system', 'system', NOW(), NOW()),
('会员卡购买', 'business:memberCard:purchase', '/api/member-card-records/purchase', 'POST', '为会员购买/绑定会员卡', 1, 'system', 'system', NOW(), NOW()),
('会员卡退卡', 'business:memberCard:refund', '/api/member-card-records/refund', 'POST', '会员卡退卡/解绑', 1, 'system', 'system', NOW(), NOW());
-- ============================================
-- 团课管理权限
-- ============================================
INSERT INTO sys_permission (permission_name, permission_code, resource, action, description, status, create_by, update_by, created_at, updated_at) VALUES
('团课查看', 'business:groupCourse:view', '/api/groupCourse', 'GET', '查看团课列表及详情', 1, 'system', 'system', NOW(), NOW()),
('团课创建', 'business:groupCourse:create', '/api/groupCourse', 'POST', '创建团课', 1, 'system', 'system', NOW(), NOW()),
('团课编辑', 'business:groupCourse:edit', '/api/groupCourse', 'PUT', '编辑团课信息', 1, 'system', 'system', NOW(), NOW()),
('团课删除', 'business:groupCourse:delete', '/api/groupCourse', 'DELETE', '删除团课', 1, 'system', 'system', NOW(), NOW()),
('团课取消', 'business:groupCourse:cancel', '/api/groupCourse/cancel', 'POST', '取消团课', 1, 'system', 'system', NOW(), NOW());
-- ============================================
-- 团课类型管理权限
-- ============================================
INSERT INTO sys_permission (permission_name, permission_code, resource, action, description, status, create_by, update_by, created_at, updated_at) VALUES
('团课类型查看', 'business:groupCourseType:view', '/api/groupCourse/types', 'GET', '查看团课类型列表', 1, 'system', 'system', NOW(), NOW()),
('团课类型创建', 'business:groupCourseType:create', '/api/groupCourse/types', 'POST', '创建团课类型', 1, 'system', 'system', NOW(), NOW()),
('团课类型编辑', 'business:groupCourseType:edit', '/api/groupCourse/types', 'PUT', '编辑团课类型', 1, 'system', 'system', NOW(), NOW()),
('团课类型删除', 'business:groupCourseType:delete', '/api/groupCourse/types', 'DELETE', '删除团课类型', 1, 'system', 'system', NOW(), NOW());
-- ============================================
-- 团课推荐管理权限
-- ============================================
INSERT INTO sys_permission (permission_name, permission_code, resource, action, description, status, create_by, update_by, created_at, updated_at) VALUES
('团课推荐查看', 'business:groupCourseRecommend:view', '/api/groupCourse/recommend', 'GET', '查看推荐团课列表', 1, 'system', 'system', NOW(), NOW()),
('团课推荐创建', 'business:groupCourseRecommend:create', '/api/groupCourse/recommend', 'POST', '创建推荐团课', 1, 'system', 'system', NOW(), NOW()),
('团课推荐编辑', 'business:groupCourseRecommend:edit', '/api/groupCourse/recommend', 'PUT', '编辑推荐团课', 1, 'system', 'system', NOW(), NOW()),
('团课推荐删除', 'business:groupCourseRecommend:delete', '/api/groupCourse/recommend', 'DELETE', '删除推荐团课', 1, 'system', 'system', NOW(), NOW());
-- ============================================
-- 团课预约管理权限
-- ============================================
INSERT INTO sys_permission (permission_name, permission_code, resource, action, description, status, create_by, update_by, created_at, updated_at) VALUES
('团课预约查看', 'business:groupCourseBooking:view', '/api/groupCourse/bookings', 'GET', '查看团课预约记录', 1, 'system', 'system', NOW(), NOW()),
('团课预约创建', 'business:groupCourseBooking:create', '/api/groupCourse/book', 'POST', '预约团课', 1, 'system', 'system', NOW(), NOW()),
('团课预约取消', 'business:groupCourseBooking:cancel', '/api/groupCourse/booking/cancel', 'POST', '取消团课预约', 1, 'system', 'system', NOW(), NOW());
-- ============================================
-- 签到管理权限
-- ============================================
INSERT INTO sys_permission (permission_name, permission_code, resource, action, description, status, create_by, update_by, created_at, updated_at) VALUES
('签到查看', 'business:checkIn:view', '/api/checkIn/records', 'GET', '查看签到记录', 1, 'system', 'system', NOW(), NOW()),
('签到操作', 'business:checkIn:create', '/api/checkIn', 'POST', '执行签到操作', 1, 'system', 'system', NOW(), NOW()),
('签到导出', 'business:checkIn:export', '/api/checkIn/records/export', 'GET', '导出签到记录', 1, 'system', 'system', NOW(), NOW());
-- ============================================
-- 数据统计权限
-- ============================================
INSERT INTO sys_permission (permission_name, permission_code, resource, action, description, status, create_by, update_by, created_at, updated_at) VALUES
('数据统计查看', 'business:dataCount:view', '/api/datacount', 'GET', '查看数据统计报表', 1, 'system', 'system', NOW(), NOW()),
('数据统计导出', 'business:dataCount:export', '/api/datacount/export', 'GET', '导出统计报表', 1, 'system', 'system', NOW(), NOW());
-- ============================================
-- 员工管理权限
-- ============================================
INSERT INTO sys_permission (permission_name, permission_code, resource, action, description, status, create_by, update_by, created_at, updated_at) VALUES
('员工查看', 'business:employee:view', '/api/employees/page', 'GET', '查看员工列表', 1, 'system', 'system', NOW(), NOW()),
('员工创建', 'business:employee:create', '/api/users', 'POST', '创建员工账号', 1, 'system', 'system', NOW(), NOW()),
('员工编辑', 'business:employee:edit', '/api/users', 'PUT', '编辑员工信息', 1, 'system', 'system', NOW(), NOW()),
('员工删除', 'business:employee:delete', '/api/users', 'DELETE', '删除/禁用员工账号', 1, 'system', 'system', NOW(), NOW()),
('员工分配角色', 'business:employee:assignRole', '/api/users/roles', 'POST', '为员工分配角色', 1, 'system', 'system', NOW(), NOW());
-- ============================================
-- 为超级管理员角色分配所有业务权限
-- ============================================
INSERT INTO sys_role_permission (role_id, permission_id, create_by, update_by, created_at, updated_at)
SELECT 1, id, 'system', 'system', NOW(), NOW()
FROM sys_permission
WHERE permission_code LIKE 'business:%'
AND status = 1
AND id NOT IN (SELECT permission_id FROM sys_role_permission WHERE role_id = 1);
-- ============================================
-- 重置序列值
-- ============================================
SELECT setval('sys_permission_id_seq', (SELECT COALESCE(MAX(id), 1) FROM sys_permission));
SELECT setval('sys_role_permission_id_seq', (SELECT COALESCE(MAX(id), 1) FROM sys_role_permission));
@@ -0,0 +1,93 @@
-- ============================================================
-- V23: 教练账号测试数据
-- 描述: 创建教练角色、教练用户及相关团课测试数据
-- 日期: 2026-06-22
-- ============================================================
-- ============================================================
-- 1. 新增教练专属权限
-- 教练只能查看自己教授的团课/预约/签到信息,不能修改数据库
-- ============================================================
INSERT INTO sys_permission (permission_name, permission_code, resource, action, description, status, create_by, update_by, created_at, updated_at) VALUES
('查看自己的团课', 'coach:course:view', '/api/coach/courses', 'GET', '查看教练自己教授的团课列表及详情', 1, 'system', 'system', NOW(), NOW()),
('查看自己团课的预约', 'coach:booking:view', '/api/coach/bookings', 'GET', '查看教练自己团课的会员预约记录', 1, 'system', 'system', NOW(), NOW()),
('查看自己团课的签到', 'coach:signIn:view', '/api/coach/signins', 'GET', '查看教练自己团课的会员签到记录', 1, 'system', 'system', NOW(), NOW()),
('教练执行签到', 'coach:signIn:create', '/api/coach/signins', 'POST', '教练为自己团课的会员执行签到操作', 1, 'system', 'system', NOW(), NOW())
ON CONFLICT (permission_code) DO NOTHING;
-- ============================================================
-- 2. 教练角色
-- ============================================================
INSERT INTO sys_role (id, role_name, role_key, role_sort, status, create_by, update_by, created_at, updated_at)
VALUES (5, '教练', 'coach', 5, 1, 'system', 'system', NOW(), NOW())
ON CONFLICT (role_key) DO NOTHING;
-- ============================================================
-- 3. 教练用户(密码: Test@123
-- ============================================================
INSERT INTO sys_user (id, username, password, email, phone, nickname, status, create_by, update_by, created_at, updated_at)
VALUES (20, 'coach', '$2a$12$nZ1EMUpZQljbnEdIKzH72eHlDJKUmHmHppnTTVth/SlHs5VpSAr8C', 'coach@novalon.com', '13900000001', '张教练', 1, 'system', 'system', NOW(), NOW())
ON CONFLICT (username) DO NOTHING;
-- ============================================================
-- 4. 教练角色关联
-- ============================================================
INSERT INTO user_role (user_id, role_id, created_by, created_at)
VALUES (20, 5, 'system', NOW())
ON CONFLICT (user_id, role_id) DO NOTHING;
-- ============================================================
-- 5. 为教练角色分配有限权限
-- 教练只能查看自己教授的团课、查看自己团课的预约/签到信息、为自己团课的会员签到
-- 不能对数据库进行写操作(签到属于业务操作,非数据库直接写入)
-- ============================================================
INSERT INTO sys_role_permission (role_id, permission_id, create_by, update_by, created_at, updated_at)
SELECT 5, id, 'system', 'system', NOW(), NOW()
FROM sys_permission
WHERE permission_code IN (
'coach:course:view', -- 查看自己的团课
'coach:booking:view', -- 查看自己团课的预约信息
'coach:signIn:view', -- 查看自己团课的签到信息
'coach:signIn:create', -- 为自己团课的会员签到
'system:notice:view' -- 查看系统公告
)
AND NOT EXISTS (
SELECT 1 FROM sys_role_permission WHERE role_id = 5 AND permission_id = sys_permission.id
);
-- ============================================================
-- 6. 为教练分配今天的测试团课
-- ============================================================
INSERT INTO group_course (course_name, coach_id, course_type, start_time, end_time, max_members, current_members, status, location, description, point_card_amount, create_by, created_at, updated_at)
VALUES
('核心力量训练', 20, (SELECT id FROM group_course_type WHERE type_name = '核心训练' LIMIT 1),
CURRENT_DATE + TIME '08:00', CURRENT_DATE + TIME '09:00', 15, 3, '0', '健身房B区', '针对核心肌群的专项训练,适合所有水平学员', 1, 'system', NOW(), NOW()),
('瑜伽入门', 20, (SELECT id FROM group_course_type WHERE type_name = '瑜伽入门' LIMIT 1),
CURRENT_DATE + TIME '10:00', CURRENT_DATE + TIME '11:00', 12, 5, '0', '瑜伽教室', '基础的瑜伽体式教学,新课上线欢迎参加', 1, 'system', NOW(), NOW()),
('动感单车', 20, (SELECT id FROM group_course_type WHERE type_name = '动感单车' LIMIT 1),
CURRENT_DATE + TIME '14:00', CURRENT_DATE + TIME '15:00', 20, 8, '0', '单车房', '高强度燃脂骑行,动感音乐带你飞', 2, 'system', NOW(), NOW()),
('晚间普拉提', 20, (SELECT id FROM group_course_type WHERE type_name = '普拉提' LIMIT 1),
CURRENT_DATE + TIME '18:00', CURRENT_DATE + TIME '19:00', 10, 2, '0', '普拉提教室', '注重核心力量和身体控制,放松一天疲劳', 1, 'system', NOW(), NOW());
-- ============================================================
-- 7. 为教练创建一个未来的团课(方便测试时间表)
-- ============================================================
INSERT INTO group_course (course_name, coach_id, course_type, start_time, end_time, max_members, current_members, status, location, description, point_card_amount, create_by, created_at, updated_at)
VALUES
('HIIT燃脂训练', 20, (SELECT id FROM group_course_type WHERE type_name = 'HIIT训练' LIMIT 1),
CURRENT_DATE + INTERVAL '1 day' + TIME '08:00', CURRENT_DATE + INTERVAL '1 day' + TIME '09:00',
15, 0, '0', '综合训练区', '高强度间歇训练,挑战心肺极限', 2, 'system', NOW(), NOW()),
('周末瑜伽', 20, (SELECT id FROM group_course_type WHERE type_name = '瑜伽进阶' LIMIT 1),
CURRENT_DATE + INTERVAL '3 days' + TIME '09:00', CURRENT_DATE + INTERVAL '3 days' + TIME '10:30',
12, 0, '0', '瑜伽教室', '针对有基础的进阶瑜伽课程', 1, 'system', NOW(), NOW());
-- ============================================================
-- 8. 重置序列值
-- ============================================================
SELECT setval('sys_role_id_seq', GREATEST((SELECT COALESCE(MAX(id), 0) FROM sys_role), 5));
SELECT setval('sys_user_id_seq', GREATEST((SELECT COALESCE(MAX(id), 0) FROM sys_user), 20));
SELECT setval('group_course_id_seq', (SELECT COALESCE(MAX(id), 0) FROM group_course));
@@ -0,0 +1,50 @@
-- ============================================================
-- V24: 新增第二个测试教练账号(李教练)
-- 描述:
-- 1. 新增测试教练用户 coachli(李教练)
-- 2. 为李教练分配教练角色(继承教练的有限权限)
-- 3. 为李教练分配未来一周的测试团课
-- 日期: 2026-06-22
-- ============================================================
-- ============================================================
-- 1. 第二个测试教练账号(密码: Test@123)
-- ============================================================
INSERT INTO sys_user (id, username, password, email, phone, nickname, status, create_by, update_by, created_at, updated_at)
VALUES (21, 'coachli', '$2a$12$nZ1EMUpZQljbnEdIKzH72eHlDJKUmHmHppnTTVth/SlHs5VpSAr8C', 'coachli@novalon.com', '13900000002', '李教练', 1, 'system', 'system', NOW(), NOW())
ON CONFLICT (username) DO NOTHING;
-- ============================================================
-- 2. 为李教练分配教练角色(role_id=5)
-- 继承教练角色的所有有限权限
-- ============================================================
INSERT INTO user_role (user_id, role_id, created_by, created_at)
VALUES (21, 5, 'system', NOW())
ON CONFLICT (user_id, role_id) DO NOTHING;
-- ============================================================
-- 3. 为李教练分配测试团课(未来一周的课程)
-- ============================================================
INSERT INTO group_course (course_name, coach_id, course_type, start_time, end_time, max_members, current_members, status, location, description, point_card_amount, create_by, created_at, updated_at)
VALUES
('入门瑜伽', 21, (SELECT id FROM group_course_type WHERE type_name = '瑜伽入门' LIMIT 1),
CURRENT_DATE + INTERVAL '2 days' + TIME '09:00', CURRENT_DATE + INTERVAL '2 days' + TIME '10:00',
15, 0, '0', '瑜伽教室', '适合零基础学员的入门瑜伽课程', 1, 'system', NOW(), NOW()),
('燃脂搏击', 21, (SELECT id FROM group_course_type WHERE type_name = '动感单车' LIMIT 1),
CURRENT_DATE + INTERVAL '2 days' + TIME '15:00', CURRENT_DATE + INTERVAL '2 days' + TIME '16:00',
20, 0, '0', '综合训练区', '高强度搏击操,燃烧卡路里', 2, 'system', NOW(), NOW()),
('肩颈理疗', 21, (SELECT id FROM group_course_type WHERE type_name = '普拉提' LIMIT 1),
CURRENT_DATE + INTERVAL '4 days' + TIME '10:00', CURRENT_DATE + INTERVAL '4 days' + TIME '11:00',
12, 0, '0', '普拉提教室', '针对久坐人群的肩颈放松课程', 1, 'system', NOW(), NOW()),
('晨间有氧', 21, (SELECT id FROM group_course_type WHERE type_name = 'HIIT训练' LIMIT 1),
CURRENT_DATE + INTERVAL '5 days' + TIME '07:00', CURRENT_DATE + INTERVAL '5 days' + TIME '08:00',
20, 0, '0', '有氧区', '清晨燃脂有氧训练,开启活力一天', 2, 'system', NOW(), NOW());
-- ============================================================
-- 4. 重置序列值
-- ============================================================
SELECT setval('sys_user_id_seq', GREATEST((SELECT COALESCE(MAX(id), 0) FROM sys_user), 21));
SELECT setval('group_course_id_seq', (SELECT COALESCE(MAX(id), 0) FROM group_course));
@@ -13,6 +13,8 @@ CREATE TABLE IF NOT EXISTS group_course (
max_members INTEGER DEFAULT 20,
current_members INTEGER DEFAULT 0,
status VARCHAR(1) DEFAULT '0',
actual_start_time TIMESTAMP,
actual_end_time TIMESTAMP,
location VARCHAR(255),
cover_image VARCHAR(500),
description TEXT,
@@ -50,7 +52,9 @@ COMMENT ON COLUMN group_course.start_time IS '开始时间';
COMMENT ON COLUMN group_course.end_time IS '结束时间';
COMMENT ON COLUMN group_course.max_members IS '最大参与人数';
COMMENT ON COLUMN group_course.current_members IS '当前参与人数';
COMMENT ON COLUMN group_course.status IS '状态(0正常 1已取消 2已结束)';
COMMENT ON COLUMN group_course.status IS '状态(0正常 1已取消 2已结束 3进行中 4超时';
COMMENT ON COLUMN group_course.actual_start_time IS '实际开课时间(教练点击开课时记录)';
COMMENT ON COLUMN group_course.actual_end_time IS '实际结课时间(教练点击结课时记录)';
COMMENT ON COLUMN group_course.location IS '上课地点';
COMMENT ON COLUMN group_course.cover_image IS '封面图URL';
COMMENT ON COLUMN group_course.description IS '课程描述';
@@ -1,28 +0,0 @@
-- 场景1: 0人预约,可预约(正常状态,6月15日,距开始还有14天)
INSERT INTO group_course (course_name, coach_id, course_type, start_time, end_time, max_members, current_members, status, location, cover_image, description, create_by, created_at, updated_at) VALUES
('极速燃脂单车', 104, 2, '2026-06-02 16:45:00', '2026-06-15 20:20:00', 25, 0, 0, '单车房', '/images/spinning.jpg', '跟随音乐节奏变换阻力和速度,体验爬坡与冲刺的快感,一节课消耗800大卡。', 'admin', '2026-06-01 11:00:00', '2026-06-01 11:00:00');
-- 场景2: 已有人预约,可预约(正常状态,6月12日,5/15人)
INSERT INTO group_course (course_name, coach_id, course_type, start_time, end_time, max_members, current_members, status, location, cover_image, description, create_by, created_at, updated_at) VALUES
('清晨流瑜伽', 101, 1, '2026-06-12 09:00:00', '2026-06-12 10:30:00', 15, 5, 0, 'A座3楼瑜伽教室', '/images/yoga_flow.jpg', '适合有一定基础的学员,通过流畅的体式连接呼吸,唤醒身体能量。', 'admin', '2026-06-01 10:00:00', '2026-06-01 10:00:00');
-- 场景3: 满员,不可预约(正常状态但已满员,6月10日,20/20人)
INSERT INTO group_course (course_name, coach_id, course_type, start_time, end_time, max_members, current_members, status, location, cover_image, description, create_by, created_at, updated_at) VALUES
('燃脂搏击', 102, 2, '2026-06-10 18:30:00', '2026-06-10 19:30:00', 20, 20, 0, '综合训练区', '/images/kickboxing.jpg', '高强度间歇训练,配合音乐快速燃脂,释放压力。名额已满,无法预约。', 'coach_zhang', '2026-06-01 14:30:00', '2026-06-01 14:30:00');
-- 场景4: 超出可预约时间,不可预约(正常状态但距开始不足30分钟)
-- 当前时间: 2026-06-01 15:00,课程开始: 2026-06-01 15:20
INSERT INTO group_course (course_name, coach_id, course_type, start_time, end_time, max_members, current_members, status, location, cover_image, description, create_by, created_at, updated_at) VALUES
('哈他瑜伽', 101, 1, '2026-06-01 15:20:00', '2026-06-01 16:50:00', 12, 3, 0, '瑜伽教室B', '/images/hatha_yoga.jpg', '基础哈他瑜伽,适合所有级别。距开始不足30分钟,已停止预约。', 'coach_li', '2026-06-01 08:00:00', '2026-06-01 08:00:00');
-- 场景5: 课程已取消,不可预约(status=1)
INSERT INTO group_course (course_name, coach_id, course_type, start_time, end_time, max_members, current_members, status, location, cover_image, description, create_by, created_at, updated_at) VALUES
('周末冥想修复', 101, 1, '2026-06-20 15:00:00', '2026-06-20 16:00:00', 12, 3, 1, '冥想室', '/images/meditation.jpg', '通过呼吸和正念冥想,深度放松身心。该课程已被取消。', 'coach_wang', '2026-05-28 08:00:00', '2026-05-28 08:00:00');
-- 场景6: 课程已结束,不可预约(status=2)
INSERT INTO group_course (course_name, coach_id, course_type, start_time, end_time, max_members, current_members, status, location, cover_image, description, create_by, created_at, updated_at) VALUES
('蜜桃臀塑造', 103, 3, '2026-05-30 19:00:00', '2026-05-30 20:00:00', 10, 8, 2, '私教专区', '/images/glute.jpg', '针对性训练臀部肌肉群,课程已于5月30日结束,无法预约。', 'coach_li', '2026-05-20 09:15:00', '2026-05-20 09:15:00');
-- 场景7(可选): 已结束但未满员的课程(status=2,即使有空位也不可预约)
INSERT INTO group_course (course_name, coach_id, course_type, start_time, end_time, max_members, current_members, status, location, cover_image, description, create_by, created_at, updated_at) VALUES
('午间冥想放松', 101, 1, '2026-05-31 12:00:00', '2026-05-31 13:00:00', 15, 6, 2, '冥想室', '/images/meditation_noon.jpg', '午间冥想课程,已于5月31日结束。', 'admin', '2026-05-25 09:00:00', '2026-05-25 09:00:00');