瀏覽代碼

fix: 修复数据库迁移SQL语法错误和测试用例

- DatabaseInitializer: 移除MySQL不支持的'ADD COLUMN IF NOT EXISTS'语法(MariaDB特性)
  - guide_packages表: 移除IF NOT EXISTS, 新增teacher_id/template_id改为NULL
  - assessment_appointments表: 移除IF NOT EXISTS
- GuideModuleIntegrationTest: 修正套餐创建使用TaskTemplatePackage(非GuidePackageTemplate)
  - 使用CreatePackageDTO + taskTemplatePackageService.createPackage()
  - 添加cycleDays必填字段
  - 新增重复创建验证替代原价格校验
- TeacherLoginTest: 补全users表NOT NULL字段(openid, familyId)
  - 修正role为ENUM有效值(teacher), 使用roles字段测试多角色
User 4 月之前
父節點
當前提交
d89dfb03ff

+ 35 - 9
zxyj-backend/src/main/java/com/zxyj/config/DatabaseInitializer.java

@@ -12,7 +12,7 @@ import java.util.List;
 
 @Slf4j
 @Component
-public class DatabaseInitializer implements CommandLineRunner {
+public class DatabaseInitializer implements CommandLineRunner {
 
     @Resource
     private JdbcTemplate jdbcTemplate;
@@ -167,7 +167,7 @@ public class DatabaseInitializer implements CommandLineRunner {
 "updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, " +
 "INDEX idx_child_id_status (child_id, status), " +
 "INDEX idx_is_template (is_template)" +
-") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4",
+") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4",
             
             // 奖励分类表
             "CREATE TABLE IF NOT EXISTS reward_categories (" +
@@ -721,7 +721,7 @@ log.info("已添加max_frequency列到admin_task_templates表");
             // 修改失败,忽略错误
         }
 
-        // 迁移16: 创建用户操作日志表
+        // 迁移16: 创建用户操作日志表
 try {
 jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS user_operation_logs (" +
 "id BIGINT AUTO_INCREMENT PRIMARY KEY, " +
@@ -875,19 +875,19 @@ log.info("已添加template_id列到tasks表");
 
         // assessment_appointments 新字段
         try {
-            jdbcTemplate.execute("ALTER TABLE assessment_appointments ADD COLUMN IF NOT EXISTS user_id BIGINT COMMENT '用户ID'");
+            jdbcTemplate.execute("ALTER TABLE assessment_appointments ADD COLUMN user_id BIGINT COMMENT '用户ID'");
         } catch (Exception e) {
         }
         try {
-            jdbcTemplate.execute("ALTER TABLE assessment_appointments ADD COLUMN IF NOT EXISTS guide_id BIGINT COMMENT '成长规划师ID'");
+            jdbcTemplate.execute("ALTER TABLE assessment_appointments ADD COLUMN guide_id BIGINT COMMENT '成长规划师ID'");
         } catch (Exception e) {
         }
         try {
-            jdbcTemplate.execute("ALTER TABLE assessment_appointments ADD COLUMN IF NOT EXISTS package_id BIGINT COMMENT '套餐ID'");
+            jdbcTemplate.execute("ALTER TABLE assessment_appointments ADD COLUMN package_id BIGINT COMMENT '套餐ID'");
         } catch (Exception e) {
         }
         try {
-            jdbcTemplate.execute("ALTER TABLE assessment_appointments ADD COLUMN IF NOT EXISTS remark VARCHAR(500) COMMENT '备注'");
+            jdbcTemplate.execute("ALTER TABLE assessment_appointments ADD COLUMN remark VARCHAR(500) COMMENT '备注'");
         } catch (Exception e) {
         }
 
@@ -919,7 +919,7 @@ log.info("已添加template_id列到tasks表");
         } catch (Exception e) {
         }
 
-        log.info("数据库迁移完成");
+        log.info("数据库迁移完成");
     }
 
     private void initializeDefaultData() {
@@ -939,7 +939,7 @@ jdbcTemplate.execute("INSERT INTO rewards (family_id, child_id, title, points_re
 "(0, NULL, \'吃冰淇淋\', 20, \'物质类\', 1), " +
 "(0, NULL, \'选择晚餐\', 25, \'特权类\', 1)");
 log.info("预设奖励模板已初始化");
-}
+}
         } catch (Exception e) {
             log.warn("初始化预设奖励失败: {}", e.getMessage());
         }
