├── .github └── workflows │ └── release.yml ├── .gitignore ├── .idea ├── .gitignore ├── compiler.xml ├── dataSources.xml ├── encodings.xml ├── jarRepositories.xml ├── misc.xml ├── uiDesigner.xml └── vcs.xml ├── CHANGELOG.md ├── LICENSE ├── README.md ├── assistant-boot-start ├── pom.xml └── src │ ├── main │ ├── java │ │ └── io │ │ │ └── github │ │ │ └── config │ │ │ └── AppConfig.java │ └── resources │ │ ├── META-INF │ │ └── spring.factories │ │ └── application.yaml │ └── test │ └── java │ └── io │ └── github │ ├── AppTest.java │ └── util │ ├── RegexUtilsTest.java │ └── TokenUtilsTest.java ├── assistant-cache ├── pom.xml └── src │ └── main │ └── java │ └── io │ └── github │ └── common │ └── RedisKey.java ├── assistant-common ├── pom.xml └── src │ ├── main │ └── java │ │ └── io │ │ └── github │ │ ├── base │ │ └── MethodDecompose.java │ │ ├── common │ │ ├── Args.java │ │ ├── SafeBag.java │ │ ├── Status.java │ │ ├── logger │ │ │ ├── CommonLogger.java │ │ │ ├── LoggerHandler.java │ │ │ └── Sl4jLoggerHandler.java │ │ ├── msgbuilder │ │ │ ├── AbstractMsgBuilder.java │ │ │ └── MsgBuilder.java │ │ └── web │ │ │ ├── PageVO.java │ │ │ └── Result.java │ │ ├── constant │ │ └── TimeConstant.java │ │ └── pool │ │ └── StatusPool.java │ └── test │ └── java │ └── io │ └── github │ └── AppTest.java ├── assistant-mysql ├── pom.xml └── src │ └── main │ └── java │ └── io │ └── github │ ├── common │ ├── JoinSection.java │ └── PageVO.java │ ├── query │ └── QueryParamGroup.java │ ├── service │ ├── AssistantMJPService.java │ ├── AssistantMJPServiceImpl.java │ ├── AssistantService.java │ └── AssistantServiceImpl.java │ └── util │ └── PageUtil.java ├── assistant-plus-generator ├── pom.xml └── src │ ├── main │ ├── java │ │ └── io │ │ │ └── github │ │ │ ├── common │ │ │ ├── apiJs │ │ │ │ ├── ApiJs.java │ │ │ │ └── ApiMethod.java │ │ │ └── mysql │ │ │ │ ├── Column.java │ │ │ │ ├── DataBase.java │ │ │ │ └── Table.java │ │ │ ├── controller │ │ │ ├── HelloController.java │ │ │ └── TestController.java │ │ │ ├── generator │ │ │ ├── AutoApiJsGenerate.java │ │ │ ├── AutoGenerate.java │ │ │ ├── autotemplate │ │ │ │ ├── ApiJsTemplateFile.java │ │ │ │ └── TemplateFile.java │ │ │ ├── builder │ │ │ │ ├── ApiJsTemplateBuilder.java │ │ │ │ └── TemplateBuilder.java │ │ │ └── mysqlClassGenerate.java │ │ │ └── util │ │ │ └── VelocityUtils.java │ └── resources │ │ ├── js │ │ └── HelloController.js │ │ └── templates │ │ ├── apiJs.java.vm │ │ └── mysqlClass.java.vm │ └── test │ └── java │ └── io │ └── github │ └── generator │ └── AutoApiJsGenerateTest.java ├── assistant-service ├── pom.xml └── src │ ├── main │ └── java │ │ └── io │ │ └── github │ │ ├── exception │ │ └── handler │ │ │ ├── AbstractExceptionHandler.java │ │ │ ├── AssistantExceptionHandlerCondition.java │ │ │ ├── CommonExceptionHandler.java │ │ │ ├── SpringWebExceptionHandler.java │ │ │ ├── ValidateExceptionHandler.java │ │ │ └── annotation │ │ │ └── AssistantControllerAdvice.java │ │ ├── id │ │ ├── IdGenerator.java │ │ ├── IdGeneratorException.java │ │ ├── UUIDGenerator.java │ │ └── snowflake │ │ │ ├── DefaultSnowflakeRegister.java │ │ │ ├── RedisSnowflakeRegister.java │ │ │ ├── SnowflakeGenerator.java │ │ │ ├── SnowflakeRegister.java │ │ │ └── SnowflakeRegisterException.java │ │ └── servicechain │ │ ├── ServiceChainContext.java │ │ ├── ServiceChainFactory.java │ │ ├── annotation │ │ ├── Chain.java │ │ └── MultiFilterFunc.java │ │ ├── bootstrap │ │ ├── ChainHandler.java │ │ ├── FailCallback.java │ │ ├── ReturnType.java │ │ ├── ServiceChainBootstrap.java │ │ ├── ServiceChainCallback.java │ │ ├── ServiceChainHandler.java │ │ └── SuccessCallback.java │ │ ├── chain │ │ ├── AbstractFilterChain.java │ │ ├── ChainBluePrint.java │ │ ├── FilterChain.java │ │ ├── MultiArgsFilterChain.java │ │ ├── ServiceChain.java │ │ ├── ServiceChainProvider.java │ │ ├── ServicePointServiceChainProvider.java │ │ └── YamlServiceChainProvider.java │ │ └── common │ │ └── ServiceHelper.java │ └── test │ └── java │ └── io │ └── github │ └── serviceHelper │ └── login │ └── FormLoginServiceTest.java ├── assistant-test ├── pom.xml └── src │ ├── main │ ├── java │ │ └── io │ │ │ └── github │ │ │ ├── TestApplication.java │ │ │ ├── chain │ │ │ ├── ExceptionFilterChain.java │ │ │ ├── ObjectNotEmptyFilterChain.java │ │ │ ├── ReturnMapFilterChain.java │ │ │ ├── StringNotEmptyFilterChain.java │ │ │ └── TaskCheckFilterChain.java │ │ │ ├── config │ │ │ └── MybatisConfiguration.java │ │ │ ├── controller │ │ │ └── TestController.java │ │ │ ├── mapper │ │ │ ├── FeedbackMapper.java │ │ │ ├── FeedbackTypeMapper.java │ │ │ └── NoticeMapper.java │ │ │ ├── pojo │ │ │ ├── FeedbackDO.java │ │ │ ├── FeedbackTypeDO.java │ │ │ ├── NoticeDO.java │ │ │ ├── TaskDO.java │ │ │ └── vo │ │ │ │ ├── FeedbackVO.java │ │ │ │ └── NoticeVO.java │ │ │ └── service │ │ │ ├── FeedbackDaoServiceImpl.java │ │ │ ├── FeedbackTypeServiceImpl.java │ │ │ └── NoticeDaoServiceImpl.java │ └── resources │ │ └── application.yml │ └── test │ └── java │ └── io │ └── github │ └── geniusay │ ├── common │ └── LoggerTest.java │ ├── mysql │ ├── AssistantServiceTest.java │ └── QueryParamGroupTest.java │ └── service │ ├── exception │ └── ExceptionHandlerTest.java │ ├── id │ └── IdGeneratorTest.java │ └── servicechain │ └── ServiceChainTest.java ├── assistant-util ├── pom.xml └── src │ ├── main │ └── java │ │ └── io │ │ └── github │ │ └── util │ │ ├── ClassUtil.java │ │ ├── GenericityUtils.java │ │ ├── StringUtils.java │ │ ├── autochecker │ │ ├── AutoChecker.java │ │ └── Checker.java │ │ ├── collection │ │ ├── list │ │ │ └── SharedList.java │ │ └── map │ │ │ ├── MapNode.java │ │ │ ├── WeightMapNode.java │ │ │ └── dag │ │ │ └── WorkWeightMapNode.java │ │ ├── convert │ │ └── ZhConvertUtil.java │ │ ├── encryption │ │ ├── AESEncryptionUtils.java │ │ ├── Base64EncryptionUtils.java │ │ ├── DESEncryptionUtils.java │ │ ├── EncryptionFactory.java │ │ ├── EncryptionType.java │ │ ├── EncryptionUtil.java │ │ ├── MD5EncryptionUtils.java │ │ └── RSAEncryptionUtils.java │ │ ├── file │ │ ├── CommonFileUtils.java │ │ ├── FileCondition.java │ │ └── JsonFileUtil.java │ │ ├── path │ │ └── PathUtils.java │ │ ├── random │ │ ├── SnowflakeUtils.java │ │ └── UUIDGeneratorUtils.java │ │ ├── regex │ │ ├── RegexPattern.java │ │ ├── RegexPool.java │ │ └── RegexUtils.java │ │ ├── time │ │ └── TimeUtil.java │ │ └── token │ │ ├── JWTTokenProperties.java │ │ ├── Token.java │ │ └── TokenUtil.java │ └── test │ └── java │ └── io │ └── github │ └── util │ ├── AutoCheckerTest.java │ ├── EncryptionUtilsTest.java │ ├── PathUtilsTest.java │ ├── RegexUtilsTest.java │ ├── TokenUtilsTest.java │ └── list │ ├── SharedListJMHTest.java │ └── SharedListTest.java ├── assistant-websocket ├── pom.xml └── src │ └── main │ └── java │ └── io │ └── github │ └── webscoket │ └── core │ ├── MessageHandlerFactory.java │ ├── WebSocketHandler.java │ └── handler │ ├── AbstractMessageHandler.java │ ├── MessageHandler.java │ └── MessageProtocol.java └── pom.xml /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Publish package to the Maven Central Repository 2 | on: 3 | workflow_dispatch: 4 | release: 5 | types: [ published ] 6 | push: 7 | tags: [ "*" ] 8 | jobs: 9 | publish: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v2 13 | - name: Set up Maven Central Repository 14 | uses: actions/setup-java@v2 15 | with: 16 | java-version: '11' 17 | distribution: 'adopt' 18 | server-id: ossrh 19 | server-username: MAVEN_USERNAME 20 | server-password: MAVEN_PASSWORD 21 | - id: install-secret-key 22 | name: Install gpg secret key 23 | run: | 24 | cat <(echo -e "${{ secrets.OSSRH_GPG_SECRET_KEY }}") | gpg --batch --import 25 | gpg --list-secret-keys --keyid-format LONG 26 | - name: Publish package 27 | env: 28 | MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }} 29 | MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }} 30 | run: mvn --batch-mode -Dgpg.passphrase=${{ secrets.OSSRH_GPG_SECRET_KEY_PASSWORD }} clean deploy -DskipTests 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Project exclude paths 2 | /target/ 3 | 4 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 40 | 41 | -------------------------------------------------------------------------------- /.idea/dataSources.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | mysql 6 | true 7 | com.mysql.jdbc.Driver 8 | jdbc:mysql://localhost:3306/deepVideo 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | mysql 20 | true 21 | com.mysql.jdbc.Driver 22 | jdbc:mysql://wumulong.space:3306/deepVideo 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /.idea/jarRepositories.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 14 | 15 | 19 | 20 | 24 | 25 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # CHANGELOG 2 | ```markdown 3 | 格式: 4 | ## [版本号] - 日期 5 | ### 模板名称 (可选 console-ui, console, FileModule, common, ...) 6 | - 🎈新增: {模块名称} {功能介绍} 7 | - 🐞Bug: #{issue号} {bug描述} 8 | - ⛏修复: #{issue号} {修复描述} 9 | - 📝文档: {文件名} 添加注释 10 | - 🚀性能: {类} {方法} {描述} 11 | - 🎨样式: 12 | - 🧹重构: 13 | - 🧪测试: {类|方法} {测试结果} 14 | - 🛑更名: {旧名} ➡ {新名} 15 | - ❌移除: {模块|方法} 16 | 17 | ------ 18 | 19 | ``` 20 | ------ 21 | ## [v1.1.1] - 2023.4.28 22 | - 🧹重构:重构整个框架,目前分为了util模块,service模块,generator模块,common模块 23 | - 🎈新增:`JsonFileUtil,FileUtil`,用于进行文件操作和Json文件读取与写入 24 | ------ 25 | ## [v1.0.7] - 2023.4.4 26 | - 🎈新增`AutoChecker`自动检查器,用于检查参数是否符合要求 27 | - 定义了`BaseServiceChain` 与 `ServiceNode`,为之后的业务流以及业务链提供基础 28 | ------ 29 | ## [v1.0.6] - 2023.4.4 30 | - ⛏bug:修复`TokenUtils`某些函数未进行空值处理判断 31 | - 完善`TokenUtils`工具类,`Token`类现在包含`Header`了 32 | - 加密工厂类`EncryptFactory`新增`add`方法,可以添加用户自定义的加密解密工具类 33 | ------ 34 | ## [v1.0.5] - 2023.4.1 35 | - 📌bug:修复`AutoApiJsGenerate`在SpringBoot2.6.4版本下路径映射改变问题,添加了自适应版本路径获取方法 36 | ------ 37 | ## [v1.0.4] - 2023.3.31 38 | - 🎈新增`RegexUtils`工具类,用于进行正则表达式匹配功能 39 | - 🎈新增`RegexPattern`正则表达式常量类 40 | ------ 41 | ## [v1.0.3] - 2023.3.24 42 | - 🎈新增`PathUtils`工具类,用于进行路径解析功能 43 | - 🎈新增`FileUtils`工具类,用于进行文件操作功能 44 | - 🎈新增`EncryptUtils`工具类,用于进行加密解密功能,目前具有AES,RSA,BASE64,MD5等加密方法 45 | - 🎈新增加密工厂类`EncryptFactory`,用于获取加密解密工具类 46 | ------ 47 | ## [v1.0.2] - 2023.3.23 48 | - 热身模块ApiJs生成工具大更新,支持多种模板生成方式,更名为 `AutoApiJsGenerate` 49 | - 🎈新增文件信息类 50 | - 🎈新增 `AutoGenerate` 接口 51 | - 🎈新增 `AutoApiJsGenerate` 自定义模板生成,异步生成,过滤器 52 | ------ 53 | ## [v1.0.1] - 2023.3.22 54 | - 📌bug:修复 `AutoApiJsGenerateHelper` 模块的对于RestMapping多个请求方式会出现解析出错的问题 55 | - 🎈新增 `TokenUtil工具类`,用于生成token和解析token 56 | ------ 57 | ## [v1.0.0] - 2023.3.20 58 | - 项目发布到Maven仓库 59 | - 热身模块新增 `AutoApiJsGenerateHelper` 模块 60 | ------ 61 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | Mybatis-Plus-Logo 4 | 5 |

6 | 7 |

8 | Low code,high efficiency 9 |

10 |

11 | 12 | maven 13 | 14 |

