Explorar o código

Merge remote-tracking branch 'origin/sit' into sit

wuchen hai 2 meses
pai
achega
cb74bd93e8
Modificáronse 18 ficheiros con 438 adicións e 190 borrados
  1. 3 0
      alien-entity/src/main/java/shop/alien/entity/store/vo/StoreUserVo.java
  2. 1 1
      alien-entity/src/main/java/shop/alien/mapper/StoreOfficialAlbumMapper.java
  3. 7 0
      alien-entity/src/main/java/shop/alien/mapper/SubAccountStoreMapper.java
  4. 74 7
      alien-entity/src/main/resources/mapper/SubAccountStoreMapper.xml
  5. 8 4
      alien-gateway/src/main/java/shop/alien/gateway/controller/StoreUserController.java
  6. 1 1
      alien-gateway/src/main/java/shop/alien/gateway/service/StoreUserService.java
  7. 104 105
      alien-gateway/src/main/java/shop/alien/gateway/service/impl/StoreUserServiceImpl.java
  8. 20 14
      alien-store/src/main/java/shop/alien/store/controller/AiSearchController.java
  9. 20 1
      alien-store/src/main/java/shop/alien/store/controller/StoreInfoController.java
  10. 7 0
      alien-store/src/main/java/shop/alien/store/service/StoreInfoService.java
  11. 37 37
      alien-store/src/main/java/shop/alien/store/service/impl/LifeMessageServiceImpl.java
  12. 7 2
      alien-store/src/main/java/shop/alien/store/service/impl/LifeUserViolationServiceImpl.java
  13. 11 0
      alien-store/src/main/java/shop/alien/store/service/impl/StoreCommentServiceImpl.java
  14. 10 0
      alien-store/src/main/java/shop/alien/store/service/impl/StoreInfoServiceImpl.java
  15. 19 9
      alien-store/src/main/java/shop/alien/store/service/impl/StoreRenovationRequirementServiceImpl.java
  16. 11 8
      alien-store/src/main/java/shop/alien/store/service/impl/StoreUserServiceImpl.java
  17. 27 1
      alien-store/src/main/java/shop/alien/store/service/impl/SubAccountStoreServiceImpl.java
  18. 71 0
      alien-store/src/main/java/shop/alien/store/util/ai/AiReportReviewUtil.java

+ 3 - 0
alien-entity/src/main/java/shop/alien/entity/store/vo/StoreUserVo.java

@@ -62,4 +62,7 @@ public class StoreUserVo extends StoreUser {
     @ApiModelProperty(value = "角色名称(当前账号在目标门店的角色名称)")
     private String roleName;
 
+    @ApiModelProperty(value = "是否有子账号(主账号且有子账号时为true)")
+    private boolean hasSubAccount;
+
 }

+ 1 - 1
alien-entity/src/main/java/shop/alien/mapper/StoreOfficialAlbumMapper.java

@@ -23,7 +23,7 @@ public interface StoreOfficialAlbumMapper extends BaseMapper<StoreOfficialAlbum>
      */
     //"图片类型, 0:其他, 1:入口图, 2:相册, 3:菜品, 4:环境, 5:价目表, 6:推荐菜, 7:菜单, 8:用户评论, 9:商家申诉, 10:商家头像, 11:店铺轮播图"
     @Select("SELECT a.*, b.img_url FROM store_official_album a LEFT JOIN store_img b ON b.id = " +
-            "(SELECT b2.id FROM store_img b2 WHERE b2.business_id = a.id and b2.img_type in ( '2','4') " +
+            "(SELECT b2.id FROM store_img b2 WHERE b2.business_id = a.id and b2.img_type in ( '2','4') and b2.delete_flag = 0 " +
             "order by b2.img_sort LIMIT 1) where a.delete_flag = '0' and  a.store_id = #{storeId}")
     List<StoreOfficialAlbumVo> getStoreOfficialAlbumList(@Param("storeId") Integer storeId);
 

+ 7 - 0
alien-entity/src/main/java/shop/alien/mapper/SubAccountStoreMapper.java

@@ -21,4 +21,11 @@ public interface SubAccountStoreMapper extends BaseMapper<Object> {
      * @return 门店列表
      */
     List<SubAccountStoreListVo> selectSubAccountStoreListByUserId(@Param("userId") Integer userId);
+
+    /**
+     * 根据用户ID查询子账号关联的门店列表 (无主账号情况)
+     * @param userId 用户ID(store_user.id)
+     * @return 门店列表
+     */
+    List<SubAccountStoreListVo> selectSubAccountStoreListByUserIdTwo(@Param("userId") Integer userId);
 }

+ 74 - 7
alien-entity/src/main/resources/mapper/SubAccountStoreMapper.xml

@@ -6,7 +6,7 @@
 
     <!-- 根据用户ID查询子账号关联的门店列表(包含主账号的门店) -->
     <select id="selectSubAccountStoreListByUserId" resultType="shop.alien.entity.store.vo.SubAccountStoreListVo">
-        -- 查询子账号通过store_platform_user_role关联的门店
+        -- 查询子账号通过store_platform_user_role关联的门店(当前用户作为子账号的门店)
         SELECT
             si.id AS storeId,
             si.store_name COLLATE utf8mb4_unicode_ci AS storeName,
@@ -33,6 +33,74 @@
         UNION
         
         -- 查询主账号的门店(通过store_user.store_id关联)
