Initial version backend code and change endpoint of device management module

This commit is contained in:
Bingkun Li 2026-01-19 10:44:18 +08:00
parent d4b7baef50
commit f839feb98b
673 changed files with 52769 additions and 9791 deletions

10
backend/Skyeye-sys-dev/.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,10 @@
# Default ignored files
/shelf/
/workspace.xml
# Ignored default folder with query files
/queries/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
# Editor-based HTTP Client requests
/httpRequests/

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile default="true" name="Default" enabled="true" />
<profile name="Maven default annotation processors profile" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<module name="skyeye-common-extend" />
<module name="skyeye-common-generator" />
<module name="skyeye-service-manager" />
</profile>
</annotationProcessing>
</component>
<component name="JavacSettings">
<option name="ADDITIONAL_OPTIONS_OVERRIDE">
<module name="skyeye-common-extend" options="-parameters" />
<module name="skyeye-common-generator" options="-parameters" />
<module name="skyeye-service-manager" options="-parameters" />
</option>
</component>
</project>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/skyeye-common/skyeye-common-extend/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/skyeye-common/skyeye-common-extend/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/skyeye-common/skyeye-common-generator/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/skyeye-common/skyeye-common-generator/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/skyeye-service-manager/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/skyeye-service-manager/src/main/resources" charset="UTF-8" />
</component>
</project>

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Central Repository" />
<option name="url" value="https://repo.maven.apache.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="osgeo" />
<option name="name" value="OSGeo Release Repository" />
<option name="url" value="https://repo.osgeo.org/repository/release/" />
</remote-repository>
</component>
</project>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/skyeye-common/skyeye-common-extend/pom.xml" />
<option value="$PROJECT_DIR$/skyeye-common/skyeye-common-generator/pom.xml" />
<option value="$PROJECT_DIR$/skyeye-service-manager/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="liberica-11" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/Skyeye-sys-dev.iml" filepath="$PROJECT_DIR$/.idea/Skyeye-sys-dev.iml" />
</modules>
</component>
</project>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/../.." vcs="Git" />
</component>
</project>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,4 @@
2026-01-19 10:11:53,254 [async-task-1] ERROR [com.zhangy.skyeye.jm.init.JmInitializer] JmInitializer.java:67 - 服务[PyAirline]未安装
2026-01-19 10:13:46,544 [SarImg-0] ERROR [com.zhangy.skyeye.sar.listen.SarAbstractListener] SarAbstractListener.java:114 - 线程SarImg-0被中断
2026-01-19 10:13:46,545 [SarStatus-0] ERROR [com.zhangy.skyeye.sar.listen.SarAbstractListener] SarAbstractListener.java:114 - 线程SarStatus-0被中断
2026-01-19 10:13:46,547 [SarBack-0] ERROR [com.zhangy.skyeye.sar.listen.SarAbstractListener] SarAbstractListener.java:114 - 线程SarBack-0被中断

View File

