|
@@ -1,6 +1,9 @@
|
|
package com.futu.course.user.service.impl;
|
|
package com.futu.course.user.service.impl;
|
|
|
|
|
|
|
|
|
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
import com.futu.course.minio.service.impl.FileServiceImpl;
|
|
import com.futu.course.minio.service.impl.FileServiceImpl;
|
|
import com.futu.course.user.domain.User;
|
|
import com.futu.course.user.domain.User;
|
|
@@ -16,9 +19,16 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
import com.futu.course.common.entity.R;
|
|
import com.futu.course.common.entity.R;
|
|
import com.futu.course.common.utils.SnowflakeIdWorker;
|
|
import com.futu.course.common.utils.SnowflakeIdWorker;
|
|
import com.futu.course.common.utils.TokenUtils;
|
|
import com.futu.course.common.utils.TokenUtils;
|
|
|
|
+import com.futu.course.common.entity.R;
|
|
|
|
+import com.futu.course.common.utils.SnowflakeIdWorker;
|
|
|
|
+import com.futu.course.common.utils.TokenUtils;
|
|
import com.futu.course.user.domain.User;
|
|
import com.futu.course.user.domain.User;
|
|
import com.futu.course.user.dto.LoginDTO;
|
|
import com.futu.course.user.dto.LoginDTO;
|
|
import com.futu.course.user.dto.UserDTO;
|
|
import com.futu.course.user.dto.UserDTO;
|
|
|
|
+import com.futu.course.user.dto.LoginDTO;
|
|
|
|
+import com.futu.course.user.dto.UserDTO;
|
|
|
|
+import com.futu.course.user.dto.UserLoginDto;
|
|
|
|
+import com.futu.course.user.dto.UserRegisterDto;
|
|
import com.futu.course.user.service.UserService;
|
|
import com.futu.course.user.service.UserService;
|
|
import com.futu.course.user.mapper.UserMapper;
|
|
import com.futu.course.user.mapper.UserMapper;
|
|
import io.jsonwebtoken.Jwts;
|
|
import io.jsonwebtoken.Jwts;
|
|
@@ -35,6 +45,23 @@ import org.apache.http.util.EntityUtils;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.data.redis.core.RedisTemplate;
|
|
import org.springframework.data.redis.core.RedisTemplate;
|
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
|
|
|
+import io.jsonwebtoken.Jwts;
|
|
|
|
+import io.jsonwebtoken.SignatureAlgorithm;
|
|
|
|
+import io.jsonwebtoken.security.Keys;
|
|
|
|
+import io.lettuce.core.RedisClient;
|
|
|
|
+import org.apache.commons.codec.binary.Base64;
|
|
|
|
+import org.apache.http.HttpEntity;
|
|
|
|
+import org.apache.http.HttpResponse;
|
|
|
|
+import org.apache.http.client.ClientProtocolException;
|
|
|
|
+import org.apache.http.client.HttpClient;
|
|
|
|
+import org.apache.http.client.methods.HttpGet;
|
|
|
|
+import org.apache.http.impl.client.HttpClients;
|
|
|
|
+import org.apache.http.util.EntityUtils;
|
|
|
|
+import org.redisson.api.RLock;
|
|
|
|
+import org.redisson.api.RedissonClient;
|
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
+import org.springframework.data.redis.core.RedisTemplate;
|
|
|
|
+import org.springframework.data.redis.core.StringRedisTemplate;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.web.bind.annotation.RequestParam;
|
|
import org.springframework.web.bind.annotation.RequestParam;
|
|
import org.springframework.web.multipart.MultipartFile;
|
|
import org.springframework.web.multipart.MultipartFile;
|
|
@@ -51,21 +78,27 @@ import java.security.NoSuchAlgorithmException;
|
|
import java.util.List;
|
|
import java.util.List;
|
|
import java.util.concurrent.TimeUnit;
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
|
|
|
|
+import org.springframework.util.DigestUtils;
|
|
|
|
+
|
|
|
|
+import javax.annotation.Resource;
|
|
|
|
+import javax.crypto.Cipher;
|
|
|
|
+import javax.crypto.SecretKey;
|
|
|
|
+import javax.crypto.spec.IvParameterSpec;
|
|
|
|
+import javax.crypto.spec.SecretKeySpec;
|
|
|
|
+import java.io.IOException;
|
|
|
|
+import java.nio.charset.StandardCharsets;
|
|
|
|
+import java.util.List;
|
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
|
|
|
/**
|
|
/**
|
|
* @author yuu
|
|
* @author yuu
|
|
* @description 针对表【user(用户表)】的数据库操作Service实现
|
|
* @description 针对表【user(用户表)】的数据库操作Service实现
|
|
* @createDate 2025-05-05 18:52:53
|
|
* @createDate 2025-05-05 18:52:53
|
|
-=======
|
|
|
|
-/**
|
|
|
|
-* @author yuu
|
|
|
|
-* @description 针对表【user(用户表)】的数据库操作Service实现
|
|
|
|
-* @createDate 2025-05-07 08:26:30
|
|
|
|
->>>>>>> bba2fa3 ("微信一键登录实现")
|
|
|
|
*/
|
|
*/
|
|
@Service
|
|
@Service
|
|
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
|
|
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
|
|
- implements UserService {
|
|
|
|
|
|
+ implements UserService{
|
|
|
|
+
|
|
|
|
|
|
@Autowired
|
|
@Autowired
|
|
private UserMapper userMapper;
|
|
private UserMapper userMapper;
|
|
@@ -73,6 +106,8 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User>
|
|
@Autowired
|
|
@Autowired
|
|
private RedisTemplate redisTemplate;
|
|
private RedisTemplate redisTemplate;
|
|
|
|
|
|
|
|
+ @Autowired
|
|
|
|
+ private RedissonClient redissonClient;
|
|
|
|
|
|
@Autowired
|
|
@Autowired
|
|
private FileServiceImpl fileService;
|
|
private FileServiceImpl fileService;
|
|
@@ -84,19 +119,21 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User>
|
|
return b?"修改成功":"修改失败";
|
|
return b?"修改成功":"修改失败";
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
// 填写上你的AppID,如何获取AppID自行百度,这步骤很简单
|
|
// 填写上你的AppID,如何获取AppID自行百度,这步骤很简单
|
|
private final static String APP_ID = "wxdbcbc020c8e4b0d9";
|
|
private final static String APP_ID = "wxdbcbc020c8e4b0d9";
|
|
// 填写上你的AppSecret,如何获取AppSecret自行百度,这步骤很简单
|
|
// 填写上你的AppSecret,如何获取AppSecret自行百度,这步骤很简单
|
|
private final static String APP_SECRET = "60efa9e4ff7fae35c7f561de7763da7a";
|
|
private final static String APP_SECRET = "60efa9e4ff7fae35c7f561de7763da7a";
|
|
// 微信小程序登录校验请求地址
|
|
// 微信小程序登录校验请求地址
|
|
private final static String LOGIN_URL = "https://api.weixin.qq.com/sns/jscode2session";
|
|
private final static String LOGIN_URL = "https://api.weixin.qq.com/sns/jscode2session";
|
|
-
|
|
|
|
@Override
|
|
@Override
|
|
public R appLogin(UserDTO dto) {
|
|
public R appLogin(UserDTO dto) {
|
|
|
|
|
|
- SnowflakeIdWorker worker = new SnowflakeIdWorker(1, 1);
|
|
|
|
|
|
+ SnowflakeIdWorker worker=new SnowflakeIdWorker(1,1);
|
|
System.out.println(dto);
|
|
System.out.println(dto);
|
|
- String url = LOGIN_URL + "?appid=" + APP_ID + "&secret=" + APP_SECRET + "&grant_type=authorization_code&js_code=" + dto.getCode();
|
|
|
|
|
|
+ String url = LOGIN_URL + "?appid=" + APP_ID + "&secret="+ APP_SECRET + "&grant_type=authorization_code&js_code=" + dto.getCode();
|
|
HttpClient client = HttpClients.createDefault(); // 创建默认http连接
|
|
HttpClient client = HttpClients.createDefault(); // 创建默认http连接
|
|
HttpGet getRequest = new HttpGet(url);// 创建一个post请求
|
|
HttpGet getRequest = new HttpGet(url);// 创建一个post请求
|
|
LoginDTO loginDTO = new LoginDTO();
|
|
LoginDTO loginDTO = new LoginDTO();
|
|
@@ -108,13 +145,13 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User>
|
|
// 把响应实体转成文本
|
|
// 把响应实体转成文本
|
|
String html = EntityUtils.toString(entity);
|
|
String html = EntityUtils.toString(entity);
|
|
loginDTO = JSON.parseObject(html, LoginDTO.class);
|
|
loginDTO = JSON.parseObject(html, LoginDTO.class);
|
|
- if (null == loginDTO.getErrCode()) {
|
|
|
|
|
|
+ if(null == loginDTO.getErrCode()) {
|
|
dto.setWxId(loginDTO.getOpenid());
|
|
dto.setWxId(loginDTO.getOpenid());
|
|
} else {
|
|
} else {
|
|
- return R.restResult(loginDTO, loginDTO.getErrCode(), loginDTO.getErrMsg());
|
|
|
|
|
|
+ return R.restResult(loginDTO,loginDTO.getErrCode(),loginDTO.getErrMsg());
|
|
}
|
|
}
|
|
List<User> users = userMapper.selectList(new LambdaQueryWrapper<User>().eq(User::getOpenId, dto.getWxId()));
|
|
List<User> users = userMapper.selectList(new LambdaQueryWrapper<User>().eq(User::getOpenId, dto.getWxId()));
|
|
- if (users.size() > 0) {
|
|
|
|
|
|
+ if(users.size() > 0) {
|
|
User user = users.get(0);
|
|
User user = users.get(0);
|
|
// 生成一个 256 位(32 字节)的安全密钥
|
|
// 生成一个 256 位(32 字节)的安全密钥
|
|
SecretKey key = Keys.secretKeyFor(SignatureAlgorithm.HS256);
|
|
SecretKey key = Keys.secretKeyFor(SignatureAlgorithm.HS256);
|
|
@@ -124,9 +161,10 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User>
|
|
.signWith(key)
|
|
.signWith(key)
|
|
.compact();
|
|
.compact();
|
|
user.setToken(jws);
|
|
user.setToken(jws);
|
|
- redisTemplate.opsForValue().set("user", user, 1, TimeUnit.DAYS);
|
|
|
|
|
|
+ redisTemplate.opsForValue().set("user",user,1, TimeUnit.DAYS);
|
|
return R.ok(user);
|
|
return R.ok(user);
|
|
- } else {
|
|
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
User user = new User();
|
|
User user = new User();
|
|
String sessionKey = loginDTO.getSession_key();
|
|
String sessionKey = loginDTO.getSession_key();
|
|
|
|
|
|
@@ -158,7 +196,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User>
|
|
.compact();
|
|
.compact();
|
|
user.setToken(jws);
|
|
user.setToken(jws);
|
|
userMapper.insert(user);
|
|
userMapper.insert(user);
|
|
- redisTemplate.opsForValue().set("user", user, 1, TimeUnit.DAYS);
|
|
|
|
|
|
+ redisTemplate.opsForValue().set("user",user,1, TimeUnit.DAYS);
|
|
return R.ok(user);
|
|
return R.ok(user);
|
|
}
|
|
}
|
|
} catch (ClientProtocolException e) {
|
|
} catch (ClientProtocolException e) {
|
|
@@ -171,12 +209,72 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User>
|
|
|
|
|
|
@Override
|
|
@Override
|
|
public R logout(UserDTO dto) {
|
|
public R logout(UserDTO dto) {
|
|
- if (redisTemplate.opsForValue().get("user") != null) {
|
|
|
|
|
|
+ if (redisTemplate.opsForValue().get("user") != null)
|
|
|
|
+ {
|
|
redisTemplate.delete("user");
|
|
redisTemplate.delete("user");
|
|
}
|
|
}
|
|
return R.ok("登出成功");
|
|
return R.ok("登出成功");
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ @Override
|
|
|
|
+ public R login(UserLoginDto dto) throws InterruptedException {
|
|
|
|
+ RLock lock = redissonClient.getLock(dto.getMobile());
|
|
|
|
+ boolean b = lock.tryLock(3, TimeUnit.SECONDS);
|
|
|
|
+ if (!b)
|
|
|
|
+ {
|
|
|
|
+ return R.failed("请勿重复提交");
|
|
|
|
+ }
|
|
|
|
+ try {
|
|
|
|
+ User user = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getMobile, dto.getMobile()));
|
|
|
|
+ if (user == null)
|
|
|
|
+ {
|
|
|
|
+ return R.restResult(null,500,"用户不存在");
|
|
|
|
+ }
|
|
|
|
+ String salt = user.getSalt();
|
|
|
|
+ String password = dto.getPassword();
|
|
|
|
+ String hex = DigestUtils.md5DigestAsHex((salt + password).getBytes());
|
|
|
|
+ if (hex.equals(user.getPassword()))
|
|
|
|
+ {
|
|
|
|
+ // 生成一个 256 位(32 字节)的安全密钥
|
|
|
|
+ SecretKey key = Keys.secretKeyFor(SignatureAlgorithm.HS256);
|
|
|
|
+ // 使用密钥生成 JWT
|
|
|
|
+ String jws = Jwts.builder()
|
|
|
|
+ .setSubject(user.getId().toString())
|
|
|
|
+ .signWith(key)
|
|
|
|
+ .compact();
|
|
|
|
+ user.setToken(jws);
|
|
|
|
+ redisTemplate.opsForValue().set("user",user,1, TimeUnit.DAYS);
|
|
|
|
+ return R.ok(user);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }catch (Exception e)
|
|
|
|
+ {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ throw e;
|
|
|
|
+ }finally {
|
|
|
|
+ if (lock.isLocked()&&lock.isHeldByCurrentThread())
|
|
|
|
+ {
|
|
|
|
+ lock.unlock();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+// @Override
|
|
|
|
+// public R register(UserRegisterDto dto) {
|
|
|
|
+// SnowflakeIdWorker worker=new SnowflakeIdWorker(1,1);
|
|
|
|
+// if (redisTemplate.opsForValue().get("user") != null)
|
|
|
|
+// {
|
|
|
|
+// return R.failed("用户已存在");
|
|
|
|
+// }
|
|
|
|
+// try {
|
|
|
|
+// User user = new User();
|
|
|
|
+// user.setId(worker.nextId());
|
|
|
|
+// }
|
|
|
|
+//
|
|
|
|
+// return null;
|
|
|
|
+// }
|
|
|
|
+
|
|
|
|
|
|
public static String decryptData(String encryptedData, String sessionKey, String iv) throws Exception {
|
|
public static String decryptData(String encryptedData, String sessionKey, String iv) throws Exception {
|
|
// Base64 解码
|
|
// Base64 解码
|
|
@@ -194,9 +292,25 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User>
|
|
byte[] decryptedBytes = cipher.doFinal(encryptedDataBytes);
|
|
byte[] decryptedBytes = cipher.doFinal(encryptedDataBytes);
|
|
return new String(decryptedBytes, StandardCharsets.UTF_8);
|
|
return new String(decryptedBytes, StandardCharsets.UTF_8);
|
|
}
|
|
}
|
|
-}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|