用户注册、登录、注销、信息获取

This commit is contained in:
Ethereal 2024-04-10 10:48:38 +08:00
parent c21397e8a4
commit 9027f82f4b
8 changed files with 659 additions and 15 deletions

View File

@ -8,4 +8,20 @@ package com.example.catchTheLetters.constant;
*/
public interface CommonConstant {
String TOKEN_SECRET = "sadao_idfdv_uvnbdson_wd01jsdnvcz";
Integer TOKEN_EXPIRE_TIME = 7200000;
Integer REDIS_EXPIRE_TIME = 7*24*60*60*1000;
String EMAIL_REGEX = "^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$";
String PHONE_REGEX = "^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\\d{8}$";
String EMAIL = "email";
String PHONE = "phone";
String USERNAME = "username";
String STATUS = "status";
}

View File

@ -3,6 +3,7 @@ package com.example.catchTheLetters.controller;
import com.example.catchTheLetters.entity.LoginDto;
import com.example.catchTheLetters.entity.RegisterDto;
import com.example.catchTheLetters.entity.User;
import com.example.catchTheLetters.model.vo.UserVo;
import com.example.catchTheLetters.service.AuthService;
import com.example.catchTheLetters.utils.R;
import io.swagger.annotations.Api;
@ -10,6 +11,7 @@ import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.math3.genetics.Fitness;
import org.springframework.web.bind.annotation.*;
/**
@ -28,7 +30,7 @@ public class AuthController {
@ApiOperation(value = "用户登录")
@PostMapping("/login")
public R<String> login(@RequestBody LoginDto loginDto) {
return R.ok(authService.login(loginDto));
return authService.login(loginDto);
}
@ApiOperation(value = "用户注销")
@ -45,15 +47,18 @@ public class AuthController {
@ApiOperation(value = "用户注册")
@PostMapping("/register")
public R<String> register(@RequestBody RegisterDto registerDto) {
return R.ok(authService.register(registerDto));
public R<UserVo> register(@RequestBody RegisterDto registerDto) {
return authService.register(registerDto);
}
@ApiOperation(value = "用户信息查询不会返回密码查不出status为0的用户")
@GetMapping("/info")
@ApiParam(name = "id", value = "用户ID不传就是拿token查自己")
public R<User> info(@RequestParam(required = false) Long id) {
return null;
public R<User> info(@RequestParam(required = false) Integer id, @RequestHeader("token")String token) {
if (id != null){
return R.ok(authService.getUserInfo(id));
}
return R.ok(authService.verify(token));
}
@ApiOperation(value = "用户信息修改")

View File

@ -1,5 +1,6 @@
package com.example.catchTheLetters.entity;
import com.example.catchTheLetters.model.vo.UserVo;
import lombok.Data;
import java.io.Serializable;
@ -13,7 +14,7 @@ public class User implements Serializable {
/**
* 用户ID
*/
private Long id;
private Integer id;
/**
* 用户名
*/
@ -66,4 +67,18 @@ public class User implements Serializable {
* 当前游戏进度关卡ID
*/
private Integer progress;
public UserVo toVo(){
UserVo userVo = new UserVo();
userVo.setId(this.getId());
userVo.setUsername(this.getUsername());
userVo.setSex(this.sex);
userVo.setAvatar(this.avatar);
userVo.setEmail(this.email);
userVo.setPhone(this.phone);
userVo.setStatus(this.status);
userVo.setIntroduction(this.introduction);
userVo.setProgress(this.progress);
return userVo;
}
}

View File

@ -0,0 +1,59 @@
package com.example.catchTheLetters.model.vo;
import lombok.Data;
import java.io.Serializable;
/**
* @author 慕华
* @date 2024/4/10
* @Version 1.0
* @description
*/
@Data
public class UserVo implements Serializable {
/**
* 用户ID
*/
private Integer id;
/**
* 用户名
*/
private String username;
/**
* 性别
* -0未知
* -1
* -2
*/
private int sex;
/**
* 头像
*/
private String avatar;
/**
* 邮箱
*/
private String email;
/**
* 手机号
*/
private String phone;
/**
* 状态
* -0已注销逻辑删除
* -1在线
* -2离线
* -3封禁
* -4未激活未验证邮箱或手机号
*/
private Integer status;
/**
* 个人介绍
*/
private String introduction;
/**
* 当前游戏进度关卡ID
*/
private Integer progress;
}

