linxk il y a 1 mois
commit
8f1f2cee02
80 fichiers modifiés avec 6270 ajouts et 0 suppressions
  1. 27 0
      .gitignore
  2. 1 0
      README.md
  3. 1 0
      deploy.bat
  4. 1 0
      eclipse.bat
  5. 1 0
      install.bat
  6. 105 0
      logs/mall/error.operating.log.2025-07-09.log
  7. 217 0
      logs/mall/log.operating.2025-07-09.0.log
  8. 72 0
      logs/operating/error.operating.log.2025-07-09.log
  9. 64 0
      logs/operating/log.operating.2025-07-09.0.log
  10. 62 0
      mall-api/pom.xml
  11. 57 0
      mall-api/src/main/java/com/txz/mall/AppModuleBO.java
  12. 16 0
      mall-api/src/main/resources/i18n/error.properties
  13. 16 0
      mall-api/src/main/resources/i18n/error_in_ID.properties
  14. 122 0
      mall-service/pom.xml
  15. 19 0
      mall-service/src/main/java/com/txz/mall/FeignConfiguration.java
  16. 51 0
      mall-service/src/main/java/com/txz/mall/MallApplication.java
  17. 43 0
      mall-service/src/main/java/com/txz/mall/configurer/HeaderAttribute.java
  18. 45 0
      mall-service/src/main/java/com/txz/mall/configurer/IpConfiguration.java
  19. 252 0
      mall-service/src/main/java/com/txz/mall/configurer/MyWebMvcConfigurer.java
  20. 49 0
      mall-service/src/main/java/com/txz/mall/configurer/MybatisConfigurer.java
  21. 47 0
      mall-service/src/main/java/com/txz/mall/configurer/Parameters.java
  22. 21 0
      mall-service/src/main/java/com/txz/mall/configurer/RibbonWeightedResponseTimeRuleConfig.java
  23. 65 0
      mall-service/src/main/java/com/txz/mall/configurer/SwaggerConfig.java
  24. 101 0
      mall-service/src/main/java/com/txz/mall/configurer/log/WebLogAspect.java
  25. 49 0
      mall-service/src/main/java/com/txz/mall/configurer/shutdown/GracefulShutdownUndertow.java
  26. 29 0
      mall-service/src/main/java/com/txz/mall/configurer/shutdown/GracefulShutdownUndertowWrapper.java
  27. 27 0
      mall-service/src/main/java/com/txz/mall/configurer/shutdown/UndertowExtraConfiguration.java
  28. 16 0
      mall-service/src/main/java/com/txz/mall/constants/MyConstants.java
  29. 38 0
      mall-service/src/main/java/com/txz/mall/constants/RedisConstants.java
  30. 83 0
      mall-service/src/main/java/com/txz/mall/core/AbstractService.java
  31. 17 0
      mall-service/src/main/java/com/txz/mall/core/Mapper.java
  32. 47 0
      mall-service/src/main/java/com/txz/mall/core/MessageTemplteType.java
  33. 39 0
      mall-service/src/main/java/com/txz/mall/core/MyPageInfo.java
  34. 29 0
      mall-service/src/main/java/com/txz/mall/core/ProjectConstant.java
  35. 542 0
      mall-service/src/main/java/com/txz/mall/core/RedisUtil.java
  36. 102 0
      mall-service/src/main/java/com/txz/mall/core/Result.java
  37. 138 0
      mall-service/src/main/java/com/txz/mall/core/ResultCode.java
  38. 36 0
      mall-service/src/main/java/com/txz/mall/core/ResultGenerator.java
  39. 22 0
      mall-service/src/main/java/com/txz/mall/core/Service.java
  40. 29 0
      mall-service/src/main/java/com/txz/mall/core/ServiceException.java
  41. 57 0
      mall-service/src/main/java/com/txz/mall/core/SmsTempletType.java
  42. 34 0
      mall-service/src/main/java/com/txz/mall/core/cache/CacheKey.java
  43. 38 0
      mall-service/src/main/java/com/txz/mall/core/cache/CacheType.java
  44. 35 0
      mall-service/src/main/java/com/txz/mall/core/cache/lock/AbstractDistributedLock.java
  45. 93 0
      mall-service/src/main/java/com/txz/mall/core/cache/lock/DistributedLock.java
  46. 101 0
      mall-service/src/main/java/com/txz/mall/core/cache/lock/RedisDistributedLock.java
  47. 7 0
      mall-service/src/main/java/com/txz/mall/dao/AppModuleMapper.java
  48. 52 0
      mall-service/src/main/java/com/txz/mall/enums/ActivityTypeEnum.java
  49. 64 0
      mall-service/src/main/java/com/txz/mall/model/AppModule.java
  50. 158 0
      mall-service/src/main/java/com/txz/mall/mq/rocket/consumer/Consumers.java
  51. 33 0
      mall-service/src/main/java/com/txz/mall/mq/rocket/consumer/TestConsumerListener.java
  52. 23 0
      mall-service/src/main/java/com/txz/mall/mq/rocket/consumer/message/MyMessage.java
  53. 26 0
      mall-service/src/main/java/com/txz/mall/mq/rocket/producer/Producers.java
  54. 11 0
      mall-service/src/main/java/com/txz/mall/service/AppModuleService.java
  55. 22 0
      mall-service/src/main/java/com/txz/mall/service/impl/AppModuleServiceImpl.java
  56. 142 0
      mall-service/src/main/java/com/txz/mall/task/SchoolCodeTask.java
  57. 104 0
      mall-service/src/main/java/com/txz/mall/util/IpUtils.java
  58. 25 0
      mall-service/src/main/java/com/txz/mall/util/MyDateUtil.java
  59. 22 0
      mall-service/src/main/java/com/txz/mall/web/NoticeApiController.java
  60. 110 0
      mall-service/src/main/java/com/txz/mall/web/param/NoticeParam.java
  61. 61 0
      mall-service/src/main/resources/bootstrap.properties
  62. 81 0
      mall-service/src/main/resources/logback.xml
  63. 21 0
      mall-service/src/main/resources/mapper/AppModuleMapper.xml
  64. 425 0
      mall-service/src/test/java/CodeGenerator.java
  65. 18 0
      mall-service/src/test/java/com/Test1111.java
  66. 313 0
      mall-service/src/test/java/com/conpany/project/MyCommentGenerator.java
  67. 110 0
      mall-service/src/test/java/com/conpany/project/SerializablePlugin.java
  68. 52 0
      mall-service/src/test/java/com/conpany/project/TestRedis.java
  69. 20 0
      mall-service/src/test/java/com/conpany/project/Tester.java
  70. 45 0
      mall-service/src/test/resources/demo-user.sql
  71. 27 0
      mall-service/src/test/resources/generator/template/client.ftl
  72. 55 0
      mall-service/src/test/resources/generator/template/controller-restful.ftl
  73. 144 0
      mall-service/src/test/resources/generator/template/controller.ftl
  74. 10 0
      mall-service/src/test/resources/generator/template/dto.ftl
  75. 22 0
      mall-service/src/test/resources/generator/template/service-impl.ftl
  76. 11 0
      mall-service/src/test/resources/generator/template/service.ftl
  77. 443 0
      mall-service/src/test/resources/operating20200818pro.sql
  78. 485 0
      mall-service/src/test/resources/operating20201027pro.sql
  79. 1 0
      package.bat
  80. 71 0
      pom.xml

+ 27 - 0
.gitignore

@@ -0,0 +1,27 @@
+/target/
+!.mvn/wrapper/maven-wrapper.jar
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+/build/
+target/
+/spy.log

+ 1 - 0
README.md

@@ -0,0 +1 @@
+111

+ 1 - 0
deploy.bat

@@ -0,0 +1 @@
+cmd /k mvn deploy -DskipTests

+ 1 - 0
eclipse.bat

@@ -0,0 +1 @@
+cmd /k mvn clean eclipse:clean eclipse:eclipse -DdownloadSources=true -DdownloadJavadocs=true

+ 1 - 0
install.bat

@@ -0,0 +1 @@
+cmd /k mvn install -Dmaven.test.skip=true

+ 105 - 0
logs/mall/error.operating.log.2025-07-09.log

@@ -0,0 +1,105 @@
+2025-07-09 15:20:09.112 [RMI TCP Connection(4)-192.168.0.102] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization.
+com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Could not create connection to database server. Attempted reconnect 3 times. Giving up.
+	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
+	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
+	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
+	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
+	at com.mysql.jdbc.Util.handleNewInstance(Util.java:425)
+	at com.mysql.jdbc.Util.getInstance(Util.java:408)
+	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:919)
+	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:898)
+	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:887)
+	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:861)
+	at com.mysql.jdbc.ConnectionImpl.connectWithRetries(ConnectionImpl.java:2105)
+	at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2030)
+	at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:778)
+	at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:47)
+	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
+	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
+	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
+	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
+	at com.mysql.jdbc.Util.handleNewInstance(Util.java:425)
+	at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:386)
+	at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:330)
+	at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:117)
+	at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:123)
+	at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:365)
+	at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:194)
+	at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:460)
+	at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:534)
+	at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115)
+	at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112)
+	at com.zaxxer.hikari.HikariDataSource$$FastClassBySpringCGLIB$$eeb1ae86.invoke(<generated>)
+	at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
+	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:746)
+	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
+	at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:136)
+	at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:124)
+	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
+	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
+	at com.zaxxer.hikari.HikariDataSource$$EnhancerBySpringCGLIB$$7e37a8bf.getConnection(<generated>)
+	at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:151)
+	at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:115)
+	at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:78)
+	at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:324)
+	at org.springframework.boot.actuate.jdbc.DataSourceHealthIndicator.getProduct(DataSourceHealthIndicator.java:122)
+	at org.springframework.boot.actuate.jdbc.DataSourceHealthIndicator.doDataSourceHealthCheck(DataSourceHealthIndicator.java:109)
+	at org.springframework.boot.actuate.jdbc.DataSourceHealthIndicator.doHealthCheck(DataSourceHealthIndicator.java:104)
+	at org.springframework.boot.actuate.health.AbstractHealthIndicator.health(AbstractHealthIndicator.java:84)
+	at org.springframework.boot.actuate.health.CompositeHealthIndicator.health(CompositeHealthIndicator.java:68)
+	at org.springframework.boot.actuate.health.HealthEndpoint.health(HealthEndpoint.java:47)
+	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
+	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+	at java.lang.reflect.Method.invoke(Method.java:498)
+	at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:223)
+	at org.springframework.boot.actuate.endpoint.invoke.reflect.ReflectiveOperationInvoker.invoke(ReflectiveOperationInvoker.java:76)
+	at org.springframework.boot.actuate.endpoint.annotation.AbstractDiscoveredOperation.invoke(AbstractDiscoveredOperation.java:61)
+	at org.springframework.boot.actuate.endpoint.jmx.EndpointMBean.invoke(EndpointMBean.java:126)
+	at org.springframework.boot.actuate.endpoint.jmx.EndpointMBean.invoke(EndpointMBean.java:99)
+	at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
+	at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
+	at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1468)
+	at javax.management.remote.rmi.RMIConnectionImpl.access$300(RMIConnectionImpl.java:76)
+	at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1309)
+	at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1401)
+	at javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:829)
+	at sun.reflect.GeneratedMethodAccessor61.invoke(Unknown Source)
+	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+	at java.lang.reflect.Method.invoke(Method.java:498)
+	at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:357)
+	at sun.rmi.transport.Transport$1.run(Transport.java:200)
+	at sun.rmi.transport.Transport$1.run(Transport.java:197)
+	at java.security.AccessController.doPrivileged(Native Method)
+	at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
+	at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:573)
+	at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:834)
+	at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:688)
+	at java.security.AccessController.doPrivileged(Native Method)
+	at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:687)
+	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
+	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
+	at java.lang.Thread.run(Thread.java:750)
+Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
+
+The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
+	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
+	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
+	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
+	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
+	at com.mysql.jdbc.Util.handleNewInstance(Util.java:425)
+	at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:990)
+	at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:342)
+	at com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2197)
+	at com.mysql.jdbc.ConnectionImpl.connectWithRetries(ConnectionImpl.java:2046)
+	... 69 common frames omitted
+Caused by: java.net.SocketTimeoutException: connect timed out
+	at java.net.PlainSocketImpl.socketConnect(Native Method)
+	at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:476)
+	at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:218)
+	at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:200)
+	at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:394)
+	at java.net.Socket.connect(Socket.java:606)
+	at com.mysql.jdbc.StandardSocketFactory.connect(StandardSocketFactory.java:211)
+	at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:301)
+	... 71 common frames omitted

+ 217 - 0
logs/mall/log.operating.2025-07-09.0.log

