From 29e3b787b008444e97ec6712f17328dda378416c Mon Sep 17 00:00:00 2001 From: dzc <2388224167@qq.com> Date: Fri, 7 Nov 2025 17:40:02 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9B=BE=E7=89=87=E6=96=87=E5=AD=97=E8=AF=86?= =?UTF-8?q?=E5=88=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/mysql/recent/member_recent.sql | 22 ++++ .../member/api/thirdauth/ThirdAuthVo.java | 18 +++ .../yudao-module-member-biz/pom.xml | 2 +- .../service/recent/RecentServiceImpl.java | 17 ++- .../service/thirdauth/ThirdAuthService.java | 6 +- .../thirdauth/ThirdAuthServiceImpl.java | 108 ++++++++++++++---- 6 files changed, 143 insertions(+), 30 deletions(-) create mode 100644 yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/thirdauth/ThirdAuthVo.java diff --git a/sql/mysql/recent/member_recent.sql b/sql/mysql/recent/member_recent.sql index 94879bd..a46d06b 100644 --- a/sql/mysql/recent/member_recent.sql +++ b/sql/mysql/recent/member_recent.sql @@ -141,4 +141,26 @@ CREATE TABLE `member_location` `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 32 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '用户位置记录'; + +-- ---------------------------- +-- Table structure for member_location +-- ---------------------------- +DROP TABLE IF EXISTS `member_location`; +CREATE TABLE `member_location` +( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '会员id', + `long` double precision DEFAULT NULL COMMENT '经度', + `lat` double precision DEFAULT NULL COMMENT '纬度', + `province` varchar(64) DEFAULT NULL COMMENT '省', + `city` varchar(64) DEFAULT NULL COMMENT '市', + `district` varchar(64) DEFAULT NULL COMMENT '区', + `address` varchar(256) DEFAULT NULL COMMENT '详细地址', + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', + `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', + PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 32 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '用户位置记录'; \ No newline at end of file diff --git a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/thirdauth/ThirdAuthVo.java b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/thirdauth/ThirdAuthVo.java new file mode 100644 index 0000000..0f4fe27 --- /dev/null +++ b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/thirdauth/ThirdAuthVo.java @@ -0,0 +1,18 @@ +package cn.iocoder.yudao.module.member.api.thirdauth; + +import lombok.Data; + +@Data +public class ThirdAuthVo { + + private Boolean isSuccess = true; + + private String firstErrorMsg; + + private String errorMsg; + + public boolean isError(){ + return !isSuccess; + } + +} diff --git a/yudao-module-member/yudao-module-member-biz/pom.xml b/yudao-module-member/yudao-module-member-biz/pom.xml index 4c32308..5985028 100644 --- a/yudao-module-member/yudao-module-member-biz/pom.xml +++ b/yudao-module-member/yudao-module-member-biz/pom.xml @@ -89,7 +89,7 @@ com.aliyun green20220302 - 2.21.1 + 3.0.1 diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/recent/RecentServiceImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/recent/RecentServiceImpl.java index b17972c..2e014f2 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/recent/RecentServiceImpl.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/recent/RecentServiceImpl.java @@ -5,6 +5,7 @@ import cn.hutool.core.collection.IterUtil; import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.framework.common.util.number.NumberUtils; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.member.api.thirdauth.ThirdAuthVo; import cn.iocoder.yudao.module.member.controller.app.recent.vo.AppRecentLikeReqVo; import cn.iocoder.yudao.module.member.controller.app.recent.vo.AppRecentOperateReqVo; import cn.iocoder.yudao.module.member.dal.dataobject.location.LocationDO; @@ -16,8 +17,6 @@ import cn.iocoder.yudao.module.member.enums.MemberRecentOperateEnum; import cn.iocoder.yudao.module.member.service.location.LocationService; import cn.iocoder.yudao.module.member.service.thirdauth.ThirdAuthService; import cn.iocoder.yudao.module.member.service.user.MemberUserService; -import com.aliyun.green20220302.models.ImageBatchModerationResponseBody; -import com.aliyun.green20220302.models.TextModerationPlusResponseBody; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -81,20 +80,26 @@ public class RecentServiceImpl implements RecentService { recentMapper.insert(recent); // 文字和图片违规处理 - CompletableFuture textFuture = CompletableFuture.supplyAsync(() -> thirdAuthService.textAuditSync(vo.getDescription())); - CompletableFuture imageFuture = CompletableFuture.supplyAsync(() -> thirdAuthService.imageAuditSync(vo.getCoverPic())); + CompletableFuture textFuture = CompletableFuture.supplyAsync(() -> thirdAuthService.textAuditSync(vo.getDescription())); + CompletableFuture imageFuture = CompletableFuture.supplyAsync(() -> thirdAuthService.imageAuditSync(vo.getCoverPic())); try { - TextModerationPlusResponseBody.TextModerationPlusResponseBodyData textRes = textFuture.get(); - ImageBatchModerationResponseBody.ImageBatchModerationResponseBodyData imageRes = imageFuture.get(); + ThirdAuthVo textRes = textFuture.get(); + ThirdAuthVo imageRes = imageFuture.get(); // 处理文字 if (ObjectUtil.isEmpty(textRes)) { throw exception(MemberErrorCode.CHECK_TEXT_NOT_PASS, "未知错误"); } + if (textRes.isError() && ObjectUtil.isNotEmpty(textRes.getFirstErrorMsg())) { + throw exception(MemberErrorCode.CHECK_TEXT_NOT_PASS, textRes.getFirstErrorMsg()); + } // 处理图片 if (ObjectUtil.isEmpty(imageRes)) { throw exception(MemberErrorCode.CHECK_IMAGE_NOT_PASS, "未知错误"); } + if (imageRes.isError() && ObjectUtil.isNotEmpty(imageRes.getFirstErrorMsg())) { + throw exception(MemberErrorCode.CHECK_TEXT_NOT_PASS, imageRes.getFirstErrorMsg()); + } } catch (Exception e) { log.error("|创建朋友圈|,以外的错误error:{}", e.getMessage()); throw new RuntimeException(e.getMessage()); diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/thirdauth/ThirdAuthService.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/thirdauth/ThirdAuthService.java index 0b06576..686ff1a 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/thirdauth/ThirdAuthService.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/thirdauth/ThirdAuthService.java @@ -1,7 +1,7 @@ package cn.iocoder.yudao.module.member.service.thirdauth; +import cn.iocoder.yudao.module.member.api.thirdauth.ThirdAuthVo; import com.aliyun.green20220302.models.ImageBatchModerationResponseBody; -import com.aliyun.green20220302.models.TextModerationPlusResponseBody; /** * @author liusiyang_dxm @@ -12,11 +12,11 @@ public interface ThirdAuthService { /** * 文本审核 */ - TextModerationPlusResponseBody.TextModerationPlusResponseBodyData textAuditSync(String text); + ThirdAuthVo textAuditSync(String text); /** * 图片审核-同步 */ - ImageBatchModerationResponseBody.ImageBatchModerationResponseBodyData imageAuditSync(String imageUrl); + ThirdAuthVo imageAuditSync(String imageUrl); } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/thirdauth/ThirdAuthServiceImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/thirdauth/ThirdAuthServiceImpl.java index ece9047..4d1c686 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/thirdauth/ThirdAuthServiceImpl.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/thirdauth/ThirdAuthServiceImpl.java @@ -1,9 +1,14 @@ package cn.iocoder.yudao.module.member.service.thirdauth; import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.URLUtil; import cn.hutool.json.JSONUtil; +import cn.iocoder.yudao.module.member.api.thirdauth.ThirdAuthVo; +import com.alibaba.fastjson.JSON; import com.aliyun.green20220302.Client; import com.aliyun.green20220302.models.*; +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; @@ -11,9 +16,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import javax.validation.Valid; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; +import java.util.*; /** * 第三方审核 @@ -25,6 +28,11 @@ public class ThirdAuthServiceImpl implements ThirdAuthService { private volatile Client clientInstance; + private final List successRiskLevelList = new ArrayList() {{ + add("low"); + add("none"); + }}; + /** * 初始化第三方审核 */ @@ -38,9 +46,9 @@ public class ThirdAuthServiceImpl implements ThirdAuthService { config.setAccessKeySecret("EVXWFTS2SB6UkjUVFLhTDBfIvIXgI3"); config.setEndpoint("green-cip.cn-shanghai.aliyuncs.com"); //读取时超时时间,单位毫秒(ms) - config.setReadTimeout(6000); + config.setReadTimeout(10_000); //连接时超时时间,单位毫秒(ms) - config.setConnectTimeout(3000); + config.setConnectTimeout(10_000); clientInstance = new Client(config); } catch (Exception e) { e.printStackTrace(); @@ -56,11 +64,13 @@ public class ThirdAuthServiceImpl implements ThirdAuthService { * 文本审核 */ @Override - public TextModerationPlusResponseBody.TextModerationPlusResponseBodyData textAuditSync(String text) { + public ThirdAuthVo textAuditSync(String text) { + ThirdAuthVo resultVo = new ThirdAuthVo(); try { Client client = createClient(); if (ObjectUtil.isEmpty(client)) return null; HashMap query = new HashMap<>(); + query.put("content", text); TextModerationPlusRequest textModerationPlusRequest = new TextModerationPlusRequest(); // 检测类型 textModerationPlusRequest.setService("comment_detection_pro"); @@ -69,12 +79,56 @@ public class ThirdAuthServiceImpl implements ThirdAuthService { if (response.getStatusCode() != 200) { throw new RuntimeException("文本审核失败code:" + response.getStatusCode()); } - TextModerationPlusResponseBody result = response.getBody(); - return result.getData(); + TextModerationPlusResponseBody body = response.getBody(); + if (ObjectUtil.isEmpty(body)) { + throw new RuntimeException("body为null"); + } + TextModerationPlusResponseBody.TextModerationPlusResponseBodyData data = body.getData(); + if (ObjectUtil.isEmpty(data)) { + throw new RuntimeException("data为null"); + } + /* + high:高风险(若命中自定义词库,风险等级默认为高风险) + medium:中风险 + low:低风险 + none:无风险 + */ + if (successRiskLevelList.contains(data.getRiskLevel())) { + resultVo.setIsSuccess(true); + return resultVo; + } + List list = data.getResult(); + if (ObjectUtil.isEmpty(list)) { + throw new RuntimeException("result为null"); + } + StringBuilder errorMsg = new StringBuilder(); + String firstErrorMsg = "你发送的内容"; + for (TextModerationPlusResponseBody.TextModerationPlusResponseBodyDataResult v : list) { + // 检测结果 + String description = v.getDescription(); + // 置信分值 + Float confidence = v.getConfidence(); + // 有问题的词汇 + String riskWords = v.getRiskWords(); + if (confidence >= 80) { + errorMsg.append(String.format("[%s]疑似%s,", riskWords, description)); + } + } + if (ObjectUtil.isNotEmpty(errorMsg)) errorMsg.append("请重新编辑"); + // confidence最大的数据 + TextModerationPlusResponseBody.TextModerationPlusResponseBodyDataResult max = list.stream().max((pren, next) -> next.getConfidence().compareTo(pren.getConfidence())).orElse(null); + if (ObjectUtil.isNotEmpty(max)) { + firstErrorMsg = String.format("你发送的内容[%s]疑似%s,请重新编辑", max.getRiskWords(), max.getDescription()); + } + resultVo.setIsSuccess(false); + resultVo.setErrorMsg(errorMsg.toString()); + resultVo.setFirstErrorMsg(firstErrorMsg); + return resultVo; } catch (Exception e) { e.printStackTrace(); log.error("|文本审核|,意外的错误text:{}error:{}", text, e.getMessage()); - return null; + resultVo.setIsSuccess(true); + return resultVo; } } @@ -82,27 +136,41 @@ public class ThirdAuthServiceImpl implements ThirdAuthService { * 图片审核-同步 */ @Override - public ImageBatchModerationResponseBody.ImageBatchModerationResponseBodyData imageAuditSync(String imageUrl) { + public ThirdAuthVo imageAuditSync(String imageUrl) { + ThirdAuthVo resultVo = new ThirdAuthVo(); try { Client client = createClient(); if (ObjectUtil.isEmpty(client)) return null; RuntimeOptions runtime = new RuntimeOptions(); - Map query = new HashMap<>(); - query.put("imageUrl", imageUrl); - query.put("dataId", UUID.randomUUID().toString()); - ImageBatchModerationRequest imageBatchModerationRequest = new ImageBatchModerationRequest(); - imageBatchModerationRequest.setService("baselineCheck,baselineCheck_pro"); - imageBatchModerationRequest.setServiceParameters(JSONUtil.toJsonStr(query)); - ImageBatchModerationResponse response = client.imageBatchModerationWithOptions(imageBatchModerationRequest, runtime); + Map serviceParameters = new HashMap<>(); + serviceParameters.put("imageUrl", "https://img.alicdn.com/tfs/TB1U4r9AeH2gK0jSZJnXXaT1FXa-2880-480.png"); + serviceParameters.put("dataId", String.valueOf(UUID.randomUUID())); + serviceParameters.put("infoType", "customImage,textInImage,publicFigure"); + ImageModerationRequest imageBatchModerationRequest = new ImageModerationRequest(); + imageBatchModerationRequest.setService("baselineCheck"); + imageBatchModerationRequest.setServiceParameters(JSON.toJSONString(serviceParameters)); + ImageModerationResponse response = client.imageModerationWithOptions(imageBatchModerationRequest, runtime); if (response.getStatusCode() != 200) { throw new RuntimeException("文本审核失败code:" + response.getStatusCode()); } - ImageBatchModerationResponseBody result = response.getBody(); - return result.getData(); + ImageModerationResponseBody body = response.getBody(); + if (ObjectUtil.isEmpty(body)) { + throw new RuntimeException("body为null"); + } + ImageModerationResponseBody.ImageModerationResponseBodyData data = body.getData(); + if (ObjectUtil.isEmpty(data)) { + throw new RuntimeException("data为null"); + } + List list = data.getResult(); + if (ObjectUtil.isEmpty(list)) { + throw new RuntimeException("result为null"); + } + return resultVo; } catch (Exception e) { e.printStackTrace(); log.error("|图片审核-同步|,意外的错误text:{}error:{}", imageUrl, e.getMessage()); - return null; + resultVo.setIsSuccess(true); + return resultVo; } }