View File

@ -3,6 +3,8 @@ package com.example.catchTheLetters.service;
import com.example.catchTheLetters.entity.LoginDto;
import com.example.catchTheLetters.entity.RegisterDto;
import com.example.catchTheLetters.entity.User;
import com.example.catchTheLetters.model.vo.UserVo;
import com.example.catchTheLetters.utils.R;
/**
* 认证服务接口
@ -14,7 +16,7 @@ public interface AuthService {
* @param loginDto 登录信息
* @return token
*/
String login(LoginDto loginDto);
R<String> login(LoginDto loginDto);
/**
* 注销
@ -35,5 +37,19 @@ public interface AuthService {
* @param registerDto 注册信息
* @return token
*/
String register(RegisterDto registerDto);
R<UserVo> register(RegisterDto registerDto);
/**
* 获取用户信息
* @param id 用户id
* @return 用户信息
*/
User getUserInfo(Integer id);
/**
* 通过用户名获取信息
* @param username 用户名
* @return 用户信息
*/
User getUserByName(String username);
}

View File

@ -0,0 +1,127 @@
package com.example.catchTheLetters.service;
import org.springframework.data.domain.Sort;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.GeoResults;
import org.springframework.data.geo.Point;
import org.springframework.data.redis.connection.RedisGeoCommands;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @author 慕华
* @date 2024/4/10
* @Version 1.0
* @description
*/
public interface RedisService {
void set(String key, Object value, long time);
void set(String key, Object value);
Object get(String key);
Boolean del(String key);
Long del(List<String> keys);
Boolean expire(String key, long time);
Long getExpire(String key);
Boolean hasKey(String key);
Long incr(String key, long delta);
Long incrExpire(String key, long time);
Long decr(String key, long delta);
Object hGet(String key, String hashKey);
Boolean hSet(String key, String hashKey, Object value, long time);
void hSet(String key, String hashKey, Object value);
Map<String, Object> hGetAll(String key);
Boolean hSetAll(String key, Map<String, Object> map, long time);
void hSetAll(String key, Map<String, ?> map);
void hDel(String key, Object... hashKey);
Boolean hHasKey(String key, String hashKey);
Long hIncr(String key, String hashKey, Long delta);
Long hDecr(String key, String hashKey, Long delta);
Double zIncr(String key, Object value, Double score);
Double zDecr(String key, Object value, Double score);
Map<Object, Double> zReverseRangeWithScore(String key, long start, long end);
Double zScore(String key, Object value);
Map<Object, Double> zAllScore(String key);
Set<Object> sMembers(String key);
Long sAdd(String key, Object... values);
Long sAddExpire(String key, long time, Object... values);
Boolean sIsMember(String key, Object value);
Long sSize(String key);
Long sRemove(String key, Object... values);
List<Object> lRange(String key, long start, long end);
Long lSize(String key);
Object lIndex(String key, long index);
Long lPush(String key, Object value);
Long lPush(String key, Object value, long time);
Long lPushAll(String key, Object... values);
Long lPushAll(String key, Long time, Object... values);
Long lRemove(String key, long count, Object value);
Boolean bitAdd(String key, int offset, boolean b);
Boolean bitGet(String key, int offset);
Long bitCount(String key);
List<Long> bitField(String key, int limit, int offset);
byte[] bitGetAll(String key);
Long hyperAdd(String key, Object... value);
Long hyperGet(String... key);
void hyperDel(String key);
Long geoAdd(String key, Double x, Double y, String name);
List<Point> geoGetPointList(String key, Object... place);
Distance geoCalculationDistance(String key, String placeOne, String placeTow);
GeoResults<RedisGeoCommands.GeoLocation<Object>> geoNearByPlace(String key, String place, Distance distance, long limit, Sort.Direction sort);
List<String> geoGetHash(String key, String... place);
}