@@ -0,0 +1,217 @@
+2025-07-09 15:18:22.282 [main] INFO  org.apache.dubbo.common.logger.LoggerFactory - using logger: org.apache.dubbo.common.logger.slf4j.Slf4jLoggerAdapter
+2025-07-09 15:18:22.288 [main] INFO  o.a.d.s.b.c.event.WelcomeLogoApplicationListener - 
+
+ :: Dubbo Spring Boot (v2.7.1) : https://github.com/apache/incubator-dubbo-spring-boot-project
+ :: Dubbo (v2.7.1) : https://github.com/apache/incubator-dubbo
+ :: Discuss group : dev@dubbo.apache.org
+
+2025-07-09 15:18:22.294 [main] INFO  o.a.d.s.b.c.e.OverrideDubboConfigApplicationListener - Dubbo Config was overridden by externalized configuration {dubbo.application.name=mall, dubbo.application.qos-enable=false, dubbo.application.qos.accept.foreign.ip=true, dubbo.application.qos.enable=true, dubbo.application.qos.port=28201, dubbo.config.multiple=true, dubbo.consumer.check=false, dubbo.protocol.dubbo.payload=83886080, dubbo.protocol.name=dubbo, dubbo.protocol.optimizer=, dubbo.protocol.port=-1, dubbo.protocol.serialization=kryo, dubbo.reference.check=false, dubbo.reference.com.foo.BarService.check=false, dubbo.registry.address=nacos://${${spring.profiles.active}.nacos}, dubbo.registry.check=false, dubbo.scan.base-packages=com.txz.${spring.application.name}.dubbo.impl}
+2025-07-09 15:18:22.573 [main] INFO  o.s.c.a.AnnotationConfigApplicationContext - Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@101639ae: startup date [Wed Jul 09 15:18:22 CST 2025]; root of context hierarchy
+2025-07-09 15:18:22.860 [main] INFO  o.s.b.f.a.AutowiredAnnotationBeanPostProcessor - JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
+2025-07-09 15:18:22.925 [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'configurationPropertiesRebinderAutoConfiguration' of type [org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration$$EnhancerBySpringCGLIB$$bc6d854c] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2025-07-09 15:18:23.158 [pool-3-thread-1] INFO  o.a.d.s.b.c.e.AwaitingNonWebApplicationListener -  [Dubbo] Current Spring Boot Application is await...
+2025-07-09 15:18:23.234 [main] INFO  o.a.d.s.b.c.e.OverrideDubboConfigApplicationListener - Dubbo Config was overridden by externalized configuration {dubbo.application.name=mall, dubbo.application.qos-enable=false, dubbo.application.qos.accept.foreign.ip=true, dubbo.application.qos.enable=true, dubbo.application.qos.port=28201, dubbo.config.multiple=true, dubbo.consumer.check=false, dubbo.protocol.dubbo.payload=83886080, dubbo.protocol.name=dubbo, dubbo.protocol.optimizer=, dubbo.protocol.port=-1, dubbo.protocol.serialization=kryo, dubbo.reference.check=false, dubbo.reference.com.foo.BarService.check=false, dubbo.registry.address=nacos://${${spring.profiles.active}.nacos}, dubbo.registry.check=false, dubbo.scan.base-packages=com.txz.${spring.application.name}.dubbo.impl}
+2025-07-09 15:18:23.433 [main] INFO  o.s.c.a.nacos.client.NacosPropertySourceBuilder - Loading nacos data, dataId: 'mq-dev.properties', group: 'DEFAULT_GROUP'
+2025-07-09 15:18:23.472 [main] INFO  o.s.c.a.nacos.client.NacosPropertySourceBuilder - Loading nacos data, dataId: 'redis-dev.properties', group: 'DEFAULT_GROUP'
+2025-07-09 15:18:23.545 [main] INFO  o.s.c.a.nacos.client.NacosPropertySourceBuilder - Loading nacos data, dataId: 'mall-dev.properties', group: 'DEFAULT_GROUP'
+2025-07-09 15:18:23.545 [main] INFO  o.s.c.b.c.PropertySourceBootstrapConfiguration - Located property source: CompositePropertySource {name='NACOS', propertySources=[NacosPropertySource {name='mall-dev.properties'}, NacosPropertySource {name='mall.properties'}, NacosPropertySource {name='redis-dev.properties'}, NacosPropertySource {name='mq-dev.properties'}]}
+2025-07-09 15:18:23.555 [main] INFO  com.txz.mall.MallApplication - The following profiles are active: dev
+2025-07-09 15:18:23.579 [main] INFO  o.s.b.w.s.c.AnnotationConfigServletWebServerApplicationContext - Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@632aa1a3: startup date [Wed Jul 09 15:18:23 CST 2025]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@101639ae
+2025-07-09 15:18:24.447 [main] INFO  o.s.b.factory.support.DefaultListableBeanFactory - Overriding bean definition for bean 'servletWebServerFactory' with a different definition: replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=undertowExtraConfiguration; factoryMethodName=servletWebServerFactory; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [com/txz/mall/configurer/shutdown/UndertowExtraConfiguration.class]] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=mallApplication; factoryMethodName=servletWebServerFactory; initMethodName=null; destroyMethodName=(inferred); defined in com.txz.mall.MallApplication]
+2025-07-09 15:18:24.558 [main] INFO  o.a.d.c.s.c.annotation.DubboConfigBindingRegistrar - The dubbo config bean definition [name : org.apache.dubbo.config.ApplicationConfig#0, class : org.apache.dubbo.config.ApplicationConfig] has been registered.
+2025-07-09 15:18:24.559 [main] INFO  o.a.d.c.s.c.annotation.DubboConfigBindingRegistrar - The BeanPostProcessor bean definition [org.apache.dubbo.config.spring.beans.factory.annotation.DubboConfigBindingBeanPostProcessor] for dubbo config bean [name : org.apache.dubbo.config.ApplicationConfig#0] has been registered.
+2025-07-09 15:18:24.560 [main] INFO  o.a.d.c.s.c.annotation.DubboConfigBindingRegistrar - The dubbo config bean definition [name : org.apache.dubbo.config.RegistryConfig#0, class : org.apache.dubbo.config.RegistryConfig] has been registered.
+2025-07-09 15:18:24.560 [main] INFO  o.a.d.c.s.c.annotation.DubboConfigBindingRegistrar - The BeanPostProcessor bean definition [org.apache.dubbo.config.spring.beans.factory.annotation.DubboConfigBindingBeanPostProcessor] for dubbo config bean [name : org.apache.dubbo.config.RegistryConfig#0] has been registered.
+2025-07-09 15:18:24.561 [main] INFO  o.a.d.c.s.c.annotation.DubboConfigBindingRegistrar - The dubbo config bean definition [name : org.apache.dubbo.config.ProtocolConfig#0, class : org.apache.dubbo.config.ProtocolConfig] has been registered.
+2025-07-09 15:18:24.561 [main] INFO  o.a.d.c.s.c.annotation.DubboConfigBindingRegistrar - The BeanPostProcessor bean definition [org.apache.dubbo.config.spring.beans.factory.annotation.DubboConfigBindingBeanPostProcessor] for dubbo config bean [name : org.apache.dubbo.config.ProtocolConfig#0] has been registered.
+2025-07-09 15:18:24.561 [main] INFO  o.a.d.c.s.c.annotation.DubboConfigBindingRegistrar - The dubbo config bean definition [name : org.apache.dubbo.config.ConsumerConfig#0, class : org.apache.dubbo.config.ConsumerConfig] has been registered.
+2025-07-09 15:18:24.561 [main] INFO  o.a.d.c.s.c.annotation.DubboConfigBindingRegistrar - The BeanPostProcessor bean definition [org.apache.dubbo.config.spring.beans.factory.annotation.DubboConfigBindingBeanPostProcessor] for dubbo config bean [name : org.apache.dubbo.config.ConsumerConfig#0] has been registered.
+2025-07-09 15:18:24.747 [main] INFO  o.s.d.r.config.RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode!
+2025-07-09 15:18:25.031 [main] INFO  o.a.d.c.s.b.f.a.ServiceAnnotationBeanPostProcessor -  [DUBBO] BeanNameGenerator bean can't be found in BeanFactory with name [org.springframework.context.annotation.internalConfigurationBeanNameGenerator], dubbo version: 2.7.1, current host: 169.254.116.82
+2025-07-09 15:18:25.032 [main] INFO  o.a.d.c.s.b.f.a.ServiceAnnotationBeanPostProcessor -  [DUBBO] BeanNameGenerator will be a instance of org.springframework.context.annotation.AnnotationBeanNameGenerator , it maybe a potential problem on bean name generation., dubbo version: 2.7.1, current host: 169.254.116.82
+2025-07-09 15:18:25.082 [main] INFO  o.s.b.factory.support.DefaultListableBeanFactory - Overriding bean definition for bean 'dataSource' with a different definition: replacing [Root bean: class [null]; scope=refresh; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=false; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration$Hikari; factoryMethodName=dataSource; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]] with [Root bean: class [org.springframework.aop.scope.ScopedProxyFactoryBean]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in BeanDefinition defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]]
+2025-07-09 15:18:25.411 [main] INFO  o.springframework.cloud.context.scope.GenericScope - BeanFactory id=3613fce5-50e7-3e6b-aa1a-bfd631e56b0f
+2025-07-09 15:18:25.451 [main] INFO  o.s.b.f.a.AutowiredAnnotationBeanPostProcessor - JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
+2025-07-09 15:18:25.530 [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'org.apache.rocketmq.spring.autoconfigure.RocketMQAutoConfiguration' of type [org.apache.rocketmq.spring.autoconfigure.RocketMQAutoConfiguration$$EnhancerBySpringCGLIB$$c8e9914b] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2025-07-09 15:18:25.551 [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'org.springframework.boot.context.properties.ConversionServiceDeducer$Factory' of type [org.springframework.boot.context.properties.ConversionServiceDeducer$Factory] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2025-07-09 15:18:25.561 [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'rocketmq-org.apache.rocketmq.spring.autoconfigure.RocketMQProperties' of type [org.apache.rocketmq.spring.autoconfigure.RocketMQProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2025-07-09 15:18:25.598 [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'defaultMQProducer' of type [org.apache.rocketmq.client.producer.DefaultMQProducer] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2025-07-09 15:18:25.606 [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$JacksonObjectMapperConfiguration' of type [org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$JacksonObjectMapperConfiguration$$EnhancerBySpringCGLIB$$fbe701e0] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2025-07-09 15:18:25.612 [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$JacksonObjectMapperBuilderConfiguration' of type [org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$JacksonObjectMapperBuilderConfiguration$$EnhancerBySpringCGLIB$$ae33c3f9] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2025-07-09 15:18:25.620 [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$Jackson2ObjectMapperBuilderCustomizerConfiguration' of type [org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$Jackson2ObjectMapperBuilderCustomizerConfiguration$$EnhancerBySpringCGLIB$$694aa9e8] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2025-07-09 15:18:25.624 [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'spring.jackson-org.springframework.boot.autoconfigure.jackson.JacksonProperties' of type [org.springframework.boot.autoconfigure.jackson.JacksonProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2025-07-09 15:18:25.633 [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'standardJacksonObjectMapperBuilderCustomizer' of type [org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$Jackson2ObjectMapperBuilderCustomizerConfiguration$StandardJackson2ObjectMapperBuilderCustomizer] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2025-07-09 15:18:25.645 [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$ParameterNamesModuleConfiguration' of type [org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$ParameterNamesModuleConfiguration$$EnhancerBySpringCGLIB$$90162116] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2025-07-09 15:18:25.674 [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'parameterNamesModule' of type [com.fasterxml.jackson.module.paramnames.ParameterNamesModule] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2025-07-09 15:18:25.688 [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration' of type [org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$$EnhancerBySpringCGLIB$$ddf29f6f] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2025-07-09 15:18:25.737 [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'jsonComponentModule' of type [org.springframework.boot.jackson.JsonComponentModule] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2025-07-09 15:18:25.740 [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'org.springframework.data.web.config.SpringDataJacksonConfiguration' of type [org.springframework.data.web.config.SpringDataJacksonConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2025-07-09 15:18:25.744 [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'jacksonGeoModule' of type [org.springframework.data.geo.GeoModule] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2025-07-09 15:18:25.748 [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'jacksonObjectMapperBuilder' of type [org.springframework.http.converter.json.Jackson2ObjectMapperBuilder] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2025-07-09 15:18:25.776 [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'jacksonObjectMapper' of type [com.fasterxml.jackson.databind.ObjectMapper] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2025-07-09 15:18:26.009 [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'rocketMQTemplate' of type [org.apache.rocketmq.spring.core.RocketMQTemplate] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2025-07-09 15:18:26.064 [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'transactionHandlerRegistry' of type [org.apache.rocketmq.spring.config.TransactionHandlerRegistry] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2025-07-09 15:18:26.485 [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$a053824f] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2025-07-09 15:18:26.725 [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'relaxedDubboConfigBinder' of type [org.apache.dubbo.spring.boot.autoconfigure.BinderDubboConfigBinder] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2025-07-09 15:18:26.749 [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'relaxedDubboConfigBinder' of type [org.apache.dubbo.spring.boot.autoconfigure.BinderDubboConfigBinder] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2025-07-09 15:18:26.751 [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'relaxedDubboConfigBinder' of type [org.apache.dubbo.spring.boot.autoconfigure.BinderDubboConfigBinder] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2025-07-09 15:18:26.753 [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'relaxedDubboConfigBinder' of type [org.apache.dubbo.spring.boot.autoconfigure.BinderDubboConfigBinder] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2025-07-09 15:18:26.779 [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration' of type [org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration$$EnhancerBySpringCGLIB$$bc6d854c] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2025-07-09 15:18:27.176 [main] INFO  org.xnio - XNIO version 3.3.8.Final
+2025-07-09 15:18:27.185 [main] INFO  org.xnio.nio - XNIO NIO Implementation Version 3.3.8.Final
+2025-07-09 15:18:27.222 [main] INFO  io.undertow.servlet - Initializing Spring embedded WebApplicationContext
+2025-07-09 15:18:27.222 [main] INFO  org.springframework.web.context.ContextLoader - Root WebApplicationContext: initialization completed in 3644 ms
+2025-07-09 15:18:28.521 [main] INFO  o.s.boot.web.servlet.FilterRegistrationBean - Mapping filter: 'characterEncodingFilter' to: [/*]
+2025-07-09 15:18:28.524 [main] INFO  o.s.boot.web.servlet.FilterRegistrationBean - Mapping filter: 'webMvcMetricsFilter' to: [/*]
+2025-07-09 15:18:28.524 [main] INFO  o.s.boot.web.servlet.FilterRegistrationBean - Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
+2025-07-09 15:18:28.524 [main] INFO  o.s.boot.web.servlet.FilterRegistrationBean - Mapping filter: 'httpPutFormContentFilter' to: [/*]
+2025-07-09 15:18:28.524 [main] INFO  o.s.boot.web.servlet.FilterRegistrationBean - Mapping filter: 'requestContextFilter' to: [/*]
+2025-07-09 15:18:28.524 [main] INFO  o.s.boot.web.servlet.FilterRegistrationBean - Mapping filter: 'httpTraceFilter' to: [/*]
+2025-07-09 15:18:28.524 [main] INFO  o.s.boot.web.servlet.ServletRegistrationBean - Servlet dispatcherServlet mapped to [/]
+2025-07-09 15:18:29.389 [main] INFO  o.s.w.s.m.m.a.RequestMappingHandlerMapping - Mapped "{[/swagger-resources/configuration/ui]}" onto public org.springframework.http.ResponseEntity<springfox.documentation.swagger.web.UiConfiguration> springfox.documentation.swagger.web.ApiResourceController.uiConfiguration()
+2025-07-09 15:18:29.390 [main] INFO  o.s.w.s.m.m.a.RequestMappingHandlerMapping - Mapped "{[/swagger-resources/configuration/security]}" onto public org.springframework.http.ResponseEntity<springfox.documentation.swagger.web.SecurityConfiguration> springfox.documentation.swagger.web.ApiResourceController.securityConfiguration()
+2025-07-09 15:18:29.391 [main] INFO  o.s.w.s.m.m.a.RequestMappingHandlerMapping - Mapped "{[/swagger-resources]}" onto public org.springframework.http.ResponseEntity<java.util.List<springfox.documentation.swagger.web.SwaggerResource>> springfox.documentation.swagger.web.ApiResourceController.swaggerResources()
+2025-07-09 15:18:29.398 [main] INFO  o.s.w.s.m.m.a.RequestMappingHandlerMapping - Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
+2025-07-09 15:18:29.398 [main] INFO  o.s.w.s.m.m.a.RequestMappingHandlerMapping - Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
+2025-07-09 15:18:29.552 [main] INFO  o.s.b.actuate.endpoint.web.EndpointLinksResolver - Exposing 21 endpoint(s) beneath base path '/mall'
+2025-07-09 15:18:29.566 [main] INFO  o.s.b.a.e.web.servlet.WebMvcEndpointHandlerMapping - Mapped "{[/mall/archaius],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>)
+2025-07-09 15:18:29.567 [main] INFO  o.s.b.a.e.web.servlet.WebMvcEndpointHandlerMapping - Mapped "{[/mall/auditevents],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>)
+2025-07-09 15:18:29.567 [main] INFO  o.s.b.a.e.web.servlet.WebMvcEndpointHandlerMapping - Mapped "{[/mall/beans],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>)
+2025-07-09 15:18:29.567 [main] INFO  o.s.b.a.e.web.servlet.WebMvcEndpointHandlerMapping - Mapped "{[/mall/health],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>)
+2025-07-09 15:18:29.567 [main] INFO  o.s.b.a.e.web.servlet.WebMvcEndpointHandlerMapping - Mapped "{[/mall/conditions],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>)
+2025-07-09 15:18:29.567 [main] INFO  o.s.b.a.e.web.servlet.WebMvcEndpointHandlerMapping - Mapped "{[/mall/shutThisBoot],methods=[POST],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>)
+2025-07-09 15:18:29.568 [main] INFO  o.s.b.a.e.web.servlet.WebMvcEndpointHandlerMapping - Mapped "{[/mall/configprops],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>)
+2025-07-09 15:18:29.568 [main] INFO  o.s.b.a.e.web.servlet.WebMvcEndpointHandlerMapping - Mapped "{[/mall/env/{toMatch}],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>)
+2025-07-09 15:18:29.569 [main] INFO  o.s.b.a.e.web.servlet.WebMvcEndpointHandlerMapping - Mapped "{[/mall/env],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>)
+2025-07-09 15:18:29.571 [main] INFO  o.s.b.a.e.web.servlet.WebMvcEndpointHandlerMapping - Mapped "{[/mall/env],methods=[POST],consumes=[application/vnd.spring-boot.actuator.v2+json || application/json],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>)
+2025-07-09 15:18:29.571 [main] INFO  o.s.b.a.e.web.servlet.WebMvcEndpointHandlerMapping - Mapped "{[/mall/env],methods=[DELETE],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>)
+2025-07-09 15:18:29.571 [main] INFO  o.s.b.a.e.web.servlet.WebMvcEndpointHandlerMapping - Mapped "{[/mall/info],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>)
+2025-07-09 15:18:29.571 [main] INFO  o.s.b.a.e.web.servlet.WebMvcEndpointHandlerMapping - Mapped "{[/mall/loggers/{name}],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>)
+2025-07-09 15:18:29.571 [main] INFO  o.s.b.a.e.web.servlet.WebMvcEndpointHandlerMapping - Mapped "{[/mall/loggers/{name}],methods=[POST],consumes=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>)
+2025-07-09 15:18:29.571 [main] INFO  o.s.b.a.e.web.servlet.WebMvcEndpointHandlerMapping - Mapped "{[/mall/loggers],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>)
+2025-07-09 15:18:29.571 [main] INFO  o.s.b.a.e.web.servlet.WebMvcEndpointHandlerMapping - Mapped "{[/mall/heapdump],methods=[GET],produces=[application/octet-stream]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>)
+2025-07-09 15:18:29.572 [main] INFO  o.s.b.a.e.web.servlet.WebMvcEndpointHandlerMapping - Mapped "{[/mall/threaddump],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>)
+2025-07-09 15:18:29.572 [main] INFO  o.s.b.a.e.web.servlet.WebMvcEndpointHandlerMapping - Mapped "{[/mall/metrics/{requiredMetricName}],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>)
+2025-07-09 15:18:29.572 [main] INFO  o.s.b.a.e.web.servlet.WebMvcEndpointHandlerMapping - Mapped "{[/mall/metrics],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>)
+2025-07-09 15:18:29.573 [main] INFO  o.s.b.a.e.web.servlet.WebMvcEndpointHandlerMapping - Mapped "{[/mall/scheduledtasks],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>)
+2025-07-09 15:18:29.573 [main] INFO  o.s.b.a.e.web.servlet.WebMvcEndpointHandlerMapping - Mapped "{[/mall/httptrace],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>)
+2025-07-09 15:18:29.573 [main] INFO  o.s.b.a.e.web.servlet.WebMvcEndpointHandlerMapping - Mapped "{[/mall/mappings],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>)
+2025-07-09 15:18:29.573 [main] INFO  o.s.b.a.e.web.servlet.WebMvcEndpointHandlerMapping - Mapped "{[/mall/nacos-config],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>)
+2025-07-09 15:18:29.574 [main] INFO  o.s.b.a.e.web.servlet.WebMvcEndpointHandlerMapping - Mapped "{[/mall/nacos-discovery],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>)
+2025-07-09 15:18:29.574 [main] INFO  o.s.b.a.e.web.servlet.WebMvcEndpointHandlerMapping - Mapped "{[/mall/refresh],methods=[POST],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>)
+2025-07-09 15:18:29.574 [main] INFO  o.s.b.a.e.web.servlet.WebMvcEndpointHandlerMapping - Mapped "{[/mall/features],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>)
+2025-07-09 15:18:29.575 [main] INFO  o.s.b.a.e.web.servlet.WebMvcEndpointHandlerMapping - Mapped "{[/mall/service-registry],methods=[POST],consumes=[application/vnd.spring-boot.actuator.v2+json || application/json],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>)
+2025-07-09 15:18:29.575 [main] INFO  o.s.b.a.e.web.servlet.WebMvcEndpointHandlerMapping - Mapped "{[/mall/service-registry],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax.servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>)
+2025-07-09 15:18:29.576 [main] INFO  o.s.b.a.e.web.servlet.WebMvcEndpointHandlerMapping - Mapped "{[/mall],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto protected java.util.Map<java.lang.String, java.util.Map<java.lang.String, org.springframework.boot.actuate.endpoint.web.Link>> org.springframework.boot.actuate.endpoint.web.servlet.WebMvcEndpointHandlerMapping.links(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
+2025-07-09 15:18:29.791 [main] INFO  s.d.s.w.PropertySourcedRequestMappingHandlerMapping - Mapped URL path [/v2/api-docs] onto method [public org.springframework.http.ResponseEntity<springfox.documentation.spring.web.json.Json> springfox.documentation.swagger2.web.Swagger2Controller.getDocumentation(java.lang.String,javax.servlet.http.HttpServletRequest)]
+2025-07-09 15:18:30.337 [main] INFO  com.netflix.config.sources.URLConfigurationSource - To enable URLs as dynamic configuration sources, define System property archaius.configurationSource.additionalUrls or make config.properties available on classpath.
+2025-07-09 15:18:30.342 [main] INFO  com.netflix.config.sources.URLConfigurationSource - To enable URLs as dynamic configuration sources, define System property archaius.configurationSource.additionalUrls or make config.properties available on classpath.
+2025-07-09 15:18:30.508 [main] INFO  o.s.web.servlet.handler.SimpleUrlHandlerMapping - Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
+2025-07-09 15:18:30.601 [main] INFO  o.s.w.s.m.m.a.RequestMappingHandlerAdapter - Looking for @ControllerAdvice: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@632aa1a3: startup date [Wed Jul 09 15:18:23 CST 2025]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@101639ae
+2025-07-09 15:18:30.626 [main] INFO  o.s.w.s.m.m.a.RequestMappingHandlerAdapter - Detected @ModelAttribute methods in headerAttribute
+2025-07-09 15:18:30.762 [main] INFO  o.s.web.servlet.handler.SimpleUrlHandlerMapping - Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
+2025-07-09 15:18:30.764 [main] INFO  o.s.web.servlet.handler.SimpleUrlHandlerMapping - Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
+2025-07-09 15:18:30.764 [main] INFO  o.s.web.servlet.handler.SimpleUrlHandlerMapping - Mapped URL path [/swagger-ui.html] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
+2025-07-09 15:18:30.764 [main] INFO  o.s.web.servlet.handler.SimpleUrlHandlerMapping - Mapped URL path [/docs.html] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
+2025-07-09 15:18:30.764 [main] INFO  o.s.web.servlet.handler.SimpleUrlHandlerMapping - Mapped URL path [/doc.html] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
+2025-07-09 15:18:30.997 [main] INFO  o.a.d.c.s.b.f.a.DubboConfigBindingBeanPostProcessor - The properties of bean [name : org.apache.dubbo.config.ApplicationConfig#0] have been binding by prefix of configuration properties : dubbo.application
+2025-07-09 15:18:31.009 [main] INFO  o.a.d.c.s.b.f.a.DubboConfigBindingBeanPostProcessor - The properties of bean [name : org.apache.dubbo.config.RegistryConfig#0] have been binding by prefix of configuration properties : dubbo.registry
+2025-07-09 15:18:31.015 [main] INFO  o.a.d.c.s.b.f.a.DubboConfigBindingBeanPostProcessor - The properties of bean [name : org.apache.dubbo.config.ProtocolConfig#0] have been binding by prefix of configuration properties : dubbo.protocol
+2025-07-09 15:18:31.033 [main] INFO  o.a.d.c.s.b.f.a.DubboConfigBindingBeanPostProcessor - The properties of bean [name : org.apache.dubbo.config.ConsumerConfig#0] have been binding by prefix of configuration properties : dubbo.consumer
+2025-07-09 15:18:31.489 [main] INFO  o.s.ui.freemarker.SpringTemplateLoader - SpringTemplateLoader for FreeMarker: using resource loader [org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@632aa1a3: startup date [Wed Jul 09 15:18:23 CST 2025]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@101639ae] and template loader path [classpath:/templates/]
+2025-07-09 15:18:31.490 [main] INFO  o.s.w.servlet.view.freemarker.FreeMarkerConfigurer - ClassTemplateLoader for Spring macros added to FreeMarker configuration
+2025-07-09 15:18:32.001 [main] INFO  o.s.scheduling.concurrent.ThreadPoolTaskScheduler - Initializing ExecutorService 
+2025-07-09 15:18:32.192 [main] INFO  o.s.jmx.export.annotation.AnnotationMBeanExporter - Registering beans for JMX exposure on startup
+2025-07-09 15:18:32.196 [main] INFO  o.s.jmx.export.annotation.AnnotationMBeanExporter - Bean with name 'dataSource' has been autodetected for JMX exposure
+2025-07-09 15:18:32.208 [main] INFO  o.s.jmx.export.annotation.AnnotationMBeanExporter - Bean with name 'environmentManager' has been autodetected for JMX exposure
+2025-07-09 15:18:32.209 [main] INFO  o.s.jmx.export.annotation.AnnotationMBeanExporter - Bean with name 'refreshScope' has been autodetected for JMX exposure
+2025-07-09 15:18:32.211 [main] INFO  o.s.jmx.export.annotation.AnnotationMBeanExporter - Bean with name 'configurationPropertiesRebinder' has been autodetected for JMX exposure
+2025-07-09 15:18:32.214 [main] INFO  o.s.jmx.export.annotation.AnnotationMBeanExporter - Located managed bean 'environmentManager': registering with JMX server as MBean [org.springframework.cloud.context.environment:name=environmentManager,type=EnvironmentManager]
+2025-07-09 15:18:32.222 [main] INFO  o.s.jmx.export.annotation.AnnotationMBeanExporter - Located managed bean 'refreshScope': registering with JMX server as MBean [org.springframework.cloud.context.scope.refresh:name=refreshScope,type=RefreshScope]
+2025-07-09 15:18:32.233 [main] INFO  o.s.jmx.export.annotation.AnnotationMBeanExporter - Located managed bean 'configurationPropertiesRebinder': registering with JMX server as MBean [org.springframework.cloud.context.properties:name=configurationPropertiesRebinder,context=632aa1a3,type=ConfigurationPropertiesRebinder]
+2025-07-09 15:18:32.241 [main] INFO  o.s.jmx.export.annotation.AnnotationMBeanExporter - Located MBean 'dataSource': registering with JMX server as MBean [com.zaxxer.hikari:name=dataSource,type=HikariDataSource]
+2025-07-09 15:18:32.257 [main] INFO  o.s.context.support.DefaultLifecycleProcessor - Starting beans in phase 0
+2025-07-09 15:18:32.260 [main] INFO  o.s.context.support.DefaultLifecycleProcessor - Starting beans in phase 2147483647
+2025-07-09 15:18:32.261 [main] INFO  s.d.s.web.plugins.DocumentationPluginsBootstrapper - Context refreshed
+2025-07-09 15:18:32.288 [main] INFO  s.d.s.web.plugins.DocumentationPluginsBootstrapper - Found 2 custom documentation plugin(s)
+2025-07-09 15:18:32.333 [main] INFO  s.d.spring.web.scanners.ApiListingReferenceScanner - Scanning for api listing references
+2025-07-09 15:18:32.551 [main] INFO  s.d.s.w.r.operation.CachingOperationNameGenerator - Generating unique operation named: handleUsingGET_1
+2025-07-09 15:18:32.554 [main] INFO  s.d.s.w.r.operation.CachingOperationNameGenerator - Generating unique operation named: handleUsingGET_2
+2025-07-09 15:18:32.557 [main] INFO  s.d.s.w.r.operation.CachingOperationNameGenerator - Generating unique operation named: handleUsingGET_3
+2025-07-09 15:18:32.561 [main] INFO  s.d.s.w.r.operation.CachingOperationNameGenerator - Generating unique operation named: handleUsingGET_4
+2025-07-09 15:18:32.565 [main] INFO  s.d.s.w.r.operation.CachingOperationNameGenerator - Generating unique operation named: handleUsingGET_5
+2025-07-09 15:18:32.566 [main] INFO  s.d.s.w.r.operation.CachingOperationNameGenerator - Generating unique operation named: handleUsingGET_6
+2025-07-09 15:18:32.570 [main] INFO  s.d.s.w.r.operation.CachingOperationNameGenerator - Generating unique operation named: handleUsingGET_7
+2025-07-09 15:18:32.573 [main] INFO  s.d.s.w.r.operation.CachingOperationNameGenerator - Generating unique operation named: handleUsingGET_8
+2025-07-09 15:18:32.574 [main] INFO  s.d.s.w.r.operation.CachingOperationNameGenerator - Generating unique operation named: handleUsingGET_9
+2025-07-09 15:18:32.578 [main] INFO  s.d.s.w.r.operation.CachingOperationNameGenerator - Generating unique operation named: handleUsingGET_10
+2025-07-09 15:18:32.586 [main] INFO  s.d.s.w.r.operation.CachingOperationNameGenerator - Generating unique operation named: handleUsingGET_11
+2025-07-09 15:18:32.587 [main] INFO  s.d.s.w.r.operation.CachingOperationNameGenerator - Generating unique operation named: handleUsingGET_12
+2025-07-09 15:18:32.590 [main] INFO  s.d.s.w.r.operation.CachingOperationNameGenerator - Generating unique operation named: handleUsingPOST_1
+2025-07-09 15:18:32.592 [main] INFO  s.d.s.w.r.operation.CachingOperationNameGenerator - Generating unique operation named: handleUsingGET_13
+2025-07-09 15:18:32.593 [main] INFO  s.d.s.w.r.operation.CachingOperationNameGenerator - Generating unique operation named: handleUsingGET_14
+2025-07-09 15:18:32.595 [main] INFO  s.d.s.w.r.operation.CachingOperationNameGenerator - Generating unique operation named: handleUsingGET_15
+2025-07-09 15:18:32.596 [main] INFO  s.d.s.w.r.operation.CachingOperationNameGenerator - Generating unique operation named: handleUsingGET_16
+2025-07-09 15:18:32.598 [main] INFO  s.d.s.w.r.operation.CachingOperationNameGenerator - Generating unique operation named: handleUsingGET_17
+2025-07-09 15:18:32.598 [main] INFO  s.d.s.w.r.operation.CachingOperationNameGenerator - Generating unique operation named: handleUsingGET_18
+2025-07-09 15:18:32.600 [main] INFO  s.d.s.w.r.operation.CachingOperationNameGenerator - Generating unique operation named: handleUsingPOST_2
+2025-07-09 15:18:32.604 [main] INFO  s.d.s.w.r.operation.CachingOperationNameGenerator - Generating unique operation named: handleUsingGET_19
+2025-07-09 15:18:32.605 [main] INFO  s.d.s.w.r.operation.CachingOperationNameGenerator - Generating unique operation named: handleUsingPOST_3
+2025-07-09 15:18:32.607 [main] INFO  s.d.s.w.r.operation.CachingOperationNameGenerator - Generating unique operation named: handleUsingGET_20
+2025-07-09 15:18:32.608 [main] INFO  s.d.s.w.r.operation.CachingOperationNameGenerator - Generating unique operation named: handleUsingPOST_4
+2025-07-09 15:18:32.610 [main] INFO  s.d.s.w.r.operation.CachingOperationNameGenerator - Generating unique operation named: handleUsingGET_21
+2025-07-09 15:18:32.650 [main] INFO  s.d.spring.web.scanners.ApiListingReferenceScanner - Scanning for api listing references
+2025-07-09 15:18:32.725 [main] INFO  o.s.b.w.embedded.undertow.UndertowServletWebServer - Undertow started on port(s) 8101 (http) with context path ''
+2025-07-09 15:18:32.767 [main] INFO  o.s.c.alibaba.nacos.registry.NacosServiceRegistry - nacos registry, mall 192.168.0.102:8101 register finished
+2025-07-09 15:18:32.778 [main] INFO  com.txz.mall.MallApplication - Started MallApplication in 11.084 seconds (JVM running for 12.692)
+2025-07-09 15:18:32.895 [com.alibaba.nacos.client.Worker.longPollingfixed-124.222.152.234_8848] INFO  o.a.d.s.b.c.e.OverrideDubboConfigApplicationListener - Dubbo Config was overridden by externalized configuration {dubbo.application.name=mall, dubbo.application.qos-enable=false, dubbo.application.qos.accept.foreign.ip=true, dubbo.application.qos.enable=true, dubbo.application.qos.port=28201, dubbo.config.multiple=true, dubbo.consumer.check=false, dubbo.protocol.dubbo.payload=83886080, dubbo.protocol.name=dubbo, dubbo.protocol.optimizer=, dubbo.protocol.port=-1, dubbo.protocol.serialization=kryo, dubbo.reference.check=false, dubbo.reference.com.foo.BarService.check=false, dubbo.registry.address=nacos://${${spring.profiles.active}.nacos}, dubbo.registry.check=false, dubbo.scan.base-packages=com.txz.${spring.application.name}.dubbo.impl}
+2025-07-09 15:18:32.916 [com.alibaba.nacos.client.Worker.longPollingfixed-124.222.152.234_8848] INFO  o.s.c.a.AnnotationConfigApplicationContext - Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@3ec08246: startup date [Wed Jul 09 15:18:32 CST 2025]; root of context hierarchy
+2025-07-09 15:18:33.012 [com.alibaba.nacos.client.Worker.longPollingfixed-124.222.152.234_8848] INFO  o.s.b.f.a.AutowiredAnnotationBeanPostProcessor - JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
+2025-07-09 15:18:33.049 [com.alibaba.nacos.client.Worker.longPollingfixed-124.222.152.234_8848] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'configurationPropertiesRebinderAutoConfiguration' of type [org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration$$EnhancerBySpringCGLIB$$bc6d854c] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2025-07-09 15:18:33.120 [pool-6-thread-1] INFO  o.a.d.s.b.c.e.AwaitingNonWebApplicationListener -  [Dubbo] Current Spring Boot Application is await...
+2025-07-09 15:18:33.183 [com.alibaba.nacos.client.Worker.longPollingfixed-124.222.152.234_8848] INFO  o.s.c.a.nacos.client.NacosPropertySourceBuilder - Loading nacos data, dataId: 'mq-dev.properties', group: 'DEFAULT_GROUP'
+2025-07-09 15:18:33.217 [com.alibaba.nacos.client.Worker.longPollingfixed-124.222.152.234_8848] INFO  o.s.c.a.nacos.client.NacosPropertySourceBuilder - Loading nacos data, dataId: 'redis-dev.properties', group: 'DEFAULT_GROUP'
+2025-07-09 15:18:33.283 [com.alibaba.nacos.client.Worker.longPollingfixed-124.222.152.234_8848] INFO  o.s.c.a.nacos.client.NacosPropertySourceBuilder - Loading nacos data, dataId: 'mall-dev.properties', group: 'DEFAULT_GROUP'
+2025-07-09 15:18:33.286 [com.alibaba.nacos.client.Worker.longPollingfixed-124.222.152.234_8848] INFO  o.s.c.b.c.PropertySourceBootstrapConfiguration - Located property source: CompositePropertySource {name='NACOS', propertySources=[NacosPropertySource {name='mall-dev.properties'}, NacosPropertySource {name='mall.properties'}, NacosPropertySource {name='redis-dev.properties'}, NacosPropertySource {name='mq-dev.properties'}]}
+2025-07-09 15:18:33.298 [com.alibaba.nacos.client.Worker.longPollingfixed-124.222.152.234_8848] INFO  org.springframework.boot.SpringApplication - The following profiles are active: dev
+2025-07-09 15:18:33.315 [com.alibaba.nacos.client.Worker.longPollingfixed-124.222.152.234_8848] INFO  o.s.c.a.AnnotationConfigApplicationContext - Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@11df9142: startup date [Wed Jul 09 15:18:33 CST 2025]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@3ec08246
+2025-07-09 15:18:33.359 [com.alibaba.nacos.client.Worker.longPollingfixed-124.222.152.234_8848] INFO  o.s.b.f.a.AutowiredAnnotationBeanPostProcessor - JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
+2025-07-09 15:18:33.436 [com.alibaba.nacos.client.Worker.longPollingfixed-124.222.152.234_8848] INFO  org.springframework.boot.SpringApplication - Started application in 0.59 seconds (JVM running for 13.35)
+2025-07-09 15:18:33.437 [com.alibaba.nacos.client.Worker.longPollingfixed-124.222.152.234_8848] INFO  o.s.c.a.AnnotationConfigApplicationContext - Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@11df9142: startup date [Wed Jul 09 15:18:33 CST 2025]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@3ec08246
+2025-07-09 15:18:33.439 [com.alibaba.nacos.client.Worker.longPollingfixed-124.222.152.234_8848] INFO  o.a.d.s.b.c.e.AwaitingNonWebApplicationListener -  [Dubbo] Current Spring Boot Application is about to shutdown...
+2025-07-09 15:18:33.446 [com.alibaba.nacos.client.Worker.longPollingfixed-124.222.152.234_8848] INFO  o.s.c.a.AnnotationConfigApplicationContext - Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@3ec08246: startup date [Wed Jul 09 15:18:32 CST 2025]; root of context hierarchy
+2025-07-09 15:18:33.657 [RMI TCP Connection(5)-192.168.0.102] INFO  io.undertow.servlet - Initializing Spring FrameworkServlet 'dispatcherServlet'
+2025-07-09 15:18:33.662 [RMI TCP Connection(5)-192.168.0.102] INFO  org.springframework.web.servlet.DispatcherServlet - FrameworkServlet 'dispatcherServlet': initialization started
+2025-07-09 15:18:33.678 [RMI TCP Connection(4)-192.168.0.102] INFO  com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Starting...
+2025-07-09 15:18:33.996 [RMI TCP Connection(5)-192.168.0.102] INFO  org.springframework.web.servlet.DispatcherServlet - FrameworkServlet 'dispatcherServlet': initialization completed in 330 ms
+2025-07-09 15:18:34.283 [com.alibaba.nacos.client.Worker.longPollingfixed-124.222.152.234_8848] INFO  o.s.cloud.endpoint.event.RefreshEventListener - Refresh keys changed: []
+2025-07-09 15:18:34.324 [com.alibaba.nacos.client.Worker.longPollingfixed-124.222.152.234_8848] INFO  o.a.d.s.b.c.e.OverrideDubboConfigApplicationListener - Dubbo Config was overridden by externalized configuration {dubbo.application.name=mall, dubbo.application.qos-enable=false, dubbo.application.qos.accept.foreign.ip=true, dubbo.application.qos.enable=true, dubbo.application.qos.port=28201, dubbo.config.multiple=true, dubbo.consumer.check=false, dubbo.protocol.dubbo.payload=83886080, dubbo.protocol.name=dubbo, dubbo.protocol.optimizer=, dubbo.protocol.port=-1, dubbo.protocol.serialization=kryo, dubbo.reference.check=false, dubbo.reference.com.foo.BarService.check=false, dubbo.registry.address=nacos://${${spring.profiles.active}.nacos}, dubbo.registry.check=false, dubbo.scan.base-packages=com.txz.${spring.application.name}.dubbo.impl}
+2025-07-09 15:18:34.335 [com.alibaba.nacos.client.Worker.longPollingfixed-124.222.152.234_8848] INFO  o.s.c.a.AnnotationConfigApplicationContext - Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@7c8c413e: startup date [Wed Jul 09 15:18:34 CST 2025]; root of context hierarchy
+2025-07-09 15:18:34.365 [com.alibaba.nacos.client.Worker.longPollingfixed-124.222.152.234_8848] INFO  o.s.b.f.a.AutowiredAnnotationBeanPostProcessor - JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
+2025-07-09 15:18:34.392 [com.alibaba.nacos.client.Worker.longPollingfixed-124.222.152.234_8848] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'configurationPropertiesRebinderAutoConfiguration' of type [org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration$$EnhancerBySpringCGLIB$$bc6d854c] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2025-07-09 15:18:34.492 [com.alibaba.nacos.client.Worker.longPollingfixed-124.222.152.234_8848] INFO  o.s.c.a.nacos.client.NacosPropertySourceBuilder - Loading nacos data, dataId: 'mq-dev.properties', group: 'DEFAULT_GROUP'
+2025-07-09 15:18:34.521 [com.alibaba.nacos.client.Worker.longPollingfixed-124.222.152.234_8848] INFO  o.s.c.a.nacos.client.NacosPropertySourceBuilder - Loading nacos data, dataId: 'redis-dev.properties', group: 'DEFAULT_GROUP'
+2025-07-09 15:18:34.578 [com.alibaba.nacos.client.Worker.longPollingfixed-124.222.152.234_8848] INFO  o.s.c.a.nacos.client.NacosPropertySourceBuilder - Loading nacos data, dataId: 'mall-dev.properties', group: 'DEFAULT_GROUP'
+2025-07-09 15:18:34.578 [com.alibaba.nacos.client.Worker.longPollingfixed-124.222.152.234_8848] INFO  o.s.c.b.c.PropertySourceBootstrapConfiguration - Located property source: CompositePropertySource {name='NACOS', propertySources=[NacosPropertySource {name='mall-dev.properties'}, NacosPropertySource {name='mall.properties'}, NacosPropertySource {name='redis-dev.properties'}, NacosPropertySource {name='mq-dev.properties'}]}
+2025-07-09 15:18:34.580 [com.alibaba.nacos.client.Worker.longPollingfixed-124.222.152.234_8848] INFO  org.springframework.boot.SpringApplication - The following profiles are active: dev
+2025-07-09 15:18:34.582 [com.alibaba.nacos.client.Worker.longPollingfixed-124.222.152.234_8848] INFO  o.s.c.a.AnnotationConfigApplicationContext - Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@6dc74f72: startup date [Wed Jul 09 15:18:34 CST 2025]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@7c8c413e
+2025-07-09 15:18:34.589 [com.alibaba.nacos.client.Worker.longPollingfixed-124.222.152.234_8848] INFO  o.s.b.f.a.AutowiredAnnotationBeanPostProcessor - JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
+2025-07-09 15:18:34.609 [com.alibaba.nacos.client.Worker.longPollingfixed-124.222.152.234_8848] INFO  org.springframework.boot.SpringApplication - Started application in 0.323 seconds (JVM running for 14.524)
+2025-07-09 15:18:34.609 [com.alibaba.nacos.client.Worker.longPollingfixed-124.222.152.234_8848] INFO  o.s.c.a.AnnotationConfigApplicationContext - Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@6dc74f72: startup date [Wed Jul 09 15:18:34 CST 2025]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@7c8c413e
+2025-07-09 15:18:34.610 [com.alibaba.nacos.client.Worker.longPollingfixed-124.222.152.234_8848] INFO  o.s.c.a.AnnotationConfigApplicationContext - Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@7c8c413e: startup date [Wed Jul 09 15:18:34 CST 2025]; root of context hierarchy
+2025-07-09 15:18:34.840 [com.alibaba.nacos.client.Worker.longPollingfixed-124.222.152.234_8848] INFO  o.s.cloud.endpoint.event.RefreshEventListener - Refresh keys changed: []
+2025-07-09 15:18:34.873 [com.alibaba.nacos.client.Worker.longPollingfixed-124.222.152.234_8848] INFO  o.a.d.s.b.c.e.OverrideDubboConfigApplicationListener - Dubbo Config was overridden by externalized configuration {dubbo.application.name=mall, dubbo.application.qos-enable=false, dubbo.application.qos.accept.foreign.ip=true, dubbo.application.qos.enable=true, dubbo.application.qos.port=28201, dubbo.config.multiple=true, dubbo.consumer.check=false, dubbo.protocol.dubbo.payload=83886080, dubbo.protocol.name=dubbo, dubbo.protocol.optimizer=, dubbo.protocol.port=-1, dubbo.protocol.serialization=kryo, dubbo.reference.check=false, dubbo.reference.com.foo.BarService.check=false, dubbo.registry.address=nacos://${${spring.profiles.active}.nacos}, dubbo.registry.check=false, dubbo.scan.base-packages=com.txz.${spring.application.name}.dubbo.impl}
+2025-07-09 15:18:34.882 [com.alibaba.nacos.client.Worker.longPollingfixed-124.222.152.234_8848] INFO  o.s.c.a.AnnotationConfigApplicationContext - Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@25c2a8ad: startup date [Wed Jul 09 15:18:34 CST 2025]; root of context hierarchy
+2025-07-09 15:18:34.904 [com.alibaba.nacos.client.Worker.longPollingfixed-124.222.152.234_8848] INFO  o.s.b.f.a.AutowiredAnnotationBeanPostProcessor - JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
+2025-07-09 15:18:34.921 [com.alibaba.nacos.client.Worker.longPollingfixed-124.222.152.234_8848] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'configurationPropertiesRebinderAutoConfiguration' of type [org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration$$EnhancerBySpringCGLIB$$bc6d854c] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2025-07-09 15:18:35.025 [com.alibaba.nacos.client.Worker.longPollingfixed-124.222.152.234_8848] INFO  o.s.c.a.nacos.client.NacosPropertySourceBuilder - Loading nacos data, dataId: 'mq-dev.properties', group: 'DEFAULT_GROUP'
+2025-07-09 15:18:35.060 [com.alibaba.nacos.client.Worker.longPollingfixed-124.222.152.234_8848] INFO  o.s.c.a.nacos.client.NacosPropertySourceBuilder - Loading nacos data, dataId: 'redis-dev.properties', group: 'DEFAULT_GROUP'
+2025-07-09 15:18:35.123 [com.alibaba.nacos.client.Worker.longPollingfixed-124.222.152.234_8848] INFO  o.s.c.a.nacos.client.NacosPropertySourceBuilder - Loading nacos data, dataId: 'mall-dev.properties', group: 'DEFAULT_GROUP'
+2025-07-09 15:18:35.123 [com.alibaba.nacos.client.Worker.longPollingfixed-124.222.152.234_8848] INFO  o.s.c.b.c.PropertySourceBootstrapConfiguration - Located property source: CompositePropertySource {name='NACOS', propertySources=[NacosPropertySource {name='mall-dev.properties'}, NacosPropertySource {name='mall.properties'}, NacosPropertySource {name='redis-dev.properties'}, NacosPropertySource {name='mq-dev.properties'}]}
+2025-07-09 15:18:35.125 [com.alibaba.nacos.client.Worker.longPollingfixed-124.222.152.234_8848] INFO  org.springframework.boot.SpringApplication - The following profiles are active: dev
+2025-07-09 15:18:35.126 [com.alibaba.nacos.client.Worker.longPollingfixed-124.222.152.234_8848] INFO  o.s.c.a.AnnotationConfigApplicationContext - Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@2c677a47: startup date [Wed Jul 09 15:18:35 CST 2025]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@25c2a8ad
+2025-07-09 15:18:35.131 [com.alibaba.nacos.client.Worker.longPollingfixed-124.222.152.234_8848] INFO  o.s.b.f.a.AutowiredAnnotationBeanPostProcessor - JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
+2025-07-09 15:18:35.149 [com.alibaba.nacos.client.Worker.longPollingfixed-124.222.152.234_8848] INFO  org.springframework.boot.SpringApplication - Started application in 0.307 seconds (JVM running for 15.064)
+2025-07-09 15:18:35.150 [com.alibaba.nacos.client.Worker.longPollingfixed-124.222.152.234_8848] INFO  o.s.c.a.AnnotationConfigApplicationContext - Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@2c677a47: startup date [Wed Jul 09 15:18:35 CST 2025]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@25c2a8ad
+2025-07-09 15:18:35.150 [com.alibaba.nacos.client.Worker.longPollingfixed-124.222.152.234_8848] INFO  o.s.c.a.AnnotationConfigApplicationContext - Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@25c2a8ad: startup date [Wed Jul 09 15:18:34 CST 2025]; root of context hierarchy
+2025-07-09 15:18:35.363 [com.alibaba.nacos.client.Worker.longPollingfixed-124.222.152.234_8848] INFO  o.s.cloud.endpoint.event.RefreshEventListener - Refresh keys changed: []

+ 72 - 0
logs/operating/error.operating.log.2025-07-09.log

@@ -0,0 +1,72 @@
+2025-07-09 15:13:18.633 [main] ERROR org.springframework.boot.SpringApplication - Application run failed
+org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mapperScannerConfigurer' defined in class path resource [com/txz/mall/configurer/MybatisConfigurer.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [tk.mybatis.spring.mapper.MapperScannerConfigurer]: Factory method 'mapperScannerConfigurer' threw exception; nested exception is tk.mybatis.mapper.MapperException: 注册通用Mapper[com.txz.operating.core.Mapper]失败,找不到该通用Mapper!
+	at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:590)
+	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1247)
+	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1096)
+	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:535)
+	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:495)
+	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317)
+	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
+	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315)
+	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:204)
+	at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:114)
+	at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:694)
+	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:532)
+	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140)
+	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:780)
+	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:412)
+	at org.springframework.boot.SpringApplication.run(SpringApplication.java:333)
+	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1277)
+	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1265)
+	at com.txz.mall.MallApplication.main(MallApplication.java:26)
+Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [tk.mybatis.spring.mapper.MapperScannerConfigurer]: Factory method 'mapperScannerConfigurer' threw exception; nested exception is tk.mybatis.mapper.MapperException: 注册通用Mapper[com.txz.operating.core.Mapper]失败,找不到该通用Mapper!
+	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
+	at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:582)
+	... 18 common frames omitted
+Caused by: tk.mybatis.mapper.MapperException: 注册通用Mapper[com.txz.operating.core.Mapper]失败,找不到该通用Mapper!
+	at tk.mybatis.mapper.mapperhelper.MapperHelper.registerMapper(MapperHelper.java:194)
+	at tk.mybatis.mapper.mapperhelper.MapperHelper.setProperties(MapperHelper.java:268)
+	at tk.mybatis.spring.mapper.MapperScannerConfigurer.setProperties(MapperScannerConfigurer.java:61)
+	at com.txz.mall.configurer.MybatisConfigurer.mapperScannerConfigurer(MybatisConfigurer.java:44)
+	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
+	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+	at java.lang.reflect.Method.invoke(Method.java:498)
+	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
+	... 19 common frames omitted
+2025-07-09 15:15:23.320 [main] ERROR org.springframework.boot.SpringApplication - Application run failed
+org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mapperScannerConfigurer' defined in class path resource [com/txz/mall/configurer/MybatisConfigurer.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [tk.mybatis.spring.mapper.MapperScannerConfigurer]: Factory method 'mapperScannerConfigurer' threw exception; nested exception is tk.mybatis.mapper.MapperException: 注册通用Mapper[com.txz.operating.core.Mapper]失败,找不到该通用Mapper!
+	at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:590)
+	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1247)
+	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1096)
+	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:535)
+	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:495)
+	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317)
+	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
+	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315)
+	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:204)
+	at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:114)
+	at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:694)
+	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:532)
+	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140)
+	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:780)
+	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:412)
+	at org.springframework.boot.SpringApplication.run(SpringApplication.java:333)
+	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1277)
+	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1265)
+	at com.txz.mall.MallApplication.main(MallApplication.java:26)
+Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [tk.mybatis.spring.mapper.MapperScannerConfigurer]: Factory method 'mapperScannerConfigurer' threw exception; nested exception is tk.mybatis.mapper.MapperException: 注册通用Mapper[com.txz.operating.core.Mapper]失败,找不到该通用Mapper!
+	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
+	at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:582)
+	... 18 common frames omitted
+Caused by: tk.mybatis.mapper.MapperException: 注册通用Mapper[com.txz.operating.core.Mapper]失败,找不到该通用Mapper!
+	at tk.mybatis.mapper.mapperhelper.MapperHelper.registerMapper(MapperHelper.java:194)
+	at tk.mybatis.mapper.mapperhelper.MapperHelper.setProperties(MapperHelper.java:268)
+	at tk.mybatis.spring.mapper.MapperScannerConfigurer.setProperties(MapperScannerConfigurer.java:61)
+	at com.txz.mall.configurer.MybatisConfigurer.mapperScannerConfigurer(MybatisConfigurer.java:44)
+	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
+	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
+	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
+	at java.lang.reflect.Method.invoke(Method.java:498)
+	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
+	... 19 common frames omitted

+ 64 - 0
logs/operating/log.operating.2025-07-09.0.log

@@ -0,0 +1,64 @@
+2025-07-09 15:13:16.031 [main] INFO  org.apache.dubbo.common.logger.LoggerFactory - using logger: org.apache.dubbo.common.logger.slf4j.Slf4jLoggerAdapter
+2025-07-09 15:13:16.040 [main] INFO  o.a.d.s.b.c.event.WelcomeLogoApplicationListener - 
+
+ :: Dubbo Spring Boot (v2.7.1) : https://github.com/apache/incubator-dubbo-spring-boot-project
+ :: Dubbo (v2.7.1) : https://github.com/apache/incubator-dubbo
+ :: Discuss group : dev@dubbo.apache.org
+
+2025-07-09 15:13:16.044 [main] INFO  o.a.d.s.b.c.e.OverrideDubboConfigApplicationListener - Dubbo Config was overridden by externalized configuration {dubbo.application.name=mall, dubbo.application.qos-enable=false, dubbo.application.qos.accept.foreign.ip=true, dubbo.application.qos.enable=true, dubbo.application.qos.port=28201, dubbo.config.multiple=true, dubbo.consumer.check=false, dubbo.protocol.dubbo.payload=83886080, dubbo.protocol.name=dubbo, dubbo.protocol.optimizer=, dubbo.protocol.port=-1, dubbo.protocol.serialization=kryo, dubbo.reference.check=false, dubbo.reference.com.foo.BarService.check=false, dubbo.registry.address=nacos://${${spring.profiles.active}.nacos}, dubbo.registry.check=false, dubbo.scan.base-packages=com.txz.${spring.application.name}.dubbo.impl}
+2025-07-09 15:13:16.282 [main] INFO  o.s.c.a.AnnotationConfigApplicationContext - Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@49872d67: startup date [Wed Jul 09 15:13:16 CST 2025]; root of context hierarchy
+2025-07-09 15:13:16.513 [main] INFO  o.s.b.f.a.AutowiredAnnotationBeanPostProcessor - JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
+2025-07-09 15:13:16.566 [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'configurationPropertiesRebinderAutoConfiguration' of type [org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration$$EnhancerBySpringCGLIB$$f1f14fba] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2025-07-09 15:13:16.798 [pool-3-thread-1] INFO  o.a.d.s.b.c.e.AwaitingNonWebApplicationListener -  [Dubbo] Current Spring Boot Application is await...
+2025-07-09 15:13:16.859 [main] INFO  o.a.d.s.b.c.e.OverrideDubboConfigApplicationListener - Dubbo Config was overridden by externalized configuration {dubbo.application.name=mall, dubbo.application.qos-enable=false, dubbo.application.qos.accept.foreign.ip=true, dubbo.application.qos.enable=true, dubbo.application.qos.port=28201, dubbo.config.multiple=true, dubbo.consumer.check=false, dubbo.protocol.dubbo.payload=83886080, dubbo.protocol.name=dubbo, dubbo.protocol.optimizer=, dubbo.protocol.port=-1, dubbo.protocol.serialization=kryo, dubbo.reference.check=false, dubbo.reference.com.foo.BarService.check=false, dubbo.registry.address=nacos://${${spring.profiles.active}.nacos}, dubbo.registry.check=false, dubbo.scan.base-packages=com.txz.${spring.application.name}.dubbo.impl}
+2025-07-09 15:13:17.066 [main] INFO  o.s.c.a.nacos.client.NacosPropertySourceBuilder - Loading nacos data, dataId: 'mq-dev.properties', group: 'DEFAULT_GROUP'
+2025-07-09 15:13:17.111 [main] INFO  o.s.c.a.nacos.client.NacosPropertySourceBuilder - Loading nacos data, dataId: 'redis-dev.properties', group: 'DEFAULT_GROUP'
+2025-07-09 15:13:17.189 [main] INFO  o.s.c.a.nacos.client.NacosPropertySourceBuilder - Loading nacos data, dataId: 'mall-dev.properties', group: 'DEFAULT_GROUP'
+2025-07-09 15:13:17.189 [main] INFO  o.s.c.b.c.PropertySourceBootstrapConfiguration - Located property source: CompositePropertySource {name='NACOS', propertySources=[NacosPropertySource {name='mall-dev.properties'}, NacosPropertySource {name='mall.properties'}, NacosPropertySource {name='redis-dev.properties'}, NacosPropertySource {name='mq-dev.properties'}]}
+2025-07-09 15:13:17.202 [main] INFO  com.txz.mall.MallApplication - The following profiles are active: dev
+2025-07-09 15:13:17.226 [main] INFO  o.s.b.w.s.c.AnnotationConfigServletWebServerApplicationContext - Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@7d2a6eac: startup date [Wed Jul 09 15:13:17 CST 2025]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@49872d67
+2025-07-09 15:13:18.107 [main] INFO  o.s.b.factory.support.DefaultListableBeanFactory - Overriding bean definition for bean 'servletWebServerFactory' with a different definition: replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=undertowExtraConfiguration; factoryMethodName=servletWebServerFactory; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [com/txz/mall/configurer/shutdown/UndertowExtraConfiguration.class]] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=mallApplication; factoryMethodName=servletWebServerFactory; initMethodName=null; destroyMethodName=(inferred); defined in com.txz.mall.MallApplication]
+2025-07-09 15:13:18.234 [main] INFO  o.a.d.c.s.c.annotation.DubboConfigBindingRegistrar - The dubbo config bean definition [name : org.apache.dubbo.config.ApplicationConfig#0, class : org.apache.dubbo.config.ApplicationConfig] has been registered.
+2025-07-09 15:13:18.234 [main] INFO  o.a.d.c.s.c.annotation.DubboConfigBindingRegistrar - The BeanPostProcessor bean definition [org.apache.dubbo.config.spring.beans.factory.annotation.DubboConfigBindingBeanPostProcessor] for dubbo config bean [name : org.apache.dubbo.config.ApplicationConfig#0] has been registered.
+2025-07-09 15:13:18.235 [main] INFO  o.a.d.c.s.c.annotation.DubboConfigBindingRegistrar - The dubbo config bean definition [name : org.apache.dubbo.config.RegistryConfig#0, class : org.apache.dubbo.config.RegistryConfig] has been registered.
+2025-07-09 15:13:18.235 [main] INFO  o.a.d.c.s.c.annotation.DubboConfigBindingRegistrar - The BeanPostProcessor bean definition [org.apache.dubbo.config.spring.beans.factory.annotation.DubboConfigBindingBeanPostProcessor] for dubbo config bean [name : org.apache.dubbo.config.RegistryConfig#0] has been registered.
+2025-07-09 15:13:18.236 [main] INFO  o.a.d.c.s.c.annotation.DubboConfigBindingRegistrar - The dubbo config bean definition [name : org.apache.dubbo.config.ProtocolConfig#0, class : org.apache.dubbo.config.ProtocolConfig] has been registered.
+2025-07-09 15:13:18.236 [main] INFO  o.a.d.c.s.c.annotation.DubboConfigBindingRegistrar - The BeanPostProcessor bean definition [org.apache.dubbo.config.spring.beans.factory.annotation.DubboConfigBindingBeanPostProcessor] for dubbo config bean [name : org.apache.dubbo.config.ProtocolConfig#0] has been registered.
+2025-07-09 15:13:18.236 [main] INFO  o.a.d.c.s.c.annotation.DubboConfigBindingRegistrar - The dubbo config bean definition [name : org.apache.dubbo.config.ConsumerConfig#0, class : org.apache.dubbo.config.ConsumerConfig] has been registered.
+2025-07-09 15:13:18.236 [main] INFO  o.a.d.c.s.c.annotation.DubboConfigBindingRegistrar - The BeanPostProcessor bean definition [org.apache.dubbo.config.spring.beans.factory.annotation.DubboConfigBindingBeanPostProcessor] for dubbo config bean [name : org.apache.dubbo.config.ConsumerConfig#0] has been registered.
+2025-07-09 15:13:18.431 [main] INFO  o.s.d.r.config.RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode!
+2025-07-09 15:13:18.624 [main] INFO  o.s.b.a.l.ConditionEvaluationReportLoggingListener - 
+
+Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
+2025-07-09 15:15:20.640 [main] INFO  org.apache.dubbo.common.logger.LoggerFactory - using logger: org.apache.dubbo.common.logger.slf4j.Slf4jLoggerAdapter
+2025-07-09 15:15:20.644 [main] INFO  o.a.d.s.b.c.event.WelcomeLogoApplicationListener - 
+
+ :: Dubbo Spring Boot (v2.7.1) : https://github.com/apache/incubator-dubbo-spring-boot-project
+ :: Dubbo (v2.7.1) : https://github.com/apache/incubator-dubbo
+ :: Discuss group : dev@dubbo.apache.org
+
+2025-07-09 15:15:20.647 [main] INFO  o.a.d.s.b.c.e.OverrideDubboConfigApplicationListener - Dubbo Config was overridden by externalized configuration {dubbo.application.name=mall, dubbo.application.qos-enable=false, dubbo.application.qos.accept.foreign.ip=true, dubbo.application.qos.enable=true, dubbo.application.qos.port=28201, dubbo.config.multiple=true, dubbo.consumer.check=false, dubbo.protocol.dubbo.payload=83886080, dubbo.protocol.name=dubbo, dubbo.protocol.optimizer=, dubbo.protocol.port=-1, dubbo.protocol.serialization=kryo, dubbo.reference.check=false, dubbo.reference.com.foo.BarService.check=false, dubbo.registry.address=nacos://${${spring.profiles.active}.nacos}, dubbo.registry.check=false, dubbo.scan.base-packages=com.txz.${spring.application.name}.dubbo.impl}
+2025-07-09 15:15:20.916 [main] INFO  o.s.c.a.AnnotationConfigApplicationContext - Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@1253e7cb: startup date [Wed Jul 09 15:15:20 CST 2025]; root of context hierarchy
+2025-07-09 15:15:21.192 [main] INFO  o.s.b.f.a.AutowiredAnnotationBeanPostProcessor - JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
+2025-07-09 15:15:21.243 [main] INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'configurationPropertiesRebinderAutoConfiguration' of type [org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration$$EnhancerBySpringCGLIB$$2ea76a7a] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
+2025-07-09 15:15:21.507 [pool-3-thread-1] INFO  o.a.d.s.b.c.e.AwaitingNonWebApplicationListener -  [Dubbo] Current Spring Boot Application is await...
+2025-07-09 15:15:21.577 [main] INFO  o.a.d.s.b.c.e.OverrideDubboConfigApplicationListener - Dubbo Config was overridden by externalized configuration {dubbo.application.name=mall, dubbo.application.qos-enable=false, dubbo.application.qos.accept.foreign.ip=true, dubbo.application.qos.enable=true, dubbo.application.qos.port=28201, dubbo.config.multiple=true, dubbo.consumer.check=false, dubbo.protocol.dubbo.payload=83886080, dubbo.protocol.name=dubbo, dubbo.protocol.optimizer=, dubbo.protocol.port=-1, dubbo.protocol.serialization=kryo, dubbo.reference.check=false, dubbo.reference.com.foo.BarService.check=false, dubbo.registry.address=nacos://${${spring.profiles.active}.nacos}, dubbo.registry.check=false, dubbo.scan.base-packages=com.txz.${spring.application.name}.dubbo.impl}
+2025-07-09 15:15:21.763 [main] INFO  o.s.c.a.nacos.client.NacosPropertySourceBuilder - Loading nacos data, dataId: 'mq-dev.properties', group: 'DEFAULT_GROUP'
+2025-07-09 15:15:21.798 [main] INFO  o.s.c.a.nacos.client.NacosPropertySourceBuilder - Loading nacos data, dataId: 'redis-dev.properties', group: 'DEFAULT_GROUP'
+2025-07-09 15:15:21.855 [main] INFO  o.s.c.a.nacos.client.NacosPropertySourceBuilder - Loading nacos data, dataId: 'mall-dev.properties', group: 'DEFAULT_GROUP'
+2025-07-09 15:15:21.856 [main] INFO  o.s.c.b.c.PropertySourceBootstrapConfiguration - Located property source: CompositePropertySource {name='NACOS', propertySources=[NacosPropertySource {name='mall-dev.properties'}, NacosPropertySource {name='mall.properties'}, NacosPropertySource {name='redis-dev.properties'}, NacosPropertySource {name='mq-dev.properties'}]}
+2025-07-09 15:15:21.866 [main] INFO  com.txz.mall.MallApplication - The following profiles are active: dev
+2025-07-09 15:15:21.890 [main] INFO  o.s.b.w.s.c.AnnotationConfigServletWebServerApplicationContext - Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@5eefa415: startup date [Wed Jul 09 15:15:21 CST 2025]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@1253e7cb
+2025-07-09 15:15:22.799 [main] INFO  o.s.b.factory.support.DefaultListableBeanFactory - Overriding bean definition for bean 'servletWebServerFactory' with a different definition: replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=undertowExtraConfiguration; factoryMethodName=servletWebServerFactory; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [com/txz/mall/configurer/shutdown/UndertowExtraConfiguration.class]] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=mallApplication; factoryMethodName=servletWebServerFactory; initMethodName=null; destroyMethodName=(inferred); defined in com.txz.mall.MallApplication]
+2025-07-09 15:15:22.915 [main] INFO  o.a.d.c.s.c.annotation.DubboConfigBindingRegistrar - The dubbo config bean definition [name : org.apache.dubbo.config.ApplicationConfig#0, class : org.apache.dubbo.config.ApplicationConfig] has been registered.
+2025-07-09 15:15:22.916 [main] INFO  o.a.d.c.s.c.annotation.DubboConfigBindingRegistrar - The BeanPostProcessor bean definition [org.apache.dubbo.config.spring.beans.factory.annotation.DubboConfigBindingBeanPostProcessor] for dubbo config bean [name : org.apache.dubbo.config.ApplicationConfig#0] has been registered.
+2025-07-09 15:15:22.917 [main] INFO  o.a.d.c.s.c.annotation.DubboConfigBindingRegistrar - The dubbo config bean definition [name : org.apache.dubbo.config.RegistryConfig#0, class : org.apache.dubbo.config.RegistryConfig] has been registered.
+2025-07-09 15:15:22.917 [main] INFO  o.a.d.c.s.c.annotation.DubboConfigBindingRegistrar - The BeanPostProcessor bean definition [org.apache.dubbo.config.spring.beans.factory.annotation.DubboConfigBindingBeanPostProcessor] for dubbo config bean [name : org.apache.dubbo.config.RegistryConfig#0] has been registered.
+2025-07-09 15:15:22.918 [main] INFO  o.a.d.c.s.c.annotation.DubboConfigBindingRegistrar - The dubbo config bean definition [name : org.apache.dubbo.config.ProtocolConfig#0, class : org.apache.dubbo.config.ProtocolConfig] has been registered.
+2025-07-09 15:15:22.918 [main] INFO  o.a.d.c.s.c.annotation.DubboConfigBindingRegistrar - The BeanPostProcessor bean definition [org.apache.dubbo.config.spring.beans.factory.annotation.DubboConfigBindingBeanPostProcessor] for dubbo config bean [name : org.apache.dubbo.config.ProtocolConfig#0] has been registered.
+2025-07-09 15:15:22.918 [main] INFO  o.a.d.c.s.c.annotation.DubboConfigBindingRegistrar - The dubbo config bean definition [name : org.apache.dubbo.config.ConsumerConfig#0, class : org.apache.dubbo.config.ConsumerConfig] has been registered.
+2025-07-09 15:15:22.918 [main] INFO  o.a.d.c.s.c.annotation.DubboConfigBindingRegistrar - The BeanPostProcessor bean definition [org.apache.dubbo.config.spring.beans.factory.annotation.DubboConfigBindingBeanPostProcessor] for dubbo config bean [name : org.apache.dubbo.config.ConsumerConfig#0] has been registered.
+2025-07-09 15:15:23.114 [main] INFO  o.s.d.r.config.RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode!
+2025-07-09 15:15:23.313 [main] INFO  o.s.b.a.l.ConditionEvaluationReportLoggingListener - 
+
+Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.

+ 62 - 0
mall-api/pom.xml

@@ -0,0 +1,62 @@
+<?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>mall</artifactId>
+        <groupId>com.txz</groupId>
+        <version>1.0.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>mall-api</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <dependencies>
+
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <version>1.18.10</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>1.2.69</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>RELEASE</version>
+            <scope>compile</scope>
+        </dependency>
+<!--        <dependency>-->
+<!--            <groupId>org.springframework.data</groupId>-->
+<!--            <artifactId>spring-data-redis</artifactId>-->
+<!--            <scope>compile</scope>-->
+<!--        </dependency>-->
+
+
+    </dependencies>
+
+
+    <build>
+        <plugins>
+            <!-- 要将源码放上去,需要加入这个插件 -->
+            <plugin>
+                <artifactId>maven-source-plugin</artifactId>
+                <version>3.2.0</version>
+                <configuration>
+                    <attach>true</attach>
+                </configuration>
+                <executions>
+                    <execution>
+                        <phase>compile</phase>
+                        <goals>
+                            <goal>jar</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>

+ 57 - 0
mall-api/src/main/java/com/txz/mall/AppModuleBO.java

@@ -0,0 +1,57 @@
+package com.txz.mall;
+
+import lombok.*;
+
+
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+@Getter
+@Setter
+public class AppModuleBO {
+    private Long id;
+
+    /**
+     * 应用编码
+     */
+    private String appCode;
+
+    /**
+     * 模块名称
+     */
+    private String name;
+
+    /**
+     * 携带内容
+     */
+    private String content;
+
+
+    /**
+     * 是否检查版本 1检查 2不检查
+     */
+    private Byte checkVersion;
+
+    /**
+     * 模块名称
+     */
+    private String version;
+
+    /**
+     * 模块编码
+     */
+    private String code;
+
+    /**
+     * 用户分群id  为空则不参与判断
+     */
+    private String clusterIds;
+
+
+    /**
+     * 状态 1开放 2关闭
+     */
+    private Byte status;
+
+
+}

+ 16 - 0
mall-api/src/main/resources/i18n/error.properties

@@ -0,0 +1,16 @@
+BUSINESS_ERROR_001=\u8BF7\u68C0\u67E5\u624B\u673A\u53F7\u662F\u5426\u6B63\u786E
+BUSINESS_ERROR_002=\u624B\u673A\u53F7\u548C\u5BC6\u7801\u4E0D\u5339\u914D
+BUSINESS_ERROR_003=APP\u767B\u5F55\u6388\u6743\u5931\u8D25
+BUSINESS_ERROR_004=AccountKit \u767B\u5F55\u5931\u8D25\uFF0C\u8BF7\u91CD\u65B0\u9A8C\u8BC1
+BUSINESS_ERROR_005=\u624B\u673A\u53F7\u5DF2\u6CE8\u518C
+BUSINESS_ERROR_006=\u9A8C\u8BC1\u5DF2\u8FC7\u671F
+BUSINESS_ERROR_007=\u9A8C\u8BC1\u7801\u9519\u8BEF
+BUSINESS_ERROR_008=\u8BBE\u7F6E\u5BC6\u7801\u5931\u8D25
+BUSINESS_ERROR_009=\u8BF7\u91CD\u65B0\u9A8C\u8BC1code
+BUSINESS_ERROR_010=Facebook \u767B\u5F55\u5931\u8D25
+BUSINESS_ERROR_011=\u6B64 Facebook \u5DF2\u88AB\u5176\u4ED6\u8D26\u53F7\u4F7F\u7528
+BUSINESS_ERROR_012=\u8BF7\u60A8\u5148\u767B\u9646
+BUSINESS_ERROR_013=\u7CFB\u7EDF\u5185\u90E8\u5F02\u5E38\uFF0Csource \u8BF7\u6C42\u53C2\u6570\u4E0D\u5408\u6CD5
+BUSINESS_ERROR_014=\u624B\u673A\u53F7\u5DF2\u5173\u8054\u8FC7\u5176\u4ED6 Facebook \u8D26\u53F7\uFF0C\u8BF7\u6362\u4E00\u4E2A\u53F7\u7801\u8BD5\u8BD5
+
+PARAMETER_ERROR_001=\u65E0\u6548\u7684\u53C2\u6570

+ 16 - 0
mall-api/src/main/resources/i18n/error_in_ID.properties

@@ -0,0 +1,16 @@
+BUSINESS_ERROR_001=Silakan periksa apakah nomor telepon sudah benar
+BUSINESS_ERROR_002=Nomor telepon dan kata sandi tidak cocok
+BUSINESS_ERROR_003=Otorisasi login APP gagal
+BUSINESS_ERROR_004=Login Akun gagal, harap verifikasi ulang
+BUSINESS_ERROR_005=Nomor anda telah diregistrasi
+BUSINESS_ERROR_006=Verifikasi telah kedaluwarsa
+BUSINESS_ERROR_007=Kode verifikasi salah
+BUSINESS_ERROR_008=Gagal mengatur kata sandi
+BUSINESS_ERROR_009=Harap verifikasi ulang kodenya
+BUSINESS_ERROR_010=Verifikasi Facebook gagal
+BUSINESS_ERROR_011=Akun Facebook ini telah digunakan oleh akun lain
+BUSINESS_ERROR_012=Silahkan login
+BUSINESS_ERROR_013=Kesalahan internal sistem
+BUSINESS_ERROR_014=Nomor telepon ini telah terhubung dengan akun Facebook, silahkan ganti nomor untuk mencoba
+
+PARAMETER_ERROR_001=Parameter tidak valid

+ 122 - 0
mall-service/pom.xml

@@ -0,0 +1,122 @@
+<?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>mall</artifactId>
+        <groupId>com.txz</groupId>
+        <version>1.0.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>mall-service</artifactId>
+    <packaging>jar</packaging>
+    <version>1.0.0-SNAPSHOT</version>
+    <properties>
+        <java.version>1.8</java.version>
+    </properties>
+
+    <!-- Inherit defaults from Spring Boot -->
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>redis.clients</groupId>
+            <artifactId>jedis</artifactId>
+            <version>3.3.0</version>
+        </dependency>
+
+
+        <dependency>
+            <groupId>org.apache.rocketmq</groupId>
+            <artifactId>rocketmq-spring-boot-starter</artifactId>
+        </dependency>
+
+
+        <!--格式化sql日志-->
+        <dependency>
+            <groupId>p6spy</groupId>
+            <artifactId>p6spy</artifactId>
+            <version>3.8.6</version>
+        </dependency>
+        <!--Spring Boot依赖-->
+
+        <!--异维科技dubbo接口包依赖-->
+        <dependency>
+            <groupId>com.txz</groupId>
+            <artifactId>mall-api</artifactId>
+            <version>1.0.0-SNAPSHOT</version>
+        </dependency>
+
+        <!--test依赖-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <!--异维科技公共包依赖-->
+        <dependency>
+            <groupId>com.txz</groupId>
+            <artifactId>common</artifactId>
+            <version>1.0.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>5.2.4</version>
+            <scope>compile</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>com.tencentcloudapi</groupId>
+            <artifactId>tencentcloud-sdk-java</artifactId>
+            <!-- 请到 https://search.maven.org/search?q=tencentcloud-sdk-java 查询最新版本 -->
+            <version>3.1.158</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.baidu.aip</groupId>
+            <artifactId>java-sdk</artifactId>
+            <version>4.15.1</version>
+            <exclusions>
+                <exclusion>
+                    <artifactId>guava</artifactId>
+                    <groupId>com.google.guava</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <finalName>mall</finalName>
+                </configuration>
+            </plugin>
+            <plugin>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>${java.version}</source>
+                    <target>${java.version}</target>
+                    <encoding>UTF-8</encoding>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <version>${maven-surefire-plugin.version}</version>
+                <configuration>
+                    <skipTests>true</skipTests>  <!--默认关掉单元测试 -->
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+
+</project>

+ 19 - 0
mall-service/src/main/java/com/txz/mall/FeignConfiguration.java

@@ -0,0 +1,19 @@
+//package com.txz.operating;
+//import feign.Request;
+//import org.springframework.beans.factory.annotation.Value;
+//import org.springframework.context.annotation.Bean;
+//import org.springframework.context.annotation.Configuration;
+//
+//@Configuration
+//public class FeignConfiguration {
+//    @Value("${feign.connectTimeout:60000}")
+//    private int connectTimeout;
+//
+//    @Value("${feign.readTimeOut:60000}")
+//    private int readTimeout;
+//
+//    @Bean
+//    public Request.Options options() {
+//        return new Request.Options(connectTimeout, readTimeout);
+//    }
+//}

+ 51 - 0
mall-service/src/main/java/com/txz/mall/MallApplication.java

@@ -0,0 +1,51 @@
+package com.txz.mall;
+
+import com.spring4all.swagger.EnableSwagger2Doc;
+import com.txz.mall.configurer.shutdown.GracefulShutdownUndertowWrapper;
+import io.undertow.UndertowOptions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.web.client.RestTemplateBuilder;
+import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+import org.springframework.cloud.client.loadbalancer.LoadBalanced;
+import org.springframework.context.annotation.Bean;
+import org.springframework.web.client.RestTemplate;
+
+@EnableDiscoveryClient
+@SpringBootApplication
+@EnableSwagger2Doc
+//@RibbonClients(value = {
+//        @RibbonClient(name = "operating",configuration = RibbonWeightedResponseTimeRuleConfig.class)
+//})
+//@EnableFeignClients(basePackages = {"com.txz.operating.service"})
+public class MallApplication {
+
+    public static void main(String[] args) throws Exception {
+        SpringApplication.run(MallApplication.class, args);
+    }
+
+    @Autowired
+    private GracefulShutdownUndertowWrapper gracefulShutdownUndertowWrapper;
+
+    @Bean
+    public UndertowServletWebServerFactory servletWebServerFactory() {
+        UndertowServletWebServerFactory factory = new UndertowServletWebServerFactory();
+        factory.addDeploymentInfoCustomizers(deploymentInfo -> deploymentInfo.addOuterHandlerChainWrapper(gracefulShutdownUndertowWrapper));
+        factory.addBuilderCustomizers(builder -> builder.setServerOption(UndertowOptions.ENABLE_STATISTICS, true));
+        return factory;
+    }
+
+    /**
+     * 负载均衡
+     * 默认的负载均衡机制采用的类似轮询的这种均衡机制
+     */
+    @Bean
+    @LoadBalanced
+    public RestTemplate restTemplate(RestTemplateBuilder builder){
+        //spring官网建议RestTemplateBuilder构造器来进行构造,这里体现了构造者设计模式
+        return builder.build();
+    }
+}
+

+ 43 - 0
mall-service/src/main/java/com/txz/mall/configurer/HeaderAttribute.java

@@ -0,0 +1,43 @@
+package com.txz.mall.configurer;
+
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ModelAttribute;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * @author :yuzhengqun
+ * @date :Created in 2019/11/15 17:19
+ */
+@ControllerAdvice
+public class HeaderAttribute {
+
+    @ModelAttribute(value = "userId")
+    public Long getUserId(HttpServletRequest request) {
+        String userId = request.getHeader("userId");
+        if (userId == null) {
+            return null;
+        }
+        return Long.valueOf(userId);
+    }
+
+    @ModelAttribute(value = "token")
+    public String getToken(HttpServletRequest request) {
+        String token = request.getHeader("token");
+        if (token == null) {
+            return null;
+        }
+        return token;
+    }
+
+
+    @ModelAttribute(value = "appCode")
+    public String getAppCode(HttpServletRequest request) {
+        String appCode = request.getHeader("appCode");
+        if (appCode == null) {
+            return null;
+        }
+        return appCode;
+    }
+
+}

+ 45 - 0
mall-service/src/main/java/com/txz/mall/configurer/IpConfiguration.java

@@ -0,0 +1,45 @@
+package com.txz.mall.configurer;
+
+
+import org.springframework.boot.web.context.WebServerInitializedEvent;
+import org.springframework.context.ApplicationListener;
+import org.springframework.stereotype.Component;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+@Component
+public class IpConfiguration implements ApplicationListener<WebServerInitializedEvent> {
+
+    private int serverPort;
+
+
+    @Override
+    public void onApplicationEvent(WebServerInitializedEvent event) {
+        this.serverPort = event.getWebServer().getPort();
+    }
+
+    public int getPort() {
+        return this.serverPort;
+    }
+
+    public String getIpAndPort() {
+        InetAddress address = null;
+        try {
+            address = InetAddress.getLocalHost();
+        } catch (UnknownHostException e) {
+            e.printStackTrace();
+        }
+        return address.getHostAddress() +":"+getPort();
+    }
+
+    public String getIp() {
+        InetAddress address = null;
+        try {
+            address = InetAddress.getLocalHost();
+        } catch (UnknownHostException e) {
+            e.printStackTrace();
+        }
+        return address.getHostAddress();
+    }
+}

+ 252 - 0
mall-service/src/main/java/com/txz/mall/configurer/MyWebMvcConfigurer.java

@@ -0,0 +1,252 @@
+package com.txz.mall.configurer;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.serializer.SerializeConfig;
+import com.alibaba.fastjson.serializer.SerializerFeature;
+import com.alibaba.fastjson.serializer.ToStringSerializer;
+import com.alibaba.fastjson.support.config.FastJsonConfig;
+import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
+import com.txz.mall.core.ProjectConstant;
+import com.txz.mall.core.Result;
+import com.txz.mall.core.ResultCode;
+import com.txz.mall.core.ServiceException;
+import com.txz.mall.core.cache.CacheKey;
+import com.txz.mall.core.cache.CacheType;
+import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.http.MediaType;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
+import org.springframework.web.method.HandlerMethod;
+import org.springframework.web.servlet.HandlerExceptionResolver;
+import org.springframework.web.servlet.ModelAndView;
+import org.springframework.web.servlet.NoHandlerFoundException;
+import org.springframework.web.servlet.config.annotation.CorsRegistry;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
+
+import javax.annotation.Resource;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Spring MVC 配置
+ */
+@Configuration
+public class MyWebMvcConfigurer implements WebMvcConfigurer {
+
+    private final Logger  logger = LoggerFactory.getLogger(MyWebMvcConfigurer.class);
+    @Resource
+    private Parameters parameters;
+
+    @Resource
+    private RedisTemplate redisTemplate;
+
+    @Override
+    public void addResourceHandlers(ResourceHandlerRegistry registry) {
+
+        registry.addResourceHandler("swagger-ui.html")
+                .addResourceLocations("classpath:/META-INF/resources/");
+        registry.addResourceHandler("docs.html")
+                .addResourceLocations("classpath:/META-INF/resources/");
+        registry.addResourceHandler("doc.html")
+                .addResourceLocations("classpath:/META-INF/resources/");
+
+        registry.addResourceHandler("/webjars/**")
+                .addResourceLocations("classpath:/META-INF/resources/webjars/");
+    }
+
+    // 使用阿里 FastJson 作为JSON MessageConverter
+    @Override
+    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
+        for (int i = converters.size() - 1; i >= 0; i--) {
+            if (converters.get(i) instanceof MappingJackson2HttpMessageConverter) {
+                converters.remove(i);
+            }
+        }
+        FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
+        //自定义fastjson配置
+        FastJsonConfig config = new FastJsonConfig();
+        config.setDateFormat("yyyy-MM-dd HH:mm:ss");
+        config.setSerializerFeatures(
+                SerializerFeature.WriteMapNullValue,        // 是否输出值为null的字段,默认为false,我们将它打开
+                SerializerFeature.WriteNullListAsEmpty,     // 将Collection类型字段的字段空值输出为[]
+                SerializerFeature.WriteNullStringAsEmpty,   // 将字符串类型字段的空值输出为空字符串
+                SerializerFeature.WriteNullNumberAsZero,    // 将数值类型字段的空值输出为0
+                SerializerFeature.WriteDateUseDateFormat,
+                SerializerFeature.DisableCircularReferenceDetect    // 禁用循环引用
+        );
+        SerializeConfig serializeConfig = SerializeConfig.globalInstance;
+        serializeConfig.put(BigInteger.class, ToStringSerializer.instance);
+        serializeConfig.put(Long.class, ToStringSerializer.instance);
+        serializeConfig.put(Long.TYPE, ToStringSerializer.instance);
+        config.setSerializeConfig(serializeConfig);
+        fastJsonHttpMessageConverter.setFastJsonConfig(config);
+        // 添加支持的MediaTypes;不添加时默认为*/*,也就是默认支持全部
+        // 但是MappingJackson2HttpMessageConverter里面支持的MediaTypes为application/json
+        // 参考它的做法, fastjson也只添加application/json的MediaType
+        List<MediaType> fastMediaTypes = new ArrayList<>();
+        fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
+        fastJsonHttpMessageConverter.setSupportedMediaTypes(fastMediaTypes);
+        converters.add(fastJsonHttpMessageConverter);
+        // 设置项目名称
+        ProjectConstant.application = parameters.getApplication();
+    }
+
+    // 统一异常处理
+    @Override
+    public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
+        exceptionResolvers.add((request, response, handler, e) -> {
+            Result result = new Result();
+            if (e instanceof ServiceException) {// 业务失败的异常,如“账号或密码错误”
+                result.setCode(ResultCode.FAIL.getCode()).setMessage(e.getMessage());
+                logger.info(e.getMessage());
+            } else if (e instanceof NoHandlerFoundException) {
+                result.setCode(ResultCode.NOT_FOUND.getCode()).setMessage(
+                    "接口 [" + request.getRequestURI() + "] 不存在");
+            } else if (e instanceof ServletException) {
+                result.setCode(ResultCode.FAIL.getCode()).setMessage(e.getMessage());
+            } else {
+                result.setCode(ResultCode.INTERNAL_SERVER_ERROR.getCode()).setMessage(
+                    "接口 [" + request.getRequestURI() + "] 内部错误,请联系管理员");
+                String message;
+                if (handler instanceof HandlerMethod) {
+                    HandlerMethod handlerMethod = (HandlerMethod) handler;
+                    message = String.format("接口 [%s] 出现异常,方法:%s.%s,异常摘要:%s",
+                        request.getRequestURI(), handlerMethod.getBean().getClass().getName(),
+                        handlerMethod.getMethod().getName(), e.getMessage());
+                } else {
+                    message = e.getMessage();
+                }
+                logger.error(message, e);
+            }
+            responseResult(response, result);
+            return new ModelAndView();
+        });
+    }
+
+    // 解决跨域问题
+    @Override
+    public void addCorsMappings(CorsRegistry registry) {
+         registry.addMapping("/**");
+    }
+
+    // 添加拦截器
+    @Override
+    public void addInterceptors(InterceptorRegistry registry) {
+        // 接口签名认证拦截器,该签名认证比较简单,实际项目中可以使用Json Web Token或其他更好的方式替代。
+        if ("true".equals(parameters.getSignature())) { // 开发环境忽略签名认证
+            registry.addInterceptor(new HandlerInterceptorAdapter() {
+                @Override
+                public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
+                                         Object handler) throws Exception {
+                    // 验证签名
+                    boolean pass = validateSign(request);
+                    if (pass) {
+                        return true;
+                    } else {
+                        logger.warn("签名认证失败,请求接口:{},请求IP:{},请求参数:{}", request.getRequestURI(),
+                            getIpAddress(request), JSON.toJSONString(request.getParameterMap()));
+
+                        Result result = new Result();
+                        result.setCode(ResultCode.UNAUTHORIZED.getCode()).setMessage("签名认证失败");
+                        responseResult(response, result);
+                        return false;
+                    }
+                }
+            });
+        }
+    }
+
+    private void responseResult(HttpServletResponse response, Result result) {
+        response.setCharacterEncoding("UTF-8");
+        response.setHeader("Content-type", "application/json;charset=UTF-8");
+        response.setStatus(200);
+        try {
+            response.getWriter().write(JSON.toJSONString(result));
+        } catch (IOException ex) {
+            logger.error(ex.getMessage());
+        }
+    }
+
+    /**
+     * 一个简单的登录认证
+     */
+    private boolean validateLogin(HttpServletRequest request) {
+        String userId = request.getParameter("userId");
+        if (StringUtils.isBlank(userId)) {
+            return false;
+        }
+        CacheKey key = CacheKey.generateKey(CacheType.AppSecretKey, userId);
+        boolean exists = redisTemplate.hasKey(key.toString());
+        if (exists) {
+            return true;
+        } else {
+            return false;
+        }
+
+    }
+
+    /**
+     * 一个简单的签名认证,规则: 1. 将请求参数按ascii码排序 2. 拼接为a=value&b=value...这样的字符串(不包含sign)
+     * 3. 混合密钥(secret)进行md5获得签名,与请求的签名进行比较
+     */
+    private boolean validateSign(HttpServletRequest request) {
+        String requestSign = request.getParameter("sign");// 获得请求签名,如sign=19e907700db7ad91318424a97c54ed57
+        if (StringUtils.isEmpty(requestSign)) {
+            return false;
+        }
+        List<String> keys = new ArrayList<String>(request.getParameterMap().keySet());
+        keys.remove("sign");// 排除sign参数
+        Collections.sort(keys);// 排序
+
+        StringBuilder sb = new StringBuilder();
+        for (String key : keys) {
+            sb.append(key).append("=").append(request.getParameter(key)).append("&");// 拼接字符串
+        }
+        String linkString = sb.toString();
+        linkString = StringUtils.substring(linkString, 0, linkString.length() - 1);// 去除最后一个'&'
+
+        String secret = "Potato";// 密钥,自己修改
+        String sign = DigestUtils.md5Hex(linkString + secret);// 混合密钥md5
+
+        return StringUtils.equals(sign, requestSign);// 比较
+    }
+
+    private String getIpAddress(HttpServletRequest request) {
+        String ip = request.getHeader("x-forwarded-for");
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("Proxy-Client-IP");
+        }
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("WL-Proxy-Client-IP");
+        }
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("HTTP_CLIENT_IP");
+        }
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
+        }
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getRemoteAddr();
+        }
+        // 如果是多级代理,那么取第一个ip为客户端ip
+        if (ip != null && ip.indexOf(",") != -1) {
+            ip = ip.substring(0, ip.indexOf(",")).trim();
+        }
+
+        return ip;
+    }
+}

+ 49 - 0
mall-service/src/main/java/com/txz/mall/configurer/MybatisConfigurer.java

@@ -0,0 +1,49 @@
+package com.txz.mall.configurer;
+
+import com.txz.mall.core.ProjectConstant;
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.mybatis.spring.SqlSessionFactoryBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+import org.springframework.core.io.support.ResourcePatternResolver;
+import tk.mybatis.spring.mapper.MapperScannerConfigurer;
+
+import javax.sql.DataSource;
+import java.util.Properties;
+
+/**
+ * Mybatis & Mapper & PageHelper 配置
+ */
+@Configuration
+public class MybatisConfigurer {
+
+    @Bean
+    public SqlSessionFactory sqlSessionFactoryBean(DataSource dataSource) throws Exception {
+        SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
+        factory.setDataSource(dataSource);
+        factory.setTypeAliasesPackage(ProjectConstant.MODEL_PACKAGE);
+
+        //添加XML目录
+        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
+        factory.setMapperLocations(resolver.getResources("classpath:mapper/*.xml"));
+        return factory.getObject();
+    }
+
+    @Bean
+    public MapperScannerConfigurer mapperScannerConfigurer() {
+        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
+        mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactoryBean");
+        mapperScannerConfigurer.setBasePackage(ProjectConstant.MAPPER_PACKAGE);
+
+        //配置通用Mapper,详情请查阅官方文档
+        Properties properties = new Properties();
+        properties.setProperty("mappers", ProjectConstant.MAPPER_INTERFACE_REFERENCE);
+        properties.setProperty("notEmpty", "false");//insert、update是否判断字符串类型!='' 即 test="str != null"表达式内是否追加 and str != ''
+        properties.setProperty("IDENTITY", "MYSQL");
+        mapperScannerConfigurer.setProperties(properties);
+
+        return mapperScannerConfigurer;
+    }
+
+}

+ 47 - 0
mall-service/src/main/java/com/txz/mall/configurer/Parameters.java

@@ -0,0 +1,47 @@
+package com.txz.mall.configurer;
+
+import lombok.Data;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.cloud.context.config.annotation.RefreshScope;
+import org.springframework.stereotype.Component;
+
+@Component
+@Data
+@RefreshScope
+public class Parameters {
+    /**
+     *
+     当前激活的配置文件
+     */
+    @Value("${spring.profiles.active}")
+    private String        env;
+
+    /**
+     *
+     是否启用签名
+     */
+    @Value("${signature}")
+    private String        signature;
+
+    /**
+     * 是否启用登录验证
+     */
+    @Value("${dubbo.registry.address}")
+    private String        dubboRegistryAddress;
+
+    /**
+     * 是否启用登录验证
+     */
+    @Value("${login.check}")
+    private String        loginCheck;
+
+    @Value("${spring.application.name}")
+    private String        application;
+
+
+
+
+
+
+
+}

+ 21 - 0
mall-service/src/main/java/com/txz/mall/configurer/RibbonWeightedResponseTimeRuleConfig.java

@@ -0,0 +1,21 @@
+package com.txz.mall.configurer;
+
+import com.netflix.loadbalancer.IRule;
+import com.netflix.loadbalancer.WeightedResponseTimeRule;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @Author: Fcx
+ * @Date: 2022/3/14 12:32
+ * @Version 1.0
+ */
+@Configuration
+public class RibbonWeightedResponseTimeRuleConfig {
+
+    //方法名一定要叫iRule
+    @Bean
+    public IRule iRule(){
+        return new WeightedResponseTimeRule();
+    }
+}

+ 65 - 0
mall-service/src/main/java/com/txz/mall/configurer/SwaggerConfig.java

@@ -0,0 +1,65 @@
+package com.txz.mall.configurer;
+
+import io.swagger.annotations.ApiOperation;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Profile;
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.ParameterBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.schema.ModelRef;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.service.Contact;
+import springfox.documentation.service.Parameter;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Fcx
+ */
+@Configuration
+@EnableSwagger2
+@Profile({"dev","test"})
+public class SwaggerConfig {
+
+    @Bean
+    public Docket docket(){
+        //添加header参数
+        List<Parameter> pars = new ArrayList<>();
+        ParameterBuilder ticketPar = new ParameterBuilder();
+        ticketPar.name("token").description("user token")
+                .modelRef(new ModelRef("string")).parameterType("header")
+                .required(false).build(); //header中的ticket参数非必填,传空也可以
+        ticketPar = new ParameterBuilder();
+        ticketPar.name("appCode").description("appCode")
+                .modelRef(new ModelRef("string")).parameterType("header")
+                .required(false).build(); //header中的ticket参数非必填,传空也可以
+
+        pars.add(ticketPar.build());
+        return new Docket(DocumentationType.SWAGGER_2)
+                .globalOperationParameters(pars)
+                .groupName("demo")
+                .apiInfo(getApiInfo())
+                .select()
+                //设置basePackage会将包下的所有被@Api标记类的所有方法作为api
+                .apis(RequestHandlerSelectors.basePackage("com.txz.project.web"))
+                //只有标记了@ApiOperation的方法才会暴露出给swagger
+                .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
+                .paths(PathSelectors.regex("/api/.*")).build();
+    }
+
+    private ApiInfo getApiInfo(){
+        return new ApiInfoBuilder()
+                .title("API接口文档")
+                .description("swagger2 demo api")
+                .termsOfServiceUrl("http://localhost/swagger-ui.html")
+                .version("1.0").contact(new Contact("admin", "http://localhost/swagger-ui.html", "xxx@qq.com"))
+                .build();
+    }
+
+}

+ 101 - 0
mall-service/src/main/java/com/txz/mall/configurer/log/WebLogAspect.java

@@ -0,0 +1,101 @@
+//
+// Source code recreated from a .class file by IntelliJ IDEA
+// (powered by Fernflower decompiler)
+//
+
+package com.txz.mall.configurer.log;
+
+import com.alibaba.fastjson.JSONObject;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.Signature;
+import org.aspectj.lang.annotation.AfterReturning;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
+import org.aspectj.lang.annotation.Pointcut;
+import org.aspectj.lang.reflect.CodeSignature;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+
+@Aspect
+@Component
+public class WebLogAspect {
+    private static Logger logger = LoggerFactory.getLogger(WebLogAspect.class);
+
+    public WebLogAspect() {
+    }
+
+    @Pointcut("execution(public * com.txz.mall.web..*Controller.*(..))")
+    public void webLog() {
+    }
+
+    private static String[] types = {"java.lang.Integer", "java.lang.Double",
+            "java.lang.Float", "java.lang.Long", "java.lang.Short",
+            "java.lang.Byte", "java.lang.Boolean", "java.lang.Char",
+            "java.lang.String", "int", "double", "long", "short", "byte",
+            "boolean", "char", "float"};
+
+    @Before("webLog()")
+    public void doBefore(JoinPoint joinPoint) throws Throwable {
+        try {
+            // 接收到请求,记录请求内容
+            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+            HttpServletRequest request = attributes.getRequest();
+            HttpServletResponse response = attributes.getResponse();
+            String logStr = "";
+            // 记录下请求内容
+            logStr += "URL:" + request.getRequestURI() + " | ";
+            logStr += "token:" + request.getHeader("token") + " | ";
+            logStr += "appCode:" + request.getHeader("appCode") + " | ";
+            logStr += "CLASS_METHOD:" + joinPoint.getSignature().getDeclaringType().getSimpleName() + "." + joinPoint.getSignature().getName() + " | ";
+            logStr += "ARGS:";
+            // joinPoint获取参数名
+            String[] params = ((CodeSignature) joinPoint.getStaticPart().getSignature()).getParameterNames();
+            // joinPoint获取参数值
+            Object[] args = joinPoint.getArgs();
+            Signature signature = joinPoint.getSignature();
+            MethodSignature methodSignature = (MethodSignature) signature;
+            Method method = methodSignature.getMethod();
+            // 打印请求参数
+            int i = 0;
+            for (Object arg : args) {
+                if (arg == request || arg == response) {
+                    i += 1;
+                    continue;
+                }
+                String typeName = "";
+                try {
+                    typeName = arg.getClass().getTypeName();
+                } catch (Exception e) {
+                }
+                if (!Arrays.asList(types).contains(typeName)) {
+                    // 把参数转成json格式
+                    logStr += "&" + params[i] + "=" + JSONObject.toJSONString(arg);
+                } else {
+                    logStr += "&" + params[i] + "=" + arg;
+                }
+                i += 1;
+            }
+            logStr += " | ";
+            logger.info(logStr);
+        } catch (Throwable e) {
+            logger.error("HaLogParamAspect error.", e);
+        }
+    }
+
+    @AfterReturning(
+        returning = "ret",
+        pointcut = "webLog()"
+    )
+    public void doAfterReturning(Object ret) throws Throwable {
+        logger.info("RESPONSE : {}", ret);
+    }
+}

+ 49 - 0
mall-service/src/main/java/com/txz/mall/configurer/shutdown/GracefulShutdownUndertow.java

@@ -0,0 +1,49 @@
+package com.txz.mall.configurer.shutdown;
+
+/**
+ * @Author: Fcx
+ * @Date: 2019/11/29 15:08
+ * @Version 1.0
+ */
+import io.undertow.Undertow;
+import io.undertow.server.ConnectorStatistics;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.web.embedded.undertow.UndertowServletWebServer;
+import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext;
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.event.ContextClosedEvent;
+import org.springframework.stereotype.Component;
+
+import java.lang.reflect.Field;
+import java.util.List;
+
+/**
+ *
+ * 优雅关闭 Spring Boot undertow
+ */
+@Component
+public class GracefulShutdownUndertow implements ApplicationListener<ContextClosedEvent> {
+
+    @Autowired
+    private GracefulShutdownUndertowWrapper gracefulShutdownUndertowWrapper;
+
+    @Autowired
+    private ServletWebServerApplicationContext context;
+
+    @Override
+    public void onApplicationEvent(ContextClosedEvent contextClosedEvent){
+        gracefulShutdownUndertowWrapper.getGracefulShutdownHandler().shutdown();
+        try {
+            UndertowServletWebServer webServer = (UndertowServletWebServer)context.getWebServer();
+            Field field = webServer.getClass().getDeclaredField("undertow");
+            field.setAccessible(true);
+            Undertow undertow = (Undertow) field.get(webServer);
+            List<Undertow.ListenerInfo> listenerInfo = undertow.getListenerInfo();
+            Undertow.ListenerInfo listener = listenerInfo.get(0);
+            ConnectorStatistics connectorStatistics = listener.getConnectorStatistics();
+            while (connectorStatistics.getActiveConnections() > 0){}
+        }catch (Exception e){
+            // Application Shutdown
+        }
+    }
+}

+ 29 - 0
mall-service/src/main/java/com/txz/mall/configurer/shutdown/GracefulShutdownUndertowWrapper.java

@@ -0,0 +1,29 @@
+package com.txz.mall.configurer.shutdown;
+
+import io.undertow.server.HandlerWrapper;
+import io.undertow.server.HttpHandler;
+import io.undertow.server.handlers.GracefulShutdownHandler;
+import org.springframework.stereotype.Component;
+
+/**
+ * @Author: Fcx
+ * @Date: 2019/11/29 15:08
+ * @Version 1.0
+ */
+@Component
+public class GracefulShutdownUndertowWrapper implements HandlerWrapper {
+
+    private GracefulShutdownHandler gracefulShutdownHandler;
+
+    @Override
+    public HttpHandler wrap(HttpHandler handler) {
+        if (gracefulShutdownHandler == null) {
+            this.gracefulShutdownHandler = new GracefulShutdownHandler(handler);
+        }
+        return gracefulShutdownHandler;
+    }
+
+    public GracefulShutdownHandler getGracefulShutdownHandler() {
+        return gracefulShutdownHandler;
+    }
+}

+ 27 - 0
mall-service/src/main/java/com/txz/mall/configurer/shutdown/UndertowExtraConfiguration.java

@@ -0,0 +1,27 @@
+package com.txz.mall.configurer.shutdown;
+
+import io.undertow.UndertowOptions;
+import lombok.AllArgsConstructor;
+import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
+import org.springframework.context.annotation.Bean;
+import org.springframework.stereotype.Component;
+
+/**
+ * @Author: Fcx
+ * @Date: 2019/11/29 15:13
+ * @Version 1.0
+ */
+@Component
+@AllArgsConstructor
+public class UndertowExtraConfiguration {
+
+    private final GracefulShutdownUndertowWrapper gracefulShutdownWrapper;
+
+    @Bean
+    public UndertowServletWebServerFactory servletWebServerFactory() {
+        UndertowServletWebServerFactory factory = new UndertowServletWebServerFactory();
+        factory.addDeploymentInfoCustomizers(deploymentInfo -> deploymentInfo.addOuterHandlerChainWrapper(gracefulShutdownWrapper));
+        factory.addBuilderCustomizers(builder -> builder.setServerOption(UndertowOptions.ENABLE_STATISTICS, true));
+        return factory;
+    }
+}

+ 16 - 0
mall-service/src/main/java/com/txz/mall/constants/MyConstants.java

@@ -0,0 +1,16 @@
+package com.txz.mall.constants;
+
+/**
+ * 自定义常量
+ *
+ * @Author: Fcx
+ * @Date: 2019/11/25 20:15
+ * @Version 1.0
+ */
+abstract public class MyConstants {
+
+    /**
+     * 排行榜里小数位的总分,用来排序
+     */
+    public static final long RANK_TOTAL_SCORE = 100000000000000L;
+}

+ 38 - 0
mall-service/src/main/java/com/txz/mall/constants/RedisConstants.java

@@ -0,0 +1,38 @@
+package com.txz.mall.constants;
+
+/**
+ * @author Fcx
+ */
+public class RedisConstants {
+
+    /**
+     * 排行榜列表
+     */
+    public static final String RANK_LIST = "rank:list:reverse:rankKey";
+
+    /**
+     * 并列分数排行榜map
+     */
+    public static final String RANK_PARATAXIS_MAP = "rank:parataxis:map:reverse:rankKey";
+
+    /**
+     * 排行榜总分
+     */
+    public static final String RANK_TOTAL_SCORE = "rank:totalScore:reverse:rankType:rankKey";
+
+    /**
+     * 排行榜的用户信息
+     */
+    public static final String RANK_USER = "rank:user:userId";
+
+    /**
+     * 排行榜MAP的分数信息
+     */
+    public static final String RANK_MAP_SCORE = "rank:map:score:num";
+
+    /**
+     * 接口列表
+     */
+    public static final String INTERFACES_MAP = "mall:interfaces:map";
+
+}

+ 83 - 0
mall-service/src/main/java/com/txz/mall/core/AbstractService.java

@@ -0,0 +1,83 @@
+package com.txz.mall.core;
+
+import org.apache.ibatis.exceptions.TooManyResultsException;
+import org.springframework.beans.factory.annotation.Autowired;
+import tk.mybatis.mapper.entity.Condition;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.ParameterizedType;
+import java.util.List;
+
+/**
+ * 基于通用MyBatis Mapper插件的Service接口的实现
+ */
+public abstract class AbstractService<T> implements Service<T> {
+
+    @Autowired
+    protected Mapper<T> mapper;
+
+    private Class<T> modelClass;    // 当前泛型真实类型的Class
+
+    public AbstractService() {
+        ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();
+        modelClass = (Class<T>) pt.getActualTypeArguments()[0];
+    }
+
+    @Override
+    public int  save(T model) {
+       return mapper.insertSelective(model);
+    }
+
+    @Override
+    public int  save(List<T> models) {
+    	return mapper.insertList(models);
+    }
+
+    @Override
+    public void deleteById(Number id) {
+        mapper.deleteByPrimaryKey(id);
+    }
+
+    @Override
+    public void deleteByIds(String ids) {
+        mapper.deleteByIds(ids);
+    }
+
+    @Override
+    public void update(T model) {
+        mapper.updateByPrimaryKeySelective(model);
+    }
+
+    @Override
+    public T findById(Number id) {
+        return mapper.selectByPrimaryKey(id);
+    }
+
+    @Override
+    public T findBy(String fieldName, Object value) throws TooManyResultsException {
+        try {
+            T model = modelClass.newInstance();
+            Field field = modelClass.getDeclaredField(fieldName);
+            field.setAccessible(true);
+            field.set(model, value);
+            return mapper.selectOne(model);
+        } catch (ReflectiveOperationException e) {
+            throw new ServiceException(e.getMessage(), e);
+        }
+    }
+
+    @Override
+    public List<T> findByIds(String ids) {
+        return mapper.selectByIds(ids);
+    }
+
+    @Override
+    public List<T> findByCondition(Condition condition) {
+        return mapper.selectByCondition(condition);
+    }
+
+    @Override
+    public List<T> findAll() {
+        return mapper.selectAll();
+    }
+}

+ 17 - 0
mall-service/src/main/java/com/txz/mall/core/Mapper.java

@@ -0,0 +1,17 @@
+package com.txz.mall.core;
+
+import tk.mybatis.mapper.common.BaseMapper;
+import tk.mybatis.mapper.common.ConditionMapper;
+import tk.mybatis.mapper.common.IdsMapper;
+import tk.mybatis.mapper.common.special.InsertListMapper;
+
+/**
+ * 定制版MyBatis Mapper插件接口,如需其他接口参考官方文档自行添加。
+ */
+public interface Mapper<T>
+        extends
+        BaseMapper<T>,
+        ConditionMapper<T>,
+        IdsMapper<T>,
+        InsertListMapper<T> {
+}

+ 47 - 0
mall-service/src/main/java/com/txz/mall/core/MessageTemplteType.java

@@ -0,0 +1,47 @@
+package com.txz.mall.core;
+
+/**
+ * 消息模板枚举
+ */
+public enum MessageTemplteType {
+
+	/** 保修报事-派单通知 */
+	DISPATCH_NOTICE("dispatchNotice", "保修报事-派单通知"),
+	/** 物业缴费-缴费提醒通知 */
+	PAYMENT_REMINDER_NOTICE("paymentReminderNotice", "物业缴费-缴费提醒通知"),
+
+
+	;
+
+	private final String code; // 状态码
+	private final String desc;
+
+	MessageTemplteType(String code, String desc) {
+		this.code = code;
+		this.desc = desc;
+	}
+
+	public String getCode() {
+		return code;
+	}
+
+	public String getDesc() {
+		return desc;
+	}
+
+	/**
+	 * 通过状态码获取ENUM的名字
+	 * 
+	 * @param statusCode
+	 * @return
+	 */
+	public static ResultCode getEnumByStatusCode(String code) {
+		for (ResultCode p : ResultCode.values()) {
+			if (p.code().equalsIgnoreCase(code)) {
+				return p;
+			}
+		}
+
+		return null;
+	}
+}

+ 39 - 0
mall-service/src/main/java/com/txz/mall/core/MyPageInfo.java

@@ -0,0 +1,39 @@
+
+
+package com.txz.mall.core;
+
+import com.github.pagehelper.PageInfo;
+import lombok.*;
+
+import java.util.List;
+
+/**
+ * 对Page<E>结果进行包装
+ * <p/>
+ * 新增分页的多项属性,主要参考:http://bbs.csdn.net/topics/360010907
+ *
+ * @author linxk
+ */
+@Builder
+@AllArgsConstructor
+@Getter
+@Setter
+public class MyPageInfo<T> extends PageInfo {
+
+    //结果集
+    private String data;
+
+    public MyPageInfo() {
+    }
+
+    /**
+     * 包装Page对象
+     *
+     * @param list
+     */
+    public MyPageInfo(List<T> list) {
+        super(list, 8);
+    }
+
+
+}

+ 29 - 0
mall-service/src/main/java/com/txz/mall/core/ProjectConstant.java

@@ -0,0 +1,29 @@
+package com.txz.mall.core;
+
+/**
+ * 项目常量
+ */
+public final class ProjectConstant {
+    public static final String BASE_PACKAGE = "com.txz.mall";//项目基础包名称,根据自己公司的项目修改
+
+    public static final String MODEL_PACKAGE = BASE_PACKAGE + ".model";//Model所在包
+    public static final String MAPPER_PACKAGE = BASE_PACKAGE + ".dao";//Mapper所在包
+    public static final String SERVICE_PACKAGE = BASE_PACKAGE + ".service";//Service所在包
+    public static final String SERVICE_IMPL_PACKAGE = SERVICE_PACKAGE + ".impl";//ServiceImpl所在包
+    public static final String SERVICE_DTO_PACKAGE = BASE_PACKAGE + ".dto";//dto所在包
+    public static final String CONTROLLER_PACKAGE = BASE_PACKAGE + ".web.mng";//Controller所在包
+
+    public static final String MAPPER_INTERFACE_REFERENCE = BASE_PACKAGE + ".core.Mapper";//Mapper插件基础接口的完全限定名
+    //项目名称
+    public static  String application;
+
+    public static final String AREA_CODE = application + ".area.code.redis";
+
+    public static final String AREA_PROVINCE_CITY = application + ".area.province.city.redis";
+
+    public static final String INTERFACES_DETAIL = application + ".interfaces.detail.redis";
+
+    public static final String ERROR_CODE = application + ".error.code.redis";
+
+
+}

+ 542 - 0
mall-service/src/main/java/com/txz/mall/core/RedisUtil.java

@@ -0,0 +1,542 @@
+package com.txz.mall.core;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+import javax.annotation.Resource;
+
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+ 
+ 
+/**
+ * 
+ * @author
+ * 基于spring和redis的redisTemplate工具类
+ * 针对所有的hash 都是以h开头的方法
+ * 针对所有的Set 都是以s开头的方法                    不含通用方法
+ * 针对所有的List 都是以l开头的方法
+ */
+@Component
+public class RedisUtil {
+ 
+	@Resource
+	private RedisTemplate<String, Object> redisTemplate;
+	
+	//=============================common============================
+	/**
+	 * 指定缓存失效时间
+	 * @param key 键
+	 * @param time 时间(秒)
+	 * @return
+	 */
+	public boolean expire(String key,long time){
+		try {
+			if(time>0){
+				redisTemplate.expire(key, time, TimeUnit.SECONDS);
+			}
+			return true;
+		} catch (Exception e) {
+			e.printStackTrace();
+			return false;
+		}
+	}
+	
+	/**
+	 * 根据key 获取过期时间
+	 * @param key 键 不能为null
+	 * @return 时间(秒) 返回0代表为永久有效
+	 */
+	public long getExpire(String key){
+		return redisTemplate.getExpire(key,TimeUnit.SECONDS);
+	}
+	
+	/**
+	 * 判断key是否存在
+	 * @param key 键
+	 * @return true 存在 false不存在
+	 */
+	public boolean hasKey(String key){
+		try {
+			return redisTemplate.hasKey(key);
+		} catch (Exception e) {
+			e.printStackTrace();
+			return false;
+		}
+	}
+	
+	/**
+	 * 删除缓存
+	 * @param key 可以传一个值 或多个
+	 */
+	@SuppressWarnings("unchecked")
+	public void del(String ... key){
+		if(key!=null&&key.length>0){
+			if(key.length==1){
+				redisTemplate.delete(key[0]);
+			}else{
+				redisTemplate.delete(CollectionUtils.arrayToList(key));
+			}
+		}
+	}
+	
+	//============================String=============================
+	/**
+	 * 普通缓存获取
+	 * @param key 键
+	 * @return 值
+	 */
+	public Object get(String key){
+		return key==null?null:redisTemplate.opsForValue().get(key);
+	}
+	
+	/**
+	 * 普通缓存放入
+	 * @param key 键
+	 * @param value 值
+	 * @return true成功 false失败
+	 */
+	public boolean set(String key,Object value) {
+		 try {
+			redisTemplate.opsForValue().set(key, value);
+			return true;
+		} catch (Exception e) {
+			e.printStackTrace();
+			return false;
+		}
+		
+	}
+	
+	/**
+	 * 普通缓存放入并设置时间
+	 * @param key 键
+	 * @param value 值
+	 * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
+	 * @return true成功 false 失败
+	 */
+	public boolean set(String key,Object value,long time){
+		try {
+			if(time>0){
+				redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
+			}else{
+				set(key, value);
+			}
+			return true;
+		} catch (Exception e) {
+			e.printStackTrace();
+			return false;
+		}
+	}
+	
+	/**
+	 * 递增
+	 * @param key 键
+	 * @param delta 要增加几(大于0)
+	 * @return
+	 */
+	public long incr(String key, long delta){  
+		if(delta<0){
+			throw new RuntimeException("递增因子必须大于0");
+		}
+		return redisTemplate.opsForValue().increment(key, delta);
+    }
+	
+	/**
+	 * 递减
+	 * @param key 键
+	 * @param delta 要减少几(小于0)
+	 * @return
+	 */
+	public long decr(String key, long delta){  
+		if(delta<0){
+			throw new RuntimeException("递减因子必须大于0");
+		}
+        return redisTemplate.opsForValue().increment(key, -delta);  
+    }  
+	
+	//================================Map=================================
+	/**
+	 * HashGet
+	 * @param key 键 不能为null
+	 * @param item 项 不能为null
+	 * @return 值
+	 */
+	public Object hget(String key,String item){
+		return redisTemplate.opsForHash().get(key, item);
+	}
+	
+	/**
+	 * 获取hashKey对应的所有键值
+	 * @param key 键
+	 * @return 对应的多个键值
+	 */
+	public Map<Object,Object> hmget(String key){
+		return redisTemplate.opsForHash().entries(key);
+	}
+	
+	/**
+	 * HashSet
+	 * @param key 键
+	 * @param map 对应多个键值
+	 * @return true 成功 false 失败
+	 */
+	public boolean hmset(String key, Map<String,Object> map){  
+        try {
+			redisTemplate.opsForHash().putAll(key, map);
+			return true;
+		} catch (Exception e) {
+			e.printStackTrace();
+			return false;
+		}
+    }
+	
+	/**
+	 * HashSet 并设置时间
+	 * @param key 键
+	 * @param map 对应多个键值
+	 * @param time 时间(秒)
+	 * @return true成功 false失败
+	 */
+    public boolean hmset(String key, Map<String,Object> map, long time){  
+        try {
+			redisTemplate.opsForHash().putAll(key, map);
+			if(time>0){
+				expire(key, time);
+			}
+			return true;
+		} catch (Exception e) {
+			e.printStackTrace();
+			return false;
+		}
+    }
+	
+	/**
+	 * 向一张hash表中放入数据,如果不存在将创建
+	 * @param key 键
+	 * @param item 项
+	 * @param value 值
+	 * @return true 成功 false失败
+	 */
+	public boolean hset(String key,String item,Object value) {
+		 try {
+			redisTemplate.opsForHash().put(key, item, value);
+			return true;
+		} catch (Exception e) {
+			e.printStackTrace();
+			return false;
+		}
+	}
+	
+	/**
+	 * 向一张hash表中放入数据,如果不存在将创建
+	 * @param key 键
+	 * @param item 项
+	 * @param value 值
+	 * @param time 时间(秒)  注意:如果已存在的hash表有时间,这里将会替换原有的时间
+	 * @return true 成功 false失败
+	 */
+	public boolean hset(String key,String item,Object value,long time) {
+		 try {
+			redisTemplate.opsForHash().put(key, item, value);
+			if(time>0){
+				expire(key, time);
+			}
+			return true;
+		} catch (Exception e) {
+			e.printStackTrace();
+			return false;
+		}
+	}
+	
+	/**
+	 * 删除hash表中的值
+	 * @param key 键 不能为null
+	 * @param item 项 可以使多个 不能为null
+	 */
+    public void hdel(String key, Object... item){  
+		redisTemplate.opsForHash().delete(key,item);
+    } 
+    
+    /**
+     * 判断hash表中是否有该项的值
+     * @param key 键 不能为null
+     * @param item 项 不能为null
+     * @return true 存在 false不存在
+     */
+    public boolean hHasKey(String key, String item){
+		return redisTemplate.opsForHash().hasKey(key, item);
+    } 
+	
+	/**
+	 * hash递增 如果不存在,就会创建一个 并把新增后的值返回
+	 * @param key 键
+	 * @param item 项
+	 * @param by 要增加几(大于0)
+	 * @return
+	 */
+	public double hincr(String key, String item,double by){  
+        return redisTemplate.opsForHash().increment(key, item, by);
+    }
+	
+	/**
+	 * hash递减
+	 * @param key 键
+	 * @param item 项
+	 * @param by 要减少记(小于0)
+	 * @return
+	 */
+	public double hdecr(String key, String item,double by){  
+        return redisTemplate.opsForHash().increment(key, item,-by);  
+    }  
+	
+	//============================set=============================
+	/**
+	 * 根据key获取Set中的所有值
+	 * @param key 键
+	 * @return
+	 */
+	public Set<Object> sGet(String key){
+		try {
+			return redisTemplate.opsForSet().members(key);
+		} catch (Exception e) {
+			e.printStackTrace();
+			return null;
+		}
+	}
+	
+	/**
+	 * 根据value从一个set中查询,是否存在
+	 * @param key 键
+	 * @param value 值
+	 * @return true 存在 false不存在
+	 */
+	public boolean sHasKey(String key,Object value){
+		try {
+			return redisTemplate.opsForSet().isMember(key, value);
+		} catch (Exception e) {
+			e.printStackTrace();
+			return false;
+		}
+	}
+	
+	/**
+	 * 将数据放入set缓存
+	 * @param key 键
+	 * @param values 值 可以是多个
+	 * @return 成功个数
+	 */
+	public long sSet(String key, Object...values) {
+        try {
+            return redisTemplate.opsForSet().add(key, values);
+        } catch (Exception e) {
+        	e.printStackTrace();
+        	return 0;
+        }
+    }
+	
+	/**
+	 * 将set数据放入缓存
+	 * @param key 键
+	 * @param time 时间(秒)
+	 * @param values 值 可以是多个
+	 * @return 成功个数
+	 */
+	public long sSetAndTime(String key,long time,Object...values) {
+        try {
+        	Long count = redisTemplate.opsForSet().add(key, values);
+        	if(time>0){
+        		expire(key, time);
+			}
+            return count;
+        } catch (Exception e) {
+        	e.printStackTrace();
+        	return 0;
+        }
+    }
+	
+	/**
+	 * 获取set缓存的长度
+	 * @param key 键
+	 * @return
+	 */
+	public long sGetSetSize(String key){
+		try {
+			return redisTemplate.opsForSet().size(key);
+		} catch (Exception e) {
+			e.printStackTrace();
+			return 0;
+		}
+	}
+	
+	/**
+	 * 移除值为value的
+	 * @param key 键
+	 * @param values 值 可以是多个
+	 * @return 移除的个数
+	 */
+	public long setRemove(String key, Object ...values) {
+        try {
+            Long count = redisTemplate.opsForSet().remove(key, values);
+            return count;
+        } catch (Exception e) {
+        	e.printStackTrace();
+        	return 0;
+        }
+    }
+    //===============================list=================================
+    
+	/**
+	 * 获取list缓存的内容
+	 * @param key 键
+	 * @param start 开始
+	 * @param end 结束  0 到 -1代表所有值
+	 * @return
+	 */
+	public List<Object> lGet(String key,long start, long end){
+		try {
+			return redisTemplate.opsForList().range(key, start, end);
+		} catch (Exception e) {
+			e.printStackTrace();
+			return null;
+		}
+	}
+	
+	/**
+	 * 获取list缓存的长度
+	 * @param key 键
+	 * @return
+	 */
+	public long lGetListSize(String key){
+		try {
+			return redisTemplate.opsForList().size(key);
+		} catch (Exception e) {
+			e.printStackTrace();
+			return 0;
+		}
+	}
+	
+	/**
+	 * 通过索引 获取list中的值
+	 * @param key 键
+	 * @param index 索引  index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
+	 * @return
+	 */
+	public Object lGetIndex(String key,long index){
+		try {
+			return redisTemplate.opsForList().index(key, index);
+		} catch (Exception e) {
+			e.printStackTrace();
+			return null;
+		}
+	}
+	
+	/**
+	 * 将list放入缓存
+	 * @param key 键
+	 * @param value 值
+	 * @return
+	 */
+	public boolean lSet(String key, Object value) {
+        try {
+            redisTemplate.opsForList().rightPush(key, value);
+            return true;
+        } catch (Exception e) {
+        	e.printStackTrace();
+        	return false;
+        }
+    }
+	
+	/**
+	 * 将list放入缓存
+	 * @param key 键
+	 * @param value 值
+	 * @param time 时间(秒)
+	 * @return
+	 */
+	public boolean lSet(String key, Object value, long time) {
+        try {
+            redisTemplate.opsForList().rightPush(key, value);
+            if (time > 0) {
+            	expire(key, time);
+			}
+            return true;
+        } catch (Exception e) {
+        	e.printStackTrace();
+        	return false;
+        }
+    }
+	
+	/**
+	 * 将list放入缓存
+	 * @param key 键
+	 * @param value 值
+	 * @return
+	 */
+	public boolean lSet(String key, List<Object> value) {
+	    try {
+			redisTemplate.opsForList().rightPushAll(key, value);
+			return true;
+		} catch (Exception e) {
+			e.printStackTrace();
+			return false;
+		}
+    }
+	
+	/**
+	 * 将list放入缓存
+	 * @param key 键
+	 * @param value 值
+	 * @param time 时间(秒)
+	 * @return
+	 */
+	public boolean lSet(String key, List<Object> value, long time) {
+	    try {
+			redisTemplate.opsForList().rightPushAll(key, value);
+			if (time > 0){
+				expire(key, time);
+			}
+			return true;
+		} catch (Exception e) {
+			e.printStackTrace();
+			return false;
+		}
+    }
+	
+	/**
+	 * 根据索引修改list中的某条数据
+	 * @param key 键
+	 * @param index 索引
+	 * @param value 值
+	 * @return
+	 */
+	public boolean lUpdateIndex(String key, long index,Object value) {
+	    try {
+			redisTemplate.opsForList().set(key, index, value);
+			return true;
+		} catch (Exception e) {
+			e.printStackTrace();
+			return false;
+		}
+    } 
+	
+	/**
+	 * 移除N个值为value 
+	 * @param key 键
+	 * @param count 移除多少个
+	 * @param value 值
+	 * @return 移除的个数
+	 */
+	public long lRemove(String key,long count,Object value) {
+		try {
+			Long remove = redisTemplate.opsForList().remove(key, count, value);
+			return remove;
+		} catch (Exception e) {
+			e.printStackTrace();
+			return 0;
+		}
+	}
+	
+}

+ 102 - 0
mall-service/src/main/java/com/txz/mall/core/Result.java

@@ -0,0 +1,102 @@
+package com.txz.mall.core;
+
+import com.alibaba.fastjson.JSON;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 统一API响应结果封装
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class Result<T> implements Serializable {
+    private String code;
+    private String message;
+    private T data;
+
+
+    public static Result success() {
+        return Result.builder()
+                .code("200")
+                .message("操作成功")
+                .build();
+    }
+
+    public static Result success(Object data) {
+        return Result.builder()
+                .code("200")
+                .message("操作成功")
+                .data(data)
+                .build();
+    }
+
+    public static Result build(String code, String message) {
+        return Result.builder()
+                .code(code)
+                .message(message)
+                .build();
+    }
+
+    public static Result fail(String code, String message, Object data) {
+        return Result.builder()
+                .code(code)
+                .message(message)
+                .data(data)
+                .build();
+    }
+
+    public static Result fail(Object data) {
+        return Result.builder()
+                .code("400")
+                .message("操作失败")
+                .data(data)
+                .build();
+    }
+
+    public static Result fail(String code, String message) {
+        return Result.builder()
+                .code(code)
+                .message(message)
+                .build();
+    }
+
+
+
+    @Override
+    public String toString() {
+        return JSON.toJSONString(this);
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public Result setCode(String code) {
+        this.code = code;
+        return this;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public Result setMessage(String message) {
+        this.message = message;
+        return this;
+    }
+
+    public T getData() {
+        return data;
+    }
+
+    public Result setData(T data) {
+        this.data = data;
+        return this;
+    }
+}

+ 138 - 0
mall-service/src/main/java/com/txz/mall/core/ResultCode.java

@@ -0,0 +1,138 @@
+package com.txz.mall.core;
+
+/**
+ * 响应码枚举,参考HTTP状态码的语义
+ */
+public enum ResultCode {
+    /**
+     * 系统错误
+     */
+    SUCCESS("200","成功"),//成功
+    FAIL("400","失败"),//失败
+    UNAUTHORIZED("401","未认证(签名错误)"),//未认证(签名错误)
+    NOT_FOUND("404","接口不存在"),//接口不存在
+    INTERNAL_SERVER_ERROR("500","服务器内部错误"),
+    PERMISSION_NOT_HAS("409","没有操作权限"),
+    BACKSTAGE_IS_ERROR("501","网关异常"),
+
+
+    APPCODE_IS_NULL("1005", "应用编号不能为空"),
+
+    /**
+     * 业务错误
+     */
+    OBJECT_IS_NULL("6000","对象不能为空"),
+    ID_IS_NULL("6001","对象ID不能为空"),
+    CODE_IS_NULL("6002","编号不能为空"),
+    NAME_IS_NULL("6003","名称不能为空"),
+    SEQ_IS_NULL("6004","排序不能为空"),
+    LEVEL_IS_NULL("6005","级别不能为空"),
+    USERID_IS_NULL("6006","用户id不能为空"),
+    RESULT_IS_NULL("6007","查询结果为空"),
+    TYPE_IS_NULL("6008","类型为空"),
+    SQL_ERROR("6009","数据库异常"),
+    IDENTITY_IS_NULL("6010","身份证不能为空"),
+    CUSTOMERID_IS_NULL("6011","客户号不能为空"),
+    CUSTOMERID_IS_ERROR("6012","未查询到用户信息"),
+    SELECT_IS_ERROR("6013","数据异常查询失败,请联系检查用户信息"),
+    IDENTITYUPKEY_IS_ERROR("6014","身份证正面照片key不能为空"),
+    CODE_IS_INVALID("6015","验证码无效"),
+    TOKEN_IS_NULL("6016","TOKEN不能为空"),
+
+
+
+    /**
+     * 缺少请求参数
+     */
+    REQUEST_ARGS_IS_NULL("6000","缺少请求参数"),
+
+    PROVINCE_IS_NULL("6001", "未找到省信息" )
+    , CITY_IS_NULL("6002","未找到城市信息" ),
+
+    CITY_TYPE_IS_ERROR("6003", "城市类型错误" ),
+    CONTENT_IS_NULL("6004", "通知内容不能为空"),
+    STARTTIME_IS_NULL("6005","开始时间不能为空" ),
+    ENDTIME_IS_NULL("6006","结束时间不能为空" ),
+    TYPE_SEQ_IS_EXIST("6007","改类型排序已存在"),
+    LIFT_OBJECT_IS_NULL("6008","通知排序已经在顶部或者底部"),
+    AREACODE_IS_NULL("6009","地区码不能为空"),
+    GROUPID_IS_NULL("6010","分组id不能为空"),
+    LOTTERYID_IS_NULL("6011","抽奖id不能为空" ),
+    USER_IS_NULL("6012","用户未找到" ),
+    SCHOOL_IS_NULL("6013","学校未找到" ),
+    STATUS_IS_ERROR("6014","状态异常:未上架" ),
+    STATUS_HAS_ERROR("6026","状态异常:已上架" ),
+    CONVERSIONCODE_IS_UESD("6015","兑换码已使用完" ),
+    TIME_IS_ERROR("6016","无效的领奖时间" ),
+    NUM_IS_NULL("6017","数量不能为空或0" ),
+    NUM_IS_BIG("6018","数量太大"), BATCH_IS_ERROR("6019","批次已用完" ),
+    USER_NUM_ERROR("6020","用户兑换次数已满" ), CONVERSION_IS_NULL("6021","兑换码不存在,更多兑换码公众号活动获取" ),
+    AWARD_ERROR("6022","领奖失败" ),
+    CREATENAME_IS_NULL("6023","创建人为空" ), STATUS_IS_NULL("6024", "状态不能为空"),
+    VERSION_IS_NULL("6025", "版本号不能为空" ),
+    DISPOSE_STATUS_IS_ERROR("6027", "处理状态异常:未处理" ),
+    DISPOSE_STATUS_HAS_ERROR("6028", "处理状态异常:已处理" ),
+    STATION_IS_NULL("6029", "基站信息未找到" ),
+    AREA_IS_NULL("6030", "地区码未找到" ),
+    BAIDU_API_ERROR("6031", "获取百度接口异常"),
+    STARTTIME_IS_ERROR("6032", "活动未开始" ),
+    ENDTIME_IS_ERROR("6033", "活动已结束" ),
+    WEEK_CONVERSION_CODE_IS_NULL("6034", "周末兑换码未配置,请联系客服" ),
+
+    APPCODE_IS_ERROR("6035", "应用编码异常"),
+    PRIZE_IS_NULL("6036", "奖品为空,请联系管理员"),
+    PRIZE_IS_DRAW("6037", "奖品已领取" ),
+    USER_IS_NOT_VIP("6038", "您还不是会员,不能领取哦") ,
+    USER_IS_NOT_SVIP("6038", "您还不是永久会员,不能领取哦") ,
+    USER_IS_LOGIN_NUM_LESS("6039", "您登录次数不足,不能领取哦" ),
+    PERMIT_IS_UPDATED("6040", "通行证天数已更新") ,
+    PERMIT_SERVICE_IS_OFF("6041", "通行证服务未开启" ),
+    SIGNED_ERROR("6043", "已签到" ),
+    ACTIVITY_IS_NOT_FINISH("6044", "未达到领取条件,请按活动规则领取。"),
+    ACTIVITY_IS_NOT_INTYPE("6045", "活动达标类型是空" ),
+    PRIZE_IS_ERROR("6046", "奖品配置异常" ),
+    ACTIVITY_IS_END("6058", "活动已结束"),
+
+    ;
+    /**
+     * 状态码
+     */
+    private final String code;
+    private final String message;
+
+    ResultCode(String code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+
+    public String code() {
+        return code;
+    }
+
+    public String message() {
+        return message;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    /**
+     * 通过状态码获取ENUM的名字
+     * @param code
+     * @return
+     */
+    public static ResultCode getEnumByStatusCode(String code) {
+        for (ResultCode p : ResultCode.values()) {
+            if (p.code().equalsIgnoreCase(code)) {
+                return p;
+            }
+        }
+
+        return null;
+    }
+}

+ 36 - 0
mall-service/src/main/java/com/txz/mall/core/ResultGenerator.java

@@ -0,0 +1,36 @@
+package com.txz.mall.core;
+
+
+
+/**
+ * 响应结果生成工具
+ */
+public class ResultGenerator {
+    private static final String DEFAULT_SUCCESS_MESSAGE = "SUCCESS";
+
+    public static Result genSuccessResult() {
+        return new Result()
+                .setCode(ResultCode.SUCCESS.getCode())
+                .setMessage(DEFAULT_SUCCESS_MESSAGE);
+    }
+
+    public static Result genSuccessResult(Object data) {
+        return new Result()
+                .setCode(ResultCode.SUCCESS.getCode())
+                .setMessage(DEFAULT_SUCCESS_MESSAGE)
+                .setData(data);
+    }
+
+    public static Result genFailResult(ResultCode code) {
+        return new Result()
+                .setCode(code.getCode())
+                .setMessage(code.getMessage());
+    }
+
+    public static Result genFailResult(ResultCode code,Object data) {
+        return new Result()
+                .setCode(code.getCode())
+                .setMessage(code.getMessage())
+                .setData(data);
+    }
+}

+ 22 - 0
mall-service/src/main/java/com/txz/mall/core/Service.java

@@ -0,0 +1,22 @@
+package com.txz.mall.core;
+
+import org.apache.ibatis.exceptions.TooManyResultsException;
+import tk.mybatis.mapper.entity.Condition;
+
+import java.util.List;
+
+/**
+ * Service 层 基础接口,其他Service 接口 请继承该接口
+ */
+public interface Service<T> {
+	int  save(T model);//持久化
+	int  save(List<T> models);//批量持久化
+    void deleteById(Number id);//通过主鍵刪除
+    void deleteByIds(String ids);//批量刪除 eg:ids -> “1,2,3,4”
+    void update(T model);//更新
+    T findById(Number id);//通过ID查找
+    T findBy(String fieldName, Object value) throws TooManyResultsException; //通过Model中某个成员变量名称(非数据表中column的名称)查找,value需符合unique约束
+    List<T> findByIds(String ids);//通过多个ID查找//eg:ids -> “1,2,3,4”
+    List<T> findByCondition(Condition condition);//根据条件查找
+    List<T> findAll();//获取所有
+}

+ 29 - 0
mall-service/src/main/java/com/txz/mall/core/ServiceException.java

@@ -0,0 +1,29 @@
+//
+// Source code recreated from a .class file by IntelliJ IDEA
+// (powered by Fernflower decompiler)
+//
+
+package com.txz.mall.core;
+
+import lombok.Data;
+
+@Data
+public class ServiceException extends RuntimeException {
+
+    private ResultCode code;
+
+    public ServiceException() {
+    }
+
+    public ServiceException(ResultCode code) {
+        this.code = code;
+    }
+
+    public ServiceException(String message) {
+        super(message);
+    }
+
+    public ServiceException(String message, Throwable cause) {
+        super(message, cause);
+    }
+}

+ 57 - 0
mall-service/src/main/java/com/txz/mall/core/SmsTempletType.java

@@ -0,0 +1,57 @@
+package com.txz.mall.core;
+
+/**
+ * 短信模板枚举
+ */
+public enum SmsTempletType {
+	
+	RAPID_REGISTRATION("rapidRegistration","快速注册短信验证码"),
+	THIRD_PARTY_LOGIN("thirdPartyLogin","第三方登陆短信验证码"),
+	VERIFICATION_CODE_LANDING("verificationCodeLanding","验证码登陆"),
+	UPDATE_VERIFICATION_CODE("updateVerificationCode","更绑手机验证码"),
+	SET_PASSWORD_VERIFICATION_CODE("setPasswordVerificationCode","设置密码验证码"),
+	
+	;
+	
+	private String code;
+	private String desc;
+	
+	SmsTempletType(String code, String desc) {
+		this.code = code;
+		this.desc = desc;
+	}
+	
+	
+	/**
+	 * 通过状态码获取ENUM的名字
+	 * 
+	 * @param code
+	 * @return
+	 */
+	public static ResultCode getEnumByStatusCode(String code) {
+		for (ResultCode p : ResultCode.values()) {
+			if (p.code().equalsIgnoreCase(code)) {
+				return p;
+			}
+		}
+
+		return null;
+	}
+	
+	public String getCode() {
+		return code;
+	}
+	public void setCode(String code) {
+		this.code = code;
+	}
+	public String getDesc() {
+		return desc;
+	}
+	public void setDesc(String desc) {
+		this.desc = desc;
+	}
+	
+	
+	
+
+}

+ 34 - 0
mall-service/src/main/java/com/txz/mall/core/cache/CacheKey.java

@@ -0,0 +1,34 @@
+package com.txz.mall.core.cache;
+
+import java.io.Serializable;
+
+
+public class CacheKey implements Serializable {
+
+	private CacheType cacheType;
+
+	private String subKey;
+
+	private CacheKey() {
+	}
+
+	public static CacheKey generateKey(CacheType cacheType, String subKey) {
+		if (cacheType == null) {
+			throw new NullPointerException("CacheKey不允许存在空参数");
+		}
+		CacheKey key = new CacheKey();
+		key.cacheType = cacheType;
+		key.subKey = subKey;
+		return key;
+	}
+
+	@Override
+	public String toString() {
+		return new StringBuilder().append(cacheType).append("_").append(subKey != null ? subKey : "").toString();
+	}
+
+	public CacheType getType() {
+		return cacheType;
+	}
+
+}

+ 38 - 0
mall-service/src/main/java/com/txz/mall/core/cache/CacheType.java

@@ -0,0 +1,38 @@
+package com.txz.mall.core.cache;
+
+import com.txz.mall.core.ProjectConstant;
+
+public enum CacheType {
+
+	// ----------------------- token 密钥相关 ------------------------
+
+	/**
+	 * app端密钥
+	 */
+	AppSecretKey,
+
+	/**
+	 * 抽奖key
+	 */
+	LotteryKey,
+
+	/**
+	 * 获奖 列表key
+	 */
+	LotteryKeyList,
+
+	Sign,
+
+	// ------------------------- 订单相关 -------------------------
+	/**
+	 * 用户相关的一些配置:黑名单等
+	 */
+	UserConfig;
+
+	private static String keyHead = ProjectConstant.application;
+
+	@Override
+	public String toString() {
+		return keyHead + "_" + name();
+	};
+}

+ 35 - 0
mall-service/src/main/java/com/txz/mall/core/cache/lock/AbstractDistributedLock.java

@@ -0,0 +1,35 @@
+package com.txz.mall.core.cache.lock;
+
+/**
+ * 分布式锁抽象类
+ *
+ * @author zlt
+ * @date 2018/5/29 14:14
+ */
+public abstract class AbstractDistributedLock implements DistributedLock{
+
+    @Override
+    public boolean lock(String key) {
+        return lock(key, TIMEOUT_MILLIS, RETRY_TIMES, SLEEP_MILLIS);
+    }
+
+    @Override
+    public boolean lock(String key, int retryTimes) {
+        return lock(key, TIMEOUT_MILLIS, retryTimes, SLEEP_MILLIS);
+    }
+
+    @Override
+    public boolean lock(String key, int retryTimes, long sleepMillis) {
+        return lock(key, TIMEOUT_MILLIS, retryTimes, sleepMillis);
+    }
+
+    @Override
+    public boolean lock(String key, long expire) {
+        return lock(key, expire, RETRY_TIMES, SLEEP_MILLIS);
+    }
+
+    @Override
+    public boolean lock(String key, long expire, int retryTimes) {
+        return lock(key, expire, retryTimes, SLEEP_MILLIS);
+    }
+}

+ 93 - 0
mall-service/src/main/java/com/txz/mall/core/cache/lock/DistributedLock.java

@@ -0,0 +1,93 @@
+package com.txz.mall.core.cache.lock;
+
+/**
+ * 分布式锁顶级接口
+ * 例如:
+ * RETRY_TIMES=100,SLEEP_MILLIS=100
+ * RETRY_TIMES * SLEEP_MILLIS = 10000 意味着如果一直获取不了锁,最长会等待10秒后抛超时异常
+ *
+ * @author zlt
+ * @date 2018/5/29 14:12
+ */
+public interface DistributedLock {
+
+    /**
+     * 默认超时时间
+     */
+    long TIMEOUT_MILLIS = 5000;
+
+    /**
+     * 重试次数
+     */
+    int RETRY_TIMES = 100;
+
+    /**
+     * 每次重试后等待的时间
+     */
+    long SLEEP_MILLIS = 100;
+
+    /**
+     * 获取锁
+     *
+     * @param key key
+     * @return 成功/失败
+     */
+    boolean lock(String key);
+
+    /**
+     * 获取锁
+     *
+     * @param key        key
+     * @param retryTimes 重试次数
+     * @return 成功/失败
+     */
+    boolean lock(String key, int retryTimes);
+
+    /**
+     * 获取锁
+     *
+     * @param key         key
+     * @param retryTimes  重试次数
+     * @param sleepMillis 获取锁失败的重试间隔
+     * @return 成功/失败
+     */
+    boolean lock(String key, int retryTimes, long sleepMillis);
+
+    /**
+     * 获取锁
+     *
+     * @param key    key
+     * @param expire 获取锁超时时间
+     * @return 成功/失败
+     */
+    boolean lock(String key, long expire);
+
+    /**
+     * 获取锁
+     *
+     * @param key        key
+     * @param expire     获取锁超时时间
+     * @param retryTimes 重试次数
+     * @return 成功/失败
+     */
+    boolean lock(String key, long expire, int retryTimes);
+
+    /**
+     * 获取锁
+     *
+     * @param key         key
+     * @param expire      获取锁超时时间
+     * @param retryTimes  重试次数
+     * @param sleepMillis 获取锁失败的重试间隔
+     * @return 成功/失败
+     */
+    boolean lock(String key, long expire, int retryTimes, long sleepMillis);
+
+    /**
+     * 释放锁
+     *
+     * @param key key值
+     * @return 释放结果
+     */
+    boolean releaseLock(String key);
+}

+ 101 - 0
mall-service/src/main/java/com/txz/mall/core/cache/lock/RedisDistributedLock.java

@@ -0,0 +1,101 @@
+package com.txz.mall.core.cache.lock;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.data.redis.connection.RedisStringCommands;
+import org.springframework.data.redis.connection.ReturnType;
+import org.springframework.data.redis.core.RedisCallback;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.types.Expiration;
+import org.springframework.stereotype.Component;
+
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * redis分布式锁实现
+ *
+ * @author zlt
+ * @date 2018/5/29 14:16
+ */
+@Slf4j
+@Component
+public class RedisDistributedLock extends AbstractDistributedLock{
+    public RedisDistributedLock(RedisTemplate redisTemplate) {
+        this.redisTemplate = redisTemplate;
+    }
+
+    private RedisTemplate<String, Object> redisTemplate;
+
+    private ThreadLocal<String> lockFlag = new ThreadLocal<>();
+
+    private static final String UNLOCK_LUA;
+
+    /*
+     * 通过lua脚本释放锁,来达到释放锁的原子操作
+     */
+    static {
+        UNLOCK_LUA = "if redis.call(\"get\",KEYS[1]) == ARGV[1] " +
+                "then " +
+                "    return redis.call(\"del\",KEYS[1]) " +
+                "else " +
+                "    return 0 " +
+                "end ";
+    }
+
+    @Override
+    public boolean lock(String key, long expire, int retryTimes, long sleepMillis) {
+        boolean result = setRedis(key, expire);
+        // 如果获取锁失败,按照传入的重试次数进行重试
+        while ((!result) && retryTimes-- > 0) {
+            try {
+                log.debug("get redisDistributeLock failed, retrying..." + retryTimes);
+                Thread.sleep(sleepMillis);
+            } catch (InterruptedException e) {
+                log.warn("Interrupted!", e);
+                Thread.currentThread().interrupt();
+            }
+            result = setRedis(key, expire);
+        }
+        return result;
+    }
+
+    @Override
+    public boolean releaseLock(String key) {
+        // 释放锁的时候,有可能因为持锁之后方法执行时间大于锁的有效期,此时有可能已经被另外一个线程持有锁,所以不能直接删除
+        try {
+            // 使用lua脚本删除redis中匹配value的key,可以避免由于方法执行时间过长而redis锁自动过期失效的时候误删其他线程的锁
+            // spring自带的执行脚本方法中,集群模式直接抛出不支持执行脚本的异常,所以只能拿到原redis的connection来执行脚本
+            Boolean result = redisTemplate.execute((RedisCallback<Boolean>) connection -> {
+                byte[] scriptByte = redisTemplate.getStringSerializer().serialize(UNLOCK_LUA);
+                return connection.eval(scriptByte, ReturnType.BOOLEAN, 1
+                        , redisTemplate.getStringSerializer().serialize(key)
+                        , redisTemplate.getStringSerializer().serialize(lockFlag.get()));
+            });
+            return result;
+        } catch (Exception e) {
+            log.error("release redisDistributeLock occured an exception", e);
+        } finally {
+            lockFlag.remove();
+        }
+        return false;
+    }
+
+
+    private boolean setRedis(final String key, final long expire) {
+        try {
+            boolean status = redisTemplate.execute((RedisCallback<Boolean>) connection -> {
+                String uuid = UUID.randomUUID().toString();
+                lockFlag.set(uuid);
+                byte[] keyByte = redisTemplate.getStringSerializer().serialize(key);
+                byte[] uuidByte = redisTemplate.getStringSerializer().serialize(uuid);
+
+                boolean result = connection.set(keyByte, uuidByte, Expiration.from(expire, TimeUnit.MILLISECONDS), RedisStringCommands.SetOption.ifAbsent());
+                return result;
+            });
+            return status;
+        } catch (Exception e) {
+            log.error("set redisDistributeLock occured an exception", e);
+        }
+        return false;
+    }
+}

+ 7 - 0
mall-service/src/main/java/com/txz/mall/dao/AppModuleMapper.java

@@ -0,0 +1,7 @@
+package com.txz.mall.dao;
+
+import com.txz.mall.core.Mapper;
+import com.txz.mall.model.AppModule;
+
+public interface AppModuleMapper extends Mapper<AppModule> {
+}

+ 52 - 0
mall-service/src/main/java/com/txz/mall/enums/ActivityTypeEnum.java

@@ -0,0 +1,52 @@
+//package com.txz.mall.enums;
+//
+///**
+// * 活动类型枚举 完成类型 1VIP 2关注公众号 3 无条件
+// */
+//public enum ActivityTypeEnum {
+//
+//    VIP((byte)1, "VIP","vip"),
+//    ACCOUNTS((byte)2, "关注公众号","focus"),
+//    NO_CONDITION((byte)3, "展示图片","activity"),
+//    MANUAL_AWARD((byte)4, "手动领奖","award"),
+//    SIGN((byte)5, "签到","sign"),
+//    PERMIT((byte)6, "通行证","permit"),
+//    conversion((byte)7, "兑换码","conversion"),
+//    ACTIVITY_MESSAGE((byte)8, "活动消息","activity_message"),
+//
+//    ;
+//
+//    private byte key;
+//    private String value;
+//    private String code;
+//
+//    ActivityTypeEnum(byte key, String value,String code) {
+//        this.key = key;
+//        this.value = value;
+//        this.code = code;
+//    }
+//
+//    public byte getKey() {
+//        return key;
+//    }
+//
+//    public String getValue() {
+//        return value;
+//    }
+//
+//    public String getCode() {
+//        return code;
+//    }
+//
+//    public static ActivityTypeEnum getEnum(Byte inType) {
+//        if (inType == null){
+//            return null;
+//        }
+//        for (ActivityTypeEnum temp:values()) {
+//            if (temp.key == inType){
+//                return temp;
+//            }
+//        }
+//        return null;
+//    }
+//}

+ 64 - 0
mall-service/src/main/java/com/txz/mall/model/AppModule.java

@@ -0,0 +1,64 @@
+package com.txz.mall.model;
+
+import lombok.*;
+
+import javax.persistence.*;
+
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+@Getter
+@Setter
+@Table(name = "o_app_module")
+public class AppModule {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    /**
+     * 应用编码
+     */
+    @Column(name = "app_code")
+    private String appCode;
+
+    /**
+     * 模块名称
+     */
+    private String name;
+
+    /**
+     * 携带内容
+     */
+    private String content;
+
+
+    /**
+     * 是否检查版本 1检查 2不检查
+     */
+    @Column(name = "check_version")
+    private Byte checkVersion;
+
+    /**
+     * 模块名称
+     */
+    private String version;
+
+    /**
+     * 模块编码
+     */
+    private String code;
+
+    /**
+     * 用户分群id  为空则不参与判断
+     */
+    @Column(name = "cluster_ids")
+    private String clusterIds;
+
+
+    /**
+     * 状态 1开放 2关闭
+     */
+    private Byte status;
+
+
+}

+ 158 - 0
mall-service/src/main/java/com/txz/mall/mq/rocket/consumer/Consumers.java

@@ -0,0 +1,158 @@
+//package com.txz.operating.mq.rocket.consumer;
+//
+//import cn.hutool.core.collection.CollUtil;
+//import cn.hutool.core.date.DateUtil;
+//import cn.hutool.json.JSONUtil;
+//import com.github.pagehelper.PageHelper;
+//import com.yiweikeji.cif.dto.UserDTO;
+//import com.txz.operating.configurer.IpConfiguration;
+//import lombok.extern.slf4j.Slf4j;
+//import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
+//import org.apache.rocketmq.common.consumer.ConsumeFromWhere;
+//import org.apache.rocketmq.spring.annotation.ConsumeMode;
+//import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
+//import org.apache.rocketmq.spring.core.RocketMQListener;
+//import org.apache.rocketmq.spring.core.RocketMQPushConsumerLifecycleListener;
+//import org.springframework.context.annotation.Configuration;
+//import org.springframework.stereotype.Service;
+//import tk.mybatis.mapper.entity.Condition;
+//import tk.mybatis.mapper.entity.Example;
+//
+//import javax.annotation.Resource;
+//import java.util.ArrayList;
+//import java.util.List;
+//
+///**
+// * 异步消费采集器上报预警消息
+// *
+// * @author Administrator
+// * @version $Id: Consumers.java, v 0.1 2019年5月30日 下午3:11:28 Administrator Exp $
+// */
+//@Configuration
+//@Slf4j
+//public class Consumers {
+//
+//    @Resource
+//    private IpConfiguration ipConfiguration;
+//
+//    @Resource
+//    private ActivityService activityService;
+//
+//    @Resource
+//    private ActivityRecordService activityRecordService;
+//
+//    @Service
+//    @RocketMQMessageListener(topic = "${cif.user.subscribe.topic}", consumerGroup = "${spring.application.name}" + "_subscribe", consumeMode = ConsumeMode.ORDERLY)
+//    public class WeChatSubscribe implements RocketMQListener<Object>, RocketMQPushConsumerLifecycleListener {
+//        @Override
+//        public void onMessage(Object message) {
+//            log.info("operating: "+ ipConfiguration.getPort() +"received message: {}", message);
+//            try {
+//                List<String> userIdList = (List<String>) message;
+//                log.info("设置玩家关注公众号,玩家ID列表:{}", JSONUtil.toJsonStr(userIdList));
+//                //将玩家设置为关注
+//                PageHelper.startPage(1, 10);
+//                String now = DateUtil.format(DateUtil.date(),"yyyyMMddHHmmss");
+//                Condition condition = new Condition(Activity.class);
+//                Example.Criteria criteria = condition.createCriteria();
+//                criteria.andEqualTo("status", 1);
+//                criteria.andEqualTo("accomplishType", 2);
+//                criteria.andGreaterThanOrEqualTo("startTime", now);
+//                criteria.andLessThanOrEqualTo("endTime", now);
+//                List<Activity> activities = activityService.findByCondition(condition);
+//                if (CollUtil.isNotEmpty(activities)){
+//                    List<ActivityRecord> records = new ArrayList<>(10);
+//                    for (String userId: userIdList) {
+//                        for (Activity activity:activities) {
+//                            records.add(ActivityRecord.builder().activityId(activity.getId()).createTime(DateUtil.date()).userId(userId).build());
+//                        }
+//                    }
+//                    if (CollUtil.isNotEmpty(records)){
+//                        //新增记录
+//                        activityRecordService.save(records);
+//                    }
+//                }
+//            } catch (Exception e) {
+//                log.error("设置玩家关注公众号异常,玩家ID列表:{}", JSONUtil.toJsonStr(message), e);
+//                return;
+//            }
+//        }
+//
+//        @Override
+//        public void prepareStart(DefaultMQPushConsumer consumer) {
+//            consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
+//        }
+//    }
+//
+//
+//    @Service
+//    @RocketMQMessageListener(topic = "${cif.user.wxPay.topic}", consumerGroup = "${spring.application.name}" + "_vip", consumeMode = ConsumeMode.ORDERLY)
+//    public class UserBuyVip implements RocketMQListener<UserDTO>, RocketMQPushConsumerLifecycleListener {
+//        @Override
+//        public void onMessage(UserDTO userDTO) {
+//            log.info("operating: "+ ipConfiguration.getPort() +"received message: {}", userDTO);
+//            try {
+//                if (userDTO == null) {
+//                    log.warn("设置玩家会员信息异常,玩家信息为空");
+//                    return;
+//                }
+//                PageHelper.startPage(1, 10);
+//                String now = DateUtil.format(DateUtil.date(),"yyyyMMddHHmmss");
+//                Condition condition = new Condition(Activity.class);
+//                Example.Criteria criteria = condition.createCriteria();
+//                criteria.andEqualTo("status", 1);
+//                criteria.andEqualTo("accomplishType", 1);
+//                criteria.andGreaterThanOrEqualTo("startTime", now);
+//                criteria.andLessThanOrEqualTo("endTime", now);
+//                List<Activity> activities = activityService.findByCondition(condition);
+//                if (CollUtil.isNotEmpty(activities)){
+//                    List<ActivityRecord> records = new ArrayList<>(10);
+//                    for (Activity activity:activities) {
+//                        records.add(ActivityRecord.builder().activityId(activity.getId()).createTime(DateUtil.date()).userId(userDTO.getUserId()).build());
+//                    }
+//                    if (CollUtil.isNotEmpty(records)){
+//                        activityRecordService.save(records);
+//                    }
+//                }
+//                log.info("玩家开通vip会员,用户ID:{},会员过期时间:{}", userDTO.getUserId(), userDTO.getMemberEndTime());
+//            } catch (Exception e) {
+//                log.error("设置玩家会员信息异常,user:{}", userDTO.toString());
+//                throw e;
+//            }
+//        }
+//
+//        @Override
+//        public void prepareStart(DefaultMQPushConsumer consumer) {
+//            consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
+//        }
+//    }
+//
+//   // @Service
+//   // @RocketMQMessageListener(topic = "${cif.user.interactive.topic}", consumerGroup = "${spring.application.name}", consumeMode = ConsumeMode.ORDERLY)
+//   // public class MyConsumer3 implements RocketMQListener<UserFriendInteractiveMsg>, RocketMQPushConsumerLifecycleListener {
+//   //     @Override
+//   //     public void onMessage(UserFriendInteractiveMsg mqMessage) {
+//   //         logger.info("cif: "+ ipConfiguration.getPort() +"received message: {}", mqMessage);
+//   //         try {
+//   //             //更新用户单元信息:
+//   //             if(mqMessage.getFriendUserId() != null && StrUtil.isNotBlank(mqMessage.getUserId())){
+//   //                 userFriendService.interactive(mqMessage);
+//   //             }
+//   //             logger.info("TODO : {}", mqMessage);
+//   //         } catch (Exception e) {
+//   //             logger.error("RocketMq解析数据出错", e);
+//   //             return;
+//   //         }
+//   //     }
+//
+//   //     @Override
+//   //     public void prepareStart(DefaultMQPushConsumer consumer) {
+//   //         consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
+//   //     }
+//   //
+//   // }
+//
+//
+//
+//
+//}

+ 33 - 0
mall-service/src/main/java/com/txz/mall/mq/rocket/consumer/TestConsumerListener.java

@@ -0,0 +1,33 @@
+//package com.txz.operating.mq.rocket.consumer;
+//
+//import com.alibaba.fastjson.JSON;
+//import com.txz.operating.mq.rocket.consumer.message.MyMessage;
+//import lombok.extern.slf4j.Slf4j;
+//import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
+//import org.apache.rocketmq.spring.core.RocketMQListener;
+//import org.springframework.stereotype.Component;
+//
+///**
+// * @Author: Fcx
+// * @Date: 2019/11/28 21:27
+// * @Version 1.0
+// */
+//@Slf4j
+//@Component
+//// topic需要和生产者的topic一致,consumerGroup属性是必须指定的,内容可以随意
+//@RocketMQMessageListener(topic = "mission-topic", consumerGroup = "consumer-group")
+//public class TestConsumerListener implements RocketMQListener<MyMessage> {
+//
+//
+//
+//    /**
+//     * 监听到消息的时候就会调用该方法
+//     *
+//     * @param message 消息体
+//     */
+//    @Override
+//    public void onMessage(MyMessage message) {
+//        log.info("从mission-topic中监听到消息");
+//        log.info(JSON.toJSONString(message));
+//    }
+//}

+ 23 - 0
mall-service/src/main/java/com/txz/mall/mq/rocket/consumer/message/MyMessage.java

@@ -0,0 +1,23 @@
+package com.txz.mall.mq.rocket.consumer.message;
+
+import lombok.Data;
+import lombok.ToString;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * @Author: Fcx
+ * @Date: 2019/11/28 21:03
+ * @Version 1.0
+ */
+@Data
+@ToString
+public class MyMessage implements Serializable {
+    private static final long serialVersionUID = 4183459183310052388L;
+
+    private Integer id = 1;
+    private String name = "fcx";
+    private String status = "default";
+    private Date createTime = new Date();
+}

+ 26 - 0
mall-service/src/main/java/com/txz/mall/mq/rocket/producer/Producers.java

@@ -0,0 +1,26 @@
+//package com.txz.operating.mq.rocket.producer;
+//
+//import org.apache.rocketmq.client.producer.SendResult;
+//import org.apache.rocketmq.spring.core.RocketMQTemplate;
+//import org.springframework.beans.factory.annotation.Value;
+//import org.springframework.stereotype.Component;
+//
+//import javax.annotation.Resource;
+//
+///**
+// * @author Administrator
+// * @version $Id: Producers.java, v 0.1 2019年5月30日 下午3:11:54 Administrator Exp $
+// */
+//@Component
+//public class Producers {
+//    @Resource
+//    private RocketMQTemplate rocketMQTemplate;
+//
+//    @Value("${user.info.topic}")
+//    private String userInfoTopic;
+//
+//    public SendResult pushUserInfo(UserInfo userInfo) {
+//        return rocketMQTemplate.syncSendOrderly(userInfoTopic, userInfo, userInfo.getUserId());
+//    }
+//
+//}

+ 11 - 0
mall-service/src/main/java/com/txz/mall/service/AppModuleService.java

@@ -0,0 +1,11 @@
+package com.txz.mall.service;
+import com.txz.mall.model.AppModule;
+import com.txz.mall.core.Service;
+
+
+/**
+ * Created by CodeGenerator on 2020/05/22.
+ */
+public interface AppModuleService extends Service<AppModule> {
+
+}

+ 22 - 0
mall-service/src/main/java/com/txz/mall/service/impl/AppModuleServiceImpl.java

@@ -0,0 +1,22 @@
+package com.txz.mall.service.impl;
+
+import com.txz.mall.core.AbstractService;
+import com.txz.mall.dao.AppModuleMapper;
+import com.txz.mall.model.AppModule;
+import com.txz.mall.service.AppModuleService;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+
+
+/**
+ * Created by CodeGenerator on 2020/05/22.
+ */
+@Service
+@Transactional
+public class AppModuleServiceImpl extends AbstractService<AppModule> implements AppModuleService {
+    @Resource
+    private AppModuleMapper oAppModuleMapper;
+
+}

+ 142 - 0
mall-service/src/main/java/com/txz/mall/task/SchoolCodeTask.java

@@ -0,0 +1,142 @@
+//package com.txz.operating.task;
+//
+//import java.util.List;
+//
+//
+//import javax.annotation.Resource;
+//
+//import cn.hutool.core.util.StrUtil;
+//import com.github.pagehelper.PageHelper;
+//import com.yiweikeji.operating.model.Area;
+//import com.yiweikeji.operating.model.School;
+//import com.yiweikeji.operating.service.AreaService;
+//import com.yiweikeji.operating.service.SchoolService;
+//import org.slf4j.Logger;
+//import org.slf4j.LoggerFactory;
+//import org.springframework.context.annotation.Configuration;
+//import org.springframework.scheduling.annotation.EnableScheduling;
+//
+//
+//import tk.mybatis.mapper.entity.Condition;
+//
+///**
+// * 更新学校地区码
+// */
+//@Configuration
+//@EnableScheduling
+//public class SchoolCodeTask {
+//
+//	private final Logger logger = LoggerFactory.getLogger(getClass());
+//
+//    @Resource
+//    private SchoolService schoolService;
+//
+//    @Resource
+//    private AreaService areaService;
+//
+//
+//
+////    @Scheduled(cron = "0 0 0 1/1 * ? ") // 每天0点执行一次
+////    @Scheduled(cron = "0 */1 * * * ? ") 关闭更新
+//	public void scheduler() {
+//		try {
+//            logger.info("执行学校地区码更新");
+//            updateCode();
+//		} catch (Exception e) {
+//			logger.error("执行学校地区码更新失败原因:e{}", e);
+//			return;
+//		}
+//	}
+//
+//    public void updateCode() throws Exception {
+//        boolean flag = true;
+//        int page = 0;
+//        PageHelper.startPage(page, 1000);
+//        Condition condition = new Condition(School.class);
+//        condition.createCriteria().andIsNull("areaCode");
+//        List<School> schools = schoolService.findByCondition(condition);
+//        page++;
+//        if (schools == null ||schools.isEmpty() ){
+//            return;
+//        }
+//        for (School school:schools) {
+//            try {
+//                School temp =new  School();
+//                temp.setId(school.getId());
+//                temp.setAreaCode(getAreaCode(school));
+//                schoolService.update(temp);
+//            } catch (Exception e) {
+//                logger.error("执行学校地区码更新失败"+ school.getName());
+//                logger.error("执行学校地区码更新失败原因:e{}", e);
+//                continue;
+//            }
+//
+//        }
+//
+//    }
+//
+//    private String getAreaCode(School school) {
+//        String provinceCode = "";
+//        String cityCode = "";
+//        String countyCode = "";
+//        if (StrUtil.isNotBlank(school.getProvince())){
+//            Condition condition = new Condition(Area.class);
+//            condition.createCriteria().andEqualTo("areaName",school.getProvince());
+//            List<Area> areas = areaService.findByCondition(condition);
+//            if (areas != null && areas.size() == 1){
+//                provinceCode = areas.get(0).getAreaCode();
+//                if("3".equals(areas.get(0).getAreaType())){
+//                    //当前为城市
+//                    cityCode = provinceCode;
+//                }
+//            } else {
+//                System.out.println("provinceCode is null,school name :"+school.getName());
+//            }
+//        }
+//        String like = provinceCode;
+//        if(StrUtil.isBlank(cityCode)){
+//            if (StrUtil.isBlank(school.getCity())){
+//                return like;
+//            }
+//            Condition condition2 = new Condition(Area.class);
+//            condition2.createCriteria().andEqualTo("areaName",school.getCity()).andLike("areaCode",like.substring(0,2)+"%");
+//            List<Area> areas2 = areaService.findByCondition(condition2);
+//            if (areas2 != null && areas2.size() == 1){
+//                cityCode =  areas2.get(0).getAreaCode();
+//            } else {
+//                System.out.println("cityCode is null,school name :"+school.getName());
+//            }
+//        }
+//        if (StrUtil.isNotBlank(cityCode)){
+//            like = cityCode;
+//        }
+//        if (StrUtil.isBlank(school.getCounty())){
+//            return like;
+//        }
+//        Condition condition3 = new Condition(Area.class);
+//        condition3.createCriteria().andEqualTo("areaName",school.getCounty()).andLike("areaCode",like.substring(0,4)+"%");
+//        List<Area> areas3 = areaService.findByCondition(condition3);
+//        if (areas3 != null && areas3.size() == 1){
+//            countyCode = areas3.get(0).getAreaCode();
+//        } else {
+//            System.out.println("countyCode is null,school name :"+school.getName());
+//        }
+//        if (StrUtil.isNotBlank(countyCode)){
+//            like = countyCode;
+//        }
+//        if (StrUtil.isBlank(school.getStreet())){
+//            return like;
+//        }
+//        Condition condition2 = new Condition(Area.class);
+//        condition2.createCriteria().andEqualTo("areaName",school.getStreet()).andLike("areaCode",like.substring(0,6)+"%");
+//        List<Area> areas2 = areaService.findByCondition(condition2);
+//        if (areas2 != null && areas2.size() == 1){
+//            return areas2.get(0).getAreaCode();
+//        } else {
+//            System.out.println("streetCode is null,school name :"+school.getName());
+//            return like;
+//        }
+//    }
+//
+//
+//}

+ 104 - 0
mall-service/src/main/java/com/txz/mall/util/IpUtils.java

@@ -0,0 +1,104 @@
+package com.txz.mall.util;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Random;
+
+public class IpUtils {
+
+//    public static void main(String[] args) {
+//        String randomIp = getRandomIp();
+//        System.out.println(randomIp);
+//    }
+    public static String getRandomIp(){
+        //ip范围
+        int[][] range = {{607649792,608174079},//36.56.0.0-36.63.255.255
+                         {1038614528,1039007743},//61.232.0.0-61.237.255.255
+                         {1783627776,1784676351},//106.80.0.0-106.95.255.255
+                         {2035023872,2035154943},//121.76.0.0-121.77.255.255
+                         {2078801920,2079064063},//123.232.0.0-123.235.255.255
+                         {-1950089216,-1948778497},//139.196.0.0-139.215.255.255
+                         {-1425539072,-1425014785},//171.8.0.0-171.15.255.255
+                         {-1236271104,-1235419137},//182.80.0.0-182.92.255.255
+                         {-770113536,-768606209},//210.25.0.0-210.47.255.255
+                         {-569376768,-564133889}, //222.16.0.0-222.95.255.255
+        };
+
+        Random rdint = new Random();
+        int index = rdint.nextInt(10);
+        String ip = num2ip(range[index][0]+new Random().nextInt(range[index][1]-range[index][0]));
+        return ip;
+    }
+
+     public static String num2ip(int ip) {
+            int [] b=new int[4] ;
+            String x = "";
+
+            b[0] = (int)((ip >> 24) & 0xff);
+            b[1] = (int)((ip >> 16) & 0xff);
+            b[2] = (int)((ip >> 8) & 0xff);
+            b[3] = (int)(ip & 0xff);
+            x=Integer.toString(b[0])+"."+Integer.toString(b[1])+"."+Integer.toString(b[2])+"."+Integer.toString(b[3]);
+
+            return x;
+     }
+
+    public static String getIPAddress(HttpServletRequest request) {
+        String ip = null;
+
+        //X-Forwarded-For:Squid 服务代理
+        String ipAddresses = request.getHeader("X-Forwarded-For");
+        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
+            //Proxy-Client-IP:apache 服务代理
+            ipAddresses = request.getHeader("Proxy-Client-IP");
+        }
+        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
+            //WL-Proxy-Client-IP:weblogic 服务代理
+            ipAddresses = request.getHeader("WL-Proxy-Client-IP");
+        }
+        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
+            //HTTP_CLIENT_IP:有些代理服务器
+            ipAddresses = request.getHeader("HTTP_CLIENT_IP");
+        }
+        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
+            //X-Real-IP:nginx服务代理
+            ipAddresses = request.getHeader("X-Real-IP");
+        }
+
+        //有些网络通过多层代理,那么获取到的ip就会有多个,一般都是通过逗号(,)分割开来,并且第一个ip为客户端的真实IP
+        if (ipAddresses != null && ipAddresses.length() != 0) {
+            ip = ipAddresses.split(",")[0];
+        }
+
+        //还是不能获取到,最后再通过request.getRemoteAddr();获取
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
+            ip = request.getRemoteAddr();
+        }
+        return ip.equals("0:0:0:0:0:0:0:1")?"127.0.0.1":ip;
+    }
+
+    private static String getIpAddress(HttpServletRequest request) {
+        String ip = request.getHeader("x-forwarded-for");
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("Proxy-Client-IP");
+        }
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("WL-Proxy-Client-IP");
+        }
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("HTTP_CLIENT_IP");
+        }
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
+        }
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getRemoteAddr();
+        }
+        // 如果是多级代理,那么取第一个ip为客户端ip
+        if (ip != null && ip.indexOf(",") != -1) {
+            ip = ip.substring(0, ip.indexOf(",")).trim();
+        }
+
+        return ip;
+    }
+
+}

+ 25 - 0
mall-service/src/main/java/com/txz/mall/util/MyDateUtil.java

@@ -0,0 +1,25 @@
+package com.txz.mall.util;
+
+import cn.hutool.core.date.DateUtil;
+
+import java.util.Date;
+
+public class MyDateUtil extends DateUtil {
+
+    /**
+     * 当前时分秒是否在时分秒指定范围内<br>
+     * 起始时分秒和结束时分秒可以互换
+     *
+     * @param date      被检查的日期
+     * @param beginDate 起始时分秒
+     * @param endDate   结束时分秒
+     * @return 是否在范围内
+     * @since 3.0.8
+     */
+    public static boolean isInTime(Date date, Date beginDate, Date endDate) {
+        String dayStr = DateUtil.format(date,"yyyy-MM-dd");
+        String beginTime = DateUtil.format(beginDate,"HH:mm:ss");
+        String endTime = DateUtil.format(endDate,"HH:mm:ss");
+        return DateUtil.isIn(date,DateUtil.parse(dayStr+" "+beginTime),DateUtil.parse(dayStr+" "+endTime));
+    }
+}

+ 22 - 0
mall-service/src/main/java/com/txz/mall/web/NoticeApiController.java

@@ -0,0 +1,22 @@
+package com.txz.mall.web;
+
+import org.springframework.web.bind.annotation.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import io.swagger.annotations.Api;
+
+import javax.annotation.Resource;
+
+/**
+* Created by CodeGenerator on 2020/03/26.
+*/
+@Api(tags = "[api]获取公告")
+@RestController
+@RequestMapping("/notice/api")
+public class NoticeApiController {
+
+	private static Logger log = LoggerFactory.getLogger(NoticeApiController.class);
+
+
+
+}

+ 110 - 0
mall-service/src/main/java/com/txz/mall/web/param/NoticeParam.java

@@ -0,0 +1,110 @@
+package com.txz.mall.web.param;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * @Author: Fcx
+ * @Date: 2019/12/14 13:56
+ * @Version 1.0
+ */
+@Data
+@ApiModel("通知参数")
+@AllArgsConstructor
+@NoArgsConstructor
+public class NoticeParam implements Serializable {
+
+    private static final long serialVersionUID = -5318595472853014732L;
+
+
+    private Integer id;
+
+    @ApiModelProperty("更新时间排序, 默认倒序, 顺序传 true")
+    private Boolean orderByUpdateTime = false;
+
+    /**
+     * 应用编码
+     */
+    @ApiModelProperty("应用编码")
+    private String appCode;
+
+    /**
+     * 文字内容
+     */
+    @ApiModelProperty("文字内容")
+    private String content;
+
+    /**
+     * 图片内容
+     */
+    @ApiModelProperty("图片内容")
+    private String pic;
+
+    @ApiModelProperty("用户分群id:多个使用,分割")
+    private String clusterIds;
+
+    /**
+     * 播放次数
+     */
+    @ApiModelProperty("播放次数")
+    private Integer num;
+
+
+    /**
+     * 音频内容
+     */
+    @ApiModelProperty("音频内容")
+    private String voice;
+
+    /**
+     * 类型 1滚屏公告 2登录公告
+     */
+    @ApiModelProperty("类型 1滚屏公告 2登录公告")
+    private Byte type;
+
+    /**
+     * 排序
+     */
+    @ApiModelProperty("排序")
+    private Integer seq;
+
+    /**
+     * 间隔时间 单位 秒
+     */
+    @ApiModelProperty("间隔时间 单位 秒")
+    private Integer intervalTime;
+
+    /**
+     * 状态 1正常 2禁用
+     */
+    @ApiModelProperty("状态 1正常 2禁用")
+    private Byte status;
+
+    /**
+     * 开始时间str
+     */
+    @ApiModelProperty("开始时间str")
+    private String startTimeStr;
+
+    /**
+     * 结束时间str
+     */
+    @ApiModelProperty("结束时间str")
+    private String endTimeStr;
+
+    /**
+     * 更新人
+     */
+    @ApiModelProperty("更新人")
+    private String updateUser;
+
+    private Integer page;
+
+    private Integer size;
+
+}

+ 61 - 0
mall-service/src/main/resources/bootstrap.properties

@@ -0,0 +1,61 @@
+spring.application.name=mall
+server.port=8101
+spring.mvc.throw-exception-if-no-handler-found=true
+spring.resources.add-mappings=true
+
+multipart.maxFileSize=50Mb
+#spring.servlet.multipart.enabled=true
+server.undertow.max-http-post-size=83886080
+# \u6700\u5927\u652F\u6301\u6587\u4EF6\u4E0A\u4F20\u7684\u5927\u5C0F
+spring.servlet.multipart.max-file-size=100MB
+# \u652F\u6301\u8BF7\u6C42\u6700\u5927\u6587\u4EF6\u4E0A\u4F20\u7684\u5927\u5C0F
+spring.servlet.multipart.max-request-size=1000MB
+# dubbo\u4F20\u8F93\u7684\u6700\u5927\u6587\u4EF6\u5927\u5C0F, \u9ED8\u8BA48388608  8M, \u8BBE\u7F6E80M
+dubbo.protocol.dubbo.payload=83886080
+spring.profiles.active=dev
+local.nacos=124.222.152.234:8848
+dev.nacos=124.222.152.234:8848
+#dev.nacos=172.17.0.3:8848
+#pro.nacos=172.17.0.15:8848,172.17.0.15:8849,172.17.0.13:8848
+#spring.profiles.include=wx,wxmp
+#spring.cloud.nacos.discovery.server-addr=129.211.99.19:84
+spring.cloud.nacos.discovery.server-addr=${${spring.profiles.active}.nacos}
+#spring.cloud.nacos.discovery.server-addr=172.17.0.2:8848
+spring.cloud.nacos.config.server-addr=${${spring.profiles.active}.nacos}
+#\u9ED8\u8BA4\u4E3APublic\u547D\u540D\u7A7A\u95F4,\u53EF\u4EE5\u7701\u7565\u4E0D\u5199
+#spring.cloud.nacos.config.namespace=7eea2e46-08a2-44b9-b067-51148ee2d71e
+#\u6307\u5B9A\u914D\u7F6E\u7FA4\u7EC4 --\u5982\u679C\u662FPublic\u547D\u540D\u7A7A\u95F4 \u5219\u53EF\u4EE5\u7701\u7565\u7FA4\u7EC4\u914D\u7F6E
+#spring.cloud.nacos.config.group=dev
+#\u6587\u4EF6\u540D -- \u5982\u679C\u6CA1\u6709\u914D\u7F6E\u5219\u9ED8\u8BA4\u4E3A ${spring.appliction.name}
+spring.cloud.nacos.config.prefix=${spring.application.name}
+spring.cloud.nacos.config.file-extension=properties
+
+spring.cloud.nacos.config.ext-config[0].data-id=mq-${spring.profiles.active}.properties
+spring.cloud.nacos.config.ext-config[0].refresh=true
+spring.cloud.nacos.config.ext-config[1].data-id=redis-${spring.profiles.active}.properties
+spring.cloud.nacos.config.ext-config[1].refresh=true
+#spring.cloud.nacos.config.ext-config[2].data-id=cos-${spring.profiles.active}.properties
+#spring.cloud.nacos.config.ext-config[2].refresh=true
+dubbo.protocol.serialization=kryo
+#dubbo.protocol.serialization=
+dubbo.protocol.optimizer=
+dubbo.protocol.name=dubbo
+dubbo.protocol.port=-1
+dubbo.registry.address=nacos://${${spring.profiles.active}.nacos}
+dubbo.scan.base-packages=com.txz.${spring.application.name}.dubbo.impl
+#dubbo.cloud.subscribed-services=cif
+dubbo.application.qos.enable=true
+dubbo.application.qos.port=28201
+dubbo.application.qos.accept.foreign.ip=true
+
+dubbo.reference.com.foo.BarService.check=false
+dubbo.reference.check=false
+dubbo.consumer.check=false
+dubbo.registry.check=false
+
+management.endpoints.web.exposure.include=*
+management.endpoint.shutdown.enabled=true
+management.endpoints.web.base-path=/${spring.application.name}
+management.endpoints.web.path-mapping.shutdown=/shutThisBoot
+management.server.address=127.0.0.1
+

+ 81 - 0
mall-service/src/main/resources/logback.xml

@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration debug="false">
+    <!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
+    <property name="LOG_HOME" value="logs/mall" />
+    <!-- 控制台输出 -->
+    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
+        </encoder>
+    </appender>
+    <!-- 按照每天生成日志文件 -->
+    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <!-- rollover daily -->
+            <fileNamePattern>${LOG_HOME}/log.operating.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
+            <!-- each file should be at most 100MB, keep 60 days worth of history, but at most 20GB -->
+            <maxFileSize>2GB</maxFileSize>
+            <maxHistory>1</maxHistory>
+        </rollingPolicy>
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
+        </encoder>
+        <filter class="ch.qos.logback.classic.filter.LevelFilter"><!-- 只打印错误日志 -->
+            <level>INFO</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+
+    <!-- 按照每天生成日志文件 -->
+    <appender name="ERROR_FILE"  class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <FileNamePattern>${LOG_HOME}/error.operating.log.%d{yyyy-MM-dd}.log</FileNamePattern>
+            <MaxHistory>5</MaxHistory>
+        </rollingPolicy>
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
+        </encoder>
+        <filter class="ch.qos.logback.classic.filter.LevelFilter"><!-- 只打印错误日志 -->
+	        <level>ERROR</level>
+	        <onMatch>ACCEPT</onMatch>
+	        <onMismatch>DENY</onMismatch>
+	    </filter>
+    </appender>
+    <!-- show parameters for hibernate sql 专为 Hibernate 定制 -->
+<!--     <logger name="org.hibernate.type.descriptor.sql.BasicBinder"  level="TRACE" /> -->
+<!--     <logger name="org.hibernate.type.descriptor.sql.BasicExtractor"  level="DEBUG" /> -->
+<!--     <logger name="org.hibernate.SQL" level="DEBUG" /> -->
+<!--     <logger name="org.hibernate.engine.QueryParameters" level="DEBUG" /> -->
+<!--     <logger name="org.hibernate.engine.query.HQLQueryPlan" level="DEBUG" /> -->
+
+    <!--myibatis log configure-->
+    <logger name="com.apache.ibatis" level="TRACE"/>
+    <logger name="java.sql.Connection" level="DEBUG"/>
+    <logger name="java.sql.Statement" level="DEBUG"/>
+    <logger name="java.sql.PreparedStatement" level="DEBUG"/>
+	<logger name="com.kameng.project" />
+
+    <!-- 日志输出级别 -->
+    <root level="INFO">
+        <appender-ref ref="STDOUT" />
+        <appender-ref ref="FILE" />
+        <appender-ref ref="ERROR_FILE" />
+    </root>
+
+    <!--日志异步到数据库 -->
+    <!--<appender name="DB" class="ch.qos.logback.classic.db.DBAppender">-->
+        <!--&lt;!&ndash;日志异步到数据库 &ndash;&gt;-->
+        <!--<connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">-->
+            <!--&lt;!&ndash;连接池 &ndash;&gt;-->
+            <!--<dataSource class="com.mchange.v2.c3p0.ComboPooledDataSource">-->
+                <!--<driverClass>com.mysql.jdbc.Driver</driverClass>-->
+                <!--<url>jdbc:mysql://127.0.0.1:3306/databaseName</url>-->
+                <!--<user>root</user>-->
+                <!--<password>root</password>-->
+            <!--</dataSource>-->
+        <!--</connectionSource>-->
+    <!--</appender>-->
+</configuration>

+ 21 - 0
mall-service/src/main/resources/mapper/AppModuleMapper.xml

@@ -0,0 +1,21 @@
+<?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="com.txz.mall.dao.AppModuleMapper">
+  <resultMap id="BaseResultMap" type="com.txz.mall.model.AppModule">
+    <!--
+      WARNING - @mbg.generated
+    -->
+    <id column="id" jdbcType="BIGINT" property="id" />
+    <result column="app_code" jdbcType="VARCHAR" property="appCode" />
+    <result column="name" jdbcType="VARCHAR" property="name" />
+    <result column="code" jdbcType="VARCHAR" property="code" />
+    <result column="status" jdbcType="TINYINT" property="status" />
+    <result column="check_version" jdbcType="TINYINT" property="checkVersion" />
+    <result column="content" jdbcType="VARCHAR" property="content" />
+    <result column="cluster_ids" jdbcType="VARCHAR" property="clusterIds" />
+    <result column="version" jdbcType="VARCHAR" property="version" />
+  </resultMap>
+
+
+
+</mapper>

+ 425 - 0
mall-service/src/test/java/CodeGenerator.java

@@ -0,0 +1,425 @@
+import com.google.common.base.CaseFormat;
+import freemarker.template.TemplateExceptionHandler;
+import org.apache.commons.lang3.StringUtils;
+import org.mybatis.generator.api.MyBatisGenerator;
+import org.mybatis.generator.config.*;
+import org.mybatis.generator.internal.DefaultShellCallback;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+import static com.txz.mall.core.ProjectConstant.*;
+
+/**
+ * 代码生成器,根据数据表名称生成对应的Model、Mapper、Service、Controller简化开发。
+ */
+public class CodeGenerator {
+	// JDBC配置,请修改为你项目的实际配置
+	private static final String JDBC_URL = "jdbc:mysql://106.54.153.203:3306/operating";
+	private static final String JDBC_USERNAME = "htds";
+	private static final String JDBC_PASSWORD = "yw1234";
+	private static final String JDBC_DIVER_CLASS_NAME = "com.mysql.jdbc.Driver";
+
+	private static final String APPLICATION = "operating";
+
+	private static final String PROJECT_PATH = System.getProperty("user.dir")+"\\"+APPLICATION+"-service";// 项目在硬盘上的基础路径
+	private static final String PROJECT_INTERFACE_PATH = System.getProperty("user.dir")+"\\"+APPLICATION+"-interface";// 项目在硬盘上的基础路径
+	private static final String PROJECT_API_PATH = System.getProperty("user.dir")+"\\"+APPLICATION+"-api";// 项目在硬盘上的基础路径
+
+
+	private static final String TEMPLATE_FILE_PATH = PROJECT_PATH + "/src/test/resources/generator/template";// 模板位置
+
+	private static final String JAVA_PATH = "/src/main/java"; // java文件路径
+	private static final String RESOURCES_PATH = "/src/main/resources";// 资源文件路径
+
+	private static final String PACKAGE_PATH_SERVICE = packageConvertPath(SERVICE_PACKAGE);// 生成的Service存放路径
+	private static final String PACKAGE_PATH_SERVICE_IMPL = packageConvertPath(SERVICE_IMPL_PACKAGE);// 生成的Service实现存放路径
+	private static final String PACKAGE_PATH_CONTROLLER = packageConvertPath(CONTROLLER_PACKAGE);// 生成的Controller存放路径
+	private static final String PACKAGE_PATH_DTO = packageConvertPath(SERVICE_DTO_PACKAGE);// 生成的Service实现存放路径
+
+
+	private static final String AUTHOR = "CodeGenerator";// @author
+	private static final String DATE = new SimpleDateFormat("yyyy/MM/dd").format(new Date());// @date
+
+	public static void main(String[] args) {
+//		genCode("o_lottery","o_lottery_prize","o_lottery_record");
+		// genCode("输入表名","输入自定义Model名称");
+		  genCode("o_app_half_time");
+		//genCode("c_member_coupon");
+	}
+
+	/**
+	 * 通过数据表名称生成代码,Model 名称通过解析数据表名称获得,下划线转大驼峰的形式。 如输入表名称 "t_user_detail" 将生成
+	 * TUserDetail、TUserDetailMapper、TUserDetailService ...
+	 *
+	 * @param tableNames 数据表名称...
+	 */
+	public static void genCode(String... tableNames) {
+		for (String tableName : tableNames) {
+			// System.out.println(tableNameConvertUpperCamel(tableName.substring(2,tableName.length())));
+			genCode2(tableName, tableNameConvertUpperCamel(tableName.substring(2, tableName.length())));
+		}
+	}
+
+	// 首字母大写
+	public static String captureName(String name) {
+		name = name.substring(0, 1).toUpperCase() + name.substring(1);
+		return name;
+
+	}
+
+	/**
+	 * 通过数据表名称,和自定义的 Model 名称生成代码 如输入表名称 "t_user_detail" 和自定义的 Model 名称 "User"
+	 * 将生成 User、UserMapper、UserService ...
+	 *
+	 * @param tableName 数据表名称
+	 * @param modelName 自定义的 Model 名称
+	 */
+	public static void genCode2(String tableName, String modelName) {
+		genModelAndMapper(tableName, modelName);
+		genService(tableName, modelName);
+		genController(tableName, modelName);
+		genClient(tableName, modelName);
+	}
+
+	public static void genModelAndMapper(String tableName, String modelName) {
+		Context context = new Context(ModelType.FLAT);
+		context.setId("Potato");
+		context.setTargetRuntime("MyBatis3Simple");
+		context.addProperty(PropertyRegistry.CONTEXT_BEGINNING_DELIMITER, "`");
+		context.addProperty(PropertyRegistry.CONTEXT_ENDING_DELIMITER, "`");
+
+		JDBCConnectionConfiguration jdbcConnectionConfiguration = new JDBCConnectionConfiguration();
+		jdbcConnectionConfiguration.setConnectionURL(JDBC_URL);
+		jdbcConnectionConfiguration.setUserId(JDBC_USERNAME);
+		jdbcConnectionConfiguration.setPassword(JDBC_PASSWORD);
+		jdbcConnectionConfiguration.setDriverClass(JDBC_DIVER_CLASS_NAME);
+		context.setJdbcConnectionConfiguration(jdbcConnectionConfiguration);
+
+		PluginConfiguration pluginConfiguration = new PluginConfiguration();
+		pluginConfiguration.setConfigurationType("tk.mybatis.mapper.generator.MapperPlugin");
+		pluginConfiguration.addProperty("mappers", MAPPER_INTERFACE_REFERENCE);
+		context.addPluginConfiguration(pluginConfiguration);
+
+		JavaModelGeneratorConfiguration javaModelGeneratorConfiguration = new JavaModelGeneratorConfiguration();
+		javaModelGeneratorConfiguration.setTargetProject(PROJECT_PATH + JAVA_PATH);
+		javaModelGeneratorConfiguration.setTargetPackage(MODEL_PACKAGE);
+		context.setJavaModelGeneratorConfiguration(javaModelGeneratorConfiguration);
+
+		SqlMapGeneratorConfiguration sqlMapGeneratorConfiguration = new SqlMapGeneratorConfiguration();
+		sqlMapGeneratorConfiguration.setTargetProject(PROJECT_PATH + RESOURCES_PATH);
+		sqlMapGeneratorConfiguration.setTargetPackage("mapper");
+		context.setSqlMapGeneratorConfiguration(sqlMapGeneratorConfiguration);
+
+		JavaClientGeneratorConfiguration javaClientGeneratorConfiguration = new JavaClientGeneratorConfiguration();
+		javaClientGeneratorConfiguration.setTargetProject(PROJECT_PATH + JAVA_PATH);
+		javaClientGeneratorConfiguration.setTargetPackage(MAPPER_PACKAGE);
+		javaClientGeneratorConfiguration.setConfigurationType("XMLMAPPER");
+		context.setJavaClientGeneratorConfiguration(javaClientGeneratorConfiguration);
+
+		TableConfiguration tableConfiguration = new TableConfiguration(context);
+		tableConfiguration.setTableName(tableName);
+		tableConfiguration.setDomainObjectName(modelName);
+		tableConfiguration.setGeneratedKey(new GeneratedKey("id", "Mysql", true, null));
+		context.addTableConfiguration(tableConfiguration);
+
+		List<String> warnings;
+		MyBatisGenerator generator;
+		try {
+			Configuration config = new Configuration();
+			config.addContext(context);
+			config.validate();
+
+			boolean overwrite = true;
+			DefaultShellCallback callback = new DefaultShellCallback(overwrite);
+			warnings = new ArrayList<String>();
+			generator = new MyBatisGenerator(config, callback, warnings);
+			generator.generate(null);
+		} catch (Exception e) {
+			throw new RuntimeException("生成Model和Mapper失败", e);
+		}
+
+		if (generator.getGeneratedJavaFiles().isEmpty() || generator.getGeneratedXmlFiles().isEmpty()) {
+			throw new RuntimeException("生成Model和Mapper失败:" + warnings);
+		}
+		if (StringUtils.isEmpty(modelName))
+			modelName = tableNameConvertUpperCamel(tableName);
+		System.out.println(modelName + ".java 生成成功");
+		System.out.println(modelName + "Mapper.java 生成成功");
+		System.out.println(modelName + "Mapper.xml 生成成功");
+		System.out.println(modelName + "开始生成interface---------------------");
+//		context = new Context(ModelType.FLAT);
+//		context.setId("Potato");
+//		context.setTargetRuntime("MyBatis3Simple");
+//		context.addProperty(PropertyRegistry.CONTEXT_BEGINNING_DELIMITER, "`");
+//		context.addProperty(PropertyRegistry.CONTEXT_ENDING_DELIMITER, "`");
+//
+//		context.setJdbcConnectionConfiguration(jdbcConnectionConfiguration);
+//
+//		CommentGeneratorConfiguration myComment = new CommentGeneratorConfiguration();
+//		myComment.setConfigurationType("com.conpany.project.MyCommentGenerator");
+//		context.setCommentGeneratorConfiguration(myComment);
+//
+//		javaModelGeneratorConfiguration = new JavaModelGeneratorConfiguration();
+//		javaModelGeneratorConfiguration.setTargetProject(PROJECT_INTERFACE_PATH + JAVA_PATH);
+//		javaModelGeneratorConfiguration.setTargetPackage(SERVICE_DTO_PACKAGE);
+//		context.setJavaModelGeneratorConfiguration(javaModelGeneratorConfiguration);
+//
+//		tableConfiguration = new TableConfiguration(context);
+//		tableConfiguration.setTableName(tableName);
+//		tableConfiguration.setDomainObjectName(modelName+"DPO");
+//		tableConfiguration.setGeneratedKey(new GeneratedKey("id", "Mysql", true, null));
+//		context.addTableConfiguration(tableConfiguration);
+//
+//
+//		try {
+//			Configuration config = new Configuration();
+//			config.addContext(context);
+//			config.validate();
+//
+//			boolean overwrite = true;
+//			DefaultShellCallback callback = new DefaultShellCallback(overwrite);
+//			warnings = new ArrayList<String>();
+//			generator = new MyBatisGenerator(config, callback, warnings);
+//			generator.generate(null);
+//		} catch (Exception e) {
+//			throw new RuntimeException("生成DPO失败", e);
+//		}
+//
+//		if (StringUtils.isEmpty(modelName))
+//			modelName = tableNameConvertUpperCamel(tableName);
+//		System.out.println(modelName + ".java 生成成功 --------DPO------");
+
+		context = new Context(ModelType.FLAT);
+		context.setId("Potato");
+		context.setTargetRuntime("MyBatis3Simple");
+		context.addProperty(PropertyRegistry.CONTEXT_BEGINNING_DELIMITER, "`");
+		context.addProperty(PropertyRegistry.CONTEXT_ENDING_DELIMITER, "`");
+
+		context.setJdbcConnectionConfiguration(jdbcConnectionConfiguration);
+
+		CommentGeneratorConfiguration myComment2 = new CommentGeneratorConfiguration();
+		myComment2.setConfigurationType("com.conpany.project.MyCommentGenerator");
+		context.setCommentGeneratorConfiguration(myComment2);
+
+		PluginConfiguration serializablePlugin2 = new PluginConfiguration();
+		serializablePlugin2.setConfigurationType("com.conpany.project.SerializablePlugin");
+		context.addPluginConfiguration(serializablePlugin2);
+
+		javaModelGeneratorConfiguration = new JavaModelGeneratorConfiguration();
+		javaModelGeneratorConfiguration.setTargetProject(PROJECT_API_PATH + JAVA_PATH);
+		javaModelGeneratorConfiguration.setTargetPackage(SERVICE_DTO_PACKAGE);
+		context.setJavaModelGeneratorConfiguration(javaModelGeneratorConfiguration);
+
+		tableConfiguration = new TableConfiguration(context);
+		tableConfiguration.setTableName(tableName);
+		tableConfiguration.setDomainObjectName(modelName+"DTO");
+		tableConfiguration.setGeneratedKey(new GeneratedKey("id", "Mysql", true, null));
+		context.addTableConfiguration(tableConfiguration);
+
+
+		try {
+			Configuration config = new Configuration();
+			config.addContext(context);
+			config.validate();
+
+			boolean overwrite = true;
+			DefaultShellCallback callback = new DefaultShellCallback(overwrite);
+			warnings = new ArrayList<String>();
+			generator = new MyBatisGenerator(config, callback, warnings);
+			generator.generate(null);
+		} catch (Exception e) {
+			throw new RuntimeException("生成DTO失败", e);
+		}
+
+		if (StringUtils.isEmpty(modelName))
+			modelName = tableNameConvertUpperCamel(tableName);
+		System.out.println(modelName + ".java 生成成功 --------DTO------");
+	}
+
+	/**
+	 * 生成请求客户端
+	 * @param tableName
+	 * @param modelName
+	 */
+	public static void genClient(String tableName, String modelName) {
+		try {
+			freemarker.template.Configuration cfg = getConfiguration();
+
+			Map<String, Object> data = new HashMap<>();
+			data.put("date", DATE);
+			data.put("author", AUTHOR);
+			String modelNameUpperCamel = StringUtils.isEmpty(modelName) ? tableNameConvertUpperCamel(tableName)
+					: modelName;
+			data.put("baseRequestMapping", modelNameConvertMappingPath(modelNameUpperCamel));
+			data.put("modelNameUpperCamel", modelNameUpperCamel);
+			data.put("modelNameLowerCamel", CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_CAMEL, modelNameUpperCamel));
+			data.put("basePackage", BASE_PACKAGE);
+			data.put("application", APPLICATION);
+
+			File file = new File(
+					PROJECT_INTERFACE_PATH + JAVA_PATH + PACKAGE_PATH_SERVICE + modelNameUpperCamel + "ServiceClient.java");
+			if (!file.getParentFile().exists()) {
+				file.getParentFile().mkdirs();
+			}
+			cfg.getTemplate("client.ftl").process(data, new FileWriter(file));
+			System.out.println(modelNameUpperCamel + "Client.java 生成成功");
+
+//			File file1 = new File(
+//					PROJECT_INTERFACE_PATH + JAVA_PATH + PACKAGE_PATH_DTO + modelNameUpperCamel + "Dto.java");
+//			if (!file1.getParentFile().exists()) {
+//				file1.getParentFile().mkdirs();
+//			}
+//			cfg.getTemplate("dto.ftl").process(data, new FileWriter(file1));
+//			System.out.println(modelNameUpperCamel + "Dto.java 生成成功");
+
+//			Context context = new Context(ModelType.FLAT);
+//			context.setId("Potato");
+//			context.setTargetRuntime("MyBatis3Simple");
+//			context.addProperty(PropertyRegistry.CONTEXT_BEGINNING_DELIMITER, "`");
+//			context.addProperty(PropertyRegistry.CONTEXT_ENDING_DELIMITER, "`");
+//
+//			JDBCConnectionConfiguration jdbcConnectionConfiguration = new JDBCConnectionConfiguration();
+//			jdbcConnectionConfiguration.setConnectionURL(JDBC_URL);
+//			jdbcConnectionConfiguration.setUserId(JDBC_USERNAME);
+//			jdbcConnectionConfiguration.setPassword(JDBC_PASSWORD);
+//			jdbcConnectionConfiguration.setDriverClass(JDBC_DIVER_CLASS_NAME);
+//			context.setJdbcConnectionConfiguration(jdbcConnectionConfiguration);
+//
+//			JavaModelGeneratorConfiguration javaModelGeneratorConfiguration = new JavaModelGeneratorConfiguration();
+//			javaModelGeneratorConfiguration.setTargetProject(PROJECT_INTERFACE_PATH + JAVA_PATH);
+//			javaModelGeneratorConfiguration.setTargetPackage(SERVICE_DTO_PACKAGE);
+//			context.setJavaModelGeneratorConfiguration(javaModelGeneratorConfiguration);
+//
+//			TableConfiguration tableConfiguration = new TableConfiguration(context);
+//			tableConfiguration.setTableName(tableName);
+//			tableConfiguration.setDomainObjectName(modelName);
+//			tableConfiguration.setGeneratedKey(new GeneratedKey("id", "Mysql", true, null));
+//			context.addTableConfiguration(tableConfiguration);
+//
+//			List<String> warnings;
+//			MyBatisGenerator generator;
+//			try {
+//				Configuration config = new Configuration();
+//				config.addContext(context);
+//				config.validate();
+//
+//				boolean overwrite = true;
+//				DefaultShellCallback callback = new DefaultShellCallback(overwrite);
+//				warnings = new ArrayList<String>();
+//				generator = new MyBatisGenerator(config, callback, warnings);
+//				generator.generate(null);
+//			} catch (Exception e) {
+//				throw new RuntimeException("生成Model失败", e);
+//			}
+//
+//			if (generator.getGeneratedJavaFiles().isEmpty() || generator.getGeneratedXmlFiles().isEmpty()) {
+//				throw new RuntimeException("生成Model失败:" + warnings);
+//			}
+//			if (StringUtils.isEmpty(modelName))
+//				modelName = tableNameConvertUpperCamel(tableName);
+//			System.out.println(modelName + ".java 生成成功");
+		} catch (Exception e) {
+			throw new RuntimeException("生成interface失败", e);
+		}
+	}
+
+	public static void genService(String tableName, String modelName) {
+		try {
+			freemarker.template.Configuration cfg = getConfiguration();
+
+			Map<String, Object> data = new HashMap<>();
+			data.put("date", DATE);
+			data.put("author", AUTHOR);
+			String modelNameUpperCamel = StringUtils.isEmpty(modelName) ? tableNameConvertUpperCamel(tableName)
+					: modelName;
+			data.put("modelNameUpperCamel", modelNameUpperCamel);
+			data.put("modelNameLowerCamel", tableNameConvertLowerCamel(tableName));
+			data.put("basePackage", BASE_PACKAGE);
+
+			File file = new File(
+					PROJECT_PATH + JAVA_PATH + PACKAGE_PATH_SERVICE + modelNameUpperCamel + "Service.java");
+			if (!file.getParentFile().exists()) {
+				file.getParentFile().mkdirs();
+			}
+			cfg.getTemplate("service.ftl").process(data, new FileWriter(file));
+			System.out.println(modelNameUpperCamel + "Service.java 生成成功");
+
+			File file1 = new File(
+					PROJECT_PATH + JAVA_PATH + PACKAGE_PATH_SERVICE_IMPL + modelNameUpperCamel + "ServiceImpl.java");
+			if (!file1.getParentFile().exists()) {
+				file1.getParentFile().mkdirs();
+			}
+			cfg.getTemplate("service-impl.ftl").process(data, new FileWriter(file1));
+			System.out.println(modelNameUpperCamel + "ServiceImpl.java 生成成功");
+		} catch (Exception e) {
+			throw new RuntimeException("生成Service失败", e);
+		}
+	}
+
+	public static void genController(String tableName, String modelName) {
+		try {
+			freemarker.template.Configuration cfg = getConfiguration();
+
+			Map<String, Object> data = new HashMap<>();
+			data.put("date", DATE);
+			data.put("author", AUTHOR);
+			String modelNameUpperCamel = StringUtils.isEmpty(modelName) ? tableNameConvertUpperCamel(tableName)
+					: modelName;
+			data.put("baseRequestMapping", modelNameConvertMappingPath(modelNameUpperCamel));
+			data.put("modelNameUpperCamel", modelNameUpperCamel);
+			data.put("modelNameLowerCamel", CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_CAMEL, modelNameUpperCamel));
+			data.put("basePackage", BASE_PACKAGE);
+
+			File file = new File(
+					PROJECT_PATH + JAVA_PATH + PACKAGE_PATH_CONTROLLER + modelNameUpperCamel + "Controller.java");
+			if (!file.getParentFile().exists()) {
+				file.getParentFile().mkdirs();
+			}
+			// cfg.getTemplate("controller-restful.ftl").process(data, new
+			// FileWriter(file));
+			cfg.getTemplate("controller.ftl").process(data, new FileWriter(file));
+
+			System.out.println(modelNameUpperCamel + "Controller.java 生成成功");
+		} catch (Exception e) {
+			throw new RuntimeException("生成Controller失败", e);
+		}
+
+	}
+
+	private static freemarker.template.Configuration getConfiguration() throws IOException {
+		freemarker.template.Configuration cfg = new freemarker.template.Configuration(
+				freemarker.template.Configuration.VERSION_2_3_23);
+		cfg.setDirectoryForTemplateLoading(new File(TEMPLATE_FILE_PATH));
+		cfg.setDefaultEncoding("UTF-8");
+		cfg.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
+		return cfg;
+	}
+
+	private static String tableNameConvertLowerCamel(String tableName) {
+		return CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, tableName.toLowerCase());
+	}
+
+	private static String tableNameConvertUpperCamel(String tableName) {
+		return CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, tableName.toLowerCase());
+
+	}
+
+	private static String tableNameConvertMappingPath(String tableName) {
+		tableName = tableName.toLowerCase();// 兼容使用大写的表名
+		return "/" + (tableName.contains("_") ? tableName.replaceAll("_", "/") : tableName);
+	}
+
+	private static String modelNameConvertMappingPath(String modelName) {
+		String tableName = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, modelName);
+		return tableNameConvertMappingPath(tableName);
+	}
+
+	private static String packageConvertPath(String packageName) {
+		return String.format("/%s/", packageName.contains(".") ? packageName.replaceAll("\\.", "/") : packageName);
+	}
+
+}

