1.停车场管理

2.客户管理
3.新增使用手机号登录方式(新用户会在客户表内新增)
4.修改登录token检验方式
This commit is contained in:
hanrenchun 2025-11-17 18:16:05 +08:00
parent 74cc82066e
commit a439f5303f
19 changed files with 679 additions and 74 deletions

View File

@ -0,0 +1,56 @@
package com.ruoyi.database.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.database.domain.BaseCustomerInfo;
import com.ruoyi.database.service.BaseCustomerInfoService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RequestMapping("/BaseCustomerInfo")
@Api(tags = "02-基础管理-客户管理")
@RestController
@RequiredArgsConstructor
public class BaseCustomerInfoController extends BaseController {
private final BaseCustomerInfoService baseCustomerInfoService;
@GetMapping
@ApiOperation("查询客户管理表")
public TableDataInfo<BaseCustomerInfo> list(BaseCustomerInfo baseCustomerInfo) {
startPage();
QueryWrapper<BaseCustomerInfo> queryWrapper = new QueryWrapper<>(baseCustomerInfo);
List<BaseCustomerInfo> list = baseCustomerInfoService.list(queryWrapper);
long size = baseCustomerInfoService.count(queryWrapper);
return getDataTableEnhance(list,size);
}
@PostMapping
@ApiOperation("新增客户管理表")
@Log(title = "客户管理表", businessType = BusinessType.INSERT)
public AjaxResult insert(@RequestBody BaseCustomerInfo baseCustomerInfo) {
return toAjax(baseCustomerInfoService.save(baseCustomerInfo));
}
@PutMapping
@ApiOperation("修改客户管理表")
@Log(title = "客户管理表", businessType = BusinessType.UPDATE)
public AjaxResult update(@RequestBody BaseCustomerInfo baseCustomerInfo) {
return toAjax(baseCustomerInfoService.updateById(baseCustomerInfo));
}
@DeleteMapping
@ApiOperation("删除客户管理表")
@Log(title = "客户管理表", businessType = BusinessType.DELETE)
public AjaxResult delete(@RequestParam("idList") List<Long> idList) {
return toAjax(baseCustomerInfoService.removeByIds(idList));
}
}

View File

@ -0,0 +1,56 @@
package com.ruoyi.database.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.database.domain.BaseParkingLotInfo;
import com.ruoyi.database.service.BaseParkingLotInfoService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RequestMapping("/BaseParkingLotInfo")
@Api(tags = "01-基础管理-停车场管理")
@RestController
@RequiredArgsConstructor
public class BaseParkingLotInfoController extends BaseController {
private final BaseParkingLotInfoService baseParkingLotInfoService;
@GetMapping
@ApiOperation("查询停车场管理表")
public TableDataInfo<BaseParkingLotInfo> list(BaseParkingLotInfo baseParkingLotInfo) {
startPage();
QueryWrapper<BaseParkingLotInfo> queryWrapper = new QueryWrapper<>(baseParkingLotInfo);
List<BaseParkingLotInfo> list = baseParkingLotInfoService.list(queryWrapper);
long size = baseParkingLotInfoService.count(queryWrapper);
return getDataTableEnhance(list,size);
}
@PostMapping
@ApiOperation("新增停车场管理表")
@Log(title = "停车场管理表", businessType = BusinessType.INSERT)
public AjaxResult insert(@RequestBody BaseParkingLotInfo baseParkingLotInfo) {
return toAjax(baseParkingLotInfoService.save(baseParkingLotInfo));
}
@PutMapping
@ApiOperation("修改停车场管理表")
@Log(title = "停车场管理表", businessType = BusinessType.UPDATE)
public AjaxResult update(@RequestBody BaseParkingLotInfo baseParkingLotInfo) {
return toAjax(baseParkingLotInfoService.updateById(baseParkingLotInfo));
}
@DeleteMapping
@ApiOperation("删除停车场管理表")
@Log(title = "停车场管理表", businessType = BusinessType.DELETE)
public AjaxResult delete(@RequestParam("idList") List<Long> idList) {
return toAjax(baseParkingLotInfoService.removeByIds(idList));
}
}

View File

@ -0,0 +1,116 @@
package com.ruoyi.database.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Date;
/**
* 客户基础信息表(BaseCustomerInfo)实体类
*
* @author makejava
* @since 2025-11-13 08:49:20
*/
@Data
@EqualsAndHashCode(callSuper = false)
@TableName(value = "base_customer_info")
@ApiModel(value = "BaseCustomerInfo", description = "客户基础信息表")
public class BaseCustomerInfo {
/**
* 主键
*/
@ApiModelProperty("主键")
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 创建时间
*/
@ApiModelProperty("创建时间")
@Excel(name = "创建时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/**
* 创建者
*/
@ApiModelProperty("创建者")
@Excel(name = "创建者")
private Integer createBy;
/**
* 更新时间
*/
@ApiModelProperty("更新时间")
@Excel(name = "更新时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
/**
* 更新者
*/
@ApiModelProperty("更新者")
@Excel(name = "更新者")
private Integer updateBy;
/**
* 微信openid
*/
@ApiModelProperty("微信openid")
@Excel(name = "微信openid")
private String openId;
/**
* 支付宝用户ID
*/
@ApiModelProperty("支付宝用户ID")
@Excel(name = "支付宝用户ID")
private String alipayUserId;
/**
* 手机号
*/
@ApiModelProperty("手机号")
@Excel(name = "手机号")
private String phone;
/**
* 昵称
*/
@ApiModelProperty("昵称")
@Excel(name = "昵称")
private String nickname;
/**
* 头像
*/
@ApiModelProperty("头像")
@Excel(name = "头像")
private String avatarUrl;
/**
* 积分
*/
@ApiModelProperty("积分")
@Excel(name = "积分")
private Long integral;
/**
* 会员等级
*/
@ApiModelProperty("会员等级")
@Excel(name = "会员等级")
private Integer memberLevel;
}

View File

@ -0,0 +1,137 @@
package com.ruoyi.database.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Date;
/**
* 停车场基础信息表(BaseParkingLotInfo)实体类
*
* @author makejava
* @since 2025-11-13 08:49:21
*/
@Data
@EqualsAndHashCode(callSuper = false)
@TableName(value = "base_parking_lot_info")
@ApiModel(value = "BaseParkingLotInfo", description = "停车场基础信息表")
public class BaseParkingLotInfo {
/**
* 主键
*/
@ApiModelProperty("主键")
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 创建时间
*/
@ApiModelProperty("创建时间")
@Excel(name = "创建时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/**
* 创建者
*/
@ApiModelProperty("创建者")
@Excel(name = "创建者")
private Integer createBy;
/**
* 更新时间
*/
@ApiModelProperty("更新时间")
@Excel(name = "更新时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
/**
* 更新者
*/
@ApiModelProperty("更新者")
@Excel(name = "更新者")
private Integer updateBy;
/**
* 停车场名称
*/
@ApiModelProperty("停车场名称")
@Excel(name = "停车场名称")
private String name;
/**
* 停车场编码
*/
@ApiModelProperty("停车场编码")
@Excel(name = "停车场编码")
private String code;
/**
* 停车场地址
*/
@ApiModelProperty("停车场地址")
@Excel(name = "停车场地址")
private String address;
/**
* 总车位数
*/
@ApiModelProperty("总车位数")
@Excel(name = "总车位数")
private Integer totalSpaces;
/**
* 可用车位数
*/
@ApiModelProperty("可用车位数")
@Excel(name = "可用车位数")
private Integer availableSpaces;
/**
* 营业时间
*/
@ApiModelProperty("营业时间")
@Excel(name = "营业时间")
private String businessHours;
/**
* 联系电话
*/
@ApiModelProperty("联系电话")
@Excel(name = "联系电话")
private String contactPhone;
/**
* 状态:0-停用,1-启用
*/
@ApiModelProperty("状态:0-停用,1-启用")
@Excel(name = "状态:0-停用,1-启用")
private Integer status;
/**
* 经度
*/
@ApiModelProperty("经度")
@Excel(name = "经度")
private Double lng;
/**
* 纬度
*/
@ApiModelProperty("纬度")
@Excel(name = "纬度")
private Double lat;
}

View File

@ -0,0 +1,16 @@
package com.ruoyi.database.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.database.domain.BaseCustomerInfo;
import org.apache.ibatis.annotations.Mapper;
/**
* 客户基础信息表(BaseCustomerInfo) Mapper 接口
*
* @author makejava
* @since ${date}
*/
@Mapper
public interface BaseCustomerInfoMapper extends BaseMapper<BaseCustomerInfo> {
}

View File

@ -0,0 +1,16 @@
package com.ruoyi.database.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.database.domain.BaseParkingLotInfo;
import org.apache.ibatis.annotations.Mapper;
/**
* 停车场基础信息表(BaseParkingLotInfo) Mapper 接口
*
* @author makejava
* @since ${date}
*/
@Mapper
public interface BaseParkingLotInfoMapper extends BaseMapper<BaseParkingLotInfo> {
}

View File

@ -0,0 +1,14 @@
package com.ruoyi.database.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.database.domain.BaseCustomerInfo;
/**
* (客户基础信息表)Service
*
* @author makejava
* @since 2025-11-13 08:49:21
*/
public interface BaseCustomerInfoService extends IService<BaseCustomerInfo> {
}

View File

@ -0,0 +1,14 @@
package com.ruoyi.database.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.database.domain.BaseParkingLotInfo;
/**
* (停车场基础信息表)Service
*
* @author makejava
* @since 2025-11-13 08:49:22
*/
public interface BaseParkingLotInfoService extends IService<BaseParkingLotInfo> {
}

View File

@ -0,0 +1,19 @@
package com.ruoyi.database.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.database.domain.BaseCustomerInfo;
import com.ruoyi.database.mapper.BaseCustomerInfoMapper;
import com.ruoyi.database.service.BaseCustomerInfoService;
import org.springframework.stereotype.Service;
/**
* (客户基础信息表)ServiceImpl
*
* @author makejava
* @since 2025-11-13 08:49:21
*/
@Service
public class BaseCustomerInfoServiceImpl extends ServiceImpl<BaseCustomerInfoMapper, BaseCustomerInfo> implements BaseCustomerInfoService {
}

View File

@ -0,0 +1,19 @@
package com.ruoyi.database.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.database.domain.BaseParkingLotInfo;
import com.ruoyi.database.mapper.BaseParkingLotInfoMapper;
import com.ruoyi.database.service.BaseParkingLotInfoService;
import org.springframework.stereotype.Service;
/**
* (停车场基础信息表)ServiceImpl
*
* @author makejava
* @since 2025-11-13 08:49:22
*/
@Service
public class BaseParkingLotInfoServiceImpl extends ServiceImpl<BaseParkingLotInfoMapper, BaseParkingLotInfo> implements BaseParkingLotInfoService {
}

View File

@ -6,7 +6,10 @@ import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysMenu; import com.ruoyi.common.core.domain.entity.SysMenu;
import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginBody; import com.ruoyi.common.core.domain.model.LoginBody;
import com.ruoyi.common.core.domain.model.LoginBodyByPhone;
import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.database.domain.BaseCustomerInfo;
import com.ruoyi.database.service.BaseCustomerInfoService;
import com.ruoyi.framework.web.service.SysLoginService; import com.ruoyi.framework.web.service.SysLoginService;
import com.ruoyi.framework.web.service.SysPermissionService; import com.ruoyi.framework.web.service.SysPermissionService;
import com.ruoyi.system.service.ISysMenuService; import com.ruoyi.system.service.ISysMenuService;
@ -18,6 +21,7 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@ -38,13 +42,16 @@ public class SysLoginController {
@Autowired @Autowired
private SysPermissionService permissionService; private SysPermissionService permissionService;
@Autowired
private BaseCustomerInfoService baseCustomerInfoService;
/** /**
* 登录方法 * 登录方法
* *
* @param loginBody 登录信息 * @param loginBody 登录信息
* @return 结果 * @return 结果
*/ */
@ApiOperation("登录") @ApiOperation("管理员登录")
@PostMapping("/login") @PostMapping("/login")
public AjaxResult login(@RequestBody LoginBody loginBody) { public AjaxResult login(@RequestBody LoginBody loginBody) {
AjaxResult ajax = AjaxResult.success(); AjaxResult ajax = AjaxResult.success();
@ -55,18 +62,39 @@ public class SysLoginController {
return ajax; return ajax;
} }
@ApiOperation("登录App") // @ApiOperation("登录App")
@PostMapping("/loginApp") // @PostMapping("/loginApp")
public AjaxResult loginApp(LoginBody loginBody) { // public AjaxResult loginApp(LoginBody loginBody) {
// AjaxResult ajax = AjaxResult.success();
// loginBody.setCode("000000");
// // 生成令牌
// String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
// loginBody.getUuid());
// ajax.put(Constants.TOKEN, token);
// return ajax;
// }
@ApiOperation("根据手机号登录(没有的用户会创建)")
@PostMapping("/loginByPhone")
public AjaxResult loginByPhone(@Valid @RequestBody LoginBodyByPhone loginBodyByPhone) {
AjaxResult ajax = AjaxResult.success(); AjaxResult ajax = AjaxResult.success();
loginBody.setCode("000000");
// 生成令牌 // 生成令牌
String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(), BaseCustomerInfo one = baseCustomerInfoService.lambdaQuery()
loginBody.getUuid()); .eq(BaseCustomerInfo::getPhone, loginBodyByPhone.getPhone())
.last("limit 1")
.one();
if (one == null) {
BaseCustomerInfo baseCustomerInfo = new BaseCustomerInfo();
baseCustomerInfo.setPhone(loginBodyByPhone.getPhone());
baseCustomerInfo.setNickname(loginBodyByPhone.getPhone());
baseCustomerInfoService.save(baseCustomerInfo);
}
String token = loginService.loginByPhone(loginBodyByPhone.getPhone());
ajax.put(Constants.TOKEN, token); ajax.put(Constants.TOKEN, token);
return ajax; return ajax;
} }
/** /**
* 获取用户信息 * 获取用户信息
* *

View File

@ -90,6 +90,17 @@ public class BaseController
return rspData; return rspData;
} }
protected TableDataInfo getDataTableEnhance(List<?> list,Long size)
{
TableDataInfo rspData = new TableDataInfo();
rspData.setCode(HttpStatus.SUCCESS);
rspData.setMsg("查询成功");
rspData.setRows(list);
rspData.setTotal(size);
return rspData;
}
/** /**
* 返回成功 * 返回成功
*/ */

View File

@ -0,0 +1,27 @@
package com.ruoyi.common.core.domain.model;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
/**
* 用户登录对象
*
* @author ruoyi
*/
public class LoginBodyByPhone
{
/**
* 手机号
*/
@NotBlank(message = "手机号不能为空")
@Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")
private String phone;
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
}

View File

@ -0,0 +1,18 @@
package com.ruoyi.common.core.domain.model;
import lombok.Data;
@Data
public class LoginUserByPhone {
private static final long serialVersionUID = 1L;
private String phone;
private String token;
private Long expireTime;
private Long loginTime;
}

View File

@ -111,7 +111,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
// 过滤请求 // 过滤请求
.authorizeRequests() .authorizeRequests()
// 对于登录login 注册register 验证码captchaImage 允许匿名访问 // 对于登录login 注册register 验证码captchaImage 允许匿名访问
.antMatchers("/login","/loginApp", "/register", "/captchaImage").permitAll() .antMatchers("/login","/loginByPhone", "/register", "/captchaImage").permitAll()
// 静态资源可匿名访问 // 静态资源可匿名访问
.antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll() .antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
.antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll() .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()

View File

@ -5,6 +5,10 @@ import javax.servlet.FilterChain;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.model.LoginUserByPhone;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
@ -31,14 +35,26 @@ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException throws ServletException, IOException
{ {
LoginUser loginUser = tokenService.getLoginUser(request); try {
if (StringUtils.isNotNull(loginUser) && StringUtils.isNull(SecurityUtils.getAuthentication())) LoginUser loginUser = tokenService.getLoginUser(request);
{ if (StringUtils.isNotNull(loginUser) && StringUtils.isNull(SecurityUtils.getAuthentication()))
tokenService.verifyToken(loginUser); {
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities()); tokenService.verifyToken(loginUser);
authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authenticationToken); authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
}
chain.doFilter(request, response);
} catch (Exception e) {
LoginUserByPhone loginUserByPhone = tokenService.getLoginUserByPhone(request);
if (StringUtils.isNotNull(loginUserByPhone) && StringUtils.isNull(SecurityUtils.getAuthentication()))
{
tokenService.verifyTokenByPhone(loginUserByPhone);
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUserByPhone, null, null);
authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
}
chain.doFilter(request, response);
} }
chain.doFilter(request, response);
} }
} }

