Commit 73c3de6c authored by liming's avatar liming

增加管理后台模块

parent 0d07aa57
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>antai-sport-http-server</artifactId>
<groupId>com.antai.sport.http.server</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>management-api</artifactId>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.antai.sport.http.server</groupId>
<artifactId>common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
</dependency>
</dependencies>
<build>
<finalName>antai-sport-http-server-management-api</finalName>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<fork>true</fork>
<encoding>${project.build.sourceEncoding}</encoding>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</path>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</path>
<!-- other annotation processors -->
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
package com.antai.sport.http.server.management.api;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import springfox.documentation.oas.annotations.EnableOpenApi;
/**
* @author 厉明
* @date 2021/8/18 11:35
* @email lmmax@126.com
* @description
*/
@SpringBootApplication
@EnableOpenApi
@ComponentScan(value = "com.antai")
@MapperScan("com.antai.**.mapper")
public class ManagementApiApplication {
public static void main(String[] args) {
SpringApplication.run(ManagementApiApplication.class, args);
}
}
package com.antai.sport.http.server.management.api.advice;
import com.antai.sport.http.server.common.base.Result;
import com.antai.sport.http.server.common.jwt.TokenService;
import com.antai.sport.http.server.common.jwt.TokenVO;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import javax.annotation.Resource;
import java.util.List;
/**
* @Author liming
* @Date 2021/8/22 18:07
* @Email lmmax@126.com
* @Description:
*/
@RestControllerAdvice(basePackages = "com.antai")
@ResponseBody
public class CustomResponseAdvice implements ResponseBodyAdvice<Object> {
@Value("${project.header-token-key}")
private String headerTokenKey;
@Value("${project.jwt.subject-key}")
private String subjectKey;
@Value("${project.jwt.long-token-key}")
private String longTokenKey;
@Resource
private TokenService tokenService;
@Override
public boolean supports(MethodParameter methodParameter,
Class<? extends HttpMessageConverter<?>> aClass) {
return true;
}
@Override
public Object beforeBodyWrite(Object result, MethodParameter methodParameter,
MediaType mediaType,
Class<? extends HttpMessageConverter<?>> aClass,
ServerHttpRequest serverHttpRequest,
ServerHttpResponse serverHttpResponse) {
if (!(result instanceof Result)) {
return result;
}
String token;
List<String> tokenList = serverHttpRequest.getHeaders().get(headerTokenKey);
if (tokenList != null && !tokenList.isEmpty()) {
token = tokenList.get(0);
if (!StringUtils.isBlank(token)) {
Claims claims = tokenService.validateToken(token);
if (claims != null && claims.containsKey(longTokenKey)) {
Result realResult = (Result) result;
TokenVO tokenVO = tokenService.initToken(claims.get(subjectKey).toString());
realResult.setRefreshToken(true);
realResult.setLongToken(tokenVO.getLongToken());
realResult.setShortToken(tokenVO.getShortToken());
}
}
}
return result;
}
}
package com.antai.sport.http.server.management.api.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @Author liming
* @Date 2021/8/23 1:59
* @Email lmmax@126.com
* @Description:
*/
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface LoginUser {
}
package com.antai.sport.http.server.management.api.business.auth.controller;
import com.antai.sport.http.server.common.base.Result;
import com.antai.sport.http.server.management.api.annotation.LoginUser;
import com.antai.sport.http.server.management.api.business.auth.dto.LoginRequestDTO;
import com.antai.sport.http.server.management.api.business.auth.dto.UserInfoResponseDTO;
import com.antai.sport.http.server.management.api.business.auth.service.AuthService;
import com.antai.sport.http.server.repository.sys.entity.SysUser;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import static com.antai.sport.http.server.common.util.ResultUtil.success;
@RequestMapping("auth")
@RestController
@Api(tags = {"授权相关接口"})
public class AuthController {
@Resource
private AuthService authService;
@ApiOperation("登录接口")
@PostMapping("login")
public ResponseEntity<Result> login(@RequestBody LoginRequestDTO loginParam) {
return success(authService.login(loginParam));
}
@ApiOperation("获取用户信息")
@GetMapping("/user/info")
public ResponseEntity<Result<UserInfoResponseDTO>> getUserInfo(@LoginUser SysUser loginUser) {
return success(authService.getUserInfo(loginUser));
}
}
package com.antai.sport.http.server.management.api.business.auth.converter;
import com.antai.sport.http.server.management.api.business.auth.dto.UserInfoResponseDTO;
import com.antai.sport.http.server.repository.sys.entity.SysUser;
import org.mapstruct.Mapper;
@Mapper(componentModel = "spring")
public interface AuthConverter {
UserInfoResponseDTO toUserInfoResponseDTO(SysUser sysUser);
}
package com.antai.sport.http.server.management.api.business.auth.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("登录接口传入参数")
public class LoginRequestDTO {
@ApiModelProperty("用户名")
private String username;
@ApiModelProperty("密码")
private String password;
}
package com.antai.sport.http.server.management.api.business.auth.dto;
import lombok.Data;
@Data
public class UserInfoResponseDTO {
private String realName;
private String avatar;
}
package com.antai.sport.http.server.management.api.business.auth.mapper;
import com.antai.sport.http.server.repository.sys.entity.SysUser;
import org.springframework.cache.annotation.Cacheable;
public interface AuthMapper {
@Cacheable(value = "sys_user", key = "#p0", unless = "#result == null")
SysUser getByUsername(String username);
}
package com.antai.sport.http.server.management.api.business.auth.service;
import com.antai.sport.http.server.common.base.Result;
import com.antai.sport.http.server.common.exception.BusinessException;
import com.antai.sport.http.server.common.jwt.TokenService;
import com.antai.sport.http.server.common.jwt.TokenVO;
import com.antai.sport.http.server.constants.DeleteStatus;
import com.antai.sport.http.server.management.api.business.auth.converter.AuthConverter;
import com.antai.sport.http.server.management.api.business.auth.dto.LoginRequestDTO;
import com.antai.sport.http.server.management.api.business.auth.dto.UserInfoResponseDTO;
import com.antai.sport.http.server.repository.sys.entity.SysUser;
import com.antai.sport.http.server.repository.sys.mapper.SysUserMapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import javax.annotation.Resource;
import java.util.List;
@Service
public class AuthService {
@Resource
private SysUserMapper sysUserMapper;
@Resource
private TokenService tokenService;
@Resource
private AuthConverter authConverter;
/**
* 登录
*
* @param loginParam
* @return
*/
public Result login(LoginRequestDTO loginParam) {
if (StringUtils.isBlank(loginParam.getUsername())) {
throw new BusinessException("请输入用户名");
}
if (StringUtils.isBlank(loginParam.getPassword())) {
throw new BusinessException("请输入密码");
}
List<SysUser> userList = sysUserMapper.selectList(new QueryWrapper<SysUser>()
.eq("username", loginParam.getUsername())
.eq("deleted", DeleteStatus.UNDELETED));
if (userList.isEmpty()) {
throw new BusinessException("用户名或密码错误");
}
SysUser user = userList.get(0);
String hashPwd = DigestUtils.md5DigestAsHex(loginParam.getPassword().getBytes());
if (!hashPwd.equals(user.getPassword())) {
throw new BusinessException("用户名或密码错误");
}
Result result = new Result();
TokenVO tokenVO = tokenService.initToken(loginParam.getUsername());
result.setLongToken(tokenVO.getLongToken());
result.setShortToken(tokenVO.getShortToken());
result.setRespMsg("登录成功");
return result;
}
/**
* 获取用户信息
*
* @param loginUser
* @return
*/
public UserInfoResponseDTO getUserInfo(SysUser loginUser) {
return authConverter.toUserInfoResponseDTO(loginUser);
}
}
package com.antai.sport.http.server.management.api.business.normalmatch.controller;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/normal/match")
@Api(tags = {"日常赛"})
public class NormalMatchController {
@ApiOperation("测试")
@GetMapping
public String test(){
return "test";
}
}
package com.antai.sport.http.server.management.api.config;
import com.antai.sport.http.server.common.resolver.SportUserArgumentResolver;
import com.antai.sport.http.server.management.api.interceptor.TokenInterceptor;
import com.antai.sport.http.server.management.api.resolver.SysUserArgumentResolver;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.List;
/**
* @Author liming
* @Date 2021/8/22 17:03
* @Email lmmax@126.com
* @Description:
*/
@Configuration
@ConfigurationProperties(prefix = "project")
public class BaseConfig implements WebMvcConfigurer {
private List<String> permitUrl;
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOriginPatterns("*")
.allowCredentials(true)
.allowedMethods("GET", "POST", "DELETE", "PUT")
.maxAge(3600);
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(tokenInterceptor()).
addPathPatterns("/**").
excludePathPatterns(permitUrl);
}
@Bean
TokenInterceptor tokenInterceptor() {
return new TokenInterceptor();
}
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(sysUserArgumentResolver());
}
@Bean
SysUserArgumentResolver sysUserArgumentResolver() {
return new SysUserArgumentResolver();
}
public void setPermitUrl(List<String> permitUrl) {
this.permitUrl = permitUrl;
}
}
package com.antai.sport.http.server.management.api.interceptor;
import com.antai.sport.http.server.common.jwt.TokenService;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import static org.springframework.http.HttpStatus.UNAUTHORIZED;
public class TokenInterceptor implements HandlerInterceptor {
@Value("${project.header-token-key}")
private String headerTokenKey;
@Resource
private TokenService tokenService;
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
String token = request.getHeader(headerTokenKey);
if (null == token) {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, UNAUTHORIZED.getReasonPhrase());
return false;
}
Claims claims = tokenService.validateToken(token);
if (claims == null) {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, UNAUTHORIZED.getReasonPhrase());
return false;
}
return true;
}
}
package com.antai.sport.http.server.management.api.resolver;
import com.antai.sport.http.server.common.exception.BusinessException;
import com.antai.sport.http.server.common.jwt.TokenService;
import com.antai.sport.http.server.management.api.annotation.LoginUser;
import com.antai.sport.http.server.management.api.business.auth.mapper.AuthMapper;
import com.antai.sport.http.server.repository.sys.entity.SysUser;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import javax.annotation.Resource;
public class SysUserArgumentResolver implements HandlerMethodArgumentResolver {
@Value("${project.header-token-key}")
private String headerTokenKey;
@Value("${project.jwt.subject-key}")
private String subjectKey;
@Resource
private AuthMapper authMapper;
@Resource
private TokenService tokenService;
/**
* 判断是否支持要转换的参数类型
*/
@Override
public boolean supportsParameter(MethodParameter methodParameter) {
if (methodParameter.getParameterType().isAssignableFrom(SysUser.class)
&& methodParameter.hasParameterAnnotation(LoginUser.class)) {
return true;
}
return false;
}
/**
* 当支持后进行相应的转换 做业务操作
*/
@Override
public Object resolveArgument(MethodParameter methodParameter,
ModelAndViewContainer modelAndViewContainer,
NativeWebRequest request,
WebDataBinderFactory webDataBinderFactory) throws Exception {
//从请求头中获参数信息
String token = request.getHeader(headerTokenKey);
if (token == null || token.isEmpty()) {
throw new BusinessException("token信息错误");
}
Claims claims = tokenService.validateToken(token);
if (claims == null) {
throw new BusinessException("token解析异常");
}
String username = claims.get(subjectKey).toString();
SysUser sysUser = authMapper.getByUsername(username);
if (sysUser == null) {
throw new BusinessException("当前用户不存在");
}
return sysUser;
}
}
spring:
profiles:
include:
- common-db-dev
redis:
database: 0
host: 127.0.0.1
port: 6379
password: 123456
swagger:
enable: true
game-server-address: http://8.141.144.99:3333/close?MatchId=force
\ No newline at end of file
spring:
profiles:
include:
- common-db-local
redis:
database: 1
host: 127.0.0.1
port: 6379
swagger:
enable: true
game-server-address: http://127.0.0.1:3333/close?MatchId=force
\ No newline at end of file
spring:
profiles:
include:
- common-db-prod
redis:
database: 0
host: 127.0.0.1
port: 6379
password: ENC(yKZoKLWfAj6BRglq4C2HWWjsL64maeCm)
game-server-address: http://8.141.144.99:3333/close?MatchId=force
\ No newline at end of file
spring:
profiles:
include:
- common-db-test
redis:
database: 1
host: 127.0.0.1
port: 6379
password: ENC(yKZoKLWfAj6BRglq4C2HWWjsL64maeCm)
swagger:
enable: true
game-server-address: http://8.141.144.99:3333/close?MatchId=force
\ No newline at end of file
server:
port: 8089
spring:
application:
name: "antai-sport-http-server-management-api"
config:
use-legacy-processing: true
profiles:
active: dev
cache:
redis:
use-key-prefix: true
time-to-live: 1d
expire:
login-sms-captcha: 600
keys:
login-sms-captcha: login:sms-captcha
redis:
timeout: 10s
jedis:
pool:
max-idle: 500
min-idle: 50
max-wait: -1s
max-active: -1
jackson:
date-format: com.antai.sport.http.server.common.jackson.StdDateFormat
time-zone: GMT+8
default-property-inclusion: always
project:
header-token-key: Authorization
jwt:
subject-key: username
long-token-key: longToken
secret: antaikeji666
prefix: Bearer
long-token-expire: 2_592_000_000
short-token-expire: 7_200_000
permit-url:
- /swagger**/**
- /webjars/**
- /doc.html
- /v3/**
- /favicon.ico
- /error
- /auth/login
swagger:
enable: false
projectName: 管理端接口
header-token-key: ${project.header-token-key}
api-version: 1.0
author: liming
email: lmmax@126.com
scan-package: com.antai.sport.http.server.management.api
description: 接口文档
service-website: https://www.antaikeji.top/
ignored-parameter-list:
- com.antai.sport.http.server.repository.sys.entity.SysUser
aliyun:
access-key-id: LTAI4FivP3A9hfXzF5Z2KKNM
access-key-secret: W1erPY4SLOoPK0YwwptLZCSfZ61K4c
sms:
sign: 安泰实业
region-id: cn-qingdao
time-out: 1000
template-code:
login: SMS_136440120 #登录确认验证码
mybatis-plus:
global-config:
db-config:
logic-delete-value: 1
logic-not-delete-value: 0
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.antai.sport.http.server.management.api.business.auth.mapper.AuthMapper">
<select id="getByUsername" parameterType="java.lang.String"
resultType="com.antai.sport.http.server.repository.sys.entity.SysUser">
select *
from sys_user t1
where t1.username = #{username}
and t1.deleted = 0
limit 1
</select>
</mapper>
\ No newline at end of file
......@@ -21,6 +21,7 @@
<module>common</module>
<module>constants</module>
<module>server-api</module>
<module>management-api</module>
</modules>
......
package com.antai.sport.http.server.repository.sys.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.time.LocalDateTime;
import java.io.Serializable;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* <p>
*
* </p>
*
* @author liming
* @since 2022-04-19
*/
@Data
@EqualsAndHashCode(callSuper = false)
public class SysUser implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 用户名
*/
private String username;
/**
* 密码
*/
private String password;
/**
* 联系电话
*/
private String phone;
/**
* 真实姓名
*/
private String realName;
/**
* 头像地址
*/
private String avatar;
/**
* 备注
*/
private String remark;
/**
* 排序号
*/
private Integer showOrder;
/**
* 数据版本号
*/
private Integer version;
/**
* 删除标记
*/
private Integer deleted;
/**
* 创建人
*/
private Long createBy;
/**
* 创建时间
*/
private LocalDateTime ctDate;
/**
* 修改人
*/
private Long updateBy;
/**
* 修改时间
*/
private LocalDateTime updateDate;
}
package com.antai.sport.http.server.repository.sys.mapper;
import com.antai.sport.http.server.repository.sys.entity.SysUser;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* Mapper 接口
* </p>
*
* @author liming
* @since 2022-04-19
*/
public interface SysUserMapper extends BaseMapper<SysUser> {
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.antai.sport.http.server.repository.sys.mapper.SysUserMapper">
</mapper>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment