完善c端登录

This commit is contained in:
menxipeng
2025-07-14 23:21:19 +08:00
parent 05403e3485
commit 121448abc4
18 changed files with 555 additions and 56 deletions

View File

@@ -0,0 +1,66 @@
package com.ruoyi.system.config;
import com.aliyun.dysmsapi20170525.Client;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.aliyun.teaopenapi.models.Config;
import com.ruoyi.common.core.domain.entity.ShopUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static com.alibaba.fastjson2.JSONObject.toJSONString;
public class AliConfig {
private static final Logger log = LoggerFactory.getLogger(AliConfig.class);
public static Client createClient() {
Config config = new Config()
// 配置 AccessKey ID请确保代码运行环境配置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。
.setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"))
// 配置 AccessKey Secret请确保代码运行环境配置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
.setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
// System.getenv()方法表示获取系统环境变量不要直接在getenv()中填入AccessKey信息。
// 配置 Endpoint。中国站请使用dysmsapi.aliyuncs.com
config.endpoint = "dysmsapi.aliyuncs.com";
try {
return new Client(config);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static String sendMsg(ShopUser shopUser) {
// 初始化请求客户端
Client client = AliConfig.createClient();
// 1. 生成6位验证码
String code = String.valueOf((int)((Math.random()*9+1)*100000));
String templateParam = "{\"name\":\"" + shopUser.getUsername() + "\",\"number\":\""+ shopUser.getPhone() +"\"}";
// 构造API请求对象请替换请求参数值
SendSmsRequest sendSmsRequest = new SendSmsRequest()
.setPhoneNumbers(shopUser.getPhone())
.setSignName("music")
.setTemplateCode(code)
.setTemplateParam(templateParam); // TemplateParam为序列化后的JSON字符串。
// 获取响应对象
SendSmsResponse sendSmsResponse;
try {
sendSmsResponse = client.sendSms(sendSmsRequest);
} catch (Exception e) {
throw new RuntimeException(e);
}
log.info("aliyun 发送验证码返回信息:{}", toJSONString(sendSmsResponse));
if (sendSmsResponse.getStatusCode() == 200){
return code;
}
return null;
}
}

View File

@@ -0,0 +1,110 @@
package com.ruoyi.system.config;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.utils.uuid.UUID;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.http.Header;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
@Component
public class UmengConfig {
public CloseableHttpResponse send(String token){
String umAppkey = "xxxx";
String appKey = "5df88f83570df3b8d40012337";
String appSecret = "xxxx";
// 下面的url要和阿里云云市场购买的商品对应
String url = "https://verify5.market.alicloudapi.com/api/v1/mobile/info?appkey=" + umAppkey;
HttpPost httpPost = new HttpPost(url);
/**
* body
*/
JSONObject object = new JSONObject();
object.put("token", token);
StringEntity stringEntity = new StringEntity(object.toJSONString(), StandardCharsets.UTF_8);
httpPost.setEntity(stringEntity);
/**
* header
*/
httpPost.setHeader("Content-Type", "application/json; charset=UTF-8");
httpPost.setHeader("Accept", "application/json");
httpPost.setHeader("X-Ca-Version", "1");
httpPost.setHeader("X-Ca-Signature-Headers", "X-Ca-Version,X-Ca-Stage,X-Ca-Key,X-Ca-Timestamp");
httpPost.setHeader("X-Ca-Stage", "RELEASE");
httpPost.setHeader("X-Ca-Key", appKey);
httpPost.setHeader("X-Ca-Timestamp", String.valueOf(System.currentTimeMillis()));
httpPost.setHeader("X-Ca-Nonce", UUID.randomUUID().toString());
httpPost.setHeader("Content-MD5", Base64.encodeBase64String(DigestUtils.md5(object.toJSONString())));
/**
* sign
*/
String stringToSign = getSignString(httpPost);
Mac hmacSha256;
try {
hmacSha256 = Mac.getInstance("HmacSHA256");
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
byte[] keyBytes = appSecret.getBytes(StandardCharsets.UTF_8);
try {
hmacSha256.init(new SecretKeySpec(keyBytes, 0, keyBytes.length, "HmacSHA256"));
} catch (InvalidKeyException e) {
throw new RuntimeException(e);
}
String sign = new String(Base64.encodeBase64(hmacSha256.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8))));
httpPost.setHeader("X-Ca-Signature", sign);
/**
* execute
*/
CloseableHttpClient httpclient = HttpClients.createDefault();
try {
CloseableHttpResponse response = httpclient.execute(httpPost);
return response;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static void main(String[] args) throws InvalidKeyException, NoSuchAlgorithmException {
}
private static String getSignString(HttpPost httpPost) {
Header[] headers = httpPost.getAllHeaders();
Map<String, String> map = new HashMap<>();
for (Header header : headers) {
map.put(header.getName(), header.getValue());
}
return httpPost.getMethod() + "\n" +
map.get("Accept") + "\n" +
map.get("Content-MD5") + "\n" +
map.get("Content-Type") + "\n\n" +
"X-Ca-Key:" + map.get("X-Ca-Key") + "\n" +
"X-Ca-Stage:" + map.get("X-Ca-Stage") + "\n" +
"X-Ca-Timestamp:" + map.get("X-Ca-Timestamp") + "\n" +
"X-Ca-Version:" + map.get("X-Ca-Version") + "\n" +
httpPost.getURI().getPath() + "?" + httpPost.getURI().getQuery();
}
}

View File

@@ -9,5 +9,13 @@ import org.apache.ibatis.annotations.Select;
@Mapper
public interface ShopUserMapper {
ShopUser selectShopUserByPhone(@Param("username") String username);
ShopUser selectShopUserByPhone(@Param("phone") String phone);
ShopUser selectShopUserByUsername(@Param("username") String username);
ShopUser selectShopUserByUsernameAndPass(@Param("username") String username,@Param("password") String password);
int insert(ShopUser shopUser);
}

View File

@@ -0,0 +1,9 @@
package com.ruoyi.system.service;
import com.ruoyi.common.core.domain.entity.ShopUser;
public interface AliConfigService {
String sendMsg(ShopUser shopUser);
}

View File

@@ -1,13 +1,5 @@
package com.ruoyi.system.service;
import org.apache.tomcat.jni.File;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.UnsupportedAudioFileException;
import java.io.IOException;
public interface MusicHandleService {

View File

@@ -0,0 +1,10 @@
package com.ruoyi.system.service;
import com.ruoyi.common.core.domain.entity.ShopUser;
import com.ruoyi.common.core.domain.entity.ShopUserResq;
public interface ShopUserService {
ShopUser login(ShopUserResq shopUser);
}

View File

@@ -0,0 +1,35 @@
package com.ruoyi.system.service.impl;
import com.aliyun.dysmsapi20170525.Client;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.ruoyi.common.core.domain.entity.ShopUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.system.config.AliConfig;
import com.ruoyi.system.service.AliConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Transactional
@Service
public class AliConfigServiceImpl implements AliConfigService {
@Autowired
private RedisCache redisCache;
@Override
public String sendMsg(ShopUser shopUser) {
String phone = shopUser.getPhone();
if (phone == null || phone.isEmpty()) {
return "手机号不能为空";
}
// 1. 生成6位验证码
String code = AliConfig.sendMsg(shopUser);
if (code != null){
// 2. 存入Redis5分钟有效
redisCache.setCacheObject("sms_code:" + phone, code, 5, java.util.concurrent.TimeUnit.MINUTES);
}
return code;
}
}

View File

@@ -0,0 +1,82 @@
package com.ruoyi.system.service.impl;
import cn.hutool.core.util.IdUtil;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.entity.ShopUser;
import com.ruoyi.common.core.domain.entity.ShopUserResq;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.config.UmengConfig;
import com.ruoyi.system.mapper.ShopUserMapper;
import com.ruoyi.system.service.ShopUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Transactional
@Service
public class ShopUserServiceImpl implements ShopUserService {
@Autowired
private RedisCache redisCache;
@Autowired
private UmengConfig umengConfig;
@Autowired
private ShopUserMapper shopUserMapper;
@Override
public ShopUser login(ShopUserResq shopUser) {
switch (shopUser.getMethod()){
case "1":
// 账号密码
// 生成令牌
ShopUser member = shopUserMapper.selectShopUserByUsernameAndPass(shopUser.getUsername(),shopUser.getPassword());
if (member == null){
ShopUser msg = new ShopUser();
msg.setMsg("用户名或密码错误");
return msg;
}else {
return member;
}
case "2":
// 验证码
String code = redisCache.getCacheObject(shopUser.getPhone());
String reqCode = shopUser.getCode();
if (code.equals(reqCode)){
// 登录
return loginAndRegis(shopUser);
}else {
ShopUser msg = new ShopUser();
msg.setMsg("验证码错误");
return msg;
}
case "3":
// 一键 todo 完善功能
String uMtoken = shopUser.getUMtoken();
umengConfig.send(uMtoken);
break;
}
return null;
}
public ShopUser loginAndRegis(ShopUserResq shopUser) {
ShopUser member = shopUserMapper.selectShopUserByPhone(shopUser.getUsername());
if (StringUtils.isNull(member)) {
// 走注册在登录
member = new ShopUser();
member.setUserId(IdUtil.getSnowflakeNextId());
member.setUsername(shopUser.getPhone());
member.setPhone(shopUser.getPhone());
member.setPassword(IdUtil.fastUUID());
member.setUsername(shopUser.getUsername());
int insertCount = shopUserMapper.insert(member);
if (insertCount > 0){
return member;
}else {
return null;
}
}
return member;
}
}

View File

@@ -3,6 +3,49 @@
<mapper namespace="com.ruoyi.system.mapper.ShopUserMapper">
<select id="selectShopUserByPhone" resultType="com.ruoyi.common.core.domain.entity.ShopUser">
SELECT * FROM shop_user where userName = #{username}
SELECT * FROM shop_user where phone = #{phone}
</select>
<select id="selectShopUserByUsername" resultType="com.ruoyi.common.core.domain.entity.ShopUser">
SELECT * FROM shop_user where username = #{username}
</select>
<select id="selectShopUserByUsernameAndPass" resultType="com.ruoyi.common.core.domain.entity.ShopUser">
SELECT * FROM shop_user where username = #{username} and password = #{password}
</select>
<!-- Insert -->
<insert id="insert" parameterType="com.ruoyi.common.core.domain.entity.ShopUser" useGeneratedKeys="true" keyProperty="id">
INSERT INTO shop_user
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="userId != null">user_id,</if>
<if test="username != null">username,</if>
<if test="password != null">password,</if>
<if test="phone != null">phone,</if>
<if test="nickname != null">nickname,</if>
<if test="sex != null">sex,</if>
<if test="birthday != null">birthday,</if>
<if test="addr != null">addr,</if>
<if test="registerTime != null">register_time,</if>
<if test="status != null">status,</if>
<if test="vip != null">vip,</if>
<if test="online != null">online,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="userId != null">#{userId},</if>
<if test="username != null">#{username},</if>
<if test="password != null">#{password},</if>
<if test="phone != null">#{phone},</if>
<if test="nickname != null">#{nickname},</if>
<if test="sex != null">#{sex},</if>
<if test="birthday != null">#{birthday},</if>
<if test="addr != null">#{addr},</if>
<if test="registerTime != null">#{registerTime},</if>
<if test="status != null">#{status},</if>
<if test="vip != null">#{vip},</if>
<if test="online != null">#{online},</if>
</trim>
</insert>
</mapper>