Ver código fonte

添加通知

lutong 3 meses atrás
pai
commit
fa42da8287

+ 142 - 4
alien-store/src/main/java/shop/alien/store/service/impl/StoreRenovationRequirementServiceImpl.java

@@ -1,5 +1,6 @@
 package shop.alien.store.service.impl;
 
+import com.alibaba.fastjson2.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -11,11 +12,17 @@ import org.springframework.beans.BeanUtils;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.StringUtils;
+import shop.alien.entity.store.LifeNotice;
 import shop.alien.entity.store.StoreInfo;
 import shop.alien.entity.store.StoreRenovationRequirement;
+import shop.alien.entity.store.StoreUser;
 import shop.alien.entity.store.dto.StoreRenovationRequirementDto;
+import shop.alien.entity.store.vo.WebSocketVo;
+import shop.alien.mapper.LifeNoticeMapper;
 import shop.alien.mapper.StoreInfoMapper;
 import shop.alien.mapper.StoreRenovationRequirementMapper;
+import shop.alien.mapper.StoreUserMapper;
+import shop.alien.store.config.WebSocketProcess;
 import shop.alien.store.service.StoreRenovationRequirementService;
 import shop.alien.store.util.ai.AiContentModerationUtil;
 import shop.alien.store.util.ai.AiVideoModerationUtil;
@@ -23,6 +30,7 @@ import shop.alien.util.common.JwtUtil;
 
 import javax.annotation.PostConstruct;
 import javax.annotation.PreDestroy;
+import java.text.SimpleDateFormat;
 import java.util.*;
 import java.util.concurrent.*;
 import java.util.stream.Collectors;
@@ -44,6 +52,13 @@ public class StoreRenovationRequirementServiceImpl extends ServiceImpl<StoreReno
 
     private final StoreInfoMapper storeInfoMapper;
 
+
+    private final LifeNoticeMapper lifeNoticeMapper;
+
+    private final WebSocketProcess webSocketProcess;
+
+    private final StoreUserMapper storeUserMapper;
+
     private final AiContentModerationUtil aiContentModerationUtil;
     private final AiVideoModerationUtil aiVideoModerationUtil;
     // 定义图片后缀常量(不可修改,保证线程安全)
@@ -150,17 +165,58 @@ public class StoreRenovationRequirementServiceImpl extends ServiceImpl<StoreReno
                 requirement.setUpdatedUserId(currentUserId);
                 requirement.setUpdatedTime(new Date());
             }
+            StoreUser storeUser = storeUserMapper.selectOne(new LambdaQueryWrapper<StoreUser>().eq(StoreUser::getStoreId, dto.getStoreId()).eq(StoreUser::getDeleteFlag, 0));
+
+            LifeNotice lifeMessage = new LifeNotice();
+            lifeMessage.setReceiverId("store_" + storeUser.getPhone());
+            String text = "您发布的装修动态已提交审核,请于1-3个工作日进行查看";
+            JSONObject jsonObject = new JSONObject();
+            jsonObject.put("message", text);
+            lifeMessage.setContext(jsonObject.toJSONString());
+            lifeMessage.setTitle("审核通知");
+            lifeMessage.setSenderId("system");
+            lifeMessage.setIsRead(0);
+            lifeMessage.setNoticeType(1);
+            lifeNoticeMapper.insert(lifeMessage);
+
+            WebSocketVo websocketVo = new WebSocketVo();
+            websocketVo.setSenderId("system");
+            websocketVo.setReceiverId("store_" + storeUser.getPhone());
+            websocketVo.setCategory("notice");
+            websocketVo.setNoticeType("1");
+            websocketVo.setIsRead(0);
+            websocketVo.setText(JSONObject.from(lifeMessage).toJSONString());
+            webSocketProcess.sendMessage("store_" + storeUser.getPhone(), JSONObject.from(websocketVo).toJSONString());
+
+
             // TODO 审核文本和图片内容是否违规
             // 一次遍历完成分类,避免多次流式处理
             Map<String, List<String>> urlCategoryMap = classifyUrls(dto.getAttachmentUrls());
