v3.0.0 【优化】登录日志回显、版本号改为3.0、文件下载

This commit is contained in:
zhuoda 2024-01-15 21:49:04 +08:00
parent 4142295ee1
commit 851d913ab6
25 changed files with 6058 additions and 104 deletions

View File

@ -4,7 +4,7 @@
<groupId>net.1024lab</groupId> <groupId>net.1024lab</groupId>
<artifactId>sa-parent</artifactId> <artifactId>sa-parent</artifactId>
<version>1.0.0</version> <version>3.0.0</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<name>sa-parent</name> <name>sa-parent</name>
@ -22,7 +22,7 @@
<springboot.version>2.7.5</springboot.version> <springboot.version>2.7.5</springboot.version>
<spring-mock.version>2.0.8</spring-mock.version> <spring-mock.version>2.0.8</spring-mock.version>
<mybatis-plus.version>3.5.2</mybatis-plus.version> <mybatis-plus.version>3.5.2</mybatis-plus.version>
<p6spy.version>3.8.6</p6spy.version> <p6spy.version>3.9.1</p6spy.version>
<springdoc-openapi-ui.version>1.7.0</springdoc-openapi-ui.version> <springdoc-openapi-ui.version>1.7.0</springdoc-openapi-ui.version>
<knife4j.version>4.3.0</knife4j.version> <knife4j.version>4.3.0</knife4j.version>
<fastjson.version>2.0.16</fastjson.version> <fastjson.version>2.0.16</fastjson.version>
@ -50,6 +50,7 @@
<ip2region.version>2.7.0</ip2region.version> <ip2region.version>2.7.0</ip2region.version>
<bcprov.version>1.59</bcprov.version> <bcprov.version>1.59</bcprov.version>
<jackson-datatype-jsr310.version>2.13.4</jackson-datatype-jsr310.version> <jackson-datatype-jsr310.version>2.13.4</jackson-datatype-jsr310.version>
<smartdb.version>1.2.0</smartdb.version>
</properties> </properties>
<dependencyManagement> <dependencyManagement>
@ -293,12 +294,17 @@
<version>${jackson-datatype-jsr310.version}</version> <version>${jackson-datatype-jsr310.version}</version>
</dependency> </dependency>
<dependency>
<groupId>net.1024lab</groupId>
<artifactId>smartdb</artifactId>
<version>${smartdb.version}</version>
</dependency>
</dependencies> </dependencies>
</dependencyManagement> </dependencyManagement>
<build> <build>
<finalName>${profiles.active}-${project.name}</finalName> <finalName>${project.name}-${profiles.active}-${project.version}</finalName>
<resources> <resources>
<resource> <resource>
<filtering>false</filtering> <filtering>false</filtering>
@ -339,14 +345,6 @@
<encoding>UTF-8</encoding> <encoding>UTF-8</encoding>
</configuration> </configuration>
</plugin> </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<testFailureIgnore>true</testFailureIgnore>
<skipTests>true</skipTests>
</configuration>
</plugin>
<plugin> <plugin>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId> <artifactId>spring-boot-maven-plugin</artifactId>

View File

@ -4,12 +4,12 @@
<parent> <parent>
<groupId>net.1024lab</groupId> <groupId>net.1024lab</groupId>
<artifactId>sa-parent</artifactId> <artifactId>sa-parent</artifactId>
<version>1.0.0</version> <version>3.0.0</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
<artifactId>sa-admin</artifactId> <artifactId>sa-admin</artifactId>
<version>1.0.0</version> <version>3.0.0</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>sa-admin</name> <name>sa-admin</name>
@ -20,7 +20,7 @@
<dependency> <dependency>
<groupId>net.1024lab</groupId> <groupId>net.1024lab</groupId>
<artifactId>sa-base</artifactId> <artifactId>sa-base</artifactId>
<version>1.0.0</version> <version>3.0.0</version>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@ -37,5 +37,4 @@ public class AdminApplication {
application.addListeners(new LogVariableListener(), new Ip2RegionListener()); application.addListeners(new LogVariableListener(), new Ip2RegionListener());
application.run(args); application.run(args);
} }
} }