+        -- 如果主账号没有门店,只查主账号信息(门店字段为NULL)
+        SELECT
+            si_main.id AS storeId,
+            si_main.store_name COLLATE utf8mb4_unicode_ci AS storeName,
+            si_main.store_address COLLATE utf8mb4_unicode_ci AS storeAddress,
+            si_main.store_tel COLLATE utf8mb4_unicode_ci AS storeTel,
+            si_main.business_status AS businessStatus,
+            NULL AS roleId,
+            NULL AS roleName,
+            su_main.id AS userId,
+            su_main.name COLLATE utf8mb4_unicode_ci AS accountName,
+            su_main.phone COLLATE utf8mb4_unicode_ci AS phone
+        FROM
+            store_user su_main
+        LEFT JOIN store_info si_main ON su_main.store_id = si_main.id 
+            AND (si_main.delete_flag = 0 OR si_main.delete_flag IS NULL)
+        WHERE
+            su_main.id = #{userId}
+            AND su_main.delete_flag = 0
+            AND (
+                -- 如果主账号在store_platform_user_role表中没有记录,或者是主账号但没有门店
+                NOT EXISTS (
+                    SELECT 1 FROM store_platform_user_role spur 
+                    WHERE spur.user_id = #{userId} 
+                    AND spur.delete_flag = 0
+                )
+                OR
+                -- 如果主账号在store_platform_user_role表中有记录,但没有门店(store_id为NULL或对应的store_info不存在)
+                (su_main.store_id IS NULL OR NOT EXISTS (
+                    SELECT 1 FROM store_info si_check 
+                    WHERE si_check.id = su_main.store_id 
+                    AND si_check.delete_flag = 0
+                ))
+            )
+        
+        
+        ORDER BY storeId DESC
+    </select>
+
+    <!-- 根据用户ID查询子账号关联的门店列表(包含主账号的门店) -->
+    <select id="selectSubAccountStoreListByUserIdTwo" resultType="shop.alien.entity.store.vo.SubAccountStoreListVo">
+        -- 查询子账号通过store_platform_user_role关联的门店
+        SELECT
+            si.id AS storeId,
+            si.store_name COLLATE utf8mb4_unicode_ci AS storeName,
+            si.store_address COLLATE utf8mb4_unicode_ci AS storeAddress,
+            si.store_tel COLLATE utf8mb4_unicode_ci AS storeTel,
+            si.business_status AS businessStatus,
+            spur.role_id AS roleId,
+            spr.role_name COLLATE utf8mb4_unicode_ci AS roleName,
+            spur.user_id AS userId,
+            spur.account_name COLLATE utf8mb4_unicode_ci AS accountName,
+            su.phone COLLATE utf8mb4_unicode_ci AS phone
+        FROM
+            store_platform_user_role spur
+                INNER JOIN store_user su ON spur.user_id = su.id
+                INNER JOIN store_info si ON spur.store_id = si.id
+                LEFT JOIN store_platform_role spr ON spur.role_id = spr.role_id
+                AND (spr.del_flag = '0' OR spr.del_flag IS NULL)
+        WHERE
+            spur.user_id = #{userId}
+          AND spur.delete_flag = 0
+          AND su.delete_flag = 0
+          AND si.delete_flag = 0
+
+        UNION
+
+        -- 查询主账号的门店(通过store_user.store_id关联)
         SELECT
             si_main.id AS storeId,
             si_main.store_name COLLATE utf8mb4_unicode_ci AS storeName,
@@ -46,20 +114,19 @@
             su_main.phone COLLATE utf8mb4_unicode_ci AS phone
         FROM
             store_user su_main
