初始化

This commit is contained in:
黎润豪 2026-02-12 09:48:07 +08:00
commit f201fa589e
22 changed files with 1150 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
/.idea
/*.iml
/target

8
README.md Normal file
View File

@ -0,0 +1,8 @@
# youfool-framework-springboot 基础项目模板
## 数据源
当前版本3.0版本以上)的基础框架使用了`苞米豆`的[动态数据源](https://github.com/baomidou/dynamic-datasource-spring-boot-starter) 。
使用事务时需注意使用`@DSTransactional`代替`@Transactional`来使用注解式事务。

146
checkstyle-v1.0.xml Normal file
View File

@ -0,0 +1,146 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
"https://checkstyle.org/dtds/configuration_1_3.dtd">
<!-- checker检查器,checkstyle固定配置写法,不能缺失 -->
<module name="Checker">
<!--排除指定文件-->
<!-- <module name="BeforeExecutionExclusionFileFilter">-->
<!-- <property name="fileNamePattern" value="(FoodTrWebinfoReport.java|IssueApplyQuery.java)"/>-->
<!-- </module>-->
<!-- 设置checkstyle以UTF8格式进行文件检查 -->
<property name="charset" value="UTF-8"/>
<!--定义严重程度,可选等级:ignore info warning error,如不定义默认为error -->
<property name="severity" value="error"/>
<!-- 检查文件的长度最多2000行-->
<module name="FileLength">
<property name="max" value="2000"/>
</module>
<!--检查**.properties配置文件 是否有相同的key值 -->
<module name="Translation">
<property name="severity" value="error"/>
</module>
<!-- 检查每行字符数 -->
<module name="LineLength">
<property name="max" value="200"/>
</module>
<!-- 语法树编辑器,会根据其中定义规则,检查每个.java文件 -->
<module name="TreeWalker">
<!-- 检查多余的导入,如一个类导入了多次-->
<module name="RedundantImport"/>
<!-- 检查是否导入的包没有使用,如导入的包在类中没有被使用-->
<module name="UnusedImports"/>
<!-- 检查局部常量命名规范,有默认规则"^[a-z][a-zA-Z0-9]*$",可自定义" -->
<module name="LocalFinalVariableName"/>
<!-- 检查局部变量命名规范,有默认规则"^[a-z][a-zA-Z0-9]*$,可自定义,如for(int i=0;i<5;i++)里面的i -->
<module name="LocalVariableName"/>
<!-- 检查非final的静态变量,有默认规则"^[a-z][a-zA-Z0-9]*$",可自定义-->
<module name="StaticVariableName">
<property name="format" value="(^[A-Z0-9_]{0,19}$)"/>
</module>
<!-- 检查包名称命名规范,有默认规则"^[a-z]+(\.[a-z][a-z0-9]*)*$",详细解释为第一位必须为小写字母,后面位数可出现"."和小写字母/大写字母/数字 -->
<module name="PackageName">
<property name="format" value="^[a-z]+(\.[a-z][a-z0-9]*)*$"/>
</module>
<!-- 类名命名规则 -->
<module name="TypeName">
<property name="format" value="(^[A-Z][a-zA-Z0-9]{0,30}$)"/>
</module>
<!-- 方法名命名规则 -->
<module name="MethodName">
<property name="format" value="(^[a-z][a-zA-Z0-9]{0,30}$)"/>
</module>
<!-- 实例变量/成员变量命名规则 -->
<module name="MemberName">
<property name="format" value="(^[a-z][a-zA-Z0-9]{0,30}$)"/>
</module>
<!-- 方法中的参数名命名规则 -->
<module name="ParameterName">
<property name="format" value="(^[a-z][a-zA-Z0-9_]{0,19}$)"/>
</module>
<!-- 静态常量命名规则 -->
<module name="ConstantName">
<property name="format" value="(^[A-Z][A-Z0-9_]{0,50}$)"/>
</module>
<!-- 检测代码缩进规则,默认值为4字节 -->
<module name="Indentation">
</module>
<!-- 检查是否存在过度复杂的boolean返回值,例: if(b) {return true;} else {return false;}-->
<module name="SimplifyBooleanReturn"/>
<!-- 确保Utils类只包含静态方法或属性(字段)的类中没有public构造器。-->
<module name="HideUtilityClassConstructor"/>
<!-- 检查class成员属性可见性只有static final 修饰的成员是可以public的其他的成员属性必需是private的 -->
<module name="VisibilityModifier"/>
<!-- 检查每个变量声明是不是在其自己的语句中及自己的行上 -->
<module name="MultipleVariableDeclarations">
</module>
<!-- 检查再定义数组时采用java风格还是c风格例如int[] num是java风格int num[]是c风格。默认是java风格-->
<module name="ArrayTypeStyle">
</module>
<!-- 检查是否是"MagicNumber",指的是未定义的数字文本,但默认情况-1/0/1/2不视为"MagicNumber" -->
<!-- <module name="MagicNumber">-->
<!-- </module>-->
<!-- 检查是否在long类型是否定义了大写的L.字母小写l和数字1很相似 -->
<module name="UpperEll"/>
<!-- 检查switch语句是否有 default从句 -->
<module name="MissingSwitchDefault"/>
<!--检查switch中case后是否加入了跳出语句例如return、break、throw、continue -->
<module name="FallThrough"/>
<!-- 检查方法或构造函数中的参数数量-->
<module name="ParameterNumber">
<property name="max" value="7"/>
</module>
<!-- 检查方法长度忽略空行和注释最大上限为300 -->
<module name="MethodLength">
<property name="max" value="300"/>
<property name="countEmpty" value="false"/>
</module>
<!-- 检查是否有多余的修饰符例如接口中的方法不必使用public、abstract修饰 -->
<module name="RedundantModifier">
</module>
<!--- 字符串比较必须使用 equals() -->
<module name="StringLiteralEquality">
</module>
<!-- if-else嵌套语句个数最多为10层 -->
<module name="NestedIfDepth">
<property name="max" value="10"/>
</module>
<!-- try-catch 嵌套语句个数 最多3层 -->
<module name="NestedTryDepth">
<property name="max" value="3"/>
</module>
</module>
</module>

163
pom.xml Normal file
View File

@ -0,0 +1,163 @@
<?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>
<groupId>com.chinaweal.youfool</groupId>
<artifactId>youfool-prj-springboot3-template</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<url>https://www.chinaweal.com.cn</url>
<description>boot基础的后台模板</description>
<properties>
<java.version>25</java.version>
<skipTests>true</skipTests>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>25</maven.compiler.source>
<maven.compiler.target>25</maven.compiler.target>
<maven.compiler.compilerVersion>25</maven.compiler.compilerVersion>
<failOnMissingWebXml>false</failOnMissingWebXml>
<spring.boot.version>3.4.5</spring.boot.version>
<skipTests>true</skipTests>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!--基础框架youfool-framework-boot-->
<dependency>
<groupId>com.chinaweal.youfool</groupId>
<artifactId>youfool-framework-springboot3</artifactId>
<version>1.0.4</version>
</dependency>
<!--postgresql-->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.7.9</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.42</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<!-- 分离依赖 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.8.1</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<!-- 依赖输出目录 -->
<outputDirectory>${project.build.directory}/libs</outputDirectory>
<!-- 排除传递依赖中的可选依赖 -->
<excludeGroupIds>org.projectlombok</excludeGroupIds>
<!-- <excludeOptional>true</excludeOptional>-->
</configuration>
</execution>
</executions>
</plugin>
<!-- 配置 Spring Boot 打包插件 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!-- 不打包依赖 -->
<layout>ZIP</layout>
<includes>
<include>
<groupId>nothing</groupId>
<artifactId>nothing</artifactId>
</include>
</includes>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- 配置编译器,添加 -parameters 参数 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.14.1</version> <!-- 适配 JDK 17 的版本 -->
<configuration>
<source>21</source>
<target>21</target>
<!-- 显式指定编译器参数,保留方法参数名 -->
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
</plugin>
<!-- 代码风格检测插件 checkstyle -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.1.1</version>
<configuration>
<!--encoding和consoleOutput一般配套使用,consoleOutput用来设置是否输出相关检查语句,encoding用来设置输出语句的编码格式-->
<encoding>utf-8</encoding>
<consoleOutput>true</consoleOutput>
<!-- 如果在检测中出现error,则打包程序会在checkstyle程序检查完成后停下来 -->
<failsOnError>true</failsOnError>
<!-- 是否包括测试类 -->
<includeTestSourceDirectory>false</includeTestSourceDirectory>
<!-- 自定义配置目录 -->
<configLocation>checkstyle-v1.0.xml</configLocation>
</configuration>
<executions>
<execution>
<id>validate</id>
<phase>validate</phase>
<goals>
<!-- checkstylecheck目标是一个普通目标它向控制台报告违规情况和/或在发生违规情况时使构建失败 -->
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,31 @@
package com.chinaweal.youfool.prj;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.cache.annotation.EnableCaching;
@SpringBootApplication(scanBasePackages = {"com.chinaweal"})
@EnableCaching
@Slf4j
public class YoufoolApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(YoufoolApplication.class, args);
log.info("========================== 程序启动成功! ==========================");
log.info("====== 程 序youfool-prj-springboot-template");
log.info("====== 描 述boot基础的后台模板");
log.info("====== CMS 基础框架后台管理系统路径:/cms账号admin、密码123456");
log.info("====== 接口文档路径:/doc.html账号admin、密码123456。注如果乱码请指定VM -Dfile.encoding=UTF-8");
log.info("====== Druid Monitor路径/druid账号admin、密码123456");
log.info("====================================================================");
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(this.getClass());
}
}

View File

@ -0,0 +1,13 @@
package com.chinaweal.youfool.prj.common.constants;
import cn.dev33.satoken.session.SaSession;
/**
* session常量
* @author lroyia
* @since 2022/7/19 11:02
**/
public interface SessionConstants {
String USER_KEY = SaSession.USER;
}

