zhangchen пре 3 недеља
родитељ
комит
8d60c838c0

+ 9 - 0
alien-lawyer/src/main/java/shop/alien/lawyer/controller/LawyerUserViolationController.java

@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import io.swagger.annotations.*;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.web.bind.annotation.*;
 import shop.alien.entity.result.R;
 import shop.alien.entity.store.LawyerUserViolation;
@@ -79,6 +80,14 @@ public class LawyerUserViolationController {
                         lawyerUserViolation.getReportingUserId());
                 return R.fail("举报失败");
             }
+        } catch (RuntimeException e) {
+            // 业务异常,返回具体的错误信息
+            String errorMessage = e.getMessage();
+            log.warn("用户举报业务异常,被举报用户ID:{},举报用户ID:{},异常信息:{}",
+                    lawyerUserViolation.getReportedUserId(),
+                    lawyerUserViolation.getReportingUserId(),
+                    errorMessage);
+            return R.fail(StringUtils.isNotEmpty(errorMessage) ? errorMessage : "举报失败");
         } catch (Exception e) {
             log.error("用户举报异常,被举报用户ID:{},举报用户ID:{},异常信息:{}",
                     lawyerUserViolation.getReportedUserId(),

+ 232 - 121
alien-lawyer/src/main/java/shop/alien/lawyer/service/impl/LawyerUserViolationServiceImpl.java

@@ -75,6 +75,16 @@ public class LawyerUserViolationServiceImpl extends ServiceImpl<LawyerUserViolat
      */
     private static final String DEFAULT_NOTICE_MESSAGE = "平台已受理,感谢您的反馈!";
 
+    /**
+     * 处理状态:通过
+     */
+    private static final String PROCESSING_STATUS_APPROVED = "1";
+
+    /**
+     * 举报内容类型:订单举报
+     */
+    private static final String REPORT_CONTEXT_TYPE_ORDER = "6";
+
     private final LawyerUserViolationMapper lawyerUserViolationMapper;
 
     private final LawyerUserMapper lawyerUserMapper;
@@ -95,9 +105,10 @@ public class LawyerUserViolationServiceImpl extends ServiceImpl<LawyerUserViolat
      * 用户举报处理
      * <p>
      * 处理用户举报信息,包括:
-     * 1. 保存举报记录到数据库
-     * 2. 向举报人发送受理通知
-     * 3. 根据举报内容类型,向被举报人发送通知(如需要)
+     * 1. 检查订单是否已被举报(一笔订单只能举报一次)
+     * 2. 保存举报记录到数据库
+     * 3. 向举报人发送受理通知
+     * 4. 根据举报内容类型,向被举报人发送通知(如需要)
      * </p>
      *
      * @param lawyerUserViolation 举报信息对象,不能为null
@@ -116,9 +127,20 @@ public class LawyerUserViolationServiceImpl extends ServiceImpl<LawyerUserViolat
 
         String reportedUserId = lawyerUserViolation.getReportedUserId();
         String reportingUserId = lawyerUserViolation.getReportingUserId();
-        log.info("开始处理用户举报,被举报用户ID:{},举报用户ID:{}", reportedUserId, reportingUserId);
+        String orderId = lawyerUserViolation.getOrderId();
+        log.info("开始处理用户举报,被举报用户ID:{},举报用户ID:{},订单ID:{}", 
+                reportedUserId, reportingUserId, orderId);
 
         try {
+            // 检查订单是否已被举报(一笔订单只能举报一次)
+            if (StringUtils.isNotEmpty(orderId)) {
+                boolean hasReported = checkOrderAlreadyReported(orderId);
+                if (hasReported) {
+                    log.warn("订单已被举报,订单ID:{}", orderId);
+                    throw new RuntimeException("该订单已被举报,无法重复举报");
+                }
+            }
+
             // 保存举报记录
             int result = lawyerUserViolationMapper.insert(lawyerUserViolation);
             if (result <= 0) {
@@ -131,15 +153,17 @@ public class LawyerUserViolationServiceImpl extends ServiceImpl<LawyerUserViolat
             // 向举报人发送受理通知
             sendReportNoticeToReporter(lawyerUserViolation);
 
-            // 根据举报内容类型,向被举报人发送通知(暂时注释)
-            // String reportContextType = lawyerUserViolation.getReportContextType();
-            // if (StringUtils.isNotEmpty(reportContextType) && reportContextType.contains("6")) {
-            //     sendReportNoticeToReported(lawyerUserViolation);
-            // }
+//             String reportContextType = lawyerUserViolation.getReportContextType();
+//             if (StringUtils.isNotEmpty(reportContextType) && reportContextType.contains("6")) {
+//                 sendReportNoticeToReported(lawyerUserViolation);
+//             }
 
             log.info("用户举报处理完成,举报ID:{}", lawyerUserViolation.getId());
             return result;
 
+        } catch (RuntimeException e) {
+            // 重新抛出业务异常,保持原有异常信息
+            throw e;
         } catch (Exception e) {
             log.error("用户举报处理异常,被举报用户ID:{},举报用户ID:{},异常信息:{}",
                     reportedUserId, reportingUserId, e.getMessage(), e);
@@ -148,6 +172,35 @@ public class LawyerUserViolationServiceImpl extends ServiceImpl<LawyerUserViolat
     }
 
     /**
+     * 检查订单是否已被举报
+     * <p>
+     * 根据订单ID查询是否已存在举报记录(一笔订单只能举报一次)
+     * </p>
+     *
+     * @param orderId 订单ID
+     * @return true-已举报,false-未举报
+     */
+    private boolean checkOrderAlreadyReported(String orderId) {
+        if (StringUtils.isEmpty(orderId)) {
+            return false;
+        }
+
+        try {
+            LambdaQueryWrapper<LawyerUserViolation> queryWrapper = new LambdaQueryWrapper<>();
+            queryWrapper.eq(LawyerUserViolation::getOrderId, orderId)
+                    .last("LIMIT 1");
+
+            LawyerUserViolation existingReport = lawyerUserViolationMapper.selectOne(queryWrapper);
+            return existingReport != null;
+        } catch (Exception e) {
+            log.error("检查订单举报状态异常,订单ID:{},异常信息:{}",
+                    orderId, e.getMessage(), e);
+            // 查询异常时,为了安全起见,返回true,阻止重复举报
+            return true;
+        }
+    }
+
+    /**
      * 向举报人发送受理通知
      *
      * @param lawyerUserViolation 举报信息对象
@@ -244,7 +297,7 @@ public class LawyerUserViolationServiceImpl extends ServiceImpl<LawyerUserViolat
             LifeNotice lifeNotice = new LifeNotice();
             lifeNotice.setSenderId(SYSTEM_SENDER_ID);
             lifeNotice.setBusinessId(lawyerUserViolation.getId());
-            lifeNotice.setTitle("举报通知");
+            lifeNotice.setTitle("咨询订单举报通知");
 
             // 获取举报人接收ID
             String receiverId = getReporterReceiverId(lawyerUserViolation);
@@ -432,7 +485,7 @@ public class LawyerUserViolationServiceImpl extends ServiceImpl<LawyerUserViolat
             LifeNotice lifeNotice = new LifeNotice();
             lifeNotice.setSenderId(SYSTEM_SENDER_ID);
             lifeNotice.setBusinessId(lawyerUserViolation.getId());
-            lifeNotice.setTitle("举报通知");
+            lifeNotice.setTitle("咨询订单举报通知");
             lifeNotice.setReceiverId(receiverId);
 
             // 构建消息内容
@@ -622,28 +675,17 @@ public class LawyerUserViolationServiceImpl extends ServiceImpl<LawyerUserViolat
     }
 
     /**
-     * 处理状态:通过
-     */
-    private static final String PROCESSING_STATUS_APPROVED = "1";
-
-    /**
-     * 举报内容类型:服务态度差
-     */
-    private static final String REPORT_CONTEXT_TYPE_SERVICE_ATTITUDE = "6";
-
-    /**
-     * 审批举报记录
+     * 审批举报
      * <p>
-     * 处理举报记录的审批,包括:
-     * 1. 更新举报记录的处理状态、处理时间和处理结果
-     * 2. 根据处理结果构建通知消息
-     * 3. 向举报人发送审批结果通知
+     * 处理举报审批,包括:
+     * 1. 更新举报处理状态
+     * 2. 向举报人发送审批结果通知
+     * 3. 向被举报人发送通知(如需要)
      * </p>
      *
-     * @param id               举报记录ID,必须大于0
-     * @param processingStatus 处理状态,"1"表示通过,其他表示驳回
-     * @param reportResult     处理结果说明,驳回时必填
-     * @throws RuntimeException 当举报记录不存在或处理失败时抛出
+     * @param id               举报记录ID
+     * @param processingStatus 处理状态(1-通过,其他-驳回)
+     * @param reportResult     处理结果说明
      * @author system
      * @since 2025-01-XX
      */
@@ -651,12 +693,10 @@ public class LawyerUserViolationServiceImpl extends ServiceImpl<LawyerUserViolat
     public void approve(int id, String processingStatus, String reportResult) {
         // 参数校验
         if (id <= 0 || StringUtils.isBlank(processingStatus)) {
-            log.warn("审批举报记录参数无效,ID:{},处理状态:{}", id, processingStatus);
+            log.warn("审批举报参数无效,ID:{},处理状态:{}", id, processingStatus);
             return;
         }
 
-        log.info("开始审批举报记录,ID:{},处理状态:{}", id, processingStatus);
-
         try {
             // 查询举报记录
             LawyerUserViolation violation = lawyerUserViolationMapper.selectById(id);
@@ -665,159 +705,221 @@ public class LawyerUserViolationServiceImpl extends ServiceImpl<LawyerUserViolat
                 return;
             }
 
-            // 更新举报记录
-            violation.setProcessingStatus(processingStatus);
-            violation.setProcessingTime(new Date());
-            violation.setReportResult(reportResult);
-            int updateResult = lawyerUserViolationMapper.updateById(violation);
-            if (updateResult <= 0) {
-                log.warn("更新举报记录失败,ID:{}", id);
-                return;
-            }
-
-            log.info("举报记录更新成功,ID:{}", id);
+            // 更新举报记录状态
+            updateViolationStatus(violation, processingStatus, reportResult);
 
-            // 构建并发送通知
-            sendApprovalNotice(violation, processingStatus, reportResult);
+            // 构建并发送通知消息
+            sendApprovalNotifications(violation, processingStatus, reportResult);
 
-            log.info("审批举报记录完成,ID:{}", id);
+            log.info("审批举报处理完成,举报ID:{},处理状态:{}", id, processingStatus);
 
         } catch (Exception e) {
-            log.error("审批举报记录异常,ID:{},异常信息:{}", id, e.getMessage(), e);
-            throw new RuntimeException("审批举报记录失败:" + e.getMessage(), e);
+            log.error("审批举报处理异常,举报ID:{},异常信息:{}", id, e.getMessage(), e);
+            throw new RuntimeException("审批举报处理失败:" + e.getMessage(), e);
         }
     }
 
     /**
-     * 发送审批结果通知
+     * 更新举报记录状态
      *
-     * @param violation        举报记录对象
+     * @param violation        举报记录
      * @param processingStatus 处理状态
-     * @param reportResult     处理结果说明
+     * @param reportResult     处理结果
      */
-    private void sendApprovalNotice(LawyerUserViolation violation, String processingStatus, String reportResult) {
-        try {
-            // 构建通知消息
-            ApprovalNoticeContent noticeContent = buildApprovalNoticeContent(violation, processingStatus, reportResult);
-            if (noticeContent == null || StringUtils.isBlank(noticeContent.getMessage())) {
-                log.warn("构建审批通知消息失败,举报ID:{}", violation.getId());
-                return;
+    private void updateViolationStatus(LawyerUserViolation violation, String processingStatus,
+                                       String reportResult) {
+        violation.setProcessingStatus(processingStatus);
+        violation.setProcessingTime(new Date());
+        violation.setReportResult(reportResult);
+        lawyerUserViolationMapper.updateById(violation);
+    }
+
+    /**
+     * 发送审批通知消息
+     *
+     * @param violation        举报记录
+     * @param processingStatus 处理状态
+     * @param reportResult     处理结果
+     */
+    private void sendApprovalNotifications(LawyerUserViolation violation, String processingStatus,
+                                           String reportResult) {
+        // 构建举报人通知消息
+        NotificationInfo reporterNotification = buildReporterNotification(violation, processingStatus,
+                reportResult);
+        if (reporterNotification != null && StringUtils.isNotEmpty(reporterNotification.getMessage())) {
+            sendNotificationToReporter(violation, reporterNotification);
+        }
+
+        // 构建被举报人通知消息(仅通过且为订单举报时)
+        if (PROCESSING_STATUS_APPROVED.equals(processingStatus)
+                && REPORT_CONTEXT_TYPE_ORDER.equals(violation.getReportContextType())) {
+            NotificationInfo reportedNotification = buildReportedNotification(violation);
+            if (reportedNotification != null && StringUtils.isNotEmpty(reportedNotification.getMessage())) {
+                sendNotificationToReported(violation, reportedNotification);
+            }
+        }
+    }
+
+    /**
+     * 构建举报人通知信息
+     *
+     * @param violation        举报记录
+     * @param processingStatus 处理状态
+     * @param reportResult     处理结果
+     * @return 通知信息
+     */
+    private NotificationInfo buildReporterNotification(LawyerUserViolation violation,
+                                                        String processingStatus, String reportResult) {
+        NotificationInfo notificationInfo = new NotificationInfo();
+        String reportContextType = violation.getReportContextType();
+
+        if (PROCESSING_STATUS_APPROVED.equals(processingStatus)) {
+            // 审批通过
+            if (REPORT_CONTEXT_TYPE_ORDER.equals(reportContextType)) {
+                notificationInfo.setMessage("您举报律师服务态度差,经核实,确实存在此行为,"
+                        + "订单金额将在1-3个工作日原路返还,请注意查收。");
+                notificationInfo.setTitle("订单举报成功通知");
+            }
+        } else {
+            // 审批驳回
+            if (REPORT_CONTEXT_TYPE_ORDER.equals(reportContextType)) {
+                String message = "您举报律师服务态度差,经核实,不存在此行为,订单金额不予退还。";
+                if (StringUtils.isNotEmpty(reportResult)) {
+                    message += "拒绝原因:" + reportResult;
+                }
+                notificationInfo.setMessage(message);
+                notificationInfo.setTitle("用户举报失败通知");
             }
+        }
+
+        return notificationInfo;
+    }
+
+    /**
+     * 构建被举报人通知信息
+     *
+     * @param violation 举报记录
+     * @return 通知信息
+     */
+    private NotificationInfo buildReportedNotification(LawyerUserViolation violation) {
+        NotificationInfo notificationInfo = new NotificationInfo();
+        String orderId = violation.getOrderId();
+        String message = String.format("用户对编号为%s的订单进行申诉,经核实,用户举报属实,"
+                + "订单金额将会退还给用户。触发条件:平台审核点击同意按钮时触发", orderId);
+        notificationInfo.setMessage(message);
+        notificationInfo.setTitle("订单举报成功通知");
+        return notificationInfo;
+    }
 
+    /**
+     * 向举报人发送通知
+     *
+     * @param violation         举报记录
+     * @param notificationInfo 通知信息
+     */
+    private void sendNotificationToReporter(LawyerUserViolation violation,
+                                             NotificationInfo notificationInfo) {
+        try {
             // 获取举报人接收ID
             String receiverId = getReporterReceiverId(violation);
-            if (StringUtils.isBlank(receiverId)) {
+            if (StringUtils.isEmpty(receiverId)) {
                 log.warn("获取举报人接收ID失败,举报ID:{}", violation.getId());
                 return;
             }
 
-            // 创建通知记录
-            LifeNotice lifeNotice = createApprovalLifeNotice(violation.getId(), receiverId, noticeContent);
-            int noticeResult = lifeNoticeMapper.insert(lifeNotice);
-            if (noticeResult <= 0) {
-                log.warn("保存审批通知失败,举报ID:{}", violation.getId());
-                return;
-            }
-
-            log.info("审批通知保存成功,接收人ID:{}", receiverId);
+            // 创建并保存通知
+            LifeNotice lifeNotice = createLifeNotice(violation.getId(), receiverId,
+                    notificationInfo.getTitle(), notificationInfo.getMessage());
+            lifeNoticeMapper.insert(lifeNotice);
 
             // 发送WebSocket消息
-            sendApprovalWebSocketMessage(lifeNotice, receiverId);
+            sendWebSocketMessage(receiverId, lifeNotice);
 
-            log.info("审批通知发送成功,接收人ID:{}", receiverId);
+            log.info("举报人通知发送成功,接收人ID:{}", receiverId);
 
         } catch (Exception e) {
-            log.error("发送审批结果通知异常,举报ID:{},异常信息:{}",
-                    violation.getId(), e.getMessage(), e);
+            log.error("向举报人发送通知异常,举报ID:{},异常信息:{}", violation.getId(), e.getMessage(), e);
         }
     }
 
     /**
-     * 构建审批通知消息内容
+     * 向被举报人发送通知
      *
-     * @param violation        举报记录对象
-     * @param processingStatus 处理状态
-     * @param reportResult     处理结果说明
-     * @return 通知内容对象,如果无法构建返回null
+     * @param violation         举报记录
+     * @param notificationInfo 通知信息
      */
-    private ApprovalNoticeContent buildApprovalNoticeContent(LawyerUserViolation violation,
-                                                             String processingStatus,
-                                                             String reportResult) {
-        String reportContextType = violation.getReportContextType();
-        if (!REPORT_CONTEXT_TYPE_SERVICE_ATTITUDE.equals(reportContextType)) {
-            log.debug("当前举报内容类型无需发送通知,举报ID:{},类型:{}", violation.getId(), reportContextType);
-            return null;
-        }
+    private void sendNotificationToReported(LawyerUserViolation violation,
+                                            NotificationInfo notificationInfo) {
+        try {
+            // 获取被举报人接收ID
+            String receiverId = getReportedReceiverId(violation);
+            if (StringUtils.isEmpty(receiverId)) {
+                log.warn("获取被举报人接收ID失败,举报ID:{}", violation.getId());
+                return;
+            }
 
-        ApprovalNoticeContent content = new ApprovalNoticeContent();
-        if (PROCESSING_STATUS_APPROVED.equals(processingStatus)) {
-            // 审批通过
-            content.setMessage("您举报律师服务态度差,经核实,确实存在此行为,订单金额将在1-3个工作日原路返还,请注意查收。");
-            content.setTitle("用户举报成功通知");
-        } else {
-            // 审批驳回
-            String rejectReason = StringUtils.isNotBlank(reportResult) ? reportResult : "无";
-            content.setMessage("您举报律师服务态度差,经核实,不存在此行为,订单金额不予退还。拒绝原因:" + rejectReason);
-            content.setTitle("用户举报失败通知");
-        }
+            // 创建并保存通知
+            LifeNotice lifeNotice = createLifeNotice(violation.getId(), receiverId,
+                    notificationInfo.getTitle(), notificationInfo.getMessage());
+            lifeNoticeMapper.insert(lifeNotice);
 
-        return content;
+            // 发送WebSocket消息
+            sendWebSocketMessage(receiverId, lifeNotice);
+
+            log.info("被举报人通知发送成功,接收人ID:{}", receiverId);
+
+        } catch (Exception e) {
+            log.error("向被举报人发送通知异常,举报ID:{},异常信息:{}", violation.getId(), e.getMessage(), e);
+        }
     }
 
     /**
-     * 创建审批通知对象
+     * 创建通知对象
      *
-     * @param businessId  业务ID(举报记录ID)
-     * @param receiverId  接收人ID
-     * @param noticeContent 通知内容
+     * @param businessId 业务ID(举报ID)
+     * @param receiverId 接收人ID
+     * @param title      通知标题
+     * @param message    通知消息
      * @return 通知对象
      */
-    private LifeNotice createApprovalLifeNotice(Integer businessId, String receiverId,
-                                                 ApprovalNoticeContent noticeContent) {
+    private LifeNotice createLifeNotice(Integer businessId, String receiverId, String title,
+                                        String message) {
         LifeNotice lifeNotice = new LifeNotice();
         lifeNotice.setSenderId(SYSTEM_SENDER_ID);
         lifeNotice.setBusinessId(businessId);
-        lifeNotice.setTitle(noticeContent.getTitle());
         lifeNotice.setReceiverId(receiverId);
+        lifeNotice.setTitle(title);
         lifeNotice.setNoticeType(1);
         lifeNotice.setIsRead(0);
 
         JSONObject jsonObject = new JSONObject();
-        jsonObject.put("message", noticeContent.getMessage());
+        jsonObject.put("message", message);
         lifeNotice.setContext(jsonObject.toJSONString());
 
         return lifeNotice;
     }
 
     /**
-     * 发送审批结果WebSocket消息
+     * 发送WebSocket消息
      *
-     * @param lifeNotice 通知对象
      * @param receiverId 接收人ID
+     * @param lifeNotice 通知对象
      */
-    private void sendApprovalWebSocketMessage(LifeNotice lifeNotice, String receiverId) {
+    private void sendWebSocketMessage(String receiverId, LifeNotice lifeNotice) {
         try {
             WebSocketVo webSocketVo = buildWebSocketVo(lifeNotice);
             webSocketProcess.sendMessage(receiverId, JSONObject.from(webSocketVo).toJSONString());
         } catch (Exception e) {
-            log.error("发送审批结果WebSocket消息异常,接收人ID:{},异常信息:{}", receiverId, e.getMessage(), e);
+            log.error("发送WebSocket消息异常,接收人ID:{},异常信息:{}", receiverId, e.getMessage(), e);
         }
     }
 
     /**
-     * 审批通知内容内部类
+     * 通知信息内部类
      */
-    private static class ApprovalNoticeContent {
-        private String message;
+    private static class NotificationInfo {
         private String title;
-
-        public String getMessage() {
-            return message;
-        }
-
-        public void setMessage(String message) {
-            this.message = message;
-        }
+        private String message;
 
         public String getTitle() {
             return title;
@@ -826,8 +928,17 @@ public class LawyerUserViolationServiceImpl extends ServiceImpl<LawyerUserViolat
         public void setTitle(String title) {
             this.title = title;
         }
+
+        public String getMessage() {
+            return message;
+        }
+
+        public void setMessage(String message) {
+            this.message = message;
+        }
     }
 
+
     @Override
     public LawyerUserViolationDto byId(Integer id) {
         LawyerUserViolation entity = lawyerUserViolationMapper.selectById(id);