+ 18 - 0
mall-service/src/test/java/com/Test1111.java

@@ -0,0 +1,18 @@
+package com;
+
+import org.junit.Test;
+
+/**
+ * @Author: Fcx
+ * @Date: 2020/11/20 15:40
+ * @Version 1.0
+ */
+public class Test1111 {
+
+
+    @Test
+    public void test11() throws Exception{
+        Long aLong = Long.valueOf(1 / 2);
+        System.out.println(aLong);
+    }
+}

+ 313 - 0
mall-service/src/test/java/com/conpany/project/MyCommentGenerator.java

@@ -0,0 +1,313 @@
+package com.conpany.project;
+
+import org.mybatis.generator.api.CommentGenerator;
+import org.mybatis.generator.api.IntrospectedColumn;
+import org.mybatis.generator.api.IntrospectedTable;
+import org.mybatis.generator.api.dom.java.*;
+import org.mybatis.generator.api.dom.xml.XmlElement;
+import org.mybatis.generator.config.MergeConstants;
+import org.mybatis.generator.config.PropertyRegistry;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Properties;
+
+import static org.mybatis.generator.internal.util.StringUtility.isTrue;
+
+/**   
+ * @Title: MyCommentGenerator.java 
+ * @Package com.fendo.mybatis_generator_plus 
+ * @Description:  mybatis generator 自定义comment生成器.
+ *                基于MBG 1.3.5
+ * @author fendo
+ * @date 2017年10月5日 下午3:07:26 
+ * @version V1.0   
+*/
+public class MyCommentGenerator implements CommentGenerator{
+ 
+    /**
+      * properties配置文件
+     */
+    private Properties properties;
+    /**
+      * properties配置文件
+     */
+    private Properties systemPro;
+    
+    /*
+     * 父类时间
+     */
+    private boolean suppressDate;
+    
+    /**
+     * 父类所有注释
+     */
+    private boolean suppressAllComments;
+    
+    /**
+     * 当前时间
+     */
+    private String currentDateStr;
+    
+    public MyCommentGenerator() {
+        super();
+        properties = new Properties();
+        systemPro = System.getProperties();
+        suppressDate = false;
+        suppressAllComments = false;
+        currentDateStr = (new SimpleDateFormat("yyyy-MM-dd")).format(new Date());
+    }
+    
+    /**
+     * Java类的类注释
+     */
+	@Override
+	public void addClassComment(InnerClass innerClass, IntrospectedTable introspectedTable) {
+        if (suppressAllComments) {
+            return;
+        }
+ 
+        StringBuilder sb = new StringBuilder();
+        innerClass.addJavaDocLine("/**");
+        sb.append(" * ");
+        sb.append(introspectedTable.getFullyQualifiedTable());
+        sb.append(" ");
+        sb.append(getDateString());
+        innerClass.addJavaDocLine(sb.toString().replace("\n", " "));
+        innerClass.addJavaDocLine(" */");
+	}
+ 
+	/**
+	 * 为类添加注释
+	 */
+	@Override
+	public void addClassComment(InnerClass innerClass, IntrospectedTable introspectedTable, boolean markAsDoNotDelete) {
+		if (suppressAllComments) {
+            return;
+        }
+        StringBuilder sb = new StringBuilder();
+        innerClass.addJavaDocLine("/**");
+        sb.append(" * ");
+        sb.append(" * ");
+        sb.append(introspectedTable.getFullyQualifiedTable());
+        innerClass.addJavaDocLine(sb.toString().replace("\n", " "));
+        sb.setLength(0);
+        sb.append(" * @author ");
+        sb.append(systemPro.getProperty("user.name"));
+        sb.append(" ");
+        sb.append(currentDateStr);
+        innerClass.addJavaDocLine(" */");
+	}
+ 
+	
+	/**
+	 * Mybatis的Mapper.xml文件里面的注释
+	 */
+	@Override
+	public void addComment(XmlElement xmlElement) {
+		
+	}
+ 
+	/**
+	 * 
+	 *@Title addConfigurationProperties 
+	 *@Description: 从该配置中的任何属性添加此实例的属性CommentGenerator配置。
+	 *              这个方法将在任何其他方法之前被调用。
+	 *@Author fendo
+	 *@Date 2017年10月5日 下午3:45:58
+	 *@return
+	 *@throws
+	 */
+	@Override
+	public void addConfigurationProperties(Properties properties) {
+		this.properties.putAll(properties);
+        suppressDate = isTrue(properties.getProperty(PropertyRegistry.COMMENT_GENERATOR_SUPPRESS_DATE));
+        suppressAllComments = isTrue(properties.getProperty(PropertyRegistry.COMMENT_GENERATOR_SUPPRESS_ALL_COMMENTS));
+	}
+ 
+	/**
+	 * 
+	 *@Title getDateString 
+	 *@Description: 此方法返回格式化的日期字符串以包含在Javadoc标记中和XML注释。 如果您不想要日期,则可以返回null在这些文档元素中。
+	 *@Author fendo
+	 *@Date 2017年10月5日 下午3:45:58
+	 *@return
+	 *@throws
+	 */
+    protected String getDateString() {
+        String result = null;
+        if (!suppressDate) {
+            result = currentDateStr;
+        }
+        return result;
+    }
+    
+    /**
+     * 
+     *@Title addJavadocTag 
+     *@Description: 此方法为其添加了自定义javadoc标签。
+     *@Author fendo
+     *@Date 2017年10月5日 下午3:49:05
+     *@param javaElement
+     *@param markAsDoNotDelete
+     *@throws
+     */
+	protected void addJavadocTag(JavaElement javaElement, boolean markAsDoNotDelete) {
+        javaElement.addJavaDocLine(" *");
+        StringBuilder sb = new StringBuilder();
+        sb.append(" * ");
+        sb.append(MergeConstants.NEW_ELEMENT_TAG);
+        if (markAsDoNotDelete) {
+            sb.append(" do_not_delete_during_merge");
+        }
+        String s = getDateString();
+        if (s != null) {
+            sb.append(' ');
+            sb.append(s);
+        }
+        javaElement.addJavaDocLine(sb.toString());
+    }
+	
+	
+	/**
+	 * 为枚举添加注释
+	 */
+	@Override
+	public void addEnumComment(InnerEnum innerEnum, IntrospectedTable introspectedTable) {
+		if (suppressAllComments) {
+            return;
+        }
+        StringBuilder sb = new StringBuilder();
+        innerEnum.addJavaDocLine("/**");
+        sb.append(" * ");
+        sb.append(introspectedTable.getFullyQualifiedTable());
+        innerEnum.addJavaDocLine(sb.toString().replace("\n", " "));
+        innerEnum.addJavaDocLine(" */");
+	}
+ 
+	/**
+	 * Java属性注释
+	 */
+	@Override
+	public void addFieldComment(Field field, IntrospectedTable introspectedTable) {
+		if (suppressAllComments) {
+            return;
+        }
+        StringBuilder sb = new StringBuilder();
+        field.addJavaDocLine("/**");
+        sb.append(" * ");
+        sb.append(introspectedTable.getFullyQualifiedTable());
+        field.addJavaDocLine(sb.toString().replace("\n", " "));
+        field.addJavaDocLine(" */");
+        
+        
+        
+	}
+ 
+	/**
+	 * 为字段添加注释
+	 */
+	@Override
+	public void addFieldComment(Field field, IntrospectedTable introspectedTable,IntrospectedColumn introspectedColumn) {
+		if (suppressAllComments) {
+            return;
+        }
+        StringBuilder sb = new StringBuilder();
+        field.addJavaDocLine("/**");
+        sb.append(" * ");
+        sb.append(introspectedColumn.getRemarks());
+        field.addJavaDocLine(sb.toString().replace("\n", " "));
+        field.addJavaDocLine(" */");
+	}
+ 
+	/**
+	 * 普通方法的注释,这里主要是XXXMapper.java里面的接口方法的注释
+	 */
+	@Override
+	public void addGeneralMethodComment(Method method, IntrospectedTable introspectedTable) {
+	  if (suppressAllComments) {
+        return;
+      }
+      method.addJavaDocLine("/**");
+      addJavadocTag(method, false);
+      method.addJavaDocLine(" */");
+	}
+ 
+	
+	/**
+	 * 给getter方法加注释
+	 */
+	@Override
+	public void addGetterComment(Method method, IntrospectedTable introspectedTable,IntrospectedColumn introspectedColumn) {
+	    if (suppressAllComments) {
+            return;
+        }
+        method.addJavaDocLine("/**");
+        StringBuilder sb = new StringBuilder();
+        sb.append(" * ");
+        sb.append(introspectedColumn.getRemarks());
+        method.addJavaDocLine(sb.toString().replace("\n", " "));
+        sb.setLength(0);
+        sb.append(" * @return ");
+        sb.append(introspectedColumn.getActualColumnName());
+        sb.append(" ");
+        sb.append(introspectedColumn.getRemarks());
+        method.addJavaDocLine(sb.toString().replace("\n", " "));
+        method.addJavaDocLine(" */");
+	}
+ 
+	/**
+	 * 给Java文件加注释,这个注释是在文件的顶部,也就是package上面。
+	 */
+	@Override
+	public void addJavaFileComment(CompilationUnit compilationUnit) {
+    	SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
+    	compilationUnit.addFileCommentLine("/*");
+    	compilationUnit.addFileCommentLine("*");
+    	compilationUnit.addFileCommentLine("* "+compilationUnit.getType().getShortName()+".java");
+    	compilationUnit.addFileCommentLine("* Copyright(C) 2017-2020 fendo公司");
+    	compilationUnit.addFileCommentLine("* @date "+sdf.format(new Date())+"");
+    	compilationUnit.addFileCommentLine("*/");
+	}
+ 
+	/**
+	 * 为模型类添加注释
+	 */
+	@Override
+	public void addModelClassComment(TopLevelClass arg0, IntrospectedTable arg1) {
+		
+	}
+ 
+	/**
+	 * 为调用此方法作为根元素的第一个子节点添加注释。
+	 */
+	@Override
+	public void addRootComment(XmlElement arg0) {
+		
+	}
+ 
+	
+	/**
+	 * 给setter方法加注释
+	 */
+	@Override
+	public void addSetterComment(Method method, IntrospectedTable introspectedTable,IntrospectedColumn introspectedColumn) {
+		if (suppressAllComments) {
+            return;
+        }
+        method.addJavaDocLine("/**");
+        StringBuilder sb = new StringBuilder();
+        sb.append(" * ");
+        sb.append(introspectedColumn.getRemarks());
+        method.addJavaDocLine(sb.toString().replace("\n", " "));
+        Parameter parm = method.getParameters().get(0);
+        sb.setLength(0);
+        sb.append(" * @param ");
+        sb.append(parm.getName());
+        sb.append(" ");
+        sb.append(introspectedColumn.getRemarks());
+        method.addJavaDocLine(sb.toString().replace("\n", " "));
+        method.addJavaDocLine(" */");
+	}
+ 
+}