View File

@ -1,37 +1,114 @@
package com.example.catchTheLetters.service.impl;
import com.auth0.jwt.interfaces.Claim;
import com.example.catchTheLetters.constant.CommonConstant;
import com.example.catchTheLetters.entity.LoginDto;
import com.example.catchTheLetters.entity.RegisterDto;
import com.example.catchTheLetters.entity.User;
import com.example.catchTheLetters.model.vo.UserVo;
import com.example.catchTheLetters.service.AuthService;
import com.example.catchTheLetters.service.RedisService;
import com.example.catchTheLetters.utils.JwtUtil;
import com.example.catchTheLetters.utils.R;
import jakarta.annotation.Resource;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Service
public class AuthServiceImpl implements AuthService {
@Resource
private MongoTemplate mongoTemplate;
@Resource
private RedisService redisService;
@Override
public String login(LoginDto loginDto) {
// TODO 从MongoDB中查询用户信息返回TOKEN
return null;
public R<String> login(LoginDto loginDto) {
// 根据用户名查询用户信息
String username = loginDto.getUsername();
// 判断用户名是否为邮箱
Pattern patternEmail = Pattern.compile(CommonConstant.EMAIL_REGEX);
Matcher matcherEmail = patternEmail.matcher(username);
// 判断用户名是否为手机号
Pattern patternPhone = Pattern.compile(CommonConstant.PHONE_REGEX);
Matcher matcherPhone = patternPhone.matcher(username);
User user;
if (matcherEmail.matches()){
user = mongoTemplate.findOne(new Query(Criteria.where(CommonConstant.EMAIL).is(username).and(CommonConstant.STATUS).ne(0)), User.class);
}
if (matcherPhone.matches()){
user = mongoTemplate.findOne(new Query(Criteria.where(CommonConstant.PHONE).is(username).and(CommonConstant.STATUS).ne(0)), User.class);
}else {
user = mongoTemplate.findOne(new Query(Criteria.where(CommonConstant.USERNAME).is(username).and(CommonConstant.STATUS).ne(0)),User.class);
}
if (Objects.isNull(user)){
return R.fail("用户不存在");
}
if (!user.getPassword().equals(loginDto.getPassword())){
return R.fail("密码错误");
}
Map<String, String> map = new HashMap<>();
map.put("id",user.getId().toString());
String token = JwtUtil.getToken(map, CommonConstant.TOKEN_EXPIRE_TIME);
redisService.hSet(token, user.getId().toString(), CommonConstant.REDIS_EXPIRE_TIME);
return R.ok(token);
}
@Override
public boolean logout(String token) {
return false;
return redisService.del(token);
}
@Override
public User verify(String token) {
return null;
Map<String, Claim> map = JwtUtil.getPayload(token);
String id = map.get("id").asString().replaceAll("\"", "");
User user = mongoTemplate.findOne(new Query(Criteria.where("id").is(id).and(CommonConstant.STATUS).ne(0)),User.class);
if (Objects.isNull(user)){
return null;
}
return user;
}
@Override
public String register(RegisterDto registerDto) {
return null;
public R<UserVo> register(RegisterDto registerDto) {
User regedUser = getUserByName(registerDto.getUsername());
R<UserVo> result = new R<>();
// 用户名重复
if (regedUser != null) {
R.fail("用户名重复");
}
User user = new User();
user.setUsername(registerDto.getUsername());
user.setPassword(registerDto.getPassword());
User insert = mongoTemplate.insert(user);
if (insert != null && insert.getId() != null){
return R.ok(user.toVo());
}else {
return R.fail("注册失败,请重试");
}
}
@Override
public User getUserInfo(Integer id) {
return mongoTemplate.findOne(new Query(Criteria.where("id").is(id).and(CommonConstant.STATUS).ne(0)),User.class);
}
@Override
public User getUserByName(String username) {
return mongoTemplate.findOne(new Query(Criteria.where("username").is(username).and(CommonConstant.STATUS).ne(0)),User.class);
}
}

View File

@ -0,0 +1,329 @@
package com.example.catchTheLetters.service.impl;
import com.example.catchTheLetters.service.RedisService;
import jakarta.annotation.Resource;
import org.springframework.data.domain.Sort;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.GeoResults;
import org.springframework.data.geo.Point;
import org.springframework.data.redis.connection.BitFieldSubCommands;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
* @author 慕华
* @date 2024/4/10
* @Version 1.0
* @description
*/
@Service
public class RedisServiceImpl implements RedisService {
@Resource
private RedisTemplate<String, Object> redisTemplate;
@Override
public void set(String key, Object value, long time) {
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
}
@Override
public void set(String key, Object value) {
redisTemplate.opsForValue().set(key, value);
}
@Override
public Object get(String key) {
return redisTemplate.opsForValue().get(key);
}
@Override
public Boolean del(String key) {
return redisTemplate.delete(key);
}
@Override
public Long del(List<String> keys) {
return redisTemplate.delete(keys);
}
@Override
public Boolean expire(String key, long time) {
return redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
@Override
public Long getExpire(String key) {
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
}
@Override
public Boolean hasKey(String key) {
return redisTemplate.hasKey(key);
}
@Override
public Long incr(String key, long delta) {
return redisTemplate.opsForValue().increment(key, delta);
}
@Override
public Long incrExpire(String key, long time) {
Long count = redisTemplate.opsForValue().increment(key, 1);
if (count != null && count == 1) {
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
return count;
}
@Override
public Long decr(String key, long delta) {
return redisTemplate.opsForValue().increment(key, -delta);
}
@Override
public Object hGet(String key, String hashKey) {
return redisTemplate.opsForHash().get(key, hashKey);
}
@Override
public Boolean hSet(String key, String hashKey, Object value, long time) {
redisTemplate.opsForHash().put(key, hashKey, value);
return expire(key, time);
}
@Override
public void hSet(String key, String hashKey, Object value) {
redisTemplate.opsForHash().put(key, hashKey, value);
}
@Override
public Map hGetAll(String key) {
return redisTemplate.opsForHash().entries(key);
}
@Override
public Boolean hSetAll(String key, Map<String, Object> map, long time) {
redisTemplate.opsForHash().putAll(key, map);
return expire(key, time);
}
@Override
public void hSetAll(String key, Map<String, ?> map) {
redisTemplate.opsForHash().putAll(key, map);
}
@Override
public void hDel(String key, Object... hashKey) {
redisTemplate.opsForHash().delete(key, hashKey);
}
@Override
public Boolean hHasKey(String key, String hashKey) {
return redisTemplate.opsForHash().hasKey(key, hashKey);
}
@Override
public Long hIncr(String key, String hashKey, Long delta) {
return redisTemplate.opsForHash().increment(key, hashKey, delta);
}
@Override
public Long hDecr(String key, String hashKey, Long delta) {
return redisTemplate.opsForHash().increment(key, hashKey, -delta);
}
@Override
public Double zIncr(String key, Object value, Double score) {
return redisTemplate.opsForZSet().incrementScore(key, value, score);
}
@Override
public Double zDecr(String key, Object value, Double score) {
return redisTemplate.opsForZSet().incrementScore(key, value, -score);
}
@Override
public Map<Object, Double> zReverseRangeWithScore(String key, long start, long end) {
return redisTemplate.opsForZSet().reverseRangeWithScores(key, start, end)
.stream()
.collect(Collectors.toMap(ZSetOperations.TypedTuple::getValue, ZSetOperations.TypedTuple::getScore));
}
@Override
public Double zScore(String key, Object value) {
return redisTemplate.opsForZSet().score(key, value);
}
@Override
public Map<Object, Double> zAllScore(String key) {
return Objects.requireNonNull(redisTemplate.opsForZSet().rangeWithScores(key, 0, -1))
.stream()
.collect(Collectors.toMap(ZSetOperations.TypedTuple::getValue, ZSetOperations.TypedTuple::getScore));
}
@Override
public Set<Object> sMembers(String key) {
return redisTemplate.opsForSet().members(key);
}
@Override
public Long sAdd(String key, Object... values) {
return redisTemplate.opsForSet().add(key, values);
}
@Override
public Long sAddExpire(String key, long time, Object... values) {
Long count = redisTemplate.opsForSet().add(key, values);
expire(key, time);
return count;
}
@Override
public Boolean sIsMember(String key, Object value) {
return redisTemplate.opsForSet().isMember(key, value);
}
@Override
public Long sSize(String key) {
return redisTemplate.opsForSet().size(key);
}
@Override
public Long sRemove(String key, Object... values) {
return redisTemplate.opsForSet().remove(key, values);
}
@Override
public List<Object> lRange(String key, long start, long end) {
return redisTemplate.opsForList().range(key, start, end);
}
@Override
public Long lSize(String key) {
return redisTemplate.opsForList().size(key);
}
@Override
public Object lIndex(String key, long index) {
return redisTemplate.opsForList().index(key, index);
}
@Override
public Long lPush(String key, Object value) {
return redisTemplate.opsForList().rightPush(key, value);
}
@Override
public Long lPush(String key, Object value, long time) {
Long index = redisTemplate.opsForList().rightPush(key, value);
expire(key, time);
return index;
}
@Override
public Long lPushAll(String key, Object... values) {
return redisTemplate.opsForList().rightPushAll(key, values);
}
@Override
public Long lPushAll(String key, Long time, Object... values) {
Long count = redisTemplate.opsForList().rightPushAll(key, values);
expire(key, time);
return count;
}
@Override
public Long lRemove(String key, long count, Object value) {
return redisTemplate.opsForList().remove(key, count, value);
}
@Override
public Boolean bitAdd(String key, int offset, boolean b) {
return redisTemplate.opsForValue().setBit(key, offset, b);
}
@Override
public Boolean bitGet(String key, int offset) {
return redisTemplate.opsForValue().getBit(key, offset);
}
@Override
public Long bitCount(String key) {
return redisTemplate.execute((RedisCallback<Long>) con -> con.bitCount(key.getBytes()));
}
@Override
public List<Long> bitField(String key, int limit, int offset) {
return redisTemplate.execute((RedisCallback<List<Long>>) con ->
con.bitField(key.getBytes(),
BitFieldSubCommands.create().get(BitFieldSubCommands.BitFieldType.unsigned(limit)).valueAt(offset)));
}
@Override
public byte[] bitGetAll(String key) {
return redisTemplate.execute((RedisCallback<byte[]>) con -> con.get(key.getBytes()));
}
@Override
public Long hyperAdd(String key, Object... value) {
return redisTemplate.opsForHyperLogLog().add(key, value);
}
@Override
public Long hyperGet(String... key) {
return redisTemplate.opsForHyperLogLog().size(key);
}
@Override
public void hyperDel(String key) {
redisTemplate.opsForHyperLogLog().delete(key);
}
@Override
public Long geoAdd(String key, Double x, Double y, String name) {
return redisTemplate.opsForGeo().add(key, new Point(x, y), name);
}
@Override
public List<Point> geoGetPointList(String key, Object... place) {
return redisTemplate.opsForGeo().position(key, place);
}
@Override
public Distance geoCalculationDistance(String key, String placeOne, String placeTow) {
return redisTemplate.opsForGeo()
.distance(key, placeOne, placeTow, RedisGeoCommands.DistanceUnit.KILOMETERS);
}
@Override
public GeoResults<RedisGeoCommands.GeoLocation<Object>> geoNearByPlace(String key, String place, Distance distance, long limit, Sort.Direction sort) {
RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs().includeDistance().includeCoordinates();
// 判断排序方式
if (Sort.Direction.ASC == sort) {
args.sortAscending();
} else {
args.sortDescending();
}
args.limit(limit);
return redisTemplate.opsForGeo()
.radius(key, place, distance, args);
}
@Override
public List<String> geoGetHash(String key, String... place) {
return redisTemplate.opsForGeo()
.hash(key, place);
}
}