+            List<String> videoUrls = urlCategoryMap.get("video");
             // 1.调用文本+图片审核接口 ai为同步接口
             AiContentModerationUtil.AuditResult auditResult = aiContentModerationUtil.auditContent(requirement.getDetailedRequirement(), urlCategoryMap.get("image"));
             if (!auditResult.isPassed()) {
                 requirement.setAuditStatus(2);
                 requirement.setAuditReason(auditResult.getFailureReason());
+                // 发送审核失败通知(文本图片)
+                if (storeUser != null && storeUser.getPhone() != null) {
+                    sendAuditNotification(storeUser.getPhone(), 2, auditResult.getFailureReason(), "text_image");
+                }
+
             } else {
-                // 异步调用视频审核接口,图片审核通过后调用(核心优化)
-                CompletableFuture.runAsync(() -> {
+                // 如果文本/图片审核通过,且没有视频需要审核,直接设置为审核通过
+                if (videoUrls == null || videoUrls.isEmpty()) {
+                    requirement.setAuditStatus(1);
+                    requirement.setAuditReason(null);
+                    // 发送审核通过通知(文本图片,无视频)
+                    if (storeUser != null && storeUser.getPhone() != null) {
+                        sendAuditNotification(storeUser.getPhone(), 1, null, "text_image");
+                    }
+                } else {
+                    // 异步调用视频审核接口,图片审核通过后调用(核心优化)
+                    // 保存storeUser信息供异步任务使用
+                    final StoreUser finalStoreUser = storeUser;
+                    CompletableFuture.runAsync(() -> {
                     AiVideoModerationUtil.VideoAuditResult videoAuditResult = null;
                     try {
                         // 调用审核接口,增加超时控制(避免接口挂死)
@@ -182,6 +238,11 @@ public class StoreRenovationRequirementServiceImpl extends ServiceImpl<StoreReno
                             this.saveOrUpdate(latestRequirement);
                             log.info("视频审核不通过,已更新状态,requirementID:{},原因:{}",
                                     requirement.getId(), videoAuditResult.getFailureReason());
+                            // 发送审核不通过通知(视频)
+                            if (finalStoreUser != null && finalStoreUser.getPhone() != null) {
+                                sendAuditNotification(finalStoreUser.getPhone(), 2, videoAuditResult.getFailureReason(), "video");
+                            }
+
                         } else if (Objects.nonNull(videoAuditResult) && videoAuditResult.isPassed()) {
                             // 审核通过也更新状态(可选,根据业务需求)
                             StoreRenovationRequirement latestRequirement = this.getById(requirement.getId());
@@ -189,6 +250,11 @@ public class StoreRenovationRequirementServiceImpl extends ServiceImpl<StoreReno
                                 latestRequirement.setAuditStatus(1);
                                 latestRequirement.setAuditReason(null);
                                 this.saveOrUpdate(latestRequirement);
+                                // 发送审核通过通知(视频)
+                                if (finalStoreUser != null && finalStoreUser.getPhone() != null) {
+                                    sendAuditNotification(finalStoreUser.getPhone(), 1, null, "video");
+                                }
+
                                 log.info("视频审核通过,已更新状态,requirementID:{}", requirement.getId());
                             }
                         }
@@ -196,12 +262,18 @@ public class StoreRenovationRequirementServiceImpl extends ServiceImpl<StoreReno
                         log.error("视频审核接口调用异常,requirementID:{}", requirement.getId(), e);
                         StoreRenovationRequirement latestRequirement = this.getById(requirement.getId());
                         if (Objects.nonNull(latestRequirement)) {
+                            String exceptionMessage = "视频审核接口调用异常:" + e.getMessage();
                             latestRequirement.setAuditStatus(2);
-                            latestRequirement.setAuditReason("视频审核接口调用异常:" + e.getMessage()); // 实际需捕获具体异常信息
+                            latestRequirement.setAuditReason(exceptionMessage);
                             this.saveOrUpdate(latestRequirement);
+                            // 发送审核异常通知(视频)
+                            if (finalStoreUser != null && finalStoreUser.getPhone() != null) {
+                                sendAuditNotification(finalStoreUser.getPhone(), 2, exceptionMessage, "video");
+                            }
                         }
                     }
-                }, videoAuditExecutor);
+                    }, videoAuditExecutor);
+                }
             }
             requirement.setAuditTime(new Date());
             boolean isSuccess  = this.saveOrUpdate(requirement);