View File

@ -0,0 +1,114 @@
package com.chinaweal.youfool.prj.common.util;
import java.util.UUID;
/**
* 字符串工具类
*
* @author lroyia
* @since 2022/4/20 15:04
**/
public abstract class StringUtils extends com.chinaweal.youfool.framework.springboot.common.util.StringUtils {
private static final char[] HEX_DIGITS_LOW = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
public static final char[] FILE_NAME_SPECIFY_CHARS = new char[]{'/', '\\', ':', '*', '"', '<', '>', '|'};
/**
* 是否全为非空
*
* @param str 判断字串可选参数
* @return 判断结果
* @author lroyia
* @since 2023年5月26日 11:39:29
*/
public static boolean isNotBlankALl(String... str) {
for (String each : str) {
if (isBlank(each)) {
return false;
}
}
return true;
}
/**
* 是否全为空
*
* @param str 判断字串可选参数
* @return 判断结果
* @author lroyia
* @since 2023年5月26日 11:35:29
*/
public static boolean isBlankAll(String... str) {
for (String each : str) {
if (isNotBlank(each)) {
return false;
}
}
return true;
}
/**
* 16进制字符串转byte数组
*
* @param hex 16进制字符串
* @return 转换结果
* @author lroyia
* @since 2022年7月12日 15:13:13
*/
public static byte[] hexFromString(String hex) {
int len = hex.length();
byte[] buf = new byte[(len + 1) / 2];
int i = 0;
int j = 0;
if (len % 2 == 1)
buf[j++] = (byte) fromDigit(hex.charAt(i++));
while (i < len)
buf[j++] = (byte) (fromDigit(hex.charAt(i++)) << 4 | fromDigit(hex.charAt(i++)));
return buf;
}
/**
* [0-9][A-F][a-f]转整形
*
* @param ch 字符
* @return 转换结果
* @author lroyia
* @since 2022年7月12日 15:11:59
*/
public static int fromDigit(char ch) {
if (ch >= '0' && ch <= '9')
return ch - 48;
if (ch >= 'A' && ch <= 'F')
return (ch - 65) + 10;
if (ch >= 'a' && ch <= 'f')
return (ch - 97) + 10;
else
throw new IllegalArgumentException("invalid hex digit '" + ch + "'");
}
/**
* 不是数字
*
* @param cs 字符
* @return 判断结果
* @author lroyia
* @since 2022年8月22日 14:56:01
*/
public static boolean isNotNumeric(CharSequence cs) {
return !isNumeric(cs);
}
/**
* 获取一个UUID
*
* @return UUID
* @author lroyia
* @since 2022年9月15日 10:27:03
*/
public static String getUUID() {
return UUID.randomUUID().toString().replace("-", EMPTY);
}
}