@@ -1210,6 +1210,32 @@ try {
             log.warn("创建guide_packages表失败: {}", e.getMessage());
         }
 
+        // 迁移:guide_packages 表添加缺失列
+        try {
+            jdbcTemplate.execute("ALTER TABLE guide_packages ADD COLUMN guide_id BIGINT COMMENT '成长规划师ID' AFTER id");
+        } catch (Exception e) {
+        }
+
+        try {
+            jdbcTemplate.execute("ALTER TABLE guide_packages ADD COLUMN package_id BIGINT COMMENT '关联模板' AFTER guide_id");
+        } catch (Exception e) {
+        }
+
+        try {
+            jdbcTemplate.execute("ALTER TABLE guide_packages ADD COLUMN commission_rate DECIMAL(5,2) COMMENT '佣金比例' AFTER package_id");
+        } catch (Exception e) {
+        }
+
+        try {
+            jdbcTemplate.execute("ALTER TABLE guide_packages MODIFY COLUMN teacher_id BIGINT NULL");
+        } catch (Exception e) {
+        }
+
+        try {
+            jdbcTemplate.execute("ALTER TABLE guide_packages MODIFY COLUMN template_id BIGINT NULL");
+        } catch (Exception e) {
+        }
+
         // 成长规划师套餐服务项表
         try {
             jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS guide_package_services (" +

+ 20 - 22
zxyj-backend/src/test/java/com/zxyj/integration/GuideModuleIntegrationTest.java

@@ -6,6 +6,8 @@ import com.zxyj.service.*;
 import org.junit.jupiter.api.Test;
 import org.springframework.boot.test.context.SpringBootTest;
 
+import com.zxyj.dto.CreatePackageDTO;
+
 import java.math.BigDecimal;
 import java.util.List;
 
@@ -30,9 +32,11 @@ public class GuideModuleIntegrationTest {
     @Resource
     private GuidePackageService guidePackageService;
 
+    @Resource
+    private TaskTemplatePackageService taskTemplatePackageService;
+
     @Test
     public void testGuidePackageCreationFlow() {
-        // Step 1: 创建服务类型
         ServiceType serviceType = new ServiceType();
         serviceType.setName("DAN测评");
         serviceType.setIcon("📊");
@@ -40,9 +44,7 @@ public class GuideModuleIntegrationTest {
         serviceType.setStatus("ACTIVE");
         ServiceType createdType = serviceTypeService.createType(serviceType);
         assertNotNull(createdType.getId());
-        System.out.println("步骤1: 创建服务类型成功, ID=" + createdType.getId());
 
-        // Step 2: 创建服务内容
         ServiceContent serviceContent = new ServiceContent();
         serviceContent.setTypeId(createdType.getId());
         serviceContent.setTitle("1对1 DAN测评");
@@ -53,34 +55,30 @@ public class GuideModuleIntegrationTest {
         serviceContent.setStatus("ACTIVE");
         ServiceContent createdContent = serviceContentService.createContent(serviceContent);
         assertNotNull(createdContent.getId());
-        System.out.println("步骤2: 创建服务内容成功, ID=" + createdContent.getId());
 
-        // Step 3: 创建套餐模板
-        GuidePackageTemplate template = new GuidePackageTemplate();
-        template.setName("年度旗舰版");
-        template.setValidityMonths(12);
-        template.setReferencePrice(new BigDecimal("1980.00"));
-        template.setMinPrice(new BigDecimal("1280.00"));
-        template.setDescription("全年度服务");
-        template.setStatus("ACTIVE");
-        GuidePackageTemplate createdTemplate = templateService.createTemplate(template);
-        assertNotNull(createdTemplate.getId());
-        System.out.println("步骤3: 创建套餐模板成功, ID=" + createdTemplate.getId());
+        CreatePackageDTO dto = new CreatePackageDTO();
+        dto.setName("年度旗舰版");
+        dto.setPrice(new BigDecimal("1980.00"));
+        dto.setDescription("全年度服务");
+        dto.setCycleDays(365);
+        TaskTemplatePackage createdTaskPackage = taskTemplatePackageService.createPackage(dto, 1L);
+        assertNotNull(createdTaskPackage.getId());
 
-        // Step 4: 成长规划师创建套餐(价格必须 >= 最低价)
         boolean saved = guidePackageService.addGuidePackage(
             1L,
-            createdTemplate.getId(),
+            createdTaskPackage.getId(),
             new BigDecimal("1680.00"),
             new BigDecimal("0.1")
         );
         assertTrue(saved);
-        System.out.println("步骤4: 成长规划师创建套餐成功");
 
-        // Step 5: 验证价格校验
-        BigDecimal invalidPrice = new BigDecimal("1000.00");
-        assertTrue(invalidPrice.compareTo(createdTemplate.getMinPrice()) < 0);
-        System.out.println("步骤5: 价格校验通过 (低于最低价会被拒绝)");
+        boolean duplicateSaved = guidePackageService.addGuidePackage(
+            1L,
+            createdTaskPackage.getId(),
+            new BigDecimal("1680.00"),
+            new BigDecimal("0.1")
+        );
+        assertFalse(duplicateSaved);
     }
 
     @Test

+ 16 - 3
zxyj-backend/src/test/java/com/zxyj/service/TeacherLoginTest.java

@@ -23,6 +23,8 @@ public class TeacherLoginTest {
     @Test
     public void testTeacherRoleLogin() {
         User teacher = new User();
+        teacher.setOpenid("test_teacher_openid_001");
+        teacher.setFamilyId(0L);
         teacher.setPhone("13800000001");
         teacher.setNickname("测试规划师");
         teacher.setRole("teacher");
@@ -39,9 +41,12 @@ public class TeacherLoginTest {
     @Test
     public void testTeacherWithMultipleRoles() {
         User teacher = new User();
+        teacher.setOpenid("test_teacher_openid_002");
+        teacher.setFamilyId(0L);
         teacher.setPhone("13800000002");
         teacher.setNickname("多角色规划师");
-        teacher.setRole("teacher,parent");
+        teacher.setRole("teacher");
+        teacher.setRoles("[\"teacher\",\"parent\"]");
         teacher.setTeacherStatus("active");
         teacher.setCreatedAt(new Date());
         teacher.setUpdatedAt(new Date());
@@ -49,13 +54,17 @@ public class TeacherLoginTest {
 
         User queryTeacher = userMapper.selectById(teacher.getId());
         assertNotNull(queryTeacher);
-        assertTrue(queryTeacher.getRole().contains("teacher"));
-        assertTrue(queryTeacher.getRole().contains("parent"));
+        assertEquals("teacher", queryTeacher.getRole());
+        assertNotNull(queryTeacher.getRoles());
+        assertTrue(queryTeacher.getRoles().contains("teacher"));
+        assertTrue(queryTeacher.getRoles().contains("parent"));
     }
 
     @Test
     public void testTeacherStatusValidation() {
         User activeTeacher = new User();
+        activeTeacher.setOpenid("test_teacher_openid_003");
+        activeTeacher.setFamilyId(0L);
         activeTeacher.setPhone("13800000003");
         activeTeacher.setNickname("活跃规划师");
         activeTeacher.setRole("teacher");
@@ -64,6 +73,8 @@ public class TeacherLoginTest {
         userMapper.insert(activeTeacher);
 
         User deactivated = new User();
+        deactivated.setOpenid("test_teacher_openid_004");
+        deactivated.setFamilyId(0L);
         deactivated.setPhone("13800000004");
         deactivated.setNickname("停用规划师");
         deactivated.setRole("teacher");
@@ -81,6 +92,8 @@ public class TeacherLoginTest {
     @Test
     public void testTeacherFamilyRelation() {
         User teacher = new User();
+        teacher.setOpenid("test_teacher_openid_005");
+        teacher.setFamilyId(0L);
         teacher.setPhone("13800000005");
         teacher.setNickname("绑定家庭规划师");
         teacher.setRole("teacher");