View File

@ -4,6 +4,8 @@ import java.io.IOException;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import com.ruoyi.common.core.domain.model.LoginUserByPhone;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
@ -38,14 +40,23 @@ public class LogoutSuccessHandlerImpl implements LogoutSuccessHandler
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws IOException, ServletException throws IOException, ServletException
{ {
LoginUser loginUser = tokenService.getLoginUser(request); try {
if (StringUtils.isNotNull(loginUser)) LoginUser loginUser = tokenService.getLoginUser(request);
{ if (StringUtils.isNotNull(loginUser))
String userName = loginUser.getUsername(); {
// 删除用户缓存记录 String userName = loginUser.getUsername();
tokenService.delLoginUser(loginUser.getToken()); // 删除用户缓存记录
// 记录用户退出日志 tokenService.delLoginUser(loginUser.getToken());
AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName, Constants.LOGOUT, "退出成功")); // 记录用户退出日志
AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName, Constants.LOGOUT, "退出成功"));
}
} catch (Exception e) {
LoginUserByPhone loginUser = tokenService.getLoginUserByPhone(request);
if (StringUtils.isNotNull(loginUser))
{
// 删除用户缓存记录
tokenService.delLoginUser(loginUser.getToken());
}
} }
ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.success("退出成功"))); ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.success("退出成功")));
} }

