|
|
@@ -1,8 +1,12 @@
|
|
|
package org.dromara.business.service.impl;
|
|
|
|
|
|
import cn.hutool.json.JSONObject;
|
|
|
+import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
|
|
|
+import com.aliyuncs.exceptions.ClientException;
|
|
|
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
+import com.fasterxml.jackson.core.JsonProcessingException;
|
|
|
+import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
import org.dromara.business.domain.PlayerItems;
|
|
|
import org.dromara.business.domain.PlayersItemsLog;
|
|
|
import org.dromara.business.domain.User;
|
|
|
@@ -16,6 +20,8 @@ import org.dromara.business.service.IUserService;
|
|
|
import org.dromara.business.utils.ItemOperationLock;
|
|
|
import org.dromara.business.utils.RedisKeys;
|
|
|
import org.dromara.business.utils.RedisUtil;
|
|
|
+import org.dromara.business.utils.SmsUtil;
|
|
|
+import org.dromara.common.core.domain.R;
|
|
|
import org.dromara.common.core.utils.MapstructUtils;
|
|
|
import org.dromara.common.core.utils.StringUtils;
|
|
|
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
|
|
@@ -29,10 +35,10 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
|
|
|
-import java.util.ArrayList;
|
|
|
-import java.util.List;
|
|
|
-import java.util.Map;
|
|
|
-import java.util.Collection;
|
|
|
+import java.rmi.ServerException;
|
|
|
+import java.util.*;
|
|
|
+import java.util.concurrent.ThreadLocalRandom;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
|
|
|
/**
|
|
|
* 【请填写功能名称】Service业务层处理
|
|
|
@@ -55,6 +61,9 @@ public class UserServiceImpl implements IUserService {
|
|
|
|
|
|
private final PlayersItemsLogMapper playersItemsLogMapper;
|
|
|
|
|
|
+
|
|
|
+ private static final ObjectMapper objectMapper = new ObjectMapper();
|
|
|
+
|
|
|
@Autowired
|
|
|
RedisUtil redisUtil;
|
|
|
|
|
|
@@ -388,6 +397,93 @@ public class UserServiceImpl implements IUserService {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ // 用于存储验证码信息
|
|
|
+ private final Map<String, String> codeStore = new HashMap<>();
|
|
|
+ // 存储验证码过期时间,默认5分钟过期
|
|
|
+ private final Map<String, Long> expireTime = new HashMap<>();
|
|
|
+
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public R<Void> getSmsCode(String phone) {
|
|
|
+ //查看对应手机号是否已经存在了
|
|
|
+ UserVo userVo = baseMapper.selUserPhoneExit(phone);
|
|
|
+ if(userVo!=null){
|
|
|
+ return R.fail("手机号码已被占用!");
|
|
|
+ }
|
|
|
+ String code = generateVerificationCode();
|
|
|
+ codeStore.put(phone, code);
|
|
|
+ expireTime.put(phone, System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(1));
|
|
|
+ try {
|
|
|
+ SendSmsResponse sendSmsResponse = SmsUtil.sendSms(phone, SmsUtil.signName, SmsUtil.templateCode, "{\"code\":\"" + code + "\"}", SmsUtil.ACCESS_KEY_ID, SmsUtil.ACCESS_KEY_SECRET);
|
|
|
+ if ("OK".equals(sendSmsResponse.getCode())) {
|
|
|
+ logger.info("✅ 短信发送成功!");
|
|
|
+ } else {
|
|
|
+ logger.info("❌ 短信发送失败:" + sendSmsResponse.getMessage());
|
|
|
+ return R.fail("短信发送失败");
|
|
|
+ }
|
|
|
+ // 方法1:转换为 JSON 字符串
|
|
|
+ String jsonString = objectMapper.writeValueAsString(sendSmsResponse);
|
|
|
+ logger.info("[SendSmsResponse] 短信发送:{}",jsonString);
|
|
|
+
|
|
|
+ String contact = phone;
|
|
|
+ String smsKey="RuoYi:code:sendObj";
|
|
|
+ String redisKey = smsKey+"_"+contact;
|
|
|
+ // 更新 Redis,记录本次发送的对象
|
|
|
+ redisUtil.set(redisKey, 000000, 60); // 设置过期时间为60秒
|
|
|
+
|
|
|
+ } catch (ServerException | JsonProcessingException e) {
|
|
|
+ throw new RuntimeException(e);
|
|
|
+ } catch (ClientException e) {
|
|
|
+ throw new RuntimeException(e);
|
|
|
+ }
|
|
|
+ logger.info("Sending SMS to " + phone+"----code----"+code);
|
|
|
+
|
|
|
+ return R.ok();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public R<Void> updateUserPhone(UserBo bo) {
|
|
|
+ // 验证验证码(调用验证码校验接口)
|
|
|
+ boolean isValid = this.verifyCode(null,bo.getNewPhone(), bo.getVerifyCode());
|
|
|
+ if(!isValid){
|
|
|
+ return R.fail("验证码错误!");
|
|
|
+ }
|
|
|
+
|
|
|
+ //查看对应手机号是否已经存在了
|
|
|
+ UserVo userVo = baseMapper.selUserPhoneExit(bo.getNewPhone());
|
|
|
+ if(userVo!=null){
|
|
|
+ return R.fail("手机号码已被占用!");
|
|
|
+ }
|
|
|
+
|
|
|
+ User update = new User();
|
|
|
+ update.setId(bo.getId());
|
|
|
+ update.setPhone(bo.getNewPhone());
|
|
|
+ baseMapper.updateUserById(update);
|
|
|
+
|
|
|
+ JSONObject jsonObject = new JSONObject();
|
|
|
+ jsonObject.put("channelType", "login_out");
|
|
|
+ jsonObject.put("value", bo.getId());
|
|
|
+ jsonObject.put("phone", bo.getPhone());
|
|
|
+
|
|
|
+ redisUtil.publish("RuoYi:admin", jsonObject);
|
|
|
+
|
|
|
+ return R.ok();
|
|
|
+ }
|
|
|
+
|
|
|
+ public boolean verifyCode(String email, String phone, String inputCode) {
|
|
|
+ String target = (email != null ? email : phone);
|
|
|
+ String storedCode = codeStore.get(target);
|
|
|
+ Long expiry = expireTime.get(target);
|
|
|
+
|
|
|
+ // 验证码是否存在、是否正确以及是否未过期
|
|
|
+ return storedCode != null && storedCode.equals(inputCode) && expiry != null && expiry > System.currentTimeMillis();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private String generateVerificationCode() {
|
|
|
+ return String.format("%06d", ThreadLocalRandom.current().nextInt(1000000));
|
|
|
+ }
|
|
|
+
|
|
|
// 参数校验
|
|
|
private void validateParams(ItemsUserBo bo) {
|
|
|
if (bo == null || bo.getUserId() == null || bo.getItemId() == null || bo.getQuantity() == null) {
|