@@ -266,6 +338,72 @@ public class StoreRenovationRequirementServiceImpl extends ServiceImpl<StoreReno
         return resultMap;
     }
 
+    /**
+     * 发送审核结果通知
+     * @param storePhone 商铺电话
+     * @param auditStatus 审核状态:1-通过,2-不通过
+     * @param auditReason 审核原因(不通过时提供)
+     * @param auditType 审核类型:text_image-文本图片审核,video-视频审核
+     */
+    private void sendAuditNotification(String storePhone, Integer auditStatus, String auditReason, String auditType) {
+        try {
+            if (storePhone == null || storePhone.trim().isEmpty()) {
+                log.warn("发送审核通知失败,商铺电话为空");
+                return;
+            }
+
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
+            String commonDate = sdf.format(new Date());
+
+            String title;
+            String message;
+            if (auditStatus == 1) {
+                // 审核通过
+                title = "审核通知";
+                if ("video".equals(auditType)) {
+                    message = "在" + commonDate + ",您发布的装修动态视频审核已通过。";
+                } else {
+                    message = "在" + commonDate + ",您发布的装修动态审核已通过。";
+                }
+            } else {
+                // 审核不通过
+                title = "审核通知";
+                String reasonText = auditReason != null && !auditReason.trim().isEmpty() 
+                    ? ",原因:" + auditReason 
+                    : "";
+                if ("video".equals(auditType)) {
+                    message = "在" + commonDate + ",您发布的装修动态视频审核未通过" + reasonText + ",请修改后重新提交。";
+                } else {
+                    message = "在" + commonDate + ",您发布的装修动态审核未通过" + reasonText + ",请修改后重新提交。";
+                }
+            }
+
+            LifeNotice lifeNotice = new LifeNotice();
+            lifeNotice.setReceiverId("store_" + storePhone);
+            JSONObject jsonObject = new JSONObject();
+            jsonObject.put("message", message);
+            lifeNotice.setContext(jsonObject.toJSONString());
+            lifeNotice.setTitle(title);
+            lifeNotice.setSenderId("system");
+            lifeNotice.setIsRead(0);
+            lifeNotice.setNoticeType(1);
+            lifeNoticeMapper.insert(lifeNotice);
+
+            WebSocketVo websocketVo = new WebSocketVo();
+            websocketVo.setSenderId("system");
+            websocketVo.setReceiverId("store_" + storePhone);
+            websocketVo.setCategory("notice");
+            websocketVo.setNoticeType("1");
+            websocketVo.setIsRead(0);
+            websocketVo.setText(JSONObject.from(lifeNotice).toJSONString());
+            webSocketProcess.sendMessage("store_" + storePhone, JSONObject.from(websocketVo).toJSONString());
+
+            log.info("审核通知发送成功,商铺电话:{},审核状态:{},审核类型:{}", storePhone, auditStatus, auditType);
+        } catch (Exception e) {
+            log.error("发送审核通知异常,商铺电话:{},审核状态:{},审核类型:{}", storePhone, auditStatus, auditType, e);
+        }
+    }
+
 
     @Override
     public StoreRenovationRequirementDto getRequirementDetail(Integer id) {