+ 110 - 0
mall-service/src/test/java/com/conpany/project/SerializablePlugin.java

@@ -0,0 +1,110 @@
+package com.conpany.project;
+
+import org.mybatis.generator.api.IntrospectedTable;
+import org.mybatis.generator.api.PluginAdapter;
+import org.mybatis.generator.api.dom.java.*;
+
+import java.util.List;
+import java.util.Properties;
+
+/**
+ * 分布式开发的话,Example对象也必须要序列化
+ * 扩展一个 mybatis generator 插件,用于不仅仅在生成的实体类 还有 *Example 类都序列化
+ * @author alexgaoyh
+ *
+ */
+public class SerializablePlugin extends PluginAdapter {  
+  
+    private FullyQualifiedJavaType serializable;  
+    private FullyQualifiedJavaType gwtSerializable;  
+    private boolean addGWTInterface;  
+    private boolean suppressJavaInterface;  
+  
+    public SerializablePlugin() {  
+        super();  
+        serializable = new FullyQualifiedJavaType("java.io.Serializable"); //$NON-NLS-1$  
+        gwtSerializable = new FullyQualifiedJavaType("com.google.gwt.user.client.rpc.IsSerializable"); //$NON-NLS-1$  
+    }  
+  
+    public boolean validate(List<String> warnings) {  
+        // this plugin is always valid  
+        return true;  
+    }  
+  
+    @Override  
+    public void setProperties(Properties properties) {  
+        super.setProperties(properties);  
+        addGWTInterface = Boolean.valueOf(properties.getProperty("addGWTInterface")); //$NON-NLS-1$  
+        suppressJavaInterface = Boolean.valueOf(properties.getProperty("suppressJavaInterface")); //$NON-NLS-1$  
+    }  
+  
+    @Override  
+    public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass,  
+                                                 IntrospectedTable introspectedTable) {  
+        makeSerializable(topLevelClass, introspectedTable);  
+        return true;  
+    }  
+  
+    @Override  
+    public boolean modelPrimaryKeyClassGenerated(TopLevelClass topLevelClass,  
+                                                 IntrospectedTable introspectedTable) {  
+        makeSerializable(topLevelClass, introspectedTable);  
+        return true;  
+    }  
+  
+    @Override  
+    public boolean modelRecordWithBLOBsClassGenerated(  
+            TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {  
+        makeSerializable(topLevelClass, introspectedTable);  
+        return true;  
+    }  
+  
+    /** 
+     * 添加给Example类序列化的方法 
+     * @param topLevelClass 
+     * @param introspectedTable 
+     * @return 
+     */  
+    @Override  
+    public boolean modelExampleClassGenerated(TopLevelClass topLevelClass,IntrospectedTable introspectedTable){  
+        makeSerializable(topLevelClass, introspectedTable);  
+  
+        for (InnerClass innerClass : topLevelClass.getInnerClasses()) {  
+            if ("GeneratedCriteria".equals(innerClass.getType().getShortName())) { //$NON-NLS-1$  
+                innerClass.addSuperInterface(serializable);  
+            }  
+            if ("Criteria".equals(innerClass.getType().getShortName())) { //$NON-NLS-1$  
+                innerClass.addSuperInterface(serializable);  
+            }  
+            if ("Criterion".equals(innerClass.getType().getShortName())) { //$NON-NLS-1$  
+                innerClass.addSuperInterface(serializable);  
+            }  
+        }  
+  
+        return true;  
+    }  
+  
+    protected void makeSerializable(TopLevelClass topLevelClass,  
+                                    IntrospectedTable introspectedTable) {  
+        if (addGWTInterface) {  
+            topLevelClass.addImportedType(gwtSerializable);  
+            topLevelClass.addSuperInterface(gwtSerializable);  
+        }  
+  
+        if (!suppressJavaInterface) {  
+            topLevelClass.addImportedType(serializable);  
+            topLevelClass.addSuperInterface(serializable);  
+  
+            Field field = new Field();  
+            field.setFinal(true);  
+            field.setInitializationString("1L"); //$NON-NLS-1$  
+            field.setName("serialVersionUID"); //$NON-NLS-1$  
+            field.setStatic(true);  
+            field.setType(new FullyQualifiedJavaType("long")); //$NON-NLS-1$  
+            field.setVisibility(JavaVisibility.PRIVATE);  
+            context.getCommentGenerator().addFieldComment(field, introspectedTable);  
+  
+            topLevelClass.addField(field);  
+        }  
+    }  
+}