View File

@ -143,6 +143,12 @@ public class SysLoginService {
} }
public String loginByPhone(String phone) {
return tokenService.createTokenByPhone(phone);
}
/** /**
* 校验验证码 * 校验验证码
* *

View File

@ -3,6 +3,7 @@ package com.ruoyi.framework.web.service;
import com.ruoyi.common.constant.CacheConstants; import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.constant.Constants; import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.model.LoginUser; import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.domain.model.LoginUserByPhone;
import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.ServletUtils; import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
@ -30,8 +31,7 @@ import java.util.concurrent.TimeUnit;
* @author ruoyi * @author ruoyi
*/ */
@Component @Component
public class TokenService public class TokenService {
{
private static final Logger log = LoggerFactory.getLogger(TokenService.class); private static final Logger log = LoggerFactory.getLogger(TokenService.class);
// 令牌自定义标识 // 令牌自定义标识
@ -60,25 +60,30 @@ public class TokenService
* *
* @return 用户信息 * @return 用户信息
*/ */
public LoginUser getLoginUser(HttpServletRequest request) public LoginUser getLoginUser(HttpServletRequest request) {
{
// 获取请求携带的令牌 // 获取请求携带的令牌
String token = getToken(request); String token = getToken(request);
if (StringUtils.isNotEmpty(token)) if (StringUtils.isNotEmpty(token)) {
{ Claims claims = parseToken(token);
try // 解析对应的权限以及用户信息
{ String uuid = (String) claims.get(Constants.LOGIN_USER_KEY);
Claims claims = parseToken(token); String userKey = getTokenKey(uuid);
// 解析对应的权限以及用户信息 LoginUser user = redisCache.getCacheObject(userKey);
String uuid = (String) claims.get(Constants.LOGIN_USER_KEY); return user;
String userKey = getTokenKey(uuid); }
LoginUser user = redisCache.getCacheObject(userKey); return null;
return user; }
}
catch (Exception e) public LoginUserByPhone getLoginUserByPhone(HttpServletRequest request) {
{ // 获取请求携带的令牌
log.error("获取用户信息异常'{}'", e.getMessage()); String token = getToken(request);
} if (StringUtils.isNotEmpty(token)) {
Claims claims = parseToken(token);
// 解析对应的权限以及用户信息
String uuid = (String) claims.get(Constants.LOGIN_USER_KEY);
String userKey = getTokenKey(uuid);
LoginUserByPhone user = redisCache.getCacheObject(userKey);
return user;
} }
return null; return null;
} }
@ -86,10 +91,8 @@ public class TokenService
/** /**
* 设置用户身份信息 * 设置用户身份信息
*/ */
public void setLoginUser(LoginUser loginUser) public void setLoginUser(LoginUser loginUser) {
{ if (StringUtils.isNotNull(loginUser) && StringUtils.isNotEmpty(loginUser.getToken())) {
if (StringUtils.isNotNull(loginUser) && StringUtils.isNotEmpty(loginUser.getToken()))
{
refreshToken(loginUser); refreshToken(loginUser);
} }
} }
@ -97,10 +100,8 @@ public class TokenService
/** /**
* 删除用户身份信息 * 删除用户身份信息
*/ */
public void delLoginUser(String token) public void delLoginUser(String token) {
{ if (StringUtils.isNotEmpty(token)) {
if (StringUtils.isNotEmpty(token))
{
String userKey = getTokenKey(token); String userKey = getTokenKey(token);
redisCache.deleteObject(userKey); redisCache.deleteObject(userKey);
} }
@ -112,8 +113,7 @@ public class TokenService
* @param loginUser 用户信息 * @param loginUser 用户信息
* @return 令牌 * @return 令牌
*/ */
public String createToken(LoginUser loginUser) public String createToken(LoginUser loginUser) {
{
String token = IdUtils.fastUUID(); String token = IdUtils.fastUUID();
loginUser.setToken(token); loginUser.setToken(token);
setUserAgent(loginUser); setUserAgent(loginUser);
@ -124,29 +124,52 @@ public class TokenService
return createToken(claims); return createToken(claims);
} }
/**
* 创建令牌
*
* @return 令牌
*/
public String createTokenByPhone(String phone) {
String token = IdUtils.fastUUID();
LoginUserByPhone loginUserByPhone = new LoginUserByPhone();
loginUserByPhone.setPhone(phone);
loginUserByPhone.setToken(token);
refreshTokenByPhone(loginUserByPhone);
Map<String, Object> claims = new HashMap<>();
claims.put(Constants.LOGIN_USER_KEY, token);
return createToken(claims);
}
/** /**
* 验证令牌有效期相差不足20分钟自动刷新缓存 * 验证令牌有效期相差不足20分钟自动刷新缓存
* *
* @param loginUser * @param loginUser
* @return 令牌 * @return 令牌
*/ */
public void verifyToken(LoginUser loginUser) public void verifyToken(LoginUser loginUser) {
{
long expireTime = loginUser.getExpireTime(); long expireTime = loginUser.getExpireTime();
long currentTime = System.currentTimeMillis(); long currentTime = System.currentTimeMillis();
if (expireTime - currentTime <= MILLIS_MINUTE_TEN) if (expireTime - currentTime <= MILLIS_MINUTE_TEN) {
{
refreshToken(loginUser); refreshToken(loginUser);
} }
} }
public void verifyTokenByPhone(LoginUserByPhone loginUserByPhone) {
long expireTime = loginUserByPhone.getExpireTime();
long currentTime = System.currentTimeMillis();
if (expireTime - currentTime <= MILLIS_MINUTE_TEN) {
refreshTokenByPhone(loginUserByPhone);
}
}
/** /**
* 刷新令牌有效期 * 刷新令牌有效期
* *
* @param loginUser 登录信息 * @param loginUser 登录信息
*/ */
public void refreshToken(LoginUser loginUser) public void refreshToken(LoginUser loginUser) {
{
loginUser.setLoginTime(System.currentTimeMillis()); loginUser.setLoginTime(System.currentTimeMillis());
loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE); loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE);
// 根据uuid将loginUser缓存 // 根据uuid将loginUser缓存
@ -154,13 +177,21 @@ public class TokenService
redisCache.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES); redisCache.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES);
} }
public void refreshTokenByPhone(LoginUserByPhone loginUserByPhone) {
// 根据uuid将loginUser缓存
loginUserByPhone.setLoginTime(System.currentTimeMillis());
loginUserByPhone.setExpireTime(loginUserByPhone.getLoginTime() + expireTime * MILLIS_MINUTE);
String userKey = getTokenKey(loginUserByPhone.getToken());
redisCache.setCacheObject(userKey, loginUserByPhone, expireTime, TimeUnit.MINUTES);
}
/** /**
* 设置用户代理信息 * 设置用户代理信息
* *
* @param loginUser 登录信息 * @param loginUser 登录信息
*/ */
public void setUserAgent(LoginUser loginUser) public void setUserAgent(LoginUser loginUser) {
{
UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent")); UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent"));
String ip = IpUtils.getIpAddr(); String ip = IpUtils.getIpAddr();
loginUser.setIpaddr(ip); loginUser.setIpaddr(ip);
@ -175,8 +206,7 @@ public class TokenService
* @param claims 数据声明 * @param claims 数据声明
* @return 令牌 * @return 令牌
*/ */
private String createToken(Map<String, Object> claims) private String createToken(Map<String, Object> claims) {
{
String token = Jwts.builder() String token = Jwts.builder()
.setClaims(claims) .setClaims(claims)
.signWith(SignatureAlgorithm.HS512, secret).compact(); .signWith(SignatureAlgorithm.HS512, secret).compact();
@ -189,8 +219,7 @@ public class TokenService
* @param token 令牌 * @param token 令牌
* @return 数据声明 * @return 数据声明
*/ */
private Claims parseToken(String token) private Claims parseToken(String token) {
{
return Jwts.parser() return Jwts.parser()
.setSigningKey(secret) .setSigningKey(secret)
.parseClaimsJws(token) .parseClaimsJws(token)
@ -203,8 +232,7 @@ public class TokenService
* @param token 令牌 * @param token 令牌
* @return 用户名 * @return 用户名
*/ */
public String getUsernameFromToken(String token) public String getUsernameFromToken(String token) {
{
Claims claims = parseToken(token); Claims claims = parseToken(token);
return claims.getSubject(); return claims.getSubject();
} }
@ -215,18 +243,15 @@ public class TokenService
* @param request * @param request
* @return token * @return token
*/ */
private String getToken(HttpServletRequest request) private String getToken(HttpServletRequest request) {
{
String token = request.getHeader(header); String token = request.getHeader(header);
if (StringUtils.isNotEmpty(token) && token.startsWith(Constants.TOKEN_PREFIX)) if (StringUtils.isNotEmpty(token) && token.startsWith(Constants.TOKEN_PREFIX)) {
{
token = token.replace(Constants.TOKEN_PREFIX, ""); token = token.replace(Constants.TOKEN_PREFIX, "");
} }
return token; return token;
} }
private String getTokenKey(String uuid) private String getTokenKey(String uuid) {
{
return CacheConstants.LOGIN_TOKEN_KEY + uuid; return CacheConstants.LOGIN_TOKEN_KEY + uuid;
} }
} }