最新代码

This commit is contained in:
admin
2024-04-19 17:20:40 +08:00
parent e4032a0183
commit 993f975edd
82 changed files with 2618 additions and 248 deletions

View File

@@ -29,7 +29,6 @@ import java.util.Objects;
public class ClerkUserLoginAspect {
@Resource
private PlayClerkUserInfoServiceImpl clerkUserInfoService;
@@ -45,7 +44,9 @@ public class ClerkUserLoginAspect {
if (StringUtils.isEmpty(userToken)) {
throw new ServiceException("token为空", HttpStatus.UNAUTHORIZED);
}
userToken = userToken.replace(Constants.TOKEN_PREFIX, "");
if (userToken.startsWith(Constants.TOKEN_PREFIX)) {
userToken = userToken.replace(Constants.TOKEN_PREFIX, "");
}
// 解析token
String userId;
try {

View File

@@ -43,7 +43,9 @@ public class CustomUserLoginAspect {
if (StringUtils.isEmpty(userToken)) {
throw new ServiceException("token为空", HttpStatus.UNAUTHORIZED);
}
userToken = userToken.replace(Constants.TOKEN_PREFIX, "");
if (userToken.startsWith(Constants.TOKEN_PREFIX)) {
userToken = userToken.replace(Constants.TOKEN_PREFIX, "");
}
// 解析token
String userId;
try {

View File

@@ -1,6 +1,7 @@
package com.starry.admin.common.aspect;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.starry.admin.common.domain.LoginUser;
import com.starry.admin.modules.system.entity.SysRoleEntity;
import com.starry.admin.modules.system.entity.SysUserEntity;
@@ -72,7 +73,7 @@ public class DataScopeAspect {
if (!DATA_SCOPE_CUSTOM.equals(dataScope) && conditions.contains(dataScope)) {
continue;
}
if (StringUtils.isNotEmpty(permission) && StringUtils.isNotEmpty(role.getPermissions())
if (StrUtil.isNotBlank(permission) && StringUtils.isNotEmpty(role.getPermissions())
&& !StringUtils.containsAny(role.getPermissions(), Convert.toStrArray(permission))) {
continue;
}

View File

@@ -1,6 +1,7 @@
package com.starry.admin.common.component;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.servlet.ServletUtil;
import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil;
@@ -185,7 +186,7 @@ public class JwtToken {
*/
public JwtUser getLoginUser(HttpServletRequest request) {
String token = getToken(request);
if (StringUtils.isNotEmpty(token)) {
if (StrUtil.isNotBlank(token)) {
try {
Claims claims = getClaimsFromToken(token);
String uuid = (String) claims.get(Constants.LOGIN_USER_KEY);
@@ -208,7 +209,7 @@ public class JwtToken {
private String getToken(HttpServletRequest request) {
// 获取请求头
String token = request.getHeader(tokenHeader);
if (StringUtils.isNotEmpty(token) && token.startsWith(tokenHead)) {
if (StrUtil.isNotBlank(token) && token.startsWith(tokenHead)) {
token = token.replace(tokenHead, "");
}
return token;
@@ -232,7 +233,7 @@ public class JwtToken {
* 删除用户身份信息
*/
public void removeJwtUser(String token) {
if (StringUtils.isNotEmpty(token)) {
if (StrUtil.isNotBlank(token)) {
String userKey = getTokenKey(token);
redisCache.deleteObject(userKey);
}
@@ -307,7 +308,7 @@ public class JwtToken {
*/
public LoginUser getNewLoginUser(HttpServletRequest request) {
String token = getToken(request);
if (StringUtils.isNotEmpty(token)) {
if (StrUtil.isNotBlank(token)) {
try {
Claims claims = getClaimsFromToken(token);
String uuid = (String) claims.get(SecurityConstants.USER_KEY);

View File

@@ -0,0 +1,54 @@
package com.starry.admin.common.conf;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.TypeReference;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import org.springframework.util.StringUtils;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
@Slf4j
@MappedJdbcTypes(JdbcType.VARCHAR) //数据库类型
@MappedTypes({List.class}) //java数据类型
public abstract class ListTypeHandler<T> extends BaseTypeHandler<List<T>> {
@Override
public void setNonNullParameter(PreparedStatement ps, int i, List<T> parameter, JdbcType jdbcType) throws SQLException {
String content = StringUtils.isEmpty(parameter) ? null : JSON.toJSONString(parameter);
ps.setString(i, content);
}
@Override
public List<T> getNullableResult(ResultSet rs, String columnName) throws SQLException {
return this.getListByJsonArrayString(rs.getString(columnName));
}
@Override
public List<T> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
return this.getListByJsonArrayString(rs.getString(columnIndex));
}
@Override
public List<T> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
return this.getListByJsonArrayString(cs.getString(columnIndex));
}
private List<T> getListByJsonArrayString(String content) {
return StringUtils.isEmpty(content) ? new ArrayList<>() : JSON.parseObject(content, this.specificType());
}
/**
* 具体类型,由子类提供
*
* @return 具体类型
*/
protected abstract TypeReference<List<T>> specificType();
}

View File

@@ -0,0 +1,13 @@
package com.starry.admin.common.conf;
import com.alibaba.fastjson2.TypeReference;
import java.util.List;
public class StringTypeHandler extends ListTypeHandler<String> {
// 将ListTypeHandler<T>T为任意对象具体为特定的对象String
@Override
protected TypeReference<List<String>> specificType() {
return new TypeReference<List<String>>() {
};
}
}

View File

@@ -1,16 +1,19 @@
package com.starry.admin.common.exception.handler;
import com.fasterxml.jackson.databind.exc.MismatchedInputException;
import com.starry.admin.common.exception.CustomException;
import com.starry.admin.common.exception.ServiceException;
import com.starry.common.result.R;
import com.starry.common.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@@ -79,6 +82,22 @@ public class GlobalExceptionHandler {
return R.error("请求参数异常," + errorMessageBuilder);
}
@ExceptionHandler(MismatchedInputException.class)
public R mismatchedInputException(MismatchedInputException e) {
return R.error("请求参数格式异常");
}
@ExceptionHandler(HttpMessageNotReadableException.class)
public R httpMessageNotReadableException(HttpMessageNotReadableException e) {
return R.error("请求参数格式异常");
}
@ExceptionHandler(MissingServletRequestParameterException.class)
public R missingServletRequestParameterException(MissingServletRequestParameterException e) {
return R.error("请求参数格式异常");
}
/**
* 自定义异常
*
@@ -89,10 +108,5 @@ public class GlobalExceptionHandler {
return R.error(e.getMessage());
}
// @ExceptionHandler(ServiceException.class)
// public R serviceException(ServiceException e) {
// return R.error(e.getMessage());
// }
}

View File

@@ -1,5 +1,6 @@
package com.starry.admin.common.mybatis.handler;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.starry.admin.modules.weichat.service.WxTokenService;
import com.starry.admin.utils.SecurityUtils;
@@ -54,13 +55,16 @@ public class MyMetaObjectHandler implements MetaObjectHandler {
public String getOperatorId() {
if (request.getServletPath().startsWith("/wx/")) {
String clerkToken = request.getHeader(Constants.CLERK_USER_LOGIN_TOKEN);
String customToken = request.getHeader(Constants.CUSTOM_USER_LOGIN_TOKEN);
if (clerkToken != null) {
return tokenService.getWxUserIdByToken(clerkToken);
}
if (customToken != null) {
return tokenService.getWxUserIdByToken(customToken);
String tenantKey = request.getHeader("tenantkey");
if (StrUtil.isBlankIfStr(tenantKey)) {
String clerkToken = request.getHeader(Constants.CLERK_USER_LOGIN_TOKEN);
String customToken = request.getHeader(Constants.CUSTOM_USER_LOGIN_TOKEN);
if (clerkToken != null) {
return tokenService.getWxUserIdByToken(clerkToken);
}
if (customToken != null) {
return tokenService.getWxUserIdByToken(customToken);
}
}
return "";
} else {
@@ -70,4 +74,4 @@ public class MyMetaObjectHandler implements MetaObjectHandler {
}
return "";
}
}
}

View File

@@ -1,6 +1,5 @@
package com.starry.admin.common.mybatis.handler;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
import com.starry.admin.utils.SecurityUtils;
import com.starry.common.utils.StringUtils;
@@ -23,7 +22,7 @@ public class MyTenantLineHandler implements TenantLineHandler {
/**
* 排除过滤的表
*/
private static final String[] TABLE_FILTER = {"sys_user", "sys_menu", "sys_tenant_package", "sys_tenant", "sys_dict", "sys_dict_data", "sys_administrative_area_dict_info"};
private static final String[] TABLE_FILTER = {"sys_login_log", "sys_role", "sys_user", "sys_menu", "sys_tenant_package", "sys_tenant", "sys_dict", "sys_dict_data", "sys_administrative_area_dict_info"};
/**
* 排除过滤的表前缀
@@ -34,9 +33,9 @@ public class MyTenantLineHandler implements TenantLineHandler {
public Expression getTenantId() {
// 取出当前请求的服务商ID通过解析器注入到SQL中。
String tenantId = SecurityUtils.getTenantId();
if (StrUtil.isBlankIfStr(tenantId)) {
tenantId = "9999";
}
// if (!StrUtil.isBlankIfStr(tenantId)) {
// throw new CustomException("租户信息获取异常");
// }
return new StringValue(tenantId);
}

View File

@@ -4,14 +4,12 @@ import com.starry.admin.common.oss.service.IOssFileService;
import com.starry.common.result.R;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.io.FileNotFoundException;
/**
* @author admin
@@ -36,11 +34,4 @@ public class CosController {
}
return R.error("上传照片异常,请联系管理员");
}
@ApiOperation(value = "获取cos临时密钥")
@GetMapping("/temp-key")
public R getTempKey() throws FileNotFoundException {
return R.ok();
}
}

View File

@@ -5,12 +5,15 @@ import java.io.InputStream;
public interface IOssFileService {
/**
* 文件上传阿里云
* 文件上传阿里云OSS
*
* @param inputStream InputStream
* @param module String
* @param originalFilename 文件名
*/
* @param inputStream 文件流
* @param module 文件保存模块地址
* @param originalFilename 原始文件名
* @return String
* @author admin
* @since 2024/4/11 10:24
**/
String upload(InputStream inputStream, String module, String originalFilename);
/**

View File

@@ -17,8 +17,13 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.stereotype.Service;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* @author admin
*/
@Service
@Slf4j
public class OssFileServiceImpl implements IOssFileService {
@@ -26,6 +31,15 @@ public class OssFileServiceImpl implements IOssFileService {
@Override
public String upload(InputStream inputStream, String module, String filename) {
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
bufferedInputStream.mark(0);
String fileType = FileTypeUtil.getType(bufferedInputStream);
try {
bufferedInputStream.reset();
} catch (IOException e) {
throw new CustomException("文件上传到OSS失败");
}
// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(OssProperties.ENDPOINT, OssProperties.KEY_ID, OssProperties.KEY_SECRET);
log.info("OSSClient实例创建成功");
@@ -42,16 +56,21 @@ public class OssFileServiceImpl implements IOssFileService {
// 构建日期路径avatar/2019/02/26/文件名
String folder = new DateTime().toString("yyyy/MM/dd");
// 文件名uuid.扩展名
filename = IdUtil.fastSimpleUUID() + FileTypeUtil.getType(inputStream);
filename = IdUtil.fastSimpleUUID() + "." + fileType;
// 文件根路径
String key = module + "/" + folder + "/" + filename;
// 创建PutObjectRequest对象。
PutObjectRequest putObjectRequest = new PutObjectRequest(OssProperties.BUCKET_NAME, key, inputStream);
PutObjectRequest putObjectRequest = new PutObjectRequest(OssProperties.BUCKET_NAME, key, bufferedInputStream);
// 创建PutObject请求。
ossClient.putObject(putObjectRequest);
log.info("oss文件上传成功");
// 阿里云文件绝对路径
String endpoint = OssProperties.ENDPOINT.substring(OssProperties.ENDPOINT.lastIndexOf("//") + 2);
String endpoint = OssProperties.ENDPOINT;
if (OssProperties.ENDPOINT.contains("//")) {
endpoint = OssProperties.ENDPOINT.substring(OssProperties.ENDPOINT.lastIndexOf("//") + 2);
}
// 返回文件的访问路径
return "https://" + OssProperties.BUCKET_NAME + "." + endpoint + "/" + key;
} catch (OSSException oe) {

View File

@@ -46,6 +46,7 @@ public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
@Resource
private CustomLogoutSuccessHandler customLogoutSuccessHandler;
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.csrf().disable()// 由于使用的是JWT我们这里不需要csrf

View File

@@ -1,19 +1,25 @@
package com.starry.admin.common.security.filter;
import cn.hutool.core.util.StrUtil;
import com.starry.admin.common.component.JwtToken;
import com.starry.admin.common.domain.LoginUser;
import com.starry.admin.common.exception.CustomException;
import com.starry.admin.modules.clear.service.impl.PlayClerkUserInfoServiceImpl;
import com.starry.admin.modules.custom.service.impl.PlayCustomUserInfoServiceImpl;
import com.starry.admin.modules.platform.entity.SysTenantEntity;
import com.starry.admin.modules.platform.service.ISysTenantService;
import com.starry.admin.modules.weichat.service.WxTokenService;
import com.starry.admin.utils.SecurityUtils;
import com.starry.common.constant.Constants;
import com.starry.common.utils.StringUtils;
import com.starry.common.redis.RedisCache;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.servlet.HandlerExceptionResolver;
import javax.annotation.Resource;
import javax.servlet.FilterChain;
@@ -37,33 +43,36 @@ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
@Resource
private JwtToken jwtToken;
@Resource
@Qualifier("handlerExceptionResolver")
private HandlerExceptionResolver resolver;
@Resource
private PlayCustomUserInfoServiceImpl customUserInfoService;
@Resource
private PlayClerkUserInfoServiceImpl clerkUserInfoService;
@Resource
private ISysTenantService sysTenantService;
@Resource
private RedisCache redisCache;
@Override
protected void doFilterInternal(@NotNull HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
protected void doFilterInternal(@NotNull HttpServletRequest httpServletRequest, @NotNull HttpServletResponse httpServletResponse, @NotNull FilterChain filterChain) throws ServletException, IOException {
// 微信公众号的请求
if (httpServletRequest.getServletPath().startsWith("/wx/")) {
String clerkToken = httpServletRequest.getHeader(Constants.CLERK_USER_LOGIN_TOKEN);
String customToken = httpServletRequest.getHeader(Constants.CUSTOM_USER_LOGIN_TOKEN);
if (StringUtils.isNotEmpty(clerkToken) || StringUtils.isNotEmpty(customToken)) {
String userId = tokenService.getWxUserIdByToken(StringUtils.isNotEmpty(clerkToken) ? clerkToken : customToken);
if (clerkToken != null) {
SecurityUtils.setTenantId(clerkUserInfoService.selectById(userId).getTenantId());
} else {
SecurityUtils.setTenantId(customUserInfoService.selectById(userId).getTenantId());
}
} else {
// 如果是微信端接口并且未登录的话从head中获取token
String header = httpServletRequest.getHeader("tenantkey");
// 根据租户表信息查询租户ID暂时先写死
String tenantId = "9999";
SecurityUtils.setTenantId(header);
String tenantKey = httpServletRequest.getHeader("tenantkey");
String tenantId = getTenantId(clerkToken, customToken, tenantKey);
if (!checkTenantId(tenantId)) {
resolver.resolveException(httpServletRequest, httpServletResponse, null, new CustomException("租户信息异常"));
return;
}
SecurityUtils.setTenantId(tenantId);
} else {
// 管理端的请求
LoginUser jwtUser = jwtToken.getNewLoginUser(httpServletRequest);
@@ -76,4 +85,61 @@ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
}
filterChain.doFilter(httpServletRequest, httpServletResponse);
}
/**
* 微信公众号端访问时获取当前用户租户ID
* 如果用户陪玩或客户已登录从token中获取租户ID
* 如果用户未登录从tenantKey中获取租户ID
*
* @param clerkToken 陪玩登录Key
* @param customToken 客户登录key
* @param tenantKey 租户标识
*/
public String getTenantId(String clerkToken, String customToken, String tenantKey) {
String tenantId = "";
//如果用户陪玩或客户已登录从token中获取租户ID
if (StrUtil.isNotBlank(clerkToken) || StrUtil.isNotBlank(customToken)) {
String userId;
try {
userId = tokenService.getWxUserIdByToken(StrUtil.isNotBlank(clerkToken) ? clerkToken : customToken);
} catch (Exception e) {
return "";
}
if (clerkToken != null) {
String redisKey = "TENANT_INFO:" + userId;
SecurityUtils.setTenantId(redisCache.getCacheObject(redisKey));
tenantId = clerkUserInfoService.selectById(userId).getTenantId();
} else {
tenantId = customUserInfoService.selectById(userId).getTenantId();
}
} else {
// 如果用户未登录从tenantKey中获取租户ID然后验证租户ID是否存在以及租户是否过期等
SysTenantEntity entity = sysTenantService.selectByTenantKey(tenantKey);
if (entity != null) {
tenantId = entity.getTenantId();
}
}
return tenantId;
}
/**
* 校验租户是否正常
*
* @param tenantId 租户ID
* @return true:租户正常false:租户不正常
*/
public boolean checkTenantId(String tenantId) {
if (StrUtil.isBlankIfStr(tenantId)) {
return false;
}
SysTenantEntity entity = sysTenantService.selectSysTenantByTenantId(tenantId);
if (entity == null) {
return false;
}
//判断租户是否过期
//...
//校验通过
return true;
}
}