Jelajahi Sumber

feat: 修复DataMigrationService性别映射、幂等性和日志

User 4 bulan lalu
induk
melakukan
c267391d28

+ 113 - 16
zxyj-backend/src/main/java/com/zxyj/service/DataMigrationService.java

@@ -2,6 +2,7 @@ package com.zxyj.service;
 
 import com.zxyj.service.api.DataMigrationServiceInterface;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.zxyj.entity.*;
 import com.zxyj.mapper.*;
 import lombok.extern.slf4j.Slf4j;
@@ -16,7 +17,7 @@ import java.util.*;
 
 @Slf4j
 @Service
-public class DataMigrationService {
+public class DataMigrationService implements DataMigrationServiceInterface {
 
     @Resource(name = "sfmsJdbcTemplate")
     private JdbcTemplate sfms;
@@ -75,6 +76,9 @@ public class DataMigrationService {
             migrateGrowthPlans();
 
             log.info("========== SFMS 数据迁移完成,耗时: {}ms ==========", System.currentTimeMillis() - start);
+            log.info("迁移统计: {} 家庭, {} 家长, {} 孩子, {} 规划师, {} 订单, {} 测评结果, {} 成长档案, {} 成长方案",
+                migratedFamilies, migratedParents, migratedChildren, migratedTeachers,
+                migratedOrders, migratedResults, migratedRecords, migratedPlans);
         } catch (Exception e) {
             log.error("迁移过程中出错", e);
             errors.add("全局错误: " + e.getMessage());
@@ -118,6 +122,16 @@ public class DataMigrationService {
                 String urgentName = (String) row.get("urgent_name");
                 String familyName = urgentName != null && !urgentName.isEmpty() ? urgentName + "的家庭" : phone + "的家庭";
 
+                Family existingFamily = familyMapper.selectOne(
+                    new LambdaQueryWrapper<Family>()
+                        .eq(Family::getName, familyName)
+                        .last("LIMIT 1")
+                );
+                if (existingFamily != null) {
+                    sfmsPhoneToFamilyId.put(phone, existingFamily.getId());
+                    continue;
+                }
+
                 Family family = new Family();
                 family.setName(familyName);
                 family.setInviteCode(generateInviteCode());
@@ -125,6 +139,9 @@ public class DataMigrationService {
                     familyMapper.insert(family);
                     sfmsPhoneToFamilyId.put(phone, family.getId());
                     migratedFamilies++;
+                    if (migratedFamilies % 100 == 0) {
+                        log.info("  Processed {} families...", migratedFamilies);
+                    }
                 } catch (Exception e) {
                     log.warn("创建家庭失败 phone={}: {}", phone, e.getMessage());
                 }
@@ -162,6 +179,13 @@ public class DataMigrationService {
                 Long familyId = sfmsPhoneToFamilyId.get(phone);
                 if (familyId == null) continue;
 
+                Long existingParentCount = userMapper.selectCount(
+                    new LambdaQueryWrapper<User>()
+                        .eq(User::getPhone, phone)
+                        .eq(User::getRole, "parent")
+                );
+                if (existingParentCount > 0) continue;
+
                 User user = new User();
                 user.setOpenid(openid + "_parent");
                 user.setFamilyId(familyId);
@@ -173,6 +197,9 @@ public class DataMigrationService {
                 try {
                     userMapper.insert(user);
                     count++;
+                    if (count % 100 == 0) {
+                        log.info("  Processed {} parent users...", count);
+                    }
                 } catch (Exception e) {
                     log.warn("创建家长用户失败 phone={}: {}", phone, e.getMessage());
                 }
@@ -213,18 +240,43 @@ public class DataMigrationService {
                         familyId = sfmsPhoneToFamilyId.get(phone);
                     }
                     if (familyId == null) {
-                        // 如果没有匹配到家庭,创建一个独立家庭
-                        Family family = new Family();
-                        family.setName(((String) row.get("name")) + "的家庭");
-                        family.setInviteCode(generateInviteCode());
-                        familyMapper.insert(family);
-                        familyId = family.getId();
-                        migratedFamilies++;
+                        String childFamilyName = ((String) row.get("name")) + "的家庭";
+                        Family existingFamily = familyMapper.selectOne(
+                            new LambdaQueryWrapper<Family>()
+                                .eq(Family::getName, childFamilyName)
+                                .last("LIMIT 1")
+                        );
+                        if (existingFamily != null) {
+                            familyId = existingFamily.getId();
+                        } else {
+                            Family family = new Family();
+                            family.setName(childFamilyName);
+                            family.setInviteCode(generateInviteCode());
+                            familyMapper.insert(family);
+                            familyId = family.getId();
+                        }
                     }
 
                     // 孩子 openid
                     String childOpenid = (openid != null && !openid.isEmpty()) ? openid + "_child_" + sfmsClientId : "migrated_child_" + sfmsClientId;
 
+                    User existingChildUser = userMapper.selectOne(
+                        new LambdaQueryWrapper<User>()
+                            .eq(User::getOpenid, childOpenid)
+                            .last("LIMIT 1")
+                    );
+                    if (existingChildUser != null) {
+                        sfmsClientIdToChildUserId.put(sfmsClientId, existingChildUser.getId());
+                        if (existingChildUser.getFamilyId() != null) {
+                            sfmsClientIdToFamilyId.put(sfmsClientId, existingChildUser.getFamilyId());
+                        }
+                        count++;
+                        if (count % 100 == 0) {
+                            log.info("  Processed {} children...", count);
+                        }
+                        continue;
+                    }
+
                     // 创建孩子用户
                     User childUser = new User();
                     childUser.setOpenid(childOpenid);
@@ -239,7 +291,7 @@ public class DataMigrationService {
                             childUser.setBirthday(sdf.parse((String) row.get("birth_day")));
                         } catch (Exception ignored) {}
                     }
-                    childUser.setGender("1".equals(String.valueOf(row.get("sex"))) ? "female" : "male");
+                    childUser.setGender("1".equals(String.valueOf(row.get("sex"))) ? "male" : "female");
                     userMapper.insert(childUser);
 
                     // 创建 children 记录
@@ -248,7 +300,7 @@ public class DataMigrationService {
                     child.setFamilyId(familyId);
                     child.setNickname((String) row.get("name"));
                     child.setAge(calcAge((String) row.get("birth_day")));
-                    child.setGender("1".equals(String.valueOf(row.get("sex"))) ? "female" : "male");
+                    child.setGender("1".equals(String.valueOf(row.get("sex"))) ? "male" : "female");
                     child.setPenaltyEnabled(1);
                     child.setTheme("default");
                     child.setTotalPoints(0);
@@ -260,6 +312,9 @@ public class DataMigrationService {
                     sfmsClientIdToChildUserId.put(sfmsClientId, childUser.getId());
                     sfmsClientIdToFamilyId.put(sfmsClientId, familyId);
                     count++;
+                    if (count % 100 == 0) {
+                        log.info("  Processed {} children...", count);
+                    }
                 } catch (Exception e) {
                     log.warn("迁移孩子失败 clientId={}: {}", row.get("crm_client_info_id"), e.getMessage());
                 }
@@ -294,6 +349,16 @@ public class DataMigrationService {
                     String openidKey = openid + "_teacher";
                     if (sfmsOpenIdToTeacherUserId.containsKey(openidKey)) continue;
 
+                    User existingTeacherUser = userMapper.selectOne(
+                        new LambdaQueryWrapper<User>()
+                            .eq(User::getOpenid, openidKey)
+                            .last("LIMIT 1")
+                    );
+                    if (existingTeacherUser != null) {
+                        sfmsOpenIdToTeacherUserId.put(openidKey, existingTeacherUser.getId());
+                        continue;
+                    }
+
                     User user = new User();
                     user.setOpenid(openidKey);
                     user.setFamilyId(0L);
@@ -314,6 +379,9 @@ public class DataMigrationService {
 
                     sfmsOpenIdToTeacherUserId.put(openidKey, user.getId());
                     count++;
+                    if (count % 100 == 0) {
+                        log.info("  Processed {} teachers...", count);
+                    }
                 } catch (Exception e) {
                     log.warn("迁移规划师失败: {}", e.getMessage());
                 }
@@ -357,6 +425,9 @@ public class DataMigrationService {
                     try {
                         guideFamilyMapper.insert(gf);
                         count++;
+                        if (count % 100 == 0) {
+                            log.info("  Processed {} guide-family relationships...", count);
+                        }
                     } catch (Exception ignored) {
                         // 唯一键冲突,跳过
                     }
@@ -409,6 +480,9 @@ public class DataMigrationService {
                     }
                     packageOrderMapper.insert(order);
                     count++;
+                    if (count % 100 == 0) {
+                        log.info("  Processed {} orders...", count);
+                    }
                 } catch (Exception e) {
                     log.warn("迁移订单失败: {}", e.getMessage());
                 }
@@ -443,12 +517,22 @@ public class DataMigrationService {
 
                     // 找 child_id
                     Child child = childMapper.selectOne(
-                        new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<Child>()
+                        new LambdaQueryWrapper<Child>()
                             .eq(Child::getUserId, childUserId)
                             .last("LIMIT 1")
                     );
                     if (child == null) continue;
 
+                    // 填充孩子快照字段
+                    String childName = child.getNickname();
+                    Date childBirthday = child.getBirthday();
+                    String childGender = child.getGender();
+                    Integer childAge = calcAge(childBirthday != null
+                        ? new SimpleDateFormat("yyyy-MM-dd").format(childBirthday) : null);
+                    if (childAge == null || childAge == 0) {
+                        childAge = child.getAge();
+                    }
+
                     // 找 teacher_id
                     Long teacherUserId = null;
                     if (row.get("responser") != null) {
@@ -457,6 +541,10 @@ public class DataMigrationService {
 
                     DanAssessmentResult result = new DanAssessmentResult();
                     result.setChildId(child.getId());
+                    result.setChildName(childName);
+                    result.setChildBirthday(childBirthday);
+                    result.setChildGender(childGender);
+                    result.setChildAge(childAge);
                     result.setTeacherId(teacherUserId != null ? teacherUserId : 0L);
                     result.setDanLevel("C"); // sfms 没有明确 DAN 等级,默认 C
                     result.setAnalysisReport((String) row.get("comm_cont"));
@@ -473,6 +561,9 @@ public class DataMigrationService {
 
                     danAssessmentResultMapper.insert(result);
                     count++;
+                    if (count % 100 == 0) {
+                        log.info("  Processed {} assessment results...", count);
+                    }
                 } catch (Exception e) {
                     log.warn("迁移测评结果失败: {}", e.getMessage());
                 }
@@ -522,7 +613,7 @@ public class DataMigrationService {
                     if (childUserId == null || familyId == null) continue;
 
                     Child child = childMapper.selectOne(
-                        new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<Child>()
+                        new LambdaQueryWrapper<Child>()
                             .eq(Child::getUserId, childUserId)
                             .last("LIMIT 1")
                     );
@@ -530,7 +621,7 @@ public class DataMigrationService {
 
                     // 找家长ID(family 中的第一个 parent)
                     User parent = userMapper.selectOne(
-                        new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<User>()
+                        new LambdaQueryWrapper<User>()
                             .eq(User::getFamilyId, familyId)
                             .eq(User::getRole, "parent")
                             .last("LIMIT 1")
@@ -563,6 +654,9 @@ public class DataMigrationService {
 
                     growthRecordMapper.insert(record);
                     count++;
+                    if (count % 100 == 0) {
+                        log.info("  Processed {} growth records...", count);
+                    }
                 } catch (Exception e) {
                     log.warn("迁移成长档案失败: {}", e.getMessage());
                 }
@@ -595,7 +689,7 @@ public class DataMigrationService {
                     if (childUserId == null) continue;
 
                     Child child = childMapper.selectOne(
-                        new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<Child>()
+                        new LambdaQueryWrapper<Child>()
                             .eq(Child::getUserId, childUserId)
                             .last("LIMIT 1")
                     );
@@ -608,6 +702,9 @@ public class DataMigrationService {
                     plan.setStatus("active".equals(row.get("plan_status")) ? "active" : "draft");
                     growthPlanService.createPlan(plan);
                     count++;
+                    if (count % 100 == 0) {
+                        log.info("  Processed {} growth plans...", count);
+                    }
                 } catch (Exception e) {
                     log.warn("迁移成长方案失败: {}", e.getMessage());
                 }
@@ -636,7 +733,7 @@ public class DataMigrationService {
                 Long uid = sfmsOpenIdToTeacherUserId.get(key);
                 if (uid != null) return uid;
                 User u = userMapper.selectOne(
-                    new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<User>()
+                    new LambdaQueryWrapper<User>()
                         .eq(User::getOpenid, key)
                         .last("LIMIT 1")
                 );
@@ -724,4 +821,4 @@ public class DataMigrationService {
         }
         return result;
     }
-}
+}