@ -0,0 +1,118 @@
2026-01-19 10:11:44,682 [background-preinit] INFO [org.hibernate.validator.internal.util.Version] Version.java:21 - HV000001: Hibernate Validator 6.2.5.Final
2026-01-19 10:11:44,736 [main] INFO [com.zhangy.skyeye.LdApplication] StartupInfoLogger.java:55 - Starting LdApplication using Java 11.0.29 on LAPTOP-4DRO6TML with PID 21976 (D:\workspace\skyeyesystem\backend\Skyeye-sys-dev\skyeye-service-manager\target\classes started by bkunlee in D:\workspace\skyeyesystem\backend\Skyeye-sys-dev)
2026-01-19 10:11:44,739 [main] INFO [com.zhangy.skyeye.LdApplication] SpringApplication.java:637 - The following 1 profile is active: "dev"
2026-01-19 10:11:47,010 [main] INFO [o.s.d.r.config.RepositoryConfigurationDelegate] RepositoryConfigurationDelegate.java:262 - Multiple Spring Data modules found, entering strict repository configuration mode
2026-01-19 10:11:47,017 [main] INFO [o.s.d.r.config.RepositoryConfigurationDelegate] RepositoryConfigurationDelegate.java:132 - Bootstrapping Spring Data Redis repositories in DEFAULT mode.
2026-01-19 10:11:47,170 [main] INFO [o.s.d.r.config.RepositoryConfigurationDelegate] RepositoryConfigurationDelegate.java:201 - Finished Spring Data repository scanning in 120 ms. Found 0 Redis repository interfaces.
2026-01-19 10:11:47,452 [main] WARN [org.mybatis.spring.mapper.ClassPathMapperScanner] Logger.java:44 - Skipping MapperFactoryBean with name 'payloadMapper' and 'com.zhangy.skyeye.device.mapper.PayloadMapper' mapperInterface. Bean already defined with the same name!
2026-01-19 10:11:47,453 [main] WARN [org.mybatis.spring.mapper.ClassPathMapperScanner] Logger.java:44 - Skipping MapperFactoryBean with name 'uavMapper' and 'com.zhangy.skyeye.device.mapper.UavMapper' mapperInterface. Bean already defined with the same name!
2026-01-19 10:11:47,453 [main] WARN [org.mybatis.spring.mapper.ClassPathMapperScanner] Logger.java:44 - Skipping MapperFactoryBean with name 'jmAirlineExecMapper' and 'com.zhangy.skyeye.jm.mapper.JmAirlineExecMapper' mapperInterface. Bean already defined with the same name!
2026-01-19 10:11:47,454 [main] WARN [org.mybatis.spring.mapper.ClassPathMapperScanner] Logger.java:44 - Skipping MapperFactoryBean with name 'jmAirlineMapper' and 'com.zhangy.skyeye.jm.mapper.JmAirlineMapper' mapperInterface. Bean already defined with the same name!
2026-01-19 10:11:47,454 [main] WARN [org.mybatis.spring.mapper.ClassPathMapperScanner] Logger.java:44 - Skipping MapperFactoryBean with name 'jmImageItemMapper' and 'com.zhangy.skyeye.jm.mapper.JmImageItemMapper' mapperInterface. Bean already defined with the same name!
2026-01-19 10:11:47,454 [main] WARN [org.mybatis.spring.mapper.ClassPathMapperScanner] Logger.java:44 - Skipping MapperFactoryBean with name 'jmImageMapper' and 'com.zhangy.skyeye.jm.mapper.JmImageMapper' mapperInterface. Bean already defined with the same name!
2026-01-19 10:11:47,455 [main] WARN [org.mybatis.spring.mapper.ClassPathMapperScanner] Logger.java:44 - Skipping MapperFactoryBean with name 'jmJobExecMapper' and 'com.zhangy.skyeye.jm.mapper.JmJobExecMapper' mapperInterface. Bean already defined with the same name!
2026-01-19 10:11:47,455 [main] WARN [org.mybatis.spring.mapper.ClassPathMapperScanner] Logger.java:44 - Skipping MapperFactoryBean with name 'jmJobMapper' and 'com.zhangy.skyeye.jm.mapper.JmJobMapper' mapperInterface. Bean already defined with the same name!
2026-01-19 10:11:47,455 [main] WARN [org.mybatis.spring.mapper.ClassPathMapperScanner] Logger.java:44 - Skipping MapperFactoryBean with name 'jmJobPayloadMapper' and 'com.zhangy.skyeye.jm.mapper.JmJobPayloadMapper' mapperInterface. Bean already defined with the same name!
2026-01-19 10:11:47,456 [main] WARN [org.mybatis.spring.mapper.ClassPathMapperScanner] Logger.java:44 - Skipping MapperFactoryBean with name 'jmJobPointMapper' and 'com.zhangy.skyeye.jm.mapper.JmJobPointMapper' mapperInterface. Bean already defined with the same name!
2026-01-19 10:11:47,456 [main] WARN [org.mybatis.spring.mapper.ClassPathMapperScanner] Logger.java:44 - Skipping MapperFactoryBean with name 'jmJobTrailMapper' and 'com.zhangy.skyeye.jm.mapper.JmJobTrailMapper' mapperInterface. Bean already defined with the same name!
2026-01-19 10:11:47,457 [main] WARN [org.mybatis.spring.mapper.ClassPathMapperScanner] Logger.java:44 - Skipping MapperFactoryBean with name 'jmJobUavMapper' and 'com.zhangy.skyeye.jm.mapper.JmJobUavMapper' mapperInterface. Bean already defined with the same name!
2026-01-19 10:11:47,458 [main] WARN [org.mybatis.spring.mapper.ClassPathMapperScanner] Logger.java:44 - Skipping MapperFactoryBean with name 'jmStatusLogMapper' and 'com.zhangy.skyeye.jm.mapper.JmStatusLogMapper' mapperInterface. Bean already defined with the same name!
2026-01-19 10:11:47,458 [main] WARN [org.mybatis.spring.mapper.ClassPathMapperScanner] Logger.java:44 - Skipping MapperFactoryBean with name 'sysDictDataMapper' and 'com.zhangy.skyeye.publics.mapper.SysDictDataMapper' mapperInterface. Bean already defined with the same name!
2026-01-19 10:11:47,458 [main] WARN [org.mybatis.spring.mapper.ClassPathMapperScanner] Logger.java:44 - Skipping MapperFactoryBean with name 'sysFileMapper' and 'com.zhangy.skyeye.publics.mapper.SysFileMapper' mapperInterface. Bean already defined with the same name!
2026-01-19 10:11:47,459 [main] WARN [org.mybatis.spring.mapper.ClassPathMapperScanner] Logger.java:44 - Skipping MapperFactoryBean with name 'sysLogMapper' and 'com.zhangy.skyeye.publics.mapper.SysLogMapper' mapperInterface. Bean already defined with the same name!
2026-01-19 10:11:47,459 [main] WARN [org.mybatis.spring.mapper.ClassPathMapperScanner] Logger.java:44 - Skipping MapperFactoryBean with name 'sysUserMapper' and 'com.zhangy.skyeye.publics.mapper.SysUserMapper' mapperInterface. Bean already defined with the same name!
2026-01-19 10:11:47,460 [main] WARN [org.mybatis.spring.mapper.ClassPathMapperScanner] Logger.java:44 - No MyBatis mapper was found in '[com.zhangy.skyeye.**.mapper]' package. Please check your configuration.
2026-01-19 10:11:47,727 [main] INFO [c.u.j.c.EnableEncryptablePropertiesBeanFactoryPostProcessor] EnableEncryptablePropertiesBeanFactoryPostProcessor.java:44 - Post-processing PropertySource instances
2026-01-19 10:11:47,729 [main] INFO [c.u.j.EncryptablePropertySourceConverter] EncryptablePropertySourceConverter.java:105 - Skipping PropertySource configurationProperties [class org.springframework.boot.context.properties.source.ConfigurationPropertySourcesPropertySource
2026-01-19 10:11:47,732 [main] INFO [c.u.j.EncryptablePropertySourceConverter] EncryptablePropertySourceConverter.java:105 - Skipping PropertySource servletConfigInitParams [class org.springframework.core.env.PropertySource$StubPropertySource
2026-01-19 10:11:47,732 [main] INFO [c.u.j.EncryptablePropertySourceConverter] EncryptablePropertySourceConverter.java:105 - Skipping PropertySource servletContextInitParams [class org.springframework.core.env.PropertySource$StubPropertySource
2026-01-19 10:11:47,735 [main] INFO [c.u.j.EncryptablePropertySourceConverter] EncryptablePropertySourceConverter.java:110 - Converting PropertySource systemProperties [org.springframework.core.env.PropertiesPropertySource] to EncryptableMapPropertySourceWrapper
2026-01-19 10:11:47,737 [main] INFO [c.u.j.EncryptablePropertySourceConverter] EncryptablePropertySourceConverter.java:110 - Converting PropertySource systemEnvironment [org.springframework.boot.env.SystemEnvironmentPropertySourceEnvironmentPostProcessor$OriginAwareSystemEnvironmentPropertySource] to EncryptableSystemEnvironmentPropertySourceWrapper
2026-01-19 10:11:47,739 [main] INFO [c.u.j.EncryptablePropertySourceConverter] EncryptablePropertySourceConverter.java:110 - Converting PropertySource random [org.springframework.boot.env.RandomValuePropertySource] to EncryptablePropertySourceWrapper
2026-01-19 10:11:47,740 [main] INFO [c.u.j.EncryptablePropertySourceConverter] EncryptablePropertySourceConverter.java:110 - Converting PropertySource Config resource 'class path resource [application-dev.yml]' via location 'optional:classpath:/' [org.springframework.boot.env.OriginTrackedMapPropertySource] to EncryptableMapPropertySourceWrapper
2026-01-19 10:11:47,740 [main] INFO [c.u.j.EncryptablePropertySourceConverter] EncryptablePropertySourceConverter.java:110 - Converting PropertySource Config resource 'class path resource [application.yml]' via location 'optional:classpath:/' [org.springframework.boot.env.OriginTrackedMapPropertySource] to EncryptableMapPropertySourceWrapper
2026-01-19 10:11:48,211 [main] INFO [c.u.j.filter.DefaultLazyPropertyFilter] DefaultLazyPropertyFilter.java:45 - Property Filter custom Bean not found with name 'encryptablePropertyFilter'. Initializing Default Property Filter
2026-01-19 10:11:48,224 [main] INFO [c.u.j.resolver.DefaultLazyPropertyResolver] DefaultLazyPropertyResolver.java:46 - Property Resolver custom Bean not found with name 'encryptablePropertyResolver'. Initializing Default Property Resolver
2026-01-19 10:11:48,227 [main] INFO [c.u.j.detector.DefaultLazyPropertyDetector] DefaultLazyPropertyDetector.java:44 - Property Detector custom Bean not found with name 'encryptablePropertyDetector'. Initializing Default Property Detector
2026-01-19 10:11:48,490 [main] INFO [o.s.boot.web.embedded.tomcat.TomcatWebServer] TomcatWebServer.java:108 - Tomcat initialized with port(s): 9116 (http)
2026-01-19 10:11:48,505 [main] INFO [org.apache.coyote.http11.Http11NioProtocol] DirectJDKLog.java:173 - Initializing ProtocolHandler ["http-nio-9116"]
2026-01-19 10:11:48,506 [main] INFO [org.apache.catalina.core.StandardService] DirectJDKLog.java:173 - Starting service [Tomcat]
2026-01-19 10:11:48,507 [main] INFO [org.apache.catalina.core.StandardEngine] DirectJDKLog.java:173 - Starting Servlet engine: [Apache Tomcat/9.0.71]
2026-01-19 10:11:48,796 [main] INFO [o.a.c.core.ContainerBase.[Tomcat].[localhost].[/]] DirectJDKLog.java:173 - Initializing Spring embedded WebApplicationContext
2026-01-19 10:11:48,797 [main] INFO [o.s.b.w.s.c.ServletWebServerApplicationContext] ServletWebServerApplicationContext.java:292 - Root WebApplicationContext: initialization completed in 3921 ms
2026-01-19 10:11:49,332 [main] INFO [c.a.d.s.b.a.DruidDataSourceAutoConfigure] DruidDataSourceAutoConfigure.java:56 - Init DruidDataSource
2026-01-19 10:11:49,423 [main] INFO [com.alibaba.druid.pool.DruidDataSource] DruidDataSource.java:994 - {dataSource-1} inited
2026-01-19 10:11:50,614 [main] INFO [c.zhangy.skyeye.sar.listen.SarAbstractUdpProcessor] SarAbstractUdpProcessor.java:60 - 雷达回图清理线程开始工作
2026-01-19 10:11:50,630 [main] INFO [com.zhangy.skyeye.sar.control.SarControlContext] SarControlContext.java:72 - 雷达传图类型1
2026-01-19 10:11:51,874 [main] INFO [org.quartz.impl.StdSchedulerFactory] StdSchedulerFactory.java:1220 - Using default implementation for ThreadExecutor
2026-01-19 10:11:51,891 [main] INFO [org.quartz.core.SchedulerSignalerImpl] SchedulerSignalerImpl.java:61 - Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl
2026-01-19 10:11:51,891 [main] INFO [org.quartz.core.QuartzScheduler] QuartzScheduler.java:229 - Quartz Scheduler v.2.3.2 created.
2026-01-19 10:11:51,898 [main] INFO [o.s.scheduling.quartz.LocalDataSourceJobStore] JobStoreSupport.java:672 - Using db table-based data access locking (synchronization).
2026-01-19 10:11:51,901 [main] INFO [o.s.scheduling.quartz.LocalDataSourceJobStore] JobStoreCMT.java:145 - JobStoreCMT initialized.
2026-01-19 10:11:51,902 [main] INFO [org.quartz.core.QuartzScheduler] QuartzScheduler.java:294 - Scheduler meta-data: Quartz Scheduler (v2.3.2) 'LD' with instanceId 'LAPTOP-4DRO6TML1768788711876'
Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally.
NOT STARTED.
Currently in standby mode.
Number of jobs executed: 0
Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 10 threads.
Using job-store 'org.springframework.scheduling.quartz.LocalDataSourceJobStore' - which supports persistence. and is clustered.
2026-01-19 10:11:51,903 [main] INFO [org.quartz.impl.StdSchedulerFactory] StdSchedulerFactory.java:1374 - Quartz scheduler 'LD' initialized from an externally provided properties instance.
2026-01-19 10:11:51,903 [main] INFO [org.quartz.impl.StdSchedulerFactory] StdSchedulerFactory.java:1378 - Quartz scheduler version: 2.3.2
2026-01-19 10:11:51,905 [main] INFO [org.quartz.core.QuartzScheduler] QuartzScheduler.java:2293 - JobFactory set to: org.springframework.scheduling.quartz.AdaptableJobFactory@5db04bd2
2026-01-19 10:11:52,026 [main] INFO [c.zhangy.skyeye.sar.listen.SarAbstractUdpProcessor] SarAbstractUdpProcessor.java:60 - 雷达回波清理线程开始工作
2026-01-19 10:11:52,038 [main] INFO [com.zhangy.skyeye.sar.listen.SarAbstractListener] SarAbstractListener.java:61 - UDP服务开始监听端口37004
2026-01-19 10:11:52,042 [main] INFO [com.zhangy.skyeye.sar.listen.SarAbstractListener] SarAbstractListener.java:61 - UDP服务开始监听端口37001
2026-01-19 10:11:52,065 [main] INFO [com.zhangy.skyeye.sar.listen.SarAbstractListener] SarAbstractListener.java:61 - UDP服务开始监听端口38004
2026-01-19 10:11:52,803 [main] INFO [org.apache.coyote.http11.Http11NioProtocol] DirectJDKLog.java:173 - Starting ProtocolHandler ["http-nio-9116"]
2026-01-19 10:11:52,815 [main] INFO [o.s.boot.web.embedded.tomcat.TomcatWebServer] TomcatWebServer.java:220 - Tomcat started on port(s): 9116 (http) with context path ''
2026-01-19 10:11:52,817 [main] INFO [c.u.j.caching.RefreshScopeRefreshedEventListener] RefreshScopeRefreshedEventListener.java:70 - Refreshing cached encryptable property sources on ServletWebServerInitializedEvent
2026-01-19 10:11:52,818 [main] INFO [c.u.j.c.CachingDelegateEncryptablePropertySource] CachingDelegateEncryptablePropertySource.java:92 - Property Source systemProperties refreshed
2026-01-19 10:11:52,818 [main] INFO [c.u.j.c.CachingDelegateEncryptablePropertySource] CachingDelegateEncryptablePropertySource.java:92 - Property Source systemEnvironment refreshed
2026-01-19 10:11:52,818 [main] INFO [c.u.j.c.CachingDelegateEncryptablePropertySource] CachingDelegateEncryptablePropertySource.java:92 - Property Source random refreshed
2026-01-19 10:11:52,819 [main] INFO [c.u.j.c.CachingDelegateEncryptablePropertySource] CachingDelegateEncryptablePropertySource.java:92 - Property Source Config resource 'class path resource [application-dev.yml]' via location 'optional:classpath:/' refreshed
2026-01-19 10:11:52,819 [main] INFO [c.u.j.c.CachingDelegateEncryptablePropertySource] CachingDelegateEncryptablePropertySource.java:92 - Property Source Config resource 'class path resource [application.yml]' via location 'optional:classpath:/' refreshed
2026-01-19 10:11:52,819 [main] INFO [c.u.j.EncryptablePropertySourceConverter] EncryptablePropertySourceConverter.java:105 - Skipping PropertySource configurationProperties [class org.springframework.boot.context.properties.source.ConfigurationPropertySourcesPropertySource
2026-01-19 10:11:52,819 [main] INFO [c.u.j.EncryptablePropertySourceConverter] EncryptablePropertySourceConverter.java:105 - Skipping PropertySource servletConfigInitParams [class org.springframework.core.env.PropertySource$StubPropertySource
2026-01-19 10:11:52,820 [main] INFO [c.u.j.EncryptablePropertySourceConverter] EncryptablePropertySourceConverter.java:110 - Converting PropertySource servletContextInitParams [org.springframework.web.context.support.ServletContextPropertySource] to EncryptableEnumerablePropertySourceWrapper
2026-01-19 10:11:52,821 [main] INFO [org.springframework.web.SimpLogging] CompositeLog.java:117 - Starting...
2026-01-19 10:11:52,821 [main] INFO [org.springframework.web.SimpLogging] CompositeLog.java:117 - BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@406808eb]]
2026-01-19 10:11:52,822 [main] INFO [org.springframework.web.SimpLogging] CompositeLog.java:117 - Started.
2026-01-19 10:11:52,823 [main] INFO [o.s.scheduling.quartz.SchedulerFactoryBean] SchedulerFactoryBean.java:734 - Will start Quartz Scheduler [LD] in 3 seconds
2026-01-19 10:11:52,855 [main] INFO [com.zhangy.skyeye.LdApplication] StartupInfoLogger.java:61 - Started LdApplication in 9.544 seconds (JVM running for 12.763)
2026-01-19 10:11:53,203 [async-task-1] WARN [com.zhangy.skyeye.jm.init.JmInitializer] JmInitializer.java:59 - 航线规划服务不可用,开始重启……
2026-01-19 10:11:53,254 [async-task-1] ERROR [com.zhangy.skyeye.jm.init.JmInitializer] JmInitializer.java:67 - 服务[PyAirline]未安装
2026-01-19 10:11:55,832 [Quartz Scheduler [LD]] INFO [o.s.scheduling.quartz.SchedulerFactoryBean] SchedulerFactoryBean.java:750 - Starting Quartz Scheduler now, after delay of 3 seconds
2026-01-19 10:11:55,900 [Quartz Scheduler [LD]] INFO [o.s.scheduling.quartz.LocalDataSourceJobStore] JobStoreSupport.java:3644 - ClusterManager: detected 1 failed or restarted instances.
2026-01-19 10:11:55,900 [Quartz Scheduler [LD]] INFO [o.s.scheduling.quartz.LocalDataSourceJobStore] JobStoreSupport.java:3503 - ClusterManager: Scanning for instance "LAPTOP-4DRO6TML1768746996787"'s failed in-progress jobs.
2026-01-19 10:11:55,912 [Quartz Scheduler [LD]] INFO [org.quartz.core.QuartzScheduler] QuartzScheduler.java:547 - Scheduler LD_$_LAPTOP-4DRO6TML1768788711876 started.
2026-01-19 10:12:19,051 [http-nio-9116-exec-3] INFO [o.a.c.core.ContainerBase.[Tomcat].[localhost].[/]] DirectJDKLog.java:173 - Initializing Spring DispatcherServlet 'dispatcherServlet'
2026-01-19 10:12:19,051 [http-nio-9116-exec-3] INFO [org.springframework.web.servlet.DispatcherServlet] FrameworkServlet.java:525 - Initializing Servlet 'dispatcherServlet'
2026-01-19 10:12:19,057 [http-nio-9116-exec-3] INFO [org.springframework.web.servlet.DispatcherServlet] FrameworkServlet.java:547 - Completed initialization in 4 ms
2026-01-19 10:12:36,187 [MessageBroker-8] WARN [com.zhangy.skyeye.jm.task.JmTaskScheduler] JmTaskScheduler.java:124 - 连接雷达[192.168.8.105]失败:控制指令[连接]发送失败,雷达[192.168.8.105]无应答,请重试
2026-01-19 10:12:47,704 [MessageBroker-8] WARN [com.zhangy.skyeye.jm.task.JmTaskScheduler] JmTaskScheduler.java:124 - 连接雷达[192.168.8.105]失败:控制指令[连接]发送失败,雷达[192.168.8.105]无应答,请重试
2026-01-19 10:12:52,222 [MessageBroker-7] INFO [o.s.web.socket.config.WebSocketMessageBrokerStats] WebSocketMessageBrokerStats.java:128 - WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 8, active threads = 1, queued tasks = 2, completed tasks = 66]
2026-01-19 10:12:57,167 [MessageBroker-3] WARN [com.zhangy.skyeye.jm.task.JmTaskScheduler] JmTaskScheduler.java:124 - 连接雷达[192.168.8.105]失败:控制指令[连接]发送失败,雷达[192.168.8.105]无应答,请重试
2026-01-19 10:13:06,118 [MessageBroker-8] WARN [com.zhangy.skyeye.jm.task.JmTaskScheduler] JmTaskScheduler.java:124 - 连接雷达[192.168.8.105]失败:控制指令[连接]发送失败,雷达[192.168.8.105]无应答,请重试
2026-01-19 10:13:17,668 [MessageBroker-7] WARN [com.zhangy.skyeye.jm.task.JmTaskScheduler] JmTaskScheduler.java:124 - 连接雷达[192.168.8.105]失败:控制指令[连接]发送失败,雷达[192.168.8.105]无应答,请重试
2026-01-19 10:13:26,086 [MessageBroker-3] WARN [com.zhangy.skyeye.jm.task.JmTaskScheduler] JmTaskScheduler.java:124 - 连接雷达[192.168.8.105]失败:控制指令[连接]发送失败,雷达[192.168.8.105]无应答,请重试
2026-01-19 10:13:35,970 [MessageBroker-1] WARN [com.zhangy.skyeye.jm.task.JmTaskScheduler] JmTaskScheduler.java:124 - 连接雷达[192.168.8.105]失败:控制指令[连接]发送失败,雷达[192.168.8.105]无应答,请重试
2026-01-19 10:13:45,945 [SpringApplicationShutdownHook] INFO [org.springframework.web.SimpLogging] CompositeLog.java:117 - Stopping...
2026-01-19 10:13:45,945 [SpringApplicationShutdownHook] INFO [org.springframework.web.SimpLogging] CompositeLog.java:117 - BrokerAvailabilityEvent[available=false, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@406808eb]]
2026-01-19 10:13:45,946 [SpringApplicationShutdownHook] INFO [org.springframework.web.SimpLogging] CompositeLog.java:117 - Stopped.
2026-01-19 10:13:45,946 [SpringApplicationShutdownHook] INFO [org.quartz.core.QuartzScheduler] QuartzScheduler.java:585 - Scheduler LD_$_LAPTOP-4DRO6TML1768788711876 paused.
2026-01-19 10:13:46,039 [MessageBroker-3] WARN [com.zhangy.skyeye.jm.task.JmTaskScheduler] JmTaskScheduler.java:124 - 连接雷达[192.168.8.105]失败:控制指令[连接]发送失败,雷达[192.168.8.105]无应答,请重试
2026-01-19 10:13:46,544 [SpringApplicationShutdownHook] INFO [com.zhangy.skyeye.sar.listen.SarAbstractListener] SarAbstractListener.java:130 - UDP-38004服务停止
2026-01-19 10:13:46,544 [SarImg-0] ERROR [com.zhangy.skyeye.sar.listen.SarAbstractListener] SarAbstractListener.java:114 - 线程SarImg-0被中断
2026-01-19 10:13:46,545 [SarStatus-0] ERROR [com.zhangy.skyeye.sar.listen.SarAbstractListener] SarAbstractListener.java:114 - 线程SarStatus-0被中断
2026-01-19 10:13:46,545 [SpringApplicationShutdownHook] INFO [com.zhangy.skyeye.sar.listen.SarAbstractListener] SarAbstractListener.java:130 - UDP-37001服务停止
2026-01-19 10:13:46,547 [SarBack-0] ERROR [com.zhangy.skyeye.sar.listen.SarAbstractListener] SarAbstractListener.java:114 - 线程SarBack-0被中断
2026-01-19 10:13:46,547 [SpringApplicationShutdownHook] INFO [com.zhangy.skyeye.sar.listen.SarAbstractListener] SarAbstractListener.java:130 - UDP-37004服务停止
2026-01-19 10:13:46,548 [SpringApplicationShutdownHook] INFO [c.zhangy.skyeye.sar.listen.SarAbstractUdpProcessor] SarAbstractUdpProcessor.java:69 - 雷达回波清理线程停止
2026-01-19 10:13:46,550 [SpringApplicationShutdownHook] INFO [o.s.scheduling.quartz.SchedulerFactoryBean] SchedulerFactoryBean.java:847 - Shutting down Quartz Scheduler
2026-01-19 10:13:46,550 [SpringApplicationShutdownHook] INFO [org.quartz.core.QuartzScheduler] QuartzScheduler.java:666 - Scheduler LD_$_LAPTOP-4DRO6TML1768788711876 shutting down.
2026-01-19 10:13:46,550 [SpringApplicationShutdownHook] INFO [org.quartz.core.QuartzScheduler] QuartzScheduler.java:585 - Scheduler LD_$_LAPTOP-4DRO6TML1768788711876 paused.
2026-01-19 10:13:46,551 [SpringApplicationShutdownHook] INFO [org.quartz.core.QuartzScheduler] QuartzScheduler.java:740 - Scheduler LD_$_LAPTOP-4DRO6TML1768788711876 shutdown complete.
2026-01-19 10:13:46,553 [SpringApplicationShutdownHook] INFO [c.zhangy.skyeye.sar.listen.SarAbstractUdpProcessor] SarAbstractUdpProcessor.java:69 - 雷达回图清理线程停止
2026-01-19 10:13:46,556 [SpringApplicationShutdownHook] INFO [com.alibaba.druid.pool.DruidDataSource] DruidDataSource.java:2029 - {dataSource-1} closing ...
2026-01-19 10:13:46,566 [SpringApplicationShutdownHook] INFO [com.alibaba.druid.pool.DruidDataSource] DruidDataSource.java:2101 - {dataSource-1} closed

View File

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>skyeye</artifactId>
<groupId>com.zhangy</groupId>
<version>1.0.0.RELEASE</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>skyeye-common-extend</artifactId>
<description>扩展工具包</description>
<dependencies>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.1</version>
</dependency>
<!-- 参数校验 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- spring mvc -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<encoding>UTF-8</encoding>
<nonFilteredFileExtensions>
<!-- 防止打包时dll文件大小被改变-->
<nonFilteredFileExtension>so</nonFilteredFileExtension>
</nonFilteredFileExtensions>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,14 @@
package com.zhangy.skyeye.common.extend.anno;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 免Token认证注解
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface IgnoreAuth {
}

View File

@ -0,0 +1,16 @@
package com.zhangy.skyeye.common.extend.anno;
import java.lang.annotation.*;
/**
* 操作日志
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface OperationLog {
String value() default "";
int type() default 0;
}

View File

@ -0,0 +1,26 @@
package com.zhangy.skyeye.common.extend.dto;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
/**
* 分页参数
*/
public class PageDTO extends Page {
/**
* 当前页
* @param pageCurrent
*/
public void setPageCurrent(Integer pageCurrent) {
this.current = pageCurrent;
}
/**
* 每页数量
* @param pageSize
*/
public void setPageSize(Integer pageSize) {
this.size = pageSize;
}
}

View File

@ -0,0 +1,7 @@
package com.zhangy.skyeye.common.extend.dto;
/**
* 查询参数
*/
public class QueryDTO {
}

View File

@ -0,0 +1,10 @@
package com.zhangy.skyeye.common.extend.enums;
import java.util.Objects;
import java.util.function.Supplier;
public interface CodeEnum<T> {
T getCode();
}

View File

@ -0,0 +1,123 @@
package com.zhangy.skyeye.common.extend.enums;
import java.util.Arrays;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Supplier;
/**
* 枚举类工具
*/
public class EnumUtil {
/**
* 根据code解析枚举如果找不到则返回null
*
* @param enumClass 枚举类
* @param codeExtractor 取值方法
* @param code
* @param <E> 枚举类型
* @return
*/
public static <E extends Enum<E>> E parse(Class<E> enumClass,
Function<E, ?> codeExtractor,
Object code) {
for (E e : enumClass.getEnumConstants()) {
if (Objects.equals(codeExtractor.apply(e), code)) {
return e;
}
}
return null;
}
/**
* 根据code解析枚举如果找不到则抛异常
*
* @param enumClass 枚举类
* @param codeExtractor 取值方法
* @param code
* @param errorMessage 解析失败时的异常提示
* @param <E> 枚举类型
* @return
*/
public static <E extends Enum<E>> E parseEx(Class<E> enumClass,
Function<E, ?> codeExtractor,
Object code,
Supplier<String> errorMessage) {
E result = parse(enumClass, codeExtractor, code);
if (result == null) {
throw new IllegalArgumentException(errorMessage.get());
}
return result;
}
/**
* 根据code解析枚举如果找不到则返回null
*
* @param enumClass 枚举类
* @param code 枚举值
* @param <E> 枚举类型
* @param <T> 值类型
* @return
*/
public static <E extends Enum<E> & CodeEnum<T>, T> E parse(Class<E> enumClass, T code) {
if (code instanceof String) {
return parseString(enumClass, (String) code);
}
for (E e : enumClass.getEnumConstants()) {
if (Objects.equals(e.getCode(), code)) {
return e;
}
}
return null;
}
/**
* 根据code解析枚举如果找不到则返回null
* @param enumClass 枚举类
* @param code 字符串
* @param <E> 枚举类型
* @param <T> 字符串类型
* @return
*/
private static <E extends Enum<E> & CodeEnum<T>, T> E parseString(Class<E> enumClass, String code) {
for (E e : enumClass.getEnumConstants()) {
if (((String)e.getCode()).equalsIgnoreCase(code)) {
return e;
}
}
return null;
}
/**
* 根据code解析枚举如果找不到则抛出默认的异常
*
* @param enumClass 枚举类
* @param code 枚举值
* @param errorMessageSupplier 解析失败时返回的提示
* @param <E> 枚举类型
* @param <T> 值类型
* @return
*/
public static <E extends Enum<E> & CodeEnum<T>, T> E parseEx(Class<E> enumClass, T code, Supplier<String> errorMessageSupplier) {
E result = parse(enumClass, code);
if (result == null) {
throw new IllegalArgumentException(errorMessageSupplier.get());
}
return result;
}
/**
* 根据code解析枚举如果找不到则抛出默认的异常
*
* @param enumClass 枚举类
* @param code 枚举值
* @param <E> 枚举类型
* @param <T> 值类型
* @return
*/
public static <E extends Enum<E> & CodeEnum<T>, T> E parseEx(Class<E> enumClass, T code) {
return parseEx(enumClass, code, () -> "无法解析的枚举值:" + code);
}
}

View File

@ -0,0 +1,5 @@
package com.zhangy.skyeye.common.extend.enums;
public interface StringCodeEnum {
String getCode();
}

View File

@ -0,0 +1,18 @@
package com.zhangy.skyeye.common.extend.exception;
import lombok.NoArgsConstructor;
/**
* 认证异常
*/
@NoArgsConstructor
public class AuthException extends RuntimeException {
public AuthException(String message) {
super(message);
}
public AuthException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@ -0,0 +1,44 @@
package com.zhangy.skyeye.common.extend.exception;
import lombok.Getter;
import lombok.NoArgsConstructor;
/**
* 服务异常
*/
@Getter
@NoArgsConstructor
public class ServiceException extends RuntimeException {
// 级别 默认0打印异常栈1 - 打印error异常信息 2 打印warn异常信息3 不输出异常信息
private int level;
public ServiceException(String message) {
super(message);
}
public ServiceException(String message, int level) {
super(message);
this.level = level;
}
public static ServiceException errorLog(String message) {
return new ServiceException(message, 1);
}
public static ServiceException errorLog(String message, Throwable cause) {
return new ServiceException(message, 0);
}
public static ServiceException warnLog(String message) {
return new ServiceException(message, 2);
}
public static ServiceException noLog(String message) {
return new ServiceException(message, 3);
}
public ServiceException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@ -0,0 +1,92 @@
package com.zhangy.skyeye.common.extend.util;
import com.zhangy.skyeye.common.extend.exception.ServiceException;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import java.io.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
/**
* Bean工具
*/
public class BeanUtil {
/** 校验器 */
private static volatile Validator validator;
private static Validator getValidator() {
if (validator == null) {
synchronized (Validator.class) {
if (validator == null) {
ValidatorFactory vf = Validation.buildDefaultValidatorFactory();
validator = vf.getValidator();
}
}
}
return validator;
}
/**
* bean值校验校验集合所有数据并返回全部失败信息
*
* @param list
* @param <T>
* @return key - 元素在集合的下标value - 校验失败信息
*/
public static <T> Map<Integer, String> validation(List<T> list) {
Map<Integer, String> map = new HashMap<>();
Validator validator = getValidator();
for (int i = 0; i < list.size(); i++) {
Set<ConstraintViolation<T>> checkSet = validator.validate(list.get(i));
if (ObjectUtil.isNotEmpty(checkSet)) {
throw ServiceException.noLog(checkSet.stream().map(ConstraintViolation::getMessage).collect(Collectors.joining(",")));
}
}
return map;
}
/**
* Bean值校验失败抛异常
* @param e
* @param <T>
*/
public static <T> void validationEx(T e) {
Set<ConstraintViolation<T>> checkSet = getValidator().validate(e);
if (ObjectUtil.isNotEmpty(checkSet)) {
String msg = checkSet.stream().map(ConstraintViolation::getMessage).collect(Collectors.joining(","));
throw ServiceException.noLog(msg);
}
}
/**
* 深克隆
* @param obj
* @param <T> 对象需要实现Serializable否则NotSerializableException
* 对象的父类也要实现Serializable否则不报错但父类属性值为null
* transient变量static变量 无法序列化
* @return
*/
public static <T> T deepClone(T obj) {
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos)) {
oos.writeObject(obj);
try (ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);){
return (T) ois.readObject();
}
} catch (NotSerializableException e) {
throw new ServiceException("深克隆错误对象没有实现Serializable无法序列化");
} catch (Exception e) {
e.printStackTrace();
throw new ServiceException("深克隆错误", e);
}
}
}

