This commit is contained in:
六如
2024-12-22 23:09:46 +08:00
parent 02fb5a9e85
commit 403e8111f4
1239 changed files with 4764 additions and 702 deletions

View File

@@ -0,0 +1,141 @@
<?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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.gitee.sop</groupId>
<artifactId>sop-admin-backend</artifactId>
<version>5.0.0-SNAPSHOT</version>
</parent>
<artifactId>admin-boot</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.gitee.sop</groupId>
<artifactId>admin-web</artifactId>
<version>5.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>
<!-- nacos注册中心 -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-nacos-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- provided -->
<!-- 仅在开发中使用 -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-zookeeper-curator5</artifactId>
<version>${dubbo.version}</version>
<type>pom</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<repositories>
<repository>
<id>aliyun</id>
<name>aliyun</name>
<url>https://maven.aliyun.com/repository/public</url>
</repository>
</repositories>
<build>
<plugins>
<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>
<version>2.12.4</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.3.1</version>
<configuration>
<configLocation>checkstyle.xml</configLocation>
<consoleOutput>true</consoleOutput>
<failsOnError>true</failsOnError>
<linkXRef>false</linkXRef>
</configuration>
<executions>
<execution>
<id>validate</id>
<phase>validate</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,15 @@
package com.gitee.sop.admin;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@EnableDubbo
public class SopAdminApplication {
public static void main(String[] args) {
SpringApplication.run(SopAdminApplication.class, args);
}
}

View File

@@ -0,0 +1,17 @@
package com.gitee.sop.admin.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* @author 六如
*/
@Configuration
@ConfigurationProperties(prefix = "admin")
@Data
public class AdminConfig {
private int jwtTimeoutDays;
}

View File

@@ -0,0 +1,106 @@
package com.gitee.sop.admin.config;
import com.gitee.sop.admin.common.context.SpringContext;
import com.gitee.sop.admin.common.util.SystemUtil;
import com.gitee.sop.admin.interceptor.LoginInterceptor;
import com.gitee.sop.admin.service.sys.UserCacheService;
import com.gitee.sop.admin.service.sys.impl.LocalUserCacheService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @author 六如
*/
@Configuration
@Slf4j
public class SopAdminConfiguration implements ApplicationContextAware, WebMvcConfigurer {
@Value("${front-location:}")
private String frontLocation;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringContext.setApplicationContext(applicationContext);
}
@Bean
@ConditionalOnProperty(value = "user.cache.type", havingValue = "local", matchIfMissing = true)
public UserCacheService userCacheService() {
return new LocalUserCacheService();
}
/**
* 配置拦截器
*
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
String[] excludes = {
"/", "/error",
// 排除前端资源
"/*.html", "/*.ico", "/*.png", "/*.json", "/static/**", "/assets/**"
};
registry.addInterceptor(new LoginInterceptor())
.excludePathPatterns(excludes);
}
/**
* 跨域设置
*/
@Bean
public CorsFilter corsFilter(
@Value("${torna.cors.allowed-origin-pattern:*}") String allowedOriginPattern,
@Value("${torna.cors.allowed-header:*}") String allowedHeader
) {
CorsConfiguration corsConfiguration = new CorsConfiguration();
// SpringBoot升级2.4.0之后,跨域配置中的.allowedOrigins不再可用,改成addAllowedOriginPattern
corsConfiguration.addAllowedOriginPattern(allowedOriginPattern);
corsConfiguration.addAllowedHeader(allowedHeader);
corsConfiguration.addAllowedMethod(CorsConfiguration.ALL);
corsConfiguration.addExposedHeader("Content-Disposition");
corsConfiguration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", corsConfiguration);
return new CorsFilter(source);
}
/**
* 配置静态资源
*
* @param registry
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
String homeDir = SystemUtil.getBinPath();
String frontRoot;
if (StringUtils.hasText(frontLocation)) {
frontRoot = StringUtils.trimTrailingCharacter(frontLocation, '/');
} else {
frontRoot = homeDir + "/dist";
}
log.info("前端资源目录:{}", frontRoot);
String location = "file:" + frontRoot;
registry.addResourceHandler("/index.html").addResourceLocations(location + "/index.html");
registry.addResourceHandler("/favicon.ico").addResourceLocations(location + "/favicon.ico");
registry.addResourceHandler("/logo.png").addResourceLocations(location + "/logo.png");
registry.addResourceHandler("/platform-config.json").addResourceLocations(location + "/platform-config.json");
registry.addResourceHandler("/static/**").addResourceLocations(location + "/static/");
registry.addResourceHandler("/assets/**").addResourceLocations(location + "/assets/");
}
}

View File

@@ -0,0 +1,45 @@
package com.gitee.sop.admin.interceptor;
import com.gitee.sop.admin.common.annotation.NoToken;
import com.gitee.sop.admin.common.enums.StatusEnum;
import com.gitee.sop.admin.common.user.User;
import com.gitee.sop.admin.common.context.UserContext;
import com.gitee.sop.admin.common.exception.LoginFailureException;
import com.gitee.sop.admin.common.util.RequestUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author tanghc
*/
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (!(handler instanceof HandlerMethod)) {
return true;
}
HandlerMethod handlerMethod = (HandlerMethod) handler;
NoToken noLogin = handlerMethod.getMethodAnnotation(NoToken.class);
if (noLogin != null) {
return true;
}
noLogin = AnnotationUtils.findAnnotation(handlerMethod.getBeanType(), NoToken.class);
if (noLogin != null) {
return true;
}
User user = UserContext.getUser(request);
if (user == null || StatusEnum.of(user.getStatus()) == StatusEnum.DISABLED) {
log.error("登录失败, 客户端ip:{}, uri:{}", RequestUtil.getIP(request), request.getRequestURI());
throw new LoginFailureException("登录失败");
}
return true;
}
}