+ 52 - 0
mall-service/src/test/java/com/conpany/project/TestRedis.java

@@ -0,0 +1,52 @@
+package com.conpany.project;
+
+import javax.annotation.Resource;
+
+import cn.hutool.crypto.SecureUtil;
+import org.junit.Assert;
+import org.junit.Test;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.StringRedisTemplate;
+
+
+public class TestRedis extends Tester{
+
+	@Resource
+    private StringRedisTemplate stringRedisTemplate;
+    
+    @Resource
+    private RedisTemplate redisTemplate;
+
+    @Test
+    public void test() throws Exception {
+        stringRedisTemplate.opsForValue().set("aaa", "111");
+        Assert.assertEquals("111", stringRedisTemplate.opsForValue().get("aaa"));
+    }
+    
+    @Test
+    public void testObj() throws Exception {
+//        User user=new User();
+//        user.setName("222");
+//        ValueOperations<String, User> operations= redisTemplate.opsForValue();
+//        operations.set("com.neox", user);
+//        operations.set("com.neo.f", user,30000,TimeUnit.SECONDS);
+        Thread.sleep(1000);
+        //redisTemplate.delete("com.neo.f");
+        boolean exists=redisTemplate.hasKey("com.neo.f");
+        if(exists){
+            System.out.println("exists is true");
+        }else{
+            System.out.println("exists is false");
+        }
+//        System.out.println(operations.get("com.neo.f").getName());
+//        Assert.assertEquals("aa", operations.get("com.neo.f").getName());
+    }
+    
+    
+    @Test
+    public void testPwd() throws Exception {
+        String salt = "rPRf46jdaru";
+        String pwd = SecureUtil.md5("123456s" + salt.toUpperCase());
+        System.out.println(pwd);
+    }
+}