View File

@ -0,0 +1,51 @@
package com.zhangy.skyeye.common.extend.util;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateUtil {
public static SimpleDateFormat DF_1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public static SimpleDateFormat DF_2 = new SimpleDateFormat("yyyyMMddHHmmss");
/**
* int Date
*
* @param yearMonthDay 年月日 20200304
* @param hourMinSec 时分秒如105959
* @return
*/
public static Date toDate(int yearMonthDay, int hourMinSec) throws ParseException {
try {
return DF_2.parse(String.valueOf(yearMonthDay) + (hourMinSec == 0 ? "000000" : String.valueOf(hourMinSec)));
} catch (ParseException ex) {
throw new ParseException("解析时间出错[年月日 " + yearMonthDay + ",时分秒 " + hourMinSec + "] " + ex.getMessage(), ex.getErrorOffset());
}
}
/**
* 获取当前时间字符串
* @return 格式 yyyy-MM-dd HH:mm:ss
*/
public static String getTimeStr() {
return DF_1.format(new Date());
}
/**
* 获取指定时间的字符串
* @param time Date或者long类型的时间
* @return
*/
public static String getTimeStr(Object time) {
return DF_1.format(time);
}
/**
* 获取指定时间的字符串
*/
public static String getTimeStr(SimpleDateFormat df) {
return df.format(new Date());
}
}

View File

@ -0,0 +1,189 @@
package com.zhangy.skyeye.common.extend.util;
import com.zhangy.skyeye.common.extend.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
/**
* 文件工具
*/
@Slf4j
public class FileUtil {
/**
* 复制文件如果目标文件已存在则会抛异常
* @param src
* @param dest
*/
public static void copy(File src, File dest) {
if (dest.exists()) {
throw new ServiceException("复制文件失败,目标[" + dest.getPath() + "]已存在");
}
copy(src, dest, false);
}
/**
* 将数据保存为文件
*
* @param data 数据
* @param outputPath 输出路径
* @param r 是否覆盖已有文件
* @return
*/
public static boolean write(byte[] data, String outputPath, boolean r) {
File dest = new File(outputPath);
if (dest.exists() && !r) {
return false;
}
createDir(dest, r);
try (FileOutputStream fos = new FileOutputStream(dest)) {
fos.write(data);
fos.flush();
} catch (IOException ex) {
throw new ServiceException("写入文件[" + dest.getName() + "]失败:" + ex.getMessage());
}
return true;
}
/**
* 将数据保存为文件追加写入
*
* @param data 数据
* @param outputPath 输出路径
* @return
*/
public static boolean writeAppend(byte[] data, String outputPath) {
File dest = new File(outputPath);
createDir(dest, false);
try (FileOutputStream fos = new FileOutputStream(dest, true)) {
fos.write(data);
fos.flush();
} catch (IOException ex) {
throw new ServiceException("写入文件[" + dest.getName() + "]失败:" + ex.getMessage());
}
return true;
}
/**
* 复制文件
* @param src 来源文件
* @param dest 目标文件
* @param deleteDestIfExists 如果目标文件已存在是否先删除
*/
public static void copy(File src, File dest, boolean deleteDestIfExists) {
createDir(dest, deleteDestIfExists);
try {
Files.copy(src.toPath(), dest.toPath(), StandardCopyOption.REPLACE_EXISTING);
} catch (IOException ex) {
throw new ServiceException("文件" + src.getName() + "复制失败:" + ex.getMessage());
}
}
/**
* 删除文件或级联删除目录若文件不存在则跳过
*
* @param array 文件绝对路径
*/
public static void delete(String... array) {
for (String path : array) {
deleteOne(new File(path));
}
}
/**
* 删除文件或级联删除目录若文件不存在则跳过
*
* @param array
*/
public static void delete(File... array) {
for (File file : array) {
deleteOne(file);
}
}
/**
* 删除文件或目录递归删除目录下所有内容
* @param file 要删除的文件或目录对象
* @return 是否删除成功
*/
private static boolean deleteOne(File file) {
if (file == null || !file.exists()) {
return false;
}
// 如果是目录先递归删除其内容
if (file.isDirectory()) {
File[] contents = file.listFiles();
if (contents != null) {
for (File f : contents) {
deleteOne(f);
}
}
}
// 删除文件或空目录
try {
return file.delete();
} catch (SecurityException ex) {
log.warn("删除文件[" + file.getPath() + "]失败:" + ex.getMessage());
return false;
}
}
/**
* 获取文件扩展名
*/
public static String getExtName(String fileName) {
int index = fileName.lastIndexOf(".");
if (index == -1 || index == fileName.length() - 1) {
return "";
}
return fileName.substring(index + 1);
}
/**
* 根据文件创建其路径中的目录用于生成文件前确保可以生成文件
* @param filePath
* @param containsLastDir 路径中最后一级是否为目录且要生成
*/
public static void createDir(String filePath, boolean containsLastDir) {
if (containsLastDir) {
new File(filePath).mkdirs(); // 目录
} else {
createDir(new File(filePath)); // 文件
}
}
public static void createDir(String filePath) {
createDir(new File(filePath), false);
}
/**
* 根据文件创建其路径中的目录用于生成文件前确保可以生成文件
* @param file
*/
public static void createDir(File file) {
createDir(file, false);
}
/**
* 根据文件创建其路径中的目录用于生成文件前确保可以生成文件
* @param file 文件
* @param deleteFileIfExists 如果文件已存在是否删除
*/
public static void createDir(File file, boolean deleteFileIfExists) {
if (deleteFileIfExists && file.exists()) {
deleteOne(file);
return;
}
File dir = file.getParentFile();
if (dir != null) {
dir.mkdirs();
}
}
}

View File

@ -0,0 +1,160 @@
package com.zhangy.skyeye.common.extend.util;
import com.zhangy.skyeye.common.extend.exception.ServiceException;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
/**
* Http请求
*/
@Slf4j
public class HttpUtil {
// 共享的 HttpClient 实例
private static final HttpClient HTTP_CLIENT;
static {
// 在静态块中初始化 HttpClient可统一配置参数
HTTP_CLIENT = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_2) // 使用 HTTP/2支持回退到 HTTP/1.1
.connectTimeout(Duration.ofMillis(3000)) // 连接超时 3
// 默认 keepalive 超时时间为 1200 20分钟可通过系统属性修改
// -Djdk.httpclient.keepalive.timeout=600 或运行时设置 System.setProperty("jdk.httpclient.keepalive.timeout", "600")
.build();
}
/**
* 读取超时毫秒- 在发送请求时通过 HttpRequest.Builder 设置
*/
public static int readTimeout = 60000;
public static HttpResponse<String> get(String url) throws IOException {
return get(url, null);
}
/**
* 同步 GET 请求
* @param url 请求地址
* @param headers 请求头
* @return HttpResponse 响应对象
*/
public static HttpResponse<String> get(String url, Map<String, String> headers) throws IOException {
try {
HttpRequest request = buildRequest(url, "GET", headers, null);
return HTTP_CLIENT.send(request, HttpResponse.BodyHandlers.ofString());
} catch (InterruptedException ex) {
throw new IOException("GET请求[" + url + "]失败,线程被中断!", ex);
}
}
/**
* 异步 GET 请求
* @param url 请求地址
* @param headers 请求头
* @return CompletableFuture<HttpResponse<String>> 异步响应
*/
public static CompletableFuture<HttpResponse<String>> getAsync(String url, Map<String, String> headers) {
HttpRequest request = buildRequest(url, "GET", headers, null);
return HTTP_CLIENT.sendAsync(request, HttpResponse.BodyHandlers.ofString());
}
/**
* 同步 POST 请求默认 JSON
* @param url 请求地址
* @param headers 请求头
* @param body 请求体对象将被转换为 JSON 字符串
* @return HttpResponse 响应对象
* @throws IOException
*/
public static HttpResponse<String> post(String url, Map<String, String> headers, Object body) throws IOException {
if (headers == null) {
headers = new java.util.HashMap<>();
}
if (!headers.containsKey("Content-Type") && !headers.containsKey("content-type")) {
headers.put("Content-Type", "application/json");
}
try {
HttpRequest request = buildRequest(url, "POST", headers, body);
return HTTP_CLIENT.send(request, HttpResponse.BodyHandlers.ofString());
} catch (InterruptedException ex) {
throw new IOException("POST请求[" + url + "]失败,线程被中断!", ex);
}
}
/**
* 异步 POST 请求
* @param url 请求地址
* @param headers 请求头
* @param body 请求体对象
* @return CompletableFuture<HttpResponse<String>> 异步响应
*/
public static CompletableFuture<HttpResponse<String>> postAsync(String url, Map<String, String> headers, Object body) {
if (headers != null) {
if (!headers.containsKey("Content-Type") && !headers.containsKey("content-type")) {
headers.put("Content-Type", "application/json");
}
}
HttpRequest request = buildRequest(url, "POST", headers, body);
return HTTP_CLIENT.sendAsync(request, HttpResponse.BodyHandlers.ofString());
}
/**
* 构建 HttpRequest
* @param url 请求地址
* @param method 请求方法
* @param headers 请求头
* @param body 请求体
* @return 构建好的 HttpRequest
*/
private static HttpRequest buildRequest(String url, String method, Map<String, String> headers, Object body) {
HttpRequest.Builder builder = HttpRequest.newBuilder()
.uri(URI.create(url))
.timeout(Duration.ofMillis(readTimeout)); // 设置读取超时
// 设置请求头
if (headers != null) {
for (Map.Entry<String, String> entry : headers.entrySet()) {
builder.header(entry.getKey(), entry.getValue());
}
}
// 设置请求方法和请求体
String bodyStr = (body != null) ? JsonUtil.toString(body) : "";
switch (method.toUpperCase()) {
case "GET":
builder.GET();
break;
case "POST":
builder.POST(HttpRequest.BodyPublishers.ofString(bodyStr, java.nio.charset.StandardCharsets.UTF_8));
break;
case "PUT":
builder.PUT(HttpRequest.BodyPublishers.ofString(bodyStr, java.nio.charset.StandardCharsets.UTF_8));
break;
case "DELETE":
if (body == null) {
builder.DELETE();
} else {
builder.method("DELETE", HttpRequest.BodyPublishers.ofString(bodyStr, java.nio.charset.StandardCharsets.UTF_8));
}
break;
default:
throw new IllegalArgumentException("不支持的HTTP方式: " + method);
}
return builder.build();
}
}

View File

@ -0,0 +1,100 @@
package com.zhangy.skyeye.common.extend.util;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zhangy.skyeye.common.extend.exception.ServiceException;
import java.util.List;
public class JsonUtil {
public static ObjectMapper objectMapper = new ObjectMapper();
static {
// 默认情况下如果JSON中有但Java类中没有的属性会抛出异常配置忽略
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// 设置全局日期格式
objectMapper.setDateFormat(DateUtil.DF_1);
}
/**
* json 字符串转对象
*
* @param content
* @param clazz
* @param <T>
* @return
*/
public static <T> T parse(String content, Class<T> clazz) {
try {
return parseEx(content, clazz);
} catch (JsonProcessingException e) {
throw new ServiceException("解析json字符串错误" + content + " " + e.getMessage());
}
}
/**
* json 字符串转对象
*
* @param content
* @param valueTypeRef
* @param <T>
* @return
*/
public static <T> T parse(String content, TypeReference<T> valueTypeRef) {
try {
return objectMapper.readValue(content, valueTypeRef);
} catch (JsonProcessingException e) {
throw new ServiceException("解析json字符串错误" + content + " " + e.getMessage());
}
}
/**
* json 字符串转对象声明异常
*
* @param content
* @param clazz
* @param <T>
* @return
*/
public static <T> T parseEx(String content, Class<T> clazz) throws JsonProcessingException {
return objectMapper.readValue(content, clazz);
}
/**
* 对象转 json 字符串
*
* @param o
* @return
*/
public static String toString(Object o) {
if (o == null) {
return null;
}
try {
return objectMapper.writeValueAsString(o);
} catch (JsonProcessingException e) {
throw new ServiceException("转换json字符串错误" + " " + e.getMessage());
}
}
/**
* json 字符串转 List
*
* @param jsonStr
* @param clazz 集合中的元素类型
* @param <T>
* @return
*/
public static <T> List<T> parseList(String jsonStr, Class<T> clazz) {
try {
JavaType javaType = objectMapper.getTypeFactory()
.constructCollectionType(List.class, clazz);
return objectMapper.readValue(jsonStr, javaType);
} catch (JsonProcessingException e) {
throw new ServiceException("解析json字符串错误" + jsonStr + " " + e.getMessage());
}
}
}

View File

@ -0,0 +1,161 @@
package com.zhangy.skyeye.common.extend.util;
import java.util.*;
public class MapUtil {
/**
* 将值放入嵌套集合
*
* @param map
* @param key1
* @param key2
* @param value
* @param <T>
*/
public static <T> void putMapList(Map<String, Map<String, List<T>>> map, String key1, String key2, T value) {
Map<String, List<T>> map2;
if (map.containsKey(key1)) {
map2 = map.get(key1);
List<T> list;
if (map2.containsKey(key2)) {
list = map2.get(key2);
} else {
list = new ArrayList<>();
}
list.add(value);
} else {
map2 = new HashMap<>();
map.put(key1, map2);
List<T> list = new ArrayList<>();
list.add(value);
map2.put(key2, list);
}
}
/**
* 将值放入嵌套集合
*
* @param map
* @param key1
* @param key2
* @param value
* @param <T>
*/
public static <T> void putMapSet(Map<String, Map<String, Set<T>>> map, String key1, String key2, T value) {
Map<String, Set<T>> map2;
if (map.containsKey(key1)) {
map2 = map.get(key1);
Set<T> set;
if (map2.containsKey(key2)) {
set = map2.get(key2);
} else {
set = new HashSet<>();
}
set.add(value);
} else {
map2 = new HashMap<>();
map.put(key1, map2);
Set<T> set = new HashSet<>();
set.add(value);
map2.put(key2, set);
}
}
/**
* 将值放入嵌套集合中并与原值加和
*
* @param map
* @param key
* @param value
*/
public static void sumInt(Map<String, Integer> map, String key, int value) {
if (map.containsKey(key)) {
int local = map.get(key);
map.put(key, local + value);
} else {
map.put(key, value);
}
}
/**
* 将值放入嵌套集合中并与原值加和
*
* @param map
* @param key1
* @param key2
* @param value
*/
public static void sumInt(Map<String, Map<String, Integer>> map, String key1, String key2, int value) {
Map<String, Integer> map2;
if (map.containsKey(key1)) {
map2 = map.get(key1);
int local;
if (map2.containsKey(key2)) {
local = map2.get(key2);
} else {
local = 0;
}
map2.put(key2, local + value);
} else {
map2 = new HashMap<>();
map.put(key1, map2);
map2.put(key2, value);
}
}
/**
* 将值放入嵌套集合
*
* @param map
* @param key
* @param value
* @param <T>
*/
public static <T> void putList(Map<String, List<T>> map, String key, T value) {
List<T> list;
if (map.containsKey(key)) {
list = map.get(key);
} else {
list = new ArrayList<>();
map.put(key, list);
}
list.add(value);
}
/**
* 将值放入集合
*
* @param map
* @param key
* @param value
* @param <T>
*/
public static <T> void putSet(Map<String, Set<T>> map, String key, T value) {
Set<T> collection;
if (map.containsKey(key)) {
collection = map.get(key);
} else {
collection = new HashSet<>();
map.put(key, collection);
}
collection.add(value);
}
/**
* 判断集合是否包含值
*
* @param map
* @param key
* @param value
* @param <T>
* @return
*/
public static <T> boolean containsSetValue(Map<String, Set<T>> map, String key, T value) {
if (!map.containsKey(key)) {
return false;
}
Set<T> set = map.get(key);
return set != null && set.contains(value);
}
}

