mirror of
https://gitee.com/bookshelfplus/bookshelfplus
synced 2025-09-12 03:31:39 +08:00
重新引入Redis;用户登录与管理员登录完成;引入NanoID代替UUID;调整Spring Boot idea中的启动参数;swagger页面描述信息完善;更新swagger,更新Api文档
This commit is contained in:
@@ -8,7 +8,8 @@ public enum BusinessErrorCode implements CommonError {
|
||||
// 20000开头为用户信息相关错误定义
|
||||
USER_NOT_EXIST(20001, "用户不存在"),
|
||||
USER_LOGIN_FAILED(20002, "用户手机号或密码不正确"),
|
||||
USER_NOT_LOGIN(20003, "用户还未登录");
|
||||
USER_NOT_LOGIN(20003, "用户还未登录"),
|
||||
USER_TOKEN_EXPIRED(20004, "用户令牌过期");
|
||||
|
||||
|
||||
private BusinessErrorCode(int errCode, String errMsg) {
|
||||
|
@@ -0,0 +1,53 @@
|
||||
package plus.bookshelf.Common.SessionManager;
|
||||
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class RedisSessionManager implements SessionManager {
|
||||
|
||||
/**
|
||||
* 私有化构造函数
|
||||
*/
|
||||
private RedisSessionManager(RedisTemplate redisTemplate) {
|
||||
this.redisTemplate = redisTemplate;
|
||||
}
|
||||
|
||||
static SessionManager sessionManager = null;
|
||||
|
||||
/**
|
||||
* 通过此方法获取当前类的实例
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static SessionManager getInstance(RedisTemplate redisTemplate) {
|
||||
if (sessionManager == null)
|
||||
sessionManager = new RedisSessionManager(redisTemplate);
|
||||
return sessionManager;
|
||||
}
|
||||
|
||||
static RedisTemplate redisTemplate = null;
|
||||
|
||||
@Override
|
||||
public Object getValue(String key) {
|
||||
try {
|
||||
return redisTemplate.opsForValue().get(key);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(String key, Object value) {
|
||||
redisTemplate.expire(key, 1, TimeUnit.HOURS);
|
||||
|
||||
// 建立token和用户登录态之间的联系
|
||||
redisTemplate.opsForValue().set(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(String key) {
|
||||
redisTemplate.delete(key);
|
||||
}
|
||||
}
|
@@ -1,6 +1,8 @@
|
||||
package plus.bookshelf.Controller.Controller;
|
||||
|
||||
import com.aventrix.jnanoid.jnanoid.NanoIdUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
@@ -10,17 +12,23 @@ import plus.bookshelf.Common.Error.BusinessException;
|
||||
import plus.bookshelf.Common.Response.CommonReturnType;
|
||||
import plus.bookshelf.Common.Response.CommonReturnTypeStatus;
|
||||
import plus.bookshelf.Common.SessionManager.LocalSessionManager;
|
||||
import plus.bookshelf.Common.SessionManager.RedisSessionManager;
|
||||
import plus.bookshelf.Common.SessionManager.SessionManager;
|
||||
import plus.bookshelf.Service.Model.UserModel;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.HashMap;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class BaseController {
|
||||
|
||||
@Autowired
|
||||
HttpServletRequest httpServletRequest;
|
||||
|
||||
@Autowired
|
||||
RedisTemplate redisTemplate;
|
||||
|
||||
// content-type 常量
|
||||
public static final String CONTENT_TYPE_FORMED = "application/x-www-form-urlencoded";
|
||||
|
||||
@@ -28,15 +36,15 @@ public class BaseController {
|
||||
public static final Integer COMMON_START_PAGE = 1;
|
||||
public static final Integer COMMON_PAGE_SIZE = 10;
|
||||
|
||||
// @Autowired
|
||||
// private RedisTemplate redisTemplate;
|
||||
|
||||
/**
|
||||
* 获取用户登陆状态
|
||||
*/
|
||||
public Boolean isLogin() {
|
||||
SessionManager sessionManager = LocalSessionManager.getInstance(httpServletRequest);
|
||||
SessionManager sessionManager = RedisSessionManager.getInstance(redisTemplate);
|
||||
return (Boolean) sessionManager.getValue("IS_LOGIN");
|
||||
|
||||
// SessionManager sessionManager = LocalSessionManager.getInstance(httpServletRequest);
|
||||
// return (Boolean) sessionManager.getValue("IS_LOGIN");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -44,28 +52,30 @@ public class BaseController {
|
||||
*
|
||||
* @return String uuidToken
|
||||
*/
|
||||
public void onLogin(UserModel userModel) {
|
||||
// String uuidToken = UUID.randomUUID().toString();
|
||||
// redisTemplate.expire(uuidToken, 1, TimeUnit.HOURS);
|
||||
public String onLogin(UserModel userModel) {
|
||||
String token = NanoIdUtils.randomNanoId(); // UUID.randomUUID().toString();
|
||||
SessionManager sessionManager = RedisSessionManager.getInstance(redisTemplate);
|
||||
sessionManager.setValue(token, userModel.getId());
|
||||
return token;
|
||||
|
||||
// // 建立token和用户登录态之间的联系
|
||||
// redisTemplate.opsForValue().set(uuidToken, userModel);
|
||||
// return uuidToken;
|
||||
|
||||
SessionManager sessionManager = LocalSessionManager.getInstance(httpServletRequest);
|
||||
sessionManager.setValue("IS_LOGIN", true);
|
||||
sessionManager.setValue("user", userModel);
|
||||
return;
|
||||
// SessionManager sessionManager = LocalSessionManager.getInstance(httpServletRequest);
|
||||
// sessionManager.setValue("IS_LOGIN", true);
|
||||
// sessionManager.setValue("user", userModel);
|
||||
// return;
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户退出登录
|
||||
*/
|
||||
public void onLogout() {
|
||||
SessionManager sessionManager = LocalSessionManager.getInstance(httpServletRequest);
|
||||
sessionManager.setValue("IS_LOGIN", false);
|
||||
sessionManager.remove("user");
|
||||
public void onLogout(String token) {
|
||||
SessionManager sessionManager = RedisSessionManager.getInstance(redisTemplate);
|
||||
sessionManager.remove(token);
|
||||
return;
|
||||
|
||||
// SessionManager sessionManager = LocalSessionManager.getInstance(httpServletRequest);
|
||||
// sessionManager.setValue("IS_LOGIN", false);
|
||||
// sessionManager.remove("user");
|
||||
// return;
|
||||
}
|
||||
|
||||
// 定义ExceptionHandler解决未被Controller层吸收的Exception
|
||||
|
@@ -18,7 +18,7 @@ import plus.bookshelf.Service.Service.BookService;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Api(value = "书籍")
|
||||
@Api(tags = "书籍信息")
|
||||
@Controller("book")
|
||||
@RequestMapping("/book")
|
||||
public class BookController extends BaseController {
|
||||
|
@@ -17,7 +17,7 @@ import plus.bookshelf.Service.Model.CategoryModel;
|
||||
import plus.bookshelf.Service.Service.BookService;
|
||||
import plus.bookshelf.Service.Service.CategoryService;
|
||||
|
||||
@Api(value = "书籍分类")
|
||||
@Api(tags = "书籍分类信息")
|
||||
@Controller("category")
|
||||
@RequestMapping("/category")
|
||||
public class CategoryController extends BaseController {
|
||||
|
@@ -14,7 +14,7 @@ import java.math.BigDecimal;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Api(value = "状态检测")
|
||||
@Api(tags = "网站后台状态检测")
|
||||
@Controller("status")
|
||||
@RequestMapping("/status")
|
||||
public class StatusController extends BaseController {
|
||||
|
@@ -1,22 +1,25 @@
|
||||
package plus.bookshelf.Controller.Controller;
|
||||
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiImplicitParams;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import plus.bookshelf.Common.Error.BusinessErrorCode;
|
||||
import plus.bookshelf.Common.Error.BusinessException;
|
||||
import plus.bookshelf.Common.Response.CommonReturnType;
|
||||
import plus.bookshelf.Common.SessionManager.LocalSessionManager;
|
||||
import plus.bookshelf.Common.SessionManager.RedisSessionManager;
|
||||
import plus.bookshelf.Controller.VO.UserVO;
|
||||
import plus.bookshelf.Dao.Mapper.UserDOMapper;
|
||||
import plus.bookshelf.Service.Impl.UserServiceImpl;
|
||||
import plus.bookshelf.Service.Model.UserModel;
|
||||
|
||||
@Api(value = "用户")
|
||||
@Api(tags = "用户操作")
|
||||
@Controller
|
||||
@RequestMapping("/user")
|
||||
public class UserController extends BaseController {
|
||||
@@ -25,12 +28,16 @@ public class UserController extends BaseController {
|
||||
UserServiceImpl userService;
|
||||
|
||||
@ApiOperation(value = "用户登录", notes = "传入用户名,以及密码明文,后台计算密码SHA1值,进行登录")
|
||||
// @ApiImplicitParams(value = {
|
||||
// @ApiImplicitParam(name = "username", value = "用户名", example = "username1", paramType = "form", dataType = "String", required = true, dataTypeClass = String.class),
|
||||
// @ApiImplicitParam(name = "password", value = "密码", example = "password1", paramType = "form", dataType = "String", required = true, dataTypeClass = String.class)
|
||||
// })
|
||||
@RequestMapping(value = "login", method = {RequestMethod.POST}, consumes = {CONTENT_TYPE_FORMED})
|
||||
@ResponseBody
|
||||
public CommonReturnType login(@RequestParam(value = "username") String username,
|
||||
@RequestParam(value = "password") String password) {
|
||||
@RequestParam(value = "password") String password) throws BusinessException {
|
||||
if (username == null || password == null) {
|
||||
return null;
|
||||
throw new BusinessException(BusinessErrorCode.PARAMETER_VALIDATION_ERROR);
|
||||
}
|
||||
String encryptPwd = DigestUtils.sha1Hex(password);
|
||||
|
||||
@@ -38,7 +45,8 @@ public class UserController extends BaseController {
|
||||
UserVO userVO = convertFromService(userModel);
|
||||
|
||||
if (userModel != null) {
|
||||
onLogin(userModel);
|
||||
String token = onLogin(userModel);
|
||||
userVO.setToken(token); // token 仅在用户登录时传一次,后面获取用户状态接口中不重复返回 token 信息
|
||||
}
|
||||
return CommonReturnType.create(userVO);
|
||||
}
|
||||
@@ -59,23 +67,40 @@ public class UserController extends BaseController {
|
||||
// }
|
||||
|
||||
@ApiOperation(value = "用户登出", notes = "用户退出登录")
|
||||
// @ApiImplicitParams({
|
||||
// @ApiImplicitParam(name = "token", value = "用户token", required = true, dataType = "String")
|
||||
// })
|
||||
@RequestMapping(value = "logout", method = {RequestMethod.GET})
|
||||
@ResponseBody
|
||||
public CommonReturnType logout() {
|
||||
onLogout();
|
||||
public CommonReturnType logout(@RequestParam(value = "token", required = false) String token) throws BusinessException {
|
||||
// token 未传入
|
||||
if (token == null || "".equals(token)) {
|
||||
throw new BusinessException(BusinessErrorCode.PARAMETER_VALIDATION_ERROR, "用户令牌未传入");
|
||||
}
|
||||
|
||||
onLogout(token);
|
||||
return CommonReturnType.create("success");
|
||||
}
|
||||
|
||||
@ApiOperation(value = "获取用户登录状态", notes = "获取用户登录状态")
|
||||
// @ApiImplicitParams({
|
||||
// @ApiImplicitParam(name = "token", value = "用户token", required = true, dataType = "String")
|
||||
// })
|
||||
@RequestMapping(value = "getUserStatus", method = {RequestMethod.GET})
|
||||
@ResponseBody
|
||||
public CommonReturnType getUserStatus() {
|
||||
Object userModelObject = LocalSessionManager.getInstance(httpServletRequest).getValue("user");
|
||||
if (userModelObject == null) {
|
||||
return CommonReturnType.create(null);
|
||||
public CommonReturnType getUserStatus(@RequestParam(value = "token", required = false) String token) throws BusinessException {
|
||||
// token 未传入
|
||||
if (token == null || "".equals(token)) {
|
||||
throw new BusinessException(BusinessErrorCode.PARAMETER_VALIDATION_ERROR, "用户令牌未传入");
|
||||
}
|
||||
|
||||
UserModel userModel = (UserModel) userModelObject;
|
||||
// token 已过期
|
||||
Object userIdObject = RedisSessionManager.getInstance(redisTemplate).getValue(token);
|
||||
if (userIdObject == null) {
|
||||
throw new BusinessException(BusinessErrorCode.USER_TOKEN_EXPIRED, "登陆过期啦,请重新登录");
|
||||
}
|
||||
Integer userId = (Integer) userIdObject;
|
||||
UserModel userModel = userService.getUserById(userId);
|
||||
UserVO userVO = convertFromService(userModel);
|
||||
return CommonReturnType.create(userVO);
|
||||
}
|
||||
|
@@ -22,4 +22,7 @@ public class UserVO {
|
||||
|
||||
// 用户手机号
|
||||
String phone;
|
||||
|
||||
// 用户 token (NanoID)
|
||||
String token;
|
||||
}
|
||||
|
@@ -21,6 +21,14 @@ public class UserServiceImpl implements UserService {
|
||||
return userModel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserModel getUserById(Integer id) {
|
||||
UserDO userDO = userDOMapper.selectByPrimaryKey(id);
|
||||
UserModel userModel = convertFromDataObject(userDO);
|
||||
|
||||
return userModel;
|
||||
}
|
||||
|
||||
private UserModel convertFromDataObject(UserDO userDO) {
|
||||
if (userDO == null) {
|
||||
return null;
|
||||
|
@@ -10,4 +10,11 @@ public interface UserService {
|
||||
* @param encryptPwd
|
||||
*/
|
||||
UserModel userLogin(String username, String encryptPwd);
|
||||
|
||||
/**
|
||||
* 通过用户Id获取用户
|
||||
* @param id 用户Id
|
||||
* @return
|
||||
*/
|
||||
UserModel getUserById(Integer id);
|
||||
}
|
||||
|
Reference in New Issue
Block a user