-        INNER JOIN store_info si_main ON su_main.store_id = si_main.id
+                INNER JOIN store_info si_main ON su_main.store_id = si_main.id
         WHERE
             (
                 -- 如果传入的是子账号,查询其主账号的门店
                 (su_main.id = (SELECT sub_account_id FROM store_user WHERE id = #{userId} AND account_type = 2 AND delete_flag = 0 LIMIT 1))
-                OR
-                -- 如果传入的是主账号,查询自己的门店
-                (su_main.id = #{userId} AND su_main.account_type = 1)
+           OR
+           -- 如果传入的是主账号,查询自己的门店
+            (su_main.id = #{userId} AND su_main.account_type = 1)
             )
             AND su_main.delete_flag = 0
             AND si_main.delete_flag = 0
             AND su_main.store_id IS NOT NULL
-        
+
         ORDER BY storeId DESC
     </select>
-
 </mapper>

+ 8 - 4
alien-gateway/src/main/java/shop/alien/gateway/controller/StoreUserController.java

@@ -94,12 +94,16 @@ public class StoreUserController {
     @ApiOperationSupport(order = 2)
     @ApiImplicitParams({
             @ApiImplicitParam(name = "userId", value = "用户ID(store_user.id)", dataType = "Integer", paramType = "query", required = true),
-            @ApiImplicitParam(name = "storeId", value = "目标门店ID", dataType = "Integer", paramType = "query", required = true)
+            @ApiImplicitParam(name = "storeId", value = "目标门店ID", dataType = "Integer", paramType = "query", required = false),
+            @ApiImplicitParam(name = "accountType", value = "主子账号类型", dataType = "Integer", paramType = "query", required = true)
     })
     @GetMapping("/switchSubAccountStore")
-    public R<StoreUserVo> switchSubAccountStore(@RequestParam("userId") Integer userId, @RequestParam("storeId") Integer storeId) {
-        log.info("StoreUserController.switchSubAccountStore?userId={}, storeId={}", userId, storeId);
-        return storeUserService.switchSubAccountStore(userId, storeId);
+    public R<StoreUserVo> switchSubAccountStore(
+            @RequestParam("userId") Integer userId, 
+            @RequestParam(value = "storeId", required = false) Integer storeId,
+            @RequestParam("accountType") Integer accountType) {
+        log.info("StoreUserController.switchSubAccountStore?userId={}, storeId={}, accountType={}", userId, storeId, accountType);
+        return storeUserService.switchSubAccountStore(userId, storeId, accountType);
     }
 
 }

+ 1 - 1
alien-gateway/src/main/java/shop/alien/gateway/service/StoreUserService.java

@@ -25,6 +25,6 @@ public interface StoreUserService extends IService<StoreUser> {
      * @param storeId 目标门店ID
      * @return 用户信息和token
      */
-    R<StoreUserVo> switchSubAccountStore(Integer userId, Integer storeId);
+    R<StoreUserVo> switchSubAccountStore(Integer userId, Integer storeId, Integer accountType);
 
 }

+ 104 - 105
alien-gateway/src/main/java/shop/alien/gateway/service/impl/StoreUserServiceImpl.java

@@ -52,9 +52,9 @@ public class StoreUserServiceImpl extends ServiceImpl<StoreUserGatewayMapper, St
     private final BaseRedisService baseRedisService;
 
     private final StorePlatformUserRoleGatewayMapper storePlatformUserRoleMapper;
-    
+
     private final StorePlatformRoleMenuGatewayMapper storePlatformRoleMenuMapper;
-    
+
     private final StorePlatformRoleGatewayMapper storePlatformRoleMapper;
 
     /**
@@ -96,62 +96,108 @@ public class StoreUserServiceImpl extends ServiceImpl<StoreUserGatewayMapper, St
         tokenMap.put("userType", "store");
         storeUserVo.setToken(JwtUtil.createJWT("store_" + storeUser.getPhone(), storeUser.getName(), JSONObject.toJSONString(tokenMap), effectiveTimeIntLong));
         baseRedisService.setString("store_" + storeUser.getPhone(), storeUserVo.getToken());
-        if(storeUserVo.getStoreId() == null){
-            // 子账号登录,查询当前子账号权限最多的那个门店和角色id
-            log.info("子账号登录,storeId为空,查询权限最多的门店 - userId: {}", storeUser.getId());
-            
-            // 查询子账号关联的所有门店和角色
+
+        if (storeUserVo.getAccountType() == 1) {
+            // 主账号登录,判断是否有子账号
+            // 通过 store_platform_user_role 表中的关联记录判断
+            // 查询该门店下是否有其他账号(子账号)在 store_platform_user_role 表中有关联记录
             LambdaQueryWrapper<StorePlatformUserRole> roleWrapper = new LambdaQueryWrapper<>();
-            roleWrapper.eq(StorePlatformUserRole::getUserId, storeUser.getId())
+            roleWrapper.eq(StorePlatformUserRole::getUserId, storeUser.getId()) // 排除当前账号自己
                     .eq(StorePlatformUserRole::getDeleteFlag, 0);
-            List<StorePlatformUserRole> userRoles = storePlatformUserRoleMapper.selectList(roleWrapper);
-            
-            if (userRoles != null && !userRoles.isEmpty()) {
-                // 计算每个角色的菜单权限数量,选择权限最多的门店
-                StorePlatformUserRole maxPermissionRole = null;
-                int maxPermissionCount = -1;
-                
-                for (StorePlatformUserRole userRole : userRoles) {
-                    if (userRole.getRoleId() != null) {
-                        // 查询该角色的菜单权限数量
-                        Integer permissionCount = storePlatformRoleMenuMapper.countMenuByRoleId(userRole.getRoleId());
-                        if (permissionCount == null) {
-                            permissionCount = 0;
-                        }
-                        
-                        // 如果权限数量更多,或者权限数量相同但角色ID更大,则更新
-                        if (permissionCount > maxPermissionCount || 
-                            (permissionCount == maxPermissionCount && 
-                             (maxPermissionRole == null || userRole.getRoleId() > maxPermissionRole.getRoleId()))) {
-                            maxPermissionCount = permissionCount;
-                            maxPermissionRole = userRole;
-                        }
+            long subAccountCount = storePlatformUserRoleMapper.selectCount(roleWrapper);
+            if (subAccountCount > 0) {
+                storeUserVo.setHasSubAccount(true);
+            } else {
+                storeUserVo.setHasSubAccount(false);
+            }
+            log.info("主账号登录,检查子账号 - userId: {}, storeId: {}, hasSubAccount: {}, subAccountCount: {}",
+                    storeUser.getId(), storeUserVo.getStoreId(), false, subAccountCount);
+        } else {
+            // 子账号切换如果有storeId 则为子账号切换无感登录 否则为正常登录
+            if (storeUser.getStoreId() != null) {
+                LambdaQueryWrapper<StorePlatformUserRole> roleWrapper = new LambdaQueryWrapper<>();
+                roleWrapper.eq(StorePlatformUserRole::getUserId, storeUser.getId())
+                        .eq(StorePlatformUserRole::getStoreId, storeUser.getStoreId())
+                        .eq(StorePlatformUserRole::getDeleteFlag, 0);
+                StorePlatformUserRole userRole = storePlatformUserRoleMapper.selectOne(roleWrapper);
+
+                if (userRole == null) {
+                    log.warn("子账号未关联目标门店 - userId: {}, storeId: {}", storeUser.getId(), storeUser.getStoreId());
+                    return R.fail("切换失败,请确认子账号是否关联了该门店");
+                }
+
+                int finalStoreId = userRole.getStoreId(); // 从关联表获取门店ID
+                StoreInfo storeInfo = storeInfoMapper.selectById(finalStoreId);
+                // 查询角色名称
+                if (userRole.getRoleId() != null) {
+                    StorePlatformRole role = storePlatformRoleMapper.selectById(userRole.getRoleId());
+                    if (role != null) {
+                        storeUserVo.setRoleName(role.getRoleName());
                     }
                 }
-                
-                if (maxPermissionRole != null) {
-                    // 设置门店ID和角色ID
-                    storeUserVo.setStoreId(maxPermissionRole.getStoreId());
-                    storeUserVo.setRoleId(maxPermissionRole.getRoleId());
-                    
-                    // 查询角色名称
-                    if (maxPermissionRole.getRoleId() != null) {
-                        StorePlatformRole role = storePlatformRoleMapper.selectById(maxPermissionRole.getRoleId());
-                        if (role != null) {
-                            storeUserVo.setRoleName(role.getRoleName());
+                storeUserVo.setRoleId(userRole.getRoleId());
+                storeUserVo.setStoreId(storeInfo.getId());
+                storeUserVo.setHasSubAccount(true);
+                storeUserVo.setRoleName(userRole.getAccountName());
+            } else {
+
+                // 子账号登录,查询当前子账号权限最多的那个门店和角色id
+                log.info("子账号登录,storeId为空,查询权限最多的门店 - userId: {}", storeUser.getId());
+                // 查询子账号关联的所有门店和角色
+                LambdaQueryWrapper<StorePlatformUserRole> roleWrapper = new LambdaQueryWrapper<>();
+                roleWrapper.eq(StorePlatformUserRole::getUserId, storeUser.getId())
+                        .eq(StorePlatformUserRole::getDeleteFlag, 0);
+                List<StorePlatformUserRole> userRoles = storePlatformUserRoleMapper.selectList(roleWrapper);
+
+                if (userRoles != null && !userRoles.isEmpty()) {
+                    // 计算每个角色的菜单权限数量,选择权限最多的门店
+                    StorePlatformUserRole maxPermissionRole = null;
+                    int maxPermissionCount = -1;
+
+                    for (StorePlatformUserRole userRole : userRoles) {
+                        if (userRole.getRoleId() != null) {
+                            // 查询该角色的菜单权限数量
+                            Integer permissionCount = storePlatformRoleMenuMapper.countMenuByRoleId(userRole.getRoleId());
+                            if (permissionCount == null) {
+                                permissionCount = 0;
+                            }
+
+                            // 如果权限数量更多,或者权限数量相同但角色ID更大,则更新
+                            if (permissionCount > maxPermissionCount ||
+                                    (permissionCount == maxPermissionCount &&
+                                            (maxPermissionRole == null || userRole.getRoleId() > maxPermissionRole.getRoleId()))) {
+                                maxPermissionCount = permissionCount;
+                                maxPermissionRole = userRole;
+                            }
+                        }
+                    }
+
+                    if (maxPermissionRole != null) {
+                        // 设置门店ID和角色ID
+                        storeUserVo.setStoreId(maxPermissionRole.getStoreId());
+                        storeUserVo.setRoleId(maxPermissionRole.getRoleId());
+                        storeUserVo.setHasSubAccount(true);
+
+                        // 查询角色名称
+                        if (maxPermissionRole.getRoleId() != null) {
+                            StorePlatformRole role = storePlatformRoleMapper.selectById(maxPermissionRole.getRoleId());
+                            if (role != null) {
+                                storeUserVo.setRoleName(role.getRoleName());
+                            }
                         }
+
+                        log.info("子账号权限最多的门店查询成功 - userId: {}, storeId: {}, roleId: {}, roleName: {}, 权限数量: {}",
+                                storeUser.getId(), maxPermissionRole.getStoreId(), maxPermissionRole.getRoleId(),
+                                storeUserVo.getRoleName(), maxPermissionCount);
+                    } else {
+                        log.warn("子账号关联的门店都没有角色ID - userId: {}", storeUser.getId());
                     }
-                    
-                    log.info("子账号权限最多的门店查询成功 - userId: {}, storeId: {}, roleId: {}, roleName: {}, 权限数量: {}", 
-                            storeUser.getId(), maxPermissionRole.getStoreId(), maxPermissionRole.getRoleId(), 
-                            storeUserVo.getRoleName(), maxPermissionCount);
                 } else {
-                    log.warn("子账号关联的门店都没有角色ID - userId: {}", storeUser.getId());
+                    log.warn("子账号未关联任何门店 - userId: {}", storeUser.getId());
                 }
-            } else {
-                log.warn("子账号未关联任何门店 - userId: {}", storeUser.getId());
             }
         }
+
         // 查询门店信息(如果storeId不为空)
         StoreInfo storeInfo = null;
         if (storeUserVo.getStoreId() != null) {
@@ -165,13 +211,13 @@ public class StoreUserServiceImpl extends ServiceImpl<StoreUserGatewayMapper, St
     }
 
     @Override
-    public R<StoreUserVo> switchSubAccountStore(Integer userId, Integer storeId) {
+    public R<StoreUserVo> switchSubAccountStore(Integer userId, Integer storeId, Integer accountType) {
         log.info("StoreUserServiceImpl.switchSubAccountStore?userId={}, storeId={}", userId, storeId);
 
-        if (userId == null || storeId == null) {
-            log.warn("用户ID或门店ID为空 - userId: {}, storeId: {}", userId, storeId);
-            return R.fail("用户ID或门店ID不能为空");
-        }
+//        if (userId == null || storeId == null) {
+//            log.warn("用户ID或门店ID为空 - userId: {}, storeId: {}", userId, storeId);
+//            return R.fail("用户ID或门店ID不能为空");
+//        }
 
         // 1. 查询用户信息(类似登录接口,验证用户是否存在)
         StoreUser storeUser = this.getById(userId);
@@ -186,72 +232,25 @@ public class StoreUserServiceImpl extends ServiceImpl<StoreUserGatewayMapper, St
             return R.fail("账号被禁用");
         }
 
-        // 3. 判断是主账号还是子账号,并验证门店关联
-        Long roleId = null;
-        Integer finalStoreId = null; // 最终要回显的门店ID
-        StoreInfo storeInfo = new StoreInfo();
-        if (storeUser.getStoreId() != null && storeUser.getStoreId().equals(storeId)) {
-            // 主账号:直接回显 store_user 的门店 id
-//            if (storeUser.getStoreId() == null || !storeUser.getStoreId().equals(storeId)) {
-//                log.warn("主账号门店ID不匹配 - userId: {}, 传入storeId: {}, 实际storeId: {}",
-//                        userId, storeId, storeUser.getStoreId());
-//                return R.fail("切换失败,门店ID不匹配");
-//            }
-            finalStoreId = storeUser.getStoreId();
-            roleId = null; // 主账号没有角色id
-        } else {
-            // 子账号:查询角色关联表,回显子账号关联的门店 id
-            LambdaQueryWrapper<StorePlatformUserRole> roleWrapper = new LambdaQueryWrapper<>();
-            roleWrapper.eq(StorePlatformUserRole::getUserId, userId)
-                    .eq(StorePlatformUserRole::getStoreId, storeId)
-                    .eq(StorePlatformUserRole::getDeleteFlag, 0);
-            StorePlatformUserRole userRole = storePlatformUserRoleMapper.selectOne(roleWrapper);
-            
-            if (userRole == null) {
-                log.warn("子账号未关联目标门店 - userId: {}, storeId: {}", userId, storeId);
-                return R.fail("切换失败,请确认子账号是否关联了该门店");
-            }
-            
-            finalStoreId = userRole.getStoreId(); // 从关联表获取门店ID
-            storeInfo = storeInfoMapper.selectById(finalStoreId);
-            roleId = userRole.getRoleId() != null ? userRole.getRoleId() : null;
-        }
-
-        // 4. 删除旧的token(参考switchingStates逻辑)
+        // 3. 删除旧的token(参考switchingStates逻辑)
         baseRedisService.delete("store_" + storeUser.getPhone());
         baseRedisService.delete("storePlatform_" + storeUser.getPhone());
         log.info("删除用户token - phone: {}", storeUser.getPhone());
 
-        // 5. 创建临时用户对象用于生成token(设置正确的门店ID)
+        // 4. 创建临时用户对象用于生成token(设置正确的门店ID)
         StoreUser tempUser = new StoreUser();
         BeanUtils.copyProperties(storeUser, tempUser);
-        tempUser.setStoreId(finalStoreId);
+        tempUser.setAccountType(accountType);
+        tempUser.setStoreId(storeId);
 
-        // 6. 生成token(类似登录接口)
+        // 6. 生成token(类似登录接口)走切换账号逻辑
         R<StoreUserVo> tokenResult = createToKen(tempUser);
         if (tokenResult.getCode() != 200 || tokenResult.getData() == null) {
             log.error("生成token失败 - userId: {}", userId);
             return R.fail("切换失败,token生成失败");
         }
 
-        // 7. 设置角色ID和门店ID(如果没有角色id,该字段为null)
         StoreUserVo storeUserVo = tokenResult.getData();
-        storeUserVo.setRoleId(roleId);
-        storeUserVo.setStoreId(finalStoreId); // 确保回显正确的门店ID
-        
-        // 查询并设置角色名称
-        if (roleId != null) {
-            StorePlatformRole role = storePlatformRoleMapper.selectById(roleId);
-            if (role != null) {
-                storeUserVo.setRoleName(role.getRoleName());
-            }
-        }
-        
-        if(storeInfo != null){
-            storeUserVo.setName(storeInfo.getStoreName());
-        }
-
-        log.info("切换门店成功 - userId: {}, storeId: {}, roleId: {}", userId, finalStoreId, roleId);
         return R.data(storeUserVo);
     }
 

+ 20 - 14
alien-store/src/main/java/shop/alien/store/controller/AiSearchController.java

@@ -19,23 +19,17 @@ import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.client.RestTemplate;
 import shop.alien.entity.result.R;
+import shop.alien.entity.store.LifeBlacklist;
 import shop.alien.entity.store.StoreImg;
-import shop.alien.entity.store.StoreUser;
 import shop.alien.entity.store.vo.StoreInfoVo;
+import shop.alien.mapper.LifeBlacklistMapper;
 import shop.alien.mapper.StoreImgMapper;
-import shop.alien.mapper.StoreUserMapper;
 import shop.alien.store.annotation.TrackEvent;
 import shop.alien.store.service.CommonRatingService;
-import shop.alien.store.service.CommonRatingService;
 import shop.alien.store.service.StoreImgService;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.stream.Collectors;
-import java.util.Comparator;
 
 
 @Slf4j
@@ -59,6 +53,8 @@ public class AiSearchController {
     private final StoreImgService storeImgService;
     private final CommonRatingService commonRatingService;
 
+    private final LifeBlacklistMapper lifeBlacklistMapper;
+
     @TrackEvent(
             eventType = "SEARCH",
             eventCategory = "TRAFFIC",
@@ -85,15 +81,15 @@ public class AiSearchController {
 
         HttpEntity<Map<String, Object>> request = new HttpEntity<>(requestBody, null);
         try {
-            
+
             ResponseEntity<String> stringResponseEntity = restTemplate.postForEntity(aiSearchExactUrl, request, String.class);
             String body = stringResponseEntity.getBody();
             JSONObject jsonObject = JSONObject.parseObject(body);
             JSONObject jsonObject1 = new JSONObject();
             // 生活服务类别:转换为StoreInfoVo,确保返回的字段名按照StoreInfoVo定义
             // 模糊搜索:从related_results和matched_results字段获取数据
-            List<StoreInfoVo> relatedResult = convertToStoreInfoList(jsonObject.getJSONArray("related_results"));
-            List<StoreInfoVo> matchedResult = convertToStoreInfoList(jsonObject.getJSONArray("matched_results"));
+            List<StoreInfoVo> relatedResult = convertToStoreInfoList(jsonObject.getJSONArray("related_results"),map.get("userId"));
+            List<StoreInfoVo> matchedResult = convertToStoreInfoList(jsonObject.getJSONArray("matched_results"),map.get("userId"));
 
             // 查找图片并设置到result中(图片类型1-入口图)
             fillStoreImages(relatedResult, 1);
@@ -139,7 +135,7 @@ public class AiSearchController {
             JSONObject jsonObject = JSONObject.parseObject(body);
             JSONObject jsonObject1 = new JSONObject();
             // 模糊搜索:从related_results和matched_results字段获取数据
-            List<StoreInfoVo> result = convertToStoreInfoList(jsonObject.getJSONArray("results"));
+            List<StoreInfoVo> result = convertToStoreInfoList(jsonObject.getJSONArray("results"),map.get("userId"));
 
             // 查找图片并设置到result中(图片类型1-入口图)
             fillStoreImages(result, 1);
@@ -159,7 +155,14 @@ public class AiSearchController {
         return  R.fail("请求失败");
     }
 
-    private List<StoreInfoVo> convertToStoreInfoList(JSONArray results) {
+    private List<StoreInfoVo> convertToStoreInfoList(JSONArray results, String  userId) {
+        // 查找用户拉黑的商户
+        QueryWrapper<LifeBlacklist> queryWrapper = new QueryWrapper<LifeBlacklist>();
+        queryWrapper.eq("blocker_id",userId);
+        queryWrapper.eq("blocker_type",2);
+        queryWrapper.eq("blocked_type",1);
+        List<LifeBlacklist> lifeBlacklists = lifeBlacklistMapper.selectList(queryWrapper);
+        List<String> blockedIds = lifeBlacklists.stream().map(x -> x.getBlockedId()).collect(Collectors.toList());
         List<StoreInfoVo> storeInfoList = new ArrayList<>();
         if (results != null) {
             for (int i = 0; i < results.size(); i++) {
@@ -183,6 +186,9 @@ public class AiSearchController {
 
                 // 使用JSON.parseObject方法进行转换
                 StoreInfoVo storeInfo = JSON.parseObject(camelCaseItem.toJSONString(), StoreInfoVo.class);
+                if(blockedIds.contains(storeInfo.getId())){
+                    continue;
+                }
                 storeInfoList.add(storeInfo);
             }
         }

+ 20 - 1
alien-store/src/main/java/shop/alien/store/controller/StoreInfoController.java

@@ -24,7 +24,6 @@ import shop.alien.entity.store.vo.*;
 import shop.alien.entity.storePlatform.StoreLicenseHistory;
 import shop.alien.mapper.*;
 import shop.alien.mapper.storePlantform.StoreLicenseHistoryMapper;
-import shop.alien.store.annotation.TrackEvent;
 import shop.alien.store.config.BaseRedisService;
 import shop.alien.store.service.StoreInfoService;
 import shop.alien.store.service.StoreQualificationService;
@@ -494,6 +493,26 @@ public class StoreInfoController {
         }
     }
 
+    @ApiOperation(value = "web端人工复核举报")
+    @ApiImplicitParams({@ApiImplicitParam(name = "reportId", value = "举报ID", dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "type", value = "类型(状态(0:待处理,1:已通过,2:已驳回))", dataType = "int", paramType = "query")})
+    @GetMapping("/manualReviewReport")
+    public R<Boolean> manualReviewReport(@RequestParam("reportId") Integer reportId, @RequestParam("type") Integer type) {
+        log.info("StoreInfoController.manualReviewReport?reportId={}&type={}", reportId, type);
+        try {
+            boolean success = storeInfoService.manualReviewReport(reportId,type);
+            if (success) {
+                return R.success("人工复核保存成功");
+            }
+            return R.fail("人工复核保存失败");
+        } catch (IllegalArgumentException e) {
+            return R.fail(e.getMessage());
+        } catch (Exception e) {
+            log.error("StoreInfoController.manualReview ERROR", e);
+            return R.fail("人工复核失败");
+        }
+    }
+
     @ApiOperation(value = "中台web端获取店铺明细详情")
     @ApiOperationSupport(order = 21)
     @GetMapping("/getNewStoreDetail")

+ 7 - 0
alien-store/src/main/java/shop/alien/store/service/StoreInfoService.java

@@ -578,4 +578,11 @@ public interface StoreInfoService extends IService<StoreInfo> {
      * @param headImgStatus 审核状态 1-审核通过,2-审核不通过
      */
     void updateHeadImgStatus(Integer storeId, Integer headImgStatus);
+    /**
+     * 人工复核举报
+     *
+     * @param reportId 举报ID
+     * @return 复核结果 true-复核通过,false-复核不通过
+     */
+    boolean manualReviewReport(Integer reportId, Integer type);
 }

+ 37 - 37
alien-store/src/main/java/shop/alien/store/service/impl/LifeMessageServiceImpl.java

@@ -417,18 +417,18 @@ public class LifeMessageServiceImpl extends ServiceImpl<LifeMessageMapper, LifeM
                 }
             }
 
-//            // 查询两个人是否是陌生人(只有一条消息)
-//            QueryWrapper<LifeMessage> wrapper = new QueryWrapper<>();
-//            // 没聊过
-//            wrapper.apply("((sender_id = '" + senderId + "' and receiver_id = '" + receiverId + "') or (sender_id = '" + receiverId + "' and receiver_id = '" + senderId + "'))");
-//            wrapper.orderByDesc("created_time");
-//            int count = lifeMessageMapper.selectCount(wrapper);
+            // 查询两个人是否是陌生人(只有一条消息)
+            QueryWrapper<LifeMessage> wrapper = new QueryWrapper<>();
+            // 没聊过
+            wrapper.apply("((sender_id = '" + senderId + "' and receiver_id = '" + receiverId + "') or (sender_id = '" + receiverId + "' and receiver_id = '" + senderId + "'))");
+            wrapper.orderByDesc("created_time");
+            int count = lifeMessageMapper.selectCount(wrapper);
 
             JSONObject jsonObject = new JSONObject();
             jsonObject.put("messageList", lifeMessageVos);
-//            jsonObject.put("isStranger", count <= 1);
+            jsonObject.put("isStranger", count <= 1);
             // 陌生人不限制一条消息
-            jsonObject.put("isStranger", false);
+//            jsonObject.put("isStranger", false);
 
             return jsonObject;
         } catch (Exception e) {
@@ -449,37 +449,37 @@ public class LifeMessageServiceImpl extends ServiceImpl<LifeMessageMapper, LifeM
 //            return lifeMessageMapper.selectCount(wrapper) <= 1;
 
             // 查询我发送过的消息
-//            QueryWrapper<LifeMessage> wrapper = new QueryWrapper<>();
-//            //本人发送的数量
-//            wrapper.apply("(sender_id = '" + senderId + "' and receiver_id = '" + receiverId + "')");
-////            wrapper.eq("sender_id", senderId);
-////            wrapper.eq("receiver_id", receiverId);
-//
-//            int senderCount = lifeMessageMapper.selectCount(wrapper);
-//            //查询对方发送过的消息
-//            QueryWrapper<LifeMessage> wrapper1 = new QueryWrapper<>();
-//            wrapper1.apply("(sender_id = '" + receiverId + "' and receiver_id = '" + senderId + "')");
-//            int receiverCount = lifeMessageMapper.selectCount(wrapper1);
-//            if (senderCount == 0){
-//                //本条可以发
-//                return "1";
-//            }
-//            senderCount++;
-//            // 可以一直唠
-//            if (senderCount >= 1 && receiverCount >= 1){
-//            // 发送本条消息并可以一直发
-//               return "2";
-//            }
-//            // 本人发过了,等待对方发
-//            if (senderCount > 1 && receiverCount==0){
-//                // 不允许发送本条消息
-//                 return "0";
-//            }
-
-//            return "0";
+            QueryWrapper<LifeMessage> wrapper = new QueryWrapper<>();
+            //本人发送的数量
+            wrapper.apply("(sender_id = '" + senderId + "' and receiver_id = '" + receiverId + "')");
+//            wrapper.eq("sender_id", senderId);
+//            wrapper.eq("receiver_id", receiverId);
+
+            int senderCount = lifeMessageMapper.selectCount(wrapper);
+            //查询对方发送过的消息
+            QueryWrapper<LifeMessage> wrapper1 = new QueryWrapper<>();
+            wrapper1.apply("(sender_id = '" + receiverId + "' and receiver_id = '" + senderId + "')");
+            int receiverCount = lifeMessageMapper.selectCount(wrapper1);
+            if (senderCount == 0){
+                //本条可以发
+                return "1";
+            }
+            senderCount++;
+            // 可以一直唠
+            if (senderCount >= 1 && receiverCount >= 1){
+            // 发送本条消息并可以一直发
+               return "2";
+            }
+            // 本人发过了,等待对方发
+            if (senderCount > 1 && receiverCount==0){
+                // 不允许发送本条消息
+                 return "0";
+            }
+
+            return "0";
 
             // 陌生人不限制一条消息
-            return "2";
+//            return "2";
         } catch (Exception e) {
             log.error("LifeMessageServiceImpl.isStranger Error Mgs={}", e.getMessage());
             throw new Exception(e);

+ 7 - 2
alien-store/src/main/java/shop/alien/store/service/impl/LifeUserViolationServiceImpl.java

@@ -30,6 +30,7 @@ import shop.alien.store.config.WebSocketProcess;
 import shop.alien.store.service.*;
 import shop.alien.store.util.AiUserViolationUtils;
 import shop.alien.store.util.FunctionMagic;
+import shop.alien.store.util.ai.AiReportReviewUtil;
 import shop.alien.util.ali.AliOSSUtil;
 import shop.alien.util.common.EnumUtil;
 
@@ -87,6 +88,9 @@ public class LifeUserViolationServiceImpl extends ServiceImpl<LifeUserViolationM
 
     private final AiUserViolationUtils aiUserViolationUtils;
     private final CommonCommentMapper commonCommentMapper;
+    private final AiReportReviewUtil aiReportReviewUtil;
+
+
 
     @Autowired
     private SecondUserViolationMapper mapper;
@@ -110,6 +114,7 @@ public class LifeUserViolationServiceImpl extends ServiceImpl<LifeUserViolationM
                 if (null != goodsRecord) lifeuserViolation.setBusinessId(goodsRecord.getId());
             }
             int result = lifeUserViolationMapper.insert(lifeuserViolation);
+            aiReportReviewUtil.reviewReport(lifeuserViolation.getId(), lifeuserViolation.getReportContextType());
             if (result > 0) {
                 // AI审核
                 //登录获取token
@@ -126,7 +131,7 @@ public class LifeUserViolationServiceImpl extends ServiceImpl<LifeUserViolationM
 
                 //String phoneId = Objects.requireNonNull(JwtUtil.getCurrentUserInfo()).getString("userType") + "_" + JwtUtil.getCurrentUserInfo().getString("phone");
                     // 举报人消息
-                    LifeNotice lifeNotice = getLifeNotice(lifeuserViolation);
+                  /*  LifeNotice lifeNotice = getLifeNotice(lifeuserViolation);
                     lifeNoticeMapper.insert(lifeNotice);
                     WebSocketVo websocketVo = new WebSocketVo();
                     websocketVo.setSenderId("system");
@@ -151,7 +156,7 @@ public class LifeUserViolationServiceImpl extends ServiceImpl<LifeUserViolationM
                             websocketVoReported.setText(com.alibaba.fastjson2.JSONObject.from(lifeNoticeReported).toJSONString());
                             webSocketProcess.sendMessage(lifeNoticeReported.getReceiverId(), com.alibaba.fastjson2.JSONObject.from(websocketVoReported).toJSONString());
                         }
-                    }
+                    }*/
                 return result;
             }
         } catch (Exception e) {

+ 11 - 0
alien-store/src/main/java/shop/alien/store/service/impl/StoreCommentServiceImpl.java

@@ -164,6 +164,17 @@ public class StoreCommentServiceImpl extends ServiceImpl<StoreCommentMapper, Sto
             }
         }
 