View File

@@ -0,0 +1,8 @@
dubbo.registry.address=zookeeper://localhost:2181
mybatis.print-sql=true
# mysql config
mysql.host=127.0.0.1:3306
mysql.username=root
mysql.password=root

View File

@@ -0,0 +1,8 @@
dubbo.registry.address=nacos://localhost:8848
mybatis.print-sql=true
# mysql config
mysql.host=127.0.0.1:3306
mysql.username=root
mysql.password=root

View File

@@ -0,0 +1,48 @@
server.port=8082
spring.profiles.active=dev
spring.application.name=sop-admin
index.path=/
####### admin config #######
# user cache
user.cache.type=local
dubbo.protocol.name=dubbo
dubbo.protocol.port=-1
dubbo.application.qos-enable=false
dubbo.consumer.check=false
# ### register config see:https://cn.dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/registry/overview/
# ------
# nacos://localhost:8848 Cluster config:nacos://localhost:8848?backup=localshot:8846,localshot:8847
# zookeeper://localhost:2181 Cluster config:zookeeper://10.20.153.10:2181?backup=10.20.153.11:2181,10.20.153.12:2181
# redis://localhost:6379 Cluster config:redis://10.20.153.10:6379?backup=10.20.153.11:6379,10.20.153.12:6379
# ------
dubbo.registry.address=zookeeper://localhost:2181
####### mysql config #######
mysql.host=127.0.0.1:3306
mysql.username=
mysql.password=
mysql.db=sop
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://${mysql.host}/${mysql.db}?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai
spring.datasource.username=${mysql.username}
spring.datasource.password=${mysql.password}
####### mybatis config #######
mybatis.fill.com.gitee.fastmybatis.core.support.LocalDateTimeFillInsert=add_time
mybatis.fill.com.gitee.fastmybatis.core.support.LocalDateTimeFillUpdate=update_time
mybatis.fill.com.gitee.sop.admin.common.fill.AddByFill=
mybatis.fill.com.gitee.sop.admin.common.fill.UpdateByFill=
# mybatis config file
mybatis.config-location=classpath:mybatis/mybatisConfig.xml
mybatis.mapper-locations=classpath:mybatis/mapper/*.xml
# print SQL
logging.level.com.gitee.sop.admin.dao=error
logging.level.com.gitee.fastmybatis=info
mybatis.print-sql=false

View File

@@ -0,0 +1,13 @@
package com.gitee.sop.admin;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class BaseTest {
@Test
void contextLoads() {
}
}

View File

@@ -0,0 +1,44 @@
package com.gitee.sop.admin.service;
import com.alibaba.fastjson2.JSON;
import com.gitee.sop.admin.BaseTest;
import com.gitee.sop.admin.service.sys.login.LoginService;
import com.gitee.sop.admin.service.sys.login.dto.LoginDTO;
import com.gitee.sop.admin.service.sys.login.dto.LoginUser;
import com.gitee.sop.admin.service.sys.login.enums.RegTypeEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.apache.commons.codec.digest.DigestUtils;
import org.junit.jupiter.api.Test;
import org.springframework.security.crypto.bcrypt.BCrypt;
import org.springframework.util.Assert;
/**
* @author 六如
*/
public class LoginServiceTest extends BaseTest {
@Autowired
LoginService loginService;
@Test
public void login() {
LoginDTO loginDTO = new LoginDTO();
loginDTO.setUsername("admin");
loginDTO.setPassword("123456");
loginDTO.setRegType(RegTypeEnum.BACKEND);
LoginUser loginUser = loginService.login(loginDTO);
Assert.notNull(loginUser, "not null");
System.out.println(JSON.toJSONString(loginUser));
}
@Test
public void resetAdminPwd() {
// 初始密码
String defPassword = "123456";
defPassword = DigestUtils.sha256Hex(defPassword);
String encodedPassword = BCrypt.hashpw(defPassword, BCrypt.gensalt());
}
}

View File

@@ -0,0 +1,36 @@
package com.gitee.sop.admin.service;
import com.gitee.sop.admin.BaseTest;
import com.gitee.sop.admin.dao.entity.SysUser;
import com.gitee.sop.admin.service.sys.SysUserService;
import org.apache.commons.codec.digest.DigestUtils;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCrypt;
/**
* @author 六如
*/
public class PasswordTest extends BaseTest {
@Autowired
SysUserService sysAdminUserService;
/**
* 重置admin密码
*/
@Test
public void resetAdminPwd() {
String username = "admin";
String defPassword = "123456";
defPassword = DigestUtils.sha256Hex(defPassword);
String encodedPassword = BCrypt.hashpw(defPassword, BCrypt.gensalt());
System.out.println("数据库保存:" + encodedPassword);
sysAdminUserService.query()
.eq(SysUser::getUsername, username)
.set(SysUser::getPassword, encodedPassword)
.update();
}
}