Bläddra i källkod

阿里安全检测

wxd 2 veckor sedan
förälder
incheckning
354d83084e

+ 101 - 2
alien-second/src/main/java/shop/alien/second/controller/SecondGoodsController.java

@@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.google.common.collect.Lists;
 import io.swagger.annotations.*;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
@@ -13,7 +14,9 @@ import shop.alien.entity.second.SecondGoods;
 import shop.alien.entity.second.vo.SecondGoodsVo;
 import shop.alien.second.service.SecondGoodsService;
 import shop.alien.util.common.JwtUtil;
+import shop.alien.util.common.safe.*;
 
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -30,6 +33,12 @@ public class SecondGoodsController {
 
     private final SecondGoodsService secondGoodsService;
 
+    // 注入文本审核工具
+    private final TextModerationUtil textModerationUtil;
+
+    // 注入图片审核工具
+    private final ImageModerationUtil imageModerationUtil;
+
     /**
      * 根据ID获取二手商品
      */
@@ -45,7 +54,7 @@ public class SecondGoodsController {
      */
     @PostMapping("/save")
     @ApiOperation("发布二手商品")
-    public R<Void> addSecondGoods(@ApiParam("二手商品信息") @RequestBody SecondGoodsVo secondGoods) {
+    public R<Void> addSecondGoods(@ApiParam("二手商品信息") @RequestBody SecondGoodsVo secondGoods) throws Exception {
         log.info("SecondGoodsController.addSecondGoods?secondGoods={}", secondGoods.toString());
         JSONObject data = JwtUtil.getCurrentUserInfo();
         if (null != data) {
@@ -71,7 +80,7 @@ public class SecondGoodsController {
      */
     @PostMapping("/edit")
     @ApiOperation("更新二手商品")
-    public R<Void> updateSecondGoods(@ApiParam("二手商品信息") @RequestBody SecondGoodsVo secondGoods) {
+    public R<Void> updateSecondGoods(@ApiParam("二手商品信息") @RequestBody SecondGoodsVo secondGoods) throws Exception {
         log.info("SecondGoodsController.updateSecondGoods?secondGoods={}", secondGoods.toString());
         // 添加商品 0 创建 1 更新
         if (!secondGoodsService.createBasicInfo(secondGoods,1)) {
@@ -119,4 +128,94 @@ public class SecondGoodsController {
         return R.data(secondGoodsService.getOne(queryWrapper).getGoodsStatus());
     }
 
+    /**
+     * 文本审核接口 - 商品发布场景
+     */
+    @GetMapping("/textModeration/productPublish")
+    @ApiOperation("文本审核 - 商品发布场景(大语言模型输入文字检测、广告法合规检测_专业版、URL风险链接检测)")
+    public R<TextModerationResultVO> productPublishTextModeration(@ApiParam("待审核文本") @RequestParam String text) {
+        log.info("SecondGoodsController.productPublishTextModeration?text={}", text);
+        try {
+            List<String> servicesList = Lists.newArrayList();
+            servicesList.add(TextReviewServiceEnum.AD_COMPLIANCE_DETECTION_PRO.getService());
+            servicesList.add(TextReviewServiceEnum.LLM_QUERY_MODERATION.getService());
+            TextModerationResultVO textModerationResultVO = textModerationUtil.invokeFunction(text,servicesList);
+            return R.data(textModerationResultVO);
+        } catch (Exception e) {
+            log.error("文本审核异常", e);
+            return R.fail("文本审核异常: " + e.getMessage());
+        }
+    }
+
+    /**
+     * 文本审核接口 - 聊一聊场景
+     */
+    @GetMapping("/textModeration/chat")
+    @ApiOperation("文本审核 - 聊一聊场景(私聊互动内容检测_专业版、广告法合规检测_专业版、URL风险链接检测)")
+    public R<TextModerationResultVO> chatTextModeration(@ApiParam("待审核文本") @RequestParam String text) {
+        log.info("SecondGoodsController.chatTextModeration?text={}", text);
+        try {
+            List<String> servicesList = Lists.newArrayList();
+            servicesList.add(TextReviewServiceEnum.AD_COMPLIANCE_DETECTION_PRO.getService());
+            servicesList.add(TextReviewServiceEnum.URL_DETECTION.getService());
+            servicesList.add(TextReviewServiceEnum.CHAT_DETECTION_PRO.getService());
+            TextModerationResultVO textModerationResultVO = textModerationUtil.invokeFunction(text,servicesList);
+            return R.data(textModerationResultVO);
+        } catch (Exception e) {
+            log.error("文本审核异常", e);
+            return R.fail("文本审核异常: " + e.getMessage());
+        }
+    }
+
+    /**
+     * 文本审核接口 - 评论场景
+     */
+    @GetMapping("/textModeration/comment")
+    @ApiOperation("文本审核 - 评论场景(公聊评论内容检测_专业版、广告法合规检测_专业版、URL风险链接检测)")
+    public R<TextModerationResultVO> commentTextModeration(@ApiParam("待审核文本") @RequestParam String text) {
+        log.info("SecondGoodsController.commentTextModeration?text={}", text);
+        try {
+            List<String> servicesList = Lists.newArrayList();
+            servicesList.add(TextReviewServiceEnum.AD_COMPLIANCE_DETECTION_PRO.getService());
+            servicesList.add(TextReviewServiceEnum.URL_DETECTION.getService());
+            servicesList.add(TextReviewServiceEnum.CHAT_DETECTION_PRO.getService());
+            TextModerationResultVO textModerationResultVO = textModerationUtil.invokeFunction(text,servicesList);
+            return R.data(textModerationResultVO);
+        } catch (Exception e) {
+            log.error("文本审核异常", e);
+            return R.fail("文本审核异常: " + e.getMessage());
+        }
+    }
+
+    /**
+     * 图片审核接口 - 发布商品场景
+     */
+    @GetMapping("/imageModeration/productPublish")
+    @ApiOperation("图片审核 - 发布商品场景(内容治理检测、AIGC图片风险检测、图片万物识别)")
+    public R<ImageModerationResultVO> productPublishImageModeration(@ApiParam("图片地址") @RequestParam String imageUrl) {
+        log.info("SecondGoodsController.productPublishImageModeration?imageUrl={}", imageUrl);
+        try {
+            ImageModerationResultVO response = imageModerationUtil.productPublishCheck(imageUrl);
+            return R.data(response);
+        } catch (Exception e) {
+            log.error("图片审核异常", e);
+            return R.fail("图片审核异常: " + e.getMessage());
+        }
+    }
+
+    /**
+     * 图片审核接口 - 聊一聊场景
+     */
+    @GetMapping("/imageModeration/chat")
+    @ApiOperation("图片审核 - 聊一聊场景(图片万物识别、内容治理检测)")
+    public R<ImageModerationResultVO> chatImageModeration(@ApiParam("图片地址") @RequestParam String imageUrl) {
+        log.info("SecondGoodsController.chatImageModeration?imageUrl={}", imageUrl);
+        try {
+            ImageModerationResultVO response = imageModerationUtil.chatCheck(imageUrl);
+            return R.data(response, "审核成功");
+        } catch (Exception e) {
+            log.error("图片审核异常", e);
+            return R.fail("图片审核异常: " + e.getMessage());
+        }
+    }
 }

+ 1 - 1
alien-second/src/main/java/shop/alien/second/service/SecondGoodsService.java

@@ -19,7 +19,7 @@ public interface SecondGoodsService extends IService<SecondGoods> {
      * @param editFlag 编辑标识 0:创建 1:编辑
      * @return 是否成功保存
      */
-    boolean createBasicInfo(SecondGoodsVo goods, Integer editFlag);
+    boolean createBasicInfo(SecondGoodsVo goods, Integer editFlag) throws Exception;
 
     /**
      * 保存为草稿

+ 27 - 13
alien-second/src/main/java/shop/alien/second/service/impl/SecondGoodsServiceImpl.java

@@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.google.common.collect.Lists;
 import lombok.RequiredArgsConstructor;
 import org.apache.ibatis.annotations.Param;
 import org.springframework.beans.BeanUtils;
@@ -22,6 +23,7 @@ import shop.alien.second.service.SecondGoodsService;
 import shop.alien.util.common.VideoUtils;
 import shop.alien.util.common.netease.ImageCheckUtil;
 import shop.alien.util.common.netease.TextCheckUtil;
+import shop.alien.util.common.safe.*;
 
 import java.util.Collections;
 import java.util.Date;
@@ -39,6 +41,16 @@ public class SecondGoodsServiceImpl extends ServiceImpl<SecondGoodsMapper, Secon
     private final VideoUtils videoUtils;
 
     /**
+     * 文本审核工具
+     */
+    private final TextModerationUtil textModerationUtil;
+
+    /**
+     * 图片审核工具
+     */
+    private final ImageModerationUtil imageModerationUtil;
+
+    /**
      * 二手商品Mapper
      */
     private final SecondGoodsMapper secondGoodsMapper;
@@ -98,7 +110,7 @@ public class SecondGoodsServiceImpl extends ServiceImpl<SecondGoodsMapper, Secon
 
 
     @Override
-    public boolean createBasicInfo(SecondGoodsVo goodsDTO,Integer editFlag) {
+    public boolean createBasicInfo(SecondGoodsVo goodsDTO,Integer editFlag) throws Exception {
         // 实现基本信息保存逻辑
         SecondGoods goods = new SecondGoods();
         BeanUtils.copyProperties(goodsDTO, goods);
@@ -154,20 +166,23 @@ public class SecondGoodsServiceImpl extends ServiceImpl<SecondGoodsMapper, Secon
     private boolean checkSafety(SecondGoods goods) {
         return true;
     }
-
     /**
      * 执行内容审核(图片和文本)
      * @param goods 商品信息
      * @param goodsDTO 商品DTO信息
      * @return 审核结果
      */
-    private boolean performContentReviews(SecondGoods goods, SecondGoodsVo goodsDTO) {
-        // 文本审核
-        Map<String, String> textCheckResult = TextCheckUtil.check(goodsDTO.getDescription());
-        if (!"200".equals(textCheckResult.get("code"))) {
-            // 文本审核不通过
+    private boolean performContentReviews(SecondGoods goods, SecondGoodsVo goodsDTO) throws Exception {
+        List<String> servicesList = Lists.newArrayList();
+        servicesList.add(TextReviewServiceEnum.AD_COMPLIANCE_DETECTION_PRO.getService());
+        servicesList.add(TextReviewServiceEnum.LLM_QUERY_MODERATION.getService());
+        // 使用商品发布场景的审核服务
+        TextModerationResultVO textCheckResult = textModerationUtil.invokeFunction(goodsDTO.getDescription(), servicesList);
+        
+        if ("high".equals(textCheckResult.getRiskLevel())) {
+            // 文本审核不通过或存在高风险
             goods.setGoodsStatus(2); // 审核失败
-            goods.setFailedReason("文本审核不通过:" + textCheckResult.get("msg"));
+            goods.setFailedReason("文本审核不通过:" + (textCheckResult.getRiskWords() != null ? textCheckResult.getRiskWords() : "存在高风险内容"));
             return false;
         }
 
@@ -176,12 +191,11 @@ public class SecondGoodsServiceImpl extends ServiceImpl<SecondGoodsMapper, Secon
         if (imageUrls != null && !imageUrls.isEmpty()) {
             StringBuilder failReasonBuilder = new StringBuilder();
             for (String imageUrl : imageUrls) {
-                Map<String, String> imageCheckResult = ImageCheckUtil.check(imageUrl, 2);
-                if (!"200".equals(imageCheckResult.get("code"))) {
-                    // 任一图片审核不通过则整体不通过
+                ImageModerationResultVO response = imageModerationUtil.productPublishCheck(imageUrl);
+                if ("high".equals(response.getRiskLevel())) {
+                    // 文本审核不通过或存在高风险
                     goods.setGoodsStatus(2); // 审核失败
-                    failReasonBuilder.append("图片审核不通过:").append(imageUrl).append(" 原因:").append(imageCheckResult.get("msg")).append("; ");
-                    goods.setFailedReason(failReasonBuilder.toString());
+                    goods.setFailedReason("图片审核不通过:图片中包含" + (response.getDescriptions() != null ? response.getDescriptions() : "高风险内容"));
                     return false;
                 }
             }

+ 44 - 0
alien-util/src/main/java/shop/alien/util/common/safe/DeepseekClient.java

@@ -0,0 +1,44 @@
+package shop.alien.util.common.safe;
+
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import okhttp3.*;
+
+import java.io.IOException;
+
+public class DeepseekClient {
+    private final String apiKey;
+    private final OkHttpClient client;
+
+    public DeepseekClient(String apiKey) {
+        this.apiKey = apiKey;
+        this.client = new OkHttpClient();
+    }
+
+    public String generateText(String prompt) throws IOException {
+        // 创建请求体
+        JSONObject messages = new JSONObject();
+        messages.put("role", "user");
+        messages.put("content", prompt);
+
+        JSONObject requestBody = new JSONObject();
+        requestBody.put("model", "deepseek-chat");
+        requestBody.put("messages", JSON.parseArray(messages.toJSONString(), Object.class));
+        requestBody.put("stream", false);
+
+        Request request = new Request.Builder()
+                .url("https://api.deepseek.com/chat/completions")
+                .post(RequestBody.create(MediaType.get("application/json"), requestBody.toJSONString()))
+                .addHeader("Content-Type", "application/json")
+                .addHeader("Authorization", "Bearer " + apiKey)
+                .build();
+
+        try (Response response = client.newCall(request).execute()) {
+            if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
+
+            JSONObject responseBody = JSON.parseObject(response.body().string());
+            return responseBody.getJSONArray("choices").getJSONObject(0).getJSONObject("message").getString("content");
+        }
+    }
+}

+ 18 - 0
alien-util/src/main/java/shop/alien/util/common/safe/ImageModerationResultVO.java

@@ -0,0 +1,18 @@
+package shop.alien.util.common.safe;
+
+import lombok.Data;
+
+/**
+ * 图片审核结果返回值对象
+ */
+@Data
+public class ImageModerationResultVO {
+    // 风险等级
+    private String riskLevel;
+    // 细分标签
+    private String labels;
+    // 细分标签描述
+    private String descriptions;
+    // 生成的商品文案
+    private String generatedText;
+}

+ 112 - 29
alien-util/src/main/java/shop/alien/util/common/safe/ImageModerationUtil.java

@@ -1,5 +1,6 @@
 package shop.alien.util.common.safe;
 import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
 import com.aliyun.green20220302.Client;
 import com.aliyun.green20220302.models.ImageBatchModerationResponse;
 import com.aliyun.green20220302.models.ImageModerationRequest;
@@ -10,18 +11,22 @@ import com.aliyun.green20220302.models.ImageBatchModerationResponseBody;
 import com.aliyun.green20220302.models.ImageModerationResponseBody;
 import com.aliyun.green20220302.models.ImageModerationResponseBody.ImageModerationResponseBodyData;
 import com.aliyun.green20220302.models.ImageModerationResponseBody.ImageModerationResponseBodyDataResult;
+
 import com.aliyun.teaopenapi.models.Config;
 import com.aliyun.teautil.models.RuntimeOptions;
+import com.google.common.collect.Lists;
 import jdk.nashorn.internal.runtime.logging.Logger;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
 
+import java.io.IOException;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 
 @Logger
+@Component
 public class ImageModerationUtil {
 
     @Value("${ali.yundun.accessKeyID}")
@@ -40,6 +45,8 @@ public class ImageModerationUtil {
      */
     public Client createClient() throws Exception {
         Config config = new Config();
+//        config.setAccessKeyId("LTAI5tReZWshffH78oQJPzZG");
+//        config.setAccessKeySecret("Gi30OLYAWunaDbwsv5qqdZ3PzbDyGP");
         config.setAccessKeyId(accessKeyId);
         config.setAccessKeySecret(accessKeySecret);
         // 设置http代理。
@@ -48,6 +55,7 @@ public class ImageModerationUtil {
         //config.setHttpsProxy("https://10.10.xx.xx:xxxx");
         // 接入区域和地址请根据实际情况修改
         // 接入地址列表:https://help.aliyun.com/document_detail/467828.html?#section-uib-qkw-0c8
+//        config.setEndpoint("green-cip.cn-shanghai.aliyuncs.com");
         config.setEndpoint(ImgEndpoint);
         return new Client(config);
     }
@@ -119,38 +127,83 @@ public class ImageModerationUtil {
      * 顺序调用内容治理检测、AIGC图片风险检测、图片万物识别
      *
      * @param imageUrl 图片地址
-     * @return 检测结果
+     * @return 检测结果VO
      * @throws Exception 检测异常
      */
-    public ImageBatchModerationResponse productPublishCheck(String imageUrl) throws Exception {
-
+    public ImageModerationResultVO productPublishCheck(String imageUrl) throws Exception {
+        ImageModerationResultVO resultVO = new ImageModerationResultVO();
         // 批量服务key
-        String serviceEnum = ImageReviewServiceEnum.TONALITY_IMPROVE.getService() + "," + ImageReviewServiceEnum.AIGC_CHECK.getService() + "," + ImageReviewServiceEnum.GENERAL_RECOGNITION.getService();
+        StringBuilder serviceBatchEnum = new StringBuilder();
+        StringBuilder serviceEnum = new StringBuilder();
+        List<String> servicesList = Lists.newArrayList();
+        // TODO 后续配置到数据库 中
+        servicesList.add(ImageReviewServiceEnum.TONALITY_IMPROVE.getService());
+        servicesList.add(ImageReviewServiceEnum.AIGC_CHECK.getService());
+        for (String service : servicesList){
+            if (isSpecialService(service)){
+                serviceBatchEnum.append(service).append(",");
+            }else {
+                serviceEnum.append(service).append(",");
+            }
+        }
+        // 若存在特殊服务,则拼接字符串  并调取多service阿里图片审核服务
+        if (serviceBatchEnum.length() > 0) {
+            serviceBatchEnum.setLength(serviceBatchEnum.length() - 1);
+            // 多service图片审核
+            resultVO = getImageModerationResultVO(imageUrl, serviceBatchEnum);
+        }
+        // TODO 现阶段使用的服务都支持多service 图片审核,后续如果有不支持的服务则 融合 使用单service图片审核
 
-        // 批量图片检测
-        ImageBatchModerationResponse response = invokeBeachFunction(imageUrl,serviceEnum);
-        if (response != null) {
-            if (response.getStatusCode() == 200) {
-                ImageBatchModerationResponseBody body = response.getBody();
-                System.out.println("requestId=" + body.getRequestId());
-                System.out.println("code=" + body.getCode());
-                System.out.println("msg=" + body.getMsg());
-                if (body.getCode() == 200) {
-                    ImageBatchModerationResponseBody.ImageBatchModerationResponseBodyData data = body.getData();
-                    System.out.println("dataId=" + data.getDataId());
+
+        return resultVO;
+    }
+
+    private ImageModerationResultVO getImageModerationResultVO(String imageUrl, StringBuilder serviceEnum) throws Exception {
+        // 多service图片审核
+        ImageBatchModerationResponse response = invokeBeachFunction(imageUrl, serviceEnum.toString());
+        ImageModerationResultVO resultVO = new ImageModerationResultVO();
+
+        if (response != null && response.getStatusCode() == 200) {
+            ImageBatchModerationResponseBody body = response.getBody();
+            if (body != null && body.getCode() == 200) {
+                ImageBatchModerationResponseBody.ImageBatchModerationResponseBodyData data = body.getData();
+                if (data != null) {
+                    String riskLevel = data.getRiskLevel();
                     List<ImageBatchModerationResponseBody.ImageBatchModerationResponseBodyDataResult> results = data.getResult();
-                    for (ImageBatchModerationResponseBody.ImageBatchModerationResponseBodyDataResult result : results) {
-                        System.out.println("label=" + result.getLabel());
-                        System.out.println("confidence=" + result.getConfidence());
+                    StringBuilder labelsBuilder = new StringBuilder();
+                    StringBuilder descriptionsBuilder = new StringBuilder();
+                    // 处理结果 多个服务总敏感程度
+                    if ("high".equals(riskLevel)) {
+                        for (ImageBatchModerationResponseBody.ImageBatchModerationResponseBodyDataResult result : results) {
+                            // 触发多个,如果置信分高于80 则拼接描述
+                            if (result.getConfidence() > 80 ) {
+                                String label = result.getLabel();
+                                String description = result.getDescription();
+                                // 拼接标签
+                                if (label != null && !label.isEmpty()) {
+                                    labelsBuilder.append(label).append(",");
+                                }
+                                // 拼接描述
+                                if (description != null && !description.isEmpty()) {
+                                    descriptionsBuilder.append(description).append(",");
+                                }
+                            }
+                        }
+                    }
+                    // 移除最后一个逗号
+                    if (labelsBuilder.length() > 0) {
+                        labelsBuilder.setLength(labelsBuilder.length() - 1);
                     }
-                } else {
-                    System.out.println("image moderation not success. code:" + body.getCode());
+                    if (descriptionsBuilder.length() > 0) {
+                        descriptionsBuilder.setLength(descriptionsBuilder.length() - 1);
+                    }
+                    resultVO.setRiskLevel(riskLevel);
+                    resultVO.setLabels(labelsBuilder.toString());
+                    resultVO.setDescriptions(descriptionsBuilder.toString());
                 }
-            } else {
-                System.out.println("response not success. status:" + response.getStatusCode());
             }
         }
-        return response;
+        return resultVO;
     }
 
     /**
@@ -161,13 +214,43 @@ public class ImageModerationUtil {
      * @return 检测结果
      * @throws Exception 检测异常
      */
-    public ImageBatchModerationResponse chatCheck(String imageUrl) throws Exception {
-        // 批量服务key
-        String serviceEnum = ImageReviewServiceEnum.GENERAL_RECOGNITION.getService() + "," + ImageReviewServiceEnum.TONALITY_IMPROVE.getService();
-
+    public ImageModerationResultVO chatCheck(String imageUrl) throws Exception {
         // 批量图片检测
-        ImageBatchModerationResponse response = invokeBeachFunction(imageUrl,serviceEnum);
+        ImageModerationResponse response = invokeFunction(imageUrl, "generalRecognition");
+        ImageModerationResultVO resultVO = new ImageModerationResultVO();
+        ImageModerationResponseBody body = response.body;
+        ImageModerationResponseBody.ImageModerationResponseBodyDataExt dataExt = body.data.ext;
+        // 调用DeepSeek接口生成商品文案
+        String prompt = "根据以下标签生成一个吸引人的商品售卖文案(200字以内): " + dataExt;
+        String generatedText = callDeepSeekAPI(prompt);
+        resultVO.setGeneratedText(generatedText);
+        return resultVO;
+    }
 
-        return response;
+    /**
+     * 调用DeepSeek接口生成商品文案
+     * @param prompt 提示信息
+     * @return 生成的文案
+     * @throws IOException 调用异常
+     */
+    private String callDeepSeekAPI(String prompt) throws IOException {
+        DeepseekClient client = new DeepseekClient("sk-dd8a6e10972145c9847883791ac9fb41");
+        return client.generateText(prompt);
+    }
+
+    /**
+     * 判断服务是否为特殊服务,若是可以调取阿里多service审核服务,返回多个场景的总审核结果
+     * @param service 服务名称
+     * @return 是否为特殊服务
+     */
+    public static boolean isSpecialService(String service) {
+        return ImageReviewServiceEnum.BASELINE_CHECK.getService().equals(service)
+                || ImageReviewServiceEnum.BASELINE_CHECK_PRO.getService().equals(service)
+                || ImageReviewServiceEnum.TONALITY_IMPROVE.getService().equals(service)
+                || ImageReviewServiceEnum.AIGC_CHECK.getService().equals(service)
+                || ImageReviewServiceEnum.PROFILE_PHOTO_CHECK.getService().equals(service)
+                || ImageReviewServiceEnum.POST_IMAGE_CHECK.getService().equals(service)
+                || ImageReviewServiceEnum.ADVERTISING_CHECK.getService().equals(service)
+                || ImageReviewServiceEnum.LIVE_STREAM_CHECK.getService().equals(service);
     }
 }

+ 1 - 0
alien-util/src/main/java/shop/alien/util/common/safe/ImageReviewServiceEnum.java

@@ -38,6 +38,7 @@ public enum ImageReviewServiceEnum {
         this.serviceScene = serviceScene;
     }
 
+
     public String getService() {
         return service;
     }

+ 120 - 0
alien-util/src/main/java/shop/alien/util/common/safe/ImageUrlDemo.java

@@ -0,0 +1,120 @@
+package shop.alien.util.common.safe;
+import com.alibaba.fastjson.JSON;
+import com.aliyun.green20220302.Client;
+import com.aliyun.green20220302.models.ImageModerationRequest;
+import com.aliyun.green20220302.models.ImageModerationResponse;
+import com.aliyun.green20220302.models.ImageModerationResponseBody;
+import com.aliyun.green20220302.models.ImageModerationResponseBody.ImageModerationResponseBodyData;
+import com.aliyun.green20220302.models.ImageModerationResponseBody.ImageModerationResponseBodyDataResult;
+import com.aliyun.teaopenapi.models.Config;
+import com.aliyun.teautil.models.RuntimeOptions;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+public class ImageUrlDemo {
+    /**
+     * 创建请求客户端
+     *
+     * @param accessKeyId
+     * @param accessKeySecret
+     * @param endpoint
+     * @return
+     * @throws Exception
+     */
+    public static Client createClient(String accessKeyId, String accessKeySecret, String endpoint) throws Exception {
+        Config config = new Config();
+        config.setAccessKeyId(accessKeyId);
+        config.setAccessKeySecret(accessKeySecret);
+        // 设置http代理。
+        //config.setHttpProxy("http://10.10.xx.xx:xxxx");
+        // 设置https代理。
+        //config.setHttpsProxy("https://10.10.xx.xx:xxxx");
+        // 接入区域和地址请根据实际情况修改
+        // 接入地址列表:https://help.aliyun.com/document_detail/467828.html?#section-uib-qkw-0c8
+        config.setEndpoint(endpoint);
+        return new Client(config);
+    }
+
+    public static ImageModerationResponse invokeFunction(String accessKeyId, String accessKeySecret, String endpoint) throws Exception {
+        //注意,此处实例化的client请尽可能重复使用,避免重复建立连接,提升检测性能。
+        Client client = createClient(accessKeyId, accessKeySecret, endpoint);
+
+        // 创建RuntimeObject实例并设置运行参数
+        RuntimeOptions runtime = new RuntimeOptions();
+
+        // 检测参数构造。
+        Map<String, String> serviceParameters = new HashMap<>();
+        //公网可访问的URL。
+        serviceParameters.put("imageUrl", "http://devfile.ailien.shop/image/暴恐违禁2367012.jpg");
+        //待检测数据唯一标识
+        serviceParameters.put("dataId", UUID.randomUUID().toString());
+
+        ImageModerationRequest request = new ImageModerationRequest();
+        // 图片检测service:内容安全控制台图片增强版规则配置的serviceCode,示例:baselineCheck
+        // 支持service请参考:https://help.aliyun.com/document_detail/467826.html?0#p-23b-o19-gff
+        request.setService("generalRecognition");
+        request.setServiceParameters(JSON.toJSONString(serviceParameters));
+
+        ImageModerationResponse response = null;
+        try {
+            response = client.imageModerationWithOptions(request, runtime);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return response;
+    }
+
+    public static void main(String[] args) throws Exception {
+        /**
+         * 阿里云账号AccessKey拥有所有API的访问权限,建议您使用RAM用户进行API访问或日常运维。
+         * 常见获取环境变量方式:
+         * 方式一:
+         *     获取RAM用户AccessKey ID:System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
+         *     获取RAM用户AccessKey Secret:System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
+         * 方式二:
+         *     获取RAM用户AccessKey ID:System.getProperty("ALIBABA_CLOUD_ACCESS_KEY_ID");
+         *     获取RAM用户AccessKey Secret:System.getProperty("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
+         */
+        String accessKeyId = "LTAI5tReZWshffH78oQJPzZG";
+        String accessKeySecret = "Gi30OLYAWunaDbwsv5qqdZ3PzbDyGP";
+        // 接入区域和地址请根据实际情况修改。
+        ImageModerationResponse response = invokeFunction(accessKeyId, accessKeySecret, "green-cip.cn-shanghai.aliyuncs.com");
+        try {
+            // 自动路由。
+            if (response != null) {
+                //区域切换到cn-beijing。
+                if (500 == response.getStatusCode() || (response.getBody() != null && 500 == (response.getBody().getCode()))) {
+                    // 接入区域和地址请根据实际情况修改。
+                    response = invokeFunction(accessKeyId, accessKeySecret, "green-cip.cn-beijing.aliyuncs.com");
+                }
+            }
+            // 打印检测结果。
+            if (response != null) {
+                if (response.getStatusCode() == 200) {
+                    ImageModerationResponseBody body = response.getBody();
+                    System.out.println("requestId=" + body.getRequestId());
+                    System.out.println("code=" + body.getCode());
+                    System.out.println("msg=" + body.getMsg());
+                    if (body.getCode() == 200) {
+                        ImageModerationResponseBodyData data = body.getData();
+                        System.out.println("dataId=" + data.getDataId());
+                        List<ImageModerationResponseBodyDataResult> results = data.getResult();
+                        for (ImageModerationResponseBodyDataResult result : results) {
+                            System.out.println("label=" + result.getLabel());
+                            System.out.println("confidence=" + result.getConfidence());
+                        }
+                    } else {
+                        System.out.println("image moderation not success. code:" + body.getCode());
+                    }
+                } else {
+                    System.out.println("response not success. status:" + response.getStatusCode());
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 0 - 10
alien-util/src/main/java/shop/alien/util/common/safe/TextModerationResultVO.java

@@ -7,17 +7,7 @@ import lombok.Data;
  */
 @Data
 public class TextModerationResultVO {
-    private Integer code;
-    private String message;
-    
-    // 以下字段对应原始data对象中的属性
-    private String labels; // 标签
-    private String reason; // 原因(JSON字符串)
-
     // 扁平化的风险信息字段
     private String riskLevel; // 风险等级
-    private String riskTips; // 细分标签
     private String riskWords; // 命中风险内容
-    private String customizedWords; // 命中用户词
-    private String customizedLibs; // 命中用户词库名
 }

+ 189 - 87
alien-util/src/main/java/shop/alien/util/common/safe/TextModerationUtil.java

@@ -1,14 +1,21 @@
 package shop.alien.util.common.safe;
+import cn.hutool.core.collection.CollectionUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.aliyun.green20220302.Client;
-import com.aliyun.green20220302.models.ImageModerationResponse;
-import com.aliyun.green20220302.models.TextModerationPlusRequest;
-import com.aliyun.green20220302.models.TextModerationPlusResponse;
-import com.aliyun.green20220302.models.TextModerationPlusResponseBody;
+import com.aliyun.green20220302.models.*;
 import com.aliyun.teaopenapi.models.Config;
+import com.aliyun.teautil.models.RuntimeOptions;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.google.common.collect.Lists;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
 
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+@Component
 public class TextModerationUtil {
 
 
@@ -50,12 +57,12 @@ public class TextModerationUtil {
     /**
      * 根据业务类型执行文本审核
      * @param text 待审核文本
-     * @param services 文本审核服务枚举
+     * @param servicesList 文本审核服务枚举
      * @return 审核结果VO
      * @throws Exception 调用服务异常
      */
-    public TextModerationResultVO invokeFunction(String text, ImageReviewServiceEnum... services) throws Exception {
-        if (services == null || services.length == 0) {
+    public TextModerationResultVO invokeFunction(String text, List<String> servicesList) throws Exception {
+        if (CollectionUtil.isEmpty(servicesList)) {
             throw new IllegalArgumentException("至少需要一个审核服务");
         }
 
@@ -64,102 +71,185 @@ public class TextModerationUtil {
         TextModerationResultVO resultVO = new TextModerationResultVO();
         
         // 存储风险等级和原因的字符串
-        StringBuilder riskTipsBuilder = new StringBuilder();
         StringBuilder riskWordsBuilder = new StringBuilder();
-        StringBuilder customizedWordsBuilder = new StringBuilder();
-        StringBuilder customizedLibsBuilder = new StringBuilder();
-        String highestRiskLevel = "low"; // 默认最低风险等级
+        String highestRiskLevel = "none"; // 默认未检测到风险
         
         try {
-            for (ImageReviewServiceEnum service : services) {
-                TextModerationPlusRequest textModerationPlusRequest = new TextModerationPlusRequest();
-                textModerationPlusRequest.setService(service.getService());
-                
-                // 构建服务参数
-                textModerationPlusRequest.setServiceParameters(buildServiceParameters(text));
-                
-                TextModerationPlusResponse response = client.textModerationPlus(textModerationPlusRequest);
-                if (response.getStatusCode() == 200) {
-                    TextModerationPlusResponseBody result = response.getBody();
-                    
-                    if (200 == result.getCode()) {
-                        // 解析审核结果
-                        TextModerationPlusResponseBody.TextModerationPlusResponseBodyData data = result.getData();
-
-                        // 解析审核结果
-                        JSONObject dataJson = JSON.parseObject(JSON.toJSONString(result.getData()));
-                        String labels = dataJson.getString("labels");
-                        String reason = dataJson.getString("reason");
-
-                        // 解析风险等级和详细信息
-                        JSONObject reasonJson = JSON.parseObject(reason);
-                        String riskLevel = reasonJson.getString("riskLevel");
-                        String riskTip = reasonJson.getString("riskTips");
-                        String riskWord = reasonJson.getString("riskWords");
-                        String customizedWord = reasonJson.getString("customizedWords");
-                        String customizedLib = reasonJson.getString("customizedLibs");
-                        
-                        // 如果存在风险信息,则添加到构建器中
-                        if (riskTip != null && !riskTip.isEmpty()) {
-                            if (riskTipsBuilder.length() > 0) {
-                                riskTipsBuilder.append(", ");
-                            }
-                            riskTipsBuilder.append(riskTip);
-                        }
-                        
-                        if (riskWord != null && !riskWord.isEmpty()) {
-                            if (riskWordsBuilder.length() > 0) {
-                                riskWordsBuilder.append(", ");
-                            }
-                            riskWordsBuilder.append(riskWord);
-                        }
-                        
-                        if (customizedWord != null && !customizedWord.isEmpty()) {
-                            if (customizedWordsBuilder.length() > 0) {
-                                customizedWordsBuilder.append(", ");
-                            }
-                            customizedWordsBuilder.append(customizedWord);
-                        }
-                        
-                        if (customizedLib != null && !customizedLib.isEmpty()) {
-                            if (customizedLibsBuilder.length() > 0) {
-                                customizedLibsBuilder.append(", ");
+            for (String service : servicesList) {
+                // 判断传入参service参数是否包含 chat_detection_pro、ad_compliance_detection_pro、llm_query_moderation、comment_detection_pro、
+                if (isSpecialService(service)) {
+                    // 处理特殊服务
+                    highestRiskLevel = handleSpecialService(text, service, client, riskWordsBuilder, highestRiskLevel);
+                } else {
+                    // 判断service中包含 url_detection ,将文本中的url进行检测 提取url 传入进行检测
+                    if ("url_detection".equals( service )) {
+                        // 写一个文本提取url 的方法
+                        List<String> urls = extractUrls(text);
+                        if (CollectionUtil.isNotEmpty(urls)){
+                            for (String url : urls) {
+                                // 链接调取
+                                highestRiskLevel = processTextModeration(client, url, service, riskWordsBuilder,highestRiskLevel);
                             }
-                            customizedLibsBuilder.append(customizedLib);
                         }
-                        
-                        // 判断风险等级优先级
-                        if (riskLevel != null) {
-                            if (riskLevel.equals("high") && !highestRiskLevel.equals("high")) {
-                                highestRiskLevel = "high";
-                            } else if (riskLevel.equals("medium") && highestRiskLevel.equals("low")) {
-                                highestRiskLevel = "medium";
-                            }
-                        }
-                        
-                        // 设置基础信息
-                        resultVO.setLabels(labels);
+                    }else {
+                        // 文本调取
+                        highestRiskLevel = processTextModeration(client, text, service, riskWordsBuilder,highestRiskLevel);
                     }
                 }
             }
-            
             // 设置结果VO
-            resultVO.setCode(200);
-            resultVO.setMessage("OK");
             resultVO.setRiskLevel(highestRiskLevel);
-            resultVO.setRiskTips(riskTipsBuilder.toString());
             resultVO.setRiskWords(riskWordsBuilder.toString());
-            resultVO.setCustomizedWords(customizedWordsBuilder.toString());
-            resultVO.setCustomizedLibs(customizedLibsBuilder.toString());
-            
         } catch (Exception e) {
-            resultVO.setCode(500);
-            resultVO.setMessage("调用服务失败: " + e.getMessage());
+            throw new RuntimeException("解析失败" + e);
         }
-        
         return resultVO;
     }
 
+    /**
+     * 通用服务调取
+     * @param text 文本
+     * @param service  服务
+     * @param client  客户端
+     * @param riskWordsBuilder 危险词
+     * @param highestRiskLevel 最高危险等级
+     * @throws Exception 错误
+     */
+    private String processTextModeration(Client client, String text, String service, StringBuilder riskWordsBuilder,String highestRiskLevel) throws Exception {
+        // 调用文本检测服务
+        TextModerationResponse response = callTextModeration(client, text, service);
+        if (response != null) {
+            if (response.getStatusCode() == 200) {
+                TextModerationResponseBody result = response.getBody();
+                Integer code = result.getCode();
+                if (code != null && code == 200) {
+                    TextModerationResponseBody.TextModerationResponseBodyData data = result.getData();
+                    String reason = data.getReason();
+                    if (reason != null) {
+                        try {
+                            JSONObject reasonObj = JSON.parseObject(reason);
+                            String riskLevel = reasonObj.getString("riskLevel");
+                            if ("high".equals(riskLevel)) {
+                                highestRiskLevel = riskLevel;
+                                String riskWords = reasonObj.getString("riskWords");
+                                if (riskWords != null && !riskWords.isEmpty()) {
+                                    riskWordsBuilder.append(riskWords).append(",");
+                                }
+                            }
+                        } catch (Exception e) {
+                            // 解析失败,忽略该条原因
+                        }
+                    }
+                }
+            }
+        }
+        return highestRiskLevel;
+    }
+
+    /**
+     * 处理TextModerationPlus服务
+     * @param text 文本
+     * @param service  服务
+     * @param client  客户端
+     * @param riskWordsBuilder 危险词
+     * @param highestRiskLevel 最高危险等级
+     * @throws Exception 错误
+     */
+    private String handleSpecialService(String text, String service, Client client, StringBuilder riskWordsBuilder, String highestRiskLevel) throws Exception {
+        // 调用plus服务并获取响应
+        TextModerationPlusResponse response = callTextModerationPlusService(client, text, service);
+        // 根据response 返回参数处理结果 返回vo所需的参数
+        TextModerationPlusResponseBody body = response.body;
+        TextModerationPlusResponseBody.TextModerationPlusResponseBodyData data = body.getData();
+        if (data != null) {
+            // 分级:riskLevel
+            String riskLevel = data.getRiskLevel();
+            // high:高风险 medium:中风险 low:低风险 none:未检测到风险
+            if ("high".equals(riskLevel)) {
+                highestRiskLevel = riskLevel;
+                List<TextModerationPlusResponseBody.TextModerationPlusResponseBodyDataResult> resultList = data.getResult();
+                for (TextModerationPlusResponseBody.TextModerationPlusResponseBodyDataResult result : resultList) {
+                    // 文字内容检测运算后返回的标签,可能会检出多个标签和分值。
+                    String label = result.getLabel();
+                    // 检测到的敏感词,多个词用逗号分隔,部分标签不会返回敏感词。
+                    String riskWords = result.getRiskWords();
+                    String description = result.getDescription();
+                    if (StringUtils.isNotEmpty(riskWords)){
+                        riskWordsBuilder.append(riskWords).append(",");
+                    }
+                    // 获取 集合 getCustomizedHit 中 所有KeyWords 拼接为字符串并追加到 riskWordsBuilder
+                    if (CollectionUtil.isNotEmpty(result.getCustomizedHit())){
+                        result.getCustomizedHit().forEach(hit -> riskWordsBuilder.append(hit.getKeyWords()).append(","));
+                    }
+                    //置信分值,0到100分,保留到小数点后2位。部分标签无置信分。
+                    Float confidence = result.getConfidence();
+
+                }
+            }
+        }
+        return highestRiskLevel;
+    }
+
+    /**
+     * 调用TextModerationPlus服务
+     * @param text 文本
+     * @param service  服务
+     * @param client  客户端
+     * @return 检测结果
+     * @throws Exception 检测异常
+     */
+    private TextModerationPlusResponse callTextModerationPlusService(Client client, String text, String service) throws Exception {
+        // 包含调取plus服务
+        TextModerationPlusRequest textModerationPlusRequest = new TextModerationPlusRequest();
+        textModerationPlusRequest.setService(service);
+        // 构建服务参数
+        textModerationPlusRequest.setServiceParameters(buildServiceParameters(text));
+        return client.textModerationPlus(textModerationPlusRequest);
+    }
+
+    /**
+     * 调取普通服务
+     * @param text 文本
+     * @param service  服务
+     * @param client  客户端
+     * @return 检测结果
+     * @throws Exception 检测异常
+     */
+    private TextModerationResponse callTextModeration(Client client, String text, String service) throws Exception {
+        // 创建RuntimeObject实例并设置运行参数。
+        RuntimeOptions runtime = new RuntimeOptions();
+        runtime.readTimeout = 10000;
+        runtime.connectTimeout = 10000;
+        //检测参数构造
+        JSONObject serviceParameters = new JSONObject();
+        serviceParameters.put("content", text);
+        // 调取普通服务
+        TextModerationRequest textModerationRequest = new TextModerationRequest();
+        textModerationRequest.setService(service);
+        textModerationRequest.setServiceParameters(serviceParameters.toJSONString());
+        return client.textModerationWithOptions(textModerationRequest, runtime);
+    }
+
+    /**
+     * 提取URL
+     * @param text 文本
+     * @return URL列表
+     */
+    private List<String> extractUrls(String text) {
+        List<String> urls = Lists.newArrayList();
+
+        // 使用改进后的正则表达式匹配URL
+        Pattern urlPattern = Pattern.compile("(https?://\\S+)(:\\d+)?(/\\S*)?");
+
+        Matcher matcher = urlPattern.matcher(text);
+
+        while (matcher.find()) {
+            urls.add(matcher.group());
+        }
+
+        return urls;
+    }
+
 
     private String buildServiceParameters(String text) {
         // 创建服务参数JSON
@@ -167,4 +257,16 @@ public class TextModerationUtil {
         serviceParameters.put("content", text);
         return serviceParameters.toJSONString();
     }
+    /**
+     * 判断服务是否为特殊服务
+     * @param service 服务名称
+     * @return 是否为特殊服务
+     */
+    public static boolean isSpecialService(String service) {
+        return TextReviewServiceEnum.CHAT_DETECTION_PRO.getService().equals(service)
+                || TextReviewServiceEnum.AD_COMPLIANCE_DETECTION_PRO.getService().equals(service)
+                || TextReviewServiceEnum.LLM_QUERY_MODERATION.getService().equals(service)
+                || TextReviewServiceEnum.COMMENT_DETECTION_PRO.getService().equals(service);
+    }
+
 }

+ 45 - 15
alien-util/src/main/java/shop/alien/util/common/safe/TextReviewServiceEnum.java

@@ -1,26 +1,56 @@
 package shop.alien.util.common.safe;
 
-import jdk.nashorn.internal.runtime.logging.Logger;
-import lombok.Getter;
-
 /**
- * @author Alien
- * @date 2021/09/05
+ * @author: alien
+ * @date: 2023/10/31
  */
-@Getter
-@Logger
 public enum TextReviewServiceEnum {
-    SPAM("spam"),
-    AD("ad"),
-    POLITICS("politics"),
-    ABUSE("abuse"),
-    VIOLENCE("violence"),
-    PORNOGRAPHY("pornography");
+    UGC_MODERATION_BY_LLM("ugc_moderation_byllm", "UGC场景文本审核大模型服务", "针对UGC场景,基于大模型能力的文本审核服务,能够高效精准地识别违规内容。", "通用场景"),
+    AIGC_MODERATION_BY_LLM("aigc_moderation_byllm", "AIGC场景文本审核大模型服务", "针对AIGC场景,基于大模型能力的文本审核服务,能够高效精准地识别违规内容。", "AIGC场景"),
+    LLM_QUERY_MODERATION("llm_query_moderation", "大语言模型输入文字检测", "检测大语言模型输入文字中是否存在色情、涉政、暴恐、违禁等红线类的违规内容。", "AIGC场景"),
+    LLM_RESPONSE_MODERATION("llm_response_moderation", "大语言模型生成文字检测", "检测大语言模型生成文字中是否存在色情、涉政、暴恐、违禁等红线类的违规内容。", "AIGC场景"),
+    COMMENT_DETECTION_PRO("comment_detection_pro", "公聊评论内容检测_专业版", "检测公聊评论中是否存在违规、不宜传播或者影响平台秩序的内容。建议对公聊评论场景的文本均进行该项检测。支持更细粒度的标签返回。", "业务场景"),
+    NICKNAME_DETECTION_PRO("nickname_detection_pro", "用户昵称检测_专业版", "检测用户昵称中是否存在违规、不宜传播或者影响平台秩序的内容。建议对用户昵称场景的文本均进行该项检测。支持更细粒度的标签返回。", "业务场景"),
+    CHAT_DETECTION_PRO("chat_detection_pro", "私聊互动内容检测_专业版", "检测私聊互动中是否存在违规、不宜传播或者影响平台秩序的内容。建议对私聊互动场景的文本均进行该项检测。支持更细粒度的标签返回。", "业务场景"),
+    AD_COMPLIANCE_DETECTION_PRO("ad_compliance_detection_pro", "广告法合规检测_专业版", "针对有推广含义的文本(包括商品标题、详情介绍页、投放营销的素材等)进行专门优化,检测是否有违反广告法以及其他违规或不宜传播的内容。支持更细粒度的标签返回。", "特殊场景"),
+    AI_ART_DETECTION("ai_art_detection", "AIGC类文字检测", "检测AIGC文生图中的文字是否存在色情、涉政、暴恐、违禁等红线类的违规内容。", "AIGC场景"),
+    COMMENT_DETECTION("comment_detection", "公聊评论内容检测", "检测公聊评论中是否存在违规、不宜传播或者影响平台秩序的内容。建议对公聊评论场景的文本均进行该项检测。", "业务场景"),
+    NICKNAME_DETECTION("nickname_detection", "用户昵称检测", "检测用户昵称中是否存在违规、不宜传播或者影响平台秩序的内容。建议对用户昵称场景的文本均进行该项检测。", "业务场景"),
+    CHAT_DETECTION("chat_detection", "私聊互动内容检测", "检测私聊互动中是否存在违规、不宜传播或者影响平台秩序的内容。建议对私聊互动场景的文本均进行该项检测。", "业务场景"),
+    AD_COMPLIANCE_DETECTION("ad_compliance_detection", "广告法合规检测", "针对有推广含义的文本(包括商品标题、详情介绍页、投放营销的素材等)进行专门优化,检测是否有违反广告法以及其他违规或不宜传播的内容。", "特殊场景"),
+    COMMENT_MULTILINGUAL_PRO("comment_multilingual_pro", "国际业务多语言检测", "针对多国语言进行检测,识别出文本中包含的违规、不宜传播或者影响平台秩序的内容。", "特殊场景"),
+    PGC_DETECTION("pgc_detection", "PGC通用物料检测", "针对新闻报道、专业视频、教育物料等具有较高制作标准的文本内容,检测判断是否存在违规、不宜传播或者影响平台秩序的内容。", "特殊场景"),
+    BAILIAN_QUERY_CHECK("bailian_query_check", "百炼文字输入检测", "支持对底线类违规(涉黄、涉政、涉暴等)、不良诱导信息的检测,支持对部分诱导性敏感话题进行检测。", "百炼场景"),
+    BAILIAN_RESPONSE_CHECK("bailian_response_check", "百炼文字输出检测", "支持对底线类违规(涉黄、涉政、涉暴等)、不良诱导信息的检测,支持对AI可能产生的辱骂、偏见、不良价值观信息进行检测。", "百炼场景"),
+    BAILIAN_QUERY_CHECK_PRO("bailian_query_check_pro", "百炼文字输入检测_pro", "支持对底线类违规(涉黄、涉政、涉暴等)、不良诱导信息的检测,支持对部分诱导性敏感话题进行检测。在部分场景中,该服务引入了审核大模型用于提升识别效果。", "百炼场景"),
+    BAILIAN_RESPONSE_CHECK_PRO("bailian_response_check_pro", "百炼文字输出检测_pro", "支持对底线类违规(涉黄、涉政、涉暴等)、不良诱导信息的检测,支持对AI可能产生的辱骂、偏见、不良价值观信息进行检测。在部分场景中,该服务引入了审核大模型用于提升识别效果。", "百炼场景"),
+    URL_DETECTION("url_detection", "URL风险链接检测", "支持检测网站是否涉及色情、赌博、钓鱼、欺诈等风险。", "--");
 
     private final String service;
+    private final String serviceName;
+    private final String serviceDescription;
+    private final String serviceScene;
 
-    TextReviewServiceEnum(String service) {
+    TextReviewServiceEnum(String service, String serviceName, String serviceDescription, String serviceScene) {
         this.service = service;
+        this.serviceName = serviceName;
+        this.serviceDescription = serviceDescription;
+        this.serviceScene = serviceScene;
+    }
+
+    public String getService() {
+        return service;
+    }
+
+    public String getServiceName() {
+        return serviceName;
+    }
+
+    public String getServiceDescription() {
+        return serviceDescription;
     }
 
-}
+    public String getServiceScene() {
+        return serviceScene;
+    }
+}