+        // 回复状态筛选:在分页查询前加入SQL条件,保证「未回复」只显示未回复数据、总数和分页正确
+        if (replyStatus != null && (replyStatus == 1 || replyStatus == 2)) {
+            if (replyStatus == 1) {
+                // 已回复:存在商家回复(子评论中 phone_id 含 store_)
+                queryWrapper.apply("EXISTS (SELECT 1 FROM store_comment r WHERE r.reply_id = a.id AND r.phone_id LIKE '%store%' AND r.delete_flag = 0)");
+            } else if (replyStatus == 2) {
+                // 未回复:不存在商家回复
+                queryWrapper.apply("NOT EXISTS (SELECT 1 FROM store_comment r WHERE r.reply_id = a.id AND r.phone_id LIKE '%store%' AND r.delete_flag = 0)");
+            }
+        }
+
         //先查询父级评论
         queryWrapper.isNull(businessType != 1, "a.reply_id").eq("a.delete_flag", 0).orderByDesc("a.created_time");
         IPage<StoreCommentVo> page = storeCommentMapper.getCommentPage(storeCommentIPage, queryWrapper);

+ 10 - 0
alien-store/src/main/java/shop/alien/store/service/impl/StoreInfoServiceImpl.java

@@ -178,6 +178,8 @@ public class StoreInfoServiceImpl extends ServiceImpl<StoreInfoMapper, StoreInfo
     @Resource
     private StoreIncomeDetailsRecordService storeIncomeDetailsRecordService;
 