+ 20 - 0
mall-service/src/test/java/com/conpany/project/Tester.java

@@ -0,0 +1,20 @@
+package com.conpany.project;
+
+
+import com.txz.mall.MallApplication;
+
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+/**
+ * 单元测试继承该类即可
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = MallApplication.class)
+//@Transactional
+//@Rollback
+public abstract class Tester {}
+
+
+

+ 45 - 0
mall-service/src/test/resources/demo-user.sql

@@ -0,0 +1,45 @@
+/*
+Navicat MySQL Data Transfer
+
+Source Server         : Localhost
+Source Server Version : 50713
+Source Host           : localhost:3306
+Source Database       : test
+
+Target Server Type    : MYSQL
+Target Server Version : 50713
+File Encoding         : 65001
+
+Date: 2017-06-23 14:25:27
+*/
+
+SET FOREIGN_KEY_CHECKS=0;
+
+-- ----------------------------
+-- Table structure for user
+-- ----------------------------
+DROP TABLE IF EXISTS `user`;
+CREATE TABLE `user` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `username` varchar(255) NOT NULL,
+  `password` varchar(255) NOT NULL,
+  `nick_name` varchar(255) DEFAULT NULL,
+  `sex` int(1) DEFAULT NULL,
+  `register_date` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
+
+-- ----------------------------
+-- Records of user
+-- ----------------------------
+INSERT INTO `user` VALUES ('1', '89921218@qq.com', '1ee04e0b1cb5af7367c80c22e42efd8b', '土豆', '1', '2017-06-23 14:24:23');
+INSERT INTO `user` VALUES ('2', '2@qq.com', '1ee04e0b1cb5af7367c80c22e42efd8b', '土豆-2', '1', '2017-06-23 14:24:23');
+INSERT INTO `user` VALUES ('3', '3@qq.com', '1ee04e0b1cb5af7367c80c22e42efd8b', '土豆-3', '1', '2017-06-23 14:24:23');
+INSERT INTO `user` VALUES ('4', '4@qq.com', '1ee04e0b1cb5af7367c80c22e42efd8b', '土豆-4', '1', '2017-06-23 14:24:23');
+INSERT INTO `user` VALUES ('5', '5@qq.com', '1ee04e0b1cb5af7367c80c22e42efd8b', '土豆-5', '1', '2017-06-23 14:24:23');
+INSERT INTO `user` VALUES ('6', '6@qq.com', '1ee04e0b1cb5af7367c80c22e42efd8b', '土豆-6', '1', '2017-06-23 14:24:23');
+INSERT INTO `user` VALUES ('7', '7@qq.com', '1ee04e0b1cb5af7367c80c22e42efd8b', '土豆-7', '1', '2017-06-23 14:24:23');
+INSERT INTO `user` VALUES ('8', '8@qq.com', '1ee04e0b1cb5af7367c80c22e42efd8b', '土豆-8', '1', '2017-06-23 14:24:23');
+INSERT INTO `user` VALUES ('9', '9@qq.com', '1ee04e0b1cb5af7367c80c22e42efd8b', '土豆-9', '1', '2017-06-23 14:24:23');
+INSERT INTO `user` VALUES ('10', '10@qq.com', '1ee04e0b1cb5af7367c80c22e42efd8b', '土豆-10', '1', '2017-06-23 14:24:23');
+SET FOREIGN_KEY_CHECKS=1;

