From eacfd189e824b6eec3f789529d8440ade3497148 Mon Sep 17 00:00:00 2001 From: 77 <77@77.com> Date: Sat, 10 Aug 2024 16:13:41 +0800 Subject: [PATCH] =?UTF-8?q?=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/cai/app/AuthAppController.java | 42 +++++++++++-- .../controller/cai/app/RankAppController.java | 9 +++ ruoyi-cai/pom.xml | 5 ++ .../com/ruoyi/cai/auth/RegisterCodeV2.java | 17 ++++++ .../com/ruoyi/cai/config/VerCodeConfig.java | 20 +++++++ .../dto/app/vo/anchor/AnchorStatusDTO.java | 12 ++++ .../cai/dto/app/vo/rank/RankNodeLove.java | 2 + .../com/ruoyi/cai/enums/SystemConfigEnum.java | 1 + .../ruoyi/cai/kit/VerificationCodeCheck.java | 60 +++++++++++++++++++ .../com/ruoyi/cai/mapper/AnchorMapper.java | 6 ++ .../resources/mapper/cai/AnchorMapper.xml | 16 +++++ 11 files changed, 184 insertions(+), 6 deletions(-) create mode 100644 ruoyi-cai/src/main/java/com/ruoyi/cai/auth/RegisterCodeV2.java create mode 100644 ruoyi-cai/src/main/java/com/ruoyi/cai/config/VerCodeConfig.java create mode 100644 ruoyi-cai/src/main/java/com/ruoyi/cai/dto/app/vo/anchor/AnchorStatusDTO.java create mode 100644 ruoyi-cai/src/main/java/com/ruoyi/cai/kit/VerificationCodeCheck.java diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cai/app/AuthAppController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cai/app/AuthAppController.java index 7df95c25..4ffc93fe 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cai/app/AuthAppController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cai/app/AuthAppController.java @@ -3,21 +3,19 @@ package com.ruoyi.web.controller.cai.app; import cn.dev33.satoken.annotation.SaIgnore; import cn.hutool.core.util.PhoneUtil; import com.ruoyi.cai.auth.*; -import com.ruoyi.cai.domain.User; import com.ruoyi.cai.dto.app.vo.LoginVo; import com.ruoyi.cai.enums.CodeEnum; +import com.ruoyi.cai.enums.SystemConfigEnum; +import com.ruoyi.cai.kit.VerificationCodeCheck; import com.ruoyi.cai.manager.CurrentUserManager; import com.ruoyi.cai.manager.LoginAfterManager; -import com.ruoyi.cai.notice.YunxinHttpService; +import com.ruoyi.cai.manager.SystemConfigManager; import com.ruoyi.cai.service.SmsVerifyService; import com.ruoyi.cai.service.UserService; import com.ruoyi.common.annotation.Log; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.enums.BusinessType; -import com.ruoyi.common.exception.ServiceException; -import com.ruoyi.common.helper.LoginHelper; import com.ruoyi.common.utils.ServletUtils; -import com.ruoyi.yunxin.Yunxin; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.extern.slf4j.Slf4j; @@ -29,7 +27,6 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; -import java.util.HashMap; import java.util.Map; @RestController @@ -48,6 +45,10 @@ public class AuthAppController { private UserService userService; @Autowired private CurrentUserManager currentUserManager; + @Autowired + private VerificationCodeCheck verificationCodeCheck; + @Autowired + private SystemConfigManager systemConfigManager; @PostMapping("/register") @Operation(summary = "注册") @@ -66,10 +67,39 @@ public class AuthAppController { private final static String[] headers = new String[]{"X-Forwarded-For", "X-Real-IP", "Proxy-Client-IP", "WL-Proxy-Client-IP", "HTTP_CLIENT_IP", "HTTP_X_FORWARDED_FOR"}; + @PostMapping("/v2/register/code") + @Operation(summary = "获取注册验证码") + @Log(title = "获取注册验证码", businessType = BusinessType.OTHER, isSaveDb = false) + public R> registerCodeV2(@Validated @RequestBody RegisterCodeV2 code){ + boolean check = verificationCodeCheck.check(code.getTicket(), code.getUserIp(), code.getRandStr()); + if(!check){ + return R.fail(600,"验证码错误!"); + } + boolean mobile = PhoneUtil.isMobile(code.getMobile()); + if(!mobile){ + return R.fail(600,"请输入正确的手机格式"); + } + HttpServletRequest request = ServletUtils.getRequest(); + StringBuilder sb = new StringBuilder(); + sb.append("注册验证码IP检测;"); + sb.append("remoteAddr:").append(request.getRemoteAddr()); + for (String header : headers) { + sb.append(header).append(":").append(request.getHeader(header)); + } + log.info(sb.toString()); + smsVerifyService.put(CodeEnum.REGISTER,code.getMobile()); + return R.ok("发送成功"); + } + + @PostMapping("/register/code") @Operation(summary = "获取注册验证码") @Log(title = "获取注册验证码", businessType = BusinessType.OTHER, isSaveDb = false) public R> registerCode(@Validated @RequestBody RegisterCode code){ + boolean openOldRegisterCode = systemConfigManager.getSystemConfigOfBool(SystemConfigEnum.OPEN_OLD_REGISTER_CODE); + if(!openOldRegisterCode){ + return R.fail(600,"验证码发送失败,主动异常"); + } boolean mobile = PhoneUtil.isMobile(code.getMobile()); if(!mobile){ return R.fail(600,"请输入正确的手机格式"); diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cai/app/RankAppController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cai/app/RankAppController.java index 606d39b3..9cbf9a9d 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cai/app/RankAppController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cai/app/RankAppController.java @@ -2,6 +2,7 @@ package com.ruoyi.web.controller.cai.app; import com.ruoyi.cai.domain.User; import com.ruoyi.cai.dto.app.RankIdReq; +import com.ruoyi.cai.dto.app.vo.anchor.AnchorStatusDTO; import com.ruoyi.cai.dto.app.vo.rank.RankRemark; import com.ruoyi.cai.dto.app.vo.rank.RankNodeInvite; import com.ruoyi.cai.dto.app.vo.rank.RankNodeLove; @@ -9,6 +10,7 @@ import com.ruoyi.cai.enums.GenderEnum; import com.ruoyi.cai.enums.SystemConfigEnum; import com.ruoyi.cai.manager.AwardManager; import com.ruoyi.cai.manager.SystemConfigManager; +import com.ruoyi.cai.mapper.AnchorMapper; import com.ruoyi.cai.rank.RankManager; import com.ruoyi.cai.rank.RankNode; import com.ruoyi.cai.service.RankService; @@ -25,6 +27,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; +import javax.annotation.Resource; import java.util.*; import java.util.function.Function; import java.util.regex.Matcher; @@ -47,6 +50,8 @@ public class RankAppController { private AwardManager awardManager; @Autowired private SystemConfigManager systemConfigManager; + @Resource + private AnchorMapper anchorMapper; @GetMapping("/loveRemark") @Operation(summary = "魅力榜榜单说明") @@ -106,6 +111,8 @@ public class RankAppController { Set userIds = rankNodeList.stream().map(RankNode::getUserId).collect(Collectors.toSet()); List userList = userService.listByIds(userIds); Map userMap = userList.stream().collect(Collectors.toMap(User::getId, Function.identity())); + List anchorStatusList = anchorMapper.anchorStatus(userList); + Map anchorStatusMap = anchorStatusList.stream().collect(Collectors.toMap(AnchorStatusDTO::getUserId, Function.identity())); long lastLove = 0; for (int i = 0; i < rankNodeList.size(); i++) { RankNode rankNode = rankNodeList.get(i); @@ -113,10 +120,12 @@ public class RankAppController { if(user == null){ continue; } + AnchorStatusDTO anchorStatus = anchorStatusMap.get(rankNode.getUserId()); RankNodeLove love = new RankNodeLove(); love.setUserId(user.getId()); love.setAvatar(user.getAvatar()); love.setNickname(user.getNickname()); + love.setAnchorStatus(anchorStatus != null ? anchorStatus.getAnchorStatus() : 0); love.setValue(rankNode.getScore()); love.setDraw(rankNode.getDraw() == null || rankNode.getDraw()); love.setRankAwardValue(rankNode.getRankAwardValue()); diff --git a/ruoyi-cai/pom.xml b/ruoyi-cai/pom.xml index c0c90934..b9420771 100644 --- a/ruoyi-cai/pom.xml +++ b/ruoyi-cai/pom.xml @@ -69,5 +69,10 @@ commons-validator 1.6 + + com.tencentcloudapi + tencentcloud-sdk-java + 3.1.360 + diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/auth/RegisterCodeV2.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/auth/RegisterCodeV2.java new file mode 100644 index 00000000..06a50857 --- /dev/null +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/auth/RegisterCodeV2.java @@ -0,0 +1,17 @@ +package com.ruoyi.cai.auth; + +import lombok.Data; + +import javax.validation.constraints.NotEmpty; + +@Data +public class RegisterCodeV2 { + @NotEmpty(message = "手机号不能为空") + private String mobile; + @NotEmpty(message = "腾讯验证码参数[ticket]") + private String ticket; + @NotEmpty(message = "腾讯验证码所属参数[randStr]") + private String randStr; + @NotEmpty(message = "腾讯验证码所属参数[客户端IP]") + private String userIp; +} diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/config/VerCodeConfig.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/config/VerCodeConfig.java new file mode 100644 index 00000000..ce608854 --- /dev/null +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/config/VerCodeConfig.java @@ -0,0 +1,20 @@ +package com.ruoyi.cai.config; + +import lombok.Data; +import lombok.ToString; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Data +@ToString(exclude={"secretKey","appSecretKey"}) +@Configuration +@ConfigurationProperties(prefix = "tencent.captcha") +public class VerCodeConfig { + + private String secretId = "IKIDMabOxIPJ0QgiW5RZr9IGD3jDVdnnZEj4"; + private String secretKey = "KUQFsJXYM0ShhWBi363rX2LTN3WnsjMt"; + + private Long captchaAppId = 189912059L; + private String appSecretKey = "QB0m1JCZjuu0c2fK33wL2HwYg"; + +} diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/dto/app/vo/anchor/AnchorStatusDTO.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/dto/app/vo/anchor/AnchorStatusDTO.java new file mode 100644 index 00000000..81add7da --- /dev/null +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/dto/app/vo/anchor/AnchorStatusDTO.java @@ -0,0 +1,12 @@ +package com.ruoyi.cai.dto.app.vo.anchor; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +public class AnchorStatusDTO { + private Long userId; + private Long anchorId; + @Schema(description = "0=离线 1=空闲/在线 2=忙碌中 3=勿扰") + private Integer anchorStatus; +} diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/dto/app/vo/rank/RankNodeLove.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/dto/app/vo/rank/RankNodeLove.java index 4cc5db80..749c8acf 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/dto/app/vo/rank/RankNodeLove.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/dto/app/vo/rank/RankNodeLove.java @@ -15,6 +15,8 @@ public class RankNodeLove { private String nickname; @Schema(description = "魅力值") private Long value; + @Schema(description = "0=离线 1=空闲/在线 2=忙碌中 3=勿扰") + private Integer anchorStatus; @Schema(description = "距离上一名差距") private Long diffLastValue; @Schema(description = "是否开启隐身模式") diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/enums/SystemConfigEnum.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/enums/SystemConfigEnum.java index ee7cedc3..a17543fd 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/enums/SystemConfigEnum.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/enums/SystemConfigEnum.java @@ -102,6 +102,7 @@ public enum SystemConfigEnum { SYSTEM_CUSTOMER_SERVICE("2,4", "系统客服",SystemConfigGroupEnum.SYSTEM), PRIVACY_AGREEMENT("/#/agreement/privacy", "隐私协议地址",SystemConfigGroupEnum.SYSTEM), USER_AGREEMENT("/#/agreement/user", "用户协议地址",SystemConfigGroupEnum.SYSTEM), + OPEN_OLD_REGISTER_CODE("1", "是否开启无验证码注册接口",SystemConfigGroupEnum.SYSTEM, new BooleanSystemConfigCheck()), ANCHOR_JOIN_AGREEMENT("/#/agreement/anchor-join", "主播入驻协议地址",SystemConfigGroupEnum.SYSTEM), WS_SOCKET_URL("ws://localhost:8080/ws?token=%s&room_id=%s", "ws通讯地址",SystemConfigGroupEnum.SYSTEM), ; diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/kit/VerificationCodeCheck.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/kit/VerificationCodeCheck.java new file mode 100644 index 00000000..1dd7900f --- /dev/null +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/kit/VerificationCodeCheck.java @@ -0,0 +1,60 @@ +package com.ruoyi.cai.kit; + +import com.ruoyi.cai.config.VerCodeConfig; +import com.tencentcloudapi.captcha.v20190722.CaptchaClient; +import com.tencentcloudapi.captcha.v20190722.models.DescribeCaptchaResultRequest; +import com.tencentcloudapi.captcha.v20190722.models.DescribeCaptchaResultResponse; +import com.tencentcloudapi.common.Credential; +import com.tencentcloudapi.common.profile.ClientProfile; +import com.tencentcloudapi.common.profile.HttpProfile; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +@Slf4j +public class VerificationCodeCheck { + + @Autowired + private VerCodeConfig verCodeConfig; + + public boolean check(String ticket,String userIp,String randStr){ + if(StringUtils.isEmpty(ticket) || StringUtils.isEmpty(ticket) || StringUtils.isEmpty(ticket)){ + log.warn("验证码校验参数为空:"); + return false; + } + try { + // 实例化一个认证对象,入参需要传入腾讯云账户secretId,secretKey,此处还需注意密钥对的保密 + // 密钥可前往https://console.cloud.tencent.com/cam/capi网站进行获取 + Credential cred = new Credential(verCodeConfig.getSecretId(), verCodeConfig.getSecretKey()); + // 实例化一个http选项,可选的,没有特殊需求可以跳过 + HttpProfile httpProfile = new HttpProfile(); + httpProfile.setEndpoint("captcha.tencentcloudapi.com"); + // 实例化一个client选项,可选的,没有特殊需求可以跳过 + ClientProfile clientProfile = new ClientProfile(); + clientProfile.setHttpProfile(httpProfile); + // 实例化要请求产品的client对象,clientProfile是可选的 + CaptchaClient client = new CaptchaClient(cred, "", clientProfile); + // 实例化一个请求对象,每个接口都会对应一个request对象 + DescribeCaptchaResultRequest req = new DescribeCaptchaResultRequest(); + req.setCaptchaType(9L); + req.setTicket(ticket); + req.setUserIp(userIp); + req.setRandstr(randStr); + req.setCaptchaAppId(verCodeConfig.getCaptchaAppId()); + req.setAppSecretKey(verCodeConfig.getAppSecretKey()); + // 返回的resp是一个DescribeCaptchaResultResponse的实例,与请求对象对应 + DescribeCaptchaResultResponse resp = client.DescribeCaptchaResult(req); + if(resp.getCaptchaCode() != null && resp.getCaptchaCode() == 1){ + return true; + } + // 输出json格式的字符串回包 + log.warn("验证码校验失败:{}",DescribeCaptchaResultResponse.toJsonString(resp)); + return false; + }catch (Exception e){ + log.error("验证码获取失败",e); + return false; + } + } +} diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/mapper/AnchorMapper.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/mapper/AnchorMapper.java index 0240b274..5069cb18 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/mapper/AnchorMapper.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/mapper/AnchorMapper.java @@ -3,11 +3,15 @@ package com.ruoyi.cai.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.cai.domain.Anchor; +import com.ruoyi.cai.domain.User; import com.ruoyi.cai.dto.admin.vo.AnchorAdminVo; import com.ruoyi.cai.dto.app.query.index.AnchorListQuery; import com.ruoyi.cai.dto.app.vo.AnchorListVo; +import com.ruoyi.cai.dto.app.vo.anchor.AnchorStatusDTO; import org.apache.ibatis.annotations.Param; +import java.util.List; + /** * 女神列表Mapper接口 * @@ -23,4 +27,6 @@ public interface AnchorMapper extends BaseMapper { Page pageAppV2(@Param("build") Page build, @Param("query") AnchorListQuery query); boolean incsServiceTimeAndCount(@Param("toUid") Long toUid, @Param("callTime") Long callTime, @Param("count") int count); + + List anchorStatus(@Param("userList") List userList); } diff --git a/ruoyi-cai/src/main/resources/mapper/cai/AnchorMapper.xml b/ruoyi-cai/src/main/resources/mapper/cai/AnchorMapper.xml index dc915438..0ea3cac1 100644 --- a/ruoyi-cai/src/main/resources/mapper/cai/AnchorMapper.xml +++ b/ruoyi-cai/src/main/resources/mapper/cai/AnchorMapper.xml @@ -121,6 +121,22 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" +