刘云鑫 пре 1 месец
родитељ
комит
ea4e79ab0d

+ 23 - 10
alien-second/src/main/java/shop/alien/second/service/impl/SecondGoodsReportingServiceImpl.java

@@ -197,16 +197,16 @@ public class SecondGoodsReportingServiceImpl implements SecondGoodsReportingServ
     @Override
     public int reporting(SecondUserViolationVo lifeuserViolation) throws Exception  {
         try {
-            if ("4".equals(lifeuserViolation.getReportContextType())) {
-                lifeuserViolation.setGoodsId(lifeuserViolation.getBusinessId());
-                LambdaQueryWrapper<SecondGoodsRecord> goodsWrapper = new LambdaQueryWrapper<>();
-                goodsWrapper.eq(SecondGoodsRecord::getGoodsId, lifeuserViolation.getBusinessId());
-                goodsWrapper.eq(SecondGoodsRecord::getGoodsStatus, "3");
-                goodsWrapper.orderByDesc(SecondGoodsRecord::getCreatedTime);
-                goodsWrapper.last(" limit 1 ");
-                SecondGoodsRecord goodsRecord = secondGoodsRecordMapper.selectOne(goodsWrapper);
-                if (null != goodsRecord) lifeuserViolation.setBusinessId(goodsRecord.getId());
-            }
+//            if ("4".equals(lifeuserViolation.getReportContextType())) {
+//                lifeuserViolation.setGoodsId(lifeuserViolation.getBusinessId());
+//                LambdaQueryWrapper<SecondGoodsRecord> goodsWrapper = new LambdaQueryWrapper<>();
+//                goodsWrapper.eq(SecondGoodsRecord::getGoodsId, lifeuserViolation.getBusinessId());
+//                goodsWrapper.eq(SecondGoodsRecord::getGoodsStatus, "3");
+//                goodsWrapper.orderByDesc(SecondGoodsRecord::getCreatedTime);
+//                goodsWrapper.last(" limit 1 ");
+//                SecondGoodsRecord goodsRecord = secondGoodsRecordMapper.selectOne(goodsWrapper);
+//                if (null != goodsRecord) lifeuserViolation.setBusinessId(goodsRecord.getId());
+//            }
             int result = lifeUserViolationMapper.insert(lifeuserViolation);
             if (result > 0) {
 
@@ -223,6 +223,19 @@ public class SecondGoodsReportingServiceImpl implements SecondGoodsReportingServ
                     lifeuserViolation.setAiTaskId(taskId);
                     lifeUserViolationMapper.updateById(lifeuserViolation);
                 }
+                if ("4".equals(lifeuserViolation.getReportContextType())) {
+                    // AI审核
+                    //登录获取token
+                    String token = aiUserViolationUtils.getAccessToken();
+                    //调用AI接口
+                    String taskId = aiUserViolationUtils.createGoodsTask(token, lifeuserViolation);
+                    if (org.springframework.util.StringUtils.isEmpty(taskId)) {
+                        log.warn("Failed to create AI task for second round review, lifeuserViolation id={}", lifeuserViolation.getId());
+                        return 0;
+                    }
+                    lifeuserViolation.setAiTaskId(taskId);
+                    lifeUserViolationMapper.updateById(lifeuserViolation);
+                }
 
                 if (lifeuserViolation.getReportContextType().equals("4") || lifeuserViolation.getReportContextType().equals("5")) {
                     String phoneId = Objects.requireNonNull(JwtUtil.getCurrentUserInfo()).getString("userType") + "_" + JwtUtil.getCurrentUserInfo().getString("phone");

+ 143 - 0
alien-second/src/main/java/shop/alien/second/util/AiUserViolationUtils.java

@@ -14,11 +14,14 @@ import org.springframework.util.MultiValueMap;
 import org.springframework.util.StringUtils;
 import org.springframework.web.client.RestTemplate;
 import shop.alien.entity.result.R;
+import shop.alien.entity.second.SecondGoods;
+import shop.alien.entity.second.vo.SecondUserViolationVo;
 import shop.alien.entity.store.LifeMessage;
 import shop.alien.entity.store.LifeUserViolation;
 import shop.alien.entity.store.vo.LifeUserVo;
 import shop.alien.mapper.LifeMessageMapper;
 import shop.alien.mapper.LifeUserMapper;
+import shop.alien.mapper.second.SecondGoodsMapper;
 
 import java.text.SimpleDateFormat;
 import java.util.Date;
@@ -34,6 +37,7 @@ public class AiUserViolationUtils {
     private final RestTemplate restTemplate;
     private final LifeUserMapper lifeUserMapper;
     private final LifeMessageMapper lifeMessageMapper;
+    private final SecondGoodsMapper secondGoodsMapper;
 
     @Value("${third-party-login.base-url}")
     private String loginUrl;
@@ -47,6 +51,8 @@ public class AiUserViolationUtils {
     @Value("${third-party-userComplaintRecordUrl.base-url}")
     private String userComplaintRecordUrl;
 
+    @Value("${third-party-goodsComplaintRecordUrl.base-url:${third-party-userComplaintRecordUrl.base-url}}")
+    private String goodsComplaintRecordUrl;
 
     /**
      * 登录 AI 服务,获取 token
@@ -210,6 +216,143 @@ public class AiUserViolationUtils {
     }
 
     /**
+     * 调用AI服务创建商品举报审核任务(参数格式:complaint_id、complaint_type、reporter/reported 信息、product 信息、complaint_text、evidence_images)
+     *
+     * @param accessToken 访问令牌
+     * @param lifeuserViolation 举报信息(商品举报时可为 SecondUserViolationVo,含 imgUrl)
+     * @return task_id 任务ID,失败返回 null
+     */
+    public String createGoodsTask(String accessToken, SecondUserViolationVo lifeuserViolation) {
+        log.info("创建Ai服务商品举报任务...{}", goodsComplaintRecordUrl);
+
+        HttpHeaders analyzeHeaders = new HttpHeaders();
+        analyzeHeaders.setContentType(MediaType.APPLICATION_JSON);
+        analyzeHeaders.set("Authorization", "Bearer " + accessToken);
+
+        Map<String, Object> analyzeRequest = new HashedMap<>();
+        // complaint_id
+        analyzeRequest.put("complaint_id", lifeuserViolation.getId().toString());
+
+        // complaint_type:举报商品类型 dictId 1-8(见图表)
+        Integer dictId = lifeuserViolation.getDictId() != null ? lifeuserViolation.getDictId() : 8;
+        if (1 == dictId) {
+            analyzeRequest.put("complaint_type", "禁限售商品");
+        } else if (2 == dictId) {
+            analyzeRequest.put("complaint_type", "政治敏感类");
+        } else if (3 == dictId) {
+            analyzeRequest.put("complaint_type", "有害信息");
+        } else if (4 == dictId) {
+            analyzeRequest.put("complaint_type", "假货/盗版");
+        } else if (5 == dictId) {
+            analyzeRequest.put("complaint_type", "盗用他人图片");
+        } else if (6 == dictId) {
+            analyzeRequest.put("complaint_type", "危害用户产权");
+        } else if (7 == dictId) {
+            analyzeRequest.put("complaint_type", "危害国家与社会安全");
+        } else {
+            analyzeRequest.put("complaint_type", "其他");
+        }
+
+        String reporterUserId = lifeuserViolation.getReportingUserId() != null ? lifeuserViolation.getReportingUserId() : "";
+        LifeUserVo reporterUser = null;
+        if (StringUtils.hasText(reporterUserId)) {
+            QueryWrapper<LifeUserVo> reporterQ = new QueryWrapper<>();
+            reporterQ.eq("id", reporterUserId);
+            reporterUser = lifeUserMapper.getUserById(reporterQ);
+        }
+        // 被举报人:通过 businessId 查 second_goods_record(id=businessId) 得到 userId,再查 life_user
+        String reportedUserId = lifeuserViolation.getReportedUserId() != null ? lifeuserViolation.getReportedUserId() : "";
+        LifeUserVo reportedUser = null;
+        Integer businessId = lifeuserViolation.getBusinessId();
+        SecondGoods secondGoods = secondGoodsMapper.selectById(businessId);
+        if (secondGoods != null && secondGoods.getUserId() != null) {
+            reportedUserId = String.valueOf(secondGoods.getUserId());
+            QueryWrapper<LifeUserVo> reportedQ = new QueryWrapper<>();
+            reportedQ.eq("id", secondGoods.getUserId());
+            reportedUser = lifeUserMapper.getUserById(reportedQ);
+        }
+
+        // 用user_去拼接,查询life_message表,获取双方两天记录
+        analyzeRequest.put("reporter_user_id", "user_" + reporterUser.getUserPhone());
+        analyzeRequest.put("reporter_user_type", "buyer");
+        analyzeRequest.put("reported_user_id", "user_" + reportedUser.getUserPhone());
+        analyzeRequest.put("reported_user_type", "seller");
+
+        // reporter_info
+        Map<String, Object> reporterInfo = new HashedMap<>();
+        QueryWrapper<LifeUserVo> reporterQ = new QueryWrapper<>();
+        reporterQ.eq("id", reporterUserId);
+        reporterInfo.put("name", reporterUser != null && StringUtils.hasText(reporterUser.getUserName()) ? reporterUser.getUserName() : "");
+        reporterInfo.put("phone", reporterUser != null && StringUtils.hasText(reporterUser.getUserPhone()) ? maskPhone(reporterUser.getUserPhone()) : "");
+        analyzeRequest.put("reporter_info", reporterInfo);
+
+        // reported_info(二手无店铺,用被举报人姓名/电话填充或填空)
+        Map<String, Object> reportedInfo = new HashedMap<>();
+        reportedInfo.put("shop_name", reportedUser != null && StringUtils.hasText(reportedUser.getUserName()) ? reportedUser.getUserName() : "");
+        reportedInfo.put("shop_id", reportedUserId);
+        analyzeRequest.put("reported_info", reportedInfo);
+
+        // product_id / product_name / product_info
+        analyzeRequest.put("product_id", secondGoods.getId().toString());
+        analyzeRequest.put("product_name", secondGoods.getTitle());
+        Map<String, Object> productInfo = new HashedMap<>();
+        productInfo.put("price", secondGoods.getPrice());
+        productInfo.put("category", secondGoods.getLabel());
+        productInfo.put("sku", secondGoods.getLabel());
+        analyzeRequest.put("product_info", productInfo);
+
+        analyzeRequest.put("complaint_text", StringUtils.hasText(lifeuserViolation.getOtherReasonContent()) ? lifeuserViolation.getOtherReasonContent() : "");
+
+        analyzeRequest.put("evidence_images", lifeuserViolation.getImgUrl());
+
+        HttpEntity<Map<String, Object>> analyzeEntity = new HttpEntity<>(analyzeRequest, analyzeHeaders);
+
+        ResponseEntity<String> analyzeResp = null;
+        try {
+            analyzeResp = restTemplate.postForEntity(goodsComplaintRecordUrl, analyzeEntity, String.class);
+        } catch (org.springframework.web.client.HttpServerErrorException.ServiceUnavailable e) {
+            log.error("调用提交商品举报审核任务接口返回503 Service Unavailable错误: {}", e.getResponseBodyAsString());
+            return null;
+        } catch (Exception e) {
+            log.error("调用提交商品举报审核任务接口异常", e);
+            return null;
+        }
+
+        if (analyzeResp != null && analyzeResp.getStatusCodeValue() == 200) {
+            String analyzeBody = analyzeResp.getBody();
+            log.info("提交商品举报审核任务成功, 返回: {}", analyzeBody);
+
+            JSONObject analyzeJson = JSONObject.parseObject(analyzeBody);
+            JSONObject dataJsonObj = analyzeJson.getJSONObject("data");
+
+            if (dataJsonObj == null) {
+                log.error("提交商品举报审核任务返回数据为空");
+                return null;
+            }
+
+            String taskId = dataJsonObj.getString("task_id");
+            if (taskId == null) {
+                log.error("提交商品举报审核任务返回task_id为空");
+                return null;
+            }
+            return taskId;
+        } else {
+            if (analyzeResp != null) {
+                log.error("调用提交商品举报审核任务接口失败, http状态: {}", analyzeResp.getStatusCode());
+                return null;
+            }
+        }
+        return null;
+    }
+
+    private static String maskPhone(String phone) {
+        if (phone == null || phone.length() < 8) {
+            return phone != null ? phone : "";
+        }
+        return phone.substring(0, 3) + "****" + phone.substring(phone.length() - 4);
+    }
+
+    /**
      * 获取双方用户的最近聊天记录
      * @param userReporterUserById 举报人ID
      * @param userReportedUserById 被举报人ID