lutong 5 годин тому
батько
коміт
82878e5840

+ 7 - 0
alien-entity/src/main/java/shop/alien/entity/store/LawyerUser.java

@@ -26,6 +26,13 @@ import java.util.List;
 @ApiModel(value = "LawyerUser对象", description = "律师用户")
 public class LawyerUser extends Model<LawyerUser> {
 
+    /** logout_flag:未注销 */
+    public static final int LOGOUT_FLAG_NORMAL = 0;
+    /** logout_flag:已注销(冷静期结束后) */
+    public static final int LOGOUT_FLAG_DONE = 1;
+    /** logout_flag:注销冷静期 */
+    public static final int LOGOUT_FLAG_COOLING = 2;
+
     public LawyerUser() {
     }
 

+ 6 - 0
alien-entity/src/main/java/shop/alien/entity/store/dto/LawyerLogoutRequestDto.java

@@ -16,6 +16,12 @@ public class LawyerLogoutRequestDto implements Serializable {
     @ApiModelProperty(value = "律师ID", required = true)
     private Integer id;
 
+    @ApiModelProperty(value = "手机号", required = true)
+    private String phone;
+
+    @ApiModelProperty(value = "短信验证码", required = true)
+    private String verificationCode;
+
     @ApiModelProperty(value = "注销原因(如:多余账号、使用过程中遇到困难、安全/隐私顾虑、不再从事该行业、其他)", required = true)
     private String logoutReason;
 

+ 3 - 3
alien-gateway/src/main/java/shop/alien/gateway/config/JwtTokenFilter.java

@@ -196,10 +196,10 @@ public class JwtTokenFilter implements GlobalFilter, Ordered {
                             map.put("code", 666);
                         }
                     } else if ("lawyer".equals(deviceType)) {
-                        //判断程序是否为用户禁用
                         LawyerUser lawyerUser = lawyerUserMapper.selectOne(new LambdaQueryWrapper<LawyerUser>().eq(LawyerUser::getPhone, phone));
-                        //注销标记, 0:未注销, 1:已注销
-                        if (lawyerUser != null && null != lawyerUser.getLogoutFlag() && lawyerUser.getLogoutFlag() == 1) {
+                        if (lawyerUser != null && lawyerUser.getLogoutFlag() != null
+                                && LawyerUser.LOGOUT_FLAG_DONE == lawyerUser.getLogoutFlag()
+                                && (lawyerUser.getDeleteFlag() == null || lawyerUser.getDeleteFlag() == 0)) {
                             map.put("msg", "你的账号已注销");
                             map.put("code", 777);
                         }

+ 4 - 16
alien-job/src/main/java/shop/alien/job/store/StoreMembershipCardJob.java

@@ -279,7 +279,7 @@ public class StoreMembershipCardJob {
 
         // 获取处于注销冷静期的律师用户
         List<LawyerUser> lawyerUsers = lawyerUserMapper.selectList(new LambdaQueryWrapper<LawyerUser>()
-                .eq(LawyerUser::getLogoutFlag, LOGOUT_FLAG_COOLING)
+                .eq(LawyerUser::getLogoutFlag, LawyerUser.LOGOUT_FLAG_COOLING)
                 .eq(LawyerUser::getDeleteFlag, 0));
         for (LawyerUser lawyerUser : lawyerUsers) {
             try {
@@ -291,33 +291,21 @@ public class StoreMembershipCardJob {
                     Date sevenDay = calendar.getTime();
                     Date date = new Date();
                     if (date.compareTo(sevenDay) >= 0) {
-                        log.info("律师账号冷静期结束,执行注销: lawyerId={}, phone={}, logoutTime={}",
+                        log.info("律师账号冷静期结束,更新注销标记为已注销: lawyerId={}, phone={}, logoutTime={}",
                                 lawyerUser.getId(), lawyerUser.getPhone(), logoutTime);
-
-                        String receiverKey = "lawyer_" + lawyerUser.getPhone();
-                        baseRedisService.delete(receiverKey);
-
                         lawyerUserMapper.update(null, new LambdaUpdateWrapper<LawyerUser>()
                                 .eq(LawyerUser::getId, lawyerUser.getId())
-                                .set(LawyerUser::getLogoutFlag, LOGOUT_FLAG_DONE)
-                                .set(LawyerUser::getStatus, 0)
+                                .set(LawyerUser::getLogoutFlag, LawyerUser.LOGOUT_FLAG_DONE)
                                 .set(LawyerUser::getOrderReceivingStatus, 0)
                                 .set(LawyerUser::getIsOnline, 0)
                                 .set(LawyerUser::getIsRecommended, 0)
-                                .set(LawyerUser::getDeleteFlag, 1)
                                 .set(LawyerUser::getLastOnlineTime, date));
-
-//                        LambdaUpdateWrapper<LifeNotice> noticeUpdateWrapper = new LambdaUpdateWrapper<>();
-//                        lifeNoticeUtil.applyReceiverUpdate(noticeUpdateWrapper, receiverKey);
-//                        noticeUpdateWrapper.set(LifeNotice::getDeleteFlag, 1);
-//                        lifeNoticeMapper.update(null, noticeUpdateWrapper);
-
                         successCount++;
                     }
                 }
             } catch (Exception e) {
                 failCount++;
-                log.error("律师账号注销失败: lawyerId={}, phone={}, error={}",
+                log.error("律师账号注销状态更新失败: lawyerId={}, phone={}, error={}",
                         lawyerUser.getId(), lawyerUser.getPhone(), e.getMessage(), e);
             }
         }

+ 38 - 2
alien-lawyer/src/main/java/shop/alien/lawyer/controller/LawyerUserController.java

@@ -13,6 +13,8 @@ import shop.alien.entity.store.dto.LawyerPaymentAccountDto;
 import shop.alien.entity.store.dto.LawyerRecommendedDto;
 import shop.alien.entity.store.dto.LawyerUserDto;
 import shop.alien.entity.store.vo.LawyerUserVo;
+import org.springframework.util.StringUtils;
+import shop.alien.lawyer.config.BaseRedisService;
 import shop.alien.lawyer.service.LawyerUserService;
 import shop.alien.util.myBaticsPlus.QueryBuilder;
 
@@ -37,6 +39,8 @@ public class LawyerUserController {
 
     private final LawyerUserService lawyerUserService;
 
+    private final BaseRedisService baseRedisService;
+
     @ApiOperation("新增律师用户")
     @ApiOperationSupport(order = 1)
     @PostMapping("/addLawyerUser")
@@ -215,12 +219,44 @@ public class LawyerUserController {
     }
 
 
+    @ApiOperation("律师端注销前校验")
+    @ApiOperationSupport(order = 12)
+    @PostMapping("/lawyerCancelAccountVerification")
+    public R<Map<String, String>> lawyerCancelAccountVerification(@RequestBody LawyerLogoutRequestDto request) {
+        log.info("LawyerUserController.lawyerCancelAccountVerification?request={}", request);
+        if (request == null || request.getId() == null) {
+            return R.fail("律师ID不能为空");
+        }
+        return R.data(lawyerUserService.lawyerCancelAccountVerification(request.getId()));
+    }
+
     @ApiOperation("注销律师用户")
     @ApiOperationSupport(order = 13)
     @PostMapping("/logOutLawyerUser")
-    public R<Map<String, Object>> logOutLawyerUser(@RequestBody LawyerLogoutRequestDto request) {
+    public R<Boolean> logOutLawyerUser(@RequestBody LawyerLogoutRequestDto request) {
         log.info("LawyerUserController.logOutLawyerUser?request={}", request);
-        return lawyerUserService.logOutLawyerUser(request);
+        if (request == null || request.getId() == null) {
+            return R.fail("律师ID不能为空");
+        }
+        if (!StringUtils.hasText(request.getPhone())) {
+            return R.fail("手机号不能为空");
+        }
+        if (!StringUtils.hasText(request.getVerificationCode())) {
+            return R.fail("验证码不能为空");
+        }
+        String cacheCode = baseRedisService.getString("verification_lawyer_" + request.getPhone());
+        if (cacheCode == null) {
+            return R.fail("当验证码过期或未发送");
+        }
+        if (!cacheCode.trim().equals(request.getVerificationCode().trim())) {
+            return R.fail("验证码错误,请重新输入");
+        }
+        try {
+            lawyerUserService.logOutLawyerUser(request);
+        } catch (IllegalArgumentException e) {
+            return R.fail(e.getMessage());
+        }
+        return R.success("注销申请已提交");
     }
 
     @ApiOperation("撤销律师注销申请")

+ 15 - 1
alien-lawyer/src/main/java/shop/alien/lawyer/controller/LawyerUserLogInController.java

@@ -17,6 +17,7 @@ import shop.alien.entity.store.dto.LawyerUserDto;
 import shop.alien.entity.store.vo.LawyerUserVo;
 import shop.alien.lawyer.config.BaseRedisService;
 import shop.alien.lawyer.service.LawyerUserLogInService;
+import shop.alien.lawyer.service.LawyerUserService;
 import shop.alien.mapper.LawyerUserMapper;
 
 import java.util.Objects;
@@ -38,6 +39,7 @@ import java.util.Optional;
 public class LawyerUserLogInController {
 
     private final LawyerUserLogInService lawyerUserService;
+    private final LawyerUserService lawyerUserBizService;
     private final LawyerUserMapper lawyerUserMapper;
     private final BaseRedisService baseRedisService;
 
@@ -67,7 +69,11 @@ public class LawyerUserLogInController {
         if (null == lawyerUser) {
             return R.fail("当前账号不存在,请先去注册账号!");
         }
-        if (lawyerUser.getStatus() == 0) {
+        R<LawyerUser> loginCheck = lawyerUserBizService.checkLogin(lawyerUserDto.getPhone());
+        if ("账号已注销".equals(loginCheck.getMsg())) {
+            return R.fail("账号已注销");
+        }
+        if ("账号已被禁用".equals(loginCheck.getMsg())) {
             return R.fail("账号被禁用");
         }
         LawyerUser lawyerUser1 = new LawyerUser();
@@ -79,6 +85,14 @@ public class LawyerUserLogInController {
                 orElseGet(() -> R.fail("手机号不存在"));
     }
 
+    @ApiOperation("律师登录前校验")
+    @ApiOperationSupport(order = 7)
+    @GetMapping("/checkLogin")
+    public R<LawyerUser> checkLogin(String phone) {
+        log.info("LawyerUserLogInController.checkLogin?phone={}", phone);
+        return lawyerUserBizService.checkLogin(phone);
+    }
+
     @ApiOperation("律师用户登出")
     @ApiOperationSupport(order = 4)
     @PostMapping("/logout")

+ 13 - 14
alien-lawyer/src/main/java/shop/alien/lawyer/service/LawyerUserService.java

@@ -115,28 +115,27 @@ public interface LawyerUserService extends IService<LawyerUser> {
     R<IPage<LawyerUser>> getAiRecommendList(int page, int size, Integer categoryId);
 
     /**
-     * 注销律师用户
-     * <p>
-     * 注销前会进行以下校验:
-     * 1. 参数校验:律师ID不能为空
-     * 2. 律师存在性校验:律师必须存在
-     * 3. 注销状态校验:已注销的律师不允许重复注销
-     * 4. 设置注销相关字段:注销标记、注销时间、状态等
-     * </p>
-     *
-     * @param request 律师ID
-     * @return R<Map < String, Object>> 注销结果,包含律师ID、姓名、手机号、注销标记、注销时间等信息
+     * 律师端注销前校验。
+     * accountMoney/accountConsultOrder/accountReceivingStatus:0 未通过,1 通过。
+     */
+    Map<String, String> lawyerCancelAccountVerification(Integer lawyerId);
+
+    /**
+     * 注销律师用户(进入 7 天冷静期)
      */
-    R<Map<String, Object>> logOutLawyerUser(LawyerLogoutRequestDto request);
+    void logOutLawyerUser(LawyerLogoutRequestDto request);
 
     /**
      * 撤销律师注销申请(冷静期内)
-     *
-     * @param id 律师ID
      */
     void cancelLogoutLawyerUser(Integer id);
 
     /**
+     * 登录前校验律师账号状态
+     */
+    R<LawyerUser> checkLogin(String phone);
+
+    /**
      * 获取律师信息
      *
      * @param lawyerId 律师ID

+ 13 - 2
alien-lawyer/src/main/java/shop/alien/lawyer/service/impl/LawyerUserLogInServiceImpl.java

@@ -103,7 +103,7 @@ public class LawyerUserLogInServiceImpl extends ServiceImpl<LawyerUserMapper, La
      * 申请注销结束时间:logoutTime 起算第 7 天(T+0~T+7),与冷静期一致。
      */
     private static String resolveLogoutEndTime(Date logoutTime, Integer logoutFlag) {
-        if (logoutTime == null || logoutFlag == null || logoutFlag == 0) {
+        if (logoutTime == null || logoutFlag == null || LawyerUser.LOGOUT_FLAG_COOLING != logoutFlag) {
             return null;
         }
         return logoutTime.toInstant()
@@ -121,6 +121,10 @@ public class LawyerUserLogInServiceImpl extends ServiceImpl<LawyerUserMapper, La
             if (lawyerUser.getStatus() == 0) {
                 return R.fail("账号被禁用");
             }
+            if (lawyerUser.getLogoutFlag() != null && LawyerUser.LOGOUT_FLAG_DONE == lawyerUser.getLogoutFlag()
+                    && (lawyerUser.getDeleteFlag() == null || lawyerUser.getDeleteFlag() == 0)) {
+                return R.fail("账号已注销");
+            }
             return createToKen(lawyerUser);
         }else {
             LawyerUser user = new LawyerUser();
@@ -137,7 +141,7 @@ public class LawyerUserLogInServiceImpl extends ServiceImpl<LawyerUserMapper, La
                     return R.fail("该律师执业证号已被使用,无法重复注册");
                 }
             }
-            user.setLogoutFlag(0);
+            user.setLogoutFlag(LawyerUser.LOGOUT_FLAG_NORMAL);
             user.setStatus(1);
             user.setDeleteFlag(0);
             user.setIsOnline(1);
@@ -179,6 +183,13 @@ public class LawyerUserLogInServiceImpl extends ServiceImpl<LawyerUserMapper, La
                         .eq(LawyerUser::getPhone, lawyerUserDto.getPhone()));
                 LawyerUserVo vo = new LawyerUserVo();
                 if (ObjectUtils.isNotEmpty(lawyerUser)) {
+                    if (lawyerUser.getStatus() != null && lawyerUser.getStatus() == 0) {
+                        return R.fail("账号被禁用");
+                    }
+                    if (lawyerUser.getLogoutFlag() != null && LawyerUser.LOGOUT_FLAG_DONE == lawyerUser.getLogoutFlag()
+                            && (lawyerUser.getDeleteFlag() == null || lawyerUser.getDeleteFlag() == 0)) {
+                        return R.fail("账号已注销");
+                    }
                     BeanUtils.copyProperties(lawyerUser, vo);
                     return createToKen(lawyerUser);
                 }

+ 179 - 104
alien-lawyer/src/main/java/shop/alien/lawyer/service/impl/LawyerUserServiceImpl.java

@@ -20,7 +20,9 @@ import shop.alien.entity.store.dto.LawyerLogoutRequestDto;
 import shop.alien.entity.store.dto.LawyerUserDto;
 import shop.alien.entity.store.excelVo.LawyerUserExcelVo;
 import shop.alien.entity.store.vo.LawyerUserVo;
+import shop.alien.entity.store.vo.WebSocketVo;
 import shop.alien.lawyer.config.BaseRedisService;
+import shop.alien.lawyer.config.WebSocketProcess;
 import shop.alien.lawyer.service.LawyerLegalProblemScenarioService;
 import shop.alien.lawyer.service.LawyerServiceAreaService;
 import shop.alien.lawyer.service.LawyerUserSearchHistoryService;
@@ -28,6 +30,7 @@ import shop.alien.lawyer.service.LawyerUserService;
 import shop.alien.lawyer.util.ai.LawyerLicenseVerifyUtil;
 import shop.alien.mapper.*;
 import shop.alien.util.common.ListToPage;
+import shop.alien.util.common.constant.LawyerStatusEnum;
 import shop.alien.util.excel.EasyExcelUtil;
 import shop.alien.util.type.LifeNoticeUtil;
 
@@ -50,10 +53,15 @@ public class LawyerUserServiceImpl extends ServiceImpl<LawyerUserMapper, LawyerU
 
     private static final String LOGOUT_REASON_OTHER = "其他";
     private static final int LOGOUT_CONTENT_MAX_LENGTH = 300;
-    private static final int LOGOUT_FLAG_COOLING = 2;
     private static final int LOGOUT_COOLING_DAYS = 7;
     private static final String CANCEL_REVOKE_NOT_IN_COOLING_MSG = "当前账号不在注销冷静期内,无法撤销";
 
+    /** 咨询订单未完成:待支付、待接单、进行中 */
+    private static final List<Integer> PENDING_CONSULTATION_ORDER_STATUSES = Arrays.asList(
+            LawyerStatusEnum.WAIT_PAY.getStatus(),
+            LawyerStatusEnum.WAIT_ACCEPT.getStatus(),
+            LawyerStatusEnum.INPROGRESS.getStatus());
+
     private final LawyerUserMapper lawyerUserMapper;
     private final LawyerServiceAreaService lawyerServiceAreaService;
     private final LawyerServiceAreaMapper lawyerServiceAreaMapper;
@@ -68,6 +76,7 @@ public class LawyerUserServiceImpl extends ServiceImpl<LawyerUserMapper, LawyerU
     private final LifeNoticeUtil lifeNoticeUtil;
     private final LawyerLicenseVerifyUtil lawyerLicenseVerifyUtil;
     private final StoreDictionaryMapper storeDictionaryMapper;
+    private final WebSocketProcess webSocketProcess;
 
     @Override
     public R<IPage<LawyerUser>> getLawyerUserList(int pageNum, int pageSize, String name, String phone, Integer status) {
@@ -488,117 +497,112 @@ public class LawyerUserServiceImpl extends ServiceImpl<LawyerUserMapper, LawyerU
         return R.data(pageResult);
     }
 
-    /**
-     * 注销律师用户
-     * <p>
-     * 注销前会进行以下校验:
-     * 1. 参数校验:律师ID不能为空
-     * 2. 律师存在性校验:律师必须存在
-     * 3. 注销状态校验:已注销的律师不允许重复注销
-     * 4. 设置注销相关字段:注销标记、注销时间、状态等
-     * </p>
-     *
-     * @param request 注销请求(含律师ID、注销原因、注销内容)
-     * @return 注销结果,包含注销信息
-     */
+    @Override
+    public Map<String, String> lawyerCancelAccountVerification(Integer lawyerId) {
+        Map<String, String> result = new HashMap<>();
+        if (lawyerId == null) {
+            return result;
+        }
+        LawyerUser lawyerUser = this.getById(lawyerId);
+        if (lawyerUser == null) {
+            return result;
+        }
+        result.put("status", lawyerUser.getStatus() != null ? lawyerUser.getStatus().toString() : "1");
+        if (lawyerUser.getMoney() != null && lawyerUser.getMoney() > 0) {
+            result.put("accountMoney", "0");
+        } else {
+            result.put("accountMoney", "1");
+        }
+        long pendingOrderCount = lawyerConsultationOrderMapper.selectCount(new LambdaQueryWrapper<LawyerConsultationOrder>()
+                .eq(LawyerConsultationOrder::getLawyerUserId, lawyerId)
+                .in(LawyerConsultationOrder::getOrderStatus, PENDING_CONSULTATION_ORDER_STATUSES)
+                .eq(LawyerConsultationOrder::getDeleteFlag, 0));
+        result.put("accountConsultOrder", pendingOrderCount > 0 ? "0" : "1");
+        result.put("accountConsultOrderCount", String.valueOf(pendingOrderCount));
+        if (lawyerUser.getOrderReceivingStatus() != null && lawyerUser.getOrderReceivingStatus() == 1) {
+            result.put("accountReceivingStatus", "0");
+        } else {
+            result.put("accountReceivingStatus", "1");
+        }
+        return result;
+    }
+
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public R<Map<String, Object>> logOutLawyerUser(LawyerLogoutRequestDto request) {
+    public void logOutLawyerUser(LawyerLogoutRequestDto request) {
         log.info("开始注销律师用户,request={}", request);
-
-        Map<String, Object> resultMap = new HashMap<>();
-
         if (request == null || request.getId() == null) {
-            log.warn("注销律师用户失败:律师ID为空");
-            return R.fail("律师ID不能为空");
+            throw new IllegalArgumentException("律师ID不能为空");
         }
         Integer id = request.getId();
 
         String logoutReason = request.getLogoutReason() == null ? null : request.getLogoutReason().trim();
         if (!StringUtils.hasText(logoutReason)) {
-            log.warn("注销律师用户失败:注销原因为空,律师ID={}", id);
-            return R.fail("请选择注销原因");
+            throw new IllegalArgumentException("请选择注销原因");
         }
 
         String logoutContent = request.getLogoutContent() == null ? null : request.getLogoutContent().trim();
         if (LOGOUT_REASON_OTHER.equals(logoutReason)) {
             if (!StringUtils.hasText(logoutContent)) {
-                log.warn("注销律师用户失败:原因为其他时注销内容为空,律师ID={}", id);
-                return R.fail("请填写注销内容");
+                throw new IllegalArgumentException("请填写注销内容");
             }
             if (logoutContent.length() > LOGOUT_CONTENT_MAX_LENGTH) {
-                log.warn("注销律师用户失败:注销内容超过{}字,律师ID={}", LOGOUT_CONTENT_MAX_LENGTH, id);
-                return R.fail("注销内容不能超过300字");
+                throw new IllegalArgumentException("注销内容不能超过300字");
             }
         }
 
-        // 查询律师信息
         LawyerUser lawyerUser = this.getById(id);
         if (lawyerUser == null) {
-            log.warn("注销律师用户失败:律师不存在,律师ID={}", id);
-            return R.fail("律师不存在");
-        }
-
-        // 检查是否已经注销
-        if (lawyerUser.getLogoutFlag() != null && lawyerUser.getLogoutFlag() == 1 && lawyerUser.getDeleteFlag() != null && lawyerUser.getDeleteFlag() == 1) {
-            log.warn("注销律师用户失败:律师已注销,律师ID={}, 律师姓名={}", id, lawyerUser.getName());
-            return R.fail("该律师账号已注销,无需重复注销");
-        }
-
-        if (lawyerUser.getLogoutFlag() != null && lawyerUser.getLogoutFlag() == LOGOUT_FLAG_COOLING) {
-            log.warn("注销律师用户失败:律师已在注销冷静期中,律师ID={}", id);
-            return R.fail("账号已在注销冷静期中");
+            throw new IllegalArgumentException("律师不存在");
         }
-
-        // 检查是否已删除
         if (lawyerUser.getDeleteFlag() != null && lawyerUser.getDeleteFlag() == 1) {
-            log.warn("注销律师用户失败:律师已删除,律师ID={}, 律师姓名={}", id, lawyerUser.getName());
-            return R.fail("该律师账号已删除");
-        }
-
-        List<LawyerConsultationOrder> list = lawyerConsultationOrderMapper.selectOrder(null, id);
-
-
-        if (!CollectionUtils.isEmpty(list)) {
-            // 提示前端有未完成订单 1:有未完成订单  0:无未完成订单
-            resultMap.put("unfinishedOrder", 1);
-        }
-
-        if (lawyerUser.getOrderReceivingStatus() != null && lawyerUser.getOrderReceivingStatus() == 1) {
-            // 提示前端接单状态为接单中 1:接单中  0:未接单
-            resultMap.put("orderReceivingStatus", 1);
-        }
-
-        if (lawyerUser.getOrderReceivingStatus() != null) {
-
-            if (CollectionUtils.isEmpty(list) && lawyerUser.getOrderReceivingStatus() == 0) {
-                // 进入注销冷静期(7天内可撤销)
-                lawyerUser.setLogoutFlag(LOGOUT_FLAG_COOLING);
-                lawyerUser.setLogoutTime(new Date());
-                lawyerUser.setLogoutReason(logoutReason);
-                lawyerUser.setLogoutCode(LOGOUT_REASON_OTHER.equals(logoutReason) ? logoutContent : null);
-                lawyerUser.setOrderReceivingStatus(0);
-                lawyerUser.setIsOnline(0);
-
-                int result = lawyerUserMapper.updateLawyerUser(lawyerUser);
-                if (result == 0) {
-                    log.error("注销律师用户失败:更新数据库失败,律师ID={}", id);
-                    return R.fail("注销失败,请稍后重试");
-                }
-
-                log.info("律师注销申请已提交,律师ID={}, 律师姓名={}, 注销时间={}",
-                        id, lawyerUser.getName(), lawyerUser.getLogoutTime());
-
-                resultMap.put("id", lawyerUser.getId());
-                resultMap.put("name", lawyerUser.getName());
-                resultMap.put("phone", lawyerUser.getPhone());
-                resultMap.put("logoutFlag", lawyerUser.getLogoutFlag());
-                resultMap.put("logoutTime", lawyerUser.getLogoutTime());
-                resultMap.put("message", "律师账号注销申请已提交");
-            }
+            throw new IllegalArgumentException("该律师账号已删除");
+        }
+        if (isLawyerLogoutCooling(lawyerUser) || isLawyerLoggedOut(lawyerUser)) {
+            throw new IllegalArgumentException("账号已在注销流程中");
+        }
+
+        lawyerUser.setLogoutReason(logoutReason);
+        lawyerUser.setLogoutCode(LOGOUT_REASON_OTHER.equals(logoutReason) ? logoutContent : null);
+        lawyerUser.setLogoutFlag(LawyerUser.LOGOUT_FLAG_COOLING);
+        lawyerUser.setLogoutTime(new Date());
+        lawyerUser.setOrderReceivingStatus(0);
+        lawyerUser.setIsOnline(0);
+
+        int num = lawyerUserMapper.updateById(lawyerUser);
+        if (num <= 0) {
+            throw new IllegalArgumentException("注销失败,请稍后重试");
+        }
+
+        LifeNotice lifeNotice = new LifeNotice();
+        lifeNotice.setReceiverId("lawyer_" + lawyerUser.getPhone());
+        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        String logoutDate = simpleDateFormat.format(new Date());
+        String text = "您在" + logoutDate + "注销了账号,平台将为您保留7天,在此期间您可撤销注销账号,7天后账号将变为已注销状态。";
+        com.alibaba.fastjson2.JSONObject jsonObject = new com.alibaba.fastjson2.JSONObject();
+        jsonObject.put("message", text);
+        lifeNotice.setContext(jsonObject.toJSONString());
+        lifeNotice.setTitle("注销律师账号通知");
+        lifeNotice.setSenderId("system");
+        lifeNotice.setIsRead(0);
+        lifeNotice.setNoticeType(1);
+        lifeNoticeUtil.fillUserTypeAndRefId(lifeNotice);
+        lifeNoticeMapper.insert(lifeNotice);
+
+        WebSocketVo websocketVo = new WebSocketVo();
+        websocketVo.setSenderId("system");
+        websocketVo.setReceiverId("lawyer_" + lawyerUser.getPhone());
+        websocketVo.setCategory("notice");
+        websocketVo.setNoticeType("1");
+        websocketVo.setIsRead(0);
+        websocketVo.setText(com.alibaba.fastjson2.JSONObject.from(lifeNotice).toJSONString());
+        try {
+            webSocketProcess.sendMessage("lawyer_" + lawyerUser.getPhone(),
+                    com.alibaba.fastjson2.JSONObject.from(websocketVo).toJSONString());
+        } catch (Exception e) {
+            log.error("律师注销通知 WebSocket 发送失败: {}", e.getMessage());
         }
-
-        return R.data(resultMap);
+        log.info("律师注销申请已提交,律师ID={}, phone={}", id, lawyerUser.getPhone());
     }
 
     @Override
@@ -611,33 +615,104 @@ public class LawyerUserServiceImpl extends ServiceImpl<LawyerUserMapper, LawyerU
         if (lawyerUser == null) {
             throw new IllegalArgumentException("律师不存在");
         }
-        boolean logoutFlagCooling = lawyerUser.getLogoutFlag() != null
-                && lawyerUser.getLogoutFlag() == LOGOUT_FLAG_COOLING;
-        if (!logoutFlagCooling && !isLawyerInLogoutCoolingPeriod(lawyerUser)) {
+        if (!isLawyerLogoutCooling(lawyerUser)) {
             throw new IllegalArgumentException(CANCEL_REVOKE_NOT_IN_COOLING_MSG);
         }
 
-        LambdaUpdateWrapper<LawyerUser> updateWrapper = new LambdaUpdateWrapper<>();
-        updateWrapper.eq(LawyerUser::getId, id)
-                .set(LawyerUser::getLogoutFlag, 0)
-                .set(LawyerUser::getLogoutTime, null)
-                .set(LawyerUser::getLogoutReason, null)
-                .set(LawyerUser::getLogoutCode, null);
-        int updated = lawyerUserMapper.update(null, updateWrapper);
+        lawyerUser.setLogoutFlag(LawyerUser.LOGOUT_FLAG_NORMAL);
+        lawyerUser.setLogoutTime(null);
+        lawyerUser.setLogoutReason(null);
+        lawyerUser.setLogoutCode(null);
+        int updated = lawyerUserMapper.updateById(lawyerUser);
         if (updated == 0) {
             throw new IllegalArgumentException("撤销注销失败,请稍后重试");
         }
+
+        LifeNotice lifeNotice = new LifeNotice();
+        lifeNotice.setReceiverId("lawyer_" + lawyerUser.getPhone());
+        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        String revokeDate = simpleDateFormat.format(new Date());
+        String text = "您在" + revokeDate + "撤销了注销账号,所有数据均已保留,您可继续在平台使用。";
+        com.alibaba.fastjson2.JSONObject jsonObject = new com.alibaba.fastjson2.JSONObject();
+        jsonObject.put("message", text);
+        lifeNotice.setContext(jsonObject.toJSONString());
+        lifeNotice.setTitle("撤销律师账号注销通知");
+        lifeNotice.setSenderId("system");
+        lifeNotice.setIsRead(0);
+        lifeNotice.setNoticeType(1);
+        lifeNoticeUtil.fillUserTypeAndRefId(lifeNotice);
+        lifeNoticeMapper.insert(lifeNotice);
+
+        WebSocketVo websocketVo = new WebSocketVo();
+        websocketVo.setSenderId("system");
+        websocketVo.setReceiverId("lawyer_" + lawyerUser.getPhone());
+        websocketVo.setCategory("notice");
+        websocketVo.setNoticeType("1");
+        websocketVo.setIsRead(0);
+        websocketVo.setText(com.alibaba.fastjson2.JSONObject.from(lifeNotice).toJSONString());
+        try {
+            webSocketProcess.sendMessage("lawyer_" + lawyerUser.getPhone(),
+                    com.alibaba.fastjson2.JSONObject.from(websocketVo).toJSONString());
+        } catch (Exception e) {
+            log.error("律师撤销注销通知 WebSocket 发送失败: {}", e.getMessage());
+        }
         log.info("律师撤销注销成功,律师ID={}", id);
     }
 
-    private static boolean isLawyerInLogoutCoolingPeriod(LawyerUser lawyerUser) {
-        if (lawyerUser == null || lawyerUser.getLogoutTime() == null) {
+    @Override
+    public R<LawyerUser> checkLogin(String phone) {
+        LambdaQueryWrapper<LawyerUser> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(LawyerUser::getPhone, phone)
+                .eq(LawyerUser::getDeleteFlag, 0)
+                .orderByDesc(LawyerUser::getCreatedTime)
+                .last("LIMIT 1");
+        LawyerUser lawyerUser = lawyerUserMapper.selectOne(queryWrapper);
+        if (lawyerUser == null) {
+            return R.success("用户不存在,快去注册吧!");
+        }
+        if (lawyerUser.getStatus() != null && lawyerUser.getStatus() == 0) {
+            return R.success("账号已被禁用");
+        }
+        if (isLawyerLoggedOut(lawyerUser)) {
+            return R.data(lawyerUser, "账号已注销");
+        }
+        if (isLawyerLogoutCooling(lawyerUser)) {
+            return R.data(lawyerUser, "账号注销冷静期中");
+        }
+        return R.data(lawyerUser, "success");
+    }
+
+    /** 是否处于注销冷静期(含旧数据:logout_flag=1 且未逻辑删除、仍在 7 天内) */
+    private static boolean isLawyerLogoutCooling(LawyerUser user) {
+        if (user == null) {
+            return false;
+        }
+        if (LawyerUser.LOGOUT_FLAG_COOLING == user.getLogoutFlag()) {
+            return true;
+        }
+        if (LawyerUser.LOGOUT_FLAG_DONE == user.getLogoutFlag()
+                && (user.getDeleteFlag() == null || user.getDeleteFlag() == 0)
+                && user.getLogoutTime() != null) {
+            Calendar calendar = Calendar.getInstance();
+            calendar.setTime(user.getLogoutTime());
+            calendar.add(Calendar.DAY_OF_YEAR, LOGOUT_COOLING_DAYS);
+            return !new Date().after(calendar.getTime());
+        }
+        return false;
+    }
+
+    /** 是否已注销(logout_flag=1 且已过冷静期,或旧数据已逻辑删除) */
+    private static boolean isLawyerLoggedOut(LawyerUser user) {
+        if (user == null) {
+            return false;
+        }
+        if (user.getDeleteFlag() != null && user.getDeleteFlag() == 1) {
+            return true;
+        }
+        if (LawyerUser.LOGOUT_FLAG_DONE != user.getLogoutFlag()) {
             return false;
         }
-        Calendar calendar = Calendar.getInstance();
-        calendar.setTime(lawyerUser.getLogoutTime());
-        calendar.add(Calendar.DAY_OF_YEAR, LOGOUT_COOLING_DAYS);
-        return !new Date().after(calendar.getTime());
+        return !isLawyerLogoutCooling(user);
     }
 
     @Override

+ 20 - 2
alien-store/src/main/java/shop/alien/store/util/ali/AliSms.java

@@ -89,7 +89,7 @@ public class AliSms {
             userForgetPasswordSmsDailyLimiter.checkLimit(phone);
         }
         try {
-            String appTypeStr = appType == 0 ? "user" : (appType == 1 ? "store" : "store_platform");
+            String appTypeStr = resolveAppTypeStr(appType);
             String businessTypeStr;
             switch (businessType) {
                 case 0:
@@ -187,7 +187,7 @@ public class AliSms {
         log.info("AliSms.checkSmsCode?phone={}&appType={}&businessType={}&code={}", phone, appType, businessType, code);
         try {
             // 构建Redis key,与sendSms方法中的key格式保持一致
-            String appTypeStr = appType == 0 ? "user" : (appType == 1 ? "store" : "store_platform");
+            String appTypeStr = resolveAppTypeStr(appType);
             String businessTypeStr;
             switch (businessType) {
                 case 0:
@@ -638,4 +638,22 @@ public class AliSms {
         }
     }
 
+    private String resolveAppTypeStr(Integer appType) {
+        if (appType == null) {
+            return "store_platform";
+        }
+        switch (appType) {
+            case 0:
+                return "user";
+            case 1:
+                return "store";
+            case 2:
+                return "store_platform";
+            case 3:
+                return "lawyer";
+            default:
+                return "store_platform";
+        }
+    }
+
 }