View File

@ -0,0 +1,43 @@
package com.chinaweal.youfool.prj.config;
import com.baomidou.mybatisplus.core.config.GlobalConfig;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import com.chinaweal.youfool.framework.springboot.mybatis.plus.CommonMetaObjectHandler;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.ArrayUtils;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import javax.sql.DataSource;
/**
* 项目的数据源
*/
@Configuration
@MapperScan(basePackages = {"com.chinaweal.youfool.framework.springboot.cms.**.mapper", "com.chinaweal.youfool.prj.**.mapper"})
public class PrjDataSource {
@Resource
private CommonMetaObjectHandler commonMetaObjectHandler;
@Bean
@Primary
public MybatisSqlSessionFactoryBean sqlSessionFactory(DataSource dataSource) throws Exception {
MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
bean.setDataSource(dataSource);
GlobalConfig globalConfig = new GlobalConfig();
globalConfig.setMetaObjectHandler(commonMetaObjectHandler);
bean.setGlobalConfig(globalConfig);
bean.setConfigLocation(new ClassPathResource("mybatis/mybatis-config.xml"));
org.springframework.core.io.Resource[] prjResources = new PathMatchingResourcePatternResolver().getResources("classpath*:mybatis/mapper/**/*.xml");
org.springframework.core.io.Resource[] cmsResources = new PathMatchingResourcePatternResolver().getResources("classpath*:cms/mybatis/mapper/**/*.xml");
org.springframework.core.io.Resource[] resources = ArrayUtils.addAll(prjResources, cmsResources);
bean.setMapperLocations(resources);
return bean;
}
}

