|
|
@@ -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
|