Bladeren bron

feat(job): 优化AI内容审核任务调度与结果处理

- 新增getResultUrl配置项用于查询审核结果
- 为每条动态单独申请token并提交,避免批量操作失败影响整体流程
- 引入ClientHttpRequestInterceptor统一管理Authorization请求头
- 调整审核提交逻辑,仅标记checkFlag=1并保存任务ID等待回调
- 实现对已提交动态的轮询查询机制以获取审核结果
- 当AI判定内容不合规时,立即禁用相关动态并记录原因
Lhaibo 2 weken geleden
bovenliggende
commit
6929a9e735
1 gewijzigde bestanden met toevoegingen van 21 en 9 verwijderingen
  1. 21 9
      alien-job/src/main/java/shop/alien/job/store/AiTagJob.java

+ 21 - 9
alien-job/src/main/java/shop/alien/job/store/AiTagJob.java

@@ -9,6 +9,7 @@ import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.http.*;
+import org.springframework.http.client.ClientHttpRequestInterceptor;
 import org.springframework.stereotype.Component;
 import org.springframework.util.CollectionUtils;
 import org.springframework.util.LinkedMultiValueMap;
@@ -70,9 +71,12 @@ public class AiTagJob {
     private String saveTagUrl;
 
     // 第三方接口地址 内容合规检测接口
-    @Value("${third-party-content-check.base-url:http://192.168.2.250:9000/ai/auto-review/api/v1/content_compliance/check}")
+    @Value("${third-party-contentcheck.base-url}")
     private String contentComplianceUrl;
 
+    @Value("${third-party-getresult.base-url}")
+    private String getResultUrl;
+
     //用户名
     @Value("${third-party-user-name.base-url}")
     private String userName;
@@ -575,6 +579,7 @@ public class AiTagJob {
         List<LifeUserDynamics> lifeUserDynamics = lifeUserDynamicsMapper.selectList(new LambdaQueryWrapper<LifeUserDynamics>()
                 .eq(LifeUserDynamics::getCheckFlag, 0).eq(LifeUserDynamics::getDeleteFlag, 0));
 
+        // 只依赖数据库字段即可判定待审核的动态,避免重复提交
         // 常见图片后缀(可按需添加,如 .heic、.svg 等)
         HashSet<String> IMAGE_SUFFIXES = new HashSet<>(Arrays.asList(
                 "jpg", "jpeg", "png", "gif", "bmp", "webp", "heic", "svg", "tiff"
@@ -608,6 +613,7 @@ public class AiTagJob {
                 } else if (VIDEO_SUFFIXES.contains(suffix)) {
                     videoList.add(trimmedPath);
                 }
+                // 对每一条动态逐条申请 token 并提交,避免批量失败导致重试逻辑复杂化
                 try {
                     log.info("登录Ai服务获取token..." + loginUrl);
                     MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
@@ -638,6 +644,7 @@ public class AiTagJob {
                             aiHeaders.set("Authorization", "Bearer " + accessToken);
 
                             Map<String, Object> jsonBody = new HashMap<>();
+                            // text/img/video 三种维度一起传入 AI,便于一次完成合规审查
                             jsonBody.put("text", lifeUserDynamic.getContext());
                             jsonBody.put("imgUrl", imageList);
                             jsonBody.put("video", videoList);
@@ -658,6 +665,7 @@ public class AiTagJob {
                                     code = responseNode.getInteger("code");
                                     if(code==200) {
                                         JSONObject dataNode = JSONObject.from(responseNode.get("data"));
+                                        // 审核发起后仅标记 checkFlag=1 并保存任务号,等待回调或后续轮询更新
                                         LifeUserDynamics dynamics = new LifeUserDynamics();
                                         dynamics.setId(lifeUserDynamic.getId());
                                         dynamics.setCheckFlag(1);
@@ -692,6 +700,7 @@ public class AiTagJob {
                 .eq(LifeUserDynamics::getCheckFlag, 1).eq(LifeUserDynamics::getDeleteFlag, 0));
 
         for (LifeUserDynamics lifeUserDynamic : lifeUserDynamics) {
+            // 针对已提交且未删除的动态轮询查询结果
             try {
                 log.info("登录Ai服务获取token..." + loginUrl);
                 MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
@@ -717,17 +726,19 @@ public class AiTagJob {
                         JSONObject dataJson = jsonObject.getJSONObject("data");
                         String accessToken = dataJson.getString("access_token");
 
-                        HttpHeaders aiHeaders = new HttpHeaders();
-                        aiHeaders.setContentType(MediaType.APPLICATION_JSON);
-                        aiHeaders.set("Authorization", "Bearer " + accessToken);
-
-                        Map<String, Object> jsonBody = new HashMap<>();
-                        jsonBody.put("task_id", lifeUserDynamic.getAiTaskId());
+                        // 创建带拦截器的RestTemplate
+                        // 使用拦截器统一追加 Authorization,避免每次手动设置 header
+                        RestTemplate restTemplateWithAuth = new RestTemplate();
+                        List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>();
+                        interceptors.add((request, body, execution) -> {
+                            request.getHeaders().set("Authorization", "Bearer " + accessToken);
+                            return execution.execute(request, body);
+                        });
+                        restTemplateWithAuth.setInterceptors(interceptors);
 
-                        HttpEntity<Map<String, Object>> request = new HttpEntity<>(jsonBody, aiHeaders);
                         ResponseEntity<String> response = null;
                         try {
-                            response = restTemplate.postForEntity(contentComplianceUrl, request, String.class);
+                            response = restTemplateWithAuth.getForEntity(getResultUrl + lifeUserDynamic.getAiTaskId(), String.class);
                             if (response.getStatusCodeValue() != 200) {
                                 log.error("AI内容审核结果获取接口调用失败 http状态:" + response.getStatusCode());
                             }
@@ -742,6 +753,7 @@ public class AiTagJob {
                                     JSONObject dataNode = JSONObject.from(responseNode.get("data"));
 
                                     if (!(boolean) dataNode.get("is_compliant")) {
+                                        // 只要 AI 判定不合规,立即禁用动态并记录原因
                                         LifeUserDynamics dynamics = new LifeUserDynamics();
                                         dynamics.setId(lifeUserDynamic.getId());
                                         dynamics.setCheckFlag(2);