From 568cf4a9be21555654d143add4643658972e29f5 Mon Sep 17 00:00:00 2001 From: huk Date: Sat, 20 Sep 2025 18:01:58 +0800 Subject: [PATCH] =?UTF-8?q?feat(member):=20=E5=A2=9E=E5=8A=A0=E7=A7=BB?= =?UTF-8?q?=E5=8A=A8=E7=AB=AF=E7=BB=99=E5=BD=93=E5=89=8D=E7=99=BB=E5=BD=95?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E6=89=8B=E6=9C=BA=E7=9F=AD=E4=BF=A1=E9=AA=8C?= =?UTF-8?q?=E8=AF=81=E7=A0=81=E5=8F=91=E9=80=81=E4=B8=8E=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E6=B3=A8=E9=94=80=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/dromara/app/AppMemberController.java | 22 +++++++++++++ .../dromara/web/service/SysLoginService.java | 1 + .../common/core/domain/event/Constants.java | 2 +- .../common/core/domain/model/LoginUser.java | 5 +++ .../member/mapper/MemberAccountMapper.java | 3 +- .../member/mapper/MemberCartMapper.java | 2 ++ .../soopin/member/service/IMemberService.java | 12 +++++++ .../service/impl/MemberServiceImpl.java | 32 +++++++++++++++++++ 8 files changed, 77 insertions(+), 2 deletions(-) diff --git a/ruoyi-admin/src/main/java/org/dromara/app/AppMemberController.java b/ruoyi-admin/src/main/java/org/dromara/app/AppMemberController.java index 3ca5335e5..3d2ec076a 100644 --- a/ruoyi-admin/src/main/java/org/dromara/app/AppMemberController.java +++ b/ruoyi-admin/src/main/java/org/dromara/app/AppMemberController.java @@ -41,6 +41,7 @@ import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.utils.ValidatorUtils; import org.dromara.common.log.annotation.Log; import org.dromara.common.log.enums.BusinessType; +import org.dromara.common.ratelimiter.annotation.RateLimiter; import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.common.social.config.properties.SocialProperties; import org.dromara.common.social.utils.SocialUtils; @@ -203,4 +204,25 @@ public class AppMemberController { } + + @RateLimiter(key = "#phonenumber", time = 60, count = 1) + @GetMapping("/sms/code") + @Operation(summary = "给当前登录会员的手机号发送短信验证码") + public R smsCode(@RequestParam String templateId) { + service.smsCode(templateId); + return R.ok(); + } + + + + @Operation(summary = "用户注销") + @Log(title = "用户注销 ", businessType = BusinessType.UPDATE) + @PostMapping("/revoked") + public R revoked(@RequestParam String smsCode) { + service.revoked(smsCode); + return R.ok(); + } + + + } diff --git a/ruoyi-admin/src/main/java/org/dromara/web/service/SysLoginService.java b/ruoyi-admin/src/main/java/org/dromara/web/service/SysLoginService.java index bfcc1ac56..505b6d31e 100644 --- a/ruoyi-admin/src/main/java/org/dromara/web/service/SysLoginService.java +++ b/ruoyi-admin/src/main/java/org/dromara/web/service/SysLoginService.java @@ -195,6 +195,7 @@ public class SysLoginService { loginUser.setNickname(member.getNickname()); loginUser.setUserType(UserType.APP_USER.getUserType()); loginUser.setUserSig(member.getUserSig()); + loginUser.setPhoneNumber(member.getPhoneHidden()); return loginUser; } diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/event/Constants.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/event/Constants.java index 6e3f10b34..aeea6d1ac 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/event/Constants.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/event/Constants.java @@ -82,7 +82,7 @@ public class Constants /** * 验证码有效期(分钟) */ - public static final Integer CAPTCHA_EXPIRATION = 2; + public static final Integer CAPTCHA_EXPIRATION = 5; /** * 令牌 diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/LoginUser.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/LoginUser.java index 17ba1ca59..7a4066eee 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/LoginUser.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/LoginUser.java @@ -107,6 +107,11 @@ public class LoginUser implements Serializable { */ private String nickname; + /** + * 用户手机号 + */ + private String phoneNumber; + /** * 角色对象 */ diff --git a/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/mapper/MemberAccountMapper.java b/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/mapper/MemberAccountMapper.java index c59db44ca..7c806de12 100644 --- a/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/mapper/MemberAccountMapper.java +++ b/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/mapper/MemberAccountMapper.java @@ -6,17 +6,18 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.wzj.soopin.member.domain.bo.MemberAccountBO; import com.wzj.soopin.member.domain.po.MemberAccount; import com.wzj.soopin.member.domain.vo.MemberAccountVO; +import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; import java.math.BigDecimal; -import java.util.List; /** * 会员账户表Mapper接口 * * @author zcc */ +@Mapper public interface MemberAccountMapper extends BaseMapper { IPage selectAccountWithMember(Page page, @Param("bo") MemberAccountBO bo); diff --git a/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/mapper/MemberCartMapper.java b/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/mapper/MemberCartMapper.java index 0a6559792..5f259471d 100644 --- a/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/mapper/MemberCartMapper.java +++ b/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/mapper/MemberCartMapper.java @@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.wzj.soopin.member.domain.po.MemberCart; import com.wzj.soopin.member.domain.bo.MemberCartBO; import com.wzj.soopin.member.domain.vo.MemberCartVO; +import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import java.time.LocalDateTime; @@ -14,6 +15,7 @@ import java.util.List; * * @author zcc */ +@Mapper public interface MemberCartMapper extends BaseMapper { /** * 查询购物车列表 diff --git a/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/service/IMemberService.java b/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/service/IMemberService.java index 9cbd92d49..704518e5d 100644 --- a/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/service/IMemberService.java +++ b/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/service/IMemberService.java @@ -94,4 +94,16 @@ public interface IMemberService extends IService { * @return */ Page getByReference(ReferenceMemberQuery query); + + /** + * 给当前登录会员的手机号发送短信验证码 + * @param templateId + */ + void smsCode(String templateId); + + /** + * 账号注销 + * @param smsCode 短信验证码 + */ + void revoked(String smsCode); } diff --git a/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/service/impl/MemberServiceImpl.java b/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/service/impl/MemberServiceImpl.java index 6628d96aa..e9fc8ef3f 100644 --- a/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/service/impl/MemberServiceImpl.java +++ b/ruoyi-modules/ruoyi-member/src/main/java/com/wzj/soopin/member/service/impl/MemberServiceImpl.java @@ -4,6 +4,7 @@ import cn.dev33.satoken.secure.BCrypt; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.date.LocalDateTimeUtil; import cn.hutool.core.lang.Assert; +import cn.hutool.core.util.RandomUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONArray; import cn.hutool.json.JSONObject; @@ -31,11 +32,16 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.dromara.common.core.constant.GlobalConstants; import org.dromara.common.core.constant.ResultCode; +import org.dromara.common.core.domain.event.Constants; import org.dromara.common.core.domain.model.LoginUser; import org.dromara.common.core.exception.ServiceException; import org.dromara.common.redis.redis.RedisCache; +import org.dromara.common.redis.utils.RedisUtils; import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.common.tenant.helper.TenantHelper; +import org.dromara.sms4j.api.SmsBlend; +import org.dromara.sms4j.api.entity.SmsResponse; +import org.dromara.sms4j.core.factory.SmsFactory; import org.dromara.system.domain.SysUser; import org.dromara.system.domain.vo.SysTenantVo; import org.dromara.system.mapper.SysUserMapper; @@ -46,6 +52,7 @@ import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import java.io.Serializable; +import java.time.Duration; import java.time.LocalDateTime; import java.util.*; import java.util.stream.Collectors; @@ -376,4 +383,29 @@ public class MemberServiceImpl extends ServiceImpl implemen objectPage.setRecords(list); return objectPage; } + + @Override + public void smsCode(String templateId) { + String phoneNumber = LoginHelper.getLoginUser().getPhoneNumber(); + String key = GlobalConstants.CAPTCHA_CODE_KEY + phoneNumber; + String code = RandomUtil.randomNumbers(4); + RedisUtils.setCacheObject(key, code, Duration.ofMinutes(Constants.CAPTCHA_EXPIRATION)); + LinkedHashMap map = new LinkedHashMap<>(1); + map.put("code", code); + SmsBlend smsBlend = SmsFactory.getSmsBlend("config2"); + SmsResponse smsResponse = smsBlend.sendMessage(phoneNumber, templateId, map); + if (!smsResponse.isSuccess()) { + log.error("短信验证码发送异常 => {}", smsResponse); + throw new ServiceException("短信验证码发送异常"); + } + } + + @Override + public void revoked(String smsCode) { + LoginUser loginUser = LoginHelper.getLoginUser(); + String phoneNumber = loginUser.getPhoneNumber(); + String code = RedisUtils.getCacheObject(GlobalConstants.CAPTCHA_CODE_KEY + phoneNumber); + Assert.isTrue(StrUtil.equals(smsCode, code), () -> new ServiceException("短信验证码错误")); + memberMapper.updateById(Member.builder().id(loginUser.getUserId()).status(Constants.MEMBER_ACCOUNT_STATUS.FORBIDDEN).build()); + } }