+ 27 - 0
mall-service/src/test/resources/generator/template/client.ftl

@@ -0,0 +1,27 @@
+package ${basePackage}.service;
+
+
+import ${basePackage}.dto.*;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.*;
+import java.util.List;
+
+
+@FeignClient("${application}")
+public interface ${modelNameUpperCamel}ServiceClient {
+
+	@RequestMapping( value = {"${baseRequestMapping}/add"}, method = {RequestMethod.POST} )
+    public Result add(@RequestBody ${modelNameUpperCamel}DPO ${modelNameLowerCamel},@RequestParam("userId") String userId);
+
+	@RequestMapping( value = {"${baseRequestMapping}/delete"}, method = {RequestMethod.POST} )
+	public Result delete(@RequestParam("id") Integer id,@RequestParam("userId") String userId);
+
+	@RequestMapping( value = {"${baseRequestMapping}/update"}, method = {RequestMethod.POST} )
+	public Result update(@RequestBody ${modelNameUpperCamel}DPO ${modelNameLowerCamel},@RequestParam("userId") String userId);
+
+	@RequestMapping( value = {"${baseRequestMapping}/detail"}, method = {RequestMethod.POST} )
+	public Result<${modelNameUpperCamel}DPO> detail(@RequestParam("id") Integer id,@RequestParam("userId") String userId);
+
+	@RequestMapping( value = {"${baseRequestMapping}/list"}, method = {RequestMethod.POST} )
+	public Result<List<${modelNameUpperCamel}DPO>> list(@RequestBody ${modelNameUpperCamel}DPO ${modelNameLowerCamel}, @RequestParam("page") Integer page, @RequestParam("size") Integer size,@RequestParam("userId") String userId);
+}

+ 55 - 0
mall-service/src/test/resources/generator/template/controller-restful.ftl

@@ -0,0 +1,55 @@
+package ${basePackage}.web;
+
+import ${basePackage}.core.Result;
+import ${basePackage}.core.ResultGenerator;
+import ${basePackage}.model.${modelNameUpperCamel};
+import ${basePackage}.service.${modelNameUpperCamel}Service;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+* Created by ${author} on ${date}.
+*/
+@RestController
+@RequestMapping("${baseRequestMapping}")
+public class ${modelNameUpperCamel}Controller {
+
+    @Resource
+    private ${modelNameUpperCamel}Service ${modelNameLowerCamel}Service;
+
+    @PostMapping
+    public Result add(@RequestBody ${modelNameUpperCamel} ${modelNameLowerCamel}) {
+        ${modelNameLowerCamel}Service.save(${modelNameLowerCamel});
+        return ResultGenerator.genSuccessResult();
+    }
+
+    @DeleteMapping("/{id}")
+    public Result delete(@PathVariable Integer id) {
+        ${modelNameLowerCamel}Service.deleteById(id);
+        return ResultGenerator.genSuccessResult();
+    }
+
+    @PutMapping
+    public Result update(@RequestBody ${modelNameUpperCamel} ${modelNameLowerCamel}) {
+        ${modelNameLowerCamel}Service.update(${modelNameLowerCamel});
+        return ResultGenerator.genSuccessResult();
+    }
+
+    @GetMapping("/{id}")
+    public Result detail(@PathVariable Integer id) {
+        ${modelNameUpperCamel} ${modelNameLowerCamel} = ${modelNameLowerCamel}Service.findById(id);
+        return ResultGenerator.genSuccessResult(${modelNameLowerCamel});
+    }
+
+    @GetMapping
+    public Result list(@RequestParam(defaultValue = "0") Integer page, @RequestParam(defaultValue = "0") Integer size) {
+        PageHelper.startPage(page, size);
+        List<${modelNameUpperCamel}> list = ${modelNameLowerCamel}Service.findAll();
+        PageInfo pageInfo = new PageInfo(list);
+        return ResultGenerator.genSuccessResult(pageInfo);
+    }
+}

+ 144 - 0
mall-service/src/test/resources/generator/template/controller.ftl

@@ -0,0 +1,144 @@
+package ${basePackage}.web.mng;
+import com.yiweikeji.project.core.Result;
+import ${basePackage}.core.ResultGenerator;
+import ${basePackage}.model.${modelNameUpperCamel};
+import ${basePackage}.service.${modelNameUpperCamel}Service;
+
+import ${basePackage}.core.ResultCode;
+
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+import tk.mybatis.mapper.entity.Condition;
+import tk.mybatis.mapper.entity.Example.Criteria;
+
+import javax.annotation.Resource;
+import java.util.List;
+import org.apache.commons.lang.StringUtils;
+
+/**
+* Created by ${author} on ${date}.
+*/
+@Api(tags = "[后台]${modelNameLowerCamel}管理")
+@RestController
+@RequestMapping("${baseRequestMapping}")
+public class ${modelNameUpperCamel}Controller {
+
+	private static Logger log = LoggerFactory.getLogger(${modelNameUpperCamel}Controller.class);
+
+    @Resource
+    private ${modelNameUpperCamel}Service ${modelNameLowerCamel}Service;
+
+    @PostMapping("/add")
+	@ApiOperation(value = "${modelNameLowerCamel}新增",httpMethod = "POST")
+    public Result add(@RequestBody ${modelNameUpperCamel} ${modelNameLowerCamel},String userId) {
+    	if(${modelNameLowerCamel} == null){
+    		return ResultGenerator.genFailResult(ResultCode.OBJECT_IS_NULL);
+    	}
+    	if(StringUtils.isBlank(userId)){
+    		return ResultGenerator.genFailResult(ResultCode.USERID_IS_NULL);
+    	}
+    	try {
+    //		${modelNameLowerCamel}.setCreateTime(new Date());
+    //		${modelNameLowerCamel}.setCreateUserId(userId);
+    		${modelNameLowerCamel}Service.save(${modelNameLowerCamel});
+		} catch (Exception e) {
+			log.error("新增对象操作异常e:{}",e);
+			return ResultGenerator.genFailResult(ResultCode.INTERNAL_SERVER_ERROR);
+		}
+
+        return ResultGenerator.genSuccessResult();
+    }
+
+    @PostMapping("/delete")
+	@ApiOperation(value = "${modelNameLowerCamel}删除",httpMethod = "POST")
+    public Result delete(@RequestParam Integer id,String userId) {
+    	if(id == null){
+    		return ResultGenerator.genFailResult(ResultCode.ID_IS_NULL);
+    	}
+    	if(StringUtils.isBlank(userId)){
+    		return ResultGenerator.genFailResult(ResultCode.USERID_IS_NULL);
+    	}
+    	try {
+    		${modelNameLowerCamel}Service.deleteById(id);
+		} catch (Exception e) {
+			log.error("删除对象操作异常e:{}",e);
+			return ResultGenerator.genFailResult(ResultCode.INTERNAL_SERVER_ERROR);
+		}
+        return ResultGenerator.genSuccessResult();
+    }
+
+    @PostMapping("/update")
+	@ApiOperation(value = "${modelNameLowerCamel}更新",httpMethod = "POST")
+    public Result update(@RequestBody ${modelNameUpperCamel} ${modelNameLowerCamel},String userId) {
+    	if(${modelNameLowerCamel} == null){
+    		return ResultGenerator.genFailResult(ResultCode.OBJECT_IS_NULL);
+    	}
+    	if(${modelNameLowerCamel}.getId() == null){
+    		return ResultGenerator.genFailResult(ResultCode.ID_IS_NULL);
+    	}
+    	if(StringUtils.isBlank(userId)){
+    		return ResultGenerator.genFailResult(ResultCode.USERID_IS_NULL);
+    	}
+    	try {
+    //		${modelNameLowerCamel}.setUpdateTime(new Date());
+    //		${modelNameLowerCamel}.setUpdateUserId(userId);
+    		${modelNameLowerCamel}Service.update(${modelNameLowerCamel});
+		} catch (Exception e) {
+			log.error("更新对象操作异常e:{}",e);
+			return ResultGenerator.genFailResult(ResultCode.INTERNAL_SERVER_ERROR);
+		}
+        return ResultGenerator.genSuccessResult();
+    }
+
+    @PostMapping("/detail")
+	@ApiOperation(value = "${modelNameLowerCamel}获取详情",httpMethod = "POST")
+    public Result<${modelNameUpperCamel}> detail(@RequestParam Integer id,String userId) {
+    	if(id == null){
+    		return ResultGenerator.genFailResult(ResultCode.ID_IS_NULL);
+    	}
+    	if(StringUtils.isBlank(userId)){
+    		return ResultGenerator.genFailResult(ResultCode.USERID_IS_NULL);
+    	}
+    	${modelNameUpperCamel} ${modelNameLowerCamel} = null;
+    	try {
+    		${modelNameLowerCamel} = ${modelNameLowerCamel}Service.findById(id);
+		} catch (Exception e) {
+			log.error("查询对象操作异常e:{}",e);
+			return ResultGenerator.genFailResult(ResultCode.INTERNAL_SERVER_ERROR);
+		}
+
+        return ResultGenerator.genSuccessResult(${modelNameLowerCamel});
+    }
+
+    @PostMapping("/list")
+	@ApiOperation(value = "${modelNameLowerCamel}获取列表",httpMethod = "POST")
+    public Result<List<${modelNameUpperCamel}>> list(@RequestBody ${modelNameUpperCamel} ${modelNameLowerCamel}, @RequestParam(defaultValue = "0") Integer page, @RequestParam(defaultValue = "0") Integer size,String userId) {
+        if(StringUtils.isBlank(userId)){
+    		return ResultGenerator.genFailResult(ResultCode.USERID_IS_NULL);
+    	}
+        PageHelper.startPage(page, size);
+
+        Condition condition = new Condition(${modelNameLowerCamel}.getClass());
+        Criteria criteria = condition.createCriteria();
+//        criteria.andEqualTo("name", city.getName());
+		PageInfo pageInfo = null;
+		try {
+    		 List<${modelNameUpperCamel}> list = ${modelNameLowerCamel}Service.findByCondition(condition);
+    		 pageInfo = new PageInfo(list);
+		} catch (Exception e) {
+			log.error("查询对象操作异常e:{}",e);
+			return ResultGenerator.genFailResult(ResultCode.INTERNAL_SERVER_ERROR);
+		}
+        return ResultGenerator.genSuccessResult(pageInfo);
+    }
+}

+ 10 - 0
mall-service/src/test/resources/generator/template/dto.ftl

@@ -0,0 +1,10 @@
+package ${basePackage}.dto;
+import java.util.*;
+
+/**
+* Created by ${author} on ${date}.
+*/
+public class ${modelNameUpperCamel}Dto {
+
+}
+

+ 22 - 0
mall-service/src/test/resources/generator/template/service-impl.ftl

@@ -0,0 +1,22 @@
+package ${basePackage}.service.impl;
+
+import ${basePackage}.dao.${modelNameUpperCamel}Mapper;
+import ${basePackage}.model.${modelNameUpperCamel};
+import ${basePackage}.service.${modelNameUpperCamel}Service;
+import ${basePackage}.core.AbstractService;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+
+
+/**
+ * Created by ${author} on ${date}.
+ */
+@Service
+@Transactional
+public class ${modelNameUpperCamel}ServiceImpl extends AbstractService<${modelNameUpperCamel}> implements ${modelNameUpperCamel}Service {
+    @Resource
+    private ${modelNameUpperCamel}Mapper ${modelNameLowerCamel}Mapper;
+
+}

+ 11 - 0
mall-service/src/test/resources/generator/template/service.ftl

@@ -0,0 +1,11 @@
+package ${basePackage}.service;
+import ${basePackage}.model.${modelNameUpperCamel};
+import ${basePackage}.core.Service;
+
+
+/**
+ * Created by ${author} on ${date}.
+ */
+public interface ${modelNameUpperCamel}Service extends Service<${modelNameUpperCamel}> {
+
+}

+ 443 - 0
mall-service/src/test/resources/operating20200818pro.sql