View File

@ -0,0 +1,37 @@
package com.zhangy.skyeye.common.extend.util;
public class MathUtil {
/**
* 取最小值
*/
public static <T extends Number & Comparable<T>> T min(T... numbers) {
if (numbers == null || numbers.length == 0) {
throw new IllegalArgumentException("至少需要传入一个数字");
}
T min = numbers[0];
for (T num : numbers) {
if (num != null && num.compareTo(min) < 0) {
min = num;
}
}
return min;
}
/**
* 取最大值
*/
public static <T extends Number & Comparable<T>> T max(T... numbers) {
if (numbers == null || numbers.length == 0) {
throw new IllegalArgumentException("至少需要传入一个数字");
}
T max = numbers[0];
for (T num : numbers) {
if (num != null && num.compareTo(max) > 0) {
max = num;
}
}
return max;
}
}

View File

@ -0,0 +1,85 @@
package com.zhangy.skyeye.common.extend.util;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
public class NumberUtil {
/**
* 判断包装类型是否非空且有效
*
* @param val
* @return
*/
public static boolean isValid(Double... val) {
if (val == null || val.length == 0) {
return false;
}
for (Double v : val) {
if (v == null || !Double.isFinite(v)){
return false;
}
}
return true;
}
/**
* byte[] 转十六进制
* @param bytes
* @param start 起始索引
* @param end 结束索引
* @param isBigEndian true 大端序false 小端序
* @return
*/
public static String byteToHex(byte[] bytes, int start, int end, boolean isBigEndian) {
StringBuilder builder = new StringBuilder();
if (bytes == null) {
throw new IllegalArgumentException("数组不能为空");
}
if (start < 0 || start > end) {
throw new IllegalArgumentException("无效的索引范围[" + start + "," + end + "]");
}
if (isBigEndian) {
for (int i = start; i <= end && i < bytes.length; i++) {
builder.append(String.format("%02X", bytes[i]));
}
} else {
for (int i = end; i >= start; i--) {
builder.append(String.format("%02X", bytes[i]));
}
}
return builder.toString();
}
/**
* byte[] int
* @param bytes
* @param isBigEndian true 大端序false 小端序
* @return
*/
public static int byteToInt(byte[] bytes, boolean isBigEndian) {
// 大端序高位在前
if (isBigEndian) {
return ((bytes[0] & 0xFF) << 24) |
((bytes[1] & 0xFF) << 16) |
((bytes[2] & 0xFF) << 8) |
(bytes[3] & 0xFF);
} else {
// 小端序低位在前
return (bytes[3] & 0xFF) << 24 |
(bytes[2] & 0xFF) << 16 |
(bytes[1] & 0xFF) << 8 |
(bytes[0] & 0xFF);
}
}
/**
* 返回有效数值否则返回null
*
* @param v
* @return
*/
public static Double getValidValue(Double v) {
return v != null && Double.isFinite(v) ? v : null;
}
}

View File

@ -0,0 +1,88 @@
package com.zhangy.skyeye.common.extend.util;
import java.lang.reflect.Array;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* 对象工具类
*/
public class ObjectUtil {
/**
* 判断对象是否为空
*
* @param o 字符串普通对象数组CollectionMap
* @return
*/
public static boolean isEmpty(Object o) {
if (o == null) {
return true;
}
if (o instanceof String) {
return ((String) o).length() == 0;
} else if (o instanceof Collection) {
return ((Collection) o).size() == 0;
} else if (o instanceof Map) {
return ((Map) o).size() == 0;
} else if (o.getClass().isArray()) {
return Array.getLength(o) == 0;
}
return false;
}
/**
* 判断对象是否非空
* @param o
* @return
*/
public static boolean isNotEmpty(Object o) {
return !isEmpty(o);
}
/**
* List转数组
*
* @param list 集合
* @param clazz 元素类型
* @param <T>
*/
public static <T> T[] toArray(List<T> list, Class<T> clazz) {
T[] array = (T[]) Array.newInstance(clazz, list.size());
for (int i = 0; i < list.size(); i++) {
T t = list.get(i);
array[i] = t;
}
return array;
}
/**
* 将值放入集合
*
* @param map
* @param key
* @param value
* @param <T>
*/
public static <T> void put(Map<String, List<T>> map, String key, T value) {
MapUtil.putList(map, key, value);
}
/**
* object转字符串
*
* @param value
* @param defaultValue
* @return
*/
public static String toStr(Object value, String defaultValue) {
if (null == value) {
return defaultValue;
}
if (value instanceof String) {
return (String) value;
}
return value.toString();
}
}

View File

@ -0,0 +1,131 @@
package com.zhangy.skyeye.common.extend.util;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import java.io.*;
import java.nio.charset.Charset;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
public class ZipUtil {
/**
* 压缩单文件或目录
* @param zos 压缩流对象不关闭
* @param file 磁盘文件
* @param zipPath 压缩文件内部路径初始为""
* @param outputFile 输出的ZIP文件用于跳过自身
* @throws IOException
*/
private static void putEntry(ZipOutputStream zos, File file, String zipPath, File outputFile) throws IOException {
// 跳过正在创建的ZIP文件本身
if (file.getCanonicalPath().equals(outputFile.getCanonicalPath())) {
return;
}
//1.文件夹则遍历全部子文件递归压缩
if(file.isDirectory()){
File[] files = file.listFiles();
if(files != null && files.length > 0) {
for (File i : files) {
putEntry(zos, i, zipPath + file.getName() + "/", outputFile);
}
} else {
//压缩空文件夹最后一定加/不能用\\其它电脑可以用\\貌似是设置问题或者冲突
zos.putNextEntry(new ZipEntry(zipPath + file.getName() +"/"));
}
} else {
//2.文件则将其内容写入压缩文件内
zos.putNextEntry(new ZipEntry(zipPath + file.getName()));
try (FileInputStream fis = new FileInputStream(file)) {
IOUtils.copy(fis, zos);
}
}
}
/**
* 压缩zip最外层如果是目录也会压缩进zip
*
* @param inPath
* @param outPath
* @param containsRoot 如果最外层是目录是否把该目录包含进压缩文件
*/
public static void zip(String inPath, String outPath, boolean containsRoot) throws IOException {
File outputFile = new File(outPath).getCanonicalFile();
try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(outputFile))) {
File root = new File(inPath).getCanonicalFile();
if (containsRoot || !root.isDirectory()) {
putEntry(zos, root, "", outputFile);
} else {
File[] files = root.listFiles();
if(files != null && files.length > 0) {
for (File i : files) {
putEntry(zos, i, "", outputFile);
}
} else {
zos.putNextEntry(new ZipEntry(root.getName() +"/"));
}
}
zos.flush();
}
}
/**
* 判断是否zip格式
*
* @param filename
* @return
*/
public static boolean isZip(String filename) {
//if (LnCommonConstant.FILE_CONTENT_TYPE_ZIP.equals(contentType) || LnCommonConstant.FILE_CONTENT_TYPE_ZIP2.equals(contentType)) {
if (filename.toLowerCase().endsWith(".zip")) {
return true;
}
return false;
}
/**
* 解压
*
* @param inPath 文件路径
* @param outDir 输出目录
* @exception IOException
*/
public static void unZip(String inPath, String outDir) throws IOException {
File inFile = new File(inPath);
if (!inFile.exists()) {
return;
}
unZip(new FileInputStream(inFile), outDir);
}
/**
* 解压
*
* @param inputStream 文件流
* @param outDir 输出目录
* @throws IOException
*/
public static void unZip(InputStream inputStream, String outDir) throws IOException {
try (BufferedInputStream bis = new BufferedInputStream(inputStream);
ZipInputStream zis = new ZipInputStream(bis, Charset.forName("GBK"))) {
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
File outFile = new File(outDir + File.separator + entry.getName());
if (!entry.isDirectory()) {
outFile.getParentFile().mkdirs(); // 创建输出路径中的目录
try (OutputStream fos = new FileOutputStream(outFile)) {
byte[] buffer = new byte[10240];
int length;
while ((length = zis.read(buffer)) > 0) {
fos.write(buffer, 0, length);
}
}
} else {
outFile.mkdirs();
}
}
}
}
}

View File

@ -0,0 +1,69 @@
package com.zhangy.skyeye.common.extend.win.consts;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* windows 服务的win32系统退出码
*
* 0 - 成功无错误
* 1064 - 服务启动过程中发生意外错误
* 1053 - 服务未及时响应启动或控制请求
* 2 - 系统找不到指定的文件
* 5 - 访问被拒绝
* 1056 - 服务实例已在运行中
*/
@Getter
@AllArgsConstructor
public enum WinServ32ExitCodeEnum {
NORMAL(0, "正常"),
/**
* 服务未安装时
*/
NOT_FOUND(2, "系统找不到服务"),
/**
* 没有管理员权限时Runtime的权限==启动Java程序的用户的权限
*/
REFUSED(5, "访问被拒绝"),
RUNNING(1053, "服务未及时响应启动或控制请求"),
/**
* 启动运行中的服务时
*/
NOT_STOPED(1056, "服务实例已在运行中"),
/**
* 停止已停止的服务时
*/
NOT_RUNNING(1062, "服务未启动"),
PAUSING(1064, "服务启动过程中发生意外错误"),
/**
* 自定义值用于处理本类没有收录的代码
*/
UNKNOWN(99, "未知异常")
;
private int code;
private String text;
public static WinServ32ExitCodeEnum parse(int code) {
for (WinServ32ExitCodeEnum e : WinServ32ExitCodeEnum.values()) {
if (e.code == code) {
return e;
}
}
return UNKNOWN;
}
@Override
public String toString() {
return text;
}
}

View File

@ -0,0 +1,47 @@
package com.zhangy.skyeye.common.extend.win.consts;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* windows 服务状态
*/
@Getter
@AllArgsConstructor
public enum WinServStateEnum {
STOPPED(1, "已停止"),
START_PENDING(2, "启动中"),
STOPPING(3, "停止中"),
RUNNING(4, "运行中"),
CONTINUE_PENDING(5, "继续中"),
PAUSING(6, "正在暂停"),
PAUSED(7, "已暂停"),
UNKNOWN(99, "未知"),
;
private int code;
private String text;
public static WinServStateEnum parse(int code) {
for (WinServStateEnum e : WinServStateEnum.values()) {
if (e.code == code) {
return e;
}
}
return UNKNOWN;
}
@Override
public String toString() {
return text;
}
}

View File

@ -0,0 +1,163 @@
package com.zhangy.skyeye.common.extend.win.dto;
import com.zhangy.skyeye.common.extend.win.consts.WinServStateEnum;
import com.zhangy.skyeye.common.extend.win.exception.WinServException;
import lombok.Data;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* windows 服务状态
*/
@Data
public class WinServStatusDTO {
/**
* 服务名称
*/
private String serviceName;
/**
* 服务类型
*
* 10 - WIN32_OWN_PROCESS
*/
private Integer type;
/**
* 服务状态
*
* @see com.skyeye.common.extend.win.consts.WinServStateEnum
*/
private WinServStateEnum state;
/**
* Win32退出代码
*
* @see com.skyeye.common.extend.win.consts.WinServ32ExitCodeEnum
*/
private Integer win32ExitCode;
/**
* 服务退出代码
*
* 0 - 服务正常退出
* 1066 - 服务在启动后立即停止通常表示配置问题
* 其他非零值 - 服务特定的错误代码
*/
private Integer serviceExitCode;
/**
* 检查点 服务在启动停止等长时间操作期间报告进度的计数器
*
* 0 - 服务未在执行长时间操作
*
* 递增数字 - 表示操作进度1, 2, 3...
*/
private Integer checkpoint;
/**
* 等待提示 服务完成当前操作预计需要的最大时间毫秒
*
* 0 - 操作应立即完成
* 3000 - 预计3秒内完成
* 60000 - 预计1分钟内完成
*/
private Integer waitHint;
/**
* 解析服务状态
*
* @param p 查询进程
* @return 服务状态信息
*/
public static WinServStatusDTO parse(Process p) {
WinServStatusDTO dto = new WinServStatusDTO();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()))) {
String line;
while ((line = reader.readLine()) != null) {
String[] array = line.split(":");
if (array.length == 2) {
set(dto, array[0].trim(), array[1].trim());
}
}
p.waitFor();
} catch (IOException ex) {
throw new WinServException("读取系统服务状态异常:" + ex.getMessage());
} catch (InterruptedException ex) {
throw new WinServException("等待查询系统服务结果时发生异常:" + ex.getMessage());
}
return dto;
}
/**
* 解析控制台每行输出解析为字段值
*
* @param dto
* @param name
* @param value
*/
private static void set(WinServStatusDTO dto, String name, String value) {
switch (name) {
case "SERVICE_NAME":
dto.setServiceName(value);
break;
case "TYPE": {
dto.setType(getFirstNumber(value));
break;
}
case "STATE":
int state = getFirstNumber(value);
dto.setState(WinServStateEnum.parse(state));
break;
case "WIN32_EXIT_CODE":
dto.setWin32ExitCode(getFirstNumber(value));
break;
case "SERVICE_EXIT_CODE":
dto.setServiceExitCode(getFirstNumber(value));
break;
case "CHECKPOINT":
dto.setCheckpoint(getFirstNumber(value));
break;
case "WAIT_HINT":
dto.setWaitHint(getFirstNumber(value));
break;
}
}
/**
* 读取字符串开头的10或16进制数字
*
* @param value 以数字开头的字符串
* @return
*/
private static int getFirstNumber(String value) {
// 十六进制数
if (value.startsWith("0x")) {
return Integer.parseInt(value.substring(2), 16);
}
// 十进制数
int endIndex = 0;
while (endIndex < value.length()) {
char c = value.charAt(endIndex);
if (c < '0' || c > '9') {
break;
}
endIndex++;
}
return Integer.parseInt(value.substring(0, endIndex));
}
@Override
public String toString() {
return "服务名:" + serviceName + "\n" +
"类型:" + type + "\n" +
"状态:" + state+ "\n" +
"系统退出码:" + win32ExitCode + "\n" +
"服务退出码:" + serviceExitCode + "\n" +
"检查点:" + checkpoint + "\n" +
"等待提示:" + waitHint;
}
}

View File