+    private final LifeUserViolationMapper lifeUserViolationMapper;
+
 
     @Value("${spring.web.resources.excel-path}")
     private String excelPath;
@@ -3416,6 +3418,14 @@ public class StoreInfoServiceImpl extends ServiceImpl<StoreInfoMapper, StoreInfo
         log.info("更新门店头图审核状态,storeId={}, headImgStatus={}", storeId, headImgStatus);
     }
 
+    @Override
+    public boolean manualReviewReport(Integer reportId, Integer type) {
+        LifeUserViolation lifeUserViolation = lifeUserViolationMapper.selectById(reportId);
+        lifeUserViolation.setProcessingStatus(type.toString());
+        int i = lifeUserViolationMapper.updateById(lifeUserViolation);
+        return i > 0 ;
+    }
+
     /**
      * 获取活动banner图
      * 关联查询 store_img 和 store_operational_activity 表

+ 19 - 9
alien-store/src/main/java/shop/alien/store/service/impl/StoreRenovationRequirementServiceImpl.java

@@ -572,15 +572,25 @@ public class StoreRenovationRequirementServiceImpl extends ServiceImpl<StoreReno
                         Boolean hasCommunicated = communicationStatusMap.get(communicationKey);
 
                         if (hasCommunicated == null) {
-                            // 查询是否有消息记录(检查双向消息)
-                            LambdaQueryWrapper<LifeMessage> messageWrapper = new LambdaQueryWrapper<>();
-                            messageWrapper.eq(LifeMessage::getDeleteFlag, 0);
-                            messageWrapper.and(w -> w.and(w1 -> w1.eq(LifeMessage::getSenderId, currentUserPhoneId)
-                                            .eq(LifeMessage::getReceiverId, publishingShopPhoneId))
-                                    .or(w2 -> w2.eq(LifeMessage::getSenderId, publishingShopPhoneId)
-                                            .eq(LifeMessage::getReceiverId, currentUserPhoneId)));
-                            Integer messageCount = lifeMessageMapper.selectCount(messageWrapper);
-                            hasCommunicated = messageCount != null && messageCount > 0;
+                            // 判断互相都发送过消息才算沟通过
+                            // 检查 currentUserPhoneId 是否给 publishingShopPhoneId 发送过消息
+                            LambdaQueryWrapper<LifeMessage> messageWrapper1 = new LambdaQueryWrapper<>();
+                            messageWrapper1.eq(LifeMessage::getDeleteFlag, 0)
+                                    .eq(LifeMessage::getSenderId, currentUserPhoneId)
+                                    .eq(LifeMessage::getReceiverId, publishingShopPhoneId);
+                            Integer messageCount1 = lifeMessageMapper.selectCount(messageWrapper1);
+                            boolean hasSentMessage1 = messageCount1 != null && messageCount1 > 0;
+
+                            // 检查 publishingShopPhoneId 是否给 currentUserPhoneId 发送过消息
+                            LambdaQueryWrapper<LifeMessage> messageWrapper2 = new LambdaQueryWrapper<>();
+                            messageWrapper2.eq(LifeMessage::getDeleteFlag, 0)
+                                    .eq(LifeMessage::getSenderId, publishingShopPhoneId)
+                                    .eq(LifeMessage::getReceiverId, currentUserPhoneId);
+                            Integer messageCount2 = lifeMessageMapper.selectCount(messageWrapper2);
+                            boolean hasSentMessage2 = messageCount2 != null && messageCount2 > 0;
+
+                            // 只有双方都发送过消息才算沟通过
+                            hasCommunicated = hasSentMessage1 && hasSentMessage2;
                             communicationStatusMap.put(communicationKey, hasCommunicated);
                         }
 

+ 11 - 8
alien-store/src/main/java/shop/alien/store/service/impl/StoreUserServiceImpl.java

@@ -252,10 +252,12 @@ public class StoreUserServiceImpl extends ServiceImpl<StoreUserMapper, StoreUser
     public Map<String, String> changePhoneVerification(String phone, String oldPassword, String verificationCode) {
         Map<String, String> changePhoneMap = new HashMap<>();
         if (oldPassword != null && !oldPassword.equals("")) {
-            LambdaUpdateWrapper<StoreUser> userLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
-            userLambdaUpdateWrapper.eq(StoreUser::getPhone, phone);
-            StoreUser storeUser = this.getOne(userLambdaUpdateWrapper);
-            if (storeUser.getPassword().equals(oldPassword)) {
+            LambdaQueryWrapper<StoreUser> userLambdaQueryWrapper = new LambdaQueryWrapper<>();
+            userLambdaQueryWrapper.eq(StoreUser::getPhone, phone);
+            StoreUser storeUser = this.getOne(userLambdaQueryWrapper);
+            // 由于password字段使用了EncryptTypeHandler,查询时密码会被自动解密
+            // 所以这里直接比较解密后的密码和用户输入的明文密码
+            if (storeUser != null && storeUser.getPassword() != null && storeUser.getPassword().equals(oldPassword)) {
                 changePhoneMap.put("passwordStatus", "1");
                 return changePhoneMap;
             } else {
@@ -269,7 +271,7 @@ public class StoreUserServiceImpl extends ServiceImpl<StoreUserMapper, StoreUser
     }
 
     private void passwordVerification(String phone, String password, String newPassword, String confirmNewPassword) {
-        LambdaUpdateWrapper<StoreUser> wrapperFans = new LambdaUpdateWrapper<>();
+        LambdaQueryWrapper<StoreUser> wrapperFans = new LambdaQueryWrapper<>();
         wrapperFans.eq(StoreUser::getPhone, phone);
         StoreUser storeUser = this.getOne(wrapperFans);
         if (!newPassword.equals(confirmNewPassword)) {
@@ -280,9 +282,10 @@ public class StoreUserServiceImpl extends ServiceImpl<StoreUserMapper, StoreUser
             log.info("该手机号没有注册过账户");
             throw new RuntimeException("该手机号没有注册过账户");
         } else {
-            wrapperFans.eq(StoreUser::getPassword, password);
-            StoreUser storeUserPw = this.getOne(wrapperFans);
-            if (storeUserPw == null || storeUserPw.getPassword().equals("")) {
+            // 由于password字段使用了EncryptTypeHandler,查询时密码会被自动解密
+            // 所以这里直接比较解密后的密码和用户输入的明文密码
+            String dbPassword = storeUser.getPassword();
+            if (dbPassword == null || dbPassword.isEmpty() || !dbPassword.equals(password)) {
                 log.info("原密码错误");
                 throw new RuntimeException("原密码错误");
             }

+ 27 - 1
alien-store/src/main/java/shop/alien/store/service/impl/SubAccountStoreServiceImpl.java

@@ -1,9 +1,15 @@
 package shop.alien.store.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
+import shop.alien.entity.store.StorePlatformRole;
+import shop.alien.entity.store.StorePlatformUserRole;
+import shop.alien.entity.store.StoreUser;
 import shop.alien.entity.store.vo.SubAccountStoreListVo;
+import shop.alien.mapper.StorePlatformUserRoleMapper;
+import shop.alien.mapper.StoreUserMapper;
 import shop.alien.mapper.SubAccountStoreMapper;
 import shop.alien.store.service.SubAccountStoreService;
 
@@ -23,14 +29,34 @@ public class SubAccountStoreServiceImpl implements SubAccountStoreService {
 
     private final SubAccountStoreMapper subAccountStoreMapper;
 
+    private final StorePlatformUserRoleMapper storePlatformUserRoleMapper;
+
+    private final StoreUserMapper storeUserMapper;
+
     @Override
     public List<SubAccountStoreListVo> getSubAccountStoreList(Integer userId) {
         log.info("SubAccountStoreServiceImpl.getSubAccountStoreList?userId={}", userId);
+        List<SubAccountStoreListVo> storeList = new ArrayList<>();
         if (userId == null) {
             log.warn("用户ID为空");
             return new ArrayList<>();
         }
-        List<SubAccountStoreListVo> storeList = subAccountStoreMapper.selectSubAccountStoreListByUserId(userId);
+        List<StorePlatformUserRole> list = new ArrayList<>();
+        StoreUser storeUser = storeUserMapper.selectOne(new LambdaQueryWrapper<StoreUser>()
+                .eq(StoreUser :: getId, userId));
+        if(storeUser!=null){
+            if(storeUser.getAccountType() != 1){
+                list = storePlatformUserRoleMapper.selectList(new LambdaQueryWrapper<StorePlatformUserRole>()
+                        .eq(StorePlatformUserRole :: getUserId, userId));
+            }
+        }
+        if(list.size()>0 || storeUser.getStoreId() != null){
+            //查出主子账号所有门店信息回显
+            storeList = subAccountStoreMapper.selectSubAccountStoreListByUserIdTwo(userId);
+        }else{
+            //主账号没有门店 子账号有门店 查出主账号 账号信息和子账号门店信息组合回显
+            storeList = subAccountStoreMapper.selectSubAccountStoreListByUserId(userId);
+        }
         log.info("查询子账号关联门店列表完成 - 用户ID: {}, 门店数量: {}", userId, storeList != null ? storeList.size() : 0);
         return storeList;
     }

+ 71 - 0
alien-store/src/main/java/shop/alien/store/util/ai/AiReportReviewUtil.java

@@ -0,0 +1,71 @@
+package shop.alien.store.util.ai;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.cloud.context.config.annotation.RefreshScope;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
+import org.springframework.web.client.RestTemplate;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * AI 举报审核(举报评论,举报动态)工具类
+ *
+ * @author system
+ * @since 2025-01-XX
+ */
+
+@Slf4j
+@Component
+@RefreshScope
+@RequiredArgsConstructor
+public class AiReportReviewUtil {
+
+    private final AiAuthTokenUtil aiAuthTokenUtil;
+    private final RestTemplate restTemplate;
+
+    @Value("${third-party-ai.report-review.base-url:http://124.93.18.180:9000/ai/auto-review/api/v1/merchant_dynamic_violation_audit_task/submit}")
+    private String aiReportReviewUrl;
+
+    @Async("taskExecutor")
+    public void reviewReport(Integer reportId, String reportType) {
+
+        if(!StringUtils.hasText(reportId.toString())){
+            throw new IllegalArgumentException("reportId 不能为空");
+        }
+
+        if(!StringUtils.hasText(reportType)){
+            throw new IllegalArgumentException("reportType 不能为空");
+        }
+
+
+        // 1. 登录 AI 服务,获取 token
+        String accessToken = aiAuthTokenUtil.getAccessToken();
+        if(!StringUtils.hasText(accessToken)){
+            throw new IllegalArgumentException("accessToken 不能为空");
+        }
+
+        // 构建请求体
+        Map<String, Object> requestBody = new HashMap<>();
+        requestBody.put("id", reportId);
+        requestBody.put("type", reportType);
+        // 构建请求头,添加Authorization
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_JSON);
+        headers.set("Authorization", "Bearer " + accessToken);
+        HttpEntity<Map<String, Object>> request = new HttpEntity<>(requestBody, headers);
+        log.info("调用ai举报接口URL:{},requestBody: {}", aiReportReviewUrl, requestBody);
+        ResponseEntity<String> response = restTemplate.postForEntity(aiReportReviewUrl, request, String.class);
+        if(response.getStatusCode().isError()){
+            log.error("调用ai举报接口失败,URL:{},requestBody: {},response: {}", aiReportReviewUrl, requestBody, response);
+        }
+    }
+}