@@ -0,0 +1,443 @@
+-- --------------------------------------------------------
+-- 主机:                           106.54.153.203
+-- 服务器版本:                        5.6.45 - MySQL Community Server (GPL)
+-- 服务器操作系统:                      Linux
+-- HeidiSQL 版本:                  9.3.0.4984
+-- --------------------------------------------------------
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET NAMES utf8mb4 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+
+-- 导出  表 operating.o_activity 结构
+CREATE TABLE IF NOT EXISTS `o_activity` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT,
+  `app_code` varchar(50) NOT NULL COMMENT '应用编号',
+  `name` varchar(50) NOT NULL COMMENT '活动名称',
+  `colour` varchar(50) DEFAULT NULL COMMENT '颜色',
+  `conversion_ids` varchar(255) DEFAULT NULL COMMENT '兑换码id  多个使用,分割',
+  `activity_describe` varchar(255) DEFAULT NULL COMMENT '活动描述',
+  `pic` varchar(255) DEFAULT NULL COMMENT '活动图片',
+  `screen_pic` varchar(255) DEFAULT NULL COMMENT '弹屏图片',
+  `link` varchar(255) DEFAULT NULL COMMENT '链接   vip:购买vip  focus:关注公众号',
+  `screen` tinyint(4) NOT NULL COMMENT '弹屏 0不需要弹屏 1需要弹屏',
+  `seq` int(11) NOT NULL DEFAULT '1' COMMENT '排序',
+  `type` tinyint(4) NOT NULL COMMENT '活动类型 1普通活动 2特殊活动',
+  `status` tinyint(4) NOT NULL COMMENT '状态 1进行中 2停用',
+  `in_type` tinyint(4) NOT NULL COMMENT '活动准入类型 1所有玩家 2非关玩家 3非VIP玩家 4非关非VIP玩家',
+  `accomplish_type` tinyint(4) NOT NULL COMMENT '完成类型 1VIP 2关注公众号 3 VIP和关注公众号',
+  `start_time` datetime NOT NULL COMMENT '开始时间',
+  `end_time` datetime NOT NULL COMMENT '结束时间',
+  `create_time` datetime NOT NULL COMMENT '创建时间',
+  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
+  `create_name` varchar(50) NOT NULL COMMENT '创建人',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='活动表';
+
+-- 数据导出被取消选择。
+
+
+-- 导出  表 operating.o_activity_item 结构
+CREATE TABLE IF NOT EXISTS `o_activity_item` (
+  `id` bigint(20) NOT NULL,
+  `activity_id` bigint(20) NOT NULL,
+  `gift_id` bigint(20) NOT NULL COMMENT '礼品id',
+  `gift_name` varchar(50) NOT NULL COMMENT '礼品名称',
+  `gift_pic` varchar(255) DEFAULT NULL COMMENT '礼品图片',
+  `num` int(11) NOT NULL COMMENT '个数',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='活动奖品列表';
+
+-- 数据导出被取消选择。
+
+
+-- 导出  表 operating.o_activity_message 结构
+CREATE TABLE IF NOT EXISTS `o_activity_message` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT,
+  `user_id` varchar(50) NOT NULL,
+  `app_code` varchar(50) NOT NULL COMMENT '应用编码',
+  `activity_id` bigint(20) NOT NULL COMMENT '活动id 系统赠送默认-1 客服赠送 -2  转盘活动-3',
+  `type` tinyint(4) NOT NULL COMMENT '消息类型 1活动赠送 2活动参加 3活动进度 4系统赠送 5客服赠送',
+  `status` tinyint(4) NOT NULL COMMENT '状态 1未读 2已读',
+  `title` varchar(50) NOT NULL COMMENT '标题',
+  `content` varchar(255) NOT NULL COMMENT '消息内容',
+  `create_time` datetime NOT NULL COMMENT '创建时间',
+  `read_time` datetime DEFAULT NULL COMMENT '读取时间',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='活动消息';
+
+-- 数据导出被取消选择。
+
+
+-- 导出  表 operating.o_activity_message_templates 结构
+CREATE TABLE IF NOT EXISTS `o_activity_message_templates` (
+  `id` int(11) NOT NULL,
+  `name` varchar(50) NOT NULL,
+  `app_code` varchar(50) NOT NULL,
+  `memo` varchar(50) DEFAULT NULL,
+  `content` varchar(512) NOT NULL,
+  `create_time` datetime NOT NULL,
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='活动消息模板';
+
+-- 数据导出被取消选择。
+
+
+-- 导出  表 operating.o_activity_record 结构
+CREATE TABLE IF NOT EXISTS `o_activity_record` (
+  `id` bigint(20) NOT NULL,
+  `activity_id` bigint(20) NOT NULL,
+  `user_id` varchar(50) NOT NULL,
+  `create_time` datetime NOT NULL COMMENT '创建时间',
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `activity_id_user_id` (`activity_id`,`user_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='活动记录';
+
+-- 数据导出被取消选择。
+
+
+-- 导出  表 operating.o_app_module 结构
+CREATE TABLE IF NOT EXISTS `o_app_module` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT,
+  `app_code` varchar(50) NOT NULL COMMENT '应用编码',
+  `name` varchar(50) NOT NULL COMMENT '模块名称',
+  `code` varchar(50) NOT NULL COMMENT '模块编码',
+  `status` tinyint(4) NOT NULL COMMENT '状态 1开放 2关闭',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='应用模块开关管理';
+
+-- 数据导出被取消选择。
+
+
+-- 导出  表 operating.o_area 结构
+CREATE TABLE IF NOT EXISTS `o_area` (
+  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',
+  `area_code` varchar(50) DEFAULT NULL COMMENT '地区码',
+  `area_name` varchar(50) DEFAULT NULL COMMENT '区域名称',
+  `area_parent_code` varchar(50) DEFAULT NULL COMMENT '上级区域编码',
+  `area_type` varchar(50) DEFAULT NULL COMMENT '区域类型 1国家2省3市4区5街道',
+  PRIMARY KEY (`id`) USING BTREE,
+  UNIQUE KEY `area_code` (`area_code`) USING BTREE,
+  KEY `idx_area_type` (`area_type`) USING BTREE,
+  KEY `idx_area_parent_code` (`area_parent_code`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='省市区关系表';
+
+-- 数据导出被取消选择。
+
+
+-- 导出  表 operating.o_conversion 结构
+CREATE TABLE IF NOT EXISTS `o_conversion` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `app_code` varchar(50) NOT NULL COMMENT '应用编号',
+  `name` varchar(50) NOT NULL COMMENT '兑换活动名称',
+  `head_code` varchar(50) NOT NULL COMMENT '前缀码',
+  `code_num` int(11) NOT NULL COMMENT '兑换码可兑换次数',
+  `user_num` int(11) NOT NULL COMMENT '用户可领次数',
+  `total_num` int(11) NOT NULL COMMENT '总发行个数',
+  `status` int(11) NOT NULL COMMENT '状态 1正常 2禁用',
+  `start_time` datetime NOT NULL COMMENT '开始时间',
+  `end_time` datetime NOT NULL COMMENT '结束时间',
+  `create_time` datetime NOT NULL COMMENT '创建时间',
+  `create_user` varchar(50) NOT NULL COMMENT '创建人',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='兑换方案';
+
+-- 数据导出被取消选择。
+
+
+-- 导出  表 operating.o_conversion_code 结构
+CREATE TABLE IF NOT EXISTS `o_conversion_code` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `code` varchar(50) NOT NULL,
+  `batch_code` varchar(1) NOT NULL COMMENT '批次编码',
+  `conversion_id` int(11) NOT NULL,
+  `status` int(11) NOT NULL COMMENT '状态 1待兑换 2部分兑换 3兑换完',
+  `total_num` int(11) NOT NULL COMMENT '允许兑换次数',
+  `used_num` int(11) NOT NULL DEFAULT '0' COMMENT '已兑换次数',
+  `create_time` datetime NOT NULL,
+  `used_time` datetime DEFAULT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `code_conversion_id` (`code`,`conversion_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='兑换码表';
+
+-- 数据导出被取消选择。
+
+
+-- 导出  表 operating.o_conversion_prize 结构
+CREATE TABLE IF NOT EXISTS `o_conversion_prize` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `conversion_id` int(11) NOT NULL COMMENT '抽奖id',
+  `menu_id` bigint(20) NOT NULL COMMENT '菜单道具id(对应游戏内道具)',
+  `name` varchar(50) NOT NULL COMMENT '道具名',
+  `num` int(11) NOT NULL DEFAULT '1' COMMENT '道具数量',
+  `create_time` datetime NOT NULL COMMENT '创建时间',
+  `create_name` varchar(50) NOT NULL COMMENT '创建人',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='抽奖奖品表';
+
+-- 数据导出被取消选择。
+
+
+-- 导出  表 operating.o_conversion_record 结构
+CREATE TABLE IF NOT EXISTS `o_conversion_record` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `code` varchar(50) NOT NULL COMMENT '兑换码',
+  `code_id` int(11) NOT NULL COMMENT '兑换码id',
+  `conversion_id` int(11) NOT NULL COMMENT '兑换活动id',
+  `user_id` varchar(50) NOT NULL COMMENT '用户id',
+  `user_name` varchar(50) NOT NULL COMMENT '兑换人冗余',
+  `used_time` datetime NOT NULL COMMENT '兑换时间',
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `code_id` (`code_id`,`user_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='兑换记录';
+
+-- 数据导出被取消选择。
+
+
+-- 导出  表 operating.o_error_code 结构
+CREATE TABLE IF NOT EXISTS `o_error_code` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `return_code` varchar(50) NOT NULL COMMENT '返回结果码',
+  `return_msg` varchar(50) NOT NULL COMMENT '返回结果消息',
+  `ret_code` varchar(50) NOT NULL COMMENT '内部系统结果码',
+  `ret_msg` varchar(50) NOT NULL COMMENT '内部系统结果消息',
+  `interface_id` int(11) NOT NULL COMMENT '接口id',
+  `interface_path` varchar(50) NOT NULL COMMENT '接口名',
+  `create_name` varchar(50) NOT NULL COMMENT '创建人',
+  `update_name` varchar(50) DEFAULT NULL COMMENT '更新人',
+  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+  `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+  PRIMARY KEY (`id`) USING BTREE,
+  UNIQUE KEY `return_code` (`return_code`) USING BTREE,
+  UNIQUE KEY `interface_path` (`interface_path`,`ret_code`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='错误码管理';
+
+-- 数据导出被取消选择。
+
+
+-- 导出  表 operating.o_feedback 结构
+CREATE TABLE IF NOT EXISTS `o_feedback` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
+  `user_id` varchar(50) NOT NULL COMMENT '用户ID',
+  `app_code` varchar(50) NOT NULL COMMENT '应用编号',
+  `file_path` varchar(256) NOT NULL COMMENT '文件路径',
+  `content` varchar(1024) DEFAULT NULL COMMENT '反馈内容,语音转文字',
+  `status` tinyint(2) NOT NULL DEFAULT '0' COMMENT '处理状态 0-未处理  1-已处理 2已处理已发奖励',
+  `remark` varchar(256) DEFAULT NULL COMMENT '备注信息',
+  `gmt_create` datetime DEFAULT CURRENT_TIMESTAMP,
+  `gmt_update` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (`id`),
+  KEY `Index_1` (`user_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='意见反馈';
+
+-- 数据导出被取消选择。
+
+
+-- 导出  表 operating.o_interfaces 结构
+CREATE TABLE IF NOT EXISTS `o_interfaces` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `api_name` varchar(64) NOT NULL COMMENT '接口名称',
+  `return_code_translate` int(64) NOT NULL COMMENT '返回结果转译 0 不转义 1转义',
+  `api_remark` varchar(64) NOT NULL COMMENT 'API中文名称',
+  `api_memo` varchar(255) DEFAULT NULL COMMENT 'API描述',
+  `service_name` varchar(64) DEFAULT NULL COMMENT '服务名',
+  `service_path` varchar(64) NOT NULL COMMENT '服务路径',
+  `service_type` varchar(64) DEFAULT NULL COMMENT '服务类型',
+  `connection_timeout` varchar(64) DEFAULT NULL COMMENT '连接超时时间',
+  `so_timeout` varchar(64) DEFAULT NULL COMMENT '读取数据超时时间',
+  `module_id` varchar(64) NOT NULL COMMENT '模块ID',
+  `module_name` varchar(64) NOT NULL COMMENT '模块名称',
+  `authorize_type` int(11) NOT NULL DEFAULT '1' COMMENT '登录授权类型(0.无需,1.需要)',
+  `merchant_authorize_type` int(11) NOT NULL DEFAULT '0' COMMENT '商户所有权认证(0.无需,1.需要)',
+  `status` int(11) NOT NULL DEFAULT '1' COMMENT '状态 0未启用 1正常 2禁用',
+  `request_json` varchar(512) NOT NULL COMMENT '请求json',
+  `request_json_demo` varchar(512) NOT NULL COMMENT '请求json例子',
+  `response_json` varchar(512) NOT NULL COMMENT '响应json',
+  `response_json_demo` varchar(512) NOT NULL COMMENT '响应json例子',
+  `create_name` varchar(64) NOT NULL COMMENT '创建人',
+  `update_name` varchar(64) DEFAULT NULL COMMENT '更新人',
+  `create_time` datetime NOT NULL COMMENT '创建时间',
+  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
+  PRIMARY KEY (`id`) USING BTREE,
+  UNIQUE KEY `service_path` (`service_path`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='接口管理';
+
+-- 数据导出被取消选择。
+
+
+-- 导出  表 operating.o_interface_pmt 结构
+CREATE TABLE IF NOT EXISTS `o_interface_pmt` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `itfc_id` varchar(50) NOT NULL COMMENT '接口id',
+  `param` varchar(50) NOT NULL COMMENT '参数',
+  `param_name` varchar(50) NOT NULL COMMENT '参数名称',
+  `data_type` varchar(50) NOT NULL COMMENT '数据类型 0varchar 1int 2date 3object',
+  `ismust` varchar(50) NOT NULL COMMENT '是否必须有值 0可为空 1不为空',
+  `length` varchar(50) NOT NULL COMMENT '长度',
+  `remark` varchar(50) NOT NULL COMMENT '备注',
+  `paramType` int(11) NOT NULL COMMENT '请求参数类型(0.请求参数,1.返回参数)',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='接口参数';
+
+-- 数据导出被取消选择。
+
+
+-- 导出  表 operating.o_lottery 结构
+CREATE TABLE IF NOT EXISTS `o_lottery` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `app_code` varchar(50) NOT NULL COMMENT 'app编码',
+  `name` varchar(50) NOT NULL COMMENT '名称',
+  `status` int(11) NOT NULL COMMENT '状态1正常 2停用',
+  `cost_free_num` int(11) NOT NULL COMMENT '每日免费次数',
+  `vip_cost_free_num` int(11) NOT NULL COMMENT 'VIP每日免费次数',
+  `gold_type` int(11) NOT NULL COMMENT '消耗代币类型 1=金币,2=能量币',
+  `gold` int(11) NOT NULL COMMENT '每次抽奖消耗代币数',
+  `ten_gold` int(11) NOT NULL COMMENT '10次抽奖消耗代币数',
+  `start_time` datetime NOT NULL COMMENT '开始时间',
+  `end_time` datetime NOT NULL COMMENT '结束时间',
+  `create_time` datetime NOT NULL COMMENT '创建时间',
+  `create_name` varchar(50) NOT NULL COMMENT '创建人',
+  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
+  `update_name` varchar(50) DEFAULT NULL COMMENT '更新人',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='抽奖表(目前只支持转盘抽奖类型)';
+
+-- 数据导出被取消选择。
+
+
+-- 导出  表 operating.o_lottery_prize 结构
+CREATE TABLE IF NOT EXISTS `o_lottery_prize` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `lottery_id` int(11) NOT NULL COMMENT '抽奖id',
+  `menu_id` bigint(20) NOT NULL COMMENT '菜单道具id(对应游戏内道具)',
+  `type` int(11) NOT NULL COMMENT '奖品类型: 1、普通 2、10次必中',
+  `group_id` int(11) NOT NULL COMMENT '组',
+  `weight` int(11) NOT NULL COMMENT '权重(命中概率为 权重/同组权重之和)',
+  `name` varchar(50) NOT NULL COMMENT '道具昵称',
+  `icon` varchar(50) NOT NULL COMMENT '道具icon(梦想:填类型)',
+  `memo` varchar(50) NOT NULL COMMENT '道具属性说明',
+  `num` int(11) NOT NULL DEFAULT '1' COMMENT '道具数量',
+  `replace_id` int(11) DEFAULT '1' COMMENT '替换的奖品id',
+  `replace_menu_id` bigint(20) DEFAULT NULL COMMENT '替代菜单道具id(当对应道具已拥有时转换为替代商品)',
+  `replace_num` int(11) DEFAULT '1' COMMENT '替代道具数量',
+  `seq` int(11) NOT NULL DEFAULT '1' COMMENT '排序',
+  `is_show` int(11) NOT NULL DEFAULT '1' COMMENT '显示 1显示 2隐藏',
+  `hint` varchar(50) DEFAULT NULL COMMENT '提示文本',
+  `create_time` datetime NOT NULL COMMENT '创建时间',
+  `create_name` varchar(50) NOT NULL COMMENT '创建人',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='抽奖奖品表';
+
+-- 数据导出被取消选择。
+
+
+-- 导出  表 operating.o_lottery_record 结构
+CREATE TABLE IF NOT EXISTS `o_lottery_record` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT,
+  `user_id` varchar(50) NOT NULL,
+  `lottery_id` int(11) NOT NULL,
+  `prize_ids` varchar(512) NOT NULL COMMENT '多个id 使用,分割',
+  `status` int(11) NOT NULL COMMENT '状态 1未领奖 2已领奖',
+  `create_time` datetime NOT NULL,
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='领奖记录表';
+
+-- 数据导出被取消选择。
+
+
+-- 导出  表 operating.o_module 结构
+CREATE TABLE IF NOT EXISTS `o_module` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `module_name` varchar(50) NOT NULL COMMENT '模块名称',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='业务模块';
+
+-- 数据导出被取消选择。
+
+
+-- 导出  表 operating.o_notice 结构
+CREATE TABLE IF NOT EXISTS `o_notice` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `app_code` varchar(50) NOT NULL COMMENT '应用编码',
+  `content` varchar(512) DEFAULT NULL COMMENT '文字内容',
+  `pic` varchar(256) DEFAULT NULL COMMENT '图片内容',
+  `voice` varchar(256) DEFAULT NULL COMMENT '音频内容',
+  `app_version` varchar(50) DEFAULT NULL COMMENT 'app版本号',
+  `type` tinyint(4) NOT NULL COMMENT '类型 1滚屏公告 2登录公告',
+  `seq` int(11) NOT NULL COMMENT '排序',
+  `interval_time` int(11) NOT NULL DEFAULT '10' COMMENT '间隔时间 单位 秒',
+  `num` int(11) NOT NULL DEFAULT '1' COMMENT '播放次数',
+  `status` tinyint(4) NOT NULL COMMENT '状态 1正常 2禁用',
+  `start_time` datetime NOT NULL COMMENT '开始时间',
+  `end_time` datetime NOT NULL COMMENT '结束时间',
+  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+  `create_user` varchar(50) NOT NULL COMMENT '创建人',
+  `update_user` varchar(50) DEFAULT NULL COMMENT '更新人',
+  `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='公告';
+
+-- 数据导出被取消选择。
+
+
+-- 导出  表 operating.o_school 结构
+CREATE TABLE IF NOT EXISTS `o_school` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `type` int(11) NOT NULL COMMENT '类型 0幼儿园 1小学 2中学 3大学、高校',
+  `name` varchar(128) NOT NULL COMMENT '名字',
+  `province` varchar(50) DEFAULT NULL COMMENT '省份',
+  `city` varchar(50) DEFAULT NULL COMMENT '城市',
+  `county` varchar(50) DEFAULT NULL COMMENT '区县',
+  `street` varchar(128) DEFAULT NULL COMMENT '街道',
+  `address` varchar(255) DEFAULT NULL COMMENT '地址',
+  `phone` varchar(255) DEFAULT NULL COMMENT '电话',
+  `zip_code` varchar(50) DEFAULT NULL COMMENT '邮编',
+  `area_code` varchar(50) DEFAULT NULL COMMENT '地区码',
+  PRIMARY KEY (`id`) USING BTREE,
+  KEY `type` (`type`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='学校数据';
+
+-- 数据导出被取消选择。
+
+
+-- 导出  表 operating.o_station 结构
+CREATE TABLE IF NOT EXISTS `o_station` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT,
+  `mcc` int(11) NOT NULL COMMENT 'mcc国家代码:中国代码 460',
+  `mnc` int(11) NOT NULL COMMENT 'mnc网络类型:0移动,1联通(电信对应sid),十进制',
+  `lac` int(11) NOT NULL COMMENT 'lac(电信对应nid),十进制',
+  `ci` int(11) NOT NULL COMMENT 'cellid(电信对应bid),十进制',
+  `radius` int(11) DEFAULT NULL COMMENT '范围',
+  `lat` double DEFAULT NULL COMMENT '纬度',
+  `lon` double DEFAULT NULL COMMENT '经度',
+  `address` varchar(512) DEFAULT NULL COMMENT '地址',
+  `ret` varchar(1024) NOT NULL COMMENT '请求原始结果',
+  PRIMARY KEY (`id`) USING BTREE,
+  UNIQUE KEY `mcc` (`mcc`,`ci`,`mnc`,`lac`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='基站信息';
+
+-- 数据导出被取消选择。
+
+
+-- 导出  表 operating.o_yc_school 结构
+CREATE TABLE IF NOT EXISTS `o_yc_school` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `stageId` int(11) NOT NULL COMMENT '类型 1小学 2中学 3高中',
+  `name` varchar(128) NOT NULL COMMENT '名字',
+  `address` varchar(512) COMMENT '地址',
+  `status` tinyint(4) DEFAULT '1' COMMENT '状态 1正常 2待审核',
+  `x` decimal(10,6) DEFAULT NULL COMMENT 'x',
+  `y` decimal(10,6) DEFAULT NULL COMMENT 'y',
+  `geo` varchar(128) DEFAULT NULL COMMENT 'geo',
+  `area_code` varchar(50) NOT NULL COMMENT '地区码',
+  `create_time` datetime NOT NULL COMMENT '创建时间',
+  `create_user_id` varchar(50) DEFAULT NULL COMMENT '创建人id',
+  PRIMARY KEY (`id`) USING BTREE,
+  KEY `type` (`stageId`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='学校数据';
+
+-- 数据导出被取消选择。
+/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;
+/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;

+ 485 - 0
mall-service/src/test/resources/operating20201027pro.sql

@@ -0,0 +1,485 @@
+-- --------------------------------------------------------
+-- 主机:                           sh-cdb-aibedpzc.sql.tencentcdb.com
+-- 服务器版本:                        5.7.18-txsql-log - 20190203
+-- 服务器操作系统:                      Linux
+-- HeidiSQL 版本:                  9.3.0.4984
+-- --------------------------------------------------------
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET NAMES utf8mb4 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+
+-- 导出  表 operating.o_activity 结构
+CREATE TABLE IF NOT EXISTS `o_activity` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT,
+  `app_code` varchar(50) NOT NULL COMMENT '应用编号',
+  `name` varchar(50) NOT NULL COMMENT '活动名称',
+  `colour` varchar(50) DEFAULT NULL COMMENT '颜色',
+  `activity_describe` varchar(255) DEFAULT NULL COMMENT '活动描述',
+  `title` varchar(255) DEFAULT NULL COMMENT '二维码标题',
+  `pic` varchar(255) DEFAULT NULL COMMENT '活动图片',
+  `pre_pic` varchar(255) DEFAULT NULL COMMENT '活动前展示图片',
+  `audio_url` varchar(255) DEFAULT NULL COMMENT '音频文件',
+  `conversion_ids` varchar(255) DEFAULT NULL COMMENT '激活码ids',
+  `screen_pic` varchar(255) DEFAULT NULL COMMENT '弹屏图片',
+  `link` varchar(255) DEFAULT NULL COMMENT '链接   vip:购买vip  focus:关注公众号',
+  `screen` tinyint(4) NOT NULL COMMENT '弹屏 0不需要弹屏 1需要弹屏',
+  `seq` int(11) NOT NULL DEFAULT '1' COMMENT '排序',
+  `type` tinyint(4) NOT NULL COMMENT '活动类型 1普通活动 2特殊活动',
+  `status` tinyint(4) NOT NULL COMMENT '状态 1进行中 2停用',
+  `in_type` tinyint(4) NOT NULL COMMENT '活动准入类型 1所有玩家 2非关玩家 3非VIP玩家 4非关非VIP玩家',
+  `accomplish_type` tinyint(4) NOT NULL COMMENT '完成类型 1VIP 2关注公众号 3 VIP和关注公众号',
+  `start_time` datetime NOT NULL COMMENT '开始时间',
+  `end_time` datetime NOT NULL COMMENT '结束时间',
+  `create_time` datetime NOT NULL COMMENT '创建时间',
+  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
+  `create_name` varchar(50) NOT NULL COMMENT '创建人',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='活动表';
+
+-- 数据导出被取消选择。
+
+
+-- 导出  表 operating.o_activity_item 结构
+CREATE TABLE IF NOT EXISTS `o_activity_item` (
+  `id` bigint(20) NOT NULL,
+  `activity_id` bigint(20) NOT NULL,
+  `gift_id` bigint(20) NOT NULL COMMENT '礼品id',
+  `gift_name` varchar(50) NOT NULL COMMENT '礼品名称',
+  `gift_pic` varchar(255) DEFAULT NULL COMMENT '礼品图片',
+  `num` int(11) NOT NULL COMMENT '个数',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='活动奖品列表';
+
+-- 数据导出被取消选择。
+
+
+-- 导出  表 operating.o_activity_message 结构
+CREATE TABLE IF NOT EXISTS `o_activity_message` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT,
+  `user_id` varchar(50) NOT NULL,
+  `app_code` varchar(50) NOT NULL COMMENT '应用编码',
+  `activity_id` bigint(20) NOT NULL COMMENT '活动id 系统赠送默认-1 客服赠送 -2',
+  `type` tinyint(4) NOT NULL COMMENT '消息类型 1活动赠送 2活动参加 3活动进度 3系统赠送 4客服赠送',
+  `status` tinyint(4) NOT NULL COMMENT '状态 1未读 2已读',
+  `title` varchar(50) NOT NULL COMMENT '标题',
+  `content` varchar(255) CHARACTER SET utf8mb4 NOT NULL COMMENT '消息内容',
+  `create_time` datetime NOT NULL COMMENT '创建时间',
+  `read_time` datetime DEFAULT NULL COMMENT '读取时间',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='活动消息';
+
+-- 数据导出被取消选择。
+
+
+-- 导出  表 operating.o_activity_message_templates 结构
+CREATE TABLE IF NOT EXISTS `o_activity_message_templates` (
+  `id` int(11) NOT NULL,
+  `name` varchar(50) NOT NULL,
+  `app_code` varchar(50) NOT NULL,
+  `memo` varchar(50) DEFAULT NULL,
+  `content` varchar(512) NOT NULL,
+  `create_time` datetime NOT NULL,
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='活动消息模板';
+
+-- 数据导出被取消选择。
+
+
+-- 导出  表 operating.o_activity_prize 结构
+CREATE TABLE IF NOT EXISTS `o_activity_prize` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT,
+  `activity_id` bigint(20) NOT NULL,
+  `menu_id` bigint(20) NOT NULL COMMENT '礼品id',
+  `name` varchar(50) NOT NULL COMMENT '礼品名称',
+  `icon` varchar(255) DEFAULT NULL COMMENT '礼品图片',
+  `num` int(11) NOT NULL COMMENT '个数',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='活动奖品列表';
+
+-- 数据导出被取消选择。
+
+
+-- 导出  表 operating.o_activity_record 结构
+CREATE TABLE IF NOT EXISTS `o_activity_record` (
+  `id` bigint(20) NOT NULL,
+  `activity_id` bigint(20) NOT NULL,
+  `user_id` varchar(50) NOT NULL,
+  `create_time` datetime NOT NULL COMMENT '创建时间',
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `activity_id_user_id` (`activity_id`,`user_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='活动记录';
+
+-- 数据导出被取消选择。
+
+
+-- 导出  表 operating.o_app_module 结构
+CREATE TABLE IF NOT EXISTS `o_app_module` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT,
+  `app_code` varchar(50) NOT NULL COMMENT '应用编码',
+  `name` varchar(50) NOT NULL COMMENT '模块名称',
+  `code` varchar(50) NOT NULL COMMENT '模块编码',
+  `status` tinyint(4) NOT NULL COMMENT '状态 1开放 2关闭',
+  `version` varchar(50) NOT NULL DEFAULT '1.0.0' COMMENT '开放版本',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='应用模块开关管理';
+
+-- 数据导出被取消选择。
+
+
+-- 导出  表 operating.o_area 结构
+CREATE TABLE IF NOT EXISTS `o_area` (
+  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',
+  `area_code` varchar(50) DEFAULT NULL COMMENT '地区码',
+  `area_name` varchar(50) DEFAULT NULL COMMENT '区域名称',
+  `area_parent_code` varchar(50) DEFAULT NULL COMMENT '上级区域编码',
+  `area_type` varchar(50) DEFAULT NULL COMMENT '区域类型 1国家2省3市4区5街道',
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `area_code` (`area_code`),
+  KEY `idx_area_type` (`area_type`),
+  KEY `idx_area_parent_code` (`area_parent_code`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='省市区关系表';
+
+-- 数据导出被取消选择。
+
+
+-- 导出  表 operating.o_conversion 结构
+CREATE TABLE IF NOT EXISTS `o_conversion` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `app_code` varchar(50) NOT NULL COMMENT '应用编号',
+  `name` varchar(50) NOT NULL COMMENT '兑换活动名称',
+  `head_code` varchar(50) NOT NULL COMMENT '前缀码',
+  `code_num` int(11) NOT NULL COMMENT '兑换码可兑换次数',
+  `user_num` int(11) NOT NULL COMMENT '用户可领次数',
+  `total_num` int(11) NOT NULL COMMENT '总发行个数',
+  `status` int(11) NOT NULL COMMENT '状态 1正常 2禁用',
+  `start_time` datetime NOT NULL COMMENT '开始时间',
+  `end_time` datetime NOT NULL COMMENT '结束时间',
+  `create_time` datetime NOT NULL COMMENT '创建时间',
+  `create_user` varchar(50) NOT NULL COMMENT '创建人',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='兑换方案';
+
+-- 数据导出被取消选择。
+
+
+-- 导出  表 operating.o_conversion_code 结构
+CREATE TABLE IF NOT EXISTS `o_conversion_code` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `code` varchar(50) NOT NULL,
+  `batch_code` varchar(1) NOT NULL COMMENT '批次编码',
+  `conversion_id` int(11) NOT NULL,
+  `status` int(11) NOT NULL COMMENT '状态 1待兑换 2部分兑换 3兑换完',
+  `total_num` int(11) NOT NULL COMMENT '允许兑换次数',
+  `used_num` int(11) NOT NULL DEFAULT '0' COMMENT '已兑换次数',
+  `create_time` datetime NOT NULL,
+  `used_time` datetime DEFAULT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `code_conversion_id` (`code`,`conversion_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='兑换码表';
+
+-- 数据导出被取消选择。
+
+
+-- 导出  表 operating.o_conversion_prize 结构
+CREATE TABLE IF NOT EXISTS `o_conversion_prize` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `conversion_id` int(11) NOT NULL COMMENT '抽奖id',
+  `menu_id` bigint(20) NOT NULL COMMENT '菜单道具id(对应游戏内道具)',
+  `name` varchar(50) NOT NULL COMMENT '道具名',
+  `num` int(11) NOT NULL DEFAULT '1' COMMENT '道具数量',
+  `create_time` datetime NOT NULL COMMENT '创建时间',
+  `create_name` varchar(50) NOT NULL COMMENT '创建人',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='抽奖奖品表';
+
+-- 数据导出被取消选择。
+
+
+-- 导出  表 operating.o_conversion_record 结构
+CREATE TABLE IF NOT EXISTS `o_conversion_record` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `code` varchar(50) NOT NULL COMMENT '兑换码',
+  `code_id` int(11) NOT NULL COMMENT '兑换码id',
+  `conversion_id` int(11) NOT NULL COMMENT '兑换活动id',
+  `user_id` varchar(50) NOT NULL COMMENT '用户id',
+  `user_name` varchar(50) NOT NULL COMMENT '兑换人冗余',
+  `used_time` datetime NOT NULL COMMENT '兑换时间',
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `code_id` (`code_id`,`user_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='兑换记录';
+
+-- 数据导出被取消选择。
+
+
+-- 导出  表 operating.o_error_code 结构
+CREATE TABLE IF NOT EXISTS `o_error_code` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `return_code` varchar(50) NOT NULL COMMENT '返回结果码',
+  `return_msg` varchar(50) NOT NULL COMMENT '返回结果消息',
+  `ret_code` varchar(50) NOT NULL COMMENT '内部系统结果码',
+  `ret_msg` varchar(50) NOT NULL COMMENT '内部系统结果消息',
+  `interface_id` int(11) NOT NULL COMMENT '接口id',
+  `interface_path` varchar(50) NOT NULL COMMENT '接口名',
+  `create_name` varchar(50) NOT NULL COMMENT '创建人',
+  `update_name` varchar(50) DEFAULT NULL COMMENT '更新人',
+  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+  `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `return_code` (`return_code`),
+  UNIQUE KEY `interface_path` (`interface_path`,`ret_code`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='错误码管理';
+
+-- 数据导出被取消选择。
+
+
+-- 导出  表 operating.o_feedback 结构
+CREATE TABLE IF NOT EXISTS `o_feedback` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
+  `user_id` varchar(50) NOT NULL COMMENT '用户ID',
+  `app_code` varchar(50) NOT NULL COMMENT '应用编号',
+  `file_path` varchar(256) NOT NULL COMMENT '文件路径',
+  `content` varchar(1024) DEFAULT NULL COMMENT '反馈内容,语音转文字',
+  `status` tinyint(2) NOT NULL DEFAULT '0' COMMENT '处理状态 0-未处理 1-已处理 2已处理已发奖励',
+  `remark` varchar(256) DEFAULT NULL COMMENT '备注信息',
+  `gmt_create` datetime DEFAULT CURRENT_TIMESTAMP,
+  `gmt_update` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  PRIMARY KEY (`id`),
+  KEY `Index_1` (`user_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='意见反馈';
+
+-- 数据导出被取消选择。
+
+
+-- 导出  表 operating.o_interfaces 结构
+CREATE TABLE IF NOT EXISTS `o_interfaces` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `api_name` varchar(64) NOT NULL COMMENT '接口名称',
+  `return_code_translate` int(64) NOT NULL COMMENT '返回结果转译 0 不转义 1转义',
+  `api_remark` varchar(64) NOT NULL COMMENT 'API中文名称',
+  `api_memo` varchar(255) DEFAULT NULL COMMENT 'API描述',
+  `service_name` varchar(64) DEFAULT NULL COMMENT '服务名',
+  `service_path` varchar(64) NOT NULL COMMENT '服务路径',
+  `service_type` varchar(64) DEFAULT NULL COMMENT '服务类型',
+  `connection_timeout` varchar(64) DEFAULT NULL COMMENT '连接超时时间',
+  `so_timeout` varchar(64) DEFAULT NULL COMMENT '读取数据超时时间',
+  `module_id` varchar(64) NOT NULL COMMENT '模块ID',
+  `module_name` varchar(64) NOT NULL COMMENT '模块名称',
+  `authorize_type` int(11) NOT NULL DEFAULT '1' COMMENT '登录授权类型(0.无需,1.需要)',
+  `merchant_authorize_type` int(11) NOT NULL DEFAULT '0' COMMENT '商户所有权认证(0.无需,1.需要)',
+  `status` int(11) NOT NULL DEFAULT '1' COMMENT '状态 0未启用 1正常 2禁用',
+  `request_json` varchar(512) NOT NULL COMMENT '请求json',
+  `request_json_demo` varchar(512) NOT NULL COMMENT '请求json例子',
+  `response_json` varchar(512) NOT NULL COMMENT '响应json',
+  `response_json_demo` varchar(512) NOT NULL COMMENT '响应json例子',
+  `create_name` varchar(64) NOT NULL COMMENT '创建人',
+  `update_name` varchar(64) DEFAULT NULL COMMENT '更新人',
+  `create_time` datetime NOT NULL COMMENT '创建时间',
+  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `service_path` (`service_path`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='接口管理';
+
+-- 数据导出被取消选择。
+
+
+-- 导出  表 operating.o_interface_pmt 结构
+CREATE TABLE IF NOT EXISTS `o_interface_pmt` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `itfc_id` varchar(50) NOT NULL COMMENT '接口id',
+  `param` varchar(50) NOT NULL COMMENT '参数',
+  `param_name` varchar(50) NOT NULL COMMENT '参数名称',
+  `data_type` varchar(50) NOT NULL COMMENT '数据类型 0varchar 1int 2date 3object',
+  `ismust` varchar(50) NOT NULL COMMENT '是否必须有值 0可为空 1不为空',
+  `length` varchar(50) NOT NULL COMMENT '长度',
+  `remark` varchar(50) NOT NULL COMMENT '备注',
+  `paramType` int(11) NOT NULL COMMENT '请求参数类型(0.请求参数,1.返回参数)',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='接口参数';
+
+-- 数据导出被取消选择。
+
+
+-- 导出  表 operating.o_lottery 结构
+CREATE TABLE IF NOT EXISTS `o_lottery` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `app_code` varchar(50) NOT NULL COMMENT 'app编码',
+  `name` varchar(50) NOT NULL COMMENT '名称',
+  `status` int(11) NOT NULL COMMENT '状态1正常 2停用',
+  `cost_free_num` int(11) NOT NULL COMMENT '每日免费次数',
+  `vip_cost_free_num` int(11) NOT NULL COMMENT 'VIP每日免费次数',
+  `gold_type` int(11) NOT NULL COMMENT '消耗代币类型 1=金币,2=能量币',
+  `gold` int(11) NOT NULL COMMENT '每次抽奖消耗代币数',
+  `ten_gold` int(11) NOT NULL COMMENT '10次抽奖消耗代币数',
+  `start_time` datetime NOT NULL COMMENT '开始时间',
+  `end_time` datetime NOT NULL COMMENT '结束时间',
+  `create_time` datetime NOT NULL COMMENT '创建时间',
+  `create_name` varchar(50) NOT NULL COMMENT '创建人',
+  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
+  `update_name` varchar(50) DEFAULT NULL COMMENT '更新人',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='抽奖表(目前只支持转盘抽奖类型)';
+
+-- 数据导出被取消选择。
+
+
+-- 导出  表 operating.o_lottery_prize 结构
+CREATE TABLE IF NOT EXISTS `o_lottery_prize` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `lottery_id` int(11) NOT NULL COMMENT '抽奖id',
+  `menu_id` bigint(20) NOT NULL COMMENT '菜单道具id(对应游戏内道具)',
+  `type` int(11) NOT NULL COMMENT '奖品类型: 1、普通 2、10次必中',
+  `group_id` int(11) NOT NULL COMMENT '组',
+  `weight` int(11) NOT NULL COMMENT '权重(命中概率为 权重/同组权重之和)',
+  `name` varchar(50) NOT NULL COMMENT '道具昵称',
+  `icon` varchar(50) NOT NULL COMMENT '道具icon(梦想:填类型)',
+  `memo` varchar(50) NOT NULL COMMENT '道具属性说明',
+  `num` int(11) NOT NULL DEFAULT '1' COMMENT '道具数量',
+  `replace_id` int(11) DEFAULT '1' COMMENT '替换的奖品id',
+  `replace_menu_id` bigint(20) DEFAULT NULL COMMENT '替代菜单道具id(当对应道具已拥有时转换为替代商品)',
+  `replace_num` int(11) DEFAULT '1' COMMENT '替代道具数量',
+  `seq` int(11) NOT NULL DEFAULT '1' COMMENT '排序',
+  `is_show` int(11) NOT NULL DEFAULT '1' COMMENT '显示 1显示 2隐藏',
+  `hint` varchar(50) DEFAULT NULL COMMENT '提示文本',
+  `create_time` datetime NOT NULL COMMENT '创建时间',
+  `create_name` varchar(50) NOT NULL COMMENT '创建人',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='抽奖奖品表';
+
+-- 数据导出被取消选择。
+
+
+-- 导出  表 operating.o_lottery_record 结构
+CREATE TABLE IF NOT EXISTS `o_lottery_record` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT,
+  `user_id` varchar(50) NOT NULL,
+  `lottery_id` int(11) NOT NULL,
+  `prize_ids` varchar(512) NOT NULL COMMENT '多个id 使用,分割',
+  `status` int(11) NOT NULL COMMENT '状态 1未领奖 2已领奖',
+  `create_time` datetime NOT NULL,
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='领奖记录表';
+
+-- 数据导出被取消选择。
+
+
+-- 导出  表 operating.o_module 结构
+CREATE TABLE IF NOT EXISTS `o_module` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `module_name` varchar(50) NOT NULL COMMENT '模块名称',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='业务模块';
+
+-- 数据导出被取消选择。
+
+
+-- 导出  表 operating.o_notice 结构
+CREATE TABLE IF NOT EXISTS `o_notice` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `app_code` varchar(50) NOT NULL COMMENT '应用编码',
+  `content` varchar(512) DEFAULT NULL COMMENT '文字内容',
+  `pic` varchar(256) DEFAULT NULL COMMENT '图片内容',
+  `voice` varchar(256) DEFAULT NULL COMMENT '音频内容',
+  `link` varchar(256) DEFAULT NULL COMMENT '跳转链接',
+  `app_version` varchar(50) DEFAULT NULL COMMENT 'app版本号',
+  `type` tinyint(4) NOT NULL COMMENT '类型 1滚屏公告 2登录公告 3按钮公告 ',
+  `in_type` tinyint(4) NOT NULL DEFAULT '1' COMMENT '准入类型 1所有玩家 2非关玩家 3非VIP玩家 4非关非VIP玩家',
+  `seq` int(11) NOT NULL COMMENT '排序',
+  `interval_time` int(11) NOT NULL DEFAULT '10' COMMENT '间隔时间 单位 秒',
+  `num` int(11) NOT NULL DEFAULT '1' COMMENT '播放次数',
+  `status` tinyint(4) NOT NULL COMMENT '状态 1正常 2禁用',
+  `start_time` datetime NOT NULL COMMENT '开始时间',
+  `end_time` datetime NOT NULL COMMENT '结束时间',
+  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+  `create_user` varchar(50) NOT NULL COMMENT '创建人',
+  `update_user` varchar(50) DEFAULT NULL COMMENT '更新人',
+  `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='公告';
+
+-- 数据导出被取消选择。
+
+
+-- 导出  表 operating.o_school 结构
+CREATE TABLE IF NOT EXISTS `o_school` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `type` int(11) NOT NULL COMMENT '类型 0幼儿园 1小学 2中学 3大学、高校',
+  `name` varchar(128) NOT NULL COMMENT '名字',
+  `province` varchar(50) DEFAULT NULL COMMENT '省份',
+  `city` varchar(50) DEFAULT NULL COMMENT '城市',
+  `county` varchar(50) DEFAULT NULL COMMENT '区县',
+  `street` varchar(128) DEFAULT NULL COMMENT '街道',
+  `address` varchar(255) DEFAULT NULL COMMENT '地址',
+  `phone` varchar(255) DEFAULT NULL COMMENT '电话',
+  `zip_code` varchar(50) DEFAULT NULL COMMENT '邮编',
+  `area_code` varchar(50) DEFAULT NULL COMMENT '地区码',
+  PRIMARY KEY (`id`),
+  KEY `type` (`type`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='学校数据';
+
+-- 数据导出被取消选择。
+
+
+-- 导出  表 operating.o_station 结构
+CREATE TABLE IF NOT EXISTS `o_station` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT,
+  `mcc` int(11) NOT NULL COMMENT 'mcc国家代码:中国代码 460',
+  `mnc` int(11) NOT NULL COMMENT 'mnc网络类型:0移动,1联通(电信对应sid),十进制',
+  `lac` int(11) NOT NULL COMMENT 'lac(电信对应nid),十进制',
+  `ci` int(11) NOT NULL COMMENT 'cellid(电信对应bid),十进制',
+  `radius` int(11) DEFAULT NULL COMMENT '范围',
+  `lat` double DEFAULT NULL COMMENT '纬度',
+  `lon` double DEFAULT NULL COMMENT '经度',
+  `address` varchar(512) DEFAULT NULL COMMENT '地址',
+  `ret` varchar(1024) NOT NULL COMMENT '请求原始结果',
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `mcc` (`mcc`,`ci`,`mnc`,`lac`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='基站信息';
+
+-- 数据导出被取消选择。
+
+
+-- 导出  表 operating.o_yc_school 结构
+CREATE TABLE IF NOT EXISTS `o_yc_school` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `stageId` int(11) NOT NULL COMMENT '类型 1小学 2中学 3高中',
+  `name` varchar(128) NOT NULL COMMENT '名字',
+  `address` varchar(512) DEFAULT NULL COMMENT '地址',
+  `status` tinyint(4) DEFAULT '1' COMMENT '状态 1正常 2待审核',
+  `x` decimal(10,6) DEFAULT NULL COMMENT 'x',
+  `y` decimal(10,6) DEFAULT NULL COMMENT 'y',
+  `geo` varchar(128) DEFAULT NULL COMMENT 'geo',
+  `area_code` varchar(50) NOT NULL COMMENT '地区码',
+  `create_time` datetime NOT NULL COMMENT '创建时间',
+  `create_user_id` varchar(50) DEFAULT NULL,
+  PRIMARY KEY (`id`) USING BTREE,
+  KEY `type` (`stageId`),
+  KEY `area_code` (`area_code`),
+  FULLTEXT KEY `name1` (`name`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='学校数据';
+
+-- 数据导出被取消选择。
+
+
+-- 导出  表 operating.q_examination 结构
+CREATE TABLE IF NOT EXISTS `q_examination` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT,
+  `name` varchar(50) NOT NULL COMMENT '名称',
+  `unit_id` bigint(20) NOT NULL COMMENT '单元id',
+  `unit_name` varchar(50) NOT NULL COMMENT '单元名称',
+  `vip` bigint(20) NOT NULL COMMENT 'vip解锁 0不是 1是',
+  `tm_id` bigint(20) NOT NULL COMMENT '教材id',
+  `tm_type` tinyint(4) NOT NULL COMMENT '教材类型 1通用版 2人教版 3 北师大 4苏教版 5浙教版 6沪教版 7西师大版',
+  `grade` tinyint(4) NOT NULL COMMENT '年级类型 0学龄前 1-6年级',
+  `download_url` varchar(255) NOT NULL COMMENT '下载地址',
+  `pic` varchar(255) NOT NULL COMMENT '预览图',
+  `create_time` datetime NOT NULL COMMENT '创建时间',
+  `create_name` varchar(50) NOT NULL COMMENT '创建人',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='考卷';
+
+-- 数据导出被取消选择。
+/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;
+/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;

+ 1 - 0
package.bat

@@ -0,0 +1 @@
+cmd /k mvn clean package

+ 71 - 0
pom.xml

@@ -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">
+	<modelVersion>4.0.0</modelVersion>
+    <groupId>com.txz</groupId>
+    <version>1.0.0-SNAPSHOT</version>
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+		<version>2.0.5.RELEASE</version>
+    </parent>
+
+
+    <artifactId>mall</artifactId>
+    <packaging>pom</packaging>
+	<modules>
+        <module>mall-service</module>
+		<module>mall-api</module>
+    </modules>
+
+   <dependencyManagement>
+		<dependencies>
+			<dependency>
+				<groupId>org.springframework.cloud</groupId>
+				<artifactId>spring-cloud-dependencies</artifactId>
+				<version>Finchley.SR1</version>
+				<type>pom</type>
+				<scope>import</scope>
+			</dependency>
+			<dependency>
+				<groupId>org.springframework.cloud</groupId>
+				<artifactId>spring-cloud-alibaba-dependencies</artifactId>
+				<version>0.2.2.RELEASE</version>
+				<type>pom</type>
+				<scope>import</scope>
+			</dependency>
+		</dependencies>
+	</dependencyManagement>
+	<distributionManagement>
+		<snapshotRepository>
+			<uniqueVersion>false</uniqueVersion>
+			<id>nexus-snapshots</id>
+			<name>nexus-snapshots</name>
+			<url>http://124.220.229.80:9091/repository/maven-snapshots/</url>
+			<layout>default</layout>
+		</snapshotRepository>
+
+		<repository>
+			<id>nexus-releases</id>
+			<name>nexus-releases</name>
+			<url>http://124.220.229.80:9091/repository/maven-releases/</url>
+		</repository>
+	</distributionManagement>
+
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.7.0</version>
+                <configuration>
+                    <source>1.8</source>
+                    <target>1.8</target>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>