@ -0,0 +1,18 @@
package com.zhangy.skyeye.common.extend.win.exception;
import lombok.NoArgsConstructor;
/**
* windows系统服务异常
*/
@NoArgsConstructor
public class WinServException extends RuntimeException {
public WinServException(String message) {
super(message);
}
public WinServException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@ -0,0 +1,137 @@
package com.zhangy.skyeye.common.extend.win.util;
import com.zhangy.skyeye.common.extend.win.consts.WinServStateEnum;
import com.zhangy.skyeye.common.extend.win.dto.WinServStatusDTO;
import com.zhangy.skyeye.common.extend.win.exception.WinServException;
import java.io.IOException;
public class Win64Util {
/**
* 重启系统服务先停止再启动等待启动成功后返回
*
* @param serviceName 服务名称
* @param waitSeconds 最大等待时间
* @return 是否成功
*/
public static boolean restartService(String serviceName, int waitSeconds) {
if (!stopService(serviceName, waitSeconds)) {
return false;
}
return startService(serviceName, waitSeconds);
}
/**
* 停止服务等待停止成功后返回
*
* @param serviceName 服务名称
* @param waitSeconds 最大等待时间
* @return 是否成功
*/
public static boolean stopService(String serviceName, int waitSeconds) {
try {
Process process = Runtime.getRuntime().exec("sc stop " + serviceName);
checkExitAndClose(serviceName, process);
return waitForState(serviceName, WinServStateEnum.STOPPED, waitSeconds);
} catch (IOException | InterruptedException ex) {
throw new WinServException("停止服务异常: " + ex.getMessage());
}
}
/**
* 检查执行结果并释放进程资源终止子进程关闭Process的输入输出流销毁指向外部进程的句柄
*
* @param serviceName 服务名
* @param process 进程
* @throws InterruptedException
*/
private static void checkExitAndClose(String serviceName, Process process) throws InterruptedException {
int exitCode = process.waitFor();
process.destroy();
if (exitCode == 1060) {
throw new WinServException("服务[" + serviceName + "]未安装");
}
}
/**
* 启动服务等待启动成功后返回
*
* @param serviceName 服务名称
* @param waitSeconds 最大等待时间
* @return 是否成功
*/
public static boolean startService(String serviceName, int waitSeconds) {
try {
Process process = Runtime.getRuntime().exec("sc start " + serviceName);
checkExitAndClose(serviceName, process);
return waitForState(serviceName, WinServStateEnum.RUNNING, waitSeconds);
} catch (IOException | InterruptedException ex) {
System.err.println("启动服务异常: " + ex.getMessage());
return false;
}
}
/**
* 查询服务状态
*
* @param serviceName 服务名
* @return
*/
public static WinServStatusDTO queryService(String serviceName) {
try {
Process process = Runtime.getRuntime().exec("sc query " + serviceName);
WinServStatusDTO statusDTO = WinServStatusDTO.parse(process);
checkExitAndClose(serviceName, process);
return statusDTO;
} catch (IOException ex) {
throw new WinServException("查询系统服务状态时发生异常:" + ex.getMessage());
} catch (InterruptedException ex) {
throw new WinServException("查询系统服务状态时被打断睡眠:" + ex.getMessage());
}
}
/**
* 等待服务状态达到期望状态
*
* @param serviceName 服务名称
* @param expectState 期望状态
* @param waitSeconds 等待时间
* @return
*/
private static boolean waitForState(String serviceName, WinServStateEnum expectState, int waitSeconds) {
Runtime r = Runtime.getRuntime();
boolean flag = false;
try {
for (int i = 0; i < waitSeconds; i++) { // 最多尝试waitSeconds次每次等待1秒
Thread.sleep(1000);
WinServStatusDTO statusDTO = queryService(serviceName);
if (statusDTO.getState() == expectState) {
flag = true;
break;
}
// 如果服务进入失败状态提前退出
if (isServiceFailed(statusDTO)) {
System.err.println("服务进入失败状态: " + statusDTO);
break;
}
}
} catch (InterruptedException ex) {
throw new WinServException("查询系统服务状态时被打断睡眠:" + ex.getMessage());
}
return flag;
}
/**
* 判断服务是否发生错误
*
* @param status 服务状态
* @return
*/
private static boolean isServiceFailed(WinServStatusDTO status) {
// 服务已停止但有错误代码
return status.getState() == WinServStateEnum.STOPPED &&
status.getWin32ExitCode() != null &&
status.getWin32ExitCode() != 0;
}
}

View File

@ -0,0 +1,134 @@
package ${package.Controller};
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.web.bind.annotation.*;
#if(${restControllerStyle})
#else
import org.springframework.stereotype.Controller;
#end
#if(${superControllerClassPackage})
import ${superControllerClassPackage};
#end
#if(${swagger2})
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
#end
#if(${entityLombokModel})
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
#end
import $!{package.Entity}.$!{entity};
import $!{package.Service}.$!{table.serviceName};
import com.zhangy.skyeye.common.pojo.result.Result;
import com.zhangy.skyeye.common.pojo.param.IdParam;
import com.zhangy.skyeye.db.utils.MPUtil;
import com.zhangy.skyeye.db.pojo.page.PageParam;
import java.util.List;
/**
* $!{table.comment} 前端控制器
*
* @author ${author}
* @since ${date}
*/
#if(${restControllerStyle})
@RestController
#else
@Controller
#end
@AllArgsConstructor
@Slf4j
@Api(value = "$!{table.comment}", tags = "$!{table.comment}接口")
@RequestMapping("#if(${controllerMappingHyphenStyle})${controllerMappingHyphen}#else${table.entityPath}#end")
#if(${superControllerClass})
public class ${table.controllerName} extends ${superControllerClass} {
#else
public class ${table.controllerName} {
#end
private $!{table.serviceName} $!{table.entityPath}Service;
/**
* 新增
*/
@PostMapping("/save")
@ApiOperationSupport(order = 1)
@ApiOperation(value = "新增", notes = "传入$!{table.entityPath}")
public Result save(@RequestBody $!{entity} $!{table.entityPath}) {
if($!{table.entityPath} == null){
return Result.error("参数异常");
}
return Result.status($!{table.entityPath}Service.save($!{table.entityPath}));
}
/**
* 修改 $!{table.comment}
*/
@PostMapping("/update")
@ApiOperationSupport(order = 2)
@ApiOperation(value = "修改", notes = "传入$!{table.entityPath}")
public Result update(@RequestBody $!{entity} $!{table.entityPath}) {
if($!{table.entityPath} == null){
return Result.error("参数异常");
}
return Result.status($!{table.entityPath}Service.updateById($!{table.entityPath}));
}
/**
* 删除 $!{table.comment}
*/
@PostMapping("/remove")
@ApiOperationSupport(order = 3)
@ApiOperation(value = "删除", notes = "传入ids")
public Result remove(@RequestBody IdParam<Long> idParam) {
if(idParam == null){
return Result.error("参数异常!");
}
return Result.status($!{table.entityPath}Service.removeByIds(idParam.getIds()));
}
/**
* 详情
*/
@GetMapping("/detail")
@ApiOperationSupport(order = 4)
@ApiOperation(value = "详情", notes = "传入id")
public Result<$!{entity}> detail(Long id) {
if(id == null){
return Result.error("参数异常");
}
$!{entity} detail = $!{table.entityPath}Service.getById(id);
return Result.successData(detail);
}
/**
* 查询 $!{table.comment}
*/
@GetMapping("/list")
@ApiOperationSupport(order = 5)
@ApiOperation(value = "查询", notes = "传入$!{table.entityPath}")
public Result list(PageParam pageParam, $!{entity} $!{table.entityPath}) {
List<$!{entity}> list = $!{table.entityPath}Service.list($!{table.entityPath}Service.getQueryWrapper(pageParam, $!{table.entityPath}));
return Result.successData(list);
}
/**
* 分页 $!{table.comment}
*/
@GetMapping("/page")
@ApiOperationSupport(order = 6)
@ApiOperation(value = "分页", notes = "传入$!{table.entityPath}")
public Result<IPage> page(PageParam pageParam, $!{entity} $!{table.entityPath}) {
IPage<$!{entity}> pages = $!{table.entityPath}Service.page(
MPUtil.getPage(pageParam),
$!{table.entityPath}Service.getQueryWrapper(null, $!{table.entityPath})
);
return Result.successData(pages);
}
}

View File

@ -0,0 +1,158 @@
package ${package.Entity};
#foreach($pkg in ${table.importPackages})
import ${pkg};
#end
#if(${swagger2})
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
#end
#if(${entityLombokModel})
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
#if(${chainModel})
import lombok.experimental.Accessors;
#end
#end
/**
* $!{table.comment}
*
* @author ${author}
* @since ${date}
*/
#if(${entityLombokModel})
@Data
@AllArgsConstructor
@NoArgsConstructor
#if(${superEntityClass})
@EqualsAndHashCode(callSuper = true)
#else
@EqualsAndHashCode(callSuper = false)
#end
#if(${chainModel})
@Accessors(chain = true)
#end
#end
#if(${table.convert})
@TableName("${table.name}")
#end
#if(${swagger2})
@ApiModel(value="${entity}对象", description="$!{table.comment}")
#end
#if(${superEntityClass})
public class ${entity} extends ${superEntityClass}#if(${activeRecord})<${entity}>#end {
#elseif(${activeRecord})
public class ${entity} extends Model<${entity}> {
#else
public class ${entity} implements Serializable {
#end
#if(${entitySerialVersionUID})
private static final long serialVersionUID = 1L;
#end
## ---------- BEGIN 字段循环遍历 ----------
#foreach($field in ${table.fields})
#if(${field.keyFlag})
#set($keyPropertyName=${field.propertyName})
#end
#if("$!field.comment" != "")
#if(${swagger2})
@ApiModelProperty(value = "${field.comment}", position = ${foreach.index})
#else
/**
* ${field.comment}
*/
#end
#end
#if(${field.keyFlag})
## 主键
#if(${field.keyIdentityFlag})
@TableId(value = "${field.annotationColumnName}", type = IdType.AUTO)
#elseif(!$null.isNull(${idType}) && "$!idType" != "")
@TableId(value = "${field.annotationColumnName}", type = IdType.${idType})
#elseif(${field.convert})
@TableId("${field.annotationColumnName}")
#end
## 普通字段
#elseif(${field.fill})
## ----- 存在字段填充设置 -----
#if(${field.convert})
@TableField(value = "${field.annotationColumnName}", fill = FieldFill.${field.fill})
#else
@TableField(fill = FieldFill.${field.fill})
#end
#elseif(${field.convert})
@TableField("${field.annotationColumnName}")
#end
## 乐观锁注解
#if(${versionFieldName}==${field.name})
@Version
#end
## 逻辑删除注解
#if(${logicDeleteFieldName}==${field.name})
@TableLogic
#end
private ${field.propertyType} ${field.propertyName};
#end
## ---------- END 字段循环遍历 ----------
#if(!${entityLombokModel})
#foreach($field in ${table.fields})
#if(${field.propertyType.equals("boolean")})
#set($getprefix="is")
#else
#set($getprefix="get")
#end
public ${field.propertyType} ${getprefix}${field.capitalName}() {
return ${field.propertyName};
}
#if(${chainModel})
public ${entity} set${field.capitalName}(${field.propertyType} ${field.propertyName}) {
#else
public void set${field.capitalName}(${field.propertyType} ${field.propertyName}) {
#end
this.${field.propertyName} = ${field.propertyName};
#if(${chainModel})
return this;
#end
}
#end
## --foreach end---
#end
## --end of #if(!${entityLombokModel})--
#if(${entityColumnConstant})
#foreach($field in ${table.fields})
public static final String ${field.name.toUpperCase()} = "${field.name}";
#end
#end
#if(${activeRecord})
@Override
protected Serializable pkVal() {
#if(${keyPropertyName})
return this.${keyPropertyName};
#else
return null;
#end
}
#end
#if(!${entityLombokModel})
@Override
public String toString() {
return "${entity}{" +
#foreach($field in ${table.fields})
#if($!{foreach.index}==0)
"${field.propertyName}=" + ${field.propertyName} +
#else
", ${field.propertyName}=" + ${field.propertyName} +
#end
#end
"}";
}
#end
}

View File

@ -0,0 +1,14 @@
package ${package.Mapper};
import ${package.Entity}.${entity};
import ${superMapperClassPackage};
/**
* $!{table.comment} Mapper 接口
*
* @author ${author}
* @since ${date}
*/
public interface ${table.mapperName} extends ${superMapperClass}<${entity}> {
}

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="${package.Mapper}.${table.mapperName}">
#if(${enableCache})
<!-- 开启二级缓存 -->
<cache type="org.mybatis.caches.ehcache.LoggingEhcache"/>
#end
#if(${baseResultMap})
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="${package.Entity}.${entity}">
#foreach($field in ${table.fields})
#if(${field.keyFlag})##生成主键排在第一位
<id column="${field.name}" property="${field.propertyName}" />
#end
#end
#foreach($field in ${table.commonFields})##生成公共字段
<result column="${field.name}" property="${field.propertyName}" />
#end
#foreach($field in ${table.fields})
#if(!${field.keyFlag})##生成普通字段
<result column="${field.name}" property="${field.propertyName}" />
#end
#end
</resultMap>
#end
#if(${baseColumnList})
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
#foreach($field in ${table.commonFields})
${field.columnName},
#end
${table.fieldNames}
</sql>
#end
</mapper>

View File

@ -0,0 +1,24 @@
package ${package.Service};
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zhangy.skyeye.db.pojo.page.PageParam;
import ${package.Entity}.${entity};
import ${superServiceClassPackage};
/**
* $!{table.comment} 服务类
*
* @author ${author}
* @since ${date}
*/
public interface ${table.serviceName} extends ${superServiceClass}<${entity}> {
/**
* 通过实体类获取QueryWrapper
* @param pageParam 分页参数
* @param $!{table.entityPath} 实体信息
* @return
*/
QueryWrapper<$!{entity}> getQueryWrapper(PageParam pageParam, $!{entity} $!{table.entityPath});
}

View File

@ -0,0 +1,60 @@
package ${package.ServiceImpl};
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zhangy.skyeye.db.pojo.page.PageParam;
import com.zhangy.skyeye.db.utils.MPUtil;
import ${package.Entity}.${entity};
import ${package.Mapper}.${table.mapperName};
import ${package.Service}.${table.serviceName};
import ${superServiceImplClassPackage};
import org.springframework.stereotype.Service;
/**
* $!{table.comment} 服务实现类
*
* @author ${author}
* @since ${date}
*/
@Service
public class ${table.serviceImplName} extends ${superServiceImplClass}<${table.mapperName}, ${entity}> implements ${table.serviceName} {
/**
* 通过实体类获取QueryWrapper
* @param pageParam 分页参数
* @param $!{table.entityPath} 实体信息
* @return
*/
@Override
public QueryWrapper<$!{entity}> getQueryWrapper(PageParam pageParam, $!{entity} $!{table.entityPath}){
QueryWrapper<$!{entity}> queryWrapper = MPUtil.getQueryWrapper(pageParam);
if($!{table.entityPath} == null){
return queryWrapper;
}
#foreach($field in ${table.fields})
## 主键
#if(${field.keyIdentityFlag})
//主键
if($!{table.entityPath}.get${field.capitalName}() != null){
queryWrapper.lambda()
.eq($!{entity}::get${field.capitalName}, $!{table.entityPath}.get${field.capitalName}());
return queryWrapper;
}
#end
#end
//TODO 此处可以根据各字段查询需求修改查询条件eq、like、ge、gt、le、lt、ne...等等等
queryWrapper.lambda()
#foreach($field in ${table.fields})
#if(!${field.keyIdentityFlag})
#if($!{foreach.last})
.eq($!{table.entityPath}.get${field.capitalName}() != null, $!{entity}::get${field.capitalName}, $!{table.entityPath}.get${field.capitalName}());
#else
.eq($!{table.entityPath}.get${field.capitalName}() != null, $!{entity}::get${field.capitalName}, $!{table.entityPath}.get${field.capitalName}())
#end
#end
#end
return queryWrapper;
}
}

View File

@ -0,0 +1,134 @@
package ${package.Controller};
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.web.bind.annotation.*;
#if(${restControllerStyle})
#else
import org.springframework.stereotype.Controller;
#end
#if(${superControllerClassPackage})
import ${superControllerClassPackage};
#end
#if(${swagger2})
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
#end
#if(${entityLombokModel})
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
#end
import $!{package.Entity}.$!{entity};
import $!{package.Service}.$!{table.serviceName};
import com.zhangy.skyeye.common.pojo.result.Result;
import com.zhangy.skyeye.common.pojo.param.IdParam;
import com.zhangy.skyeye.db.utils.MPUtil;
import com.zhangy.skyeye.db.pojo.page.PageParam;
import java.util.List;
/**
* $!{table.comment} 前端控制器
*
* @author ${author}
* @since ${date}
*/
#if(${restControllerStyle})
@RestController
#else
@Controller
#end
@AllArgsConstructor
@Slf4j
@Api(value = "$!{table.comment}", tags = "$!{table.comment}接口")
@RequestMapping("#if(${controllerMappingHyphenStyle})${controllerMappingHyphen}#else${table.entityPath}#end")
#if(${superControllerClass})
public class ${table.controllerName} extends ${superControllerClass} {
#else
public class ${table.controllerName} {
#end
private $!{table.serviceName} $!{table.entityPath}Service;
/**
* 新增
*/
@PostMapping("/save")
@ApiOperationSupport(order = 1)
@ApiOperation(value = "新增", notes = "传入$!{table.entityPath}")
public Result save(@RequestBody $!{entity} $!{table.entityPath}) {
if($!{table.entityPath} == null){
return Result.error("参数异常");
}
return Result.status($!{table.entityPath}Service.save($!{table.entityPath}));
}
/**
* 修改 $!{table.comment}
*/
@PostMapping("/update")
@ApiOperationSupport(order = 2)
@ApiOperation(value = "修改", notes = "传入$!{table.entityPath}")
public Result update(@RequestBody $!{entity} $!{table.entityPath}) {
if($!{table.entityPath} == null){
return Result.error("参数异常");
}
return Result.status($!{table.entityPath}Service.updateById($!{table.entityPath}));
}
/**
* 删除 $!{table.comment}
*/
@PostMapping("/remove")
@ApiOperationSupport(order = 3)
@ApiOperation(value = "删除", notes = "传入ids")
public Result remove(@RequestBody IdParam<Long> idParam) {
if(idParam == null){
return Result.error("参数异常!");
}
return Result.status($!{table.entityPath}Service.removeByIds(idParam.getIds()));
}
/**
* 详情
*/
@GetMapping("/detail")
@ApiOperationSupport(order = 4)
@ApiOperation(value = "详情", notes = "传入id")
public Result<$!{entity}> detail(Long id) {
if(id == null){
return Result.error("参数异常");
}
$!{entity} detail = $!{table.entityPath}Service.getById(id);
return Result.successData(detail);
}
/**
* 查询 $!{table.comment}
*/
@GetMapping("/list")
@ApiOperationSupport(order = 5)
@ApiOperation(value = "查询", notes = "传入$!{table.entityPath}")
public Result list(PageParam pageParam, $!{entity} $!{table.entityPath}) {
List<$!{entity}> list = $!{table.entityPath}Service.list($!{table.entityPath}Service.getQueryWrapper(pageParam, $!{table.entityPath}));
return Result.successData(list);
}
/**
* 分页 $!{table.comment}
*/
@GetMapping("/page")
@ApiOperationSupport(order = 6)
@ApiOperation(value = "分页", notes = "传入$!{table.entityPath}")
public Result<IPage> page(PageParam pageParam, $!{entity} $!{table.entityPath}) {
IPage<$!{entity}> pages = $!{table.entityPath}Service.page(
MPUtil.getPage(pageParam),
$!{table.entityPath}Service.getQueryWrapper(null, $!{table.entityPath})
);
return Result.successData(pages);
}
}

View File

@ -0,0 +1,158 @@
package ${package.Entity};
#foreach($pkg in ${table.importPackages})
import ${pkg};
#end
#if(${swagger2})
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
#end
#if(${entityLombokModel})
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
#if(${chainModel})
import lombok.experimental.Accessors;
#end
#end
/**
* $!{table.comment}
*
* @author ${author}
* @since ${date}
*/
#if(${entityLombokModel})
@Data
@AllArgsConstructor
@NoArgsConstructor
#if(${superEntityClass})
@EqualsAndHashCode(callSuper = true)
#else
@EqualsAndHashCode(callSuper = false)
#end
#if(${chainModel})
@Accessors(chain = true)
#end
#end
#if(${table.convert})
@TableName("${table.name}")
#end
#if(${swagger2})
@ApiModel(value="${entity}对象", description="$!{table.comment}")
#end
#if(${superEntityClass})
public class ${entity} extends ${superEntityClass}#if(${activeRecord})<${entity}>#end {
#elseif(${activeRecord})
public class ${entity} extends Model<${entity}> {
#else
public class ${entity} implements Serializable {
#end
#if(${entitySerialVersionUID})
private static final long serialVersionUID = 1L;
#end
## ---------- BEGIN 字段循环遍历 ----------
#foreach($field in ${table.fields})
#if(${field.keyFlag})
#set($keyPropertyName=${field.propertyName})
#end
#if("$!field.comment" != "")
#if(${swagger2})
@ApiModelProperty(value = "${field.comment}", position = ${foreach.index})
#else
/**
* ${field.comment}
*/
#end
#end
#if(${field.keyFlag})
## 主键
#if(${field.keyIdentityFlag})
@TableId(value = "${field.annotationColumnName}", type = IdType.AUTO)
#elseif(!$null.isNull(${idType}) && "$!idType" != "")
@TableId(value = "${field.annotationColumnName}", type = IdType.${idType})
#elseif(${field.convert})
@TableId("${field.annotationColumnName}")
#end
## 普通字段
#elseif(${field.fill})
## ----- 存在字段填充设置 -----
#if(${field.convert})
@TableField(value = "${field.annotationColumnName}", fill = FieldFill.${field.fill})
#else
@TableField(fill = FieldFill.${field.fill})
#end
#elseif(${field.convert})
@TableField("${field.annotationColumnName}")
#end
## 乐观锁注解
#if(${versionFieldName}==${field.name})
@Version
#end
## 逻辑删除注解
#if(${logicDeleteFieldName}==${field.name})
@TableLogic
#end
private ${field.propertyType} ${field.propertyName};
#end
## ---------- END 字段循环遍历 ----------
#if(!${entityLombokModel})
#foreach($field in ${table.fields})
#if(${field.propertyType.equals("boolean")})
#set($getprefix="is")
#else
#set($getprefix="get")
#end
public ${field.propertyType} ${getprefix}${field.capitalName}() {
return ${field.propertyName};
}
#if(${chainModel})
public ${entity} set${field.capitalName}(${field.propertyType} ${field.propertyName}) {
#else
public void set${field.capitalName}(${field.propertyType} ${field.propertyName}) {
#end
this.${field.propertyName} = ${field.propertyName};
#if(${chainModel})
return this;
#end
}
#end
## --foreach end---
#end
## --end of #if(!${entityLombokModel})--
#if(${entityColumnConstant})
#foreach($field in ${table.fields})
public static final String ${field.name.toUpperCase()} = "${field.name}";
#end
#end
#if(${activeRecord})
@Override
protected Serializable pkVal() {
#if(${keyPropertyName})
return this.${keyPropertyName};
#else
return null;
#end
}
#end
#if(!${entityLombokModel})
@Override
public String toString() {
return "${entity}{" +
#foreach($field in ${table.fields})
#if($!{foreach.index}==0)
"${field.propertyName}=" + ${field.propertyName} +
#else
", ${field.propertyName}=" + ${field.propertyName} +
#end
#end
"}";
}
#end
}

View File

@ -0,0 +1,14 @@
package ${package.Mapper};
import ${package.Entity}.${entity};
import ${superMapperClassPackage};
/**
* $!{table.comment} Mapper 接口
*
* @author ${author}
* @since ${date}
*/
public interface ${table.mapperName} extends ${superMapperClass}<${entity}> {
}

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="${package.Mapper}.${table.mapperName}">
#if(${enableCache})
<!-- 开启二级缓存 -->
<cache type="org.mybatis.caches.ehcache.LoggingEhcache"/>
#end
#if(${baseResultMap})
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="${package.Entity}.${entity}">
#foreach($field in ${table.fields})
#if(${field.keyFlag})##生成主键排在第一位
<id column="${field.name}" property="${field.propertyName}" />
#end
#end
#foreach($field in ${table.commonFields})##生成公共字段
<result column="${field.name}" property="${field.propertyName}" />
#end
#foreach($field in ${table.fields})
#if(!${field.keyFlag})##生成普通字段
<result column="${field.name}" property="${field.propertyName}" />
#end
#end
</resultMap>
#end
#if(${baseColumnList})
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
#foreach($field in ${table.commonFields})
${field.columnName},
#end
${table.fieldNames}
</sql>
#end
</mapper>

View File

@ -0,0 +1,24 @@
package ${package.Service};
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zhangy.skyeye.db.pojo.page.PageParam;
import ${package.Entity}.${entity};
import ${superServiceClassPackage};
/**
* $!{table.comment} 服务类
*
* @author ${author}
* @since ${date}
*/
public interface ${table.serviceName} extends ${superServiceClass}<${entity}> {
/**
* 通过实体类获取QueryWrapper
* @param pageParam 分页参数
* @param $!{table.entityPath} 实体信息
* @return
*/
QueryWrapper<$!{entity}> getQueryWrapper(PageParam pageParam, $!{entity} $!{table.entityPath});
}

View File

@ -0,0 +1,60 @@
package ${package.ServiceImpl};
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zhangy.skyeye.db.pojo.page.PageParam;
import com.zhangy.skyeye.db.utils.MPUtil;
import ${package.Entity}.${entity};
import ${package.Mapper}.${table.mapperName};
import ${package.Service}.${table.serviceName};
import ${superServiceImplClassPackage};
import org.springframework.stereotype.Service;
/**
* $!{table.comment} 服务实现类
*
* @author ${author}
* @since ${date}
*/
@Service
public class ${table.serviceImplName} extends ${superServiceImplClass}<${table.mapperName}, ${entity}> implements ${table.serviceName} {
/**
* 通过实体类获取QueryWrapper
* @param pageParam 分页参数
* @param $!{table.entityPath} 实体信息
* @return
*/
@Override
public QueryWrapper<$!{entity}> getQueryWrapper(PageParam pageParam, $!{entity} $!{table.entityPath}){
QueryWrapper<$!{entity}> queryWrapper = MPUtil.getQueryWrapper(pageParam);
if($!{table.entityPath} == null){
return queryWrapper;
}
#foreach($field in ${table.fields})
## 主键
#if(${field.keyIdentityFlag})
//主键
if($!{table.entityPath}.get${field.capitalName}() != null){
queryWrapper.lambda()
.eq($!{entity}::get${field.capitalName}, $!{table.entityPath}.get${field.capitalName}());
return queryWrapper;
}
#end
#end
//TODO 此处可以根据各字段查询需求修改查询条件eq、like、ge、gt、le、lt、ne...等等等
queryWrapper.lambda()
#foreach($field in ${table.fields})
#if(!${field.keyIdentityFlag})
#if($!{foreach.last})
.eq($!{table.entityPath}.get${field.capitalName}() != null, $!{entity}::get${field.capitalName}, $!{table.entityPath}.get${field.capitalName}());
#else
.eq($!{table.entityPath}.get${field.capitalName}() != null, $!{entity}::get${field.capitalName}, $!{table.entityPath}.get${field.capitalName}())
#end
#end
#end
return queryWrapper;
}
}

View File

@ -0,0 +1,3 @@
artifactId=skyeye-common-extend
groupId=com.zhangy
version=1.0.0.RELEASE

View File

@ -0,0 +1,24 @@
com\zhangy\skyeye\common\extend\exception\AuthException.class
com\zhangy\skyeye\common\extend\dto\PageDTO.class
com\zhangy\skyeye\common\extend\util\BeanUtil.class
com\zhangy\skyeye\common\extend\util\HttpUtil.class
com\zhangy\skyeye\common\extend\util\NumberUtil.class
com\zhangy\skyeye\common\extend\util\ZipUtil.class
com\zhangy\skyeye\common\extend\win\exception\WinServException.class
com\zhangy\skyeye\common\extend\win\consts\WinServ32ExitCodeEnum.class
com\zhangy\skyeye\common\extend\win\util\Win64Util.class
com\zhangy\skyeye\common\extend\util\JsonUtil.class
com\zhangy\skyeye\common\extend\dto\QueryDTO.class
com\zhangy\skyeye\common\extend\util\ObjectUtil.class
com\zhangy\skyeye\common\extend\enums\CodeEnum.class
com\zhangy\skyeye\common\extend\win\dto\WinServStatusDTO.class
com\zhangy\skyeye\common\extend\util\DateUtil.class
com\zhangy\skyeye\common\extend\exception\ServiceException.class
com\zhangy\skyeye\common\extend\util\FileUtil.class
com\zhangy\skyeye\common\extend\util\MapUtil.class
com\zhangy\skyeye\common\extend\enums\StringCodeEnum.class
com\zhangy\skyeye\common\extend\win\consts\WinServStateEnum.class
com\zhangy\skyeye\common\extend\anno\OperationLog.class
com\zhangy\skyeye\common\extend\enums\EnumUtil.class
com\zhangy\skyeye\common\extend\anno\IgnoreAuth.class
com\zhangy\skyeye\common\extend\util\MathUtil.class

View File

@ -0,0 +1,24 @@
D:\workspace\skyeyesystem\backend\Skyeye-sys-dev\skyeye-common\skyeye-common-extend\src\main\java\com\zhangy\skyeye\common\extend\util\HttpUtil.java
D:\workspace\skyeyesystem\backend\Skyeye-sys-dev\skyeye-common\skyeye-common-extend\src\main\java\com\zhangy\skyeye\common\extend\util\BeanUtil.java
D:\workspace\skyeyesystem\backend\Skyeye-sys-dev\skyeye-common\skyeye-common-extend\src\main\java\com\zhangy\skyeye\common\extend\util\FileUtil.java
D:\workspace\skyeyesystem\backend\Skyeye-sys-dev\skyeye-common\skyeye-common-extend\src\main\java\com\zhangy\skyeye\common\extend\util\MapUtil.java
D:\workspace\skyeyesystem\backend\Skyeye-sys-dev\skyeye-common\skyeye-common-extend\src\main\java\com\zhangy\skyeye\common\extend\win\util\Win64Util.java
D:\workspace\skyeyesystem\backend\Skyeye-sys-dev\skyeye-common\skyeye-common-extend\src\main\java\com\zhangy\skyeye\common\extend\exception\AuthException.java
D:\workspace\skyeyesystem\backend\Skyeye-sys-dev\skyeye-common\skyeye-common-extend\src\main\java\com\zhangy\skyeye\common\extend\enums\CodeEnum.java
D:\workspace\skyeyesystem\backend\Skyeye-sys-dev\skyeye-common\skyeye-common-extend\src\main\java\com\zhangy\skyeye\common\extend\util\DateUtil.java
D:\workspace\skyeyesystem\backend\Skyeye-sys-dev\skyeye-common\skyeye-common-extend\src\main\java\com\zhangy\skyeye\common\extend\enums\EnumUtil.java
D:\workspace\skyeyesystem\backend\Skyeye-sys-dev\skyeye-common\skyeye-common-extend\src\main\java\com\zhangy\skyeye\common\extend\util\JsonUtil.java
D:\workspace\skyeyesystem\backend\Skyeye-sys-dev\skyeye-common\skyeye-common-extend\src\main\java\com\zhangy\skyeye\common\extend\dto\QueryDTO.java
D:\workspace\skyeyesystem\backend\Skyeye-sys-dev\skyeye-common\skyeye-common-extend\src\main\java\com\zhangy\skyeye\common\extend\util\ZipUtil.java
D:\workspace\skyeyesystem\backend\Skyeye-sys-dev\skyeye-common\skyeye-common-extend\src\main\java\com\zhangy\skyeye\common\extend\anno\OperationLog.java
D:\workspace\skyeyesystem\backend\Skyeye-sys-dev\skyeye-common\skyeye-common-extend\src\main\java\com\zhangy\skyeye\common\extend\win\consts\WinServStateEnum.java
D:\workspace\skyeyesystem\backend\Skyeye-sys-dev\skyeye-common\skyeye-common-extend\src\main\java\com\zhangy\skyeye\common\extend\win\exception\WinServException.java
D:\workspace\skyeyesystem\backend\Skyeye-sys-dev\skyeye-common\skyeye-common-extend\src\main\java\com\zhangy\skyeye\common\extend\dto\PageDTO.java
D:\workspace\skyeyesystem\backend\Skyeye-sys-dev\skyeye-common\skyeye-common-extend\src\main\java\com\zhangy\skyeye\common\extend\util\MathUtil.java
D:\workspace\skyeyesystem\backend\Skyeye-sys-dev\skyeye-common\skyeye-common-extend\src\main\java\com\zhangy\skyeye\common\extend\util\NumberUtil.java
D:\workspace\skyeyesystem\backend\Skyeye-sys-dev\skyeye-common\skyeye-common-extend\src\main\java\com\zhangy\skyeye\common\extend\exception\ServiceException.java
D:\workspace\skyeyesystem\backend\Skyeye-sys-dev\skyeye-common\skyeye-common-extend\src\main\java\com\zhangy\skyeye\common\extend\win\dto\WinServStatusDTO.java
D:\workspace\skyeyesystem\backend\Skyeye-sys-dev\skyeye-common\skyeye-common-extend\src\main\java\com\zhangy\skyeye\common\extend\anno\IgnoreAuth.java
D:\workspace\skyeyesystem\backend\Skyeye-sys-dev\skyeye-common\skyeye-common-extend\src\main\java\com\zhangy\skyeye\common\extend\util\ObjectUtil.java
D:\workspace\skyeyesystem\backend\Skyeye-sys-dev\skyeye-common\skyeye-common-extend\src\main\java\com\zhangy\skyeye\common\extend\enums\StringCodeEnum.java
D:\workspace\skyeyesystem\backend\Skyeye-sys-dev\skyeye-common\skyeye-common-extend\src\main\java\com\zhangy\skyeye\common\extend\win\consts\WinServ32ExitCodeEnum.java

View File

@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>skyeye</artifactId>
<groupId>com.zhangy</groupId>
<version>1.0.0.RELEASE</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>skyeye-common-generator</artifactId>
<description>代码生成模板</description>
<dependencies>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- Mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.4.1</version>
</dependency>
<!-- 模板引擎 -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.3</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<encoding>UTF-8</encoding>
<nonFilteredFileExtensions>
<!-- 防止打包时dll文件大小被改变-->
<nonFilteredFileExtension>so</nonFilteredFileExtension>
</nonFilteredFileExtensions>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,255 @@
package com.zhangy.skyeye.common.generator;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.converts.OracleTypeConvert;
import com.baomidou.mybatisplus.generator.config.converts.PostgreSqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.converts.SqlServerTypeConvert;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
/**
* 代码生成器配置类
*/
@Data
public class GeneratorApi {
/**
* 数据库驱动名
*/
private String driverName;
/**
* 数据库链接地址
*/
private String url;
/**
* 数据库用户名
*/
private String username;
/**
* 数据库密码
*/
private String password;
/**
* 输出文件目录
*/
private String outputDir;
/**
* 作者
*/
private String author = "Zhangy";
/**
* 代码生成的包名
*/
private String packageName;
/**
* 需要生成的表名(两者只能取其一)
*/
private String[] includeTables;
/**
* 需要排除的表名(两者只能取其一)
*/
private String[] excludeTables;
/**
* 是否启用swagger
*/
private Boolean isSwagger2 = Boolean.TRUE;
public void run() {
AutoGenerator mpg = new AutoGenerator();
//全局配置
GlobalConfig gc = new GlobalConfig();
//代码输出目录
gc.setOutputDir(outputDir);
//开发人员
gc.setAuthor(author);
gc.setFileOverride(true);
//是否打开输出目录
gc.setOpen(false);
gc.setActiveRecord(false);
gc.setEnableCache(false);
//Mybatis Mapping.xml中增加BaseResult和BaseColumn
gc.setBaseResultMap(true);
gc.setBaseColumnList(true);
/*gc.setMapperName("%sMapper");
gc.setXmlName("%sMapping");
gc.setServiceName("I%sService");
gc.setServiceImplName("%sServiceImpl");
gc.setControllerName("%sController");*/
gc.setSwagger2(isSwagger2);
mpg.setGlobalConfig(gc);
//数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setDriverName(this.driverName);
dsc.setUrl(this.url);
dsc.setUsername(this.username);
dsc.setPassword(this.password);
if (this.driverName.contains(DbType.MYSQL.getDb())) {
dsc.setDbType(DbType.MYSQL);
dsc.setTypeConvert(new MySqlTypeConvert());
} else if (this.driverName.contains(DbType.POSTGRE_SQL.getDb())) {
dsc.setDbType(DbType.POSTGRE_SQL);
dsc.setTypeConvert(new PostgreSqlTypeConvert());
} else if (this.driverName.contains(DbType.SQL_SERVER.getDb())) {
dsc.setDbType(DbType.SQL_SERVER);
dsc.setTypeConvert(new SqlServerTypeConvert());
} else if (this.driverName.contains(DbType.ORACLE.getDb())) {
dsc.setDbType(DbType.ORACLE);
dsc.setTypeConvert(new OracleTypeConvert());
} else {
System.out.println("数据库类型异常,代码生成失败!");
return;
}
mpg.setDataSource(dsc);
// 策略配置
StrategyConfig strategy = new StrategyConfig();
// strategy.setCapitalMode(true);// 全局大写命名
// strategy.setDbColumnUnderline(true);//全局下划线命名
strategy.setNaming(NamingStrategy.underline_to_camel);
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
// strategy.setTablePrefix(tablePrefix);
if (includeTables.length > 0) {
strategy.setInclude(includeTables);
}
if (excludeTables.length > 0) {
strategy.setExclude(excludeTables);
}
// 自定义 controller 父类
strategy.setEntityBuilderModel(false);
strategy.setEntityLombokModel(true);
strategy.setRestControllerStyle(true);
strategy.setControllerMappingHyphenStyle(true);
mpg.setStrategy(strategy);
// 包配置
PackageConfig pc = new PackageConfig();
// 控制台扫描
pc.setModuleName(null);
//父包名
pc.setParent("com.zhangye.skyeye.service.manager");
//controller包名
// pc.setController("controller");
// //entity包名
// pc.setEntity("entity");
// //mapping包名
// pc.setXml("mapping");
mpg.setPackageInfo(pc);
//自定义配置
InjectionConfig injectionConfig = new InjectionConfig() {
@Override
public void initMap() {
}
};
//如果模板引擎是 freemarker
//String templatePath = "/templates/mapping.xml.ftl";
// 如果模板引擎是 velocity
String templatePath = "/templates/mapping.xml.vm";
// 自定义输出配置
List<FileOutConfig> focList = new ArrayList<>();
// 自定义配置会被优先输出
focList.add(new FileOutConfig(templatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
// 自定义输出文件名 如果你 Entity 设置了前后缀此处注意 xml 的名称会跟着发生变化
return outputDir + "/src/main/resources/mapping/"
+ tableInfo.getEntityName() + "Mapping" + StringPool.DOT_XML;
}
});
injectionConfig.setFileOutConfigList(focList);
mpg.setCfg(injectionConfig);
// 配置模板
TemplateConfig templateConfig = new TemplateConfig();
// 配置自定义输出模板
//指定自定义模板路径注意不要带上.ftl/.vm, 会根据使用的模板引擎自动识别
// templateConfig.setEntity("templates/entity2.java");
// templateConfig.setService();
// templateConfig.setController();
templateConfig.setXml(null);
mpg.setTemplate(templateConfig);
mpg.execute();
}
public static void main(String[] args) {
GeneratorApi generator = new GeneratorApi();
//数据库驱动名
generator.setDriverName("com.mysql.cj.jdbc.Driver");
// generator.setDriverName("com.oscar.Driver");
//数据库链接地址
// generator.setUrl("jdbc:mysql://dt-mysql:3306/dt-chuangpu?autoReconnect=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=false");
// generator.setUrl("jdbc:mysql://dt-mysql:3306/dt-env?autoReconnect=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=false");
// generator.setUrl("jdbc:mysql://dt-mysql:3306/dt-pggc?autoReconnect=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=false");
// generator.setUrl("jdbc:oscar://127.0.0.1:2003/OSRDB?serverTimezone=UTC&useSSL=FALSE");
// generator.setUrl("jdbc:mysql://192.168.1.92:3306/1854096855953195009?autoReconnect=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&useSSL=false");
//generator.setUrl("jdbc:mysql://dt-mysql:3306/cloud_sample?autoReconnect=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=false");
generator.setUrl("jdbc:mysql://192.168.209.130:3306/sztk-ld?autoReconnect=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=false");
//数据库用户名
generator.setUsername("root");
//数据库密码
generator.setPassword("333444");
// generator.setPassword("bn3cv2zx1");
//输出文件目录
generator.setOutputDir("D://generator");
//作者
generator.setAuthor("lz");
//代码生成的包名
// //需要生成的表名(两者只能取其一)
// generator.setIncludeTables(("env_goes_electron").replaceAll(" ", "").split(","));
// String [] includeTables = {"user","sysuser","student","coach","sportevents","student_events"};
// generator.setIncludeTables(includeTables);
String [] includeTables = {"sys_log" };
generator.setIncludeTables(includeTables);
//需要排除的表名(两者只能取其一)
generator.setExcludeTables(new String[]{});
generator.run();
// GeneratorApi generator = new GeneratorApi();
//
// //数据库驱动名
// generator.setDriverName("com.mysql.cj.jdbc.Driver");
// //数据库链接地址
// generator.setUrl("jdbc:mysql://dt-mysql:3306/dt-manager?autoReconnect=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=false");
// //数据库用户名
// generator.setUsername("root");
// //数据库密码
// generator.setPassword("123456");
//
// //输出文件目录
// generator.setOutputDir("D://generator");
// //作者
// generator.setAuthor("wj");
// //代码生成的包名
// //需要生成的表名(两者只能取其一)
// generator.setIncludeTables(("res_wj_emp").replaceAll(" ", "").split(","));
// //需要排除的表名(两者只能取其一)
// generator.setExcludeTables(new String[]{});
// generator.run();
}
}

View File

@ -0,0 +1,300 @@
package com.zhangy.skyeye.common.generator;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.converts.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
/**
* 代码生成器配置类
*/
@Data
public class GeneratorApi_DM {
/**
* 数据库驱动名
*/
private String driverName;
/**
* 数据库链接地址
*/
private String url;
/**
* 数据库用户名
*/
private String username;
/**
* 数据库密码
*/
private String password;
/**
* scheme
*/
private String scheme;
/**
* 输出文件目录
*/
private String outputDir;
/**
* 作者
*/
private String author = "Zhangy";
/**
* 代码生成的包名
*/
private String packageName;
/**
* 需要生成的表名(两者只能取其一)
*/
private String[] includeTables;
/**
* 需要排除的表名(两者只能取其一)
*/
private String[] excludeTables;
/**
* 是否启用swagger
*/
private Boolean isSwagger2 = Boolean.TRUE;
public void run() {
AutoGenerator mpg = new AutoGenerator();
//全局配置
GlobalConfig gc = new GlobalConfig();
//代码输出目录
gc.setOutputDir(outputDir + "/src/main/java");
//开发人员
gc.setAuthor(author);
gc.setFileOverride(true);
//是否打开输出目录
gc.setOpen(false);
gc.setActiveRecord(false);
gc.setEnableCache(false);
//Mybatis Mapping.xml中增加BaseResult和BaseColumn
gc.setBaseResultMap(true);
gc.setBaseColumnList(true);
/*gc.setMapperName("%sMapper");
gc.setXmlName("%sMapping");
gc.setServiceName("I%sService");
gc.setServiceImplName("%sServiceImpl");
gc.setControllerName("%sController");*/
gc.setSwagger2(isSwagger2);
mpg.setGlobalConfig(gc);
//数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setDriverName(this.driverName);
dsc.setUrl(this.url);
dsc.setUsername(this.username);
dsc.setPassword(this.password);
if (this.driverName.contains(DbType.MYSQL.getDb())) {
dsc.setDbType(DbType.MYSQL);
dsc.setTypeConvert(new MySqlTypeConvert());
} else if (this.driverName.contains(DbType.POSTGRE_SQL.getDb())) {
dsc.setDbType(DbType.POSTGRE_SQL);
dsc.setTypeConvert(new PostgreSqlTypeConvert());
} else if (this.driverName.contains(DbType.SQL_SERVER.getDb())) {
dsc.setDbType(DbType.SQL_SERVER);
dsc.setTypeConvert(new SqlServerTypeConvert());
} else if (this.driverName.contains(DbType.ORACLE.getDb())) {
dsc.setDbType(DbType.ORACLE);
dsc.setTypeConvert(new OracleTypeConvert());
} else if (this.driverName.contains(DbType.DM.getDb())) {
dsc.setDbType(DbType.DM);
dsc.setSchemaName(this.scheme);
dsc.setTypeConvert(new DmTypeConvert());
} else {
System.out.println("数据库类型异常,代码生成失败!");
return;
}
mpg.setDataSource(dsc);
// 策略配置
StrategyConfig strategy = new StrategyConfig();
// strategy.setCapitalMode(true);// 全局大写命名
// strategy.setDbColumnUnderline(true);//全局下划线命名
strategy.setNaming(NamingStrategy.underline_to_camel);
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
// strategy.setTablePrefix(tablePrefix);
if (includeTables.length > 0) {
strategy.setInclude(includeTables);
}
if (excludeTables.length > 0) {
strategy.setExclude(excludeTables);
}
// 自定义 controller 父类
strategy.setEntityBuilderModel(false);
strategy.setEntityLombokModel(true);
strategy.setRestControllerStyle(true);
strategy.setControllerMappingHyphenStyle(true);
mpg.setStrategy(strategy);
// 包配置
PackageConfig pc = new PackageConfig();
// 控制台扫描
pc.setModuleName(null);
//父包名
pc.setParent("com.zhangy.skyeye.service.manager");
//controller包名
// pc.setController("controller");
// //entity包名
// pc.setEntity("entity");
// //mapping包名
// pc.setXml("mapping");
mpg.setPackageInfo(pc);
//自定义配置
InjectionConfig injectionConfig = new InjectionConfig() {
@Override
public void initMap() {
}
};
//如果模板引擎是 freemarker
//String templatePath = "/templates/mapping.xml.ftl";
// 如果模板引擎是 velocity
String templatePath = "/templates/mapping.xml.vm";
// 自定义输出配置
List<FileOutConfig> focList = new ArrayList<>();
// 自定义配置会被优先输出
focList.add(new FileOutConfig(templatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
// 自定义输出文件名 如果你 Entity 设置了前后缀此处注意 xml 的名称会跟着发生变化
return outputDir + "/src/main/resources/mapping/"
+ tableInfo.getEntityName() + "Mapping" + StringPool.DOT_XML;
}
});
injectionConfig.setFileOutConfigList(focList);
mpg.setCfg(injectionConfig);
// 配置模板
TemplateConfig templateConfig = new TemplateConfig();
// 配置自定义输出模板
//指定自定义模板路径注意不要带上.ftl/.vm, 会根据使用的模板引擎自动识别
// templateConfig.setEntity("templates/entity2.java");
// templateConfig.setService();
// templateConfig.setController();
templateConfig.setXml(null);
mpg.setTemplate(templateConfig);
mpg.execute();
}
public static void main(String[] args) {
GeneratorApi_DM generator = new GeneratorApi_DM();
//数据库驱动名
generator.setDriverName("dm.jdbc.driver.DmDriver");
//数据库链接地址
// generator.setUrl("jdbc:mysql://dt-mysql:3306/dt-chuangpu?autoReconnect=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=false");
// generator.setUrl("jdbc:mysql://dt-mysql:3306/dt-env?autoReconnect=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=false");
// generator.setUrl("jdbc:mysql://dt-mysql:3306/dt-pggc?autoReconnect=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=false");
// generator.setUrl("jdbc:dm://192.168.127.129:5237");
// generator.setUrl("jdbc:dm://192.168.1.60:5236");
generator.setUrl("jdbc:dm://localhost:5236");
//
// generator.setScheme("TGKY");
//
// //数据库用户名
// generator.setUsername("SYSDBA");
// //数据库密码
// generator.setPassword("123456789");
//
// //输出文件目录
// generator.setOutputDir("D://generator");
// //作者
// generator.setAuthor("wj");
// generator.setUrl("jdbc:dm://192.168.1.60:5236");
generator.setScheme("TGKY");
//数据库用户名
generator.setUsername("SYSDBA");
//数据库密码
generator.setPassword("123456789");
//输出文件目录
generator.setOutputDir("D://generator");
//作者
generator.setAuthor("wj");
//代码生成的包名
// //需要生成的表名(两者只能取其一)
// generator.setIncludeTables(("env_goes_electron").replaceAll(" ", "").split(","));
// String [] includeTables = {"user","sysuser","student","coach","sportevents","student_events"};
// generator.setIncludeTables(includeTables);
// String [] includeTables = {"ATMO_ENVIRONMENT_BACKGROUND" ,"ATMO_ENVIRONMENT_INIT_EVENT","ATMO_ENVIRONMENT_SPECIFIC"};
String [] includeTables = {"ZHIKONG_TASK"};
generator.setIncludeTables(includeTables);
//需要排除的表名(两者只能取其一)
generator.setExcludeTables(new String[]{});
generator.run();
// GeneratorApi generator = new GeneratorApi();
//
// //数据库驱动名
// generator.setDriverName("com.mysql.cj.jdbc.Driver");
// //数据库链接地址
// generator.setUrl("jdbc:mysql://dt-mysql:3306/dt-manager?autoReconnect=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=false");
// //数据库用户名
// generator.setUsername("root");
// //数据库密码
// generator.setPassword("123456");
//
// //输出文件目录
// generator.setOutputDir("D://generator");
// //作者
// generator.setAuthor("wj");
// //代码生成的包名
// //需要生成的表名(两者只能取其一)
// generator.setIncludeTables(("res_wj_emp").replaceAll(" ", "").split(","));
// //需要排除的表名(两者只能取其一)
// generator.setExcludeTables(new String[]{});
// generator.run();
}
}

View File

@ -0,0 +1,134 @@
package ${package.Controller};
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.web.bind.annotation.*;
#if(${restControllerStyle})
#else
import org.springframework.stereotype.Controller;
#end
#if(${superControllerClassPackage})
import ${superControllerClassPackage};
#end
#if(${swagger2})
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
#end
#if(${entityLombokModel})
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
#end
import $!{package.Entity}.$!{entity};
import $!{package.Service}.$!{table.serviceName};
import com.zhangy.skyeye.common.pojo.result.Result;
import com.zhangy.skyeye.common.pojo.param.IdParam;
import com.zhangy.skyeye.db.utils.MPUtil;
import com.zhangy.skyeye.db.pojo.page.PageParam;
import java.util.List;
/**
* $!{table.comment} 前端控制器
*
* @author ${author}
* @since ${date}
*/
#if(${restControllerStyle})
@RestController
#else
@Controller
#end
@AllArgsConstructor
@Slf4j
@Api(value = "$!{table.comment}", tags = "$!{table.comment}接口")
@RequestMapping("#if(${controllerMappingHyphenStyle})${controllerMappingHyphen}#else${table.entityPath}#end")
#if(${superControllerClass})
public class ${table.controllerName} extends ${superControllerClass} {
#else
public class ${table.controllerName} {
#end
private $!{table.serviceName} $!{table.entityPath}Service;
/**
* 新增
*/
@PostMapping("/save")
@ApiOperationSupport(order = 1)
@ApiOperation(value = "新增", notes = "传入$!{table.entityPath}")
public Result save(@RequestBody $!{entity} $!{table.entityPath}) {
if($!{table.entityPath} == null){
return Result.error("参数异常");
}
return Result.status($!{table.entityPath}Service.save($!{table.entityPath}));
}
/**
* 修改 $!{table.comment}
*/
@PostMapping("/update")
@ApiOperationSupport(order = 2)
@ApiOperation(value = "修改", notes = "传入$!{table.entityPath}")
public Result update(@RequestBody $!{entity} $!{table.entityPath}) {
if($!{table.entityPath} == null){
return Result.error("参数异常");
}
return Result.status($!{table.entityPath}Service.updateById($!{table.entityPath}));
}
/**
* 删除 $!{table.comment}
*/
@PostMapping("/remove")
@ApiOperationSupport(order = 3)
@ApiOperation(value = "删除", notes = "传入ids")
public Result remove(@RequestBody IdParam<Long> idParam) {
if(idParam == null){
return Result.error("参数异常!");
}
return Result.status($!{table.entityPath}Service.removeByIds(idParam.getIds()));
}
/**
* 详情
*/
@GetMapping("/detail")
@ApiOperationSupport(order = 4)
@ApiOperation(value = "详情", notes = "传入id")
public Result<$!{entity}> detail(Long id) {
if(id == null){
return Result.error("参数异常");
}
$!{entity} detail = $!{table.entityPath}Service.getById(id);
return Result.successData(detail);
}
/**
* 查询 $!{table.comment}
*/
@GetMapping("/list")
@ApiOperationSupport(order = 5)
@ApiOperation(value = "查询", notes = "传入$!{table.entityPath}")
public Result list(PageParam pageParam, $!{entity} $!{table.entityPath}) {
List<$!{entity}> list = $!{table.entityPath}Service.list($!{table.entityPath}Service.getQueryWrapper(pageParam, $!{table.entityPath}));
return Result.successData(list);
}
/**
* 分页 $!{table.comment}
*/
@GetMapping("/page")
@ApiOperationSupport(order = 6)
@ApiOperation(value = "分页", notes = "传入$!{table.entityPath}")
public Result<IPage> page(PageParam pageParam, $!{entity} $!{table.entityPath}) {
IPage<$!{entity}> pages = $!{table.entityPath}Service.page(
MPUtil.getPage(pageParam),
$!{table.entityPath}Service.getQueryWrapper(null, $!{table.entityPath})
);
return Result.successData(pages);
}
}

View File

@ -0,0 +1,158 @@
package ${package.Entity};
#foreach($pkg in ${table.importPackages})
import ${pkg};
#end
#if(${swagger2})
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
#end
#if(${entityLombokModel})
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
#if(${chainModel})
import lombok.experimental.Accessors;
#end
#end
/**
* $!{table.comment}
*
* @author ${author}
* @since ${date}
*/
#if(${entityLombokModel})
@Data
@AllArgsConstructor
@NoArgsConstructor
#if(${superEntityClass})
@EqualsAndHashCode(callSuper = true)
#else
@EqualsAndHashCode(callSuper = false)
#end
#if(${chainModel})
@Accessors(chain = true)
#end
#end
#if(${table.convert})
@TableName("${table.name}")
#end
#if(${swagger2})
@ApiModel(value="${entity}对象", description="$!{table.comment}")
#end
#if(${superEntityClass})
public class ${entity} extends ${superEntityClass}#if(${activeRecord})<${entity}>#end {
#elseif(${activeRecord})
public class ${entity} extends Model<${entity}> {
#else
public class ${entity} implements Serializable {
#end
#if(${entitySerialVersionUID})
private static final long serialVersionUID = 1L;
#end
## ---------- BEGIN 字段循环遍历 ----------
#foreach($field in ${table.fields})
#if(${field.keyFlag})
#set($keyPropertyName=${field.propertyName})
#end
#if("$!field.comment" != "")
#if(${swagger2})
@ApiModelProperty(value = "${field.comment}", position = ${foreach.index})
#else
/**
* ${field.comment}
*/
#end
#end
#if(${field.keyFlag})
## 主键
#if(${field.keyIdentityFlag})
@TableId(value = "${field.annotationColumnName}", type = IdType.AUTO)
#elseif(!$null.isNull(${idType}) && "$!idType" != "")
@TableId(value = "${field.annotationColumnName}", type = IdType.${idType})
#elseif(${field.convert})
@TableId("${field.annotationColumnName}")
#end
## 普通字段
#elseif(${field.fill})
## ----- 存在字段填充设置 -----
#if(${field.convert})
@TableField(value = "${field.annotationColumnName}", fill = FieldFill.${field.fill})
#else
@TableField(fill = FieldFill.${field.fill})
#end
#elseif(${field.convert})
@TableField("${field.annotationColumnName}")
#end
## 乐观锁注解
#if(${versionFieldName}==${field.name})
@Version
#end
## 逻辑删除注解
#if(${logicDeleteFieldName}==${field.name})
@TableLogic
#end
private ${field.propertyType} ${field.propertyName};
#end
## ---------- END 字段循环遍历 ----------
#if(!${entityLombokModel})
#foreach($field in ${table.fields})
#if(${field.propertyType.equals("boolean")})
#set($getprefix="is")
#else
#set($getprefix="get")
#end
public ${field.propertyType} ${getprefix}${field.capitalName}() {
return ${field.propertyName};
}
#if(${chainModel})
public ${entity} set${field.capitalName}(${field.propertyType} ${field.propertyName}) {
#else
public void set${field.capitalName}(${field.propertyType} ${field.propertyName}) {
#end
this.${field.propertyName} = ${field.propertyName};
#if(${chainModel})
return this;
#end
}
#end
## --foreach end---
#end
## --end of #if(!${entityLombokModel})--
#if(${entityColumnConstant})
#foreach($field in ${table.fields})
public static final String ${field.name.toUpperCase()} = "${field.name}";
#end
#end
#if(${activeRecord})
@Override
protected Serializable pkVal() {
#if(${keyPropertyName})
return this.${keyPropertyName};
#else
return null;
#end
}
#end
#if(!${entityLombokModel})
@Override
public String toString() {
return "${entity}{" +
#foreach($field in ${table.fields})
#if($!{foreach.index}==0)
"${field.propertyName}=" + ${field.propertyName} +
#else
", ${field.propertyName}=" + ${field.propertyName} +
#end
#end
"}";
}
#end
}

View File

@ -0,0 +1,14 @@
package ${package.Mapper};
import ${package.Entity}.${entity};
import ${superMapperClassPackage};
/**
* $!{table.comment} Mapper 接口
*
* @author ${author}
* @since ${date}
*/
public interface ${table.mapperName} extends ${superMapperClass}<${entity}> {
}

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="${package.Mapper}.${table.mapperName}">
#if(${enableCache})
<!-- 开启二级缓存 -->
<cache type="org.mybatis.caches.ehcache.LoggingEhcache"/>
#end
#if(${baseResultMap})
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="${package.Entity}.${entity}">
#foreach($field in ${table.fields})
#if(${field.keyFlag})##生成主键排在第一位
<id column="${field.name}" property="${field.propertyName}" />
#end
#end
#foreach($field in ${table.commonFields})##生成公共字段
<result column="${field.name}" property="${field.propertyName}" />
#end
#foreach($field in ${table.fields})
#if(!${field.keyFlag})##生成普通字段
<result column="${field.name}" property="${field.propertyName}" />
#end
#end
</resultMap>
#end
#if(${baseColumnList})
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
#foreach($field in ${table.commonFields})
${field.columnName},
#end
${table.fieldNames}
</sql>
#end
</mapper>

View File

@ -0,0 +1,24 @@
package ${package.Service};
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zhangy.skyeye.db.pojo.page.PageParam;
import ${package.Entity}.${entity};
import ${superServiceClassPackage};
/**
* $!{table.comment} 服务类
*
* @author ${author}
* @since ${date}
*/
public interface ${table.serviceName} extends ${superServiceClass}<${entity}> {
/**
* 通过实体类获取QueryWrapper
* @param pageParam 分页参数
* @param $!{table.entityPath} 实体信息
* @return
*/
QueryWrapper<$!{entity}> getQueryWrapper(PageParam pageParam, $!{entity} $!{table.entityPath});
}

View File

@ -0,0 +1,60 @@
package ${package.ServiceImpl};
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zhangy.skyeye.db.pojo.page.PageParam;
import com.zhangy.skyeye.db.utils.MPUtil;
import ${package.Entity}.${entity};
import ${package.Mapper}.${table.mapperName};
import ${package.Service}.${table.serviceName};
import ${superServiceImplClassPackage};
import org.springframework.stereotype.Service;
/**
* $!{table.comment} 服务实现类
*
* @author ${author}
* @since ${date}
*/
@Service
public class ${table.serviceImplName} extends ${superServiceImplClass}<${table.mapperName}, ${entity}> implements ${table.serviceName} {
/**
* 通过实体类获取QueryWrapper
* @param pageParam 分页参数
* @param $!{table.entityPath} 实体信息
* @return
*/
@Override
public QueryWrapper<$!{entity}> getQueryWrapper(PageParam pageParam, $!{entity} $!{table.entityPath}){
QueryWrapper<$!{entity}> queryWrapper = MPUtil.getQueryWrapper(pageParam);
if($!{table.entityPath} == null){
return queryWrapper;
}
#foreach($field in ${table.fields})
## 主键
#if(${field.keyIdentityFlag})
//主键
if($!{table.entityPath}.get${field.capitalName}() != null){
queryWrapper.lambda()
.eq($!{entity}::get${field.capitalName}, $!{table.entityPath}.get${field.capitalName}());
return queryWrapper;
}
#end
#end
//TODO 此处可以根据各字段查询需求修改查询条件eq、like、ge、gt、le、lt、ne...等等等
queryWrapper.lambda()
#foreach($field in ${table.fields})
#if(!${field.keyIdentityFlag})
#if($!{foreach.last})
.eq($!{table.entityPath}.get${field.capitalName}() != null, $!{entity}::get${field.capitalName}, $!{table.entityPath}.get${field.capitalName}());
#else
.eq($!{table.entityPath}.get${field.capitalName}() != null, $!{entity}::get${field.capitalName}, $!{table.entityPath}.get${field.capitalName}())
#end
#end
#end
return queryWrapper;
}
}

View File

@ -0,0 +1,134 @@
package ${package.Controller};
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.web.bind.annotation.*;
#if(${restControllerStyle})
#else
import org.springframework.stereotype.Controller;
#end
#if(${superControllerClassPackage})
import ${superControllerClassPackage};
#end
#if(${swagger2})
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
#end
#if(${entityLombokModel})
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
#end
import $!{package.Entity}.$!{entity};
import $!{package.Service}.$!{table.serviceName};
import com.zhangy.skyeye.common.pojo.result.Result;
import com.zhangy.skyeye.common.pojo.param.IdParam;
import com.zhangy.skyeye.db.utils.MPUtil;
import com.zhangy.skyeye.db.pojo.page.PageParam;
import java.util.List;
/**
* $!{table.comment} 前端控制器
*
* @author ${author}
* @since ${date}
*/
#if(${restControllerStyle})
@RestController
#else
@Controller
#end
@AllArgsConstructor
@Slf4j
@Api(value = "$!{table.comment}", tags = "$!{table.comment}接口")
@RequestMapping("#if(${controllerMappingHyphenStyle})${controllerMappingHyphen}#else${table.entityPath}#end")
#if(${superControllerClass})
public class ${table.controllerName} extends ${superControllerClass} {
#else
public class ${table.controllerName} {
#end
private $!{table.serviceName} $!{table.entityPath}Service;
/**
* 新增
*/
@PostMapping("/save")
@ApiOperationSupport(order = 1)
@ApiOperation(value = "新增", notes = "传入$!{table.entityPath}")
public Result save(@RequestBody $!{entity} $!{table.entityPath}) {
if($!{table.entityPath} == null){
return Result.error("参数异常");
}
return Result.status($!{table.entityPath}Service.save($!{table.entityPath}));
}
/**
* 修改 $!{table.comment}
*/
@PostMapping("/update")
@ApiOperationSupport(order = 2)
@ApiOperation(value = "修改", notes = "传入$!{table.entityPath}")
public Result update(@RequestBody $!{entity} $!{table.entityPath}) {
if($!{table.entityPath} == null){
return Result.error("参数异常");
}
return Result.status($!{table.entityPath}Service.updateById($!{table.entityPath}));
}
/**
* 删除 $!{table.comment}
*/
@PostMapping("/remove")
@ApiOperationSupport(order = 3)
@ApiOperation(value = "删除", notes = "传入ids")
public Result remove(@RequestBody IdParam<Long> idParam) {
if(idParam == null){
return Result.error("参数异常!");
}
return Result.status($!{table.entityPath}Service.removeByIds(idParam.getIds()));
}
/**
* 详情
*/
@GetMapping("/detail")
@ApiOperationSupport(order = 4)
@ApiOperation(value = "详情", notes = "传入id")
public Result<$!{entity}> detail(Long id) {
if(id == null){
return Result.error("参数异常");
}
$!{entity} detail = $!{table.entityPath}Service.getById(id);
return Result.successData(detail);
}
/**
* 查询 $!{table.comment}
*/
@GetMapping("/list")
@ApiOperationSupport(order = 5)
@ApiOperation(value = "查询", notes = "传入$!{table.entityPath}")
public Result list(PageParam pageParam, $!{entity} $!{table.entityPath}) {
List<$!{entity}> list = $!{table.entityPath}Service.list($!{table.entityPath}Service.getQueryWrapper(pageParam, $!{table.entityPath}));
return Result.successData(list);
}
/**
* 分页 $!{table.comment}
*/
@GetMapping("/page")
@ApiOperationSupport(order = 6)
@ApiOperation(value = "分页", notes = "传入$!{table.entityPath}")
public Result<IPage> page(PageParam pageParam, $!{entity} $!{table.entityPath}) {
IPage<$!{entity}> pages = $!{table.entityPath}Service.page(
MPUtil.getPage(pageParam),
$!{table.entityPath}Service.getQueryWrapper(null, $!{table.entityPath})
);
return Result.successData(pages);
}
}

View File

@ -0,0 +1,158 @@
package ${package.Entity};
#foreach($pkg in ${table.importPackages})
import ${pkg};
#end
#if(${swagger2})
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
#end
#if(${entityLombokModel})
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
#if(${chainModel})
import lombok.experimental.Accessors;
#end
#end
/**
* $!{table.comment}
*
* @author ${author}
* @since ${date}
*/
#if(${entityLombokModel})
@Data
@AllArgsConstructor
@NoArgsConstructor
#if(${superEntityClass})
@EqualsAndHashCode(callSuper = true)
#else
@EqualsAndHashCode(callSuper = false)
#end
#if(${chainModel})
@Accessors(chain = true)
#end
#end
#if(${table.convert})
@TableName("${table.name}")
#end
#if(${swagger2})
@ApiModel(value="${entity}对象", description="$!{table.comment}")
#end
#if(${superEntityClass})
public class ${entity} extends ${superEntityClass}#if(${activeRecord})<${entity}>#end {
#elseif(${activeRecord})
public class ${entity} extends Model<${entity}> {
#else
public class ${entity} implements Serializable {
#end
#if(${entitySerialVersionUID})
private static final long serialVersionUID = 1L;
#end
## ---------- BEGIN 字段循环遍历 ----------
#foreach($field in ${table.fields})
#if(${field.keyFlag})
#set($keyPropertyName=${field.propertyName})
#end
#if("$!field.comment" != "")
#if(${swagger2})
@ApiModelProperty(value = "${field.comment}", position = ${foreach.index})
#else
/**
* ${field.comment}
*/
#end
#end
#if(${field.keyFlag})
## 主键
#if(${field.keyIdentityFlag})
@TableId(value = "${field.annotationColumnName}", type = IdType.AUTO)
#elseif(!$null.isNull(${idType}) && "$!idType" != "")
@TableId(value = "${field.annotationColumnName}", type = IdType.${idType})
#elseif(${field.convert})
@TableId("${field.annotationColumnName}")
#end
## 普通字段
#elseif(${field.fill})
## ----- 存在字段填充设置 -----
#if(${field.convert})
@TableField(value = "${field.annotationColumnName}", fill = FieldFill.${field.fill})
#else
@TableField(fill = FieldFill.${field.fill})
#end
#elseif(${field.convert})
@TableField("${field.annotationColumnName}")
#end
## 乐观锁注解
#if(${versionFieldName}==${field.name})
@Version
#end
## 逻辑删除注解
#if(${logicDeleteFieldName}==${field.name})
@TableLogic
#end
private ${field.propertyType} ${field.propertyName};
#end
## ---------- END 字段循环遍历 ----------
#if(!${entityLombokModel})
#foreach($field in ${table.fields})
#if(${field.propertyType.equals("boolean")})
#set($getprefix="is")
#else
#set($getprefix="get")
#end
public ${field.propertyType} ${getprefix}${field.capitalName}() {
return ${field.propertyName};
}
#if(${chainModel})
public ${entity} set${field.capitalName}(${field.propertyType} ${field.propertyName}) {
#else
public void set${field.capitalName}(${field.propertyType} ${field.propertyName}) {
#end
this.${field.propertyName} = ${field.propertyName};
#if(${chainModel})
return this;
#end
}
#end
## --foreach end---
#end
## --end of #if(!${entityLombokModel})--
#if(${entityColumnConstant})
#foreach($field in ${table.fields})
public static final String ${field.name.toUpperCase()} = "${field.name}";
#end
#end
#if(${activeRecord})
@Override
protected Serializable pkVal() {
#if(${keyPropertyName})
return this.${keyPropertyName};
#else
return null;
#end
}
#end
#if(!${entityLombokModel})
@Override
public String toString() {
return "${entity}{" +
#foreach($field in ${table.fields})
#if($!{foreach.index}==0)
"${field.propertyName}=" + ${field.propertyName} +
#else
", ${field.propertyName}=" + ${field.propertyName} +
#end
#end
"}";
}
#end
}

View File

@ -0,0 +1,14 @@
package ${package.Mapper};
import ${package.Entity}.${entity};
import ${superMapperClassPackage};
/**
* $!{table.comment} Mapper 接口
*
* @author ${author}
* @since ${date}
*/
public interface ${table.mapperName} extends ${superMapperClass}<${entity}> {
}

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="${package.Mapper}.${table.mapperName}">
#if(${enableCache})
<!-- 开启二级缓存 -->
<cache type="org.mybatis.caches.ehcache.LoggingEhcache"/>
#end
#if(${baseResultMap})
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="${package.Entity}.${entity}">
#foreach($field in ${table.fields})
#if(${field.keyFlag})##生成主键排在第一位
<id column="${field.name}" property="${field.propertyName}" />
#end
#end
#foreach($field in ${table.commonFields})##生成公共字段
<result column="${field.name}" property="${field.propertyName}" />
#end
#foreach($field in ${table.fields})
#if(!${field.keyFlag})##生成普通字段
<result column="${field.name}" property="${field.propertyName}" />
#end
#end
</resultMap>
#end
#if(${baseColumnList})
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
#foreach($field in ${table.commonFields})
${field.columnName},
#end
${table.fieldNames}
</sql>
#end
</mapper>

View File

@ -0,0 +1,24 @@
package ${package.Service};
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zhangy.skyeye.db.pojo.page.PageParam;
import ${package.Entity}.${entity};
import ${superServiceClassPackage};
/**
* $!{table.comment} 服务类
*
* @author ${author}
* @since ${date}
*/
public interface ${table.serviceName} extends ${superServiceClass}<${entity}> {
/**
* 通过实体类获取QueryWrapper
* @param pageParam 分页参数
* @param $!{table.entityPath} 实体信息
* @return
*/
QueryWrapper<$!{entity}> getQueryWrapper(PageParam pageParam, $!{entity} $!{table.entityPath});
}

View File

@ -0,0 +1,60 @@
package ${package.ServiceImpl};
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zhangy.skyeye.db.pojo.page.PageParam;
import com.zhangy.skyeye.db.utils.MPUtil;
import ${package.Entity}.${entity};
import ${package.Mapper}.${table.mapperName};
import ${package.Service}.${table.serviceName};
import ${superServiceImplClassPackage};
import org.springframework.stereotype.Service;
/**
* $!{table.comment} 服务实现类
*
* @author ${author}
* @since ${date}
*/
@Service
public class ${table.serviceImplName} extends ${superServiceImplClass}<${table.mapperName}, ${entity}> implements ${table.serviceName} {
/**
* 通过实体类获取QueryWrapper
* @param pageParam 分页参数
* @param $!{table.entityPath} 实体信息
* @return
*/
@Override
public QueryWrapper<$!{entity}> getQueryWrapper(PageParam pageParam, $!{entity} $!{table.entityPath}){
QueryWrapper<$!{entity}> queryWrapper = MPUtil.getQueryWrapper(pageParam);
if($!{table.entityPath} == null){
return queryWrapper;
}
#foreach($field in ${table.fields})
## 主键
#if(${field.keyIdentityFlag})
//主键
if($!{table.entityPath}.get${field.capitalName}() != null){
queryWrapper.lambda()
.eq($!{entity}::get${field.capitalName}, $!{table.entityPath}.get${field.capitalName}());
return queryWrapper;
}
#end
#end
//TODO 此处可以根据各字段查询需求修改查询条件eq、like、ge、gt、le、lt、ne...等等等
queryWrapper.lambda()
#foreach($field in ${table.fields})
#if(!${field.keyIdentityFlag})
#if($!{foreach.last})
.eq($!{table.entityPath}.get${field.capitalName}() != null, $!{entity}::get${field.capitalName}, $!{table.entityPath}.get${field.capitalName}());
#else
.eq($!{table.entityPath}.get${field.capitalName}() != null, $!{entity}::get${field.capitalName}, $!{table.entityPath}.get${field.capitalName}())
#end
#end
#end
return queryWrapper;
}
}

View File

@ -0,0 +1,3 @@
artifactId=skyeye-common-generator
groupId=com.zhangy
version=1.0.0.RELEASE

View File

@ -0,0 +1,6 @@
com\zhangy\skyeye\common\generator\GeneratorApi_DM$2.class
com\zhangy\skyeye\common\generator\GeneratorApi$1.class
com\zhangy\skyeye\common\generator\GeneratorApi_DM.class
com\zhangy\skyeye\common\generator\GeneratorApi_DM$1.class
com\zhangy\skyeye\common\generator\GeneratorApi$2.class
com\zhangy\skyeye\common\generator\GeneratorApi.class

Some files were not shown because too many files have changed in this diff Show More