View File

@ -159,6 +159,7 @@ public class AdminInterceptor implements HandlerInterceptor {
} }
StpUtil.checkActiveTimeout(); StpUtil.checkActiveTimeout();
StpUtil.updateLastActiveToNow();
} }

View File

@ -17,7 +17,6 @@ import net.lab1024.sa.admin.module.system.menu.domain.vo.MenuVO;
import net.lab1024.sa.admin.module.system.role.domain.vo.RoleVO; import net.lab1024.sa.admin.module.system.role.domain.vo.RoleVO;
import net.lab1024.sa.admin.module.system.role.service.RoleEmployeeService; import net.lab1024.sa.admin.module.system.role.service.RoleEmployeeService;
import net.lab1024.sa.admin.module.system.role.service.RoleMenuService; import net.lab1024.sa.admin.module.system.role.service.RoleMenuService;
import net.lab1024.sa.base.common.code.ErrorCode;
import net.lab1024.sa.base.common.code.UserErrorCode; import net.lab1024.sa.base.common.code.UserErrorCode;
import net.lab1024.sa.base.common.constant.RequestHeaderConst; import net.lab1024.sa.base.common.constant.RequestHeaderConst;
import net.lab1024.sa.base.common.constant.StringConst; import net.lab1024.sa.base.common.constant.StringConst;
@ -37,8 +36,8 @@ import net.lab1024.sa.base.module.support.loginlog.LoginLogResultEnum;
import net.lab1024.sa.base.module.support.loginlog.LoginLogService; import net.lab1024.sa.base.module.support.loginlog.LoginLogService;
import net.lab1024.sa.base.module.support.loginlog.domain.LoginLogEntity; import net.lab1024.sa.base.module.support.loginlog.domain.LoginLogEntity;
import net.lab1024.sa.base.module.support.loginlog.domain.LoginLogVO; import net.lab1024.sa.base.module.support.loginlog.domain.LoginLogVO;
import net.lab1024.sa.base.module.support.securityprotect.service.ProtectLoginService;
import net.lab1024.sa.base.module.support.securityprotect.domain.LoginFailEntity; import net.lab1024.sa.base.module.support.securityprotect.domain.LoginFailEntity;
import net.lab1024.sa.base.module.support.securityprotect.service.ProtectLoginService;
import net.lab1024.sa.base.module.support.securityprotect.service.ProtectPasswordService; import net.lab1024.sa.base.module.support.securityprotect.service.ProtectPasswordService;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -57,7 +56,7 @@ import java.util.stream.Collectors;
* @Date 2021-12-01 22:56:34 * @Date 2021-12-01 22:56:34
* @Wechat zhuoda1024 * @Wechat zhuoda1024
* @Email lab1024@163.com * @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024创新实验室</a> * @Copyright <a href="https://1024lab.net">1024创新实验室</a>
*/ */
@Slf4j @Slf4j
@Service @Service
@ -113,7 +112,6 @@ public class LoginService implements StpInterface {
/** /**
* 获取验证码 * 获取验证码
*
*/ */
public ResponseDTO<CaptchaVO> getCaptcha() { public ResponseDTO<CaptchaVO> getCaptcha() {
return ResponseDTO.ok(captchaService.generateCaptcha()); return ResponseDTO.ok(captchaService.generateCaptcha());
@ -134,51 +132,57 @@ public class LoginService implements StpInterface {
// 校验 图形验证码 // 校验 图形验证码
ResponseDTO<String> checkCaptcha = captchaService.checkCaptcha(loginForm); ResponseDTO<String> checkCaptcha = captchaService.checkCaptcha(loginForm);
if (!checkCaptcha.getOk()) { if (!checkCaptcha.getOk()) {
return ResponseDTO.error(UserErrorCode.PARAM_ERROR,checkCaptcha.getMsg()); return ResponseDTO.error(UserErrorCode.PARAM_ERROR, checkCaptcha.getMsg());
} }
// 验证账号和账号状态 // 验证登录名
EmployeeEntity employeeEntity = employeeService.getByLoginName(loginForm.getLoginName()); EmployeeEntity employeeEntity = employeeService.getByLoginName(loginForm.getLoginName());
if (null == employeeEntity) { if (null == employeeEntity) {
return ResponseDTO.userErrorParam("登录名不存在!"); return ResponseDTO.userErrorParam("登录名不存在!");
} }
// 验证账号状态
if (employeeEntity.getDisabledFlag()) { if (employeeEntity.getDisabledFlag()) {
saveLoginLog(employeeEntity, ip, userAgent, "账号已禁用", LoginLogResultEnum.LOGIN_FAIL); saveLoginLog(employeeEntity, ip, userAgent, "账号已禁用", LoginLogResultEnum.LOGIN_FAIL);
return ResponseDTO.userErrorParam("您的账号已被禁用,请联系工作人员!"); return ResponseDTO.userErrorParam("您的账号已被禁用,请联系工作人员!");
} }
// 按照等保要求进行登录校验
ResponseDTO<LoginFailEntity> loginFailEntityResponseDTO = protectLoginService.checkLogin(employeeEntity.getEmployeeId(), UserTypeEnum.ADMIN_EMPLOYEE);
if (!loginFailEntityResponseDTO.getOk()) {
return ResponseDTO.error(loginFailEntityResponseDTO);
}
// 解密前端加密的密码 // 解密前端加密的密码
loginForm.setPassword(profectPasswordService.decryptSm2Password(loginForm.getPassword())); String requestPassword = profectPasswordService.decryptPassword(loginForm.getPassword());
// 验证密码 1万能密码 或者 2真实密码 // 验证密码 是否为万能密码
String superPassword = EmployeeService.getEncryptPwd(configService.getConfigValue(ConfigKeyEnum.SUPER_PASSWORD)); String superPassword = configService.getConfigValue(ConfigKeyEnum.SUPER_PASSWORD);
String requestPassword = EmployeeService.getEncryptPwd(loginForm.getPassword());
boolean superPasswordFlag = superPassword.equals(requestPassword); boolean superPasswordFlag = superPassword.equals(requestPassword);
if (!(superPasswordFlag || employeeEntity.getLoginPwd().equals(requestPassword))) {
// 记录登录失败
saveLoginLog(employeeEntity, ip, userAgent, "密码错误", LoginLogResultEnum.LOGIN_FAIL);
// 记录等级保护次数
String msg = protectLoginService.recordLoginFail(employeeEntity.getEmployeeId(), UserTypeEnum.ADMIN_EMPLOYEE, employeeEntity.getLoginName(), loginFailEntityResponseDTO.getData());
return msg == null ? ResponseDTO.userErrorParam("登录名或密码错误!") : ResponseDTO.error(UserErrorCode.LOGIN_FAIL_WILL_LOCK, msg);
}
// 生成 sa-token的 loginId对于万能密码受限制sa token 要求loginId唯一万能密码只能插入一段uuid // 万能密码特殊操作
String saTokenLoginId = null;
if (superPasswordFlag) { if (superPasswordFlag) {
saTokenLoginId = SUPER_PASSWORD_LOGIN_ID_PREFIX + StringConst.COLON + UUID.randomUUID().toString().replace("-", "") + StringConst.COLON + employeeEntity.getEmployeeId();
} else {
saTokenLoginId = UserTypeEnum.ADMIN_EMPLOYEE.getValue() + StringConst.COLON + employeeEntity.getEmployeeId();
}
// 登录 // 对于万能密码受限制sa token 要求loginId唯一万能密码只能插入一段uuid
StpUtil.login(saTokenLoginId, String.valueOf(loginDeviceEnum.getDesc())); String saTokenLoginId = SUPER_PASSWORD_LOGIN_ID_PREFIX + StringConst.COLON + UUID.randomUUID().toString().replace("-", "") + StringConst.COLON + employeeEntity.getEmployeeId();
// 万能密码登录只能登录15分钟
StpUtil.login(saTokenLoginId, 900);
} else {
// 按照等保登录要求进行登录失败次数校验
ResponseDTO<LoginFailEntity> loginFailEntityResponseDTO = protectLoginService.checkLogin(employeeEntity.getEmployeeId(), UserTypeEnum.ADMIN_EMPLOYEE);
if (!loginFailEntityResponseDTO.getOk()) {
return ResponseDTO.error(loginFailEntityResponseDTO);
}
// 密码错误
if (!employeeEntity.getLoginPwd().equals(EmployeeService.getEncryptPwd(requestPassword))) {
// 记录登录失败
saveLoginLog(employeeEntity, ip, userAgent, "密码错误", LoginLogResultEnum.LOGIN_FAIL);
// 记录等级保护次数
String msg = protectLoginService.recordLoginFail(employeeEntity.getEmployeeId(), UserTypeEnum.ADMIN_EMPLOYEE, employeeEntity.getLoginName(), loginFailEntityResponseDTO.getData());
return msg == null ? ResponseDTO.userErrorParam("登录名或密码错误!") : ResponseDTO.error(UserErrorCode.LOGIN_FAIL_WILL_LOCK, msg);
}
String saTokenLoginId = UserTypeEnum.ADMIN_EMPLOYEE.getValue() + StringConst.COLON + employeeEntity.getEmployeeId();
// 登录
StpUtil.login(saTokenLoginId, String.valueOf(loginDeviceEnum.getDesc()));
}
// 获取员工信息 // 获取员工信息
RequestEmployee requestEmployee = loadLoginInfo(employeeEntity); RequestEmployee requestEmployee = loadLoginInfo(employeeEntity);
@ -186,15 +190,15 @@ public class LoginService implements StpInterface {
// 放入缓存 // 放入缓存
loginEmployeeCache.put(employeeEntity.getEmployeeId(), requestEmployee); loginEmployeeCache.put(employeeEntity.getEmployeeId(), requestEmployee);
//保存登录记录
saveLoginLog(employeeEntity, ip, userAgent, superPasswordFlag ? "万能密码登录" : loginDeviceEnum.getDesc(), LoginLogResultEnum.LOGIN_SUCCESS);
// 移除登录失败 // 移除登录失败
protectLoginService.removeLoginFail(employeeEntity.getEmployeeId(), UserTypeEnum.ADMIN_EMPLOYEE); protectLoginService.removeLoginFail(employeeEntity.getEmployeeId(), UserTypeEnum.ADMIN_EMPLOYEE);
// 获取登录结果信息 // 获取登录结果信息
LoginResultVO loginResultVO = getLoginResult(requestEmployee); LoginResultVO loginResultVO = getLoginResult(requestEmployee);
//保存登录记录
saveLoginLog(employeeEntity, ip, userAgent, superPasswordFlag ? "万能密码登录" : loginDeviceEnum.getDesc(), LoginLogResultEnum.LOGIN_SUCCESS);
// 设置 token // 设置 token
loginResultVO.setToken(StpUtil.getTokenValue()); loginResultVO.setToken(StpUtil.getTokenValue());
@ -207,11 +211,10 @@ public class LoginService implements StpInterface {
/** /**
* 获取登录结果信息 * 获取登录结果信息
*
*/ */
public LoginResultVO getLoginResult(RequestEmployee requestEmployee) { public LoginResultVO getLoginResult(RequestEmployee requestEmployee) {
// 基础信息xde2 // 基础信息
LoginResultVO loginResultVO = SmartBeanUtil.copy(requestEmployee, LoginResultVO.class); LoginResultVO loginResultVO = SmartBeanUtil.copy(requestEmployee, LoginResultVO.class);
// 前端菜单和功能点清单 // 前端菜单和功能点清单
@ -224,7 +227,7 @@ public class LoginService implements StpInterface {
permissionCache.put(requestEmployee.getUserId(), userPermission); permissionCache.put(requestEmployee.getUserId(), userPermission);
// 上次登录信息 // 上次登录信息
LoginLogVO loginLogVO = loginLogService.queryLastByUserId(requestEmployee.getEmployeeId(), UserTypeEnum.ADMIN_EMPLOYEE); LoginLogVO loginLogVO = loginLogService.queryLastByUserId(requestEmployee.getEmployeeId(), UserTypeEnum.ADMIN_EMPLOYEE, LoginLogResultEnum.LOGIN_SUCCESS);
if (loginLogVO != null) { if (loginLogVO != null) {
loginResultVO.setLastLoginIp(loginLogVO.getLoginIp()); loginResultVO.setLastLoginIp(loginLogVO.getLoginIp());
loginResultVO.setLastLoginIpRegion(loginLogVO.getLoginIpRegion()); loginResultVO.setLastLoginIpRegion(loginLogVO.getLoginIpRegion());
@ -238,7 +241,6 @@ public class LoginService implements StpInterface {
/** /**
* 获取登录的用户信息 * 获取登录的用户信息
*
*/ */
private RequestEmployee loadLoginInfo(EmployeeEntity employeeEntity) { private RequestEmployee loadLoginInfo(EmployeeEntity employeeEntity) {
@ -288,7 +290,6 @@ public class LoginService implements StpInterface {
/** /**
* 根据 loginId 获取 员工id * 根据 loginId 获取 员工id
*
*/ */
Long getEmployeeIdByLoginId(String loginId) { Long getEmployeeIdByLoginId(String loginId) {
@ -315,7 +316,6 @@ public class LoginService implements StpInterface {
/** /**
* 退出登录 * 退出登录
*
*/ */
public ResponseDTO<String> logout(String token, RequestUser requestUser) { public ResponseDTO<String> logout(String token, RequestUser requestUser) {
@ -343,15 +343,15 @@ public class LoginService implements StpInterface {
/** /**
* 保存登录日志 * 保存登录日志
*
*/ */
private void saveLoginLog(EmployeeEntity employeeEntity, String ip, String userAgent, String remark, LoginLogResultEnum result) { private void saveLoginLog(EmployeeEntity employeeEntity, String ip, String userAgent, String remark, LoginLogResultEnum result) {
LoginLogEntity loginEntity = LoginLogEntity.builder() LoginLogEntity loginEntity = LoginLogEntity.builder()
.userId(employeeEntity.getEmployeeId()) .userId(employeeEntity.getEmployeeId())
.userType(UserTypeEnum.ADMIN_EMPLOYEE.getValue()) .userType(UserTypeEnum.ADMIN_EMPLOYEE.getValue())
.userName(employeeEntity.getLoginName()) .userName(employeeEntity.getActualName())
.userAgent(userAgent) .userAgent(userAgent)
.loginIp(ip) .loginIp(ip)
.loginIpRegion(SmartIpUtil.getRegion(ip))
.remark(remark) .remark(remark)
.loginResult(result.getValue()) .loginResult(result.getValue())
.createTime(LocalDateTime.now()) .createTime(LocalDateTime.now())
@ -393,7 +393,6 @@ public class LoginService implements StpInterface {
/** /**
* 获取用户的权限包含 角色列表权限列表 * 获取用户的权限包含 角色列表权限列表
*
*/ */
private UserPermission getUserPermission(Long employeeId) { private UserPermission getUserPermission(Long employeeId) {

View File

@ -8,7 +8,7 @@
# 项目配置: 名称、日志目录 # 项目配置: 名称、日志目录
project: project:
name: sa-admin name: sa-admin
log-directory: /home/smart-admin/${project.name}/${spring.profiles.active} log-directory: /home/logs/smart_admin_v3/${project.name}/${spring.profiles.active}
# 项目端口和url根路径 # 项目端口和url根路径
server: server:

View File

@ -8,7 +8,7 @@
# 项目配置: 名称、日志目录 # 项目配置: 名称、日志目录
project: project:
name: sa-admin name: sa-admin
log-directory: /home/smart-admin/${project.name}/${spring.profiles.active} log-directory: /home/logs/smart_admin_v3/${project.name}/${spring.profiles.active}
# 项目端口和url根路径 # 项目端口和url根路径
server: server:

View File

@ -8,7 +8,7 @@
# 项目配置: 名称、日志目录 # 项目配置: 名称、日志目录
project: project:
name: sa-admin name: sa-admin
log-directory: /home/smart-admin/${project.name}/${spring.profiles.active} log-directory: /home/logs/smart_admin_v3/${project.name}/${spring.profiles.active}
# 项目端口和url根路径 # 项目端口和url根路径
server: server:

View File

@ -8,7 +8,7 @@
# 项目配置: 名称、日志目录 # 项目配置: 名称、日志目录
project: project:
name: sa-admin name: sa-admin
log-directory: /home/smart-admin/${project.name}/${spring.profiles.active} log-directory: /home/logs/smart_admin_v3/${project.name}/${spring.profiles.active}
# 项目端口和url根路径 # 项目端口和url根路径
server: server:

View File

@ -4,12 +4,12 @@
<parent> <parent>
<groupId>net.1024lab</groupId> <groupId>net.1024lab</groupId>
<artifactId>sa-parent</artifactId> <artifactId>sa-parent</artifactId>
<version>1.0.0</version> <version>3.0.0</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
<artifactId>sa-base</artifactId> <artifactId>sa-base</artifactId>
<version>1.0.0</version> <version>3.0.0</version>
<name>sa-base</name> <name>sa-base</name>
<description>sa-base project</description> <description>sa-base project</description>
@ -248,12 +248,17 @@
<artifactId>poi-scratchpad</artifactId> <artifactId>poi-scratchpad</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.fasterxml.jackson.datatype</groupId> <groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId> <artifactId>jackson-datatype-jsr310</artifactId>
</dependency> </dependency>
<dependency>
<groupId>net.1024lab</groupId>
<artifactId>smartdb</artifactId>
<version>${smartdb.version}</version>
</dependency>
</dependencies> </dependencies>

View File

@ -5,6 +5,7 @@ import net.lab1024.sa.base.common.constant.StringConst;
import org.lionsoul.ip2region.xdb.Searcher; import org.lionsoul.ip2region.xdb.Searcher;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
/** /**
@ -46,21 +47,19 @@ public class SmartIpUtil {
* @return 返回结果例 [河南省, 洛阳市, 洛龙区] * @return 返回结果例 [河南省, 洛阳市, 洛龙区]
*/ */
public static List<String> getRegionList(String ipStr) { public static List<String> getRegionList(String ipStr) {
List<String> regionList = new ArrayList<>();
try { try {
List<String> regionList = new ArrayList<>();
if (SmartStringUtil.isEmpty(ipStr)) { if (SmartStringUtil.isEmpty(ipStr)) {
return regionList; return regionList;
} }
ipStr = ipStr.trim(); ipStr = ipStr.trim();
String region = IP_SEARCHER.search(ipStr); String region = IP_SEARCHER.search(ipStr);
String[] split = region.split("\\|"); String[] split = region.split("\\|");
for (String str : split) { regionList.addAll(Arrays.asList(split));
regionList.add(str);
}
return regionList;
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException(e); log.error("解析ip地址出错", e);
} }
return regionList;
} }
/** /**
@ -77,7 +76,8 @@ public class SmartIpUtil {
ipStr = ipStr.trim(); ipStr = ipStr.trim();
return IP_SEARCHER.search(ipStr); return IP_SEARCHER.search(ipStr);
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException(e); log.error("解析ip地址出错", e);
return StringConst.EMPTY;
} }
} }

View File

@ -76,7 +76,8 @@ public class FileConfig implements WebMvcConfigurer {
.withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials(accessKey, secretKey))) .withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials(accessKey, secretKey)))
.withClientConfiguration(clientConfig) .withClientConfiguration(clientConfig)
.withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(endpoint, region)) .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(endpoint, region))
.withPathStyleAccessEnabled(true) .withPathStyleAccessEnabled(false)
.withChunkedEncodingDisabled(true)
.build(); .build();
} }

View File

@ -1,5 +1,7 @@
package net.lab1024.sa.base.module.support.file.service; package net.lab1024.sa.base.module.support.file.service;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.CannedAccessControlList; import com.amazonaws.services.s3.model.CannedAccessControlList;
import com.amazonaws.services.s3.model.ObjectMetadata; import com.amazonaws.services.s3.model.ObjectMetadata;
@ -30,6 +32,7 @@ import java.io.UnsupportedEncodingException;
import java.net.URL; import java.net.URL;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -84,7 +87,8 @@ public class FileStorageCloudServiceImpl implements IFileStorageService {
String fileType = FilenameUtils.getExtension(originalFileName); String fileType = FilenameUtils.getExtension(originalFileName);
String uuid = UUID.randomUUID().toString().replaceAll("-", ""); String uuid = UUID.randomUUID().toString().replaceAll("-", "");
String fileKey = path + uuid + "." + fileType; String time = LocalDateTimeUtil.format(LocalDateTime.now(), DatePattern.PURE_DATETIME_FORMATTER);
String fileKey = path + uuid + "_" + time+ "." + fileType;
// 文件名称 URL 编码 // 文件名称 URL 编码
String urlEncoderFilename; String urlEncoderFilename;

View File

@ -40,7 +40,7 @@ public interface LoginLogDao extends BaseMapper<LoginLogEntity> {
* @param userType * @param userType
* @return LoginLogVO * @return LoginLogVO
*/ */
LoginLogVO queryLastByUserId(@Param("userId") Long userId,@Param("userType") Integer userType); LoginLogVO queryLastByUserId(@Param("userId") Long userId,@Param("userType") Integer userType, @Param("loginLogResult")Integer loginLogResult);
} }

View File

@ -60,8 +60,8 @@ public class LoginLogService {
* @author 卓大 * @author 卓大
* @description 查询上一个登录记录 * @description 查询上一个登录记录
*/ */
public LoginLogVO queryLastByUserId(Long userId, UserTypeEnum userTypeEnum) { public LoginLogVO queryLastByUserId(Long userId, UserTypeEnum userTypeEnum, LoginLogResultEnum loginLogResultEnum) {
return loginLogDao.queryLastByUserId(userId,userTypeEnum.getValue()); return loginLogDao.queryLastByUserId(userId,userTypeEnum.getValue(), loginLogResultEnum.getValue());
} }
} }

View File

@ -91,7 +91,7 @@ public class ProtectPasswordService {
* @param encryptedPassword * @param encryptedPassword
* @return * @return
*/ */
public String decryptSm2Password(String encryptedPassword) { public String decryptPassword(String encryptedPassword) {
return apiEncryptService.decrypt(encryptedPassword); return apiEncryptService.decrypt(encryptedPassword);
} }

View File

@ -1,9 +1,9 @@
spring: spring:
# 数据库连接信息 # 数据库连接信息
datasource: datasource:
url: jdbc:p6spy:mysql://127.0.0.1:3306/smart_admin_v3?autoReconnect=true&useServerPreparedStmts=false&rewriteBatchedStatements=true&characterEncoding=UTF-8&useSSL=false&allowMultiQueries=true&serverTimezone=Asia/Shanghai url: jdbc:p6spy:mysql://127.0.0.1/smart_admin_v3?autoReconnect=true&useServerPreparedStmts=false&rewriteBatchedStatements=true&characterEncoding=UTF-8&useSSL=false&allowMultiQueries=true&serverTimezone=Asia/Shanghai
username: root username: root
password: Java@1024 password: Zhuoda.666
initial-size: 2 initial-size: 2
min-idle: 2 min-idle: 2
max-active: 10 max-active: 10
@ -65,6 +65,22 @@ server:
pattern: "%t %{X-Forwarded-For}i %a %r %s (%D ms) %I (%B byte)" pattern: "%t %{X-Forwarded-For}i %a %r %s (%D ms) %I (%B byte)"
# 文件上传 配置
#file:
# storage:
# mode: local
# local:
# upload-path: /home/smart_admin_v3/upload/ #文件上传目录
# url-prefix:
# cloud:
# region: oss-cn-qingdao
# endpoint: oss-cn-qingdao.aliyuncs.com
# bucket-name: common
# access-key:
# secret-key:
# url-prefix: https://${file.storage.cloud.bucket-name}.${file.storage.cloud.endpoint}/
# private-url-expire-seconds: 3600
# 文件上传 配置 # 文件上传 配置
file: file:
storage: storage:
@ -73,15 +89,14 @@ file:
upload-path: /home/smart_admin_v3/upload/ #文件上传目录 upload-path: /home/smart_admin_v3/upload/ #文件上传目录
url-prefix: url-prefix:
cloud: cloud:
region: oss-cn-qingdao region: oss-cn-hangzhou
endpoint: oss-cn-qingdao.aliyuncs.com endpoint: oss-cn-hangzhou.aliyuncs.com
bucket-name: common bucket-name: smart-admin
access-key: access-key:
secret-key: secret-key:
url-prefix: https://${file.storage.cloud.bucket-name}.${file.storage.cloud.endpoint}/ url-prefix: https://${file.storage.cloud.bucket-name}.${file.storage.cloud.endpoint}/
private-url-expire-seconds: 3600 private-url-expire-seconds: 3600
# open api配置 # open api配置
springdoc: springdoc:
swagger-ui: swagger-ui:

View File

@ -30,7 +30,8 @@
where where
user_id = #{userId} user_id = #{userId}
and user_type = #{userType} and user_type = #{userType}
order by create_time desc and login_result = #{loginLogResult}
order by login_log_id desc
limit 1 limit 1
</select> </select>

View File

@ -1,3 +1,3 @@
NODE_ENV=production NODE_ENV=production
VITE_APP_TITLE='SmartAdmin 预发布环境(Pre)' VITE_APP_TITLE='SmartAdmin 预发布环境(Pre)'
VITE_APP_API_URL='http://preview.smartadmin.1024lab.net/smart-admin-api' VITE_APP_API_URL='https://preview.smartadmin.vip/smart-admin-api'

View File

@ -1,3 +1,3 @@
NODE_ENV=production NODE_ENV=production
VITE_APP_TITLE='SmartAdmin V3.X' VITE_APP_TITLE='SmartAdmin V3.X'
VITE_APP_API_URL='http://preview.smartadmin.1024lab.net/smart-admin-api' VITE_APP_API_URL='https://preview.smartadmin.vip/smart-admin-api'

File diff suppressed because it is too large Load Diff

View File

@ -33,6 +33,6 @@ export const fileApi = {
* 下载文件流根据fileKey @author 胡克 * 下载文件流根据fileKey @author 胡克
*/ */
downLoadFile: (fileName, fileKey) => { downLoadFile: (fileName, fileKey) => {
return getDownload(fileName, '/support/file/downLoad', { fileKey }); return getDownload('/support/file/downLoad', { fileKey });
}, },
}; };

View File

@ -9,17 +9,17 @@
* *
--> -->
<template> <template>
<div class="container"> <div class="container">
<a-image <a-image
class="img-prev" class="img-prev"
:style="{ display: 'none' }" :style="{ display: 'none' }"
:preview="{ :preview="{
visible, visible,
onVisibleChange: setVisible, onVisibleChange: setVisible,
}" }"
:src="previewUrl" :src="previewUrl"
/> />
</div> </div>
</template> </template>
<script setup> <script setup>
@ -62,7 +62,7 @@
setVisible(true); setVisible(true);
return; return;
} }
getDownload(fileItem.fileName, fileItem.fileUrl); window.open(fileItem.fileUrl);
} }
// //

View File

@ -64,7 +64,7 @@
previewCurrent.value = index; previewCurrent.value = index;
visible.value = true; visible.value = true;
} else { } else {
getDownload(file.fileName, file.fileUrl); window.open(file.fileUrl);
} }
} }

View File

@ -140,7 +140,6 @@
{ {
title: '文件名称', title: '文件名称',
dataIndex: 'fileName', dataIndex: 'fileName',
ellipsis: true,
width: 200, width: 200,
}, },
{ {
@ -152,7 +151,6 @@
{ {
title: '文件key', title: '文件key',
dataIndex: 'fileKey', dataIndex: 'fileKey',
ellipsis: true,
}, },
{ {
title: '文件类型', title: '文件类型',
@ -218,7 +216,7 @@
// //
function onSearch(){ function onSearch() {
queryForm.pageNum = 1; queryForm.pageNum = 1;
queryData(); queryData();
} }