15 | 16 | ## 什么是Assistant? 17 | 18 | Assistant (opens new window)是一个后端开发的小助手,提供多种工具,自动生成器,以及多种高性能高自由度业务方法,让你在开发道路上更加简便。 19 | 20 | ## 相关链接 21 | 22 | - [Documentation](https://tmlgenius.github.io/assistant-docs/) 23 | - [Gitee](https://gitee.com/sbg-genius/Assistant) 24 | 25 | ## 特点 26 | 27 | - **赛前热身**:提供多个开发前的“热身”工具,所谓热身工具指的是快速完成api文件的创建,controller文件,mapper文件等重复度高的编码工作,可以直接开始项目开发 28 | - **百宝箱**:蕴含多种工具类,在打造项目的无需再东翻西找打造工具 29 | - **业务大师**:包含多种多样的业务,高性能,低代码,根据你的需要自行DIY,几行代码轻松搞定 30 | - **内置代码生成器**:内置多种文件生成器,apiJs,controller,VO,DTO等等 31 | #代码托管 32 | 33 | ## 快速开始 34 | 35 | - Add Assistant dependency 36 | - Latest Version: [![Maven Central](https://img.shields.io/maven-metadata/v.svg?label=maven-central&metadataUrl=https%3A%2F%2Frepo1.maven.org%2Fmaven2%2Fio%2Fgithub%2Fgeniusay%2Fassistant%2Fmaven-metadata.xml)](https://central.sonatype.com/artifact/io.github.geniusay/assistant-boot-start/1.0.3) 37 | - Maven: 38 | ```xml 39 | 40 | io.github.Geniusay 41 | assistant-boot-start 42 | 1.1.2 43 | 44 | ``` 45 | 46 | > 更多详情请前往 [documentation](https://tmlgenius.github.io/assistant-docs/). 47 | -------------------------------------------------------------------------------- /assistant-boot-start/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | assistant 5 | io.github.geniusay 6 | 1.1.2 7 | 8 | 4.0.0 9 | 10 | ${assistant-boot-start.version} 11 | assistant-boot-start 12 | jar 13 | 14 | assistant-boot-start 15 | http://maven.apache.org 16 | 17 | 18 | UTF-8 19 | 20 | 21 | 22 | 23 | io.github.geniusay 24 | assistant-common 25 | 26 | 27 | 28 | io.github.geniusay 29 | assistant-util 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /assistant-boot-start/src/main/java/io/github/config/AppConfig.java: -------------------------------------------------------------------------------- 1 | package io.github.config; 2 | 3 | import org.springframework.context.annotation.ComponentScan; 4 | import org.springframework.context.annotation.Configuration; 5 | 6 | 7 | @Configuration 8 | @ComponentScan("io.github.*") 9 | public class AppConfig { 10 | 11 | public AppConfig() { 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /assistant-boot-start/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ 2 | io.github.config.AppConfig 3 | -------------------------------------------------------------------------------- /assistant-boot-start/src/main/resources/application.yaml: -------------------------------------------------------------------------------- 1 | assistant: 2 | token: 3 | access-token-expire-time: 3600 4 | access-token-time-unit: SECONDS 5 | enable-refresh: true 6 | regex: 7 | pool: 8 | phone: ^1[3|4|5|7|8][0-9]{9}$#$ 9 | -------------------------------------------------------------------------------- /assistant-boot-start/src/test/java/io/github/AppTest.java: -------------------------------------------------------------------------------- 1 | package io.github; 2 | 3 | import junit.framework.Test; 4 | import junit.framework.TestCase; 5 | import junit.framework.TestSuite; 6 | import org.springframework.boot.test.context.SpringBootTest; 7 | 8 | /** 9 | * Unit test for simple App. 10 | */ 11 | @SpringBootTest 12 | public class AppTest 13 | extends TestCase 14 | { 15 | /** 16 | * Create the test case 17 | * 18 | * @param testName name of the test case 19 | */ 20 | public AppTest( String testName ) 21 | { 22 | super( testName ); 23 | } 24 | 25 | /** 26 | * @return the suite of tests being tested 27 | */ 28 | public static Test suite() 29 | { 30 | return new TestSuite( AppTest.class ); 31 | } 32 | 33 | /** 34 | * Rigourous Test :-) 35 | */ 36 | public void testApp() 37 | { 38 | assertTrue( true ); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /assistant-boot-start/src/test/java/io/github/util/RegexUtilsTest.java: -------------------------------------------------------------------------------- 1 | package io.github.util; 2 | 3 | 4 | import io.github.util.regex.RegexUtils; 5 | import org.junit.jupiter.api.Test; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.boot.test.context.SpringBootTest; 8 | 9 | /** 10 | * Genius 11 | 12 | **/ 13 | 14 | @SpringBootTest 15 | public class RegexUtilsTest { 16 | @Autowired 17 | RegexUtils regexUtils; 18 | @Test 19 | public void testRegexPool(){ 20 | System.out.println(regexUtils.getRegexPool().getPhone()); 21 | } 22 | 23 | @Test 24 | public void testRegexUtils(){ 25 | System.out.println("邮箱是否正确:"+regexUtils.isEmail("123456789@qq.com")); 26 | System.out.println("邮箱是否正确:"+regexUtils.isEmail("123456789@qqcom")); 27 | System.out.println("电话是否正确:"+regexUtils.isPhone("13601607121")); 28 | System.out.println("电话是否正确:"+regexUtils.isPhone("1234567890")); 29 | System.out.println("电话(严格)是否正确:"+regexUtils.isPhone("123456789012",true)); 30 | System.out.println("电话(严格)是否正确:"+regexUtils.isPhone("13601607121",true)); 31 | System.out.println("QQ是否正确:"+regexUtils.VerifyRegex("123456789", regexUtils.getRegexPool().getQq())); 32 | System.out.println("QQ是否正确:"+regexUtils.VerifyRegex("1142880114", regexUtils.getRegexPool().getQq())); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /assistant-boot-start/src/test/java/io/github/util/TokenUtilsTest.java: -------------------------------------------------------------------------------- 1 | package io.github.util; 2 | 3 | 4 | import io.github.util.token.Token; 5 | import io.github.util.token.TokenUtil; 6 | import io.jsonwebtoken.Claims; 7 | import io.jsonwebtoken.Jwts; 8 | import org.junit.jupiter.api.Test; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.boot.test.context.SpringBootTest; 11 | 12 | import java.util.Date; 13 | import java.util.Map; 14 | 15 | /** 16 | * Genius 17 | 18 | **/ 19 | @SpringBootTest 20 | public class TokenUtilsTest { 21 | @Autowired 22 | TokenUtil tokenUtils; 23 | class User{ 24 | private String name; 25 | private int age; 26 | public User(String name, int age) { 27 | this.name = name; 28 | this.age = age; 29 | } 30 | 31 | } 32 | @Test 33 | public void testCreateToken(){ 34 | User user = new User("Genius",18); 35 | Claims claims = Jwts.claims(); 36 | claims.put("user",user); 37 | 38 | String token = tokenUtils.createToken("user",user,"123456").getAccessToken(); 39 | String token2 = tokenUtils.createToken(Map.of("user",user),"123456").getAccessToken(); 40 | String token3 = tokenUtils.createToken( 41 | Map.of("type","jwt","alg","HS256"), //token头信息 42 | claims, //token payload 43 | new Date(), //token签发时间 44 | new Date(new Date().getTime() + 60*1000), //token过期时间 45 | new Date(new Date().getTime() + 120*1000), //token刷新时间,如果未启用则无效 46 | new Date(new Date().getTime()), //Token生效时间 47 | "Genius", //token签名者 48 | "public Path", //公共区域 49 | tokenUtils.getJwtTokenProperties().getJit(), //token唯一身份标识 50 | "Genius", //发布人 51 | true //是否需要进行刷新操作 52 | ).getAccessToken(); 53 | System.out.println(tokenUtils.parseTokenToToken(token, "user", User.class)); 54 | System.out.println(tokenUtils.parseTokenToToken(token2, "user", User.class)); 55 | System.out.println(tokenUtils.parseTokenToToken(token3, "user", User.class)); 56 | System.out.println(tokenUtils.parseTokenToObj(token3, "user", User.class)); 57 | } 58 | 59 | @Test 60 | public void tesReFreshToken(){ 61 | User user = new User("Genius",18); 62 | Claims claims = Jwts.claims(); 63 | claims.put("user",user); 64 | Token token = tokenUtils.createToken( 65 | Map.of("type","jwt","alg","HS256"), //token头信息 66 | claims, //token payload 67 | new Date(), //token签发时间 68 | new Date(new Date().getTime() + 10), //token过期时间 69 | new Date(new Date().getTime() + 120*1000), //token刷新时间,如果未启用则无效 70 | new Date(new Date().getTime()), //Token生效时间 71 | "Genius", //token签名者 72 | "public Path", //公共区域 73 | tokenUtils.getJwtTokenProperties().getJit(), //token唯一身份标识 74 | "Genius", //发布人 75 | true //是否需要进行刷新操作 76 | ); 77 | System.out.println(token.getAccessToken()); 78 | System.out.println(tokenUtils.refreshToken(token).getAccessToken()); 79 | 80 | } 81 | 82 | @Test 83 | public void testCreateTokenByMap(){ 84 | String accessToken = tokenUtils.createToken(Map.of( 85 | "username", "Genius", 86 | "uid", "123456" 87 | ), "123456").getAccessToken(); 88 | System.out.println(tokenUtils.parseTokenToObj(accessToken, "username", String.class)); 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /assistant-cache/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | assistant 7 | io.github.geniusay 8 | 1.1.2 9 | 10 | 4.0.0 11 | ${assistant-cache.version} 12 | assistant-cache 13 | 14 | 15 | 11 16 | 11 17 | UTF-8 18 | 19 | 20 | 21 | 22 | org.springframework.data 23 | spring-data-redis 24 | 25 | 26 | 27 | org.springframework.boot 28 | spring-boot-starter-data-redis 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /assistant-cache/src/main/java/io/github/common/RedisKey.java: -------------------------------------------------------------------------------- 1 | package io.github.common; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | 6 | import java.util.concurrent.TimeUnit; 7 | 8 | /** 9 | * @author Genius 10 | * 2023/08/15 23:11 11 | **/ 12 | @Data 13 | public class RedisKey { 14 | private String key; 15 | private long time; 16 | private TimeUnit timeUnit; 17 | 18 | public RedisKey(String key, long time, TimeUnit timeUnit) { 19 | this.key = key; 20 | this.time = time; 21 | this.timeUnit = timeUnit; 22 | } 23 | 24 | public RedisKey(String key) { 25 | this.key = key; 26 | this.time = -1; 27 | this.timeUnit = TimeUnit.SECONDS; 28 | } 29 | 30 | public String getKey(Object value){ 31 | return String.format(key,value); 32 | } 33 | 34 | public String getKey(Object...values){ 35 | return String.format(key,values); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /assistant-common/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | assistant 5 | io.github.geniusay 6 | 1.1.2 7 | 8 | 4.0.0 9 | 10 | assistant-common 11 | jar 12 | ${assistant-common.version} 13 | assistant-common 14 | http://maven.apache.org 15 | 16 | 17 | UTF-8 18 | 19 | 20 | 21 | 22 | org.springframework.boot 23 | spring-boot-starter-web 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /assistant-common/src/main/java/io/github/base/MethodDecompose.java: -------------------------------------------------------------------------------- 1 | package io.github.base; 2 | 3 | import javassist.ClassPool; 4 | import javassist.CtClass; 5 | import javassist.CtMethod; 6 | import javassist.NotFoundException; 7 | import javassist.bytecode.CodeAttribute; 8 | import javassist.bytecode.LocalVariableAttribute; 9 | import javassist.bytecode.MethodInfo; 10 | import org.springframework.core.DefaultParameterNameDiscoverer; 11 | import org.springframework.stereotype.Component; 12 | 13 | import java.lang.reflect.Method; 14 | import java.util.ArrayList; 15 | import java.util.List; 16 | import java.util.Objects; 17 | 18 | /** 19 | * Genius 20 | * 21 | **/ 22 | @Component 23 | public class MethodDecompose { 24 | 25 | 26 | private static final DefaultParameterNameDiscoverer discoverer = new DefaultParameterNameDiscoverer(); 27 | /* 28 | * 利用asm对字节码进行分析,获取方法的参数名 29 | * @param ClassPath 类的全路径 30 | * @param methodName 方法名 31 | */ 32 | public List getMethodParamName(String ClassPath,String methodName){ 33 | try { 34 | ClassPool classPool = ClassPool.getDefault(); 35 | CtClass ctClass = classPool.getOrNull(ClassPath); 36 | CtMethod ctMethod = ctClass.getDeclaredMethod(methodName); 37 | MethodInfo methodInfo = ctMethod.getMethodInfo(); 38 | CodeAttribute attribute = methodInfo.getCodeAttribute(); 39 | LocalVariableAttribute attr = (LocalVariableAttribute) attribute.getAttribute(LocalVariableAttribute.tag); 40 | List paramNames = new ArrayList<>(); 41 | for (int i = 0; i < ctMethod.getParameterTypes().length; i++) { 42 | paramNames.add(attr.variableName(i)); 43 | } 44 | return paramNames; 45 | }catch (NotFoundException e) { 46 | throw new RuntimeException("不存在的类"); 47 | } 48 | } 49 | 50 | public List getMethodParamNameByDiscover(Method method){ 51 | if(method != null){ 52 | return List.of(Objects.requireNonNull(discoverer.getParameterNames(method))); 53 | }else{ 54 | throw new RuntimeException("不存在的方法"); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /assistant-common/src/main/java/io/github/common/Args.java: -------------------------------------------------------------------------------- 1 | package io.github.common; 2 | 3 | import java.util.List; 4 | 5 | public class Args { 6 | 7 | private final List args; 8 | 9 | private Args(List args) { 10 | this.args = args; 11 | } 12 | 13 | private Args(Object... args){ 14 | this.args = List.of(args); 15 | } 16 | 17 | public static Args of(Object... args){ 18 | return new Args(args); 19 | } 20 | 21 | public static Object[] args(Object... args){ 22 | return args; 23 | } 24 | 25 | public List argList() { 26 | return args; 27 | } 28 | 29 | public Object[] args(){ 30 | return args.toArray(); 31 | } 32 | 33 | public Object get(int index){ 34 | return args.get(index); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /assistant-common/src/main/java/io/github/common/SafeBag.java: -------------------------------------------------------------------------------- 1 | package io.github.common; 2 | 3 | /** 4 | * Genius 5 | * 2023/10/17 01:30 6 | **/ 7 | 8 | /** 9 | * 安全Bag类,安全存放某个类 10 | * @param 11 | */ 12 | public class SafeBag { 13 | T data; 14 | 15 | public SafeBag(T data) { 16 | this.data = data; 17 | } 18 | 19 | public SafeBag() { 20 | } 21 | 22 | public T getData() { 23 | return data; 24 | } 25 | 26 | public void setData(T data){ 27 | this.data = data; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /assistant-common/src/main/java/io/github/common/Status.java: -------------------------------------------------------------------------------- 1 | package io.github.common; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | import org.springframework.http.HttpStatus; 7 | 8 | /** 9 | * Genius 10 | 11 | **/ 12 | 13 | /** 14 | * 状态码 15 | */ 16 | @Data 17 | @AllArgsConstructor 18 | @NoArgsConstructor 19 | public class Status { 20 | 21 | private String code; //状态码 22 | 23 | private String msg; //状态信息 24 | 25 | private Exception exception;//异常 26 | 27 | //将HttpStatus转换为Status 28 | public static Status HttpStatusToStatus(HttpStatus httpStatus){ 29 | return new Status(String.valueOf(httpStatus.value()),httpStatus.getReasonPhrase(),null); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /assistant-common/src/main/java/io/github/common/logger/CommonLogger.java: -------------------------------------------------------------------------------- 1 | package io.github.common.logger; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | import javax.annotation.Resource; 6 | 7 | /** 8 | * Genius 9 | * 2023/10/26 21:59 10 | **/ 11 | @Component 12 | public class CommonLogger { 13 | 14 | @Resource(name="${assistant.logger.handler:sl4j}") 15 | private LoggerHandler loggerHandler; 16 | 17 | public void info(String msg,Object... args){ 18 | loggerHandler.info(msg,args); 19 | } 20 | 21 | public void error(String msg,Object... args){ 22 | loggerHandler.error(msg,args); 23 | } 24 | 25 | public void warn(String msg,Object... args){ 26 | loggerHandler.warn(msg,args); 27 | } 28 | 29 | public void debug(String msg,Object... args){ 30 | loggerHandler.debug(msg,args); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /assistant-common/src/main/java/io/github/common/logger/LoggerHandler.java: -------------------------------------------------------------------------------- 1 | package io.github.common.logger; 2 | 3 | public interface LoggerHandler { 4 | 5 | void info(String msg, Object... args); 6 | 7 | void error(String msg, Object... args); 8 | 9 | void warn(String msg, Object... args); 10 | 11 | void debug(String msg, Object... args); 12 | } 13 | -------------------------------------------------------------------------------- /assistant-common/src/main/java/io/github/common/logger/Sl4jLoggerHandler.java: -------------------------------------------------------------------------------- 1 | package io.github.common.logger; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.stereotype.Component; 6 | 7 | /** 8 | * Genius 9 | * 2023/10/26 22:00 10 | **/ 11 | @Component("sl4j") 12 | public class Sl4jLoggerHandler implements LoggerHandler{ 13 | private static final String LOGGER_NAME = "review_service"; 14 | 15 | private final static Logger REVIEW_LOGGER = LoggerFactory.getLogger(LOGGER_NAME); 16 | 17 | @Override 18 | public void info(String msg, Object... args) { 19 | REVIEW_LOGGER.info(String.format(msg, args)); 20 | } 21 | 22 | @Override 23 | public void error(String msg, Object... args) { 24 | REVIEW_LOGGER.error(String.format(msg, args)); 25 | } 26 | 27 | @Override 28 | public void warn(String msg, Object... args) { 29 | REVIEW_LOGGER.warn(String.format(msg, args)); 30 | } 31 | 32 | @Override 33 | public void debug(String msg, Object... args) { 34 | REVIEW_LOGGER.debug(String.format(msg, args)); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /assistant-common/src/main/java/io/github/common/msgbuilder/AbstractMsgBuilder.java: -------------------------------------------------------------------------------- 1 | package io.github.common.msgbuilder; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | /** 9 | * 2023/10/13 10 | * xiaochun 11 | */ 12 | public abstract class AbstractMsgBuilder implements MsgBuilder{ 13 | protected Map map; 14 | 15 | public AbstractMsgBuilder() { 16 | this.map = new HashMap<>(); 17 | } 18 | 19 | @Override 20 | public AbstractMsgBuilder build(String key, Object data){ 21 | if(data==null){ 22 | return this; 23 | } 24 | map.put(key,data); 25 | return this; 26 | } 27 | 28 | @Override 29 | public String done(){ 30 | return JSONObject.toJSONString(map); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /assistant-common/src/main/java/io/github/common/msgbuilder/MsgBuilder.java: -------------------------------------------------------------------------------- 1 | package io.github.common.msgbuilder; 2 | 3 | /** 4 | * 2023/10/13 5 | * xiaochun 6 | */ 7 | public interface MsgBuilder { 8 | MsgBuilder build(String key,Object data); 9 | 10 | String done(); 11 | } 12 | -------------------------------------------------------------------------------- /assistant-common/src/main/java/io/github/common/web/PageVO.java: -------------------------------------------------------------------------------- 1 | package io.github.common.web; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * 数据库分页展示类 11 | * @param 12 | */ 13 | @Data 14 | @NoArgsConstructor 15 | @AllArgsConstructor 16 | public class PageVO { 17 | private List pageList; 18 | 19 | private long page; 20 | 21 | private long limit; 22 | 23 | private long total; 24 | } 25 | -------------------------------------------------------------------------------- /assistant-common/src/main/java/io/github/common/web/Result.java: -------------------------------------------------------------------------------- 1 | package io.github.common.web; 2 | 3 | import io.github.common.Status; 4 | import io.github.pool.StatusPool; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | 9 | import java.time.LocalDateTime; 10 | 11 | /** 12 | * Genius 13 | 14 | **/ 15 | 16 | @Data 17 | @AllArgsConstructor 18 | public class Result { 19 | 20 | private String code; //状态码 21 | 22 | private String msg; //状态信息 23 | 24 | private T data; //返回数据 25 | 26 | private String timestamp;//时间戳 27 | 28 | public Result() { 29 | this.timestamp = String.valueOf(LocalDateTime.now()); 30 | } 31 | 32 | public Result(T data) { 33 | this.data = data; 34 | } 35 | 36 | private static void success(Status status, Result result){ 37 | 38 | result.setCode(status.getCode()); 39 | result.setMsg(status.getMsg()); 40 | } 41 | 42 | public static Result success(){ 43 | Result result = new Result(); 44 | success(StatusPool.Success,result); 45 | return result; 46 | } 47 | 48 | public static Result success(T data){ 49 | Result result = new Result<>(data); 50 | success(StatusPool.Success,result); 51 | return result; 52 | } 53 | 54 | public static Result success(T data,Status status){ 55 | Result result = new Result<>(data); 56 | success(status,result); 57 | return result; 58 | } 59 | 60 | public static Result error(String code,String msg){ 61 | Result result = new Result(); 62 | result.setCode(code); 63 | result.setMsg(msg); 64 | return result; 65 | } 66 | 67 | 68 | public static Result error(Status error){ 69 | Result result = new Result(); 70 | result.setCode(error.getCode()); 71 | result.setMsg(error.getMsg()); 72 | return result; 73 | } 74 | 75 | //抛出Status异常 76 | public static Result throwError(Boolean Condition, Status error) throws Exception { 77 | if(error!=null&&error.getException()!=null){ 78 | throw new RuntimeException("Status异常为Null"); 79 | } 80 | if (Condition) { 81 | throw error.getException(); 82 | } 83 | return Result.success(); 84 | } 85 | 86 | public static Result throwError(Status error) throws Exception { 87 | return throwError(true,error); 88 | } 89 | 90 | 91 | } 92 | -------------------------------------------------------------------------------- /assistant-common/src/main/java/io/github/constant/TimeConstant.java: -------------------------------------------------------------------------------- 1 | package io.github.constant; 2 | 3 | public class TimeConstant { 4 | 5 | public static final String YMD_HMS = "yyyy-MM-dd HH:mm:ss"; 6 | 7 | public static final String YMD_HM = "yyyy-MM-dd HH:mm"; 8 | 9 | public static final String YMD_HMSS = "yyyy-MM-dd HH:mm:ss.SSS"; 10 | 11 | public static final String YMD = "yyyy-MM-dd"; 12 | 13 | public static final String HMS = "HH:mm:ss"; 14 | 15 | } 16 | -------------------------------------------------------------------------------- /assistant-common/src/main/java/io/github/pool/StatusPool.java: -------------------------------------------------------------------------------- 1 | package io.github.pool; 2 | 3 | 4 | import io.github.common.Status; 5 | 6 | /** 7 | * Genius 8 | 9 | **/ 10 | public class StatusPool { 11 | public static final Status Success = new Status("200", "Success", null); 12 | 13 | 14 | } 15 | -------------------------------------------------------------------------------- /assistant-common/src/test/java/io/github/AppTest.java: -------------------------------------------------------------------------------- 1 | package io.github; 2 | 3 | import io.github.common.logger.CommonLogger; 4 | import junit.framework.TestCase; 5 | import junit.framework.TestSuite; 6 | import org.junit.jupiter.api.Test; 7 | import org.springframework.boot.test.context.SpringBootTest; 8 | 9 | import javax.annotation.Resource; 10 | 11 | /** 12 | * Unit test for simple App. 13 | */ 14 | @SpringBootTest 15 | public class AppTest 16 | { 17 | @Resource 18 | CommonLogger commonLogger; 19 | @Test 20 | public void testLogger(){ 21 | commonLogger.info("test %s","jett"); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /assistant-mysql/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | assistant 7 | io.github.geniusay 8 | 1.1.2 9 | 10 | 4.0.0 11 | 12 | assistant-mysql 13 | 14 | 15 | 11 16 | 11 17 | UTF-8 18 | 19 | 20 | 21 | 22 | com.github.yulichang 23 | mybatis-plus-join 24 | 1.2.4 25 | provided 26 | 27 | 28 | 29 | org.mybatis.spring.boot 30 | mybatis-spring-boot-starter 31 | provided 32 | 33 | 34 | 35 | 36 | com.baomidou 37 | mybatis-plus-boot-starter 38 | provided 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /assistant-mysql/src/main/java/io/github/common/JoinSection.java: -------------------------------------------------------------------------------- 1 | package io.github.common; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | @Data 9 | @AllArgsConstructor 10 | @NoArgsConstructor 11 | public class JoinSection { 12 | public enum JoinType{ 13 | LEFT, 14 | RIGHT, 15 | INNER, 16 | JOIN 17 | } 18 | 19 | public static JoinSectionBuilder builder() { 20 | return new JoinSectionBuilder(); 21 | } 22 | 23 | //插入类型 24 | private JoinType type; 25 | 26 | //插入表 27 | private String table; 28 | 29 | //插入表 as name 30 | private String asName; 31 | 32 | private String selectSQL; 33 | //连接条件 34 | private String connectColumn; 35 | 36 | public static class JoinSectionBuilder { 37 | private JoinType type; 38 | private String table; 39 | private String asName; 40 | 41 | private String selectSQL; 42 | private String connectColumn; 43 | 44 | JoinSectionBuilder() { 45 | } 46 | 47 | public JoinSectionBuilder type(final JoinType type) { 48 | this.type = type; 49 | return this; 50 | } 51 | 52 | public JoinSectionBuilder table(final String table) { 53 | this.table = table; 54 | return this; 55 | } 56 | 57 | public JoinSectionBuilder asName(final String asName) { 58 | this.asName = asName; 59 | return this; 60 | } 61 | 62 | public JoinSectionBuilder connectColumn(final String source, final String target) { 63 | this.connectColumn = source + " = " + target; 64 | return this; 65 | } 66 | 67 | public JoinSectionBuilder connectColumn(final String connectColumn) { 68 | this.connectColumn = connectColumn; 69 | return this; 70 | } 71 | 72 | public JoinSectionBuilder selectSQL(final String selectSQL) { 73 | this.selectSQL = selectSQL; 74 | return this; 75 | } 76 | 77 | public JoinSection build() { 78 | return new JoinSection(this.type, this.table, this.asName,selectSQL, this.connectColumn); 79 | } 80 | 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /assistant-mysql/src/main/java/io/github/common/PageVO.java: -------------------------------------------------------------------------------- 1 | package io.github.common; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.util.List; 8 | 9 | @Data 10 | @NoArgsConstructor 11 | @AllArgsConstructor 12 | public class PageVO { 13 | private List pageList; 14 | 15 | private long page; 16 | 17 | private long limit; 18 | 19 | private long total; 20 | } 21 | -------------------------------------------------------------------------------- /assistant-mysql/src/main/java/io/github/query/QueryParamGroup.java: -------------------------------------------------------------------------------- 1 | package io.github.query; 2 | 3 | import lombok.Data; 4 | import org.springframework.beans.factory.annotation.Value; 5 | import org.springframework.boot.context.properties.ConfigurationProperties; 6 | import org.springframework.stereotype.Component; 7 | 8 | import java.util.HashMap; 9 | import java.util.List; 10 | import java.util.Map; 11 | import java.util.Optional; 12 | import java.util.stream.Collectors; 13 | @Component 14 | @Data 15 | @ConfigurationProperties(prefix = "assistant.mysql") 16 | public class QueryParamGroup { 17 | 18 | private Map> queryGroup = new HashMap<>(); 19 | 20 | public List getQueryParams(String queryType){ 21 | 22 | return Optional.ofNullable(queryGroup.get(queryType)).orElse(List.of()); 23 | } 24 | 25 | public List getQueryParams(String queryType,String prefix){ 26 | List list = Optional.ofNullable(queryGroup.get(queryType)).orElse(List.of()); 27 | return list.stream().map( 28 | e -> prefix + "." + e 29 | ).collect(Collectors.toList()); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /assistant-mysql/src/main/java/io/github/service/AssistantMJPService.java: -------------------------------------------------------------------------------- 1 | package io.github.service; 2 | 3 | import com.baomidou.mybatisplus.core.metadata.IPage; 4 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 5 | import io.github.common.JoinSection; 6 | 7 | import java.util.List; 8 | import java.util.Map; 9 | 10 | public interface AssistantMJPService extends AssistantService { 11 | 12 | IPage BeanPageVOList(int page, int limit, List params ,Map conditions, List orders,Class vClass,Boolean isAes); 13 | 14 | IPage BeanPageVOList(int page, int limit, List params, Map conditions, List joinSections , List orders, Class vClass, Boolean isAsc); 15 | List getBeanVOList(List params,Map condition,Class vClass); 16 | 17 | V getBeanVO(List params, Map condition, Class vClass); 18 | 19 | V getBeanVO(List params, Map condition,List joinSections ,Class vClass); 20 | } 21 | -------------------------------------------------------------------------------- /assistant-mysql/src/main/java/io/github/service/AssistantService.java: -------------------------------------------------------------------------------- 1 | package io.github.service; 2 | 3 | import com.baomidou.mybatisplus.core.metadata.IPage; 4 | import com.baomidou.mybatisplus.extension.api.R; 5 | 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | public interface AssistantService { 10 | 11 | IPage BeanPageList(int page, int limit, List params,Map conditions, List orders, Boolean isAsc); 12 | 13 | T getBean(List params, Map condition); 14 | 15 | List getBeanList(List params,Map condition); 16 | List batchBeanList(List params, Map> inCondition); 17 | 18 | Boolean updateBean(T t, Map condition); 19 | 20 | Boolean deleteBean( Map condition); 21 | } 22 | -------------------------------------------------------------------------------- /assistant-mysql/src/main/java/io/github/service/AssistantServiceImpl.java: -------------------------------------------------------------------------------- 1 | package io.github.service; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 4 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 5 | import com.baomidou.mybatisplus.core.metadata.IPage; 6 | import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper; 7 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 8 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 9 | import org.springframework.stereotype.Service; 10 | 11 | import javax.annotation.Resource; 12 | import java.util.List; 13 | import java.util.Map; 14 | 15 | public class AssistantServiceImpl,T> extends ServiceImpl implements AssistantService { 16 | 17 | protected M mapper; 18 | 19 | @Resource 20 | public void setMapper(M mapper){ 21 | this.mapper = mapper; 22 | } 23 | 24 | @Override 25 | public IPage BeanPageList(int page, int limit, List params,Map conditions, List orders, Boolean isAsc) { 26 | Page pageQuery = new Page<>(page, limit); 27 | QueryWrapper select = new QueryWrapper().select(params.toArray(new String[0])); 28 | if(orders!=null && orders.size()>0){ 29 | if (isAsc){ 30 | orders.forEach( 31 | select::orderByAsc 32 | ); 33 | }else{ 34 | orders.forEach( 35 | select::orderByDesc 36 | ); 37 | } 38 | } 39 | return mapper.selectPage(pageQuery,select); 40 | } 41 | 42 | 43 | public IPage BeanPageList(int page, int limit, List params) { 44 | return BeanPageList(page, limit, params,Map.of(),List.of(),false); 45 | } 46 | 47 | public IPage BeanPageList(int page, int limit, List params, Map conditions) { 48 | return BeanPageList(page, limit, params,conditions,List.of(),false); 49 | } 50 | 51 | public IPage BeanPageList(int page, int limit, List params, List orders, Boolean isAsc) { 52 | return BeanPageList(page, limit, params,Map.of(),orders,isAsc); 53 | } 54 | 55 | @Override 56 | public T getBean(List params, Map condition) { 57 | return query().select(params.toArray(new String[0])) 58 | .allEq(condition) 59 | .one(); 60 | } 61 | 62 | public List getBeanList(List params,Map condition){ 63 | return query().select(params.toArray(new String[0])) 64 | .allEq(condition) 65 | .list(); 66 | } 67 | 68 | @Override 69 | public List batchBeanList(List params, Map> inCondition) { 70 | QueryChainWrapper selectChain = query().select(params.toArray(new String[0])); 71 | inCondition.forEach( 72 | selectChain::in 73 | ); 74 | return selectChain.list(); 75 | } 76 | 77 | @Override 78 | public Boolean updateBean(T t, Map condition) { 79 | return mapper.update(t,new QueryWrapper().allEq(condition))>0; 80 | } 81 | 82 | @Override 83 | public Boolean deleteBean(Map condition) { 84 | return mapper.deleteByMap(condition)>0; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /assistant-mysql/src/main/java/io/github/util/PageUtil.java: -------------------------------------------------------------------------------- 1 | package io.github.util; 2 | 3 | import com.baomidou.mybatisplus.core.metadata.IPage; 4 | import io.github.common.PageVO; 5 | import java.util.ArrayList; 6 | 7 | public class PageUtil{ 8 | 9 | public static PageVO toPageVO(IPage page){ 10 | return new PageVO( 11 | page.getRecords(), 12 | page.getCurrent(), 13 | page.getSize(), 14 | page.getTotal() 15 | ); 16 | } 17 | 18 | public static PageVO emptyPageVO(){ 19 | return new PageVO(new ArrayList(), -1, 0, 0); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /assistant-plus-generator/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | assistant 5 | io.github.geniusay 6 | 1.1.2 7 | 8 | 4.0.0 9 | 10 | assistant-plus-generator 11 | jar 12 | ${assistant-plus-generator.version} 13 | assistant-plus-generator 14 | http://maven.apache.org 15 | 16 | 17 | UTF-8 18 | 19 | 20 | 21 | 22 | 23 | io.github.geniusay 24 | assistant-common 25 | 26 | 27 | 28 | io.github.geniusay 29 | assistant-util 30 | 31 | 32 | 33 | 34 | org.apache.velocity 35 | velocity 36 | 1.6.2 37 | 38 | 39 | 40 | org.springframework.boot 41 | spring-boot-starter-web 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /assistant-plus-generator/src/main/java/io/github/common/apiJs/ApiJs.java: -------------------------------------------------------------------------------- 1 | package io.github.common.apiJs; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | /** 11 | * Genius 12 | **/ 13 | 14 | /** 15 | * apiJs的文件信息类 16 | */ 17 | @Data 18 | @AllArgsConstructor 19 | @NoArgsConstructor 20 | public class ApiJs { 21 | private String controllerClassName; //控制器类名 22 | private List apiMethodList = new ArrayList<>(); //api方法列表 23 | 24 | 25 | } 26 | -------------------------------------------------------------------------------- /assistant-plus-generator/src/main/java/io/github/common/apiJs/ApiMethod.java: -------------------------------------------------------------------------------- 1 | package io.github.common.apiJs; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | /** 11 | * Genius 12 | **/ 13 | @Data 14 | @AllArgsConstructor 15 | @NoArgsConstructor 16 | public class ApiMethod { 17 | private String methodName; //方法名 18 | private String methodUrl; //方法url 19 | private String methodType; //方法类型 20 | private String methodDesc; //方法描述 21 | private List methodParam = new ArrayList<>(); //方法参数 22 | private Boolean isRestFul; //是否是restful风格 23 | } 24 | -------------------------------------------------------------------------------- /assistant-plus-generator/src/main/java/io/github/common/mysql/Column.java: -------------------------------------------------------------------------------- 1 | package io.github.common.mysql; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | /** 8 | * Genius 9 | **/ 10 | 11 | @Data 12 | @NoArgsConstructor 13 | @AllArgsConstructor 14 | public class Column { 15 | private Class type; //字段类型 16 | private String typeInSql; //字段类型 17 | private String name; //字段名 18 | private String comment; //字段注释 19 | private Object defaultValue; //默认值 20 | private Integer length; //字段长度 21 | private Boolean isNull; //是否为空 22 | private Boolean isPrimaryKey; //是否为主键 23 | } 24 | -------------------------------------------------------------------------------- /assistant-plus-generator/src/main/java/io/github/common/mysql/DataBase.java: -------------------------------------------------------------------------------- 1 | package io.github.common.mysql; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | import org.springframework.stereotype.Component; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * Genius 12 | **/ 13 | 14 | @Data 15 | @Component 16 | @AllArgsConstructor 17 | @NoArgsConstructor 18 | public class DataBase { 19 | private String dataBaseName; //数据库名 20 | private List tables; //数据库表信息 21 | } 22 | -------------------------------------------------------------------------------- /assistant-plus-generator/src/main/java/io/github/common/mysql/Table.java: -------------------------------------------------------------------------------- 1 | package io.github.common.mysql; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | import org.springframework.stereotype.Component; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * Genius 12 | 13 | **/ 14 | 15 | 16 | /** 17 | * 表信息 18 | */ 19 | @Data 20 | @Component 21 | @NoArgsConstructor 22 | @AllArgsConstructor 23 | public class Table { 24 | private String tableName; //表名 25 | private String tableComment; //表注释 26 | private String tableCreateSql; //建表语句 27 | private List columns; //表字段信息 28 | } 29 | -------------------------------------------------------------------------------- /assistant-plus-generator/src/main/java/io/github/controller/HelloController.java: -------------------------------------------------------------------------------- 1 | package io.github.controller; 2 | 3 | import org.springframework.web.bind.annotation.*; 4 | 5 | /** 6 | * Genius 7 | * 8 | **/ 9 | @RestController 10 | @RequestMapping("/hello") 11 | public class HelloController { 12 | 13 | @GetMapping("/helloGet") 14 | public void hello(){ 15 | System.out.println("hello"); 16 | } 17 | 18 | @PostMapping("/helloPost") 19 | public void helloPost(@RequestBody String body){ 20 | System.out.println("helloPost"); 21 | } 22 | 23 | @GetMapping("/helloGet/{id}/{name}") 24 | public void helloGetById(@PathVariable("id") String id,@PathVariable("name") String name){ 25 | System.out.println("helloGet"); 26 | } 27 | 28 | @GetMapping("/helloNotRestful") 29 | public void helloNotRestful(@RequestParam("id") String id,@RequestParam("name") String name){ 30 | System.out.println("helloNotRestful"); 31 | } 32 | 33 | @RequestMapping(value = "/helloRequest",method = {RequestMethod.GET,RequestMethod.POST}) 34 | public void helloRequest(){ 35 | System.out.println("helloRequest"); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /assistant-plus-generator/src/main/java/io/github/controller/TestController.java: -------------------------------------------------------------------------------- 1 | package io.github.controller; 2 | 3 | import org.springframework.web.bind.annotation.*; 4 | 5 | /** 6 | * Genius 7 | * 8 | **/ 9 | @RestController 10 | @RequestMapping("/test") 11 | public class TestController { 12 | 13 | @GetMapping("/testGet") 14 | public void test(){ 15 | System.out.println("test"); 16 | } 17 | 18 | @PostMapping("/testPost") 19 | public void testPost(@RequestBody String body){ 20 | System.out.println("testPost"); 21 | } 22 | 23 | @GetMapping("/testGet/{id}") 24 | public void testGetById(@PathVariable("id") String id){ 25 | System.out.println("testGet"); 26 | } 27 | 28 | @GetMapping("/testNotRestful") 29 | public void testNotRestful(@RequestParam("id") String id,@RequestParam("name") String name){ 30 | System.out.println("testNotRestful"); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /assistant-plus-generator/src/main/java/io/github/generator/AutoGenerate.java: -------------------------------------------------------------------------------- 1 | package io.github.generator; 2 | 3 | 4 | import io.github.generator.autotemplate.TemplateFile; 5 | import io.github.util.path.PathUtils; 6 | import lombok.Data; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | import org.springframework.stereotype.Component; 10 | 11 | /** 12 | * Genius 13 | **/ 14 | @Data 15 | @Component 16 | public abstract class AutoGenerate { 17 | private Logger logger = LoggerFactory.getLogger(getClass()); 18 | private String fileSavePath = PathUtils.getProjectPath(); //文件保存路径 19 | 20 | private String templatePath = "src/main/resources/templates/"; //模板路径 21 | 22 | private String templateName; //模板名称 23 | 24 | public abstract void generate(); 25 | 26 | public abstract void generate(Boolean isAsync); 27 | 28 | public abstract void generateByTemplate(); 29 | 30 | public abstract TemplateFile buildTemplateFile(); 31 | 32 | public AutoGenerate setTemplatePath(String templatePath){ 33 | this.templatePath = templatePath; 34 | return this; 35 | } 36 | 37 | public AutoGenerate setFileSavePath(String fileSavePath){ 38 | this.fileSavePath = fileSavePath; 39 | return this; 40 | } 41 | 42 | public AutoGenerate setTemplateName(String templateName){ 43 | this.templateName = templateName; 44 | return this; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /assistant-plus-generator/src/main/java/io/github/generator/autotemplate/ApiJsTemplateFile.java: -------------------------------------------------------------------------------- 1 | package io.github.generator.autotemplate; 2 | 3 | import io.github.common.apiJs.ApiJs; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | /** 12 | * Genius 13 | **/ 14 | @Data 15 | @NoArgsConstructor 16 | @AllArgsConstructor 17 | public class ApiJsTemplateFile extends TemplateFile { 18 | 19 | private final String fileSuffix = ".js"; 20 | 21 | private String fileAxiosPath; 22 | 23 | private List apiJsList = new ArrayList<>(); 24 | } 25 | -------------------------------------------------------------------------------- /assistant-plus-generator/src/main/java/io/github/generator/autotemplate/TemplateFile.java: -------------------------------------------------------------------------------- 1 | package io.github.generator.autotemplate; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * Genius 11 | **/ 12 | 13 | @Data 14 | @AllArgsConstructor 15 | @NoArgsConstructor 16 | public abstract class TemplateFile implements Serializable { 17 | //文件后缀 18 | private String fileSuffix; 19 | 20 | } 21 | -------------------------------------------------------------------------------- /assistant-plus-generator/src/main/java/io/github/generator/builder/TemplateBuilder.java: -------------------------------------------------------------------------------- 1 | package io.github.generator.builder; 2 | 3 | 4 | import io.github.generator.autotemplate.TemplateFile; 5 | 6 | public interface TemplateBuilder { 7 | T build(); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /assistant-plus-generator/src/main/java/io/github/generator/mysqlClassGenerate.java: -------------------------------------------------------------------------------- 1 | package io.github.generator; 2 | 3 | 4 | import io.github.generator.autotemplate.TemplateFile; 5 | 6 | /** 7 | * Genius 8 | **/ 9 | public class mysqlClassGenerate extends AutoGenerate { 10 | 11 | @Override 12 | public void generate() { 13 | 14 | } 15 | 16 | @Override 17 | public void generate(Boolean isAsync) { 18 | 19 | } 20 | 21 | @Override 22 | public void generateByTemplate() { 23 | 24 | } 25 | 26 | @Override 27 | public TemplateFile buildTemplateFile() { 28 | return null; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /assistant-plus-generator/src/main/java/io/github/util/VelocityUtils.java: -------------------------------------------------------------------------------- 1 | package io.github.util; 2 | 3 | 4 | import io.github.generator.autotemplate.TemplateFile; 5 | import io.github.util.file.CommonFileUtils; 6 | import org.apache.velocity.Template; 7 | import org.apache.velocity.VelocityContext; 8 | import org.apache.velocity.app.Velocity; 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | import org.springframework.stereotype.Component; 12 | 13 | import java.io.File; 14 | import java.io.FileWriter; 15 | 16 | /** 17 | * Genius 18 | **/ 19 | /* 20 | 模板生成引擎,目前使用的是velocity,后期可以考虑使用freemarker 21 | */ 22 | @Component 23 | public class VelocityUtils { 24 | 25 | private static Logger logger = LoggerFactory.getLogger(VelocityUtils.class); 26 | 27 | public static VelocityContext getVelocityContext(String name, T templateFile){ 28 | VelocityContext velocityContext = new VelocityContext(); 29 | velocityContext.put(name, templateFile); 30 | return velocityContext; 31 | } 32 | 33 | public static VelocityContext getVelocityContextByObject(String name, Object object){ 34 | VelocityContext velocityContext = new VelocityContext(); 35 | velocityContext.put(name, object); 36 | return velocityContext; 37 | } 38 | 39 | /* 40 | * 通过模板生成文件 41 | * @param velocityContext 42 | * @param templateName 模板路径 43 | * @param loadPath 模板加载路径 44 | * @param filePath 生成文件路径包含文件名 45 | */ 46 | public static void generateFileByVelocity(VelocityContext velocityContext, String templateName, 47 | String loadPath, String filePath) throws Exception { 48 | Velocity.setProperty(Velocity.FILE_RESOURCE_LOADER_PATH, loadPath); 49 | 50 | Template template = Velocity.getTemplate(templateName); 51 | File f = CommonFileUtils.createFile(filePath); 52 | 53 | try(FileWriter fileWriter = new FileWriter(f)){ 54 | template.merge(velocityContext, fileWriter); 55 | logger.info("-----模板生成文件成功-----:{}",filePath); 56 | }catch (Exception e){ 57 | throw e; 58 | }finally { 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /assistant-plus-generator/src/main/resources/js/HelloController.js: -------------------------------------------------------------------------------- 1 | import request from 'axios'; export function helloRequestGET() { return request({ url: '/hello/helloRequest/', method: 'get', params: { } }); } export function helloRequestPOST() { return request({ url: '/hello/helloRequest/', method: 'post', data: { } }); } export function helloPost(body) { return request({ url: '/hello/helloPost/', method: 'post', data: { body: body, } }); } export function helloGetById(id,name) { return request({ url: '/hello/helloGet/'+id+'/'+name+'/', method: 'get', }); } export function helloNotRestful(id,name) { return request({ url: '/hello/helloNotRestful/', method: 'get', params: { id: id, name: name, } }); } export function hello() { return request({ url: '/hello/helloGet/', method: 'get', params: { } }); } -------------------------------------------------------------------------------- /assistant-plus-generator/src/main/resources/templates/apiJs.java.vm: -------------------------------------------------------------------------------- 1 | import request from '$axiosPath'; 2 | 3 | 4 | #foreach($method in $apiJsInfo.getApiMethodList()) 5 | export function $method.getMethodName()(#foreach($param in $method.getMethodParam())$param#if($velocityCount!= $method.getMethodParam().size()),#end #end) { 6 | return request({ 7 | url: '$method.getMethodUrl()/'#if($method.getMethodType() == 'get'&&$method.getIsRestFul()==true)#foreach($param in $method.getMethodParam())+ $param +'/'#end#end, 8 | method: $method.getMethodType(), 9 | #if($method.getMethodType() == 'get'&&$method.getIsRestFul()==false) 10 | params: { 11 | #foreach($param in $method.getMethodParam()) 12 | $param:$param, 13 | #end 14 | } 15 | #elseif($method.getMethodType() == 'post') 16 | data: { 17 | #foreach($param in $method.getMethodParam()) 18 | $param:$param, 19 | #end 20 | } 21 | #end 22 | }); 23 | } 24 | #end 25 | 26 | -------------------------------------------------------------------------------- /assistant-plus-generator/src/main/resources/templates/mysqlClass.java.vm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Geniusay/Assistant/0bc9ab94d5642a703f77fe38ac3bc854e3bfeb9a/assistant-plus-generator/src/main/resources/templates/mysqlClass.java.vm -------------------------------------------------------------------------------- /assistant-plus-generator/src/test/java/io/github/generator/AutoApiJsGenerateTest.java: -------------------------------------------------------------------------------- 1 | package io.github.generator; 2 | 3 | 4 | import io.github.controller.TestController; 5 | import org.junit.jupiter.api.Test; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.boot.test.context.SpringBootTest; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * Genius 13 | **/ 14 | 15 | /** 16 | * ApiJs自动生成器 17 | */ 18 | @SpringBootTest 19 | public class AutoApiJsGenerateTest { 20 | 21 | @Autowired 22 | AutoApiJsGenerate autoApiJsGenerate; 23 | 24 | @Test 25 | public void testGenerateByJs(){ 26 | autoApiJsGenerate.generate(); 27 | } 28 | 29 | //根据模板生成 30 | @Test 31 | public void testGenerateByTemplate(){ 32 | autoApiJsGenerate.generate(); 33 | } 34 | 35 | //根据传统的Js生成 36 | @Test 37 | public void testGenerateJS(){ 38 | autoApiJsGenerate. 39 | setIsJsMoodleGenerated(true). 40 | generate(); 41 | } 42 | 43 | 44 | //自定义生成 45 | @Test 46 | public void testGenerateByDIY(){ 47 | 48 | autoApiJsGenerate. 49 | setIsJsMoodleGenerated(true). //是否使用传统Js模板 50 | setFileSavePath("E:\\Project\\Assistant\\Assistant\\assistant-plus-generator\\src\\main\\resources\\js"). //文件保存区域 51 | generate(); 52 | 53 | 54 | 55 | autoApiJsGenerate 56 | .filter(List.of(TestController.class)) 57 | .setTemplatePath("src/main/resources/templates/")//选择模板加载路径 58 | .setTemplateName("apiJs.java.vm") //选择模板名字 59 | .setFileSavePath("E:\\Project\\Assistant\\Assistant\\assistant-plus-generator\\src\\main\\resources\\js") 60 | .generate(false); //是否异步生成 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /assistant-service/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | assistant 5 | io.github.geniusay 6 | 1.1.2 7 | 8 | 4.0.0 9 | 10 | assistant-service 11 | jar 12 | ${assistant-service.version} 13 | assistant-service 14 | http://maven.apache.org 15 | 16 | 17 | UTF-8 18 | 19 | 20 | 21 | 22 | org.springframework.boot 23 | spring-boot-starter-web 24 | provided 25 | 26 | 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-validation 31 | provided 32 | 33 | 34 | 35 | io.github.geniusay 36 | assistant-common 37 | provided 38 | 39 | 40 | 41 | io.github.geniusay 42 | assistant-util 43 | provided 44 | 45 | 46 | 47 | io.github.geniusay 48 | assistant-cache 49 | provided 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /assistant-service/src/main/java/io/github/exception/handler/AbstractExceptionHandler.java: -------------------------------------------------------------------------------- 1 | package io.github.exception.handler; 2 | 3 | import io.github.common.logger.CommonLogger; 4 | import lombok.Data; 5 | import org.springframework.core.Ordered; 6 | 7 | import javax.annotation.Resource; 8 | 9 | @Data 10 | public abstract class AbstractExceptionHandler implements Ordered { 11 | 12 | @Resource 13 | protected CommonLogger commonLogger; 14 | } 15 | -------------------------------------------------------------------------------- /assistant-service/src/main/java/io/github/exception/handler/AssistantExceptionHandlerCondition.java: -------------------------------------------------------------------------------- 1 | package io.github.exception.handler; 2 | 3 | import io.github.exception.handler.annotation.AssistantControllerAdvice; 4 | import lombok.Data; 5 | import org.springframework.beans.factory.annotation.Value; 6 | import org.springframework.boot.context.properties.ConfigurationProperties; 7 | import org.springframework.context.annotation.Condition; 8 | import org.springframework.context.annotation.ConditionContext; 9 | import org.springframework.core.annotation.AnnotationAttributes; 10 | import org.springframework.core.env.Environment; 11 | import org.springframework.core.type.AnnotatedTypeMetadata; 12 | import org.springframework.stereotype.Component; 13 | 14 | import java.util.ArrayList; 15 | import java.util.List; 16 | 17 | /** 18 | * assistant异常处理开启条件类 19 | * 使用方法: 20 | * 1,关闭某个异常处理类 21 | * assistant.service.exception.handler.disables:xxxx,xxxx 22 | * 2,不配置则默认全部开启 23 | */ 24 | @Component 25 | public class AssistantExceptionHandlerCondition implements Condition { 26 | 27 | @Override 28 | public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { 29 | Environment environment = context.getEnvironment(); 30 | // 获取@ControllerAdvice注解的属性 31 | AnnotationAttributes attributes = AnnotationAttributes.fromMap(metadata.getAnnotationAttributes(AssistantControllerAdvice.class.getName())); 32 | 33 | if (attributes != null) { 34 | List disables = environment.getProperty("assistant.service.exception.handler.disables", List.class); 35 | String value = attributes.getString("value"); 36 | return disables==null||!disables.contains(value); 37 | } 38 | return false; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /assistant-service/src/main/java/io/github/exception/handler/CommonExceptionHandler.java: -------------------------------------------------------------------------------- 1 | package io.github.exception.handler; 2 | 3 | import io.github.common.logger.CommonLogger; 4 | import io.github.common.web.Result; 5 | import io.github.exception.handler.annotation.AssistantControllerAdvice; 6 | import org.springframework.context.annotation.Conditional; 7 | import org.springframework.core.Ordered; 8 | import org.springframework.stereotype.Component; 9 | import org.springframework.web.bind.annotation.ControllerAdvice; 10 | import org.springframework.web.bind.annotation.ExceptionHandler; 11 | import org.springframework.web.bind.annotation.ResponseBody; 12 | 13 | import javax.annotation.Resource; 14 | import javax.servlet.http.HttpServletRequest; 15 | import javax.servlet.http.HttpServletResponse; 16 | 17 | @AssistantControllerAdvice("commonExceptionHandler") 18 | @Conditional(AssistantExceptionHandlerCondition.class) 19 | public class CommonExceptionHandler extends AbstractExceptionHandler { 20 | 21 | 22 | @ExceptionHandler(Exception.class) 23 | @ResponseBody 24 | public Result ExceptionHandler(HttpServletRequest request, HttpServletResponse response, Object o, Exception exception){ 25 | commonLogger.error("系统异常:异常类:%s , 异常信息:%s",exception.getClass().getSimpleName(),exception.getMessage()); 26 | return Result.error("500","未知异常"); 27 | } 28 | 29 | @Override 30 | public int getOrder() { 31 | return Integer.MAX_VALUE; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /assistant-service/src/main/java/io/github/exception/handler/ValidateExceptionHandler.java: -------------------------------------------------------------------------------- 1 | package io.github.exception.handler; 2 | 3 | import io.github.common.logger.CommonLogger; 4 | import io.github.common.web.Result; 5 | import io.github.exception.handler.annotation.AssistantControllerAdvice; 6 | import org.springframework.context.annotation.Conditional; 7 | import org.springframework.stereotype.Component; 8 | import org.springframework.web.bind.annotation.ControllerAdvice; 9 | import org.springframework.web.bind.annotation.ExceptionHandler; 10 | import org.springframework.web.bind.annotation.ResponseBody; 11 | 12 | import javax.annotation.Resource; 13 | import javax.servlet.http.HttpServletRequest; 14 | import javax.servlet.http.HttpServletResponse; 15 | import javax.validation.ValidationException; 16 | 17 | @AssistantControllerAdvice("validateExceptionHandler") 18 | @Conditional(AssistantExceptionHandlerCondition.class) 19 | public class ValidateExceptionHandler extends AbstractExceptionHandler{ 20 | 21 | @ExceptionHandler(ValidationException.class) 22 | @ResponseBody 23 | public Result ValidationExceptionHandler(HttpServletRequest request, HttpServletResponse response, Object o, Exception exception){ 24 | 25 | if(exception instanceof ValidationException){ 26 | commonLogger.error("请求路径:%s 参数校验错误%s",request.getRequestURI(),exception.getMessage()); 27 | return Result.error("400",String.format("参数校验错误:%s",exception.getMessage())); 28 | } 29 | return Result.error("400","参数校验错误"); 30 | } 31 | 32 | @Override 33 | public int getOrder() { 34 | return Integer.MAX_VALUE-3; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /assistant-service/src/main/java/io/github/exception/handler/annotation/AssistantControllerAdvice.java: -------------------------------------------------------------------------------- 1 | package io.github.exception.handler.annotation; 2 | 3 | import org.springframework.core.annotation.AliasFor; 4 | import org.springframework.web.bind.annotation.ControllerAdvice; 5 | 6 | import java.lang.annotation.*; 7 | 8 | import org.springframework.stereotype.Component; 9 | import org.springframework.web.bind.annotation.RestController; 10 | 11 | @Target(ElementType.TYPE) 12 | @Retention(RetentionPolicy.RUNTIME) 13 | @ControllerAdvice 14 | public @interface AssistantControllerAdvice { 15 | 16 | @AliasFor(annotation = Component.class, attribute = "value") 17 | String value() default ""; 18 | 19 | @AliasFor(annotation = ControllerAdvice.class,attribute = "basePackages") 20 | String[] values() default {}; 21 | 22 | 23 | @AliasFor(annotation = ControllerAdvice.class,attribute = "value") 24 | String[] basePackages() default {}; 25 | 26 | @AliasFor(annotation = ControllerAdvice.class,attribute = "basePackageClasses") 27 | Class[] basePackageClasses() default {}; 28 | 29 | @AliasFor(annotation = ControllerAdvice.class,attribute = "assignableTypes") 30 | Class[] assignableTypes() default {}; 31 | 32 | @AliasFor(annotation = ControllerAdvice.class,attribute = "annotations") 33 | Class[] annotations() default {}; 34 | } 35 | -------------------------------------------------------------------------------- /assistant-service/src/main/java/io/github/id/IdGenerator.java: -------------------------------------------------------------------------------- 1 | package io.github.id; 2 | 3 | import org.springframework.data.annotation.Id; 4 | 5 | public interface IdGenerator { 6 | 7 | T generate() throws IdGeneratorException; 8 | 9 | default T safeGenerate(){ 10 | try { 11 | return generate(); 12 | }catch (IdGeneratorException e){ 13 | return null; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /assistant-service/src/main/java/io/github/id/IdGeneratorException.java: -------------------------------------------------------------------------------- 1 | package io.github.id; 2 | 3 | public class IdGeneratorException extends Throwable{ 4 | 5 | 6 | public IdGeneratorException(String msg) { 7 | super(msg); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /assistant-service/src/main/java/io/github/id/UUIDGenerator.java: -------------------------------------------------------------------------------- 1 | package io.github.id; 2 | 3 | import io.github.util.random.UUIDGeneratorUtils; 4 | import org.springframework.stereotype.Component; 5 | 6 | @Component("assistant-id-uuid") 7 | public class UUIDGenerator implements IdGenerator{ 8 | 9 | @Override 10 | public String generate() { 11 | return UUIDGeneratorUtils.uuid(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /assistant-service/src/main/java/io/github/id/snowflake/DefaultSnowflakeRegister.java: -------------------------------------------------------------------------------- 1 | package io.github.id.snowflake; 2 | 3 | import org.springframework.beans.factory.annotation.Value; 4 | import org.springframework.stereotype.Component; 5 | 6 | /** 7 | * 默认雪花算法注册机 8 | * 用户手动配置assistant.service.id.snowflake.workerId和assistant.service.id.snowflake.dataCenterId设置workId与dataCenterId 9 | * 默认workId与dataId都为0 10 | */ 11 | @Component("register-default") 12 | public class DefaultSnowflakeRegister implements SnowflakeRegister{ 13 | 14 | @Value("${assistant.service.id.snowflake.workerId:0}") 15 | private long workerId; 16 | 17 | @Value("${assistant.service.id.snowflake.dataCenterId:0}") 18 | private long dataCenterId; 19 | 20 | @Override 21 | public long workId() { 22 | return workerId; 23 | } 24 | 25 | @Override 26 | public long dataCenterId() { 27 | return dataCenterId; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /assistant-service/src/main/java/io/github/id/snowflake/RedisSnowflakeRegister.java: -------------------------------------------------------------------------------- 1 | package io.github.id.snowflake; 2 | 3 | 4 | import io.github.common.RedisKey; 5 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 6 | import org.springframework.data.redis.core.StringRedisTemplate; 7 | import org.springframework.stereotype.Component; 8 | 9 | import javax.annotation.PostConstruct; 10 | import javax.annotation.Resource; 11 | import java.util.Optional; 12 | import java.util.concurrent.TimeUnit; 13 | 14 | /** 15 | * TODO Redis锁优化成 Redisson 16 | * Redis雪花算法注册机 17 | * 配置项assistant.service.id.snowflake.register: register-redis时启用 18 | */ 19 | @Component("register-redis") 20 | @ConditionalOnProperty(name = "assistant.service.id.snowflake.register", havingValue = "register-redis") 21 | public class RedisSnowflakeRegister implements SnowflakeRegister{ 22 | 23 | @Resource 24 | private StringRedisTemplate stringRedisTemplate; 25 | 26 | private final static RedisKey WORK_ID_KEY = new RedisKey("assistant:snowflake:workId"); 27 | private final static RedisKey DATACENTER_ID_KEY = new RedisKey("assistant:snowflake:datacenterId"); 28 | private final static RedisKey LOCK = new RedisKey("assistant:snowflake:lock",1, TimeUnit.MINUTES); 29 | 30 | private static final int MAX_WORKER_ID = 32; 31 | private static final int MAX_DATACENTER_ID = 32; 32 | 33 | private void tryLock() throws InterruptedException { 34 | if (Boolean.TRUE.equals(stringRedisTemplate.opsForValue().setIfAbsent(LOCK.getKey(), "1", LOCK.getTime(), LOCK.getTimeUnit()))) { 35 | return; 36 | } 37 | Thread.sleep(10); 38 | tryLock(); 39 | } 40 | 41 | private void unlock(){ 42 | stringRedisTemplate.delete(LOCK.getKey()); 43 | } 44 | 45 | @PostConstruct 46 | public void init(){ 47 | stringRedisTemplate.opsForValue().setIfAbsent(WORK_ID_KEY.getKey(),"0"); 48 | stringRedisTemplate.opsForValue().setIfAbsent(DATACENTER_ID_KEY.getKey(),"0"); 49 | } 50 | 51 | @Override 52 | public long workId() throws SnowflakeRegisterException, InterruptedException { 53 | long workId; 54 | try { 55 | tryLock(); 56 | Long increment = Optional.ofNullable(stringRedisTemplate.opsForValue().increment(WORK_ID_KEY.getKey())).orElse(0L); 57 | if(increment==0){ 58 | throw new SnowflakeRegisterException("redis generate workId error,please check redis config"); 59 | } 60 | workId = increment-1; 61 | if(workId==MAX_WORKER_ID){ 62 | stringRedisTemplate.opsForValue().increment(DATACENTER_ID_KEY.getKey()); 63 | stringRedisTemplate.opsForValue().set(WORK_ID_KEY.getKey(),"0"); 64 | workId=0; 65 | return workId; 66 | } 67 | }finally { 68 | unlock(); 69 | } 70 | return workId; 71 | } 72 | 73 | @Override 74 | public long dataCenterId() throws SnowflakeRegisterException { 75 | String incrementStr = stringRedisTemplate.opsForValue().get(DATACENTER_ID_KEY.getKey()); 76 | if(incrementStr==null){ 77 | throw new SnowflakeRegisterException("redis generate dataCenterId error,please check redis config"); 78 | } 79 | long increment = Long.parseLong(incrementStr); 80 | return increment>=MAX_DATACENTER_ID?0:increment; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /assistant-service/src/main/java/io/github/id/snowflake/SnowflakeRegister.java: -------------------------------------------------------------------------------- 1 | package io.github.id.snowflake; 2 | 3 | public interface SnowflakeRegister { 4 | 5 | long workId() throws SnowflakeRegisterException, InterruptedException; 6 | 7 | long dataCenterId() throws SnowflakeRegisterException; 8 | } 9 | -------------------------------------------------------------------------------- /assistant-service/src/main/java/io/github/id/snowflake/SnowflakeRegisterException.java: -------------------------------------------------------------------------------- 1 | package io.github.id.snowflake; 2 | 3 | import io.github.id.IdGeneratorException; 4 | 5 | public class SnowflakeRegisterException extends IdGeneratorException { 6 | 7 | public SnowflakeRegisterException(String msg) { 8 | super(msg); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /assistant-service/src/main/java/io/github/servicechain/ServiceChainContext.java: -------------------------------------------------------------------------------- 1 | package io.github.servicechain; 2 | 3 | 4 | import java.util.ArrayList; 5 | import java.util.HashMap; 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | public class ServiceChainContext { 10 | 11 | private static final ThreadLocal CONTEXT = ThreadLocal.withInitial(ServiceChainContext::new); 12 | 13 | private List resultRecord; 14 | private final Map data; 15 | 16 | private ServiceChainContext() { 17 | resultRecord = new ArrayList<>(); 18 | this.data = new HashMap<>(); 19 | } 20 | 21 | private static ThreadLocal getContext() { 22 | return CONTEXT; 23 | } 24 | 25 | public static ServiceChainContext context() { 26 | return getContext().get(); 27 | } 28 | 29 | public static Object get(String key){ 30 | return context().data.get(key); 31 | } 32 | 33 | public static void recordSet(String key, Object value){ 34 | context().resultRecord.add(value); 35 | set(key, value); 36 | } 37 | public static Object set(String key, Object value){ 38 | return context().data.put(key, value); 39 | } 40 | 41 | public static void setAll(Map data){ 42 | context().data.putAll(data); 43 | } 44 | 45 | public static void remove(String key){ 46 | context().data.remove(key); 47 | } 48 | 49 | public static void clear(){ 50 | context().data.clear(); 51 | } 52 | 53 | public T get(String key, Class type){ 54 | return type.cast(get(key)); 55 | } 56 | 57 | public static void extendTo(ServiceChainContext context){ 58 | ServiceChainContext.setAll(context.data); 59 | } 60 | 61 | public static Object getPreSetResult(){ 62 | return context().resultRecord.isEmpty()?null: context().resultRecord.get(context().resultRecord.size()-1); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /assistant-service/src/main/java/io/github/servicechain/ServiceChainFactory.java: -------------------------------------------------------------------------------- 1 | package io.github.servicechain; 2 | 3 | import io.github.servicechain.bootstrap.ServiceChainBootstrap; 4 | import io.github.servicechain.bootstrap.ServiceChainHandler; 5 | import io.github.servicechain.chain.AbstractFilterChain; 6 | import io.github.servicechain.chain.ChainBluePrint; 7 | import io.github.servicechain.chain.ServiceChain; 8 | import io.github.servicechain.chain.ServiceChainProvider; 9 | import io.github.servicechain.common.ServiceHelper; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.context.ApplicationContext; 12 | import org.springframework.stereotype.Component; 13 | 14 | import javax.annotation.Resource; 15 | import java.util.HashMap; 16 | import java.util.List; 17 | import java.util.Map; 18 | 19 | @Component 20 | public class ServiceChainFactory { 21 | private final Map chainMap; 22 | 23 | private final Map serviceChainMap; 24 | 25 | private final Map> chainBluePrintMap; 26 | 27 | @Resource 28 | private ServiceHelper helper; 29 | 30 | @Autowired 31 | public ServiceChainFactory(ApplicationContext applicationContext){ 32 | chainMap = applicationContext.getBeansOfType(AbstractFilterChain.class); 33 | serviceChainMap = new HashMap<>(); 34 | chainBluePrintMap = new HashMap<>(); 35 | applicationContext.getBeansOfType(ServiceChainProvider.class).forEach( 36 | (name, serviceChainProvider) -> { 37 | Map> provideBluePrint = serviceChainProvider.provideBluePrint(chainMap); 38 | chainBluePrintMap.putAll(provideBluePrint); 39 | serviceChainMap.putAll(serviceChainProvider.provide(provideBluePrint)); 40 | } 41 | ); 42 | } 43 | 44 | public AbstractFilterChain getChain(String name){ 45 | return chainMap.get(name); 46 | } 47 | 48 | public ServiceChainBootstrap get(String serviceName){ 49 | return get(serviceName,true); 50 | } 51 | 52 | public ServiceChainBootstrap get(String serviceName,boolean singleton){ 53 | ServiceChain serviceChain; 54 | if(singleton){ 55 | serviceChain = serviceChainMap.get(serviceName); 56 | }else{ 57 | serviceChain = ChainBluePrint.buildServiceChain(chainBluePrintMap.get(serviceName)); 58 | } 59 | 60 | if(serviceChain == null){ 61 | throw new RuntimeException("No service chain found for service: " + serviceName); 62 | } 63 | return ServiceChainHandler.bootstrap().serviceChain(serviceChain); 64 | } 65 | public ServiceChainBootstrap bootstrap(){ 66 | return ServiceChainHandler.bootstrap(); 67 | } 68 | 69 | public ServiceHelper helper(){ 70 | return helper; 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /assistant-service/src/main/java/io/github/servicechain/annotation/Chain.java: -------------------------------------------------------------------------------- 1 | package io.github.servicechain.annotation; 2 | 3 | 4 | import org.springframework.context.annotation.Scope; 5 | import org.springframework.stereotype.Component; 6 | 7 | import java.lang.annotation.ElementType; 8 | import java.lang.annotation.Retention; 9 | import java.lang.annotation.RetentionPolicy; 10 | import java.lang.annotation.Target; 11 | 12 | @Component 13 | @Target(ElementType.TYPE) // 只能用于类上 14 | @Retention(RetentionPolicy.RUNTIME) 15 | public @interface Chain { 16 | String value(); 17 | } 18 | -------------------------------------------------------------------------------- /assistant-service/src/main/java/io/github/servicechain/annotation/MultiFilterFunc.java: -------------------------------------------------------------------------------- 1 | package io.github.servicechain.annotation; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Retention(RetentionPolicy.RUNTIME) 9 | @Target(ElementType.METHOD) 10 | public @interface MultiFilterFunc { 11 | } 12 | -------------------------------------------------------------------------------- /assistant-service/src/main/java/io/github/servicechain/bootstrap/ChainHandler.java: -------------------------------------------------------------------------------- 1 | package io.github.servicechain.bootstrap; 2 | 3 | public interface ChainHandler { 4 | R execute(T t); 5 | } 6 | -------------------------------------------------------------------------------- /assistant-service/src/main/java/io/github/servicechain/bootstrap/FailCallback.java: -------------------------------------------------------------------------------- 1 | package io.github.servicechain.bootstrap; 2 | 3 | public interface FailCallback extends ServiceChainCallback{ 4 | } 5 | -------------------------------------------------------------------------------- /assistant-service/src/main/java/io/github/servicechain/bootstrap/ReturnType.java: -------------------------------------------------------------------------------- 1 | package io.github.servicechain.bootstrap; 2 | 3 | public enum ReturnType { 4 | BOOLEAN, 5 | THROW 6 | } 7 | -------------------------------------------------------------------------------- /assistant-service/src/main/java/io/github/servicechain/bootstrap/ServiceChainBootstrap.java: -------------------------------------------------------------------------------- 1 | package io.github.servicechain.bootstrap; 2 | 3 | import io.github.servicechain.chain.AbstractFilterChain; 4 | import io.github.servicechain.chain.ServiceChain; 5 | import lombok.Getter; 6 | 7 | import java.util.HashMap; 8 | import java.util.Map; 9 | import java.util.function.Function; 10 | import java.util.function.Supplier; 11 | 12 | @Getter 13 | public class ServiceChainBootstrap { 14 | 15 | private ReturnType returnType = ReturnType.BOOLEAN; 16 | 17 | private Map supplierMap = new HashMap<>(); 18 | 19 | private Map successCallbackMap = new HashMap<>(); 20 | 21 | private Map failCallbackMap = new HashMap<>(); 22 | 23 | private ServiceChain serviceChain; 24 | 25 | private ServiceChain tempChain; 26 | 27 | public ServiceChainBootstrap next(AbstractFilterChain chain,boolean isIgnore){ 28 | ServiceChain tempServiceChain = new ServiceChain<>(chain, null); 29 | tempServiceChain.setIgnore(isIgnore); 30 | if(serviceChain == null){ 31 | serviceChain = tempServiceChain; 32 | tempChain = serviceChain; 33 | }else{ 34 | tempChain.setNext(tempServiceChain); 35 | tempChain = tempServiceChain; 36 | } 37 | return this; 38 | } 39 | 40 | public ServiceChainBootstrap next(AbstractFilterChain chain){ 41 | return this.next(chain,false); 42 | } 43 | 44 | public ServiceChainBootstrap next(AbstractFilterChain...chains){ 45 | for (AbstractFilterChain chain : chains) { 46 | this.next(chain,false); 47 | } 48 | return this; 49 | } 50 | 51 | public ServiceChainBootstrap serviceChain(ServiceChain serviceChain){ 52 | this.serviceChain = serviceChain; 53 | return this; 54 | } 55 | 56 | public ServiceChainBootstrap supplierMap(Map> supplierMap){ 57 | this.supplierMap.putAll(supplierMap); 58 | return this; 59 | } 60 | 61 | public ServiceChainBootstrap successCallbackMap(Map successCallbackMap){ 62 | this.successCallbackMap.putAll(successCallbackMap); 63 | return this; 64 | } 65 | 66 | public ServiceChainBootstrap failCallbackMap(Map failCallbackMap){ 67 | this.failCallbackMap.putAll(failCallbackMap); 68 | return this; 69 | } 70 | 71 | public ServiceChainBootstrap returnType(ReturnType returnType){ 72 | this.returnType = returnType; 73 | return this; 74 | } 75 | 76 | public boolean execute(T obj){ 77 | ServiceChainHandler handler = new ServiceChainHandler(this); 78 | return handler.execute(obj); 79 | } 80 | 81 | public V executeAndReturn(T obj){ 82 | ServiceChainHandler handler = new ServiceChainHandler(this); 83 | return handler.executeAndReturn(obj); 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /assistant-service/src/main/java/io/github/servicechain/bootstrap/ServiceChainCallback.java: -------------------------------------------------------------------------------- 1 | package io.github.servicechain.bootstrap; 2 | 3 | @FunctionalInterface 4 | public interface ServiceChainCallback { 5 | void callback(); 6 | } 7 | -------------------------------------------------------------------------------- /assistant-service/src/main/java/io/github/servicechain/bootstrap/ServiceChainHandler.java: -------------------------------------------------------------------------------- 1 | package io.github.servicechain.bootstrap; 2 | 3 | import io.github.servicechain.ServiceChainContext; 4 | import io.github.servicechain.chain.ServiceChain; 5 | 6 | import java.util.Map; 7 | import java.util.function.Function; 8 | 9 | public class ServiceChainHandler implements ChainHandler{ 10 | 11 | private ReturnType returnType; 12 | 13 | private Map supplierMap; 14 | 15 | private Map successCallbackMap; 16 | 17 | private Map failCallbackMap; 18 | 19 | private ServiceChain serviceChain; 20 | 21 | private final Function originSupplier = (obj)->obj; 22 | 23 | public static ServiceChainBootstrap bootstrap(){ 24 | return new ServiceChainBootstrap(); 25 | } 26 | 27 | protected ServiceChainHandler(ServiceChainBootstrap bootstrap){ 28 | this.returnType = bootstrap.getReturnType(); 29 | this.supplierMap = bootstrap.getSupplierMap(); 30 | this.successCallbackMap = bootstrap.getSuccessCallbackMap(); 31 | this.failCallbackMap = bootstrap.getFailCallbackMap(); 32 | this.serviceChain = bootstrap.getServiceChain(); 33 | } 34 | 35 | 36 | private boolean doFilter(T obj,ServiceChain chain,int number){ 37 | try { 38 | Function function = supplierMap.getOrDefault(number,originSupplier); 39 | boolean res = chain.doFilter(function.apply(obj)); 40 | callback(res,number); 41 | return res||chain.isIgnore(); 42 | }catch (Exception e){ 43 | callback(false,number); 44 | if (chain.isIgnore()||ReturnType.BOOLEAN.equals(returnType)) { 45 | return chain.isIgnore(); 46 | } 47 | throw e; 48 | } 49 | } 50 | 51 | private void callback(Boolean res,int number){ 52 | ServiceChainCallback callback = res? successCallbackMap.get(number): failCallbackMap.get(number); 53 | if(callback!=null){ 54 | callback.callback(); 55 | } 56 | } 57 | 58 | @Override 59 | public Boolean execute(T obj) { 60 | ServiceChain temp = serviceChain; 61 | int number = 0; 62 | while (temp != null) { 63 | number++; 64 | try { 65 | if(doFilter(obj,temp,number)){ 66 | temp = temp.next(); 67 | }else{ 68 | return false; 69 | } 70 | }catch (Exception e){ 71 | throw e; 72 | } 73 | } 74 | return true; 75 | } 76 | 77 | public V executeAndReturn(T obj){ 78 | if (!execute(obj)) { 79 | return null; 80 | }else { 81 | return (V) ServiceChainContext.getPreSetResult(); 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /assistant-service/src/main/java/io/github/servicechain/bootstrap/SuccessCallback.java: -------------------------------------------------------------------------------- 1 | package io.github.servicechain.bootstrap; 2 | 3 | public interface SuccessCallback extends ServiceChainCallback{ 4 | } 5 | -------------------------------------------------------------------------------- /assistant-service/src/main/java/io/github/servicechain/chain/AbstractFilterChain.java: -------------------------------------------------------------------------------- 1 | package io.github.servicechain.chain; 2 | 3 | import lombok.Data; 4 | import lombok.Getter; 5 | 6 | import java.util.List; 7 | 8 | @Data 9 | public abstract class AbstractFilterChain implements FilterChain{ 10 | 11 | public AbstractFilterChain() { 12 | } 13 | 14 | 15 | public List servicePoints(){ 16 | return null; 17 | }; 18 | 19 | @Getter 20 | static protected class ServicePoint{ 21 | 22 | private String serviceName; 23 | 24 | private int order; 25 | 26 | private boolean isIgnore = false; 27 | 28 | public ServicePoint(String serviceName, int order) { 29 | this.serviceName = serviceName; 30 | this.order = order; 31 | } 32 | 33 | public ServicePoint(String serviceName) { 34 | this.serviceName = serviceName; 35 | this.order = 5; 36 | } 37 | 38 | public ServicePoint(String serviceName, int order, boolean isIgnore) { 39 | this.serviceName = serviceName; 40 | this.order = order; 41 | this.isIgnore = isIgnore; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /assistant-service/src/main/java/io/github/servicechain/chain/ChainBluePrint.java: -------------------------------------------------------------------------------- 1 | package io.github.servicechain.chain; 2 | 3 | import lombok.Builder; 4 | import lombok.Getter; 5 | 6 | import java.util.List; 7 | import java.util.Objects; 8 | 9 | @Builder 10 | @Getter 11 | public class ChainBluePrint implements Comparable{ 12 | 13 | private final boolean isIgnore; 14 | 15 | private final AbstractFilterChain chain; 16 | 17 | private final int order; 18 | 19 | public ChainBluePrint(boolean isIgnore, AbstractFilterChain chain, int order) { 20 | this.isIgnore = isIgnore; 21 | this.chain = chain; 22 | this.order = order; 23 | } 24 | 25 | @Override 26 | public int compareTo(ChainBluePrint o) { 27 | return o.getOrder() - this.getOrder() ; 28 | } 29 | 30 | public static ServiceChain buildServiceChain(List bluePrints){ 31 | ServiceChain head = null; 32 | 33 | for (int i = bluePrints.size()-1; i >=0; i--) { 34 | ServiceChain temp = new ServiceChain<>( bluePrints.get(i)); 35 | temp.setNext(head); 36 | head = temp; 37 | } 38 | return head; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /assistant-service/src/main/java/io/github/servicechain/chain/FilterChain.java: -------------------------------------------------------------------------------- 1 | package io.github.servicechain.chain; 2 | 3 | public interface FilterChain { 4 | 5 | boolean filter(V value); 6 | } 7 | -------------------------------------------------------------------------------- /assistant-service/src/main/java/io/github/servicechain/chain/MultiArgsFilterChain.java: -------------------------------------------------------------------------------- 1 | package io.github.servicechain.chain; 2 | 3 | import io.github.servicechain.ServiceChainContext; 4 | import io.github.servicechain.annotation.MultiFilterFunc; 5 | import io.github.common.Args; 6 | 7 | import java.lang.reflect.Method; 8 | import java.util.Objects; 9 | 10 | public abstract class MultiArgsFilterChain extends AbstractFilterChain { 11 | 12 | private Method filterMethod; 13 | 14 | public MultiArgsFilterChain() { 15 | Method[] methods = this.getClass().getDeclaredMethods(); 16 | for (Method method : methods) { 17 | if (method.isAnnotationPresent(MultiFilterFunc.class) ) { 18 | filterMethod = method; 19 | break; 20 | } 21 | } 22 | if(filterMethod==null){ 23 | throw new RuntimeException("not found MultiFilterFunc method"); 24 | } 25 | } 26 | 27 | @Override 28 | public boolean filter(Object... value) { 29 | T result; 30 | try { 31 | result = (T) filterMethod.invoke(this, value); 32 | if(!Objects.isNull(result)){ 33 | saveRes(result); 34 | } 35 | }catch (Exception e){ 36 | throw new RuntimeException(e); 37 | } 38 | return nextLogic(result); 39 | } 40 | 41 | public boolean filter(Args args){ 42 | return filter(args.args()); 43 | } 44 | 45 | public String filterId(){ 46 | return String.valueOf(this.hashCode()); 47 | } 48 | public boolean nextLogic(T res){ 49 | return !Objects.isNull(res); 50 | } 51 | 52 | private void saveRes(T result){ 53 | ServiceChainContext.recordSet(filterId(),result); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /assistant-service/src/main/java/io/github/servicechain/chain/ServiceChain.java: -------------------------------------------------------------------------------- 1 | package io.github.servicechain.chain; 2 | 3 | import lombok.Getter; 4 | 5 | 6 | public class ServiceChain{ 7 | @Getter 8 | private int order = 5; 9 | 10 | @Getter 11 | private AbstractFilterChain chain; 12 | 13 | private boolean isIgnore = false; 14 | 15 | private ServiceChain() { 16 | } 17 | 18 | private ServiceChain next; 19 | public ServiceChain(int order, AbstractFilterChain chain, ServiceChain next) { 20 | this.order = order; 21 | this.chain = chain; 22 | this.next = next; 23 | } 24 | 25 | public ServiceChain(int order, AbstractFilterChain chain, boolean isIgnore) { 26 | this.order = order; 27 | this.chain = chain; 28 | this.isIgnore = isIgnore; 29 | } 30 | 31 | public ServiceChain(ChainBluePrint bluePrint){ 32 | this.order = bluePrint.getOrder(); 33 | this.chain = bluePrint.getChain(); 34 | this.isIgnore =bluePrint.isIgnore(); 35 | } 36 | 37 | public ServiceChain(AbstractFilterChain chain, ServiceChain next) { 38 | this.chain = chain; 39 | this.next = next; 40 | } 41 | 42 | public void setNext(ServiceChain next){ 43 | this.next = next; 44 | } 45 | 46 | public ServiceChain next(){ 47 | return next; 48 | } 49 | 50 | public boolean doFilter(T value){ 51 | return chain.filter(value); 52 | } 53 | 54 | public void setIgnore(boolean ignore) { 55 | isIgnore = ignore; 56 | } 57 | 58 | 59 | public boolean isIgnore() { 60 | return this.isIgnore; 61 | } 62 | 63 | public static ServiceChain empty(){ 64 | return new ServiceChain(); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /assistant-service/src/main/java/io/github/servicechain/chain/ServiceChainProvider.java: -------------------------------------------------------------------------------- 1 | package io.github.servicechain.chain; 2 | 3 | import java.util.HashMap; 4 | import java.util.List; 5 | import java.util.Map; 6 | import java.util.Objects; 7 | 8 | public interface ServiceChainProvider{ 9 | 10 | Map> provideBluePrint(Map map); 11 | 12 | default Map> provide(Map> bluePrintMap) { 13 | Map> res = new HashMap<>(); 14 | bluePrintMap.forEach( 15 | (name, bluePrints) -> { 16 | res.put(name,ChainBluePrint.buildServiceChain(bluePrints)); 17 | } 18 | ); 19 | return res; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /assistant-service/src/main/java/io/github/servicechain/chain/ServicePointServiceChainProvider.java: -------------------------------------------------------------------------------- 1 | package io.github.servicechain.chain; 2 | 3 | import org.springframework.context.ApplicationContext; 4 | import org.springframework.stereotype.Component; 5 | 6 | import javax.annotation.Resource; 7 | import java.util.*; 8 | 9 | @Component 10 | public class ServicePointServiceChainProvider implements ServiceChainProvider{ 11 | 12 | @Resource 13 | private ApplicationContext context; 14 | 15 | 16 | @Override 17 | public Map> provideBluePrint(Map map) { 18 | Map> bluePrintMap = new HashMap<>(); 19 | map.forEach( 20 | (name, filterChain) ->{ 21 | List servicePoints = filterChain.servicePoints(); 22 | if(Objects.isNull(servicePoints)||servicePoints.isEmpty()){ 23 | return; 24 | } 25 | for (AbstractFilterChain.ServicePoint point : servicePoints) { 26 | int order = point.getOrder(); 27 | String serviceName = point.getServiceName(); 28 | bluePrintMap.computeIfAbsent(serviceName,(k)->new PriorityQueue<>()) 29 | .add(new ChainBluePrint(point.isIgnore(),filterChain,order)); 30 | } 31 | } 32 | ); 33 | Map> ans = new HashMap<>(); 34 | bluePrintMap.forEach( 35 | (k,v)->{ 36 | ans.put(k,new ArrayList<>(v)); 37 | } 38 | ); 39 | return ans; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /assistant-service/src/main/java/io/github/servicechain/chain/YamlServiceChainProvider.java: -------------------------------------------------------------------------------- 1 | package io.github.servicechain.chain; 2 | 3 | import lombok.Data; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | import org.springframework.stereotype.Component; 6 | 7 | import java.util.*; 8 | import java.util.regex.Matcher; 9 | import java.util.regex.Pattern; 10 | 11 | @Data 12 | @Component 13 | @ConfigurationProperties(prefix = "assistant.service-chain") 14 | public class YamlServiceChainProvider implements ServiceChainProvider{ 15 | 16 | private Map serviceMap = Collections.emptyMap(); 17 | 18 | private static final String IGNORE = "IGNORE"; 19 | 20 | @Override 21 | public Map> provideBluePrint(Map map) { 22 | Map> res = new HashMap<>(); 23 | Pattern pattern = Pattern.compile("(\\w+)\\[(\\w+)]"); 24 | serviceMap.forEach( 25 | (serviceName,str)->{ 26 | String[] chains = str.split("->"); 27 | int order = 0; 28 | List bluePrints = new ArrayList<>(); 29 | for (String chainName:chains) { 30 | ChainBluePrint bluePrint; 31 | boolean isIgnore = false; 32 | if(chainName.contains("[")){ 33 | Matcher matcher = pattern.matcher(chainName); 34 | if(matcher.find()){ 35 | chainName = matcher.group(1); 36 | isIgnore = IGNORE.equalsIgnoreCase(matcher.group(2)); 37 | 38 | }else{ 39 | continue; 40 | } 41 | } 42 | AbstractFilterChain chain = map.getOrDefault(chainName, null); 43 | if(chain==null){ 44 | throw new RuntimeException("service name "+chainName+" not found"); 45 | } 46 | bluePrint = ChainBluePrint.builder() 47 | .isIgnore(isIgnore) 48 | .chain(chain) 49 | .order(order++).build(); 50 | 51 | bluePrints.add(bluePrint); 52 | } 53 | res.put(serviceName,bluePrints); 54 | } 55 | ); 56 | return res; 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /assistant-service/src/main/java/io/github/servicechain/common/ServiceHelper.java: -------------------------------------------------------------------------------- 1 | package io.github.servicechain.common; 2 | 3 | import io.github.servicechain.ServiceChainContext; 4 | import org.springframework.stereotype.Component; 5 | 6 | @Component 7 | public class ServiceHelper { 8 | 9 | public Object preResult(){ 10 | return ServiceChainContext.getPreSetResult(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /assistant-service/src/test/java/io/github/serviceHelper/login/FormLoginServiceTest.java: -------------------------------------------------------------------------------- 1 | package io.github.serviceHelper.login; 2 | import org.springframework.boot.test.context.SpringBootTest; 3 | 4 | import java.util.Map; 5 | 6 | /** 7 | * Genius 8 | * 2023/04/13 01:11 9 | **/ 10 | @SpringBootTest 11 | public class FormLoginServiceTest { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /assistant-test/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | assistant 5 | io.github.geniusay 6 | 1.1.2 7 | 8 | 4.0.0 9 | 10 | assistant-test 11 | jar 12 | 13 | assistant-test 14 | http://maven.apache.org 15 | 16 | 17 | UTF-8 18 | 19 | 20 | 21 | 22 | 23 | mysql 24 | mysql-connector-java 25 | provided 26 | 27 | 28 | 29 | com.github.yulichang 30 | mybatis-plus-join 31 | 1.2.4 32 | provided 33 | 34 | 35 | 36 | org.mybatis.spring.boot 37 | mybatis-spring-boot-starter 38 | provided 39 | 40 | 41 | 42 | 43 | com.baomidou 44 | mybatis-plus-boot-starter 45 | provided 46 | 47 | 48 | 49 | org.springframework.boot 50 | spring-boot-starter-test 51 | provided 52 | 53 | 54 | 55 | io.github.geniusay 56 | assistant-boot-start 57 | provided 58 | 59 | 60 | 61 | io.github.geniusay 62 | assistant-mysql 63 | provided 64 | 65 | 66 | 67 | io.github.geniusay 68 | assistant-service 69 | provided 70 | 71 | 72 | 73 | org.springframework.boot 74 | spring-boot-starter-validation 75 | provided 76 | 77 | 78 | 79 | io.github.geniusay 80 | assistant-cache 81 | provided 82 | 83 | 84 | 85 | junit 86 | junit 87 | 4.12 88 | test 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /assistant-test/src/main/java/io/github/TestApplication.java: -------------------------------------------------------------------------------- 1 | package io.github; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class TestApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(TestApplication.class, args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /assistant-test/src/main/java/io/github/chain/ExceptionFilterChain.java: -------------------------------------------------------------------------------- 1 | package io.github.chain; 2 | 3 | import io.github.servicechain.annotation.Chain; 4 | import io.github.servicechain.chain.AbstractFilterChain; 5 | 6 | import java.util.List; 7 | 8 | @Chain("Exception") 9 | public class ExceptionFilterChain extends AbstractFilterChain { 10 | 11 | @Override 12 | public List servicePoints() { 13 | return null; 14 | } 15 | 16 | @Override 17 | public boolean filter(Object value) { 18 | throw new RuntimeException("ExceptionFilterChain error!!!!!!!!"); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /assistant-test/src/main/java/io/github/chain/ObjectNotEmptyFilterChain.java: -------------------------------------------------------------------------------- 1 | package io.github.chain; 2 | 3 | import io.github.servicechain.annotation.Chain; 4 | import io.github.servicechain.chain.AbstractFilterChain; 5 | 6 | import java.util.List; 7 | import java.util.Objects; 8 | 9 | @Chain("objectNotEmpty") 10 | public class ObjectNotEmptyFilterChain extends AbstractFilterChain { 11 | 12 | @Override 13 | public List servicePoints(){ 14 | return List.of( 15 | new ServicePoint("hello",5,true), 16 | new ServicePoint("world",4) 17 | ); 18 | } 19 | 20 | @Override 21 | public boolean filter(Object value) { 22 | return !Objects.isNull(value); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /assistant-test/src/main/java/io/github/chain/ReturnMapFilterChain.java: -------------------------------------------------------------------------------- 1 | package io.github.chain; 2 | 3 | import io.github.servicechain.annotation.Chain; 4 | import io.github.servicechain.annotation.MultiFilterFunc; 5 | import io.github.servicechain.chain.MultiArgsFilterChain; 6 | 7 | import java.util.Map; 8 | 9 | @Chain("returnMap") 10 | public class ReturnMapFilterChain extends MultiArgsFilterChain { 11 | 12 | @MultiFilterFunc 13 | public Map get(String key,String value){ 14 | return Map.of(key,value); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /assistant-test/src/main/java/io/github/chain/StringNotEmptyFilterChain.java: -------------------------------------------------------------------------------- 1 | package io.github.chain; 2 | 3 | import io.github.servicechain.annotation.Chain; 4 | import io.github.servicechain.chain.AbstractFilterChain; 5 | import io.github.util.StringUtils; 6 | 7 | import java.util.List; 8 | 9 | @Chain("stringNotEmpty") 10 | public class StringNotEmptyFilterChain extends AbstractFilterChain { 11 | 12 | @Override 13 | public List servicePoints() { 14 | return List.of( 15 | new ServicePoint("hello",2), 16 | new ServicePoint("world",5) 17 | ); 18 | } 19 | 20 | @Override 21 | public boolean filter(String value) { 22 | return !StringUtils.isEmpty(value); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /assistant-test/src/main/java/io/github/chain/TaskCheckFilterChain.java: -------------------------------------------------------------------------------- 1 | package io.github.chain; 2 | 3 | import io.github.pojo.TaskDO; 4 | import io.github.servicechain.annotation.Chain; 5 | import io.github.servicechain.chain.AbstractFilterChain; 6 | import io.github.util.StringUtils; 7 | 8 | import java.util.List; 9 | 10 | @Chain("taskCheck") 11 | public class TaskCheckFilterChain extends AbstractFilterChain { 12 | 13 | 14 | @Override 15 | public List servicePoints() { 16 | return null; 17 | } 18 | 19 | @Override 20 | public boolean filter(TaskDO value) { 21 | if (!value.getTaskName().startsWith("task")) { 22 | return false; 23 | } 24 | if(StringUtils.isEmpty(value.getTaskDescription())){ 25 | return false; 26 | } 27 | return true; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /assistant-test/src/main/java/io/github/config/MybatisConfiguration.java: -------------------------------------------------------------------------------- 1 | package io.github.config; 2 | 3 | import com.baomidou.mybatisplus.annotation.DbType; 4 | import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; 5 | import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; 6 | import org.mybatis.spring.annotation.MapperScan; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.Configuration; 9 | 10 | @Configuration 11 | @MapperScan("io.github.mapper") 12 | public class MybatisConfiguration { 13 | @Bean 14 | public MybatisPlusInterceptor mybatisPlusInterceptor() { 15 | MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); 16 | interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); 17 | return interceptor; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /assistant-test/src/main/java/io/github/controller/TestController.java: -------------------------------------------------------------------------------- 1 | package io.github.controller; 2 | 3 | import io.github.common.web.Result; 4 | import org.springframework.validation.annotation.Validated; 5 | import org.springframework.web.bind.annotation.GetMapping; 6 | import org.springframework.web.bind.annotation.RequestMapping; 7 | import org.springframework.web.bind.annotation.RequestParam; 8 | import org.springframework.web.bind.annotation.RestController; 9 | 10 | import javax.validation.constraints.NotBlank; 11 | 12 | @RestController 13 | @RequestMapping("/test") 14 | @Validated 15 | public class TestController { 16 | 17 | @GetMapping("/paramTest") 18 | public Result testParam(@RequestParam @NotBlank(message="hello 字段为null") String hello){ 19 | return Result.success(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /assistant-test/src/main/java/io/github/mapper/FeedbackMapper.java: -------------------------------------------------------------------------------- 1 | package io.github.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.github.yulichang.base.mapper.MPJJoinMapper; 5 | import io.github.pojo.FeedbackDO; 6 | 7 | public interface FeedbackMapper extends MPJJoinMapper { 8 | } 9 | -------------------------------------------------------------------------------- /assistant-test/src/main/java/io/github/mapper/FeedbackTypeMapper.java: -------------------------------------------------------------------------------- 1 | package io.github.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import io.github.pojo.FeedbackTypeDO; 5 | 6 | public interface FeedbackTypeMapper extends BaseMapper { 7 | } 8 | -------------------------------------------------------------------------------- /assistant-test/src/main/java/io/github/mapper/NoticeMapper.java: -------------------------------------------------------------------------------- 1 | package io.github.mapper; 2 | 3 | import com.github.yulichang.base.MPJBaseMapper; 4 | import io.github.pojo.NoticeDO; 5 | 6 | public interface NoticeMapper extends MPJBaseMapper { 7 | } 8 | -------------------------------------------------------------------------------- /assistant-test/src/main/java/io/github/pojo/FeedbackDO.java: -------------------------------------------------------------------------------- 1 | package io.github.pojo; 2 | 3 | import com.baomidou.mybatisplus.annotation.FieldStrategy; 4 | import com.baomidou.mybatisplus.annotation.TableField; 5 | import com.baomidou.mybatisplus.annotation.TableId; 6 | import com.baomidou.mybatisplus.annotation.TableName; 7 | import com.fasterxml.jackson.annotation.JsonFormat; 8 | import com.fasterxml.jackson.databind.annotation.JsonDeserialize; 9 | import com.fasterxml.jackson.databind.annotation.JsonSerialize; 10 | import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; 11 | import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; 12 | import io.github.constant.TimeConstant; 13 | import lombok.AllArgsConstructor; 14 | import lombok.Builder; 15 | import lombok.Data; 16 | import lombok.NoArgsConstructor; 17 | 18 | import java.time.LocalDateTime; 19 | 20 | /** 21 | * FeedbackDO 22 | */ 23 | @Data 24 | @AllArgsConstructor 25 | @NoArgsConstructor 26 | @Builder 27 | @TableName(value = "rvc_feedback" ) 28 | public class FeedbackDO { 29 | 30 | /** 31 | * 反馈ID 32 | */ 33 | @TableId(value = "fb_id") 34 | @TableField(updateStrategy = FieldStrategy.NEVER) 35 | private Long fbid; 36 | 37 | /** 38 | * 用户uid 39 | */ 40 | @TableField(updateStrategy = FieldStrategy.NEVER) 41 | private String uid; 42 | 43 | /** 44 | * 反馈帖子内容 45 | */ 46 | private String content; 47 | 48 | /** 49 | * 反馈帖子标题 50 | */ 51 | private String title; 52 | /** 53 | * 帖子类型 54 | */ 55 | private Integer type; 56 | 57 | /** 58 | * 帖子状态 59 | */ 60 | private Integer status; 61 | 62 | /** 63 | * 点赞数 64 | */ 65 | private Long upNum; 66 | 67 | /** 68 | * 评论数 69 | */ 70 | private Long commentNum; 71 | 72 | private Integer hasShow; 73 | 74 | /** 75 | * 最近创建时间 76 | */ 77 | @TableField(updateStrategy = FieldStrategy.NEVER) 78 | @JsonDeserialize(using = LocalDateTimeDeserializer.class) 79 | @JsonSerialize(using = LocalDateTimeSerializer.class) 80 | @JsonFormat(pattern = TimeConstant.YMD_HMS, timezone = "GMT+8") 81 | private LocalDateTime createAt; 82 | 83 | /** 84 | * 最近更新时间 85 | */ 86 | @TableField(updateStrategy = FieldStrategy.NEVER) 87 | @JsonDeserialize(using = LocalDateTimeDeserializer.class) 88 | @JsonSerialize(using = LocalDateTimeSerializer.class) 89 | @JsonFormat(pattern = TimeConstant.YMD_HMS, timezone = "GMT+8") 90 | private LocalDateTime updateAt; 91 | } 92 | -------------------------------------------------------------------------------- /assistant-test/src/main/java/io/github/pojo/FeedbackTypeDO.java: -------------------------------------------------------------------------------- 1 | package io.github.pojo; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableId; 5 | import com.baomidou.mybatisplus.annotation.TableName; 6 | import lombok.AllArgsConstructor; 7 | import lombok.Builder; 8 | import lombok.Data; 9 | import lombok.NoArgsConstructor; 10 | 11 | @Data 12 | @AllArgsConstructor 13 | @NoArgsConstructor 14 | @Builder 15 | @TableName(value = "rvc_feedback_type" ) 16 | public class FeedbackTypeDO { 17 | 18 | @TableId(value = "id",type = IdType.AUTO) 19 | private Integer id; 20 | 21 | private String type; 22 | } 23 | -------------------------------------------------------------------------------- /assistant-test/src/main/java/io/github/pojo/NoticeDO.java: -------------------------------------------------------------------------------- 1 | package io.github.pojo; 2 | 3 | import com.baomidou.mybatisplus.annotation.*; 4 | import com.fasterxml.jackson.annotation.JsonFormat; 5 | import com.fasterxml.jackson.databind.annotation.JsonDeserialize; 6 | import com.fasterxml.jackson.databind.annotation.JsonSerialize; 7 | import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; 8 | import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; 9 | import io.github.constant.TimeConstant; 10 | import lombok.AllArgsConstructor; 11 | import lombok.Data; 12 | import lombok.NoArgsConstructor; 13 | 14 | import java.time.LocalDateTime; 15 | 16 | @Data 17 | @AllArgsConstructor 18 | @NoArgsConstructor 19 | @TableName(value = "rvc_web_notice" ) 20 | public class NoticeDO { 21 | 22 | @TableId(value = "id", type = IdType.AUTO) 23 | private Integer id; 24 | 25 | @TableField(updateStrategy = FieldStrategy.NEVER) 26 | private String noticeId; 27 | 28 | private String title; 29 | 30 | private String author; 31 | 32 | private String content; 33 | /** 34 | * 封面图片地址 35 | */ 36 | private String cover; 37 | 38 | /** 39 | * 创建时间 40 | */ 41 | @TableField(updateStrategy = FieldStrategy.NEVER) 42 | @JsonDeserialize(using = LocalDateTimeDeserializer.class) 43 | @JsonSerialize(using = LocalDateTimeSerializer.class) 44 | @JsonFormat(pattern = TimeConstant.YMD_HMS, timezone = "GMT+8") 45 | private LocalDateTime createAt; 46 | 47 | /** 48 | * 点赞数 49 | */ 50 | private Integer likeNum; 51 | 52 | /** 53 | * 浏览数 54 | */ 55 | private Integer watchNum; 56 | 57 | } 58 | -------------------------------------------------------------------------------- /assistant-test/src/main/java/io/github/pojo/TaskDO.java: -------------------------------------------------------------------------------- 1 | package io.github.pojo; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | 6 | @Data 7 | @AllArgsConstructor 8 | public class TaskDO { 9 | private Integer taskId; 10 | 11 | private String taskName; 12 | 13 | private String taskDescription; 14 | } 15 | -------------------------------------------------------------------------------- /assistant-test/src/main/java/io/github/pojo/vo/FeedbackVO.java: -------------------------------------------------------------------------------- 1 | package io.github.pojo.vo; 2 | 3 | import com.fasterxml.jackson.annotation.JsonFormat; 4 | import com.fasterxml.jackson.databind.annotation.JsonDeserialize; 5 | import com.fasterxml.jackson.databind.annotation.JsonSerialize; 6 | import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; 7 | import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; 8 | import io.github.constant.TimeConstant; 9 | import lombok.AllArgsConstructor; 10 | import lombok.Builder; 11 | import lombok.Data; 12 | import lombok.NoArgsConstructor; 13 | 14 | import java.time.LocalDateTime; 15 | 16 | @Data 17 | @Builder 18 | @AllArgsConstructor 19 | @NoArgsConstructor 20 | public class FeedbackVO { 21 | 22 | /** 23 | * 反馈ID 24 | */ 25 | private Long fbid; 26 | 27 | /** 28 | * 用户uid 29 | */ 30 | private String uid; 31 | 32 | /** 33 | * 用户昵称 34 | */ 35 | private String nickname; 36 | 37 | /** 38 | * 用户头像 39 | */ 40 | private String avatar; 41 | 42 | /** 43 | * 反馈帖子内容 44 | */ 45 | private String content; 46 | 47 | /** 48 | * 反馈帖子标题 49 | */ 50 | private String title; 51 | 52 | /** 53 | * 帖子类型 54 | */ 55 | private Integer type; 56 | 57 | private String typeName; 58 | 59 | /** 60 | * 帖子状态 61 | */ 62 | private Integer status; 63 | 64 | private String statusName; 65 | 66 | /** 67 | * 点赞数 68 | */ 69 | private Long upNum; 70 | 71 | /** 72 | * 该用户是否对该反馈帖子点赞 73 | */ 74 | private Boolean hasUp = false; 75 | /** 76 | * 评论数 77 | */ 78 | private Long commentNum; 79 | 80 | private Integer hasShow; 81 | 82 | /** 83 | * 最近创建时间 84 | */ 85 | @JsonDeserialize(using = LocalDateTimeDeserializer.class) 86 | @JsonSerialize(using = LocalDateTimeSerializer.class) 87 | @JsonFormat(pattern = TimeConstant.YMD_HMS, timezone = "GMT+8") 88 | private LocalDateTime createAt; 89 | 90 | } 91 | -------------------------------------------------------------------------------- /assistant-test/src/main/java/io/github/pojo/vo/NoticeVO.java: -------------------------------------------------------------------------------- 1 | package io.github.pojo.vo; 2 | 3 | import com.fasterxml.jackson.annotation.JsonFormat; 4 | import com.fasterxml.jackson.databind.annotation.JsonDeserialize; 5 | import com.fasterxml.jackson.databind.annotation.JsonSerialize; 6 | import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; 7 | import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; 8 | import io.github.constant.TimeConstant; 9 | import lombok.AllArgsConstructor; 10 | import lombok.Data; 11 | import lombok.NoArgsConstructor; 12 | 13 | import java.time.LocalDateTime; 14 | 15 | @Data 16 | @AllArgsConstructor 17 | @NoArgsConstructor 18 | public class NoticeVO { 19 | 20 | private String noticeId; 21 | 22 | private String title; 23 | 24 | private String author; 25 | 26 | private String content; 27 | 28 | private String cover; 29 | 30 | @JsonDeserialize(using = LocalDateTimeDeserializer.class) 31 | @JsonSerialize(using = LocalDateTimeSerializer.class) 32 | @JsonFormat(pattern = TimeConstant.YMD_HMS, timezone = "GMT+8") 33 | private LocalDateTime createAt; 34 | 35 | private Integer likeNum; 36 | 37 | private Integer watchNum; 38 | } 39 | -------------------------------------------------------------------------------- /assistant-test/src/main/java/io/github/service/FeedbackDaoServiceImpl.java: -------------------------------------------------------------------------------- 1 | package io.github.service; 2 | 3 | import io.github.mapper.FeedbackMapper; 4 | import io.github.pojo.FeedbackDO; 5 | import org.springframework.stereotype.Service; 6 | 7 | @Service 8 | public class FeedbackDaoServiceImpl extends AssistantMJPServiceImpl { 9 | } 10 | -------------------------------------------------------------------------------- /assistant-test/src/main/java/io/github/service/FeedbackTypeServiceImpl.java: -------------------------------------------------------------------------------- 1 | package io.github.service; 2 | 3 | import io.github.mapper.FeedbackTypeMapper; 4 | import io.github.pojo.FeedbackTypeDO; 5 | import org.springframework.stereotype.Service; 6 | 7 | @Service 8 | public class FeedbackTypeServiceImpl extends AssistantServiceImpl { 9 | } 10 | -------------------------------------------------------------------------------- /assistant-test/src/main/java/io/github/service/NoticeDaoServiceImpl.java: -------------------------------------------------------------------------------- 1 | package io.github.service; 2 | 3 | import io.github.mapper.NoticeMapper; 4 | import io.github.pojo.NoticeDO; 5 | import org.springframework.stereotype.Service; 6 | 7 | 8 | @Service 9 | public class NoticeDaoServiceImpl extends AssistantMJPServiceImpl { 10 | } 11 | -------------------------------------------------------------------------------- /assistant-test/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | 2 | spring: 3 | redis: 4 | host: localhost # Redis服务器地址 5 | database: 0 # Redis数据库索引(默认为0) 6 | port: 6379 # Redis服务器连接端口 7 | 8 | password: Genius123 # Redis服务器连接密码(默认为空) 9 | timeout: 3000ms # 连接超时时间(毫秒) 10 | datasource: 11 | driver-class-name: com.mysql.cj.jdbc.Driver 12 | url: jdbc:mysql://localhost:3307/rvc2?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=UTC 13 | username: root 14 | password: root 15 | 16 | assistant: 17 | token: 18 | access-token-expire-time: 3600 19 | access-token-time-unit: SECONDS 20 | enable-refresh: true 21 | regex: 22 | pool: 23 | phone: ^1[3|4|5|7|8][0-9]{9}$#$ 24 | service: 25 | id: 26 | snowflake: 27 | workerId: 1 28 | dataCenterId: 1 29 | register: register-redis 30 | startTime: 2023-12-05 00:00:00 31 | exception: 32 | handler: 33 | disables: springWebExceptionHandler 34 | mysql: 35 | query-group: 36 | feedback_list: fb_id,uid,title,type,status,comment_num,up_num,create_at 37 | feedback_detail: fb_id,uid,title,content,type,status,comment_num,up_num,create_at 38 | service-chain: 39 | serviceMap: 40 | string: stringNotEmpty->objectNotEmpty 41 | task: stringNotEmpty->objectNotEmpty->taskCheck 42 | taskException: stringNotEmpty->objectNotEmpty->taskCheck->Exception 43 | ignoreTaskException: stringNotEmpty->objectNotEmpty->taskCheck->Exception[ignore] 44 | getResult: stringNotEmpty->objectNotEmpty->returnMap 45 | server: 46 | port: 16666 47 | -------------------------------------------------------------------------------- /assistant-test/src/test/java/io/github/geniusay/common/LoggerTest.java: -------------------------------------------------------------------------------- 1 | package io.github.geniusay.common; 2 | 3 | import io.github.common.logger.CommonLogger; 4 | import org.junit.Test; 5 | import org.junit.runner.RunWith; 6 | import org.springframework.boot.test.context.SpringBootTest; 7 | import org.springframework.test.context.junit4.SpringRunner; 8 | import org.springframework.test.context.web.WebAppConfiguration; 9 | 10 | import javax.annotation.Resource; 11 | import java.util.Arrays; 12 | import java.util.Collections; 13 | import java.util.Comparator; 14 | import java.util.List; 15 | 16 | @RunWith(SpringRunner.class) 17 | @SpringBootTest 18 | @WebAppConfiguration 19 | public class LoggerTest { 20 | 21 | @Resource 22 | CommonLogger commonLogger; 23 | 24 | @Test 25 | public void testSlf4jLogger(){ 26 | int[] prices = {6,1,3,2,4,7}; 27 | Arrays.sort(prices); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /assistant-test/src/test/java/io/github/geniusay/mysql/AssistantServiceTest.java: -------------------------------------------------------------------------------- 1 | package io.github.geniusay.mysql; 2 | 3 | import com.baomidou.mybatisplus.core.metadata.IPage; 4 | import io.github.common.JoinSection; 5 | import io.github.pojo.FeedbackDO; 6 | import io.github.pojo.NoticeDO; 7 | import io.github.pojo.vo.FeedbackVO; 8 | import io.github.pojo.vo.NoticeVO; 9 | import io.github.service.FeedbackDaoServiceImpl; 10 | import io.github.service.FeedbackTypeServiceImpl; 11 | import io.github.service.NoticeDaoServiceImpl; 12 | import io.github.util.PageUtil; 13 | import org.junit.Test; 14 | import org.junit.runner.RunWith; 15 | import org.springframework.boot.test.context.SpringBootTest; 16 | import org.springframework.test.context.junit4.SpringRunner; 17 | import org.springframework.test.context.web.WebAppConfiguration; 18 | 19 | import javax.annotation.Resource; 20 | import java.util.List; 21 | import java.util.Map; 22 | 23 | @RunWith(SpringRunner.class) 24 | @SpringBootTest 25 | @WebAppConfiguration 26 | public class AssistantServiceTest { 27 | @Resource 28 | NoticeDaoServiceImpl noticeDaoService; 29 | 30 | @Resource 31 | FeedbackDaoServiceImpl feedbackDaoService; 32 | 33 | @Resource 34 | FeedbackTypeServiceImpl feedbackTypeService; 35 | @Test 36 | public void testAssistantService(){ 37 | IPage noticeVOIPage = noticeDaoService.BeanPageVOList(1, 1, List.of("notice_id,title,author"),Map.of("notice_id","06dab345-b611-410a-a9d8-980ff11591c4"), NoticeVO.class); 38 | IPage noticeDOIPage = noticeDaoService.BeanPageList(1, 1, List.of("notice_id,title,author")); 39 | // System.out.println(noticeDaoService.getBean(List.of("notice_id,title"), Map.of("notice_id", "5bcd73d6-8546-42a7-8afe-1819643aac6c"))); 40 | // System.out.println(noticeDaoService.getBeanVO(List.of("notice_id,title"), Map.of("notice_id", "06dab345-b611-410a-a9d8-980ff11591c4"), NoticeVO.class)); 41 | // System.out.println(noticeDaoService.getBeanList(List.of("notice_id,title"), Map.of("author", "RVC社区官方"))); 42 | // System.out.println(noticeDaoService.getBeanVOList(List.of("notice_id,title"), Map.of("author", "RVC社区官方"), NoticeVO.class)); 43 | System.out.println(feedbackTypeService.list()); 44 | System.out.println(PageUtil.toPageVO(noticeVOIPage)); 45 | System.out.println(PageUtil.toPageVO(noticeDOIPage)); 46 | } 47 | 48 | @Test 49 | public void testAssistantJoin(){ 50 | JoinSection typeJoin = JoinSection.builder() 51 | .type(JoinSection.JoinType.LEFT) 52 | .table("rvc_feedback_type") 53 | .asName("type") 54 | .connectColumn("type.id","t.type") 55 | .selectSQL("type.type as typeName") 56 | .build(); 57 | 58 | JoinSection statusJoin = JoinSection.builder() 59 | .type(JoinSection.JoinType.LEFT) 60 | .table("rvc_feedback_status") 61 | .asName("status") 62 | .connectColumn("t.status = status.id") 63 | .selectSQL("status.status as statusName") 64 | .build(); 65 | 66 | IPage feedbackVOIPage = feedbackDaoService.BeanPageVOList(1, 10, 67 | List.of("t.*"), 68 | List.of(typeJoin,statusJoin), 69 | FeedbackVO.class 70 | ); 71 | System.out.println(PageUtil.toPageVO(feedbackVOIPage)); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /assistant-test/src/test/java/io/github/geniusay/mysql/QueryParamGroupTest.java: -------------------------------------------------------------------------------- 1 | package io.github.geniusay.mysql; 2 | 3 | import io.github.query.QueryParamGroup; 4 | import org.junit.Test; 5 | import org.junit.runner.RunWith; 6 | import org.springframework.boot.test.context.SpringBootTest; 7 | import org.springframework.test.context.junit4.SpringRunner; 8 | import org.springframework.test.context.web.WebAppConfiguration; 9 | 10 | import javax.annotation.Resource; 11 | 12 | @RunWith(SpringRunner.class) 13 | @SpringBootTest 14 | @WebAppConfiguration 15 | public class QueryParamGroupTest { 16 | 17 | @Resource 18 | QueryParamGroup queryParamGroup; 19 | 20 | @Test 21 | public void testQueryParamGroup(){ 22 | System.out.println(queryParamGroup.getQueryParams("feedback_list", "t")); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /assistant-test/src/test/java/io/github/geniusay/service/exception/ExceptionHandlerTest.java: -------------------------------------------------------------------------------- 1 | package io.github.geniusay.service.exception; 2 | 3 | import io.github.exception.handler.CommonExceptionHandler; 4 | import org.junit.Test; 5 | import org.junit.runner.RunWith; 6 | import org.springframework.boot.test.context.SpringBootTest; 7 | import org.springframework.context.ApplicationContext; 8 | import org.springframework.test.context.junit4.SpringRunner; 9 | import org.springframework.test.context.web.WebAppConfiguration; 10 | import org.springframework.web.bind.annotation.ControllerAdvice; 11 | 12 | import javax.annotation.Resource; 13 | import java.util.Map; 14 | 15 | @RunWith(SpringRunner.class) 16 | @SpringBootTest 17 | @WebAppConfiguration 18 | public class ExceptionHandlerTest { 19 | 20 | @Resource 21 | ApplicationContext context; 22 | 23 | @Test 24 | public void testInitHandlerCondition() { 25 | Map beansWithControllerAdvice = context.getBeansWithAnnotation(ControllerAdvice.class); 26 | 27 | int numberOfControllerAdviceBeans = beansWithControllerAdvice.size(); 28 | 29 | System.out.println("Number of beans with @ControllerAdvice: " + numberOfControllerAdviceBeans); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /assistant-test/src/test/java/io/github/geniusay/service/id/IdGeneratorTest.java: -------------------------------------------------------------------------------- 1 | package io.github.geniusay.service.id; 2 | 3 | import io.github.id.IdGenerator; 4 | import io.github.id.IdGeneratorException; 5 | import io.github.id.UUIDGenerator; 6 | import io.github.id.snowflake.SnowflakeGenerator; 7 | import io.github.id.snowflake.SnowflakeRegisterException; 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | import org.springframework.boot.test.context.SpringBootTest; 11 | import org.springframework.test.context.junit4.SpringRunner; 12 | import org.springframework.test.context.web.WebAppConfiguration; 13 | 14 | import javax.annotation.Resource; 15 | 16 | @RunWith(SpringRunner.class) 17 | @SpringBootTest 18 | @WebAppConfiguration 19 | public class IdGeneratorTest { 20 | 21 | @Resource 22 | SnowflakeGenerator snowflakeGenerator; 23 | @Resource 24 | UUIDGenerator uuidGenerator; 25 | 26 | @Test 27 | public void testSnowflakeGenerator() throws IdGeneratorException { 28 | for (int i = 0; i < 100; i++) { 29 | System.out.println(snowflakeGenerator.generate()); 30 | } 31 | } 32 | 33 | @Test 34 | public void testUUIDGenerator(){ 35 | for (int i = 0; i < 100; i++) { 36 | System.out.println(uuidGenerator.generate()); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /assistant-test/src/test/java/io/github/geniusay/service/servicechain/ServiceChainTest.java: -------------------------------------------------------------------------------- 1 | package io.github.geniusay.service.servicechain; 2 | 3 | import io.github.chain.ObjectNotEmptyFilterChain; 4 | import io.github.chain.StringNotEmptyFilterChain; 5 | import io.github.common.Args; 6 | import io.github.pojo.TaskDO; 7 | import io.github.servicechain.ServiceChainFactory; 8 | import io.github.servicechain.bootstrap.ReturnType; 9 | import io.github.servicechain.bootstrap.ServiceChainBootstrap; 10 | import org.junit.Test; 11 | import org.junit.runner.RunWith; 12 | import org.springframework.boot.test.context.SpringBootTest; 13 | import org.springframework.test.context.junit4.SpringRunner; 14 | import org.springframework.test.context.web.WebAppConfiguration; 15 | 16 | import javax.annotation.Resource; 17 | import java.util.Map; 18 | 19 | @RunWith(SpringRunner.class) 20 | @SpringBootTest 21 | @WebAppConfiguration 22 | public class ServiceChainTest { 23 | 24 | @Resource 25 | private ServiceChainFactory factory; 26 | 27 | @Test 28 | public void testCommonChain(){ 29 | String str = "12345"; 30 | boolean res = factory.get("string").execute(str); 31 | } 32 | 33 | @Test 34 | public void testSupplierChain(){ 35 | TaskDO task = new TaskDO(12, "taskHello", "hello"); 36 | TaskDO empty = new TaskDO(12, "", ""); 37 | TaskDO errorTask = new TaskDO(12, "1234567890", "error"); 38 | 39 | ServiceChainBootstrap bootstrap = factory 40 | .get("task") 41 | .supplierMap(Map.of(1, TaskDO::getTaskName)); 42 | 43 | System.out.println(bootstrap.execute(task)); 44 | System.out.println(bootstrap.execute(empty)); 45 | System.out.println(bootstrap.execute(errorTask)); 46 | } 47 | 48 | @Test 49 | public void testIgnoreChain(){ 50 | TaskDO task = new TaskDO(12, "taskHello", "hello"); 51 | TaskDO empty = new TaskDO(12, "", ""); 52 | TaskDO errorTask = new TaskDO(12, "1234567890", "error"); 53 | 54 | ServiceChainBootstrap bootstrap = factory 55 | .get("ignoreTaskException") 56 | .returnType(ReturnType.THROW) 57 | .supplierMap(Map.of(1, TaskDO::getTaskName)) 58 | .failCallbackMap(Map.of( 59 | 1, () -> System.out.println("taskName is empty") 60 | )) 61 | .successCallbackMap(Map.of( 62 | 1, () -> System.out.println("taskName not empty") 63 | )); 64 | 65 | System.out.println(bootstrap.execute(task)); 66 | System.out.println(bootstrap.execute(empty)); 67 | System.out.println(bootstrap.execute(errorTask)); 68 | } 69 | 70 | @Test 71 | public void testCallbackChain(){ 72 | TaskDO task = new TaskDO(12, "taskHello", "hello"); 73 | TaskDO empty = new TaskDO(12, "", ""); 74 | TaskDO errorTask = new TaskDO(12, "1234567890", "error"); 75 | 76 | ServiceChainBootstrap bootstrap = factory 77 | .get("taskException") 78 | .returnType(ReturnType.THROW) 79 | .supplierMap(Map.of(1, TaskDO::getTaskName)); 80 | 81 | System.out.println(bootstrap.execute(task)); 82 | System.out.println(bootstrap.execute(empty)); 83 | System.out.println(bootstrap.execute(errorTask)); 84 | } 85 | 86 | @Test 87 | public void testBuildChain(){ 88 | boolean res = factory.bootstrap() 89 | .next(new ObjectNotEmptyFilterChain(), new StringNotEmptyFilterChain()) 90 | .next(factory.getChain("Exception"), true) 91 | .next(factory.getChain("taskCheck")) 92 | .supplierMap( 93 | Map.of(2, TaskDO::getTaskName) 94 | ).execute(new TaskDO(12, "taskHello", "hello")); 95 | System.out.println(res); 96 | } 97 | 98 | @Test 99 | public void testReturnResult(){ 100 | System.out.println(factory.get("getResult") 101 | .returnType(ReturnType.THROW) 102 | .supplierMap(Map.of( 103 | 1, (args) -> args.get(0), 104 | 3,(args)-> args.args() 105 | )) 106 | .executeAndReturn( 107 | Args.of("hello", "world") 108 | ) 109 | ); 110 | 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /assistant-util/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | assistant 5 | io.github.geniusay 6 | 1.1.2 7 | 8 | 4.0.0 9 | 10 | assistant-util 11 | jar 12 | ${assistant-util.version} 13 | assistant-util 14 | http://maven.apache.org 15 | 16 | 17 | UTF-8 18 | 19 | 20 | 21 | 22 | io.github.geniusay 23 | assistant-common 24 | provided 25 | 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter-web 30 | provided 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /assistant-util/src/main/java/io/github/util/ClassUtil.java: -------------------------------------------------------------------------------- 1 | package io.github.util; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.lang.reflect.Field; 6 | import java.lang.reflect.ParameterizedType; 7 | import java.lang.reflect.Type; 8 | import java.util.*; 9 | 10 | /** 11 | * Genius 12 | * 2023/07/21 09:56 13 | **/ 14 | public class ClassUtil { 15 | 16 | /** 17 | * 获得某一个包下的所有类 18 | */ 19 | public static List getClassesInPackage(String packageName)throws IOException { 20 | List classNames = new ArrayList<>(); 21 | 22 | String packagePath = packageName.replace(".", "/"); 23 | ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); 24 | 25 | var resources = classLoader.getResources(packagePath); 26 | while (resources.hasMoreElements()) { 27 | var resource = resources.nextElement(); 28 | File file = new File(resource.getFile()); 29 | if (file.isDirectory()) { 30 | scanClassesInDirectory(packageName, file, classNames); 31 | } 32 | } 33 | 34 | return classNames; 35 | } 36 | 37 | //对包名进行分割 38 | private static void scanClassesInDirectory(String packageName, File directory, List classNames) { 39 | for (File file : directory.listFiles()) { 40 | if (file.isFile()) { 41 | String className = packageName + "." + file.getName().replace(".class", ""); 42 | classNames.add(className); 43 | } else if (file.isDirectory()) { 44 | scanClassesInDirectory(packageName + "." + file.getName(), file, classNames); 45 | } 46 | } 47 | } 48 | 49 | 50 | /** 51 | * 类 to Map(浅转换,不考虑继承) 52 | * @param obj 要转换的类 53 | * @return 类对应的映射map 54 | * input:User.class(name:xxxx,age:xx) 55 | * output: (name:xxxx,age:xx) 56 | */ 57 | public static Map toMap(Object obj) throws IllegalAccessException { 58 | Map map = new HashMap<>(); 59 | Class clazz = obj.getClass(); 60 | 61 | for (Field field : clazz.getDeclaredFields()) { 62 | field.setAccessible(true); 63 | map.put(field.getName(), field.get(obj)); 64 | } 65 | 66 | return map; 67 | } 68 | 69 | /** 70 | * 类 to Map(深转换,考虑继承) 71 | * @param obj 要转换的类 72 | * @return 类对应的映射map 73 | * input:User.class(name:xxxx,age:xx) 74 | * output: (name:xxxx,age:xx) 75 | */ 76 | public static Map toDeepMap(Object obj) throws IllegalAccessException { 77 | Map map = new HashMap<>(); 78 | Class clazz = obj.getClass(); 79 | 80 | // 获取当前类的字段 81 | for (Field field : clazz.getDeclaredFields()) { 82 | field.setAccessible(true); 83 | map.put(field.getName(), field.get(obj)); 84 | } 85 | 86 | // 如果有父类且不是 Object 类,递归调用获取父类的字段 87 | Class superClass = clazz.getSuperclass(); 88 | if (superClass != null && !superClass.equals(Object.class)) { 89 | try { 90 | Object superObj = superClass.getDeclaredConstructor().newInstance(); 91 | copyFields(superObj, obj, superClass); 92 | map.putAll(toDeepMap(superObj)); 93 | } catch (Exception e) { 94 | e.printStackTrace(); 95 | } 96 | } 97 | 98 | return map; 99 | } 100 | 101 | private static void copyFields(Object dest, Object source, Class clazz) throws IllegalAccessException { 102 | for (Field field : clazz.getDeclaredFields()) { 103 | field.setAccessible(true); 104 | Field destField; 105 | try { 106 | destField = dest.getClass().getDeclaredField(field.getName()); 107 | destField.setAccessible(true); 108 | destField.set(dest, field.get(source)); 109 | } catch (NoSuchFieldException e) { 110 | // 忽略字段不存在的异常 111 | } 112 | } 113 | } 114 | 115 | } 116 | -------------------------------------------------------------------------------- /assistant-util/src/main/java/io/github/util/GenericityUtils.java: -------------------------------------------------------------------------------- 1 | package io.github.util; 2 | 3 | /** 4 | * Genius 5 | **/ 6 | // 泛型工具类 7 | public class GenericityUtils { 8 | 9 | // 判断对象是否是某个类的实例 10 | public static boolean instanceofFunc(Object obj,Class b){ 11 | boolean result; 12 | if (obj == null) { 13 | result = false; 14 | } else { 15 | try { 16 | T temp=b.cast(obj); 17 | // T temp= (T) obj; // checkcast 18 | result = true; 19 | } catch (ClassCastException e) { 20 | result = false; 21 | } 22 | } 23 | return result; 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /assistant-util/src/main/java/io/github/util/StringUtils.java: -------------------------------------------------------------------------------- 1 | package io.github.util; 2 | 3 | /** 4 | * Genius 5 | * 6 | **/ 7 | 8 | /* 9 | * 字符串工具类 10 | */ 11 | public class StringUtils extends org.springframework.util.StringUtils { 12 | 13 | 14 | /* 去除操作 */ 15 | //去除小括号包括其中的内容 16 | public static String removeParentheses(String str){ 17 | return str.replaceAll("\\(.*\\)","").trim(); 18 | } 19 | 20 | //去除大括号包括其中的内容 21 | public static String removeBraces(String str){ 22 | return str.replaceAll("\\{.*\\}","").trim(); 23 | } 24 | 25 | //去除中括号包括其中的内容 26 | public static String removeBrackets(String str){ 27 | return str.replaceAll("\\[.*\\]","").trim(); 28 | } 29 | 30 | //去除双引号 31 | public static String removeDoubleQuotes(String str){ 32 | return str.replaceAll("\"","").trim(); 33 | } 34 | 35 | //去除单引号 36 | public static String removeSingleQuotes(String str){ 37 | return str.replaceAll("'","").trim(); 38 | } 39 | 40 | //去除尖括号包括其中的内容 41 | public static String removeAngleBrackets(String str){ 42 | return str.replaceAll("<.*>","").trim(); 43 | } 44 | 45 | //去除小括号不包括其中的内容 46 | public static String removeParenthesesNotContent(String str){ 47 | return str.replaceAll("\\(|\\)", "").trim(); 48 | } 49 | 50 | //去除大括号不包括其中的内容 51 | public static String removeBracesNotContent(String str){ 52 | return str.replaceAll("\\{|\\}", "").trim(); 53 | } 54 | 55 | //去除中括号不包括其中的内容 56 | public static String removeBracketsNotContent(String str){ 57 | return str.replaceAll("\\[|\\]", "").trim(); 58 | } 59 | 60 | //去除空格 61 | public static String removeSpace(String str){ 62 | return str.replaceAll(" ","").trim(); 63 | } 64 | 65 | //去除双斜线 66 | public static String removeDoubleSlash(String str){ 67 | return str.replaceAll("//","").trim(); 68 | } 69 | 70 | //去除双反斜线 71 | public static String removeDoubleBackslash(String str){ 72 | return str.replaceAll("\\\\","").trim(); 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /assistant-util/src/main/java/io/github/util/autochecker/AutoChecker.java: -------------------------------------------------------------------------------- 1 | package io.github.util.autochecker; 2 | 3 | 4 | import io.github.util.regex.RegexPool; 5 | import io.github.util.regex.RegexUtils; 6 | import org.springframework.stereotype.Component; 7 | 8 | import java.util.HashMap; 9 | import java.util.Map; 10 | 11 | 12 | /** 13 | * 自动检查器 14 | */ 15 | @Component 16 | public class AutoChecker { 17 | 18 | //检查参数是否符合要求,传入类型和Checker接口 19 | public static boolean check(Map> params){ 20 | for (Map.Entry> entry : params.entrySet()) { 21 | if (!entry.getValue().goCheck(entry.getKey())) { 22 | return false; 23 | } 24 | } 25 | return true; 26 | } 27 | 28 | //检查参数是否符合要求,传入类型和正则表达式 29 | public static boolean checkByRegex(Map params){ 30 | for (Map.Entry entry : params.entrySet()) { 31 | if (!RegexUtils.VerifyRegex(entry.getKey(),entry.getValue())) { 32 | return false; 33 | } 34 | } 35 | return true; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /assistant-util/src/main/java/io/github/util/autochecker/Checker.java: -------------------------------------------------------------------------------- 1 | package io.github.util.autochecker; 2 | 3 | @FunctionalInterface 4 | public interface Checker { 5 | boolean goCheck(T obj); 6 | } 7 | -------------------------------------------------------------------------------- /assistant-util/src/main/java/io/github/util/collection/map/MapNode.java: -------------------------------------------------------------------------------- 1 | package io.github.util.collection.map; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class MapNode { 7 | 8 | private T data; 9 | 10 | private final List> linkNode; 11 | 12 | public MapNode(T data, List> linkNode) { 13 | this.data = data; 14 | this.linkNode = linkNode; 15 | } 16 | 17 | public MapNode(T data) { 18 | this.data = data; 19 | this.linkNode = new ArrayList<>(); 20 | } 21 | 22 | public T getData() { 23 | return data; 24 | } 25 | 26 | public List> getLinkNode() { 27 | return linkNode; 28 | } 29 | 30 | public void addLinkNode(MapNode node){ 31 | linkNode.add(node); 32 | } 33 | 34 | public void setData(T data) { 35 | this.data = data; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /assistant-util/src/main/java/io/github/util/collection/map/WeightMapNode.java: -------------------------------------------------------------------------------- 1 | package io.github.util.collection.map; 2 | 3 | import java.util.List; 4 | 5 | public class WeightMapNode extends MapNode{ 6 | 7 | private long weight; 8 | 9 | public interface WeightCompute{ 10 | long weight(); 11 | } 12 | 13 | private WeightCompute weightCompute; 14 | 15 | private final WeightCompute DEFAULT_COMPUTE = ()-> this.weight; 16 | 17 | public WeightMapNode(long weight, T data, List> linkNode) { 18 | super(data, linkNode); 19 | this.weight = weight; 20 | this.weightCompute = DEFAULT_COMPUTE; 21 | } 22 | 23 | public WeightMapNode(T data, long weight) { 24 | super(data); 25 | this.weight = weight; 26 | this.weightCompute = DEFAULT_COMPUTE; 27 | } 28 | 29 | public WeightMapNode(T data, long weight, WeightCompute weightCompute) { 30 | super(data); 31 | this.weight = weight; 32 | this.weightCompute = weightCompute; 33 | } 34 | 35 | public WeightMapNode(T data, WeightCompute weightCompute) { 36 | super(data); 37 | this.weight = 0; 38 | this.weightCompute = weightCompute; 39 | } 40 | 41 | public WeightMapNode(T data) { 42 | super(data); 43 | this.weight = 0; 44 | this.weightCompute = DEFAULT_COMPUTE; 45 | } 46 | 47 | public long getWeight() { 48 | return weightCompute.weight(); 49 | } 50 | 51 | public void setWeight(long weight) { 52 | this.weight = weight; 53 | } 54 | 55 | public void setWeightCompute(WeightCompute weightCompute) { 56 | this.weightCompute = weightCompute; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /assistant-util/src/main/java/io/github/util/collection/map/dag/WorkWeightMapNode.java: -------------------------------------------------------------------------------- 1 | package io.github.util.collection.map.dag; 2 | 3 | import io.github.util.collection.map.MapNode; 4 | import io.github.util.collection.map.WeightMapNode; 5 | 6 | import java.util.List; 7 | import java.util.concurrent.locks.ReentrantLock; 8 | 9 | /** 10 | * 工作图节点 11 | */ 12 | public class WorkWeightMapNode extends WeightMapNode { 13 | 14 | 15 | public interface WorkHandler{ 16 | Object work(Object data); 17 | } 18 | 19 | private static final int NONE = 0; 20 | private static final int READY = 1; 21 | private static final int WORKING = 0x02; 22 | 23 | private static final int WAITING = 0x04; 24 | private static final int COMPLETING = 0x08; 25 | private static final int ERROR = 0x10; 26 | private static final WorkHandler DEFAULT = (obj)-> null; 27 | 28 | private WorkHandler workHandler = DEFAULT; 29 | 30 | private volatile int workStatus = NONE; 31 | 32 | private final ReentrantLock workLock = new ReentrantLock(); 33 | 34 | public WorkWeightMapNode(long weight, T data, List> linkNode) { 35 | super(weight, data, linkNode); 36 | } 37 | 38 | public WorkWeightMapNode(T data, long weight) { 39 | super(data, weight); 40 | } 41 | 42 | public WorkWeightMapNode(T data, WeightMapNode.WeightCompute weightCompute, WorkHandler workHandler) { 43 | super(data, weightCompute); 44 | this.workHandler = workHandler; 45 | } 46 | 47 | public WorkWeightMapNode(T data, WorkHandler workHandler) { 48 | super(data); 49 | this.workHandler = workHandler; 50 | } 51 | 52 | public WorkWeightMapNode(T data) { 53 | super(data); 54 | } 55 | 56 | public void setWorkHandler(WorkHandler workHandler) { 57 | this.workHandler = workHandler; 58 | } 59 | 60 | public int getWorkStatus() { 61 | return workStatus; 62 | } 63 | 64 | public void setWorkStatus(int workStatus){ 65 | if(workStatus>ERROR || workStatus>1)&0x5555); 73 | x = (x&0x3333)+((x>>2)&0x3333); 74 | x = (x&0x0f0f)+((x>>4)&0x0f0f); 75 | x = (x&0x00ff)+((x>>8)&0x00ff); 76 | return x; 77 | } 78 | 79 | 80 | public Object work(Object obj){ 81 | if(equalsStatus(READY)){ 82 | try { 83 | workLock.lock(); 84 | if(equalsStatus(READY)){ 85 | this.workStatus = WORKING; 86 | Object res = workHandler.work(obj); 87 | this.workStatus = COMPLETING; 88 | return res; 89 | } 90 | }catch (Exception e){ 91 | this.workStatus = ERROR; 92 | throw e; 93 | }finally { 94 | workLock.unlock(); 95 | } 96 | } 97 | throw new RuntimeException("The node status must be ready to run"); 98 | } 99 | 100 | private boolean equalsStatus(int status){ 101 | return (this.workStatus & status)!=0; 102 | } 103 | 104 | public static void main(String[] args) { 105 | System.out.println(pop_count(3)); 106 | System.out.println(pop_count(2)); 107 | System.out.println(pop_count(37)); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /assistant-util/src/main/java/io/github/util/convert/ZhConvertUtil.java: -------------------------------------------------------------------------------- 1 | package io.github.util.convert; 2 | 3 | /** 4 | * Genius 5 | * 2023/10/28 02:58 6 | **/ 7 | public class ZhConvertUtil { 8 | 9 | /** 10 | * 中文数字单位转Int 11 | * @param zhNumber 例如(3以) 12 | * @return 13 | */ 14 | public static int zhNumericUnitsToInt(String zhNumber){ 15 | String[] parts = zhNumber.split("(?<=\\d\\.\\d)(?=\\D)"); 16 | if(parts.length==2){ 17 | float num = Float.parseFloat(parts[0]); 18 | switch (parts[1]){ 19 | case "亿": 20 | return (int)num*100000; 21 | case "万": 22 | return (int)num*10000; 23 | case "千": 24 | return (int)num*1000; 25 | case "百": 26 | return (int)num*100; 27 | case "个": 28 | return (int)num; 29 | } 30 | } 31 | return Integer.parseInt(zhNumber); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /assistant-util/src/main/java/io/github/util/encryption/AESEncryptionUtils.java: -------------------------------------------------------------------------------- 1 | package io.github.util.encryption; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | import org.springframework.stereotype.Component; 7 | 8 | import javax.crypto.Cipher; 9 | import javax.crypto.KeyGenerator; 10 | import javax.crypto.SecretKey; 11 | import java.nio.charset.Charset; 12 | import java.security.NoSuchAlgorithmException; 13 | import java.security.SecureRandom; 14 | 15 | /** 16 | * Genius 17 | 18 | **/ 19 | 20 | @Data 21 | @Component 22 | @NoArgsConstructor 23 | @AllArgsConstructor 24 | public class AESEncryptionUtils implements EncryptionUtil{ 25 | 26 | public static final String ALGORITHM = "AES"; 27 | 28 | private SecretKey secretKey; 29 | 30 | /** 31 | * 生成密钥 32 | * 33 | * @return 34 | * @throws NoSuchAlgorithmException 35 | */ 36 | public SecretKey generateKey() throws NoSuchAlgorithmException { 37 | KeyGenerator secretGenerator = KeyGenerator.getInstance(ALGORITHM); 38 | SecureRandom secureRandom = new SecureRandom(); 39 | secretGenerator.init(secureRandom); 40 | SecretKey secretKey = secretGenerator.generateKey(); 41 | return secretKey; 42 | } 43 | 44 | private Charset charset = Charset.forName("UTF-8"); 45 | 46 | 47 | private byte[] aes(byte[] contentArray, int mode, SecretKey secretKey) throws Exception { 48 | Cipher cipher = Cipher.getInstance(ALGORITHM); 49 | cipher.init(mode, secretKey); 50 | byte[] result = cipher.doFinal(contentArray); 51 | return result; 52 | } 53 | 54 | @Override 55 | public String Encipher(String password) throws Exception { 56 | if(secretKey == null) 57 | throw new RuntimeException("SecretKey is null, please generate a SecretKey first"); 58 | return new String(aes(password.getBytes(charset), Cipher.ENCRYPT_MODE, secretKey),charset); 59 | } 60 | 61 | @Override 62 | public String Decrypt(String password) throws Exception { 63 | if(secretKey == null) 64 | throw new RuntimeException("SecretKey is null, please generate a SecretKey first"); 65 | byte[] result = aes(password.getBytes(), Cipher.DECRYPT_MODE, secretKey); 66 | return new String(result, charset); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /assistant-util/src/main/java/io/github/util/encryption/Base64EncryptionUtils.java: -------------------------------------------------------------------------------- 1 | package io.github.util.encryption; 2 | 3 | 4 | import io.github.util.file.CommonFileUtils; 5 | import io.github.util.path.PathUtils; 6 | import org.apache.tomcat.util.codec.binary.Base64; 7 | import org.apache.tomcat.util.http.fileupload.FileUtils; 8 | import org.springframework.boot.system.ApplicationHome; 9 | import org.springframework.stereotype.Component; 10 | import org.springframework.util.Base64Utils; 11 | 12 | import java.io.*; 13 | import java.nio.charset.StandardCharsets; 14 | 15 | /** 16 | * Genius 17 | 18 | **/ 19 | 20 | /* 21 | * Base64加密 22 | */ 23 | @Component 24 | public class Base64EncryptionUtils implements EncryptionUtil { 25 | 26 | @Override 27 | public String Encipher(String password) { 28 | try { 29 | return Base64Utils.encodeToString(password.getBytes(StandardCharsets.UTF_8)); 30 | } catch (Exception e) { 31 | e.printStackTrace(); 32 | } 33 | return password; 34 | } 35 | 36 | @Override 37 | public String Decrypt(String cipher) { 38 | try { 39 | byte[] bytes = Base64Utils.decodeFromString(cipher); 40 | return new String(bytes, StandardCharsets.UTF_8); 41 | }catch (Exception e){ 42 | e.printStackTrace(); 43 | } 44 | return cipher; 45 | } 46 | 47 | /** 48 | * 将图片转换成Base64编码的字符串 49 | * 50 | * @param imgPath 51 | * @return 52 | */ 53 | public String getImageStr(String imgPath) { 54 | InputStream in = null; 55 | byte[] data = null; 56 | String encode = null; 57 | // 对字节数组Base64编码 58 | try { 59 | // 读取图片字节数组 60 | in = new FileInputStream(imgPath); 61 | data = new byte[in.available()]; 62 | in.read(data); 63 | encode = Base64.encodeBase64String(data); 64 | } catch (IOException e) { 65 | e.printStackTrace(); 66 | } finally { 67 | try { 68 | in.close(); 69 | } catch (IOException e) { 70 | e.printStackTrace(); 71 | } 72 | } 73 | return encode; 74 | } 75 | 76 | /** 77 | * 将Base64编码的字符串转换成图片 78 | * 79 | * @param imgData 图片编码 80 | * @param fileName 图片名称 81 | * @return 82 | */ 83 | public String generateImage(String imgData, String fileName) { 84 | if (imgData == null) { 85 | // 图像数据为空 86 | return "null"; 87 | } 88 | ApplicationHome applicationHome = new ApplicationHome(FileUtils.class); 89 | File source = applicationHome.getSource(); 90 | String dirPath = source.getParentFile().toString() + "/upload"; 91 | 92 | File dir = CommonFileUtils.createFile(dirPath); 93 | if (!dir.exists()){ 94 | dir.mkdirs(); 95 | } 96 | File file = CommonFileUtils.createFile(PathUtils.smartFilePath(dirPath, fileName)); 97 | if (file.exists()){ 98 | file.delete(); 99 | } 100 | try { 101 | // Base64解码 102 | byte[] b = Base64.decodeBase64(imgData); 103 | for (int i = 0; i < b.length; ++i) { 104 | // 调整异常数据 105 | if (b[i] < 0) { 106 | b[i] += 256; 107 | } 108 | } 109 | OutputStream out = new FileOutputStream(PathUtils.smartFilePath(dirPath, fileName)); 110 | out.write(b); 111 | out.flush(); 112 | out.close(); 113 | return PathUtils.smartFilePath(dirPath, fileName); 114 | } catch (Exception e) { 115 | e.printStackTrace(); 116 | return "null"; 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /assistant-util/src/main/java/io/github/util/encryption/DESEncryptionUtils.java: -------------------------------------------------------------------------------- 1 | package io.github.util.encryption; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | import org.springframework.stereotype.Component; 7 | 8 | import javax.crypto.Cipher; 9 | import javax.crypto.SecretKey; 10 | import javax.crypto.SecretKeyFactory; 11 | import javax.crypto.spec.DESKeySpec; 12 | import java.security.SecureRandom; 13 | 14 | /** 15 | * Genius 16 | 17 | **/ 18 | @Data 19 | @Component 20 | @AllArgsConstructor 21 | @NoArgsConstructor 22 | public class DESEncryptionUtils implements EncryptionUtil { 23 | 24 | 25 | public String key = "12345678"; 26 | 27 | 28 | @Override 29 | public String Encipher(String password) throws Exception { 30 | try{ 31 | SecureRandom random = new SecureRandom(); 32 | DESKeySpec desKey = new DESKeySpec(key.getBytes()); 33 | //创建一个密匙工厂,然后用它把DESKeySpec转换成 34 | SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); 35 | SecretKey securekey = keyFactory.generateSecret(desKey); 36 | //Cipher对象实际完成加密操作 37 | Cipher cipher = Cipher.getInstance("DES"); 38 | //用密匙初始化Cipher对象 39 | cipher.init(Cipher.ENCRYPT_MODE, securekey, random); 40 | //现在,获取数据并加密 41 | //正式执行加密操作 42 | return new String(cipher.doFinal(password.getBytes())); 43 | }catch(Throwable e){ 44 | e.printStackTrace(); 45 | } 46 | return null; 47 | } 48 | 49 | @Override 50 | public String Decrypt(String password) throws Exception { 51 | // DES算法要求有一个可信任的随机数源 52 | SecureRandom random = new SecureRandom(); 53 | // 创建一个DESKeySpec对象 54 | DESKeySpec desKey = new DESKeySpec(key.getBytes()); 55 | // 创建一个密匙工厂 56 | SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); 57 | // 将DESKeySpec对象转换成SecretKey对象 58 | SecretKey securekey = keyFactory.generateSecret(desKey); 59 | // Cipher对象实际完成解密操作 60 | Cipher cipher = Cipher.getInstance("DES"); 61 | // 用密匙初始化Cipher对象 62 | cipher.init(Cipher.DECRYPT_MODE, securekey, random); 63 | // 真正开始解密操作 64 | return new String(cipher.doFinal(password.getBytes())); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /assistant-util/src/main/java/io/github/util/encryption/EncryptionFactory.java: -------------------------------------------------------------------------------- 1 | package io.github.util.encryption; 2 | 3 | import java.util.Map; 4 | import java.util.concurrent.ConcurrentHashMap; 5 | 6 | /** 7 | * Genius 8 | 9 | **/ 10 | /* 11 | * 加密工具工厂 12 | */ 13 | public class EncryptionFactory { 14 | 15 | //需要优化 16 | private static ConcurrentHashMap encryptionUtilMap = new ConcurrentHashMap<>( 17 | Map.of( 18 | EncryptionType.MD5.toString(),new MD5EncryptionUtils(), 19 | EncryptionType.RSA.toString(),new RSAEncryptionUtils(), 20 | EncryptionType.AES.toString(),new AESEncryptionUtils(), 21 | EncryptionType.DES.toString(),new DESEncryptionUtils(), 22 | EncryptionType.Base64.toString(),new Base64EncryptionUtils() 23 | ) 24 | ); 25 | 26 | public static EncryptionUtil getEncryptionUtil(EncryptionType type){ 27 | return getEncryptionUtil(type.toString()); 28 | } 29 | 30 | public static EncryptionUtil getEncryptionUtil(String type){ 31 | if(!encryptionUtilMap.containsKey(type)) 32 | throw new RuntimeException("EncryptionUtil not found"); 33 | return encryptionUtilMap.get(type); 34 | } 35 | 36 | //添加加密工具 37 | public static void add(String type,EncryptionUtil encryptionUtil){ 38 | encryptionUtilMap.put(type,encryptionUtil); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /assistant-util/src/main/java/io/github/util/encryption/EncryptionType.java: -------------------------------------------------------------------------------- 1 | package io.github.util.encryption; 2 | 3 | /** 4 | * Genius 5 | 6 | **/ 7 | public enum EncryptionType { 8 | MD5, 9 | Base64, 10 | DES, 11 | AES, 12 | RSA, 13 | } 14 | -------------------------------------------------------------------------------- /assistant-util/src/main/java/io/github/util/encryption/EncryptionUtil.java: -------------------------------------------------------------------------------- 1 | package io.github.util.encryption; 2 | 3 | public interface EncryptionUtil { 4 | String Encipher(String password) throws Exception; 5 | String Decrypt(String password) throws Exception; 6 | } 7 | -------------------------------------------------------------------------------- /assistant-util/src/main/java/io/github/util/encryption/MD5EncryptionUtils.java: -------------------------------------------------------------------------------- 1 | package io.github.util.encryption; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | import java.security.MessageDigest; 6 | import java.security.NoSuchAlgorithmException; 7 | 8 | /** 9 | * Genius 10 | 11 | **/ 12 | 13 | /*Md5加密工具类*/ 14 | @Component 15 | public class MD5EncryptionUtils implements EncryptionUtil { 16 | 17 | private final static char HexChars[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', 18 | '9', 'a', 'b', 'c', 'd', 'e', 'f' }; 19 | 20 | public String Encipher(String password) { 21 | byte[] bytes = password.getBytes(); 22 | try { 23 | MessageDigest md = MessageDigest.getInstance("MD5"); 24 | md.update(bytes); 25 | bytes = md.digest(); 26 | int j = bytes.length; 27 | char[] chars = new char[j * 2]; 28 | int k = 0; 29 | for (int i = 0; i < bytes.length; i++) { 30 | byte b = bytes[i]; 31 | chars[k++] = HexChars[b >>> 4 & 0xf]; 32 | chars[k++] = HexChars[b & 0xf]; 33 | } 34 | return new String(chars); 35 | } catch (NoSuchAlgorithmException e) { 36 | e.printStackTrace(); 37 | throw new RuntimeException("MD5加密出错!!+" + e); 38 | 39 | } 40 | } 41 | 42 | @Override 43 | public String Decrypt(String password) { 44 | return password; 45 | } 46 | } 47 | 48 | -------------------------------------------------------------------------------- /assistant-util/src/main/java/io/github/util/file/FileCondition.java: -------------------------------------------------------------------------------- 1 | package io.github.util.file; 2 | 3 | import java.nio.file.Path; 4 | 5 | @FunctionalInterface 6 | public interface FileCondition { 7 | boolean condition(Path path); 8 | } 9 | -------------------------------------------------------------------------------- /assistant-util/src/main/java/io/github/util/path/PathUtils.java: -------------------------------------------------------------------------------- 1 | package io.github.util.path; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | import java.io.File; 6 | 7 | /** 8 | * Genius 9 | **/ 10 | 11 | /* 12 | * 路径工具类 13 | * 目前可以适配linux的文件路径拼接 14 | */ 15 | @Component 16 | public class PathUtils { 17 | //获取当前项目的路径 18 | public static String getProjectPath() { 19 | return System.getProperty("user.dir"); 20 | } 21 | 22 | //组装文件路径,适配Linux和Windows,无需在意paths的格式错误,自动为了修正格式 23 | // TODO需要优化算法 24 | public static String smartFilePath(String... paths) { 25 | return smartFilePath(File.separatorChar, paths); 26 | } 27 | 28 | public static String smartFilePath(char type,String...paths){ 29 | StringBuilder sb = new StringBuilder(); 30 | String separator = String.valueOf(type); 31 | String replace = separator.equals("\\") ? "/" : "\\"; 32 | for (String path : paths) { 33 | path = path.replace(replace, separator); 34 | if (!path.contains(".")&&!path.endsWith(separator)) { 35 | path = path + separator; 36 | } 37 | if (path.startsWith(separator)) { 38 | path = path.substring(1); 39 | } 40 | sb.append(path); 41 | } 42 | String res = sb.toString(); 43 | //将多个分隔符替换为一个分隔符 44 | if(separator.equals("\\")) 45 | res = res.replaceAll("\\\\+", "\\\\"); 46 | else 47 | res = res.replaceAll("\\/+", "\\/"); 48 | 49 | return res.startsWith(separator) ? res : separator + res; 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /assistant-util/src/main/java/io/github/util/random/SnowflakeUtils.java: -------------------------------------------------------------------------------- 1 | package io.github.util.random; 2 | 3 | import io.github.util.time.TimeUtil; 4 | 5 | import java.time.LocalDateTime; 6 | 7 | /** 8 | * 雪花算法随机数生成器 9 | */ 10 | public class SnowflakeUtils { 11 | 12 | 13 | /** 14 | * 生成一个雪花ID 15 | * @param epoch //起始时间戳 16 | * @return long 雪花ID 17 | */ 18 | public static long snowflakeId(long epoch){ 19 | long timestamp = System.currentTimeMillis(); 20 | return ((timestamp - epoch) << 42); 21 | } 22 | 23 | /** 24 | * 生成一个雪花ID 25 | * @param timestamp //当前时间戳 26 | * @param epoch //起始时间戳 27 | * @param timestamp_left_shift //时间戳左移位数 28 | * @param sequence //序列号 29 | * @return long 雪花ID 30 | */ 31 | public static long snowflakeId(long timestamp,long epoch,long timestamp_left_shift,long sequence){ 32 | return ((timestamp - epoch) << timestamp_left_shift) 33 | | sequence; 34 | } 35 | 36 | 37 | /** 38 | * 生成一个雪花ID(包含数据中心ID和机器ID) 39 | * @param timestamp //当前时间戳 40 | * @param epoch //起始时间戳 41 | * @param workerId //机器ID 42 | * @param dataCenterId //数据中心ID 43 | * @param timestamp_left_shift //时间戳左移位数 44 | * @param data_center_id_shift //数据中心ID左移位数 45 | * @param worker_id_shift //机器ID左移位数 46 | * @param sequence //序列号 47 | * @return long 雪花ID 48 | */ 49 | public static long snowflakeId(long timestamp,long epoch,long workerId,long dataCenterId 50 | ,long timestamp_left_shift,long data_center_id_shift,long worker_id_shift,long sequence){ 51 | return ((timestamp - epoch) << timestamp_left_shift) 52 | | (dataCenterId << data_center_id_shift) 53 | | (workerId << worker_id_shift) 54 | | sequence; 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /assistant-util/src/main/java/io/github/util/random/UUIDGeneratorUtils.java: -------------------------------------------------------------------------------- 1 | package io.github.util.random; 2 | 3 | import java.util.UUID; 4 | 5 | public class UUIDGeneratorUtils { 6 | 7 | public static String uuid(){ 8 | return UUID.randomUUID().toString(); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /assistant-util/src/main/java/io/github/util/regex/RegexPattern.java: -------------------------------------------------------------------------------- 1 | package io.github.util.regex; 2 | 3 | /** 4 | * Genius 5 | 6 | **/ 7 | 8 | /** 9 | * 正则表达式静态类 10 | */ 11 | public class RegexPattern { 12 | 13 | /** 14 | * 用户信息的一些基本表达式 15 | */ 16 | public final static String EMAIL = "^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$"; //邮箱 17 | public final static String PHONE = "^1[3|4|5|7|8][0-9]\\d{8}$"; //手机号 18 | 19 | public final static String STRICT_PHONE = "^(?:(?:\\+|00)86)?1(?:(?:3[\\d])|(?:4[5-79])|" + 20 | "(?:5[0-35-9])|(?:6[5-7])|(?:7[0-8])|(?:8[\\d])|(?:9[189]))\\d{8}$"; //严格手机号(根据工信部规定) 21 | 22 | public final static String TEL_PHONE = "^(?:(?:\\d{3}-)?\\d{8}|^(?:\\d{4}-)" + 23 | "?\\d{7,8})(?:-\\d+)?$"; //座机(CHINA) 24 | public final static String QQ = "^[1-9][0-9]{4,10}$"; //QQ号从10000开始 25 | public final static String PASSWORD = "^[a-zA-Z0-9_-]{6,16}$"; //密码 26 | 27 | public final static String ID_CARD = "^[1-9]\\d{7}(?:0\\d|10|11|12)" + 28 | "(?:0[1-9]|[1-2][\\d]|30|31)\\d{3}$"; //1代身份证 29 | public final static String ID_CARD2 = "(^\\d{15}$)|(^\\d{18}$)|(^\\d{17}(\\d|X|x)$)"; //2代身份证 30 | 31 | public final static String USERNAME = "^[a-zA-Z0-9_-]{4,16}$"; //用户名 32 | 33 | public final static String NICKNAME = "^[a-zA-Z0-9_-]{4,16}$"; //昵称 34 | 35 | //护照 36 | public final static String PASSPORT = "(^[EeKkGgDdSsPpHh]\\d{8}$)|(^(([Ee][a-fA-F])" + 37 | "|([DdSsPp][Ee])|([Kk][Jj])|([Mm][Aa])|(1[45]))\\d{7}$)"; //护照 38 | 39 | /** 40 | * 以下为中文、字母、数字相关的正则表达式 41 | */ 42 | public final static String CHINESE = "[\\u4e00-\\u9fa5]"; //中文 43 | public final static String NUMBER = "^[0-9]*$"; //数字 44 | public final static String LETTER = "^[A-Za-z]+$"; //字母 45 | public final static String CHINESE_LETTER = "^[A-Za-z\\u4e00-\\u9fa5]+$"; //中文和字母 46 | public final static String CHINESE_LETTER_NUMBER = "^[A-Za-z0-9\\u4e00-\\u9fa5]+$"; //中文和字母和数字 47 | public final static String CHINESE_NAME = "^[\\u4e00-\\u9fa5]{2,4}$"; //中文姓名 48 | 49 | /** 50 | * 以下为日期和时间相关的正则表达式 51 | */ 52 | public final static String DATE = "^(\\d{4})-(\\d{2})-(\\d{2})$"; //日期 53 | public final static String TIME = "^(\\d{2}):(\\d{2}):(\\d{2})$"; //时间 54 | public final static String DATE_TIME = "^(\\d{4})-(\\d{2})-(\\d{2}) (\\d{2}):(\\d{2}):(\\d{2})$"; //日期和时间 55 | public final static String DATE_TIME_MILLS = "^(\\d{4})-(\\d{2})-(\\d{2}) (\\d{2}):(\\d{2}):(\\d{2})\\.(\\d{3})$"; //日期和时间和毫秒 56 | 57 | /** 58 | * 以下为文件相关的正则表达式 59 | */ 60 | public final static String FILE_NAME = "^[^\\\\/:*?\"<>|]+$"; //文件名 61 | public final static String FILE_PATH = "^[^\\*\\?\"<>|]+$"; //文件路径 62 | public final static String LINUX_PATH = "^(/[^/]+)+$"; //Linux路径 63 | public final static String WINDOWS_PATH = "^([a-zA-Z]:\\\\[^\\\\/:*?\"<>|]+)+$"; //Windows路径 64 | 65 | /** 66 | * 以下为URL相关的正则表达式 67 | */ 68 | public final static String URL = "^(https|http)://([\\w-]+\\.)+[\\w-]+(/[\\w- ./?%&=]*)?$"; //URL 69 | public final static String URL_PORT = "^(https|http)://([\\w-]+\\.)+[\\w-]+(:[\\d]{1,5})?(/[\\w- ./?%&=]*)?$"; //带端口号的URL 70 | public final static String IP = "((25[0-5]|2[0-4]\\d|((1\\d{2})|([1-9]?\\d)))\\.){3}(25[0-5]|2[0-4]\\d|((1\\d{2})|([1-9]?\\d)))"; //IP 71 | 72 | /** 73 | * 以下为其他相关的正则表达式 74 | */ 75 | public final static String COLOR = "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})$"; //颜色 76 | public final static String HTML = "<(\\S*?)[^>]*>.*?|<.*? />"; //HTML标记 77 | public final static String CAR_ID = "^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-HJ-NP-Z][A-HJ-NP-Z0-9]{4,5}[A-HJ-NP-Z0-9挂学警港澳]$"; //车牌号(新能源+非新能源) 78 | 79 | public final static String PROVINCE = "^(北京市|天津市|河北省|山西省|内蒙古自治区|辽宁省|吉林省|黑龙江省|上海市|江苏省|浙江省" + 80 | "|安徽省|福建省|江西省|山东省|河南省|湖北省|湖南省|广东省|广西壮族自治区|海南省|重庆市|四川省" + 81 | "|贵州省|云南省|西藏自治区|陕西省|甘肃省|青海省|宁夏回族自治区|新疆维吾尔自治区|台湾省|香港特别行政区|澳门特别行政区)$"; //中国省 82 | } 83 | -------------------------------------------------------------------------------- /assistant-util/src/main/java/io/github/util/regex/RegexPool.java: -------------------------------------------------------------------------------- 1 | package io.github.util.regex; 2 | 3 | import lombok.Data; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | import org.springframework.stereotype.Component; 6 | 7 | /** 8 | * Genius 9 | 10 | **/ 11 | @Data 12 | @Component 13 | @ConfigurationProperties(prefix = "assistant.regex.pool") 14 | public class RegexPool { 15 | /** 16 | * 用户信息的一些基本表达式 17 | */ 18 | private String email = RegexPattern.EMAIL; //邮箱 19 | private String phone = RegexPattern.PHONE; //手机号 20 | private String strictPhone = RegexPattern.STRICT_PHONE; //严格的手机号 21 | private String telPhone = RegexPattern.TEL_PHONE; //手机号或者座机号 22 | private String qq = RegexPattern.QQ; //QQ号从10000开始 23 | private String password = RegexPattern.PASSWORD; //密码 24 | private String idCard = RegexPattern.ID_CARD; //身份证 25 | private String idCard2 = RegexPattern.ID_CARD2; //二代居民身份证 26 | private String username = RegexPattern.USERNAME; //用户名 27 | private String nickname = RegexPattern.NICKNAME; //昵称 28 | private String passPort = RegexPattern.PASSPORT; //护照 29 | 30 | /** 31 | * 以下为中文、字母、数字相关的正则表达式 32 | */ 33 | private String chinese = RegexPattern.CHINESE; //中文 34 | private String number = RegexPattern.NUMBER; //数字 35 | private String letter = RegexPattern.LETTER; //字母 36 | private String chineseLetter = RegexPattern.CHINESE_LETTER; //中文和字母 37 | private String chineseLetterNumber = RegexPattern.CHINESE_LETTER_NUMBER; //中文和字母和数字 38 | private String chineseName = RegexPattern.CHINESE_NAME; //中文姓名 39 | 40 | /** 41 | * 以下为日期和时间相关的正则表达式 42 | */ 43 | private String date = RegexPattern.DATE; //日期 44 | private String time = RegexPattern.TIME; //时间 45 | private String dateTime = RegexPattern.DATE_TIME; //日期和时间 46 | private String dateTimeMills = RegexPattern.DATE_TIME_MILLS; //日期和时间和毫秒 47 | 48 | /** 49 | * 以下为文件相关的正则表达式 50 | */ 51 | private String fileName = RegexPattern.FILE_NAME; //文件名 52 | private String filePath = RegexPattern.FILE_PATH; //文件路径 53 | private String linuxPath = RegexPattern.LINUX_PATH; //Linux路径 54 | private String windowsPath = RegexPattern.WINDOWS_PATH; //Windows路径 55 | 56 | /** 57 | * 以下为URL相关的正则表达式 58 | */ 59 | private String url = RegexPattern.URL; //URL 60 | private String urlPort = RegexPattern.URL_PORT; //带端口号的URL 61 | private String ip = RegexPattern.IP; //IP 62 | 63 | /** 64 | * 以下为其他相关的正则表达式 65 | */ 66 | private String color = RegexPattern.COLOR; //颜色 67 | private String html = RegexPattern.HTML; //HTML标记 68 | private String carID = RegexPattern.CAR_ID; //车牌号(新能源+非新能源) 69 | 70 | private String province = RegexPattern.PROVINCE; //中国省 71 | 72 | 73 | } 74 | -------------------------------------------------------------------------------- /assistant-util/src/main/java/io/github/util/regex/RegexUtils.java: -------------------------------------------------------------------------------- 1 | package io.github.util.regex; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Component; 7 | 8 | import java.util.regex.Matcher; 9 | import java.util.regex.Pattern; 10 | 11 | /** 12 | * Genius 13 | 14 | **/ 15 | 16 | /* 17 | * 正则表达式工具类 18 | */ 19 | @Data 20 | @Component 21 | @AllArgsConstructor 22 | public class RegexUtils { 23 | 24 | @Autowired 25 | RegexPool regexPool; 26 | //是否是邮箱 27 | public boolean isEmail(String email){ 28 | return VerifyRegex(email,regexPool.getEmail()); 29 | } 30 | 31 | /* 32 | 是否是电话 33 | @param strict 是否严格 34 | */ 35 | public boolean isPhone(String phone,boolean strict){ 36 | return VerifyRegex(phone,strict?regexPool.getStrictPhone():regexPool.getPhone()); 37 | } 38 | 39 | //是否是电话 40 | public boolean isPhone(String phone){ 41 | return isPhone(phone,false); 42 | } 43 | 44 | //是否是用户名 45 | public boolean isUserName(String username){ 46 | return VerifyRegex(username,regexPool.getUsername()); 47 | } 48 | 49 | //是否是密码 50 | public boolean isPassword(String password){ 51 | return VerifyRegex(password,regexPool.getPassword()); 52 | } 53 | 54 | //URL是否正确 55 | public boolean isURL(String url){ 56 | return VerifyRegex(url,regexPool.getUrl()); 57 | } 58 | 59 | //是否带有端口号的url 60 | public boolean isPortUrl(String portUrl){ 61 | return VerifyRegex(portUrl,regexPool.getUrlPort()); 62 | } 63 | 64 | public static boolean VerifyRegex(String str,String regex){ 65 | //正则表达式检测 66 | Pattern pattern = Pattern.compile(regex); 67 | Matcher matcher = pattern.matcher(str); 68 | return matcher.find(); 69 | } 70 | 71 | 72 | } 73 | -------------------------------------------------------------------------------- /assistant-util/src/main/java/io/github/util/token/JWTTokenProperties.java: -------------------------------------------------------------------------------- 1 | package io.github.util.token; 2 | 3 | import lombok.Data; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | import org.springframework.stereotype.Component; 6 | 7 | import java.util.UUID; 8 | import java.util.concurrent.TimeUnit; 9 | 10 | /** 11 | * Genius 12 | * 13 | **/ 14 | @Data 15 | @Component 16 | @ConfigurationProperties(prefix = "assistant.token") 17 | public class JWTTokenProperties { 18 | 19 | private String accessTokenName="accessToken"; //访问token的header名称 20 | private long accessTokenExpireTime = 30; //访问token过期时间 21 | private String accessTokenTimeUnit = "MINUTES"; //token过期时间单位 22 | 23 | private String refreshTokenName = "refreshToken"; //刷新token的header名称 24 | 25 | private Boolean enableRefresh = false; //是否开启刷新token 26 | private long refreshTokenExpireTime = 24; //刷新token过期时间 27 | private String refreshTokenTimeUnit = "HOURS"; //token过期时间单位 28 | 29 | private String tokenSecret = "cuAihCz53DZRjZwbsGcZJ2Ai6At+T142uphtJMsk7iQ="; //token密钥 30 | 31 | private Boolean isRandomJIT = false; //是否随机生成jti 32 | 33 | private static final String JIT = UUID.randomUUID().toString(); 34 | //根据accessTokenExpireTimeUnit返回不同的时间 35 | public long getAccessTokenExpireTime() { 36 | //根据tokenExpireTimeUnit返回不同的时间 37 | return TimeUnit.valueOf(accessTokenTimeUnit).toMillis(accessTokenExpireTime); 38 | } 39 | 40 | public long getRefreshTokenExpireTime(){ 41 | if(!enableRefresh) return 0; 42 | 43 | return TimeUnit.valueOf(refreshTokenTimeUnit).toMillis(refreshTokenExpireTime); 44 | } 45 | 46 | public String getJit(){ 47 | if(isRandomJIT) return UUID.randomUUID().toString(); 48 | 49 | return JIT; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /assistant-util/src/main/java/io/github/util/token/Token.java: -------------------------------------------------------------------------------- 1 | package io.github.util.token; 2 | 3 | import lombok.Data; 4 | import lombok.NoArgsConstructor; 5 | 6 | import java.util.Date; 7 | import java.util.Map; 8 | 9 | /** 10 | * Genius 11 | * 12 | **/ 13 | @Data 14 | @NoArgsConstructor 15 | public class Token implements java.io.Serializable{ 16 | 17 | private static final long serialVersionUID = 1L; 18 | 19 | private Map header; //头部 20 | 21 | private T payload; 22 | 23 | private String accessToken; 24 | 25 | private String refreshToken; 26 | 27 | private String iss; //token签发者 28 | 29 | private String sub; //token所面向的用户 30 | 31 | private String aud; //接收token的一方 32 | 33 | private Date accessExp; //access-token的过期时间,这个过期时间必须要大于签发时间 34 | 35 | private Date refreshExp; //refresh-token的过期时间,这个过期时间必须要大于签发时间 36 | 37 | private Date nbf; //定义在什么时间之前,该jwt都是不可用的. 38 | 39 | private Date iat; //token的签发时间 40 | 41 | private String jti; //jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。 42 | 43 | public Token(String accessToken, String refreshToken){ 44 | this.accessToken = accessToken; 45 | this.refreshToken = refreshToken; 46 | } 47 | 48 | public Token(Map header, String accessToken, String refreshToken, String iss, String sub, String aud, Date accessExp, Date refreshExp, Date nbf, Date iat, String jti) { 49 | this.header = header; 50 | this.accessToken = accessToken; 51 | this.refreshToken = refreshToken; 52 | this.iss = iss; 53 | this.sub = sub; 54 | this.aud = aud; 55 | this.accessExp = accessExp; 56 | this.refreshExp = refreshExp; 57 | this.nbf = nbf; 58 | this.iat = iat; 59 | this.jti = jti; 60 | } 61 | 62 | 63 | } 64 | -------------------------------------------------------------------------------- /assistant-util/src/test/java/io/github/util/AutoCheckerTest.java: -------------------------------------------------------------------------------- 1 | package io.github.util; 2 | 3 | 4 | import io.github.util.autochecker.AutoChecker; 5 | import io.github.util.regex.RegexPattern; 6 | import io.github.util.regex.RegexUtils; 7 | import org.junit.jupiter.api.Test; 8 | import org.springframework.boot.test.context.SpringBootTest; 9 | 10 | import java.util.Date; 11 | import java.util.Map; 12 | 13 | /** 14 | * Genius 15 | **/ 16 | @SpringBootTest 17 | public class AutoCheckerTest { 18 | 19 | @Test 20 | public void testRegexChecker(){ 21 | boolean b = AutoChecker.checkByRegex(Map.of( 22 | "123456789@qq.com", RegexPattern.EMAIL, 23 | "13601607121", RegexPattern.PHONE, 24 | "1142880114", RegexPattern.QQ) 25 | ); 26 | System.out.println(b); 27 | 28 | boolean a = AutoChecker.checkByRegex(Map.of( 29 | "123456789@qq.com", RegexPattern.EMAIL, 30 | "13601607121", RegexPattern.PHONE, 31 | "1142880114123", RegexPattern.QQ) 32 | ); 33 | System.out.println(a); 34 | } 35 | 36 | @Test 37 | public void testChecker(){ 38 | boolean b = AutoChecker.check(Map.of( 39 | 1234,(obj)->(Integer)obj>1000, 40 | "12345", (obj)->((String)obj).length() >3, 41 | "Geniusay",(obj)-> RegexUtils.VerifyRegex((String)obj,RegexPattern.QQ), 42 | "123456789@qq.com",(obj)->RegexUtils.VerifyRegex((String)obj,RegexPattern.EMAIL), 43 | new Date(),(obj)->((Date)obj).getTime()>100 44 | ) 45 | ); 46 | System.out.println(b); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /assistant-util/src/test/java/io/github/util/EncryptionUtilsTest.java: -------------------------------------------------------------------------------- 1 | package io.github.util; 2 | 3 | import io.github.util.encryption.AESEncryptionUtils; 4 | import io.github.util.encryption.EncryptionFactory; 5 | import io.github.util.encryption.EncryptionType; 6 | import io.github.util.encryption.MD5EncryptionUtils; 7 | import org.junit.jupiter.api.Test; 8 | import org.springframework.boot.test.context.SpringBootTest; 9 | 10 | import javax.crypto.SecretKey; 11 | 12 | /** 13 | * Genius 14 | 15 | **/ 16 | 17 | @SpringBootTest 18 | public class EncryptionUtilsTest { 19 | 20 | 21 | @Test 22 | public void testMD5Encryption() throws Exception { 23 | String md5Encipher = EncryptionFactory.getEncryptionUtil(EncryptionType.MD5).Encipher("123456"); 24 | System.out.println("md5加密:"+ md5Encipher); 25 | System.out.println("md5解密:"+ EncryptionFactory.getEncryptionUtil(EncryptionType.MD5).Decrypt(md5Encipher)); 26 | 27 | String rsaEncipher = EncryptionFactory.getEncryptionUtil(EncryptionType.RSA).Encipher("123456"); 28 | System.out.println("rsa加密:"+ rsaEncipher); 29 | System.out.println("rsa解密:"+ EncryptionFactory.getEncryptionUtil(EncryptionType.RSA).Decrypt(rsaEncipher)); 30 | 31 | AESEncryptionUtils encryptionUtil = (AESEncryptionUtils) EncryptionFactory.getEncryptionUtil(EncryptionType.AES); 32 | SecretKey secretKey = encryptionUtil.generateKey(); 33 | encryptionUtil.setSecretKey(secretKey); 34 | String encipher = encryptionUtil.Encipher("123456"); 35 | System.out.println("aes加密:"+ encipher); 36 | System.out.println("aes解密:"+ encryptionUtil.Decrypt(encipher)); 37 | 38 | String desEncipher = EncryptionFactory.getEncryptionUtil(EncryptionType.DES).Encipher("123456"); 39 | System.out.println("des加密:"+ desEncipher); 40 | System.out.println("des解密:"+ EncryptionFactory.getEncryptionUtil(EncryptionType.DES).Decrypt(desEncipher)); 41 | } 42 | 43 | @Test 44 | public void newVersionEncryption() throws Exception{ 45 | EncryptionFactory.add("MD55",new MD5EncryptionUtils()); 46 | String md55 = EncryptionFactory.getEncryptionUtil("MD55").Encipher("123456"); 47 | System.out.println("md55加密:"+ md55); 48 | System.out.println("md55解密:"+ EncryptionFactory.getEncryptionUtil("MD55").Decrypt(md55)); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /assistant-util/src/test/java/io/github/util/PathUtilsTest.java: -------------------------------------------------------------------------------- 1 | package io.github.util; 2 | 3 | 4 | import io.github.util.path.PathUtils; 5 | import org.junit.jupiter.api.Test; 6 | import org.springframework.boot.test.context.SpringBootTest; 7 | 8 | /** 9 | * Genius 10 | **/ 11 | @SpringBootTest 12 | public class PathUtilsTest { 13 | 14 | @Test 15 | public void testSmartPath(){ 16 | System.out.println(PathUtils.smartFilePath("a/","\\b","c\\","/d")); 17 | System.out.println(PathUtils.smartFilePath('\\',"a//","\\b","c\\","/d")); 18 | 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /assistant-util/src/test/java/io/github/util/RegexUtilsTest.java: -------------------------------------------------------------------------------- 1 | package io.github.util; 2 | 3 | 4 | import io.github.util.regex.RegexUtils; 5 | import org.junit.jupiter.api.Test; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.boot.test.context.SpringBootTest; 8 | 9 | /** 10 | * Genius 11 | 12 | **/ 13 | 14 | public class RegexUtilsTest { 15 | @Autowired 16 | RegexUtils regexUtils; 17 | @Test 18 | public void testRegexPool(){ 19 | System.out.println(regexUtils.getRegexPool().getPhone()); 20 | } 21 | 22 | @Test 23 | public void testRegexUtils(){ 24 | System.out.println("邮箱是否正确:"+regexUtils.isEmail("123456789@qq.com")); 25 | System.out.println("邮箱是否正确:"+regexUtils.isEmail("123456789@qqcom")); 26 | System.out.println("电话是否正确:"+regexUtils.isPhone("13601607121")); 27 | System.out.println("电话是否正确:"+regexUtils.isPhone("1234567890")); 28 | System.out.println("电话(严格)是否正确:"+regexUtils.isPhone("123456789012",true)); 29 | System.out.println("电话(严格)是否正确:"+regexUtils.isPhone("13601607121",true)); 30 | System.out.println("QQ是否正确:"+regexUtils.VerifyRegex("123456789", regexUtils.getRegexPool().getQq())); 31 | System.out.println("QQ是否正确:"+regexUtils.VerifyRegex("1142880114", regexUtils.getRegexPool().getQq())); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /assistant-util/src/test/java/io/github/util/TokenUtilsTest.java: -------------------------------------------------------------------------------- 1 | package io.github.util; 2 | 3 | 4 | import io.github.util.token.Token; 5 | import io.github.util.token.TokenUtil; 6 | import io.jsonwebtoken.Claims; 7 | import io.jsonwebtoken.Jwts; 8 | import org.junit.jupiter.api.Test; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.boot.test.context.SpringBootTest; 11 | 12 | import java.util.Date; 13 | import java.util.Map; 14 | 15 | /** 16 | * Genius 17 | 18 | **/ 19 | public class TokenUtilsTest { 20 | @Autowired 21 | TokenUtil tokenUtils; 22 | class User{ 23 | private String name; 24 | private int age; 25 | public User(String name, int age) { 26 | this.name = name; 27 | this.age = age; 28 | } 29 | 30 | } 31 | @Test 32 | public void testCreateToken(){ 33 | User user = new User("Genius",18); 34 | Claims claims = Jwts.claims(); 35 | claims.put("user",user); 36 | 37 | String token = tokenUtils.createToken("user",user,"123456").getAccessToken(); 38 | String token2 = tokenUtils.createToken(Map.of("user",user),"123456").getAccessToken(); 39 | String token3 = tokenUtils.createToken( 40 | Map.of("type","jwt","alg","HS256"), //token头信息 41 | claims, //token payload 42 | new Date(), //token签发时间 43 | new Date(new Date().getTime() + 60*1000), //token过期时间 44 | new Date(new Date().getTime() + 120*1000), //token刷新时间,如果未启用则无效 45 | new Date(new Date().getTime()), //Token生效时间 46 | "Genius", //token签名者 47 | "public Path", //公共区域 48 | tokenUtils.getJwtTokenProperties().getJit(), //token唯一身份标识 49 | "Genius", //发布人 50 | true //是否需要进行刷新操作 51 | ).getAccessToken(); 52 | System.out.println(tokenUtils.parseTokenToToken(token, "user", User.class)); 53 | System.out.println(tokenUtils.parseTokenToToken(token2, "user", User.class)); 54 | System.out.println(tokenUtils.parseTokenToToken(token3, "user", User.class)); 55 | System.out.println(tokenUtils.parseTokenToObj(token3, "user", User.class)); 56 | } 57 | 58 | @Test 59 | public void tesReFreshToken(){ 60 | User user = new User("Genius",18); 61 | Claims claims = Jwts.claims(); 62 | claims.put("user",user); 63 | Token token = tokenUtils.createToken( 64 | Map.of("type","jwt","alg","HS256"), //token头信息 65 | claims, //token payload 66 | new Date(), //token签发时间 67 | new Date(new Date().getTime() + 10), //token过期时间 68 | new Date(new Date().getTime() + 120*1000), //token刷新时间,如果未启用则无效 69 | new Date(new Date().getTime()), //Token生效时间 70 | "Genius", //token签名者 71 | "public Path", //公共区域 72 | tokenUtils.getJwtTokenProperties().getJit(), //token唯一身份标识 73 | "Genius", //发布人 74 | true //是否需要进行刷新操作 75 | ); 76 | System.out.println(token.getAccessToken()); 77 | System.out.println(tokenUtils.refreshToken(token).getAccessToken()); 78 | 79 | } 80 | 81 | @Test 82 | public void testCreateTokenByMap(){ 83 | String accessToken = tokenUtils.createToken(Map.of( 84 | "username", "Genius", 85 | "uid", "123456" 86 | ), "123456").getAccessToken(); 87 | System.out.println(tokenUtils.parseTokenToObj(accessToken, "username", String.class)); 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /assistant-util/src/test/java/io/github/util/list/SharedListJMHTest.java: -------------------------------------------------------------------------------- 1 | package io.github.util.list; 2 | 3 | import io.github.util.collection.list.SharedList; 4 | import org.openjdk.jmh.annotations.*; 5 | import org.openjdk.jmh.runner.Runner; 6 | import org.openjdk.jmh.runner.RunnerException; 7 | import org.openjdk.jmh.runner.options.Options; 8 | import org.openjdk.jmh.runner.options.OptionsBuilder; 9 | 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | import java.util.Random; 13 | import java.util.concurrent.TimeUnit; 14 | 15 | @State(Scope.Benchmark) 16 | @OutputTimeUnit(TimeUnit.SECONDS) 17 | @Threads(Threads.MAX) 18 | public class SharedListJMHTest { 19 | 20 | List list1 = new ArrayList<>(); 21 | List list2 = new ArrayList<>(); 22 | List list3 = new ArrayList<>(); 23 | 24 | ArrayList list = new ArrayList<>(); 25 | 26 | Random random = new Random(); 27 | 28 | SharedList merge; 29 | @Setup 30 | public void setup() { 31 | for (int i = 0; i < 10000000; i++) { 32 | list1.add("a" + i); 33 | list2.add("A" + i); 34 | list3.add("b" + i); 35 | } 36 | merge = SharedList.SharedListBuilder.merge(list1, list2, list3); 37 | list.addAll(list1); 38 | list.addAll(list2); 39 | list.addAll(list2); 40 | } 41 | 42 | @Benchmark 43 | @BenchmarkMode(Mode.Throughput) 44 | public void foreachSharedList() { 45 | 46 | for (int i = 0; i < 10000; i++) { 47 | int index = random.nextInt(100000) + 1; 48 | merge.get(index); 49 | } 50 | } 51 | 52 | @Benchmark 53 | @BenchmarkMode(Mode.Throughput) 54 | public void foreachCopyList() { 55 | for (int i = 0; i < 10000; i++) { 56 | int index = random.nextInt(100000) + 1; 57 | list.get(index); 58 | } 59 | } 60 | 61 | public static void main(String[] args) throws RunnerException { 62 | Options opt = new OptionsBuilder() 63 | .include(SharedListJMHTest.class.getSimpleName()) 64 | .forks(2) 65 | .warmupIterations(2) 66 | .measurementIterations(2) 67 | .build(); 68 | 69 | new Runner(opt).run(); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /assistant-util/src/test/java/io/github/util/list/SharedListTest.java: -------------------------------------------------------------------------------- 1 | package io.github.util.list; 2 | 3 | 4 | import io.github.common.SafeBag; 5 | import io.github.util.collection.list.SharedList; 6 | import org.junit.Test; 7 | import org.yaml.snakeyaml.util.ArrayUtils; 8 | 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | public class SharedListTest { 13 | 14 | private List list = new ArrayList<>(List.of("a", "b", "c","e","f")); 15 | 16 | @Test 17 | public void testSliceSharedList(){ 18 | SharedList sharedList = SharedList.SharedListBuilder.slice(1, 3, list); 19 | System.out.println(sharedList); 20 | System.out.println(sharedList.get(0)); 21 | System.out.println(sharedList.get(1)); 22 | System.out.println(sharedList.get(3)); 23 | } 24 | 25 | @Test 26 | public void testFreedomList(){ 27 | SharedList freedomList = SharedList.SharedListBuilder.freedomList(1, list); 28 | System.out.println(freedomList); 29 | freedomList.add("x"); 30 | freedomList.add("y"); 31 | freedomList.add("z"); 32 | System.out.println(freedomList); 33 | 34 | freedomList.set(0,"hello"); 35 | System.out.println(list); 36 | System.out.println(freedomList); 37 | } 38 | 39 | @Test 40 | public void testMergeSharedList(){ 41 | List list1 = new ArrayList<>(List.of("a", "b", "c","d","e")); 42 | List list2 = new ArrayList<>(List.of("X", "D", "F","X","Y")); 43 | System.out.println("list1: "+list1); 44 | System.out.println("list2: "+list2); 45 | 46 | SharedList mergeList = SharedList.SharedListBuilder.merge(list1, list2); 47 | 48 | System.out.println("merge list1 and list2 : "+ mergeList); 49 | 50 | SharedList slice = SharedList.SharedListBuilder.slice(2, 6, mergeList); 51 | System.out.println("slice mergeList from 2 to 6 : "+ slice); 52 | 53 | SharedList merge2List = SharedList.SharedListBuilder.merge(list1, list2, slice); 54 | System.out.println("merge list1 and list2 and slice : "+ merge2List); 55 | System.out.println("merge2 get index 1: "+ merge2List.get(1)); 56 | 57 | SharedList subList = merge2List.subList(4, 5); 58 | System.out.println("merge2 subList from 4 to 5 :"+ subList); 59 | 60 | subList.set(1, "hello"); 61 | System.out.println("sublist after set sublist index 1 to hello: "+subList); 62 | System.out.println("merge2 after set sublist index 1 to hello: "+merge2List); 63 | } 64 | 65 | @Test 66 | public void testTime() { 67 | List list1 = new ArrayList<>(); 68 | List list2 = new ArrayList<>(); 69 | List list3 = new ArrayList<>(); 70 | List copyList = new ArrayList<>(); 71 | for (int i = 0; i < 10000000; i++) { 72 | list1.add("a" + i); 73 | list2.add("A" + i); 74 | list3.add("b" + i); 75 | } 76 | 77 | SafeBag> sharedListSafeBag = new SafeBag<>(); 78 | 79 | logTime(() -> { 80 | sharedListSafeBag.setData(SharedList.SharedListBuilder.merge(list1, list2, list3)); 81 | }, "merge"); 82 | 83 | logTime(() -> { 84 | copyList.addAll(list1); 85 | copyList.addAll(list2); 86 | copyList.addAll(list3); 87 | }, "copy"); 88 | 89 | 90 | logTime(() -> { 91 | int i = 0; 92 | for (String datum : copyList) { 93 | i++; 94 | } 95 | System.out.println(i); 96 | }, "foreach copy"); 97 | 98 | logTime(() -> { 99 | int i = 0; 100 | SharedList data = sharedListSafeBag.getData(); 101 | for (String datum : data) { 102 | i++; 103 | } 104 | System.out.println(i); 105 | }, "foreach merge"); 106 | } 107 | 108 | public void logTime(Runnable runnable,String name){ 109 | long time = System.currentTimeMillis(); 110 | runnable.run(); 111 | System.out.println(name + " time: "+(System.currentTimeMillis()-time)); 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /assistant-websocket/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | assistant 7 | io.github.geniusay 8 | 1.1.2 9 | 10 | 11 | ${assistant-webscoket.version} 12 | 13 | 4.0.0 14 | 15 | assistant-websocket 16 | 17 | 18 | 11 19 | 11 20 | UTF-8 21 | 22 | 23 | 24 | 25 | io.github.geniusay 26 | assistant-common 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-websocket 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /assistant-websocket/src/main/java/io/github/webscoket/core/MessageHandlerFactory.java: -------------------------------------------------------------------------------- 1 | package io.github.webscoket.core; 2 | 3 | import io.github.webscoket.core.handler.AbstractMessageHandler; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.boot.CommandLineRunner; 6 | import org.springframework.stereotype.Component; 7 | 8 | import javax.websocket.Session; 9 | import java.util.List; 10 | 11 | /** 12 | * Genius 13 | * 2023/09/06 19:34 14 | **/ 15 | @Component 16 | public class MessageHandlerFactory implements CommandLineRunner { 17 | 18 | private static List link; 19 | 20 | @Autowired 21 | public MessageHandlerFactory(List link){ 22 | MessageHandlerFactory.link = link; 23 | } 24 | 25 | public static void doHandler(String msg, Session session){ 26 | for (AbstractMessageHandler abstractMessageHandler : link) { 27 | if (abstractMessageHandler.check(msg)) { 28 | abstractMessageHandler.handler(msg,session); 29 | return; 30 | } 31 | } 32 | } 33 | 34 | public static AbstractMessageHandler getHandler(String type){ 35 | for (AbstractMessageHandler abstractMessageHandler : link) { 36 | if (abstractMessageHandler.check(type)) { 37 | return abstractMessageHandler; 38 | } 39 | } 40 | return null; 41 | } 42 | 43 | @Override 44 | public void run(String... args) throws Exception { 45 | 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /assistant-websocket/src/main/java/io/github/webscoket/core/WebSocketHandler.java: -------------------------------------------------------------------------------- 1 | package io.github.webscoket.core; 2 | 3 | 4 | import io.github.common.logger.CommonLogger; 5 | import org.slf4j.Logger; 6 | import org.springframework.stereotype.Component; 7 | 8 | import javax.annotation.Resource; 9 | import javax.websocket.*; 10 | import javax.websocket.server.ServerEndpoint; 11 | import java.io.IOException; 12 | import java.util.concurrent.ConcurrentHashMap; 13 | 14 | /** 15 | * Genius 16 | * 2023/09/06 19:24 17 | **/ 18 | @Component 19 | @ServerEndpoint("/chopperBot") 20 | public class WebSocketHandler { 21 | 22 | @Resource 23 | CommonLogger log; 24 | 25 | private static ConcurrentHashMap sessionMap = new ConcurrentHashMap<>(); 26 | 27 | @OnOpen 28 | public void onOpen(Session session) { 29 | // WebSocket 连接建立时执行的逻辑 30 | log.info("%s connect websocket",session); 31 | } 32 | 33 | @OnMessage 34 | public void onMessage(String message, Session session) { 35 | // 处理收到的消息 36 | log.info("%s send a message:{}",session,message); 37 | MessageHandlerFactory.doHandler(message,session); 38 | } 39 | 40 | @OnClose 41 | public void onClose(Session session, CloseReason closeReason) { 42 | // WebSocket 连接关闭时执行的逻辑 43 | log.info("{} close connect~",session); 44 | } 45 | 46 | public void sendMsg(String message) { 47 | if(sessionMap.containsKey("ChopperBot")){ 48 | Session chopperBot = sessionMap.get("ChopperBot"); 49 | try { 50 | chopperBot.getBasicRemote().sendText(message); 51 | } catch (IOException e) { 52 | e.printStackTrace(); 53 | } 54 | } 55 | } 56 | 57 | public void sendMsg(String message,String user) { 58 | if(sessionMap.containsKey(user)){ 59 | Session session = sessionMap.get(user); 60 | try { 61 | session.getBasicRemote().sendText(message); 62 | } catch (IOException e) { 63 | sessionMap.remove(user); 64 | } 65 | } 66 | } 67 | 68 | public void register(String user,Session session){ 69 | sessionMap.put(user,session); 70 | log.info("{} {} register websocket",user,session); 71 | } 72 | 73 | public boolean isRegister(String user){ 74 | 75 | return sessionMap.containsKey(user); 76 | } 77 | 78 | public boolean close(String user){ 79 | if(sessionMap.containsKey(user)){ 80 | Session session = sessionMap.get(user); 81 | try { 82 | session.close(); 83 | } catch (IOException e) { 84 | e.printStackTrace(); 85 | return false; 86 | } 87 | } 88 | return true; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /assistant-websocket/src/main/java/io/github/webscoket/core/handler/AbstractMessageHandler.java: -------------------------------------------------------------------------------- 1 | package io.github.webscoket.core.handler; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import io.github.webscoket.core.WebSocketHandler; 5 | 6 | import java.util.Map; 7 | 8 | /** 9 | * Genius 10 | * 2023/09/06 19:45 11 | **/ 12 | 13 | public abstract class AbstractMessageHandler implements MessageHandler { 14 | protected final WebSocketHandler webSocketHandler; 15 | 16 | protected String msgType; 17 | 18 | public AbstractMessageHandler(WebSocketHandler webSocketHandler) { 19 | this.webSocketHandler = webSocketHandler; 20 | } 21 | 22 | @Override 23 | public boolean check(String msg) { 24 | return MessageProtocol.isThisType(msg,msgType); 25 | } 26 | 27 | @Override 28 | public void wrapperAndSend(String msg) { 29 | String resp = MessageProtocol.encodeMsg(msgType, msg); 30 | this.webSocketHandler.sendMsg(resp); 31 | } 32 | 33 | @Override 34 | public void wrapperAndSend(Object msg) { 35 | String jsonMsg = JSON.toJSONString(msg); 36 | String resp = MessageProtocol.encodeMsg(msgType,jsonMsg); 37 | this.webSocketHandler.sendMsg(resp); 38 | } 39 | 40 | @Override 41 | public void wrapperAndSend(Map msg) { 42 | String resp = MessageProtocol.encodeMsg(msgType, msg); 43 | this.webSocketHandler.sendMsg(resp); 44 | } 45 | 46 | @Override 47 | public void wrapperAndSend(String msg, String user) { 48 | String resp = MessageProtocol.encodeMsg(msgType, msg); 49 | this.webSocketHandler.sendMsg(resp,user); 50 | } 51 | 52 | @Override 53 | public void wrapperAndSend(Object msg, String user) { 54 | String jsonMsg = JSON.toJSONString(msg); 55 | String resp = MessageProtocol.encodeMsg(msgType,jsonMsg); 56 | this.webSocketHandler.sendMsg(resp,user); 57 | } 58 | 59 | @Override 60 | public void wrapperAndSend(Map map, String user) { 61 | String resp = MessageProtocol.encodeMsg(msgType, map); 62 | this.webSocketHandler.sendMsg(resp,user); 63 | } 64 | 65 | @Override 66 | public void send(String msg) { 67 | this.webSocketHandler.sendMsg(msg); 68 | } 69 | 70 | @Override 71 | public boolean close(String user) { 72 | return this.webSocketHandler.close(user); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /assistant-websocket/src/main/java/io/github/webscoket/core/handler/MessageHandler.java: -------------------------------------------------------------------------------- 1 | package io.github.webscoket.core.handler; 2 | 3 | 4 | import javax.websocket.Session; 5 | import java.util.Map; 6 | 7 | /** 8 | * Genius 9 | * 2023/09/06 19:28 10 | **/ 11 | public interface MessageHandler { 12 | 13 | boolean check(String msg); 14 | void handler(String msg, Session session); 15 | void wrapperAndSend(String msg); 16 | void wrapperAndSend(Object msg); 17 | 18 | void wrapperAndSend(Map msg); 19 | void wrapperAndSend(String msg,String user); 20 | void wrapperAndSend(Object msg,String user); 21 | void wrapperAndSend(Map map,String user); 22 | 23 | void send(String msg); 24 | 25 | boolean close(String user); 26 | } 27 | -------------------------------------------------------------------------------- /assistant-websocket/src/main/java/io/github/webscoket/core/handler/MessageProtocol.java: -------------------------------------------------------------------------------- 1 | package io.github.webscoket.core.handler; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * Genius 8 | * 2023/09/06 19:49 9 | **/ 10 | public class MessageProtocol { 11 | private static final String head = "type@=%s|"; 12 | private static final String body = "data@=%s|"; 13 | 14 | 15 | public static String getHead(String type){ 16 | return String.format(head, type); 17 | } 18 | public static String encodeMsg(String type,String data){ 19 | return getHead(type) + String.format(body, data); 20 | } 21 | 22 | public static String encodeMsg(String type, Map contentBody){ 23 | StringBuffer buffer = new StringBuffer(getHead(type)); 24 | contentBody.forEach( 25 | (k,v)->{ 26 | buffer.append(k).append("@=").append(v).append("|"); 27 | } 28 | ); 29 | return buffer.toString(); 30 | } 31 | 32 | public static Map decodeMsg(String msg){ 33 | String[] params = msg.split("\\|"); 34 | HashMap res = new HashMap<>(); 35 | if(params.length>0){ 36 | for (String param : params) { 37 | String[] kv = param.split("@="); 38 | if(kv.length==2){ 39 | res.put(kv[0],kv[1]); 40 | } 41 | } 42 | } 43 | return res; 44 | } 45 | 46 | public static boolean isThisType(String msg,String msgType){ 47 | return msg.startsWith(String.format(head, msgType)); 48 | } 49 | 50 | } 51 | --------------------------------------------------------------------------------