View File

@ -0,0 +1,45 @@
package com.chinaweal.youfool.prj.config;
import cn.dev33.satoken.interceptor.SaInterceptor;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.stp.StpUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* spring mvc 配置
*
* @author lroyia
* @since 2022/2/8 18:04
**/
@Slf4j
@Configuration
public class SpringMvcConfig implements WebMvcConfigurer {
/**
* 拦截器注册
*
* @param registry 注册对象
* @author lroyia
* @since 2022年4月20日 16:41:54
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 注册 Sa-Token 拦截器,定义详细认证规则
registry.addInterceptor(new SaInterceptor(handler -> {
// // 根据路由划分模块,不同模块不同鉴权
// SaRouter.match("/user/**", r -> StpUtil.checkPermission("user"));
// SaRouter.match("/admin/**", r -> StpUtil.checkPermission("admin"));
// SaRouter.match("/goods/**", r -> StpUtil.checkPermission("goods"));
// SaRouter.match("/orders/**", r -> StpUtil.checkPermission("orders"));
// SaRouter.match("/notice/**", r -> StpUtil.checkPermission("notice"));
// SaRouter.match("/comment/**", r -> StpUtil.checkPermission("comment"));
// 指定一条 match 规则
SaRouter.notMatch("/user/auth/**", "/test/**", "/doc.html**", "/cross/**", "/swagger*",
"/cms/index.html", "/cms/static/**", "/cms/favicon.ico", "/cms/user/login", "/network/ping", "/error", "/static/data/**")
.match("/**", r -> StpUtil.checkLogin());
})).addPathPatterns("/**");
}
}

View File

@ -0,0 +1,101 @@
package com.chinaweal.youfool.prj.controller;
import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.StpUtil;
import com.chinaweal.youfool.framework.springboot.common.util.AssertUtils;
import com.chinaweal.youfool.framework.springboot.common.util.RSAUtil;
import com.chinaweal.youfool.framework.springboot.rest.RestResult;
import com.chinaweal.youfool.framework.springboot.rest.ResultCode;
import com.chinaweal.youfool.framework.springboot.user.entity.UserBase;
import com.chinaweal.youfool.prj.common.constants.SessionConstants;
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 java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* 登录相关接口
*
* @author lroyia
* @since 2022/4/20 15:02
**/
@Slf4j
@RestController
@RequestMapping("/user/auth")
public class LoginController {
/**
* 登录接口
*
* @param username 用户名
* @param password 密码
* @param encrypt 密码是否已经加密
* @return 登录结果
* @author lroyia
* @since 2022年4月20日 15:47:35
*/
@PostMapping("login")
public RestResult<?> doLogin(String username, String password, Boolean encrypt) {
AssertUtils.isNotBlank(username, password);
// TODO与数据库匹配校验具体按用户信息表
// 匹配成功的话,登记登录信息 TODO:这里的userId是用户唯一号应根据实际的数据库信息进行替换
StpUtil.login("userId");
SaSession session = StpUtil.getSession();
// 将用户信息存储至session TODO:登录信息存到这里
UserBase userBase = new UserBase();
Set<String> permissionSet = new HashSet<>();
permissionSet.add("admin");
userBase.setPermission(permissionSet);
session.set("user", userBase);
return RestResult.ok();
}
/**
* 登录信息
*
* @return 状态判断
* @author lroyia
* @since 2022年4月20日 15:58:26
*/
@GetMapping("login/info")
public RestResult<UserBase> loginInfo() {
boolean login = StpUtil.isLogin();
if (login) {
SaSession session = StpUtil.getSession();
return RestResult.ok((UserBase) session.get(SessionConstants.USER_KEY));
}
return RestResult.ok(null);
}
/**
* 登出
*
* @return 操作结果
* @author lroyia
* @since 2022年4月20日 15:59:55
*/
@GetMapping("logout")
public RestResult<?> logout() {
StpUtil.logout();
return RestResult.ok();
}
/**
* 列出用户权限信息
*
* @return 权限列表
* @author lroyia
* @since 2022年4月20日 16:12:09
*/
@GetMapping("perm/list")
public RestResult<List<String>> getPermList() {
return RestResult.ok(StpUtil.getPermissionList());
}
}

View File

@ -0,0 +1,17 @@
package com.chinaweal.youfool.prj.dev;
import com.chinaweal.youfool.framework.springboot.cms.dev.GenerateDictConstant;
/**
* 常量代码生成器
*/
public class ConstantCodeGen {
public static void main(String[] args) {
GenerateDictConstant generator = new GenerateDictConstant("properties/codeGenerator");
generator.generateConstant();
}
private ConstantCodeGen(){
}
}

View File

@ -0,0 +1,17 @@
package com.chinaweal.youfool.prj.dev;
import com.chinaweal.youfool.framework.springboot.cms.dev.GenerateDictEnums;
/**
* 常量代码生成器
*/
public class EnumsCodeGen {
public static void main(String[] args) {
GenerateDictEnums generator = new GenerateDictEnums("properties/codeGenerator");
generator.generateEnums();
}
private EnumsCodeGen(){
}
}

View File

@ -0,0 +1,19 @@
package com.chinaweal.youfool.prj.dev;
import com.chinaweal.youfool.framework.springboot.mybatis.plus.FastCodeGenerator;
/**
* 根据库表结构生成代码层
*/
public class TableCodeGen {
public static void main(String[] args) {
FastCodeGenerator fastCodeGenerator = new FastCodeGenerator("properties/codeGenerator");
fastCodeGenerator.generate();
}
private TableCodeGen() {
}
}

View File

@ -0,0 +1,31 @@
package com.chinaweal.youfool.prj.service.impl;
import cn.dev33.satoken.stp.StpInterface;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/**
* 授权服务
* @author lroyia
* @since 2022/4/20 15:42
**/
@Service
public class StpInterfaceImpl implements StpInterface {
@Override
public List<String> getPermissionList(Object loginId, String loginType) {
List<String> permList = new ArrayList<>();
// TODO:利用loginId去数据库查询权限并存到list中
// 如List<String> permList = userService.getPermList(loginId);
return permList;
}
@Override
public List<String> getRoleList(Object loginId, String loginType) {
List<String> roleList = new ArrayList<>();
// TODO:利用loginId去数据库查询用户角色并存到list中
// 如List<String> roleList = userService.getRoleList(loginId);
return roleList;
}
}

View File

@ -0,0 +1,40 @@
package com.chinaweal.youfool.prj.service.impl;
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.StpUtil;
import com.chinaweal.youfool.framework.springboot.rest.RestResult;
import com.chinaweal.youfool.framework.springboot.user.entity.UserBase;
import com.chinaweal.youfool.framework.springboot.user.service.UserBaseService;
import com.chinaweal.youfool.prj.common.constants.SessionConstants;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 用户
*/
@Service
public class UserBaseServiceImpl implements UserBaseService {
@Override
public RestResult<UserBase> login(String userName, String password, boolean frameworkLogin) {
return null;
}
@Override
public UserBase getCurrentUser() {
try {
SaSession session = StpUtil.getSession();
return session.get(SessionConstants.USER_KEY, null);
} catch (NotLoginException e) {
UserBase userBase = new UserBase();
userBase.setUsername("guest");
return userBase;
}
}
@Override
public List<UserBase> getUserInfoByLoginId(List<String> loginIdList) {
return null;
}
}

View File

@ -0,0 +1,21 @@
logging:
level:
dao: debug
youfool.dao: info
com.chinaweal.youfool.framework.springboot.log: debug
com.chinaweal.youfool.pms: debug
filePath: D:\project\pms\logs
spring:
datasource:
dynamic:
datasource:
master:
url: jdbc:mysql://172.22.80.35:3306/crgs?characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&serverTimezone=UTC
username: chinaweal
password: ChinaWeal2021
driver-class-name: com.mysql.cj.jdbc.Driver # 3.2.0开始支持SPI可省略此配置
youfool:
url: jdbc:mysql://172.22.80.35:3306/aiccs?characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&serverTimezone=UTC
username: chinaweal
password: ChinaWeal2021
driver-class-name: com.mysql.cj.jdbc.Driver

View File

@ -0,0 +1,21 @@
logging:
level:
dao: info
youfool.dao: info
com.chinaweal.youfool.framework.springboot.log: info
com.chinaweal.youfool.pms: info
filePath: D:\project\pms\logs
spring:
datasource:
dynamic:
datasource:
master:
url: jdbc:mysql://172.22.80.35:3306/crgs?characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&serverTimezone=UTC
username: chinaweal
password: ChinaWeal2021
driver-class-name: com.mysql.cj.jdbc.Driver # 3.2.0开始支持SPI可省略此配置
youfool:
url: jdbc:mysql://172.22.80.35:3306/aiccs?characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&serverTimezone=UTC
username: chinaweal
password: ChinaWeal2021
driver-class-name: com.mysql.cj.jdbc.Driver

View File

@ -0,0 +1,95 @@
logging:
level:
root: info
spring:
profiles:
active: ${PROFILES_ACTIVE:dev}
application:
name: youfool-prj-springboot-template
datasource:
dynamic:
primary: master #设置默认的数据源或者数据源组,默认值即为master
strict: false #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
datasource:
master:
druid:
filters: stat
initial-size: 2
min-idle: 1
max-active: 20
max-wait: 30000
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 300000
validation-query: select version()
youfool: # 基础框架必要数据源用于存储restLog
druid:
filters: stat
initial-size: 2
min-idle: 1
max-active: 20
max-wait: 30000
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 300000
validation-query: select version()
druid:
web-stat-filter:
enabled: true
stat-view-servlet:
enabled: true
url-pattern: /druid/*
login-username: admin
login-password: 123456
servlet:
multipart:
max-file-size: 100MB
max-request-size: 100MB
restLog:
ignoreServletPath: /druid,/swagger-resources,/v2/api-docs,/webjars
isSaveDb: false
# ignoreSuffix: .css,.jpg,.png,.icon,.html,.js
knife4j:
enable: true
# production: false
# basic:
# enable: true
# username: admin
# password: 123456
server:
port: ${PRJ_PORT:8080}
servlet:
context-path: ${PRJ_CONTEXT_PATH:}
# Sa-Token配置
sa-token:
# token名称 (同时也是cookie名称)
token-name: satoken
# token有效期单位s 默认30天, -1代表永不过期
timeout: 2592000
# token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒
active-timeout: -1
# 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
is-concurrent: true
# 在多人登录同一账号时是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
is-share: false
# token风格
token-style: uuid
# 是否输出操作日志
is-log: false
# swagger配置
springdoc:
swagger-ui:
path: /swagger-ui.html
tags-sorter: alpha
operations-sorter: alpha
api-docs:
path: /v3/api-docs
group-configs: # 新增直接按照下面的编写拷贝后改下group分组以及扫描的包路径即可path不用改
- group: '基础框架'
paths-to-match: '/**'
packages-to-scan: com.chinaweal.youfool.framework.springboot.cms
- group: '登录相关'
paths-to-match: '/**'
packages-to-scan: com.chinaweal.youfool.prj.controller

View File

@ -0,0 +1,113 @@
<!-- packagingData="true" : 输出异常栈时也打印出 jar 包的信息 -->
<configuration>
<springProperty scope="context" name="logFilePath" source="logging.filePath" defaultValue="../logs"/>
<springProperty scope="context" name="application" source="spring.application.name" defaultValue="application"/>
<!--设置自定义pattern属性-->
<property name="filePattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %X{traceRootId} %5level %F%L - %msg%n"/>
<property name="consolePattern" value="%d{HH:mm:ss.SSS} %X{traceRootId} %5level %F%L - %msg%n"/>
<property name="logFilePath" value="${logFilePath}/"/>
<property name="logFileName" value="${application}"/>
<!--控制台输出日志-->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<!--设置控制台输出日志的格式-->
<encoder>
<pattern>${consolePattern}</pattern>
<!-- <charset>GBK</charset>-->
</encoder>
</appender>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>${filePattern}</pattern>
</encoder>
<file>${logFilePath}/${logFileName}.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${logFilePath}/${logFileName}.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxFileSize>${LOG_FILE_MAX_SIZE:-5MB}</maxFileSize>
<maxHistory>${LOG_FILE_MAX_HISTORY:-0}</maxHistory>
</rollingPolicy>
</appender>
<appender name="FILE_DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>${filePattern}</pattern>
</encoder>
<file>${logFilePath}/${logFileName}-debug.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${logFilePath}/${logFileName}-debug.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxFileSize>${LOG_FILE_MAX_SIZE:-5MB}</maxFileSize>
<maxHistory>${LOG_FILE_MAX_HISTORY:-0}</maxHistory>
</rollingPolicy>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>DEBUG</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="FILE_INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>${filePattern}</pattern>
</encoder>
<file>${logFilePath}/${logFileName}-info.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${logFilePath}/${logFileName}-info.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxFileSize>${LOG_FILE_MAX_SIZE:-5MB}</maxFileSize>
<maxHistory>${LOG_FILE_MAX_HISTORY:-0}</maxHistory>
</rollingPolicy>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="FILE_WARN" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>${filePattern}</pattern>
</encoder>
<file>${logFilePath}/${logFileName}-warn.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${logFilePath}/${logFileName}-warn.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxFileSize>${LOG_FILE_MAX_SIZE:-5MB}</maxFileSize>
<maxHistory>${LOG_FILE_MAX_HISTORY:-0}</maxHistory>
</rollingPolicy>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>WARN</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="FILE_ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>${filePattern}</pattern>
</encoder>
<file>${logFilePath}/${logFileName}-error.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${logFilePath}/${logFileName}-error.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxFileSize>${LOG_FILE_MAX_SIZE:-5MB}</maxFileSize>
<maxHistory>${LOG_FILE_MAX_HISTORY:-0}</maxHistory>
</rollingPolicy>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<root>
<appender-ref ref="CONSOLE"/>
<springProfile name="prod">
<appender-ref ref="FILE"/>
<appender-ref ref="FILE_DEBUG"/>
<appender-ref ref="FILE_INFO"/>
<appender-ref ref="FILE_WARN"/>
<appender-ref ref="FILE_ERROR"/>
</springProfile>
</root>
<logger name="com.baomidou.mybatisplus.generator" level="debug"/>
</configuration>

View File

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD SQL Map Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--
| plugins在配置文件中的位置必须符合要求否则会报错顺序如下:
| properties?, settings?,
| typeAliases?, typeHandlers?,
| objectFactory?,objectWrapperFactory?,
| plugins?,
| environments?, databaseIdProvider?, mappers?
|-->
<configuration>
<!--
| 全局配置设置
|
| 可配置选项 默认值, 描述
|
| aggressiveLazyLoading true, 当设置为true的时候懒加载的对象可能被任何懒属性全部加载。否则每个属性都按需加载。
| multipleResultSetsEnabled true, 允许和不允许单条语句返回多个数据集(取决于驱动需求)
| useColumnLabel true, 使用列标签代替列名称。不同的驱动器有不同的作法。参考一下驱动器文档,或者用这两个不同的选项进行测试一下。
| useGeneratedKeys false, 允许JDBC 生成主键。需要驱动器支持。如果设为了true这个设置将强制使用被生成的主键有一些驱动器不兼容不过仍然可以执行。
| autoMappingBehavior PARTIAL, 指定MyBatis 是否并且如何来自动映射数据表字段与对象的属性。PARTIAL将只自动映射简单的没有嵌套的结果。FULL 将自动映射所有复杂的结果。
| mapUnderscoreToCamelCase false , 指定MyBatis 映射数据表字段与对象的属性,下划线转成驼峰。
| defaultExecutorType SIMPLE, 配置和设定执行器SIMPLE 执行器执行其它语句。REUSE 执行器可能重复使用prepared statements 语句BATCH执行器可以重复执行语句和批量更新。
| defaultStatementTimeout null, 设置一个时限,以决定让驱动器等待数据库回应的多长时间为超时
| jdbcTypeForNull Other oracle数据库需配置JdbcType.NULL
| -->
<settings>
<!-- 这个配置使全局的映射器启用或禁用缓存 -->
<setting name="cacheEnabled" value="true"/>
<!-- 全局启用或禁用延迟加载。当禁用时,所有关联对象都会即时加载 -->
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="multipleResultSetsEnabled" value="true"/>
<setting name="useColumnLabel" value="true"/>
<setting name="defaultExecutorType" value="REUSE"/>
<setting name="defaultStatementTimeout" value="25000"/>
<setting name="mapUnderscoreToCamelCase" value="true"/>
<setting name="jdbcTypeForNull" value="NULL"/>
<setting name="logPrefix" value="dao."/>
</settings>
<!-- mybatis-plus 分页插件-->
<plugins>
<plugin interceptor="com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor">
<property name="@page" value="com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor"/>
</plugin>
</plugins>
</configuration>

View File

@ -0,0 +1,24 @@
#mybatis-plus 代码生成器参数
url=jdbc:postgresql://172.22.80.157:5432/prj_template
driverName=org.postgresql.Driver
#PostgreSQL schemaName
schemaName=public
username=postgres
password=123456
#父包名
parentPackageName=com.chinaweal.youfool.prj
#mapper文件存放路径
mapperFilePath=/src/main/resources/mybatis/mapper/
author=chinaweal
#mybatis-plus 代码生成器参数-------配置文件模板
#module=rl-biz-med
#实体目录
#entityPackagePath=/rl-rpc-service/src/main/java/com/chinaweal/fsrl/med/entity
#servicePackagePath=/rl-rpc-service/src/main/java/com/chinaweal/fsrl/med/service
#mapperPackagePath=/module
#serviceImplPackagePath=/module
#controllerPackagePath=/module
#mapper文件存放路径
#字典常量生成路径
constantPackagePath=/src/main/java/com/chinaweal/common
enumsPackagePath=/src/main/java/com/chinaweal/common

View File

@ -0,0 +1,32 @@
package com.chinaweal.youfool.prj;
import org.junit.Test;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
//@RunWith(SpringRunner.class)
//@SpringBootTest(classes = {YoufoolPmsApplication.class})
public class AppTest {
@Test
public void test1() {
String no = String.format("%04d", 51);
System.out.println(no);
System.out.println("12345678");
}
@Test
public void test2() {
List<Map<String, String>> params = new ArrayList<>();
Map<String, String> map = new LinkedHashMap<>();
map.put("测试", "askdjf;kl ");
params.add(map);
String str = String.format("测试,%s", LocalDate.now());
System.out.println(str);
}
}