diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9e20bc1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea/ +**/target/** +logs/ +*.iml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9e20bc1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea/ +**/target/** +logs/ +*.iml diff --git a/README.md b/README.md new file mode 100644 index 0000000..2fdcd74 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# casic项目 V2.0.0 + +[^_^]: # (Talk is cheap,Show me the code!) + +## 介绍 +基于SpringBoot,致力于做更简洁的后台管理系统,完美整合springboot2.4 + shiro + mybatis-plus ! +基于casic项目代码简洁,注释丰富,上手容易,同时包含许多基础模块(用户管理,角色管理,部门管理,字典管理等10个模块) +可以直接作为一个后台管理系统的脚手架! 2022目标 `更简洁`,`更规范`! + + +#### 其他 +>* [git地址](http://192.168.0.203:8080/gitbucket) +>* [本地免登地址](http://localhost:8083/route/mockToken) diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9e20bc1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea/ +**/target/** +logs/ +*.iml diff --git a/README.md b/README.md new file mode 100644 index 0000000..2fdcd74 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# casic项目 V2.0.0 + +[^_^]: # (Talk is cheap,Show me the code!) + +## 介绍 +基于SpringBoot,致力于做更简洁的后台管理系统,完美整合springboot2.4 + shiro + mybatis-plus ! +基于casic项目代码简洁,注释丰富,上手容易,同时包含许多基础模块(用户管理,角色管理,部门管理,字典管理等10个模块) +可以直接作为一个后台管理系统的脚手架! 2022目标 `更简洁`,`更规范`! + + +#### 其他 +>* [git地址](http://192.168.0.203:8080/gitbucket) +>* [本地免登地址](http://localhost:8083/route/mockToken) diff --git a/casic-server/pom.xml b/casic-server/pom.xml new file mode 100644 index 0000000..c150a12 --- /dev/null +++ b/casic-server/pom.xml @@ -0,0 +1,70 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + 2.0.0 + ../pom.xml + + + casic-server + 2.0.0 + jar + casic-server + casic 的spring boot版本 + + + + + com.casic + casic-core + ${core.version} + provided + + + com.casic + casic-admin-support + ${admin.version} + provided + + + org.springframework.boot + spring-boot-starter-web + ${boot.version} + provided + + + + + com.hikvision.ga + artemis-http-client + 1.1.3 + + + commons-io + commons-io + + + org.springframework.boot + spring-boot-starter-websocket + 2.4.5 + + + io.netty + netty-all + 4.1.42.Final + + + + + + src/main/java + + **/*.xml + + + + + \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9e20bc1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea/ +**/target/** +logs/ +*.iml diff --git a/README.md b/README.md new file mode 100644 index 0000000..2fdcd74 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# casic项目 V2.0.0 + +[^_^]: # (Talk is cheap,Show me the code!) + +## 介绍 +基于SpringBoot,致力于做更简洁的后台管理系统,完美整合springboot2.4 + shiro + mybatis-plus ! +基于casic项目代码简洁,注释丰富,上手容易,同时包含许多基础模块(用户管理,角色管理,部门管理,字典管理等10个模块) +可以直接作为一个后台管理系统的脚手架! 2022目标 `更简洁`,`更规范`! + + +#### 其他 +>* [git地址](http://192.168.0.203:8080/gitbucket) +>* [本地免登地址](http://localhost:8083/route/mockToken) diff --git a/casic-server/pom.xml b/casic-server/pom.xml new file mode 100644 index 0000000..c150a12 --- /dev/null +++ b/casic-server/pom.xml @@ -0,0 +1,70 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + 2.0.0 + ../pom.xml + + + casic-server + 2.0.0 + jar + casic-server + casic 的spring boot版本 + + + + + com.casic + casic-core + ${core.version} + provided + + + com.casic + casic-admin-support + ${admin.version} + provided + + + org.springframework.boot + spring-boot-starter-web + ${boot.version} + provided + + + + + com.hikvision.ga + artemis-http-client + 1.1.3 + + + commons-io + commons-io + + + org.springframework.boot + spring-boot-starter-websocket + 2.4.5 + + + io.netty + netty-all + 4.1.42.Final + + + + + + src/main/java + + **/*.xml + + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java new file mode 100644 index 0000000..3a60b9e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java @@ -0,0 +1,36 @@ +package com.casic.missiles.modular.async; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.TaskExecutor; +import org.springframework.scheduling.annotation.AsyncConfigurer; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadPoolExecutor; + +@Configuration +@EnableAsync +public class AsyncConfig implements AsyncConfigurer { + @Override + public Executor getAsyncExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + //核心线程数 + executor.setCorePoolSize(5); + //最大线程数 + executor.setMaxPoolSize(10); + //队列容量 + executor.setQueueCapacity(20); + //设置线程活跃时间(秒) + executor.setKeepAliveSeconds(60); + //默认线程名称 + executor.setThreadNamePrefix("user-rpt-"); + //拒绝策略 + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + //等待所有任务结束后再关闭线程池 + executor.setWaitForTasksToCompleteOnShutdown(true); + return executor; + } + +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9e20bc1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea/ +**/target/** +logs/ +*.iml diff --git a/README.md b/README.md new file mode 100644 index 0000000..2fdcd74 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# casic项目 V2.0.0 + +[^_^]: # (Talk is cheap,Show me the code!) + +## 介绍 +基于SpringBoot,致力于做更简洁的后台管理系统,完美整合springboot2.4 + shiro + mybatis-plus ! +基于casic项目代码简洁,注释丰富,上手容易,同时包含许多基础模块(用户管理,角色管理,部门管理,字典管理等10个模块) +可以直接作为一个后台管理系统的脚手架! 2022目标 `更简洁`,`更规范`! + + +#### 其他 +>* [git地址](http://192.168.0.203:8080/gitbucket) +>* [本地免登地址](http://localhost:8083/route/mockToken) diff --git a/casic-server/pom.xml b/casic-server/pom.xml new file mode 100644 index 0000000..c150a12 --- /dev/null +++ b/casic-server/pom.xml @@ -0,0 +1,70 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + 2.0.0 + ../pom.xml + + + casic-server + 2.0.0 + jar + casic-server + casic 的spring boot版本 + + + + + com.casic + casic-core + ${core.version} + provided + + + com.casic + casic-admin-support + ${admin.version} + provided + + + org.springframework.boot + spring-boot-starter-web + ${boot.version} + provided + + + + + com.hikvision.ga + artemis-http-client + 1.1.3 + + + commons-io + commons-io + + + org.springframework.boot + spring-boot-starter-websocket + 2.4.5 + + + io.netty + netty-all + 4.1.42.Final + + + + + + src/main/java + + **/*.xml + + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java new file mode 100644 index 0000000..3a60b9e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java @@ -0,0 +1,36 @@ +package com.casic.missiles.modular.async; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.TaskExecutor; +import org.springframework.scheduling.annotation.AsyncConfigurer; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadPoolExecutor; + +@Configuration +@EnableAsync +public class AsyncConfig implements AsyncConfigurer { + @Override + public Executor getAsyncExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + //核心线程数 + executor.setCorePoolSize(5); + //最大线程数 + executor.setMaxPoolSize(10); + //队列容量 + executor.setQueueCapacity(20); + //设置线程活跃时间(秒) + executor.setKeepAliveSeconds(60); + //默认线程名称 + executor.setThreadNamePrefix("user-rpt-"); + //拒绝策略 + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + //等待所有任务结束后再关闭线程池 + executor.setWaitForTasksToCompleteOnShutdown(true); + return executor; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java new file mode 100644 index 0000000..8ca554c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java @@ -0,0 +1,18 @@ +package com.casic.missiles.modular.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +// tomcat启动无需配置 +@Configuration +public class WebSocketConfig { + /** + * 注入ServerEndpointExporter, + * 这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint + */ + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9e20bc1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea/ +**/target/** +logs/ +*.iml diff --git a/README.md b/README.md new file mode 100644 index 0000000..2fdcd74 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# casic项目 V2.0.0 + +[^_^]: # (Talk is cheap,Show me the code!) + +## 介绍 +基于SpringBoot,致力于做更简洁的后台管理系统,完美整合springboot2.4 + shiro + mybatis-plus ! +基于casic项目代码简洁,注释丰富,上手容易,同时包含许多基础模块(用户管理,角色管理,部门管理,字典管理等10个模块) +可以直接作为一个后台管理系统的脚手架! 2022目标 `更简洁`,`更规范`! + + +#### 其他 +>* [git地址](http://192.168.0.203:8080/gitbucket) +>* [本地免登地址](http://localhost:8083/route/mockToken) diff --git a/casic-server/pom.xml b/casic-server/pom.xml new file mode 100644 index 0000000..c150a12 --- /dev/null +++ b/casic-server/pom.xml @@ -0,0 +1,70 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + 2.0.0 + ../pom.xml + + + casic-server + 2.0.0 + jar + casic-server + casic 的spring boot版本 + + + + + com.casic + casic-core + ${core.version} + provided + + + com.casic + casic-admin-support + ${admin.version} + provided + + + org.springframework.boot + spring-boot-starter-web + ${boot.version} + provided + + + + + com.hikvision.ga + artemis-http-client + 1.1.3 + + + commons-io + commons-io + + + org.springframework.boot + spring-boot-starter-websocket + 2.4.5 + + + io.netty + netty-all + 4.1.42.Final + + + + + + src/main/java + + **/*.xml + + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java new file mode 100644 index 0000000..3a60b9e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java @@ -0,0 +1,36 @@ +package com.casic.missiles.modular.async; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.TaskExecutor; +import org.springframework.scheduling.annotation.AsyncConfigurer; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadPoolExecutor; + +@Configuration +@EnableAsync +public class AsyncConfig implements AsyncConfigurer { + @Override + public Executor getAsyncExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + //核心线程数 + executor.setCorePoolSize(5); + //最大线程数 + executor.setMaxPoolSize(10); + //队列容量 + executor.setQueueCapacity(20); + //设置线程活跃时间(秒) + executor.setKeepAliveSeconds(60); + //默认线程名称 + executor.setThreadNamePrefix("user-rpt-"); + //拒绝策略 + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + //等待所有任务结束后再关闭线程池 + executor.setWaitForTasksToCompleteOnShutdown(true); + return executor; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java new file mode 100644 index 0000000..8ca554c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java @@ -0,0 +1,18 @@ +package com.casic.missiles.modular.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +// tomcat启动无需配置 +@Configuration +public class WebSocketConfig { + /** + * 注入ServerEndpointExporter, + * 这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint + */ + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java new file mode 100644 index 0000000..34fe2cd --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java @@ -0,0 +1,39 @@ +package com.casic.missiles.modular.controller; + + +import com.casic.missiles.model.application.event.core.EventPublisher; +import com.casic.missiles.model.application.event.enums.ModelEventTypeEnum; +import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.modular.event.UserEvent; +import com.casic.missiles.modular.system.model.User; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +/** + * @Description: DemoController + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@RestController +@RequestMapping("/demo") +public class DemoController { + @Autowired + private EventPublisher publisher; + + /** + * 获取mockToken + */ + @PostMapping("/list") + @ResponseBody + public Object list() { + User user = new User(); + user.setAccount("张三"); + publisher.publishEvent(new UserEvent(ModelEventTypeEnum.ADD, user)); + return ResponseData.success(); + } + + +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9e20bc1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea/ +**/target/** +logs/ +*.iml diff --git a/README.md b/README.md new file mode 100644 index 0000000..2fdcd74 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# casic项目 V2.0.0 + +[^_^]: # (Talk is cheap,Show me the code!) + +## 介绍 +基于SpringBoot,致力于做更简洁的后台管理系统,完美整合springboot2.4 + shiro + mybatis-plus ! +基于casic项目代码简洁,注释丰富,上手容易,同时包含许多基础模块(用户管理,角色管理,部门管理,字典管理等10个模块) +可以直接作为一个后台管理系统的脚手架! 2022目标 `更简洁`,`更规范`! + + +#### 其他 +>* [git地址](http://192.168.0.203:8080/gitbucket) +>* [本地免登地址](http://localhost:8083/route/mockToken) diff --git a/casic-server/pom.xml b/casic-server/pom.xml new file mode 100644 index 0000000..c150a12 --- /dev/null +++ b/casic-server/pom.xml @@ -0,0 +1,70 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + 2.0.0 + ../pom.xml + + + casic-server + 2.0.0 + jar + casic-server + casic 的spring boot版本 + + + + + com.casic + casic-core + ${core.version} + provided + + + com.casic + casic-admin-support + ${admin.version} + provided + + + org.springframework.boot + spring-boot-starter-web + ${boot.version} + provided + + + + + com.hikvision.ga + artemis-http-client + 1.1.3 + + + commons-io + commons-io + + + org.springframework.boot + spring-boot-starter-websocket + 2.4.5 + + + io.netty + netty-all + 4.1.42.Final + + + + + + src/main/java + + **/*.xml + + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java new file mode 100644 index 0000000..3a60b9e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java @@ -0,0 +1,36 @@ +package com.casic.missiles.modular.async; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.TaskExecutor; +import org.springframework.scheduling.annotation.AsyncConfigurer; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadPoolExecutor; + +@Configuration +@EnableAsync +public class AsyncConfig implements AsyncConfigurer { + @Override + public Executor getAsyncExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + //核心线程数 + executor.setCorePoolSize(5); + //最大线程数 + executor.setMaxPoolSize(10); + //队列容量 + executor.setQueueCapacity(20); + //设置线程活跃时间(秒) + executor.setKeepAliveSeconds(60); + //默认线程名称 + executor.setThreadNamePrefix("user-rpt-"); + //拒绝策略 + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + //等待所有任务结束后再关闭线程池 + executor.setWaitForTasksToCompleteOnShutdown(true); + return executor; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java new file mode 100644 index 0000000..8ca554c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java @@ -0,0 +1,18 @@ +package com.casic.missiles.modular.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +// tomcat启动无需配置 +@Configuration +public class WebSocketConfig { + /** + * 注入ServerEndpointExporter, + * 这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint + */ + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java new file mode 100644 index 0000000..34fe2cd --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java @@ -0,0 +1,39 @@ +package com.casic.missiles.modular.controller; + + +import com.casic.missiles.model.application.event.core.EventPublisher; +import com.casic.missiles.model.application.event.enums.ModelEventTypeEnum; +import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.modular.event.UserEvent; +import com.casic.missiles.modular.system.model.User; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +/** + * @Description: DemoController + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@RestController +@RequestMapping("/demo") +public class DemoController { + @Autowired + private EventPublisher publisher; + + /** + * 获取mockToken + */ + @PostMapping("/list") + @ResponseBody + public Object list() { + User user = new User(); + user.setAccount("张三"); + publisher.publishEvent(new UserEvent(ModelEventTypeEnum.ADD, user)); + return ResponseData.success(); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java new file mode 100644 index 0000000..aff2889 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java @@ -0,0 +1,23 @@ +package com.casic.missiles.modular.event; + +import com.casic.missiles.model.application.event.core.ModelEvent; +import com.casic.missiles.model.application.event.type.AbstractEventTypeEnum; +import com.casic.missiles.modular.system.model.User; + +/** + * @Description: 用户事件 + * @Author: wangpeng + * @Date: 2022/7/17 11:23 + */ +public class UserEvent extends ModelEvent { + /** + * Create a new {@code ApplicationEvent}. + * + * @param type 事件类型 + * @param source the object on which the event initially occurred or with + * which the event is associated (never {@code null}) + */ + public UserEvent(AbstractEventTypeEnum type, User source) { + super(type, source); + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9e20bc1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea/ +**/target/** +logs/ +*.iml diff --git a/README.md b/README.md new file mode 100644 index 0000000..2fdcd74 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# casic项目 V2.0.0 + +[^_^]: # (Talk is cheap,Show me the code!) + +## 介绍 +基于SpringBoot,致力于做更简洁的后台管理系统,完美整合springboot2.4 + shiro + mybatis-plus ! +基于casic项目代码简洁,注释丰富,上手容易,同时包含许多基础模块(用户管理,角色管理,部门管理,字典管理等10个模块) +可以直接作为一个后台管理系统的脚手架! 2022目标 `更简洁`,`更规范`! + + +#### 其他 +>* [git地址](http://192.168.0.203:8080/gitbucket) +>* [本地免登地址](http://localhost:8083/route/mockToken) diff --git a/casic-server/pom.xml b/casic-server/pom.xml new file mode 100644 index 0000000..c150a12 --- /dev/null +++ b/casic-server/pom.xml @@ -0,0 +1,70 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + 2.0.0 + ../pom.xml + + + casic-server + 2.0.0 + jar + casic-server + casic 的spring boot版本 + + + + + com.casic + casic-core + ${core.version} + provided + + + com.casic + casic-admin-support + ${admin.version} + provided + + + org.springframework.boot + spring-boot-starter-web + ${boot.version} + provided + + + + + com.hikvision.ga + artemis-http-client + 1.1.3 + + + commons-io + commons-io + + + org.springframework.boot + spring-boot-starter-websocket + 2.4.5 + + + io.netty + netty-all + 4.1.42.Final + + + + + + src/main/java + + **/*.xml + + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java new file mode 100644 index 0000000..3a60b9e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java @@ -0,0 +1,36 @@ +package com.casic.missiles.modular.async; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.TaskExecutor; +import org.springframework.scheduling.annotation.AsyncConfigurer; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadPoolExecutor; + +@Configuration +@EnableAsync +public class AsyncConfig implements AsyncConfigurer { + @Override + public Executor getAsyncExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + //核心线程数 + executor.setCorePoolSize(5); + //最大线程数 + executor.setMaxPoolSize(10); + //队列容量 + executor.setQueueCapacity(20); + //设置线程活跃时间(秒) + executor.setKeepAliveSeconds(60); + //默认线程名称 + executor.setThreadNamePrefix("user-rpt-"); + //拒绝策略 + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + //等待所有任务结束后再关闭线程池 + executor.setWaitForTasksToCompleteOnShutdown(true); + return executor; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java new file mode 100644 index 0000000..8ca554c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java @@ -0,0 +1,18 @@ +package com.casic.missiles.modular.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +// tomcat启动无需配置 +@Configuration +public class WebSocketConfig { + /** + * 注入ServerEndpointExporter, + * 这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint + */ + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java new file mode 100644 index 0000000..34fe2cd --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java @@ -0,0 +1,39 @@ +package com.casic.missiles.modular.controller; + + +import com.casic.missiles.model.application.event.core.EventPublisher; +import com.casic.missiles.model.application.event.enums.ModelEventTypeEnum; +import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.modular.event.UserEvent; +import com.casic.missiles.modular.system.model.User; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +/** + * @Description: DemoController + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@RestController +@RequestMapping("/demo") +public class DemoController { + @Autowired + private EventPublisher publisher; + + /** + * 获取mockToken + */ + @PostMapping("/list") + @ResponseBody + public Object list() { + User user = new User(); + user.setAccount("张三"); + publisher.publishEvent(new UserEvent(ModelEventTypeEnum.ADD, user)); + return ResponseData.success(); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java new file mode 100644 index 0000000..aff2889 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java @@ -0,0 +1,23 @@ +package com.casic.missiles.modular.event; + +import com.casic.missiles.model.application.event.core.ModelEvent; +import com.casic.missiles.model.application.event.type.AbstractEventTypeEnum; +import com.casic.missiles.modular.system.model.User; + +/** + * @Description: 用户事件 + * @Author: wangpeng + * @Date: 2022/7/17 11:23 + */ +public class UserEvent extends ModelEvent { + /** + * Create a new {@code ApplicationEvent}. + * + * @param type 事件类型 + * @param source the object on which the event initially occurred or with + * which the event is associated (never {@code null}) + */ + public UserEvent(AbstractEventTypeEnum type, User source) { + super(type, source); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java new file mode 100644 index 0000000..8f9603e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.core.application.event.UserLoginEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserOneListener { + @EventListener + public void onApplicationEvent(UserLoginEvent event) { + log.debug("用户1订阅:{}", event); + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9e20bc1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea/ +**/target/** +logs/ +*.iml diff --git a/README.md b/README.md new file mode 100644 index 0000000..2fdcd74 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# casic项目 V2.0.0 + +[^_^]: # (Talk is cheap,Show me the code!) + +## 介绍 +基于SpringBoot,致力于做更简洁的后台管理系统,完美整合springboot2.4 + shiro + mybatis-plus ! +基于casic项目代码简洁,注释丰富,上手容易,同时包含许多基础模块(用户管理,角色管理,部门管理,字典管理等10个模块) +可以直接作为一个后台管理系统的脚手架! 2022目标 `更简洁`,`更规范`! + + +#### 其他 +>* [git地址](http://192.168.0.203:8080/gitbucket) +>* [本地免登地址](http://localhost:8083/route/mockToken) diff --git a/casic-server/pom.xml b/casic-server/pom.xml new file mode 100644 index 0000000..c150a12 --- /dev/null +++ b/casic-server/pom.xml @@ -0,0 +1,70 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + 2.0.0 + ../pom.xml + + + casic-server + 2.0.0 + jar + casic-server + casic 的spring boot版本 + + + + + com.casic + casic-core + ${core.version} + provided + + + com.casic + casic-admin-support + ${admin.version} + provided + + + org.springframework.boot + spring-boot-starter-web + ${boot.version} + provided + + + + + com.hikvision.ga + artemis-http-client + 1.1.3 + + + commons-io + commons-io + + + org.springframework.boot + spring-boot-starter-websocket + 2.4.5 + + + io.netty + netty-all + 4.1.42.Final + + + + + + src/main/java + + **/*.xml + + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java new file mode 100644 index 0000000..3a60b9e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java @@ -0,0 +1,36 @@ +package com.casic.missiles.modular.async; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.TaskExecutor; +import org.springframework.scheduling.annotation.AsyncConfigurer; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadPoolExecutor; + +@Configuration +@EnableAsync +public class AsyncConfig implements AsyncConfigurer { + @Override + public Executor getAsyncExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + //核心线程数 + executor.setCorePoolSize(5); + //最大线程数 + executor.setMaxPoolSize(10); + //队列容量 + executor.setQueueCapacity(20); + //设置线程活跃时间(秒) + executor.setKeepAliveSeconds(60); + //默认线程名称 + executor.setThreadNamePrefix("user-rpt-"); + //拒绝策略 + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + //等待所有任务结束后再关闭线程池 + executor.setWaitForTasksToCompleteOnShutdown(true); + return executor; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java new file mode 100644 index 0000000..8ca554c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java @@ -0,0 +1,18 @@ +package com.casic.missiles.modular.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +// tomcat启动无需配置 +@Configuration +public class WebSocketConfig { + /** + * 注入ServerEndpointExporter, + * 这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint + */ + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java new file mode 100644 index 0000000..34fe2cd --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java @@ -0,0 +1,39 @@ +package com.casic.missiles.modular.controller; + + +import com.casic.missiles.model.application.event.core.EventPublisher; +import com.casic.missiles.model.application.event.enums.ModelEventTypeEnum; +import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.modular.event.UserEvent; +import com.casic.missiles.modular.system.model.User; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +/** + * @Description: DemoController + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@RestController +@RequestMapping("/demo") +public class DemoController { + @Autowired + private EventPublisher publisher; + + /** + * 获取mockToken + */ + @PostMapping("/list") + @ResponseBody + public Object list() { + User user = new User(); + user.setAccount("张三"); + publisher.publishEvent(new UserEvent(ModelEventTypeEnum.ADD, user)); + return ResponseData.success(); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java new file mode 100644 index 0000000..aff2889 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java @@ -0,0 +1,23 @@ +package com.casic.missiles.modular.event; + +import com.casic.missiles.model.application.event.core.ModelEvent; +import com.casic.missiles.model.application.event.type.AbstractEventTypeEnum; +import com.casic.missiles.modular.system.model.User; + +/** + * @Description: 用户事件 + * @Author: wangpeng + * @Date: 2022/7/17 11:23 + */ +public class UserEvent extends ModelEvent { + /** + * Create a new {@code ApplicationEvent}. + * + * @param type 事件类型 + * @param source the object on which the event initially occurred or with + * which the event is associated (never {@code null}) + */ + public UserEvent(AbstractEventTypeEnum type, User source) { + super(type, source); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java new file mode 100644 index 0000000..8f9603e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.core.application.event.UserLoginEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserOneListener { + @EventListener + public void onApplicationEvent(UserLoginEvent event) { + log.debug("用户1订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java new file mode 100644 index 0000000..0bd52a3 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.model.application.event.core.EventSubscriber; +import com.casic.missiles.modular.event.UserEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserTwoListener extends EventSubscriber { + @Override + public void onApplicationEvent(UserEvent event) { + log.debug("用户2订阅:{}", event); + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9e20bc1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea/ +**/target/** +logs/ +*.iml diff --git a/README.md b/README.md new file mode 100644 index 0000000..2fdcd74 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# casic项目 V2.0.0 + +[^_^]: # (Talk is cheap,Show me the code!) + +## 介绍 +基于SpringBoot,致力于做更简洁的后台管理系统,完美整合springboot2.4 + shiro + mybatis-plus ! +基于casic项目代码简洁,注释丰富,上手容易,同时包含许多基础模块(用户管理,角色管理,部门管理,字典管理等10个模块) +可以直接作为一个后台管理系统的脚手架! 2022目标 `更简洁`,`更规范`! + + +#### 其他 +>* [git地址](http://192.168.0.203:8080/gitbucket) +>* [本地免登地址](http://localhost:8083/route/mockToken) diff --git a/casic-server/pom.xml b/casic-server/pom.xml new file mode 100644 index 0000000..c150a12 --- /dev/null +++ b/casic-server/pom.xml @@ -0,0 +1,70 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + 2.0.0 + ../pom.xml + + + casic-server + 2.0.0 + jar + casic-server + casic 的spring boot版本 + + + + + com.casic + casic-core + ${core.version} + provided + + + com.casic + casic-admin-support + ${admin.version} + provided + + + org.springframework.boot + spring-boot-starter-web + ${boot.version} + provided + + + + + com.hikvision.ga + artemis-http-client + 1.1.3 + + + commons-io + commons-io + + + org.springframework.boot + spring-boot-starter-websocket + 2.4.5 + + + io.netty + netty-all + 4.1.42.Final + + + + + + src/main/java + + **/*.xml + + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java new file mode 100644 index 0000000..3a60b9e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java @@ -0,0 +1,36 @@ +package com.casic.missiles.modular.async; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.TaskExecutor; +import org.springframework.scheduling.annotation.AsyncConfigurer; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadPoolExecutor; + +@Configuration +@EnableAsync +public class AsyncConfig implements AsyncConfigurer { + @Override + public Executor getAsyncExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + //核心线程数 + executor.setCorePoolSize(5); + //最大线程数 + executor.setMaxPoolSize(10); + //队列容量 + executor.setQueueCapacity(20); + //设置线程活跃时间(秒) + executor.setKeepAliveSeconds(60); + //默认线程名称 + executor.setThreadNamePrefix("user-rpt-"); + //拒绝策略 + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + //等待所有任务结束后再关闭线程池 + executor.setWaitForTasksToCompleteOnShutdown(true); + return executor; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java new file mode 100644 index 0000000..8ca554c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java @@ -0,0 +1,18 @@ +package com.casic.missiles.modular.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +// tomcat启动无需配置 +@Configuration +public class WebSocketConfig { + /** + * 注入ServerEndpointExporter, + * 这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint + */ + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java new file mode 100644 index 0000000..34fe2cd --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java @@ -0,0 +1,39 @@ +package com.casic.missiles.modular.controller; + + +import com.casic.missiles.model.application.event.core.EventPublisher; +import com.casic.missiles.model.application.event.enums.ModelEventTypeEnum; +import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.modular.event.UserEvent; +import com.casic.missiles.modular.system.model.User; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +/** + * @Description: DemoController + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@RestController +@RequestMapping("/demo") +public class DemoController { + @Autowired + private EventPublisher publisher; + + /** + * 获取mockToken + */ + @PostMapping("/list") + @ResponseBody + public Object list() { + User user = new User(); + user.setAccount("张三"); + publisher.publishEvent(new UserEvent(ModelEventTypeEnum.ADD, user)); + return ResponseData.success(); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java new file mode 100644 index 0000000..aff2889 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java @@ -0,0 +1,23 @@ +package com.casic.missiles.modular.event; + +import com.casic.missiles.model.application.event.core.ModelEvent; +import com.casic.missiles.model.application.event.type.AbstractEventTypeEnum; +import com.casic.missiles.modular.system.model.User; + +/** + * @Description: 用户事件 + * @Author: wangpeng + * @Date: 2022/7/17 11:23 + */ +public class UserEvent extends ModelEvent { + /** + * Create a new {@code ApplicationEvent}. + * + * @param type 事件类型 + * @param source the object on which the event initially occurred or with + * which the event is associated (never {@code null}) + */ + public UserEvent(AbstractEventTypeEnum type, User source) { + super(type, source); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java new file mode 100644 index 0000000..8f9603e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.core.application.event.UserLoginEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserOneListener { + @EventListener + public void onApplicationEvent(UserLoginEvent event) { + log.debug("用户1订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java new file mode 100644 index 0000000..0bd52a3 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.model.application.event.core.EventSubscriber; +import com.casic.missiles.modular.event.UserEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserTwoListener extends EventSubscriber { + @Override + public void onApplicationEvent(UserEvent event) { + log.debug("用户2订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java new file mode 100644 index 0000000..4012170 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java @@ -0,0 +1,88 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang3.StringUtils; +import sun.misc.BASE64Decoder; + +import java.io.*; + +public class Base64Util { + /** + * base64字符串转换成图片 + * + * @param imgStr base64字符串 + * @param imgFilePath 图片存放路径 + * @return + * @author ZHANGJL + * @dateTime 2018-02-23 14:42:17 + */ + public static boolean Base64ToImage(String imgStr, String imgFilePath, String fileDir) { // 对字节数组字符串进行Base64解码并生成图片 + + if (StringUtils.isEmpty(imgStr)) // 图像数据为空 + return false; + + imgStr = imgStr.substring(imgStr.indexOf(",") + 1); + + BASE64Decoder decoder = new BASE64Decoder(); + try { + // Base64解码 + byte[] b = decoder.decodeBuffer(imgStr); + + for (int i = 0; i < b.length; ++i) { + if (b[i] < 0) {// 调整异常数据 + b[i] += 256; + } + } + //如果已存在图像,先删除 + File file = new File(fileDir+File.separator + imgFilePath); + if (file.exists() && file.isFile()) { + file.delete(); + } + File dir = new File(fileDir); + if (!dir.exists()) { + dir.mkdirs(); + } + file = new File(fileDir+File.separator+imgFilePath); + file.createNewFile(); +// ImageIO.write(bImage, "bmp", name); + OutputStream out = new FileOutputStream(fileDir+File.separator+imgFilePath); + out.write(b); + out.flush(); + out.close(); + + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + + } + + public static String getBase64FromInputStream(InputStream in) { + // 将图片文件转化为字节数组字符串,并对其进行Base64编码处理 + byte[] data = null; + // 读取图片字节数组 + try { + ByteArrayOutputStream swapStream = new ByteArrayOutputStream(); + byte[] buff = new byte[100]; + int rc = 0; + while ((rc = in.read(buff, 0, 100)) > 0) { + swapStream.write(buff, 0, rc); + } + data = swapStream.toByteArray(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return new String(Base64.encodeBase64(data)); + } + + +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9e20bc1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea/ +**/target/** +logs/ +*.iml diff --git a/README.md b/README.md new file mode 100644 index 0000000..2fdcd74 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# casic项目 V2.0.0 + +[^_^]: # (Talk is cheap,Show me the code!) + +## 介绍 +基于SpringBoot,致力于做更简洁的后台管理系统,完美整合springboot2.4 + shiro + mybatis-plus ! +基于casic项目代码简洁,注释丰富,上手容易,同时包含许多基础模块(用户管理,角色管理,部门管理,字典管理等10个模块) +可以直接作为一个后台管理系统的脚手架! 2022目标 `更简洁`,`更规范`! + + +#### 其他 +>* [git地址](http://192.168.0.203:8080/gitbucket) +>* [本地免登地址](http://localhost:8083/route/mockToken) diff --git a/casic-server/pom.xml b/casic-server/pom.xml new file mode 100644 index 0000000..c150a12 --- /dev/null +++ b/casic-server/pom.xml @@ -0,0 +1,70 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + 2.0.0 + ../pom.xml + + + casic-server + 2.0.0 + jar + casic-server + casic 的spring boot版本 + + + + + com.casic + casic-core + ${core.version} + provided + + + com.casic + casic-admin-support + ${admin.version} + provided + + + org.springframework.boot + spring-boot-starter-web + ${boot.version} + provided + + + + + com.hikvision.ga + artemis-http-client + 1.1.3 + + + commons-io + commons-io + + + org.springframework.boot + spring-boot-starter-websocket + 2.4.5 + + + io.netty + netty-all + 4.1.42.Final + + + + + + src/main/java + + **/*.xml + + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java new file mode 100644 index 0000000..3a60b9e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java @@ -0,0 +1,36 @@ +package com.casic.missiles.modular.async; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.TaskExecutor; +import org.springframework.scheduling.annotation.AsyncConfigurer; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadPoolExecutor; + +@Configuration +@EnableAsync +public class AsyncConfig implements AsyncConfigurer { + @Override + public Executor getAsyncExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + //核心线程数 + executor.setCorePoolSize(5); + //最大线程数 + executor.setMaxPoolSize(10); + //队列容量 + executor.setQueueCapacity(20); + //设置线程活跃时间(秒) + executor.setKeepAliveSeconds(60); + //默认线程名称 + executor.setThreadNamePrefix("user-rpt-"); + //拒绝策略 + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + //等待所有任务结束后再关闭线程池 + executor.setWaitForTasksToCompleteOnShutdown(true); + return executor; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java new file mode 100644 index 0000000..8ca554c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java @@ -0,0 +1,18 @@ +package com.casic.missiles.modular.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +// tomcat启动无需配置 +@Configuration +public class WebSocketConfig { + /** + * 注入ServerEndpointExporter, + * 这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint + */ + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java new file mode 100644 index 0000000..34fe2cd --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java @@ -0,0 +1,39 @@ +package com.casic.missiles.modular.controller; + + +import com.casic.missiles.model.application.event.core.EventPublisher; +import com.casic.missiles.model.application.event.enums.ModelEventTypeEnum; +import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.modular.event.UserEvent; +import com.casic.missiles.modular.system.model.User; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +/** + * @Description: DemoController + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@RestController +@RequestMapping("/demo") +public class DemoController { + @Autowired + private EventPublisher publisher; + + /** + * 获取mockToken + */ + @PostMapping("/list") + @ResponseBody + public Object list() { + User user = new User(); + user.setAccount("张三"); + publisher.publishEvent(new UserEvent(ModelEventTypeEnum.ADD, user)); + return ResponseData.success(); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java new file mode 100644 index 0000000..aff2889 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java @@ -0,0 +1,23 @@ +package com.casic.missiles.modular.event; + +import com.casic.missiles.model.application.event.core.ModelEvent; +import com.casic.missiles.model.application.event.type.AbstractEventTypeEnum; +import com.casic.missiles.modular.system.model.User; + +/** + * @Description: 用户事件 + * @Author: wangpeng + * @Date: 2022/7/17 11:23 + */ +public class UserEvent extends ModelEvent { + /** + * Create a new {@code ApplicationEvent}. + * + * @param type 事件类型 + * @param source the object on which the event initially occurred or with + * which the event is associated (never {@code null}) + */ + public UserEvent(AbstractEventTypeEnum type, User source) { + super(type, source); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java new file mode 100644 index 0000000..8f9603e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.core.application.event.UserLoginEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserOneListener { + @EventListener + public void onApplicationEvent(UserLoginEvent event) { + log.debug("用户1订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java new file mode 100644 index 0000000..0bd52a3 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.model.application.event.core.EventSubscriber; +import com.casic.missiles.modular.event.UserEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserTwoListener extends EventSubscriber { + @Override + public void onApplicationEvent(UserEvent event) { + log.debug("用户2订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java new file mode 100644 index 0000000..4012170 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java @@ -0,0 +1,88 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang3.StringUtils; +import sun.misc.BASE64Decoder; + +import java.io.*; + +public class Base64Util { + /** + * base64字符串转换成图片 + * + * @param imgStr base64字符串 + * @param imgFilePath 图片存放路径 + * @return + * @author ZHANGJL + * @dateTime 2018-02-23 14:42:17 + */ + public static boolean Base64ToImage(String imgStr, String imgFilePath, String fileDir) { // 对字节数组字符串进行Base64解码并生成图片 + + if (StringUtils.isEmpty(imgStr)) // 图像数据为空 + return false; + + imgStr = imgStr.substring(imgStr.indexOf(",") + 1); + + BASE64Decoder decoder = new BASE64Decoder(); + try { + // Base64解码 + byte[] b = decoder.decodeBuffer(imgStr); + + for (int i = 0; i < b.length; ++i) { + if (b[i] < 0) {// 调整异常数据 + b[i] += 256; + } + } + //如果已存在图像,先删除 + File file = new File(fileDir+File.separator + imgFilePath); + if (file.exists() && file.isFile()) { + file.delete(); + } + File dir = new File(fileDir); + if (!dir.exists()) { + dir.mkdirs(); + } + file = new File(fileDir+File.separator+imgFilePath); + file.createNewFile(); +// ImageIO.write(bImage, "bmp", name); + OutputStream out = new FileOutputStream(fileDir+File.separator+imgFilePath); + out.write(b); + out.flush(); + out.close(); + + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + + } + + public static String getBase64FromInputStream(InputStream in) { + // 将图片文件转化为字节数组字符串,并对其进行Base64编码处理 + byte[] data = null; + // 读取图片字节数组 + try { + ByteArrayOutputStream swapStream = new ByteArrayOutputStream(); + byte[] buff = new byte[100]; + int rc = 0; + while ((rc = in.read(buff, 0, 100)) > 0) { + swapStream.write(buff, 0, rc); + } + data = swapStream.toByteArray(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return new String(Base64.encodeBase64(data)); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java new file mode 100644 index 0000000..9c93895 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java @@ -0,0 +1,75 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.lang3.StringUtils; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class CommonUtil { + + public static String CutId(String id) { + return id.substring(6, 10) + "-" + id.substring(10, 12) + "-" + id.substring(12, 14); + } + + public static boolean isIDNumber(String IDNumber) { + if (IDNumber == null || "".equals(IDNumber)) { + return false; + } + // 定义判别用户身份证号的正则表达式(15位或者18位,最后一位可以为字母) + String regularExpression = + "(^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|" + + "(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}$)"; + boolean matches = IDNumber.matches(regularExpression); + // 判断第18位校验值 + if (matches) { + if (IDNumber.length() == 18) { + try { + char[] charArray = IDNumber.toCharArray(); + // 前十七位加权因子 + int[] idCardWi = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; + // 这是除以11后,可能产生的11位余数对应的验证码 + String[] idCardY = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"}; + int sum = 0; + for (int i = 0; i < idCardWi.length; i++) { + int current = Integer.parseInt(String.valueOf(charArray[i])); + int count = current * idCardWi[i]; + sum += count; + } + char idCardLast = charArray[17]; + int idCardMod = sum % 11; + if (idCardY[idCardMod].toUpperCase() + .equals(String.valueOf(idCardLast).toUpperCase())) { + return true; + } else { + System.out.println("身份证最后一位:" + String.valueOf(idCardLast).toUpperCase() + + "错误,正确的应该是:" + idCardY[idCardMod].toUpperCase()); + return false; + } + + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } else { + return false; + } + } + return matches; + } + + + public static boolean CheckMobilePhoneNum(String phoneNum) { + if (StringUtils.isEmpty(phoneNum)) + return true; + String regex = "^(1[3-9]\\d{9}$)"; + if (phoneNum.length() == 11) { + Pattern p = Pattern.compile(regex); + Matcher m = p.matcher(phoneNum); + if (m.matches()) { + return true; + } + } + return false; + } + +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9e20bc1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea/ +**/target/** +logs/ +*.iml diff --git a/README.md b/README.md new file mode 100644 index 0000000..2fdcd74 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# casic项目 V2.0.0 + +[^_^]: # (Talk is cheap,Show me the code!) + +## 介绍 +基于SpringBoot,致力于做更简洁的后台管理系统,完美整合springboot2.4 + shiro + mybatis-plus ! +基于casic项目代码简洁,注释丰富,上手容易,同时包含许多基础模块(用户管理,角色管理,部门管理,字典管理等10个模块) +可以直接作为一个后台管理系统的脚手架! 2022目标 `更简洁`,`更规范`! + + +#### 其他 +>* [git地址](http://192.168.0.203:8080/gitbucket) +>* [本地免登地址](http://localhost:8083/route/mockToken) diff --git a/casic-server/pom.xml b/casic-server/pom.xml new file mode 100644 index 0000000..c150a12 --- /dev/null +++ b/casic-server/pom.xml @@ -0,0 +1,70 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + 2.0.0 + ../pom.xml + + + casic-server + 2.0.0 + jar + casic-server + casic 的spring boot版本 + + + + + com.casic + casic-core + ${core.version} + provided + + + com.casic + casic-admin-support + ${admin.version} + provided + + + org.springframework.boot + spring-boot-starter-web + ${boot.version} + provided + + + + + com.hikvision.ga + artemis-http-client + 1.1.3 + + + commons-io + commons-io + + + org.springframework.boot + spring-boot-starter-websocket + 2.4.5 + + + io.netty + netty-all + 4.1.42.Final + + + + + + src/main/java + + **/*.xml + + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java new file mode 100644 index 0000000..3a60b9e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java @@ -0,0 +1,36 @@ +package com.casic.missiles.modular.async; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.TaskExecutor; +import org.springframework.scheduling.annotation.AsyncConfigurer; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadPoolExecutor; + +@Configuration +@EnableAsync +public class AsyncConfig implements AsyncConfigurer { + @Override + public Executor getAsyncExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + //核心线程数 + executor.setCorePoolSize(5); + //最大线程数 + executor.setMaxPoolSize(10); + //队列容量 + executor.setQueueCapacity(20); + //设置线程活跃时间(秒) + executor.setKeepAliveSeconds(60); + //默认线程名称 + executor.setThreadNamePrefix("user-rpt-"); + //拒绝策略 + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + //等待所有任务结束后再关闭线程池 + executor.setWaitForTasksToCompleteOnShutdown(true); + return executor; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java new file mode 100644 index 0000000..8ca554c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java @@ -0,0 +1,18 @@ +package com.casic.missiles.modular.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +// tomcat启动无需配置 +@Configuration +public class WebSocketConfig { + /** + * 注入ServerEndpointExporter, + * 这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint + */ + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java new file mode 100644 index 0000000..34fe2cd --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java @@ -0,0 +1,39 @@ +package com.casic.missiles.modular.controller; + + +import com.casic.missiles.model.application.event.core.EventPublisher; +import com.casic.missiles.model.application.event.enums.ModelEventTypeEnum; +import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.modular.event.UserEvent; +import com.casic.missiles.modular.system.model.User; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +/** + * @Description: DemoController + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@RestController +@RequestMapping("/demo") +public class DemoController { + @Autowired + private EventPublisher publisher; + + /** + * 获取mockToken + */ + @PostMapping("/list") + @ResponseBody + public Object list() { + User user = new User(); + user.setAccount("张三"); + publisher.publishEvent(new UserEvent(ModelEventTypeEnum.ADD, user)); + return ResponseData.success(); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java new file mode 100644 index 0000000..aff2889 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java @@ -0,0 +1,23 @@ +package com.casic.missiles.modular.event; + +import com.casic.missiles.model.application.event.core.ModelEvent; +import com.casic.missiles.model.application.event.type.AbstractEventTypeEnum; +import com.casic.missiles.modular.system.model.User; + +/** + * @Description: 用户事件 + * @Author: wangpeng + * @Date: 2022/7/17 11:23 + */ +public class UserEvent extends ModelEvent { + /** + * Create a new {@code ApplicationEvent}. + * + * @param type 事件类型 + * @param source the object on which the event initially occurred or with + * which the event is associated (never {@code null}) + */ + public UserEvent(AbstractEventTypeEnum type, User source) { + super(type, source); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java new file mode 100644 index 0000000..8f9603e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.core.application.event.UserLoginEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserOneListener { + @EventListener + public void onApplicationEvent(UserLoginEvent event) { + log.debug("用户1订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java new file mode 100644 index 0000000..0bd52a3 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.model.application.event.core.EventSubscriber; +import com.casic.missiles.modular.event.UserEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserTwoListener extends EventSubscriber { + @Override + public void onApplicationEvent(UserEvent event) { + log.debug("用户2订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java new file mode 100644 index 0000000..4012170 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java @@ -0,0 +1,88 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang3.StringUtils; +import sun.misc.BASE64Decoder; + +import java.io.*; + +public class Base64Util { + /** + * base64字符串转换成图片 + * + * @param imgStr base64字符串 + * @param imgFilePath 图片存放路径 + * @return + * @author ZHANGJL + * @dateTime 2018-02-23 14:42:17 + */ + public static boolean Base64ToImage(String imgStr, String imgFilePath, String fileDir) { // 对字节数组字符串进行Base64解码并生成图片 + + if (StringUtils.isEmpty(imgStr)) // 图像数据为空 + return false; + + imgStr = imgStr.substring(imgStr.indexOf(",") + 1); + + BASE64Decoder decoder = new BASE64Decoder(); + try { + // Base64解码 + byte[] b = decoder.decodeBuffer(imgStr); + + for (int i = 0; i < b.length; ++i) { + if (b[i] < 0) {// 调整异常数据 + b[i] += 256; + } + } + //如果已存在图像,先删除 + File file = new File(fileDir+File.separator + imgFilePath); + if (file.exists() && file.isFile()) { + file.delete(); + } + File dir = new File(fileDir); + if (!dir.exists()) { + dir.mkdirs(); + } + file = new File(fileDir+File.separator+imgFilePath); + file.createNewFile(); +// ImageIO.write(bImage, "bmp", name); + OutputStream out = new FileOutputStream(fileDir+File.separator+imgFilePath); + out.write(b); + out.flush(); + out.close(); + + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + + } + + public static String getBase64FromInputStream(InputStream in) { + // 将图片文件转化为字节数组字符串,并对其进行Base64编码处理 + byte[] data = null; + // 读取图片字节数组 + try { + ByteArrayOutputStream swapStream = new ByteArrayOutputStream(); + byte[] buff = new byte[100]; + int rc = 0; + while ((rc = in.read(buff, 0, 100)) > 0) { + swapStream.write(buff, 0, rc); + } + data = swapStream.toByteArray(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return new String(Base64.encodeBase64(data)); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java new file mode 100644 index 0000000..9c93895 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java @@ -0,0 +1,75 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.lang3.StringUtils; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class CommonUtil { + + public static String CutId(String id) { + return id.substring(6, 10) + "-" + id.substring(10, 12) + "-" + id.substring(12, 14); + } + + public static boolean isIDNumber(String IDNumber) { + if (IDNumber == null || "".equals(IDNumber)) { + return false; + } + // 定义判别用户身份证号的正则表达式(15位或者18位,最后一位可以为字母) + String regularExpression = + "(^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|" + + "(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}$)"; + boolean matches = IDNumber.matches(regularExpression); + // 判断第18位校验值 + if (matches) { + if (IDNumber.length() == 18) { + try { + char[] charArray = IDNumber.toCharArray(); + // 前十七位加权因子 + int[] idCardWi = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; + // 这是除以11后,可能产生的11位余数对应的验证码 + String[] idCardY = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"}; + int sum = 0; + for (int i = 0; i < idCardWi.length; i++) { + int current = Integer.parseInt(String.valueOf(charArray[i])); + int count = current * idCardWi[i]; + sum += count; + } + char idCardLast = charArray[17]; + int idCardMod = sum % 11; + if (idCardY[idCardMod].toUpperCase() + .equals(String.valueOf(idCardLast).toUpperCase())) { + return true; + } else { + System.out.println("身份证最后一位:" + String.valueOf(idCardLast).toUpperCase() + + "错误,正确的应该是:" + idCardY[idCardMod].toUpperCase()); + return false; + } + + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } else { + return false; + } + } + return matches; + } + + + public static boolean CheckMobilePhoneNum(String phoneNum) { + if (StringUtils.isEmpty(phoneNum)) + return true; + String regex = "^(1[3-9]\\d{9}$)"; + if (phoneNum.length() == 11) { + Pattern p = Pattern.compile(regex); + Matcher m = p.matcher(phoneNum); + if (m.matches()) { + return true; + } + } + return false; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java new file mode 100644 index 0000000..191ef79 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java @@ -0,0 +1,116 @@ +package com.casic.missiles.modular.util; + + +import javafx.util.Pair; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +/** + * Created by Administrator on 2015/2/25. + */ +public class DateUtils { + public static SimpleDateFormat sdf_day = new SimpleDateFormat("yyyy-MM-dd"); + public static SimpleDateFormat sdf_day_time = new SimpleDateFormat("yyyyMMddhhmmss"); + public static final SimpleDateFormat sdf4 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + public static final SimpleDateFormat sdf5 = new SimpleDateFormat("HH:mm:ss"); + + + /** + * 获取当年的第一天 + * + * @return + */ + public static Date getCurrYearFirst() { + Calendar currCal = Calendar.getInstance(); + int currentYear = currCal.get(Calendar.YEAR); + return getYearFirst(currentYear); + } + + + /** + * 获取某年第一天日期 + * + * @param year 年份 + * @return Date + */ + public static Date getYearFirst(int year) { + Calendar calendar = Calendar.getInstance(); + calendar.clear(); + calendar.set(Calendar.YEAR, year); + Date currYearFirst = calendar.getTime(); + return currYearFirst; + } + + /** + * 最近7日(不包括今日) + */ + public static Pair getLastSevenDays() { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, -7); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 最近n日(不包括今日) + */ + public static Pair getLastNDays(int n) { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, n * -1); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 日期时间加n天 + */ + public static String addDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf4.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf4.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 日期加n天 + */ + public static String addNDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf_day.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf_day.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 昨日 + */ + public static String getYesterday() { + + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.DATE, -2); + return sdf_day.format(calendar.getTime()); + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9e20bc1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea/ +**/target/** +logs/ +*.iml diff --git a/README.md b/README.md new file mode 100644 index 0000000..2fdcd74 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# casic项目 V2.0.0 + +[^_^]: # (Talk is cheap,Show me the code!) + +## 介绍 +基于SpringBoot,致力于做更简洁的后台管理系统,完美整合springboot2.4 + shiro + mybatis-plus ! +基于casic项目代码简洁,注释丰富,上手容易,同时包含许多基础模块(用户管理,角色管理,部门管理,字典管理等10个模块) +可以直接作为一个后台管理系统的脚手架! 2022目标 `更简洁`,`更规范`! + + +#### 其他 +>* [git地址](http://192.168.0.203:8080/gitbucket) +>* [本地免登地址](http://localhost:8083/route/mockToken) diff --git a/casic-server/pom.xml b/casic-server/pom.xml new file mode 100644 index 0000000..c150a12 --- /dev/null +++ b/casic-server/pom.xml @@ -0,0 +1,70 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + 2.0.0 + ../pom.xml + + + casic-server + 2.0.0 + jar + casic-server + casic 的spring boot版本 + + + + + com.casic + casic-core + ${core.version} + provided + + + com.casic + casic-admin-support + ${admin.version} + provided + + + org.springframework.boot + spring-boot-starter-web + ${boot.version} + provided + + + + + com.hikvision.ga + artemis-http-client + 1.1.3 + + + commons-io + commons-io + + + org.springframework.boot + spring-boot-starter-websocket + 2.4.5 + + + io.netty + netty-all + 4.1.42.Final + + + + + + src/main/java + + **/*.xml + + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java new file mode 100644 index 0000000..3a60b9e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java @@ -0,0 +1,36 @@ +package com.casic.missiles.modular.async; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.TaskExecutor; +import org.springframework.scheduling.annotation.AsyncConfigurer; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadPoolExecutor; + +@Configuration +@EnableAsync +public class AsyncConfig implements AsyncConfigurer { + @Override + public Executor getAsyncExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + //核心线程数 + executor.setCorePoolSize(5); + //最大线程数 + executor.setMaxPoolSize(10); + //队列容量 + executor.setQueueCapacity(20); + //设置线程活跃时间(秒) + executor.setKeepAliveSeconds(60); + //默认线程名称 + executor.setThreadNamePrefix("user-rpt-"); + //拒绝策略 + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + //等待所有任务结束后再关闭线程池 + executor.setWaitForTasksToCompleteOnShutdown(true); + return executor; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java new file mode 100644 index 0000000..8ca554c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java @@ -0,0 +1,18 @@ +package com.casic.missiles.modular.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +// tomcat启动无需配置 +@Configuration +public class WebSocketConfig { + /** + * 注入ServerEndpointExporter, + * 这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint + */ + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java new file mode 100644 index 0000000..34fe2cd --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java @@ -0,0 +1,39 @@ +package com.casic.missiles.modular.controller; + + +import com.casic.missiles.model.application.event.core.EventPublisher; +import com.casic.missiles.model.application.event.enums.ModelEventTypeEnum; +import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.modular.event.UserEvent; +import com.casic.missiles.modular.system.model.User; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +/** + * @Description: DemoController + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@RestController +@RequestMapping("/demo") +public class DemoController { + @Autowired + private EventPublisher publisher; + + /** + * 获取mockToken + */ + @PostMapping("/list") + @ResponseBody + public Object list() { + User user = new User(); + user.setAccount("张三"); + publisher.publishEvent(new UserEvent(ModelEventTypeEnum.ADD, user)); + return ResponseData.success(); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java new file mode 100644 index 0000000..aff2889 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java @@ -0,0 +1,23 @@ +package com.casic.missiles.modular.event; + +import com.casic.missiles.model.application.event.core.ModelEvent; +import com.casic.missiles.model.application.event.type.AbstractEventTypeEnum; +import com.casic.missiles.modular.system.model.User; + +/** + * @Description: 用户事件 + * @Author: wangpeng + * @Date: 2022/7/17 11:23 + */ +public class UserEvent extends ModelEvent { + /** + * Create a new {@code ApplicationEvent}. + * + * @param type 事件类型 + * @param source the object on which the event initially occurred or with + * which the event is associated (never {@code null}) + */ + public UserEvent(AbstractEventTypeEnum type, User source) { + super(type, source); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java new file mode 100644 index 0000000..8f9603e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.core.application.event.UserLoginEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserOneListener { + @EventListener + public void onApplicationEvent(UserLoginEvent event) { + log.debug("用户1订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java new file mode 100644 index 0000000..0bd52a3 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.model.application.event.core.EventSubscriber; +import com.casic.missiles.modular.event.UserEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserTwoListener extends EventSubscriber { + @Override + public void onApplicationEvent(UserEvent event) { + log.debug("用户2订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java new file mode 100644 index 0000000..4012170 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java @@ -0,0 +1,88 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang3.StringUtils; +import sun.misc.BASE64Decoder; + +import java.io.*; + +public class Base64Util { + /** + * base64字符串转换成图片 + * + * @param imgStr base64字符串 + * @param imgFilePath 图片存放路径 + * @return + * @author ZHANGJL + * @dateTime 2018-02-23 14:42:17 + */ + public static boolean Base64ToImage(String imgStr, String imgFilePath, String fileDir) { // 对字节数组字符串进行Base64解码并生成图片 + + if (StringUtils.isEmpty(imgStr)) // 图像数据为空 + return false; + + imgStr = imgStr.substring(imgStr.indexOf(",") + 1); + + BASE64Decoder decoder = new BASE64Decoder(); + try { + // Base64解码 + byte[] b = decoder.decodeBuffer(imgStr); + + for (int i = 0; i < b.length; ++i) { + if (b[i] < 0) {// 调整异常数据 + b[i] += 256; + } + } + //如果已存在图像,先删除 + File file = new File(fileDir+File.separator + imgFilePath); + if (file.exists() && file.isFile()) { + file.delete(); + } + File dir = new File(fileDir); + if (!dir.exists()) { + dir.mkdirs(); + } + file = new File(fileDir+File.separator+imgFilePath); + file.createNewFile(); +// ImageIO.write(bImage, "bmp", name); + OutputStream out = new FileOutputStream(fileDir+File.separator+imgFilePath); + out.write(b); + out.flush(); + out.close(); + + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + + } + + public static String getBase64FromInputStream(InputStream in) { + // 将图片文件转化为字节数组字符串,并对其进行Base64编码处理 + byte[] data = null; + // 读取图片字节数组 + try { + ByteArrayOutputStream swapStream = new ByteArrayOutputStream(); + byte[] buff = new byte[100]; + int rc = 0; + while ((rc = in.read(buff, 0, 100)) > 0) { + swapStream.write(buff, 0, rc); + } + data = swapStream.toByteArray(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return new String(Base64.encodeBase64(data)); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java new file mode 100644 index 0000000..9c93895 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java @@ -0,0 +1,75 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.lang3.StringUtils; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class CommonUtil { + + public static String CutId(String id) { + return id.substring(6, 10) + "-" + id.substring(10, 12) + "-" + id.substring(12, 14); + } + + public static boolean isIDNumber(String IDNumber) { + if (IDNumber == null || "".equals(IDNumber)) { + return false; + } + // 定义判别用户身份证号的正则表达式(15位或者18位,最后一位可以为字母) + String regularExpression = + "(^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|" + + "(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}$)"; + boolean matches = IDNumber.matches(regularExpression); + // 判断第18位校验值 + if (matches) { + if (IDNumber.length() == 18) { + try { + char[] charArray = IDNumber.toCharArray(); + // 前十七位加权因子 + int[] idCardWi = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; + // 这是除以11后,可能产生的11位余数对应的验证码 + String[] idCardY = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"}; + int sum = 0; + for (int i = 0; i < idCardWi.length; i++) { + int current = Integer.parseInt(String.valueOf(charArray[i])); + int count = current * idCardWi[i]; + sum += count; + } + char idCardLast = charArray[17]; + int idCardMod = sum % 11; + if (idCardY[idCardMod].toUpperCase() + .equals(String.valueOf(idCardLast).toUpperCase())) { + return true; + } else { + System.out.println("身份证最后一位:" + String.valueOf(idCardLast).toUpperCase() + + "错误,正确的应该是:" + idCardY[idCardMod].toUpperCase()); + return false; + } + + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } else { + return false; + } + } + return matches; + } + + + public static boolean CheckMobilePhoneNum(String phoneNum) { + if (StringUtils.isEmpty(phoneNum)) + return true; + String regex = "^(1[3-9]\\d{9}$)"; + if (phoneNum.length() == 11) { + Pattern p = Pattern.compile(regex); + Matcher m = p.matcher(phoneNum); + if (m.matches()) { + return true; + } + } + return false; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java new file mode 100644 index 0000000..191ef79 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java @@ -0,0 +1,116 @@ +package com.casic.missiles.modular.util; + + +import javafx.util.Pair; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +/** + * Created by Administrator on 2015/2/25. + */ +public class DateUtils { + public static SimpleDateFormat sdf_day = new SimpleDateFormat("yyyy-MM-dd"); + public static SimpleDateFormat sdf_day_time = new SimpleDateFormat("yyyyMMddhhmmss"); + public static final SimpleDateFormat sdf4 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + public static final SimpleDateFormat sdf5 = new SimpleDateFormat("HH:mm:ss"); + + + /** + * 获取当年的第一天 + * + * @return + */ + public static Date getCurrYearFirst() { + Calendar currCal = Calendar.getInstance(); + int currentYear = currCal.get(Calendar.YEAR); + return getYearFirst(currentYear); + } + + + /** + * 获取某年第一天日期 + * + * @param year 年份 + * @return Date + */ + public static Date getYearFirst(int year) { + Calendar calendar = Calendar.getInstance(); + calendar.clear(); + calendar.set(Calendar.YEAR, year); + Date currYearFirst = calendar.getTime(); + return currYearFirst; + } + + /** + * 最近7日(不包括今日) + */ + public static Pair getLastSevenDays() { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, -7); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 最近n日(不包括今日) + */ + public static Pair getLastNDays(int n) { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, n * -1); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 日期时间加n天 + */ + public static String addDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf4.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf4.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 日期加n天 + */ + public static String addNDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf_day.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf_day.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 昨日 + */ + public static String getYesterday() { + + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.DATE, -2); + return sdf_day.format(calendar.getTime()); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java new file mode 100644 index 0000000..da0f8ee --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java @@ -0,0 +1,49 @@ +package com.casic.missiles.modular.util; + +import com.hikvision.artemis.sdk.ArtemisHttpUtil; +import com.hikvision.artemis.sdk.config.ArtemisConfig; + +import java.util.HashMap; +import java.util.Map; + +public class HikUtil { + + public static String hikApi(String uri, String body) { + + /** + * STEP1:设置平台参数,根据实际情况,设置host appkey appsecret 三个参数. + */ + ArtemisConfig.host = "192.168.1.22:443"; // artemis网关服务器ip端口 + ArtemisConfig.appKey = "25766251"; // 秘钥appkey + ArtemisConfig.appSecret = "h2o6zXtzCmt8eaOaMkXb";// 秘钥appSecret + + /** + * STEP2:设置OpenAPI接口的上下文 + */ + final String ARTEMIS_PATH = "/artemis"; + + /** + * STEP3:设置接口的URI地址 + */ + final String previewURLsApi = ARTEMIS_PATH + uri; + Map path = new HashMap(2) { + { + put("https://", previewURLsApi);//根据现场环境部署确认是http还是https + } + }; + + /** + * STEP4:设置参数提交方式 + */ + String contentType = "application/json"; + + /** + * STEP5:组装请求参数 + */ + /** + * STEP6:调用接口 + */ + String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, contentType, null);// post请求application/json类型参数 + return result; + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9e20bc1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea/ +**/target/** +logs/ +*.iml diff --git a/README.md b/README.md new file mode 100644 index 0000000..2fdcd74 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# casic项目 V2.0.0 + +[^_^]: # (Talk is cheap,Show me the code!) + +## 介绍 +基于SpringBoot,致力于做更简洁的后台管理系统,完美整合springboot2.4 + shiro + mybatis-plus ! +基于casic项目代码简洁,注释丰富,上手容易,同时包含许多基础模块(用户管理,角色管理,部门管理,字典管理等10个模块) +可以直接作为一个后台管理系统的脚手架! 2022目标 `更简洁`,`更规范`! + + +#### 其他 +>* [git地址](http://192.168.0.203:8080/gitbucket) +>* [本地免登地址](http://localhost:8083/route/mockToken) diff --git a/casic-server/pom.xml b/casic-server/pom.xml new file mode 100644 index 0000000..c150a12 --- /dev/null +++ b/casic-server/pom.xml @@ -0,0 +1,70 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + 2.0.0 + ../pom.xml + + + casic-server + 2.0.0 + jar + casic-server + casic 的spring boot版本 + + + + + com.casic + casic-core + ${core.version} + provided + + + com.casic + casic-admin-support + ${admin.version} + provided + + + org.springframework.boot + spring-boot-starter-web + ${boot.version} + provided + + + + + com.hikvision.ga + artemis-http-client + 1.1.3 + + + commons-io + commons-io + + + org.springframework.boot + spring-boot-starter-websocket + 2.4.5 + + + io.netty + netty-all + 4.1.42.Final + + + + + + src/main/java + + **/*.xml + + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java new file mode 100644 index 0000000..3a60b9e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java @@ -0,0 +1,36 @@ +package com.casic.missiles.modular.async; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.TaskExecutor; +import org.springframework.scheduling.annotation.AsyncConfigurer; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadPoolExecutor; + +@Configuration +@EnableAsync +public class AsyncConfig implements AsyncConfigurer { + @Override + public Executor getAsyncExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + //核心线程数 + executor.setCorePoolSize(5); + //最大线程数 + executor.setMaxPoolSize(10); + //队列容量 + executor.setQueueCapacity(20); + //设置线程活跃时间(秒) + executor.setKeepAliveSeconds(60); + //默认线程名称 + executor.setThreadNamePrefix("user-rpt-"); + //拒绝策略 + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + //等待所有任务结束后再关闭线程池 + executor.setWaitForTasksToCompleteOnShutdown(true); + return executor; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java new file mode 100644 index 0000000..8ca554c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java @@ -0,0 +1,18 @@ +package com.casic.missiles.modular.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +// tomcat启动无需配置 +@Configuration +public class WebSocketConfig { + /** + * 注入ServerEndpointExporter, + * 这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint + */ + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java new file mode 100644 index 0000000..34fe2cd --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java @@ -0,0 +1,39 @@ +package com.casic.missiles.modular.controller; + + +import com.casic.missiles.model.application.event.core.EventPublisher; +import com.casic.missiles.model.application.event.enums.ModelEventTypeEnum; +import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.modular.event.UserEvent; +import com.casic.missiles.modular.system.model.User; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +/** + * @Description: DemoController + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@RestController +@RequestMapping("/demo") +public class DemoController { + @Autowired + private EventPublisher publisher; + + /** + * 获取mockToken + */ + @PostMapping("/list") + @ResponseBody + public Object list() { + User user = new User(); + user.setAccount("张三"); + publisher.publishEvent(new UserEvent(ModelEventTypeEnum.ADD, user)); + return ResponseData.success(); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java new file mode 100644 index 0000000..aff2889 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java @@ -0,0 +1,23 @@ +package com.casic.missiles.modular.event; + +import com.casic.missiles.model.application.event.core.ModelEvent; +import com.casic.missiles.model.application.event.type.AbstractEventTypeEnum; +import com.casic.missiles.modular.system.model.User; + +/** + * @Description: 用户事件 + * @Author: wangpeng + * @Date: 2022/7/17 11:23 + */ +public class UserEvent extends ModelEvent { + /** + * Create a new {@code ApplicationEvent}. + * + * @param type 事件类型 + * @param source the object on which the event initially occurred or with + * which the event is associated (never {@code null}) + */ + public UserEvent(AbstractEventTypeEnum type, User source) { + super(type, source); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java new file mode 100644 index 0000000..8f9603e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.core.application.event.UserLoginEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserOneListener { + @EventListener + public void onApplicationEvent(UserLoginEvent event) { + log.debug("用户1订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java new file mode 100644 index 0000000..0bd52a3 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.model.application.event.core.EventSubscriber; +import com.casic.missiles.modular.event.UserEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserTwoListener extends EventSubscriber { + @Override + public void onApplicationEvent(UserEvent event) { + log.debug("用户2订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java new file mode 100644 index 0000000..4012170 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java @@ -0,0 +1,88 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang3.StringUtils; +import sun.misc.BASE64Decoder; + +import java.io.*; + +public class Base64Util { + /** + * base64字符串转换成图片 + * + * @param imgStr base64字符串 + * @param imgFilePath 图片存放路径 + * @return + * @author ZHANGJL + * @dateTime 2018-02-23 14:42:17 + */ + public static boolean Base64ToImage(String imgStr, String imgFilePath, String fileDir) { // 对字节数组字符串进行Base64解码并生成图片 + + if (StringUtils.isEmpty(imgStr)) // 图像数据为空 + return false; + + imgStr = imgStr.substring(imgStr.indexOf(",") + 1); + + BASE64Decoder decoder = new BASE64Decoder(); + try { + // Base64解码 + byte[] b = decoder.decodeBuffer(imgStr); + + for (int i = 0; i < b.length; ++i) { + if (b[i] < 0) {// 调整异常数据 + b[i] += 256; + } + } + //如果已存在图像,先删除 + File file = new File(fileDir+File.separator + imgFilePath); + if (file.exists() && file.isFile()) { + file.delete(); + } + File dir = new File(fileDir); + if (!dir.exists()) { + dir.mkdirs(); + } + file = new File(fileDir+File.separator+imgFilePath); + file.createNewFile(); +// ImageIO.write(bImage, "bmp", name); + OutputStream out = new FileOutputStream(fileDir+File.separator+imgFilePath); + out.write(b); + out.flush(); + out.close(); + + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + + } + + public static String getBase64FromInputStream(InputStream in) { + // 将图片文件转化为字节数组字符串,并对其进行Base64编码处理 + byte[] data = null; + // 读取图片字节数组 + try { + ByteArrayOutputStream swapStream = new ByteArrayOutputStream(); + byte[] buff = new byte[100]; + int rc = 0; + while ((rc = in.read(buff, 0, 100)) > 0) { + swapStream.write(buff, 0, rc); + } + data = swapStream.toByteArray(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return new String(Base64.encodeBase64(data)); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java new file mode 100644 index 0000000..9c93895 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java @@ -0,0 +1,75 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.lang3.StringUtils; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class CommonUtil { + + public static String CutId(String id) { + return id.substring(6, 10) + "-" + id.substring(10, 12) + "-" + id.substring(12, 14); + } + + public static boolean isIDNumber(String IDNumber) { + if (IDNumber == null || "".equals(IDNumber)) { + return false; + } + // 定义判别用户身份证号的正则表达式(15位或者18位,最后一位可以为字母) + String regularExpression = + "(^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|" + + "(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}$)"; + boolean matches = IDNumber.matches(regularExpression); + // 判断第18位校验值 + if (matches) { + if (IDNumber.length() == 18) { + try { + char[] charArray = IDNumber.toCharArray(); + // 前十七位加权因子 + int[] idCardWi = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; + // 这是除以11后,可能产生的11位余数对应的验证码 + String[] idCardY = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"}; + int sum = 0; + for (int i = 0; i < idCardWi.length; i++) { + int current = Integer.parseInt(String.valueOf(charArray[i])); + int count = current * idCardWi[i]; + sum += count; + } + char idCardLast = charArray[17]; + int idCardMod = sum % 11; + if (idCardY[idCardMod].toUpperCase() + .equals(String.valueOf(idCardLast).toUpperCase())) { + return true; + } else { + System.out.println("身份证最后一位:" + String.valueOf(idCardLast).toUpperCase() + + "错误,正确的应该是:" + idCardY[idCardMod].toUpperCase()); + return false; + } + + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } else { + return false; + } + } + return matches; + } + + + public static boolean CheckMobilePhoneNum(String phoneNum) { + if (StringUtils.isEmpty(phoneNum)) + return true; + String regex = "^(1[3-9]\\d{9}$)"; + if (phoneNum.length() == 11) { + Pattern p = Pattern.compile(regex); + Matcher m = p.matcher(phoneNum); + if (m.matches()) { + return true; + } + } + return false; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java new file mode 100644 index 0000000..191ef79 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java @@ -0,0 +1,116 @@ +package com.casic.missiles.modular.util; + + +import javafx.util.Pair; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +/** + * Created by Administrator on 2015/2/25. + */ +public class DateUtils { + public static SimpleDateFormat sdf_day = new SimpleDateFormat("yyyy-MM-dd"); + public static SimpleDateFormat sdf_day_time = new SimpleDateFormat("yyyyMMddhhmmss"); + public static final SimpleDateFormat sdf4 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + public static final SimpleDateFormat sdf5 = new SimpleDateFormat("HH:mm:ss"); + + + /** + * 获取当年的第一天 + * + * @return + */ + public static Date getCurrYearFirst() { + Calendar currCal = Calendar.getInstance(); + int currentYear = currCal.get(Calendar.YEAR); + return getYearFirst(currentYear); + } + + + /** + * 获取某年第一天日期 + * + * @param year 年份 + * @return Date + */ + public static Date getYearFirst(int year) { + Calendar calendar = Calendar.getInstance(); + calendar.clear(); + calendar.set(Calendar.YEAR, year); + Date currYearFirst = calendar.getTime(); + return currYearFirst; + } + + /** + * 最近7日(不包括今日) + */ + public static Pair getLastSevenDays() { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, -7); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 最近n日(不包括今日) + */ + public static Pair getLastNDays(int n) { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, n * -1); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 日期时间加n天 + */ + public static String addDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf4.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf4.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 日期加n天 + */ + public static String addNDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf_day.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf_day.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 昨日 + */ + public static String getYesterday() { + + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.DATE, -2); + return sdf_day.format(calendar.getTime()); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java new file mode 100644 index 0000000..da0f8ee --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java @@ -0,0 +1,49 @@ +package com.casic.missiles.modular.util; + +import com.hikvision.artemis.sdk.ArtemisHttpUtil; +import com.hikvision.artemis.sdk.config.ArtemisConfig; + +import java.util.HashMap; +import java.util.Map; + +public class HikUtil { + + public static String hikApi(String uri, String body) { + + /** + * STEP1:设置平台参数,根据实际情况,设置host appkey appsecret 三个参数. + */ + ArtemisConfig.host = "192.168.1.22:443"; // artemis网关服务器ip端口 + ArtemisConfig.appKey = "25766251"; // 秘钥appkey + ArtemisConfig.appSecret = "h2o6zXtzCmt8eaOaMkXb";// 秘钥appSecret + + /** + * STEP2:设置OpenAPI接口的上下文 + */ + final String ARTEMIS_PATH = "/artemis"; + + /** + * STEP3:设置接口的URI地址 + */ + final String previewURLsApi = ARTEMIS_PATH + uri; + Map path = new HashMap(2) { + { + put("https://", previewURLsApi);//根据现场环境部署确认是http还是https + } + }; + + /** + * STEP4:设置参数提交方式 + */ + String contentType = "application/json"; + + /** + * STEP5:组装请求参数 + */ + /** + * STEP6:调用接口 + */ + String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, contentType, null);// post请求application/json类型参数 + return result; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java new file mode 100644 index 0000000..4867144 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java @@ -0,0 +1,149 @@ +package com.casic.missiles.modular.util; + +import org.springframework.http.*; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; + +/** + * @Description: http请求工具类 + * @Author: wangpeng + * @Date: 2022/7/17 11:49 + */ +public class HttpUtil { + /** + * get请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String get(String url, MultiValueMap params) { + return get(url, params, null); + } + + /** + * get请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String get(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.GET); + } + + /** + * post请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String post(String url, MultiValueMap params) { + return post(url, params, null); + } + + /** + * post请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String post(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.POST); + } + + /** + * put请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String put(String url, MultiValueMap params) { + return put(url, params, null); + } + + /** + * put请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String put(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.PUT); + } + + /** + * delete请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String delete(String url, MultiValueMap params) { + return delete(url, params, null); + } + + /** + * delete请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String delete(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.DELETE); + } + + /** + * 表单请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @param method 请求方式 + * @return + */ + public static String request(String url, MultiValueMap params, MultiValueMap headers, HttpMethod method) { + if (params == null) { + params = new LinkedMultiValueMap<>(); + } + return request(url, params, headers, method, MediaType.APPLICATION_FORM_URLENCODED); + } + + /** + * http请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @param method 请求方式 + * @param mediaType 参数类型 + * @return + */ + public static String request(String url, Object params, MultiValueMap headers, HttpMethod method, MediaType mediaType) { + if (url == null || url.trim().isEmpty()) { + return null; + } + RestTemplate client = new RestTemplate(); + // header + HttpHeaders httpHeaders = new HttpHeaders(); + if (headers != null) { +// httpHeaders.addAll(headers); + httpHeaders.putAll(headers); + } + // 提交方式:表单、json + httpHeaders.setContentType(mediaType); + HttpEntity httpEntity = new HttpEntity(params, httpHeaders); + ResponseEntity response = client.exchange(url, method, httpEntity, String.class); + return response.getBody(); + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9e20bc1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea/ +**/target/** +logs/ +*.iml diff --git a/README.md b/README.md new file mode 100644 index 0000000..2fdcd74 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# casic项目 V2.0.0 + +[^_^]: # (Talk is cheap,Show me the code!) + +## 介绍 +基于SpringBoot,致力于做更简洁的后台管理系统,完美整合springboot2.4 + shiro + mybatis-plus ! +基于casic项目代码简洁,注释丰富,上手容易,同时包含许多基础模块(用户管理,角色管理,部门管理,字典管理等10个模块) +可以直接作为一个后台管理系统的脚手架! 2022目标 `更简洁`,`更规范`! + + +#### 其他 +>* [git地址](http://192.168.0.203:8080/gitbucket) +>* [本地免登地址](http://localhost:8083/route/mockToken) diff --git a/casic-server/pom.xml b/casic-server/pom.xml new file mode 100644 index 0000000..c150a12 --- /dev/null +++ b/casic-server/pom.xml @@ -0,0 +1,70 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + 2.0.0 + ../pom.xml + + + casic-server + 2.0.0 + jar + casic-server + casic 的spring boot版本 + + + + + com.casic + casic-core + ${core.version} + provided + + + com.casic + casic-admin-support + ${admin.version} + provided + + + org.springframework.boot + spring-boot-starter-web + ${boot.version} + provided + + + + + com.hikvision.ga + artemis-http-client + 1.1.3 + + + commons-io + commons-io + + + org.springframework.boot + spring-boot-starter-websocket + 2.4.5 + + + io.netty + netty-all + 4.1.42.Final + + + + + + src/main/java + + **/*.xml + + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java new file mode 100644 index 0000000..3a60b9e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java @@ -0,0 +1,36 @@ +package com.casic.missiles.modular.async; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.TaskExecutor; +import org.springframework.scheduling.annotation.AsyncConfigurer; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadPoolExecutor; + +@Configuration +@EnableAsync +public class AsyncConfig implements AsyncConfigurer { + @Override + public Executor getAsyncExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + //核心线程数 + executor.setCorePoolSize(5); + //最大线程数 + executor.setMaxPoolSize(10); + //队列容量 + executor.setQueueCapacity(20); + //设置线程活跃时间(秒) + executor.setKeepAliveSeconds(60); + //默认线程名称 + executor.setThreadNamePrefix("user-rpt-"); + //拒绝策略 + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + //等待所有任务结束后再关闭线程池 + executor.setWaitForTasksToCompleteOnShutdown(true); + return executor; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java new file mode 100644 index 0000000..8ca554c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java @@ -0,0 +1,18 @@ +package com.casic.missiles.modular.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +// tomcat启动无需配置 +@Configuration +public class WebSocketConfig { + /** + * 注入ServerEndpointExporter, + * 这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint + */ + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java new file mode 100644 index 0000000..34fe2cd --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java @@ -0,0 +1,39 @@ +package com.casic.missiles.modular.controller; + + +import com.casic.missiles.model.application.event.core.EventPublisher; +import com.casic.missiles.model.application.event.enums.ModelEventTypeEnum; +import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.modular.event.UserEvent; +import com.casic.missiles.modular.system.model.User; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +/** + * @Description: DemoController + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@RestController +@RequestMapping("/demo") +public class DemoController { + @Autowired + private EventPublisher publisher; + + /** + * 获取mockToken + */ + @PostMapping("/list") + @ResponseBody + public Object list() { + User user = new User(); + user.setAccount("张三"); + publisher.publishEvent(new UserEvent(ModelEventTypeEnum.ADD, user)); + return ResponseData.success(); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java new file mode 100644 index 0000000..aff2889 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java @@ -0,0 +1,23 @@ +package com.casic.missiles.modular.event; + +import com.casic.missiles.model.application.event.core.ModelEvent; +import com.casic.missiles.model.application.event.type.AbstractEventTypeEnum; +import com.casic.missiles.modular.system.model.User; + +/** + * @Description: 用户事件 + * @Author: wangpeng + * @Date: 2022/7/17 11:23 + */ +public class UserEvent extends ModelEvent { + /** + * Create a new {@code ApplicationEvent}. + * + * @param type 事件类型 + * @param source the object on which the event initially occurred or with + * which the event is associated (never {@code null}) + */ + public UserEvent(AbstractEventTypeEnum type, User source) { + super(type, source); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java new file mode 100644 index 0000000..8f9603e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.core.application.event.UserLoginEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserOneListener { + @EventListener + public void onApplicationEvent(UserLoginEvent event) { + log.debug("用户1订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java new file mode 100644 index 0000000..0bd52a3 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.model.application.event.core.EventSubscriber; +import com.casic.missiles.modular.event.UserEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserTwoListener extends EventSubscriber { + @Override + public void onApplicationEvent(UserEvent event) { + log.debug("用户2订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java new file mode 100644 index 0000000..4012170 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java @@ -0,0 +1,88 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang3.StringUtils; +import sun.misc.BASE64Decoder; + +import java.io.*; + +public class Base64Util { + /** + * base64字符串转换成图片 + * + * @param imgStr base64字符串 + * @param imgFilePath 图片存放路径 + * @return + * @author ZHANGJL + * @dateTime 2018-02-23 14:42:17 + */ + public static boolean Base64ToImage(String imgStr, String imgFilePath, String fileDir) { // 对字节数组字符串进行Base64解码并生成图片 + + if (StringUtils.isEmpty(imgStr)) // 图像数据为空 + return false; + + imgStr = imgStr.substring(imgStr.indexOf(",") + 1); + + BASE64Decoder decoder = new BASE64Decoder(); + try { + // Base64解码 + byte[] b = decoder.decodeBuffer(imgStr); + + for (int i = 0; i < b.length; ++i) { + if (b[i] < 0) {// 调整异常数据 + b[i] += 256; + } + } + //如果已存在图像,先删除 + File file = new File(fileDir+File.separator + imgFilePath); + if (file.exists() && file.isFile()) { + file.delete(); + } + File dir = new File(fileDir); + if (!dir.exists()) { + dir.mkdirs(); + } + file = new File(fileDir+File.separator+imgFilePath); + file.createNewFile(); +// ImageIO.write(bImage, "bmp", name); + OutputStream out = new FileOutputStream(fileDir+File.separator+imgFilePath); + out.write(b); + out.flush(); + out.close(); + + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + + } + + public static String getBase64FromInputStream(InputStream in) { + // 将图片文件转化为字节数组字符串,并对其进行Base64编码处理 + byte[] data = null; + // 读取图片字节数组 + try { + ByteArrayOutputStream swapStream = new ByteArrayOutputStream(); + byte[] buff = new byte[100]; + int rc = 0; + while ((rc = in.read(buff, 0, 100)) > 0) { + swapStream.write(buff, 0, rc); + } + data = swapStream.toByteArray(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return new String(Base64.encodeBase64(data)); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java new file mode 100644 index 0000000..9c93895 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java @@ -0,0 +1,75 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.lang3.StringUtils; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class CommonUtil { + + public static String CutId(String id) { + return id.substring(6, 10) + "-" + id.substring(10, 12) + "-" + id.substring(12, 14); + } + + public static boolean isIDNumber(String IDNumber) { + if (IDNumber == null || "".equals(IDNumber)) { + return false; + } + // 定义判别用户身份证号的正则表达式(15位或者18位,最后一位可以为字母) + String regularExpression = + "(^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|" + + "(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}$)"; + boolean matches = IDNumber.matches(regularExpression); + // 判断第18位校验值 + if (matches) { + if (IDNumber.length() == 18) { + try { + char[] charArray = IDNumber.toCharArray(); + // 前十七位加权因子 + int[] idCardWi = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; + // 这是除以11后,可能产生的11位余数对应的验证码 + String[] idCardY = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"}; + int sum = 0; + for (int i = 0; i < idCardWi.length; i++) { + int current = Integer.parseInt(String.valueOf(charArray[i])); + int count = current * idCardWi[i]; + sum += count; + } + char idCardLast = charArray[17]; + int idCardMod = sum % 11; + if (idCardY[idCardMod].toUpperCase() + .equals(String.valueOf(idCardLast).toUpperCase())) { + return true; + } else { + System.out.println("身份证最后一位:" + String.valueOf(idCardLast).toUpperCase() + + "错误,正确的应该是:" + idCardY[idCardMod].toUpperCase()); + return false; + } + + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } else { + return false; + } + } + return matches; + } + + + public static boolean CheckMobilePhoneNum(String phoneNum) { + if (StringUtils.isEmpty(phoneNum)) + return true; + String regex = "^(1[3-9]\\d{9}$)"; + if (phoneNum.length() == 11) { + Pattern p = Pattern.compile(regex); + Matcher m = p.matcher(phoneNum); + if (m.matches()) { + return true; + } + } + return false; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java new file mode 100644 index 0000000..191ef79 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java @@ -0,0 +1,116 @@ +package com.casic.missiles.modular.util; + + +import javafx.util.Pair; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +/** + * Created by Administrator on 2015/2/25. + */ +public class DateUtils { + public static SimpleDateFormat sdf_day = new SimpleDateFormat("yyyy-MM-dd"); + public static SimpleDateFormat sdf_day_time = new SimpleDateFormat("yyyyMMddhhmmss"); + public static final SimpleDateFormat sdf4 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + public static final SimpleDateFormat sdf5 = new SimpleDateFormat("HH:mm:ss"); + + + /** + * 获取当年的第一天 + * + * @return + */ + public static Date getCurrYearFirst() { + Calendar currCal = Calendar.getInstance(); + int currentYear = currCal.get(Calendar.YEAR); + return getYearFirst(currentYear); + } + + + /** + * 获取某年第一天日期 + * + * @param year 年份 + * @return Date + */ + public static Date getYearFirst(int year) { + Calendar calendar = Calendar.getInstance(); + calendar.clear(); + calendar.set(Calendar.YEAR, year); + Date currYearFirst = calendar.getTime(); + return currYearFirst; + } + + /** + * 最近7日(不包括今日) + */ + public static Pair getLastSevenDays() { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, -7); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 最近n日(不包括今日) + */ + public static Pair getLastNDays(int n) { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, n * -1); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 日期时间加n天 + */ + public static String addDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf4.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf4.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 日期加n天 + */ + public static String addNDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf_day.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf_day.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 昨日 + */ + public static String getYesterday() { + + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.DATE, -2); + return sdf_day.format(calendar.getTime()); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java new file mode 100644 index 0000000..da0f8ee --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java @@ -0,0 +1,49 @@ +package com.casic.missiles.modular.util; + +import com.hikvision.artemis.sdk.ArtemisHttpUtil; +import com.hikvision.artemis.sdk.config.ArtemisConfig; + +import java.util.HashMap; +import java.util.Map; + +public class HikUtil { + + public static String hikApi(String uri, String body) { + + /** + * STEP1:设置平台参数,根据实际情况,设置host appkey appsecret 三个参数. + */ + ArtemisConfig.host = "192.168.1.22:443"; // artemis网关服务器ip端口 + ArtemisConfig.appKey = "25766251"; // 秘钥appkey + ArtemisConfig.appSecret = "h2o6zXtzCmt8eaOaMkXb";// 秘钥appSecret + + /** + * STEP2:设置OpenAPI接口的上下文 + */ + final String ARTEMIS_PATH = "/artemis"; + + /** + * STEP3:设置接口的URI地址 + */ + final String previewURLsApi = ARTEMIS_PATH + uri; + Map path = new HashMap(2) { + { + put("https://", previewURLsApi);//根据现场环境部署确认是http还是https + } + }; + + /** + * STEP4:设置参数提交方式 + */ + String contentType = "application/json"; + + /** + * STEP5:组装请求参数 + */ + /** + * STEP6:调用接口 + */ + String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, contentType, null);// post请求application/json类型参数 + return result; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java new file mode 100644 index 0000000..4867144 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java @@ -0,0 +1,149 @@ +package com.casic.missiles.modular.util; + +import org.springframework.http.*; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; + +/** + * @Description: http请求工具类 + * @Author: wangpeng + * @Date: 2022/7/17 11:49 + */ +public class HttpUtil { + /** + * get请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String get(String url, MultiValueMap params) { + return get(url, params, null); + } + + /** + * get请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String get(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.GET); + } + + /** + * post请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String post(String url, MultiValueMap params) { + return post(url, params, null); + } + + /** + * post请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String post(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.POST); + } + + /** + * put请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String put(String url, MultiValueMap params) { + return put(url, params, null); + } + + /** + * put请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String put(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.PUT); + } + + /** + * delete请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String delete(String url, MultiValueMap params) { + return delete(url, params, null); + } + + /** + * delete请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String delete(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.DELETE); + } + + /** + * 表单请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @param method 请求方式 + * @return + */ + public static String request(String url, MultiValueMap params, MultiValueMap headers, HttpMethod method) { + if (params == null) { + params = new LinkedMultiValueMap<>(); + } + return request(url, params, headers, method, MediaType.APPLICATION_FORM_URLENCODED); + } + + /** + * http请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @param method 请求方式 + * @param mediaType 参数类型 + * @return + */ + public static String request(String url, Object params, MultiValueMap headers, HttpMethod method, MediaType mediaType) { + if (url == null || url.trim().isEmpty()) { + return null; + } + RestTemplate client = new RestTemplate(); + // header + HttpHeaders httpHeaders = new HttpHeaders(); + if (headers != null) { +// httpHeaders.addAll(headers); + httpHeaders.putAll(headers); + } + // 提交方式:表单、json + httpHeaders.setContentType(mediaType); + HttpEntity httpEntity = new HttpEntity(params, httpHeaders); + ResponseEntity response = client.exchange(url, method, httpEntity, String.class); + return response.getBody(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java new file mode 100644 index 0000000..19d8d67 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java @@ -0,0 +1,30 @@ +package com.casic.missiles.modular.util; + +public class SelectDTO { + private String name; + private String value; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public SelectDTO() { + } + + public SelectDTO(String name, String value) { + this.name = name; + this.value = value; + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9e20bc1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea/ +**/target/** +logs/ +*.iml diff --git a/README.md b/README.md new file mode 100644 index 0000000..2fdcd74 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# casic项目 V2.0.0 + +[^_^]: # (Talk is cheap,Show me the code!) + +## 介绍 +基于SpringBoot,致力于做更简洁的后台管理系统,完美整合springboot2.4 + shiro + mybatis-plus ! +基于casic项目代码简洁,注释丰富,上手容易,同时包含许多基础模块(用户管理,角色管理,部门管理,字典管理等10个模块) +可以直接作为一个后台管理系统的脚手架! 2022目标 `更简洁`,`更规范`! + + +#### 其他 +>* [git地址](http://192.168.0.203:8080/gitbucket) +>* [本地免登地址](http://localhost:8083/route/mockToken) diff --git a/casic-server/pom.xml b/casic-server/pom.xml new file mode 100644 index 0000000..c150a12 --- /dev/null +++ b/casic-server/pom.xml @@ -0,0 +1,70 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + 2.0.0 + ../pom.xml + + + casic-server + 2.0.0 + jar + casic-server + casic 的spring boot版本 + + + + + com.casic + casic-core + ${core.version} + provided + + + com.casic + casic-admin-support + ${admin.version} + provided + + + org.springframework.boot + spring-boot-starter-web + ${boot.version} + provided + + + + + com.hikvision.ga + artemis-http-client + 1.1.3 + + + commons-io + commons-io + + + org.springframework.boot + spring-boot-starter-websocket + 2.4.5 + + + io.netty + netty-all + 4.1.42.Final + + + + + + src/main/java + + **/*.xml + + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java new file mode 100644 index 0000000..3a60b9e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java @@ -0,0 +1,36 @@ +package com.casic.missiles.modular.async; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.TaskExecutor; +import org.springframework.scheduling.annotation.AsyncConfigurer; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadPoolExecutor; + +@Configuration +@EnableAsync +public class AsyncConfig implements AsyncConfigurer { + @Override + public Executor getAsyncExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + //核心线程数 + executor.setCorePoolSize(5); + //最大线程数 + executor.setMaxPoolSize(10); + //队列容量 + executor.setQueueCapacity(20); + //设置线程活跃时间(秒) + executor.setKeepAliveSeconds(60); + //默认线程名称 + executor.setThreadNamePrefix("user-rpt-"); + //拒绝策略 + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + //等待所有任务结束后再关闭线程池 + executor.setWaitForTasksToCompleteOnShutdown(true); + return executor; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java new file mode 100644 index 0000000..8ca554c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java @@ -0,0 +1,18 @@ +package com.casic.missiles.modular.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +// tomcat启动无需配置 +@Configuration +public class WebSocketConfig { + /** + * 注入ServerEndpointExporter, + * 这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint + */ + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java new file mode 100644 index 0000000..34fe2cd --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java @@ -0,0 +1,39 @@ +package com.casic.missiles.modular.controller; + + +import com.casic.missiles.model.application.event.core.EventPublisher; +import com.casic.missiles.model.application.event.enums.ModelEventTypeEnum; +import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.modular.event.UserEvent; +import com.casic.missiles.modular.system.model.User; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +/** + * @Description: DemoController + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@RestController +@RequestMapping("/demo") +public class DemoController { + @Autowired + private EventPublisher publisher; + + /** + * 获取mockToken + */ + @PostMapping("/list") + @ResponseBody + public Object list() { + User user = new User(); + user.setAccount("张三"); + publisher.publishEvent(new UserEvent(ModelEventTypeEnum.ADD, user)); + return ResponseData.success(); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java new file mode 100644 index 0000000..aff2889 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java @@ -0,0 +1,23 @@ +package com.casic.missiles.modular.event; + +import com.casic.missiles.model.application.event.core.ModelEvent; +import com.casic.missiles.model.application.event.type.AbstractEventTypeEnum; +import com.casic.missiles.modular.system.model.User; + +/** + * @Description: 用户事件 + * @Author: wangpeng + * @Date: 2022/7/17 11:23 + */ +public class UserEvent extends ModelEvent { + /** + * Create a new {@code ApplicationEvent}. + * + * @param type 事件类型 + * @param source the object on which the event initially occurred or with + * which the event is associated (never {@code null}) + */ + public UserEvent(AbstractEventTypeEnum type, User source) { + super(type, source); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java new file mode 100644 index 0000000..8f9603e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.core.application.event.UserLoginEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserOneListener { + @EventListener + public void onApplicationEvent(UserLoginEvent event) { + log.debug("用户1订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java new file mode 100644 index 0000000..0bd52a3 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.model.application.event.core.EventSubscriber; +import com.casic.missiles.modular.event.UserEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserTwoListener extends EventSubscriber { + @Override + public void onApplicationEvent(UserEvent event) { + log.debug("用户2订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java new file mode 100644 index 0000000..4012170 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java @@ -0,0 +1,88 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang3.StringUtils; +import sun.misc.BASE64Decoder; + +import java.io.*; + +public class Base64Util { + /** + * base64字符串转换成图片 + * + * @param imgStr base64字符串 + * @param imgFilePath 图片存放路径 + * @return + * @author ZHANGJL + * @dateTime 2018-02-23 14:42:17 + */ + public static boolean Base64ToImage(String imgStr, String imgFilePath, String fileDir) { // 对字节数组字符串进行Base64解码并生成图片 + + if (StringUtils.isEmpty(imgStr)) // 图像数据为空 + return false; + + imgStr = imgStr.substring(imgStr.indexOf(",") + 1); + + BASE64Decoder decoder = new BASE64Decoder(); + try { + // Base64解码 + byte[] b = decoder.decodeBuffer(imgStr); + + for (int i = 0; i < b.length; ++i) { + if (b[i] < 0) {// 调整异常数据 + b[i] += 256; + } + } + //如果已存在图像,先删除 + File file = new File(fileDir+File.separator + imgFilePath); + if (file.exists() && file.isFile()) { + file.delete(); + } + File dir = new File(fileDir); + if (!dir.exists()) { + dir.mkdirs(); + } + file = new File(fileDir+File.separator+imgFilePath); + file.createNewFile(); +// ImageIO.write(bImage, "bmp", name); + OutputStream out = new FileOutputStream(fileDir+File.separator+imgFilePath); + out.write(b); + out.flush(); + out.close(); + + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + + } + + public static String getBase64FromInputStream(InputStream in) { + // 将图片文件转化为字节数组字符串,并对其进行Base64编码处理 + byte[] data = null; + // 读取图片字节数组 + try { + ByteArrayOutputStream swapStream = new ByteArrayOutputStream(); + byte[] buff = new byte[100]; + int rc = 0; + while ((rc = in.read(buff, 0, 100)) > 0) { + swapStream.write(buff, 0, rc); + } + data = swapStream.toByteArray(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return new String(Base64.encodeBase64(data)); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java new file mode 100644 index 0000000..9c93895 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java @@ -0,0 +1,75 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.lang3.StringUtils; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class CommonUtil { + + public static String CutId(String id) { + return id.substring(6, 10) + "-" + id.substring(10, 12) + "-" + id.substring(12, 14); + } + + public static boolean isIDNumber(String IDNumber) { + if (IDNumber == null || "".equals(IDNumber)) { + return false; + } + // 定义判别用户身份证号的正则表达式(15位或者18位,最后一位可以为字母) + String regularExpression = + "(^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|" + + "(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}$)"; + boolean matches = IDNumber.matches(regularExpression); + // 判断第18位校验值 + if (matches) { + if (IDNumber.length() == 18) { + try { + char[] charArray = IDNumber.toCharArray(); + // 前十七位加权因子 + int[] idCardWi = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; + // 这是除以11后,可能产生的11位余数对应的验证码 + String[] idCardY = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"}; + int sum = 0; + for (int i = 0; i < idCardWi.length; i++) { + int current = Integer.parseInt(String.valueOf(charArray[i])); + int count = current * idCardWi[i]; + sum += count; + } + char idCardLast = charArray[17]; + int idCardMod = sum % 11; + if (idCardY[idCardMod].toUpperCase() + .equals(String.valueOf(idCardLast).toUpperCase())) { + return true; + } else { + System.out.println("身份证最后一位:" + String.valueOf(idCardLast).toUpperCase() + + "错误,正确的应该是:" + idCardY[idCardMod].toUpperCase()); + return false; + } + + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } else { + return false; + } + } + return matches; + } + + + public static boolean CheckMobilePhoneNum(String phoneNum) { + if (StringUtils.isEmpty(phoneNum)) + return true; + String regex = "^(1[3-9]\\d{9}$)"; + if (phoneNum.length() == 11) { + Pattern p = Pattern.compile(regex); + Matcher m = p.matcher(phoneNum); + if (m.matches()) { + return true; + } + } + return false; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java new file mode 100644 index 0000000..191ef79 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java @@ -0,0 +1,116 @@ +package com.casic.missiles.modular.util; + + +import javafx.util.Pair; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +/** + * Created by Administrator on 2015/2/25. + */ +public class DateUtils { + public static SimpleDateFormat sdf_day = new SimpleDateFormat("yyyy-MM-dd"); + public static SimpleDateFormat sdf_day_time = new SimpleDateFormat("yyyyMMddhhmmss"); + public static final SimpleDateFormat sdf4 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + public static final SimpleDateFormat sdf5 = new SimpleDateFormat("HH:mm:ss"); + + + /** + * 获取当年的第一天 + * + * @return + */ + public static Date getCurrYearFirst() { + Calendar currCal = Calendar.getInstance(); + int currentYear = currCal.get(Calendar.YEAR); + return getYearFirst(currentYear); + } + + + /** + * 获取某年第一天日期 + * + * @param year 年份 + * @return Date + */ + public static Date getYearFirst(int year) { + Calendar calendar = Calendar.getInstance(); + calendar.clear(); + calendar.set(Calendar.YEAR, year); + Date currYearFirst = calendar.getTime(); + return currYearFirst; + } + + /** + * 最近7日(不包括今日) + */ + public static Pair getLastSevenDays() { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, -7); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 最近n日(不包括今日) + */ + public static Pair getLastNDays(int n) { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, n * -1); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 日期时间加n天 + */ + public static String addDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf4.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf4.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 日期加n天 + */ + public static String addNDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf_day.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf_day.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 昨日 + */ + public static String getYesterday() { + + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.DATE, -2); + return sdf_day.format(calendar.getTime()); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java new file mode 100644 index 0000000..da0f8ee --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java @@ -0,0 +1,49 @@ +package com.casic.missiles.modular.util; + +import com.hikvision.artemis.sdk.ArtemisHttpUtil; +import com.hikvision.artemis.sdk.config.ArtemisConfig; + +import java.util.HashMap; +import java.util.Map; + +public class HikUtil { + + public static String hikApi(String uri, String body) { + + /** + * STEP1:设置平台参数,根据实际情况,设置host appkey appsecret 三个参数. + */ + ArtemisConfig.host = "192.168.1.22:443"; // artemis网关服务器ip端口 + ArtemisConfig.appKey = "25766251"; // 秘钥appkey + ArtemisConfig.appSecret = "h2o6zXtzCmt8eaOaMkXb";// 秘钥appSecret + + /** + * STEP2:设置OpenAPI接口的上下文 + */ + final String ARTEMIS_PATH = "/artemis"; + + /** + * STEP3:设置接口的URI地址 + */ + final String previewURLsApi = ARTEMIS_PATH + uri; + Map path = new HashMap(2) { + { + put("https://", previewURLsApi);//根据现场环境部署确认是http还是https + } + }; + + /** + * STEP4:设置参数提交方式 + */ + String contentType = "application/json"; + + /** + * STEP5:组装请求参数 + */ + /** + * STEP6:调用接口 + */ + String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, contentType, null);// post请求application/json类型参数 + return result; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java new file mode 100644 index 0000000..4867144 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java @@ -0,0 +1,149 @@ +package com.casic.missiles.modular.util; + +import org.springframework.http.*; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; + +/** + * @Description: http请求工具类 + * @Author: wangpeng + * @Date: 2022/7/17 11:49 + */ +public class HttpUtil { + /** + * get请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String get(String url, MultiValueMap params) { + return get(url, params, null); + } + + /** + * get请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String get(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.GET); + } + + /** + * post请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String post(String url, MultiValueMap params) { + return post(url, params, null); + } + + /** + * post请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String post(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.POST); + } + + /** + * put请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String put(String url, MultiValueMap params) { + return put(url, params, null); + } + + /** + * put请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String put(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.PUT); + } + + /** + * delete请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String delete(String url, MultiValueMap params) { + return delete(url, params, null); + } + + /** + * delete请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String delete(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.DELETE); + } + + /** + * 表单请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @param method 请求方式 + * @return + */ + public static String request(String url, MultiValueMap params, MultiValueMap headers, HttpMethod method) { + if (params == null) { + params = new LinkedMultiValueMap<>(); + } + return request(url, params, headers, method, MediaType.APPLICATION_FORM_URLENCODED); + } + + /** + * http请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @param method 请求方式 + * @param mediaType 参数类型 + * @return + */ + public static String request(String url, Object params, MultiValueMap headers, HttpMethod method, MediaType mediaType) { + if (url == null || url.trim().isEmpty()) { + return null; + } + RestTemplate client = new RestTemplate(); + // header + HttpHeaders httpHeaders = new HttpHeaders(); + if (headers != null) { +// httpHeaders.addAll(headers); + httpHeaders.putAll(headers); + } + // 提交方式:表单、json + httpHeaders.setContentType(mediaType); + HttpEntity httpEntity = new HttpEntity(params, httpHeaders); + ResponseEntity response = client.exchange(url, method, httpEntity, String.class); + return response.getBody(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java new file mode 100644 index 0000000..19d8d67 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java @@ -0,0 +1,30 @@ +package com.casic.missiles.modular.util; + +public class SelectDTO { + private String name; + private String value; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public SelectDTO() { + } + + public SelectDTO(String name, String value) { + this.name = name; + this.value = value; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java new file mode 100644 index 0000000..0bd484c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java @@ -0,0 +1,28 @@ +package com.casic.missiles.modular.util; + +public class SocketConst { + + /** + * 新增授权socket前缀 + */ + public static final String SOCKET_PREFIX_ADD_PERMISSION = "addPermission:"; + + /** + * 取消授权socket前缀 + */ + public static final String SOCKET_PREFIX_DELETE_PERMISSION = "deletePermission:"; + + /** + * 人员数据下发socket前缀 + */ + public static final String SOCKET_PREFIX_ADD_PERSON = "addPerson:"; + + /** + * socket返回成功信息 + */ + public static final String SOCKET_SUCCESS_MSG = "ok"; + /** + * 人员数据下发socket前缀 + */ + public static final String SOCKET_PREFIX_DELETE_PERSON = "deletePerson:"; +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9e20bc1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea/ +**/target/** +logs/ +*.iml diff --git a/README.md b/README.md new file mode 100644 index 0000000..2fdcd74 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# casic项目 V2.0.0 + +[^_^]: # (Talk is cheap,Show me the code!) + +## 介绍 +基于SpringBoot,致力于做更简洁的后台管理系统,完美整合springboot2.4 + shiro + mybatis-plus ! +基于casic项目代码简洁,注释丰富,上手容易,同时包含许多基础模块(用户管理,角色管理,部门管理,字典管理等10个模块) +可以直接作为一个后台管理系统的脚手架! 2022目标 `更简洁`,`更规范`! + + +#### 其他 +>* [git地址](http://192.168.0.203:8080/gitbucket) +>* [本地免登地址](http://localhost:8083/route/mockToken) diff --git a/casic-server/pom.xml b/casic-server/pom.xml new file mode 100644 index 0000000..c150a12 --- /dev/null +++ b/casic-server/pom.xml @@ -0,0 +1,70 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + 2.0.0 + ../pom.xml + + + casic-server + 2.0.0 + jar + casic-server + casic 的spring boot版本 + + + + + com.casic + casic-core + ${core.version} + provided + + + com.casic + casic-admin-support + ${admin.version} + provided + + + org.springframework.boot + spring-boot-starter-web + ${boot.version} + provided + + + + + com.hikvision.ga + artemis-http-client + 1.1.3 + + + commons-io + commons-io + + + org.springframework.boot + spring-boot-starter-websocket + 2.4.5 + + + io.netty + netty-all + 4.1.42.Final + + + + + + src/main/java + + **/*.xml + + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java new file mode 100644 index 0000000..3a60b9e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java @@ -0,0 +1,36 @@ +package com.casic.missiles.modular.async; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.TaskExecutor; +import org.springframework.scheduling.annotation.AsyncConfigurer; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadPoolExecutor; + +@Configuration +@EnableAsync +public class AsyncConfig implements AsyncConfigurer { + @Override + public Executor getAsyncExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + //核心线程数 + executor.setCorePoolSize(5); + //最大线程数 + executor.setMaxPoolSize(10); + //队列容量 + executor.setQueueCapacity(20); + //设置线程活跃时间(秒) + executor.setKeepAliveSeconds(60); + //默认线程名称 + executor.setThreadNamePrefix("user-rpt-"); + //拒绝策略 + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + //等待所有任务结束后再关闭线程池 + executor.setWaitForTasksToCompleteOnShutdown(true); + return executor; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java new file mode 100644 index 0000000..8ca554c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java @@ -0,0 +1,18 @@ +package com.casic.missiles.modular.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +// tomcat启动无需配置 +@Configuration +public class WebSocketConfig { + /** + * 注入ServerEndpointExporter, + * 这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint + */ + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java new file mode 100644 index 0000000..34fe2cd --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java @@ -0,0 +1,39 @@ +package com.casic.missiles.modular.controller; + + +import com.casic.missiles.model.application.event.core.EventPublisher; +import com.casic.missiles.model.application.event.enums.ModelEventTypeEnum; +import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.modular.event.UserEvent; +import com.casic.missiles.modular.system.model.User; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +/** + * @Description: DemoController + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@RestController +@RequestMapping("/demo") +public class DemoController { + @Autowired + private EventPublisher publisher; + + /** + * 获取mockToken + */ + @PostMapping("/list") + @ResponseBody + public Object list() { + User user = new User(); + user.setAccount("张三"); + publisher.publishEvent(new UserEvent(ModelEventTypeEnum.ADD, user)); + return ResponseData.success(); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java new file mode 100644 index 0000000..aff2889 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java @@ -0,0 +1,23 @@ +package com.casic.missiles.modular.event; + +import com.casic.missiles.model.application.event.core.ModelEvent; +import com.casic.missiles.model.application.event.type.AbstractEventTypeEnum; +import com.casic.missiles.modular.system.model.User; + +/** + * @Description: 用户事件 + * @Author: wangpeng + * @Date: 2022/7/17 11:23 + */ +public class UserEvent extends ModelEvent { + /** + * Create a new {@code ApplicationEvent}. + * + * @param type 事件类型 + * @param source the object on which the event initially occurred or with + * which the event is associated (never {@code null}) + */ + public UserEvent(AbstractEventTypeEnum type, User source) { + super(type, source); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java new file mode 100644 index 0000000..8f9603e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.core.application.event.UserLoginEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserOneListener { + @EventListener + public void onApplicationEvent(UserLoginEvent event) { + log.debug("用户1订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java new file mode 100644 index 0000000..0bd52a3 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.model.application.event.core.EventSubscriber; +import com.casic.missiles.modular.event.UserEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserTwoListener extends EventSubscriber { + @Override + public void onApplicationEvent(UserEvent event) { + log.debug("用户2订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java new file mode 100644 index 0000000..4012170 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java @@ -0,0 +1,88 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang3.StringUtils; +import sun.misc.BASE64Decoder; + +import java.io.*; + +public class Base64Util { + /** + * base64字符串转换成图片 + * + * @param imgStr base64字符串 + * @param imgFilePath 图片存放路径 + * @return + * @author ZHANGJL + * @dateTime 2018-02-23 14:42:17 + */ + public static boolean Base64ToImage(String imgStr, String imgFilePath, String fileDir) { // 对字节数组字符串进行Base64解码并生成图片 + + if (StringUtils.isEmpty(imgStr)) // 图像数据为空 + return false; + + imgStr = imgStr.substring(imgStr.indexOf(",") + 1); + + BASE64Decoder decoder = new BASE64Decoder(); + try { + // Base64解码 + byte[] b = decoder.decodeBuffer(imgStr); + + for (int i = 0; i < b.length; ++i) { + if (b[i] < 0) {// 调整异常数据 + b[i] += 256; + } + } + //如果已存在图像,先删除 + File file = new File(fileDir+File.separator + imgFilePath); + if (file.exists() && file.isFile()) { + file.delete(); + } + File dir = new File(fileDir); + if (!dir.exists()) { + dir.mkdirs(); + } + file = new File(fileDir+File.separator+imgFilePath); + file.createNewFile(); +// ImageIO.write(bImage, "bmp", name); + OutputStream out = new FileOutputStream(fileDir+File.separator+imgFilePath); + out.write(b); + out.flush(); + out.close(); + + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + + } + + public static String getBase64FromInputStream(InputStream in) { + // 将图片文件转化为字节数组字符串,并对其进行Base64编码处理 + byte[] data = null; + // 读取图片字节数组 + try { + ByteArrayOutputStream swapStream = new ByteArrayOutputStream(); + byte[] buff = new byte[100]; + int rc = 0; + while ((rc = in.read(buff, 0, 100)) > 0) { + swapStream.write(buff, 0, rc); + } + data = swapStream.toByteArray(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return new String(Base64.encodeBase64(data)); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java new file mode 100644 index 0000000..9c93895 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java @@ -0,0 +1,75 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.lang3.StringUtils; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class CommonUtil { + + public static String CutId(String id) { + return id.substring(6, 10) + "-" + id.substring(10, 12) + "-" + id.substring(12, 14); + } + + public static boolean isIDNumber(String IDNumber) { + if (IDNumber == null || "".equals(IDNumber)) { + return false; + } + // 定义判别用户身份证号的正则表达式(15位或者18位,最后一位可以为字母) + String regularExpression = + "(^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|" + + "(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}$)"; + boolean matches = IDNumber.matches(regularExpression); + // 判断第18位校验值 + if (matches) { + if (IDNumber.length() == 18) { + try { + char[] charArray = IDNumber.toCharArray(); + // 前十七位加权因子 + int[] idCardWi = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; + // 这是除以11后,可能产生的11位余数对应的验证码 + String[] idCardY = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"}; + int sum = 0; + for (int i = 0; i < idCardWi.length; i++) { + int current = Integer.parseInt(String.valueOf(charArray[i])); + int count = current * idCardWi[i]; + sum += count; + } + char idCardLast = charArray[17]; + int idCardMod = sum % 11; + if (idCardY[idCardMod].toUpperCase() + .equals(String.valueOf(idCardLast).toUpperCase())) { + return true; + } else { + System.out.println("身份证最后一位:" + String.valueOf(idCardLast).toUpperCase() + + "错误,正确的应该是:" + idCardY[idCardMod].toUpperCase()); + return false; + } + + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } else { + return false; + } + } + return matches; + } + + + public static boolean CheckMobilePhoneNum(String phoneNum) { + if (StringUtils.isEmpty(phoneNum)) + return true; + String regex = "^(1[3-9]\\d{9}$)"; + if (phoneNum.length() == 11) { + Pattern p = Pattern.compile(regex); + Matcher m = p.matcher(phoneNum); + if (m.matches()) { + return true; + } + } + return false; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java new file mode 100644 index 0000000..191ef79 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java @@ -0,0 +1,116 @@ +package com.casic.missiles.modular.util; + + +import javafx.util.Pair; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +/** + * Created by Administrator on 2015/2/25. + */ +public class DateUtils { + public static SimpleDateFormat sdf_day = new SimpleDateFormat("yyyy-MM-dd"); + public static SimpleDateFormat sdf_day_time = new SimpleDateFormat("yyyyMMddhhmmss"); + public static final SimpleDateFormat sdf4 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + public static final SimpleDateFormat sdf5 = new SimpleDateFormat("HH:mm:ss"); + + + /** + * 获取当年的第一天 + * + * @return + */ + public static Date getCurrYearFirst() { + Calendar currCal = Calendar.getInstance(); + int currentYear = currCal.get(Calendar.YEAR); + return getYearFirst(currentYear); + } + + + /** + * 获取某年第一天日期 + * + * @param year 年份 + * @return Date + */ + public static Date getYearFirst(int year) { + Calendar calendar = Calendar.getInstance(); + calendar.clear(); + calendar.set(Calendar.YEAR, year); + Date currYearFirst = calendar.getTime(); + return currYearFirst; + } + + /** + * 最近7日(不包括今日) + */ + public static Pair getLastSevenDays() { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, -7); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 最近n日(不包括今日) + */ + public static Pair getLastNDays(int n) { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, n * -1); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 日期时间加n天 + */ + public static String addDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf4.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf4.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 日期加n天 + */ + public static String addNDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf_day.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf_day.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 昨日 + */ + public static String getYesterday() { + + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.DATE, -2); + return sdf_day.format(calendar.getTime()); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java new file mode 100644 index 0000000..da0f8ee --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java @@ -0,0 +1,49 @@ +package com.casic.missiles.modular.util; + +import com.hikvision.artemis.sdk.ArtemisHttpUtil; +import com.hikvision.artemis.sdk.config.ArtemisConfig; + +import java.util.HashMap; +import java.util.Map; + +public class HikUtil { + + public static String hikApi(String uri, String body) { + + /** + * STEP1:设置平台参数,根据实际情况,设置host appkey appsecret 三个参数. + */ + ArtemisConfig.host = "192.168.1.22:443"; // artemis网关服务器ip端口 + ArtemisConfig.appKey = "25766251"; // 秘钥appkey + ArtemisConfig.appSecret = "h2o6zXtzCmt8eaOaMkXb";// 秘钥appSecret + + /** + * STEP2:设置OpenAPI接口的上下文 + */ + final String ARTEMIS_PATH = "/artemis"; + + /** + * STEP3:设置接口的URI地址 + */ + final String previewURLsApi = ARTEMIS_PATH + uri; + Map path = new HashMap(2) { + { + put("https://", previewURLsApi);//根据现场环境部署确认是http还是https + } + }; + + /** + * STEP4:设置参数提交方式 + */ + String contentType = "application/json"; + + /** + * STEP5:组装请求参数 + */ + /** + * STEP6:调用接口 + */ + String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, contentType, null);// post请求application/json类型参数 + return result; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java new file mode 100644 index 0000000..4867144 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java @@ -0,0 +1,149 @@ +package com.casic.missiles.modular.util; + +import org.springframework.http.*; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; + +/** + * @Description: http请求工具类 + * @Author: wangpeng + * @Date: 2022/7/17 11:49 + */ +public class HttpUtil { + /** + * get请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String get(String url, MultiValueMap params) { + return get(url, params, null); + } + + /** + * get请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String get(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.GET); + } + + /** + * post请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String post(String url, MultiValueMap params) { + return post(url, params, null); + } + + /** + * post请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String post(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.POST); + } + + /** + * put请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String put(String url, MultiValueMap params) { + return put(url, params, null); + } + + /** + * put请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String put(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.PUT); + } + + /** + * delete请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String delete(String url, MultiValueMap params) { + return delete(url, params, null); + } + + /** + * delete请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String delete(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.DELETE); + } + + /** + * 表单请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @param method 请求方式 + * @return + */ + public static String request(String url, MultiValueMap params, MultiValueMap headers, HttpMethod method) { + if (params == null) { + params = new LinkedMultiValueMap<>(); + } + return request(url, params, headers, method, MediaType.APPLICATION_FORM_URLENCODED); + } + + /** + * http请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @param method 请求方式 + * @param mediaType 参数类型 + * @return + */ + public static String request(String url, Object params, MultiValueMap headers, HttpMethod method, MediaType mediaType) { + if (url == null || url.trim().isEmpty()) { + return null; + } + RestTemplate client = new RestTemplate(); + // header + HttpHeaders httpHeaders = new HttpHeaders(); + if (headers != null) { +// httpHeaders.addAll(headers); + httpHeaders.putAll(headers); + } + // 提交方式:表单、json + httpHeaders.setContentType(mediaType); + HttpEntity httpEntity = new HttpEntity(params, httpHeaders); + ResponseEntity response = client.exchange(url, method, httpEntity, String.class); + return response.getBody(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java new file mode 100644 index 0000000..19d8d67 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java @@ -0,0 +1,30 @@ +package com.casic.missiles.modular.util; + +public class SelectDTO { + private String name; + private String value; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public SelectDTO() { + } + + public SelectDTO(String name, String value) { + this.name = name; + this.value = value; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java new file mode 100644 index 0000000..0bd484c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java @@ -0,0 +1,28 @@ +package com.casic.missiles.modular.util; + +public class SocketConst { + + /** + * 新增授权socket前缀 + */ + public static final String SOCKET_PREFIX_ADD_PERMISSION = "addPermission:"; + + /** + * 取消授权socket前缀 + */ + public static final String SOCKET_PREFIX_DELETE_PERMISSION = "deletePermission:"; + + /** + * 人员数据下发socket前缀 + */ + public static final String SOCKET_PREFIX_ADD_PERSON = "addPerson:"; + + /** + * socket返回成功信息 + */ + public static final String SOCKET_SUCCESS_MSG = "ok"; + /** + * 人员数据下发socket前缀 + */ + public static final String SOCKET_PREFIX_DELETE_PERSON = "deletePerson:"; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java new file mode 100644 index 0000000..0452bca --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java @@ -0,0 +1,90 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.io.IOUtils; +import org.springframework.stereotype.Component; + +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.text.SimpleDateFormat; +import java.util.Date; + +@Component +public class SocketUtil { + + public static byte[] sendMessage(String ip, int port, String msg) { + byte[] data = new byte[20]; + + System.out.println("往 " + ip + ":" + port + " 发送数据:" + msg); + InputStream in = null; + OutputStream out = null; + Socket socket = null; + try { + socket = new Socket(); + socket.connect(new InetSocketAddress(ip, port), 1000); + socket.setSoTimeout(2000); + // 向服务端发送数据 + out = socket.getOutputStream(); + out.write(hexString2Bytes(msg)); + out.flush(); + //socket.shutdownOutput(); + // 读取服务端返回数据 + in = socket.getInputStream(); + in.read(data); + } catch (Exception e) { + e.printStackTrace(); + } finally { + IOUtils.closeQuietly(in); + IOUtils.closeQuietly(out); + IOUtils.closeQuietly(socket); + } + return data; + } + + private static int code = 0; + + public static void main(String[] args) { +// byte[] dd = sendMessage("192.168.5.211",6001,"090300000002C543"); + + String dateStr = new SimpleDateFormat("yyMMddHHmmssSSS").format(new Date()); + //String dd = dateStr + String.format("%04d",++code); + + System.out.println(dateStr); + } + + /** + * 返回由字节数组转换来的 16 位有符号整数 + * + * @param bytes 字节数组 + * @return 由两个字节构成的 16 位有符号整数 + */ + public static short toShort(byte[] bytes) { + return (short) ((0xff & bytes[0]) | (0xff00 & (bytes[1] << 8))); + + } + + + public static byte[] hexString2Bytes(String hex) { + if ((hex == null) || (hex.equals(""))) { + return null; + } else if (hex.length() % 2 != 0) { + return null; + } else { + hex = hex.toUpperCase(); + int len = hex.length() / 2; + byte[] b = new byte[len]; + char[] hc = hex.toCharArray(); + for (int i = 0; i < len; i++) { + int p = 2 * i; + b[i] = (byte) (charToByte(hc[p]) << 4 | charToByte(hc[p + 1])); + } + return b; + } + } + + private static byte charToByte(char c) { + return (byte) "0123456789ABCDEF".indexOf(c); + } + +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9e20bc1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea/ +**/target/** +logs/ +*.iml diff --git a/README.md b/README.md new file mode 100644 index 0000000..2fdcd74 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# casic项目 V2.0.0 + +[^_^]: # (Talk is cheap,Show me the code!) + +## 介绍 +基于SpringBoot,致力于做更简洁的后台管理系统,完美整合springboot2.4 + shiro + mybatis-plus ! +基于casic项目代码简洁,注释丰富,上手容易,同时包含许多基础模块(用户管理,角色管理,部门管理,字典管理等10个模块) +可以直接作为一个后台管理系统的脚手架! 2022目标 `更简洁`,`更规范`! + + +#### 其他 +>* [git地址](http://192.168.0.203:8080/gitbucket) +>* [本地免登地址](http://localhost:8083/route/mockToken) diff --git a/casic-server/pom.xml b/casic-server/pom.xml new file mode 100644 index 0000000..c150a12 --- /dev/null +++ b/casic-server/pom.xml @@ -0,0 +1,70 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + 2.0.0 + ../pom.xml + + + casic-server + 2.0.0 + jar + casic-server + casic 的spring boot版本 + + + + + com.casic + casic-core + ${core.version} + provided + + + com.casic + casic-admin-support + ${admin.version} + provided + + + org.springframework.boot + spring-boot-starter-web + ${boot.version} + provided + + + + + com.hikvision.ga + artemis-http-client + 1.1.3 + + + commons-io + commons-io + + + org.springframework.boot + spring-boot-starter-websocket + 2.4.5 + + + io.netty + netty-all + 4.1.42.Final + + + + + + src/main/java + + **/*.xml + + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java new file mode 100644 index 0000000..3a60b9e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java @@ -0,0 +1,36 @@ +package com.casic.missiles.modular.async; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.TaskExecutor; +import org.springframework.scheduling.annotation.AsyncConfigurer; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadPoolExecutor; + +@Configuration +@EnableAsync +public class AsyncConfig implements AsyncConfigurer { + @Override + public Executor getAsyncExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + //核心线程数 + executor.setCorePoolSize(5); + //最大线程数 + executor.setMaxPoolSize(10); + //队列容量 + executor.setQueueCapacity(20); + //设置线程活跃时间(秒) + executor.setKeepAliveSeconds(60); + //默认线程名称 + executor.setThreadNamePrefix("user-rpt-"); + //拒绝策略 + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + //等待所有任务结束后再关闭线程池 + executor.setWaitForTasksToCompleteOnShutdown(true); + return executor; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java new file mode 100644 index 0000000..8ca554c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java @@ -0,0 +1,18 @@ +package com.casic.missiles.modular.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +// tomcat启动无需配置 +@Configuration +public class WebSocketConfig { + /** + * 注入ServerEndpointExporter, + * 这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint + */ + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java new file mode 100644 index 0000000..34fe2cd --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java @@ -0,0 +1,39 @@ +package com.casic.missiles.modular.controller; + + +import com.casic.missiles.model.application.event.core.EventPublisher; +import com.casic.missiles.model.application.event.enums.ModelEventTypeEnum; +import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.modular.event.UserEvent; +import com.casic.missiles.modular.system.model.User; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +/** + * @Description: DemoController + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@RestController +@RequestMapping("/demo") +public class DemoController { + @Autowired + private EventPublisher publisher; + + /** + * 获取mockToken + */ + @PostMapping("/list") + @ResponseBody + public Object list() { + User user = new User(); + user.setAccount("张三"); + publisher.publishEvent(new UserEvent(ModelEventTypeEnum.ADD, user)); + return ResponseData.success(); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java new file mode 100644 index 0000000..aff2889 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java @@ -0,0 +1,23 @@ +package com.casic.missiles.modular.event; + +import com.casic.missiles.model.application.event.core.ModelEvent; +import com.casic.missiles.model.application.event.type.AbstractEventTypeEnum; +import com.casic.missiles.modular.system.model.User; + +/** + * @Description: 用户事件 + * @Author: wangpeng + * @Date: 2022/7/17 11:23 + */ +public class UserEvent extends ModelEvent { + /** + * Create a new {@code ApplicationEvent}. + * + * @param type 事件类型 + * @param source the object on which the event initially occurred or with + * which the event is associated (never {@code null}) + */ + public UserEvent(AbstractEventTypeEnum type, User source) { + super(type, source); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java new file mode 100644 index 0000000..8f9603e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.core.application.event.UserLoginEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserOneListener { + @EventListener + public void onApplicationEvent(UserLoginEvent event) { + log.debug("用户1订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java new file mode 100644 index 0000000..0bd52a3 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.model.application.event.core.EventSubscriber; +import com.casic.missiles.modular.event.UserEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserTwoListener extends EventSubscriber { + @Override + public void onApplicationEvent(UserEvent event) { + log.debug("用户2订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java new file mode 100644 index 0000000..4012170 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java @@ -0,0 +1,88 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang3.StringUtils; +import sun.misc.BASE64Decoder; + +import java.io.*; + +public class Base64Util { + /** + * base64字符串转换成图片 + * + * @param imgStr base64字符串 + * @param imgFilePath 图片存放路径 + * @return + * @author ZHANGJL + * @dateTime 2018-02-23 14:42:17 + */ + public static boolean Base64ToImage(String imgStr, String imgFilePath, String fileDir) { // 对字节数组字符串进行Base64解码并生成图片 + + if (StringUtils.isEmpty(imgStr)) // 图像数据为空 + return false; + + imgStr = imgStr.substring(imgStr.indexOf(",") + 1); + + BASE64Decoder decoder = new BASE64Decoder(); + try { + // Base64解码 + byte[] b = decoder.decodeBuffer(imgStr); + + for (int i = 0; i < b.length; ++i) { + if (b[i] < 0) {// 调整异常数据 + b[i] += 256; + } + } + //如果已存在图像,先删除 + File file = new File(fileDir+File.separator + imgFilePath); + if (file.exists() && file.isFile()) { + file.delete(); + } + File dir = new File(fileDir); + if (!dir.exists()) { + dir.mkdirs(); + } + file = new File(fileDir+File.separator+imgFilePath); + file.createNewFile(); +// ImageIO.write(bImage, "bmp", name); + OutputStream out = new FileOutputStream(fileDir+File.separator+imgFilePath); + out.write(b); + out.flush(); + out.close(); + + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + + } + + public static String getBase64FromInputStream(InputStream in) { + // 将图片文件转化为字节数组字符串,并对其进行Base64编码处理 + byte[] data = null; + // 读取图片字节数组 + try { + ByteArrayOutputStream swapStream = new ByteArrayOutputStream(); + byte[] buff = new byte[100]; + int rc = 0; + while ((rc = in.read(buff, 0, 100)) > 0) { + swapStream.write(buff, 0, rc); + } + data = swapStream.toByteArray(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return new String(Base64.encodeBase64(data)); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java new file mode 100644 index 0000000..9c93895 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java @@ -0,0 +1,75 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.lang3.StringUtils; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class CommonUtil { + + public static String CutId(String id) { + return id.substring(6, 10) + "-" + id.substring(10, 12) + "-" + id.substring(12, 14); + } + + public static boolean isIDNumber(String IDNumber) { + if (IDNumber == null || "".equals(IDNumber)) { + return false; + } + // 定义判别用户身份证号的正则表达式(15位或者18位,最后一位可以为字母) + String regularExpression = + "(^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|" + + "(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}$)"; + boolean matches = IDNumber.matches(regularExpression); + // 判断第18位校验值 + if (matches) { + if (IDNumber.length() == 18) { + try { + char[] charArray = IDNumber.toCharArray(); + // 前十七位加权因子 + int[] idCardWi = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; + // 这是除以11后,可能产生的11位余数对应的验证码 + String[] idCardY = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"}; + int sum = 0; + for (int i = 0; i < idCardWi.length; i++) { + int current = Integer.parseInt(String.valueOf(charArray[i])); + int count = current * idCardWi[i]; + sum += count; + } + char idCardLast = charArray[17]; + int idCardMod = sum % 11; + if (idCardY[idCardMod].toUpperCase() + .equals(String.valueOf(idCardLast).toUpperCase())) { + return true; + } else { + System.out.println("身份证最后一位:" + String.valueOf(idCardLast).toUpperCase() + + "错误,正确的应该是:" + idCardY[idCardMod].toUpperCase()); + return false; + } + + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } else { + return false; + } + } + return matches; + } + + + public static boolean CheckMobilePhoneNum(String phoneNum) { + if (StringUtils.isEmpty(phoneNum)) + return true; + String regex = "^(1[3-9]\\d{9}$)"; + if (phoneNum.length() == 11) { + Pattern p = Pattern.compile(regex); + Matcher m = p.matcher(phoneNum); + if (m.matches()) { + return true; + } + } + return false; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java new file mode 100644 index 0000000..191ef79 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java @@ -0,0 +1,116 @@ +package com.casic.missiles.modular.util; + + +import javafx.util.Pair; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +/** + * Created by Administrator on 2015/2/25. + */ +public class DateUtils { + public static SimpleDateFormat sdf_day = new SimpleDateFormat("yyyy-MM-dd"); + public static SimpleDateFormat sdf_day_time = new SimpleDateFormat("yyyyMMddhhmmss"); + public static final SimpleDateFormat sdf4 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + public static final SimpleDateFormat sdf5 = new SimpleDateFormat("HH:mm:ss"); + + + /** + * 获取当年的第一天 + * + * @return + */ + public static Date getCurrYearFirst() { + Calendar currCal = Calendar.getInstance(); + int currentYear = currCal.get(Calendar.YEAR); + return getYearFirst(currentYear); + } + + + /** + * 获取某年第一天日期 + * + * @param year 年份 + * @return Date + */ + public static Date getYearFirst(int year) { + Calendar calendar = Calendar.getInstance(); + calendar.clear(); + calendar.set(Calendar.YEAR, year); + Date currYearFirst = calendar.getTime(); + return currYearFirst; + } + + /** + * 最近7日(不包括今日) + */ + public static Pair getLastSevenDays() { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, -7); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 最近n日(不包括今日) + */ + public static Pair getLastNDays(int n) { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, n * -1); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 日期时间加n天 + */ + public static String addDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf4.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf4.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 日期加n天 + */ + public static String addNDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf_day.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf_day.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 昨日 + */ + public static String getYesterday() { + + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.DATE, -2); + return sdf_day.format(calendar.getTime()); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java new file mode 100644 index 0000000..da0f8ee --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java @@ -0,0 +1,49 @@ +package com.casic.missiles.modular.util; + +import com.hikvision.artemis.sdk.ArtemisHttpUtil; +import com.hikvision.artemis.sdk.config.ArtemisConfig; + +import java.util.HashMap; +import java.util.Map; + +public class HikUtil { + + public static String hikApi(String uri, String body) { + + /** + * STEP1:设置平台参数,根据实际情况,设置host appkey appsecret 三个参数. + */ + ArtemisConfig.host = "192.168.1.22:443"; // artemis网关服务器ip端口 + ArtemisConfig.appKey = "25766251"; // 秘钥appkey + ArtemisConfig.appSecret = "h2o6zXtzCmt8eaOaMkXb";// 秘钥appSecret + + /** + * STEP2:设置OpenAPI接口的上下文 + */ + final String ARTEMIS_PATH = "/artemis"; + + /** + * STEP3:设置接口的URI地址 + */ + final String previewURLsApi = ARTEMIS_PATH + uri; + Map path = new HashMap(2) { + { + put("https://", previewURLsApi);//根据现场环境部署确认是http还是https + } + }; + + /** + * STEP4:设置参数提交方式 + */ + String contentType = "application/json"; + + /** + * STEP5:组装请求参数 + */ + /** + * STEP6:调用接口 + */ + String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, contentType, null);// post请求application/json类型参数 + return result; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java new file mode 100644 index 0000000..4867144 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java @@ -0,0 +1,149 @@ +package com.casic.missiles.modular.util; + +import org.springframework.http.*; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; + +/** + * @Description: http请求工具类 + * @Author: wangpeng + * @Date: 2022/7/17 11:49 + */ +public class HttpUtil { + /** + * get请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String get(String url, MultiValueMap params) { + return get(url, params, null); + } + + /** + * get请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String get(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.GET); + } + + /** + * post请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String post(String url, MultiValueMap params) { + return post(url, params, null); + } + + /** + * post请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String post(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.POST); + } + + /** + * put请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String put(String url, MultiValueMap params) { + return put(url, params, null); + } + + /** + * put请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String put(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.PUT); + } + + /** + * delete请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String delete(String url, MultiValueMap params) { + return delete(url, params, null); + } + + /** + * delete请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String delete(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.DELETE); + } + + /** + * 表单请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @param method 请求方式 + * @return + */ + public static String request(String url, MultiValueMap params, MultiValueMap headers, HttpMethod method) { + if (params == null) { + params = new LinkedMultiValueMap<>(); + } + return request(url, params, headers, method, MediaType.APPLICATION_FORM_URLENCODED); + } + + /** + * http请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @param method 请求方式 + * @param mediaType 参数类型 + * @return + */ + public static String request(String url, Object params, MultiValueMap headers, HttpMethod method, MediaType mediaType) { + if (url == null || url.trim().isEmpty()) { + return null; + } + RestTemplate client = new RestTemplate(); + // header + HttpHeaders httpHeaders = new HttpHeaders(); + if (headers != null) { +// httpHeaders.addAll(headers); + httpHeaders.putAll(headers); + } + // 提交方式:表单、json + httpHeaders.setContentType(mediaType); + HttpEntity httpEntity = new HttpEntity(params, httpHeaders); + ResponseEntity response = client.exchange(url, method, httpEntity, String.class); + return response.getBody(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java new file mode 100644 index 0000000..19d8d67 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java @@ -0,0 +1,30 @@ +package com.casic.missiles.modular.util; + +public class SelectDTO { + private String name; + private String value; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public SelectDTO() { + } + + public SelectDTO(String name, String value) { + this.name = name; + this.value = value; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java new file mode 100644 index 0000000..0bd484c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java @@ -0,0 +1,28 @@ +package com.casic.missiles.modular.util; + +public class SocketConst { + + /** + * 新增授权socket前缀 + */ + public static final String SOCKET_PREFIX_ADD_PERMISSION = "addPermission:"; + + /** + * 取消授权socket前缀 + */ + public static final String SOCKET_PREFIX_DELETE_PERMISSION = "deletePermission:"; + + /** + * 人员数据下发socket前缀 + */ + public static final String SOCKET_PREFIX_ADD_PERSON = "addPerson:"; + + /** + * socket返回成功信息 + */ + public static final String SOCKET_SUCCESS_MSG = "ok"; + /** + * 人员数据下发socket前缀 + */ + public static final String SOCKET_PREFIX_DELETE_PERSON = "deletePerson:"; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java new file mode 100644 index 0000000..0452bca --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java @@ -0,0 +1,90 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.io.IOUtils; +import org.springframework.stereotype.Component; + +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.text.SimpleDateFormat; +import java.util.Date; + +@Component +public class SocketUtil { + + public static byte[] sendMessage(String ip, int port, String msg) { + byte[] data = new byte[20]; + + System.out.println("往 " + ip + ":" + port + " 发送数据:" + msg); + InputStream in = null; + OutputStream out = null; + Socket socket = null; + try { + socket = new Socket(); + socket.connect(new InetSocketAddress(ip, port), 1000); + socket.setSoTimeout(2000); + // 向服务端发送数据 + out = socket.getOutputStream(); + out.write(hexString2Bytes(msg)); + out.flush(); + //socket.shutdownOutput(); + // 读取服务端返回数据 + in = socket.getInputStream(); + in.read(data); + } catch (Exception e) { + e.printStackTrace(); + } finally { + IOUtils.closeQuietly(in); + IOUtils.closeQuietly(out); + IOUtils.closeQuietly(socket); + } + return data; + } + + private static int code = 0; + + public static void main(String[] args) { +// byte[] dd = sendMessage("192.168.5.211",6001,"090300000002C543"); + + String dateStr = new SimpleDateFormat("yyMMddHHmmssSSS").format(new Date()); + //String dd = dateStr + String.format("%04d",++code); + + System.out.println(dateStr); + } + + /** + * 返回由字节数组转换来的 16 位有符号整数 + * + * @param bytes 字节数组 + * @return 由两个字节构成的 16 位有符号整数 + */ + public static short toShort(byte[] bytes) { + return (short) ((0xff & bytes[0]) | (0xff00 & (bytes[1] << 8))); + + } + + + public static byte[] hexString2Bytes(String hex) { + if ((hex == null) || (hex.equals(""))) { + return null; + } else if (hex.length() % 2 != 0) { + return null; + } else { + hex = hex.toUpperCase(); + int len = hex.length() / 2; + byte[] b = new byte[len]; + char[] hc = hex.toCharArray(); + for (int i = 0; i < len; i++) { + int p = 2 * i; + b[i] = (byte) (charToByte(hc[p]) << 4 | charToByte(hc[p + 1])); + } + return b; + } + } + + private static byte charToByte(char c) { + return (byte) "0123456789ABCDEF".indexOf(c); + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java b/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java new file mode 100644 index 0000000..9b4155c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java @@ -0,0 +1,105 @@ +package com.casic.missiles.modular.util; + +import org.springframework.stereotype.Component; + +import javax.websocket.OnClose; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.PathParam; +import javax.websocket.server.ServerEndpoint; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CopyOnWriteArraySet; + +/** + * @Description: 此注解相当于设置访问URL + * @Author: wangpeng + * @Date: 2022/7/17 11:48 + */ +@Component +@ServerEndpoint("/websocket/{userId}") +public class WebSocket { + private Session session; + + private static CopyOnWriteArraySet webSockets = new CopyOnWriteArraySet<>(); + private static Map sessionPool = new HashMap(); + + @OnOpen + public void onOpen(Session session, @PathParam(value = "userId") String userId) { + this.session = session; + webSockets.add(this); + sessionPool.put(userId, session); + System.out.println(userId + "【websocket消息】有新的连接,总数为:" + webSockets.size()); + } + + @OnClose + public void onClose() { + webSockets.remove(this); + System.out.println("【websocket消息】连接断开,总数为:" + webSockets.size()); + } + + @OnMessage + public void onMessage(String message) { + System.out.println("【websocket消息】收到客户端消息:" + message); + } + + // 此为广播消息 + public void sendAllMessage(String message) { + for (WebSocket webSocket : webSockets) { + System.out.println("【websocket消息】广播消息:" + message); + try { + webSocket.session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + // 发送列表消息 + public void sendListMessage(List userIds, String message) { + System.out.println("【websocket消息】列表消息:" + message); + for (String userId : userIds) { + Session session = sessionPool.get(userId); + if (session != null) { + try { + session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + + // 发送列表消息 + +// public void sendListMessage(List userIds, Object data){ +// System.out.println("【websocket消息】列表消息:"+data); +// for (String userId : userIds) { +// Session session = sessionPool.get(userId); +// if (session != null) { +// try { +//// session.getAsyncRemote().sendText(message); +// session.getAsyncRemote().sendObject(data); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// } +// } + + // 此为单点消息 + public void sendOneMessage(String userId, String message) { + System.out.println("【websocket消息】单点消息:" + message); + Session session = sessionPool.get(userId); + if (session != null) { + try { + session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9e20bc1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea/ +**/target/** +logs/ +*.iml diff --git a/README.md b/README.md new file mode 100644 index 0000000..2fdcd74 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# casic项目 V2.0.0 + +[^_^]: # (Talk is cheap,Show me the code!) + +## 介绍 +基于SpringBoot,致力于做更简洁的后台管理系统,完美整合springboot2.4 + shiro + mybatis-plus ! +基于casic项目代码简洁,注释丰富,上手容易,同时包含许多基础模块(用户管理,角色管理,部门管理,字典管理等10个模块) +可以直接作为一个后台管理系统的脚手架! 2022目标 `更简洁`,`更规范`! + + +#### 其他 +>* [git地址](http://192.168.0.203:8080/gitbucket) +>* [本地免登地址](http://localhost:8083/route/mockToken) diff --git a/casic-server/pom.xml b/casic-server/pom.xml new file mode 100644 index 0000000..c150a12 --- /dev/null +++ b/casic-server/pom.xml @@ -0,0 +1,70 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + 2.0.0 + ../pom.xml + + + casic-server + 2.0.0 + jar + casic-server + casic 的spring boot版本 + + + + + com.casic + casic-core + ${core.version} + provided + + + com.casic + casic-admin-support + ${admin.version} + provided + + + org.springframework.boot + spring-boot-starter-web + ${boot.version} + provided + + + + + com.hikvision.ga + artemis-http-client + 1.1.3 + + + commons-io + commons-io + + + org.springframework.boot + spring-boot-starter-websocket + 2.4.5 + + + io.netty + netty-all + 4.1.42.Final + + + + + + src/main/java + + **/*.xml + + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java new file mode 100644 index 0000000..3a60b9e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java @@ -0,0 +1,36 @@ +package com.casic.missiles.modular.async; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.TaskExecutor; +import org.springframework.scheduling.annotation.AsyncConfigurer; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadPoolExecutor; + +@Configuration +@EnableAsync +public class AsyncConfig implements AsyncConfigurer { + @Override + public Executor getAsyncExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + //核心线程数 + executor.setCorePoolSize(5); + //最大线程数 + executor.setMaxPoolSize(10); + //队列容量 + executor.setQueueCapacity(20); + //设置线程活跃时间(秒) + executor.setKeepAliveSeconds(60); + //默认线程名称 + executor.setThreadNamePrefix("user-rpt-"); + //拒绝策略 + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + //等待所有任务结束后再关闭线程池 + executor.setWaitForTasksToCompleteOnShutdown(true); + return executor; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java new file mode 100644 index 0000000..8ca554c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java @@ -0,0 +1,18 @@ +package com.casic.missiles.modular.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +// tomcat启动无需配置 +@Configuration +public class WebSocketConfig { + /** + * 注入ServerEndpointExporter, + * 这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint + */ + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java new file mode 100644 index 0000000..34fe2cd --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java @@ -0,0 +1,39 @@ +package com.casic.missiles.modular.controller; + + +import com.casic.missiles.model.application.event.core.EventPublisher; +import com.casic.missiles.model.application.event.enums.ModelEventTypeEnum; +import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.modular.event.UserEvent; +import com.casic.missiles.modular.system.model.User; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +/** + * @Description: DemoController + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@RestController +@RequestMapping("/demo") +public class DemoController { + @Autowired + private EventPublisher publisher; + + /** + * 获取mockToken + */ + @PostMapping("/list") + @ResponseBody + public Object list() { + User user = new User(); + user.setAccount("张三"); + publisher.publishEvent(new UserEvent(ModelEventTypeEnum.ADD, user)); + return ResponseData.success(); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java new file mode 100644 index 0000000..aff2889 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java @@ -0,0 +1,23 @@ +package com.casic.missiles.modular.event; + +import com.casic.missiles.model.application.event.core.ModelEvent; +import com.casic.missiles.model.application.event.type.AbstractEventTypeEnum; +import com.casic.missiles.modular.system.model.User; + +/** + * @Description: 用户事件 + * @Author: wangpeng + * @Date: 2022/7/17 11:23 + */ +public class UserEvent extends ModelEvent { + /** + * Create a new {@code ApplicationEvent}. + * + * @param type 事件类型 + * @param source the object on which the event initially occurred or with + * which the event is associated (never {@code null}) + */ + public UserEvent(AbstractEventTypeEnum type, User source) { + super(type, source); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java new file mode 100644 index 0000000..8f9603e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.core.application.event.UserLoginEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserOneListener { + @EventListener + public void onApplicationEvent(UserLoginEvent event) { + log.debug("用户1订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java new file mode 100644 index 0000000..0bd52a3 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.model.application.event.core.EventSubscriber; +import com.casic.missiles.modular.event.UserEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserTwoListener extends EventSubscriber { + @Override + public void onApplicationEvent(UserEvent event) { + log.debug("用户2订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java new file mode 100644 index 0000000..4012170 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java @@ -0,0 +1,88 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang3.StringUtils; +import sun.misc.BASE64Decoder; + +import java.io.*; + +public class Base64Util { + /** + * base64字符串转换成图片 + * + * @param imgStr base64字符串 + * @param imgFilePath 图片存放路径 + * @return + * @author ZHANGJL + * @dateTime 2018-02-23 14:42:17 + */ + public static boolean Base64ToImage(String imgStr, String imgFilePath, String fileDir) { // 对字节数组字符串进行Base64解码并生成图片 + + if (StringUtils.isEmpty(imgStr)) // 图像数据为空 + return false; + + imgStr = imgStr.substring(imgStr.indexOf(",") + 1); + + BASE64Decoder decoder = new BASE64Decoder(); + try { + // Base64解码 + byte[] b = decoder.decodeBuffer(imgStr); + + for (int i = 0; i < b.length; ++i) { + if (b[i] < 0) {// 调整异常数据 + b[i] += 256; + } + } + //如果已存在图像,先删除 + File file = new File(fileDir+File.separator + imgFilePath); + if (file.exists() && file.isFile()) { + file.delete(); + } + File dir = new File(fileDir); + if (!dir.exists()) { + dir.mkdirs(); + } + file = new File(fileDir+File.separator+imgFilePath); + file.createNewFile(); +// ImageIO.write(bImage, "bmp", name); + OutputStream out = new FileOutputStream(fileDir+File.separator+imgFilePath); + out.write(b); + out.flush(); + out.close(); + + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + + } + + public static String getBase64FromInputStream(InputStream in) { + // 将图片文件转化为字节数组字符串,并对其进行Base64编码处理 + byte[] data = null; + // 读取图片字节数组 + try { + ByteArrayOutputStream swapStream = new ByteArrayOutputStream(); + byte[] buff = new byte[100]; + int rc = 0; + while ((rc = in.read(buff, 0, 100)) > 0) { + swapStream.write(buff, 0, rc); + } + data = swapStream.toByteArray(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return new String(Base64.encodeBase64(data)); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java new file mode 100644 index 0000000..9c93895 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java @@ -0,0 +1,75 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.lang3.StringUtils; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class CommonUtil { + + public static String CutId(String id) { + return id.substring(6, 10) + "-" + id.substring(10, 12) + "-" + id.substring(12, 14); + } + + public static boolean isIDNumber(String IDNumber) { + if (IDNumber == null || "".equals(IDNumber)) { + return false; + } + // 定义判别用户身份证号的正则表达式(15位或者18位,最后一位可以为字母) + String regularExpression = + "(^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|" + + "(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}$)"; + boolean matches = IDNumber.matches(regularExpression); + // 判断第18位校验值 + if (matches) { + if (IDNumber.length() == 18) { + try { + char[] charArray = IDNumber.toCharArray(); + // 前十七位加权因子 + int[] idCardWi = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; + // 这是除以11后,可能产生的11位余数对应的验证码 + String[] idCardY = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"}; + int sum = 0; + for (int i = 0; i < idCardWi.length; i++) { + int current = Integer.parseInt(String.valueOf(charArray[i])); + int count = current * idCardWi[i]; + sum += count; + } + char idCardLast = charArray[17]; + int idCardMod = sum % 11; + if (idCardY[idCardMod].toUpperCase() + .equals(String.valueOf(idCardLast).toUpperCase())) { + return true; + } else { + System.out.println("身份证最后一位:" + String.valueOf(idCardLast).toUpperCase() + + "错误,正确的应该是:" + idCardY[idCardMod].toUpperCase()); + return false; + } + + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } else { + return false; + } + } + return matches; + } + + + public static boolean CheckMobilePhoneNum(String phoneNum) { + if (StringUtils.isEmpty(phoneNum)) + return true; + String regex = "^(1[3-9]\\d{9}$)"; + if (phoneNum.length() == 11) { + Pattern p = Pattern.compile(regex); + Matcher m = p.matcher(phoneNum); + if (m.matches()) { + return true; + } + } + return false; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java new file mode 100644 index 0000000..191ef79 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java @@ -0,0 +1,116 @@ +package com.casic.missiles.modular.util; + + +import javafx.util.Pair; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +/** + * Created by Administrator on 2015/2/25. + */ +public class DateUtils { + public static SimpleDateFormat sdf_day = new SimpleDateFormat("yyyy-MM-dd"); + public static SimpleDateFormat sdf_day_time = new SimpleDateFormat("yyyyMMddhhmmss"); + public static final SimpleDateFormat sdf4 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + public static final SimpleDateFormat sdf5 = new SimpleDateFormat("HH:mm:ss"); + + + /** + * 获取当年的第一天 + * + * @return + */ + public static Date getCurrYearFirst() { + Calendar currCal = Calendar.getInstance(); + int currentYear = currCal.get(Calendar.YEAR); + return getYearFirst(currentYear); + } + + + /** + * 获取某年第一天日期 + * + * @param year 年份 + * @return Date + */ + public static Date getYearFirst(int year) { + Calendar calendar = Calendar.getInstance(); + calendar.clear(); + calendar.set(Calendar.YEAR, year); + Date currYearFirst = calendar.getTime(); + return currYearFirst; + } + + /** + * 最近7日(不包括今日) + */ + public static Pair getLastSevenDays() { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, -7); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 最近n日(不包括今日) + */ + public static Pair getLastNDays(int n) { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, n * -1); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 日期时间加n天 + */ + public static String addDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf4.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf4.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 日期加n天 + */ + public static String addNDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf_day.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf_day.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 昨日 + */ + public static String getYesterday() { + + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.DATE, -2); + return sdf_day.format(calendar.getTime()); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java new file mode 100644 index 0000000..da0f8ee --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java @@ -0,0 +1,49 @@ +package com.casic.missiles.modular.util; + +import com.hikvision.artemis.sdk.ArtemisHttpUtil; +import com.hikvision.artemis.sdk.config.ArtemisConfig; + +import java.util.HashMap; +import java.util.Map; + +public class HikUtil { + + public static String hikApi(String uri, String body) { + + /** + * STEP1:设置平台参数,根据实际情况,设置host appkey appsecret 三个参数. + */ + ArtemisConfig.host = "192.168.1.22:443"; // artemis网关服务器ip端口 + ArtemisConfig.appKey = "25766251"; // 秘钥appkey + ArtemisConfig.appSecret = "h2o6zXtzCmt8eaOaMkXb";// 秘钥appSecret + + /** + * STEP2:设置OpenAPI接口的上下文 + */ + final String ARTEMIS_PATH = "/artemis"; + + /** + * STEP3:设置接口的URI地址 + */ + final String previewURLsApi = ARTEMIS_PATH + uri; + Map path = new HashMap(2) { + { + put("https://", previewURLsApi);//根据现场环境部署确认是http还是https + } + }; + + /** + * STEP4:设置参数提交方式 + */ + String contentType = "application/json"; + + /** + * STEP5:组装请求参数 + */ + /** + * STEP6:调用接口 + */ + String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, contentType, null);// post请求application/json类型参数 + return result; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java new file mode 100644 index 0000000..4867144 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java @@ -0,0 +1,149 @@ +package com.casic.missiles.modular.util; + +import org.springframework.http.*; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; + +/** + * @Description: http请求工具类 + * @Author: wangpeng + * @Date: 2022/7/17 11:49 + */ +public class HttpUtil { + /** + * get请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String get(String url, MultiValueMap params) { + return get(url, params, null); + } + + /** + * get请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String get(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.GET); + } + + /** + * post请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String post(String url, MultiValueMap params) { + return post(url, params, null); + } + + /** + * post请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String post(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.POST); + } + + /** + * put请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String put(String url, MultiValueMap params) { + return put(url, params, null); + } + + /** + * put请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String put(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.PUT); + } + + /** + * delete请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String delete(String url, MultiValueMap params) { + return delete(url, params, null); + } + + /** + * delete请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String delete(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.DELETE); + } + + /** + * 表单请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @param method 请求方式 + * @return + */ + public static String request(String url, MultiValueMap params, MultiValueMap headers, HttpMethod method) { + if (params == null) { + params = new LinkedMultiValueMap<>(); + } + return request(url, params, headers, method, MediaType.APPLICATION_FORM_URLENCODED); + } + + /** + * http请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @param method 请求方式 + * @param mediaType 参数类型 + * @return + */ + public static String request(String url, Object params, MultiValueMap headers, HttpMethod method, MediaType mediaType) { + if (url == null || url.trim().isEmpty()) { + return null; + } + RestTemplate client = new RestTemplate(); + // header + HttpHeaders httpHeaders = new HttpHeaders(); + if (headers != null) { +// httpHeaders.addAll(headers); + httpHeaders.putAll(headers); + } + // 提交方式:表单、json + httpHeaders.setContentType(mediaType); + HttpEntity httpEntity = new HttpEntity(params, httpHeaders); + ResponseEntity response = client.exchange(url, method, httpEntity, String.class); + return response.getBody(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java new file mode 100644 index 0000000..19d8d67 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java @@ -0,0 +1,30 @@ +package com.casic.missiles.modular.util; + +public class SelectDTO { + private String name; + private String value; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public SelectDTO() { + } + + public SelectDTO(String name, String value) { + this.name = name; + this.value = value; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java new file mode 100644 index 0000000..0bd484c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java @@ -0,0 +1,28 @@ +package com.casic.missiles.modular.util; + +public class SocketConst { + + /** + * 新增授权socket前缀 + */ + public static final String SOCKET_PREFIX_ADD_PERMISSION = "addPermission:"; + + /** + * 取消授权socket前缀 + */ + public static final String SOCKET_PREFIX_DELETE_PERMISSION = "deletePermission:"; + + /** + * 人员数据下发socket前缀 + */ + public static final String SOCKET_PREFIX_ADD_PERSON = "addPerson:"; + + /** + * socket返回成功信息 + */ + public static final String SOCKET_SUCCESS_MSG = "ok"; + /** + * 人员数据下发socket前缀 + */ + public static final String SOCKET_PREFIX_DELETE_PERSON = "deletePerson:"; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java new file mode 100644 index 0000000..0452bca --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java @@ -0,0 +1,90 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.io.IOUtils; +import org.springframework.stereotype.Component; + +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.text.SimpleDateFormat; +import java.util.Date; + +@Component +public class SocketUtil { + + public static byte[] sendMessage(String ip, int port, String msg) { + byte[] data = new byte[20]; + + System.out.println("往 " + ip + ":" + port + " 发送数据:" + msg); + InputStream in = null; + OutputStream out = null; + Socket socket = null; + try { + socket = new Socket(); + socket.connect(new InetSocketAddress(ip, port), 1000); + socket.setSoTimeout(2000); + // 向服务端发送数据 + out = socket.getOutputStream(); + out.write(hexString2Bytes(msg)); + out.flush(); + //socket.shutdownOutput(); + // 读取服务端返回数据 + in = socket.getInputStream(); + in.read(data); + } catch (Exception e) { + e.printStackTrace(); + } finally { + IOUtils.closeQuietly(in); + IOUtils.closeQuietly(out); + IOUtils.closeQuietly(socket); + } + return data; + } + + private static int code = 0; + + public static void main(String[] args) { +// byte[] dd = sendMessage("192.168.5.211",6001,"090300000002C543"); + + String dateStr = new SimpleDateFormat("yyMMddHHmmssSSS").format(new Date()); + //String dd = dateStr + String.format("%04d",++code); + + System.out.println(dateStr); + } + + /** + * 返回由字节数组转换来的 16 位有符号整数 + * + * @param bytes 字节数组 + * @return 由两个字节构成的 16 位有符号整数 + */ + public static short toShort(byte[] bytes) { + return (short) ((0xff & bytes[0]) | (0xff00 & (bytes[1] << 8))); + + } + + + public static byte[] hexString2Bytes(String hex) { + if ((hex == null) || (hex.equals(""))) { + return null; + } else if (hex.length() % 2 != 0) { + return null; + } else { + hex = hex.toUpperCase(); + int len = hex.length() / 2; + byte[] b = new byte[len]; + char[] hc = hex.toCharArray(); + for (int i = 0; i < len; i++) { + int p = 2 * i; + b[i] = (byte) (charToByte(hc[p]) << 4 | charToByte(hc[p + 1])); + } + return b; + } + } + + private static byte charToByte(char c) { + return (byte) "0123456789ABCDEF".indexOf(c); + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java b/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java new file mode 100644 index 0000000..9b4155c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java @@ -0,0 +1,105 @@ +package com.casic.missiles.modular.util; + +import org.springframework.stereotype.Component; + +import javax.websocket.OnClose; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.PathParam; +import javax.websocket.server.ServerEndpoint; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CopyOnWriteArraySet; + +/** + * @Description: 此注解相当于设置访问URL + * @Author: wangpeng + * @Date: 2022/7/17 11:48 + */ +@Component +@ServerEndpoint("/websocket/{userId}") +public class WebSocket { + private Session session; + + private static CopyOnWriteArraySet webSockets = new CopyOnWriteArraySet<>(); + private static Map sessionPool = new HashMap(); + + @OnOpen + public void onOpen(Session session, @PathParam(value = "userId") String userId) { + this.session = session; + webSockets.add(this); + sessionPool.put(userId, session); + System.out.println(userId + "【websocket消息】有新的连接,总数为:" + webSockets.size()); + } + + @OnClose + public void onClose() { + webSockets.remove(this); + System.out.println("【websocket消息】连接断开,总数为:" + webSockets.size()); + } + + @OnMessage + public void onMessage(String message) { + System.out.println("【websocket消息】收到客户端消息:" + message); + } + + // 此为广播消息 + public void sendAllMessage(String message) { + for (WebSocket webSocket : webSockets) { + System.out.println("【websocket消息】广播消息:" + message); + try { + webSocket.session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + // 发送列表消息 + public void sendListMessage(List userIds, String message) { + System.out.println("【websocket消息】列表消息:" + message); + for (String userId : userIds) { + Session session = sessionPool.get(userId); + if (session != null) { + try { + session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + + // 发送列表消息 + +// public void sendListMessage(List userIds, Object data){ +// System.out.println("【websocket消息】列表消息:"+data); +// for (String userId : userIds) { +// Session session = sessionPool.get(userId); +// if (session != null) { +// try { +//// session.getAsyncRemote().sendText(message); +// session.getAsyncRemote().sendObject(data); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// } +// } + + // 此为单点消息 + public void sendOneMessage(String userId, String message) { + System.out.println("【websocket消息】单点消息:" + message); + Session session = sessionPool.get(userId); + if (session != null) { + try { + session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java new file mode 100644 index 0000000..0c1f5f1 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java @@ -0,0 +1,115 @@ +package com.casic.missiles.modular.util; + +import org.springframework.web.multipart.MultipartFile; + +import java.io.*; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipInputStream; + +/** + * @Description: 读取zip文件内容 + * @Author: wangpeng + * @Date: 2022/7/17 11:48 + */ +public class ZipFileUtil { + public static List getFile(String fileName) { + File file = new File(fileName); + ZipFile zipFile = null; + ZipInputStream zin = null; + FileInputStream fis = null; + List selectDTOList = new ArrayList<>(); + try { + Charset gbk = Charset.forName("GBK"); + zipFile = new ZipFile(file, gbk); + fis = new FileInputStream(file); + zin = new ZipInputStream(fis, gbk); + + ZipEntry ze = null; + while ((ze = zin.getNextEntry()) != null) { + String path = ze.getName(); + System.out.println(path); + if (!ze.isDirectory()) { + InputStream inputStream = zipFile.getInputStream(ze); + String base64Photo = Base64Util.getBase64FromInputStream(inputStream); +// List texts = IOUtils.readLines(inputStream); +// for (String text : texts) { +// System.out.println(" " + text); +// } + selectDTOList.add(new SelectDTO(path.substring(path.indexOf("/")+1), "data:image/png;base64,"+base64Photo)); + inputStream.close(); + } + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (zin != null) { + zin.closeEntry(); + zin.close(); + } + if (fis != null) + fis.close(); + if (zipFile != null) + zipFile.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return selectDTOList; + } + + + /** + * MultipartFile 转 File + * + * @param file + * @throws Exception + */ + public static File multipartFileToFile(MultipartFile file) throws Exception { + + File toFile = null; + if (file.equals("") || file.getSize() <= 0) { + file = null; + } else { + InputStream ins = null; + ins = file.getInputStream(); + toFile = new File(file.getOriginalFilename()); + inputStreamToFile(ins, toFile); + ins.close(); + } + return toFile; + } + + //获取流文件 + private static void inputStreamToFile(InputStream ins, File file) { + try { + OutputStream os = new FileOutputStream(file); + int bytesRead = 0; + byte[] buffer = new byte[8192]; + while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) { + os.write(buffer, 0, bytesRead); + } + os.close(); + ins.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 删除本地临时文件 + * + * @param file + */ + public static void delteTempFile(File file) { + if (file != null) { + File del = new File(file.toURI()); + del.delete(); + } + } +} + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9e20bc1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea/ +**/target/** +logs/ +*.iml diff --git a/README.md b/README.md new file mode 100644 index 0000000..2fdcd74 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# casic项目 V2.0.0 + +[^_^]: # (Talk is cheap,Show me the code!) + +## 介绍 +基于SpringBoot,致力于做更简洁的后台管理系统,完美整合springboot2.4 + shiro + mybatis-plus ! +基于casic项目代码简洁,注释丰富,上手容易,同时包含许多基础模块(用户管理,角色管理,部门管理,字典管理等10个模块) +可以直接作为一个后台管理系统的脚手架! 2022目标 `更简洁`,`更规范`! + + +#### 其他 +>* [git地址](http://192.168.0.203:8080/gitbucket) +>* [本地免登地址](http://localhost:8083/route/mockToken) diff --git a/casic-server/pom.xml b/casic-server/pom.xml new file mode 100644 index 0000000..c150a12 --- /dev/null +++ b/casic-server/pom.xml @@ -0,0 +1,70 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + 2.0.0 + ../pom.xml + + + casic-server + 2.0.0 + jar + casic-server + casic 的spring boot版本 + + + + + com.casic + casic-core + ${core.version} + provided + + + com.casic + casic-admin-support + ${admin.version} + provided + + + org.springframework.boot + spring-boot-starter-web + ${boot.version} + provided + + + + + com.hikvision.ga + artemis-http-client + 1.1.3 + + + commons-io + commons-io + + + org.springframework.boot + spring-boot-starter-websocket + 2.4.5 + + + io.netty + netty-all + 4.1.42.Final + + + + + + src/main/java + + **/*.xml + + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java new file mode 100644 index 0000000..3a60b9e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java @@ -0,0 +1,36 @@ +package com.casic.missiles.modular.async; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.TaskExecutor; +import org.springframework.scheduling.annotation.AsyncConfigurer; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadPoolExecutor; + +@Configuration +@EnableAsync +public class AsyncConfig implements AsyncConfigurer { + @Override + public Executor getAsyncExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + //核心线程数 + executor.setCorePoolSize(5); + //最大线程数 + executor.setMaxPoolSize(10); + //队列容量 + executor.setQueueCapacity(20); + //设置线程活跃时间(秒) + executor.setKeepAliveSeconds(60); + //默认线程名称 + executor.setThreadNamePrefix("user-rpt-"); + //拒绝策略 + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + //等待所有任务结束后再关闭线程池 + executor.setWaitForTasksToCompleteOnShutdown(true); + return executor; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java new file mode 100644 index 0000000..8ca554c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java @@ -0,0 +1,18 @@ +package com.casic.missiles.modular.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +// tomcat启动无需配置 +@Configuration +public class WebSocketConfig { + /** + * 注入ServerEndpointExporter, + * 这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint + */ + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java new file mode 100644 index 0000000..34fe2cd --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java @@ -0,0 +1,39 @@ +package com.casic.missiles.modular.controller; + + +import com.casic.missiles.model.application.event.core.EventPublisher; +import com.casic.missiles.model.application.event.enums.ModelEventTypeEnum; +import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.modular.event.UserEvent; +import com.casic.missiles.modular.system.model.User; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +/** + * @Description: DemoController + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@RestController +@RequestMapping("/demo") +public class DemoController { + @Autowired + private EventPublisher publisher; + + /** + * 获取mockToken + */ + @PostMapping("/list") + @ResponseBody + public Object list() { + User user = new User(); + user.setAccount("张三"); + publisher.publishEvent(new UserEvent(ModelEventTypeEnum.ADD, user)); + return ResponseData.success(); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java new file mode 100644 index 0000000..aff2889 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java @@ -0,0 +1,23 @@ +package com.casic.missiles.modular.event; + +import com.casic.missiles.model.application.event.core.ModelEvent; +import com.casic.missiles.model.application.event.type.AbstractEventTypeEnum; +import com.casic.missiles.modular.system.model.User; + +/** + * @Description: 用户事件 + * @Author: wangpeng + * @Date: 2022/7/17 11:23 + */ +public class UserEvent extends ModelEvent { + /** + * Create a new {@code ApplicationEvent}. + * + * @param type 事件类型 + * @param source the object on which the event initially occurred or with + * which the event is associated (never {@code null}) + */ + public UserEvent(AbstractEventTypeEnum type, User source) { + super(type, source); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java new file mode 100644 index 0000000..8f9603e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.core.application.event.UserLoginEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserOneListener { + @EventListener + public void onApplicationEvent(UserLoginEvent event) { + log.debug("用户1订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java new file mode 100644 index 0000000..0bd52a3 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.model.application.event.core.EventSubscriber; +import com.casic.missiles.modular.event.UserEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserTwoListener extends EventSubscriber { + @Override + public void onApplicationEvent(UserEvent event) { + log.debug("用户2订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java new file mode 100644 index 0000000..4012170 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java @@ -0,0 +1,88 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang3.StringUtils; +import sun.misc.BASE64Decoder; + +import java.io.*; + +public class Base64Util { + /** + * base64字符串转换成图片 + * + * @param imgStr base64字符串 + * @param imgFilePath 图片存放路径 + * @return + * @author ZHANGJL + * @dateTime 2018-02-23 14:42:17 + */ + public static boolean Base64ToImage(String imgStr, String imgFilePath, String fileDir) { // 对字节数组字符串进行Base64解码并生成图片 + + if (StringUtils.isEmpty(imgStr)) // 图像数据为空 + return false; + + imgStr = imgStr.substring(imgStr.indexOf(",") + 1); + + BASE64Decoder decoder = new BASE64Decoder(); + try { + // Base64解码 + byte[] b = decoder.decodeBuffer(imgStr); + + for (int i = 0; i < b.length; ++i) { + if (b[i] < 0) {// 调整异常数据 + b[i] += 256; + } + } + //如果已存在图像,先删除 + File file = new File(fileDir+File.separator + imgFilePath); + if (file.exists() && file.isFile()) { + file.delete(); + } + File dir = new File(fileDir); + if (!dir.exists()) { + dir.mkdirs(); + } + file = new File(fileDir+File.separator+imgFilePath); + file.createNewFile(); +// ImageIO.write(bImage, "bmp", name); + OutputStream out = new FileOutputStream(fileDir+File.separator+imgFilePath); + out.write(b); + out.flush(); + out.close(); + + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + + } + + public static String getBase64FromInputStream(InputStream in) { + // 将图片文件转化为字节数组字符串,并对其进行Base64编码处理 + byte[] data = null; + // 读取图片字节数组 + try { + ByteArrayOutputStream swapStream = new ByteArrayOutputStream(); + byte[] buff = new byte[100]; + int rc = 0; + while ((rc = in.read(buff, 0, 100)) > 0) { + swapStream.write(buff, 0, rc); + } + data = swapStream.toByteArray(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return new String(Base64.encodeBase64(data)); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java new file mode 100644 index 0000000..9c93895 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java @@ -0,0 +1,75 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.lang3.StringUtils; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class CommonUtil { + + public static String CutId(String id) { + return id.substring(6, 10) + "-" + id.substring(10, 12) + "-" + id.substring(12, 14); + } + + public static boolean isIDNumber(String IDNumber) { + if (IDNumber == null || "".equals(IDNumber)) { + return false; + } + // 定义判别用户身份证号的正则表达式(15位或者18位,最后一位可以为字母) + String regularExpression = + "(^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|" + + "(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}$)"; + boolean matches = IDNumber.matches(regularExpression); + // 判断第18位校验值 + if (matches) { + if (IDNumber.length() == 18) { + try { + char[] charArray = IDNumber.toCharArray(); + // 前十七位加权因子 + int[] idCardWi = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; + // 这是除以11后,可能产生的11位余数对应的验证码 + String[] idCardY = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"}; + int sum = 0; + for (int i = 0; i < idCardWi.length; i++) { + int current = Integer.parseInt(String.valueOf(charArray[i])); + int count = current * idCardWi[i]; + sum += count; + } + char idCardLast = charArray[17]; + int idCardMod = sum % 11; + if (idCardY[idCardMod].toUpperCase() + .equals(String.valueOf(idCardLast).toUpperCase())) { + return true; + } else { + System.out.println("身份证最后一位:" + String.valueOf(idCardLast).toUpperCase() + + "错误,正确的应该是:" + idCardY[idCardMod].toUpperCase()); + return false; + } + + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } else { + return false; + } + } + return matches; + } + + + public static boolean CheckMobilePhoneNum(String phoneNum) { + if (StringUtils.isEmpty(phoneNum)) + return true; + String regex = "^(1[3-9]\\d{9}$)"; + if (phoneNum.length() == 11) { + Pattern p = Pattern.compile(regex); + Matcher m = p.matcher(phoneNum); + if (m.matches()) { + return true; + } + } + return false; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java new file mode 100644 index 0000000..191ef79 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java @@ -0,0 +1,116 @@ +package com.casic.missiles.modular.util; + + +import javafx.util.Pair; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +/** + * Created by Administrator on 2015/2/25. + */ +public class DateUtils { + public static SimpleDateFormat sdf_day = new SimpleDateFormat("yyyy-MM-dd"); + public static SimpleDateFormat sdf_day_time = new SimpleDateFormat("yyyyMMddhhmmss"); + public static final SimpleDateFormat sdf4 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + public static final SimpleDateFormat sdf5 = new SimpleDateFormat("HH:mm:ss"); + + + /** + * 获取当年的第一天 + * + * @return + */ + public static Date getCurrYearFirst() { + Calendar currCal = Calendar.getInstance(); + int currentYear = currCal.get(Calendar.YEAR); + return getYearFirst(currentYear); + } + + + /** + * 获取某年第一天日期 + * + * @param year 年份 + * @return Date + */ + public static Date getYearFirst(int year) { + Calendar calendar = Calendar.getInstance(); + calendar.clear(); + calendar.set(Calendar.YEAR, year); + Date currYearFirst = calendar.getTime(); + return currYearFirst; + } + + /** + * 最近7日(不包括今日) + */ + public static Pair getLastSevenDays() { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, -7); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 最近n日(不包括今日) + */ + public static Pair getLastNDays(int n) { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, n * -1); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 日期时间加n天 + */ + public static String addDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf4.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf4.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 日期加n天 + */ + public static String addNDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf_day.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf_day.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 昨日 + */ + public static String getYesterday() { + + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.DATE, -2); + return sdf_day.format(calendar.getTime()); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java new file mode 100644 index 0000000..da0f8ee --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java @@ -0,0 +1,49 @@ +package com.casic.missiles.modular.util; + +import com.hikvision.artemis.sdk.ArtemisHttpUtil; +import com.hikvision.artemis.sdk.config.ArtemisConfig; + +import java.util.HashMap; +import java.util.Map; + +public class HikUtil { + + public static String hikApi(String uri, String body) { + + /** + * STEP1:设置平台参数,根据实际情况,设置host appkey appsecret 三个参数. + */ + ArtemisConfig.host = "192.168.1.22:443"; // artemis网关服务器ip端口 + ArtemisConfig.appKey = "25766251"; // 秘钥appkey + ArtemisConfig.appSecret = "h2o6zXtzCmt8eaOaMkXb";// 秘钥appSecret + + /** + * STEP2:设置OpenAPI接口的上下文 + */ + final String ARTEMIS_PATH = "/artemis"; + + /** + * STEP3:设置接口的URI地址 + */ + final String previewURLsApi = ARTEMIS_PATH + uri; + Map path = new HashMap(2) { + { + put("https://", previewURLsApi);//根据现场环境部署确认是http还是https + } + }; + + /** + * STEP4:设置参数提交方式 + */ + String contentType = "application/json"; + + /** + * STEP5:组装请求参数 + */ + /** + * STEP6:调用接口 + */ + String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, contentType, null);// post请求application/json类型参数 + return result; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java new file mode 100644 index 0000000..4867144 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java @@ -0,0 +1,149 @@ +package com.casic.missiles.modular.util; + +import org.springframework.http.*; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; + +/** + * @Description: http请求工具类 + * @Author: wangpeng + * @Date: 2022/7/17 11:49 + */ +public class HttpUtil { + /** + * get请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String get(String url, MultiValueMap params) { + return get(url, params, null); + } + + /** + * get请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String get(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.GET); + } + + /** + * post请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String post(String url, MultiValueMap params) { + return post(url, params, null); + } + + /** + * post请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String post(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.POST); + } + + /** + * put请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String put(String url, MultiValueMap params) { + return put(url, params, null); + } + + /** + * put请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String put(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.PUT); + } + + /** + * delete请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String delete(String url, MultiValueMap params) { + return delete(url, params, null); + } + + /** + * delete请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String delete(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.DELETE); + } + + /** + * 表单请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @param method 请求方式 + * @return + */ + public static String request(String url, MultiValueMap params, MultiValueMap headers, HttpMethod method) { + if (params == null) { + params = new LinkedMultiValueMap<>(); + } + return request(url, params, headers, method, MediaType.APPLICATION_FORM_URLENCODED); + } + + /** + * http请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @param method 请求方式 + * @param mediaType 参数类型 + * @return + */ + public static String request(String url, Object params, MultiValueMap headers, HttpMethod method, MediaType mediaType) { + if (url == null || url.trim().isEmpty()) { + return null; + } + RestTemplate client = new RestTemplate(); + // header + HttpHeaders httpHeaders = new HttpHeaders(); + if (headers != null) { +// httpHeaders.addAll(headers); + httpHeaders.putAll(headers); + } + // 提交方式:表单、json + httpHeaders.setContentType(mediaType); + HttpEntity httpEntity = new HttpEntity(params, httpHeaders); + ResponseEntity response = client.exchange(url, method, httpEntity, String.class); + return response.getBody(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java new file mode 100644 index 0000000..19d8d67 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java @@ -0,0 +1,30 @@ +package com.casic.missiles.modular.util; + +public class SelectDTO { + private String name; + private String value; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public SelectDTO() { + } + + public SelectDTO(String name, String value) { + this.name = name; + this.value = value; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java new file mode 100644 index 0000000..0bd484c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java @@ -0,0 +1,28 @@ +package com.casic.missiles.modular.util; + +public class SocketConst { + + /** + * 新增授权socket前缀 + */ + public static final String SOCKET_PREFIX_ADD_PERMISSION = "addPermission:"; + + /** + * 取消授权socket前缀 + */ + public static final String SOCKET_PREFIX_DELETE_PERMISSION = "deletePermission:"; + + /** + * 人员数据下发socket前缀 + */ + public static final String SOCKET_PREFIX_ADD_PERSON = "addPerson:"; + + /** + * socket返回成功信息 + */ + public static final String SOCKET_SUCCESS_MSG = "ok"; + /** + * 人员数据下发socket前缀 + */ + public static final String SOCKET_PREFIX_DELETE_PERSON = "deletePerson:"; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java new file mode 100644 index 0000000..0452bca --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java @@ -0,0 +1,90 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.io.IOUtils; +import org.springframework.stereotype.Component; + +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.text.SimpleDateFormat; +import java.util.Date; + +@Component +public class SocketUtil { + + public static byte[] sendMessage(String ip, int port, String msg) { + byte[] data = new byte[20]; + + System.out.println("往 " + ip + ":" + port + " 发送数据:" + msg); + InputStream in = null; + OutputStream out = null; + Socket socket = null; + try { + socket = new Socket(); + socket.connect(new InetSocketAddress(ip, port), 1000); + socket.setSoTimeout(2000); + // 向服务端发送数据 + out = socket.getOutputStream(); + out.write(hexString2Bytes(msg)); + out.flush(); + //socket.shutdownOutput(); + // 读取服务端返回数据 + in = socket.getInputStream(); + in.read(data); + } catch (Exception e) { + e.printStackTrace(); + } finally { + IOUtils.closeQuietly(in); + IOUtils.closeQuietly(out); + IOUtils.closeQuietly(socket); + } + return data; + } + + private static int code = 0; + + public static void main(String[] args) { +// byte[] dd = sendMessage("192.168.5.211",6001,"090300000002C543"); + + String dateStr = new SimpleDateFormat("yyMMddHHmmssSSS").format(new Date()); + //String dd = dateStr + String.format("%04d",++code); + + System.out.println(dateStr); + } + + /** + * 返回由字节数组转换来的 16 位有符号整数 + * + * @param bytes 字节数组 + * @return 由两个字节构成的 16 位有符号整数 + */ + public static short toShort(byte[] bytes) { + return (short) ((0xff & bytes[0]) | (0xff00 & (bytes[1] << 8))); + + } + + + public static byte[] hexString2Bytes(String hex) { + if ((hex == null) || (hex.equals(""))) { + return null; + } else if (hex.length() % 2 != 0) { + return null; + } else { + hex = hex.toUpperCase(); + int len = hex.length() / 2; + byte[] b = new byte[len]; + char[] hc = hex.toCharArray(); + for (int i = 0; i < len; i++) { + int p = 2 * i; + b[i] = (byte) (charToByte(hc[p]) << 4 | charToByte(hc[p + 1])); + } + return b; + } + } + + private static byte charToByte(char c) { + return (byte) "0123456789ABCDEF".indexOf(c); + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java b/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java new file mode 100644 index 0000000..9b4155c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java @@ -0,0 +1,105 @@ +package com.casic.missiles.modular.util; + +import org.springframework.stereotype.Component; + +import javax.websocket.OnClose; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.PathParam; +import javax.websocket.server.ServerEndpoint; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CopyOnWriteArraySet; + +/** + * @Description: 此注解相当于设置访问URL + * @Author: wangpeng + * @Date: 2022/7/17 11:48 + */ +@Component +@ServerEndpoint("/websocket/{userId}") +public class WebSocket { + private Session session; + + private static CopyOnWriteArraySet webSockets = new CopyOnWriteArraySet<>(); + private static Map sessionPool = new HashMap(); + + @OnOpen + public void onOpen(Session session, @PathParam(value = "userId") String userId) { + this.session = session; + webSockets.add(this); + sessionPool.put(userId, session); + System.out.println(userId + "【websocket消息】有新的连接,总数为:" + webSockets.size()); + } + + @OnClose + public void onClose() { + webSockets.remove(this); + System.out.println("【websocket消息】连接断开,总数为:" + webSockets.size()); + } + + @OnMessage + public void onMessage(String message) { + System.out.println("【websocket消息】收到客户端消息:" + message); + } + + // 此为广播消息 + public void sendAllMessage(String message) { + for (WebSocket webSocket : webSockets) { + System.out.println("【websocket消息】广播消息:" + message); + try { + webSocket.session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + // 发送列表消息 + public void sendListMessage(List userIds, String message) { + System.out.println("【websocket消息】列表消息:" + message); + for (String userId : userIds) { + Session session = sessionPool.get(userId); + if (session != null) { + try { + session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + + // 发送列表消息 + +// public void sendListMessage(List userIds, Object data){ +// System.out.println("【websocket消息】列表消息:"+data); +// for (String userId : userIds) { +// Session session = sessionPool.get(userId); +// if (session != null) { +// try { +//// session.getAsyncRemote().sendText(message); +// session.getAsyncRemote().sendObject(data); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// } +// } + + // 此为单点消息 + public void sendOneMessage(String userId, String message) { + System.out.println("【websocket消息】单点消息:" + message); + Session session = sessionPool.get(userId); + if (session != null) { + try { + session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java new file mode 100644 index 0000000..0c1f5f1 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java @@ -0,0 +1,115 @@ +package com.casic.missiles.modular.util; + +import org.springframework.web.multipart.MultipartFile; + +import java.io.*; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipInputStream; + +/** + * @Description: 读取zip文件内容 + * @Author: wangpeng + * @Date: 2022/7/17 11:48 + */ +public class ZipFileUtil { + public static List getFile(String fileName) { + File file = new File(fileName); + ZipFile zipFile = null; + ZipInputStream zin = null; + FileInputStream fis = null; + List selectDTOList = new ArrayList<>(); + try { + Charset gbk = Charset.forName("GBK"); + zipFile = new ZipFile(file, gbk); + fis = new FileInputStream(file); + zin = new ZipInputStream(fis, gbk); + + ZipEntry ze = null; + while ((ze = zin.getNextEntry()) != null) { + String path = ze.getName(); + System.out.println(path); + if (!ze.isDirectory()) { + InputStream inputStream = zipFile.getInputStream(ze); + String base64Photo = Base64Util.getBase64FromInputStream(inputStream); +// List texts = IOUtils.readLines(inputStream); +// for (String text : texts) { +// System.out.println(" " + text); +// } + selectDTOList.add(new SelectDTO(path.substring(path.indexOf("/")+1), "data:image/png;base64,"+base64Photo)); + inputStream.close(); + } + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (zin != null) { + zin.closeEntry(); + zin.close(); + } + if (fis != null) + fis.close(); + if (zipFile != null) + zipFile.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return selectDTOList; + } + + + /** + * MultipartFile 转 File + * + * @param file + * @throws Exception + */ + public static File multipartFileToFile(MultipartFile file) throws Exception { + + File toFile = null; + if (file.equals("") || file.getSize() <= 0) { + file = null; + } else { + InputStream ins = null; + ins = file.getInputStream(); + toFile = new File(file.getOriginalFilename()); + inputStreamToFile(ins, toFile); + ins.close(); + } + return toFile; + } + + //获取流文件 + private static void inputStreamToFile(InputStream ins, File file) { + try { + OutputStream os = new FileOutputStream(file); + int bytesRead = 0; + byte[] buffer = new byte[8192]; + while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) { + os.write(buffer, 0, bytesRead); + } + os.close(); + ins.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 删除本地临时文件 + * + * @param file + */ + public static void delteTempFile(File file) { + if (file != null) { + File del = new File(file.toURI()); + del.delete(); + } + } +} + diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java new file mode 100644 index 0000000..ae93a17 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java @@ -0,0 +1,34 @@ +package com.casic.missiles.modular.util.netty; + +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.EventLoop; +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.TimeUnit; + +/** + * 负责监听启动时连接失败,重新连接功能 + * + */ +@Slf4j +public class ConnectionListener implements ChannelFutureListener { + + private NettyClient client = new NettyClient(); + + @Override + public void operationComplete(ChannelFuture channelFuture) throws Exception { + if (!channelFuture.isSuccess()) { + final EventLoop loop = channelFuture.channel().eventLoop(); + loop.schedule(new Runnable() { + @Override + public void run() { + log.info("服务端连接不上,开始重连操作..."); + client.connect(); + } + }, 5L, TimeUnit.MINUTES); + } else { + log.info("服务端连接成功..."); + } + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9e20bc1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea/ +**/target/** +logs/ +*.iml diff --git a/README.md b/README.md new file mode 100644 index 0000000..2fdcd74 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# casic项目 V2.0.0 + +[^_^]: # (Talk is cheap,Show me the code!) + +## 介绍 +基于SpringBoot,致力于做更简洁的后台管理系统,完美整合springboot2.4 + shiro + mybatis-plus ! +基于casic项目代码简洁,注释丰富,上手容易,同时包含许多基础模块(用户管理,角色管理,部门管理,字典管理等10个模块) +可以直接作为一个后台管理系统的脚手架! 2022目标 `更简洁`,`更规范`! + + +#### 其他 +>* [git地址](http://192.168.0.203:8080/gitbucket) +>* [本地免登地址](http://localhost:8083/route/mockToken) diff --git a/casic-server/pom.xml b/casic-server/pom.xml new file mode 100644 index 0000000..c150a12 --- /dev/null +++ b/casic-server/pom.xml @@ -0,0 +1,70 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + 2.0.0 + ../pom.xml + + + casic-server + 2.0.0 + jar + casic-server + casic 的spring boot版本 + + + + + com.casic + casic-core + ${core.version} + provided + + + com.casic + casic-admin-support + ${admin.version} + provided + + + org.springframework.boot + spring-boot-starter-web + ${boot.version} + provided + + + + + com.hikvision.ga + artemis-http-client + 1.1.3 + + + commons-io + commons-io + + + org.springframework.boot + spring-boot-starter-websocket + 2.4.5 + + + io.netty + netty-all + 4.1.42.Final + + + + + + src/main/java + + **/*.xml + + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java new file mode 100644 index 0000000..3a60b9e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java @@ -0,0 +1,36 @@ +package com.casic.missiles.modular.async; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.TaskExecutor; +import org.springframework.scheduling.annotation.AsyncConfigurer; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadPoolExecutor; + +@Configuration +@EnableAsync +public class AsyncConfig implements AsyncConfigurer { + @Override + public Executor getAsyncExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + //核心线程数 + executor.setCorePoolSize(5); + //最大线程数 + executor.setMaxPoolSize(10); + //队列容量 + executor.setQueueCapacity(20); + //设置线程活跃时间(秒) + executor.setKeepAliveSeconds(60); + //默认线程名称 + executor.setThreadNamePrefix("user-rpt-"); + //拒绝策略 + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + //等待所有任务结束后再关闭线程池 + executor.setWaitForTasksToCompleteOnShutdown(true); + return executor; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java new file mode 100644 index 0000000..8ca554c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java @@ -0,0 +1,18 @@ +package com.casic.missiles.modular.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +// tomcat启动无需配置 +@Configuration +public class WebSocketConfig { + /** + * 注入ServerEndpointExporter, + * 这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint + */ + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java new file mode 100644 index 0000000..34fe2cd --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java @@ -0,0 +1,39 @@ +package com.casic.missiles.modular.controller; + + +import com.casic.missiles.model.application.event.core.EventPublisher; +import com.casic.missiles.model.application.event.enums.ModelEventTypeEnum; +import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.modular.event.UserEvent; +import com.casic.missiles.modular.system.model.User; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +/** + * @Description: DemoController + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@RestController +@RequestMapping("/demo") +public class DemoController { + @Autowired + private EventPublisher publisher; + + /** + * 获取mockToken + */ + @PostMapping("/list") + @ResponseBody + public Object list() { + User user = new User(); + user.setAccount("张三"); + publisher.publishEvent(new UserEvent(ModelEventTypeEnum.ADD, user)); + return ResponseData.success(); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java new file mode 100644 index 0000000..aff2889 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java @@ -0,0 +1,23 @@ +package com.casic.missiles.modular.event; + +import com.casic.missiles.model.application.event.core.ModelEvent; +import com.casic.missiles.model.application.event.type.AbstractEventTypeEnum; +import com.casic.missiles.modular.system.model.User; + +/** + * @Description: 用户事件 + * @Author: wangpeng + * @Date: 2022/7/17 11:23 + */ +public class UserEvent extends ModelEvent { + /** + * Create a new {@code ApplicationEvent}. + * + * @param type 事件类型 + * @param source the object on which the event initially occurred or with + * which the event is associated (never {@code null}) + */ + public UserEvent(AbstractEventTypeEnum type, User source) { + super(type, source); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java new file mode 100644 index 0000000..8f9603e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.core.application.event.UserLoginEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserOneListener { + @EventListener + public void onApplicationEvent(UserLoginEvent event) { + log.debug("用户1订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java new file mode 100644 index 0000000..0bd52a3 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.model.application.event.core.EventSubscriber; +import com.casic.missiles.modular.event.UserEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserTwoListener extends EventSubscriber { + @Override + public void onApplicationEvent(UserEvent event) { + log.debug("用户2订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java new file mode 100644 index 0000000..4012170 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java @@ -0,0 +1,88 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang3.StringUtils; +import sun.misc.BASE64Decoder; + +import java.io.*; + +public class Base64Util { + /** + * base64字符串转换成图片 + * + * @param imgStr base64字符串 + * @param imgFilePath 图片存放路径 + * @return + * @author ZHANGJL + * @dateTime 2018-02-23 14:42:17 + */ + public static boolean Base64ToImage(String imgStr, String imgFilePath, String fileDir) { // 对字节数组字符串进行Base64解码并生成图片 + + if (StringUtils.isEmpty(imgStr)) // 图像数据为空 + return false; + + imgStr = imgStr.substring(imgStr.indexOf(",") + 1); + + BASE64Decoder decoder = new BASE64Decoder(); + try { + // Base64解码 + byte[] b = decoder.decodeBuffer(imgStr); + + for (int i = 0; i < b.length; ++i) { + if (b[i] < 0) {// 调整异常数据 + b[i] += 256; + } + } + //如果已存在图像,先删除 + File file = new File(fileDir+File.separator + imgFilePath); + if (file.exists() && file.isFile()) { + file.delete(); + } + File dir = new File(fileDir); + if (!dir.exists()) { + dir.mkdirs(); + } + file = new File(fileDir+File.separator+imgFilePath); + file.createNewFile(); +// ImageIO.write(bImage, "bmp", name); + OutputStream out = new FileOutputStream(fileDir+File.separator+imgFilePath); + out.write(b); + out.flush(); + out.close(); + + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + + } + + public static String getBase64FromInputStream(InputStream in) { + // 将图片文件转化为字节数组字符串,并对其进行Base64编码处理 + byte[] data = null; + // 读取图片字节数组 + try { + ByteArrayOutputStream swapStream = new ByteArrayOutputStream(); + byte[] buff = new byte[100]; + int rc = 0; + while ((rc = in.read(buff, 0, 100)) > 0) { + swapStream.write(buff, 0, rc); + } + data = swapStream.toByteArray(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return new String(Base64.encodeBase64(data)); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java new file mode 100644 index 0000000..9c93895 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java @@ -0,0 +1,75 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.lang3.StringUtils; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class CommonUtil { + + public static String CutId(String id) { + return id.substring(6, 10) + "-" + id.substring(10, 12) + "-" + id.substring(12, 14); + } + + public static boolean isIDNumber(String IDNumber) { + if (IDNumber == null || "".equals(IDNumber)) { + return false; + } + // 定义判别用户身份证号的正则表达式(15位或者18位,最后一位可以为字母) + String regularExpression = + "(^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|" + + "(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}$)"; + boolean matches = IDNumber.matches(regularExpression); + // 判断第18位校验值 + if (matches) { + if (IDNumber.length() == 18) { + try { + char[] charArray = IDNumber.toCharArray(); + // 前十七位加权因子 + int[] idCardWi = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; + // 这是除以11后,可能产生的11位余数对应的验证码 + String[] idCardY = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"}; + int sum = 0; + for (int i = 0; i < idCardWi.length; i++) { + int current = Integer.parseInt(String.valueOf(charArray[i])); + int count = current * idCardWi[i]; + sum += count; + } + char idCardLast = charArray[17]; + int idCardMod = sum % 11; + if (idCardY[idCardMod].toUpperCase() + .equals(String.valueOf(idCardLast).toUpperCase())) { + return true; + } else { + System.out.println("身份证最后一位:" + String.valueOf(idCardLast).toUpperCase() + + "错误,正确的应该是:" + idCardY[idCardMod].toUpperCase()); + return false; + } + + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } else { + return false; + } + } + return matches; + } + + + public static boolean CheckMobilePhoneNum(String phoneNum) { + if (StringUtils.isEmpty(phoneNum)) + return true; + String regex = "^(1[3-9]\\d{9}$)"; + if (phoneNum.length() == 11) { + Pattern p = Pattern.compile(regex); + Matcher m = p.matcher(phoneNum); + if (m.matches()) { + return true; + } + } + return false; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java new file mode 100644 index 0000000..191ef79 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java @@ -0,0 +1,116 @@ +package com.casic.missiles.modular.util; + + +import javafx.util.Pair; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +/** + * Created by Administrator on 2015/2/25. + */ +public class DateUtils { + public static SimpleDateFormat sdf_day = new SimpleDateFormat("yyyy-MM-dd"); + public static SimpleDateFormat sdf_day_time = new SimpleDateFormat("yyyyMMddhhmmss"); + public static final SimpleDateFormat sdf4 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + public static final SimpleDateFormat sdf5 = new SimpleDateFormat("HH:mm:ss"); + + + /** + * 获取当年的第一天 + * + * @return + */ + public static Date getCurrYearFirst() { + Calendar currCal = Calendar.getInstance(); + int currentYear = currCal.get(Calendar.YEAR); + return getYearFirst(currentYear); + } + + + /** + * 获取某年第一天日期 + * + * @param year 年份 + * @return Date + */ + public static Date getYearFirst(int year) { + Calendar calendar = Calendar.getInstance(); + calendar.clear(); + calendar.set(Calendar.YEAR, year); + Date currYearFirst = calendar.getTime(); + return currYearFirst; + } + + /** + * 最近7日(不包括今日) + */ + public static Pair getLastSevenDays() { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, -7); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 最近n日(不包括今日) + */ + public static Pair getLastNDays(int n) { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, n * -1); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 日期时间加n天 + */ + public static String addDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf4.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf4.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 日期加n天 + */ + public static String addNDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf_day.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf_day.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 昨日 + */ + public static String getYesterday() { + + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.DATE, -2); + return sdf_day.format(calendar.getTime()); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java new file mode 100644 index 0000000..da0f8ee --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java @@ -0,0 +1,49 @@ +package com.casic.missiles.modular.util; + +import com.hikvision.artemis.sdk.ArtemisHttpUtil; +import com.hikvision.artemis.sdk.config.ArtemisConfig; + +import java.util.HashMap; +import java.util.Map; + +public class HikUtil { + + public static String hikApi(String uri, String body) { + + /** + * STEP1:设置平台参数,根据实际情况,设置host appkey appsecret 三个参数. + */ + ArtemisConfig.host = "192.168.1.22:443"; // artemis网关服务器ip端口 + ArtemisConfig.appKey = "25766251"; // 秘钥appkey + ArtemisConfig.appSecret = "h2o6zXtzCmt8eaOaMkXb";// 秘钥appSecret + + /** + * STEP2:设置OpenAPI接口的上下文 + */ + final String ARTEMIS_PATH = "/artemis"; + + /** + * STEP3:设置接口的URI地址 + */ + final String previewURLsApi = ARTEMIS_PATH + uri; + Map path = new HashMap(2) { + { + put("https://", previewURLsApi);//根据现场环境部署确认是http还是https + } + }; + + /** + * STEP4:设置参数提交方式 + */ + String contentType = "application/json"; + + /** + * STEP5:组装请求参数 + */ + /** + * STEP6:调用接口 + */ + String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, contentType, null);// post请求application/json类型参数 + return result; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java new file mode 100644 index 0000000..4867144 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java @@ -0,0 +1,149 @@ +package com.casic.missiles.modular.util; + +import org.springframework.http.*; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; + +/** + * @Description: http请求工具类 + * @Author: wangpeng + * @Date: 2022/7/17 11:49 + */ +public class HttpUtil { + /** + * get请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String get(String url, MultiValueMap params) { + return get(url, params, null); + } + + /** + * get请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String get(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.GET); + } + + /** + * post请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String post(String url, MultiValueMap params) { + return post(url, params, null); + } + + /** + * post请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String post(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.POST); + } + + /** + * put请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String put(String url, MultiValueMap params) { + return put(url, params, null); + } + + /** + * put请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String put(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.PUT); + } + + /** + * delete请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String delete(String url, MultiValueMap params) { + return delete(url, params, null); + } + + /** + * delete请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String delete(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.DELETE); + } + + /** + * 表单请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @param method 请求方式 + * @return + */ + public static String request(String url, MultiValueMap params, MultiValueMap headers, HttpMethod method) { + if (params == null) { + params = new LinkedMultiValueMap<>(); + } + return request(url, params, headers, method, MediaType.APPLICATION_FORM_URLENCODED); + } + + /** + * http请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @param method 请求方式 + * @param mediaType 参数类型 + * @return + */ + public static String request(String url, Object params, MultiValueMap headers, HttpMethod method, MediaType mediaType) { + if (url == null || url.trim().isEmpty()) { + return null; + } + RestTemplate client = new RestTemplate(); + // header + HttpHeaders httpHeaders = new HttpHeaders(); + if (headers != null) { +// httpHeaders.addAll(headers); + httpHeaders.putAll(headers); + } + // 提交方式:表单、json + httpHeaders.setContentType(mediaType); + HttpEntity httpEntity = new HttpEntity(params, httpHeaders); + ResponseEntity response = client.exchange(url, method, httpEntity, String.class); + return response.getBody(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java new file mode 100644 index 0000000..19d8d67 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java @@ -0,0 +1,30 @@ +package com.casic.missiles.modular.util; + +public class SelectDTO { + private String name; + private String value; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public SelectDTO() { + } + + public SelectDTO(String name, String value) { + this.name = name; + this.value = value; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java new file mode 100644 index 0000000..0bd484c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java @@ -0,0 +1,28 @@ +package com.casic.missiles.modular.util; + +public class SocketConst { + + /** + * 新增授权socket前缀 + */ + public static final String SOCKET_PREFIX_ADD_PERMISSION = "addPermission:"; + + /** + * 取消授权socket前缀 + */ + public static final String SOCKET_PREFIX_DELETE_PERMISSION = "deletePermission:"; + + /** + * 人员数据下发socket前缀 + */ + public static final String SOCKET_PREFIX_ADD_PERSON = "addPerson:"; + + /** + * socket返回成功信息 + */ + public static final String SOCKET_SUCCESS_MSG = "ok"; + /** + * 人员数据下发socket前缀 + */ + public static final String SOCKET_PREFIX_DELETE_PERSON = "deletePerson:"; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java new file mode 100644 index 0000000..0452bca --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java @@ -0,0 +1,90 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.io.IOUtils; +import org.springframework.stereotype.Component; + +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.text.SimpleDateFormat; +import java.util.Date; + +@Component +public class SocketUtil { + + public static byte[] sendMessage(String ip, int port, String msg) { + byte[] data = new byte[20]; + + System.out.println("往 " + ip + ":" + port + " 发送数据:" + msg); + InputStream in = null; + OutputStream out = null; + Socket socket = null; + try { + socket = new Socket(); + socket.connect(new InetSocketAddress(ip, port), 1000); + socket.setSoTimeout(2000); + // 向服务端发送数据 + out = socket.getOutputStream(); + out.write(hexString2Bytes(msg)); + out.flush(); + //socket.shutdownOutput(); + // 读取服务端返回数据 + in = socket.getInputStream(); + in.read(data); + } catch (Exception e) { + e.printStackTrace(); + } finally { + IOUtils.closeQuietly(in); + IOUtils.closeQuietly(out); + IOUtils.closeQuietly(socket); + } + return data; + } + + private static int code = 0; + + public static void main(String[] args) { +// byte[] dd = sendMessage("192.168.5.211",6001,"090300000002C543"); + + String dateStr = new SimpleDateFormat("yyMMddHHmmssSSS").format(new Date()); + //String dd = dateStr + String.format("%04d",++code); + + System.out.println(dateStr); + } + + /** + * 返回由字节数组转换来的 16 位有符号整数 + * + * @param bytes 字节数组 + * @return 由两个字节构成的 16 位有符号整数 + */ + public static short toShort(byte[] bytes) { + return (short) ((0xff & bytes[0]) | (0xff00 & (bytes[1] << 8))); + + } + + + public static byte[] hexString2Bytes(String hex) { + if ((hex == null) || (hex.equals(""))) { + return null; + } else if (hex.length() % 2 != 0) { + return null; + } else { + hex = hex.toUpperCase(); + int len = hex.length() / 2; + byte[] b = new byte[len]; + char[] hc = hex.toCharArray(); + for (int i = 0; i < len; i++) { + int p = 2 * i; + b[i] = (byte) (charToByte(hc[p]) << 4 | charToByte(hc[p + 1])); + } + return b; + } + } + + private static byte charToByte(char c) { + return (byte) "0123456789ABCDEF".indexOf(c); + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java b/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java new file mode 100644 index 0000000..9b4155c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java @@ -0,0 +1,105 @@ +package com.casic.missiles.modular.util; + +import org.springframework.stereotype.Component; + +import javax.websocket.OnClose; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.PathParam; +import javax.websocket.server.ServerEndpoint; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CopyOnWriteArraySet; + +/** + * @Description: 此注解相当于设置访问URL + * @Author: wangpeng + * @Date: 2022/7/17 11:48 + */ +@Component +@ServerEndpoint("/websocket/{userId}") +public class WebSocket { + private Session session; + + private static CopyOnWriteArraySet webSockets = new CopyOnWriteArraySet<>(); + private static Map sessionPool = new HashMap(); + + @OnOpen + public void onOpen(Session session, @PathParam(value = "userId") String userId) { + this.session = session; + webSockets.add(this); + sessionPool.put(userId, session); + System.out.println(userId + "【websocket消息】有新的连接,总数为:" + webSockets.size()); + } + + @OnClose + public void onClose() { + webSockets.remove(this); + System.out.println("【websocket消息】连接断开,总数为:" + webSockets.size()); + } + + @OnMessage + public void onMessage(String message) { + System.out.println("【websocket消息】收到客户端消息:" + message); + } + + // 此为广播消息 + public void sendAllMessage(String message) { + for (WebSocket webSocket : webSockets) { + System.out.println("【websocket消息】广播消息:" + message); + try { + webSocket.session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + // 发送列表消息 + public void sendListMessage(List userIds, String message) { + System.out.println("【websocket消息】列表消息:" + message); + for (String userId : userIds) { + Session session = sessionPool.get(userId); + if (session != null) { + try { + session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + + // 发送列表消息 + +// public void sendListMessage(List userIds, Object data){ +// System.out.println("【websocket消息】列表消息:"+data); +// for (String userId : userIds) { +// Session session = sessionPool.get(userId); +// if (session != null) { +// try { +//// session.getAsyncRemote().sendText(message); +// session.getAsyncRemote().sendObject(data); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// } +// } + + // 此为单点消息 + public void sendOneMessage(String userId, String message) { + System.out.println("【websocket消息】单点消息:" + message); + Session session = sessionPool.get(userId); + if (session != null) { + try { + session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java new file mode 100644 index 0000000..0c1f5f1 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java @@ -0,0 +1,115 @@ +package com.casic.missiles.modular.util; + +import org.springframework.web.multipart.MultipartFile; + +import java.io.*; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipInputStream; + +/** + * @Description: 读取zip文件内容 + * @Author: wangpeng + * @Date: 2022/7/17 11:48 + */ +public class ZipFileUtil { + public static List getFile(String fileName) { + File file = new File(fileName); + ZipFile zipFile = null; + ZipInputStream zin = null; + FileInputStream fis = null; + List selectDTOList = new ArrayList<>(); + try { + Charset gbk = Charset.forName("GBK"); + zipFile = new ZipFile(file, gbk); + fis = new FileInputStream(file); + zin = new ZipInputStream(fis, gbk); + + ZipEntry ze = null; + while ((ze = zin.getNextEntry()) != null) { + String path = ze.getName(); + System.out.println(path); + if (!ze.isDirectory()) { + InputStream inputStream = zipFile.getInputStream(ze); + String base64Photo = Base64Util.getBase64FromInputStream(inputStream); +// List texts = IOUtils.readLines(inputStream); +// for (String text : texts) { +// System.out.println(" " + text); +// } + selectDTOList.add(new SelectDTO(path.substring(path.indexOf("/")+1), "data:image/png;base64,"+base64Photo)); + inputStream.close(); + } + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (zin != null) { + zin.closeEntry(); + zin.close(); + } + if (fis != null) + fis.close(); + if (zipFile != null) + zipFile.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return selectDTOList; + } + + + /** + * MultipartFile 转 File + * + * @param file + * @throws Exception + */ + public static File multipartFileToFile(MultipartFile file) throws Exception { + + File toFile = null; + if (file.equals("") || file.getSize() <= 0) { + file = null; + } else { + InputStream ins = null; + ins = file.getInputStream(); + toFile = new File(file.getOriginalFilename()); + inputStreamToFile(ins, toFile); + ins.close(); + } + return toFile; + } + + //获取流文件 + private static void inputStreamToFile(InputStream ins, File file) { + try { + OutputStream os = new FileOutputStream(file); + int bytesRead = 0; + byte[] buffer = new byte[8192]; + while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) { + os.write(buffer, 0, bytesRead); + } + os.close(); + ins.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 删除本地临时文件 + * + * @param file + */ + public static void delteTempFile(File file) { + if (file != null) { + File del = new File(file.toURI()); + del.delete(); + } + } +} + diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java new file mode 100644 index 0000000..ae93a17 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java @@ -0,0 +1,34 @@ +package com.casic.missiles.modular.util.netty; + +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.EventLoop; +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.TimeUnit; + +/** + * 负责监听启动时连接失败,重新连接功能 + * + */ +@Slf4j +public class ConnectionListener implements ChannelFutureListener { + + private NettyClient client = new NettyClient(); + + @Override + public void operationComplete(ChannelFuture channelFuture) throws Exception { + if (!channelFuture.isSuccess()) { + final EventLoop loop = channelFuture.channel().eventLoop(); + loop.schedule(new Runnable() { + @Override + public void run() { + log.info("服务端连接不上,开始重连操作..."); + client.connect(); + } + }, 5L, TimeUnit.MINUTES); + } else { + log.info("服务端连接成功..."); + } + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java new file mode 100644 index 0000000..ef9ae76 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java @@ -0,0 +1,66 @@ +package com.casic.missiles.modular.util.netty; + +import io.netty.bootstrap.Bootstrap; +import io.netty.channel.*; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioSocketChannel; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public class NettyClient { + + private static Channel channel; + + private String fenceServiceHost = "127.0.0.1"; + private Integer fenceServicePort = 9200; + + public Channel connect() { + doConnect(fenceServiceHost, fenceServicePort); + return channel; + } + + public Channel connect(String host, int port) { + doConnect(host, port); + return channel; + } + + private void doConnect(String host, int port) { + EventLoopGroup workerGroup = new NioEventLoopGroup(); + try { + Bootstrap b = new Bootstrap(); + b.group(workerGroup); + b.channel(NioSocketChannel.class); + b.option(ChannelOption.SO_KEEPALIVE, true); + b.option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(1024 * 1024)); + + b.handler(new ChannelInitializer() { + @Override + public void initChannel(SocketChannel ch) throws Exception { + + ch.pipeline().addLast("decoder", new StringDecoder()); + ch.pipeline().addLast("encoder", new StringEncoder()); + ch.pipeline().addLast(new NettyClientHandler()); + } + }); + + ChannelFuture f = b.connect(host, port); + f.addListener(new ConnectionListener()); + channel = f.channel(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static void writeAndFlush(String message) { + + if (channel != null) { + channel.writeAndFlush(message); + System.out.println("电子围栏客户端发送消息:" + message); + } + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9e20bc1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea/ +**/target/** +logs/ +*.iml diff --git a/README.md b/README.md new file mode 100644 index 0000000..2fdcd74 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# casic项目 V2.0.0 + +[^_^]: # (Talk is cheap,Show me the code!) + +## 介绍 +基于SpringBoot,致力于做更简洁的后台管理系统,完美整合springboot2.4 + shiro + mybatis-plus ! +基于casic项目代码简洁,注释丰富,上手容易,同时包含许多基础模块(用户管理,角色管理,部门管理,字典管理等10个模块) +可以直接作为一个后台管理系统的脚手架! 2022目标 `更简洁`,`更规范`! + + +#### 其他 +>* [git地址](http://192.168.0.203:8080/gitbucket) +>* [本地免登地址](http://localhost:8083/route/mockToken) diff --git a/casic-server/pom.xml b/casic-server/pom.xml new file mode 100644 index 0000000..c150a12 --- /dev/null +++ b/casic-server/pom.xml @@ -0,0 +1,70 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + 2.0.0 + ../pom.xml + + + casic-server + 2.0.0 + jar + casic-server + casic 的spring boot版本 + + + + + com.casic + casic-core + ${core.version} + provided + + + com.casic + casic-admin-support + ${admin.version} + provided + + + org.springframework.boot + spring-boot-starter-web + ${boot.version} + provided + + + + + com.hikvision.ga + artemis-http-client + 1.1.3 + + + commons-io + commons-io + + + org.springframework.boot + spring-boot-starter-websocket + 2.4.5 + + + io.netty + netty-all + 4.1.42.Final + + + + + + src/main/java + + **/*.xml + + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java new file mode 100644 index 0000000..3a60b9e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java @@ -0,0 +1,36 @@ +package com.casic.missiles.modular.async; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.TaskExecutor; +import org.springframework.scheduling.annotation.AsyncConfigurer; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadPoolExecutor; + +@Configuration +@EnableAsync +public class AsyncConfig implements AsyncConfigurer { + @Override + public Executor getAsyncExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + //核心线程数 + executor.setCorePoolSize(5); + //最大线程数 + executor.setMaxPoolSize(10); + //队列容量 + executor.setQueueCapacity(20); + //设置线程活跃时间(秒) + executor.setKeepAliveSeconds(60); + //默认线程名称 + executor.setThreadNamePrefix("user-rpt-"); + //拒绝策略 + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + //等待所有任务结束后再关闭线程池 + executor.setWaitForTasksToCompleteOnShutdown(true); + return executor; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java new file mode 100644 index 0000000..8ca554c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java @@ -0,0 +1,18 @@ +package com.casic.missiles.modular.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +// tomcat启动无需配置 +@Configuration +public class WebSocketConfig { + /** + * 注入ServerEndpointExporter, + * 这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint + */ + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java new file mode 100644 index 0000000..34fe2cd --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java @@ -0,0 +1,39 @@ +package com.casic.missiles.modular.controller; + + +import com.casic.missiles.model.application.event.core.EventPublisher; +import com.casic.missiles.model.application.event.enums.ModelEventTypeEnum; +import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.modular.event.UserEvent; +import com.casic.missiles.modular.system.model.User; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +/** + * @Description: DemoController + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@RestController +@RequestMapping("/demo") +public class DemoController { + @Autowired + private EventPublisher publisher; + + /** + * 获取mockToken + */ + @PostMapping("/list") + @ResponseBody + public Object list() { + User user = new User(); + user.setAccount("张三"); + publisher.publishEvent(new UserEvent(ModelEventTypeEnum.ADD, user)); + return ResponseData.success(); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java new file mode 100644 index 0000000..aff2889 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java @@ -0,0 +1,23 @@ +package com.casic.missiles.modular.event; + +import com.casic.missiles.model.application.event.core.ModelEvent; +import com.casic.missiles.model.application.event.type.AbstractEventTypeEnum; +import com.casic.missiles.modular.system.model.User; + +/** + * @Description: 用户事件 + * @Author: wangpeng + * @Date: 2022/7/17 11:23 + */ +public class UserEvent extends ModelEvent { + /** + * Create a new {@code ApplicationEvent}. + * + * @param type 事件类型 + * @param source the object on which the event initially occurred or with + * which the event is associated (never {@code null}) + */ + public UserEvent(AbstractEventTypeEnum type, User source) { + super(type, source); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java new file mode 100644 index 0000000..8f9603e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.core.application.event.UserLoginEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserOneListener { + @EventListener + public void onApplicationEvent(UserLoginEvent event) { + log.debug("用户1订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java new file mode 100644 index 0000000..0bd52a3 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.model.application.event.core.EventSubscriber; +import com.casic.missiles.modular.event.UserEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserTwoListener extends EventSubscriber { + @Override + public void onApplicationEvent(UserEvent event) { + log.debug("用户2订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java new file mode 100644 index 0000000..4012170 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java @@ -0,0 +1,88 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang3.StringUtils; +import sun.misc.BASE64Decoder; + +import java.io.*; + +public class Base64Util { + /** + * base64字符串转换成图片 + * + * @param imgStr base64字符串 + * @param imgFilePath 图片存放路径 + * @return + * @author ZHANGJL + * @dateTime 2018-02-23 14:42:17 + */ + public static boolean Base64ToImage(String imgStr, String imgFilePath, String fileDir) { // 对字节数组字符串进行Base64解码并生成图片 + + if (StringUtils.isEmpty(imgStr)) // 图像数据为空 + return false; + + imgStr = imgStr.substring(imgStr.indexOf(",") + 1); + + BASE64Decoder decoder = new BASE64Decoder(); + try { + // Base64解码 + byte[] b = decoder.decodeBuffer(imgStr); + + for (int i = 0; i < b.length; ++i) { + if (b[i] < 0) {// 调整异常数据 + b[i] += 256; + } + } + //如果已存在图像,先删除 + File file = new File(fileDir+File.separator + imgFilePath); + if (file.exists() && file.isFile()) { + file.delete(); + } + File dir = new File(fileDir); + if (!dir.exists()) { + dir.mkdirs(); + } + file = new File(fileDir+File.separator+imgFilePath); + file.createNewFile(); +// ImageIO.write(bImage, "bmp", name); + OutputStream out = new FileOutputStream(fileDir+File.separator+imgFilePath); + out.write(b); + out.flush(); + out.close(); + + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + + } + + public static String getBase64FromInputStream(InputStream in) { + // 将图片文件转化为字节数组字符串,并对其进行Base64编码处理 + byte[] data = null; + // 读取图片字节数组 + try { + ByteArrayOutputStream swapStream = new ByteArrayOutputStream(); + byte[] buff = new byte[100]; + int rc = 0; + while ((rc = in.read(buff, 0, 100)) > 0) { + swapStream.write(buff, 0, rc); + } + data = swapStream.toByteArray(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return new String(Base64.encodeBase64(data)); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java new file mode 100644 index 0000000..9c93895 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java @@ -0,0 +1,75 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.lang3.StringUtils; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class CommonUtil { + + public static String CutId(String id) { + return id.substring(6, 10) + "-" + id.substring(10, 12) + "-" + id.substring(12, 14); + } + + public static boolean isIDNumber(String IDNumber) { + if (IDNumber == null || "".equals(IDNumber)) { + return false; + } + // 定义判别用户身份证号的正则表达式(15位或者18位,最后一位可以为字母) + String regularExpression = + "(^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|" + + "(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}$)"; + boolean matches = IDNumber.matches(regularExpression); + // 判断第18位校验值 + if (matches) { + if (IDNumber.length() == 18) { + try { + char[] charArray = IDNumber.toCharArray(); + // 前十七位加权因子 + int[] idCardWi = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; + // 这是除以11后,可能产生的11位余数对应的验证码 + String[] idCardY = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"}; + int sum = 0; + for (int i = 0; i < idCardWi.length; i++) { + int current = Integer.parseInt(String.valueOf(charArray[i])); + int count = current * idCardWi[i]; + sum += count; + } + char idCardLast = charArray[17]; + int idCardMod = sum % 11; + if (idCardY[idCardMod].toUpperCase() + .equals(String.valueOf(idCardLast).toUpperCase())) { + return true; + } else { + System.out.println("身份证最后一位:" + String.valueOf(idCardLast).toUpperCase() + + "错误,正确的应该是:" + idCardY[idCardMod].toUpperCase()); + return false; + } + + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } else { + return false; + } + } + return matches; + } + + + public static boolean CheckMobilePhoneNum(String phoneNum) { + if (StringUtils.isEmpty(phoneNum)) + return true; + String regex = "^(1[3-9]\\d{9}$)"; + if (phoneNum.length() == 11) { + Pattern p = Pattern.compile(regex); + Matcher m = p.matcher(phoneNum); + if (m.matches()) { + return true; + } + } + return false; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java new file mode 100644 index 0000000..191ef79 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java @@ -0,0 +1,116 @@ +package com.casic.missiles.modular.util; + + +import javafx.util.Pair; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +/** + * Created by Administrator on 2015/2/25. + */ +public class DateUtils { + public static SimpleDateFormat sdf_day = new SimpleDateFormat("yyyy-MM-dd"); + public static SimpleDateFormat sdf_day_time = new SimpleDateFormat("yyyyMMddhhmmss"); + public static final SimpleDateFormat sdf4 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + public static final SimpleDateFormat sdf5 = new SimpleDateFormat("HH:mm:ss"); + + + /** + * 获取当年的第一天 + * + * @return + */ + public static Date getCurrYearFirst() { + Calendar currCal = Calendar.getInstance(); + int currentYear = currCal.get(Calendar.YEAR); + return getYearFirst(currentYear); + } + + + /** + * 获取某年第一天日期 + * + * @param year 年份 + * @return Date + */ + public static Date getYearFirst(int year) { + Calendar calendar = Calendar.getInstance(); + calendar.clear(); + calendar.set(Calendar.YEAR, year); + Date currYearFirst = calendar.getTime(); + return currYearFirst; + } + + /** + * 最近7日(不包括今日) + */ + public static Pair getLastSevenDays() { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, -7); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 最近n日(不包括今日) + */ + public static Pair getLastNDays(int n) { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, n * -1); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 日期时间加n天 + */ + public static String addDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf4.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf4.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 日期加n天 + */ + public static String addNDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf_day.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf_day.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 昨日 + */ + public static String getYesterday() { + + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.DATE, -2); + return sdf_day.format(calendar.getTime()); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java new file mode 100644 index 0000000..da0f8ee --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java @@ -0,0 +1,49 @@ +package com.casic.missiles.modular.util; + +import com.hikvision.artemis.sdk.ArtemisHttpUtil; +import com.hikvision.artemis.sdk.config.ArtemisConfig; + +import java.util.HashMap; +import java.util.Map; + +public class HikUtil { + + public static String hikApi(String uri, String body) { + + /** + * STEP1:设置平台参数,根据实际情况,设置host appkey appsecret 三个参数. + */ + ArtemisConfig.host = "192.168.1.22:443"; // artemis网关服务器ip端口 + ArtemisConfig.appKey = "25766251"; // 秘钥appkey + ArtemisConfig.appSecret = "h2o6zXtzCmt8eaOaMkXb";// 秘钥appSecret + + /** + * STEP2:设置OpenAPI接口的上下文 + */ + final String ARTEMIS_PATH = "/artemis"; + + /** + * STEP3:设置接口的URI地址 + */ + final String previewURLsApi = ARTEMIS_PATH + uri; + Map path = new HashMap(2) { + { + put("https://", previewURLsApi);//根据现场环境部署确认是http还是https + } + }; + + /** + * STEP4:设置参数提交方式 + */ + String contentType = "application/json"; + + /** + * STEP5:组装请求参数 + */ + /** + * STEP6:调用接口 + */ + String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, contentType, null);// post请求application/json类型参数 + return result; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java new file mode 100644 index 0000000..4867144 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java @@ -0,0 +1,149 @@ +package com.casic.missiles.modular.util; + +import org.springframework.http.*; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; + +/** + * @Description: http请求工具类 + * @Author: wangpeng + * @Date: 2022/7/17 11:49 + */ +public class HttpUtil { + /** + * get请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String get(String url, MultiValueMap params) { + return get(url, params, null); + } + + /** + * get请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String get(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.GET); + } + + /** + * post请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String post(String url, MultiValueMap params) { + return post(url, params, null); + } + + /** + * post请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String post(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.POST); + } + + /** + * put请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String put(String url, MultiValueMap params) { + return put(url, params, null); + } + + /** + * put请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String put(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.PUT); + } + + /** + * delete请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String delete(String url, MultiValueMap params) { + return delete(url, params, null); + } + + /** + * delete请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String delete(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.DELETE); + } + + /** + * 表单请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @param method 请求方式 + * @return + */ + public static String request(String url, MultiValueMap params, MultiValueMap headers, HttpMethod method) { + if (params == null) { + params = new LinkedMultiValueMap<>(); + } + return request(url, params, headers, method, MediaType.APPLICATION_FORM_URLENCODED); + } + + /** + * http请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @param method 请求方式 + * @param mediaType 参数类型 + * @return + */ + public static String request(String url, Object params, MultiValueMap headers, HttpMethod method, MediaType mediaType) { + if (url == null || url.trim().isEmpty()) { + return null; + } + RestTemplate client = new RestTemplate(); + // header + HttpHeaders httpHeaders = new HttpHeaders(); + if (headers != null) { +// httpHeaders.addAll(headers); + httpHeaders.putAll(headers); + } + // 提交方式:表单、json + httpHeaders.setContentType(mediaType); + HttpEntity httpEntity = new HttpEntity(params, httpHeaders); + ResponseEntity response = client.exchange(url, method, httpEntity, String.class); + return response.getBody(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java new file mode 100644 index 0000000..19d8d67 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java @@ -0,0 +1,30 @@ +package com.casic.missiles.modular.util; + +public class SelectDTO { + private String name; + private String value; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public SelectDTO() { + } + + public SelectDTO(String name, String value) { + this.name = name; + this.value = value; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java new file mode 100644 index 0000000..0bd484c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java @@ -0,0 +1,28 @@ +package com.casic.missiles.modular.util; + +public class SocketConst { + + /** + * 新增授权socket前缀 + */ + public static final String SOCKET_PREFIX_ADD_PERMISSION = "addPermission:"; + + /** + * 取消授权socket前缀 + */ + public static final String SOCKET_PREFIX_DELETE_PERMISSION = "deletePermission:"; + + /** + * 人员数据下发socket前缀 + */ + public static final String SOCKET_PREFIX_ADD_PERSON = "addPerson:"; + + /** + * socket返回成功信息 + */ + public static final String SOCKET_SUCCESS_MSG = "ok"; + /** + * 人员数据下发socket前缀 + */ + public static final String SOCKET_PREFIX_DELETE_PERSON = "deletePerson:"; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java new file mode 100644 index 0000000..0452bca --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java @@ -0,0 +1,90 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.io.IOUtils; +import org.springframework.stereotype.Component; + +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.text.SimpleDateFormat; +import java.util.Date; + +@Component +public class SocketUtil { + + public static byte[] sendMessage(String ip, int port, String msg) { + byte[] data = new byte[20]; + + System.out.println("往 " + ip + ":" + port + " 发送数据:" + msg); + InputStream in = null; + OutputStream out = null; + Socket socket = null; + try { + socket = new Socket(); + socket.connect(new InetSocketAddress(ip, port), 1000); + socket.setSoTimeout(2000); + // 向服务端发送数据 + out = socket.getOutputStream(); + out.write(hexString2Bytes(msg)); + out.flush(); + //socket.shutdownOutput(); + // 读取服务端返回数据 + in = socket.getInputStream(); + in.read(data); + } catch (Exception e) { + e.printStackTrace(); + } finally { + IOUtils.closeQuietly(in); + IOUtils.closeQuietly(out); + IOUtils.closeQuietly(socket); + } + return data; + } + + private static int code = 0; + + public static void main(String[] args) { +// byte[] dd = sendMessage("192.168.5.211",6001,"090300000002C543"); + + String dateStr = new SimpleDateFormat("yyMMddHHmmssSSS").format(new Date()); + //String dd = dateStr + String.format("%04d",++code); + + System.out.println(dateStr); + } + + /** + * 返回由字节数组转换来的 16 位有符号整数 + * + * @param bytes 字节数组 + * @return 由两个字节构成的 16 位有符号整数 + */ + public static short toShort(byte[] bytes) { + return (short) ((0xff & bytes[0]) | (0xff00 & (bytes[1] << 8))); + + } + + + public static byte[] hexString2Bytes(String hex) { + if ((hex == null) || (hex.equals(""))) { + return null; + } else if (hex.length() % 2 != 0) { + return null; + } else { + hex = hex.toUpperCase(); + int len = hex.length() / 2; + byte[] b = new byte[len]; + char[] hc = hex.toCharArray(); + for (int i = 0; i < len; i++) { + int p = 2 * i; + b[i] = (byte) (charToByte(hc[p]) << 4 | charToByte(hc[p + 1])); + } + return b; + } + } + + private static byte charToByte(char c) { + return (byte) "0123456789ABCDEF".indexOf(c); + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java b/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java new file mode 100644 index 0000000..9b4155c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java @@ -0,0 +1,105 @@ +package com.casic.missiles.modular.util; + +import org.springframework.stereotype.Component; + +import javax.websocket.OnClose; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.PathParam; +import javax.websocket.server.ServerEndpoint; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CopyOnWriteArraySet; + +/** + * @Description: 此注解相当于设置访问URL + * @Author: wangpeng + * @Date: 2022/7/17 11:48 + */ +@Component +@ServerEndpoint("/websocket/{userId}") +public class WebSocket { + private Session session; + + private static CopyOnWriteArraySet webSockets = new CopyOnWriteArraySet<>(); + private static Map sessionPool = new HashMap(); + + @OnOpen + public void onOpen(Session session, @PathParam(value = "userId") String userId) { + this.session = session; + webSockets.add(this); + sessionPool.put(userId, session); + System.out.println(userId + "【websocket消息】有新的连接,总数为:" + webSockets.size()); + } + + @OnClose + public void onClose() { + webSockets.remove(this); + System.out.println("【websocket消息】连接断开,总数为:" + webSockets.size()); + } + + @OnMessage + public void onMessage(String message) { + System.out.println("【websocket消息】收到客户端消息:" + message); + } + + // 此为广播消息 + public void sendAllMessage(String message) { + for (WebSocket webSocket : webSockets) { + System.out.println("【websocket消息】广播消息:" + message); + try { + webSocket.session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + // 发送列表消息 + public void sendListMessage(List userIds, String message) { + System.out.println("【websocket消息】列表消息:" + message); + for (String userId : userIds) { + Session session = sessionPool.get(userId); + if (session != null) { + try { + session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + + // 发送列表消息 + +// public void sendListMessage(List userIds, Object data){ +// System.out.println("【websocket消息】列表消息:"+data); +// for (String userId : userIds) { +// Session session = sessionPool.get(userId); +// if (session != null) { +// try { +//// session.getAsyncRemote().sendText(message); +// session.getAsyncRemote().sendObject(data); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// } +// } + + // 此为单点消息 + public void sendOneMessage(String userId, String message) { + System.out.println("【websocket消息】单点消息:" + message); + Session session = sessionPool.get(userId); + if (session != null) { + try { + session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java new file mode 100644 index 0000000..0c1f5f1 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java @@ -0,0 +1,115 @@ +package com.casic.missiles.modular.util; + +import org.springframework.web.multipart.MultipartFile; + +import java.io.*; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipInputStream; + +/** + * @Description: 读取zip文件内容 + * @Author: wangpeng + * @Date: 2022/7/17 11:48 + */ +public class ZipFileUtil { + public static List getFile(String fileName) { + File file = new File(fileName); + ZipFile zipFile = null; + ZipInputStream zin = null; + FileInputStream fis = null; + List selectDTOList = new ArrayList<>(); + try { + Charset gbk = Charset.forName("GBK"); + zipFile = new ZipFile(file, gbk); + fis = new FileInputStream(file); + zin = new ZipInputStream(fis, gbk); + + ZipEntry ze = null; + while ((ze = zin.getNextEntry()) != null) { + String path = ze.getName(); + System.out.println(path); + if (!ze.isDirectory()) { + InputStream inputStream = zipFile.getInputStream(ze); + String base64Photo = Base64Util.getBase64FromInputStream(inputStream); +// List texts = IOUtils.readLines(inputStream); +// for (String text : texts) { +// System.out.println(" " + text); +// } + selectDTOList.add(new SelectDTO(path.substring(path.indexOf("/")+1), "data:image/png;base64,"+base64Photo)); + inputStream.close(); + } + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (zin != null) { + zin.closeEntry(); + zin.close(); + } + if (fis != null) + fis.close(); + if (zipFile != null) + zipFile.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return selectDTOList; + } + + + /** + * MultipartFile 转 File + * + * @param file + * @throws Exception + */ + public static File multipartFileToFile(MultipartFile file) throws Exception { + + File toFile = null; + if (file.equals("") || file.getSize() <= 0) { + file = null; + } else { + InputStream ins = null; + ins = file.getInputStream(); + toFile = new File(file.getOriginalFilename()); + inputStreamToFile(ins, toFile); + ins.close(); + } + return toFile; + } + + //获取流文件 + private static void inputStreamToFile(InputStream ins, File file) { + try { + OutputStream os = new FileOutputStream(file); + int bytesRead = 0; + byte[] buffer = new byte[8192]; + while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) { + os.write(buffer, 0, bytesRead); + } + os.close(); + ins.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 删除本地临时文件 + * + * @param file + */ + public static void delteTempFile(File file) { + if (file != null) { + File del = new File(file.toURI()); + del.delete(); + } + } +} + diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java new file mode 100644 index 0000000..ae93a17 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java @@ -0,0 +1,34 @@ +package com.casic.missiles.modular.util.netty; + +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.EventLoop; +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.TimeUnit; + +/** + * 负责监听启动时连接失败,重新连接功能 + * + */ +@Slf4j +public class ConnectionListener implements ChannelFutureListener { + + private NettyClient client = new NettyClient(); + + @Override + public void operationComplete(ChannelFuture channelFuture) throws Exception { + if (!channelFuture.isSuccess()) { + final EventLoop loop = channelFuture.channel().eventLoop(); + loop.schedule(new Runnable() { + @Override + public void run() { + log.info("服务端连接不上,开始重连操作..."); + client.connect(); + } + }, 5L, TimeUnit.MINUTES); + } else { + log.info("服务端连接成功..."); + } + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java new file mode 100644 index 0000000..ef9ae76 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java @@ -0,0 +1,66 @@ +package com.casic.missiles.modular.util.netty; + +import io.netty.bootstrap.Bootstrap; +import io.netty.channel.*; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioSocketChannel; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public class NettyClient { + + private static Channel channel; + + private String fenceServiceHost = "127.0.0.1"; + private Integer fenceServicePort = 9200; + + public Channel connect() { + doConnect(fenceServiceHost, fenceServicePort); + return channel; + } + + public Channel connect(String host, int port) { + doConnect(host, port); + return channel; + } + + private void doConnect(String host, int port) { + EventLoopGroup workerGroup = new NioEventLoopGroup(); + try { + Bootstrap b = new Bootstrap(); + b.group(workerGroup); + b.channel(NioSocketChannel.class); + b.option(ChannelOption.SO_KEEPALIVE, true); + b.option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(1024 * 1024)); + + b.handler(new ChannelInitializer() { + @Override + public void initChannel(SocketChannel ch) throws Exception { + + ch.pipeline().addLast("decoder", new StringDecoder()); + ch.pipeline().addLast("encoder", new StringEncoder()); + ch.pipeline().addLast(new NettyClientHandler()); + } + }); + + ChannelFuture f = b.connect(host, port); + f.addListener(new ConnectionListener()); + channel = f.channel(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static void writeAndFlush(String message) { + + if (channel != null) { + channel.writeAndFlush(message); + System.out.println("电子围栏客户端发送消息:" + message); + } + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClientHandler.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClientHandler.java new file mode 100644 index 0000000..28093f0 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClientHandler.java @@ -0,0 +1,62 @@ +package com.casic.missiles.modular.util.netty; + +import com.casic.missiles.modular.util.HttpUtil; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import io.netty.channel.EventLoop; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; + +import java.util.concurrent.TimeUnit; + +/** + * 客户端处理器 + **/ +@Slf4j +@Component +public class NettyClientHandler extends ChannelInboundHandlerAdapter { + static boolean handle = true; + + private NettyClient client = new NettyClient(); + + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + log.info("连接成功....."); + } + + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + log.info("断开连接....."); + + //使用过程中断线重连 + final EventLoop eventLoop = ctx.channel().eventLoop(); + eventLoop.schedule(new Runnable() { + @Override + public void run() { + client.connect(); + } + }, 5L, TimeUnit.SECONDS); + super.channelInactive(ctx); + } + + + @Override + public void channelRead(ChannelHandlerContext ctx, Object message) throws Exception { + + if (handle) { + MultiValueMap map = new LinkedMultiValueMap<>(); + map.add("message", message.toString()); + HttpUtil.post("http://127.0.0.1:20311/data/addPerimeterAlarm", map); + } + handle = !handle; + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + cause.printStackTrace(); + ctx.close(); + } +} + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9e20bc1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea/ +**/target/** +logs/ +*.iml diff --git a/README.md b/README.md new file mode 100644 index 0000000..2fdcd74 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# casic项目 V2.0.0 + +[^_^]: # (Talk is cheap,Show me the code!) + +## 介绍 +基于SpringBoot,致力于做更简洁的后台管理系统,完美整合springboot2.4 + shiro + mybatis-plus ! +基于casic项目代码简洁,注释丰富,上手容易,同时包含许多基础模块(用户管理,角色管理,部门管理,字典管理等10个模块) +可以直接作为一个后台管理系统的脚手架! 2022目标 `更简洁`,`更规范`! + + +#### 其他 +>* [git地址](http://192.168.0.203:8080/gitbucket) +>* [本地免登地址](http://localhost:8083/route/mockToken) diff --git a/casic-server/pom.xml b/casic-server/pom.xml new file mode 100644 index 0000000..c150a12 --- /dev/null +++ b/casic-server/pom.xml @@ -0,0 +1,70 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + 2.0.0 + ../pom.xml + + + casic-server + 2.0.0 + jar + casic-server + casic 的spring boot版本 + + + + + com.casic + casic-core + ${core.version} + provided + + + com.casic + casic-admin-support + ${admin.version} + provided + + + org.springframework.boot + spring-boot-starter-web + ${boot.version} + provided + + + + + com.hikvision.ga + artemis-http-client + 1.1.3 + + + commons-io + commons-io + + + org.springframework.boot + spring-boot-starter-websocket + 2.4.5 + + + io.netty + netty-all + 4.1.42.Final + + + + + + src/main/java + + **/*.xml + + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java new file mode 100644 index 0000000..3a60b9e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java @@ -0,0 +1,36 @@ +package com.casic.missiles.modular.async; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.TaskExecutor; +import org.springframework.scheduling.annotation.AsyncConfigurer; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadPoolExecutor; + +@Configuration +@EnableAsync +public class AsyncConfig implements AsyncConfigurer { + @Override + public Executor getAsyncExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + //核心线程数 + executor.setCorePoolSize(5); + //最大线程数 + executor.setMaxPoolSize(10); + //队列容量 + executor.setQueueCapacity(20); + //设置线程活跃时间(秒) + executor.setKeepAliveSeconds(60); + //默认线程名称 + executor.setThreadNamePrefix("user-rpt-"); + //拒绝策略 + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + //等待所有任务结束后再关闭线程池 + executor.setWaitForTasksToCompleteOnShutdown(true); + return executor; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java new file mode 100644 index 0000000..8ca554c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java @@ -0,0 +1,18 @@ +package com.casic.missiles.modular.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +// tomcat启动无需配置 +@Configuration +public class WebSocketConfig { + /** + * 注入ServerEndpointExporter, + * 这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint + */ + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java new file mode 100644 index 0000000..34fe2cd --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java @@ -0,0 +1,39 @@ +package com.casic.missiles.modular.controller; + + +import com.casic.missiles.model.application.event.core.EventPublisher; +import com.casic.missiles.model.application.event.enums.ModelEventTypeEnum; +import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.modular.event.UserEvent; +import com.casic.missiles.modular.system.model.User; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +/** + * @Description: DemoController + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@RestController +@RequestMapping("/demo") +public class DemoController { + @Autowired + private EventPublisher publisher; + + /** + * 获取mockToken + */ + @PostMapping("/list") + @ResponseBody + public Object list() { + User user = new User(); + user.setAccount("张三"); + publisher.publishEvent(new UserEvent(ModelEventTypeEnum.ADD, user)); + return ResponseData.success(); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java new file mode 100644 index 0000000..aff2889 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java @@ -0,0 +1,23 @@ +package com.casic.missiles.modular.event; + +import com.casic.missiles.model.application.event.core.ModelEvent; +import com.casic.missiles.model.application.event.type.AbstractEventTypeEnum; +import com.casic.missiles.modular.system.model.User; + +/** + * @Description: 用户事件 + * @Author: wangpeng + * @Date: 2022/7/17 11:23 + */ +public class UserEvent extends ModelEvent { + /** + * Create a new {@code ApplicationEvent}. + * + * @param type 事件类型 + * @param source the object on which the event initially occurred or with + * which the event is associated (never {@code null}) + */ + public UserEvent(AbstractEventTypeEnum type, User source) { + super(type, source); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java new file mode 100644 index 0000000..8f9603e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.core.application.event.UserLoginEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserOneListener { + @EventListener + public void onApplicationEvent(UserLoginEvent event) { + log.debug("用户1订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java new file mode 100644 index 0000000..0bd52a3 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.model.application.event.core.EventSubscriber; +import com.casic.missiles.modular.event.UserEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserTwoListener extends EventSubscriber { + @Override + public void onApplicationEvent(UserEvent event) { + log.debug("用户2订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java new file mode 100644 index 0000000..4012170 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java @@ -0,0 +1,88 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang3.StringUtils; +import sun.misc.BASE64Decoder; + +import java.io.*; + +public class Base64Util { + /** + * base64字符串转换成图片 + * + * @param imgStr base64字符串 + * @param imgFilePath 图片存放路径 + * @return + * @author ZHANGJL + * @dateTime 2018-02-23 14:42:17 + */ + public static boolean Base64ToImage(String imgStr, String imgFilePath, String fileDir) { // 对字节数组字符串进行Base64解码并生成图片 + + if (StringUtils.isEmpty(imgStr)) // 图像数据为空 + return false; + + imgStr = imgStr.substring(imgStr.indexOf(",") + 1); + + BASE64Decoder decoder = new BASE64Decoder(); + try { + // Base64解码 + byte[] b = decoder.decodeBuffer(imgStr); + + for (int i = 0; i < b.length; ++i) { + if (b[i] < 0) {// 调整异常数据 + b[i] += 256; + } + } + //如果已存在图像,先删除 + File file = new File(fileDir+File.separator + imgFilePath); + if (file.exists() && file.isFile()) { + file.delete(); + } + File dir = new File(fileDir); + if (!dir.exists()) { + dir.mkdirs(); + } + file = new File(fileDir+File.separator+imgFilePath); + file.createNewFile(); +// ImageIO.write(bImage, "bmp", name); + OutputStream out = new FileOutputStream(fileDir+File.separator+imgFilePath); + out.write(b); + out.flush(); + out.close(); + + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + + } + + public static String getBase64FromInputStream(InputStream in) { + // 将图片文件转化为字节数组字符串,并对其进行Base64编码处理 + byte[] data = null; + // 读取图片字节数组 + try { + ByteArrayOutputStream swapStream = new ByteArrayOutputStream(); + byte[] buff = new byte[100]; + int rc = 0; + while ((rc = in.read(buff, 0, 100)) > 0) { + swapStream.write(buff, 0, rc); + } + data = swapStream.toByteArray(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return new String(Base64.encodeBase64(data)); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java new file mode 100644 index 0000000..9c93895 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java @@ -0,0 +1,75 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.lang3.StringUtils; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class CommonUtil { + + public static String CutId(String id) { + return id.substring(6, 10) + "-" + id.substring(10, 12) + "-" + id.substring(12, 14); + } + + public static boolean isIDNumber(String IDNumber) { + if (IDNumber == null || "".equals(IDNumber)) { + return false; + } + // 定义判别用户身份证号的正则表达式(15位或者18位,最后一位可以为字母) + String regularExpression = + "(^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|" + + "(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}$)"; + boolean matches = IDNumber.matches(regularExpression); + // 判断第18位校验值 + if (matches) { + if (IDNumber.length() == 18) { + try { + char[] charArray = IDNumber.toCharArray(); + // 前十七位加权因子 + int[] idCardWi = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; + // 这是除以11后,可能产生的11位余数对应的验证码 + String[] idCardY = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"}; + int sum = 0; + for (int i = 0; i < idCardWi.length; i++) { + int current = Integer.parseInt(String.valueOf(charArray[i])); + int count = current * idCardWi[i]; + sum += count; + } + char idCardLast = charArray[17]; + int idCardMod = sum % 11; + if (idCardY[idCardMod].toUpperCase() + .equals(String.valueOf(idCardLast).toUpperCase())) { + return true; + } else { + System.out.println("身份证最后一位:" + String.valueOf(idCardLast).toUpperCase() + + "错误,正确的应该是:" + idCardY[idCardMod].toUpperCase()); + return false; + } + + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } else { + return false; + } + } + return matches; + } + + + public static boolean CheckMobilePhoneNum(String phoneNum) { + if (StringUtils.isEmpty(phoneNum)) + return true; + String regex = "^(1[3-9]\\d{9}$)"; + if (phoneNum.length() == 11) { + Pattern p = Pattern.compile(regex); + Matcher m = p.matcher(phoneNum); + if (m.matches()) { + return true; + } + } + return false; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java new file mode 100644 index 0000000..191ef79 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java @@ -0,0 +1,116 @@ +package com.casic.missiles.modular.util; + + +import javafx.util.Pair; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +/** + * Created by Administrator on 2015/2/25. + */ +public class DateUtils { + public static SimpleDateFormat sdf_day = new SimpleDateFormat("yyyy-MM-dd"); + public static SimpleDateFormat sdf_day_time = new SimpleDateFormat("yyyyMMddhhmmss"); + public static final SimpleDateFormat sdf4 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + public static final SimpleDateFormat sdf5 = new SimpleDateFormat("HH:mm:ss"); + + + /** + * 获取当年的第一天 + * + * @return + */ + public static Date getCurrYearFirst() { + Calendar currCal = Calendar.getInstance(); + int currentYear = currCal.get(Calendar.YEAR); + return getYearFirst(currentYear); + } + + + /** + * 获取某年第一天日期 + * + * @param year 年份 + * @return Date + */ + public static Date getYearFirst(int year) { + Calendar calendar = Calendar.getInstance(); + calendar.clear(); + calendar.set(Calendar.YEAR, year); + Date currYearFirst = calendar.getTime(); + return currYearFirst; + } + + /** + * 最近7日(不包括今日) + */ + public static Pair getLastSevenDays() { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, -7); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 最近n日(不包括今日) + */ + public static Pair getLastNDays(int n) { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, n * -1); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 日期时间加n天 + */ + public static String addDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf4.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf4.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 日期加n天 + */ + public static String addNDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf_day.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf_day.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 昨日 + */ + public static String getYesterday() { + + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.DATE, -2); + return sdf_day.format(calendar.getTime()); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java new file mode 100644 index 0000000..da0f8ee --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java @@ -0,0 +1,49 @@ +package com.casic.missiles.modular.util; + +import com.hikvision.artemis.sdk.ArtemisHttpUtil; +import com.hikvision.artemis.sdk.config.ArtemisConfig; + +import java.util.HashMap; +import java.util.Map; + +public class HikUtil { + + public static String hikApi(String uri, String body) { + + /** + * STEP1:设置平台参数,根据实际情况,设置host appkey appsecret 三个参数. + */ + ArtemisConfig.host = "192.168.1.22:443"; // artemis网关服务器ip端口 + ArtemisConfig.appKey = "25766251"; // 秘钥appkey + ArtemisConfig.appSecret = "h2o6zXtzCmt8eaOaMkXb";// 秘钥appSecret + + /** + * STEP2:设置OpenAPI接口的上下文 + */ + final String ARTEMIS_PATH = "/artemis"; + + /** + * STEP3:设置接口的URI地址 + */ + final String previewURLsApi = ARTEMIS_PATH + uri; + Map path = new HashMap(2) { + { + put("https://", previewURLsApi);//根据现场环境部署确认是http还是https + } + }; + + /** + * STEP4:设置参数提交方式 + */ + String contentType = "application/json"; + + /** + * STEP5:组装请求参数 + */ + /** + * STEP6:调用接口 + */ + String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, contentType, null);// post请求application/json类型参数 + return result; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java new file mode 100644 index 0000000..4867144 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java @@ -0,0 +1,149 @@ +package com.casic.missiles.modular.util; + +import org.springframework.http.*; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; + +/** + * @Description: http请求工具类 + * @Author: wangpeng + * @Date: 2022/7/17 11:49 + */ +public class HttpUtil { + /** + * get请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String get(String url, MultiValueMap params) { + return get(url, params, null); + } + + /** + * get请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String get(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.GET); + } + + /** + * post请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String post(String url, MultiValueMap params) { + return post(url, params, null); + } + + /** + * post请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String post(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.POST); + } + + /** + * put请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String put(String url, MultiValueMap params) { + return put(url, params, null); + } + + /** + * put请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String put(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.PUT); + } + + /** + * delete请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String delete(String url, MultiValueMap params) { + return delete(url, params, null); + } + + /** + * delete请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String delete(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.DELETE); + } + + /** + * 表单请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @param method 请求方式 + * @return + */ + public static String request(String url, MultiValueMap params, MultiValueMap headers, HttpMethod method) { + if (params == null) { + params = new LinkedMultiValueMap<>(); + } + return request(url, params, headers, method, MediaType.APPLICATION_FORM_URLENCODED); + } + + /** + * http请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @param method 请求方式 + * @param mediaType 参数类型 + * @return + */ + public static String request(String url, Object params, MultiValueMap headers, HttpMethod method, MediaType mediaType) { + if (url == null || url.trim().isEmpty()) { + return null; + } + RestTemplate client = new RestTemplate(); + // header + HttpHeaders httpHeaders = new HttpHeaders(); + if (headers != null) { +// httpHeaders.addAll(headers); + httpHeaders.putAll(headers); + } + // 提交方式:表单、json + httpHeaders.setContentType(mediaType); + HttpEntity httpEntity = new HttpEntity(params, httpHeaders); + ResponseEntity response = client.exchange(url, method, httpEntity, String.class); + return response.getBody(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java new file mode 100644 index 0000000..19d8d67 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java @@ -0,0 +1,30 @@ +package com.casic.missiles.modular.util; + +public class SelectDTO { + private String name; + private String value; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public SelectDTO() { + } + + public SelectDTO(String name, String value) { + this.name = name; + this.value = value; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java new file mode 100644 index 0000000..0bd484c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java @@ -0,0 +1,28 @@ +package com.casic.missiles.modular.util; + +public class SocketConst { + + /** + * 新增授权socket前缀 + */ + public static final String SOCKET_PREFIX_ADD_PERMISSION = "addPermission:"; + + /** + * 取消授权socket前缀 + */ + public static final String SOCKET_PREFIX_DELETE_PERMISSION = "deletePermission:"; + + /** + * 人员数据下发socket前缀 + */ + public static final String SOCKET_PREFIX_ADD_PERSON = "addPerson:"; + + /** + * socket返回成功信息 + */ + public static final String SOCKET_SUCCESS_MSG = "ok"; + /** + * 人员数据下发socket前缀 + */ + public static final String SOCKET_PREFIX_DELETE_PERSON = "deletePerson:"; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java new file mode 100644 index 0000000..0452bca --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java @@ -0,0 +1,90 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.io.IOUtils; +import org.springframework.stereotype.Component; + +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.text.SimpleDateFormat; +import java.util.Date; + +@Component +public class SocketUtil { + + public static byte[] sendMessage(String ip, int port, String msg) { + byte[] data = new byte[20]; + + System.out.println("往 " + ip + ":" + port + " 发送数据:" + msg); + InputStream in = null; + OutputStream out = null; + Socket socket = null; + try { + socket = new Socket(); + socket.connect(new InetSocketAddress(ip, port), 1000); + socket.setSoTimeout(2000); + // 向服务端发送数据 + out = socket.getOutputStream(); + out.write(hexString2Bytes(msg)); + out.flush(); + //socket.shutdownOutput(); + // 读取服务端返回数据 + in = socket.getInputStream(); + in.read(data); + } catch (Exception e) { + e.printStackTrace(); + } finally { + IOUtils.closeQuietly(in); + IOUtils.closeQuietly(out); + IOUtils.closeQuietly(socket); + } + return data; + } + + private static int code = 0; + + public static void main(String[] args) { +// byte[] dd = sendMessage("192.168.5.211",6001,"090300000002C543"); + + String dateStr = new SimpleDateFormat("yyMMddHHmmssSSS").format(new Date()); + //String dd = dateStr + String.format("%04d",++code); + + System.out.println(dateStr); + } + + /** + * 返回由字节数组转换来的 16 位有符号整数 + * + * @param bytes 字节数组 + * @return 由两个字节构成的 16 位有符号整数 + */ + public static short toShort(byte[] bytes) { + return (short) ((0xff & bytes[0]) | (0xff00 & (bytes[1] << 8))); + + } + + + public static byte[] hexString2Bytes(String hex) { + if ((hex == null) || (hex.equals(""))) { + return null; + } else if (hex.length() % 2 != 0) { + return null; + } else { + hex = hex.toUpperCase(); + int len = hex.length() / 2; + byte[] b = new byte[len]; + char[] hc = hex.toCharArray(); + for (int i = 0; i < len; i++) { + int p = 2 * i; + b[i] = (byte) (charToByte(hc[p]) << 4 | charToByte(hc[p + 1])); + } + return b; + } + } + + private static byte charToByte(char c) { + return (byte) "0123456789ABCDEF".indexOf(c); + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java b/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java new file mode 100644 index 0000000..9b4155c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java @@ -0,0 +1,105 @@ +package com.casic.missiles.modular.util; + +import org.springframework.stereotype.Component; + +import javax.websocket.OnClose; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.PathParam; +import javax.websocket.server.ServerEndpoint; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CopyOnWriteArraySet; + +/** + * @Description: 此注解相当于设置访问URL + * @Author: wangpeng + * @Date: 2022/7/17 11:48 + */ +@Component +@ServerEndpoint("/websocket/{userId}") +public class WebSocket { + private Session session; + + private static CopyOnWriteArraySet webSockets = new CopyOnWriteArraySet<>(); + private static Map sessionPool = new HashMap(); + + @OnOpen + public void onOpen(Session session, @PathParam(value = "userId") String userId) { + this.session = session; + webSockets.add(this); + sessionPool.put(userId, session); + System.out.println(userId + "【websocket消息】有新的连接,总数为:" + webSockets.size()); + } + + @OnClose + public void onClose() { + webSockets.remove(this); + System.out.println("【websocket消息】连接断开,总数为:" + webSockets.size()); + } + + @OnMessage + public void onMessage(String message) { + System.out.println("【websocket消息】收到客户端消息:" + message); + } + + // 此为广播消息 + public void sendAllMessage(String message) { + for (WebSocket webSocket : webSockets) { + System.out.println("【websocket消息】广播消息:" + message); + try { + webSocket.session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + // 发送列表消息 + public void sendListMessage(List userIds, String message) { + System.out.println("【websocket消息】列表消息:" + message); + for (String userId : userIds) { + Session session = sessionPool.get(userId); + if (session != null) { + try { + session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + + // 发送列表消息 + +// public void sendListMessage(List userIds, Object data){ +// System.out.println("【websocket消息】列表消息:"+data); +// for (String userId : userIds) { +// Session session = sessionPool.get(userId); +// if (session != null) { +// try { +//// session.getAsyncRemote().sendText(message); +// session.getAsyncRemote().sendObject(data); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// } +// } + + // 此为单点消息 + public void sendOneMessage(String userId, String message) { + System.out.println("【websocket消息】单点消息:" + message); + Session session = sessionPool.get(userId); + if (session != null) { + try { + session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java new file mode 100644 index 0000000..0c1f5f1 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java @@ -0,0 +1,115 @@ +package com.casic.missiles.modular.util; + +import org.springframework.web.multipart.MultipartFile; + +import java.io.*; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipInputStream; + +/** + * @Description: 读取zip文件内容 + * @Author: wangpeng + * @Date: 2022/7/17 11:48 + */ +public class ZipFileUtil { + public static List getFile(String fileName) { + File file = new File(fileName); + ZipFile zipFile = null; + ZipInputStream zin = null; + FileInputStream fis = null; + List selectDTOList = new ArrayList<>(); + try { + Charset gbk = Charset.forName("GBK"); + zipFile = new ZipFile(file, gbk); + fis = new FileInputStream(file); + zin = new ZipInputStream(fis, gbk); + + ZipEntry ze = null; + while ((ze = zin.getNextEntry()) != null) { + String path = ze.getName(); + System.out.println(path); + if (!ze.isDirectory()) { + InputStream inputStream = zipFile.getInputStream(ze); + String base64Photo = Base64Util.getBase64FromInputStream(inputStream); +// List texts = IOUtils.readLines(inputStream); +// for (String text : texts) { +// System.out.println(" " + text); +// } + selectDTOList.add(new SelectDTO(path.substring(path.indexOf("/")+1), "data:image/png;base64,"+base64Photo)); + inputStream.close(); + } + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (zin != null) { + zin.closeEntry(); + zin.close(); + } + if (fis != null) + fis.close(); + if (zipFile != null) + zipFile.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return selectDTOList; + } + + + /** + * MultipartFile 转 File + * + * @param file + * @throws Exception + */ + public static File multipartFileToFile(MultipartFile file) throws Exception { + + File toFile = null; + if (file.equals("") || file.getSize() <= 0) { + file = null; + } else { + InputStream ins = null; + ins = file.getInputStream(); + toFile = new File(file.getOriginalFilename()); + inputStreamToFile(ins, toFile); + ins.close(); + } + return toFile; + } + + //获取流文件 + private static void inputStreamToFile(InputStream ins, File file) { + try { + OutputStream os = new FileOutputStream(file); + int bytesRead = 0; + byte[] buffer = new byte[8192]; + while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) { + os.write(buffer, 0, bytesRead); + } + os.close(); + ins.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 删除本地临时文件 + * + * @param file + */ + public static void delteTempFile(File file) { + if (file != null) { + File del = new File(file.toURI()); + del.delete(); + } + } +} + diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java new file mode 100644 index 0000000..ae93a17 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java @@ -0,0 +1,34 @@ +package com.casic.missiles.modular.util.netty; + +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.EventLoop; +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.TimeUnit; + +/** + * 负责监听启动时连接失败,重新连接功能 + * + */ +@Slf4j +public class ConnectionListener implements ChannelFutureListener { + + private NettyClient client = new NettyClient(); + + @Override + public void operationComplete(ChannelFuture channelFuture) throws Exception { + if (!channelFuture.isSuccess()) { + final EventLoop loop = channelFuture.channel().eventLoop(); + loop.schedule(new Runnable() { + @Override + public void run() { + log.info("服务端连接不上,开始重连操作..."); + client.connect(); + } + }, 5L, TimeUnit.MINUTES); + } else { + log.info("服务端连接成功..."); + } + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java new file mode 100644 index 0000000..ef9ae76 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java @@ -0,0 +1,66 @@ +package com.casic.missiles.modular.util.netty; + +import io.netty.bootstrap.Bootstrap; +import io.netty.channel.*; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioSocketChannel; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public class NettyClient { + + private static Channel channel; + + private String fenceServiceHost = "127.0.0.1"; + private Integer fenceServicePort = 9200; + + public Channel connect() { + doConnect(fenceServiceHost, fenceServicePort); + return channel; + } + + public Channel connect(String host, int port) { + doConnect(host, port); + return channel; + } + + private void doConnect(String host, int port) { + EventLoopGroup workerGroup = new NioEventLoopGroup(); + try { + Bootstrap b = new Bootstrap(); + b.group(workerGroup); + b.channel(NioSocketChannel.class); + b.option(ChannelOption.SO_KEEPALIVE, true); + b.option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(1024 * 1024)); + + b.handler(new ChannelInitializer() { + @Override + public void initChannel(SocketChannel ch) throws Exception { + + ch.pipeline().addLast("decoder", new StringDecoder()); + ch.pipeline().addLast("encoder", new StringEncoder()); + ch.pipeline().addLast(new NettyClientHandler()); + } + }); + + ChannelFuture f = b.connect(host, port); + f.addListener(new ConnectionListener()); + channel = f.channel(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static void writeAndFlush(String message) { + + if (channel != null) { + channel.writeAndFlush(message); + System.out.println("电子围栏客户端发送消息:" + message); + } + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClientHandler.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClientHandler.java new file mode 100644 index 0000000..28093f0 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClientHandler.java @@ -0,0 +1,62 @@ +package com.casic.missiles.modular.util.netty; + +import com.casic.missiles.modular.util.HttpUtil; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import io.netty.channel.EventLoop; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; + +import java.util.concurrent.TimeUnit; + +/** + * 客户端处理器 + **/ +@Slf4j +@Component +public class NettyClientHandler extends ChannelInboundHandlerAdapter { + static boolean handle = true; + + private NettyClient client = new NettyClient(); + + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + log.info("连接成功....."); + } + + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + log.info("断开连接....."); + + //使用过程中断线重连 + final EventLoop eventLoop = ctx.channel().eventLoop(); + eventLoop.schedule(new Runnable() { + @Override + public void run() { + client.connect(); + } + }, 5L, TimeUnit.SECONDS); + super.channelInactive(ctx); + } + + + @Override + public void channelRead(ChannelHandlerContext ctx, Object message) throws Exception { + + if (handle) { + MultiValueMap map = new LinkedMultiValueMap<>(); + map.add("message", message.toString()); + HttpUtil.post("http://127.0.0.1:20311/data/addPerimeterAlarm", map); + } + handle = !handle; + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + cause.printStackTrace(); + ctx.close(); + } +} + diff --git a/casic-web/pom.xml b/casic-web/pom.xml new file mode 100644 index 0000000..8fb0b2c --- /dev/null +++ b/casic-web/pom.xml @@ -0,0 +1,171 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + ../pom.xml + 2.0.0 + + casic-web + 2.0.0 + jar + casic-web + casic web启动入口 + + + + dev + + true + + + dev + + + + test + + test + + + + prod + + prod + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + io.micrometer + micrometer-core + + + + + org.springframework.boot + spring-boot-starter-jdbc + + + + com.casic + casic-core + ${core.version} + + + com.casic + casic-admin-core + ${admin.version} + + + io.springfox + springfox-swagger-ui + + + + + com.casic + casic-admin-support + ${admin.version} + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.dameng + DmJdbcDriver18 + 1.8 + + + com.casic + casic-area-starter + ${admin.version} + + + + com.casic + casic-server + ${pro.version} + + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + + + org.apache.maven.plugins + maven-jar-plugin + ${maven.jar.plugin.version} + + + + /config/*-*.yml + **/MockController.class + + + + com.casic.missiles.CasicApplication + true + ./ + + + + + + org.apache.maven.plugins + maven-assembly-plugin + ${maven.assembly.plugin.version} + + + make-assembly + package + + single + + + + + + org.apache.maven.plugins + maven-war-plugin + ${maven.war.plugin.version} + + + + + src/main/resources + + + /config/*/* + /config/*-*.yml + + true + + + src/main/java + + **/*.xml + + true + + + + \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9e20bc1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea/ +**/target/** +logs/ +*.iml diff --git a/README.md b/README.md new file mode 100644 index 0000000..2fdcd74 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# casic项目 V2.0.0 + +[^_^]: # (Talk is cheap,Show me the code!) + +## 介绍 +基于SpringBoot,致力于做更简洁的后台管理系统,完美整合springboot2.4 + shiro + mybatis-plus ! +基于casic项目代码简洁,注释丰富,上手容易,同时包含许多基础模块(用户管理,角色管理,部门管理,字典管理等10个模块) +可以直接作为一个后台管理系统的脚手架! 2022目标 `更简洁`,`更规范`! + + +#### 其他 +>* [git地址](http://192.168.0.203:8080/gitbucket) +>* [本地免登地址](http://localhost:8083/route/mockToken) diff --git a/casic-server/pom.xml b/casic-server/pom.xml new file mode 100644 index 0000000..c150a12 --- /dev/null +++ b/casic-server/pom.xml @@ -0,0 +1,70 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + 2.0.0 + ../pom.xml + + + casic-server + 2.0.0 + jar + casic-server + casic 的spring boot版本 + + + + + com.casic + casic-core + ${core.version} + provided + + + com.casic + casic-admin-support + ${admin.version} + provided + + + org.springframework.boot + spring-boot-starter-web + ${boot.version} + provided + + + + + com.hikvision.ga + artemis-http-client + 1.1.3 + + + commons-io + commons-io + + + org.springframework.boot + spring-boot-starter-websocket + 2.4.5 + + + io.netty + netty-all + 4.1.42.Final + + + + + + src/main/java + + **/*.xml + + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java new file mode 100644 index 0000000..3a60b9e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java @@ -0,0 +1,36 @@ +package com.casic.missiles.modular.async; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.TaskExecutor; +import org.springframework.scheduling.annotation.AsyncConfigurer; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadPoolExecutor; + +@Configuration +@EnableAsync +public class AsyncConfig implements AsyncConfigurer { + @Override + public Executor getAsyncExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + //核心线程数 + executor.setCorePoolSize(5); + //最大线程数 + executor.setMaxPoolSize(10); + //队列容量 + executor.setQueueCapacity(20); + //设置线程活跃时间(秒) + executor.setKeepAliveSeconds(60); + //默认线程名称 + executor.setThreadNamePrefix("user-rpt-"); + //拒绝策略 + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + //等待所有任务结束后再关闭线程池 + executor.setWaitForTasksToCompleteOnShutdown(true); + return executor; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java new file mode 100644 index 0000000..8ca554c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java @@ -0,0 +1,18 @@ +package com.casic.missiles.modular.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +// tomcat启动无需配置 +@Configuration +public class WebSocketConfig { + /** + * 注入ServerEndpointExporter, + * 这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint + */ + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java new file mode 100644 index 0000000..34fe2cd --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java @@ -0,0 +1,39 @@ +package com.casic.missiles.modular.controller; + + +import com.casic.missiles.model.application.event.core.EventPublisher; +import com.casic.missiles.model.application.event.enums.ModelEventTypeEnum; +import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.modular.event.UserEvent; +import com.casic.missiles.modular.system.model.User; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +/** + * @Description: DemoController + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@RestController +@RequestMapping("/demo") +public class DemoController { + @Autowired + private EventPublisher publisher; + + /** + * 获取mockToken + */ + @PostMapping("/list") + @ResponseBody + public Object list() { + User user = new User(); + user.setAccount("张三"); + publisher.publishEvent(new UserEvent(ModelEventTypeEnum.ADD, user)); + return ResponseData.success(); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java new file mode 100644 index 0000000..aff2889 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java @@ -0,0 +1,23 @@ +package com.casic.missiles.modular.event; + +import com.casic.missiles.model.application.event.core.ModelEvent; +import com.casic.missiles.model.application.event.type.AbstractEventTypeEnum; +import com.casic.missiles.modular.system.model.User; + +/** + * @Description: 用户事件 + * @Author: wangpeng + * @Date: 2022/7/17 11:23 + */ +public class UserEvent extends ModelEvent { + /** + * Create a new {@code ApplicationEvent}. + * + * @param type 事件类型 + * @param source the object on which the event initially occurred or with + * which the event is associated (never {@code null}) + */ + public UserEvent(AbstractEventTypeEnum type, User source) { + super(type, source); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java new file mode 100644 index 0000000..8f9603e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.core.application.event.UserLoginEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserOneListener { + @EventListener + public void onApplicationEvent(UserLoginEvent event) { + log.debug("用户1订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java new file mode 100644 index 0000000..0bd52a3 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.model.application.event.core.EventSubscriber; +import com.casic.missiles.modular.event.UserEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserTwoListener extends EventSubscriber { + @Override + public void onApplicationEvent(UserEvent event) { + log.debug("用户2订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java new file mode 100644 index 0000000..4012170 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java @@ -0,0 +1,88 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang3.StringUtils; +import sun.misc.BASE64Decoder; + +import java.io.*; + +public class Base64Util { + /** + * base64字符串转换成图片 + * + * @param imgStr base64字符串 + * @param imgFilePath 图片存放路径 + * @return + * @author ZHANGJL + * @dateTime 2018-02-23 14:42:17 + */ + public static boolean Base64ToImage(String imgStr, String imgFilePath, String fileDir) { // 对字节数组字符串进行Base64解码并生成图片 + + if (StringUtils.isEmpty(imgStr)) // 图像数据为空 + return false; + + imgStr = imgStr.substring(imgStr.indexOf(",") + 1); + + BASE64Decoder decoder = new BASE64Decoder(); + try { + // Base64解码 + byte[] b = decoder.decodeBuffer(imgStr); + + for (int i = 0; i < b.length; ++i) { + if (b[i] < 0) {// 调整异常数据 + b[i] += 256; + } + } + //如果已存在图像,先删除 + File file = new File(fileDir+File.separator + imgFilePath); + if (file.exists() && file.isFile()) { + file.delete(); + } + File dir = new File(fileDir); + if (!dir.exists()) { + dir.mkdirs(); + } + file = new File(fileDir+File.separator+imgFilePath); + file.createNewFile(); +// ImageIO.write(bImage, "bmp", name); + OutputStream out = new FileOutputStream(fileDir+File.separator+imgFilePath); + out.write(b); + out.flush(); + out.close(); + + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + + } + + public static String getBase64FromInputStream(InputStream in) { + // 将图片文件转化为字节数组字符串,并对其进行Base64编码处理 + byte[] data = null; + // 读取图片字节数组 + try { + ByteArrayOutputStream swapStream = new ByteArrayOutputStream(); + byte[] buff = new byte[100]; + int rc = 0; + while ((rc = in.read(buff, 0, 100)) > 0) { + swapStream.write(buff, 0, rc); + } + data = swapStream.toByteArray(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return new String(Base64.encodeBase64(data)); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java new file mode 100644 index 0000000..9c93895 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java @@ -0,0 +1,75 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.lang3.StringUtils; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class CommonUtil { + + public static String CutId(String id) { + return id.substring(6, 10) + "-" + id.substring(10, 12) + "-" + id.substring(12, 14); + } + + public static boolean isIDNumber(String IDNumber) { + if (IDNumber == null || "".equals(IDNumber)) { + return false; + } + // 定义判别用户身份证号的正则表达式(15位或者18位,最后一位可以为字母) + String regularExpression = + "(^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|" + + "(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}$)"; + boolean matches = IDNumber.matches(regularExpression); + // 判断第18位校验值 + if (matches) { + if (IDNumber.length() == 18) { + try { + char[] charArray = IDNumber.toCharArray(); + // 前十七位加权因子 + int[] idCardWi = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; + // 这是除以11后,可能产生的11位余数对应的验证码 + String[] idCardY = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"}; + int sum = 0; + for (int i = 0; i < idCardWi.length; i++) { + int current = Integer.parseInt(String.valueOf(charArray[i])); + int count = current * idCardWi[i]; + sum += count; + } + char idCardLast = charArray[17]; + int idCardMod = sum % 11; + if (idCardY[idCardMod].toUpperCase() + .equals(String.valueOf(idCardLast).toUpperCase())) { + return true; + } else { + System.out.println("身份证最后一位:" + String.valueOf(idCardLast).toUpperCase() + + "错误,正确的应该是:" + idCardY[idCardMod].toUpperCase()); + return false; + } + + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } else { + return false; + } + } + return matches; + } + + + public static boolean CheckMobilePhoneNum(String phoneNum) { + if (StringUtils.isEmpty(phoneNum)) + return true; + String regex = "^(1[3-9]\\d{9}$)"; + if (phoneNum.length() == 11) { + Pattern p = Pattern.compile(regex); + Matcher m = p.matcher(phoneNum); + if (m.matches()) { + return true; + } + } + return false; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java new file mode 100644 index 0000000..191ef79 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java @@ -0,0 +1,116 @@ +package com.casic.missiles.modular.util; + + +import javafx.util.Pair; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +/** + * Created by Administrator on 2015/2/25. + */ +public class DateUtils { + public static SimpleDateFormat sdf_day = new SimpleDateFormat("yyyy-MM-dd"); + public static SimpleDateFormat sdf_day_time = new SimpleDateFormat("yyyyMMddhhmmss"); + public static final SimpleDateFormat sdf4 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + public static final SimpleDateFormat sdf5 = new SimpleDateFormat("HH:mm:ss"); + + + /** + * 获取当年的第一天 + * + * @return + */ + public static Date getCurrYearFirst() { + Calendar currCal = Calendar.getInstance(); + int currentYear = currCal.get(Calendar.YEAR); + return getYearFirst(currentYear); + } + + + /** + * 获取某年第一天日期 + * + * @param year 年份 + * @return Date + */ + public static Date getYearFirst(int year) { + Calendar calendar = Calendar.getInstance(); + calendar.clear(); + calendar.set(Calendar.YEAR, year); + Date currYearFirst = calendar.getTime(); + return currYearFirst; + } + + /** + * 最近7日(不包括今日) + */ + public static Pair getLastSevenDays() { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, -7); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 最近n日(不包括今日) + */ + public static Pair getLastNDays(int n) { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, n * -1); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 日期时间加n天 + */ + public static String addDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf4.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf4.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 日期加n天 + */ + public static String addNDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf_day.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf_day.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 昨日 + */ + public static String getYesterday() { + + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.DATE, -2); + return sdf_day.format(calendar.getTime()); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java new file mode 100644 index 0000000..da0f8ee --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java @@ -0,0 +1,49 @@ +package com.casic.missiles.modular.util; + +import com.hikvision.artemis.sdk.ArtemisHttpUtil; +import com.hikvision.artemis.sdk.config.ArtemisConfig; + +import java.util.HashMap; +import java.util.Map; + +public class HikUtil { + + public static String hikApi(String uri, String body) { + + /** + * STEP1:设置平台参数,根据实际情况,设置host appkey appsecret 三个参数. + */ + ArtemisConfig.host = "192.168.1.22:443"; // artemis网关服务器ip端口 + ArtemisConfig.appKey = "25766251"; // 秘钥appkey + ArtemisConfig.appSecret = "h2o6zXtzCmt8eaOaMkXb";// 秘钥appSecret + + /** + * STEP2:设置OpenAPI接口的上下文 + */ + final String ARTEMIS_PATH = "/artemis"; + + /** + * STEP3:设置接口的URI地址 + */ + final String previewURLsApi = ARTEMIS_PATH + uri; + Map path = new HashMap(2) { + { + put("https://", previewURLsApi);//根据现场环境部署确认是http还是https + } + }; + + /** + * STEP4:设置参数提交方式 + */ + String contentType = "application/json"; + + /** + * STEP5:组装请求参数 + */ + /** + * STEP6:调用接口 + */ + String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, contentType, null);// post请求application/json类型参数 + return result; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java new file mode 100644 index 0000000..4867144 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java @@ -0,0 +1,149 @@ +package com.casic.missiles.modular.util; + +import org.springframework.http.*; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; + +/** + * @Description: http请求工具类 + * @Author: wangpeng + * @Date: 2022/7/17 11:49 + */ +public class HttpUtil { + /** + * get请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String get(String url, MultiValueMap params) { + return get(url, params, null); + } + + /** + * get请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String get(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.GET); + } + + /** + * post请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String post(String url, MultiValueMap params) { + return post(url, params, null); + } + + /** + * post请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String post(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.POST); + } + + /** + * put请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String put(String url, MultiValueMap params) { + return put(url, params, null); + } + + /** + * put请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String put(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.PUT); + } + + /** + * delete请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String delete(String url, MultiValueMap params) { + return delete(url, params, null); + } + + /** + * delete请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String delete(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.DELETE); + } + + /** + * 表单请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @param method 请求方式 + * @return + */ + public static String request(String url, MultiValueMap params, MultiValueMap headers, HttpMethod method) { + if (params == null) { + params = new LinkedMultiValueMap<>(); + } + return request(url, params, headers, method, MediaType.APPLICATION_FORM_URLENCODED); + } + + /** + * http请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @param method 请求方式 + * @param mediaType 参数类型 + * @return + */ + public static String request(String url, Object params, MultiValueMap headers, HttpMethod method, MediaType mediaType) { + if (url == null || url.trim().isEmpty()) { + return null; + } + RestTemplate client = new RestTemplate(); + // header + HttpHeaders httpHeaders = new HttpHeaders(); + if (headers != null) { +// httpHeaders.addAll(headers); + httpHeaders.putAll(headers); + } + // 提交方式:表单、json + httpHeaders.setContentType(mediaType); + HttpEntity httpEntity = new HttpEntity(params, httpHeaders); + ResponseEntity response = client.exchange(url, method, httpEntity, String.class); + return response.getBody(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java new file mode 100644 index 0000000..19d8d67 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java @@ -0,0 +1,30 @@ +package com.casic.missiles.modular.util; + +public class SelectDTO { + private String name; + private String value; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public SelectDTO() { + } + + public SelectDTO(String name, String value) { + this.name = name; + this.value = value; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java new file mode 100644 index 0000000..0bd484c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java @@ -0,0 +1,28 @@ +package com.casic.missiles.modular.util; + +public class SocketConst { + + /** + * 新增授权socket前缀 + */ + public static final String SOCKET_PREFIX_ADD_PERMISSION = "addPermission:"; + + /** + * 取消授权socket前缀 + */ + public static final String SOCKET_PREFIX_DELETE_PERMISSION = "deletePermission:"; + + /** + * 人员数据下发socket前缀 + */ + public static final String SOCKET_PREFIX_ADD_PERSON = "addPerson:"; + + /** + * socket返回成功信息 + */ + public static final String SOCKET_SUCCESS_MSG = "ok"; + /** + * 人员数据下发socket前缀 + */ + public static final String SOCKET_PREFIX_DELETE_PERSON = "deletePerson:"; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java new file mode 100644 index 0000000..0452bca --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java @@ -0,0 +1,90 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.io.IOUtils; +import org.springframework.stereotype.Component; + +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.text.SimpleDateFormat; +import java.util.Date; + +@Component +public class SocketUtil { + + public static byte[] sendMessage(String ip, int port, String msg) { + byte[] data = new byte[20]; + + System.out.println("往 " + ip + ":" + port + " 发送数据:" + msg); + InputStream in = null; + OutputStream out = null; + Socket socket = null; + try { + socket = new Socket(); + socket.connect(new InetSocketAddress(ip, port), 1000); + socket.setSoTimeout(2000); + // 向服务端发送数据 + out = socket.getOutputStream(); + out.write(hexString2Bytes(msg)); + out.flush(); + //socket.shutdownOutput(); + // 读取服务端返回数据 + in = socket.getInputStream(); + in.read(data); + } catch (Exception e) { + e.printStackTrace(); + } finally { + IOUtils.closeQuietly(in); + IOUtils.closeQuietly(out); + IOUtils.closeQuietly(socket); + } + return data; + } + + private static int code = 0; + + public static void main(String[] args) { +// byte[] dd = sendMessage("192.168.5.211",6001,"090300000002C543"); + + String dateStr = new SimpleDateFormat("yyMMddHHmmssSSS").format(new Date()); + //String dd = dateStr + String.format("%04d",++code); + + System.out.println(dateStr); + } + + /** + * 返回由字节数组转换来的 16 位有符号整数 + * + * @param bytes 字节数组 + * @return 由两个字节构成的 16 位有符号整数 + */ + public static short toShort(byte[] bytes) { + return (short) ((0xff & bytes[0]) | (0xff00 & (bytes[1] << 8))); + + } + + + public static byte[] hexString2Bytes(String hex) { + if ((hex == null) || (hex.equals(""))) { + return null; + } else if (hex.length() % 2 != 0) { + return null; + } else { + hex = hex.toUpperCase(); + int len = hex.length() / 2; + byte[] b = new byte[len]; + char[] hc = hex.toCharArray(); + for (int i = 0; i < len; i++) { + int p = 2 * i; + b[i] = (byte) (charToByte(hc[p]) << 4 | charToByte(hc[p + 1])); + } + return b; + } + } + + private static byte charToByte(char c) { + return (byte) "0123456789ABCDEF".indexOf(c); + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java b/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java new file mode 100644 index 0000000..9b4155c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java @@ -0,0 +1,105 @@ +package com.casic.missiles.modular.util; + +import org.springframework.stereotype.Component; + +import javax.websocket.OnClose; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.PathParam; +import javax.websocket.server.ServerEndpoint; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CopyOnWriteArraySet; + +/** + * @Description: 此注解相当于设置访问URL + * @Author: wangpeng + * @Date: 2022/7/17 11:48 + */ +@Component +@ServerEndpoint("/websocket/{userId}") +public class WebSocket { + private Session session; + + private static CopyOnWriteArraySet webSockets = new CopyOnWriteArraySet<>(); + private static Map sessionPool = new HashMap(); + + @OnOpen + public void onOpen(Session session, @PathParam(value = "userId") String userId) { + this.session = session; + webSockets.add(this); + sessionPool.put(userId, session); + System.out.println(userId + "【websocket消息】有新的连接,总数为:" + webSockets.size()); + } + + @OnClose + public void onClose() { + webSockets.remove(this); + System.out.println("【websocket消息】连接断开,总数为:" + webSockets.size()); + } + + @OnMessage + public void onMessage(String message) { + System.out.println("【websocket消息】收到客户端消息:" + message); + } + + // 此为广播消息 + public void sendAllMessage(String message) { + for (WebSocket webSocket : webSockets) { + System.out.println("【websocket消息】广播消息:" + message); + try { + webSocket.session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + // 发送列表消息 + public void sendListMessage(List userIds, String message) { + System.out.println("【websocket消息】列表消息:" + message); + for (String userId : userIds) { + Session session = sessionPool.get(userId); + if (session != null) { + try { + session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + + // 发送列表消息 + +// public void sendListMessage(List userIds, Object data){ +// System.out.println("【websocket消息】列表消息:"+data); +// for (String userId : userIds) { +// Session session = sessionPool.get(userId); +// if (session != null) { +// try { +//// session.getAsyncRemote().sendText(message); +// session.getAsyncRemote().sendObject(data); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// } +// } + + // 此为单点消息 + public void sendOneMessage(String userId, String message) { + System.out.println("【websocket消息】单点消息:" + message); + Session session = sessionPool.get(userId); + if (session != null) { + try { + session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java new file mode 100644 index 0000000..0c1f5f1 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java @@ -0,0 +1,115 @@ +package com.casic.missiles.modular.util; + +import org.springframework.web.multipart.MultipartFile; + +import java.io.*; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipInputStream; + +/** + * @Description: 读取zip文件内容 + * @Author: wangpeng + * @Date: 2022/7/17 11:48 + */ +public class ZipFileUtil { + public static List getFile(String fileName) { + File file = new File(fileName); + ZipFile zipFile = null; + ZipInputStream zin = null; + FileInputStream fis = null; + List selectDTOList = new ArrayList<>(); + try { + Charset gbk = Charset.forName("GBK"); + zipFile = new ZipFile(file, gbk); + fis = new FileInputStream(file); + zin = new ZipInputStream(fis, gbk); + + ZipEntry ze = null; + while ((ze = zin.getNextEntry()) != null) { + String path = ze.getName(); + System.out.println(path); + if (!ze.isDirectory()) { + InputStream inputStream = zipFile.getInputStream(ze); + String base64Photo = Base64Util.getBase64FromInputStream(inputStream); +// List texts = IOUtils.readLines(inputStream); +// for (String text : texts) { +// System.out.println(" " + text); +// } + selectDTOList.add(new SelectDTO(path.substring(path.indexOf("/")+1), "data:image/png;base64,"+base64Photo)); + inputStream.close(); + } + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (zin != null) { + zin.closeEntry(); + zin.close(); + } + if (fis != null) + fis.close(); + if (zipFile != null) + zipFile.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return selectDTOList; + } + + + /** + * MultipartFile 转 File + * + * @param file + * @throws Exception + */ + public static File multipartFileToFile(MultipartFile file) throws Exception { + + File toFile = null; + if (file.equals("") || file.getSize() <= 0) { + file = null; + } else { + InputStream ins = null; + ins = file.getInputStream(); + toFile = new File(file.getOriginalFilename()); + inputStreamToFile(ins, toFile); + ins.close(); + } + return toFile; + } + + //获取流文件 + private static void inputStreamToFile(InputStream ins, File file) { + try { + OutputStream os = new FileOutputStream(file); + int bytesRead = 0; + byte[] buffer = new byte[8192]; + while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) { + os.write(buffer, 0, bytesRead); + } + os.close(); + ins.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 删除本地临时文件 + * + * @param file + */ + public static void delteTempFile(File file) { + if (file != null) { + File del = new File(file.toURI()); + del.delete(); + } + } +} + diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java new file mode 100644 index 0000000..ae93a17 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java @@ -0,0 +1,34 @@ +package com.casic.missiles.modular.util.netty; + +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.EventLoop; +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.TimeUnit; + +/** + * 负责监听启动时连接失败,重新连接功能 + * + */ +@Slf4j +public class ConnectionListener implements ChannelFutureListener { + + private NettyClient client = new NettyClient(); + + @Override + public void operationComplete(ChannelFuture channelFuture) throws Exception { + if (!channelFuture.isSuccess()) { + final EventLoop loop = channelFuture.channel().eventLoop(); + loop.schedule(new Runnable() { + @Override + public void run() { + log.info("服务端连接不上,开始重连操作..."); + client.connect(); + } + }, 5L, TimeUnit.MINUTES); + } else { + log.info("服务端连接成功..."); + } + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java new file mode 100644 index 0000000..ef9ae76 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java @@ -0,0 +1,66 @@ +package com.casic.missiles.modular.util.netty; + +import io.netty.bootstrap.Bootstrap; +import io.netty.channel.*; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioSocketChannel; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public class NettyClient { + + private static Channel channel; + + private String fenceServiceHost = "127.0.0.1"; + private Integer fenceServicePort = 9200; + + public Channel connect() { + doConnect(fenceServiceHost, fenceServicePort); + return channel; + } + + public Channel connect(String host, int port) { + doConnect(host, port); + return channel; + } + + private void doConnect(String host, int port) { + EventLoopGroup workerGroup = new NioEventLoopGroup(); + try { + Bootstrap b = new Bootstrap(); + b.group(workerGroup); + b.channel(NioSocketChannel.class); + b.option(ChannelOption.SO_KEEPALIVE, true); + b.option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(1024 * 1024)); + + b.handler(new ChannelInitializer() { + @Override + public void initChannel(SocketChannel ch) throws Exception { + + ch.pipeline().addLast("decoder", new StringDecoder()); + ch.pipeline().addLast("encoder", new StringEncoder()); + ch.pipeline().addLast(new NettyClientHandler()); + } + }); + + ChannelFuture f = b.connect(host, port); + f.addListener(new ConnectionListener()); + channel = f.channel(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static void writeAndFlush(String message) { + + if (channel != null) { + channel.writeAndFlush(message); + System.out.println("电子围栏客户端发送消息:" + message); + } + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClientHandler.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClientHandler.java new file mode 100644 index 0000000..28093f0 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClientHandler.java @@ -0,0 +1,62 @@ +package com.casic.missiles.modular.util.netty; + +import com.casic.missiles.modular.util.HttpUtil; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import io.netty.channel.EventLoop; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; + +import java.util.concurrent.TimeUnit; + +/** + * 客户端处理器 + **/ +@Slf4j +@Component +public class NettyClientHandler extends ChannelInboundHandlerAdapter { + static boolean handle = true; + + private NettyClient client = new NettyClient(); + + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + log.info("连接成功....."); + } + + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + log.info("断开连接....."); + + //使用过程中断线重连 + final EventLoop eventLoop = ctx.channel().eventLoop(); + eventLoop.schedule(new Runnable() { + @Override + public void run() { + client.connect(); + } + }, 5L, TimeUnit.SECONDS); + super.channelInactive(ctx); + } + + + @Override + public void channelRead(ChannelHandlerContext ctx, Object message) throws Exception { + + if (handle) { + MultiValueMap map = new LinkedMultiValueMap<>(); + map.add("message", message.toString()); + HttpUtil.post("http://127.0.0.1:20311/data/addPerimeterAlarm", map); + } + handle = !handle; + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + cause.printStackTrace(); + ctx.close(); + } +} + diff --git a/casic-web/pom.xml b/casic-web/pom.xml new file mode 100644 index 0000000..8fb0b2c --- /dev/null +++ b/casic-web/pom.xml @@ -0,0 +1,171 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + ../pom.xml + 2.0.0 + + casic-web + 2.0.0 + jar + casic-web + casic web启动入口 + + + + dev + + true + + + dev + + + + test + + test + + + + prod + + prod + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + io.micrometer + micrometer-core + + + + + org.springframework.boot + spring-boot-starter-jdbc + + + + com.casic + casic-core + ${core.version} + + + com.casic + casic-admin-core + ${admin.version} + + + io.springfox + springfox-swagger-ui + + + + + com.casic + casic-admin-support + ${admin.version} + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.dameng + DmJdbcDriver18 + 1.8 + + + com.casic + casic-area-starter + ${admin.version} + + + + com.casic + casic-server + ${pro.version} + + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + + + org.apache.maven.plugins + maven-jar-plugin + ${maven.jar.plugin.version} + + + + /config/*-*.yml + **/MockController.class + + + + com.casic.missiles.CasicApplication + true + ./ + + + + + + org.apache.maven.plugins + maven-assembly-plugin + ${maven.assembly.plugin.version} + + + make-assembly + package + + single + + + + + + org.apache.maven.plugins + maven-war-plugin + ${maven.war.plugin.version} + + + + + src/main/resources + + + /config/*/* + /config/*-*.yml + + true + + + src/main/java + + **/*.xml + + true + + + + \ No newline at end of file diff --git a/casic-web/src/main/build/bin/start.bat b/casic-web/src/main/build/bin/start.bat new file mode 100644 index 0000000..1db4e88 --- /dev/null +++ b/casic-web/src/main/build/bin/start.bat @@ -0,0 +1,4 @@ +@echo off +title ${project.build.finalName} +java -jar ./lib/${project.build.finalName}.jar +@pause diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9e20bc1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea/ +**/target/** +logs/ +*.iml diff --git a/README.md b/README.md new file mode 100644 index 0000000..2fdcd74 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# casic项目 V2.0.0 + +[^_^]: # (Talk is cheap,Show me the code!) + +## 介绍 +基于SpringBoot,致力于做更简洁的后台管理系统,完美整合springboot2.4 + shiro + mybatis-plus ! +基于casic项目代码简洁,注释丰富,上手容易,同时包含许多基础模块(用户管理,角色管理,部门管理,字典管理等10个模块) +可以直接作为一个后台管理系统的脚手架! 2022目标 `更简洁`,`更规范`! + + +#### 其他 +>* [git地址](http://192.168.0.203:8080/gitbucket) +>* [本地免登地址](http://localhost:8083/route/mockToken) diff --git a/casic-server/pom.xml b/casic-server/pom.xml new file mode 100644 index 0000000..c150a12 --- /dev/null +++ b/casic-server/pom.xml @@ -0,0 +1,70 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + 2.0.0 + ../pom.xml + + + casic-server + 2.0.0 + jar + casic-server + casic 的spring boot版本 + + + + + com.casic + casic-core + ${core.version} + provided + + + com.casic + casic-admin-support + ${admin.version} + provided + + + org.springframework.boot + spring-boot-starter-web + ${boot.version} + provided + + + + + com.hikvision.ga + artemis-http-client + 1.1.3 + + + commons-io + commons-io + + + org.springframework.boot + spring-boot-starter-websocket + 2.4.5 + + + io.netty + netty-all + 4.1.42.Final + + + + + + src/main/java + + **/*.xml + + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java new file mode 100644 index 0000000..3a60b9e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java @@ -0,0 +1,36 @@ +package com.casic.missiles.modular.async; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.TaskExecutor; +import org.springframework.scheduling.annotation.AsyncConfigurer; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadPoolExecutor; + +@Configuration +@EnableAsync +public class AsyncConfig implements AsyncConfigurer { + @Override + public Executor getAsyncExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + //核心线程数 + executor.setCorePoolSize(5); + //最大线程数 + executor.setMaxPoolSize(10); + //队列容量 + executor.setQueueCapacity(20); + //设置线程活跃时间(秒) + executor.setKeepAliveSeconds(60); + //默认线程名称 + executor.setThreadNamePrefix("user-rpt-"); + //拒绝策略 + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + //等待所有任务结束后再关闭线程池 + executor.setWaitForTasksToCompleteOnShutdown(true); + return executor; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java new file mode 100644 index 0000000..8ca554c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java @@ -0,0 +1,18 @@ +package com.casic.missiles.modular.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +// tomcat启动无需配置 +@Configuration +public class WebSocketConfig { + /** + * 注入ServerEndpointExporter, + * 这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint + */ + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java new file mode 100644 index 0000000..34fe2cd --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java @@ -0,0 +1,39 @@ +package com.casic.missiles.modular.controller; + + +import com.casic.missiles.model.application.event.core.EventPublisher; +import com.casic.missiles.model.application.event.enums.ModelEventTypeEnum; +import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.modular.event.UserEvent; +import com.casic.missiles.modular.system.model.User; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +/** + * @Description: DemoController + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@RestController +@RequestMapping("/demo") +public class DemoController { + @Autowired + private EventPublisher publisher; + + /** + * 获取mockToken + */ + @PostMapping("/list") + @ResponseBody + public Object list() { + User user = new User(); + user.setAccount("张三"); + publisher.publishEvent(new UserEvent(ModelEventTypeEnum.ADD, user)); + return ResponseData.success(); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java new file mode 100644 index 0000000..aff2889 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java @@ -0,0 +1,23 @@ +package com.casic.missiles.modular.event; + +import com.casic.missiles.model.application.event.core.ModelEvent; +import com.casic.missiles.model.application.event.type.AbstractEventTypeEnum; +import com.casic.missiles.modular.system.model.User; + +/** + * @Description: 用户事件 + * @Author: wangpeng + * @Date: 2022/7/17 11:23 + */ +public class UserEvent extends ModelEvent { + /** + * Create a new {@code ApplicationEvent}. + * + * @param type 事件类型 + * @param source the object on which the event initially occurred or with + * which the event is associated (never {@code null}) + */ + public UserEvent(AbstractEventTypeEnum type, User source) { + super(type, source); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java new file mode 100644 index 0000000..8f9603e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.core.application.event.UserLoginEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserOneListener { + @EventListener + public void onApplicationEvent(UserLoginEvent event) { + log.debug("用户1订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java new file mode 100644 index 0000000..0bd52a3 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.model.application.event.core.EventSubscriber; +import com.casic.missiles.modular.event.UserEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserTwoListener extends EventSubscriber { + @Override + public void onApplicationEvent(UserEvent event) { + log.debug("用户2订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java new file mode 100644 index 0000000..4012170 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java @@ -0,0 +1,88 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang3.StringUtils; +import sun.misc.BASE64Decoder; + +import java.io.*; + +public class Base64Util { + /** + * base64字符串转换成图片 + * + * @param imgStr base64字符串 + * @param imgFilePath 图片存放路径 + * @return + * @author ZHANGJL + * @dateTime 2018-02-23 14:42:17 + */ + public static boolean Base64ToImage(String imgStr, String imgFilePath, String fileDir) { // 对字节数组字符串进行Base64解码并生成图片 + + if (StringUtils.isEmpty(imgStr)) // 图像数据为空 + return false; + + imgStr = imgStr.substring(imgStr.indexOf(",") + 1); + + BASE64Decoder decoder = new BASE64Decoder(); + try { + // Base64解码 + byte[] b = decoder.decodeBuffer(imgStr); + + for (int i = 0; i < b.length; ++i) { + if (b[i] < 0) {// 调整异常数据 + b[i] += 256; + } + } + //如果已存在图像,先删除 + File file = new File(fileDir+File.separator + imgFilePath); + if (file.exists() && file.isFile()) { + file.delete(); + } + File dir = new File(fileDir); + if (!dir.exists()) { + dir.mkdirs(); + } + file = new File(fileDir+File.separator+imgFilePath); + file.createNewFile(); +// ImageIO.write(bImage, "bmp", name); + OutputStream out = new FileOutputStream(fileDir+File.separator+imgFilePath); + out.write(b); + out.flush(); + out.close(); + + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + + } + + public static String getBase64FromInputStream(InputStream in) { + // 将图片文件转化为字节数组字符串,并对其进行Base64编码处理 + byte[] data = null; + // 读取图片字节数组 + try { + ByteArrayOutputStream swapStream = new ByteArrayOutputStream(); + byte[] buff = new byte[100]; + int rc = 0; + while ((rc = in.read(buff, 0, 100)) > 0) { + swapStream.write(buff, 0, rc); + } + data = swapStream.toByteArray(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return new String(Base64.encodeBase64(data)); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java new file mode 100644 index 0000000..9c93895 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java @@ -0,0 +1,75 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.lang3.StringUtils; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class CommonUtil { + + public static String CutId(String id) { + return id.substring(6, 10) + "-" + id.substring(10, 12) + "-" + id.substring(12, 14); + } + + public static boolean isIDNumber(String IDNumber) { + if (IDNumber == null || "".equals(IDNumber)) { + return false; + } + // 定义判别用户身份证号的正则表达式(15位或者18位,最后一位可以为字母) + String regularExpression = + "(^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|" + + "(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}$)"; + boolean matches = IDNumber.matches(regularExpression); + // 判断第18位校验值 + if (matches) { + if (IDNumber.length() == 18) { + try { + char[] charArray = IDNumber.toCharArray(); + // 前十七位加权因子 + int[] idCardWi = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; + // 这是除以11后,可能产生的11位余数对应的验证码 + String[] idCardY = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"}; + int sum = 0; + for (int i = 0; i < idCardWi.length; i++) { + int current = Integer.parseInt(String.valueOf(charArray[i])); + int count = current * idCardWi[i]; + sum += count; + } + char idCardLast = charArray[17]; + int idCardMod = sum % 11; + if (idCardY[idCardMod].toUpperCase() + .equals(String.valueOf(idCardLast).toUpperCase())) { + return true; + } else { + System.out.println("身份证最后一位:" + String.valueOf(idCardLast).toUpperCase() + + "错误,正确的应该是:" + idCardY[idCardMod].toUpperCase()); + return false; + } + + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } else { + return false; + } + } + return matches; + } + + + public static boolean CheckMobilePhoneNum(String phoneNum) { + if (StringUtils.isEmpty(phoneNum)) + return true; + String regex = "^(1[3-9]\\d{9}$)"; + if (phoneNum.length() == 11) { + Pattern p = Pattern.compile(regex); + Matcher m = p.matcher(phoneNum); + if (m.matches()) { + return true; + } + } + return false; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java new file mode 100644 index 0000000..191ef79 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java @@ -0,0 +1,116 @@ +package com.casic.missiles.modular.util; + + +import javafx.util.Pair; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +/** + * Created by Administrator on 2015/2/25. + */ +public class DateUtils { + public static SimpleDateFormat sdf_day = new SimpleDateFormat("yyyy-MM-dd"); + public static SimpleDateFormat sdf_day_time = new SimpleDateFormat("yyyyMMddhhmmss"); + public static final SimpleDateFormat sdf4 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + public static final SimpleDateFormat sdf5 = new SimpleDateFormat("HH:mm:ss"); + + + /** + * 获取当年的第一天 + * + * @return + */ + public static Date getCurrYearFirst() { + Calendar currCal = Calendar.getInstance(); + int currentYear = currCal.get(Calendar.YEAR); + return getYearFirst(currentYear); + } + + + /** + * 获取某年第一天日期 + * + * @param year 年份 + * @return Date + */ + public static Date getYearFirst(int year) { + Calendar calendar = Calendar.getInstance(); + calendar.clear(); + calendar.set(Calendar.YEAR, year); + Date currYearFirst = calendar.getTime(); + return currYearFirst; + } + + /** + * 最近7日(不包括今日) + */ + public static Pair getLastSevenDays() { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, -7); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 最近n日(不包括今日) + */ + public static Pair getLastNDays(int n) { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, n * -1); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 日期时间加n天 + */ + public static String addDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf4.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf4.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 日期加n天 + */ + public static String addNDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf_day.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf_day.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 昨日 + */ + public static String getYesterday() { + + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.DATE, -2); + return sdf_day.format(calendar.getTime()); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java new file mode 100644 index 0000000..da0f8ee --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java @@ -0,0 +1,49 @@ +package com.casic.missiles.modular.util; + +import com.hikvision.artemis.sdk.ArtemisHttpUtil; +import com.hikvision.artemis.sdk.config.ArtemisConfig; + +import java.util.HashMap; +import java.util.Map; + +public class HikUtil { + + public static String hikApi(String uri, String body) { + + /** + * STEP1:设置平台参数,根据实际情况,设置host appkey appsecret 三个参数. + */ + ArtemisConfig.host = "192.168.1.22:443"; // artemis网关服务器ip端口 + ArtemisConfig.appKey = "25766251"; // 秘钥appkey + ArtemisConfig.appSecret = "h2o6zXtzCmt8eaOaMkXb";// 秘钥appSecret + + /** + * STEP2:设置OpenAPI接口的上下文 + */ + final String ARTEMIS_PATH = "/artemis"; + + /** + * STEP3:设置接口的URI地址 + */ + final String previewURLsApi = ARTEMIS_PATH + uri; + Map path = new HashMap(2) { + { + put("https://", previewURLsApi);//根据现场环境部署确认是http还是https + } + }; + + /** + * STEP4:设置参数提交方式 + */ + String contentType = "application/json"; + + /** + * STEP5:组装请求参数 + */ + /** + * STEP6:调用接口 + */ + String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, contentType, null);// post请求application/json类型参数 + return result; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java new file mode 100644 index 0000000..4867144 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java @@ -0,0 +1,149 @@ +package com.casic.missiles.modular.util; + +import org.springframework.http.*; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; + +/** + * @Description: http请求工具类 + * @Author: wangpeng + * @Date: 2022/7/17 11:49 + */ +public class HttpUtil { + /** + * get请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String get(String url, MultiValueMap params) { + return get(url, params, null); + } + + /** + * get请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String get(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.GET); + } + + /** + * post请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String post(String url, MultiValueMap params) { + return post(url, params, null); + } + + /** + * post请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String post(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.POST); + } + + /** + * put请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String put(String url, MultiValueMap params) { + return put(url, params, null); + } + + /** + * put请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String put(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.PUT); + } + + /** + * delete请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String delete(String url, MultiValueMap params) { + return delete(url, params, null); + } + + /** + * delete请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String delete(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.DELETE); + } + + /** + * 表单请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @param method 请求方式 + * @return + */ + public static String request(String url, MultiValueMap params, MultiValueMap headers, HttpMethod method) { + if (params == null) { + params = new LinkedMultiValueMap<>(); + } + return request(url, params, headers, method, MediaType.APPLICATION_FORM_URLENCODED); + } + + /** + * http请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @param method 请求方式 + * @param mediaType 参数类型 + * @return + */ + public static String request(String url, Object params, MultiValueMap headers, HttpMethod method, MediaType mediaType) { + if (url == null || url.trim().isEmpty()) { + return null; + } + RestTemplate client = new RestTemplate(); + // header + HttpHeaders httpHeaders = new HttpHeaders(); + if (headers != null) { +// httpHeaders.addAll(headers); + httpHeaders.putAll(headers); + } + // 提交方式:表单、json + httpHeaders.setContentType(mediaType); + HttpEntity httpEntity = new HttpEntity(params, httpHeaders); + ResponseEntity response = client.exchange(url, method, httpEntity, String.class); + return response.getBody(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java new file mode 100644 index 0000000..19d8d67 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java @@ -0,0 +1,30 @@ +package com.casic.missiles.modular.util; + +public class SelectDTO { + private String name; + private String value; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public SelectDTO() { + } + + public SelectDTO(String name, String value) { + this.name = name; + this.value = value; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java new file mode 100644 index 0000000..0bd484c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java @@ -0,0 +1,28 @@ +package com.casic.missiles.modular.util; + +public class SocketConst { + + /** + * 新增授权socket前缀 + */ + public static final String SOCKET_PREFIX_ADD_PERMISSION = "addPermission:"; + + /** + * 取消授权socket前缀 + */ + public static final String SOCKET_PREFIX_DELETE_PERMISSION = "deletePermission:"; + + /** + * 人员数据下发socket前缀 + */ + public static final String SOCKET_PREFIX_ADD_PERSON = "addPerson:"; + + /** + * socket返回成功信息 + */ + public static final String SOCKET_SUCCESS_MSG = "ok"; + /** + * 人员数据下发socket前缀 + */ + public static final String SOCKET_PREFIX_DELETE_PERSON = "deletePerson:"; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java new file mode 100644 index 0000000..0452bca --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java @@ -0,0 +1,90 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.io.IOUtils; +import org.springframework.stereotype.Component; + +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.text.SimpleDateFormat; +import java.util.Date; + +@Component +public class SocketUtil { + + public static byte[] sendMessage(String ip, int port, String msg) { + byte[] data = new byte[20]; + + System.out.println("往 " + ip + ":" + port + " 发送数据:" + msg); + InputStream in = null; + OutputStream out = null; + Socket socket = null; + try { + socket = new Socket(); + socket.connect(new InetSocketAddress(ip, port), 1000); + socket.setSoTimeout(2000); + // 向服务端发送数据 + out = socket.getOutputStream(); + out.write(hexString2Bytes(msg)); + out.flush(); + //socket.shutdownOutput(); + // 读取服务端返回数据 + in = socket.getInputStream(); + in.read(data); + } catch (Exception e) { + e.printStackTrace(); + } finally { + IOUtils.closeQuietly(in); + IOUtils.closeQuietly(out); + IOUtils.closeQuietly(socket); + } + return data; + } + + private static int code = 0; + + public static void main(String[] args) { +// byte[] dd = sendMessage("192.168.5.211",6001,"090300000002C543"); + + String dateStr = new SimpleDateFormat("yyMMddHHmmssSSS").format(new Date()); + //String dd = dateStr + String.format("%04d",++code); + + System.out.println(dateStr); + } + + /** + * 返回由字节数组转换来的 16 位有符号整数 + * + * @param bytes 字节数组 + * @return 由两个字节构成的 16 位有符号整数 + */ + public static short toShort(byte[] bytes) { + return (short) ((0xff & bytes[0]) | (0xff00 & (bytes[1] << 8))); + + } + + + public static byte[] hexString2Bytes(String hex) { + if ((hex == null) || (hex.equals(""))) { + return null; + } else if (hex.length() % 2 != 0) { + return null; + } else { + hex = hex.toUpperCase(); + int len = hex.length() / 2; + byte[] b = new byte[len]; + char[] hc = hex.toCharArray(); + for (int i = 0; i < len; i++) { + int p = 2 * i; + b[i] = (byte) (charToByte(hc[p]) << 4 | charToByte(hc[p + 1])); + } + return b; + } + } + + private static byte charToByte(char c) { + return (byte) "0123456789ABCDEF".indexOf(c); + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java b/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java new file mode 100644 index 0000000..9b4155c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java @@ -0,0 +1,105 @@ +package com.casic.missiles.modular.util; + +import org.springframework.stereotype.Component; + +import javax.websocket.OnClose; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.PathParam; +import javax.websocket.server.ServerEndpoint; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CopyOnWriteArraySet; + +/** + * @Description: 此注解相当于设置访问URL + * @Author: wangpeng + * @Date: 2022/7/17 11:48 + */ +@Component +@ServerEndpoint("/websocket/{userId}") +public class WebSocket { + private Session session; + + private static CopyOnWriteArraySet webSockets = new CopyOnWriteArraySet<>(); + private static Map sessionPool = new HashMap(); + + @OnOpen + public void onOpen(Session session, @PathParam(value = "userId") String userId) { + this.session = session; + webSockets.add(this); + sessionPool.put(userId, session); + System.out.println(userId + "【websocket消息】有新的连接,总数为:" + webSockets.size()); + } + + @OnClose + public void onClose() { + webSockets.remove(this); + System.out.println("【websocket消息】连接断开,总数为:" + webSockets.size()); + } + + @OnMessage + public void onMessage(String message) { + System.out.println("【websocket消息】收到客户端消息:" + message); + } + + // 此为广播消息 + public void sendAllMessage(String message) { + for (WebSocket webSocket : webSockets) { + System.out.println("【websocket消息】广播消息:" + message); + try { + webSocket.session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + // 发送列表消息 + public void sendListMessage(List userIds, String message) { + System.out.println("【websocket消息】列表消息:" + message); + for (String userId : userIds) { + Session session = sessionPool.get(userId); + if (session != null) { + try { + session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + + // 发送列表消息 + +// public void sendListMessage(List userIds, Object data){ +// System.out.println("【websocket消息】列表消息:"+data); +// for (String userId : userIds) { +// Session session = sessionPool.get(userId); +// if (session != null) { +// try { +//// session.getAsyncRemote().sendText(message); +// session.getAsyncRemote().sendObject(data); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// } +// } + + // 此为单点消息 + public void sendOneMessage(String userId, String message) { + System.out.println("【websocket消息】单点消息:" + message); + Session session = sessionPool.get(userId); + if (session != null) { + try { + session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java new file mode 100644 index 0000000..0c1f5f1 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java @@ -0,0 +1,115 @@ +package com.casic.missiles.modular.util; + +import org.springframework.web.multipart.MultipartFile; + +import java.io.*; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipInputStream; + +/** + * @Description: 读取zip文件内容 + * @Author: wangpeng + * @Date: 2022/7/17 11:48 + */ +public class ZipFileUtil { + public static List getFile(String fileName) { + File file = new File(fileName); + ZipFile zipFile = null; + ZipInputStream zin = null; + FileInputStream fis = null; + List selectDTOList = new ArrayList<>(); + try { + Charset gbk = Charset.forName("GBK"); + zipFile = new ZipFile(file, gbk); + fis = new FileInputStream(file); + zin = new ZipInputStream(fis, gbk); + + ZipEntry ze = null; + while ((ze = zin.getNextEntry()) != null) { + String path = ze.getName(); + System.out.println(path); + if (!ze.isDirectory()) { + InputStream inputStream = zipFile.getInputStream(ze); + String base64Photo = Base64Util.getBase64FromInputStream(inputStream); +// List texts = IOUtils.readLines(inputStream); +// for (String text : texts) { +// System.out.println(" " + text); +// } + selectDTOList.add(new SelectDTO(path.substring(path.indexOf("/")+1), "data:image/png;base64,"+base64Photo)); + inputStream.close(); + } + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (zin != null) { + zin.closeEntry(); + zin.close(); + } + if (fis != null) + fis.close(); + if (zipFile != null) + zipFile.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return selectDTOList; + } + + + /** + * MultipartFile 转 File + * + * @param file + * @throws Exception + */ + public static File multipartFileToFile(MultipartFile file) throws Exception { + + File toFile = null; + if (file.equals("") || file.getSize() <= 0) { + file = null; + } else { + InputStream ins = null; + ins = file.getInputStream(); + toFile = new File(file.getOriginalFilename()); + inputStreamToFile(ins, toFile); + ins.close(); + } + return toFile; + } + + //获取流文件 + private static void inputStreamToFile(InputStream ins, File file) { + try { + OutputStream os = new FileOutputStream(file); + int bytesRead = 0; + byte[] buffer = new byte[8192]; + while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) { + os.write(buffer, 0, bytesRead); + } + os.close(); + ins.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 删除本地临时文件 + * + * @param file + */ + public static void delteTempFile(File file) { + if (file != null) { + File del = new File(file.toURI()); + del.delete(); + } + } +} + diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java new file mode 100644 index 0000000..ae93a17 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java @@ -0,0 +1,34 @@ +package com.casic.missiles.modular.util.netty; + +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.EventLoop; +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.TimeUnit; + +/** + * 负责监听启动时连接失败,重新连接功能 + * + */ +@Slf4j +public class ConnectionListener implements ChannelFutureListener { + + private NettyClient client = new NettyClient(); + + @Override + public void operationComplete(ChannelFuture channelFuture) throws Exception { + if (!channelFuture.isSuccess()) { + final EventLoop loop = channelFuture.channel().eventLoop(); + loop.schedule(new Runnable() { + @Override + public void run() { + log.info("服务端连接不上,开始重连操作..."); + client.connect(); + } + }, 5L, TimeUnit.MINUTES); + } else { + log.info("服务端连接成功..."); + } + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java new file mode 100644 index 0000000..ef9ae76 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java @@ -0,0 +1,66 @@ +package com.casic.missiles.modular.util.netty; + +import io.netty.bootstrap.Bootstrap; +import io.netty.channel.*; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioSocketChannel; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public class NettyClient { + + private static Channel channel; + + private String fenceServiceHost = "127.0.0.1"; + private Integer fenceServicePort = 9200; + + public Channel connect() { + doConnect(fenceServiceHost, fenceServicePort); + return channel; + } + + public Channel connect(String host, int port) { + doConnect(host, port); + return channel; + } + + private void doConnect(String host, int port) { + EventLoopGroup workerGroup = new NioEventLoopGroup(); + try { + Bootstrap b = new Bootstrap(); + b.group(workerGroup); + b.channel(NioSocketChannel.class); + b.option(ChannelOption.SO_KEEPALIVE, true); + b.option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(1024 * 1024)); + + b.handler(new ChannelInitializer() { + @Override + public void initChannel(SocketChannel ch) throws Exception { + + ch.pipeline().addLast("decoder", new StringDecoder()); + ch.pipeline().addLast("encoder", new StringEncoder()); + ch.pipeline().addLast(new NettyClientHandler()); + } + }); + + ChannelFuture f = b.connect(host, port); + f.addListener(new ConnectionListener()); + channel = f.channel(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static void writeAndFlush(String message) { + + if (channel != null) { + channel.writeAndFlush(message); + System.out.println("电子围栏客户端发送消息:" + message); + } + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClientHandler.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClientHandler.java new file mode 100644 index 0000000..28093f0 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClientHandler.java @@ -0,0 +1,62 @@ +package com.casic.missiles.modular.util.netty; + +import com.casic.missiles.modular.util.HttpUtil; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import io.netty.channel.EventLoop; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; + +import java.util.concurrent.TimeUnit; + +/** + * 客户端处理器 + **/ +@Slf4j +@Component +public class NettyClientHandler extends ChannelInboundHandlerAdapter { + static boolean handle = true; + + private NettyClient client = new NettyClient(); + + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + log.info("连接成功....."); + } + + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + log.info("断开连接....."); + + //使用过程中断线重连 + final EventLoop eventLoop = ctx.channel().eventLoop(); + eventLoop.schedule(new Runnable() { + @Override + public void run() { + client.connect(); + } + }, 5L, TimeUnit.SECONDS); + super.channelInactive(ctx); + } + + + @Override + public void channelRead(ChannelHandlerContext ctx, Object message) throws Exception { + + if (handle) { + MultiValueMap map = new LinkedMultiValueMap<>(); + map.add("message", message.toString()); + HttpUtil.post("http://127.0.0.1:20311/data/addPerimeterAlarm", map); + } + handle = !handle; + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + cause.printStackTrace(); + ctx.close(); + } +} + diff --git a/casic-web/pom.xml b/casic-web/pom.xml new file mode 100644 index 0000000..8fb0b2c --- /dev/null +++ b/casic-web/pom.xml @@ -0,0 +1,171 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + ../pom.xml + 2.0.0 + + casic-web + 2.0.0 + jar + casic-web + casic web启动入口 + + + + dev + + true + + + dev + + + + test + + test + + + + prod + + prod + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + io.micrometer + micrometer-core + + + + + org.springframework.boot + spring-boot-starter-jdbc + + + + com.casic + casic-core + ${core.version} + + + com.casic + casic-admin-core + ${admin.version} + + + io.springfox + springfox-swagger-ui + + + + + com.casic + casic-admin-support + ${admin.version} + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.dameng + DmJdbcDriver18 + 1.8 + + + com.casic + casic-area-starter + ${admin.version} + + + + com.casic + casic-server + ${pro.version} + + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + + + org.apache.maven.plugins + maven-jar-plugin + ${maven.jar.plugin.version} + + + + /config/*-*.yml + **/MockController.class + + + + com.casic.missiles.CasicApplication + true + ./ + + + + + + org.apache.maven.plugins + maven-assembly-plugin + ${maven.assembly.plugin.version} + + + make-assembly + package + + single + + + + + + org.apache.maven.plugins + maven-war-plugin + ${maven.war.plugin.version} + + + + + src/main/resources + + + /config/*/* + /config/*-*.yml + + true + + + src/main/java + + **/*.xml + + true + + + + \ No newline at end of file diff --git a/casic-web/src/main/build/bin/start.bat b/casic-web/src/main/build/bin/start.bat new file mode 100644 index 0000000..1db4e88 --- /dev/null +++ b/casic-web/src/main/build/bin/start.bat @@ -0,0 +1,4 @@ +@echo off +title ${project.build.finalName} +java -jar ./lib/${project.build.finalName}.jar +@pause diff --git a/casic-web/src/main/build/bin/start.sh b/casic-web/src/main/build/bin/start.sh new file mode 100644 index 0000000..c00b1ef --- /dev/null +++ b/casic-web/src/main/build/bin/start.sh @@ -0,0 +1,2 @@ +java -jar ./lib/${project.build.finalName}.jar + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9e20bc1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea/ +**/target/** +logs/ +*.iml diff --git a/README.md b/README.md new file mode 100644 index 0000000..2fdcd74 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# casic项目 V2.0.0 + +[^_^]: # (Talk is cheap,Show me the code!) + +## 介绍 +基于SpringBoot,致力于做更简洁的后台管理系统,完美整合springboot2.4 + shiro + mybatis-plus ! +基于casic项目代码简洁,注释丰富,上手容易,同时包含许多基础模块(用户管理,角色管理,部门管理,字典管理等10个模块) +可以直接作为一个后台管理系统的脚手架! 2022目标 `更简洁`,`更规范`! + + +#### 其他 +>* [git地址](http://192.168.0.203:8080/gitbucket) +>* [本地免登地址](http://localhost:8083/route/mockToken) diff --git a/casic-server/pom.xml b/casic-server/pom.xml new file mode 100644 index 0000000..c150a12 --- /dev/null +++ b/casic-server/pom.xml @@ -0,0 +1,70 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + 2.0.0 + ../pom.xml + + + casic-server + 2.0.0 + jar + casic-server + casic 的spring boot版本 + + + + + com.casic + casic-core + ${core.version} + provided + + + com.casic + casic-admin-support + ${admin.version} + provided + + + org.springframework.boot + spring-boot-starter-web + ${boot.version} + provided + + + + + com.hikvision.ga + artemis-http-client + 1.1.3 + + + commons-io + commons-io + + + org.springframework.boot + spring-boot-starter-websocket + 2.4.5 + + + io.netty + netty-all + 4.1.42.Final + + + + + + src/main/java + + **/*.xml + + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java new file mode 100644 index 0000000..3a60b9e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java @@ -0,0 +1,36 @@ +package com.casic.missiles.modular.async; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.TaskExecutor; +import org.springframework.scheduling.annotation.AsyncConfigurer; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadPoolExecutor; + +@Configuration +@EnableAsync +public class AsyncConfig implements AsyncConfigurer { + @Override + public Executor getAsyncExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + //核心线程数 + executor.setCorePoolSize(5); + //最大线程数 + executor.setMaxPoolSize(10); + //队列容量 + executor.setQueueCapacity(20); + //设置线程活跃时间(秒) + executor.setKeepAliveSeconds(60); + //默认线程名称 + executor.setThreadNamePrefix("user-rpt-"); + //拒绝策略 + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + //等待所有任务结束后再关闭线程池 + executor.setWaitForTasksToCompleteOnShutdown(true); + return executor; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java new file mode 100644 index 0000000..8ca554c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java @@ -0,0 +1,18 @@ +package com.casic.missiles.modular.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +// tomcat启动无需配置 +@Configuration +public class WebSocketConfig { + /** + * 注入ServerEndpointExporter, + * 这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint + */ + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java new file mode 100644 index 0000000..34fe2cd --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java @@ -0,0 +1,39 @@ +package com.casic.missiles.modular.controller; + + +import com.casic.missiles.model.application.event.core.EventPublisher; +import com.casic.missiles.model.application.event.enums.ModelEventTypeEnum; +import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.modular.event.UserEvent; +import com.casic.missiles.modular.system.model.User; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +/** + * @Description: DemoController + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@RestController +@RequestMapping("/demo") +public class DemoController { + @Autowired + private EventPublisher publisher; + + /** + * 获取mockToken + */ + @PostMapping("/list") + @ResponseBody + public Object list() { + User user = new User(); + user.setAccount("张三"); + publisher.publishEvent(new UserEvent(ModelEventTypeEnum.ADD, user)); + return ResponseData.success(); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java new file mode 100644 index 0000000..aff2889 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java @@ -0,0 +1,23 @@ +package com.casic.missiles.modular.event; + +import com.casic.missiles.model.application.event.core.ModelEvent; +import com.casic.missiles.model.application.event.type.AbstractEventTypeEnum; +import com.casic.missiles.modular.system.model.User; + +/** + * @Description: 用户事件 + * @Author: wangpeng + * @Date: 2022/7/17 11:23 + */ +public class UserEvent extends ModelEvent { + /** + * Create a new {@code ApplicationEvent}. + * + * @param type 事件类型 + * @param source the object on which the event initially occurred or with + * which the event is associated (never {@code null}) + */ + public UserEvent(AbstractEventTypeEnum type, User source) { + super(type, source); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java new file mode 100644 index 0000000..8f9603e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.core.application.event.UserLoginEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserOneListener { + @EventListener + public void onApplicationEvent(UserLoginEvent event) { + log.debug("用户1订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java new file mode 100644 index 0000000..0bd52a3 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.model.application.event.core.EventSubscriber; +import com.casic.missiles.modular.event.UserEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserTwoListener extends EventSubscriber { + @Override + public void onApplicationEvent(UserEvent event) { + log.debug("用户2订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java new file mode 100644 index 0000000..4012170 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java @@ -0,0 +1,88 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang3.StringUtils; +import sun.misc.BASE64Decoder; + +import java.io.*; + +public class Base64Util { + /** + * base64字符串转换成图片 + * + * @param imgStr base64字符串 + * @param imgFilePath 图片存放路径 + * @return + * @author ZHANGJL + * @dateTime 2018-02-23 14:42:17 + */ + public static boolean Base64ToImage(String imgStr, String imgFilePath, String fileDir) { // 对字节数组字符串进行Base64解码并生成图片 + + if (StringUtils.isEmpty(imgStr)) // 图像数据为空 + return false; + + imgStr = imgStr.substring(imgStr.indexOf(",") + 1); + + BASE64Decoder decoder = new BASE64Decoder(); + try { + // Base64解码 + byte[] b = decoder.decodeBuffer(imgStr); + + for (int i = 0; i < b.length; ++i) { + if (b[i] < 0) {// 调整异常数据 + b[i] += 256; + } + } + //如果已存在图像,先删除 + File file = new File(fileDir+File.separator + imgFilePath); + if (file.exists() && file.isFile()) { + file.delete(); + } + File dir = new File(fileDir); + if (!dir.exists()) { + dir.mkdirs(); + } + file = new File(fileDir+File.separator+imgFilePath); + file.createNewFile(); +// ImageIO.write(bImage, "bmp", name); + OutputStream out = new FileOutputStream(fileDir+File.separator+imgFilePath); + out.write(b); + out.flush(); + out.close(); + + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + + } + + public static String getBase64FromInputStream(InputStream in) { + // 将图片文件转化为字节数组字符串,并对其进行Base64编码处理 + byte[] data = null; + // 读取图片字节数组 + try { + ByteArrayOutputStream swapStream = new ByteArrayOutputStream(); + byte[] buff = new byte[100]; + int rc = 0; + while ((rc = in.read(buff, 0, 100)) > 0) { + swapStream.write(buff, 0, rc); + } + data = swapStream.toByteArray(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return new String(Base64.encodeBase64(data)); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java new file mode 100644 index 0000000..9c93895 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java @@ -0,0 +1,75 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.lang3.StringUtils; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class CommonUtil { + + public static String CutId(String id) { + return id.substring(6, 10) + "-" + id.substring(10, 12) + "-" + id.substring(12, 14); + } + + public static boolean isIDNumber(String IDNumber) { + if (IDNumber == null || "".equals(IDNumber)) { + return false; + } + // 定义判别用户身份证号的正则表达式(15位或者18位,最后一位可以为字母) + String regularExpression = + "(^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|" + + "(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}$)"; + boolean matches = IDNumber.matches(regularExpression); + // 判断第18位校验值 + if (matches) { + if (IDNumber.length() == 18) { + try { + char[] charArray = IDNumber.toCharArray(); + // 前十七位加权因子 + int[] idCardWi = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; + // 这是除以11后,可能产生的11位余数对应的验证码 + String[] idCardY = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"}; + int sum = 0; + for (int i = 0; i < idCardWi.length; i++) { + int current = Integer.parseInt(String.valueOf(charArray[i])); + int count = current * idCardWi[i]; + sum += count; + } + char idCardLast = charArray[17]; + int idCardMod = sum % 11; + if (idCardY[idCardMod].toUpperCase() + .equals(String.valueOf(idCardLast).toUpperCase())) { + return true; + } else { + System.out.println("身份证最后一位:" + String.valueOf(idCardLast).toUpperCase() + + "错误,正确的应该是:" + idCardY[idCardMod].toUpperCase()); + return false; + } + + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } else { + return false; + } + } + return matches; + } + + + public static boolean CheckMobilePhoneNum(String phoneNum) { + if (StringUtils.isEmpty(phoneNum)) + return true; + String regex = "^(1[3-9]\\d{9}$)"; + if (phoneNum.length() == 11) { + Pattern p = Pattern.compile(regex); + Matcher m = p.matcher(phoneNum); + if (m.matches()) { + return true; + } + } + return false; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java new file mode 100644 index 0000000..191ef79 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java @@ -0,0 +1,116 @@ +package com.casic.missiles.modular.util; + + +import javafx.util.Pair; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +/** + * Created by Administrator on 2015/2/25. + */ +public class DateUtils { + public static SimpleDateFormat sdf_day = new SimpleDateFormat("yyyy-MM-dd"); + public static SimpleDateFormat sdf_day_time = new SimpleDateFormat("yyyyMMddhhmmss"); + public static final SimpleDateFormat sdf4 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + public static final SimpleDateFormat sdf5 = new SimpleDateFormat("HH:mm:ss"); + + + /** + * 获取当年的第一天 + * + * @return + */ + public static Date getCurrYearFirst() { + Calendar currCal = Calendar.getInstance(); + int currentYear = currCal.get(Calendar.YEAR); + return getYearFirst(currentYear); + } + + + /** + * 获取某年第一天日期 + * + * @param year 年份 + * @return Date + */ + public static Date getYearFirst(int year) { + Calendar calendar = Calendar.getInstance(); + calendar.clear(); + calendar.set(Calendar.YEAR, year); + Date currYearFirst = calendar.getTime(); + return currYearFirst; + } + + /** + * 最近7日(不包括今日) + */ + public static Pair getLastSevenDays() { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, -7); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 最近n日(不包括今日) + */ + public static Pair getLastNDays(int n) { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, n * -1); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 日期时间加n天 + */ + public static String addDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf4.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf4.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 日期加n天 + */ + public static String addNDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf_day.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf_day.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 昨日 + */ + public static String getYesterday() { + + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.DATE, -2); + return sdf_day.format(calendar.getTime()); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java new file mode 100644 index 0000000..da0f8ee --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java @@ -0,0 +1,49 @@ +package com.casic.missiles.modular.util; + +import com.hikvision.artemis.sdk.ArtemisHttpUtil; +import com.hikvision.artemis.sdk.config.ArtemisConfig; + +import java.util.HashMap; +import java.util.Map; + +public class HikUtil { + + public static String hikApi(String uri, String body) { + + /** + * STEP1:设置平台参数,根据实际情况,设置host appkey appsecret 三个参数. + */ + ArtemisConfig.host = "192.168.1.22:443"; // artemis网关服务器ip端口 + ArtemisConfig.appKey = "25766251"; // 秘钥appkey + ArtemisConfig.appSecret = "h2o6zXtzCmt8eaOaMkXb";// 秘钥appSecret + + /** + * STEP2:设置OpenAPI接口的上下文 + */ + final String ARTEMIS_PATH = "/artemis"; + + /** + * STEP3:设置接口的URI地址 + */ + final String previewURLsApi = ARTEMIS_PATH + uri; + Map path = new HashMap(2) { + { + put("https://", previewURLsApi);//根据现场环境部署确认是http还是https + } + }; + + /** + * STEP4:设置参数提交方式 + */ + String contentType = "application/json"; + + /** + * STEP5:组装请求参数 + */ + /** + * STEP6:调用接口 + */ + String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, contentType, null);// post请求application/json类型参数 + return result; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java new file mode 100644 index 0000000..4867144 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java @@ -0,0 +1,149 @@ +package com.casic.missiles.modular.util; + +import org.springframework.http.*; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; + +/** + * @Description: http请求工具类 + * @Author: wangpeng + * @Date: 2022/7/17 11:49 + */ +public class HttpUtil { + /** + * get请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String get(String url, MultiValueMap params) { + return get(url, params, null); + } + + /** + * get请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String get(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.GET); + } + + /** + * post请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String post(String url, MultiValueMap params) { + return post(url, params, null); + } + + /** + * post请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String post(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.POST); + } + + /** + * put请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String put(String url, MultiValueMap params) { + return put(url, params, null); + } + + /** + * put请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String put(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.PUT); + } + + /** + * delete请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String delete(String url, MultiValueMap params) { + return delete(url, params, null); + } + + /** + * delete请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String delete(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.DELETE); + } + + /** + * 表单请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @param method 请求方式 + * @return + */ + public static String request(String url, MultiValueMap params, MultiValueMap headers, HttpMethod method) { + if (params == null) { + params = new LinkedMultiValueMap<>(); + } + return request(url, params, headers, method, MediaType.APPLICATION_FORM_URLENCODED); + } + + /** + * http请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @param method 请求方式 + * @param mediaType 参数类型 + * @return + */ + public static String request(String url, Object params, MultiValueMap headers, HttpMethod method, MediaType mediaType) { + if (url == null || url.trim().isEmpty()) { + return null; + } + RestTemplate client = new RestTemplate(); + // header + HttpHeaders httpHeaders = new HttpHeaders(); + if (headers != null) { +// httpHeaders.addAll(headers); + httpHeaders.putAll(headers); + } + // 提交方式:表单、json + httpHeaders.setContentType(mediaType); + HttpEntity httpEntity = new HttpEntity(params, httpHeaders); + ResponseEntity response = client.exchange(url, method, httpEntity, String.class); + return response.getBody(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java new file mode 100644 index 0000000..19d8d67 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java @@ -0,0 +1,30 @@ +package com.casic.missiles.modular.util; + +public class SelectDTO { + private String name; + private String value; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public SelectDTO() { + } + + public SelectDTO(String name, String value) { + this.name = name; + this.value = value; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java new file mode 100644 index 0000000..0bd484c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java @@ -0,0 +1,28 @@ +package com.casic.missiles.modular.util; + +public class SocketConst { + + /** + * 新增授权socket前缀 + */ + public static final String SOCKET_PREFIX_ADD_PERMISSION = "addPermission:"; + + /** + * 取消授权socket前缀 + */ + public static final String SOCKET_PREFIX_DELETE_PERMISSION = "deletePermission:"; + + /** + * 人员数据下发socket前缀 + */ + public static final String SOCKET_PREFIX_ADD_PERSON = "addPerson:"; + + /** + * socket返回成功信息 + */ + public static final String SOCKET_SUCCESS_MSG = "ok"; + /** + * 人员数据下发socket前缀 + */ + public static final String SOCKET_PREFIX_DELETE_PERSON = "deletePerson:"; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java new file mode 100644 index 0000000..0452bca --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java @@ -0,0 +1,90 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.io.IOUtils; +import org.springframework.stereotype.Component; + +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.text.SimpleDateFormat; +import java.util.Date; + +@Component +public class SocketUtil { + + public static byte[] sendMessage(String ip, int port, String msg) { + byte[] data = new byte[20]; + + System.out.println("往 " + ip + ":" + port + " 发送数据:" + msg); + InputStream in = null; + OutputStream out = null; + Socket socket = null; + try { + socket = new Socket(); + socket.connect(new InetSocketAddress(ip, port), 1000); + socket.setSoTimeout(2000); + // 向服务端发送数据 + out = socket.getOutputStream(); + out.write(hexString2Bytes(msg)); + out.flush(); + //socket.shutdownOutput(); + // 读取服务端返回数据 + in = socket.getInputStream(); + in.read(data); + } catch (Exception e) { + e.printStackTrace(); + } finally { + IOUtils.closeQuietly(in); + IOUtils.closeQuietly(out); + IOUtils.closeQuietly(socket); + } + return data; + } + + private static int code = 0; + + public static void main(String[] args) { +// byte[] dd = sendMessage("192.168.5.211",6001,"090300000002C543"); + + String dateStr = new SimpleDateFormat("yyMMddHHmmssSSS").format(new Date()); + //String dd = dateStr + String.format("%04d",++code); + + System.out.println(dateStr); + } + + /** + * 返回由字节数组转换来的 16 位有符号整数 + * + * @param bytes 字节数组 + * @return 由两个字节构成的 16 位有符号整数 + */ + public static short toShort(byte[] bytes) { + return (short) ((0xff & bytes[0]) | (0xff00 & (bytes[1] << 8))); + + } + + + public static byte[] hexString2Bytes(String hex) { + if ((hex == null) || (hex.equals(""))) { + return null; + } else if (hex.length() % 2 != 0) { + return null; + } else { + hex = hex.toUpperCase(); + int len = hex.length() / 2; + byte[] b = new byte[len]; + char[] hc = hex.toCharArray(); + for (int i = 0; i < len; i++) { + int p = 2 * i; + b[i] = (byte) (charToByte(hc[p]) << 4 | charToByte(hc[p + 1])); + } + return b; + } + } + + private static byte charToByte(char c) { + return (byte) "0123456789ABCDEF".indexOf(c); + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java b/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java new file mode 100644 index 0000000..9b4155c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java @@ -0,0 +1,105 @@ +package com.casic.missiles.modular.util; + +import org.springframework.stereotype.Component; + +import javax.websocket.OnClose; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.PathParam; +import javax.websocket.server.ServerEndpoint; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CopyOnWriteArraySet; + +/** + * @Description: 此注解相当于设置访问URL + * @Author: wangpeng + * @Date: 2022/7/17 11:48 + */ +@Component +@ServerEndpoint("/websocket/{userId}") +public class WebSocket { + private Session session; + + private static CopyOnWriteArraySet webSockets = new CopyOnWriteArraySet<>(); + private static Map sessionPool = new HashMap(); + + @OnOpen + public void onOpen(Session session, @PathParam(value = "userId") String userId) { + this.session = session; + webSockets.add(this); + sessionPool.put(userId, session); + System.out.println(userId + "【websocket消息】有新的连接,总数为:" + webSockets.size()); + } + + @OnClose + public void onClose() { + webSockets.remove(this); + System.out.println("【websocket消息】连接断开,总数为:" + webSockets.size()); + } + + @OnMessage + public void onMessage(String message) { + System.out.println("【websocket消息】收到客户端消息:" + message); + } + + // 此为广播消息 + public void sendAllMessage(String message) { + for (WebSocket webSocket : webSockets) { + System.out.println("【websocket消息】广播消息:" + message); + try { + webSocket.session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + // 发送列表消息 + public void sendListMessage(List userIds, String message) { + System.out.println("【websocket消息】列表消息:" + message); + for (String userId : userIds) { + Session session = sessionPool.get(userId); + if (session != null) { + try { + session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + + // 发送列表消息 + +// public void sendListMessage(List userIds, Object data){ +// System.out.println("【websocket消息】列表消息:"+data); +// for (String userId : userIds) { +// Session session = sessionPool.get(userId); +// if (session != null) { +// try { +//// session.getAsyncRemote().sendText(message); +// session.getAsyncRemote().sendObject(data); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// } +// } + + // 此为单点消息 + public void sendOneMessage(String userId, String message) { + System.out.println("【websocket消息】单点消息:" + message); + Session session = sessionPool.get(userId); + if (session != null) { + try { + session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java new file mode 100644 index 0000000..0c1f5f1 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java @@ -0,0 +1,115 @@ +package com.casic.missiles.modular.util; + +import org.springframework.web.multipart.MultipartFile; + +import java.io.*; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipInputStream; + +/** + * @Description: 读取zip文件内容 + * @Author: wangpeng + * @Date: 2022/7/17 11:48 + */ +public class ZipFileUtil { + public static List getFile(String fileName) { + File file = new File(fileName); + ZipFile zipFile = null; + ZipInputStream zin = null; + FileInputStream fis = null; + List selectDTOList = new ArrayList<>(); + try { + Charset gbk = Charset.forName("GBK"); + zipFile = new ZipFile(file, gbk); + fis = new FileInputStream(file); + zin = new ZipInputStream(fis, gbk); + + ZipEntry ze = null; + while ((ze = zin.getNextEntry()) != null) { + String path = ze.getName(); + System.out.println(path); + if (!ze.isDirectory()) { + InputStream inputStream = zipFile.getInputStream(ze); + String base64Photo = Base64Util.getBase64FromInputStream(inputStream); +// List texts = IOUtils.readLines(inputStream); +// for (String text : texts) { +// System.out.println(" " + text); +// } + selectDTOList.add(new SelectDTO(path.substring(path.indexOf("/")+1), "data:image/png;base64,"+base64Photo)); + inputStream.close(); + } + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (zin != null) { + zin.closeEntry(); + zin.close(); + } + if (fis != null) + fis.close(); + if (zipFile != null) + zipFile.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return selectDTOList; + } + + + /** + * MultipartFile 转 File + * + * @param file + * @throws Exception + */ + public static File multipartFileToFile(MultipartFile file) throws Exception { + + File toFile = null; + if (file.equals("") || file.getSize() <= 0) { + file = null; + } else { + InputStream ins = null; + ins = file.getInputStream(); + toFile = new File(file.getOriginalFilename()); + inputStreamToFile(ins, toFile); + ins.close(); + } + return toFile; + } + + //获取流文件 + private static void inputStreamToFile(InputStream ins, File file) { + try { + OutputStream os = new FileOutputStream(file); + int bytesRead = 0; + byte[] buffer = new byte[8192]; + while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) { + os.write(buffer, 0, bytesRead); + } + os.close(); + ins.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 删除本地临时文件 + * + * @param file + */ + public static void delteTempFile(File file) { + if (file != null) { + File del = new File(file.toURI()); + del.delete(); + } + } +} + diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java new file mode 100644 index 0000000..ae93a17 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java @@ -0,0 +1,34 @@ +package com.casic.missiles.modular.util.netty; + +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.EventLoop; +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.TimeUnit; + +/** + * 负责监听启动时连接失败,重新连接功能 + * + */ +@Slf4j +public class ConnectionListener implements ChannelFutureListener { + + private NettyClient client = new NettyClient(); + + @Override + public void operationComplete(ChannelFuture channelFuture) throws Exception { + if (!channelFuture.isSuccess()) { + final EventLoop loop = channelFuture.channel().eventLoop(); + loop.schedule(new Runnable() { + @Override + public void run() { + log.info("服务端连接不上,开始重连操作..."); + client.connect(); + } + }, 5L, TimeUnit.MINUTES); + } else { + log.info("服务端连接成功..."); + } + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java new file mode 100644 index 0000000..ef9ae76 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java @@ -0,0 +1,66 @@ +package com.casic.missiles.modular.util.netty; + +import io.netty.bootstrap.Bootstrap; +import io.netty.channel.*; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioSocketChannel; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public class NettyClient { + + private static Channel channel; + + private String fenceServiceHost = "127.0.0.1"; + private Integer fenceServicePort = 9200; + + public Channel connect() { + doConnect(fenceServiceHost, fenceServicePort); + return channel; + } + + public Channel connect(String host, int port) { + doConnect(host, port); + return channel; + } + + private void doConnect(String host, int port) { + EventLoopGroup workerGroup = new NioEventLoopGroup(); + try { + Bootstrap b = new Bootstrap(); + b.group(workerGroup); + b.channel(NioSocketChannel.class); + b.option(ChannelOption.SO_KEEPALIVE, true); + b.option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(1024 * 1024)); + + b.handler(new ChannelInitializer() { + @Override + public void initChannel(SocketChannel ch) throws Exception { + + ch.pipeline().addLast("decoder", new StringDecoder()); + ch.pipeline().addLast("encoder", new StringEncoder()); + ch.pipeline().addLast(new NettyClientHandler()); + } + }); + + ChannelFuture f = b.connect(host, port); + f.addListener(new ConnectionListener()); + channel = f.channel(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static void writeAndFlush(String message) { + + if (channel != null) { + channel.writeAndFlush(message); + System.out.println("电子围栏客户端发送消息:" + message); + } + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClientHandler.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClientHandler.java new file mode 100644 index 0000000..28093f0 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClientHandler.java @@ -0,0 +1,62 @@ +package com.casic.missiles.modular.util.netty; + +import com.casic.missiles.modular.util.HttpUtil; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import io.netty.channel.EventLoop; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; + +import java.util.concurrent.TimeUnit; + +/** + * 客户端处理器 + **/ +@Slf4j +@Component +public class NettyClientHandler extends ChannelInboundHandlerAdapter { + static boolean handle = true; + + private NettyClient client = new NettyClient(); + + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + log.info("连接成功....."); + } + + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + log.info("断开连接....."); + + //使用过程中断线重连 + final EventLoop eventLoop = ctx.channel().eventLoop(); + eventLoop.schedule(new Runnable() { + @Override + public void run() { + client.connect(); + } + }, 5L, TimeUnit.SECONDS); + super.channelInactive(ctx); + } + + + @Override + public void channelRead(ChannelHandlerContext ctx, Object message) throws Exception { + + if (handle) { + MultiValueMap map = new LinkedMultiValueMap<>(); + map.add("message", message.toString()); + HttpUtil.post("http://127.0.0.1:20311/data/addPerimeterAlarm", map); + } + handle = !handle; + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + cause.printStackTrace(); + ctx.close(); + } +} + diff --git a/casic-web/pom.xml b/casic-web/pom.xml new file mode 100644 index 0000000..8fb0b2c --- /dev/null +++ b/casic-web/pom.xml @@ -0,0 +1,171 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + ../pom.xml + 2.0.0 + + casic-web + 2.0.0 + jar + casic-web + casic web启动入口 + + + + dev + + true + + + dev + + + + test + + test + + + + prod + + prod + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + io.micrometer + micrometer-core + + + + + org.springframework.boot + spring-boot-starter-jdbc + + + + com.casic + casic-core + ${core.version} + + + com.casic + casic-admin-core + ${admin.version} + + + io.springfox + springfox-swagger-ui + + + + + com.casic + casic-admin-support + ${admin.version} + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.dameng + DmJdbcDriver18 + 1.8 + + + com.casic + casic-area-starter + ${admin.version} + + + + com.casic + casic-server + ${pro.version} + + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + + + org.apache.maven.plugins + maven-jar-plugin + ${maven.jar.plugin.version} + + + + /config/*-*.yml + **/MockController.class + + + + com.casic.missiles.CasicApplication + true + ./ + + + + + + org.apache.maven.plugins + maven-assembly-plugin + ${maven.assembly.plugin.version} + + + make-assembly + package + + single + + + + + + org.apache.maven.plugins + maven-war-plugin + ${maven.war.plugin.version} + + + + + src/main/resources + + + /config/*/* + /config/*-*.yml + + true + + + src/main/java + + **/*.xml + + true + + + + \ No newline at end of file diff --git a/casic-web/src/main/build/bin/start.bat b/casic-web/src/main/build/bin/start.bat new file mode 100644 index 0000000..1db4e88 --- /dev/null +++ b/casic-web/src/main/build/bin/start.bat @@ -0,0 +1,4 @@ +@echo off +title ${project.build.finalName} +java -jar ./lib/${project.build.finalName}.jar +@pause diff --git a/casic-web/src/main/build/bin/start.sh b/casic-web/src/main/build/bin/start.sh new file mode 100644 index 0000000..c00b1ef --- /dev/null +++ b/casic-web/src/main/build/bin/start.sh @@ -0,0 +1,2 @@ +java -jar ./lib/${project.build.finalName}.jar + diff --git a/casic-web/src/main/build/package.xml b/casic-web/src/main/build/package.xml new file mode 100644 index 0000000..c9259ad --- /dev/null +++ b/casic-web/src/main/build/package.xml @@ -0,0 +1,43 @@ + + + package + + zip + tar.gz + + true + + + + true + true + lib + runtime + + + + + src/main/build/bin + + start.bat + start.sh + + true + 0744 + / + + + src/main/resources/config + true + + *.yml + /*/* + + /config + + + src/main/resources/i18n + / + + + \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9e20bc1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea/ +**/target/** +logs/ +*.iml diff --git a/README.md b/README.md new file mode 100644 index 0000000..2fdcd74 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# casic项目 V2.0.0 + +[^_^]: # (Talk is cheap,Show me the code!) + +## 介绍 +基于SpringBoot,致力于做更简洁的后台管理系统,完美整合springboot2.4 + shiro + mybatis-plus ! +基于casic项目代码简洁,注释丰富,上手容易,同时包含许多基础模块(用户管理,角色管理,部门管理,字典管理等10个模块) +可以直接作为一个后台管理系统的脚手架! 2022目标 `更简洁`,`更规范`! + + +#### 其他 +>* [git地址](http://192.168.0.203:8080/gitbucket) +>* [本地免登地址](http://localhost:8083/route/mockToken) diff --git a/casic-server/pom.xml b/casic-server/pom.xml new file mode 100644 index 0000000..c150a12 --- /dev/null +++ b/casic-server/pom.xml @@ -0,0 +1,70 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + 2.0.0 + ../pom.xml + + + casic-server + 2.0.0 + jar + casic-server + casic 的spring boot版本 + + + + + com.casic + casic-core + ${core.version} + provided + + + com.casic + casic-admin-support + ${admin.version} + provided + + + org.springframework.boot + spring-boot-starter-web + ${boot.version} + provided + + + + + com.hikvision.ga + artemis-http-client + 1.1.3 + + + commons-io + commons-io + + + org.springframework.boot + spring-boot-starter-websocket + 2.4.5 + + + io.netty + netty-all + 4.1.42.Final + + + + + + src/main/java + + **/*.xml + + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java new file mode 100644 index 0000000..3a60b9e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java @@ -0,0 +1,36 @@ +package com.casic.missiles.modular.async; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.TaskExecutor; +import org.springframework.scheduling.annotation.AsyncConfigurer; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadPoolExecutor; + +@Configuration +@EnableAsync +public class AsyncConfig implements AsyncConfigurer { + @Override + public Executor getAsyncExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + //核心线程数 + executor.setCorePoolSize(5); + //最大线程数 + executor.setMaxPoolSize(10); + //队列容量 + executor.setQueueCapacity(20); + //设置线程活跃时间(秒) + executor.setKeepAliveSeconds(60); + //默认线程名称 + executor.setThreadNamePrefix("user-rpt-"); + //拒绝策略 + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + //等待所有任务结束后再关闭线程池 + executor.setWaitForTasksToCompleteOnShutdown(true); + return executor; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java new file mode 100644 index 0000000..8ca554c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java @@ -0,0 +1,18 @@ +package com.casic.missiles.modular.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +// tomcat启动无需配置 +@Configuration +public class WebSocketConfig { + /** + * 注入ServerEndpointExporter, + * 这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint + */ + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java new file mode 100644 index 0000000..34fe2cd --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java @@ -0,0 +1,39 @@ +package com.casic.missiles.modular.controller; + + +import com.casic.missiles.model.application.event.core.EventPublisher; +import com.casic.missiles.model.application.event.enums.ModelEventTypeEnum; +import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.modular.event.UserEvent; +import com.casic.missiles.modular.system.model.User; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +/** + * @Description: DemoController + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@RestController +@RequestMapping("/demo") +public class DemoController { + @Autowired + private EventPublisher publisher; + + /** + * 获取mockToken + */ + @PostMapping("/list") + @ResponseBody + public Object list() { + User user = new User(); + user.setAccount("张三"); + publisher.publishEvent(new UserEvent(ModelEventTypeEnum.ADD, user)); + return ResponseData.success(); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java new file mode 100644 index 0000000..aff2889 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java @@ -0,0 +1,23 @@ +package com.casic.missiles.modular.event; + +import com.casic.missiles.model.application.event.core.ModelEvent; +import com.casic.missiles.model.application.event.type.AbstractEventTypeEnum; +import com.casic.missiles.modular.system.model.User; + +/** + * @Description: 用户事件 + * @Author: wangpeng + * @Date: 2022/7/17 11:23 + */ +public class UserEvent extends ModelEvent { + /** + * Create a new {@code ApplicationEvent}. + * + * @param type 事件类型 + * @param source the object on which the event initially occurred or with + * which the event is associated (never {@code null}) + */ + public UserEvent(AbstractEventTypeEnum type, User source) { + super(type, source); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java new file mode 100644 index 0000000..8f9603e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.core.application.event.UserLoginEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserOneListener { + @EventListener + public void onApplicationEvent(UserLoginEvent event) { + log.debug("用户1订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java new file mode 100644 index 0000000..0bd52a3 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.model.application.event.core.EventSubscriber; +import com.casic.missiles.modular.event.UserEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserTwoListener extends EventSubscriber { + @Override + public void onApplicationEvent(UserEvent event) { + log.debug("用户2订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java new file mode 100644 index 0000000..4012170 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java @@ -0,0 +1,88 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang3.StringUtils; +import sun.misc.BASE64Decoder; + +import java.io.*; + +public class Base64Util { + /** + * base64字符串转换成图片 + * + * @param imgStr base64字符串 + * @param imgFilePath 图片存放路径 + * @return + * @author ZHANGJL + * @dateTime 2018-02-23 14:42:17 + */ + public static boolean Base64ToImage(String imgStr, String imgFilePath, String fileDir) { // 对字节数组字符串进行Base64解码并生成图片 + + if (StringUtils.isEmpty(imgStr)) // 图像数据为空 + return false; + + imgStr = imgStr.substring(imgStr.indexOf(",") + 1); + + BASE64Decoder decoder = new BASE64Decoder(); + try { + // Base64解码 + byte[] b = decoder.decodeBuffer(imgStr); + + for (int i = 0; i < b.length; ++i) { + if (b[i] < 0) {// 调整异常数据 + b[i] += 256; + } + } + //如果已存在图像,先删除 + File file = new File(fileDir+File.separator + imgFilePath); + if (file.exists() && file.isFile()) { + file.delete(); + } + File dir = new File(fileDir); + if (!dir.exists()) { + dir.mkdirs(); + } + file = new File(fileDir+File.separator+imgFilePath); + file.createNewFile(); +// ImageIO.write(bImage, "bmp", name); + OutputStream out = new FileOutputStream(fileDir+File.separator+imgFilePath); + out.write(b); + out.flush(); + out.close(); + + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + + } + + public static String getBase64FromInputStream(InputStream in) { + // 将图片文件转化为字节数组字符串,并对其进行Base64编码处理 + byte[] data = null; + // 读取图片字节数组 + try { + ByteArrayOutputStream swapStream = new ByteArrayOutputStream(); + byte[] buff = new byte[100]; + int rc = 0; + while ((rc = in.read(buff, 0, 100)) > 0) { + swapStream.write(buff, 0, rc); + } + data = swapStream.toByteArray(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return new String(Base64.encodeBase64(data)); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java new file mode 100644 index 0000000..9c93895 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java @@ -0,0 +1,75 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.lang3.StringUtils; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class CommonUtil { + + public static String CutId(String id) { + return id.substring(6, 10) + "-" + id.substring(10, 12) + "-" + id.substring(12, 14); + } + + public static boolean isIDNumber(String IDNumber) { + if (IDNumber == null || "".equals(IDNumber)) { + return false; + } + // 定义判别用户身份证号的正则表达式(15位或者18位,最后一位可以为字母) + String regularExpression = + "(^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|" + + "(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}$)"; + boolean matches = IDNumber.matches(regularExpression); + // 判断第18位校验值 + if (matches) { + if (IDNumber.length() == 18) { + try { + char[] charArray = IDNumber.toCharArray(); + // 前十七位加权因子 + int[] idCardWi = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; + // 这是除以11后,可能产生的11位余数对应的验证码 + String[] idCardY = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"}; + int sum = 0; + for (int i = 0; i < idCardWi.length; i++) { + int current = Integer.parseInt(String.valueOf(charArray[i])); + int count = current * idCardWi[i]; + sum += count; + } + char idCardLast = charArray[17]; + int idCardMod = sum % 11; + if (idCardY[idCardMod].toUpperCase() + .equals(String.valueOf(idCardLast).toUpperCase())) { + return true; + } else { + System.out.println("身份证最后一位:" + String.valueOf(idCardLast).toUpperCase() + + "错误,正确的应该是:" + idCardY[idCardMod].toUpperCase()); + return false; + } + + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } else { + return false; + } + } + return matches; + } + + + public static boolean CheckMobilePhoneNum(String phoneNum) { + if (StringUtils.isEmpty(phoneNum)) + return true; + String regex = "^(1[3-9]\\d{9}$)"; + if (phoneNum.length() == 11) { + Pattern p = Pattern.compile(regex); + Matcher m = p.matcher(phoneNum); + if (m.matches()) { + return true; + } + } + return false; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java new file mode 100644 index 0000000..191ef79 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java @@ -0,0 +1,116 @@ +package com.casic.missiles.modular.util; + + +import javafx.util.Pair; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +/** + * Created by Administrator on 2015/2/25. + */ +public class DateUtils { + public static SimpleDateFormat sdf_day = new SimpleDateFormat("yyyy-MM-dd"); + public static SimpleDateFormat sdf_day_time = new SimpleDateFormat("yyyyMMddhhmmss"); + public static final SimpleDateFormat sdf4 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + public static final SimpleDateFormat sdf5 = new SimpleDateFormat("HH:mm:ss"); + + + /** + * 获取当年的第一天 + * + * @return + */ + public static Date getCurrYearFirst() { + Calendar currCal = Calendar.getInstance(); + int currentYear = currCal.get(Calendar.YEAR); + return getYearFirst(currentYear); + } + + + /** + * 获取某年第一天日期 + * + * @param year 年份 + * @return Date + */ + public static Date getYearFirst(int year) { + Calendar calendar = Calendar.getInstance(); + calendar.clear(); + calendar.set(Calendar.YEAR, year); + Date currYearFirst = calendar.getTime(); + return currYearFirst; + } + + /** + * 最近7日(不包括今日) + */ + public static Pair getLastSevenDays() { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, -7); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 最近n日(不包括今日) + */ + public static Pair getLastNDays(int n) { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, n * -1); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 日期时间加n天 + */ + public static String addDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf4.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf4.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 日期加n天 + */ + public static String addNDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf_day.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf_day.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 昨日 + */ + public static String getYesterday() { + + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.DATE, -2); + return sdf_day.format(calendar.getTime()); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java new file mode 100644 index 0000000..da0f8ee --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java @@ -0,0 +1,49 @@ +package com.casic.missiles.modular.util; + +import com.hikvision.artemis.sdk.ArtemisHttpUtil; +import com.hikvision.artemis.sdk.config.ArtemisConfig; + +import java.util.HashMap; +import java.util.Map; + +public class HikUtil { + + public static String hikApi(String uri, String body) { + + /** + * STEP1:设置平台参数,根据实际情况,设置host appkey appsecret 三个参数. + */ + ArtemisConfig.host = "192.168.1.22:443"; // artemis网关服务器ip端口 + ArtemisConfig.appKey = "25766251"; // 秘钥appkey + ArtemisConfig.appSecret = "h2o6zXtzCmt8eaOaMkXb";// 秘钥appSecret + + /** + * STEP2:设置OpenAPI接口的上下文 + */ + final String ARTEMIS_PATH = "/artemis"; + + /** + * STEP3:设置接口的URI地址 + */ + final String previewURLsApi = ARTEMIS_PATH + uri; + Map path = new HashMap(2) { + { + put("https://", previewURLsApi);//根据现场环境部署确认是http还是https + } + }; + + /** + * STEP4:设置参数提交方式 + */ + String contentType = "application/json"; + + /** + * STEP5:组装请求参数 + */ + /** + * STEP6:调用接口 + */ + String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, contentType, null);// post请求application/json类型参数 + return result; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java new file mode 100644 index 0000000..4867144 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java @@ -0,0 +1,149 @@ +package com.casic.missiles.modular.util; + +import org.springframework.http.*; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; + +/** + * @Description: http请求工具类 + * @Author: wangpeng + * @Date: 2022/7/17 11:49 + */ +public class HttpUtil { + /** + * get请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String get(String url, MultiValueMap params) { + return get(url, params, null); + } + + /** + * get请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String get(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.GET); + } + + /** + * post请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String post(String url, MultiValueMap params) { + return post(url, params, null); + } + + /** + * post请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String post(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.POST); + } + + /** + * put请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String put(String url, MultiValueMap params) { + return put(url, params, null); + } + + /** + * put请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String put(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.PUT); + } + + /** + * delete请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String delete(String url, MultiValueMap params) { + return delete(url, params, null); + } + + /** + * delete请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String delete(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.DELETE); + } + + /** + * 表单请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @param method 请求方式 + * @return + */ + public static String request(String url, MultiValueMap params, MultiValueMap headers, HttpMethod method) { + if (params == null) { + params = new LinkedMultiValueMap<>(); + } + return request(url, params, headers, method, MediaType.APPLICATION_FORM_URLENCODED); + } + + /** + * http请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @param method 请求方式 + * @param mediaType 参数类型 + * @return + */ + public static String request(String url, Object params, MultiValueMap headers, HttpMethod method, MediaType mediaType) { + if (url == null || url.trim().isEmpty()) { + return null; + } + RestTemplate client = new RestTemplate(); + // header + HttpHeaders httpHeaders = new HttpHeaders(); + if (headers != null) { +// httpHeaders.addAll(headers); + httpHeaders.putAll(headers); + } + // 提交方式:表单、json + httpHeaders.setContentType(mediaType); + HttpEntity httpEntity = new HttpEntity(params, httpHeaders); + ResponseEntity response = client.exchange(url, method, httpEntity, String.class); + return response.getBody(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java new file mode 100644 index 0000000..19d8d67 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java @@ -0,0 +1,30 @@ +package com.casic.missiles.modular.util; + +public class SelectDTO { + private String name; + private String value; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public SelectDTO() { + } + + public SelectDTO(String name, String value) { + this.name = name; + this.value = value; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java new file mode 100644 index 0000000..0bd484c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java @@ -0,0 +1,28 @@ +package com.casic.missiles.modular.util; + +public class SocketConst { + + /** + * 新增授权socket前缀 + */ + public static final String SOCKET_PREFIX_ADD_PERMISSION = "addPermission:"; + + /** + * 取消授权socket前缀 + */ + public static final String SOCKET_PREFIX_DELETE_PERMISSION = "deletePermission:"; + + /** + * 人员数据下发socket前缀 + */ + public static final String SOCKET_PREFIX_ADD_PERSON = "addPerson:"; + + /** + * socket返回成功信息 + */ + public static final String SOCKET_SUCCESS_MSG = "ok"; + /** + * 人员数据下发socket前缀 + */ + public static final String SOCKET_PREFIX_DELETE_PERSON = "deletePerson:"; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java new file mode 100644 index 0000000..0452bca --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java @@ -0,0 +1,90 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.io.IOUtils; +import org.springframework.stereotype.Component; + +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.text.SimpleDateFormat; +import java.util.Date; + +@Component +public class SocketUtil { + + public static byte[] sendMessage(String ip, int port, String msg) { + byte[] data = new byte[20]; + + System.out.println("往 " + ip + ":" + port + " 发送数据:" + msg); + InputStream in = null; + OutputStream out = null; + Socket socket = null; + try { + socket = new Socket(); + socket.connect(new InetSocketAddress(ip, port), 1000); + socket.setSoTimeout(2000); + // 向服务端发送数据 + out = socket.getOutputStream(); + out.write(hexString2Bytes(msg)); + out.flush(); + //socket.shutdownOutput(); + // 读取服务端返回数据 + in = socket.getInputStream(); + in.read(data); + } catch (Exception e) { + e.printStackTrace(); + } finally { + IOUtils.closeQuietly(in); + IOUtils.closeQuietly(out); + IOUtils.closeQuietly(socket); + } + return data; + } + + private static int code = 0; + + public static void main(String[] args) { +// byte[] dd = sendMessage("192.168.5.211",6001,"090300000002C543"); + + String dateStr = new SimpleDateFormat("yyMMddHHmmssSSS").format(new Date()); + //String dd = dateStr + String.format("%04d",++code); + + System.out.println(dateStr); + } + + /** + * 返回由字节数组转换来的 16 位有符号整数 + * + * @param bytes 字节数组 + * @return 由两个字节构成的 16 位有符号整数 + */ + public static short toShort(byte[] bytes) { + return (short) ((0xff & bytes[0]) | (0xff00 & (bytes[1] << 8))); + + } + + + public static byte[] hexString2Bytes(String hex) { + if ((hex == null) || (hex.equals(""))) { + return null; + } else if (hex.length() % 2 != 0) { + return null; + } else { + hex = hex.toUpperCase(); + int len = hex.length() / 2; + byte[] b = new byte[len]; + char[] hc = hex.toCharArray(); + for (int i = 0; i < len; i++) { + int p = 2 * i; + b[i] = (byte) (charToByte(hc[p]) << 4 | charToByte(hc[p + 1])); + } + return b; + } + } + + private static byte charToByte(char c) { + return (byte) "0123456789ABCDEF".indexOf(c); + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java b/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java new file mode 100644 index 0000000..9b4155c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java @@ -0,0 +1,105 @@ +package com.casic.missiles.modular.util; + +import org.springframework.stereotype.Component; + +import javax.websocket.OnClose; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.PathParam; +import javax.websocket.server.ServerEndpoint; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CopyOnWriteArraySet; + +/** + * @Description: 此注解相当于设置访问URL + * @Author: wangpeng + * @Date: 2022/7/17 11:48 + */ +@Component +@ServerEndpoint("/websocket/{userId}") +public class WebSocket { + private Session session; + + private static CopyOnWriteArraySet webSockets = new CopyOnWriteArraySet<>(); + private static Map sessionPool = new HashMap(); + + @OnOpen + public void onOpen(Session session, @PathParam(value = "userId") String userId) { + this.session = session; + webSockets.add(this); + sessionPool.put(userId, session); + System.out.println(userId + "【websocket消息】有新的连接,总数为:" + webSockets.size()); + } + + @OnClose + public void onClose() { + webSockets.remove(this); + System.out.println("【websocket消息】连接断开,总数为:" + webSockets.size()); + } + + @OnMessage + public void onMessage(String message) { + System.out.println("【websocket消息】收到客户端消息:" + message); + } + + // 此为广播消息 + public void sendAllMessage(String message) { + for (WebSocket webSocket : webSockets) { + System.out.println("【websocket消息】广播消息:" + message); + try { + webSocket.session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + // 发送列表消息 + public void sendListMessage(List userIds, String message) { + System.out.println("【websocket消息】列表消息:" + message); + for (String userId : userIds) { + Session session = sessionPool.get(userId); + if (session != null) { + try { + session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + + // 发送列表消息 + +// public void sendListMessage(List userIds, Object data){ +// System.out.println("【websocket消息】列表消息:"+data); +// for (String userId : userIds) { +// Session session = sessionPool.get(userId); +// if (session != null) { +// try { +//// session.getAsyncRemote().sendText(message); +// session.getAsyncRemote().sendObject(data); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// } +// } + + // 此为单点消息 + public void sendOneMessage(String userId, String message) { + System.out.println("【websocket消息】单点消息:" + message); + Session session = sessionPool.get(userId); + if (session != null) { + try { + session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java new file mode 100644 index 0000000..0c1f5f1 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java @@ -0,0 +1,115 @@ +package com.casic.missiles.modular.util; + +import org.springframework.web.multipart.MultipartFile; + +import java.io.*; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipInputStream; + +/** + * @Description: 读取zip文件内容 + * @Author: wangpeng + * @Date: 2022/7/17 11:48 + */ +public class ZipFileUtil { + public static List getFile(String fileName) { + File file = new File(fileName); + ZipFile zipFile = null; + ZipInputStream zin = null; + FileInputStream fis = null; + List selectDTOList = new ArrayList<>(); + try { + Charset gbk = Charset.forName("GBK"); + zipFile = new ZipFile(file, gbk); + fis = new FileInputStream(file); + zin = new ZipInputStream(fis, gbk); + + ZipEntry ze = null; + while ((ze = zin.getNextEntry()) != null) { + String path = ze.getName(); + System.out.println(path); + if (!ze.isDirectory()) { + InputStream inputStream = zipFile.getInputStream(ze); + String base64Photo = Base64Util.getBase64FromInputStream(inputStream); +// List texts = IOUtils.readLines(inputStream); +// for (String text : texts) { +// System.out.println(" " + text); +// } + selectDTOList.add(new SelectDTO(path.substring(path.indexOf("/")+1), "data:image/png;base64,"+base64Photo)); + inputStream.close(); + } + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (zin != null) { + zin.closeEntry(); + zin.close(); + } + if (fis != null) + fis.close(); + if (zipFile != null) + zipFile.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return selectDTOList; + } + + + /** + * MultipartFile 转 File + * + * @param file + * @throws Exception + */ + public static File multipartFileToFile(MultipartFile file) throws Exception { + + File toFile = null; + if (file.equals("") || file.getSize() <= 0) { + file = null; + } else { + InputStream ins = null; + ins = file.getInputStream(); + toFile = new File(file.getOriginalFilename()); + inputStreamToFile(ins, toFile); + ins.close(); + } + return toFile; + } + + //获取流文件 + private static void inputStreamToFile(InputStream ins, File file) { + try { + OutputStream os = new FileOutputStream(file); + int bytesRead = 0; + byte[] buffer = new byte[8192]; + while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) { + os.write(buffer, 0, bytesRead); + } + os.close(); + ins.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 删除本地临时文件 + * + * @param file + */ + public static void delteTempFile(File file) { + if (file != null) { + File del = new File(file.toURI()); + del.delete(); + } + } +} + diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java new file mode 100644 index 0000000..ae93a17 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java @@ -0,0 +1,34 @@ +package com.casic.missiles.modular.util.netty; + +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.EventLoop; +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.TimeUnit; + +/** + * 负责监听启动时连接失败,重新连接功能 + * + */ +@Slf4j +public class ConnectionListener implements ChannelFutureListener { + + private NettyClient client = new NettyClient(); + + @Override + public void operationComplete(ChannelFuture channelFuture) throws Exception { + if (!channelFuture.isSuccess()) { + final EventLoop loop = channelFuture.channel().eventLoop(); + loop.schedule(new Runnable() { + @Override + public void run() { + log.info("服务端连接不上,开始重连操作..."); + client.connect(); + } + }, 5L, TimeUnit.MINUTES); + } else { + log.info("服务端连接成功..."); + } + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java new file mode 100644 index 0000000..ef9ae76 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java @@ -0,0 +1,66 @@ +package com.casic.missiles.modular.util.netty; + +import io.netty.bootstrap.Bootstrap; +import io.netty.channel.*; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioSocketChannel; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public class NettyClient { + + private static Channel channel; + + private String fenceServiceHost = "127.0.0.1"; + private Integer fenceServicePort = 9200; + + public Channel connect() { + doConnect(fenceServiceHost, fenceServicePort); + return channel; + } + + public Channel connect(String host, int port) { + doConnect(host, port); + return channel; + } + + private void doConnect(String host, int port) { + EventLoopGroup workerGroup = new NioEventLoopGroup(); + try { + Bootstrap b = new Bootstrap(); + b.group(workerGroup); + b.channel(NioSocketChannel.class); + b.option(ChannelOption.SO_KEEPALIVE, true); + b.option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(1024 * 1024)); + + b.handler(new ChannelInitializer() { + @Override + public void initChannel(SocketChannel ch) throws Exception { + + ch.pipeline().addLast("decoder", new StringDecoder()); + ch.pipeline().addLast("encoder", new StringEncoder()); + ch.pipeline().addLast(new NettyClientHandler()); + } + }); + + ChannelFuture f = b.connect(host, port); + f.addListener(new ConnectionListener()); + channel = f.channel(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static void writeAndFlush(String message) { + + if (channel != null) { + channel.writeAndFlush(message); + System.out.println("电子围栏客户端发送消息:" + message); + } + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClientHandler.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClientHandler.java new file mode 100644 index 0000000..28093f0 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClientHandler.java @@ -0,0 +1,62 @@ +package com.casic.missiles.modular.util.netty; + +import com.casic.missiles.modular.util.HttpUtil; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import io.netty.channel.EventLoop; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; + +import java.util.concurrent.TimeUnit; + +/** + * 客户端处理器 + **/ +@Slf4j +@Component +public class NettyClientHandler extends ChannelInboundHandlerAdapter { + static boolean handle = true; + + private NettyClient client = new NettyClient(); + + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + log.info("连接成功....."); + } + + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + log.info("断开连接....."); + + //使用过程中断线重连 + final EventLoop eventLoop = ctx.channel().eventLoop(); + eventLoop.schedule(new Runnable() { + @Override + public void run() { + client.connect(); + } + }, 5L, TimeUnit.SECONDS); + super.channelInactive(ctx); + } + + + @Override + public void channelRead(ChannelHandlerContext ctx, Object message) throws Exception { + + if (handle) { + MultiValueMap map = new LinkedMultiValueMap<>(); + map.add("message", message.toString()); + HttpUtil.post("http://127.0.0.1:20311/data/addPerimeterAlarm", map); + } + handle = !handle; + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + cause.printStackTrace(); + ctx.close(); + } +} + diff --git a/casic-web/pom.xml b/casic-web/pom.xml new file mode 100644 index 0000000..8fb0b2c --- /dev/null +++ b/casic-web/pom.xml @@ -0,0 +1,171 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + ../pom.xml + 2.0.0 + + casic-web + 2.0.0 + jar + casic-web + casic web启动入口 + + + + dev + + true + + + dev + + + + test + + test + + + + prod + + prod + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + io.micrometer + micrometer-core + + + + + org.springframework.boot + spring-boot-starter-jdbc + + + + com.casic + casic-core + ${core.version} + + + com.casic + casic-admin-core + ${admin.version} + + + io.springfox + springfox-swagger-ui + + + + + com.casic + casic-admin-support + ${admin.version} + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.dameng + DmJdbcDriver18 + 1.8 + + + com.casic + casic-area-starter + ${admin.version} + + + + com.casic + casic-server + ${pro.version} + + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + + + org.apache.maven.plugins + maven-jar-plugin + ${maven.jar.plugin.version} + + + + /config/*-*.yml + **/MockController.class + + + + com.casic.missiles.CasicApplication + true + ./ + + + + + + org.apache.maven.plugins + maven-assembly-plugin + ${maven.assembly.plugin.version} + + + make-assembly + package + + single + + + + + + org.apache.maven.plugins + maven-war-plugin + ${maven.war.plugin.version} + + + + + src/main/resources + + + /config/*/* + /config/*-*.yml + + true + + + src/main/java + + **/*.xml + + true + + + + \ No newline at end of file diff --git a/casic-web/src/main/build/bin/start.bat b/casic-web/src/main/build/bin/start.bat new file mode 100644 index 0000000..1db4e88 --- /dev/null +++ b/casic-web/src/main/build/bin/start.bat @@ -0,0 +1,4 @@ +@echo off +title ${project.build.finalName} +java -jar ./lib/${project.build.finalName}.jar +@pause diff --git a/casic-web/src/main/build/bin/start.sh b/casic-web/src/main/build/bin/start.sh new file mode 100644 index 0000000..c00b1ef --- /dev/null +++ b/casic-web/src/main/build/bin/start.sh @@ -0,0 +1,2 @@ +java -jar ./lib/${project.build.finalName}.jar + diff --git a/casic-web/src/main/build/package.xml b/casic-web/src/main/build/package.xml new file mode 100644 index 0000000..c9259ad --- /dev/null +++ b/casic-web/src/main/build/package.xml @@ -0,0 +1,43 @@ + + + package + + zip + tar.gz + + true + + + + true + true + lib + runtime + + + + + src/main/build/bin + + start.bat + start.sh + + true + 0744 + / + + + src/main/resources/config + true + + *.yml + /*/* + + /config + + + src/main/resources/i18n + / + + + \ No newline at end of file diff --git a/casic-web/src/main/java/com/casic/missiles/CasicApplication.java b/casic-web/src/main/java/com/casic/missiles/CasicApplication.java new file mode 100644 index 0000000..308dcad --- /dev/null +++ b/casic-web/src/main/java/com/casic/missiles/CasicApplication.java @@ -0,0 +1,29 @@ +package com.casic.missiles; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.ServletComponentScan; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +/** + * SpringBoot方式启动类 + * + * @author lwh + * @Date 2021/06/06 12:06 + */ +@SpringBootApplication +@EnableCaching +@EnableTransactionManagement(proxyTargetClass = true) +@EnableAsync +@Slf4j +public class CasicApplication { + public static void main(String[] args) { + SpringApplication.run(CasicApplication.class, args); + + log.info("CasicApplication is success!"); + } + +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9e20bc1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea/ +**/target/** +logs/ +*.iml diff --git a/README.md b/README.md new file mode 100644 index 0000000..2fdcd74 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# casic项目 V2.0.0 + +[^_^]: # (Talk is cheap,Show me the code!) + +## 介绍 +基于SpringBoot,致力于做更简洁的后台管理系统,完美整合springboot2.4 + shiro + mybatis-plus ! +基于casic项目代码简洁,注释丰富,上手容易,同时包含许多基础模块(用户管理,角色管理,部门管理,字典管理等10个模块) +可以直接作为一个后台管理系统的脚手架! 2022目标 `更简洁`,`更规范`! + + +#### 其他 +>* [git地址](http://192.168.0.203:8080/gitbucket) +>* [本地免登地址](http://localhost:8083/route/mockToken) diff --git a/casic-server/pom.xml b/casic-server/pom.xml new file mode 100644 index 0000000..c150a12 --- /dev/null +++ b/casic-server/pom.xml @@ -0,0 +1,70 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + 2.0.0 + ../pom.xml + + + casic-server + 2.0.0 + jar + casic-server + casic 的spring boot版本 + + + + + com.casic + casic-core + ${core.version} + provided + + + com.casic + casic-admin-support + ${admin.version} + provided + + + org.springframework.boot + spring-boot-starter-web + ${boot.version} + provided + + + + + com.hikvision.ga + artemis-http-client + 1.1.3 + + + commons-io + commons-io + + + org.springframework.boot + spring-boot-starter-websocket + 2.4.5 + + + io.netty + netty-all + 4.1.42.Final + + + + + + src/main/java + + **/*.xml + + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java new file mode 100644 index 0000000..3a60b9e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java @@ -0,0 +1,36 @@ +package com.casic.missiles.modular.async; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.TaskExecutor; +import org.springframework.scheduling.annotation.AsyncConfigurer; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadPoolExecutor; + +@Configuration +@EnableAsync +public class AsyncConfig implements AsyncConfigurer { + @Override + public Executor getAsyncExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + //核心线程数 + executor.setCorePoolSize(5); + //最大线程数 + executor.setMaxPoolSize(10); + //队列容量 + executor.setQueueCapacity(20); + //设置线程活跃时间(秒) + executor.setKeepAliveSeconds(60); + //默认线程名称 + executor.setThreadNamePrefix("user-rpt-"); + //拒绝策略 + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + //等待所有任务结束后再关闭线程池 + executor.setWaitForTasksToCompleteOnShutdown(true); + return executor; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java new file mode 100644 index 0000000..8ca554c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java @@ -0,0 +1,18 @@ +package com.casic.missiles.modular.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +// tomcat启动无需配置 +@Configuration +public class WebSocketConfig { + /** + * 注入ServerEndpointExporter, + * 这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint + */ + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java new file mode 100644 index 0000000..34fe2cd --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java @@ -0,0 +1,39 @@ +package com.casic.missiles.modular.controller; + + +import com.casic.missiles.model.application.event.core.EventPublisher; +import com.casic.missiles.model.application.event.enums.ModelEventTypeEnum; +import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.modular.event.UserEvent; +import com.casic.missiles.modular.system.model.User; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +/** + * @Description: DemoController + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@RestController +@RequestMapping("/demo") +public class DemoController { + @Autowired + private EventPublisher publisher; + + /** + * 获取mockToken + */ + @PostMapping("/list") + @ResponseBody + public Object list() { + User user = new User(); + user.setAccount("张三"); + publisher.publishEvent(new UserEvent(ModelEventTypeEnum.ADD, user)); + return ResponseData.success(); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java new file mode 100644 index 0000000..aff2889 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java @@ -0,0 +1,23 @@ +package com.casic.missiles.modular.event; + +import com.casic.missiles.model.application.event.core.ModelEvent; +import com.casic.missiles.model.application.event.type.AbstractEventTypeEnum; +import com.casic.missiles.modular.system.model.User; + +/** + * @Description: 用户事件 + * @Author: wangpeng + * @Date: 2022/7/17 11:23 + */ +public class UserEvent extends ModelEvent { + /** + * Create a new {@code ApplicationEvent}. + * + * @param type 事件类型 + * @param source the object on which the event initially occurred or with + * which the event is associated (never {@code null}) + */ + public UserEvent(AbstractEventTypeEnum type, User source) { + super(type, source); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java new file mode 100644 index 0000000..8f9603e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.core.application.event.UserLoginEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserOneListener { + @EventListener + public void onApplicationEvent(UserLoginEvent event) { + log.debug("用户1订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java new file mode 100644 index 0000000..0bd52a3 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.model.application.event.core.EventSubscriber; +import com.casic.missiles.modular.event.UserEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserTwoListener extends EventSubscriber { + @Override + public void onApplicationEvent(UserEvent event) { + log.debug("用户2订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java new file mode 100644 index 0000000..4012170 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java @@ -0,0 +1,88 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang3.StringUtils; +import sun.misc.BASE64Decoder; + +import java.io.*; + +public class Base64Util { + /** + * base64字符串转换成图片 + * + * @param imgStr base64字符串 + * @param imgFilePath 图片存放路径 + * @return + * @author ZHANGJL + * @dateTime 2018-02-23 14:42:17 + */ + public static boolean Base64ToImage(String imgStr, String imgFilePath, String fileDir) { // 对字节数组字符串进行Base64解码并生成图片 + + if (StringUtils.isEmpty(imgStr)) // 图像数据为空 + return false; + + imgStr = imgStr.substring(imgStr.indexOf(",") + 1); + + BASE64Decoder decoder = new BASE64Decoder(); + try { + // Base64解码 + byte[] b = decoder.decodeBuffer(imgStr); + + for (int i = 0; i < b.length; ++i) { + if (b[i] < 0) {// 调整异常数据 + b[i] += 256; + } + } + //如果已存在图像,先删除 + File file = new File(fileDir+File.separator + imgFilePath); + if (file.exists() && file.isFile()) { + file.delete(); + } + File dir = new File(fileDir); + if (!dir.exists()) { + dir.mkdirs(); + } + file = new File(fileDir+File.separator+imgFilePath); + file.createNewFile(); +// ImageIO.write(bImage, "bmp", name); + OutputStream out = new FileOutputStream(fileDir+File.separator+imgFilePath); + out.write(b); + out.flush(); + out.close(); + + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + + } + + public static String getBase64FromInputStream(InputStream in) { + // 将图片文件转化为字节数组字符串,并对其进行Base64编码处理 + byte[] data = null; + // 读取图片字节数组 + try { + ByteArrayOutputStream swapStream = new ByteArrayOutputStream(); + byte[] buff = new byte[100]; + int rc = 0; + while ((rc = in.read(buff, 0, 100)) > 0) { + swapStream.write(buff, 0, rc); + } + data = swapStream.toByteArray(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return new String(Base64.encodeBase64(data)); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java new file mode 100644 index 0000000..9c93895 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java @@ -0,0 +1,75 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.lang3.StringUtils; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class CommonUtil { + + public static String CutId(String id) { + return id.substring(6, 10) + "-" + id.substring(10, 12) + "-" + id.substring(12, 14); + } + + public static boolean isIDNumber(String IDNumber) { + if (IDNumber == null || "".equals(IDNumber)) { + return false; + } + // 定义判别用户身份证号的正则表达式(15位或者18位,最后一位可以为字母) + String regularExpression = + "(^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|" + + "(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}$)"; + boolean matches = IDNumber.matches(regularExpression); + // 判断第18位校验值 + if (matches) { + if (IDNumber.length() == 18) { + try { + char[] charArray = IDNumber.toCharArray(); + // 前十七位加权因子 + int[] idCardWi = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; + // 这是除以11后,可能产生的11位余数对应的验证码 + String[] idCardY = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"}; + int sum = 0; + for (int i = 0; i < idCardWi.length; i++) { + int current = Integer.parseInt(String.valueOf(charArray[i])); + int count = current * idCardWi[i]; + sum += count; + } + char idCardLast = charArray[17]; + int idCardMod = sum % 11; + if (idCardY[idCardMod].toUpperCase() + .equals(String.valueOf(idCardLast).toUpperCase())) { + return true; + } else { + System.out.println("身份证最后一位:" + String.valueOf(idCardLast).toUpperCase() + + "错误,正确的应该是:" + idCardY[idCardMod].toUpperCase()); + return false; + } + + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } else { + return false; + } + } + return matches; + } + + + public static boolean CheckMobilePhoneNum(String phoneNum) { + if (StringUtils.isEmpty(phoneNum)) + return true; + String regex = "^(1[3-9]\\d{9}$)"; + if (phoneNum.length() == 11) { + Pattern p = Pattern.compile(regex); + Matcher m = p.matcher(phoneNum); + if (m.matches()) { + return true; + } + } + return false; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java new file mode 100644 index 0000000..191ef79 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java @@ -0,0 +1,116 @@ +package com.casic.missiles.modular.util; + + +import javafx.util.Pair; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +/** + * Created by Administrator on 2015/2/25. + */ +public class DateUtils { + public static SimpleDateFormat sdf_day = new SimpleDateFormat("yyyy-MM-dd"); + public static SimpleDateFormat sdf_day_time = new SimpleDateFormat("yyyyMMddhhmmss"); + public static final SimpleDateFormat sdf4 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + public static final SimpleDateFormat sdf5 = new SimpleDateFormat("HH:mm:ss"); + + + /** + * 获取当年的第一天 + * + * @return + */ + public static Date getCurrYearFirst() { + Calendar currCal = Calendar.getInstance(); + int currentYear = currCal.get(Calendar.YEAR); + return getYearFirst(currentYear); + } + + + /** + * 获取某年第一天日期 + * + * @param year 年份 + * @return Date + */ + public static Date getYearFirst(int year) { + Calendar calendar = Calendar.getInstance(); + calendar.clear(); + calendar.set(Calendar.YEAR, year); + Date currYearFirst = calendar.getTime(); + return currYearFirst; + } + + /** + * 最近7日(不包括今日) + */ + public static Pair getLastSevenDays() { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, -7); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 最近n日(不包括今日) + */ + public static Pair getLastNDays(int n) { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, n * -1); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 日期时间加n天 + */ + public static String addDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf4.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf4.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 日期加n天 + */ + public static String addNDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf_day.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf_day.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 昨日 + */ + public static String getYesterday() { + + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.DATE, -2); + return sdf_day.format(calendar.getTime()); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java new file mode 100644 index 0000000..da0f8ee --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java @@ -0,0 +1,49 @@ +package com.casic.missiles.modular.util; + +import com.hikvision.artemis.sdk.ArtemisHttpUtil; +import com.hikvision.artemis.sdk.config.ArtemisConfig; + +import java.util.HashMap; +import java.util.Map; + +public class HikUtil { + + public static String hikApi(String uri, String body) { + + /** + * STEP1:设置平台参数,根据实际情况,设置host appkey appsecret 三个参数. + */ + ArtemisConfig.host = "192.168.1.22:443"; // artemis网关服务器ip端口 + ArtemisConfig.appKey = "25766251"; // 秘钥appkey + ArtemisConfig.appSecret = "h2o6zXtzCmt8eaOaMkXb";// 秘钥appSecret + + /** + * STEP2:设置OpenAPI接口的上下文 + */ + final String ARTEMIS_PATH = "/artemis"; + + /** + * STEP3:设置接口的URI地址 + */ + final String previewURLsApi = ARTEMIS_PATH + uri; + Map path = new HashMap(2) { + { + put("https://", previewURLsApi);//根据现场环境部署确认是http还是https + } + }; + + /** + * STEP4:设置参数提交方式 + */ + String contentType = "application/json"; + + /** + * STEP5:组装请求参数 + */ + /** + * STEP6:调用接口 + */ + String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, contentType, null);// post请求application/json类型参数 + return result; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java new file mode 100644 index 0000000..4867144 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java @@ -0,0 +1,149 @@ +package com.casic.missiles.modular.util; + +import org.springframework.http.*; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; + +/** + * @Description: http请求工具类 + * @Author: wangpeng + * @Date: 2022/7/17 11:49 + */ +public class HttpUtil { + /** + * get请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String get(String url, MultiValueMap params) { + return get(url, params, null); + } + + /** + * get请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String get(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.GET); + } + + /** + * post请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String post(String url, MultiValueMap params) { + return post(url, params, null); + } + + /** + * post请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String post(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.POST); + } + + /** + * put请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String put(String url, MultiValueMap params) { + return put(url, params, null); + } + + /** + * put请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String put(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.PUT); + } + + /** + * delete请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String delete(String url, MultiValueMap params) { + return delete(url, params, null); + } + + /** + * delete请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String delete(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.DELETE); + } + + /** + * 表单请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @param method 请求方式 + * @return + */ + public static String request(String url, MultiValueMap params, MultiValueMap headers, HttpMethod method) { + if (params == null) { + params = new LinkedMultiValueMap<>(); + } + return request(url, params, headers, method, MediaType.APPLICATION_FORM_URLENCODED); + } + + /** + * http请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @param method 请求方式 + * @param mediaType 参数类型 + * @return + */ + public static String request(String url, Object params, MultiValueMap headers, HttpMethod method, MediaType mediaType) { + if (url == null || url.trim().isEmpty()) { + return null; + } + RestTemplate client = new RestTemplate(); + // header + HttpHeaders httpHeaders = new HttpHeaders(); + if (headers != null) { +// httpHeaders.addAll(headers); + httpHeaders.putAll(headers); + } + // 提交方式:表单、json + httpHeaders.setContentType(mediaType); + HttpEntity httpEntity = new HttpEntity(params, httpHeaders); + ResponseEntity response = client.exchange(url, method, httpEntity, String.class); + return response.getBody(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java new file mode 100644 index 0000000..19d8d67 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java @@ -0,0 +1,30 @@ +package com.casic.missiles.modular.util; + +public class SelectDTO { + private String name; + private String value; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public SelectDTO() { + } + + public SelectDTO(String name, String value) { + this.name = name; + this.value = value; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java new file mode 100644 index 0000000..0bd484c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java @@ -0,0 +1,28 @@ +package com.casic.missiles.modular.util; + +public class SocketConst { + + /** + * 新增授权socket前缀 + */ + public static final String SOCKET_PREFIX_ADD_PERMISSION = "addPermission:"; + + /** + * 取消授权socket前缀 + */ + public static final String SOCKET_PREFIX_DELETE_PERMISSION = "deletePermission:"; + + /** + * 人员数据下发socket前缀 + */ + public static final String SOCKET_PREFIX_ADD_PERSON = "addPerson:"; + + /** + * socket返回成功信息 + */ + public static final String SOCKET_SUCCESS_MSG = "ok"; + /** + * 人员数据下发socket前缀 + */ + public static final String SOCKET_PREFIX_DELETE_PERSON = "deletePerson:"; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java new file mode 100644 index 0000000..0452bca --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java @@ -0,0 +1,90 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.io.IOUtils; +import org.springframework.stereotype.Component; + +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.text.SimpleDateFormat; +import java.util.Date; + +@Component +public class SocketUtil { + + public static byte[] sendMessage(String ip, int port, String msg) { + byte[] data = new byte[20]; + + System.out.println("往 " + ip + ":" + port + " 发送数据:" + msg); + InputStream in = null; + OutputStream out = null; + Socket socket = null; + try { + socket = new Socket(); + socket.connect(new InetSocketAddress(ip, port), 1000); + socket.setSoTimeout(2000); + // 向服务端发送数据 + out = socket.getOutputStream(); + out.write(hexString2Bytes(msg)); + out.flush(); + //socket.shutdownOutput(); + // 读取服务端返回数据 + in = socket.getInputStream(); + in.read(data); + } catch (Exception e) { + e.printStackTrace(); + } finally { + IOUtils.closeQuietly(in); + IOUtils.closeQuietly(out); + IOUtils.closeQuietly(socket); + } + return data; + } + + private static int code = 0; + + public static void main(String[] args) { +// byte[] dd = sendMessage("192.168.5.211",6001,"090300000002C543"); + + String dateStr = new SimpleDateFormat("yyMMddHHmmssSSS").format(new Date()); + //String dd = dateStr + String.format("%04d",++code); + + System.out.println(dateStr); + } + + /** + * 返回由字节数组转换来的 16 位有符号整数 + * + * @param bytes 字节数组 + * @return 由两个字节构成的 16 位有符号整数 + */ + public static short toShort(byte[] bytes) { + return (short) ((0xff & bytes[0]) | (0xff00 & (bytes[1] << 8))); + + } + + + public static byte[] hexString2Bytes(String hex) { + if ((hex == null) || (hex.equals(""))) { + return null; + } else if (hex.length() % 2 != 0) { + return null; + } else { + hex = hex.toUpperCase(); + int len = hex.length() / 2; + byte[] b = new byte[len]; + char[] hc = hex.toCharArray(); + for (int i = 0; i < len; i++) { + int p = 2 * i; + b[i] = (byte) (charToByte(hc[p]) << 4 | charToByte(hc[p + 1])); + } + return b; + } + } + + private static byte charToByte(char c) { + return (byte) "0123456789ABCDEF".indexOf(c); + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java b/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java new file mode 100644 index 0000000..9b4155c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java @@ -0,0 +1,105 @@ +package com.casic.missiles.modular.util; + +import org.springframework.stereotype.Component; + +import javax.websocket.OnClose; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.PathParam; +import javax.websocket.server.ServerEndpoint; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CopyOnWriteArraySet; + +/** + * @Description: 此注解相当于设置访问URL + * @Author: wangpeng + * @Date: 2022/7/17 11:48 + */ +@Component +@ServerEndpoint("/websocket/{userId}") +public class WebSocket { + private Session session; + + private static CopyOnWriteArraySet webSockets = new CopyOnWriteArraySet<>(); + private static Map sessionPool = new HashMap(); + + @OnOpen + public void onOpen(Session session, @PathParam(value = "userId") String userId) { + this.session = session; + webSockets.add(this); + sessionPool.put(userId, session); + System.out.println(userId + "【websocket消息】有新的连接,总数为:" + webSockets.size()); + } + + @OnClose + public void onClose() { + webSockets.remove(this); + System.out.println("【websocket消息】连接断开,总数为:" + webSockets.size()); + } + + @OnMessage + public void onMessage(String message) { + System.out.println("【websocket消息】收到客户端消息:" + message); + } + + // 此为广播消息 + public void sendAllMessage(String message) { + for (WebSocket webSocket : webSockets) { + System.out.println("【websocket消息】广播消息:" + message); + try { + webSocket.session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + // 发送列表消息 + public void sendListMessage(List userIds, String message) { + System.out.println("【websocket消息】列表消息:" + message); + for (String userId : userIds) { + Session session = sessionPool.get(userId); + if (session != null) { + try { + session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + + // 发送列表消息 + +// public void sendListMessage(List userIds, Object data){ +// System.out.println("【websocket消息】列表消息:"+data); +// for (String userId : userIds) { +// Session session = sessionPool.get(userId); +// if (session != null) { +// try { +//// session.getAsyncRemote().sendText(message); +// session.getAsyncRemote().sendObject(data); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// } +// } + + // 此为单点消息 + public void sendOneMessage(String userId, String message) { + System.out.println("【websocket消息】单点消息:" + message); + Session session = sessionPool.get(userId); + if (session != null) { + try { + session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java new file mode 100644 index 0000000..0c1f5f1 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java @@ -0,0 +1,115 @@ +package com.casic.missiles.modular.util; + +import org.springframework.web.multipart.MultipartFile; + +import java.io.*; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipInputStream; + +/** + * @Description: 读取zip文件内容 + * @Author: wangpeng + * @Date: 2022/7/17 11:48 + */ +public class ZipFileUtil { + public static List getFile(String fileName) { + File file = new File(fileName); + ZipFile zipFile = null; + ZipInputStream zin = null; + FileInputStream fis = null; + List selectDTOList = new ArrayList<>(); + try { + Charset gbk = Charset.forName("GBK"); + zipFile = new ZipFile(file, gbk); + fis = new FileInputStream(file); + zin = new ZipInputStream(fis, gbk); + + ZipEntry ze = null; + while ((ze = zin.getNextEntry()) != null) { + String path = ze.getName(); + System.out.println(path); + if (!ze.isDirectory()) { + InputStream inputStream = zipFile.getInputStream(ze); + String base64Photo = Base64Util.getBase64FromInputStream(inputStream); +// List texts = IOUtils.readLines(inputStream); +// for (String text : texts) { +// System.out.println(" " + text); +// } + selectDTOList.add(new SelectDTO(path.substring(path.indexOf("/")+1), "data:image/png;base64,"+base64Photo)); + inputStream.close(); + } + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (zin != null) { + zin.closeEntry(); + zin.close(); + } + if (fis != null) + fis.close(); + if (zipFile != null) + zipFile.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return selectDTOList; + } + + + /** + * MultipartFile 转 File + * + * @param file + * @throws Exception + */ + public static File multipartFileToFile(MultipartFile file) throws Exception { + + File toFile = null; + if (file.equals("") || file.getSize() <= 0) { + file = null; + } else { + InputStream ins = null; + ins = file.getInputStream(); + toFile = new File(file.getOriginalFilename()); + inputStreamToFile(ins, toFile); + ins.close(); + } + return toFile; + } + + //获取流文件 + private static void inputStreamToFile(InputStream ins, File file) { + try { + OutputStream os = new FileOutputStream(file); + int bytesRead = 0; + byte[] buffer = new byte[8192]; + while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) { + os.write(buffer, 0, bytesRead); + } + os.close(); + ins.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 删除本地临时文件 + * + * @param file + */ + public static void delteTempFile(File file) { + if (file != null) { + File del = new File(file.toURI()); + del.delete(); + } + } +} + diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java new file mode 100644 index 0000000..ae93a17 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java @@ -0,0 +1,34 @@ +package com.casic.missiles.modular.util.netty; + +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.EventLoop; +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.TimeUnit; + +/** + * 负责监听启动时连接失败,重新连接功能 + * + */ +@Slf4j +public class ConnectionListener implements ChannelFutureListener { + + private NettyClient client = new NettyClient(); + + @Override + public void operationComplete(ChannelFuture channelFuture) throws Exception { + if (!channelFuture.isSuccess()) { + final EventLoop loop = channelFuture.channel().eventLoop(); + loop.schedule(new Runnable() { + @Override + public void run() { + log.info("服务端连接不上,开始重连操作..."); + client.connect(); + } + }, 5L, TimeUnit.MINUTES); + } else { + log.info("服务端连接成功..."); + } + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java new file mode 100644 index 0000000..ef9ae76 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java @@ -0,0 +1,66 @@ +package com.casic.missiles.modular.util.netty; + +import io.netty.bootstrap.Bootstrap; +import io.netty.channel.*; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioSocketChannel; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public class NettyClient { + + private static Channel channel; + + private String fenceServiceHost = "127.0.0.1"; + private Integer fenceServicePort = 9200; + + public Channel connect() { + doConnect(fenceServiceHost, fenceServicePort); + return channel; + } + + public Channel connect(String host, int port) { + doConnect(host, port); + return channel; + } + + private void doConnect(String host, int port) { + EventLoopGroup workerGroup = new NioEventLoopGroup(); + try { + Bootstrap b = new Bootstrap(); + b.group(workerGroup); + b.channel(NioSocketChannel.class); + b.option(ChannelOption.SO_KEEPALIVE, true); + b.option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(1024 * 1024)); + + b.handler(new ChannelInitializer() { + @Override + public void initChannel(SocketChannel ch) throws Exception { + + ch.pipeline().addLast("decoder", new StringDecoder()); + ch.pipeline().addLast("encoder", new StringEncoder()); + ch.pipeline().addLast(new NettyClientHandler()); + } + }); + + ChannelFuture f = b.connect(host, port); + f.addListener(new ConnectionListener()); + channel = f.channel(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static void writeAndFlush(String message) { + + if (channel != null) { + channel.writeAndFlush(message); + System.out.println("电子围栏客户端发送消息:" + message); + } + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClientHandler.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClientHandler.java new file mode 100644 index 0000000..28093f0 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClientHandler.java @@ -0,0 +1,62 @@ +package com.casic.missiles.modular.util.netty; + +import com.casic.missiles.modular.util.HttpUtil; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import io.netty.channel.EventLoop; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; + +import java.util.concurrent.TimeUnit; + +/** + * 客户端处理器 + **/ +@Slf4j +@Component +public class NettyClientHandler extends ChannelInboundHandlerAdapter { + static boolean handle = true; + + private NettyClient client = new NettyClient(); + + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + log.info("连接成功....."); + } + + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + log.info("断开连接....."); + + //使用过程中断线重连 + final EventLoop eventLoop = ctx.channel().eventLoop(); + eventLoop.schedule(new Runnable() { + @Override + public void run() { + client.connect(); + } + }, 5L, TimeUnit.SECONDS); + super.channelInactive(ctx); + } + + + @Override + public void channelRead(ChannelHandlerContext ctx, Object message) throws Exception { + + if (handle) { + MultiValueMap map = new LinkedMultiValueMap<>(); + map.add("message", message.toString()); + HttpUtil.post("http://127.0.0.1:20311/data/addPerimeterAlarm", map); + } + handle = !handle; + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + cause.printStackTrace(); + ctx.close(); + } +} + diff --git a/casic-web/pom.xml b/casic-web/pom.xml new file mode 100644 index 0000000..8fb0b2c --- /dev/null +++ b/casic-web/pom.xml @@ -0,0 +1,171 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + ../pom.xml + 2.0.0 + + casic-web + 2.0.0 + jar + casic-web + casic web启动入口 + + + + dev + + true + + + dev + + + + test + + test + + + + prod + + prod + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + io.micrometer + micrometer-core + + + + + org.springframework.boot + spring-boot-starter-jdbc + + + + com.casic + casic-core + ${core.version} + + + com.casic + casic-admin-core + ${admin.version} + + + io.springfox + springfox-swagger-ui + + + + + com.casic + casic-admin-support + ${admin.version} + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.dameng + DmJdbcDriver18 + 1.8 + + + com.casic + casic-area-starter + ${admin.version} + + + + com.casic + casic-server + ${pro.version} + + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + + + org.apache.maven.plugins + maven-jar-plugin + ${maven.jar.plugin.version} + + + + /config/*-*.yml + **/MockController.class + + + + com.casic.missiles.CasicApplication + true + ./ + + + + + + org.apache.maven.plugins + maven-assembly-plugin + ${maven.assembly.plugin.version} + + + make-assembly + package + + single + + + + + + org.apache.maven.plugins + maven-war-plugin + ${maven.war.plugin.version} + + + + + src/main/resources + + + /config/*/* + /config/*-*.yml + + true + + + src/main/java + + **/*.xml + + true + + + + \ No newline at end of file diff --git a/casic-web/src/main/build/bin/start.bat b/casic-web/src/main/build/bin/start.bat new file mode 100644 index 0000000..1db4e88 --- /dev/null +++ b/casic-web/src/main/build/bin/start.bat @@ -0,0 +1,4 @@ +@echo off +title ${project.build.finalName} +java -jar ./lib/${project.build.finalName}.jar +@pause diff --git a/casic-web/src/main/build/bin/start.sh b/casic-web/src/main/build/bin/start.sh new file mode 100644 index 0000000..c00b1ef --- /dev/null +++ b/casic-web/src/main/build/bin/start.sh @@ -0,0 +1,2 @@ +java -jar ./lib/${project.build.finalName}.jar + diff --git a/casic-web/src/main/build/package.xml b/casic-web/src/main/build/package.xml new file mode 100644 index 0000000..c9259ad --- /dev/null +++ b/casic-web/src/main/build/package.xml @@ -0,0 +1,43 @@ + + + package + + zip + tar.gz + + true + + + + true + true + lib + runtime + + + + + src/main/build/bin + + start.bat + start.sh + + true + 0744 + / + + + src/main/resources/config + true + + *.yml + /*/* + + /config + + + src/main/resources/i18n + / + + + \ No newline at end of file diff --git a/casic-web/src/main/java/com/casic/missiles/CasicApplication.java b/casic-web/src/main/java/com/casic/missiles/CasicApplication.java new file mode 100644 index 0000000..308dcad --- /dev/null +++ b/casic-web/src/main/java/com/casic/missiles/CasicApplication.java @@ -0,0 +1,29 @@ +package com.casic.missiles; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.ServletComponentScan; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +/** + * SpringBoot方式启动类 + * + * @author lwh + * @Date 2021/06/06 12:06 + */ +@SpringBootApplication +@EnableCaching +@EnableTransactionManagement(proxyTargetClass = true) +@EnableAsync +@Slf4j +public class CasicApplication { + public static void main(String[] args) { + SpringApplication.run(CasicApplication.class, args); + + log.info("CasicApplication is success!"); + } + +} diff --git a/casic-web/src/main/java/com/casic/missiles/CasicServletInitializer.java b/casic-web/src/main/java/com/casic/missiles/CasicServletInitializer.java new file mode 100644 index 0000000..e30585b --- /dev/null +++ b/casic-web/src/main/java/com/casic/missiles/CasicServletInitializer.java @@ -0,0 +1,18 @@ +package com.casic.missiles; + +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; + +/** + * Guns Web程序启动类 + * + * @author fengshuonan + * @date 2017-05-21 9:43 + */ +public class CasicServletInitializer extends SpringBootServletInitializer { + + @Override + protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { + return application.sources(CasicApplication.class); + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9e20bc1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea/ +**/target/** +logs/ +*.iml diff --git a/README.md b/README.md new file mode 100644 index 0000000..2fdcd74 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# casic项目 V2.0.0 + +[^_^]: # (Talk is cheap,Show me the code!) + +## 介绍 +基于SpringBoot,致力于做更简洁的后台管理系统,完美整合springboot2.4 + shiro + mybatis-plus ! +基于casic项目代码简洁,注释丰富,上手容易,同时包含许多基础模块(用户管理,角色管理,部门管理,字典管理等10个模块) +可以直接作为一个后台管理系统的脚手架! 2022目标 `更简洁`,`更规范`! + + +#### 其他 +>* [git地址](http://192.168.0.203:8080/gitbucket) +>* [本地免登地址](http://localhost:8083/route/mockToken) diff --git a/casic-server/pom.xml b/casic-server/pom.xml new file mode 100644 index 0000000..c150a12 --- /dev/null +++ b/casic-server/pom.xml @@ -0,0 +1,70 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + 2.0.0 + ../pom.xml + + + casic-server + 2.0.0 + jar + casic-server + casic 的spring boot版本 + + + + + com.casic + casic-core + ${core.version} + provided + + + com.casic + casic-admin-support + ${admin.version} + provided + + + org.springframework.boot + spring-boot-starter-web + ${boot.version} + provided + + + + + com.hikvision.ga + artemis-http-client + 1.1.3 + + + commons-io + commons-io + + + org.springframework.boot + spring-boot-starter-websocket + 2.4.5 + + + io.netty + netty-all + 4.1.42.Final + + + + + + src/main/java + + **/*.xml + + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java new file mode 100644 index 0000000..3a60b9e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java @@ -0,0 +1,36 @@ +package com.casic.missiles.modular.async; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.TaskExecutor; +import org.springframework.scheduling.annotation.AsyncConfigurer; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadPoolExecutor; + +@Configuration +@EnableAsync +public class AsyncConfig implements AsyncConfigurer { + @Override + public Executor getAsyncExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + //核心线程数 + executor.setCorePoolSize(5); + //最大线程数 + executor.setMaxPoolSize(10); + //队列容量 + executor.setQueueCapacity(20); + //设置线程活跃时间(秒) + executor.setKeepAliveSeconds(60); + //默认线程名称 + executor.setThreadNamePrefix("user-rpt-"); + //拒绝策略 + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + //等待所有任务结束后再关闭线程池 + executor.setWaitForTasksToCompleteOnShutdown(true); + return executor; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java new file mode 100644 index 0000000..8ca554c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java @@ -0,0 +1,18 @@ +package com.casic.missiles.modular.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +// tomcat启动无需配置 +@Configuration +public class WebSocketConfig { + /** + * 注入ServerEndpointExporter, + * 这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint + */ + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java new file mode 100644 index 0000000..34fe2cd --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java @@ -0,0 +1,39 @@ +package com.casic.missiles.modular.controller; + + +import com.casic.missiles.model.application.event.core.EventPublisher; +import com.casic.missiles.model.application.event.enums.ModelEventTypeEnum; +import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.modular.event.UserEvent; +import com.casic.missiles.modular.system.model.User; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +/** + * @Description: DemoController + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@RestController +@RequestMapping("/demo") +public class DemoController { + @Autowired + private EventPublisher publisher; + + /** + * 获取mockToken + */ + @PostMapping("/list") + @ResponseBody + public Object list() { + User user = new User(); + user.setAccount("张三"); + publisher.publishEvent(new UserEvent(ModelEventTypeEnum.ADD, user)); + return ResponseData.success(); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java new file mode 100644 index 0000000..aff2889 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java @@ -0,0 +1,23 @@ +package com.casic.missiles.modular.event; + +import com.casic.missiles.model.application.event.core.ModelEvent; +import com.casic.missiles.model.application.event.type.AbstractEventTypeEnum; +import com.casic.missiles.modular.system.model.User; + +/** + * @Description: 用户事件 + * @Author: wangpeng + * @Date: 2022/7/17 11:23 + */ +public class UserEvent extends ModelEvent { + /** + * Create a new {@code ApplicationEvent}. + * + * @param type 事件类型 + * @param source the object on which the event initially occurred or with + * which the event is associated (never {@code null}) + */ + public UserEvent(AbstractEventTypeEnum type, User source) { + super(type, source); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java new file mode 100644 index 0000000..8f9603e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.core.application.event.UserLoginEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserOneListener { + @EventListener + public void onApplicationEvent(UserLoginEvent event) { + log.debug("用户1订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java new file mode 100644 index 0000000..0bd52a3 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.model.application.event.core.EventSubscriber; +import com.casic.missiles.modular.event.UserEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserTwoListener extends EventSubscriber { + @Override + public void onApplicationEvent(UserEvent event) { + log.debug("用户2订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java new file mode 100644 index 0000000..4012170 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java @@ -0,0 +1,88 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang3.StringUtils; +import sun.misc.BASE64Decoder; + +import java.io.*; + +public class Base64Util { + /** + * base64字符串转换成图片 + * + * @param imgStr base64字符串 + * @param imgFilePath 图片存放路径 + * @return + * @author ZHANGJL + * @dateTime 2018-02-23 14:42:17 + */ + public static boolean Base64ToImage(String imgStr, String imgFilePath, String fileDir) { // 对字节数组字符串进行Base64解码并生成图片 + + if (StringUtils.isEmpty(imgStr)) // 图像数据为空 + return false; + + imgStr = imgStr.substring(imgStr.indexOf(",") + 1); + + BASE64Decoder decoder = new BASE64Decoder(); + try { + // Base64解码 + byte[] b = decoder.decodeBuffer(imgStr); + + for (int i = 0; i < b.length; ++i) { + if (b[i] < 0) {// 调整异常数据 + b[i] += 256; + } + } + //如果已存在图像,先删除 + File file = new File(fileDir+File.separator + imgFilePath); + if (file.exists() && file.isFile()) { + file.delete(); + } + File dir = new File(fileDir); + if (!dir.exists()) { + dir.mkdirs(); + } + file = new File(fileDir+File.separator+imgFilePath); + file.createNewFile(); +// ImageIO.write(bImage, "bmp", name); + OutputStream out = new FileOutputStream(fileDir+File.separator+imgFilePath); + out.write(b); + out.flush(); + out.close(); + + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + + } + + public static String getBase64FromInputStream(InputStream in) { + // 将图片文件转化为字节数组字符串,并对其进行Base64编码处理 + byte[] data = null; + // 读取图片字节数组 + try { + ByteArrayOutputStream swapStream = new ByteArrayOutputStream(); + byte[] buff = new byte[100]; + int rc = 0; + while ((rc = in.read(buff, 0, 100)) > 0) { + swapStream.write(buff, 0, rc); + } + data = swapStream.toByteArray(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return new String(Base64.encodeBase64(data)); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java new file mode 100644 index 0000000..9c93895 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java @@ -0,0 +1,75 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.lang3.StringUtils; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class CommonUtil { + + public static String CutId(String id) { + return id.substring(6, 10) + "-" + id.substring(10, 12) + "-" + id.substring(12, 14); + } + + public static boolean isIDNumber(String IDNumber) { + if (IDNumber == null || "".equals(IDNumber)) { + return false; + } + // 定义判别用户身份证号的正则表达式(15位或者18位,最后一位可以为字母) + String regularExpression = + "(^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|" + + "(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}$)"; + boolean matches = IDNumber.matches(regularExpression); + // 判断第18位校验值 + if (matches) { + if (IDNumber.length() == 18) { + try { + char[] charArray = IDNumber.toCharArray(); + // 前十七位加权因子 + int[] idCardWi = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; + // 这是除以11后,可能产生的11位余数对应的验证码 + String[] idCardY = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"}; + int sum = 0; + for (int i = 0; i < idCardWi.length; i++) { + int current = Integer.parseInt(String.valueOf(charArray[i])); + int count = current * idCardWi[i]; + sum += count; + } + char idCardLast = charArray[17]; + int idCardMod = sum % 11; + if (idCardY[idCardMod].toUpperCase() + .equals(String.valueOf(idCardLast).toUpperCase())) { + return true; + } else { + System.out.println("身份证最后一位:" + String.valueOf(idCardLast).toUpperCase() + + "错误,正确的应该是:" + idCardY[idCardMod].toUpperCase()); + return false; + } + + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } else { + return false; + } + } + return matches; + } + + + public static boolean CheckMobilePhoneNum(String phoneNum) { + if (StringUtils.isEmpty(phoneNum)) + return true; + String regex = "^(1[3-9]\\d{9}$)"; + if (phoneNum.length() == 11) { + Pattern p = Pattern.compile(regex); + Matcher m = p.matcher(phoneNum); + if (m.matches()) { + return true; + } + } + return false; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java new file mode 100644 index 0000000..191ef79 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java @@ -0,0 +1,116 @@ +package com.casic.missiles.modular.util; + + +import javafx.util.Pair; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +/** + * Created by Administrator on 2015/2/25. + */ +public class DateUtils { + public static SimpleDateFormat sdf_day = new SimpleDateFormat("yyyy-MM-dd"); + public static SimpleDateFormat sdf_day_time = new SimpleDateFormat("yyyyMMddhhmmss"); + public static final SimpleDateFormat sdf4 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + public static final SimpleDateFormat sdf5 = new SimpleDateFormat("HH:mm:ss"); + + + /** + * 获取当年的第一天 + * + * @return + */ + public static Date getCurrYearFirst() { + Calendar currCal = Calendar.getInstance(); + int currentYear = currCal.get(Calendar.YEAR); + return getYearFirst(currentYear); + } + + + /** + * 获取某年第一天日期 + * + * @param year 年份 + * @return Date + */ + public static Date getYearFirst(int year) { + Calendar calendar = Calendar.getInstance(); + calendar.clear(); + calendar.set(Calendar.YEAR, year); + Date currYearFirst = calendar.getTime(); + return currYearFirst; + } + + /** + * 最近7日(不包括今日) + */ + public static Pair getLastSevenDays() { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, -7); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 最近n日(不包括今日) + */ + public static Pair getLastNDays(int n) { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, n * -1); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 日期时间加n天 + */ + public static String addDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf4.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf4.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 日期加n天 + */ + public static String addNDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf_day.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf_day.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 昨日 + */ + public static String getYesterday() { + + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.DATE, -2); + return sdf_day.format(calendar.getTime()); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java new file mode 100644 index 0000000..da0f8ee --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java @@ -0,0 +1,49 @@ +package com.casic.missiles.modular.util; + +import com.hikvision.artemis.sdk.ArtemisHttpUtil; +import com.hikvision.artemis.sdk.config.ArtemisConfig; + +import java.util.HashMap; +import java.util.Map; + +public class HikUtil { + + public static String hikApi(String uri, String body) { + + /** + * STEP1:设置平台参数,根据实际情况,设置host appkey appsecret 三个参数. + */ + ArtemisConfig.host = "192.168.1.22:443"; // artemis网关服务器ip端口 + ArtemisConfig.appKey = "25766251"; // 秘钥appkey + ArtemisConfig.appSecret = "h2o6zXtzCmt8eaOaMkXb";// 秘钥appSecret + + /** + * STEP2:设置OpenAPI接口的上下文 + */ + final String ARTEMIS_PATH = "/artemis"; + + /** + * STEP3:设置接口的URI地址 + */ + final String previewURLsApi = ARTEMIS_PATH + uri; + Map path = new HashMap(2) { + { + put("https://", previewURLsApi);//根据现场环境部署确认是http还是https + } + }; + + /** + * STEP4:设置参数提交方式 + */ + String contentType = "application/json"; + + /** + * STEP5:组装请求参数 + */ + /** + * STEP6:调用接口 + */ + String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, contentType, null);// post请求application/json类型参数 + return result; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java new file mode 100644 index 0000000..4867144 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java @@ -0,0 +1,149 @@ +package com.casic.missiles.modular.util; + +import org.springframework.http.*; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; + +/** + * @Description: http请求工具类 + * @Author: wangpeng + * @Date: 2022/7/17 11:49 + */ +public class HttpUtil { + /** + * get请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String get(String url, MultiValueMap params) { + return get(url, params, null); + } + + /** + * get请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String get(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.GET); + } + + /** + * post请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String post(String url, MultiValueMap params) { + return post(url, params, null); + } + + /** + * post请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String post(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.POST); + } + + /** + * put请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String put(String url, MultiValueMap params) { + return put(url, params, null); + } + + /** + * put请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String put(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.PUT); + } + + /** + * delete请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String delete(String url, MultiValueMap params) { + return delete(url, params, null); + } + + /** + * delete请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String delete(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.DELETE); + } + + /** + * 表单请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @param method 请求方式 + * @return + */ + public static String request(String url, MultiValueMap params, MultiValueMap headers, HttpMethod method) { + if (params == null) { + params = new LinkedMultiValueMap<>(); + } + return request(url, params, headers, method, MediaType.APPLICATION_FORM_URLENCODED); + } + + /** + * http请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @param method 请求方式 + * @param mediaType 参数类型 + * @return + */ + public static String request(String url, Object params, MultiValueMap headers, HttpMethod method, MediaType mediaType) { + if (url == null || url.trim().isEmpty()) { + return null; + } + RestTemplate client = new RestTemplate(); + // header + HttpHeaders httpHeaders = new HttpHeaders(); + if (headers != null) { +// httpHeaders.addAll(headers); + httpHeaders.putAll(headers); + } + // 提交方式:表单、json + httpHeaders.setContentType(mediaType); + HttpEntity httpEntity = new HttpEntity(params, httpHeaders); + ResponseEntity response = client.exchange(url, method, httpEntity, String.class); + return response.getBody(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java new file mode 100644 index 0000000..19d8d67 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java @@ -0,0 +1,30 @@ +package com.casic.missiles.modular.util; + +public class SelectDTO { + private String name; + private String value; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public SelectDTO() { + } + + public SelectDTO(String name, String value) { + this.name = name; + this.value = value; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java new file mode 100644 index 0000000..0bd484c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java @@ -0,0 +1,28 @@ +package com.casic.missiles.modular.util; + +public class SocketConst { + + /** + * 新增授权socket前缀 + */ + public static final String SOCKET_PREFIX_ADD_PERMISSION = "addPermission:"; + + /** + * 取消授权socket前缀 + */ + public static final String SOCKET_PREFIX_DELETE_PERMISSION = "deletePermission:"; + + /** + * 人员数据下发socket前缀 + */ + public static final String SOCKET_PREFIX_ADD_PERSON = "addPerson:"; + + /** + * socket返回成功信息 + */ + public static final String SOCKET_SUCCESS_MSG = "ok"; + /** + * 人员数据下发socket前缀 + */ + public static final String SOCKET_PREFIX_DELETE_PERSON = "deletePerson:"; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java new file mode 100644 index 0000000..0452bca --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java @@ -0,0 +1,90 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.io.IOUtils; +import org.springframework.stereotype.Component; + +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.text.SimpleDateFormat; +import java.util.Date; + +@Component +public class SocketUtil { + + public static byte[] sendMessage(String ip, int port, String msg) { + byte[] data = new byte[20]; + + System.out.println("往 " + ip + ":" + port + " 发送数据:" + msg); + InputStream in = null; + OutputStream out = null; + Socket socket = null; + try { + socket = new Socket(); + socket.connect(new InetSocketAddress(ip, port), 1000); + socket.setSoTimeout(2000); + // 向服务端发送数据 + out = socket.getOutputStream(); + out.write(hexString2Bytes(msg)); + out.flush(); + //socket.shutdownOutput(); + // 读取服务端返回数据 + in = socket.getInputStream(); + in.read(data); + } catch (Exception e) { + e.printStackTrace(); + } finally { + IOUtils.closeQuietly(in); + IOUtils.closeQuietly(out); + IOUtils.closeQuietly(socket); + } + return data; + } + + private static int code = 0; + + public static void main(String[] args) { +// byte[] dd = sendMessage("192.168.5.211",6001,"090300000002C543"); + + String dateStr = new SimpleDateFormat("yyMMddHHmmssSSS").format(new Date()); + //String dd = dateStr + String.format("%04d",++code); + + System.out.println(dateStr); + } + + /** + * 返回由字节数组转换来的 16 位有符号整数 + * + * @param bytes 字节数组 + * @return 由两个字节构成的 16 位有符号整数 + */ + public static short toShort(byte[] bytes) { + return (short) ((0xff & bytes[0]) | (0xff00 & (bytes[1] << 8))); + + } + + + public static byte[] hexString2Bytes(String hex) { + if ((hex == null) || (hex.equals(""))) { + return null; + } else if (hex.length() % 2 != 0) { + return null; + } else { + hex = hex.toUpperCase(); + int len = hex.length() / 2; + byte[] b = new byte[len]; + char[] hc = hex.toCharArray(); + for (int i = 0; i < len; i++) { + int p = 2 * i; + b[i] = (byte) (charToByte(hc[p]) << 4 | charToByte(hc[p + 1])); + } + return b; + } + } + + private static byte charToByte(char c) { + return (byte) "0123456789ABCDEF".indexOf(c); + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java b/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java new file mode 100644 index 0000000..9b4155c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java @@ -0,0 +1,105 @@ +package com.casic.missiles.modular.util; + +import org.springframework.stereotype.Component; + +import javax.websocket.OnClose; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.PathParam; +import javax.websocket.server.ServerEndpoint; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CopyOnWriteArraySet; + +/** + * @Description: 此注解相当于设置访问URL + * @Author: wangpeng + * @Date: 2022/7/17 11:48 + */ +@Component +@ServerEndpoint("/websocket/{userId}") +public class WebSocket { + private Session session; + + private static CopyOnWriteArraySet webSockets = new CopyOnWriteArraySet<>(); + private static Map sessionPool = new HashMap(); + + @OnOpen + public void onOpen(Session session, @PathParam(value = "userId") String userId) { + this.session = session; + webSockets.add(this); + sessionPool.put(userId, session); + System.out.println(userId + "【websocket消息】有新的连接,总数为:" + webSockets.size()); + } + + @OnClose + public void onClose() { + webSockets.remove(this); + System.out.println("【websocket消息】连接断开,总数为:" + webSockets.size()); + } + + @OnMessage + public void onMessage(String message) { + System.out.println("【websocket消息】收到客户端消息:" + message); + } + + // 此为广播消息 + public void sendAllMessage(String message) { + for (WebSocket webSocket : webSockets) { + System.out.println("【websocket消息】广播消息:" + message); + try { + webSocket.session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + // 发送列表消息 + public void sendListMessage(List userIds, String message) { + System.out.println("【websocket消息】列表消息:" + message); + for (String userId : userIds) { + Session session = sessionPool.get(userId); + if (session != null) { + try { + session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + + // 发送列表消息 + +// public void sendListMessage(List userIds, Object data){ +// System.out.println("【websocket消息】列表消息:"+data); +// for (String userId : userIds) { +// Session session = sessionPool.get(userId); +// if (session != null) { +// try { +//// session.getAsyncRemote().sendText(message); +// session.getAsyncRemote().sendObject(data); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// } +// } + + // 此为单点消息 + public void sendOneMessage(String userId, String message) { + System.out.println("【websocket消息】单点消息:" + message); + Session session = sessionPool.get(userId); + if (session != null) { + try { + session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java new file mode 100644 index 0000000..0c1f5f1 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java @@ -0,0 +1,115 @@ +package com.casic.missiles.modular.util; + +import org.springframework.web.multipart.MultipartFile; + +import java.io.*; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipInputStream; + +/** + * @Description: 读取zip文件内容 + * @Author: wangpeng + * @Date: 2022/7/17 11:48 + */ +public class ZipFileUtil { + public static List getFile(String fileName) { + File file = new File(fileName); + ZipFile zipFile = null; + ZipInputStream zin = null; + FileInputStream fis = null; + List selectDTOList = new ArrayList<>(); + try { + Charset gbk = Charset.forName("GBK"); + zipFile = new ZipFile(file, gbk); + fis = new FileInputStream(file); + zin = new ZipInputStream(fis, gbk); + + ZipEntry ze = null; + while ((ze = zin.getNextEntry()) != null) { + String path = ze.getName(); + System.out.println(path); + if (!ze.isDirectory()) { + InputStream inputStream = zipFile.getInputStream(ze); + String base64Photo = Base64Util.getBase64FromInputStream(inputStream); +// List texts = IOUtils.readLines(inputStream); +// for (String text : texts) { +// System.out.println(" " + text); +// } + selectDTOList.add(new SelectDTO(path.substring(path.indexOf("/")+1), "data:image/png;base64,"+base64Photo)); + inputStream.close(); + } + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (zin != null) { + zin.closeEntry(); + zin.close(); + } + if (fis != null) + fis.close(); + if (zipFile != null) + zipFile.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return selectDTOList; + } + + + /** + * MultipartFile 转 File + * + * @param file + * @throws Exception + */ + public static File multipartFileToFile(MultipartFile file) throws Exception { + + File toFile = null; + if (file.equals("") || file.getSize() <= 0) { + file = null; + } else { + InputStream ins = null; + ins = file.getInputStream(); + toFile = new File(file.getOriginalFilename()); + inputStreamToFile(ins, toFile); + ins.close(); + } + return toFile; + } + + //获取流文件 + private static void inputStreamToFile(InputStream ins, File file) { + try { + OutputStream os = new FileOutputStream(file); + int bytesRead = 0; + byte[] buffer = new byte[8192]; + while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) { + os.write(buffer, 0, bytesRead); + } + os.close(); + ins.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 删除本地临时文件 + * + * @param file + */ + public static void delteTempFile(File file) { + if (file != null) { + File del = new File(file.toURI()); + del.delete(); + } + } +} + diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java new file mode 100644 index 0000000..ae93a17 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java @@ -0,0 +1,34 @@ +package com.casic.missiles.modular.util.netty; + +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.EventLoop; +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.TimeUnit; + +/** + * 负责监听启动时连接失败,重新连接功能 + * + */ +@Slf4j +public class ConnectionListener implements ChannelFutureListener { + + private NettyClient client = new NettyClient(); + + @Override + public void operationComplete(ChannelFuture channelFuture) throws Exception { + if (!channelFuture.isSuccess()) { + final EventLoop loop = channelFuture.channel().eventLoop(); + loop.schedule(new Runnable() { + @Override + public void run() { + log.info("服务端连接不上,开始重连操作..."); + client.connect(); + } + }, 5L, TimeUnit.MINUTES); + } else { + log.info("服务端连接成功..."); + } + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java new file mode 100644 index 0000000..ef9ae76 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java @@ -0,0 +1,66 @@ +package com.casic.missiles.modular.util.netty; + +import io.netty.bootstrap.Bootstrap; +import io.netty.channel.*; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioSocketChannel; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public class NettyClient { + + private static Channel channel; + + private String fenceServiceHost = "127.0.0.1"; + private Integer fenceServicePort = 9200; + + public Channel connect() { + doConnect(fenceServiceHost, fenceServicePort); + return channel; + } + + public Channel connect(String host, int port) { + doConnect(host, port); + return channel; + } + + private void doConnect(String host, int port) { + EventLoopGroup workerGroup = new NioEventLoopGroup(); + try { + Bootstrap b = new Bootstrap(); + b.group(workerGroup); + b.channel(NioSocketChannel.class); + b.option(ChannelOption.SO_KEEPALIVE, true); + b.option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(1024 * 1024)); + + b.handler(new ChannelInitializer() { + @Override + public void initChannel(SocketChannel ch) throws Exception { + + ch.pipeline().addLast("decoder", new StringDecoder()); + ch.pipeline().addLast("encoder", new StringEncoder()); + ch.pipeline().addLast(new NettyClientHandler()); + } + }); + + ChannelFuture f = b.connect(host, port); + f.addListener(new ConnectionListener()); + channel = f.channel(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static void writeAndFlush(String message) { + + if (channel != null) { + channel.writeAndFlush(message); + System.out.println("电子围栏客户端发送消息:" + message); + } + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClientHandler.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClientHandler.java new file mode 100644 index 0000000..28093f0 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClientHandler.java @@ -0,0 +1,62 @@ +package com.casic.missiles.modular.util.netty; + +import com.casic.missiles.modular.util.HttpUtil; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import io.netty.channel.EventLoop; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; + +import java.util.concurrent.TimeUnit; + +/** + * 客户端处理器 + **/ +@Slf4j +@Component +public class NettyClientHandler extends ChannelInboundHandlerAdapter { + static boolean handle = true; + + private NettyClient client = new NettyClient(); + + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + log.info("连接成功....."); + } + + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + log.info("断开连接....."); + + //使用过程中断线重连 + final EventLoop eventLoop = ctx.channel().eventLoop(); + eventLoop.schedule(new Runnable() { + @Override + public void run() { + client.connect(); + } + }, 5L, TimeUnit.SECONDS); + super.channelInactive(ctx); + } + + + @Override + public void channelRead(ChannelHandlerContext ctx, Object message) throws Exception { + + if (handle) { + MultiValueMap map = new LinkedMultiValueMap<>(); + map.add("message", message.toString()); + HttpUtil.post("http://127.0.0.1:20311/data/addPerimeterAlarm", map); + } + handle = !handle; + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + cause.printStackTrace(); + ctx.close(); + } +} + diff --git a/casic-web/pom.xml b/casic-web/pom.xml new file mode 100644 index 0000000..8fb0b2c --- /dev/null +++ b/casic-web/pom.xml @@ -0,0 +1,171 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + ../pom.xml + 2.0.0 + + casic-web + 2.0.0 + jar + casic-web + casic web启动入口 + + + + dev + + true + + + dev + + + + test + + test + + + + prod + + prod + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + io.micrometer + micrometer-core + + + + + org.springframework.boot + spring-boot-starter-jdbc + + + + com.casic + casic-core + ${core.version} + + + com.casic + casic-admin-core + ${admin.version} + + + io.springfox + springfox-swagger-ui + + + + + com.casic + casic-admin-support + ${admin.version} + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.dameng + DmJdbcDriver18 + 1.8 + + + com.casic + casic-area-starter + ${admin.version} + + + + com.casic + casic-server + ${pro.version} + + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + + + org.apache.maven.plugins + maven-jar-plugin + ${maven.jar.plugin.version} + + + + /config/*-*.yml + **/MockController.class + + + + com.casic.missiles.CasicApplication + true + ./ + + + + + + org.apache.maven.plugins + maven-assembly-plugin + ${maven.assembly.plugin.version} + + + make-assembly + package + + single + + + + + + org.apache.maven.plugins + maven-war-plugin + ${maven.war.plugin.version} + + + + + src/main/resources + + + /config/*/* + /config/*-*.yml + + true + + + src/main/java + + **/*.xml + + true + + + + \ No newline at end of file diff --git a/casic-web/src/main/build/bin/start.bat b/casic-web/src/main/build/bin/start.bat new file mode 100644 index 0000000..1db4e88 --- /dev/null +++ b/casic-web/src/main/build/bin/start.bat @@ -0,0 +1,4 @@ +@echo off +title ${project.build.finalName} +java -jar ./lib/${project.build.finalName}.jar +@pause diff --git a/casic-web/src/main/build/bin/start.sh b/casic-web/src/main/build/bin/start.sh new file mode 100644 index 0000000..c00b1ef --- /dev/null +++ b/casic-web/src/main/build/bin/start.sh @@ -0,0 +1,2 @@ +java -jar ./lib/${project.build.finalName}.jar + diff --git a/casic-web/src/main/build/package.xml b/casic-web/src/main/build/package.xml new file mode 100644 index 0000000..c9259ad --- /dev/null +++ b/casic-web/src/main/build/package.xml @@ -0,0 +1,43 @@ + + + package + + zip + tar.gz + + true + + + + true + true + lib + runtime + + + + + src/main/build/bin + + start.bat + start.sh + + true + 0744 + / + + + src/main/resources/config + true + + *.yml + /*/* + + /config + + + src/main/resources/i18n + / + + + \ No newline at end of file diff --git a/casic-web/src/main/java/com/casic/missiles/CasicApplication.java b/casic-web/src/main/java/com/casic/missiles/CasicApplication.java new file mode 100644 index 0000000..308dcad --- /dev/null +++ b/casic-web/src/main/java/com/casic/missiles/CasicApplication.java @@ -0,0 +1,29 @@ +package com.casic.missiles; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.ServletComponentScan; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +/** + * SpringBoot方式启动类 + * + * @author lwh + * @Date 2021/06/06 12:06 + */ +@SpringBootApplication +@EnableCaching +@EnableTransactionManagement(proxyTargetClass = true) +@EnableAsync +@Slf4j +public class CasicApplication { + public static void main(String[] args) { + SpringApplication.run(CasicApplication.class, args); + + log.info("CasicApplication is success!"); + } + +} diff --git a/casic-web/src/main/java/com/casic/missiles/CasicServletInitializer.java b/casic-web/src/main/java/com/casic/missiles/CasicServletInitializer.java new file mode 100644 index 0000000..e30585b --- /dev/null +++ b/casic-web/src/main/java/com/casic/missiles/CasicServletInitializer.java @@ -0,0 +1,18 @@ +package com.casic.missiles; + +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; + +/** + * Guns Web程序启动类 + * + * @author fengshuonan + * @date 2017-05-21 9:43 + */ +public class CasicServletInitializer extends SpringBootServletInitializer { + + @Override + protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { + return application.sources(CasicApplication.class); + } +} diff --git a/casic-web/src/main/java/com/casic/missiles/controller/MockController.java b/casic-web/src/main/java/com/casic/missiles/controller/MockController.java new file mode 100644 index 0000000..eae6c54 --- /dev/null +++ b/casic-web/src/main/java/com/casic/missiles/controller/MockController.java @@ -0,0 +1,82 @@ +package com.casic.missiles.controller; + +import cn.hutool.core.util.StrUtil; +import com.casic.missiles.core.application.enums.LoginType; +import com.casic.missiles.core.base.controller.BaseController; +import com.casic.missiles.core.model.auth.AuthUser; +import com.casic.missiles.core.model.auth.CasicCustomToken; +import com.casic.missiles.core.shiro.ShiroKit; +import com.casic.missiles.core.util.RSAUtils; +import com.casic.missiles.model.response.SuccessResponseData; +import com.casic.missiles.modular.domain.constants.PermissionConstants; +import com.casic.missiles.modular.interfaces.log.LogManager; +import com.casic.missiles.modular.interfaces.log.factory.LogTaskFactory; +import com.casic.missiles.modular.system.dto.LoginSuccessDTO; +import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.subject.Subject; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import java.security.NoSuchAlgorithmException; +import java.util.Map; + +import static com.casic.missiles.core.util.HttpContext.getIp; + + +/** + * 仅为mock登录使用 + * + * @author lenovo + */ +@Controller +@RequestMapping("/route") +@Slf4j +public class MockController extends BaseController { + + /** + * 获取mockToken + */ + @GetMapping("/mockToken") + @ResponseBody + public Object mockToken(String username, String password) { + super.getSession().setAttribute(PermissionConstants.IS_APP, false); + SuccessResponseData resultData = new SuccessResponseData(); + if (StrUtil.hasEmpty(username, password)) { + username = "admin"; + password = "111111"; + } + Subject currentUser = ShiroKit.getSubject(); + + try { + Map key = RSAUtils.genKeyPair(); + ShiroKit.getSession().setAttribute(PermissionConstants.PRIVATE_KEY, key.get(RSAUtils.RSAPrivateKey)); + + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + + //token自定义 + CasicCustomToken token = new CasicCustomToken(username, password); + token.setType(LoginType.PASSWORD); + token.setRememberMe(false); + + try { + currentUser.login(token); + } catch (Exception e) { + e.printStackTrace(); + } + AuthUser shiroUser = ShiroKit.getUser(); + super.getSession().setAttribute("shiroUser", shiroUser); + super.getSession().setAttribute("username", shiroUser.getAccount()); + super.getSession().setAttribute(PermissionConstants.SESSION_KEY, shiroUser.getId()); + + LogManager.me().executeLog(LogTaskFactory.loginLog(shiroUser.getId(), getIp())); + + ShiroKit.getSession().setAttribute("sessionFlag", true); + resultData.setData(new LoginSuccessDTO(ShiroKit.getSession().getId().toString(), null)); + resultData.setMessage("登录成功"); + return resultData; + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9e20bc1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea/ +**/target/** +logs/ +*.iml diff --git a/README.md b/README.md new file mode 100644 index 0000000..2fdcd74 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# casic项目 V2.0.0 + +[^_^]: # (Talk is cheap,Show me the code!) + +## 介绍 +基于SpringBoot,致力于做更简洁的后台管理系统,完美整合springboot2.4 + shiro + mybatis-plus ! +基于casic项目代码简洁,注释丰富,上手容易,同时包含许多基础模块(用户管理,角色管理,部门管理,字典管理等10个模块) +可以直接作为一个后台管理系统的脚手架! 2022目标 `更简洁`,`更规范`! + + +#### 其他 +>* [git地址](http://192.168.0.203:8080/gitbucket) +>* [本地免登地址](http://localhost:8083/route/mockToken) diff --git a/casic-server/pom.xml b/casic-server/pom.xml new file mode 100644 index 0000000..c150a12 --- /dev/null +++ b/casic-server/pom.xml @@ -0,0 +1,70 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + 2.0.0 + ../pom.xml + + + casic-server + 2.0.0 + jar + casic-server + casic 的spring boot版本 + + + + + com.casic + casic-core + ${core.version} + provided + + + com.casic + casic-admin-support + ${admin.version} + provided + + + org.springframework.boot + spring-boot-starter-web + ${boot.version} + provided + + + + + com.hikvision.ga + artemis-http-client + 1.1.3 + + + commons-io + commons-io + + + org.springframework.boot + spring-boot-starter-websocket + 2.4.5 + + + io.netty + netty-all + 4.1.42.Final + + + + + + src/main/java + + **/*.xml + + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java new file mode 100644 index 0000000..3a60b9e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java @@ -0,0 +1,36 @@ +package com.casic.missiles.modular.async; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.TaskExecutor; +import org.springframework.scheduling.annotation.AsyncConfigurer; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadPoolExecutor; + +@Configuration +@EnableAsync +public class AsyncConfig implements AsyncConfigurer { + @Override + public Executor getAsyncExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + //核心线程数 + executor.setCorePoolSize(5); + //最大线程数 + executor.setMaxPoolSize(10); + //队列容量 + executor.setQueueCapacity(20); + //设置线程活跃时间(秒) + executor.setKeepAliveSeconds(60); + //默认线程名称 + executor.setThreadNamePrefix("user-rpt-"); + //拒绝策略 + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + //等待所有任务结束后再关闭线程池 + executor.setWaitForTasksToCompleteOnShutdown(true); + return executor; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java new file mode 100644 index 0000000..8ca554c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java @@ -0,0 +1,18 @@ +package com.casic.missiles.modular.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +// tomcat启动无需配置 +@Configuration +public class WebSocketConfig { + /** + * 注入ServerEndpointExporter, + * 这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint + */ + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java new file mode 100644 index 0000000..34fe2cd --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java @@ -0,0 +1,39 @@ +package com.casic.missiles.modular.controller; + + +import com.casic.missiles.model.application.event.core.EventPublisher; +import com.casic.missiles.model.application.event.enums.ModelEventTypeEnum; +import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.modular.event.UserEvent; +import com.casic.missiles.modular.system.model.User; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +/** + * @Description: DemoController + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@RestController +@RequestMapping("/demo") +public class DemoController { + @Autowired + private EventPublisher publisher; + + /** + * 获取mockToken + */ + @PostMapping("/list") + @ResponseBody + public Object list() { + User user = new User(); + user.setAccount("张三"); + publisher.publishEvent(new UserEvent(ModelEventTypeEnum.ADD, user)); + return ResponseData.success(); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java new file mode 100644 index 0000000..aff2889 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java @@ -0,0 +1,23 @@ +package com.casic.missiles.modular.event; + +import com.casic.missiles.model.application.event.core.ModelEvent; +import com.casic.missiles.model.application.event.type.AbstractEventTypeEnum; +import com.casic.missiles.modular.system.model.User; + +/** + * @Description: 用户事件 + * @Author: wangpeng + * @Date: 2022/7/17 11:23 + */ +public class UserEvent extends ModelEvent { + /** + * Create a new {@code ApplicationEvent}. + * + * @param type 事件类型 + * @param source the object on which the event initially occurred or with + * which the event is associated (never {@code null}) + */ + public UserEvent(AbstractEventTypeEnum type, User source) { + super(type, source); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java new file mode 100644 index 0000000..8f9603e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.core.application.event.UserLoginEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserOneListener { + @EventListener + public void onApplicationEvent(UserLoginEvent event) { + log.debug("用户1订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java new file mode 100644 index 0000000..0bd52a3 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.model.application.event.core.EventSubscriber; +import com.casic.missiles.modular.event.UserEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserTwoListener extends EventSubscriber { + @Override + public void onApplicationEvent(UserEvent event) { + log.debug("用户2订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java new file mode 100644 index 0000000..4012170 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java @@ -0,0 +1,88 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang3.StringUtils; +import sun.misc.BASE64Decoder; + +import java.io.*; + +public class Base64Util { + /** + * base64字符串转换成图片 + * + * @param imgStr base64字符串 + * @param imgFilePath 图片存放路径 + * @return + * @author ZHANGJL + * @dateTime 2018-02-23 14:42:17 + */ + public static boolean Base64ToImage(String imgStr, String imgFilePath, String fileDir) { // 对字节数组字符串进行Base64解码并生成图片 + + if (StringUtils.isEmpty(imgStr)) // 图像数据为空 + return false; + + imgStr = imgStr.substring(imgStr.indexOf(",") + 1); + + BASE64Decoder decoder = new BASE64Decoder(); + try { + // Base64解码 + byte[] b = decoder.decodeBuffer(imgStr); + + for (int i = 0; i < b.length; ++i) { + if (b[i] < 0) {// 调整异常数据 + b[i] += 256; + } + } + //如果已存在图像,先删除 + File file = new File(fileDir+File.separator + imgFilePath); + if (file.exists() && file.isFile()) { + file.delete(); + } + File dir = new File(fileDir); + if (!dir.exists()) { + dir.mkdirs(); + } + file = new File(fileDir+File.separator+imgFilePath); + file.createNewFile(); +// ImageIO.write(bImage, "bmp", name); + OutputStream out = new FileOutputStream(fileDir+File.separator+imgFilePath); + out.write(b); + out.flush(); + out.close(); + + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + + } + + public static String getBase64FromInputStream(InputStream in) { + // 将图片文件转化为字节数组字符串,并对其进行Base64编码处理 + byte[] data = null; + // 读取图片字节数组 + try { + ByteArrayOutputStream swapStream = new ByteArrayOutputStream(); + byte[] buff = new byte[100]; + int rc = 0; + while ((rc = in.read(buff, 0, 100)) > 0) { + swapStream.write(buff, 0, rc); + } + data = swapStream.toByteArray(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return new String(Base64.encodeBase64(data)); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java new file mode 100644 index 0000000..9c93895 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java @@ -0,0 +1,75 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.lang3.StringUtils; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class CommonUtil { + + public static String CutId(String id) { + return id.substring(6, 10) + "-" + id.substring(10, 12) + "-" + id.substring(12, 14); + } + + public static boolean isIDNumber(String IDNumber) { + if (IDNumber == null || "".equals(IDNumber)) { + return false; + } + // 定义判别用户身份证号的正则表达式(15位或者18位,最后一位可以为字母) + String regularExpression = + "(^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|" + + "(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}$)"; + boolean matches = IDNumber.matches(regularExpression); + // 判断第18位校验值 + if (matches) { + if (IDNumber.length() == 18) { + try { + char[] charArray = IDNumber.toCharArray(); + // 前十七位加权因子 + int[] idCardWi = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; + // 这是除以11后,可能产生的11位余数对应的验证码 + String[] idCardY = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"}; + int sum = 0; + for (int i = 0; i < idCardWi.length; i++) { + int current = Integer.parseInt(String.valueOf(charArray[i])); + int count = current * idCardWi[i]; + sum += count; + } + char idCardLast = charArray[17]; + int idCardMod = sum % 11; + if (idCardY[idCardMod].toUpperCase() + .equals(String.valueOf(idCardLast).toUpperCase())) { + return true; + } else { + System.out.println("身份证最后一位:" + String.valueOf(idCardLast).toUpperCase() + + "错误,正确的应该是:" + idCardY[idCardMod].toUpperCase()); + return false; + } + + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } else { + return false; + } + } + return matches; + } + + + public static boolean CheckMobilePhoneNum(String phoneNum) { + if (StringUtils.isEmpty(phoneNum)) + return true; + String regex = "^(1[3-9]\\d{9}$)"; + if (phoneNum.length() == 11) { + Pattern p = Pattern.compile(regex); + Matcher m = p.matcher(phoneNum); + if (m.matches()) { + return true; + } + } + return false; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java new file mode 100644 index 0000000..191ef79 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java @@ -0,0 +1,116 @@ +package com.casic.missiles.modular.util; + + +import javafx.util.Pair; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +/** + * Created by Administrator on 2015/2/25. + */ +public class DateUtils { + public static SimpleDateFormat sdf_day = new SimpleDateFormat("yyyy-MM-dd"); + public static SimpleDateFormat sdf_day_time = new SimpleDateFormat("yyyyMMddhhmmss"); + public static final SimpleDateFormat sdf4 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + public static final SimpleDateFormat sdf5 = new SimpleDateFormat("HH:mm:ss"); + + + /** + * 获取当年的第一天 + * + * @return + */ + public static Date getCurrYearFirst() { + Calendar currCal = Calendar.getInstance(); + int currentYear = currCal.get(Calendar.YEAR); + return getYearFirst(currentYear); + } + + + /** + * 获取某年第一天日期 + * + * @param year 年份 + * @return Date + */ + public static Date getYearFirst(int year) { + Calendar calendar = Calendar.getInstance(); + calendar.clear(); + calendar.set(Calendar.YEAR, year); + Date currYearFirst = calendar.getTime(); + return currYearFirst; + } + + /** + * 最近7日(不包括今日) + */ + public static Pair getLastSevenDays() { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, -7); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 最近n日(不包括今日) + */ + public static Pair getLastNDays(int n) { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, n * -1); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 日期时间加n天 + */ + public static String addDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf4.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf4.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 日期加n天 + */ + public static String addNDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf_day.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf_day.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 昨日 + */ + public static String getYesterday() { + + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.DATE, -2); + return sdf_day.format(calendar.getTime()); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java new file mode 100644 index 0000000..da0f8ee --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java @@ -0,0 +1,49 @@ +package com.casic.missiles.modular.util; + +import com.hikvision.artemis.sdk.ArtemisHttpUtil; +import com.hikvision.artemis.sdk.config.ArtemisConfig; + +import java.util.HashMap; +import java.util.Map; + +public class HikUtil { + + public static String hikApi(String uri, String body) { + + /** + * STEP1:设置平台参数,根据实际情况,设置host appkey appsecret 三个参数. + */ + ArtemisConfig.host = "192.168.1.22:443"; // artemis网关服务器ip端口 + ArtemisConfig.appKey = "25766251"; // 秘钥appkey + ArtemisConfig.appSecret = "h2o6zXtzCmt8eaOaMkXb";// 秘钥appSecret + + /** + * STEP2:设置OpenAPI接口的上下文 + */ + final String ARTEMIS_PATH = "/artemis"; + + /** + * STEP3:设置接口的URI地址 + */ + final String previewURLsApi = ARTEMIS_PATH + uri; + Map path = new HashMap(2) { + { + put("https://", previewURLsApi);//根据现场环境部署确认是http还是https + } + }; + + /** + * STEP4:设置参数提交方式 + */ + String contentType = "application/json"; + + /** + * STEP5:组装请求参数 + */ + /** + * STEP6:调用接口 + */ + String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, contentType, null);// post请求application/json类型参数 + return result; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java new file mode 100644 index 0000000..4867144 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java @@ -0,0 +1,149 @@ +package com.casic.missiles.modular.util; + +import org.springframework.http.*; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; + +/** + * @Description: http请求工具类 + * @Author: wangpeng + * @Date: 2022/7/17 11:49 + */ +public class HttpUtil { + /** + * get请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String get(String url, MultiValueMap params) { + return get(url, params, null); + } + + /** + * get请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String get(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.GET); + } + + /** + * post请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String post(String url, MultiValueMap params) { + return post(url, params, null); + } + + /** + * post请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String post(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.POST); + } + + /** + * put请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String put(String url, MultiValueMap params) { + return put(url, params, null); + } + + /** + * put请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String put(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.PUT); + } + + /** + * delete请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String delete(String url, MultiValueMap params) { + return delete(url, params, null); + } + + /** + * delete请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String delete(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.DELETE); + } + + /** + * 表单请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @param method 请求方式 + * @return + */ + public static String request(String url, MultiValueMap params, MultiValueMap headers, HttpMethod method) { + if (params == null) { + params = new LinkedMultiValueMap<>(); + } + return request(url, params, headers, method, MediaType.APPLICATION_FORM_URLENCODED); + } + + /** + * http请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @param method 请求方式 + * @param mediaType 参数类型 + * @return + */ + public static String request(String url, Object params, MultiValueMap headers, HttpMethod method, MediaType mediaType) { + if (url == null || url.trim().isEmpty()) { + return null; + } + RestTemplate client = new RestTemplate(); + // header + HttpHeaders httpHeaders = new HttpHeaders(); + if (headers != null) { +// httpHeaders.addAll(headers); + httpHeaders.putAll(headers); + } + // 提交方式:表单、json + httpHeaders.setContentType(mediaType); + HttpEntity httpEntity = new HttpEntity(params, httpHeaders); + ResponseEntity response = client.exchange(url, method, httpEntity, String.class); + return response.getBody(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java new file mode 100644 index 0000000..19d8d67 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java @@ -0,0 +1,30 @@ +package com.casic.missiles.modular.util; + +public class SelectDTO { + private String name; + private String value; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public SelectDTO() { + } + + public SelectDTO(String name, String value) { + this.name = name; + this.value = value; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java new file mode 100644 index 0000000..0bd484c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java @@ -0,0 +1,28 @@ +package com.casic.missiles.modular.util; + +public class SocketConst { + + /** + * 新增授权socket前缀 + */ + public static final String SOCKET_PREFIX_ADD_PERMISSION = "addPermission:"; + + /** + * 取消授权socket前缀 + */ + public static final String SOCKET_PREFIX_DELETE_PERMISSION = "deletePermission:"; + + /** + * 人员数据下发socket前缀 + */ + public static final String SOCKET_PREFIX_ADD_PERSON = "addPerson:"; + + /** + * socket返回成功信息 + */ + public static final String SOCKET_SUCCESS_MSG = "ok"; + /** + * 人员数据下发socket前缀 + */ + public static final String SOCKET_PREFIX_DELETE_PERSON = "deletePerson:"; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java new file mode 100644 index 0000000..0452bca --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java @@ -0,0 +1,90 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.io.IOUtils; +import org.springframework.stereotype.Component; + +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.text.SimpleDateFormat; +import java.util.Date; + +@Component +public class SocketUtil { + + public static byte[] sendMessage(String ip, int port, String msg) { + byte[] data = new byte[20]; + + System.out.println("往 " + ip + ":" + port + " 发送数据:" + msg); + InputStream in = null; + OutputStream out = null; + Socket socket = null; + try { + socket = new Socket(); + socket.connect(new InetSocketAddress(ip, port), 1000); + socket.setSoTimeout(2000); + // 向服务端发送数据 + out = socket.getOutputStream(); + out.write(hexString2Bytes(msg)); + out.flush(); + //socket.shutdownOutput(); + // 读取服务端返回数据 + in = socket.getInputStream(); + in.read(data); + } catch (Exception e) { + e.printStackTrace(); + } finally { + IOUtils.closeQuietly(in); + IOUtils.closeQuietly(out); + IOUtils.closeQuietly(socket); + } + return data; + } + + private static int code = 0; + + public static void main(String[] args) { +// byte[] dd = sendMessage("192.168.5.211",6001,"090300000002C543"); + + String dateStr = new SimpleDateFormat("yyMMddHHmmssSSS").format(new Date()); + //String dd = dateStr + String.format("%04d",++code); + + System.out.println(dateStr); + } + + /** + * 返回由字节数组转换来的 16 位有符号整数 + * + * @param bytes 字节数组 + * @return 由两个字节构成的 16 位有符号整数 + */ + public static short toShort(byte[] bytes) { + return (short) ((0xff & bytes[0]) | (0xff00 & (bytes[1] << 8))); + + } + + + public static byte[] hexString2Bytes(String hex) { + if ((hex == null) || (hex.equals(""))) { + return null; + } else if (hex.length() % 2 != 0) { + return null; + } else { + hex = hex.toUpperCase(); + int len = hex.length() / 2; + byte[] b = new byte[len]; + char[] hc = hex.toCharArray(); + for (int i = 0; i < len; i++) { + int p = 2 * i; + b[i] = (byte) (charToByte(hc[p]) << 4 | charToByte(hc[p + 1])); + } + return b; + } + } + + private static byte charToByte(char c) { + return (byte) "0123456789ABCDEF".indexOf(c); + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java b/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java new file mode 100644 index 0000000..9b4155c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java @@ -0,0 +1,105 @@ +package com.casic.missiles.modular.util; + +import org.springframework.stereotype.Component; + +import javax.websocket.OnClose; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.PathParam; +import javax.websocket.server.ServerEndpoint; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CopyOnWriteArraySet; + +/** + * @Description: 此注解相当于设置访问URL + * @Author: wangpeng + * @Date: 2022/7/17 11:48 + */ +@Component +@ServerEndpoint("/websocket/{userId}") +public class WebSocket { + private Session session; + + private static CopyOnWriteArraySet webSockets = new CopyOnWriteArraySet<>(); + private static Map sessionPool = new HashMap(); + + @OnOpen + public void onOpen(Session session, @PathParam(value = "userId") String userId) { + this.session = session; + webSockets.add(this); + sessionPool.put(userId, session); + System.out.println(userId + "【websocket消息】有新的连接,总数为:" + webSockets.size()); + } + + @OnClose + public void onClose() { + webSockets.remove(this); + System.out.println("【websocket消息】连接断开,总数为:" + webSockets.size()); + } + + @OnMessage + public void onMessage(String message) { + System.out.println("【websocket消息】收到客户端消息:" + message); + } + + // 此为广播消息 + public void sendAllMessage(String message) { + for (WebSocket webSocket : webSockets) { + System.out.println("【websocket消息】广播消息:" + message); + try { + webSocket.session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + // 发送列表消息 + public void sendListMessage(List userIds, String message) { + System.out.println("【websocket消息】列表消息:" + message); + for (String userId : userIds) { + Session session = sessionPool.get(userId); + if (session != null) { + try { + session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + + // 发送列表消息 + +// public void sendListMessage(List userIds, Object data){ +// System.out.println("【websocket消息】列表消息:"+data); +// for (String userId : userIds) { +// Session session = sessionPool.get(userId); +// if (session != null) { +// try { +//// session.getAsyncRemote().sendText(message); +// session.getAsyncRemote().sendObject(data); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// } +// } + + // 此为单点消息 + public void sendOneMessage(String userId, String message) { + System.out.println("【websocket消息】单点消息:" + message); + Session session = sessionPool.get(userId); + if (session != null) { + try { + session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java new file mode 100644 index 0000000..0c1f5f1 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java @@ -0,0 +1,115 @@ +package com.casic.missiles.modular.util; + +import org.springframework.web.multipart.MultipartFile; + +import java.io.*; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipInputStream; + +/** + * @Description: 读取zip文件内容 + * @Author: wangpeng + * @Date: 2022/7/17 11:48 + */ +public class ZipFileUtil { + public static List getFile(String fileName) { + File file = new File(fileName); + ZipFile zipFile = null; + ZipInputStream zin = null; + FileInputStream fis = null; + List selectDTOList = new ArrayList<>(); + try { + Charset gbk = Charset.forName("GBK"); + zipFile = new ZipFile(file, gbk); + fis = new FileInputStream(file); + zin = new ZipInputStream(fis, gbk); + + ZipEntry ze = null; + while ((ze = zin.getNextEntry()) != null) { + String path = ze.getName(); + System.out.println(path); + if (!ze.isDirectory()) { + InputStream inputStream = zipFile.getInputStream(ze); + String base64Photo = Base64Util.getBase64FromInputStream(inputStream); +// List texts = IOUtils.readLines(inputStream); +// for (String text : texts) { +// System.out.println(" " + text); +// } + selectDTOList.add(new SelectDTO(path.substring(path.indexOf("/")+1), "data:image/png;base64,"+base64Photo)); + inputStream.close(); + } + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (zin != null) { + zin.closeEntry(); + zin.close(); + } + if (fis != null) + fis.close(); + if (zipFile != null) + zipFile.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return selectDTOList; + } + + + /** + * MultipartFile 转 File + * + * @param file + * @throws Exception + */ + public static File multipartFileToFile(MultipartFile file) throws Exception { + + File toFile = null; + if (file.equals("") || file.getSize() <= 0) { + file = null; + } else { + InputStream ins = null; + ins = file.getInputStream(); + toFile = new File(file.getOriginalFilename()); + inputStreamToFile(ins, toFile); + ins.close(); + } + return toFile; + } + + //获取流文件 + private static void inputStreamToFile(InputStream ins, File file) { + try { + OutputStream os = new FileOutputStream(file); + int bytesRead = 0; + byte[] buffer = new byte[8192]; + while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) { + os.write(buffer, 0, bytesRead); + } + os.close(); + ins.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 删除本地临时文件 + * + * @param file + */ + public static void delteTempFile(File file) { + if (file != null) { + File del = new File(file.toURI()); + del.delete(); + } + } +} + diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java new file mode 100644 index 0000000..ae93a17 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java @@ -0,0 +1,34 @@ +package com.casic.missiles.modular.util.netty; + +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.EventLoop; +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.TimeUnit; + +/** + * 负责监听启动时连接失败,重新连接功能 + * + */ +@Slf4j +public class ConnectionListener implements ChannelFutureListener { + + private NettyClient client = new NettyClient(); + + @Override + public void operationComplete(ChannelFuture channelFuture) throws Exception { + if (!channelFuture.isSuccess()) { + final EventLoop loop = channelFuture.channel().eventLoop(); + loop.schedule(new Runnable() { + @Override + public void run() { + log.info("服务端连接不上,开始重连操作..."); + client.connect(); + } + }, 5L, TimeUnit.MINUTES); + } else { + log.info("服务端连接成功..."); + } + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java new file mode 100644 index 0000000..ef9ae76 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java @@ -0,0 +1,66 @@ +package com.casic.missiles.modular.util.netty; + +import io.netty.bootstrap.Bootstrap; +import io.netty.channel.*; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioSocketChannel; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public class NettyClient { + + private static Channel channel; + + private String fenceServiceHost = "127.0.0.1"; + private Integer fenceServicePort = 9200; + + public Channel connect() { + doConnect(fenceServiceHost, fenceServicePort); + return channel; + } + + public Channel connect(String host, int port) { + doConnect(host, port); + return channel; + } + + private void doConnect(String host, int port) { + EventLoopGroup workerGroup = new NioEventLoopGroup(); + try { + Bootstrap b = new Bootstrap(); + b.group(workerGroup); + b.channel(NioSocketChannel.class); + b.option(ChannelOption.SO_KEEPALIVE, true); + b.option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(1024 * 1024)); + + b.handler(new ChannelInitializer() { + @Override + public void initChannel(SocketChannel ch) throws Exception { + + ch.pipeline().addLast("decoder", new StringDecoder()); + ch.pipeline().addLast("encoder", new StringEncoder()); + ch.pipeline().addLast(new NettyClientHandler()); + } + }); + + ChannelFuture f = b.connect(host, port); + f.addListener(new ConnectionListener()); + channel = f.channel(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static void writeAndFlush(String message) { + + if (channel != null) { + channel.writeAndFlush(message); + System.out.println("电子围栏客户端发送消息:" + message); + } + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClientHandler.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClientHandler.java new file mode 100644 index 0000000..28093f0 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClientHandler.java @@ -0,0 +1,62 @@ +package com.casic.missiles.modular.util.netty; + +import com.casic.missiles.modular.util.HttpUtil; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import io.netty.channel.EventLoop; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; + +import java.util.concurrent.TimeUnit; + +/** + * 客户端处理器 + **/ +@Slf4j +@Component +public class NettyClientHandler extends ChannelInboundHandlerAdapter { + static boolean handle = true; + + private NettyClient client = new NettyClient(); + + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + log.info("连接成功....."); + } + + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + log.info("断开连接....."); + + //使用过程中断线重连 + final EventLoop eventLoop = ctx.channel().eventLoop(); + eventLoop.schedule(new Runnable() { + @Override + public void run() { + client.connect(); + } + }, 5L, TimeUnit.SECONDS); + super.channelInactive(ctx); + } + + + @Override + public void channelRead(ChannelHandlerContext ctx, Object message) throws Exception { + + if (handle) { + MultiValueMap map = new LinkedMultiValueMap<>(); + map.add("message", message.toString()); + HttpUtil.post("http://127.0.0.1:20311/data/addPerimeterAlarm", map); + } + handle = !handle; + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + cause.printStackTrace(); + ctx.close(); + } +} + diff --git a/casic-web/pom.xml b/casic-web/pom.xml new file mode 100644 index 0000000..8fb0b2c --- /dev/null +++ b/casic-web/pom.xml @@ -0,0 +1,171 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + ../pom.xml + 2.0.0 + + casic-web + 2.0.0 + jar + casic-web + casic web启动入口 + + + + dev + + true + + + dev + + + + test + + test + + + + prod + + prod + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + io.micrometer + micrometer-core + + + + + org.springframework.boot + spring-boot-starter-jdbc + + + + com.casic + casic-core + ${core.version} + + + com.casic + casic-admin-core + ${admin.version} + + + io.springfox + springfox-swagger-ui + + + + + com.casic + casic-admin-support + ${admin.version} + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.dameng + DmJdbcDriver18 + 1.8 + + + com.casic + casic-area-starter + ${admin.version} + + + + com.casic + casic-server + ${pro.version} + + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + + + org.apache.maven.plugins + maven-jar-plugin + ${maven.jar.plugin.version} + + + + /config/*-*.yml + **/MockController.class + + + + com.casic.missiles.CasicApplication + true + ./ + + + + + + org.apache.maven.plugins + maven-assembly-plugin + ${maven.assembly.plugin.version} + + + make-assembly + package + + single + + + + + + org.apache.maven.plugins + maven-war-plugin + ${maven.war.plugin.version} + + + + + src/main/resources + + + /config/*/* + /config/*-*.yml + + true + + + src/main/java + + **/*.xml + + true + + + + \ No newline at end of file diff --git a/casic-web/src/main/build/bin/start.bat b/casic-web/src/main/build/bin/start.bat new file mode 100644 index 0000000..1db4e88 --- /dev/null +++ b/casic-web/src/main/build/bin/start.bat @@ -0,0 +1,4 @@ +@echo off +title ${project.build.finalName} +java -jar ./lib/${project.build.finalName}.jar +@pause diff --git a/casic-web/src/main/build/bin/start.sh b/casic-web/src/main/build/bin/start.sh new file mode 100644 index 0000000..c00b1ef --- /dev/null +++ b/casic-web/src/main/build/bin/start.sh @@ -0,0 +1,2 @@ +java -jar ./lib/${project.build.finalName}.jar + diff --git a/casic-web/src/main/build/package.xml b/casic-web/src/main/build/package.xml new file mode 100644 index 0000000..c9259ad --- /dev/null +++ b/casic-web/src/main/build/package.xml @@ -0,0 +1,43 @@ + + + package + + zip + tar.gz + + true + + + + true + true + lib + runtime + + + + + src/main/build/bin + + start.bat + start.sh + + true + 0744 + / + + + src/main/resources/config + true + + *.yml + /*/* + + /config + + + src/main/resources/i18n + / + + + \ No newline at end of file diff --git a/casic-web/src/main/java/com/casic/missiles/CasicApplication.java b/casic-web/src/main/java/com/casic/missiles/CasicApplication.java new file mode 100644 index 0000000..308dcad --- /dev/null +++ b/casic-web/src/main/java/com/casic/missiles/CasicApplication.java @@ -0,0 +1,29 @@ +package com.casic.missiles; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.ServletComponentScan; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +/** + * SpringBoot方式启动类 + * + * @author lwh + * @Date 2021/06/06 12:06 + */ +@SpringBootApplication +@EnableCaching +@EnableTransactionManagement(proxyTargetClass = true) +@EnableAsync +@Slf4j +public class CasicApplication { + public static void main(String[] args) { + SpringApplication.run(CasicApplication.class, args); + + log.info("CasicApplication is success!"); + } + +} diff --git a/casic-web/src/main/java/com/casic/missiles/CasicServletInitializer.java b/casic-web/src/main/java/com/casic/missiles/CasicServletInitializer.java new file mode 100644 index 0000000..e30585b --- /dev/null +++ b/casic-web/src/main/java/com/casic/missiles/CasicServletInitializer.java @@ -0,0 +1,18 @@ +package com.casic.missiles; + +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; + +/** + * Guns Web程序启动类 + * + * @author fengshuonan + * @date 2017-05-21 9:43 + */ +public class CasicServletInitializer extends SpringBootServletInitializer { + + @Override + protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { + return application.sources(CasicApplication.class); + } +} diff --git a/casic-web/src/main/java/com/casic/missiles/controller/MockController.java b/casic-web/src/main/java/com/casic/missiles/controller/MockController.java new file mode 100644 index 0000000..eae6c54 --- /dev/null +++ b/casic-web/src/main/java/com/casic/missiles/controller/MockController.java @@ -0,0 +1,82 @@ +package com.casic.missiles.controller; + +import cn.hutool.core.util.StrUtil; +import com.casic.missiles.core.application.enums.LoginType; +import com.casic.missiles.core.base.controller.BaseController; +import com.casic.missiles.core.model.auth.AuthUser; +import com.casic.missiles.core.model.auth.CasicCustomToken; +import com.casic.missiles.core.shiro.ShiroKit; +import com.casic.missiles.core.util.RSAUtils; +import com.casic.missiles.model.response.SuccessResponseData; +import com.casic.missiles.modular.domain.constants.PermissionConstants; +import com.casic.missiles.modular.interfaces.log.LogManager; +import com.casic.missiles.modular.interfaces.log.factory.LogTaskFactory; +import com.casic.missiles.modular.system.dto.LoginSuccessDTO; +import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.subject.Subject; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import java.security.NoSuchAlgorithmException; +import java.util.Map; + +import static com.casic.missiles.core.util.HttpContext.getIp; + + +/** + * 仅为mock登录使用 + * + * @author lenovo + */ +@Controller +@RequestMapping("/route") +@Slf4j +public class MockController extends BaseController { + + /** + * 获取mockToken + */ + @GetMapping("/mockToken") + @ResponseBody + public Object mockToken(String username, String password) { + super.getSession().setAttribute(PermissionConstants.IS_APP, false); + SuccessResponseData resultData = new SuccessResponseData(); + if (StrUtil.hasEmpty(username, password)) { + username = "admin"; + password = "111111"; + } + Subject currentUser = ShiroKit.getSubject(); + + try { + Map key = RSAUtils.genKeyPair(); + ShiroKit.getSession().setAttribute(PermissionConstants.PRIVATE_KEY, key.get(RSAUtils.RSAPrivateKey)); + + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + + //token自定义 + CasicCustomToken token = new CasicCustomToken(username, password); + token.setType(LoginType.PASSWORD); + token.setRememberMe(false); + + try { + currentUser.login(token); + } catch (Exception e) { + e.printStackTrace(); + } + AuthUser shiroUser = ShiroKit.getUser(); + super.getSession().setAttribute("shiroUser", shiroUser); + super.getSession().setAttribute("username", shiroUser.getAccount()); + super.getSession().setAttribute(PermissionConstants.SESSION_KEY, shiroUser.getId()); + + LogManager.me().executeLog(LogTaskFactory.loginLog(shiroUser.getId(), getIp())); + + ShiroKit.getSession().setAttribute("sessionFlag", true); + resultData.setData(new LoginSuccessDTO(ShiroKit.getSession().getId().toString(), null)); + resultData.setMessage("登录成功"); + return resultData; + } +} diff --git a/casic-web/src/main/resources/META-INF/spring-devtools.properties b/casic-web/src/main/resources/META-INF/spring-devtools.properties new file mode 100644 index 0000000..e3b0a7f --- /dev/null +++ b/casic-web/src/main/resources/META-INF/spring-devtools.properties @@ -0,0 +1 @@ +restart.include.beetl=/beetl-2.7.15.jar \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9e20bc1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea/ +**/target/** +logs/ +*.iml diff --git a/README.md b/README.md new file mode 100644 index 0000000..2fdcd74 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# casic项目 V2.0.0 + +[^_^]: # (Talk is cheap,Show me the code!) + +## 介绍 +基于SpringBoot,致力于做更简洁的后台管理系统,完美整合springboot2.4 + shiro + mybatis-plus ! +基于casic项目代码简洁,注释丰富,上手容易,同时包含许多基础模块(用户管理,角色管理,部门管理,字典管理等10个模块) +可以直接作为一个后台管理系统的脚手架! 2022目标 `更简洁`,`更规范`! + + +#### 其他 +>* [git地址](http://192.168.0.203:8080/gitbucket) +>* [本地免登地址](http://localhost:8083/route/mockToken) diff --git a/casic-server/pom.xml b/casic-server/pom.xml new file mode 100644 index 0000000..c150a12 --- /dev/null +++ b/casic-server/pom.xml @@ -0,0 +1,70 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + 2.0.0 + ../pom.xml + + + casic-server + 2.0.0 + jar + casic-server + casic 的spring boot版本 + + + + + com.casic + casic-core + ${core.version} + provided + + + com.casic + casic-admin-support + ${admin.version} + provided + + + org.springframework.boot + spring-boot-starter-web + ${boot.version} + provided + + + + + com.hikvision.ga + artemis-http-client + 1.1.3 + + + commons-io + commons-io + + + org.springframework.boot + spring-boot-starter-websocket + 2.4.5 + + + io.netty + netty-all + 4.1.42.Final + + + + + + src/main/java + + **/*.xml + + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java new file mode 100644 index 0000000..3a60b9e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java @@ -0,0 +1,36 @@ +package com.casic.missiles.modular.async; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.TaskExecutor; +import org.springframework.scheduling.annotation.AsyncConfigurer; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadPoolExecutor; + +@Configuration +@EnableAsync +public class AsyncConfig implements AsyncConfigurer { + @Override + public Executor getAsyncExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + //核心线程数 + executor.setCorePoolSize(5); + //最大线程数 + executor.setMaxPoolSize(10); + //队列容量 + executor.setQueueCapacity(20); + //设置线程活跃时间(秒) + executor.setKeepAliveSeconds(60); + //默认线程名称 + executor.setThreadNamePrefix("user-rpt-"); + //拒绝策略 + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + //等待所有任务结束后再关闭线程池 + executor.setWaitForTasksToCompleteOnShutdown(true); + return executor; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java new file mode 100644 index 0000000..8ca554c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java @@ -0,0 +1,18 @@ +package com.casic.missiles.modular.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +// tomcat启动无需配置 +@Configuration +public class WebSocketConfig { + /** + * 注入ServerEndpointExporter, + * 这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint + */ + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java new file mode 100644 index 0000000..34fe2cd --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java @@ -0,0 +1,39 @@ +package com.casic.missiles.modular.controller; + + +import com.casic.missiles.model.application.event.core.EventPublisher; +import com.casic.missiles.model.application.event.enums.ModelEventTypeEnum; +import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.modular.event.UserEvent; +import com.casic.missiles.modular.system.model.User; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +/** + * @Description: DemoController + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@RestController +@RequestMapping("/demo") +public class DemoController { + @Autowired + private EventPublisher publisher; + + /** + * 获取mockToken + */ + @PostMapping("/list") + @ResponseBody + public Object list() { + User user = new User(); + user.setAccount("张三"); + publisher.publishEvent(new UserEvent(ModelEventTypeEnum.ADD, user)); + return ResponseData.success(); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java new file mode 100644 index 0000000..aff2889 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java @@ -0,0 +1,23 @@ +package com.casic.missiles.modular.event; + +import com.casic.missiles.model.application.event.core.ModelEvent; +import com.casic.missiles.model.application.event.type.AbstractEventTypeEnum; +import com.casic.missiles.modular.system.model.User; + +/** + * @Description: 用户事件 + * @Author: wangpeng + * @Date: 2022/7/17 11:23 + */ +public class UserEvent extends ModelEvent { + /** + * Create a new {@code ApplicationEvent}. + * + * @param type 事件类型 + * @param source the object on which the event initially occurred or with + * which the event is associated (never {@code null}) + */ + public UserEvent(AbstractEventTypeEnum type, User source) { + super(type, source); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java new file mode 100644 index 0000000..8f9603e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.core.application.event.UserLoginEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserOneListener { + @EventListener + public void onApplicationEvent(UserLoginEvent event) { + log.debug("用户1订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java new file mode 100644 index 0000000..0bd52a3 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.model.application.event.core.EventSubscriber; +import com.casic.missiles.modular.event.UserEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserTwoListener extends EventSubscriber { + @Override + public void onApplicationEvent(UserEvent event) { + log.debug("用户2订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java new file mode 100644 index 0000000..4012170 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java @@ -0,0 +1,88 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang3.StringUtils; +import sun.misc.BASE64Decoder; + +import java.io.*; + +public class Base64Util { + /** + * base64字符串转换成图片 + * + * @param imgStr base64字符串 + * @param imgFilePath 图片存放路径 + * @return + * @author ZHANGJL + * @dateTime 2018-02-23 14:42:17 + */ + public static boolean Base64ToImage(String imgStr, String imgFilePath, String fileDir) { // 对字节数组字符串进行Base64解码并生成图片 + + if (StringUtils.isEmpty(imgStr)) // 图像数据为空 + return false; + + imgStr = imgStr.substring(imgStr.indexOf(",") + 1); + + BASE64Decoder decoder = new BASE64Decoder(); + try { + // Base64解码 + byte[] b = decoder.decodeBuffer(imgStr); + + for (int i = 0; i < b.length; ++i) { + if (b[i] < 0) {// 调整异常数据 + b[i] += 256; + } + } + //如果已存在图像,先删除 + File file = new File(fileDir+File.separator + imgFilePath); + if (file.exists() && file.isFile()) { + file.delete(); + } + File dir = new File(fileDir); + if (!dir.exists()) { + dir.mkdirs(); + } + file = new File(fileDir+File.separator+imgFilePath); + file.createNewFile(); +// ImageIO.write(bImage, "bmp", name); + OutputStream out = new FileOutputStream(fileDir+File.separator+imgFilePath); + out.write(b); + out.flush(); + out.close(); + + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + + } + + public static String getBase64FromInputStream(InputStream in) { + // 将图片文件转化为字节数组字符串,并对其进行Base64编码处理 + byte[] data = null; + // 读取图片字节数组 + try { + ByteArrayOutputStream swapStream = new ByteArrayOutputStream(); + byte[] buff = new byte[100]; + int rc = 0; + while ((rc = in.read(buff, 0, 100)) > 0) { + swapStream.write(buff, 0, rc); + } + data = swapStream.toByteArray(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return new String(Base64.encodeBase64(data)); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java new file mode 100644 index 0000000..9c93895 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java @@ -0,0 +1,75 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.lang3.StringUtils; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class CommonUtil { + + public static String CutId(String id) { + return id.substring(6, 10) + "-" + id.substring(10, 12) + "-" + id.substring(12, 14); + } + + public static boolean isIDNumber(String IDNumber) { + if (IDNumber == null || "".equals(IDNumber)) { + return false; + } + // 定义判别用户身份证号的正则表达式(15位或者18位,最后一位可以为字母) + String regularExpression = + "(^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|" + + "(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}$)"; + boolean matches = IDNumber.matches(regularExpression); + // 判断第18位校验值 + if (matches) { + if (IDNumber.length() == 18) { + try { + char[] charArray = IDNumber.toCharArray(); + // 前十七位加权因子 + int[] idCardWi = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; + // 这是除以11后,可能产生的11位余数对应的验证码 + String[] idCardY = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"}; + int sum = 0; + for (int i = 0; i < idCardWi.length; i++) { + int current = Integer.parseInt(String.valueOf(charArray[i])); + int count = current * idCardWi[i]; + sum += count; + } + char idCardLast = charArray[17]; + int idCardMod = sum % 11; + if (idCardY[idCardMod].toUpperCase() + .equals(String.valueOf(idCardLast).toUpperCase())) { + return true; + } else { + System.out.println("身份证最后一位:" + String.valueOf(idCardLast).toUpperCase() + + "错误,正确的应该是:" + idCardY[idCardMod].toUpperCase()); + return false; + } + + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } else { + return false; + } + } + return matches; + } + + + public static boolean CheckMobilePhoneNum(String phoneNum) { + if (StringUtils.isEmpty(phoneNum)) + return true; + String regex = "^(1[3-9]\\d{9}$)"; + if (phoneNum.length() == 11) { + Pattern p = Pattern.compile(regex); + Matcher m = p.matcher(phoneNum); + if (m.matches()) { + return true; + } + } + return false; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java new file mode 100644 index 0000000..191ef79 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java @@ -0,0 +1,116 @@ +package com.casic.missiles.modular.util; + + +import javafx.util.Pair; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +/** + * Created by Administrator on 2015/2/25. + */ +public class DateUtils { + public static SimpleDateFormat sdf_day = new SimpleDateFormat("yyyy-MM-dd"); + public static SimpleDateFormat sdf_day_time = new SimpleDateFormat("yyyyMMddhhmmss"); + public static final SimpleDateFormat sdf4 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + public static final SimpleDateFormat sdf5 = new SimpleDateFormat("HH:mm:ss"); + + + /** + * 获取当年的第一天 + * + * @return + */ + public static Date getCurrYearFirst() { + Calendar currCal = Calendar.getInstance(); + int currentYear = currCal.get(Calendar.YEAR); + return getYearFirst(currentYear); + } + + + /** + * 获取某年第一天日期 + * + * @param year 年份 + * @return Date + */ + public static Date getYearFirst(int year) { + Calendar calendar = Calendar.getInstance(); + calendar.clear(); + calendar.set(Calendar.YEAR, year); + Date currYearFirst = calendar.getTime(); + return currYearFirst; + } + + /** + * 最近7日(不包括今日) + */ + public static Pair getLastSevenDays() { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, -7); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 最近n日(不包括今日) + */ + public static Pair getLastNDays(int n) { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, n * -1); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 日期时间加n天 + */ + public static String addDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf4.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf4.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 日期加n天 + */ + public static String addNDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf_day.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf_day.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 昨日 + */ + public static String getYesterday() { + + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.DATE, -2); + return sdf_day.format(calendar.getTime()); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java new file mode 100644 index 0000000..da0f8ee --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java @@ -0,0 +1,49 @@ +package com.casic.missiles.modular.util; + +import com.hikvision.artemis.sdk.ArtemisHttpUtil; +import com.hikvision.artemis.sdk.config.ArtemisConfig; + +import java.util.HashMap; +import java.util.Map; + +public class HikUtil { + + public static String hikApi(String uri, String body) { + + /** + * STEP1:设置平台参数,根据实际情况,设置host appkey appsecret 三个参数. + */ + ArtemisConfig.host = "192.168.1.22:443"; // artemis网关服务器ip端口 + ArtemisConfig.appKey = "25766251"; // 秘钥appkey + ArtemisConfig.appSecret = "h2o6zXtzCmt8eaOaMkXb";// 秘钥appSecret + + /** + * STEP2:设置OpenAPI接口的上下文 + */ + final String ARTEMIS_PATH = "/artemis"; + + /** + * STEP3:设置接口的URI地址 + */ + final String previewURLsApi = ARTEMIS_PATH + uri; + Map path = new HashMap(2) { + { + put("https://", previewURLsApi);//根据现场环境部署确认是http还是https + } + }; + + /** + * STEP4:设置参数提交方式 + */ + String contentType = "application/json"; + + /** + * STEP5:组装请求参数 + */ + /** + * STEP6:调用接口 + */ + String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, contentType, null);// post请求application/json类型参数 + return result; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java new file mode 100644 index 0000000..4867144 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java @@ -0,0 +1,149 @@ +package com.casic.missiles.modular.util; + +import org.springframework.http.*; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; + +/** + * @Description: http请求工具类 + * @Author: wangpeng + * @Date: 2022/7/17 11:49 + */ +public class HttpUtil { + /** + * get请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String get(String url, MultiValueMap params) { + return get(url, params, null); + } + + /** + * get请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String get(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.GET); + } + + /** + * post请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String post(String url, MultiValueMap params) { + return post(url, params, null); + } + + /** + * post请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String post(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.POST); + } + + /** + * put请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String put(String url, MultiValueMap params) { + return put(url, params, null); + } + + /** + * put请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String put(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.PUT); + } + + /** + * delete请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String delete(String url, MultiValueMap params) { + return delete(url, params, null); + } + + /** + * delete请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String delete(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.DELETE); + } + + /** + * 表单请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @param method 请求方式 + * @return + */ + public static String request(String url, MultiValueMap params, MultiValueMap headers, HttpMethod method) { + if (params == null) { + params = new LinkedMultiValueMap<>(); + } + return request(url, params, headers, method, MediaType.APPLICATION_FORM_URLENCODED); + } + + /** + * http请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @param method 请求方式 + * @param mediaType 参数类型 + * @return + */ + public static String request(String url, Object params, MultiValueMap headers, HttpMethod method, MediaType mediaType) { + if (url == null || url.trim().isEmpty()) { + return null; + } + RestTemplate client = new RestTemplate(); + // header + HttpHeaders httpHeaders = new HttpHeaders(); + if (headers != null) { +// httpHeaders.addAll(headers); + httpHeaders.putAll(headers); + } + // 提交方式:表单、json + httpHeaders.setContentType(mediaType); + HttpEntity httpEntity = new HttpEntity(params, httpHeaders); + ResponseEntity response = client.exchange(url, method, httpEntity, String.class); + return response.getBody(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java new file mode 100644 index 0000000..19d8d67 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java @@ -0,0 +1,30 @@ +package com.casic.missiles.modular.util; + +public class SelectDTO { + private String name; + private String value; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public SelectDTO() { + } + + public SelectDTO(String name, String value) { + this.name = name; + this.value = value; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java new file mode 100644 index 0000000..0bd484c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java @@ -0,0 +1,28 @@ +package com.casic.missiles.modular.util; + +public class SocketConst { + + /** + * 新增授权socket前缀 + */ + public static final String SOCKET_PREFIX_ADD_PERMISSION = "addPermission:"; + + /** + * 取消授权socket前缀 + */ + public static final String SOCKET_PREFIX_DELETE_PERMISSION = "deletePermission:"; + + /** + * 人员数据下发socket前缀 + */ + public static final String SOCKET_PREFIX_ADD_PERSON = "addPerson:"; + + /** + * socket返回成功信息 + */ + public static final String SOCKET_SUCCESS_MSG = "ok"; + /** + * 人员数据下发socket前缀 + */ + public static final String SOCKET_PREFIX_DELETE_PERSON = "deletePerson:"; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java new file mode 100644 index 0000000..0452bca --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java @@ -0,0 +1,90 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.io.IOUtils; +import org.springframework.stereotype.Component; + +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.text.SimpleDateFormat; +import java.util.Date; + +@Component +public class SocketUtil { + + public static byte[] sendMessage(String ip, int port, String msg) { + byte[] data = new byte[20]; + + System.out.println("往 " + ip + ":" + port + " 发送数据:" + msg); + InputStream in = null; + OutputStream out = null; + Socket socket = null; + try { + socket = new Socket(); + socket.connect(new InetSocketAddress(ip, port), 1000); + socket.setSoTimeout(2000); + // 向服务端发送数据 + out = socket.getOutputStream(); + out.write(hexString2Bytes(msg)); + out.flush(); + //socket.shutdownOutput(); + // 读取服务端返回数据 + in = socket.getInputStream(); + in.read(data); + } catch (Exception e) { + e.printStackTrace(); + } finally { + IOUtils.closeQuietly(in); + IOUtils.closeQuietly(out); + IOUtils.closeQuietly(socket); + } + return data; + } + + private static int code = 0; + + public static void main(String[] args) { +// byte[] dd = sendMessage("192.168.5.211",6001,"090300000002C543"); + + String dateStr = new SimpleDateFormat("yyMMddHHmmssSSS").format(new Date()); + //String dd = dateStr + String.format("%04d",++code); + + System.out.println(dateStr); + } + + /** + * 返回由字节数组转换来的 16 位有符号整数 + * + * @param bytes 字节数组 + * @return 由两个字节构成的 16 位有符号整数 + */ + public static short toShort(byte[] bytes) { + return (short) ((0xff & bytes[0]) | (0xff00 & (bytes[1] << 8))); + + } + + + public static byte[] hexString2Bytes(String hex) { + if ((hex == null) || (hex.equals(""))) { + return null; + } else if (hex.length() % 2 != 0) { + return null; + } else { + hex = hex.toUpperCase(); + int len = hex.length() / 2; + byte[] b = new byte[len]; + char[] hc = hex.toCharArray(); + for (int i = 0; i < len; i++) { + int p = 2 * i; + b[i] = (byte) (charToByte(hc[p]) << 4 | charToByte(hc[p + 1])); + } + return b; + } + } + + private static byte charToByte(char c) { + return (byte) "0123456789ABCDEF".indexOf(c); + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java b/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java new file mode 100644 index 0000000..9b4155c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java @@ -0,0 +1,105 @@ +package com.casic.missiles.modular.util; + +import org.springframework.stereotype.Component; + +import javax.websocket.OnClose; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.PathParam; +import javax.websocket.server.ServerEndpoint; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CopyOnWriteArraySet; + +/** + * @Description: 此注解相当于设置访问URL + * @Author: wangpeng + * @Date: 2022/7/17 11:48 + */ +@Component +@ServerEndpoint("/websocket/{userId}") +public class WebSocket { + private Session session; + + private static CopyOnWriteArraySet webSockets = new CopyOnWriteArraySet<>(); + private static Map sessionPool = new HashMap(); + + @OnOpen + public void onOpen(Session session, @PathParam(value = "userId") String userId) { + this.session = session; + webSockets.add(this); + sessionPool.put(userId, session); + System.out.println(userId + "【websocket消息】有新的连接,总数为:" + webSockets.size()); + } + + @OnClose + public void onClose() { + webSockets.remove(this); + System.out.println("【websocket消息】连接断开,总数为:" + webSockets.size()); + } + + @OnMessage + public void onMessage(String message) { + System.out.println("【websocket消息】收到客户端消息:" + message); + } + + // 此为广播消息 + public void sendAllMessage(String message) { + for (WebSocket webSocket : webSockets) { + System.out.println("【websocket消息】广播消息:" + message); + try { + webSocket.session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + // 发送列表消息 + public void sendListMessage(List userIds, String message) { + System.out.println("【websocket消息】列表消息:" + message); + for (String userId : userIds) { + Session session = sessionPool.get(userId); + if (session != null) { + try { + session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + + // 发送列表消息 + +// public void sendListMessage(List userIds, Object data){ +// System.out.println("【websocket消息】列表消息:"+data); +// for (String userId : userIds) { +// Session session = sessionPool.get(userId); +// if (session != null) { +// try { +//// session.getAsyncRemote().sendText(message); +// session.getAsyncRemote().sendObject(data); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// } +// } + + // 此为单点消息 + public void sendOneMessage(String userId, String message) { + System.out.println("【websocket消息】单点消息:" + message); + Session session = sessionPool.get(userId); + if (session != null) { + try { + session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java new file mode 100644 index 0000000..0c1f5f1 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java @@ -0,0 +1,115 @@ +package com.casic.missiles.modular.util; + +import org.springframework.web.multipart.MultipartFile; + +import java.io.*; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipInputStream; + +/** + * @Description: 读取zip文件内容 + * @Author: wangpeng + * @Date: 2022/7/17 11:48 + */ +public class ZipFileUtil { + public static List getFile(String fileName) { + File file = new File(fileName); + ZipFile zipFile = null; + ZipInputStream zin = null; + FileInputStream fis = null; + List selectDTOList = new ArrayList<>(); + try { + Charset gbk = Charset.forName("GBK"); + zipFile = new ZipFile(file, gbk); + fis = new FileInputStream(file); + zin = new ZipInputStream(fis, gbk); + + ZipEntry ze = null; + while ((ze = zin.getNextEntry()) != null) { + String path = ze.getName(); + System.out.println(path); + if (!ze.isDirectory()) { + InputStream inputStream = zipFile.getInputStream(ze); + String base64Photo = Base64Util.getBase64FromInputStream(inputStream); +// List texts = IOUtils.readLines(inputStream); +// for (String text : texts) { +// System.out.println(" " + text); +// } + selectDTOList.add(new SelectDTO(path.substring(path.indexOf("/")+1), "data:image/png;base64,"+base64Photo)); + inputStream.close(); + } + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (zin != null) { + zin.closeEntry(); + zin.close(); + } + if (fis != null) + fis.close(); + if (zipFile != null) + zipFile.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return selectDTOList; + } + + + /** + * MultipartFile 转 File + * + * @param file + * @throws Exception + */ + public static File multipartFileToFile(MultipartFile file) throws Exception { + + File toFile = null; + if (file.equals("") || file.getSize() <= 0) { + file = null; + } else { + InputStream ins = null; + ins = file.getInputStream(); + toFile = new File(file.getOriginalFilename()); + inputStreamToFile(ins, toFile); + ins.close(); + } + return toFile; + } + + //获取流文件 + private static void inputStreamToFile(InputStream ins, File file) { + try { + OutputStream os = new FileOutputStream(file); + int bytesRead = 0; + byte[] buffer = new byte[8192]; + while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) { + os.write(buffer, 0, bytesRead); + } + os.close(); + ins.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 删除本地临时文件 + * + * @param file + */ + public static void delteTempFile(File file) { + if (file != null) { + File del = new File(file.toURI()); + del.delete(); + } + } +} + diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java new file mode 100644 index 0000000..ae93a17 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java @@ -0,0 +1,34 @@ +package com.casic.missiles.modular.util.netty; + +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.EventLoop; +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.TimeUnit; + +/** + * 负责监听启动时连接失败,重新连接功能 + * + */ +@Slf4j +public class ConnectionListener implements ChannelFutureListener { + + private NettyClient client = new NettyClient(); + + @Override + public void operationComplete(ChannelFuture channelFuture) throws Exception { + if (!channelFuture.isSuccess()) { + final EventLoop loop = channelFuture.channel().eventLoop(); + loop.schedule(new Runnable() { + @Override + public void run() { + log.info("服务端连接不上,开始重连操作..."); + client.connect(); + } + }, 5L, TimeUnit.MINUTES); + } else { + log.info("服务端连接成功..."); + } + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java new file mode 100644 index 0000000..ef9ae76 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java @@ -0,0 +1,66 @@ +package com.casic.missiles.modular.util.netty; + +import io.netty.bootstrap.Bootstrap; +import io.netty.channel.*; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioSocketChannel; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public class NettyClient { + + private static Channel channel; + + private String fenceServiceHost = "127.0.0.1"; + private Integer fenceServicePort = 9200; + + public Channel connect() { + doConnect(fenceServiceHost, fenceServicePort); + return channel; + } + + public Channel connect(String host, int port) { + doConnect(host, port); + return channel; + } + + private void doConnect(String host, int port) { + EventLoopGroup workerGroup = new NioEventLoopGroup(); + try { + Bootstrap b = new Bootstrap(); + b.group(workerGroup); + b.channel(NioSocketChannel.class); + b.option(ChannelOption.SO_KEEPALIVE, true); + b.option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(1024 * 1024)); + + b.handler(new ChannelInitializer() { + @Override + public void initChannel(SocketChannel ch) throws Exception { + + ch.pipeline().addLast("decoder", new StringDecoder()); + ch.pipeline().addLast("encoder", new StringEncoder()); + ch.pipeline().addLast(new NettyClientHandler()); + } + }); + + ChannelFuture f = b.connect(host, port); + f.addListener(new ConnectionListener()); + channel = f.channel(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static void writeAndFlush(String message) { + + if (channel != null) { + channel.writeAndFlush(message); + System.out.println("电子围栏客户端发送消息:" + message); + } + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClientHandler.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClientHandler.java new file mode 100644 index 0000000..28093f0 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClientHandler.java @@ -0,0 +1,62 @@ +package com.casic.missiles.modular.util.netty; + +import com.casic.missiles.modular.util.HttpUtil; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import io.netty.channel.EventLoop; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; + +import java.util.concurrent.TimeUnit; + +/** + * 客户端处理器 + **/ +@Slf4j +@Component +public class NettyClientHandler extends ChannelInboundHandlerAdapter { + static boolean handle = true; + + private NettyClient client = new NettyClient(); + + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + log.info("连接成功....."); + } + + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + log.info("断开连接....."); + + //使用过程中断线重连 + final EventLoop eventLoop = ctx.channel().eventLoop(); + eventLoop.schedule(new Runnable() { + @Override + public void run() { + client.connect(); + } + }, 5L, TimeUnit.SECONDS); + super.channelInactive(ctx); + } + + + @Override + public void channelRead(ChannelHandlerContext ctx, Object message) throws Exception { + + if (handle) { + MultiValueMap map = new LinkedMultiValueMap<>(); + map.add("message", message.toString()); + HttpUtil.post("http://127.0.0.1:20311/data/addPerimeterAlarm", map); + } + handle = !handle; + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + cause.printStackTrace(); + ctx.close(); + } +} + diff --git a/casic-web/pom.xml b/casic-web/pom.xml new file mode 100644 index 0000000..8fb0b2c --- /dev/null +++ b/casic-web/pom.xml @@ -0,0 +1,171 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + ../pom.xml + 2.0.0 + + casic-web + 2.0.0 + jar + casic-web + casic web启动入口 + + + + dev + + true + + + dev + + + + test + + test + + + + prod + + prod + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + io.micrometer + micrometer-core + + + + + org.springframework.boot + spring-boot-starter-jdbc + + + + com.casic + casic-core + ${core.version} + + + com.casic + casic-admin-core + ${admin.version} + + + io.springfox + springfox-swagger-ui + + + + + com.casic + casic-admin-support + ${admin.version} + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.dameng + DmJdbcDriver18 + 1.8 + + + com.casic + casic-area-starter + ${admin.version} + + + + com.casic + casic-server + ${pro.version} + + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + + + org.apache.maven.plugins + maven-jar-plugin + ${maven.jar.plugin.version} + + + + /config/*-*.yml + **/MockController.class + + + + com.casic.missiles.CasicApplication + true + ./ + + + + + + org.apache.maven.plugins + maven-assembly-plugin + ${maven.assembly.plugin.version} + + + make-assembly + package + + single + + + + + + org.apache.maven.plugins + maven-war-plugin + ${maven.war.plugin.version} + + + + + src/main/resources + + + /config/*/* + /config/*-*.yml + + true + + + src/main/java + + **/*.xml + + true + + + + \ No newline at end of file diff --git a/casic-web/src/main/build/bin/start.bat b/casic-web/src/main/build/bin/start.bat new file mode 100644 index 0000000..1db4e88 --- /dev/null +++ b/casic-web/src/main/build/bin/start.bat @@ -0,0 +1,4 @@ +@echo off +title ${project.build.finalName} +java -jar ./lib/${project.build.finalName}.jar +@pause diff --git a/casic-web/src/main/build/bin/start.sh b/casic-web/src/main/build/bin/start.sh new file mode 100644 index 0000000..c00b1ef --- /dev/null +++ b/casic-web/src/main/build/bin/start.sh @@ -0,0 +1,2 @@ +java -jar ./lib/${project.build.finalName}.jar + diff --git a/casic-web/src/main/build/package.xml b/casic-web/src/main/build/package.xml new file mode 100644 index 0000000..c9259ad --- /dev/null +++ b/casic-web/src/main/build/package.xml @@ -0,0 +1,43 @@ + + + package + + zip + tar.gz + + true + + + + true + true + lib + runtime + + + + + src/main/build/bin + + start.bat + start.sh + + true + 0744 + / + + + src/main/resources/config + true + + *.yml + /*/* + + /config + + + src/main/resources/i18n + / + + + \ No newline at end of file diff --git a/casic-web/src/main/java/com/casic/missiles/CasicApplication.java b/casic-web/src/main/java/com/casic/missiles/CasicApplication.java new file mode 100644 index 0000000..308dcad --- /dev/null +++ b/casic-web/src/main/java/com/casic/missiles/CasicApplication.java @@ -0,0 +1,29 @@ +package com.casic.missiles; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.ServletComponentScan; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +/** + * SpringBoot方式启动类 + * + * @author lwh + * @Date 2021/06/06 12:06 + */ +@SpringBootApplication +@EnableCaching +@EnableTransactionManagement(proxyTargetClass = true) +@EnableAsync +@Slf4j +public class CasicApplication { + public static void main(String[] args) { + SpringApplication.run(CasicApplication.class, args); + + log.info("CasicApplication is success!"); + } + +} diff --git a/casic-web/src/main/java/com/casic/missiles/CasicServletInitializer.java b/casic-web/src/main/java/com/casic/missiles/CasicServletInitializer.java new file mode 100644 index 0000000..e30585b --- /dev/null +++ b/casic-web/src/main/java/com/casic/missiles/CasicServletInitializer.java @@ -0,0 +1,18 @@ +package com.casic.missiles; + +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; + +/** + * Guns Web程序启动类 + * + * @author fengshuonan + * @date 2017-05-21 9:43 + */ +public class CasicServletInitializer extends SpringBootServletInitializer { + + @Override + protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { + return application.sources(CasicApplication.class); + } +} diff --git a/casic-web/src/main/java/com/casic/missiles/controller/MockController.java b/casic-web/src/main/java/com/casic/missiles/controller/MockController.java new file mode 100644 index 0000000..eae6c54 --- /dev/null +++ b/casic-web/src/main/java/com/casic/missiles/controller/MockController.java @@ -0,0 +1,82 @@ +package com.casic.missiles.controller; + +import cn.hutool.core.util.StrUtil; +import com.casic.missiles.core.application.enums.LoginType; +import com.casic.missiles.core.base.controller.BaseController; +import com.casic.missiles.core.model.auth.AuthUser; +import com.casic.missiles.core.model.auth.CasicCustomToken; +import com.casic.missiles.core.shiro.ShiroKit; +import com.casic.missiles.core.util.RSAUtils; +import com.casic.missiles.model.response.SuccessResponseData; +import com.casic.missiles.modular.domain.constants.PermissionConstants; +import com.casic.missiles.modular.interfaces.log.LogManager; +import com.casic.missiles.modular.interfaces.log.factory.LogTaskFactory; +import com.casic.missiles.modular.system.dto.LoginSuccessDTO; +import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.subject.Subject; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import java.security.NoSuchAlgorithmException; +import java.util.Map; + +import static com.casic.missiles.core.util.HttpContext.getIp; + + +/** + * 仅为mock登录使用 + * + * @author lenovo + */ +@Controller +@RequestMapping("/route") +@Slf4j +public class MockController extends BaseController { + + /** + * 获取mockToken + */ + @GetMapping("/mockToken") + @ResponseBody + public Object mockToken(String username, String password) { + super.getSession().setAttribute(PermissionConstants.IS_APP, false); + SuccessResponseData resultData = new SuccessResponseData(); + if (StrUtil.hasEmpty(username, password)) { + username = "admin"; + password = "111111"; + } + Subject currentUser = ShiroKit.getSubject(); + + try { + Map key = RSAUtils.genKeyPair(); + ShiroKit.getSession().setAttribute(PermissionConstants.PRIVATE_KEY, key.get(RSAUtils.RSAPrivateKey)); + + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + + //token自定义 + CasicCustomToken token = new CasicCustomToken(username, password); + token.setType(LoginType.PASSWORD); + token.setRememberMe(false); + + try { + currentUser.login(token); + } catch (Exception e) { + e.printStackTrace(); + } + AuthUser shiroUser = ShiroKit.getUser(); + super.getSession().setAttribute("shiroUser", shiroUser); + super.getSession().setAttribute("username", shiroUser.getAccount()); + super.getSession().setAttribute(PermissionConstants.SESSION_KEY, shiroUser.getId()); + + LogManager.me().executeLog(LogTaskFactory.loginLog(shiroUser.getId(), getIp())); + + ShiroKit.getSession().setAttribute("sessionFlag", true); + resultData.setData(new LoginSuccessDTO(ShiroKit.getSession().getId().toString(), null)); + resultData.setMessage("登录成功"); + return resultData; + } +} diff --git a/casic-web/src/main/resources/META-INF/spring-devtools.properties b/casic-web/src/main/resources/META-INF/spring-devtools.properties new file mode 100644 index 0000000..e3b0a7f --- /dev/null +++ b/casic-web/src/main/resources/META-INF/spring-devtools.properties @@ -0,0 +1 @@ +restart.include.beetl=/beetl-2.7.15.jar \ No newline at end of file diff --git a/casic-web/src/main/resources/config/application-dev.yml b/casic-web/src/main/resources/config/application-dev.yml new file mode 100644 index 0000000..8c18554 --- /dev/null +++ b/casic-web/src/main/resources/config/application-dev.yml @@ -0,0 +1,30 @@ +server: + port: 8083 +################### spring配置 ################### +spring: + datasource: + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://111.198.10.15:11336/casic_template2.0?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&serverTimezone=UTC&&allowMultiQueries=true + username: root + password: Casic203 +jms: + pub-sub-domain: true +# session: +# store-type: redis +# redis: +# host: 111.198.10.15 +# port: 11412 +# password: ew5T4K3#203lwh +# serializer: org.springframework.data.redis.serializer.StringRedisSerializer +# redisValueSerializer: org.springframework.data.redis.serializer.JdkSerializationRedisSerializer +casic: + #kaptcha-open: false #是否开启登录时验证码 (true/false) + no-login-urls: ${casic.sysUrl}/user/login,${casic.sysUrl}/user/appLogin,${casic.sysUrl}/kaptcha/base64,${casic.sysUrl}/config/baseConfig,/route/mockToken + #flowable数据源和多数据源配置 + db: + init: + enable: false +logging: + level.root: info + level.com.casic: debug + level.org.springframework.web: info \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9e20bc1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea/ +**/target/** +logs/ +*.iml diff --git a/README.md b/README.md new file mode 100644 index 0000000..2fdcd74 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# casic项目 V2.0.0 + +[^_^]: # (Talk is cheap,Show me the code!) + +## 介绍 +基于SpringBoot,致力于做更简洁的后台管理系统,完美整合springboot2.4 + shiro + mybatis-plus ! +基于casic项目代码简洁,注释丰富,上手容易,同时包含许多基础模块(用户管理,角色管理,部门管理,字典管理等10个模块) +可以直接作为一个后台管理系统的脚手架! 2022目标 `更简洁`,`更规范`! + + +#### 其他 +>* [git地址](http://192.168.0.203:8080/gitbucket) +>* [本地免登地址](http://localhost:8083/route/mockToken) diff --git a/casic-server/pom.xml b/casic-server/pom.xml new file mode 100644 index 0000000..c150a12 --- /dev/null +++ b/casic-server/pom.xml @@ -0,0 +1,70 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + 2.0.0 + ../pom.xml + + + casic-server + 2.0.0 + jar + casic-server + casic 的spring boot版本 + + + + + com.casic + casic-core + ${core.version} + provided + + + com.casic + casic-admin-support + ${admin.version} + provided + + + org.springframework.boot + spring-boot-starter-web + ${boot.version} + provided + + + + + com.hikvision.ga + artemis-http-client + 1.1.3 + + + commons-io + commons-io + + + org.springframework.boot + spring-boot-starter-websocket + 2.4.5 + + + io.netty + netty-all + 4.1.42.Final + + + + + + src/main/java + + **/*.xml + + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java new file mode 100644 index 0000000..3a60b9e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java @@ -0,0 +1,36 @@ +package com.casic.missiles.modular.async; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.TaskExecutor; +import org.springframework.scheduling.annotation.AsyncConfigurer; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadPoolExecutor; + +@Configuration +@EnableAsync +public class AsyncConfig implements AsyncConfigurer { + @Override + public Executor getAsyncExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + //核心线程数 + executor.setCorePoolSize(5); + //最大线程数 + executor.setMaxPoolSize(10); + //队列容量 + executor.setQueueCapacity(20); + //设置线程活跃时间(秒) + executor.setKeepAliveSeconds(60); + //默认线程名称 + executor.setThreadNamePrefix("user-rpt-"); + //拒绝策略 + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + //等待所有任务结束后再关闭线程池 + executor.setWaitForTasksToCompleteOnShutdown(true); + return executor; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java new file mode 100644 index 0000000..8ca554c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java @@ -0,0 +1,18 @@ +package com.casic.missiles.modular.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +// tomcat启动无需配置 +@Configuration +public class WebSocketConfig { + /** + * 注入ServerEndpointExporter, + * 这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint + */ + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java new file mode 100644 index 0000000..34fe2cd --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java @@ -0,0 +1,39 @@ +package com.casic.missiles.modular.controller; + + +import com.casic.missiles.model.application.event.core.EventPublisher; +import com.casic.missiles.model.application.event.enums.ModelEventTypeEnum; +import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.modular.event.UserEvent; +import com.casic.missiles.modular.system.model.User; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +/** + * @Description: DemoController + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@RestController +@RequestMapping("/demo") +public class DemoController { + @Autowired + private EventPublisher publisher; + + /** + * 获取mockToken + */ + @PostMapping("/list") + @ResponseBody + public Object list() { + User user = new User(); + user.setAccount("张三"); + publisher.publishEvent(new UserEvent(ModelEventTypeEnum.ADD, user)); + return ResponseData.success(); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java new file mode 100644 index 0000000..aff2889 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java @@ -0,0 +1,23 @@ +package com.casic.missiles.modular.event; + +import com.casic.missiles.model.application.event.core.ModelEvent; +import com.casic.missiles.model.application.event.type.AbstractEventTypeEnum; +import com.casic.missiles.modular.system.model.User; + +/** + * @Description: 用户事件 + * @Author: wangpeng + * @Date: 2022/7/17 11:23 + */ +public class UserEvent extends ModelEvent { + /** + * Create a new {@code ApplicationEvent}. + * + * @param type 事件类型 + * @param source the object on which the event initially occurred or with + * which the event is associated (never {@code null}) + */ + public UserEvent(AbstractEventTypeEnum type, User source) { + super(type, source); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java new file mode 100644 index 0000000..8f9603e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.core.application.event.UserLoginEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserOneListener { + @EventListener + public void onApplicationEvent(UserLoginEvent event) { + log.debug("用户1订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java new file mode 100644 index 0000000..0bd52a3 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.model.application.event.core.EventSubscriber; +import com.casic.missiles.modular.event.UserEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserTwoListener extends EventSubscriber { + @Override + public void onApplicationEvent(UserEvent event) { + log.debug("用户2订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java new file mode 100644 index 0000000..4012170 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java @@ -0,0 +1,88 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang3.StringUtils; +import sun.misc.BASE64Decoder; + +import java.io.*; + +public class Base64Util { + /** + * base64字符串转换成图片 + * + * @param imgStr base64字符串 + * @param imgFilePath 图片存放路径 + * @return + * @author ZHANGJL + * @dateTime 2018-02-23 14:42:17 + */ + public static boolean Base64ToImage(String imgStr, String imgFilePath, String fileDir) { // 对字节数组字符串进行Base64解码并生成图片 + + if (StringUtils.isEmpty(imgStr)) // 图像数据为空 + return false; + + imgStr = imgStr.substring(imgStr.indexOf(",") + 1); + + BASE64Decoder decoder = new BASE64Decoder(); + try { + // Base64解码 + byte[] b = decoder.decodeBuffer(imgStr); + + for (int i = 0; i < b.length; ++i) { + if (b[i] < 0) {// 调整异常数据 + b[i] += 256; + } + } + //如果已存在图像,先删除 + File file = new File(fileDir+File.separator + imgFilePath); + if (file.exists() && file.isFile()) { + file.delete(); + } + File dir = new File(fileDir); + if (!dir.exists()) { + dir.mkdirs(); + } + file = new File(fileDir+File.separator+imgFilePath); + file.createNewFile(); +// ImageIO.write(bImage, "bmp", name); + OutputStream out = new FileOutputStream(fileDir+File.separator+imgFilePath); + out.write(b); + out.flush(); + out.close(); + + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + + } + + public static String getBase64FromInputStream(InputStream in) { + // 将图片文件转化为字节数组字符串,并对其进行Base64编码处理 + byte[] data = null; + // 读取图片字节数组 + try { + ByteArrayOutputStream swapStream = new ByteArrayOutputStream(); + byte[] buff = new byte[100]; + int rc = 0; + while ((rc = in.read(buff, 0, 100)) > 0) { + swapStream.write(buff, 0, rc); + } + data = swapStream.toByteArray(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return new String(Base64.encodeBase64(data)); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java new file mode 100644 index 0000000..9c93895 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java @@ -0,0 +1,75 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.lang3.StringUtils; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class CommonUtil { + + public static String CutId(String id) { + return id.substring(6, 10) + "-" + id.substring(10, 12) + "-" + id.substring(12, 14); + } + + public static boolean isIDNumber(String IDNumber) { + if (IDNumber == null || "".equals(IDNumber)) { + return false; + } + // 定义判别用户身份证号的正则表达式(15位或者18位,最后一位可以为字母) + String regularExpression = + "(^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|" + + "(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}$)"; + boolean matches = IDNumber.matches(regularExpression); + // 判断第18位校验值 + if (matches) { + if (IDNumber.length() == 18) { + try { + char[] charArray = IDNumber.toCharArray(); + // 前十七位加权因子 + int[] idCardWi = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; + // 这是除以11后,可能产生的11位余数对应的验证码 + String[] idCardY = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"}; + int sum = 0; + for (int i = 0; i < idCardWi.length; i++) { + int current = Integer.parseInt(String.valueOf(charArray[i])); + int count = current * idCardWi[i]; + sum += count; + } + char idCardLast = charArray[17]; + int idCardMod = sum % 11; + if (idCardY[idCardMod].toUpperCase() + .equals(String.valueOf(idCardLast).toUpperCase())) { + return true; + } else { + System.out.println("身份证最后一位:" + String.valueOf(idCardLast).toUpperCase() + + "错误,正确的应该是:" + idCardY[idCardMod].toUpperCase()); + return false; + } + + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } else { + return false; + } + } + return matches; + } + + + public static boolean CheckMobilePhoneNum(String phoneNum) { + if (StringUtils.isEmpty(phoneNum)) + return true; + String regex = "^(1[3-9]\\d{9}$)"; + if (phoneNum.length() == 11) { + Pattern p = Pattern.compile(regex); + Matcher m = p.matcher(phoneNum); + if (m.matches()) { + return true; + } + } + return false; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java new file mode 100644 index 0000000..191ef79 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java @@ -0,0 +1,116 @@ +package com.casic.missiles.modular.util; + + +import javafx.util.Pair; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +/** + * Created by Administrator on 2015/2/25. + */ +public class DateUtils { + public static SimpleDateFormat sdf_day = new SimpleDateFormat("yyyy-MM-dd"); + public static SimpleDateFormat sdf_day_time = new SimpleDateFormat("yyyyMMddhhmmss"); + public static final SimpleDateFormat sdf4 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + public static final SimpleDateFormat sdf5 = new SimpleDateFormat("HH:mm:ss"); + + + /** + * 获取当年的第一天 + * + * @return + */ + public static Date getCurrYearFirst() { + Calendar currCal = Calendar.getInstance(); + int currentYear = currCal.get(Calendar.YEAR); + return getYearFirst(currentYear); + } + + + /** + * 获取某年第一天日期 + * + * @param year 年份 + * @return Date + */ + public static Date getYearFirst(int year) { + Calendar calendar = Calendar.getInstance(); + calendar.clear(); + calendar.set(Calendar.YEAR, year); + Date currYearFirst = calendar.getTime(); + return currYearFirst; + } + + /** + * 最近7日(不包括今日) + */ + public static Pair getLastSevenDays() { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, -7); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 最近n日(不包括今日) + */ + public static Pair getLastNDays(int n) { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, n * -1); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 日期时间加n天 + */ + public static String addDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf4.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf4.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 日期加n天 + */ + public static String addNDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf_day.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf_day.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 昨日 + */ + public static String getYesterday() { + + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.DATE, -2); + return sdf_day.format(calendar.getTime()); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java new file mode 100644 index 0000000..da0f8ee --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java @@ -0,0 +1,49 @@ +package com.casic.missiles.modular.util; + +import com.hikvision.artemis.sdk.ArtemisHttpUtil; +import com.hikvision.artemis.sdk.config.ArtemisConfig; + +import java.util.HashMap; +import java.util.Map; + +public class HikUtil { + + public static String hikApi(String uri, String body) { + + /** + * STEP1:设置平台参数,根据实际情况,设置host appkey appsecret 三个参数. + */ + ArtemisConfig.host = "192.168.1.22:443"; // artemis网关服务器ip端口 + ArtemisConfig.appKey = "25766251"; // 秘钥appkey + ArtemisConfig.appSecret = "h2o6zXtzCmt8eaOaMkXb";// 秘钥appSecret + + /** + * STEP2:设置OpenAPI接口的上下文 + */ + final String ARTEMIS_PATH = "/artemis"; + + /** + * STEP3:设置接口的URI地址 + */ + final String previewURLsApi = ARTEMIS_PATH + uri; + Map path = new HashMap(2) { + { + put("https://", previewURLsApi);//根据现场环境部署确认是http还是https + } + }; + + /** + * STEP4:设置参数提交方式 + */ + String contentType = "application/json"; + + /** + * STEP5:组装请求参数 + */ + /** + * STEP6:调用接口 + */ + String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, contentType, null);// post请求application/json类型参数 + return result; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java new file mode 100644 index 0000000..4867144 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java @@ -0,0 +1,149 @@ +package com.casic.missiles.modular.util; + +import org.springframework.http.*; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; + +/** + * @Description: http请求工具类 + * @Author: wangpeng + * @Date: 2022/7/17 11:49 + */ +public class HttpUtil { + /** + * get请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String get(String url, MultiValueMap params) { + return get(url, params, null); + } + + /** + * get请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String get(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.GET); + } + + /** + * post请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String post(String url, MultiValueMap params) { + return post(url, params, null); + } + + /** + * post请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String post(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.POST); + } + + /** + * put请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String put(String url, MultiValueMap params) { + return put(url, params, null); + } + + /** + * put请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String put(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.PUT); + } + + /** + * delete请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String delete(String url, MultiValueMap params) { + return delete(url, params, null); + } + + /** + * delete请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String delete(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.DELETE); + } + + /** + * 表单请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @param method 请求方式 + * @return + */ + public static String request(String url, MultiValueMap params, MultiValueMap headers, HttpMethod method) { + if (params == null) { + params = new LinkedMultiValueMap<>(); + } + return request(url, params, headers, method, MediaType.APPLICATION_FORM_URLENCODED); + } + + /** + * http请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @param method 请求方式 + * @param mediaType 参数类型 + * @return + */ + public static String request(String url, Object params, MultiValueMap headers, HttpMethod method, MediaType mediaType) { + if (url == null || url.trim().isEmpty()) { + return null; + } + RestTemplate client = new RestTemplate(); + // header + HttpHeaders httpHeaders = new HttpHeaders(); + if (headers != null) { +// httpHeaders.addAll(headers); + httpHeaders.putAll(headers); + } + // 提交方式:表单、json + httpHeaders.setContentType(mediaType); + HttpEntity httpEntity = new HttpEntity(params, httpHeaders); + ResponseEntity response = client.exchange(url, method, httpEntity, String.class); + return response.getBody(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java new file mode 100644 index 0000000..19d8d67 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java @@ -0,0 +1,30 @@ +package com.casic.missiles.modular.util; + +public class SelectDTO { + private String name; + private String value; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public SelectDTO() { + } + + public SelectDTO(String name, String value) { + this.name = name; + this.value = value; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java new file mode 100644 index 0000000..0bd484c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java @@ -0,0 +1,28 @@ +package com.casic.missiles.modular.util; + +public class SocketConst { + + /** + * 新增授权socket前缀 + */ + public static final String SOCKET_PREFIX_ADD_PERMISSION = "addPermission:"; + + /** + * 取消授权socket前缀 + */ + public static final String SOCKET_PREFIX_DELETE_PERMISSION = "deletePermission:"; + + /** + * 人员数据下发socket前缀 + */ + public static final String SOCKET_PREFIX_ADD_PERSON = "addPerson:"; + + /** + * socket返回成功信息 + */ + public static final String SOCKET_SUCCESS_MSG = "ok"; + /** + * 人员数据下发socket前缀 + */ + public static final String SOCKET_PREFIX_DELETE_PERSON = "deletePerson:"; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java new file mode 100644 index 0000000..0452bca --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java @@ -0,0 +1,90 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.io.IOUtils; +import org.springframework.stereotype.Component; + +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.text.SimpleDateFormat; +import java.util.Date; + +@Component +public class SocketUtil { + + public static byte[] sendMessage(String ip, int port, String msg) { + byte[] data = new byte[20]; + + System.out.println("往 " + ip + ":" + port + " 发送数据:" + msg); + InputStream in = null; + OutputStream out = null; + Socket socket = null; + try { + socket = new Socket(); + socket.connect(new InetSocketAddress(ip, port), 1000); + socket.setSoTimeout(2000); + // 向服务端发送数据 + out = socket.getOutputStream(); + out.write(hexString2Bytes(msg)); + out.flush(); + //socket.shutdownOutput(); + // 读取服务端返回数据 + in = socket.getInputStream(); + in.read(data); + } catch (Exception e) { + e.printStackTrace(); + } finally { + IOUtils.closeQuietly(in); + IOUtils.closeQuietly(out); + IOUtils.closeQuietly(socket); + } + return data; + } + + private static int code = 0; + + public static void main(String[] args) { +// byte[] dd = sendMessage("192.168.5.211",6001,"090300000002C543"); + + String dateStr = new SimpleDateFormat("yyMMddHHmmssSSS").format(new Date()); + //String dd = dateStr + String.format("%04d",++code); + + System.out.println(dateStr); + } + + /** + * 返回由字节数组转换来的 16 位有符号整数 + * + * @param bytes 字节数组 + * @return 由两个字节构成的 16 位有符号整数 + */ + public static short toShort(byte[] bytes) { + return (short) ((0xff & bytes[0]) | (0xff00 & (bytes[1] << 8))); + + } + + + public static byte[] hexString2Bytes(String hex) { + if ((hex == null) || (hex.equals(""))) { + return null; + } else if (hex.length() % 2 != 0) { + return null; + } else { + hex = hex.toUpperCase(); + int len = hex.length() / 2; + byte[] b = new byte[len]; + char[] hc = hex.toCharArray(); + for (int i = 0; i < len; i++) { + int p = 2 * i; + b[i] = (byte) (charToByte(hc[p]) << 4 | charToByte(hc[p + 1])); + } + return b; + } + } + + private static byte charToByte(char c) { + return (byte) "0123456789ABCDEF".indexOf(c); + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java b/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java new file mode 100644 index 0000000..9b4155c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java @@ -0,0 +1,105 @@ +package com.casic.missiles.modular.util; + +import org.springframework.stereotype.Component; + +import javax.websocket.OnClose; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.PathParam; +import javax.websocket.server.ServerEndpoint; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CopyOnWriteArraySet; + +/** + * @Description: 此注解相当于设置访问URL + * @Author: wangpeng + * @Date: 2022/7/17 11:48 + */ +@Component +@ServerEndpoint("/websocket/{userId}") +public class WebSocket { + private Session session; + + private static CopyOnWriteArraySet webSockets = new CopyOnWriteArraySet<>(); + private static Map sessionPool = new HashMap(); + + @OnOpen + public void onOpen(Session session, @PathParam(value = "userId") String userId) { + this.session = session; + webSockets.add(this); + sessionPool.put(userId, session); + System.out.println(userId + "【websocket消息】有新的连接,总数为:" + webSockets.size()); + } + + @OnClose + public void onClose() { + webSockets.remove(this); + System.out.println("【websocket消息】连接断开,总数为:" + webSockets.size()); + } + + @OnMessage + public void onMessage(String message) { + System.out.println("【websocket消息】收到客户端消息:" + message); + } + + // 此为广播消息 + public void sendAllMessage(String message) { + for (WebSocket webSocket : webSockets) { + System.out.println("【websocket消息】广播消息:" + message); + try { + webSocket.session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + // 发送列表消息 + public void sendListMessage(List userIds, String message) { + System.out.println("【websocket消息】列表消息:" + message); + for (String userId : userIds) { + Session session = sessionPool.get(userId); + if (session != null) { + try { + session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + + // 发送列表消息 + +// public void sendListMessage(List userIds, Object data){ +// System.out.println("【websocket消息】列表消息:"+data); +// for (String userId : userIds) { +// Session session = sessionPool.get(userId); +// if (session != null) { +// try { +//// session.getAsyncRemote().sendText(message); +// session.getAsyncRemote().sendObject(data); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// } +// } + + // 此为单点消息 + public void sendOneMessage(String userId, String message) { + System.out.println("【websocket消息】单点消息:" + message); + Session session = sessionPool.get(userId); + if (session != null) { + try { + session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java new file mode 100644 index 0000000..0c1f5f1 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java @@ -0,0 +1,115 @@ +package com.casic.missiles.modular.util; + +import org.springframework.web.multipart.MultipartFile; + +import java.io.*; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipInputStream; + +/** + * @Description: 读取zip文件内容 + * @Author: wangpeng + * @Date: 2022/7/17 11:48 + */ +public class ZipFileUtil { + public static List getFile(String fileName) { + File file = new File(fileName); + ZipFile zipFile = null; + ZipInputStream zin = null; + FileInputStream fis = null; + List selectDTOList = new ArrayList<>(); + try { + Charset gbk = Charset.forName("GBK"); + zipFile = new ZipFile(file, gbk); + fis = new FileInputStream(file); + zin = new ZipInputStream(fis, gbk); + + ZipEntry ze = null; + while ((ze = zin.getNextEntry()) != null) { + String path = ze.getName(); + System.out.println(path); + if (!ze.isDirectory()) { + InputStream inputStream = zipFile.getInputStream(ze); + String base64Photo = Base64Util.getBase64FromInputStream(inputStream); +// List texts = IOUtils.readLines(inputStream); +// for (String text : texts) { +// System.out.println(" " + text); +// } + selectDTOList.add(new SelectDTO(path.substring(path.indexOf("/")+1), "data:image/png;base64,"+base64Photo)); + inputStream.close(); + } + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (zin != null) { + zin.closeEntry(); + zin.close(); + } + if (fis != null) + fis.close(); + if (zipFile != null) + zipFile.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return selectDTOList; + } + + + /** + * MultipartFile 转 File + * + * @param file + * @throws Exception + */ + public static File multipartFileToFile(MultipartFile file) throws Exception { + + File toFile = null; + if (file.equals("") || file.getSize() <= 0) { + file = null; + } else { + InputStream ins = null; + ins = file.getInputStream(); + toFile = new File(file.getOriginalFilename()); + inputStreamToFile(ins, toFile); + ins.close(); + } + return toFile; + } + + //获取流文件 + private static void inputStreamToFile(InputStream ins, File file) { + try { + OutputStream os = new FileOutputStream(file); + int bytesRead = 0; + byte[] buffer = new byte[8192]; + while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) { + os.write(buffer, 0, bytesRead); + } + os.close(); + ins.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 删除本地临时文件 + * + * @param file + */ + public static void delteTempFile(File file) { + if (file != null) { + File del = new File(file.toURI()); + del.delete(); + } + } +} + diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java new file mode 100644 index 0000000..ae93a17 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java @@ -0,0 +1,34 @@ +package com.casic.missiles.modular.util.netty; + +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.EventLoop; +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.TimeUnit; + +/** + * 负责监听启动时连接失败,重新连接功能 + * + */ +@Slf4j +public class ConnectionListener implements ChannelFutureListener { + + private NettyClient client = new NettyClient(); + + @Override + public void operationComplete(ChannelFuture channelFuture) throws Exception { + if (!channelFuture.isSuccess()) { + final EventLoop loop = channelFuture.channel().eventLoop(); + loop.schedule(new Runnable() { + @Override + public void run() { + log.info("服务端连接不上,开始重连操作..."); + client.connect(); + } + }, 5L, TimeUnit.MINUTES); + } else { + log.info("服务端连接成功..."); + } + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java new file mode 100644 index 0000000..ef9ae76 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java @@ -0,0 +1,66 @@ +package com.casic.missiles.modular.util.netty; + +import io.netty.bootstrap.Bootstrap; +import io.netty.channel.*; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioSocketChannel; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public class NettyClient { + + private static Channel channel; + + private String fenceServiceHost = "127.0.0.1"; + private Integer fenceServicePort = 9200; + + public Channel connect() { + doConnect(fenceServiceHost, fenceServicePort); + return channel; + } + + public Channel connect(String host, int port) { + doConnect(host, port); + return channel; + } + + private void doConnect(String host, int port) { + EventLoopGroup workerGroup = new NioEventLoopGroup(); + try { + Bootstrap b = new Bootstrap(); + b.group(workerGroup); + b.channel(NioSocketChannel.class); + b.option(ChannelOption.SO_KEEPALIVE, true); + b.option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(1024 * 1024)); + + b.handler(new ChannelInitializer() { + @Override + public void initChannel(SocketChannel ch) throws Exception { + + ch.pipeline().addLast("decoder", new StringDecoder()); + ch.pipeline().addLast("encoder", new StringEncoder()); + ch.pipeline().addLast(new NettyClientHandler()); + } + }); + + ChannelFuture f = b.connect(host, port); + f.addListener(new ConnectionListener()); + channel = f.channel(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static void writeAndFlush(String message) { + + if (channel != null) { + channel.writeAndFlush(message); + System.out.println("电子围栏客户端发送消息:" + message); + } + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClientHandler.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClientHandler.java new file mode 100644 index 0000000..28093f0 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClientHandler.java @@ -0,0 +1,62 @@ +package com.casic.missiles.modular.util.netty; + +import com.casic.missiles.modular.util.HttpUtil; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import io.netty.channel.EventLoop; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; + +import java.util.concurrent.TimeUnit; + +/** + * 客户端处理器 + **/ +@Slf4j +@Component +public class NettyClientHandler extends ChannelInboundHandlerAdapter { + static boolean handle = true; + + private NettyClient client = new NettyClient(); + + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + log.info("连接成功....."); + } + + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + log.info("断开连接....."); + + //使用过程中断线重连 + final EventLoop eventLoop = ctx.channel().eventLoop(); + eventLoop.schedule(new Runnable() { + @Override + public void run() { + client.connect(); + } + }, 5L, TimeUnit.SECONDS); + super.channelInactive(ctx); + } + + + @Override + public void channelRead(ChannelHandlerContext ctx, Object message) throws Exception { + + if (handle) { + MultiValueMap map = new LinkedMultiValueMap<>(); + map.add("message", message.toString()); + HttpUtil.post("http://127.0.0.1:20311/data/addPerimeterAlarm", map); + } + handle = !handle; + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + cause.printStackTrace(); + ctx.close(); + } +} + diff --git a/casic-web/pom.xml b/casic-web/pom.xml new file mode 100644 index 0000000..8fb0b2c --- /dev/null +++ b/casic-web/pom.xml @@ -0,0 +1,171 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + ../pom.xml + 2.0.0 + + casic-web + 2.0.0 + jar + casic-web + casic web启动入口 + + + + dev + + true + + + dev + + + + test + + test + + + + prod + + prod + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + io.micrometer + micrometer-core + + + + + org.springframework.boot + spring-boot-starter-jdbc + + + + com.casic + casic-core + ${core.version} + + + com.casic + casic-admin-core + ${admin.version} + + + io.springfox + springfox-swagger-ui + + + + + com.casic + casic-admin-support + ${admin.version} + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.dameng + DmJdbcDriver18 + 1.8 + + + com.casic + casic-area-starter + ${admin.version} + + + + com.casic + casic-server + ${pro.version} + + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + + + org.apache.maven.plugins + maven-jar-plugin + ${maven.jar.plugin.version} + + + + /config/*-*.yml + **/MockController.class + + + + com.casic.missiles.CasicApplication + true + ./ + + + + + + org.apache.maven.plugins + maven-assembly-plugin + ${maven.assembly.plugin.version} + + + make-assembly + package + + single + + + + + + org.apache.maven.plugins + maven-war-plugin + ${maven.war.plugin.version} + + + + + src/main/resources + + + /config/*/* + /config/*-*.yml + + true + + + src/main/java + + **/*.xml + + true + + + + \ No newline at end of file diff --git a/casic-web/src/main/build/bin/start.bat b/casic-web/src/main/build/bin/start.bat new file mode 100644 index 0000000..1db4e88 --- /dev/null +++ b/casic-web/src/main/build/bin/start.bat @@ -0,0 +1,4 @@ +@echo off +title ${project.build.finalName} +java -jar ./lib/${project.build.finalName}.jar +@pause diff --git a/casic-web/src/main/build/bin/start.sh b/casic-web/src/main/build/bin/start.sh new file mode 100644 index 0000000..c00b1ef --- /dev/null +++ b/casic-web/src/main/build/bin/start.sh @@ -0,0 +1,2 @@ +java -jar ./lib/${project.build.finalName}.jar + diff --git a/casic-web/src/main/build/package.xml b/casic-web/src/main/build/package.xml new file mode 100644 index 0000000..c9259ad --- /dev/null +++ b/casic-web/src/main/build/package.xml @@ -0,0 +1,43 @@ + + + package + + zip + tar.gz + + true + + + + true + true + lib + runtime + + + + + src/main/build/bin + + start.bat + start.sh + + true + 0744 + / + + + src/main/resources/config + true + + *.yml + /*/* + + /config + + + src/main/resources/i18n + / + + + \ No newline at end of file diff --git a/casic-web/src/main/java/com/casic/missiles/CasicApplication.java b/casic-web/src/main/java/com/casic/missiles/CasicApplication.java new file mode 100644 index 0000000..308dcad --- /dev/null +++ b/casic-web/src/main/java/com/casic/missiles/CasicApplication.java @@ -0,0 +1,29 @@ +package com.casic.missiles; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.ServletComponentScan; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +/** + * SpringBoot方式启动类 + * + * @author lwh + * @Date 2021/06/06 12:06 + */ +@SpringBootApplication +@EnableCaching +@EnableTransactionManagement(proxyTargetClass = true) +@EnableAsync +@Slf4j +public class CasicApplication { + public static void main(String[] args) { + SpringApplication.run(CasicApplication.class, args); + + log.info("CasicApplication is success!"); + } + +} diff --git a/casic-web/src/main/java/com/casic/missiles/CasicServletInitializer.java b/casic-web/src/main/java/com/casic/missiles/CasicServletInitializer.java new file mode 100644 index 0000000..e30585b --- /dev/null +++ b/casic-web/src/main/java/com/casic/missiles/CasicServletInitializer.java @@ -0,0 +1,18 @@ +package com.casic.missiles; + +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; + +/** + * Guns Web程序启动类 + * + * @author fengshuonan + * @date 2017-05-21 9:43 + */ +public class CasicServletInitializer extends SpringBootServletInitializer { + + @Override + protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { + return application.sources(CasicApplication.class); + } +} diff --git a/casic-web/src/main/java/com/casic/missiles/controller/MockController.java b/casic-web/src/main/java/com/casic/missiles/controller/MockController.java new file mode 100644 index 0000000..eae6c54 --- /dev/null +++ b/casic-web/src/main/java/com/casic/missiles/controller/MockController.java @@ -0,0 +1,82 @@ +package com.casic.missiles.controller; + +import cn.hutool.core.util.StrUtil; +import com.casic.missiles.core.application.enums.LoginType; +import com.casic.missiles.core.base.controller.BaseController; +import com.casic.missiles.core.model.auth.AuthUser; +import com.casic.missiles.core.model.auth.CasicCustomToken; +import com.casic.missiles.core.shiro.ShiroKit; +import com.casic.missiles.core.util.RSAUtils; +import com.casic.missiles.model.response.SuccessResponseData; +import com.casic.missiles.modular.domain.constants.PermissionConstants; +import com.casic.missiles.modular.interfaces.log.LogManager; +import com.casic.missiles.modular.interfaces.log.factory.LogTaskFactory; +import com.casic.missiles.modular.system.dto.LoginSuccessDTO; +import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.subject.Subject; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import java.security.NoSuchAlgorithmException; +import java.util.Map; + +import static com.casic.missiles.core.util.HttpContext.getIp; + + +/** + * 仅为mock登录使用 + * + * @author lenovo + */ +@Controller +@RequestMapping("/route") +@Slf4j +public class MockController extends BaseController { + + /** + * 获取mockToken + */ + @GetMapping("/mockToken") + @ResponseBody + public Object mockToken(String username, String password) { + super.getSession().setAttribute(PermissionConstants.IS_APP, false); + SuccessResponseData resultData = new SuccessResponseData(); + if (StrUtil.hasEmpty(username, password)) { + username = "admin"; + password = "111111"; + } + Subject currentUser = ShiroKit.getSubject(); + + try { + Map key = RSAUtils.genKeyPair(); + ShiroKit.getSession().setAttribute(PermissionConstants.PRIVATE_KEY, key.get(RSAUtils.RSAPrivateKey)); + + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + + //token自定义 + CasicCustomToken token = new CasicCustomToken(username, password); + token.setType(LoginType.PASSWORD); + token.setRememberMe(false); + + try { + currentUser.login(token); + } catch (Exception e) { + e.printStackTrace(); + } + AuthUser shiroUser = ShiroKit.getUser(); + super.getSession().setAttribute("shiroUser", shiroUser); + super.getSession().setAttribute("username", shiroUser.getAccount()); + super.getSession().setAttribute(PermissionConstants.SESSION_KEY, shiroUser.getId()); + + LogManager.me().executeLog(LogTaskFactory.loginLog(shiroUser.getId(), getIp())); + + ShiroKit.getSession().setAttribute("sessionFlag", true); + resultData.setData(new LoginSuccessDTO(ShiroKit.getSession().getId().toString(), null)); + resultData.setMessage("登录成功"); + return resultData; + } +} diff --git a/casic-web/src/main/resources/META-INF/spring-devtools.properties b/casic-web/src/main/resources/META-INF/spring-devtools.properties new file mode 100644 index 0000000..e3b0a7f --- /dev/null +++ b/casic-web/src/main/resources/META-INF/spring-devtools.properties @@ -0,0 +1 @@ +restart.include.beetl=/beetl-2.7.15.jar \ No newline at end of file diff --git a/casic-web/src/main/resources/config/application-dev.yml b/casic-web/src/main/resources/config/application-dev.yml new file mode 100644 index 0000000..8c18554 --- /dev/null +++ b/casic-web/src/main/resources/config/application-dev.yml @@ -0,0 +1,30 @@ +server: + port: 8083 +################### spring配置 ################### +spring: + datasource: + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://111.198.10.15:11336/casic_template2.0?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&serverTimezone=UTC&&allowMultiQueries=true + username: root + password: Casic203 +jms: + pub-sub-domain: true +# session: +# store-type: redis +# redis: +# host: 111.198.10.15 +# port: 11412 +# password: ew5T4K3#203lwh +# serializer: org.springframework.data.redis.serializer.StringRedisSerializer +# redisValueSerializer: org.springframework.data.redis.serializer.JdkSerializationRedisSerializer +casic: + #kaptcha-open: false #是否开启登录时验证码 (true/false) + no-login-urls: ${casic.sysUrl}/user/login,${casic.sysUrl}/user/appLogin,${casic.sysUrl}/kaptcha/base64,${casic.sysUrl}/config/baseConfig,/route/mockToken + #flowable数据源和多数据源配置 + db: + init: + enable: false +logging: + level.root: info + level.com.casic: debug + level.org.springframework.web: info \ No newline at end of file diff --git a/casic-web/src/main/resources/config/application-prod.yml b/casic-web/src/main/resources/config/application-prod.yml new file mode 100644 index 0000000..6553b10 --- /dev/null +++ b/casic-web/src/main/resources/config/application-prod.yml @@ -0,0 +1,34 @@ +server: + port: 8085 +# context-path: /callcenter/api +################### spring配置 ################### +spring: + datasource: + url: jdbc:mysql://10.18.0.20:3306/casic_smartcity_callcenter?autoReconnect=true&useUnicode=true&characterEncoding=utf8&useSSL=false&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull + username: root + password: Casic203 + initial-size: 2 + min-idle: 1 + jms: + pub-sub-domain: true + # session: + # store-type: redis + redis: + host: 127.0.0.1 + port: 6379 + password: + +#flowable数据源和多数据源配置 +casic: + kaptcha-open: false #是否开启登录时验证码 (true/false) + nologin-urls: /user/login,/user/appLogin,/kaptcha,/config/baseConfig,/route/mockToken + flowable: + datasource: + url: jdbc:mysql://10.18.0.20:3306/callcenter_flowable?autoReconnect=true&useUnicode=true&characterEncoding=utf8&useSSL=false&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull + username: root + password: Casic203 +logging: + level.root: info + level.com.casic: debug + path: logs/ + file: missiles.log \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9e20bc1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea/ +**/target/** +logs/ +*.iml diff --git a/README.md b/README.md new file mode 100644 index 0000000..2fdcd74 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# casic项目 V2.0.0 + +[^_^]: # (Talk is cheap,Show me the code!) + +## 介绍 +基于SpringBoot,致力于做更简洁的后台管理系统,完美整合springboot2.4 + shiro + mybatis-plus ! +基于casic项目代码简洁,注释丰富,上手容易,同时包含许多基础模块(用户管理,角色管理,部门管理,字典管理等10个模块) +可以直接作为一个后台管理系统的脚手架! 2022目标 `更简洁`,`更规范`! + + +#### 其他 +>* [git地址](http://192.168.0.203:8080/gitbucket) +>* [本地免登地址](http://localhost:8083/route/mockToken) diff --git a/casic-server/pom.xml b/casic-server/pom.xml new file mode 100644 index 0000000..c150a12 --- /dev/null +++ b/casic-server/pom.xml @@ -0,0 +1,70 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + 2.0.0 + ../pom.xml + + + casic-server + 2.0.0 + jar + casic-server + casic 的spring boot版本 + + + + + com.casic + casic-core + ${core.version} + provided + + + com.casic + casic-admin-support + ${admin.version} + provided + + + org.springframework.boot + spring-boot-starter-web + ${boot.version} + provided + + + + + com.hikvision.ga + artemis-http-client + 1.1.3 + + + commons-io + commons-io + + + org.springframework.boot + spring-boot-starter-websocket + 2.4.5 + + + io.netty + netty-all + 4.1.42.Final + + + + + + src/main/java + + **/*.xml + + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java new file mode 100644 index 0000000..3a60b9e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java @@ -0,0 +1,36 @@ +package com.casic.missiles.modular.async; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.TaskExecutor; +import org.springframework.scheduling.annotation.AsyncConfigurer; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadPoolExecutor; + +@Configuration +@EnableAsync +public class AsyncConfig implements AsyncConfigurer { + @Override + public Executor getAsyncExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + //核心线程数 + executor.setCorePoolSize(5); + //最大线程数 + executor.setMaxPoolSize(10); + //队列容量 + executor.setQueueCapacity(20); + //设置线程活跃时间(秒) + executor.setKeepAliveSeconds(60); + //默认线程名称 + executor.setThreadNamePrefix("user-rpt-"); + //拒绝策略 + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + //等待所有任务结束后再关闭线程池 + executor.setWaitForTasksToCompleteOnShutdown(true); + return executor; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java new file mode 100644 index 0000000..8ca554c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java @@ -0,0 +1,18 @@ +package com.casic.missiles.modular.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +// tomcat启动无需配置 +@Configuration +public class WebSocketConfig { + /** + * 注入ServerEndpointExporter, + * 这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint + */ + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java new file mode 100644 index 0000000..34fe2cd --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java @@ -0,0 +1,39 @@ +package com.casic.missiles.modular.controller; + + +import com.casic.missiles.model.application.event.core.EventPublisher; +import com.casic.missiles.model.application.event.enums.ModelEventTypeEnum; +import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.modular.event.UserEvent; +import com.casic.missiles.modular.system.model.User; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +/** + * @Description: DemoController + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@RestController +@RequestMapping("/demo") +public class DemoController { + @Autowired + private EventPublisher publisher; + + /** + * 获取mockToken + */ + @PostMapping("/list") + @ResponseBody + public Object list() { + User user = new User(); + user.setAccount("张三"); + publisher.publishEvent(new UserEvent(ModelEventTypeEnum.ADD, user)); + return ResponseData.success(); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java new file mode 100644 index 0000000..aff2889 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java @@ -0,0 +1,23 @@ +package com.casic.missiles.modular.event; + +import com.casic.missiles.model.application.event.core.ModelEvent; +import com.casic.missiles.model.application.event.type.AbstractEventTypeEnum; +import com.casic.missiles.modular.system.model.User; + +/** + * @Description: 用户事件 + * @Author: wangpeng + * @Date: 2022/7/17 11:23 + */ +public class UserEvent extends ModelEvent { + /** + * Create a new {@code ApplicationEvent}. + * + * @param type 事件类型 + * @param source the object on which the event initially occurred or with + * which the event is associated (never {@code null}) + */ + public UserEvent(AbstractEventTypeEnum type, User source) { + super(type, source); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java new file mode 100644 index 0000000..8f9603e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.core.application.event.UserLoginEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserOneListener { + @EventListener + public void onApplicationEvent(UserLoginEvent event) { + log.debug("用户1订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java new file mode 100644 index 0000000..0bd52a3 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.model.application.event.core.EventSubscriber; +import com.casic.missiles.modular.event.UserEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserTwoListener extends EventSubscriber { + @Override + public void onApplicationEvent(UserEvent event) { + log.debug("用户2订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java new file mode 100644 index 0000000..4012170 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java @@ -0,0 +1,88 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang3.StringUtils; +import sun.misc.BASE64Decoder; + +import java.io.*; + +public class Base64Util { + /** + * base64字符串转换成图片 + * + * @param imgStr base64字符串 + * @param imgFilePath 图片存放路径 + * @return + * @author ZHANGJL + * @dateTime 2018-02-23 14:42:17 + */ + public static boolean Base64ToImage(String imgStr, String imgFilePath, String fileDir) { // 对字节数组字符串进行Base64解码并生成图片 + + if (StringUtils.isEmpty(imgStr)) // 图像数据为空 + return false; + + imgStr = imgStr.substring(imgStr.indexOf(",") + 1); + + BASE64Decoder decoder = new BASE64Decoder(); + try { + // Base64解码 + byte[] b = decoder.decodeBuffer(imgStr); + + for (int i = 0; i < b.length; ++i) { + if (b[i] < 0) {// 调整异常数据 + b[i] += 256; + } + } + //如果已存在图像,先删除 + File file = new File(fileDir+File.separator + imgFilePath); + if (file.exists() && file.isFile()) { + file.delete(); + } + File dir = new File(fileDir); + if (!dir.exists()) { + dir.mkdirs(); + } + file = new File(fileDir+File.separator+imgFilePath); + file.createNewFile(); +// ImageIO.write(bImage, "bmp", name); + OutputStream out = new FileOutputStream(fileDir+File.separator+imgFilePath); + out.write(b); + out.flush(); + out.close(); + + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + + } + + public static String getBase64FromInputStream(InputStream in) { + // 将图片文件转化为字节数组字符串,并对其进行Base64编码处理 + byte[] data = null; + // 读取图片字节数组 + try { + ByteArrayOutputStream swapStream = new ByteArrayOutputStream(); + byte[] buff = new byte[100]; + int rc = 0; + while ((rc = in.read(buff, 0, 100)) > 0) { + swapStream.write(buff, 0, rc); + } + data = swapStream.toByteArray(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return new String(Base64.encodeBase64(data)); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java new file mode 100644 index 0000000..9c93895 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java @@ -0,0 +1,75 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.lang3.StringUtils; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class CommonUtil { + + public static String CutId(String id) { + return id.substring(6, 10) + "-" + id.substring(10, 12) + "-" + id.substring(12, 14); + } + + public static boolean isIDNumber(String IDNumber) { + if (IDNumber == null || "".equals(IDNumber)) { + return false; + } + // 定义判别用户身份证号的正则表达式(15位或者18位,最后一位可以为字母) + String regularExpression = + "(^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|" + + "(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}$)"; + boolean matches = IDNumber.matches(regularExpression); + // 判断第18位校验值 + if (matches) { + if (IDNumber.length() == 18) { + try { + char[] charArray = IDNumber.toCharArray(); + // 前十七位加权因子 + int[] idCardWi = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; + // 这是除以11后,可能产生的11位余数对应的验证码 + String[] idCardY = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"}; + int sum = 0; + for (int i = 0; i < idCardWi.length; i++) { + int current = Integer.parseInt(String.valueOf(charArray[i])); + int count = current * idCardWi[i]; + sum += count; + } + char idCardLast = charArray[17]; + int idCardMod = sum % 11; + if (idCardY[idCardMod].toUpperCase() + .equals(String.valueOf(idCardLast).toUpperCase())) { + return true; + } else { + System.out.println("身份证最后一位:" + String.valueOf(idCardLast).toUpperCase() + + "错误,正确的应该是:" + idCardY[idCardMod].toUpperCase()); + return false; + } + + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } else { + return false; + } + } + return matches; + } + + + public static boolean CheckMobilePhoneNum(String phoneNum) { + if (StringUtils.isEmpty(phoneNum)) + return true; + String regex = "^(1[3-9]\\d{9}$)"; + if (phoneNum.length() == 11) { + Pattern p = Pattern.compile(regex); + Matcher m = p.matcher(phoneNum); + if (m.matches()) { + return true; + } + } + return false; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java new file mode 100644 index 0000000..191ef79 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java @@ -0,0 +1,116 @@ +package com.casic.missiles.modular.util; + + +import javafx.util.Pair; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +/** + * Created by Administrator on 2015/2/25. + */ +public class DateUtils { + public static SimpleDateFormat sdf_day = new SimpleDateFormat("yyyy-MM-dd"); + public static SimpleDateFormat sdf_day_time = new SimpleDateFormat("yyyyMMddhhmmss"); + public static final SimpleDateFormat sdf4 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + public static final SimpleDateFormat sdf5 = new SimpleDateFormat("HH:mm:ss"); + + + /** + * 获取当年的第一天 + * + * @return + */ + public static Date getCurrYearFirst() { + Calendar currCal = Calendar.getInstance(); + int currentYear = currCal.get(Calendar.YEAR); + return getYearFirst(currentYear); + } + + + /** + * 获取某年第一天日期 + * + * @param year 年份 + * @return Date + */ + public static Date getYearFirst(int year) { + Calendar calendar = Calendar.getInstance(); + calendar.clear(); + calendar.set(Calendar.YEAR, year); + Date currYearFirst = calendar.getTime(); + return currYearFirst; + } + + /** + * 最近7日(不包括今日) + */ + public static Pair getLastSevenDays() { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, -7); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 最近n日(不包括今日) + */ + public static Pair getLastNDays(int n) { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, n * -1); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 日期时间加n天 + */ + public static String addDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf4.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf4.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 日期加n天 + */ + public static String addNDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf_day.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf_day.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 昨日 + */ + public static String getYesterday() { + + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.DATE, -2); + return sdf_day.format(calendar.getTime()); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java new file mode 100644 index 0000000..da0f8ee --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java @@ -0,0 +1,49 @@ +package com.casic.missiles.modular.util; + +import com.hikvision.artemis.sdk.ArtemisHttpUtil; +import com.hikvision.artemis.sdk.config.ArtemisConfig; + +import java.util.HashMap; +import java.util.Map; + +public class HikUtil { + + public static String hikApi(String uri, String body) { + + /** + * STEP1:设置平台参数,根据实际情况,设置host appkey appsecret 三个参数. + */ + ArtemisConfig.host = "192.168.1.22:443"; // artemis网关服务器ip端口 + ArtemisConfig.appKey = "25766251"; // 秘钥appkey + ArtemisConfig.appSecret = "h2o6zXtzCmt8eaOaMkXb";// 秘钥appSecret + + /** + * STEP2:设置OpenAPI接口的上下文 + */ + final String ARTEMIS_PATH = "/artemis"; + + /** + * STEP3:设置接口的URI地址 + */ + final String previewURLsApi = ARTEMIS_PATH + uri; + Map path = new HashMap(2) { + { + put("https://", previewURLsApi);//根据现场环境部署确认是http还是https + } + }; + + /** + * STEP4:设置参数提交方式 + */ + String contentType = "application/json"; + + /** + * STEP5:组装请求参数 + */ + /** + * STEP6:调用接口 + */ + String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, contentType, null);// post请求application/json类型参数 + return result; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java new file mode 100644 index 0000000..4867144 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java @@ -0,0 +1,149 @@ +package com.casic.missiles.modular.util; + +import org.springframework.http.*; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; + +/** + * @Description: http请求工具类 + * @Author: wangpeng + * @Date: 2022/7/17 11:49 + */ +public class HttpUtil { + /** + * get请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String get(String url, MultiValueMap params) { + return get(url, params, null); + } + + /** + * get请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String get(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.GET); + } + + /** + * post请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String post(String url, MultiValueMap params) { + return post(url, params, null); + } + + /** + * post请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String post(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.POST); + } + + /** + * put请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String put(String url, MultiValueMap params) { + return put(url, params, null); + } + + /** + * put请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String put(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.PUT); + } + + /** + * delete请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String delete(String url, MultiValueMap params) { + return delete(url, params, null); + } + + /** + * delete请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String delete(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.DELETE); + } + + /** + * 表单请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @param method 请求方式 + * @return + */ + public static String request(String url, MultiValueMap params, MultiValueMap headers, HttpMethod method) { + if (params == null) { + params = new LinkedMultiValueMap<>(); + } + return request(url, params, headers, method, MediaType.APPLICATION_FORM_URLENCODED); + } + + /** + * http请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @param method 请求方式 + * @param mediaType 参数类型 + * @return + */ + public static String request(String url, Object params, MultiValueMap headers, HttpMethod method, MediaType mediaType) { + if (url == null || url.trim().isEmpty()) { + return null; + } + RestTemplate client = new RestTemplate(); + // header + HttpHeaders httpHeaders = new HttpHeaders(); + if (headers != null) { +// httpHeaders.addAll(headers); + httpHeaders.putAll(headers); + } + // 提交方式:表单、json + httpHeaders.setContentType(mediaType); + HttpEntity httpEntity = new HttpEntity(params, httpHeaders); + ResponseEntity response = client.exchange(url, method, httpEntity, String.class); + return response.getBody(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java new file mode 100644 index 0000000..19d8d67 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java @@ -0,0 +1,30 @@ +package com.casic.missiles.modular.util; + +public class SelectDTO { + private String name; + private String value; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public SelectDTO() { + } + + public SelectDTO(String name, String value) { + this.name = name; + this.value = value; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java new file mode 100644 index 0000000..0bd484c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java @@ -0,0 +1,28 @@ +package com.casic.missiles.modular.util; + +public class SocketConst { + + /** + * 新增授权socket前缀 + */ + public static final String SOCKET_PREFIX_ADD_PERMISSION = "addPermission:"; + + /** + * 取消授权socket前缀 + */ + public static final String SOCKET_PREFIX_DELETE_PERMISSION = "deletePermission:"; + + /** + * 人员数据下发socket前缀 + */ + public static final String SOCKET_PREFIX_ADD_PERSON = "addPerson:"; + + /** + * socket返回成功信息 + */ + public static final String SOCKET_SUCCESS_MSG = "ok"; + /** + * 人员数据下发socket前缀 + */ + public static final String SOCKET_PREFIX_DELETE_PERSON = "deletePerson:"; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java new file mode 100644 index 0000000..0452bca --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java @@ -0,0 +1,90 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.io.IOUtils; +import org.springframework.stereotype.Component; + +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.text.SimpleDateFormat; +import java.util.Date; + +@Component +public class SocketUtil { + + public static byte[] sendMessage(String ip, int port, String msg) { + byte[] data = new byte[20]; + + System.out.println("往 " + ip + ":" + port + " 发送数据:" + msg); + InputStream in = null; + OutputStream out = null; + Socket socket = null; + try { + socket = new Socket(); + socket.connect(new InetSocketAddress(ip, port), 1000); + socket.setSoTimeout(2000); + // 向服务端发送数据 + out = socket.getOutputStream(); + out.write(hexString2Bytes(msg)); + out.flush(); + //socket.shutdownOutput(); + // 读取服务端返回数据 + in = socket.getInputStream(); + in.read(data); + } catch (Exception e) { + e.printStackTrace(); + } finally { + IOUtils.closeQuietly(in); + IOUtils.closeQuietly(out); + IOUtils.closeQuietly(socket); + } + return data; + } + + private static int code = 0; + + public static void main(String[] args) { +// byte[] dd = sendMessage("192.168.5.211",6001,"090300000002C543"); + + String dateStr = new SimpleDateFormat("yyMMddHHmmssSSS").format(new Date()); + //String dd = dateStr + String.format("%04d",++code); + + System.out.println(dateStr); + } + + /** + * 返回由字节数组转换来的 16 位有符号整数 + * + * @param bytes 字节数组 + * @return 由两个字节构成的 16 位有符号整数 + */ + public static short toShort(byte[] bytes) { + return (short) ((0xff & bytes[0]) | (0xff00 & (bytes[1] << 8))); + + } + + + public static byte[] hexString2Bytes(String hex) { + if ((hex == null) || (hex.equals(""))) { + return null; + } else if (hex.length() % 2 != 0) { + return null; + } else { + hex = hex.toUpperCase(); + int len = hex.length() / 2; + byte[] b = new byte[len]; + char[] hc = hex.toCharArray(); + for (int i = 0; i < len; i++) { + int p = 2 * i; + b[i] = (byte) (charToByte(hc[p]) << 4 | charToByte(hc[p + 1])); + } + return b; + } + } + + private static byte charToByte(char c) { + return (byte) "0123456789ABCDEF".indexOf(c); + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java b/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java new file mode 100644 index 0000000..9b4155c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java @@ -0,0 +1,105 @@ +package com.casic.missiles.modular.util; + +import org.springframework.stereotype.Component; + +import javax.websocket.OnClose; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.PathParam; +import javax.websocket.server.ServerEndpoint; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CopyOnWriteArraySet; + +/** + * @Description: 此注解相当于设置访问URL + * @Author: wangpeng + * @Date: 2022/7/17 11:48 + */ +@Component +@ServerEndpoint("/websocket/{userId}") +public class WebSocket { + private Session session; + + private static CopyOnWriteArraySet webSockets = new CopyOnWriteArraySet<>(); + private static Map sessionPool = new HashMap(); + + @OnOpen + public void onOpen(Session session, @PathParam(value = "userId") String userId) { + this.session = session; + webSockets.add(this); + sessionPool.put(userId, session); + System.out.println(userId + "【websocket消息】有新的连接,总数为:" + webSockets.size()); + } + + @OnClose + public void onClose() { + webSockets.remove(this); + System.out.println("【websocket消息】连接断开,总数为:" + webSockets.size()); + } + + @OnMessage + public void onMessage(String message) { + System.out.println("【websocket消息】收到客户端消息:" + message); + } + + // 此为广播消息 + public void sendAllMessage(String message) { + for (WebSocket webSocket : webSockets) { + System.out.println("【websocket消息】广播消息:" + message); + try { + webSocket.session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + // 发送列表消息 + public void sendListMessage(List userIds, String message) { + System.out.println("【websocket消息】列表消息:" + message); + for (String userId : userIds) { + Session session = sessionPool.get(userId); + if (session != null) { + try { + session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + + // 发送列表消息 + +// public void sendListMessage(List userIds, Object data){ +// System.out.println("【websocket消息】列表消息:"+data); +// for (String userId : userIds) { +// Session session = sessionPool.get(userId); +// if (session != null) { +// try { +//// session.getAsyncRemote().sendText(message); +// session.getAsyncRemote().sendObject(data); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// } +// } + + // 此为单点消息 + public void sendOneMessage(String userId, String message) { + System.out.println("【websocket消息】单点消息:" + message); + Session session = sessionPool.get(userId); + if (session != null) { + try { + session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java new file mode 100644 index 0000000..0c1f5f1 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java @@ -0,0 +1,115 @@ +package com.casic.missiles.modular.util; + +import org.springframework.web.multipart.MultipartFile; + +import java.io.*; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipInputStream; + +/** + * @Description: 读取zip文件内容 + * @Author: wangpeng + * @Date: 2022/7/17 11:48 + */ +public class ZipFileUtil { + public static List getFile(String fileName) { + File file = new File(fileName); + ZipFile zipFile = null; + ZipInputStream zin = null; + FileInputStream fis = null; + List selectDTOList = new ArrayList<>(); + try { + Charset gbk = Charset.forName("GBK"); + zipFile = new ZipFile(file, gbk); + fis = new FileInputStream(file); + zin = new ZipInputStream(fis, gbk); + + ZipEntry ze = null; + while ((ze = zin.getNextEntry()) != null) { + String path = ze.getName(); + System.out.println(path); + if (!ze.isDirectory()) { + InputStream inputStream = zipFile.getInputStream(ze); + String base64Photo = Base64Util.getBase64FromInputStream(inputStream); +// List texts = IOUtils.readLines(inputStream); +// for (String text : texts) { +// System.out.println(" " + text); +// } + selectDTOList.add(new SelectDTO(path.substring(path.indexOf("/")+1), "data:image/png;base64,"+base64Photo)); + inputStream.close(); + } + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (zin != null) { + zin.closeEntry(); + zin.close(); + } + if (fis != null) + fis.close(); + if (zipFile != null) + zipFile.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return selectDTOList; + } + + + /** + * MultipartFile 转 File + * + * @param file + * @throws Exception + */ + public static File multipartFileToFile(MultipartFile file) throws Exception { + + File toFile = null; + if (file.equals("") || file.getSize() <= 0) { + file = null; + } else { + InputStream ins = null; + ins = file.getInputStream(); + toFile = new File(file.getOriginalFilename()); + inputStreamToFile(ins, toFile); + ins.close(); + } + return toFile; + } + + //获取流文件 + private static void inputStreamToFile(InputStream ins, File file) { + try { + OutputStream os = new FileOutputStream(file); + int bytesRead = 0; + byte[] buffer = new byte[8192]; + while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) { + os.write(buffer, 0, bytesRead); + } + os.close(); + ins.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 删除本地临时文件 + * + * @param file + */ + public static void delteTempFile(File file) { + if (file != null) { + File del = new File(file.toURI()); + del.delete(); + } + } +} + diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java new file mode 100644 index 0000000..ae93a17 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java @@ -0,0 +1,34 @@ +package com.casic.missiles.modular.util.netty; + +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.EventLoop; +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.TimeUnit; + +/** + * 负责监听启动时连接失败,重新连接功能 + * + */ +@Slf4j +public class ConnectionListener implements ChannelFutureListener { + + private NettyClient client = new NettyClient(); + + @Override + public void operationComplete(ChannelFuture channelFuture) throws Exception { + if (!channelFuture.isSuccess()) { + final EventLoop loop = channelFuture.channel().eventLoop(); + loop.schedule(new Runnable() { + @Override + public void run() { + log.info("服务端连接不上,开始重连操作..."); + client.connect(); + } + }, 5L, TimeUnit.MINUTES); + } else { + log.info("服务端连接成功..."); + } + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java new file mode 100644 index 0000000..ef9ae76 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java @@ -0,0 +1,66 @@ +package com.casic.missiles.modular.util.netty; + +import io.netty.bootstrap.Bootstrap; +import io.netty.channel.*; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioSocketChannel; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public class NettyClient { + + private static Channel channel; + + private String fenceServiceHost = "127.0.0.1"; + private Integer fenceServicePort = 9200; + + public Channel connect() { + doConnect(fenceServiceHost, fenceServicePort); + return channel; + } + + public Channel connect(String host, int port) { + doConnect(host, port); + return channel; + } + + private void doConnect(String host, int port) { + EventLoopGroup workerGroup = new NioEventLoopGroup(); + try { + Bootstrap b = new Bootstrap(); + b.group(workerGroup); + b.channel(NioSocketChannel.class); + b.option(ChannelOption.SO_KEEPALIVE, true); + b.option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(1024 * 1024)); + + b.handler(new ChannelInitializer() { + @Override + public void initChannel(SocketChannel ch) throws Exception { + + ch.pipeline().addLast("decoder", new StringDecoder()); + ch.pipeline().addLast("encoder", new StringEncoder()); + ch.pipeline().addLast(new NettyClientHandler()); + } + }); + + ChannelFuture f = b.connect(host, port); + f.addListener(new ConnectionListener()); + channel = f.channel(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static void writeAndFlush(String message) { + + if (channel != null) { + channel.writeAndFlush(message); + System.out.println("电子围栏客户端发送消息:" + message); + } + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClientHandler.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClientHandler.java new file mode 100644 index 0000000..28093f0 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClientHandler.java @@ -0,0 +1,62 @@ +package com.casic.missiles.modular.util.netty; + +import com.casic.missiles.modular.util.HttpUtil; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import io.netty.channel.EventLoop; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; + +import java.util.concurrent.TimeUnit; + +/** + * 客户端处理器 + **/ +@Slf4j +@Component +public class NettyClientHandler extends ChannelInboundHandlerAdapter { + static boolean handle = true; + + private NettyClient client = new NettyClient(); + + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + log.info("连接成功....."); + } + + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + log.info("断开连接....."); + + //使用过程中断线重连 + final EventLoop eventLoop = ctx.channel().eventLoop(); + eventLoop.schedule(new Runnable() { + @Override + public void run() { + client.connect(); + } + }, 5L, TimeUnit.SECONDS); + super.channelInactive(ctx); + } + + + @Override + public void channelRead(ChannelHandlerContext ctx, Object message) throws Exception { + + if (handle) { + MultiValueMap map = new LinkedMultiValueMap<>(); + map.add("message", message.toString()); + HttpUtil.post("http://127.0.0.1:20311/data/addPerimeterAlarm", map); + } + handle = !handle; + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + cause.printStackTrace(); + ctx.close(); + } +} + diff --git a/casic-web/pom.xml b/casic-web/pom.xml new file mode 100644 index 0000000..8fb0b2c --- /dev/null +++ b/casic-web/pom.xml @@ -0,0 +1,171 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + ../pom.xml + 2.0.0 + + casic-web + 2.0.0 + jar + casic-web + casic web启动入口 + + + + dev + + true + + + dev + + + + test + + test + + + + prod + + prod + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + io.micrometer + micrometer-core + + + + + org.springframework.boot + spring-boot-starter-jdbc + + + + com.casic + casic-core + ${core.version} + + + com.casic + casic-admin-core + ${admin.version} + + + io.springfox + springfox-swagger-ui + + + + + com.casic + casic-admin-support + ${admin.version} + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.dameng + DmJdbcDriver18 + 1.8 + + + com.casic + casic-area-starter + ${admin.version} + + + + com.casic + casic-server + ${pro.version} + + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + + + org.apache.maven.plugins + maven-jar-plugin + ${maven.jar.plugin.version} + + + + /config/*-*.yml + **/MockController.class + + + + com.casic.missiles.CasicApplication + true + ./ + + + + + + org.apache.maven.plugins + maven-assembly-plugin + ${maven.assembly.plugin.version} + + + make-assembly + package + + single + + + + + + org.apache.maven.plugins + maven-war-plugin + ${maven.war.plugin.version} + + + + + src/main/resources + + + /config/*/* + /config/*-*.yml + + true + + + src/main/java + + **/*.xml + + true + + + + \ No newline at end of file diff --git a/casic-web/src/main/build/bin/start.bat b/casic-web/src/main/build/bin/start.bat new file mode 100644 index 0000000..1db4e88 --- /dev/null +++ b/casic-web/src/main/build/bin/start.bat @@ -0,0 +1,4 @@ +@echo off +title ${project.build.finalName} +java -jar ./lib/${project.build.finalName}.jar +@pause diff --git a/casic-web/src/main/build/bin/start.sh b/casic-web/src/main/build/bin/start.sh new file mode 100644 index 0000000..c00b1ef --- /dev/null +++ b/casic-web/src/main/build/bin/start.sh @@ -0,0 +1,2 @@ +java -jar ./lib/${project.build.finalName}.jar + diff --git a/casic-web/src/main/build/package.xml b/casic-web/src/main/build/package.xml new file mode 100644 index 0000000..c9259ad --- /dev/null +++ b/casic-web/src/main/build/package.xml @@ -0,0 +1,43 @@ + + + package + + zip + tar.gz + + true + + + + true + true + lib + runtime + + + + + src/main/build/bin + + start.bat + start.sh + + true + 0744 + / + + + src/main/resources/config + true + + *.yml + /*/* + + /config + + + src/main/resources/i18n + / + + + \ No newline at end of file diff --git a/casic-web/src/main/java/com/casic/missiles/CasicApplication.java b/casic-web/src/main/java/com/casic/missiles/CasicApplication.java new file mode 100644 index 0000000..308dcad --- /dev/null +++ b/casic-web/src/main/java/com/casic/missiles/CasicApplication.java @@ -0,0 +1,29 @@ +package com.casic.missiles; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.ServletComponentScan; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +/** + * SpringBoot方式启动类 + * + * @author lwh + * @Date 2021/06/06 12:06 + */ +@SpringBootApplication +@EnableCaching +@EnableTransactionManagement(proxyTargetClass = true) +@EnableAsync +@Slf4j +public class CasicApplication { + public static void main(String[] args) { + SpringApplication.run(CasicApplication.class, args); + + log.info("CasicApplication is success!"); + } + +} diff --git a/casic-web/src/main/java/com/casic/missiles/CasicServletInitializer.java b/casic-web/src/main/java/com/casic/missiles/CasicServletInitializer.java new file mode 100644 index 0000000..e30585b --- /dev/null +++ b/casic-web/src/main/java/com/casic/missiles/CasicServletInitializer.java @@ -0,0 +1,18 @@ +package com.casic.missiles; + +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; + +/** + * Guns Web程序启动类 + * + * @author fengshuonan + * @date 2017-05-21 9:43 + */ +public class CasicServletInitializer extends SpringBootServletInitializer { + + @Override + protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { + return application.sources(CasicApplication.class); + } +} diff --git a/casic-web/src/main/java/com/casic/missiles/controller/MockController.java b/casic-web/src/main/java/com/casic/missiles/controller/MockController.java new file mode 100644 index 0000000..eae6c54 --- /dev/null +++ b/casic-web/src/main/java/com/casic/missiles/controller/MockController.java @@ -0,0 +1,82 @@ +package com.casic.missiles.controller; + +import cn.hutool.core.util.StrUtil; +import com.casic.missiles.core.application.enums.LoginType; +import com.casic.missiles.core.base.controller.BaseController; +import com.casic.missiles.core.model.auth.AuthUser; +import com.casic.missiles.core.model.auth.CasicCustomToken; +import com.casic.missiles.core.shiro.ShiroKit; +import com.casic.missiles.core.util.RSAUtils; +import com.casic.missiles.model.response.SuccessResponseData; +import com.casic.missiles.modular.domain.constants.PermissionConstants; +import com.casic.missiles.modular.interfaces.log.LogManager; +import com.casic.missiles.modular.interfaces.log.factory.LogTaskFactory; +import com.casic.missiles.modular.system.dto.LoginSuccessDTO; +import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.subject.Subject; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import java.security.NoSuchAlgorithmException; +import java.util.Map; + +import static com.casic.missiles.core.util.HttpContext.getIp; + + +/** + * 仅为mock登录使用 + * + * @author lenovo + */ +@Controller +@RequestMapping("/route") +@Slf4j +public class MockController extends BaseController { + + /** + * 获取mockToken + */ + @GetMapping("/mockToken") + @ResponseBody + public Object mockToken(String username, String password) { + super.getSession().setAttribute(PermissionConstants.IS_APP, false); + SuccessResponseData resultData = new SuccessResponseData(); + if (StrUtil.hasEmpty(username, password)) { + username = "admin"; + password = "111111"; + } + Subject currentUser = ShiroKit.getSubject(); + + try { + Map key = RSAUtils.genKeyPair(); + ShiroKit.getSession().setAttribute(PermissionConstants.PRIVATE_KEY, key.get(RSAUtils.RSAPrivateKey)); + + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + + //token自定义 + CasicCustomToken token = new CasicCustomToken(username, password); + token.setType(LoginType.PASSWORD); + token.setRememberMe(false); + + try { + currentUser.login(token); + } catch (Exception e) { + e.printStackTrace(); + } + AuthUser shiroUser = ShiroKit.getUser(); + super.getSession().setAttribute("shiroUser", shiroUser); + super.getSession().setAttribute("username", shiroUser.getAccount()); + super.getSession().setAttribute(PermissionConstants.SESSION_KEY, shiroUser.getId()); + + LogManager.me().executeLog(LogTaskFactory.loginLog(shiroUser.getId(), getIp())); + + ShiroKit.getSession().setAttribute("sessionFlag", true); + resultData.setData(new LoginSuccessDTO(ShiroKit.getSession().getId().toString(), null)); + resultData.setMessage("登录成功"); + return resultData; + } +} diff --git a/casic-web/src/main/resources/META-INF/spring-devtools.properties b/casic-web/src/main/resources/META-INF/spring-devtools.properties new file mode 100644 index 0000000..e3b0a7f --- /dev/null +++ b/casic-web/src/main/resources/META-INF/spring-devtools.properties @@ -0,0 +1 @@ +restart.include.beetl=/beetl-2.7.15.jar \ No newline at end of file diff --git a/casic-web/src/main/resources/config/application-dev.yml b/casic-web/src/main/resources/config/application-dev.yml new file mode 100644 index 0000000..8c18554 --- /dev/null +++ b/casic-web/src/main/resources/config/application-dev.yml @@ -0,0 +1,30 @@ +server: + port: 8083 +################### spring配置 ################### +spring: + datasource: + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://111.198.10.15:11336/casic_template2.0?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&serverTimezone=UTC&&allowMultiQueries=true + username: root + password: Casic203 +jms: + pub-sub-domain: true +# session: +# store-type: redis +# redis: +# host: 111.198.10.15 +# port: 11412 +# password: ew5T4K3#203lwh +# serializer: org.springframework.data.redis.serializer.StringRedisSerializer +# redisValueSerializer: org.springframework.data.redis.serializer.JdkSerializationRedisSerializer +casic: + #kaptcha-open: false #是否开启登录时验证码 (true/false) + no-login-urls: ${casic.sysUrl}/user/login,${casic.sysUrl}/user/appLogin,${casic.sysUrl}/kaptcha/base64,${casic.sysUrl}/config/baseConfig,/route/mockToken + #flowable数据源和多数据源配置 + db: + init: + enable: false +logging: + level.root: info + level.com.casic: debug + level.org.springframework.web: info \ No newline at end of file diff --git a/casic-web/src/main/resources/config/application-prod.yml b/casic-web/src/main/resources/config/application-prod.yml new file mode 100644 index 0000000..6553b10 --- /dev/null +++ b/casic-web/src/main/resources/config/application-prod.yml @@ -0,0 +1,34 @@ +server: + port: 8085 +# context-path: /callcenter/api +################### spring配置 ################### +spring: + datasource: + url: jdbc:mysql://10.18.0.20:3306/casic_smartcity_callcenter?autoReconnect=true&useUnicode=true&characterEncoding=utf8&useSSL=false&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull + username: root + password: Casic203 + initial-size: 2 + min-idle: 1 + jms: + pub-sub-domain: true + # session: + # store-type: redis + redis: + host: 127.0.0.1 + port: 6379 + password: + +#flowable数据源和多数据源配置 +casic: + kaptcha-open: false #是否开启登录时验证码 (true/false) + nologin-urls: /user/login,/user/appLogin,/kaptcha,/config/baseConfig,/route/mockToken + flowable: + datasource: + url: jdbc:mysql://10.18.0.20:3306/callcenter_flowable?autoReconnect=true&useUnicode=true&characterEncoding=utf8&useSSL=false&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull + username: root + password: Casic203 +logging: + level.root: info + level.com.casic: debug + path: logs/ + file: missiles.log \ No newline at end of file diff --git a/casic-web/src/main/resources/config/application-test.yml b/casic-web/src/main/resources/config/application-test.yml new file mode 100644 index 0000000..54d7252 --- /dev/null +++ b/casic-web/src/main/resources/config/application-test.yml @@ -0,0 +1,30 @@ +server: + port: 11307 +################### spring配置 ################### +spring: + datasource: + url: jdbc:mysql://localhost:3306/casic_template?autoReconnect=true&useUnicode=true&characterEncoding=utf8&useSSL=false&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull + username: root + password: Casic203! + initial-size: 2 + min-idle: 1 + jms: + pub-sub-domain: true +# session: +# store-type: redis +casic: + # kaptcha-open: false #是否开启登录时验证码 (true/false) + nologin-urls: /user/login,/user/appLogin,/kaptcha/base64,/config/baseConfig,/route/mockToken,/workflow/** + #flowable数据源和多数据源配置 + flowable: + datasource: + url: jdbc:mysql://localhost:3306/template_flowable?autoReconnect=true&useUnicode=true&characterEncoding=utf8&useSSL=false&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull + username: root + password: Casic203! +flowable: + checkProcessDefinitions: false #不校验process文件 +logging: + level.root: info + level.com.casic: debug + path: logs/ + file: missiles.log \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9e20bc1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea/ +**/target/** +logs/ +*.iml diff --git a/README.md b/README.md new file mode 100644 index 0000000..2fdcd74 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# casic项目 V2.0.0 + +[^_^]: # (Talk is cheap,Show me the code!) + +## 介绍 +基于SpringBoot,致力于做更简洁的后台管理系统,完美整合springboot2.4 + shiro + mybatis-plus ! +基于casic项目代码简洁,注释丰富,上手容易,同时包含许多基础模块(用户管理,角色管理,部门管理,字典管理等10个模块) +可以直接作为一个后台管理系统的脚手架! 2022目标 `更简洁`,`更规范`! + + +#### 其他 +>* [git地址](http://192.168.0.203:8080/gitbucket) +>* [本地免登地址](http://localhost:8083/route/mockToken) diff --git a/casic-server/pom.xml b/casic-server/pom.xml new file mode 100644 index 0000000..c150a12 --- /dev/null +++ b/casic-server/pom.xml @@ -0,0 +1,70 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + 2.0.0 + ../pom.xml + + + casic-server + 2.0.0 + jar + casic-server + casic 的spring boot版本 + + + + + com.casic + casic-core + ${core.version} + provided + + + com.casic + casic-admin-support + ${admin.version} + provided + + + org.springframework.boot + spring-boot-starter-web + ${boot.version} + provided + + + + + com.hikvision.ga + artemis-http-client + 1.1.3 + + + commons-io + commons-io + + + org.springframework.boot + spring-boot-starter-websocket + 2.4.5 + + + io.netty + netty-all + 4.1.42.Final + + + + + + src/main/java + + **/*.xml + + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java new file mode 100644 index 0000000..3a60b9e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java @@ -0,0 +1,36 @@ +package com.casic.missiles.modular.async; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.TaskExecutor; +import org.springframework.scheduling.annotation.AsyncConfigurer; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadPoolExecutor; + +@Configuration +@EnableAsync +public class AsyncConfig implements AsyncConfigurer { + @Override + public Executor getAsyncExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + //核心线程数 + executor.setCorePoolSize(5); + //最大线程数 + executor.setMaxPoolSize(10); + //队列容量 + executor.setQueueCapacity(20); + //设置线程活跃时间(秒) + executor.setKeepAliveSeconds(60); + //默认线程名称 + executor.setThreadNamePrefix("user-rpt-"); + //拒绝策略 + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + //等待所有任务结束后再关闭线程池 + executor.setWaitForTasksToCompleteOnShutdown(true); + return executor; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java new file mode 100644 index 0000000..8ca554c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java @@ -0,0 +1,18 @@ +package com.casic.missiles.modular.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +// tomcat启动无需配置 +@Configuration +public class WebSocketConfig { + /** + * 注入ServerEndpointExporter, + * 这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint + */ + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java new file mode 100644 index 0000000..34fe2cd --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java @@ -0,0 +1,39 @@ +package com.casic.missiles.modular.controller; + + +import com.casic.missiles.model.application.event.core.EventPublisher; +import com.casic.missiles.model.application.event.enums.ModelEventTypeEnum; +import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.modular.event.UserEvent; +import com.casic.missiles.modular.system.model.User; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +/** + * @Description: DemoController + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@RestController +@RequestMapping("/demo") +public class DemoController { + @Autowired + private EventPublisher publisher; + + /** + * 获取mockToken + */ + @PostMapping("/list") + @ResponseBody + public Object list() { + User user = new User(); + user.setAccount("张三"); + publisher.publishEvent(new UserEvent(ModelEventTypeEnum.ADD, user)); + return ResponseData.success(); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java new file mode 100644 index 0000000..aff2889 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java @@ -0,0 +1,23 @@ +package com.casic.missiles.modular.event; + +import com.casic.missiles.model.application.event.core.ModelEvent; +import com.casic.missiles.model.application.event.type.AbstractEventTypeEnum; +import com.casic.missiles.modular.system.model.User; + +/** + * @Description: 用户事件 + * @Author: wangpeng + * @Date: 2022/7/17 11:23 + */ +public class UserEvent extends ModelEvent { + /** + * Create a new {@code ApplicationEvent}. + * + * @param type 事件类型 + * @param source the object on which the event initially occurred or with + * which the event is associated (never {@code null}) + */ + public UserEvent(AbstractEventTypeEnum type, User source) { + super(type, source); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java new file mode 100644 index 0000000..8f9603e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.core.application.event.UserLoginEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserOneListener { + @EventListener + public void onApplicationEvent(UserLoginEvent event) { + log.debug("用户1订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java new file mode 100644 index 0000000..0bd52a3 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.model.application.event.core.EventSubscriber; +import com.casic.missiles.modular.event.UserEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserTwoListener extends EventSubscriber { + @Override + public void onApplicationEvent(UserEvent event) { + log.debug("用户2订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java new file mode 100644 index 0000000..4012170 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java @@ -0,0 +1,88 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang3.StringUtils; +import sun.misc.BASE64Decoder; + +import java.io.*; + +public class Base64Util { + /** + * base64字符串转换成图片 + * + * @param imgStr base64字符串 + * @param imgFilePath 图片存放路径 + * @return + * @author ZHANGJL + * @dateTime 2018-02-23 14:42:17 + */ + public static boolean Base64ToImage(String imgStr, String imgFilePath, String fileDir) { // 对字节数组字符串进行Base64解码并生成图片 + + if (StringUtils.isEmpty(imgStr)) // 图像数据为空 + return false; + + imgStr = imgStr.substring(imgStr.indexOf(",") + 1); + + BASE64Decoder decoder = new BASE64Decoder(); + try { + // Base64解码 + byte[] b = decoder.decodeBuffer(imgStr); + + for (int i = 0; i < b.length; ++i) { + if (b[i] < 0) {// 调整异常数据 + b[i] += 256; + } + } + //如果已存在图像,先删除 + File file = new File(fileDir+File.separator + imgFilePath); + if (file.exists() && file.isFile()) { + file.delete(); + } + File dir = new File(fileDir); + if (!dir.exists()) { + dir.mkdirs(); + } + file = new File(fileDir+File.separator+imgFilePath); + file.createNewFile(); +// ImageIO.write(bImage, "bmp", name); + OutputStream out = new FileOutputStream(fileDir+File.separator+imgFilePath); + out.write(b); + out.flush(); + out.close(); + + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + + } + + public static String getBase64FromInputStream(InputStream in) { + // 将图片文件转化为字节数组字符串,并对其进行Base64编码处理 + byte[] data = null; + // 读取图片字节数组 + try { + ByteArrayOutputStream swapStream = new ByteArrayOutputStream(); + byte[] buff = new byte[100]; + int rc = 0; + while ((rc = in.read(buff, 0, 100)) > 0) { + swapStream.write(buff, 0, rc); + } + data = swapStream.toByteArray(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return new String(Base64.encodeBase64(data)); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java new file mode 100644 index 0000000..9c93895 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java @@ -0,0 +1,75 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.lang3.StringUtils; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class CommonUtil { + + public static String CutId(String id) { + return id.substring(6, 10) + "-" + id.substring(10, 12) + "-" + id.substring(12, 14); + } + + public static boolean isIDNumber(String IDNumber) { + if (IDNumber == null || "".equals(IDNumber)) { + return false; + } + // 定义判别用户身份证号的正则表达式(15位或者18位,最后一位可以为字母) + String regularExpression = + "(^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|" + + "(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}$)"; + boolean matches = IDNumber.matches(regularExpression); + // 判断第18位校验值 + if (matches) { + if (IDNumber.length() == 18) { + try { + char[] charArray = IDNumber.toCharArray(); + // 前十七位加权因子 + int[] idCardWi = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; + // 这是除以11后,可能产生的11位余数对应的验证码 + String[] idCardY = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"}; + int sum = 0; + for (int i = 0; i < idCardWi.length; i++) { + int current = Integer.parseInt(String.valueOf(charArray[i])); + int count = current * idCardWi[i]; + sum += count; + } + char idCardLast = charArray[17]; + int idCardMod = sum % 11; + if (idCardY[idCardMod].toUpperCase() + .equals(String.valueOf(idCardLast).toUpperCase())) { + return true; + } else { + System.out.println("身份证最后一位:" + String.valueOf(idCardLast).toUpperCase() + + "错误,正确的应该是:" + idCardY[idCardMod].toUpperCase()); + return false; + } + + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } else { + return false; + } + } + return matches; + } + + + public static boolean CheckMobilePhoneNum(String phoneNum) { + if (StringUtils.isEmpty(phoneNum)) + return true; + String regex = "^(1[3-9]\\d{9}$)"; + if (phoneNum.length() == 11) { + Pattern p = Pattern.compile(regex); + Matcher m = p.matcher(phoneNum); + if (m.matches()) { + return true; + } + } + return false; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java new file mode 100644 index 0000000..191ef79 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java @@ -0,0 +1,116 @@ +package com.casic.missiles.modular.util; + + +import javafx.util.Pair; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +/** + * Created by Administrator on 2015/2/25. + */ +public class DateUtils { + public static SimpleDateFormat sdf_day = new SimpleDateFormat("yyyy-MM-dd"); + public static SimpleDateFormat sdf_day_time = new SimpleDateFormat("yyyyMMddhhmmss"); + public static final SimpleDateFormat sdf4 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + public static final SimpleDateFormat sdf5 = new SimpleDateFormat("HH:mm:ss"); + + + /** + * 获取当年的第一天 + * + * @return + */ + public static Date getCurrYearFirst() { + Calendar currCal = Calendar.getInstance(); + int currentYear = currCal.get(Calendar.YEAR); + return getYearFirst(currentYear); + } + + + /** + * 获取某年第一天日期 + * + * @param year 年份 + * @return Date + */ + public static Date getYearFirst(int year) { + Calendar calendar = Calendar.getInstance(); + calendar.clear(); + calendar.set(Calendar.YEAR, year); + Date currYearFirst = calendar.getTime(); + return currYearFirst; + } + + /** + * 最近7日(不包括今日) + */ + public static Pair getLastSevenDays() { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, -7); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 最近n日(不包括今日) + */ + public static Pair getLastNDays(int n) { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, n * -1); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 日期时间加n天 + */ + public static String addDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf4.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf4.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 日期加n天 + */ + public static String addNDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf_day.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf_day.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 昨日 + */ + public static String getYesterday() { + + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.DATE, -2); + return sdf_day.format(calendar.getTime()); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java new file mode 100644 index 0000000..da0f8ee --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java @@ -0,0 +1,49 @@ +package com.casic.missiles.modular.util; + +import com.hikvision.artemis.sdk.ArtemisHttpUtil; +import com.hikvision.artemis.sdk.config.ArtemisConfig; + +import java.util.HashMap; +import java.util.Map; + +public class HikUtil { + + public static String hikApi(String uri, String body) { + + /** + * STEP1:设置平台参数,根据实际情况,设置host appkey appsecret 三个参数. + */ + ArtemisConfig.host = "192.168.1.22:443"; // artemis网关服务器ip端口 + ArtemisConfig.appKey = "25766251"; // 秘钥appkey + ArtemisConfig.appSecret = "h2o6zXtzCmt8eaOaMkXb";// 秘钥appSecret + + /** + * STEP2:设置OpenAPI接口的上下文 + */ + final String ARTEMIS_PATH = "/artemis"; + + /** + * STEP3:设置接口的URI地址 + */ + final String previewURLsApi = ARTEMIS_PATH + uri; + Map path = new HashMap(2) { + { + put("https://", previewURLsApi);//根据现场环境部署确认是http还是https + } + }; + + /** + * STEP4:设置参数提交方式 + */ + String contentType = "application/json"; + + /** + * STEP5:组装请求参数 + */ + /** + * STEP6:调用接口 + */ + String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, contentType, null);// post请求application/json类型参数 + return result; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java new file mode 100644 index 0000000..4867144 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java @@ -0,0 +1,149 @@ +package com.casic.missiles.modular.util; + +import org.springframework.http.*; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; + +/** + * @Description: http请求工具类 + * @Author: wangpeng + * @Date: 2022/7/17 11:49 + */ +public class HttpUtil { + /** + * get请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String get(String url, MultiValueMap params) { + return get(url, params, null); + } + + /** + * get请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String get(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.GET); + } + + /** + * post请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String post(String url, MultiValueMap params) { + return post(url, params, null); + } + + /** + * post请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String post(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.POST); + } + + /** + * put请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String put(String url, MultiValueMap params) { + return put(url, params, null); + } + + /** + * put请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String put(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.PUT); + } + + /** + * delete请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String delete(String url, MultiValueMap params) { + return delete(url, params, null); + } + + /** + * delete请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String delete(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.DELETE); + } + + /** + * 表单请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @param method 请求方式 + * @return + */ + public static String request(String url, MultiValueMap params, MultiValueMap headers, HttpMethod method) { + if (params == null) { + params = new LinkedMultiValueMap<>(); + } + return request(url, params, headers, method, MediaType.APPLICATION_FORM_URLENCODED); + } + + /** + * http请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @param method 请求方式 + * @param mediaType 参数类型 + * @return + */ + public static String request(String url, Object params, MultiValueMap headers, HttpMethod method, MediaType mediaType) { + if (url == null || url.trim().isEmpty()) { + return null; + } + RestTemplate client = new RestTemplate(); + // header + HttpHeaders httpHeaders = new HttpHeaders(); + if (headers != null) { +// httpHeaders.addAll(headers); + httpHeaders.putAll(headers); + } + // 提交方式:表单、json + httpHeaders.setContentType(mediaType); + HttpEntity httpEntity = new HttpEntity(params, httpHeaders); + ResponseEntity response = client.exchange(url, method, httpEntity, String.class); + return response.getBody(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java new file mode 100644 index 0000000..19d8d67 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java @@ -0,0 +1,30 @@ +package com.casic.missiles.modular.util; + +public class SelectDTO { + private String name; + private String value; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public SelectDTO() { + } + + public SelectDTO(String name, String value) { + this.name = name; + this.value = value; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java new file mode 100644 index 0000000..0bd484c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java @@ -0,0 +1,28 @@ +package com.casic.missiles.modular.util; + +public class SocketConst { + + /** + * 新增授权socket前缀 + */ + public static final String SOCKET_PREFIX_ADD_PERMISSION = "addPermission:"; + + /** + * 取消授权socket前缀 + */ + public static final String SOCKET_PREFIX_DELETE_PERMISSION = "deletePermission:"; + + /** + * 人员数据下发socket前缀 + */ + public static final String SOCKET_PREFIX_ADD_PERSON = "addPerson:"; + + /** + * socket返回成功信息 + */ + public static final String SOCKET_SUCCESS_MSG = "ok"; + /** + * 人员数据下发socket前缀 + */ + public static final String SOCKET_PREFIX_DELETE_PERSON = "deletePerson:"; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java new file mode 100644 index 0000000..0452bca --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java @@ -0,0 +1,90 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.io.IOUtils; +import org.springframework.stereotype.Component; + +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.text.SimpleDateFormat; +import java.util.Date; + +@Component +public class SocketUtil { + + public static byte[] sendMessage(String ip, int port, String msg) { + byte[] data = new byte[20]; + + System.out.println("往 " + ip + ":" + port + " 发送数据:" + msg); + InputStream in = null; + OutputStream out = null; + Socket socket = null; + try { + socket = new Socket(); + socket.connect(new InetSocketAddress(ip, port), 1000); + socket.setSoTimeout(2000); + // 向服务端发送数据 + out = socket.getOutputStream(); + out.write(hexString2Bytes(msg)); + out.flush(); + //socket.shutdownOutput(); + // 读取服务端返回数据 + in = socket.getInputStream(); + in.read(data); + } catch (Exception e) { + e.printStackTrace(); + } finally { + IOUtils.closeQuietly(in); + IOUtils.closeQuietly(out); + IOUtils.closeQuietly(socket); + } + return data; + } + + private static int code = 0; + + public static void main(String[] args) { +// byte[] dd = sendMessage("192.168.5.211",6001,"090300000002C543"); + + String dateStr = new SimpleDateFormat("yyMMddHHmmssSSS").format(new Date()); + //String dd = dateStr + String.format("%04d",++code); + + System.out.println(dateStr); + } + + /** + * 返回由字节数组转换来的 16 位有符号整数 + * + * @param bytes 字节数组 + * @return 由两个字节构成的 16 位有符号整数 + */ + public static short toShort(byte[] bytes) { + return (short) ((0xff & bytes[0]) | (0xff00 & (bytes[1] << 8))); + + } + + + public static byte[] hexString2Bytes(String hex) { + if ((hex == null) || (hex.equals(""))) { + return null; + } else if (hex.length() % 2 != 0) { + return null; + } else { + hex = hex.toUpperCase(); + int len = hex.length() / 2; + byte[] b = new byte[len]; + char[] hc = hex.toCharArray(); + for (int i = 0; i < len; i++) { + int p = 2 * i; + b[i] = (byte) (charToByte(hc[p]) << 4 | charToByte(hc[p + 1])); + } + return b; + } + } + + private static byte charToByte(char c) { + return (byte) "0123456789ABCDEF".indexOf(c); + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java b/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java new file mode 100644 index 0000000..9b4155c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java @@ -0,0 +1,105 @@ +package com.casic.missiles.modular.util; + +import org.springframework.stereotype.Component; + +import javax.websocket.OnClose; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.PathParam; +import javax.websocket.server.ServerEndpoint; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CopyOnWriteArraySet; + +/** + * @Description: 此注解相当于设置访问URL + * @Author: wangpeng + * @Date: 2022/7/17 11:48 + */ +@Component +@ServerEndpoint("/websocket/{userId}") +public class WebSocket { + private Session session; + + private static CopyOnWriteArraySet webSockets = new CopyOnWriteArraySet<>(); + private static Map sessionPool = new HashMap(); + + @OnOpen + public void onOpen(Session session, @PathParam(value = "userId") String userId) { + this.session = session; + webSockets.add(this); + sessionPool.put(userId, session); + System.out.println(userId + "【websocket消息】有新的连接,总数为:" + webSockets.size()); + } + + @OnClose + public void onClose() { + webSockets.remove(this); + System.out.println("【websocket消息】连接断开,总数为:" + webSockets.size()); + } + + @OnMessage + public void onMessage(String message) { + System.out.println("【websocket消息】收到客户端消息:" + message); + } + + // 此为广播消息 + public void sendAllMessage(String message) { + for (WebSocket webSocket : webSockets) { + System.out.println("【websocket消息】广播消息:" + message); + try { + webSocket.session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + // 发送列表消息 + public void sendListMessage(List userIds, String message) { + System.out.println("【websocket消息】列表消息:" + message); + for (String userId : userIds) { + Session session = sessionPool.get(userId); + if (session != null) { + try { + session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + + // 发送列表消息 + +// public void sendListMessage(List userIds, Object data){ +// System.out.println("【websocket消息】列表消息:"+data); +// for (String userId : userIds) { +// Session session = sessionPool.get(userId); +// if (session != null) { +// try { +//// session.getAsyncRemote().sendText(message); +// session.getAsyncRemote().sendObject(data); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// } +// } + + // 此为单点消息 + public void sendOneMessage(String userId, String message) { + System.out.println("【websocket消息】单点消息:" + message); + Session session = sessionPool.get(userId); + if (session != null) { + try { + session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java new file mode 100644 index 0000000..0c1f5f1 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java @@ -0,0 +1,115 @@ +package com.casic.missiles.modular.util; + +import org.springframework.web.multipart.MultipartFile; + +import java.io.*; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipInputStream; + +/** + * @Description: 读取zip文件内容 + * @Author: wangpeng + * @Date: 2022/7/17 11:48 + */ +public class ZipFileUtil { + public static List getFile(String fileName) { + File file = new File(fileName); + ZipFile zipFile = null; + ZipInputStream zin = null; + FileInputStream fis = null; + List selectDTOList = new ArrayList<>(); + try { + Charset gbk = Charset.forName("GBK"); + zipFile = new ZipFile(file, gbk); + fis = new FileInputStream(file); + zin = new ZipInputStream(fis, gbk); + + ZipEntry ze = null; + while ((ze = zin.getNextEntry()) != null) { + String path = ze.getName(); + System.out.println(path); + if (!ze.isDirectory()) { + InputStream inputStream = zipFile.getInputStream(ze); + String base64Photo = Base64Util.getBase64FromInputStream(inputStream); +// List texts = IOUtils.readLines(inputStream); +// for (String text : texts) { +// System.out.println(" " + text); +// } + selectDTOList.add(new SelectDTO(path.substring(path.indexOf("/")+1), "data:image/png;base64,"+base64Photo)); + inputStream.close(); + } + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (zin != null) { + zin.closeEntry(); + zin.close(); + } + if (fis != null) + fis.close(); + if (zipFile != null) + zipFile.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return selectDTOList; + } + + + /** + * MultipartFile 转 File + * + * @param file + * @throws Exception + */ + public static File multipartFileToFile(MultipartFile file) throws Exception { + + File toFile = null; + if (file.equals("") || file.getSize() <= 0) { + file = null; + } else { + InputStream ins = null; + ins = file.getInputStream(); + toFile = new File(file.getOriginalFilename()); + inputStreamToFile(ins, toFile); + ins.close(); + } + return toFile; + } + + //获取流文件 + private static void inputStreamToFile(InputStream ins, File file) { + try { + OutputStream os = new FileOutputStream(file); + int bytesRead = 0; + byte[] buffer = new byte[8192]; + while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) { + os.write(buffer, 0, bytesRead); + } + os.close(); + ins.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 删除本地临时文件 + * + * @param file + */ + public static void delteTempFile(File file) { + if (file != null) { + File del = new File(file.toURI()); + del.delete(); + } + } +} + diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java new file mode 100644 index 0000000..ae93a17 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java @@ -0,0 +1,34 @@ +package com.casic.missiles.modular.util.netty; + +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.EventLoop; +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.TimeUnit; + +/** + * 负责监听启动时连接失败,重新连接功能 + * + */ +@Slf4j +public class ConnectionListener implements ChannelFutureListener { + + private NettyClient client = new NettyClient(); + + @Override + public void operationComplete(ChannelFuture channelFuture) throws Exception { + if (!channelFuture.isSuccess()) { + final EventLoop loop = channelFuture.channel().eventLoop(); + loop.schedule(new Runnable() { + @Override + public void run() { + log.info("服务端连接不上,开始重连操作..."); + client.connect(); + } + }, 5L, TimeUnit.MINUTES); + } else { + log.info("服务端连接成功..."); + } + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java new file mode 100644 index 0000000..ef9ae76 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java @@ -0,0 +1,66 @@ +package com.casic.missiles.modular.util.netty; + +import io.netty.bootstrap.Bootstrap; +import io.netty.channel.*; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioSocketChannel; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public class NettyClient { + + private static Channel channel; + + private String fenceServiceHost = "127.0.0.1"; + private Integer fenceServicePort = 9200; + + public Channel connect() { + doConnect(fenceServiceHost, fenceServicePort); + return channel; + } + + public Channel connect(String host, int port) { + doConnect(host, port); + return channel; + } + + private void doConnect(String host, int port) { + EventLoopGroup workerGroup = new NioEventLoopGroup(); + try { + Bootstrap b = new Bootstrap(); + b.group(workerGroup); + b.channel(NioSocketChannel.class); + b.option(ChannelOption.SO_KEEPALIVE, true); + b.option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(1024 * 1024)); + + b.handler(new ChannelInitializer() { + @Override + public void initChannel(SocketChannel ch) throws Exception { + + ch.pipeline().addLast("decoder", new StringDecoder()); + ch.pipeline().addLast("encoder", new StringEncoder()); + ch.pipeline().addLast(new NettyClientHandler()); + } + }); + + ChannelFuture f = b.connect(host, port); + f.addListener(new ConnectionListener()); + channel = f.channel(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static void writeAndFlush(String message) { + + if (channel != null) { + channel.writeAndFlush(message); + System.out.println("电子围栏客户端发送消息:" + message); + } + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClientHandler.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClientHandler.java new file mode 100644 index 0000000..28093f0 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClientHandler.java @@ -0,0 +1,62 @@ +package com.casic.missiles.modular.util.netty; + +import com.casic.missiles.modular.util.HttpUtil; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import io.netty.channel.EventLoop; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; + +import java.util.concurrent.TimeUnit; + +/** + * 客户端处理器 + **/ +@Slf4j +@Component +public class NettyClientHandler extends ChannelInboundHandlerAdapter { + static boolean handle = true; + + private NettyClient client = new NettyClient(); + + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + log.info("连接成功....."); + } + + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + log.info("断开连接....."); + + //使用过程中断线重连 + final EventLoop eventLoop = ctx.channel().eventLoop(); + eventLoop.schedule(new Runnable() { + @Override + public void run() { + client.connect(); + } + }, 5L, TimeUnit.SECONDS); + super.channelInactive(ctx); + } + + + @Override + public void channelRead(ChannelHandlerContext ctx, Object message) throws Exception { + + if (handle) { + MultiValueMap map = new LinkedMultiValueMap<>(); + map.add("message", message.toString()); + HttpUtil.post("http://127.0.0.1:20311/data/addPerimeterAlarm", map); + } + handle = !handle; + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + cause.printStackTrace(); + ctx.close(); + } +} + diff --git a/casic-web/pom.xml b/casic-web/pom.xml new file mode 100644 index 0000000..8fb0b2c --- /dev/null +++ b/casic-web/pom.xml @@ -0,0 +1,171 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + ../pom.xml + 2.0.0 + + casic-web + 2.0.0 + jar + casic-web + casic web启动入口 + + + + dev + + true + + + dev + + + + test + + test + + + + prod + + prod + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + io.micrometer + micrometer-core + + + + + org.springframework.boot + spring-boot-starter-jdbc + + + + com.casic + casic-core + ${core.version} + + + com.casic + casic-admin-core + ${admin.version} + + + io.springfox + springfox-swagger-ui + + + + + com.casic + casic-admin-support + ${admin.version} + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.dameng + DmJdbcDriver18 + 1.8 + + + com.casic + casic-area-starter + ${admin.version} + + + + com.casic + casic-server + ${pro.version} + + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + + + org.apache.maven.plugins + maven-jar-plugin + ${maven.jar.plugin.version} + + + + /config/*-*.yml + **/MockController.class + + + + com.casic.missiles.CasicApplication + true + ./ + + + + + + org.apache.maven.plugins + maven-assembly-plugin + ${maven.assembly.plugin.version} + + + make-assembly + package + + single + + + + + + org.apache.maven.plugins + maven-war-plugin + ${maven.war.plugin.version} + + + + + src/main/resources + + + /config/*/* + /config/*-*.yml + + true + + + src/main/java + + **/*.xml + + true + + + + \ No newline at end of file diff --git a/casic-web/src/main/build/bin/start.bat b/casic-web/src/main/build/bin/start.bat new file mode 100644 index 0000000..1db4e88 --- /dev/null +++ b/casic-web/src/main/build/bin/start.bat @@ -0,0 +1,4 @@ +@echo off +title ${project.build.finalName} +java -jar ./lib/${project.build.finalName}.jar +@pause diff --git a/casic-web/src/main/build/bin/start.sh b/casic-web/src/main/build/bin/start.sh new file mode 100644 index 0000000..c00b1ef --- /dev/null +++ b/casic-web/src/main/build/bin/start.sh @@ -0,0 +1,2 @@ +java -jar ./lib/${project.build.finalName}.jar + diff --git a/casic-web/src/main/build/package.xml b/casic-web/src/main/build/package.xml new file mode 100644 index 0000000..c9259ad --- /dev/null +++ b/casic-web/src/main/build/package.xml @@ -0,0 +1,43 @@ + + + package + + zip + tar.gz + + true + + + + true + true + lib + runtime + + + + + src/main/build/bin + + start.bat + start.sh + + true + 0744 + / + + + src/main/resources/config + true + + *.yml + /*/* + + /config + + + src/main/resources/i18n + / + + + \ No newline at end of file diff --git a/casic-web/src/main/java/com/casic/missiles/CasicApplication.java b/casic-web/src/main/java/com/casic/missiles/CasicApplication.java new file mode 100644 index 0000000..308dcad --- /dev/null +++ b/casic-web/src/main/java/com/casic/missiles/CasicApplication.java @@ -0,0 +1,29 @@ +package com.casic.missiles; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.ServletComponentScan; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +/** + * SpringBoot方式启动类 + * + * @author lwh + * @Date 2021/06/06 12:06 + */ +@SpringBootApplication +@EnableCaching +@EnableTransactionManagement(proxyTargetClass = true) +@EnableAsync +@Slf4j +public class CasicApplication { + public static void main(String[] args) { + SpringApplication.run(CasicApplication.class, args); + + log.info("CasicApplication is success!"); + } + +} diff --git a/casic-web/src/main/java/com/casic/missiles/CasicServletInitializer.java b/casic-web/src/main/java/com/casic/missiles/CasicServletInitializer.java new file mode 100644 index 0000000..e30585b --- /dev/null +++ b/casic-web/src/main/java/com/casic/missiles/CasicServletInitializer.java @@ -0,0 +1,18 @@ +package com.casic.missiles; + +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; + +/** + * Guns Web程序启动类 + * + * @author fengshuonan + * @date 2017-05-21 9:43 + */ +public class CasicServletInitializer extends SpringBootServletInitializer { + + @Override + protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { + return application.sources(CasicApplication.class); + } +} diff --git a/casic-web/src/main/java/com/casic/missiles/controller/MockController.java b/casic-web/src/main/java/com/casic/missiles/controller/MockController.java new file mode 100644 index 0000000..eae6c54 --- /dev/null +++ b/casic-web/src/main/java/com/casic/missiles/controller/MockController.java @@ -0,0 +1,82 @@ +package com.casic.missiles.controller; + +import cn.hutool.core.util.StrUtil; +import com.casic.missiles.core.application.enums.LoginType; +import com.casic.missiles.core.base.controller.BaseController; +import com.casic.missiles.core.model.auth.AuthUser; +import com.casic.missiles.core.model.auth.CasicCustomToken; +import com.casic.missiles.core.shiro.ShiroKit; +import com.casic.missiles.core.util.RSAUtils; +import com.casic.missiles.model.response.SuccessResponseData; +import com.casic.missiles.modular.domain.constants.PermissionConstants; +import com.casic.missiles.modular.interfaces.log.LogManager; +import com.casic.missiles.modular.interfaces.log.factory.LogTaskFactory; +import com.casic.missiles.modular.system.dto.LoginSuccessDTO; +import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.subject.Subject; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import java.security.NoSuchAlgorithmException; +import java.util.Map; + +import static com.casic.missiles.core.util.HttpContext.getIp; + + +/** + * 仅为mock登录使用 + * + * @author lenovo + */ +@Controller +@RequestMapping("/route") +@Slf4j +public class MockController extends BaseController { + + /** + * 获取mockToken + */ + @GetMapping("/mockToken") + @ResponseBody + public Object mockToken(String username, String password) { + super.getSession().setAttribute(PermissionConstants.IS_APP, false); + SuccessResponseData resultData = new SuccessResponseData(); + if (StrUtil.hasEmpty(username, password)) { + username = "admin"; + password = "111111"; + } + Subject currentUser = ShiroKit.getSubject(); + + try { + Map key = RSAUtils.genKeyPair(); + ShiroKit.getSession().setAttribute(PermissionConstants.PRIVATE_KEY, key.get(RSAUtils.RSAPrivateKey)); + + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + + //token自定义 + CasicCustomToken token = new CasicCustomToken(username, password); + token.setType(LoginType.PASSWORD); + token.setRememberMe(false); + + try { + currentUser.login(token); + } catch (Exception e) { + e.printStackTrace(); + } + AuthUser shiroUser = ShiroKit.getUser(); + super.getSession().setAttribute("shiroUser", shiroUser); + super.getSession().setAttribute("username", shiroUser.getAccount()); + super.getSession().setAttribute(PermissionConstants.SESSION_KEY, shiroUser.getId()); + + LogManager.me().executeLog(LogTaskFactory.loginLog(shiroUser.getId(), getIp())); + + ShiroKit.getSession().setAttribute("sessionFlag", true); + resultData.setData(new LoginSuccessDTO(ShiroKit.getSession().getId().toString(), null)); + resultData.setMessage("登录成功"); + return resultData; + } +} diff --git a/casic-web/src/main/resources/META-INF/spring-devtools.properties b/casic-web/src/main/resources/META-INF/spring-devtools.properties new file mode 100644 index 0000000..e3b0a7f --- /dev/null +++ b/casic-web/src/main/resources/META-INF/spring-devtools.properties @@ -0,0 +1 @@ +restart.include.beetl=/beetl-2.7.15.jar \ No newline at end of file diff --git a/casic-web/src/main/resources/config/application-dev.yml b/casic-web/src/main/resources/config/application-dev.yml new file mode 100644 index 0000000..8c18554 --- /dev/null +++ b/casic-web/src/main/resources/config/application-dev.yml @@ -0,0 +1,30 @@ +server: + port: 8083 +################### spring配置 ################### +spring: + datasource: + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://111.198.10.15:11336/casic_template2.0?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&serverTimezone=UTC&&allowMultiQueries=true + username: root + password: Casic203 +jms: + pub-sub-domain: true +# session: +# store-type: redis +# redis: +# host: 111.198.10.15 +# port: 11412 +# password: ew5T4K3#203lwh +# serializer: org.springframework.data.redis.serializer.StringRedisSerializer +# redisValueSerializer: org.springframework.data.redis.serializer.JdkSerializationRedisSerializer +casic: + #kaptcha-open: false #是否开启登录时验证码 (true/false) + no-login-urls: ${casic.sysUrl}/user/login,${casic.sysUrl}/user/appLogin,${casic.sysUrl}/kaptcha/base64,${casic.sysUrl}/config/baseConfig,/route/mockToken + #flowable数据源和多数据源配置 + db: + init: + enable: false +logging: + level.root: info + level.com.casic: debug + level.org.springframework.web: info \ No newline at end of file diff --git a/casic-web/src/main/resources/config/application-prod.yml b/casic-web/src/main/resources/config/application-prod.yml new file mode 100644 index 0000000..6553b10 --- /dev/null +++ b/casic-web/src/main/resources/config/application-prod.yml @@ -0,0 +1,34 @@ +server: + port: 8085 +# context-path: /callcenter/api +################### spring配置 ################### +spring: + datasource: + url: jdbc:mysql://10.18.0.20:3306/casic_smartcity_callcenter?autoReconnect=true&useUnicode=true&characterEncoding=utf8&useSSL=false&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull + username: root + password: Casic203 + initial-size: 2 + min-idle: 1 + jms: + pub-sub-domain: true + # session: + # store-type: redis + redis: + host: 127.0.0.1 + port: 6379 + password: + +#flowable数据源和多数据源配置 +casic: + kaptcha-open: false #是否开启登录时验证码 (true/false) + nologin-urls: /user/login,/user/appLogin,/kaptcha,/config/baseConfig,/route/mockToken + flowable: + datasource: + url: jdbc:mysql://10.18.0.20:3306/callcenter_flowable?autoReconnect=true&useUnicode=true&characterEncoding=utf8&useSSL=false&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull + username: root + password: Casic203 +logging: + level.root: info + level.com.casic: debug + path: logs/ + file: missiles.log \ No newline at end of file diff --git a/casic-web/src/main/resources/config/application-test.yml b/casic-web/src/main/resources/config/application-test.yml new file mode 100644 index 0000000..54d7252 --- /dev/null +++ b/casic-web/src/main/resources/config/application-test.yml @@ -0,0 +1,30 @@ +server: + port: 11307 +################### spring配置 ################### +spring: + datasource: + url: jdbc:mysql://localhost:3306/casic_template?autoReconnect=true&useUnicode=true&characterEncoding=utf8&useSSL=false&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull + username: root + password: Casic203! + initial-size: 2 + min-idle: 1 + jms: + pub-sub-domain: true +# session: +# store-type: redis +casic: + # kaptcha-open: false #是否开启登录时验证码 (true/false) + nologin-urls: /user/login,/user/appLogin,/kaptcha/base64,/config/baseConfig,/route/mockToken,/workflow/** + #flowable数据源和多数据源配置 + flowable: + datasource: + url: jdbc:mysql://localhost:3306/template_flowable?autoReconnect=true&useUnicode=true&characterEncoding=utf8&useSSL=false&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull + username: root + password: Casic203! +flowable: + checkProcessDefinitions: false #不校验process文件 +logging: + level.root: info + level.com.casic: debug + path: logs/ + file: missiles.log \ No newline at end of file diff --git a/casic-web/src/main/resources/config/application.yml b/casic-web/src/main/resources/config/application.yml new file mode 100644 index 0000000..33cce3f --- /dev/null +++ b/casic-web/src/main/resources/config/application.yml @@ -0,0 +1,26 @@ +########################################################## +################## 所有profile共有的配置 ################# +########################################################## +spring: + profiles: + active: dev + servlet: + multipart: + max-file-size: 50MB + max-request-size: 80MB +#mybatis-plus: +# sql-injector: com.baomidou.mybatisplus.mapper.LogicSqlInjector +################### mybatis-plus配置 ################### +################### guns配置 ################### +casic: + swagger-open: false #是否开启swagger (true/false) + kaptcha-open: false #是否开启登录时验证码 (true/false) + muti-datasource-open: false #是否开启多数据源(true/false) + spring-session-open: false #是否开启spring session,如果是多机环境需要开启(true/false) + session-invalidate-time: 86400 #session失效时间(只在单机环境下生效,,多机环境在SpringSessionConfig类中配置) 单位:秒 + session-validation-interval: 900 #多久检测一次失效的session(只在单机环境下生效) 单位:秒 + no-login-urls: /user/login,/kaptcha,/config/baseConfig + + config: + export-path: D:\java\boot\guns-web-1.0.0-SNAPSHOT\export\ + config-path: E:\Develop\IdeaProject\smartcity\casic-smartcity-dcms\casic-web\src\main\resources\config\ \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9e20bc1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea/ +**/target/** +logs/ +*.iml diff --git a/README.md b/README.md new file mode 100644 index 0000000..2fdcd74 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# casic项目 V2.0.0 + +[^_^]: # (Talk is cheap,Show me the code!) + +## 介绍 +基于SpringBoot,致力于做更简洁的后台管理系统,完美整合springboot2.4 + shiro + mybatis-plus ! +基于casic项目代码简洁,注释丰富,上手容易,同时包含许多基础模块(用户管理,角色管理,部门管理,字典管理等10个模块) +可以直接作为一个后台管理系统的脚手架! 2022目标 `更简洁`,`更规范`! + + +#### 其他 +>* [git地址](http://192.168.0.203:8080/gitbucket) +>* [本地免登地址](http://localhost:8083/route/mockToken) diff --git a/casic-server/pom.xml b/casic-server/pom.xml new file mode 100644 index 0000000..c150a12 --- /dev/null +++ b/casic-server/pom.xml @@ -0,0 +1,70 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + 2.0.0 + ../pom.xml + + + casic-server + 2.0.0 + jar + casic-server + casic 的spring boot版本 + + + + + com.casic + casic-core + ${core.version} + provided + + + com.casic + casic-admin-support + ${admin.version} + provided + + + org.springframework.boot + spring-boot-starter-web + ${boot.version} + provided + + + + + com.hikvision.ga + artemis-http-client + 1.1.3 + + + commons-io + commons-io + + + org.springframework.boot + spring-boot-starter-websocket + 2.4.5 + + + io.netty + netty-all + 4.1.42.Final + + + + + + src/main/java + + **/*.xml + + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java new file mode 100644 index 0000000..3a60b9e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java @@ -0,0 +1,36 @@ +package com.casic.missiles.modular.async; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.TaskExecutor; +import org.springframework.scheduling.annotation.AsyncConfigurer; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadPoolExecutor; + +@Configuration +@EnableAsync +public class AsyncConfig implements AsyncConfigurer { + @Override + public Executor getAsyncExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + //核心线程数 + executor.setCorePoolSize(5); + //最大线程数 + executor.setMaxPoolSize(10); + //队列容量 + executor.setQueueCapacity(20); + //设置线程活跃时间(秒) + executor.setKeepAliveSeconds(60); + //默认线程名称 + executor.setThreadNamePrefix("user-rpt-"); + //拒绝策略 + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + //等待所有任务结束后再关闭线程池 + executor.setWaitForTasksToCompleteOnShutdown(true); + return executor; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java new file mode 100644 index 0000000..8ca554c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java @@ -0,0 +1,18 @@ +package com.casic.missiles.modular.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +// tomcat启动无需配置 +@Configuration +public class WebSocketConfig { + /** + * 注入ServerEndpointExporter, + * 这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint + */ + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java new file mode 100644 index 0000000..34fe2cd --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java @@ -0,0 +1,39 @@ +package com.casic.missiles.modular.controller; + + +import com.casic.missiles.model.application.event.core.EventPublisher; +import com.casic.missiles.model.application.event.enums.ModelEventTypeEnum; +import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.modular.event.UserEvent; +import com.casic.missiles.modular.system.model.User; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +/** + * @Description: DemoController + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@RestController +@RequestMapping("/demo") +public class DemoController { + @Autowired + private EventPublisher publisher; + + /** + * 获取mockToken + */ + @PostMapping("/list") + @ResponseBody + public Object list() { + User user = new User(); + user.setAccount("张三"); + publisher.publishEvent(new UserEvent(ModelEventTypeEnum.ADD, user)); + return ResponseData.success(); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java new file mode 100644 index 0000000..aff2889 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java @@ -0,0 +1,23 @@ +package com.casic.missiles.modular.event; + +import com.casic.missiles.model.application.event.core.ModelEvent; +import com.casic.missiles.model.application.event.type.AbstractEventTypeEnum; +import com.casic.missiles.modular.system.model.User; + +/** + * @Description: 用户事件 + * @Author: wangpeng + * @Date: 2022/7/17 11:23 + */ +public class UserEvent extends ModelEvent { + /** + * Create a new {@code ApplicationEvent}. + * + * @param type 事件类型 + * @param source the object on which the event initially occurred or with + * which the event is associated (never {@code null}) + */ + public UserEvent(AbstractEventTypeEnum type, User source) { + super(type, source); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java new file mode 100644 index 0000000..8f9603e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.core.application.event.UserLoginEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserOneListener { + @EventListener + public void onApplicationEvent(UserLoginEvent event) { + log.debug("用户1订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java new file mode 100644 index 0000000..0bd52a3 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.model.application.event.core.EventSubscriber; +import com.casic.missiles.modular.event.UserEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserTwoListener extends EventSubscriber { + @Override + public void onApplicationEvent(UserEvent event) { + log.debug("用户2订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java new file mode 100644 index 0000000..4012170 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java @@ -0,0 +1,88 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang3.StringUtils; +import sun.misc.BASE64Decoder; + +import java.io.*; + +public class Base64Util { + /** + * base64字符串转换成图片 + * + * @param imgStr base64字符串 + * @param imgFilePath 图片存放路径 + * @return + * @author ZHANGJL + * @dateTime 2018-02-23 14:42:17 + */ + public static boolean Base64ToImage(String imgStr, String imgFilePath, String fileDir) { // 对字节数组字符串进行Base64解码并生成图片 + + if (StringUtils.isEmpty(imgStr)) // 图像数据为空 + return false; + + imgStr = imgStr.substring(imgStr.indexOf(",") + 1); + + BASE64Decoder decoder = new BASE64Decoder(); + try { + // Base64解码 + byte[] b = decoder.decodeBuffer(imgStr); + + for (int i = 0; i < b.length; ++i) { + if (b[i] < 0) {// 调整异常数据 + b[i] += 256; + } + } + //如果已存在图像,先删除 + File file = new File(fileDir+File.separator + imgFilePath); + if (file.exists() && file.isFile()) { + file.delete(); + } + File dir = new File(fileDir); + if (!dir.exists()) { + dir.mkdirs(); + } + file = new File(fileDir+File.separator+imgFilePath); + file.createNewFile(); +// ImageIO.write(bImage, "bmp", name); + OutputStream out = new FileOutputStream(fileDir+File.separator+imgFilePath); + out.write(b); + out.flush(); + out.close(); + + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + + } + + public static String getBase64FromInputStream(InputStream in) { + // 将图片文件转化为字节数组字符串,并对其进行Base64编码处理 + byte[] data = null; + // 读取图片字节数组 + try { + ByteArrayOutputStream swapStream = new ByteArrayOutputStream(); + byte[] buff = new byte[100]; + int rc = 0; + while ((rc = in.read(buff, 0, 100)) > 0) { + swapStream.write(buff, 0, rc); + } + data = swapStream.toByteArray(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return new String(Base64.encodeBase64(data)); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java new file mode 100644 index 0000000..9c93895 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java @@ -0,0 +1,75 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.lang3.StringUtils; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class CommonUtil { + + public static String CutId(String id) { + return id.substring(6, 10) + "-" + id.substring(10, 12) + "-" + id.substring(12, 14); + } + + public static boolean isIDNumber(String IDNumber) { + if (IDNumber == null || "".equals(IDNumber)) { + return false; + } + // 定义判别用户身份证号的正则表达式(15位或者18位,最后一位可以为字母) + String regularExpression = + "(^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|" + + "(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}$)"; + boolean matches = IDNumber.matches(regularExpression); + // 判断第18位校验值 + if (matches) { + if (IDNumber.length() == 18) { + try { + char[] charArray = IDNumber.toCharArray(); + // 前十七位加权因子 + int[] idCardWi = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; + // 这是除以11后,可能产生的11位余数对应的验证码 + String[] idCardY = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"}; + int sum = 0; + for (int i = 0; i < idCardWi.length; i++) { + int current = Integer.parseInt(String.valueOf(charArray[i])); + int count = current * idCardWi[i]; + sum += count; + } + char idCardLast = charArray[17]; + int idCardMod = sum % 11; + if (idCardY[idCardMod].toUpperCase() + .equals(String.valueOf(idCardLast).toUpperCase())) { + return true; + } else { + System.out.println("身份证最后一位:" + String.valueOf(idCardLast).toUpperCase() + + "错误,正确的应该是:" + idCardY[idCardMod].toUpperCase()); + return false; + } + + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } else { + return false; + } + } + return matches; + } + + + public static boolean CheckMobilePhoneNum(String phoneNum) { + if (StringUtils.isEmpty(phoneNum)) + return true; + String regex = "^(1[3-9]\\d{9}$)"; + if (phoneNum.length() == 11) { + Pattern p = Pattern.compile(regex); + Matcher m = p.matcher(phoneNum); + if (m.matches()) { + return true; + } + } + return false; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java new file mode 100644 index 0000000..191ef79 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java @@ -0,0 +1,116 @@ +package com.casic.missiles.modular.util; + + +import javafx.util.Pair; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +/** + * Created by Administrator on 2015/2/25. + */ +public class DateUtils { + public static SimpleDateFormat sdf_day = new SimpleDateFormat("yyyy-MM-dd"); + public static SimpleDateFormat sdf_day_time = new SimpleDateFormat("yyyyMMddhhmmss"); + public static final SimpleDateFormat sdf4 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + public static final SimpleDateFormat sdf5 = new SimpleDateFormat("HH:mm:ss"); + + + /** + * 获取当年的第一天 + * + * @return + */ + public static Date getCurrYearFirst() { + Calendar currCal = Calendar.getInstance(); + int currentYear = currCal.get(Calendar.YEAR); + return getYearFirst(currentYear); + } + + + /** + * 获取某年第一天日期 + * + * @param year 年份 + * @return Date + */ + public static Date getYearFirst(int year) { + Calendar calendar = Calendar.getInstance(); + calendar.clear(); + calendar.set(Calendar.YEAR, year); + Date currYearFirst = calendar.getTime(); + return currYearFirst; + } + + /** + * 最近7日(不包括今日) + */ + public static Pair getLastSevenDays() { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, -7); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 最近n日(不包括今日) + */ + public static Pair getLastNDays(int n) { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, n * -1); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 日期时间加n天 + */ + public static String addDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf4.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf4.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 日期加n天 + */ + public static String addNDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf_day.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf_day.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 昨日 + */ + public static String getYesterday() { + + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.DATE, -2); + return sdf_day.format(calendar.getTime()); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java new file mode 100644 index 0000000..da0f8ee --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java @@ -0,0 +1,49 @@ +package com.casic.missiles.modular.util; + +import com.hikvision.artemis.sdk.ArtemisHttpUtil; +import com.hikvision.artemis.sdk.config.ArtemisConfig; + +import java.util.HashMap; +import java.util.Map; + +public class HikUtil { + + public static String hikApi(String uri, String body) { + + /** + * STEP1:设置平台参数,根据实际情况,设置host appkey appsecret 三个参数. + */ + ArtemisConfig.host = "192.168.1.22:443"; // artemis网关服务器ip端口 + ArtemisConfig.appKey = "25766251"; // 秘钥appkey + ArtemisConfig.appSecret = "h2o6zXtzCmt8eaOaMkXb";// 秘钥appSecret + + /** + * STEP2:设置OpenAPI接口的上下文 + */ + final String ARTEMIS_PATH = "/artemis"; + + /** + * STEP3:设置接口的URI地址 + */ + final String previewURLsApi = ARTEMIS_PATH + uri; + Map path = new HashMap(2) { + { + put("https://", previewURLsApi);//根据现场环境部署确认是http还是https + } + }; + + /** + * STEP4:设置参数提交方式 + */ + String contentType = "application/json"; + + /** + * STEP5:组装请求参数 + */ + /** + * STEP6:调用接口 + */ + String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, contentType, null);// post请求application/json类型参数 + return result; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java new file mode 100644 index 0000000..4867144 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java @@ -0,0 +1,149 @@ +package com.casic.missiles.modular.util; + +import org.springframework.http.*; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; + +/** + * @Description: http请求工具类 + * @Author: wangpeng + * @Date: 2022/7/17 11:49 + */ +public class HttpUtil { + /** + * get请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String get(String url, MultiValueMap params) { + return get(url, params, null); + } + + /** + * get请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String get(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.GET); + } + + /** + * post请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String post(String url, MultiValueMap params) { + return post(url, params, null); + } + + /** + * post请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String post(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.POST); + } + + /** + * put请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String put(String url, MultiValueMap params) { + return put(url, params, null); + } + + /** + * put请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String put(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.PUT); + } + + /** + * delete请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String delete(String url, MultiValueMap params) { + return delete(url, params, null); + } + + /** + * delete请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String delete(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.DELETE); + } + + /** + * 表单请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @param method 请求方式 + * @return + */ + public static String request(String url, MultiValueMap params, MultiValueMap headers, HttpMethod method) { + if (params == null) { + params = new LinkedMultiValueMap<>(); + } + return request(url, params, headers, method, MediaType.APPLICATION_FORM_URLENCODED); + } + + /** + * http请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @param method 请求方式 + * @param mediaType 参数类型 + * @return + */ + public static String request(String url, Object params, MultiValueMap headers, HttpMethod method, MediaType mediaType) { + if (url == null || url.trim().isEmpty()) { + return null; + } + RestTemplate client = new RestTemplate(); + // header + HttpHeaders httpHeaders = new HttpHeaders(); + if (headers != null) { +// httpHeaders.addAll(headers); + httpHeaders.putAll(headers); + } + // 提交方式:表单、json + httpHeaders.setContentType(mediaType); + HttpEntity httpEntity = new HttpEntity(params, httpHeaders); + ResponseEntity response = client.exchange(url, method, httpEntity, String.class); + return response.getBody(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java new file mode 100644 index 0000000..19d8d67 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java @@ -0,0 +1,30 @@ +package com.casic.missiles.modular.util; + +public class SelectDTO { + private String name; + private String value; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public SelectDTO() { + } + + public SelectDTO(String name, String value) { + this.name = name; + this.value = value; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java new file mode 100644 index 0000000..0bd484c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java @@ -0,0 +1,28 @@ +package com.casic.missiles.modular.util; + +public class SocketConst { + + /** + * 新增授权socket前缀 + */ + public static final String SOCKET_PREFIX_ADD_PERMISSION = "addPermission:"; + + /** + * 取消授权socket前缀 + */ + public static final String SOCKET_PREFIX_DELETE_PERMISSION = "deletePermission:"; + + /** + * 人员数据下发socket前缀 + */ + public static final String SOCKET_PREFIX_ADD_PERSON = "addPerson:"; + + /** + * socket返回成功信息 + */ + public static final String SOCKET_SUCCESS_MSG = "ok"; + /** + * 人员数据下发socket前缀 + */ + public static final String SOCKET_PREFIX_DELETE_PERSON = "deletePerson:"; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java new file mode 100644 index 0000000..0452bca --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java @@ -0,0 +1,90 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.io.IOUtils; +import org.springframework.stereotype.Component; + +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.text.SimpleDateFormat; +import java.util.Date; + +@Component +public class SocketUtil { + + public static byte[] sendMessage(String ip, int port, String msg) { + byte[] data = new byte[20]; + + System.out.println("往 " + ip + ":" + port + " 发送数据:" + msg); + InputStream in = null; + OutputStream out = null; + Socket socket = null; + try { + socket = new Socket(); + socket.connect(new InetSocketAddress(ip, port), 1000); + socket.setSoTimeout(2000); + // 向服务端发送数据 + out = socket.getOutputStream(); + out.write(hexString2Bytes(msg)); + out.flush(); + //socket.shutdownOutput(); + // 读取服务端返回数据 + in = socket.getInputStream(); + in.read(data); + } catch (Exception e) { + e.printStackTrace(); + } finally { + IOUtils.closeQuietly(in); + IOUtils.closeQuietly(out); + IOUtils.closeQuietly(socket); + } + return data; + } + + private static int code = 0; + + public static void main(String[] args) { +// byte[] dd = sendMessage("192.168.5.211",6001,"090300000002C543"); + + String dateStr = new SimpleDateFormat("yyMMddHHmmssSSS").format(new Date()); + //String dd = dateStr + String.format("%04d",++code); + + System.out.println(dateStr); + } + + /** + * 返回由字节数组转换来的 16 位有符号整数 + * + * @param bytes 字节数组 + * @return 由两个字节构成的 16 位有符号整数 + */ + public static short toShort(byte[] bytes) { + return (short) ((0xff & bytes[0]) | (0xff00 & (bytes[1] << 8))); + + } + + + public static byte[] hexString2Bytes(String hex) { + if ((hex == null) || (hex.equals(""))) { + return null; + } else if (hex.length() % 2 != 0) { + return null; + } else { + hex = hex.toUpperCase(); + int len = hex.length() / 2; + byte[] b = new byte[len]; + char[] hc = hex.toCharArray(); + for (int i = 0; i < len; i++) { + int p = 2 * i; + b[i] = (byte) (charToByte(hc[p]) << 4 | charToByte(hc[p + 1])); + } + return b; + } + } + + private static byte charToByte(char c) { + return (byte) "0123456789ABCDEF".indexOf(c); + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java b/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java new file mode 100644 index 0000000..9b4155c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java @@ -0,0 +1,105 @@ +package com.casic.missiles.modular.util; + +import org.springframework.stereotype.Component; + +import javax.websocket.OnClose; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.PathParam; +import javax.websocket.server.ServerEndpoint; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CopyOnWriteArraySet; + +/** + * @Description: 此注解相当于设置访问URL + * @Author: wangpeng + * @Date: 2022/7/17 11:48 + */ +@Component +@ServerEndpoint("/websocket/{userId}") +public class WebSocket { + private Session session; + + private static CopyOnWriteArraySet webSockets = new CopyOnWriteArraySet<>(); + private static Map sessionPool = new HashMap(); + + @OnOpen + public void onOpen(Session session, @PathParam(value = "userId") String userId) { + this.session = session; + webSockets.add(this); + sessionPool.put(userId, session); + System.out.println(userId + "【websocket消息】有新的连接,总数为:" + webSockets.size()); + } + + @OnClose + public void onClose() { + webSockets.remove(this); + System.out.println("【websocket消息】连接断开,总数为:" + webSockets.size()); + } + + @OnMessage + public void onMessage(String message) { + System.out.println("【websocket消息】收到客户端消息:" + message); + } + + // 此为广播消息 + public void sendAllMessage(String message) { + for (WebSocket webSocket : webSockets) { + System.out.println("【websocket消息】广播消息:" + message); + try { + webSocket.session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + // 发送列表消息 + public void sendListMessage(List userIds, String message) { + System.out.println("【websocket消息】列表消息:" + message); + for (String userId : userIds) { + Session session = sessionPool.get(userId); + if (session != null) { + try { + session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + + // 发送列表消息 + +// public void sendListMessage(List userIds, Object data){ +// System.out.println("【websocket消息】列表消息:"+data); +// for (String userId : userIds) { +// Session session = sessionPool.get(userId); +// if (session != null) { +// try { +//// session.getAsyncRemote().sendText(message); +// session.getAsyncRemote().sendObject(data); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// } +// } + + // 此为单点消息 + public void sendOneMessage(String userId, String message) { + System.out.println("【websocket消息】单点消息:" + message); + Session session = sessionPool.get(userId); + if (session != null) { + try { + session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java new file mode 100644 index 0000000..0c1f5f1 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java @@ -0,0 +1,115 @@ +package com.casic.missiles.modular.util; + +import org.springframework.web.multipart.MultipartFile; + +import java.io.*; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipInputStream; + +/** + * @Description: 读取zip文件内容 + * @Author: wangpeng + * @Date: 2022/7/17 11:48 + */ +public class ZipFileUtil { + public static List getFile(String fileName) { + File file = new File(fileName); + ZipFile zipFile = null; + ZipInputStream zin = null; + FileInputStream fis = null; + List selectDTOList = new ArrayList<>(); + try { + Charset gbk = Charset.forName("GBK"); + zipFile = new ZipFile(file, gbk); + fis = new FileInputStream(file); + zin = new ZipInputStream(fis, gbk); + + ZipEntry ze = null; + while ((ze = zin.getNextEntry()) != null) { + String path = ze.getName(); + System.out.println(path); + if (!ze.isDirectory()) { + InputStream inputStream = zipFile.getInputStream(ze); + String base64Photo = Base64Util.getBase64FromInputStream(inputStream); +// List texts = IOUtils.readLines(inputStream); +// for (String text : texts) { +// System.out.println(" " + text); +// } + selectDTOList.add(new SelectDTO(path.substring(path.indexOf("/")+1), "data:image/png;base64,"+base64Photo)); + inputStream.close(); + } + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (zin != null) { + zin.closeEntry(); + zin.close(); + } + if (fis != null) + fis.close(); + if (zipFile != null) + zipFile.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return selectDTOList; + } + + + /** + * MultipartFile 转 File + * + * @param file + * @throws Exception + */ + public static File multipartFileToFile(MultipartFile file) throws Exception { + + File toFile = null; + if (file.equals("") || file.getSize() <= 0) { + file = null; + } else { + InputStream ins = null; + ins = file.getInputStream(); + toFile = new File(file.getOriginalFilename()); + inputStreamToFile(ins, toFile); + ins.close(); + } + return toFile; + } + + //获取流文件 + private static void inputStreamToFile(InputStream ins, File file) { + try { + OutputStream os = new FileOutputStream(file); + int bytesRead = 0; + byte[] buffer = new byte[8192]; + while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) { + os.write(buffer, 0, bytesRead); + } + os.close(); + ins.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 删除本地临时文件 + * + * @param file + */ + public static void delteTempFile(File file) { + if (file != null) { + File del = new File(file.toURI()); + del.delete(); + } + } +} + diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java new file mode 100644 index 0000000..ae93a17 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java @@ -0,0 +1,34 @@ +package com.casic.missiles.modular.util.netty; + +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.EventLoop; +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.TimeUnit; + +/** + * 负责监听启动时连接失败,重新连接功能 + * + */ +@Slf4j +public class ConnectionListener implements ChannelFutureListener { + + private NettyClient client = new NettyClient(); + + @Override + public void operationComplete(ChannelFuture channelFuture) throws Exception { + if (!channelFuture.isSuccess()) { + final EventLoop loop = channelFuture.channel().eventLoop(); + loop.schedule(new Runnable() { + @Override + public void run() { + log.info("服务端连接不上,开始重连操作..."); + client.connect(); + } + }, 5L, TimeUnit.MINUTES); + } else { + log.info("服务端连接成功..."); + } + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java new file mode 100644 index 0000000..ef9ae76 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java @@ -0,0 +1,66 @@ +package com.casic.missiles.modular.util.netty; + +import io.netty.bootstrap.Bootstrap; +import io.netty.channel.*; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioSocketChannel; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public class NettyClient { + + private static Channel channel; + + private String fenceServiceHost = "127.0.0.1"; + private Integer fenceServicePort = 9200; + + public Channel connect() { + doConnect(fenceServiceHost, fenceServicePort); + return channel; + } + + public Channel connect(String host, int port) { + doConnect(host, port); + return channel; + } + + private void doConnect(String host, int port) { + EventLoopGroup workerGroup = new NioEventLoopGroup(); + try { + Bootstrap b = new Bootstrap(); + b.group(workerGroup); + b.channel(NioSocketChannel.class); + b.option(ChannelOption.SO_KEEPALIVE, true); + b.option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(1024 * 1024)); + + b.handler(new ChannelInitializer() { + @Override + public void initChannel(SocketChannel ch) throws Exception { + + ch.pipeline().addLast("decoder", new StringDecoder()); + ch.pipeline().addLast("encoder", new StringEncoder()); + ch.pipeline().addLast(new NettyClientHandler()); + } + }); + + ChannelFuture f = b.connect(host, port); + f.addListener(new ConnectionListener()); + channel = f.channel(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static void writeAndFlush(String message) { + + if (channel != null) { + channel.writeAndFlush(message); + System.out.println("电子围栏客户端发送消息:" + message); + } + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClientHandler.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClientHandler.java new file mode 100644 index 0000000..28093f0 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClientHandler.java @@ -0,0 +1,62 @@ +package com.casic.missiles.modular.util.netty; + +import com.casic.missiles.modular.util.HttpUtil; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import io.netty.channel.EventLoop; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; + +import java.util.concurrent.TimeUnit; + +/** + * 客户端处理器 + **/ +@Slf4j +@Component +public class NettyClientHandler extends ChannelInboundHandlerAdapter { + static boolean handle = true; + + private NettyClient client = new NettyClient(); + + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + log.info("连接成功....."); + } + + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + log.info("断开连接....."); + + //使用过程中断线重连 + final EventLoop eventLoop = ctx.channel().eventLoop(); + eventLoop.schedule(new Runnable() { + @Override + public void run() { + client.connect(); + } + }, 5L, TimeUnit.SECONDS); + super.channelInactive(ctx); + } + + + @Override + public void channelRead(ChannelHandlerContext ctx, Object message) throws Exception { + + if (handle) { + MultiValueMap map = new LinkedMultiValueMap<>(); + map.add("message", message.toString()); + HttpUtil.post("http://127.0.0.1:20311/data/addPerimeterAlarm", map); + } + handle = !handle; + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + cause.printStackTrace(); + ctx.close(); + } +} + diff --git a/casic-web/pom.xml b/casic-web/pom.xml new file mode 100644 index 0000000..8fb0b2c --- /dev/null +++ b/casic-web/pom.xml @@ -0,0 +1,171 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + ../pom.xml + 2.0.0 + + casic-web + 2.0.0 + jar + casic-web + casic web启动入口 + + + + dev + + true + + + dev + + + + test + + test + + + + prod + + prod + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + io.micrometer + micrometer-core + + + + + org.springframework.boot + spring-boot-starter-jdbc + + + + com.casic + casic-core + ${core.version} + + + com.casic + casic-admin-core + ${admin.version} + + + io.springfox + springfox-swagger-ui + + + + + com.casic + casic-admin-support + ${admin.version} + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.dameng + DmJdbcDriver18 + 1.8 + + + com.casic + casic-area-starter + ${admin.version} + + + + com.casic + casic-server + ${pro.version} + + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + + + org.apache.maven.plugins + maven-jar-plugin + ${maven.jar.plugin.version} + + + + /config/*-*.yml + **/MockController.class + + + + com.casic.missiles.CasicApplication + true + ./ + + + + + + org.apache.maven.plugins + maven-assembly-plugin + ${maven.assembly.plugin.version} + + + make-assembly + package + + single + + + + + + org.apache.maven.plugins + maven-war-plugin + ${maven.war.plugin.version} + + + + + src/main/resources + + + /config/*/* + /config/*-*.yml + + true + + + src/main/java + + **/*.xml + + true + + + + \ No newline at end of file diff --git a/casic-web/src/main/build/bin/start.bat b/casic-web/src/main/build/bin/start.bat new file mode 100644 index 0000000..1db4e88 --- /dev/null +++ b/casic-web/src/main/build/bin/start.bat @@ -0,0 +1,4 @@ +@echo off +title ${project.build.finalName} +java -jar ./lib/${project.build.finalName}.jar +@pause diff --git a/casic-web/src/main/build/bin/start.sh b/casic-web/src/main/build/bin/start.sh new file mode 100644 index 0000000..c00b1ef --- /dev/null +++ b/casic-web/src/main/build/bin/start.sh @@ -0,0 +1,2 @@ +java -jar ./lib/${project.build.finalName}.jar + diff --git a/casic-web/src/main/build/package.xml b/casic-web/src/main/build/package.xml new file mode 100644 index 0000000..c9259ad --- /dev/null +++ b/casic-web/src/main/build/package.xml @@ -0,0 +1,43 @@ + + + package + + zip + tar.gz + + true + + + + true + true + lib + runtime + + + + + src/main/build/bin + + start.bat + start.sh + + true + 0744 + / + + + src/main/resources/config + true + + *.yml + /*/* + + /config + + + src/main/resources/i18n + / + + + \ No newline at end of file diff --git a/casic-web/src/main/java/com/casic/missiles/CasicApplication.java b/casic-web/src/main/java/com/casic/missiles/CasicApplication.java new file mode 100644 index 0000000..308dcad --- /dev/null +++ b/casic-web/src/main/java/com/casic/missiles/CasicApplication.java @@ -0,0 +1,29 @@ +package com.casic.missiles; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.ServletComponentScan; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +/** + * SpringBoot方式启动类 + * + * @author lwh + * @Date 2021/06/06 12:06 + */ +@SpringBootApplication +@EnableCaching +@EnableTransactionManagement(proxyTargetClass = true) +@EnableAsync +@Slf4j +public class CasicApplication { + public static void main(String[] args) { + SpringApplication.run(CasicApplication.class, args); + + log.info("CasicApplication is success!"); + } + +} diff --git a/casic-web/src/main/java/com/casic/missiles/CasicServletInitializer.java b/casic-web/src/main/java/com/casic/missiles/CasicServletInitializer.java new file mode 100644 index 0000000..e30585b --- /dev/null +++ b/casic-web/src/main/java/com/casic/missiles/CasicServletInitializer.java @@ -0,0 +1,18 @@ +package com.casic.missiles; + +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; + +/** + * Guns Web程序启动类 + * + * @author fengshuonan + * @date 2017-05-21 9:43 + */ +public class CasicServletInitializer extends SpringBootServletInitializer { + + @Override + protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { + return application.sources(CasicApplication.class); + } +} diff --git a/casic-web/src/main/java/com/casic/missiles/controller/MockController.java b/casic-web/src/main/java/com/casic/missiles/controller/MockController.java new file mode 100644 index 0000000..eae6c54 --- /dev/null +++ b/casic-web/src/main/java/com/casic/missiles/controller/MockController.java @@ -0,0 +1,82 @@ +package com.casic.missiles.controller; + +import cn.hutool.core.util.StrUtil; +import com.casic.missiles.core.application.enums.LoginType; +import com.casic.missiles.core.base.controller.BaseController; +import com.casic.missiles.core.model.auth.AuthUser; +import com.casic.missiles.core.model.auth.CasicCustomToken; +import com.casic.missiles.core.shiro.ShiroKit; +import com.casic.missiles.core.util.RSAUtils; +import com.casic.missiles.model.response.SuccessResponseData; +import com.casic.missiles.modular.domain.constants.PermissionConstants; +import com.casic.missiles.modular.interfaces.log.LogManager; +import com.casic.missiles.modular.interfaces.log.factory.LogTaskFactory; +import com.casic.missiles.modular.system.dto.LoginSuccessDTO; +import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.subject.Subject; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import java.security.NoSuchAlgorithmException; +import java.util.Map; + +import static com.casic.missiles.core.util.HttpContext.getIp; + + +/** + * 仅为mock登录使用 + * + * @author lenovo + */ +@Controller +@RequestMapping("/route") +@Slf4j +public class MockController extends BaseController { + + /** + * 获取mockToken + */ + @GetMapping("/mockToken") + @ResponseBody + public Object mockToken(String username, String password) { + super.getSession().setAttribute(PermissionConstants.IS_APP, false); + SuccessResponseData resultData = new SuccessResponseData(); + if (StrUtil.hasEmpty(username, password)) { + username = "admin"; + password = "111111"; + } + Subject currentUser = ShiroKit.getSubject(); + + try { + Map key = RSAUtils.genKeyPair(); + ShiroKit.getSession().setAttribute(PermissionConstants.PRIVATE_KEY, key.get(RSAUtils.RSAPrivateKey)); + + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + + //token自定义 + CasicCustomToken token = new CasicCustomToken(username, password); + token.setType(LoginType.PASSWORD); + token.setRememberMe(false); + + try { + currentUser.login(token); + } catch (Exception e) { + e.printStackTrace(); + } + AuthUser shiroUser = ShiroKit.getUser(); + super.getSession().setAttribute("shiroUser", shiroUser); + super.getSession().setAttribute("username", shiroUser.getAccount()); + super.getSession().setAttribute(PermissionConstants.SESSION_KEY, shiroUser.getId()); + + LogManager.me().executeLog(LogTaskFactory.loginLog(shiroUser.getId(), getIp())); + + ShiroKit.getSession().setAttribute("sessionFlag", true); + resultData.setData(new LoginSuccessDTO(ShiroKit.getSession().getId().toString(), null)); + resultData.setMessage("登录成功"); + return resultData; + } +} diff --git a/casic-web/src/main/resources/META-INF/spring-devtools.properties b/casic-web/src/main/resources/META-INF/spring-devtools.properties new file mode 100644 index 0000000..e3b0a7f --- /dev/null +++ b/casic-web/src/main/resources/META-INF/spring-devtools.properties @@ -0,0 +1 @@ +restart.include.beetl=/beetl-2.7.15.jar \ No newline at end of file diff --git a/casic-web/src/main/resources/config/application-dev.yml b/casic-web/src/main/resources/config/application-dev.yml new file mode 100644 index 0000000..8c18554 --- /dev/null +++ b/casic-web/src/main/resources/config/application-dev.yml @@ -0,0 +1,30 @@ +server: + port: 8083 +################### spring配置 ################### +spring: + datasource: + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://111.198.10.15:11336/casic_template2.0?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&serverTimezone=UTC&&allowMultiQueries=true + username: root + password: Casic203 +jms: + pub-sub-domain: true +# session: +# store-type: redis +# redis: +# host: 111.198.10.15 +# port: 11412 +# password: ew5T4K3#203lwh +# serializer: org.springframework.data.redis.serializer.StringRedisSerializer +# redisValueSerializer: org.springframework.data.redis.serializer.JdkSerializationRedisSerializer +casic: + #kaptcha-open: false #是否开启登录时验证码 (true/false) + no-login-urls: ${casic.sysUrl}/user/login,${casic.sysUrl}/user/appLogin,${casic.sysUrl}/kaptcha/base64,${casic.sysUrl}/config/baseConfig,/route/mockToken + #flowable数据源和多数据源配置 + db: + init: + enable: false +logging: + level.root: info + level.com.casic: debug + level.org.springframework.web: info \ No newline at end of file diff --git a/casic-web/src/main/resources/config/application-prod.yml b/casic-web/src/main/resources/config/application-prod.yml new file mode 100644 index 0000000..6553b10 --- /dev/null +++ b/casic-web/src/main/resources/config/application-prod.yml @@ -0,0 +1,34 @@ +server: + port: 8085 +# context-path: /callcenter/api +################### spring配置 ################### +spring: + datasource: + url: jdbc:mysql://10.18.0.20:3306/casic_smartcity_callcenter?autoReconnect=true&useUnicode=true&characterEncoding=utf8&useSSL=false&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull + username: root + password: Casic203 + initial-size: 2 + min-idle: 1 + jms: + pub-sub-domain: true + # session: + # store-type: redis + redis: + host: 127.0.0.1 + port: 6379 + password: + +#flowable数据源和多数据源配置 +casic: + kaptcha-open: false #是否开启登录时验证码 (true/false) + nologin-urls: /user/login,/user/appLogin,/kaptcha,/config/baseConfig,/route/mockToken + flowable: + datasource: + url: jdbc:mysql://10.18.0.20:3306/callcenter_flowable?autoReconnect=true&useUnicode=true&characterEncoding=utf8&useSSL=false&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull + username: root + password: Casic203 +logging: + level.root: info + level.com.casic: debug + path: logs/ + file: missiles.log \ No newline at end of file diff --git a/casic-web/src/main/resources/config/application-test.yml b/casic-web/src/main/resources/config/application-test.yml new file mode 100644 index 0000000..54d7252 --- /dev/null +++ b/casic-web/src/main/resources/config/application-test.yml @@ -0,0 +1,30 @@ +server: + port: 11307 +################### spring配置 ################### +spring: + datasource: + url: jdbc:mysql://localhost:3306/casic_template?autoReconnect=true&useUnicode=true&characterEncoding=utf8&useSSL=false&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull + username: root + password: Casic203! + initial-size: 2 + min-idle: 1 + jms: + pub-sub-domain: true +# session: +# store-type: redis +casic: + # kaptcha-open: false #是否开启登录时验证码 (true/false) + nologin-urls: /user/login,/user/appLogin,/kaptcha/base64,/config/baseConfig,/route/mockToken,/workflow/** + #flowable数据源和多数据源配置 + flowable: + datasource: + url: jdbc:mysql://localhost:3306/template_flowable?autoReconnect=true&useUnicode=true&characterEncoding=utf8&useSSL=false&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull + username: root + password: Casic203! +flowable: + checkProcessDefinitions: false #不校验process文件 +logging: + level.root: info + level.com.casic: debug + path: logs/ + file: missiles.log \ No newline at end of file diff --git a/casic-web/src/main/resources/config/application.yml b/casic-web/src/main/resources/config/application.yml new file mode 100644 index 0000000..33cce3f --- /dev/null +++ b/casic-web/src/main/resources/config/application.yml @@ -0,0 +1,26 @@ +########################################################## +################## 所有profile共有的配置 ################# +########################################################## +spring: + profiles: + active: dev + servlet: + multipart: + max-file-size: 50MB + max-request-size: 80MB +#mybatis-plus: +# sql-injector: com.baomidou.mybatisplus.mapper.LogicSqlInjector +################### mybatis-plus配置 ################### +################### guns配置 ################### +casic: + swagger-open: false #是否开启swagger (true/false) + kaptcha-open: false #是否开启登录时验证码 (true/false) + muti-datasource-open: false #是否开启多数据源(true/false) + spring-session-open: false #是否开启spring session,如果是多机环境需要开启(true/false) + session-invalidate-time: 86400 #session失效时间(只在单机环境下生效,,多机环境在SpringSessionConfig类中配置) 单位:秒 + session-validation-interval: 900 #多久检测一次失效的session(只在单机环境下生效) 单位:秒 + no-login-urls: /user/login,/kaptcha,/config/baseConfig + + config: + export-path: D:\java\boot\guns-web-1.0.0-SNAPSHOT\export\ + config-path: E:\Develop\IdeaProject\smartcity\casic-smartcity-dcms\casic-web\src\main\resources\config\ \ No newline at end of file diff --git a/casic-web/src/main/resources/logback-spring.xml b/casic-web/src/main/resources/logback-spring.xml new file mode 100644 index 0000000..c0c7ac9 --- /dev/null +++ b/casic-web/src/main/resources/logback-spring.xml @@ -0,0 +1,113 @@ + + + + + + + + + + + + + ${CONSOLE_LOG_PATTERN} + utf-8 + + + + + + + + + + + + + + + + + + + + + + ${CONSOLE_LOG_PATTERN} + utf-8 + + + + + + + + ${LOG_PATH}/missiles_error.log + + + + + + ${LOG_PATH}/error/log-error-%d{yyyy-MM-dd}.%i.log + + + + 10MB + + + + + true + + + + ${FILE_LOG_PATTERN} + utf-8 + + + + + error + ACCEPT + DENY + + + + + + + + ${LOG_PATH}/missiles_total.log + + + + + + ${LOG_PATH}/total/log-total-%d{yyyy-MM-dd}.%i.log + + + + 10MB + + + + + true + + + + ${FILE_LOG_PATTERN} + utf-8 + + + + + + + + + + + \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9e20bc1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea/ +**/target/** +logs/ +*.iml diff --git a/README.md b/README.md new file mode 100644 index 0000000..2fdcd74 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# casic项目 V2.0.0 + +[^_^]: # (Talk is cheap,Show me the code!) + +## 介绍 +基于SpringBoot,致力于做更简洁的后台管理系统,完美整合springboot2.4 + shiro + mybatis-plus ! +基于casic项目代码简洁,注释丰富,上手容易,同时包含许多基础模块(用户管理,角色管理,部门管理,字典管理等10个模块) +可以直接作为一个后台管理系统的脚手架! 2022目标 `更简洁`,`更规范`! + + +#### 其他 +>* [git地址](http://192.168.0.203:8080/gitbucket) +>* [本地免登地址](http://localhost:8083/route/mockToken) diff --git a/casic-server/pom.xml b/casic-server/pom.xml new file mode 100644 index 0000000..c150a12 --- /dev/null +++ b/casic-server/pom.xml @@ -0,0 +1,70 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + 2.0.0 + ../pom.xml + + + casic-server + 2.0.0 + jar + casic-server + casic 的spring boot版本 + + + + + com.casic + casic-core + ${core.version} + provided + + + com.casic + casic-admin-support + ${admin.version} + provided + + + org.springframework.boot + spring-boot-starter-web + ${boot.version} + provided + + + + + com.hikvision.ga + artemis-http-client + 1.1.3 + + + commons-io + commons-io + + + org.springframework.boot + spring-boot-starter-websocket + 2.4.5 + + + io.netty + netty-all + 4.1.42.Final + + + + + + src/main/java + + **/*.xml + + + + + \ No newline at end of file diff --git a/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java new file mode 100644 index 0000000..3a60b9e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/async/AsyncConfig.java @@ -0,0 +1,36 @@ +package com.casic.missiles.modular.async; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.TaskExecutor; +import org.springframework.scheduling.annotation.AsyncConfigurer; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadPoolExecutor; + +@Configuration +@EnableAsync +public class AsyncConfig implements AsyncConfigurer { + @Override + public Executor getAsyncExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + //核心线程数 + executor.setCorePoolSize(5); + //最大线程数 + executor.setMaxPoolSize(10); + //队列容量 + executor.setQueueCapacity(20); + //设置线程活跃时间(秒) + executor.setKeepAliveSeconds(60); + //默认线程名称 + executor.setThreadNamePrefix("user-rpt-"); + //拒绝策略 + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + //等待所有任务结束后再关闭线程池 + executor.setWaitForTasksToCompleteOnShutdown(true); + return executor; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java new file mode 100644 index 0000000..8ca554c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/config/WebSocketConfig.java @@ -0,0 +1,18 @@ +package com.casic.missiles.modular.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +// tomcat启动无需配置 +@Configuration +public class WebSocketConfig { + /** + * 注入ServerEndpointExporter, + * 这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint + */ + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java new file mode 100644 index 0000000..34fe2cd --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/controller/DemoController.java @@ -0,0 +1,39 @@ +package com.casic.missiles.modular.controller; + + +import com.casic.missiles.model.application.event.core.EventPublisher; +import com.casic.missiles.model.application.event.enums.ModelEventTypeEnum; +import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.modular.event.UserEvent; +import com.casic.missiles.modular.system.model.User; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +/** + * @Description: DemoController + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@RestController +@RequestMapping("/demo") +public class DemoController { + @Autowired + private EventPublisher publisher; + + /** + * 获取mockToken + */ + @PostMapping("/list") + @ResponseBody + public Object list() { + User user = new User(); + user.setAccount("张三"); + publisher.publishEvent(new UserEvent(ModelEventTypeEnum.ADD, user)); + return ResponseData.success(); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java new file mode 100644 index 0000000..aff2889 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/UserEvent.java @@ -0,0 +1,23 @@ +package com.casic.missiles.modular.event; + +import com.casic.missiles.model.application.event.core.ModelEvent; +import com.casic.missiles.model.application.event.type.AbstractEventTypeEnum; +import com.casic.missiles.modular.system.model.User; + +/** + * @Description: 用户事件 + * @Author: wangpeng + * @Date: 2022/7/17 11:23 + */ +public class UserEvent extends ModelEvent { + /** + * Create a new {@code ApplicationEvent}. + * + * @param type 事件类型 + * @param source the object on which the event initially occurred or with + * which the event is associated (never {@code null}) + */ + public UserEvent(AbstractEventTypeEnum type, User source) { + super(type, source); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java new file mode 100644 index 0000000..8f9603e --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserOneListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.core.application.event.UserLoginEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserOneListener { + @EventListener + public void onApplicationEvent(UserLoginEvent event) { + log.debug("用户1订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java new file mode 100644 index 0000000..0bd52a3 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/event/listener/UserTwoListener.java @@ -0,0 +1,20 @@ +package com.casic.missiles.modular.event.listener; + +import com.casic.missiles.model.application.event.core.EventSubscriber; +import com.casic.missiles.modular.event.UserEvent; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * @Description: 用户事件订阅 + * @Author: wangpeng + * @Date: 2022/7/17 11:22 + */ +@Slf4j +@Component +public class UserTwoListener extends EventSubscriber { + @Override + public void onApplicationEvent(UserEvent event) { + log.debug("用户2订阅:{}", event); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java new file mode 100644 index 0000000..4012170 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/Base64Util.java @@ -0,0 +1,88 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang3.StringUtils; +import sun.misc.BASE64Decoder; + +import java.io.*; + +public class Base64Util { + /** + * base64字符串转换成图片 + * + * @param imgStr base64字符串 + * @param imgFilePath 图片存放路径 + * @return + * @author ZHANGJL + * @dateTime 2018-02-23 14:42:17 + */ + public static boolean Base64ToImage(String imgStr, String imgFilePath, String fileDir) { // 对字节数组字符串进行Base64解码并生成图片 + + if (StringUtils.isEmpty(imgStr)) // 图像数据为空 + return false; + + imgStr = imgStr.substring(imgStr.indexOf(",") + 1); + + BASE64Decoder decoder = new BASE64Decoder(); + try { + // Base64解码 + byte[] b = decoder.decodeBuffer(imgStr); + + for (int i = 0; i < b.length; ++i) { + if (b[i] < 0) {// 调整异常数据 + b[i] += 256; + } + } + //如果已存在图像,先删除 + File file = new File(fileDir+File.separator + imgFilePath); + if (file.exists() && file.isFile()) { + file.delete(); + } + File dir = new File(fileDir); + if (!dir.exists()) { + dir.mkdirs(); + } + file = new File(fileDir+File.separator+imgFilePath); + file.createNewFile(); +// ImageIO.write(bImage, "bmp", name); + OutputStream out = new FileOutputStream(fileDir+File.separator+imgFilePath); + out.write(b); + out.flush(); + out.close(); + + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + + } + + public static String getBase64FromInputStream(InputStream in) { + // 将图片文件转化为字节数组字符串,并对其进行Base64编码处理 + byte[] data = null; + // 读取图片字节数组 + try { + ByteArrayOutputStream swapStream = new ByteArrayOutputStream(); + byte[] buff = new byte[100]; + int rc = 0; + while ((rc = in.read(buff, 0, 100)) > 0) { + swapStream.write(buff, 0, rc); + } + data = swapStream.toByteArray(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return new String(Base64.encodeBase64(data)); + } + + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java new file mode 100644 index 0000000..9c93895 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/CommonUtil.java @@ -0,0 +1,75 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.lang3.StringUtils; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class CommonUtil { + + public static String CutId(String id) { + return id.substring(6, 10) + "-" + id.substring(10, 12) + "-" + id.substring(12, 14); + } + + public static boolean isIDNumber(String IDNumber) { + if (IDNumber == null || "".equals(IDNumber)) { + return false; + } + // 定义判别用户身份证号的正则表达式(15位或者18位,最后一位可以为字母) + String regularExpression = + "(^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|" + + "(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}$)"; + boolean matches = IDNumber.matches(regularExpression); + // 判断第18位校验值 + if (matches) { + if (IDNumber.length() == 18) { + try { + char[] charArray = IDNumber.toCharArray(); + // 前十七位加权因子 + int[] idCardWi = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; + // 这是除以11后,可能产生的11位余数对应的验证码 + String[] idCardY = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"}; + int sum = 0; + for (int i = 0; i < idCardWi.length; i++) { + int current = Integer.parseInt(String.valueOf(charArray[i])); + int count = current * idCardWi[i]; + sum += count; + } + char idCardLast = charArray[17]; + int idCardMod = sum % 11; + if (idCardY[idCardMod].toUpperCase() + .equals(String.valueOf(idCardLast).toUpperCase())) { + return true; + } else { + System.out.println("身份证最后一位:" + String.valueOf(idCardLast).toUpperCase() + + "错误,正确的应该是:" + idCardY[idCardMod].toUpperCase()); + return false; + } + + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } else { + return false; + } + } + return matches; + } + + + public static boolean CheckMobilePhoneNum(String phoneNum) { + if (StringUtils.isEmpty(phoneNum)) + return true; + String regex = "^(1[3-9]\\d{9}$)"; + if (phoneNum.length() == 11) { + Pattern p = Pattern.compile(regex); + Matcher m = p.matcher(phoneNum); + if (m.matches()) { + return true; + } + } + return false; + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java new file mode 100644 index 0000000..191ef79 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/DateUtils.java @@ -0,0 +1,116 @@ +package com.casic.missiles.modular.util; + + +import javafx.util.Pair; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +/** + * Created by Administrator on 2015/2/25. + */ +public class DateUtils { + public static SimpleDateFormat sdf_day = new SimpleDateFormat("yyyy-MM-dd"); + public static SimpleDateFormat sdf_day_time = new SimpleDateFormat("yyyyMMddhhmmss"); + public static final SimpleDateFormat sdf4 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + public static final SimpleDateFormat sdf5 = new SimpleDateFormat("HH:mm:ss"); + + + /** + * 获取当年的第一天 + * + * @return + */ + public static Date getCurrYearFirst() { + Calendar currCal = Calendar.getInstance(); + int currentYear = currCal.get(Calendar.YEAR); + return getYearFirst(currentYear); + } + + + /** + * 获取某年第一天日期 + * + * @param year 年份 + * @return Date + */ + public static Date getYearFirst(int year) { + Calendar calendar = Calendar.getInstance(); + calendar.clear(); + calendar.set(Calendar.YEAR, year); + Date currYearFirst = calendar.getTime(); + return currYearFirst; + } + + /** + * 最近7日(不包括今日) + */ + public static Pair getLastSevenDays() { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, -7); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 最近n日(不包括今日) + */ + public static Pair getLastNDays(int n) { + + Calendar calendar = Calendar.getInstance(); + String endDate = sdf4.format(calendar.getTime()); + + calendar.add(Calendar.DATE, n * -1); + String beginDate = sdf4.format(calendar.getTime()); + + return new Pair<>(beginDate, endDate); + } + + /** + * 日期时间加n天 + */ + public static String addDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf4.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf4.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 日期加n天 + */ + public static String addNDays(String date, int n) { + + try { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(sdf_day.parse(date)); + calendar.add(Calendar.DATE, n); + return sdf_day.format(calendar.getTime()); + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 昨日 + */ + public static String getYesterday() { + + Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.DATE, -2); + return sdf_day.format(calendar.getTime()); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java new file mode 100644 index 0000000..da0f8ee --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/HikUtil.java @@ -0,0 +1,49 @@ +package com.casic.missiles.modular.util; + +import com.hikvision.artemis.sdk.ArtemisHttpUtil; +import com.hikvision.artemis.sdk.config.ArtemisConfig; + +import java.util.HashMap; +import java.util.Map; + +public class HikUtil { + + public static String hikApi(String uri, String body) { + + /** + * STEP1:设置平台参数,根据实际情况,设置host appkey appsecret 三个参数. + */ + ArtemisConfig.host = "192.168.1.22:443"; // artemis网关服务器ip端口 + ArtemisConfig.appKey = "25766251"; // 秘钥appkey + ArtemisConfig.appSecret = "h2o6zXtzCmt8eaOaMkXb";// 秘钥appSecret + + /** + * STEP2:设置OpenAPI接口的上下文 + */ + final String ARTEMIS_PATH = "/artemis"; + + /** + * STEP3:设置接口的URI地址 + */ + final String previewURLsApi = ARTEMIS_PATH + uri; + Map path = new HashMap(2) { + { + put("https://", previewURLsApi);//根据现场环境部署确认是http还是https + } + }; + + /** + * STEP4:设置参数提交方式 + */ + String contentType = "application/json"; + + /** + * STEP5:组装请求参数 + */ + /** + * STEP6:调用接口 + */ + String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, contentType, null);// post请求application/json类型参数 + return result; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java new file mode 100644 index 0000000..4867144 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/HttpUtil.java @@ -0,0 +1,149 @@ +package com.casic.missiles.modular.util; + +import org.springframework.http.*; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; + +/** + * @Description: http请求工具类 + * @Author: wangpeng + * @Date: 2022/7/17 11:49 + */ +public class HttpUtil { + /** + * get请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String get(String url, MultiValueMap params) { + return get(url, params, null); + } + + /** + * get请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String get(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.GET); + } + + /** + * post请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String post(String url, MultiValueMap params) { + return post(url, params, null); + } + + /** + * post请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String post(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.POST); + } + + /** + * put请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String put(String url, MultiValueMap params) { + return put(url, params, null); + } + + /** + * put请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String put(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.PUT); + } + + /** + * delete请求 + * + * @param url + * @param params 请求参数 + * @return + */ + public static String delete(String url, MultiValueMap params) { + return delete(url, params, null); + } + + /** + * delete请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @return + */ + public static String delete(String url, MultiValueMap params, MultiValueMap headers) { + return request(url, params, headers, HttpMethod.DELETE); + } + + /** + * 表单请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @param method 请求方式 + * @return + */ + public static String request(String url, MultiValueMap params, MultiValueMap headers, HttpMethod method) { + if (params == null) { + params = new LinkedMultiValueMap<>(); + } + return request(url, params, headers, method, MediaType.APPLICATION_FORM_URLENCODED); + } + + /** + * http请求 + * + * @param url + * @param params 请求参数 + * @param headers 请求头 + * @param method 请求方式 + * @param mediaType 参数类型 + * @return + */ + public static String request(String url, Object params, MultiValueMap headers, HttpMethod method, MediaType mediaType) { + if (url == null || url.trim().isEmpty()) { + return null; + } + RestTemplate client = new RestTemplate(); + // header + HttpHeaders httpHeaders = new HttpHeaders(); + if (headers != null) { +// httpHeaders.addAll(headers); + httpHeaders.putAll(headers); + } + // 提交方式:表单、json + httpHeaders.setContentType(mediaType); + HttpEntity httpEntity = new HttpEntity(params, httpHeaders); + ResponseEntity response = client.exchange(url, method, httpEntity, String.class); + return response.getBody(); + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java new file mode 100644 index 0000000..19d8d67 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SelectDTO.java @@ -0,0 +1,30 @@ +package com.casic.missiles.modular.util; + +public class SelectDTO { + private String name; + private String value; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public SelectDTO() { + } + + public SelectDTO(String name, String value) { + this.name = name; + this.value = value; + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java new file mode 100644 index 0000000..0bd484c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketConst.java @@ -0,0 +1,28 @@ +package com.casic.missiles.modular.util; + +public class SocketConst { + + /** + * 新增授权socket前缀 + */ + public static final String SOCKET_PREFIX_ADD_PERMISSION = "addPermission:"; + + /** + * 取消授权socket前缀 + */ + public static final String SOCKET_PREFIX_DELETE_PERMISSION = "deletePermission:"; + + /** + * 人员数据下发socket前缀 + */ + public static final String SOCKET_PREFIX_ADD_PERSON = "addPerson:"; + + /** + * socket返回成功信息 + */ + public static final String SOCKET_SUCCESS_MSG = "ok"; + /** + * 人员数据下发socket前缀 + */ + public static final String SOCKET_PREFIX_DELETE_PERSON = "deletePerson:"; +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java new file mode 100644 index 0000000..0452bca --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/SocketUtil.java @@ -0,0 +1,90 @@ +package com.casic.missiles.modular.util; + +import org.apache.commons.io.IOUtils; +import org.springframework.stereotype.Component; + +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.text.SimpleDateFormat; +import java.util.Date; + +@Component +public class SocketUtil { + + public static byte[] sendMessage(String ip, int port, String msg) { + byte[] data = new byte[20]; + + System.out.println("往 " + ip + ":" + port + " 发送数据:" + msg); + InputStream in = null; + OutputStream out = null; + Socket socket = null; + try { + socket = new Socket(); + socket.connect(new InetSocketAddress(ip, port), 1000); + socket.setSoTimeout(2000); + // 向服务端发送数据 + out = socket.getOutputStream(); + out.write(hexString2Bytes(msg)); + out.flush(); + //socket.shutdownOutput(); + // 读取服务端返回数据 + in = socket.getInputStream(); + in.read(data); + } catch (Exception e) { + e.printStackTrace(); + } finally { + IOUtils.closeQuietly(in); + IOUtils.closeQuietly(out); + IOUtils.closeQuietly(socket); + } + return data; + } + + private static int code = 0; + + public static void main(String[] args) { +// byte[] dd = sendMessage("192.168.5.211",6001,"090300000002C543"); + + String dateStr = new SimpleDateFormat("yyMMddHHmmssSSS").format(new Date()); + //String dd = dateStr + String.format("%04d",++code); + + System.out.println(dateStr); + } + + /** + * 返回由字节数组转换来的 16 位有符号整数 + * + * @param bytes 字节数组 + * @return 由两个字节构成的 16 位有符号整数 + */ + public static short toShort(byte[] bytes) { + return (short) ((0xff & bytes[0]) | (0xff00 & (bytes[1] << 8))); + + } + + + public static byte[] hexString2Bytes(String hex) { + if ((hex == null) || (hex.equals(""))) { + return null; + } else if (hex.length() % 2 != 0) { + return null; + } else { + hex = hex.toUpperCase(); + int len = hex.length() / 2; + byte[] b = new byte[len]; + char[] hc = hex.toCharArray(); + for (int i = 0; i < len; i++) { + int p = 2 * i; + b[i] = (byte) (charToByte(hc[p]) << 4 | charToByte(hc[p + 1])); + } + return b; + } + } + + private static byte charToByte(char c) { + return (byte) "0123456789ABCDEF".indexOf(c); + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java b/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java new file mode 100644 index 0000000..9b4155c --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/WebSocket.java @@ -0,0 +1,105 @@ +package com.casic.missiles.modular.util; + +import org.springframework.stereotype.Component; + +import javax.websocket.OnClose; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.PathParam; +import javax.websocket.server.ServerEndpoint; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CopyOnWriteArraySet; + +/** + * @Description: 此注解相当于设置访问URL + * @Author: wangpeng + * @Date: 2022/7/17 11:48 + */ +@Component +@ServerEndpoint("/websocket/{userId}") +public class WebSocket { + private Session session; + + private static CopyOnWriteArraySet webSockets = new CopyOnWriteArraySet<>(); + private static Map sessionPool = new HashMap(); + + @OnOpen + public void onOpen(Session session, @PathParam(value = "userId") String userId) { + this.session = session; + webSockets.add(this); + sessionPool.put(userId, session); + System.out.println(userId + "【websocket消息】有新的连接,总数为:" + webSockets.size()); + } + + @OnClose + public void onClose() { + webSockets.remove(this); + System.out.println("【websocket消息】连接断开,总数为:" + webSockets.size()); + } + + @OnMessage + public void onMessage(String message) { + System.out.println("【websocket消息】收到客户端消息:" + message); + } + + // 此为广播消息 + public void sendAllMessage(String message) { + for (WebSocket webSocket : webSockets) { + System.out.println("【websocket消息】广播消息:" + message); + try { + webSocket.session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + // 发送列表消息 + public void sendListMessage(List userIds, String message) { + System.out.println("【websocket消息】列表消息:" + message); + for (String userId : userIds) { + Session session = sessionPool.get(userId); + if (session != null) { + try { + session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + + // 发送列表消息 + +// public void sendListMessage(List userIds, Object data){ +// System.out.println("【websocket消息】列表消息:"+data); +// for (String userId : userIds) { +// Session session = sessionPool.get(userId); +// if (session != null) { +// try { +//// session.getAsyncRemote().sendText(message); +// session.getAsyncRemote().sendObject(data); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// } +// } + + // 此为单点消息 + public void sendOneMessage(String userId, String message) { + System.out.println("【websocket消息】单点消息:" + message); + Session session = sessionPool.get(userId); + if (session != null) { + try { + session.getAsyncRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java b/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java new file mode 100644 index 0000000..0c1f5f1 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/ZipFileUtil.java @@ -0,0 +1,115 @@ +package com.casic.missiles.modular.util; + +import org.springframework.web.multipart.MultipartFile; + +import java.io.*; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipInputStream; + +/** + * @Description: 读取zip文件内容 + * @Author: wangpeng + * @Date: 2022/7/17 11:48 + */ +public class ZipFileUtil { + public static List getFile(String fileName) { + File file = new File(fileName); + ZipFile zipFile = null; + ZipInputStream zin = null; + FileInputStream fis = null; + List selectDTOList = new ArrayList<>(); + try { + Charset gbk = Charset.forName("GBK"); + zipFile = new ZipFile(file, gbk); + fis = new FileInputStream(file); + zin = new ZipInputStream(fis, gbk); + + ZipEntry ze = null; + while ((ze = zin.getNextEntry()) != null) { + String path = ze.getName(); + System.out.println(path); + if (!ze.isDirectory()) { + InputStream inputStream = zipFile.getInputStream(ze); + String base64Photo = Base64Util.getBase64FromInputStream(inputStream); +// List texts = IOUtils.readLines(inputStream); +// for (String text : texts) { +// System.out.println(" " + text); +// } + selectDTOList.add(new SelectDTO(path.substring(path.indexOf("/")+1), "data:image/png;base64,"+base64Photo)); + inputStream.close(); + } + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (zin != null) { + zin.closeEntry(); + zin.close(); + } + if (fis != null) + fis.close(); + if (zipFile != null) + zipFile.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return selectDTOList; + } + + + /** + * MultipartFile 转 File + * + * @param file + * @throws Exception + */ + public static File multipartFileToFile(MultipartFile file) throws Exception { + + File toFile = null; + if (file.equals("") || file.getSize() <= 0) { + file = null; + } else { + InputStream ins = null; + ins = file.getInputStream(); + toFile = new File(file.getOriginalFilename()); + inputStreamToFile(ins, toFile); + ins.close(); + } + return toFile; + } + + //获取流文件 + private static void inputStreamToFile(InputStream ins, File file) { + try { + OutputStream os = new FileOutputStream(file); + int bytesRead = 0; + byte[] buffer = new byte[8192]; + while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) { + os.write(buffer, 0, bytesRead); + } + os.close(); + ins.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 删除本地临时文件 + * + * @param file + */ + public static void delteTempFile(File file) { + if (file != null) { + File del = new File(file.toURI()); + del.delete(); + } + } +} + diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java new file mode 100644 index 0000000..ae93a17 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/ConnectionListener.java @@ -0,0 +1,34 @@ +package com.casic.missiles.modular.util.netty; + +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.EventLoop; +import lombok.extern.slf4j.Slf4j; + +import java.util.concurrent.TimeUnit; + +/** + * 负责监听启动时连接失败,重新连接功能 + * + */ +@Slf4j +public class ConnectionListener implements ChannelFutureListener { + + private NettyClient client = new NettyClient(); + + @Override + public void operationComplete(ChannelFuture channelFuture) throws Exception { + if (!channelFuture.isSuccess()) { + final EventLoop loop = channelFuture.channel().eventLoop(); + loop.schedule(new Runnable() { + @Override + public void run() { + log.info("服务端连接不上,开始重连操作..."); + client.connect(); + } + }, 5L, TimeUnit.MINUTES); + } else { + log.info("服务端连接成功..."); + } + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java new file mode 100644 index 0000000..ef9ae76 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClient.java @@ -0,0 +1,66 @@ +package com.casic.missiles.modular.util.netty; + +import io.netty.bootstrap.Bootstrap; +import io.netty.channel.*; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioSocketChannel; +import io.netty.handler.codec.string.StringDecoder; +import io.netty.handler.codec.string.StringEncoder; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public class NettyClient { + + private static Channel channel; + + private String fenceServiceHost = "127.0.0.1"; + private Integer fenceServicePort = 9200; + + public Channel connect() { + doConnect(fenceServiceHost, fenceServicePort); + return channel; + } + + public Channel connect(String host, int port) { + doConnect(host, port); + return channel; + } + + private void doConnect(String host, int port) { + EventLoopGroup workerGroup = new NioEventLoopGroup(); + try { + Bootstrap b = new Bootstrap(); + b.group(workerGroup); + b.channel(NioSocketChannel.class); + b.option(ChannelOption.SO_KEEPALIVE, true); + b.option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(1024 * 1024)); + + b.handler(new ChannelInitializer() { + @Override + public void initChannel(SocketChannel ch) throws Exception { + + ch.pipeline().addLast("decoder", new StringDecoder()); + ch.pipeline().addLast("encoder", new StringEncoder()); + ch.pipeline().addLast(new NettyClientHandler()); + } + }); + + ChannelFuture f = b.connect(host, port); + f.addListener(new ConnectionListener()); + channel = f.channel(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static void writeAndFlush(String message) { + + if (channel != null) { + channel.writeAndFlush(message); + System.out.println("电子围栏客户端发送消息:" + message); + } + } +} diff --git a/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClientHandler.java b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClientHandler.java new file mode 100644 index 0000000..28093f0 --- /dev/null +++ b/casic-server/src/main/java/com/casic/missiles/modular/util/netty/NettyClientHandler.java @@ -0,0 +1,62 @@ +package com.casic.missiles.modular.util.netty; + +import com.casic.missiles.modular.util.HttpUtil; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import io.netty.channel.EventLoop; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; + +import java.util.concurrent.TimeUnit; + +/** + * 客户端处理器 + **/ +@Slf4j +@Component +public class NettyClientHandler extends ChannelInboundHandlerAdapter { + static boolean handle = true; + + private NettyClient client = new NettyClient(); + + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + log.info("连接成功....."); + } + + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + log.info("断开连接....."); + + //使用过程中断线重连 + final EventLoop eventLoop = ctx.channel().eventLoop(); + eventLoop.schedule(new Runnable() { + @Override + public void run() { + client.connect(); + } + }, 5L, TimeUnit.SECONDS); + super.channelInactive(ctx); + } + + + @Override + public void channelRead(ChannelHandlerContext ctx, Object message) throws Exception { + + if (handle) { + MultiValueMap map = new LinkedMultiValueMap<>(); + map.add("message", message.toString()); + HttpUtil.post("http://127.0.0.1:20311/data/addPerimeterAlarm", map); + } + handle = !handle; + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + cause.printStackTrace(); + ctx.close(); + } +} + diff --git a/casic-web/pom.xml b/casic-web/pom.xml new file mode 100644 index 0000000..8fb0b2c --- /dev/null +++ b/casic-web/pom.xml @@ -0,0 +1,171 @@ + + + 4.0.0 + + com.casic + casic-security-cockpit + ../pom.xml + 2.0.0 + + casic-web + 2.0.0 + jar + casic-web + casic web启动入口 + + + + dev + + true + + + dev + + + + test + + test + + + + prod + + prod + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + io.micrometer + micrometer-core + + + + + org.springframework.boot + spring-boot-starter-jdbc + + + + com.casic + casic-core + ${core.version} + + + com.casic + casic-admin-core + ${admin.version} + + + io.springfox + springfox-swagger-ui + + + + + com.casic + casic-admin-support + ${admin.version} + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.dameng + DmJdbcDriver18 + 1.8 + + + com.casic + casic-area-starter + ${admin.version} + + + + com.casic + casic-server + ${pro.version} + + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + + + org.apache.maven.plugins + maven-jar-plugin + ${maven.jar.plugin.version} + + + + /config/*-*.yml + **/MockController.class + + + + com.casic.missiles.CasicApplication + true + ./ + + + + + + org.apache.maven.plugins + maven-assembly-plugin + ${maven.assembly.plugin.version} + + + make-assembly + package + + single + + + + + + org.apache.maven.plugins + maven-war-plugin + ${maven.war.plugin.version} + + + + + src/main/resources + + + /config/*/* + /config/*-*.yml + + true + + + src/main/java + + **/*.xml + + true + + + + \ No newline at end of file diff --git a/casic-web/src/main/build/bin/start.bat b/casic-web/src/main/build/bin/start.bat new file mode 100644 index 0000000..1db4e88 --- /dev/null +++ b/casic-web/src/main/build/bin/start.bat @@ -0,0 +1,4 @@ +@echo off +title ${project.build.finalName} +java -jar ./lib/${project.build.finalName}.jar +@pause diff --git a/casic-web/src/main/build/bin/start.sh b/casic-web/src/main/build/bin/start.sh new file mode 100644 index 0000000..c00b1ef --- /dev/null +++ b/casic-web/src/main/build/bin/start.sh @@ -0,0 +1,2 @@ +java -jar ./lib/${project.build.finalName}.jar + diff --git a/casic-web/src/main/build/package.xml b/casic-web/src/main/build/package.xml new file mode 100644 index 0000000..c9259ad --- /dev/null +++ b/casic-web/src/main/build/package.xml @@ -0,0 +1,43 @@ + + + package + + zip + tar.gz + + true + + + + true + true + lib + runtime + + + + + src/main/build/bin + + start.bat + start.sh + + true + 0744 + / + + + src/main/resources/config + true + + *.yml + /*/* + + /config + + + src/main/resources/i18n + / + + + \ No newline at end of file diff --git a/casic-web/src/main/java/com/casic/missiles/CasicApplication.java b/casic-web/src/main/java/com/casic/missiles/CasicApplication.java new file mode 100644 index 0000000..308dcad --- /dev/null +++ b/casic-web/src/main/java/com/casic/missiles/CasicApplication.java @@ -0,0 +1,29 @@ +package com.casic.missiles; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.ServletComponentScan; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +/** + * SpringBoot方式启动类 + * + * @author lwh + * @Date 2021/06/06 12:06 + */ +@SpringBootApplication +@EnableCaching +@EnableTransactionManagement(proxyTargetClass = true) +@EnableAsync +@Slf4j +public class CasicApplication { + public static void main(String[] args) { + SpringApplication.run(CasicApplication.class, args); + + log.info("CasicApplication is success!"); + } + +} diff --git a/casic-web/src/main/java/com/casic/missiles/CasicServletInitializer.java b/casic-web/src/main/java/com/casic/missiles/CasicServletInitializer.java new file mode 100644 index 0000000..e30585b --- /dev/null +++ b/casic-web/src/main/java/com/casic/missiles/CasicServletInitializer.java @@ -0,0 +1,18 @@ +package com.casic.missiles; + +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; + +/** + * Guns Web程序启动类 + * + * @author fengshuonan + * @date 2017-05-21 9:43 + */ +public class CasicServletInitializer extends SpringBootServletInitializer { + + @Override + protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { + return application.sources(CasicApplication.class); + } +} diff --git a/casic-web/src/main/java/com/casic/missiles/controller/MockController.java b/casic-web/src/main/java/com/casic/missiles/controller/MockController.java new file mode 100644 index 0000000..eae6c54 --- /dev/null +++ b/casic-web/src/main/java/com/casic/missiles/controller/MockController.java @@ -0,0 +1,82 @@ +package com.casic.missiles.controller; + +import cn.hutool.core.util.StrUtil; +import com.casic.missiles.core.application.enums.LoginType; +import com.casic.missiles.core.base.controller.BaseController; +import com.casic.missiles.core.model.auth.AuthUser; +import com.casic.missiles.core.model.auth.CasicCustomToken; +import com.casic.missiles.core.shiro.ShiroKit; +import com.casic.missiles.core.util.RSAUtils; +import com.casic.missiles.model.response.SuccessResponseData; +import com.casic.missiles.modular.domain.constants.PermissionConstants; +import com.casic.missiles.modular.interfaces.log.LogManager; +import com.casic.missiles.modular.interfaces.log.factory.LogTaskFactory; +import com.casic.missiles.modular.system.dto.LoginSuccessDTO; +import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.subject.Subject; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import java.security.NoSuchAlgorithmException; +import java.util.Map; + +import static com.casic.missiles.core.util.HttpContext.getIp; + + +/** + * 仅为mock登录使用 + * + * @author lenovo + */ +@Controller +@RequestMapping("/route") +@Slf4j +public class MockController extends BaseController { + + /** + * 获取mockToken + */ + @GetMapping("/mockToken") + @ResponseBody + public Object mockToken(String username, String password) { + super.getSession().setAttribute(PermissionConstants.IS_APP, false); + SuccessResponseData resultData = new SuccessResponseData(); + if (StrUtil.hasEmpty(username, password)) { + username = "admin"; + password = "111111"; + } + Subject currentUser = ShiroKit.getSubject(); + + try { + Map key = RSAUtils.genKeyPair(); + ShiroKit.getSession().setAttribute(PermissionConstants.PRIVATE_KEY, key.get(RSAUtils.RSAPrivateKey)); + + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + + //token自定义 + CasicCustomToken token = new CasicCustomToken(username, password); + token.setType(LoginType.PASSWORD); + token.setRememberMe(false); + + try { + currentUser.login(token); + } catch (Exception e) { + e.printStackTrace(); + } + AuthUser shiroUser = ShiroKit.getUser(); + super.getSession().setAttribute("shiroUser", shiroUser); + super.getSession().setAttribute("username", shiroUser.getAccount()); + super.getSession().setAttribute(PermissionConstants.SESSION_KEY, shiroUser.getId()); + + LogManager.me().executeLog(LogTaskFactory.loginLog(shiroUser.getId(), getIp())); + + ShiroKit.getSession().setAttribute("sessionFlag", true); + resultData.setData(new LoginSuccessDTO(ShiroKit.getSession().getId().toString(), null)); + resultData.setMessage("登录成功"); + return resultData; + } +} diff --git a/casic-web/src/main/resources/META-INF/spring-devtools.properties b/casic-web/src/main/resources/META-INF/spring-devtools.properties new file mode 100644 index 0000000..e3b0a7f --- /dev/null +++ b/casic-web/src/main/resources/META-INF/spring-devtools.properties @@ -0,0 +1 @@ +restart.include.beetl=/beetl-2.7.15.jar \ No newline at end of file diff --git a/casic-web/src/main/resources/config/application-dev.yml b/casic-web/src/main/resources/config/application-dev.yml new file mode 100644 index 0000000..8c18554 --- /dev/null +++ b/casic-web/src/main/resources/config/application-dev.yml @@ -0,0 +1,30 @@ +server: + port: 8083 +################### spring配置 ################### +spring: + datasource: + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://111.198.10.15:11336/casic_template2.0?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&serverTimezone=UTC&&allowMultiQueries=true + username: root + password: Casic203 +jms: + pub-sub-domain: true +# session: +# store-type: redis +# redis: +# host: 111.198.10.15 +# port: 11412 +# password: ew5T4K3#203lwh +# serializer: org.springframework.data.redis.serializer.StringRedisSerializer +# redisValueSerializer: org.springframework.data.redis.serializer.JdkSerializationRedisSerializer +casic: + #kaptcha-open: false #是否开启登录时验证码 (true/false) + no-login-urls: ${casic.sysUrl}/user/login,${casic.sysUrl}/user/appLogin,${casic.sysUrl}/kaptcha/base64,${casic.sysUrl}/config/baseConfig,/route/mockToken + #flowable数据源和多数据源配置 + db: + init: + enable: false +logging: + level.root: info + level.com.casic: debug + level.org.springframework.web: info \ No newline at end of file diff --git a/casic-web/src/main/resources/config/application-prod.yml b/casic-web/src/main/resources/config/application-prod.yml new file mode 100644 index 0000000..6553b10 --- /dev/null +++ b/casic-web/src/main/resources/config/application-prod.yml @@ -0,0 +1,34 @@ +server: + port: 8085 +# context-path: /callcenter/api +################### spring配置 ################### +spring: + datasource: + url: jdbc:mysql://10.18.0.20:3306/casic_smartcity_callcenter?autoReconnect=true&useUnicode=true&characterEncoding=utf8&useSSL=false&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull + username: root + password: Casic203 + initial-size: 2 + min-idle: 1 + jms: + pub-sub-domain: true + # session: + # store-type: redis + redis: + host: 127.0.0.1 + port: 6379 + password: + +#flowable数据源和多数据源配置 +casic: + kaptcha-open: false #是否开启登录时验证码 (true/false) + nologin-urls: /user/login,/user/appLogin,/kaptcha,/config/baseConfig,/route/mockToken + flowable: + datasource: + url: jdbc:mysql://10.18.0.20:3306/callcenter_flowable?autoReconnect=true&useUnicode=true&characterEncoding=utf8&useSSL=false&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull + username: root + password: Casic203 +logging: + level.root: info + level.com.casic: debug + path: logs/ + file: missiles.log \ No newline at end of file diff --git a/casic-web/src/main/resources/config/application-test.yml b/casic-web/src/main/resources/config/application-test.yml new file mode 100644 index 0000000..54d7252 --- /dev/null +++ b/casic-web/src/main/resources/config/application-test.yml @@ -0,0 +1,30 @@ +server: + port: 11307 +################### spring配置 ################### +spring: + datasource: + url: jdbc:mysql://localhost:3306/casic_template?autoReconnect=true&useUnicode=true&characterEncoding=utf8&useSSL=false&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull + username: root + password: Casic203! + initial-size: 2 + min-idle: 1 + jms: + pub-sub-domain: true +# session: +# store-type: redis +casic: + # kaptcha-open: false #是否开启登录时验证码 (true/false) + nologin-urls: /user/login,/user/appLogin,/kaptcha/base64,/config/baseConfig,/route/mockToken,/workflow/** + #flowable数据源和多数据源配置 + flowable: + datasource: + url: jdbc:mysql://localhost:3306/template_flowable?autoReconnect=true&useUnicode=true&characterEncoding=utf8&useSSL=false&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull + username: root + password: Casic203! +flowable: + checkProcessDefinitions: false #不校验process文件 +logging: + level.root: info + level.com.casic: debug + path: logs/ + file: missiles.log \ No newline at end of file diff --git a/casic-web/src/main/resources/config/application.yml b/casic-web/src/main/resources/config/application.yml new file mode 100644 index 0000000..33cce3f --- /dev/null +++ b/casic-web/src/main/resources/config/application.yml @@ -0,0 +1,26 @@ +########################################################## +################## 所有profile共有的配置 ################# +########################################################## +spring: + profiles: + active: dev + servlet: + multipart: + max-file-size: 50MB + max-request-size: 80MB +#mybatis-plus: +# sql-injector: com.baomidou.mybatisplus.mapper.LogicSqlInjector +################### mybatis-plus配置 ################### +################### guns配置 ################### +casic: + swagger-open: false #是否开启swagger (true/false) + kaptcha-open: false #是否开启登录时验证码 (true/false) + muti-datasource-open: false #是否开启多数据源(true/false) + spring-session-open: false #是否开启spring session,如果是多机环境需要开启(true/false) + session-invalidate-time: 86400 #session失效时间(只在单机环境下生效,,多机环境在SpringSessionConfig类中配置) 单位:秒 + session-validation-interval: 900 #多久检测一次失效的session(只在单机环境下生效) 单位:秒 + no-login-urls: /user/login,/kaptcha,/config/baseConfig + + config: + export-path: D:\java\boot\guns-web-1.0.0-SNAPSHOT\export\ + config-path: E:\Develop\IdeaProject\smartcity\casic-smartcity-dcms\casic-web\src\main\resources\config\ \ No newline at end of file diff --git a/casic-web/src/main/resources/logback-spring.xml b/casic-web/src/main/resources/logback-spring.xml new file mode 100644 index 0000000..c0c7ac9 --- /dev/null +++ b/casic-web/src/main/resources/logback-spring.xml @@ -0,0 +1,113 @@ + + + + + + + + + + + + + ${CONSOLE_LOG_PATTERN} + utf-8 + + + + + + + + + + + + + + + + + + + + + + ${CONSOLE_LOG_PATTERN} + utf-8 + + + + + + + + ${LOG_PATH}/missiles_error.log + + + + + + ${LOG_PATH}/error/log-error-%d{yyyy-MM-dd}.%i.log + + + + 10MB + + + + + true + + + + ${FILE_LOG_PATTERN} + utf-8 + + + + + error + ACCEPT + DENY + + + + + + + + ${LOG_PATH}/missiles_total.log + + + + + + ${LOG_PATH}/total/log-total-%d{yyyy-MM-dd}.%i.log + + + + 10MB + + + + + true + + + + ${FILE_LOG_PATTERN} + utf-8 + + + + + + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..bcae612 --- /dev/null +++ b/pom.xml @@ -0,0 +1,146 @@ + + 4.0.0 + com.casic + casic-security-cockpit + 2.0.0 + casic-security-cockpit + pom + + casic-web + casic-server + + + com.casic + casic-boot-starter-parent + 2.0.0.alpha + + + UTF-8 + UTF-8 + 1.8 + + 2.0.0 + + 2.0.0.alpha + + 2.0.0.alpha + + + + 3.2.1 + 1.7 + 3.6 + 2.6.11 + 1.0.3 + 3.4.5 + + + + + + org.springframework.boot + spring-boot-starter-web + ${boot.version} + + + + com.casic + casic-core + ${core.version} + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus-boot-starter} + + + + com.alibaba + druid + ${druid.version} + + + com.alibaba + fastjson + ${fastjson.version} + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven.compiler.plugin.version} + + + + + + + + + + + cn.smallbun.screw + screw-maven-plugin + ${screw.version} + + + + com.zaxxer + HikariCP + ${hikari.version} + + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + + root + + casic203! + + + com.mysql.jdbc.Driver + + jdbc:mysql://localhost:3306/casic_template?useSSL=false + + WORD + + true + + freemarker + + + 基础权限库 + + ${pro.version} + + 基础库文档速查 + + + + compile + + run + + + + + + + + \ No newline at end of file