Преглед изворни кода

fix(service-role): 审核通过补齐规划师状态/admin记录与管家档案状态

Xiaogang Liao пре 6 дана
родитељ
комит
71c49840c4

+ 121 - 51
cfc-backend/src/main/java/com/etotem/cfc/service/impl/ServiceRoleApplicationServiceImpl.java

@@ -8,6 +8,7 @@ import com.etotem.cfc.dto.ServiceRoleApplyDTO;
 import com.etotem.cfc.entity.*;
 import com.etotem.cfc.mapper.*;
 import com.etotem.cfc.service.ServiceRoleApplicationService;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -15,6 +16,7 @@ import javax.annotation.Resource;
 import java.time.LocalDateTime;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
@@ -37,6 +39,9 @@ public class ServiceRoleApplicationServiceImpl
     @Resource
     private ButlerProfileMapper butlerProfileMapper;
 
+    @Resource
+    private AdminMapper adminMapper;
+
     @Override
     public Result submit(Long userId, ServiceRoleApplyDTO dto) {
         ServiceRoleApplication existing = this.getOne(
@@ -91,60 +96,16 @@ public class ServiceRoleApplicationServiceImpl
 
         List<String> roles = JSON.parseArray(app.getRoles(), String.class);
         User user = userMapper.selectById(app.getUserId());
+        if (user == null) {
+            return Result.error("用户不存在");
+        }
 
         // 初始化已有角色集合(保持一人多角色)
-        List<String> ownedRoles = user.getRoles() != null ? new java.util.ArrayList<>(user.getRoles()) : new java.util.ArrayList<>();
+        List<String> ownedRoles = user.getRoles() != null ? new ArrayList<>(user.getRoles()) : new ArrayList<>();
 
-        for (String role : roles) {
-            // 申请角色 → 后台角色枚举映射,审核通过即回写 users.roles(B-2)
-            switch (role) {
-                case "planner":
-                    Guide guide = new Guide();
-                    guide.setUserId(app.getUserId());
-                    guide.setStatus("active");
-                    guide.setProvince(app.getProvince());
-                    guide.setCity(app.getCity());
-                    guide.setDistrict(app.getDistrict());
-                    guide.setStreet(app.getStreet());
-                    guideMapper.insert(guide);
-                    if (!ownedRoles.contains("teacher")) {
-                        ownedRoles.add("teacher");
-                    }
-                    break;
-                case "nutritionist":
-                    user.setNutritionistStatus("approved");
-                    if (!ownedRoles.contains("nutritionist")) {
-                        ownedRoles.add("nutritionist");
-                    }
-                    break;
-                case "butler":
-                    user.setButlerStatus("approved");
-                    ButlerProfile bp = new ButlerProfile();
-                    bp.setUserId(app.getUserId());
-                    bp.setStatus("active");
-                    butlerProfileMapper.insert(bp);
-                    if (!ownedRoles.contains("butler")) {
-                        ownedRoles.add("butler");
-                    }
-                    break;
-                case "vendor":
-                    user.setVendorStatus("approved");
-                    if (!ownedRoles.contains("supplier")) {
-                        ownedRoles.add("supplier");
-                    }
-                    break;
-                case "article_admin":
-                    user.setArticleAdminStatus("approved");
-                    if (!ownedRoles.contains("knowledge_admin")) {
-                        ownedRoles.add("knowledge_admin");
-                    }
-                    break;
-                case "activity_provider":
-                    user.setActivityProviderStatus("approved");
-                    if (!ownedRoles.contains("activity_manager")) {
-                        ownedRoles.add("activity_manager");
-                    }
-                    break;
+        if (roles != null) {
+            for (String role : roles) {
+                applyApprovedRole(role, app, user, ownedRoles);
             }
         }
         user.setRoles(ownedRoles);
@@ -153,6 +114,115 @@ public class ServiceRoleApplicationServiceImpl
         return Result.success("审核通过");
     }
 
+    /**
+     * 按申请角色回写用户状态/角色集合,并做必要的关联表写入。审核通过时逐角色调用。
+     */
+    public void applyApprovedRole(String role, ServiceRoleApplication app, User user, List<String> ownedRoles) {
+        if (role == null) {
+            return;
+        }
+        switch (role) {
+            case "planner": {
+                Guide guide = new Guide();
+                guide.setUserId(app.getUserId());
+                guide.setStatus("active");
+                guide.setProvince(app.getProvince());
+                guide.setCity(app.getCity());
+                guide.setDistrict(app.getDistrict());
+                guide.setStreet(app.getStreet());
+                guideMapper.insert(guide);
+                user.setTeacherStatus("approved");
+                if (!ownedRoles.contains("teacher")) {
+                    ownedRoles.add("teacher");
+                }
+                upsertTeacherAdmin(user);
+                break;
+            }
+            case "nutritionist":
+                user.setNutritionistStatus("approved");
+                if (!ownedRoles.contains("nutritionist")) {
+                    ownedRoles.add("nutritionist");
+                }
+                break;
+            case "butler":
+                user.setButlerStatus("approved");
+                upsertButlerProfile(app.getUserId());
+                if (!ownedRoles.contains("butler")) {
+                    ownedRoles.add("butler");
+                }
+                break;
+            case "vendor":
+                user.setVendorStatus("approved");
+                if (!ownedRoles.contains("supplier")) {
+                    ownedRoles.add("supplier");
+                }
+                break;
+            case "article_admin":
+                user.setArticleAdminStatus("approved");
+                if (!ownedRoles.contains("knowledge_admin")) {
+                    ownedRoles.add("knowledge_admin");
+                }
+                break;
+            case "activity_provider":
+                user.setActivityProviderStatus("approved");
+                if (!ownedRoles.contains("activity_manager")) {
+                    ownedRoles.add("activity_manager");
+                }
+                break;
+            default:
+                break;
+        }
+    }
+
+    /**
+     * 规划师审核通过后创建/更新 admins 记录,使其可登录 Web 管理端。
+     */
+    private void upsertTeacherAdmin(User user) {
+        Admin admin = adminMapper.selectOne(new LambdaQueryWrapper<Admin>()
+                .eq(Admin::getPhone, user.getPhone()));
+        if (admin == null) {
+            admin = new Admin();
+            String usernameVal = user.getPhone() != null ? user.getPhone() : ("teacher_" + user.getId());
+            admin.setPhone(user.getPhone());
+            admin.setUsername(usernameVal);
+            admin.setRealName(user.getRealName());
+            admin.setNickname(user.getNickname());
+            admin.setRole("teacher");
+            admin.setStatus(1);
+            admin.setPassword(new BCryptPasswordEncoder().encode(usernameVal));
+            admin.setCreatedAt(new Date());
+            admin.setUpdatedAt(new Date());
+            adminMapper.insert(admin);
+        } else {
+            admin.setRole("teacher");
+            admin.setUpdatedAt(new Date());
+            adminMapper.updateById(admin);
+        }
+    }
+
+    /**
+     * 管家审核通过后创建/更新 butler_profiles,状态统一为 approved。
+     */
+    private void upsertButlerProfile(Long userId) {
+        ButlerProfile bp = butlerProfileMapper.selectOne(new LambdaQueryWrapper<ButlerProfile>()
+                .eq(ButlerProfile::getUserId, userId));
+        Date now = new Date();
+        if (bp == null) {
+            bp = new ButlerProfile();
+            bp.setUserId(userId);
+            bp.setStatus("approved");
+            bp.setApprovedAt(now);
+            bp.setCreatedAt(now);
+            bp.setUpdatedAt(now);
+            butlerProfileMapper.insert(bp);
+        } else {
+            bp.setStatus("approved");
+            bp.setApprovedAt(now);
+            bp.setUpdatedAt(now);
+            butlerProfileMapper.updateById(bp);
+        }
+    }
+
     @Override
     public List<ServiceRoleApplication> listApplications(Integer status) {
         return this.list(new LambdaQueryWrapper<ServiceRoleApplication>()

+ 148 - 0
cfc-backend/src/test/java/com/etotem/cfc/unit/ServiceRoleApproveTest.java

@@ -0,0 +1,148 @@
+package com.etotem.cfc.unit;
+
+import com.etotem.cfc.entity.Admin;
+import com.etotem.cfc.entity.ButlerProfile;
+import com.etotem.cfc.entity.Guide;
+import com.etotem.cfc.entity.ServiceRoleApplication;
+import com.etotem.cfc.entity.User;
+import com.etotem.cfc.mapper.AdminMapper;
+import com.etotem.cfc.mapper.ButlerProfileMapper;
+import com.etotem.cfc.mapper.GuideMapper;
+import com.etotem.cfc.service.impl.ServiceRoleApplicationServiceImpl;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.*;
+
+class ServiceRoleApproveTest {
+
+    private ServiceRoleApplicationServiceImpl service;
+    private GuideMapper guideMapper;
+    private ButlerProfileMapper butlerProfileMapper;
+    private AdminMapper adminMapper;
+
+    @BeforeEach
+    void setUp() throws Exception {
+        service = new ServiceRoleApplicationServiceImpl();
+        guideMapper = mock(GuideMapper.class);
+        butlerProfileMapper = mock(ButlerProfileMapper.class);
+        adminMapper = mock(AdminMapper.class);
+        set("guideMapper", guideMapper);
+        set("butlerProfileMapper", butlerProfileMapper);
+        set("adminMapper", adminMapper);
+    }
+
+    private void set(String name, Object v) throws Exception {
+        Field f = ServiceRoleApplicationServiceImpl.class.getDeclaredField(name);
+        f.setAccessible(true);
+        f.set(service, v);
+    }
+
+    private ServiceRoleApplication app() {
+        ServiceRoleApplication app = new ServiceRoleApplication();
+        app.setId(1L);
+        app.setUserId(12L);
+        app.setProvince("北京");
+        app.setCity("北京市");
+        return app;
+    }
+
+    private User user() {
+        User user = new User();
+        user.setId(12L);
+        user.setPhone("13900000000");
+        user.setNickname("他爹");
+        user.setRealName("张三");
+        return user;
+    }
+
+    @Test
+    void planner_通过后写teacher_status并创建admins记录() {
+        User user = user();
+        List<String> roles = new ArrayList<>();
+        when(guideMapper.insert(any())).thenReturn(1);
+        when(adminMapper.selectOne(any())).thenReturn(null);
+        when(adminMapper.insert(any())).thenReturn(1);
+
+        service.applyApprovedRole("planner", app(), user, roles);
+
+        assertEquals("approved", user.getTeacherStatus());
+        assertTrue(roles.contains("teacher"));
+        verify(guideMapper).insert(any(Guide.class));
+        verify(adminMapper).insert(any(Admin.class));
+    }
+
+    @Test
+    void planner_已有同手机号admin则更新不重复插入() {
+        User user = user();
+        List<String> roles = new ArrayList<>();
+        Admin existing = new Admin();
+        existing.setId(5L);
+        when(guideMapper.insert(any())).thenReturn(1);
+        when(adminMapper.selectOne(any())).thenReturn(existing);
+
+        service.applyApprovedRole("planner", app(), user, roles);
+
+        verify(adminMapper, never()).insert(any(Admin.class));
+        verify(adminMapper).updateById(existing);
+    }
+
+    @Test
+    void butler_通过后写butler_status且profile状态为approved() {
+        User user = user();
+        List<String> roles = new ArrayList<>();
+        when(butlerProfileMapper.selectOne(any())).thenReturn(null);
+        when(butlerProfileMapper.insert(any())).thenReturn(1);
+
+        service.applyApprovedRole("butler", app(), user, roles);
+
+        assertEquals("approved", user.getButlerStatus());
+        assertTrue(roles.contains("butler"));
+        verify(butlerProfileMapper).insert(argThat(p -> "approved".equals(p.getStatus())));
+    }
+
+    @Test
+    void butler_已有profile则更新为approved不新增() {
+        User user = user();
+        List<String> roles = new ArrayList<>();
+        ButlerProfile existing = new ButlerProfile();
+        existing.setId(7L);
+        when(butlerProfileMapper.selectOne(any())).thenReturn(existing);
+
+        service.applyApprovedRole("butler", app(), user, roles);
+
+        assertEquals("approved", user.getButlerStatus());
+        assertEquals("approved", existing.getStatus());
+        verify(butlerProfileMapper, never()).insert(any(ButlerProfile.class));
+        verify(butlerProfileMapper).updateById(existing);
+    }
+
+    @Test
+    void nutritionist_通过后写nutritionist_status并回写角色() {
+        User user = user();
+        List<String> roles = new ArrayList<>();
+
+        service.applyApprovedRole("nutritionist", app(), user, roles);
+
+        assertEquals("approved", user.getNutritionistStatus());
+        assertTrue(roles.contains("nutritionist"));
+    }
+
+    @Test
+    void 未知角色不改变任何状态() {
+        User user = user();
+        List<String> roles = new ArrayList<>();
+
+        service.applyApprovedRole("unknown_role", app(), user, roles);
+
+        assertTrue(roles.isEmpty());
+        assertNull(user.getTeacherStatus());
+        assertNull(user.getButlerStatus());
+    }
+}