yonge 3 years ago
commit
b8a254405d
100 changed files with 7897 additions and 0 deletions
  1. 31 0
      audio-analysis/pom.xml
  2. 13 0
      audio-analysis/src/main/java/com/yonge/audio/App.java
  3. 38 0
      audio-analysis/src/test/java/com/yonge/audio/AppTest.java
  4. 31 0
      cooleshow-auth/pom.xml
  5. 31 0
      cooleshow-cms/pom.xml
  6. 13 0
      cooleshow-cms/src/main/java/com/yonge/cooleshow/App.java
  7. 38 0
      cooleshow-cms/src/test/java/com/yonge/cooleshow/AppTest.java
  8. 31 0
      cooleshow-common/pom.xml
  9. 31 0
      cooleshow-gateway/pom.xml
  10. 29 0
      cooleshow-user/pom.xml
  11. 76 0
      cooleshow-user/user-admin/pom.xml
  12. 15 0
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/AdminApplication.java
  13. 15 0
      cooleshow-user/user-admin/src/main/resources/bootstrap-test.properties
  14. 26 0
      cooleshow-user/user-student/pom.xml
  15. 26 0
      cooleshow-user/user-teacher/pom.xml
  16. 345 0
      pom.xml
  17. 31 0
      toolset/audit-log/pom.xml
  18. 16 0
      toolset/audit-log/src/main/java/com/yonge/toolset/log/dal/dao/AuditLogDao.java
  19. 16 0
      toolset/audit-log/src/main/java/com/yonge/toolset/log/dal/dao/HistoryMessageDao.java
  20. 16 0
      toolset/audit-log/src/main/java/com/yonge/toolset/log/dal/dao/OperationLogDao.java
  21. 120 0
      toolset/audit-log/src/main/java/com/yonge/toolset/log/dal/model/AuditLog.java
  22. 164 0
      toolset/audit-log/src/main/java/com/yonge/toolset/log/dal/model/HistoryMessage.java
  23. 81 0
      toolset/audit-log/src/main/java/com/yonge/toolset/log/dal/model/OperationLog.java
  24. 158 0
      toolset/audit-log/src/main/java/com/yonge/toolset/log/interceptor/AuditLogInterceptor.java
  25. 16 0
      toolset/audit-log/src/main/java/com/yonge/toolset/log/model/AuditLogAnnotation.java
  26. 8 0
      toolset/audit-log/src/main/java/com/yonge/toolset/log/service/AuditLogService.java
  27. 16 0
      toolset/audit-log/src/main/java/com/yonge/toolset/log/service/HistoryMessageService.java
  28. 8 0
      toolset/audit-log/src/main/java/com/yonge/toolset/log/service/OperationLogService.java
  29. 23 0
      toolset/audit-log/src/main/java/com/yonge/toolset/log/service/impl/AuditLogServiceImpl.java
  30. 164 0
      toolset/audit-log/src/main/java/com/yonge/toolset/log/service/impl/HistoryMessageServiceImpl.java
  31. 23 0
      toolset/audit-log/src/main/java/com/yonge/toolset/log/service/impl/OperationLogServiceImpl.java
  32. 20 0
      toolset/audit-log/src/test/java/com/yonge/log/AuditLogServerApplication.java
  33. 87 0
      toolset/audit-log/src/test/java/com/yonge/log/test/SpringBootMongodbApplicationTests.java
  34. 6 0
      toolset/audit-log/src/test/resources/application.properties
  35. 34 0
      toolset/codegen/pom.xml
  36. 63 0
      toolset/codegen/src/main/java/com/yonge/toolset/crud/CodegenApplication.java
  37. 111 0
      toolset/codegen/src/main/java/com/yonge/toolset/crud/core/Configuration.java
  38. 144 0
      toolset/codegen/src/main/java/com/yonge/toolset/crud/core/CrudSession.java
  39. 60 0
      toolset/codegen/src/main/java/com/yonge/toolset/crud/core/CrudSessionFactory.java
  40. 93 0
      toolset/codegen/src/main/java/com/yonge/toolset/crud/core/FreemarkerTemplateEngine.java
  41. 84 0
      toolset/codegen/src/main/java/com/yonge/toolset/crud/core/GenerateConfiguration.java
  42. 59 0
      toolset/codegen/src/main/java/com/yonge/toolset/crud/core/db/ConnectionFactory.java
  43. 117 0
      toolset/codegen/src/main/java/com/yonge/toolset/crud/core/db/DatabaseIntrospector.java
  44. 127 0
      toolset/codegen/src/main/java/com/yonge/toolset/crud/core/db/model/Column.java
  45. 86 0
      toolset/codegen/src/main/java/com/yonge/toolset/crud/core/db/model/Table.java
  46. 234 0
      toolset/codegen/src/main/java/com/yonge/toolset/crud/core/generator/ModuleGenerateIntrospector.java
  47. 41 0
      toolset/codegen/src/main/java/com/yonge/toolset/crud/core/generator/module/JavaFileGenerator.java
  48. 129 0
      toolset/codegen/src/main/java/com/yonge/toolset/crud/core/generator/module/SpringGenerator.java
  49. 82 0
      toolset/codegen/src/main/java/com/yonge/toolset/crud/core/generator/module/SqlMapConfigGenerator.java
  50. 160 0
      toolset/codegen/src/main/java/com/yonge/toolset/crud/core/util/JavaBeansUtil.java
  51. 169 0
      toolset/codegen/src/main/java/com/yonge/toolset/crud/core/util/XmlUtil.java
  52. 17 0
      toolset/codegen/src/main/resources/generateConfigration.xml
  53. 10 0
      toolset/codegen/src/main/resources/template/dao.ftl
  54. 44 0
      toolset/codegen/src/main/resources/template/pojo.ftl
  55. 9 0
      toolset/codegen/src/main/resources/template/service.ftl
  56. 22 0
      toolset/codegen/src/main/resources/template/service_impl.ftl
  57. 36 0
      toolset/codegen/src/main/resources/template/spring.ftl
  58. 64 0
      toolset/codegen/src/main/resources/template/sqlmap.ftl
  59. 11 0
      toolset/codegen/src/main/resources/template/sqlmapConfig.ftl
  60. 44 0
      toolset/dynamic-datasource/pom.xml
  61. 73 0
      toolset/dynamic-datasource/src/main/java/com/yonge/toolset/datasource/DataSourceConfig.java
  62. 46 0
      toolset/dynamic-datasource/src/main/java/com/yonge/toolset/datasource/DataSourceContextHolder.java
  63. 22 0
      toolset/dynamic-datasource/src/main/java/com/yonge/toolset/datasource/DynamicRoutingDataSource.java
  64. 56 0
      toolset/dynamic-datasource/src/main/java/com/yonge/toolset/datasource/dao/DatabaseSourceDao.java
  65. 125 0
      toolset/dynamic-datasource/src/main/java/com/yonge/toolset/datasource/entity/DatabaseSource.java
  66. 36 0
      toolset/dynamic-datasource/src/main/java/com/yonge/toolset/datasource/interceptor/DataSourceInterceptor.java
  67. 61 0
      toolset/dynamic-datasource/src/main/java/com/yonge/toolset/datasource/interceptor/TenantSqlInterceptor.java
  68. 6 0
      toolset/dynamic-datasource/src/main/java/com/yonge/toolset/datasource/service/DatabaseSourceService.java
  69. 63 0
      toolset/dynamic-datasource/src/main/java/com/yonge/toolset/datasource/service/impl/DatabaseSourceServiceImpl.java
  70. 95 0
      toolset/dynamic-datasource/src/main/resources/config/mybatis/DatabaseSourceMapper.xml
  71. 30 0
      toolset/mongo-db/pom.xml
  72. 153 0
      toolset/mongo-db/src/main/java/com/yonge/toolset/mongodb/PageInfo.java
  73. 79 0
      toolset/mongo-db/src/main/java/com/yonge/toolset/mongodb/QueryInfo.java
  74. 153 0
      toolset/mongo-db/src/main/java/com/yonge/toolset/mongodb/dao/BaseDaoWithMongo.java
  75. 25 0
      toolset/mongo-db/src/main/java/com/yonge/toolset/mongodb/service/BaseServiceWithMongo.java
  76. 75 0
      toolset/mongo-db/src/main/java/com/yonge/toolset/mongodb/service/impl/BaseServiceImplWithMongo.java
  77. 35 0
      toolset/pom.xml
  78. BIN
      toolset/thirdparty-component/libs/tech-sdk-2.1.20.jar
  79. 68 0
      toolset/thirdparty-component/pom.xml
  80. 96 0
      toolset/thirdparty-component/src/main/java/com/ym/mec/thirdparty/entity/SysEmail.java
  81. 103 0
      toolset/thirdparty-component/src/main/java/com/ym/mec/thirdparty/eseal/ESealPlugin.java
  82. 65 0
      toolset/thirdparty-component/src/main/java/com/ym/mec/thirdparty/eseal/ESealPluginContext.java
  83. 177 0
      toolset/thirdparty-component/src/main/java/com/ym/mec/thirdparty/eseal/provider/BytedancePlugin.java
  84. 337 0
      toolset/thirdparty-component/src/main/java/com/ym/mec/thirdparty/eseal/provider/TsignPlugin.java
  85. 36 0
      toolset/thirdparty-component/src/main/java/com/ym/mec/thirdparty/exception/ThirdpartyException.java
  86. 128 0
      toolset/thirdparty-component/src/main/java/com/ym/mec/thirdparty/lingxinpay/ContractSignService.java
  87. 443 0
      toolset/thirdparty-component/src/main/java/com/ym/mec/thirdparty/lingxinpay/RSA.java
  88. 30 0
      toolset/thirdparty-component/src/main/java/com/ym/mec/thirdparty/message/MessageSenderPlugin.java
  89. 138 0
      toolset/thirdparty-component/src/main/java/com/ym/mec/thirdparty/message/MessageSenderPluginContext.java
  90. 127 0
      toolset/thirdparty-component/src/main/java/com/ym/mec/thirdparty/message/provider/AwSmsPlugin.java
  91. 144 0
      toolset/thirdparty-component/src/main/java/com/ym/mec/thirdparty/message/provider/CommEmailPlugin.java
  92. 256 0
      toolset/thirdparty-component/src/main/java/com/ym/mec/thirdparty/message/provider/JiguangPushPlugin.java
  93. 114 0
      toolset/thirdparty-component/src/main/java/com/ym/mec/thirdparty/message/provider/MOxintongSMSPlugin.java
  94. 124 0
      toolset/thirdparty-component/src/main/java/com/ym/mec/thirdparty/message/provider/ShiyuanSMSPlugin.java
  95. 89 0
      toolset/thirdparty-component/src/main/java/com/ym/mec/thirdparty/message/provider/YimeiSmsPlugin.java
  96. 35 0
      toolset/thirdparty-component/src/main/java/com/ym/mec/thirdparty/storage/StoragePlugin.java
  97. 43 0
      toolset/thirdparty-component/src/main/java/com/ym/mec/thirdparty/storage/StoragePluginContext.java
  98. 160 0
      toolset/thirdparty-component/src/main/java/com/ym/mec/thirdparty/storage/provider/AliyunOssStoragePlugin.java
  99. 176 0
      toolset/thirdparty-component/src/main/java/com/ym/mec/thirdparty/storage/provider/KS3StoragePlugin.java
  100. 63 0
      toolset/thirdparty-component/src/main/java/com/ym/mec/thirdparty/union/GenerateNum.java

+ 31 - 0
audio-analysis/pom.xml

@@ -0,0 +1,31 @@
+<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>
+  
+  <parent>
+    <groupId>com.yonge.cooleshow</groupId>
+    <artifactId>cooleshow</artifactId>
+    <version>1.0</version>
+  </parent>
+
+  <groupId>com.yonge.audio</groupId>
+  <artifactId>audio-analysis</artifactId>
+  <version>1.0</version>
+  <packaging>jar</packaging>
+
+  <name>audio-analysis</name>
+  <url>http://maven.apache.org</url>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.1</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+</project>

+ 13 - 0
audio-analysis/src/main/java/com/yonge/audio/App.java

@@ -0,0 +1,13 @@
+package com.yonge.audio;
+
+/**
+ * Hello world!
+ *
+ */
+public class App 
+{
+    public static void main( String[] args )
+    {
+        System.out.println( "Hello World!" );
+    }
+}

+ 38 - 0
audio-analysis/src/test/java/com/yonge/audio/AppTest.java

@@ -0,0 +1,38 @@
+package com.yonge.audio;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * Unit test for simple App.
+ */
+public class AppTest 
+    extends TestCase
+{
+    /**
+     * Create the test case
+     *
+     * @param testName name of the test case
+     */
+    public AppTest( String testName )
+    {
+        super( testName );
+    }
+
+    /**
+     * @return the suite of tests being tested
+     */
+    public static Test suite()
+    {
+        return new TestSuite( AppTest.class );
+    }
+
+    /**
+     * Rigourous Test :-)
+     */
+    public void testApp()
+    {
+        assertTrue( true );
+    }
+}

+ 31 - 0
cooleshow-auth/pom.xml

@@ -0,0 +1,31 @@
+<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>
+  
+  <parent>
+    <groupId>com.yonge.cooleshow</groupId>
+    <artifactId>cooleshow</artifactId>
+    <version>1.0</version>
+  </parent>
+
+  <groupId>com.yonge.cooleshow</groupId>
+  <artifactId>cooleshow-auth</artifactId>
+  <version>1.0</version>
+  <packaging>jar</packaging>
+
+  <name>cooleshow-auth</name>
+  <url>http://maven.apache.org</url>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.1</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+</project>

+ 31 - 0
cooleshow-cms/pom.xml

@@ -0,0 +1,31 @@
+<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>
+  
+  <parent>
+    <groupId>com.yonge.cooleshow</groupId>
+    <artifactId>cooleshow</artifactId>
+    <version>1.0</version>
+  </parent>
+
+  <groupId>com.yonge.cooleshow</groupId>
+  <artifactId>cooleshow-cms</artifactId>
+  <version>1.0</version>
+  <packaging>jar</packaging>
+
+  <name>cooleshow-cms</name>
+  <url>http://maven.apache.org</url>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.1</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+</project>

+ 13 - 0
cooleshow-cms/src/main/java/com/yonge/cooleshow/App.java

@@ -0,0 +1,13 @@
+package com.yonge.cooleshow;
+
+/**
+ * Hello world!
+ *
+ */
+public class App 
+{
+    public static void main( String[] args )
+    {
+        System.out.println( "Hello World!" );
+    }
+}

+ 38 - 0
cooleshow-cms/src/test/java/com/yonge/cooleshow/AppTest.java

@@ -0,0 +1,38 @@
+package com.yonge.cooleshow;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * Unit test for simple App.
+ */
+public class AppTest 
+    extends TestCase
+{
+    /**
+     * Create the test case
+     *
+     * @param testName name of the test case
+     */
+    public AppTest( String testName )
+    {
+        super( testName );
+    }
+
+    /**
+     * @return the suite of tests being tested
+     */
+    public static Test suite()
+    {
+        return new TestSuite( AppTest.class );
+    }
+
+    /**
+     * Rigourous Test :-)
+     */
+    public void testApp()
+    {
+        assertTrue( true );
+    }
+}

+ 31 - 0
cooleshow-common/pom.xml

@@ -0,0 +1,31 @@
+<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>
+  
+  <parent>
+    <groupId>com.yonge.cooleshow</groupId>
+    <artifactId>cooleshow</artifactId>
+    <version>1.0</version>
+  </parent>
+
+  <groupId>com.yonge.cooleshow</groupId>
+  <artifactId>cooleshow-common</artifactId>
+  <version>1.0</version>
+  <packaging>jar</packaging>
+
+  <name>cooleshow-common</name>
+  <url>http://maven.apache.org</url>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.1</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+</project>

+ 31 - 0
cooleshow-gateway/pom.xml

@@ -0,0 +1,31 @@
+<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>
+  
+  <parent>
+    <groupId>com.yonge.cooleshow</groupId>
+    <artifactId>cooleshow</artifactId>
+    <version>1.0</version>
+  </parent>
+
+  <groupId>com.yonge.cooleshow</groupId>
+  <artifactId>cooleshow-gateway</artifactId>
+  <version>1.0</version>
+  <packaging>jar</packaging>
+
+  <name>cooleshow-gateway</name>
+  <url>http://maven.apache.org</url>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.1</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+</project>

+ 29 - 0
cooleshow-user/pom.xml

@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<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>
+  
+  <parent>
+    <groupId>com.yonge.cooleshow</groupId>
+    <artifactId>cooleshow</artifactId>
+    <version>1.0</version>
+  </parent>
+
+  <groupId>com.yonge.cooleshow</groupId>
+  <artifactId>cooleshow-user</artifactId>
+  <version>1.0</version>
+  <packaging>pom</packaging>
+
+  <name>cooleshow-user</name>
+  <url>http://maven.apache.org</url>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  </properties>
+
+  <dependencies>
+  </dependencies>
+<modules>  <module>user-student</module>
+    <module>user-teacher</module>
+    <module>user-admin</module>
+  </modules>
+</project>

+ 76 - 0
cooleshow-user/user-admin/pom.xml

@@ -0,0 +1,76 @@
+<?xml version="1.0"?>
+<project
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+	xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<groupId>com.yonge.cooleshow</groupId>
+		<artifactId>cooleshow-user</artifactId>
+		<version>1.0</version>
+	</parent>
+	<groupId>com.yonge.cooleshow</groupId>
+	<artifactId>user-admin</artifactId>
+	<version>1.0</version>
+	<name>user-admin</name>
+	<url>http://maven.apache.org</url>
+	<properties>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+	</properties>
+	<dependencies>
+
+		<dependency>
+			<groupId>com.alibaba.cloud</groupId>
+			<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>com.alibaba.cloud</groupId>
+			<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>org.springframework.cloud</groupId>
+			<artifactId>spring-cloud-starter-security</artifactId>
+		</dependency>
+
+		<!-- swagger-spring-boot -->
+		<dependency>
+			<groupId>com.spring4all</groupId>
+			<artifactId>swagger-spring-boot-starter</artifactId>
+		</dependency>
+
+		<!-- <dependency>
+			<groupId>com.alibaba</groupId>
+			<artifactId>druid-spring-boot-starter</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>mysql</groupId>
+			<artifactId>mysql-connector-java</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>com.yonge.toolset</groupId>
+			<artifactId>audit-log</artifactId>
+		</dependency> -->
+
+		<dependency>
+			<groupId>com.github.whvcse</groupId>
+			<artifactId>easy-captcha</artifactId>
+			<version>1.6.2</version>
+		</dependency>
+	</dependencies>
+
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.springframework.boot</groupId>
+				<artifactId>spring-boot-maven-plugin</artifactId>
+			</plugin>
+			<plugin>
+				<groupId>com.spotify</groupId>
+				<artifactId>docker-maven-plugin</artifactId>
+			</plugin>
+		</plugins>
+	</build>
+</project>

+ 15 - 0
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/AdminApplication.java

@@ -0,0 +1,15 @@
+package com.yonge.cooleshow;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+
+@SpringBootApplication
+@EnableDiscoveryClient
+public class AdminApplication {
+
+	public static void main(String[] args) {
+        SpringApplication.run(AdminApplication.class, args);
+	}
+	
+}

+ 15 - 0
cooleshow-user/user-admin/src/main/resources/bootstrap-test.properties

@@ -0,0 +1,15 @@
+
+#\u670d\u52a1\u5668\u5730\u5740
+spring.cloud.nacos.config.server-addr=47.114.176.40:8848
+#\u9ed8\u8ba4\u4e3aPublic\u547d\u540d\u7a7a\u95f4,\u53ef\u4ee5\u7701\u7565\u4e0d\u5199
+spring.cloud.nacos.config.namespace=46f06363-b9d6-46f0-9cd7-7b33dcf26bb0
+#\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=DEFAULT_GROUP
+#\u6587\u4ef6\u540d -- \u5982\u679c\u6ca1\u6709\u914d\u7f6e\u5219\u9ed8\u8ba4\u4e3a ${spring.appliction.name}
+spring.cloud.nacos.config.prefix=admin
+#\u6307\u5b9a\u6587\u4ef6\u540e\u7f00
+spring.cloud.nacos.config.file-extension=yaml
+#\u662f\u5426\u52a8\u6001\u5237\u65b0
+spring.cloud.nacos.config.refresh.enabled=true
+#\u662f\u5426\u542f\u7528nacos\u914d\u7f6e\u4e2d\u5fc3
+spring.cloud.nacos.config.enabled=true

+ 26 - 0
cooleshow-user/user-student/pom.xml

@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>com.yonge.cooleshow</groupId>
+    <artifactId>cooleshow-user</artifactId>
+    <version>1.0</version>
+  </parent>
+  <groupId>com.yonge.cooleshow</groupId>
+  <artifactId>user-student</artifactId>
+  <version>1.0</version>
+  <name>user-student</name>
+  <url>http://maven.apache.org</url>
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  </properties>
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.1</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+</project>

+ 26 - 0
cooleshow-user/user-teacher/pom.xml

@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>com.yonge.cooleshow</groupId>
+    <artifactId>cooleshow-user</artifactId>
+    <version>1.0</version>
+  </parent>
+  <groupId>com.yonge.cooleshow</groupId>
+  <artifactId>user-teacher</artifactId>
+  <version>1.0</version>
+  <name>user-teacher</name>
+  <url>http://maven.apache.org</url>
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  </properties>
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.1</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+</project>

+ 345 - 0
pom.xml

@@ -0,0 +1,345 @@
+<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.yonge.cooleshow</groupId>
+	<artifactId>cooleshow</artifactId>
+	<version>1.0</version>
+	<packaging>pom</packaging>
+
+	<name>cooleshow</name>
+	<url>http://maven.apache.org</url>
+
+	<properties>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+		<maven.compiler.source>1.8</maven.compiler.source>
+		<maven.compiler.target>1.8</maven.compiler.target>
+		<spring-boot.version>2.1.6.RELEASE</spring-boot.version>
+		<spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
+		<zipkin.version>2.12.2</zipkin.version>
+		<google.zxing.version>3.4.0</google.zxing.version>
+	</properties>
+
+
+	<dependencyManagement>
+		<dependencies>
+			<!--֧��Spring Boot 2.1.X -->
+			<dependency>
+				<groupId>org.springframework.boot</groupId>
+				<artifactId>spring-boot-dependencies</artifactId>
+				<version>${spring-boot.version}</version>
+				<type>pom</type>
+				<scope>import</scope>
+				<exclusions>
+					<exclusion>
+						<groupId>org.springframework.boot</groupId>
+						<artifactId>spring-boot-starter-log4j2</artifactId>
+					</exclusion>
+				</exclusions>
+			</dependency>
+
+			<dependency>
+				<groupId>org.springframework.cloud</groupId>
+				<artifactId>spring-cloud-dependencies</artifactId>
+				<version>${spring-cloud.version}</version>
+				<type>pom</type>
+				<scope>import</scope>
+				<exclusions>
+					<exclusion>
+						<groupId>org.springframework.boot</groupId>
+						<artifactId>spring-boot-starter-log4j2</artifactId>
+					</exclusion>
+				</exclusions>
+			</dependency>
+
+			<dependency>
+				<groupId>de.codecentric</groupId>
+				<artifactId>spring-boot-admin-starter-client</artifactId>
+				<version>2.1.6</version>
+			</dependency>
+
+			<dependency>
+				<groupId>com.yonge.toolset</groupId>
+				<artifactId>utils</artifactId>
+				<version>1.0</version>
+			</dependency>
+
+			<dependency>
+				<groupId>com.yonge.toolset</groupId>
+				<artifactId>thirdparty-component</artifactId>
+				<version>1.0</version>
+			</dependency>
+
+			<dependency>
+				<groupId>com.yonge.toolset</groupId>
+				<artifactId>mongo-db</artifactId>
+				<version>1.0</version>
+			</dependency>
+
+			<dependency>
+				<groupId>com.yonge.toolset</groupId>
+				<artifactId>audit-log</artifactId>
+				<version>1.0</version>
+			</dependency>
+
+			<dependency>
+				<groupId>com.alibaba.cloud</groupId>
+				<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
+				<version>2.1.4.RELEASE</version>
+			</dependency>
+
+			<dependency>
+				<groupId>com.alibaba.cloud</groupId>
+				<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
+				<version>2.1.4.RELEASE</version>
+			</dependency>
+
+			<dependency>
+				<groupId>io.zipkin.java</groupId>
+				<artifactId>zipkin-server</artifactId>
+				<version>${zipkin.version}</version>
+				<!--�ų�log4j2 �����logback��ͻ���� -->
+				<exclusions>
+					<exclusion>
+						<groupId>org.springframework.boot</groupId>
+						<artifactId>spring-boot-starter-log4j2</artifactId>
+					</exclusion>
+				</exclusions>
+			</dependency>
+
+			<dependency>
+				<groupId>io.zipkin.java</groupId>
+				<artifactId>zipkin-autoconfigure-ui</artifactId>
+				<version>${zipkin.version}</version>
+			</dependency>
+
+			<!-- ʹ����Ϣ�ķ�ʽ�ռ����ݣ�ʹ��rabbitmq�� -->
+			<dependency>
+				<groupId>io.zipkin.java</groupId>
+				<artifactId>zipkin-autoconfigure-collector-rabbitmq</artifactId>
+				<version>${zipkin.version}</version>
+			</dependency>
+
+			<!-- ���� elasticsearch �洢���� -->
+			<dependency>
+				<groupId>io.zipkin.java</groupId>
+				<artifactId>zipkin-autoconfigure-storage-elasticsearch-http</artifactId>
+				<version>2.8.4</version>
+			</dependency>
+
+			<!-- swagger-spring-boot -->
+			<dependency>
+				<groupId>com.spring4all</groupId>
+				<artifactId>swagger-spring-boot-starter</artifactId>
+				<version>1.9.0.RELEASE</version>
+			</dependency>
+
+			<dependency>
+				<groupId>com.github.xiaoymin</groupId>
+				<artifactId>swagger-bootstrap-ui</artifactId>
+				<version>1.9.5</version>
+			</dependency>
+
+			<dependency>
+				<groupId>com.alibaba</groupId>
+				<artifactId>druid-spring-boot-starter</artifactId>
+				<version>1.1.10</version>
+			</dependency>
+
+			<dependency>
+				<groupId>org.mybatis.spring.boot</groupId>
+				<artifactId>mybatis-spring-boot-starter</artifactId>
+				<version>1.3.2</version>
+			</dependency>
+
+			<dependency>
+				<groupId>org.springframework.social</groupId>
+				<artifactId>spring-social-security</artifactId>
+				<version>1.1.6.RELEASE</version>
+			</dependency>
+
+			<dependency>
+				<groupId>commons-beanutils</groupId>
+				<artifactId>commons-beanutils</artifactId>
+				<version>1.9.2</version>
+			</dependency>
+
+			<dependency>
+				<groupId>com.google.zxing</groupId>
+				<artifactId>core</artifactId>
+				<version>${google.zxing.version}</version>
+			</dependency>
+
+			<dependency>
+				<groupId>com.google.zxing</groupId>
+				<artifactId>javase</artifactId>
+				<version>${google.zxing.version}</version>
+			</dependency>
+
+			<dependency>
+				<groupId>com.vdurmont</groupId>
+				<artifactId>emoji-java</artifactId>
+				<version>5.1.1</version>
+			</dependency>
+
+		</dependencies>
+	</dependencyManagement>
+
+	<repositories>
+		<repository>
+			<id>spring-milestones</id>
+			<name>Spring Milestones</name>
+			<url>https://repo.spring.io/libs-milestone</url>
+			<snapshots>
+				<enabled>false</enabled>
+			</snapshots>
+		</repository>
+		<repository>
+			<id>sonatype-nexus-snapshots</id>
+			<name>Sonatype Nexus Snapshots</name>
+			<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
+			<snapshots>
+				<enabled>true</enabled>
+			</snapshots>
+			<releases>
+				<enabled>false</enabled>
+			</releases>
+		</repository>
+	</repositories>
+
+	<pluginRepositories>
+		<pluginRepository>
+			<id>repository.spring.release</id>
+			<name>Spring GA Repository</name>
+			<url>https://repo.spring.io/plugins-release/</url>
+		</pluginRepository>
+		<pluginRepository>
+			<id>jcenter-snapshots</id>
+			<name>jcenter</name>
+			<url>http://oss.jfrog.org/artifactory/oss-snapshot-local/</url>
+		</pluginRepository>
+		<pluginRepository>
+			<id>jcenter-releases</id>
+			<name>jcenter</name>
+			<url>http://jcenter.bintray.com</url>
+			<snapshots>
+				<enabled>false</enabled>
+			</snapshots>
+		</pluginRepository>
+	</pluginRepositories>
+
+	<dependencies>
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-web</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-actuator</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-test</artifactId>
+			<scope>test</scope>
+		</dependency>
+
+		<dependency>
+			<groupId>org.springframework.cloud</groupId>
+			<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
+			<exclusions>
+				<exclusion>
+					<groupId>commons-lang</groupId>
+					<artifactId>commons-lang</artifactId>
+				</exclusion>
+			</exclusions>
+		</dependency>
+	</dependencies>
+
+	<build>
+		<finalName>${project.name}</finalName>
+		<resources>
+			<resource>
+				<directory>src/main/resources</directory>
+				<filtering>true</filtering>
+				<excludes>
+					<exclude>**/*.ttf</exclude>
+					<exclude>**/*.ttc</exclude>
+				</excludes>
+			</resource>
+			<resource>
+				<directory>src/main/resources</directory>
+				<filtering>false</filtering>
+				<includes>
+					<include>**/*.ttf</include>
+					<include>**/*.ttc</include>
+				</includes>
+			</resource>
+		</resources>
+		<pluginManagement>
+			<plugins>
+				<plugin>
+					<groupId>org.springframework.boot</groupId>
+					<artifactId>spring-boot-maven-plugin</artifactId>
+					<version>${spring-boot.version}</version>
+					<configuration>
+						<finalName>${project.build.finalName}</finalName>
+						<includeSystemScope>true</includeSystemScope>
+					</configuration>
+					<executions>
+						<execution>
+							<goals>
+								<goal>repackage</goal>
+							</goals>
+						</execution>
+					</executions>
+				</plugin>
+			</plugins>
+		</pluginManagement>
+		<plugins>
+			<plugin>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>3.8.0</version>
+				<configuration>
+					<target>${maven.compiler.target}</target>
+					<source>${maven.compiler.source}</source>
+					<encoding>${project.build.sourceEncoding}</encoding>
+				</configuration>
+			</plugin>
+			<plugin>
+				<groupId>pl.project13.maven</groupId>
+				<artifactId>git-commit-id-plugin</artifactId>
+				<version>2.2.5</version>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-resources-plugin</artifactId>
+				<configuration>
+					<encoding>UTF-8</encoding>
+					<!-- 过滤后缀为pem、pfx的证书文件 -->
+					<nonFilteredFileExtensions>
+						<nonFilteredFileExtension>cer</nonFilteredFileExtension>
+						<nonFilteredFileExtension>pem</nonFilteredFileExtension>
+						<nonFilteredFileExtension>pfx</nonFilteredFileExtension>
+						<nonFilteredFileExtension>ttc</nonFilteredFileExtension>
+						<nonFilteredFileExtension>ttf</nonFilteredFileExtension>
+						<nonFilteredFileExtension>xls</nonFilteredFileExtension>
+						<nonFilteredFileExtension>xlsx</nonFilteredFileExtension>
+					</nonFilteredFileExtensions>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+
+	<modules>
+		<module>audio-analysis</module>
+		<module>cms</module>
+		<module>cooleshow-auth</module>
+		<module>cooleshow-common</module>
+		<module>cooleshow-gateway</module>
+		<module>cooleshow-user</module>
+		<module>toolset</module>
+	</modules>
+</project>

+ 31 - 0
toolset/audit-log/pom.xml

@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>com.yonge.toolset</groupId>
+    <artifactId>toolset</artifactId>
+    <version>1.0</version>
+  </parent>
+  <groupId>com.yonge.toolset</groupId>
+  <artifactId>audit-log</artifactId>
+  <version>1.0</version>
+  <name>audit-log</name>
+  <url>http://maven.apache.org</url>
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  </properties>
+  <dependencies>
+		<dependency>
+			<groupId>com.yonge.toolset</groupId>
+			<artifactId>mongo-db</artifactId>
+		</dependency>
+		
+		<dependency>
+			<groupId>io.swagger</groupId>
+			<artifactId>swagger-annotations</artifactId>
+			<version>1.5.20</version>
+			<scope>compile</scope>
+		</dependency>
+  </dependencies>
+</project>

+ 16 - 0
toolset/audit-log/src/main/java/com/yonge/toolset/log/dal/dao/AuditLogDao.java

@@ -0,0 +1,16 @@
+package com.yonge.toolset.log.dal.dao;
+
+import org.springframework.stereotype.Component;
+
+import com.yonge.toolset.log.dal.model.AuditLog;
+import com.yonge.toolset.mongodb.dao.BaseDaoWithMongo;
+
+@Component
+public class AuditLogDao extends BaseDaoWithMongo<String, AuditLog> {
+
+	@Override
+	public Class<AuditLog> getClassEntity() {
+		return AuditLog.class;
+	}
+
+}

+ 16 - 0
toolset/audit-log/src/main/java/com/yonge/toolset/log/dal/dao/HistoryMessageDao.java

@@ -0,0 +1,16 @@
+package com.yonge.toolset.log.dal.dao;
+
+import org.springframework.stereotype.Component;
+
+import com.yonge.toolset.log.dal.model.HistoryMessage;
+import com.yonge.toolset.mongodb.dao.BaseDaoWithMongo;
+
+@Component
+public class HistoryMessageDao extends BaseDaoWithMongo<String, HistoryMessage> {
+
+	@Override
+	public Class<HistoryMessage> getClassEntity() {
+		return HistoryMessage.class;
+	}
+
+}

+ 16 - 0
toolset/audit-log/src/main/java/com/yonge/toolset/log/dal/dao/OperationLogDao.java

@@ -0,0 +1,16 @@
+package com.yonge.toolset.log.dal.dao;
+
+import org.springframework.stereotype.Component;
+
+import com.yonge.toolset.log.dal.model.OperationLog;
+import com.yonge.toolset.mongodb.dao.BaseDaoWithMongo;
+
+@Component
+public class OperationLogDao extends BaseDaoWithMongo<String, OperationLog> {
+
+	@Override
+	public Class<OperationLog> getClassEntity() {
+		return OperationLog.class;
+	}
+
+}

+ 120 - 0
toolset/audit-log/src/main/java/com/yonge/toolset/log/dal/model/AuditLog.java

@@ -0,0 +1,120 @@
+package com.yonge.toolset.log.dal.model;
+
+import java.io.Serializable;
+
+import org.springframework.data.annotation.Id;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+@Document(collection = "sys_audit_log")
+public class AuditLog implements Serializable {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 7721535265828759275L;
+
+	@Id
+	private String id;
+
+	private String username;
+
+	private Integer userId;
+
+	private String operateName;
+
+	private String interfaceUrl;
+
+	private String inputParams;
+
+	private String operateTime;
+
+	private String userIp;
+
+	private String token;
+
+	private String service;
+
+	public Integer getUserId() {
+		return userId;
+	}
+
+	public void setUserId(Integer userId) {
+		this.userId = userId;
+	}
+
+	public String getService() {
+		return service;
+	}
+
+	public void setService(String service) {
+		this.service = service;
+	}
+
+	public static long getSerialVersionUID() {
+		return serialVersionUID;
+	}
+
+	public String getToken() {
+		return token;
+	}
+
+	public void setToken(String token) {
+		this.token = token;
+	}
+
+	public String getId() {
+		return id;
+	}
+
+	public void setId(String id) {
+		this.id = id;
+	}
+
+	public String getUsername() {
+		return username;
+	}
+
+	public void setUsername(String username) {
+		this.username = username;
+	}
+
+	public String getOperateName() {
+		return operateName;
+	}
+
+	public void setOperateName(String operateName) {
+		this.operateName = operateName;
+	}
+
+	public String getInterfaceUrl() {
+		return interfaceUrl;
+	}
+
+	public void setInterfaceUrl(String interfaceUrl) {
+		this.interfaceUrl = interfaceUrl;
+	}
+
+	public String getInputParams() {
+		return inputParams;
+	}
+
+	public void setInputParams(String inputParams) {
+		this.inputParams = inputParams;
+	}
+
+	public String getOperateTime() {
+		return operateTime;
+	}
+
+	public void setOperateTime(String operateTime) {
+		this.operateTime = operateTime;
+	}
+
+	public String getUserIp() {
+		return userIp;
+	}
+
+	public void setUserIp(String userIp) {
+		this.userIp = userIp;
+	}
+}

+ 164 - 0
toolset/audit-log/src/main/java/com/yonge/toolset/log/dal/model/HistoryMessage.java

@@ -0,0 +1,164 @@
+package com.yonge.toolset.log.dal.model;
+
+import org.springframework.data.annotation.Id;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+@Document(collection = "im_history_message")
+public class HistoryMessage implements Serializable {
+    @Id
+    private String msgUID;
+
+    private String fromUserId;
+
+    private String targetId;
+
+    private Integer targetType;
+
+    private String GroupId;
+
+    private String classname;
+
+    private String dateTime;
+
+    private String source;
+
+    private String isDiscard;
+
+    private String isSensitiveWord;
+
+    private String isForbidden;
+
+    private String isNotForward;
+
+    private String groupUserIds;
+
+    private String content;
+
+    public String getFromUserId() {
+        return fromUserId;
+    }
+
+    public void setFromUserId(String fromUserId) {
+        this.fromUserId = fromUserId;
+    }
+
+    public String getTargetId() {
+        return targetId;
+    }
+
+    public void setTargetId(String targetId) {
+        this.targetId = targetId;
+    }
+
+    public Integer getTargetType() {
+        return targetType;
+    }
+
+    public void setTargetType(Integer targetType) {
+        this.targetType = targetType;
+    }
+
+    public String getGroupId() {
+        return GroupId;
+    }
+
+    public void setGroupId(String groupId) {
+        GroupId = groupId;
+    }
+
+    public String getClassname() {
+        return classname;
+    }
+
+    public void setClassname(String classname) {
+        this.classname = classname;
+    }
+
+    public String getDateTime() {
+        return dateTime;
+    }
+
+    public void setDateTime(String dateTime) {
+        this.dateTime = dateTime;
+    }
+
+    public String getSource() {
+        return source;
+    }
+
+    public void setSource(String source) {
+        this.source = source;
+    }
+
+    public String getIsDiscard() {
+        return isDiscard;
+    }
+
+    public void setIsDiscard(String isDiscard) {
+        this.isDiscard = isDiscard;
+    }
+
+    public String getIsSensitiveWord() {
+        return isSensitiveWord;
+    }
+
+    public void setIsSensitiveWord(String isSensitiveWord) {
+        this.isSensitiveWord = isSensitiveWord;
+    }
+
+    public String getIsForbidden() {
+        return isForbidden;
+    }
+
+    public void setIsForbidden(String isForbidden) {
+        this.isForbidden = isForbidden;
+    }
+
+    public String getIsNotForward() {
+        return isNotForward;
+    }
+
+    public void setIsNotForward(String isNotForward) {
+        this.isNotForward = isNotForward;
+    }
+
+    public String getMsgUID() {
+        return msgUID;
+    }
+
+    public void setMsgUID(String msgUID) {
+        this.msgUID = msgUID;
+    }
+
+    public String getGroupUserIds() {
+        return groupUserIds;
+    }
+
+    public void setGroupUserIds(String groupUserIds) {
+        this.groupUserIds = groupUserIds;
+    }
+
+    public String getContent() {
+        return content;
+    }
+
+    public void setContent(String content) {
+        this.content = content;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        HistoryMessage that = (HistoryMessage) o;
+        return msgUID.equals(that.msgUID);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(msgUID);
+    }
+}

+ 81 - 0
toolset/audit-log/src/main/java/com/yonge/toolset/log/dal/model/OperationLog.java

@@ -0,0 +1,81 @@
+package com.yonge.toolset.log.dal.model;
+
+import org.springframework.data.annotation.Id;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+import java.io.Serializable;
+
+@Document(collection = "sys_operation_log")
+public class OperationLog implements Serializable {
+
+	@Id
+	private String id;
+
+	private String username;
+
+	private Integer userId;
+
+	private String operateName;
+
+	private String interfaceUrl;
+
+	private String operateTime;
+
+	private String token;
+
+	public Integer getUserId() {
+		return userId;
+	}
+
+	public void setUserId(Integer userId) {
+		this.userId = userId;
+	}
+
+	public String getToken() {
+		return token;
+	}
+
+	public void setToken(String token) {
+		this.token = token;
+	}
+
+	public String getId() {
+		return id;
+	}
+
+	public void setId(String id) {
+		this.id = id;
+	}
+
+	public String getUsername() {
+		return username;
+	}
+
+	public void setUsername(String username) {
+		this.username = username;
+	}
+
+	public String getOperateName() {
+		return operateName;
+	}
+
+	public void setOperateName(String operateName) {
+		this.operateName = operateName;
+	}
+
+	public String getInterfaceUrl() {
+		return interfaceUrl;
+	}
+
+	public void setInterfaceUrl(String interfaceUrl) {
+		this.interfaceUrl = interfaceUrl;
+	}
+
+	public String getOperateTime() {
+		return operateTime;
+	}
+
+	public void setOperateTime(String operateTime) {
+		this.operateTime = operateTime;
+	}
+}

+ 158 - 0
toolset/audit-log/src/main/java/com/yonge/toolset/log/interceptor/AuditLogInterceptor.java

@@ -0,0 +1,158 @@
+package com.yonge.toolset.log.interceptor;
+
+import io.swagger.annotations.ApiOperation;
+
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ThreadPoolExecutor;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+import org.springframework.web.method.HandlerMethod;
+import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
+
+import com.yonge.toolset.log.dal.model.AuditLog;
+import com.yonge.toolset.log.model.AuditLogAnnotation;
+import com.yonge.toolset.log.service.AuditLogService;
+import com.yonge.toolset.utils.json.JsonUtil;
+import com.yonge.toolset.utils.web.WebUtil;
+
+/**
+ * 日志审计的拦截器
+ */
+public class AuditLogInterceptor extends HandlerInterceptorAdapter {
+
+    @Autowired
+    private AuditLogService auditLogService;
+
+    @Value("${spring.application.name}")
+    private String clientName;
+
+    private String username;
+
+    private Integer userId;
+    
+    private String tenantId;
+
+    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+    private static List<String> ignoreLogUrl;
+
+    /**
+     * 异步线程池配置
+     */
+    @Bean("syncSaveLog")
+    public Executor asyncExecutor() {
+        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+        // 设置核心线程数
+        executor.setCorePoolSize(10);
+        // 设置最大线程数
+        executor.setMaxPoolSize(100);
+        // 设置队列容量
+        executor.setQueueCapacity(1000);
+        // 设置线程活跃时间(秒)
+        executor.setKeepAliveSeconds(60);
+        // 设置默认线程名称
+        executor.setThreadNamePrefix("syncSaveLog-");
+        // 设置拒绝策略
+        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
+        // 等待所有任务结束后再关闭线程池
+        executor.setWaitForTasksToCompleteOnShutdown(true);
+        executor.initialize();
+        return executor;
+    }
+
+
+    @Override
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException {
+        return true;
+    }
+
+    @Override
+    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
+        syncSaveLog(request, handler);
+    }
+
+    public void syncSaveLog(HttpServletRequest request, Object handler) {
+        try {
+            String servletPath = request.getServletPath();
+            HandlerMethod handlerMethod = (HandlerMethod) handler;
+            AuditLogAnnotation anno = handlerMethod.getMethodAnnotation(AuditLogAnnotation.class);
+            ApiOperation apiOperation = handlerMethod.getMethodAnnotation(ApiOperation.class);
+            String operateName = null;
+            if (StringUtils.isEmpty(operateName) && apiOperation != null) {
+                operateName = apiOperation.value();
+            }
+            if (StringUtils.isEmpty(operateName) && anno != null) {
+                operateName = anno.operateName();
+            }
+            if (anno != null) {
+                saveLog(operateName, servletPath, request);
+                return;
+            }
+            if (servletPath.contains("/task/") || servletPath.contains("/import/")) {
+                return;
+            }
+            String substring = servletPath.substring(servletPath.lastIndexOf("/") + 1).toLowerCase();
+            if (ignoreLogUrl == null) {
+                ignoreLogUrl = new ArrayList<>();
+                ignoreLogUrl.add("query");
+                ignoreLogUrl.add("get");
+                ignoreLogUrl.add("find");
+                ignoreLogUrl.add("list");
+                ignoreLogUrl.add("detail");
+                ignoreLogUrl.add("hasindexerrdata");
+                ignoreLogUrl.add("newindex");
+            }
+            for (String e : ignoreLogUrl) {
+                if (substring.contains(e)) {
+                    return;
+                }
+            }
+            saveLog(operateName, servletPath, request);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    private void saveLog(String operateName, String servletPath, HttpServletRequest request) throws IOException {
+        AuditLog auditLog = new AuditLog();
+        auditLog.setOperateName(operateName);
+        auditLog.setInterfaceUrl(servletPath);
+        auditLog.setToken(request.getHeader("Authorization"));
+        auditLog.setService(clientName);
+        auditLog.setUserIp(WebUtil.getRemoteIp(request));
+
+        Map<String, Object> params = WebUtil.getParameterMap(request);
+        if (params == null || params.size() == 0) {
+            auditLog.setInputParams(IOUtils.toString(request.getInputStream(), Charset.defaultCharset()));
+        } else {
+            auditLog.setInputParams(JsonUtil.toJSONString(WebUtil.getParameterMap(request)));
+        }
+        // 操作人
+        auditLog.setUsername(username);
+        auditLog.setUserId(userId);
+        auditLog.setOperateTime(sdf.format(new Date()));
+        auditLogService.insert(auditLog);
+    }
+
+    public void setUsername(String username, Integer userId, String tenantId) {
+        this.username = username;
+        this.userId = userId;
+        this.tenantId = tenantId;
+    }
+}

+ 16 - 0
toolset/audit-log/src/main/java/com/yonge/toolset/log/model/AuditLogAnnotation.java

@@ -0,0 +1,16 @@
+package com.yonge.toolset.log.model;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface AuditLogAnnotation {
+
+	String operateName();
+
+	String interfaceURL() default "";
+
+}

+ 8 - 0
toolset/audit-log/src/main/java/com/yonge/toolset/log/service/AuditLogService.java

@@ -0,0 +1,8 @@
+package com.yonge.toolset.log.service;
+
+import com.yonge.toolset.log.dal.model.AuditLog;
+import com.yonge.toolset.mongodb.service.BaseServiceWithMongo;
+
+public interface AuditLogService extends BaseServiceWithMongo<String, AuditLog> {
+
+}

+ 16 - 0
toolset/audit-log/src/main/java/com/yonge/toolset/log/service/HistoryMessageService.java

@@ -0,0 +1,16 @@
+package com.yonge.toolset.log.service;
+
+import java.io.File;
+
+import com.yonge.toolset.log.dal.model.HistoryMessage;
+import com.yonge.toolset.mongodb.service.BaseServiceWithMongo;
+
+public interface HistoryMessageService extends BaseServiceWithMongo<String, HistoryMessage> {
+
+    /**
+     * 保存融云历史聊天记录
+     * @param file
+     * @throws Exception
+     */
+    void saveImHistoryMessage(File file) throws Exception;
+}

+ 8 - 0
toolset/audit-log/src/main/java/com/yonge/toolset/log/service/OperationLogService.java

@@ -0,0 +1,8 @@
+package com.yonge.toolset.log.service;
+
+import com.yonge.toolset.log.dal.model.OperationLog;
+import com.yonge.toolset.mongodb.service.BaseServiceWithMongo;
+
+public interface OperationLogService extends BaseServiceWithMongo<String, OperationLog> {
+
+}

+ 23 - 0
toolset/audit-log/src/main/java/com/yonge/toolset/log/service/impl/AuditLogServiceImpl.java

@@ -0,0 +1,23 @@
+package com.yonge.toolset.log.service.impl;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.yonge.toolset.log.dal.dao.AuditLogDao;
+import com.yonge.toolset.log.dal.model.AuditLog;
+import com.yonge.toolset.log.service.AuditLogService;
+import com.yonge.toolset.mongodb.dao.BaseDaoWithMongo;
+import com.yonge.toolset.mongodb.service.impl.BaseServiceImplWithMongo;
+
+@Service
+public class AuditLogServiceImpl extends BaseServiceImplWithMongo<String, AuditLog> implements AuditLogService {
+
+	@Autowired
+	private AuditLogDao auditLogDao;
+
+	@Override
+	public BaseDaoWithMongo<String, AuditLog> getDAO() {
+		return auditLogDao;
+	}
+
+}

+ 164 - 0
toolset/audit-log/src/main/java/com/yonge/toolset/log/service/impl/HistoryMessageServiceImpl.java

@@ -0,0 +1,164 @@
+package com.yonge.toolset.log.service.impl;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipInputStream;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.alibaba.fastjson.JSONObject;
+import com.yonge.toolset.log.dal.dao.HistoryMessageDao;
+import com.yonge.toolset.log.dal.model.HistoryMessage;
+import com.yonge.toolset.log.service.HistoryMessageService;
+import com.yonge.toolset.mongodb.dao.BaseDaoWithMongo;
+import com.yonge.toolset.mongodb.service.impl.BaseServiceImplWithMongo;
+
+@Service
+public class HistoryMessageServiceImpl extends BaseServiceImplWithMongo<String, HistoryMessage> implements HistoryMessageService {
+
+	@Autowired
+	private HistoryMessageDao historyMessageDao;
+
+	@Override
+	public BaseDaoWithMongo<String, HistoryMessage> getDAO() {
+		return historyMessageDao;
+	}
+
+	@Override
+	public void saveImHistoryMessage(File file) throws Exception {
+//		long length = file.length();
+//		if(length > 1048576){
+			doNioReadFile(file);
+//		}else {
+//			doBufferReadFile(file);
+//		}
+	}
+
+//	public static void main(String[] args) throws Exception {
+//		doNioReadFile1(new File("/Users/chenxiaoyu/Documents/77fe9ce6-7d91-4568-afe3-9e8ac351e87f.zip"));
+//	}
+
+	public void doNioReadFile(File file) {
+		ZipInputStream zin = null;
+		try {
+			zin = new ZipInputStream(new FileInputStream(file), StandardCharsets.UTF_8);
+			ZipFile zf = new ZipFile(file);
+			ZipEntry ze;
+			Set<HistoryMessage> historyMessages = new HashSet<>();
+			while ((ze = zin.getNextEntry()) != null) {
+				BufferedReader br = new BufferedReader(new InputStreamReader(zf.getInputStream(ze)));
+				String line;
+				while ((line = br.readLine()) != null) {
+					try {
+						historyMessages.add(JSONObject.parseObject(line.substring(line.indexOf("{")), HistoryMessage.class));
+//						if(historyMessages.size() >= 2000){
+//							historyMessageDao.batchInsert(new ArrayList<>(historyMessages),HistoryMessage.class);
+//							historyMessages.clear();
+//						}
+					}catch (Exception e){
+						e.printStackTrace();
+					}
+				}
+				br.close();
+				break;
+			}
+			if(historyMessages.size() > 0){
+				historyMessageDao.batchInsert(historyMessages.stream().sorted(Comparator.comparing(HistoryMessage::getDateTime)).collect(Collectors.toList()),HistoryMessage.class);
+			}
+		} catch (IOException e) {
+			e.printStackTrace();
+		} finally {
+			if (zin != null) {
+				try {
+					zin.closeEntry();
+				} catch (IOException e) {
+					e.printStackTrace();
+				}
+			}
+		}
+	}
+
+//	public void doBufferReadFile(File file) throws Exception
+//	{
+//		BufferedReader reader = null;
+//		try {
+//
+////			InputStreamReader isr = new InputStreamReader(new FileInputStream(file), "GBK");
+//			reader = new BufferedReader(new FileReader(file));
+//			String line = null;
+//			int num = 0;
+//			List<HistoryMessage> historyMessages = new ArrayList<>();
+//			while ((line = reader.readLine()) != null){
+//				try {
+//					historyMessages.add(JSONObject.parseObject(line.substring(line.indexOf("{")), HistoryMessage.class));
+//					if(historyMessages.size() >= 2000){
+//						historyMessageDao.batchInsert(historyMessages,HistoryMessage.class);
+//						historyMessages.clear();
+//					}
+//				}catch (Exception e){
+//					e.printStackTrace();
+//				}
+//				num++;
+//			}
+//			if(historyMessages.size() > 0){
+//				historyMessageDao.batchInsert(historyMessages,HistoryMessage.class);
+//			}
+//		} finally {
+//			reader.close();
+//		}
+//	}
+
+
+//	public static void doNioReadFile(File file) throws Exception
+//	{
+//		String enterStr = "\n";
+//
+//		FileChannel inChannel = new FileInputStream(file).getChannel();
+//		ByteBuffer buffer = ByteBuffer.allocate(1048576);
+//
+//		StringBuilder newlinesBui = new StringBuilder();
+//		while (inChannel.read(buffer) != -1)
+//		{
+//			buffer.flip();
+//			//数据组合.
+//			String content = new String(buffer.array());
+//			newlinesBui.append(content).toString();
+//
+//			int fromIndex = 0;
+//			int endIndex = -1;
+//			//循环找到 \n
+//			List<HistoryMessage> historyMessages = new ArrayList<>();
+//			while ((endIndex = newlinesBui.indexOf(enterStr, fromIndex)) > -1)
+//			{
+//				//得到一行
+//				String line = newlinesBui.substring(fromIndex, endIndex);
+//				try {
+//					historyMessages.add(JSONObject.parseObject(line.substring(line.indexOf("{")), HistoryMessage.class));
+//					if(historyMessages.size() >= 2000){
+////						historyMessageDao.batchInsert(historyMessages,HistoryMessage.class);
+//						historyMessages.clear();
+//					}
+//				}catch (Exception e){
+//					e.printStackTrace();
+//				}
+//				fromIndex = endIndex + 1;
+//			}
+//			if(historyMessages.size() > 0){
+////				historyMessageDao.batchInsert(historyMessages,HistoryMessage.class);
+//			}
+//			newlinesBui.delete(0, fromIndex);
+//			buffer.clear();
+//		}
+//	}
+}

+ 23 - 0
toolset/audit-log/src/main/java/com/yonge/toolset/log/service/impl/OperationLogServiceImpl.java

@@ -0,0 +1,23 @@
+package com.yonge.toolset.log.service.impl;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.yonge.toolset.log.dal.dao.OperationLogDao;
+import com.yonge.toolset.log.dal.model.OperationLog;
+import com.yonge.toolset.log.service.OperationLogService;
+import com.yonge.toolset.mongodb.dao.BaseDaoWithMongo;
+import com.yonge.toolset.mongodb.service.impl.BaseServiceImplWithMongo;
+
+@Service
+public class OperationLogServiceImpl extends BaseServiceImplWithMongo<String, OperationLog> implements OperationLogService {
+
+	@Autowired
+	private OperationLogDao operationLogDao;
+
+	@Override
+	public BaseDaoWithMongo<String, OperationLog> getDAO() {
+		return operationLogDao;
+	}
+
+}

+ 20 - 0
toolset/audit-log/src/test/java/com/yonge/log/AuditLogServerApplication.java

@@ -0,0 +1,20 @@
+package com.yonge.log;
+
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+
+@SpringBootApplication
+@EnableDiscoveryClient
+@ComponentScan(basePackages = { "com.yonge.log" })
+@Configuration
+public class AuditLogServerApplication {
+
+	public static void main(String[] args) {
+		SpringApplication.run(AuditLogServerApplication.class, args);
+	}
+
+}

+ 87 - 0
toolset/audit-log/src/test/java/com/yonge/log/test/SpringBootMongodbApplicationTests.java

@@ -0,0 +1,87 @@
+package com.yonge.log.test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import com.yonge.log.AuditLogServerApplication;
+import com.yonge.toolset.log.dal.model.AuditLog;
+import com.yonge.toolset.log.service.AuditLogService;
+import com.yonge.toolset.mongodb.QueryInfo;
+import com.yonge.toolset.utils.json.JsonUtil;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = AuditLogServerApplication.class)
+public class SpringBootMongodbApplicationTests {
+
+	@Autowired
+	private AuditLogService auditLogService;
+	
+	@Test
+	public void add() {
+		AuditLog auditLog = new AuditLog();
+		auditLog.setId("1");
+		auditLog.setInputParams("{'signClassId':'','mixClassId':'','snapClassIds':'','highClassId':'','temporaryCourseFee':null,'studentRegistration':{'name':'上低08','gender':1,'birthdate':'2020-12-21','parentsName':'上低08家长','parentsPhone':'18881230038','currentGrade':'一年级','currentClass':'A','subjectId':2,'musicGroupId':'20123009470100001'},'studentPaymentOrderDetails':[]}");
+		auditLog.setInterfaceUrl("api-web/studentRegistration/insertStudent");
+		auditLog.setOperateName("进行中加学员");
+		auditLog.setUserIp("127.0.0.1");
+		auditLog.setUsername("xxx");
+		auditLogService.insert(auditLog);
+		
+		System.out.println("*********insert*********");
+		System.out.println(JsonUtil.toJSONString(auditLog));
+		System.out.println("******************");
+	}
+
+	@Test
+	public void query() {
+		System.out.println("********query**********");
+		System.out.println(JsonUtil.toJSONString(auditLogService.get("1")));
+		System.out.println("******************");
+	}
+
+	@Test
+	public void update() {
+		AuditLog auditLog = auditLogService.get("1");
+		auditLog.setInputParams("测试输入参数222");
+		System.out.println("********update**********");
+		System.out.println(JsonUtil.toJSONString(auditLogService.update("1", auditLog)));
+		System.out.println("******************");
+	}
+
+	@Test
+	public void delete() {
+		System.out.println("********delete**********");
+		System.out.println(JsonUtil.toJSONString(auditLogService.delete("1")));
+		System.out.println("******************");
+	}
+
+	@Test
+	public void findAll() {
+		System.out.println("********findAll**********");
+		System.out.println(JsonUtil.toJSONString(auditLogService.findAll(null)));
+		System.out.println("******************");
+	}
+
+	@Test
+	public void queryCount() {
+		System.out.println("********queryCount**********");
+		Map<String, Object> params = new HashMap<String, Object>();
+		params.put("id", 1);
+		System.out.println(JsonUtil.toJSONString(auditLogService.queryCount(params)));
+		System.out.println("******************");
+	}
+
+	@Test
+	public void queryPage() {
+		System.out.println("********queryPage**********");
+		QueryInfo queryInfo = new QueryInfo();
+		System.out.println(JsonUtil.toJSONString(auditLogService.queryPage(queryInfo)));
+		System.out.println("******************");
+	}
+}

+ 6 - 0
toolset/audit-log/src/test/resources/application.properties

@@ -0,0 +1,6 @@
+spring.application.name=audit-log
+
+# mongodb
+spring.data.mongodb.uri=mongodb://47.114.1.200:27017
+
+spring.data.mongodb.database=mec_dev

+ 34 - 0
toolset/codegen/pom.xml

@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>com.yonge.toolset</groupId>
+    <artifactId>toolset</artifactId>
+    <version>1.0</version>
+  </parent>
+  <groupId>com.yonge.toolset</groupId>
+  <artifactId>codegen</artifactId>
+  <version>1.0</version>
+  <name>codegen</name>
+  <url>http://maven.apache.org</url>
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  </properties>
+  <dependencies>
+		<dependency>
+			<groupId>org.freemarker</groupId>
+			<artifactId>freemarker</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>mysql</groupId>
+			<artifactId>mysql-connector-java</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>com.yonge.toolset</groupId>
+			<artifactId>utils</artifactId>
+		</dependency>
+  </dependencies>
+</project>

+ 63 - 0
toolset/codegen/src/main/java/com/yonge/toolset/crud/CodegenApplication.java

@@ -0,0 +1,63 @@
+package com.yonge.toolset.crud;
+
+import java.util.List;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.transform.stream.StreamSource;
+
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+import com.yonge.toolset.crud.core.Configuration;
+import com.yonge.toolset.crud.core.CrudSession;
+import com.yonge.toolset.crud.core.CrudSessionFactory;
+import com.yonge.toolset.crud.core.GenerateConfiguration;
+import com.yonge.toolset.crud.core.db.model.Table;
+
+@SpringBootApplication
+public class CodegenApplication {
+
+	public static void main(String[] args) throws JAXBException {
+		//SpringApplication.run(CodegenApplication.class, args);
+
+		/*
+		 * Configuration config = new Configuration("oracle.jdbc.driver.OracleDriver", "jdbc:oracle:thin:@192.168.10.134:1521:orcl", "margin_gy",
+		 * "margin_gy", null, "margin_gy");
+		 */
+
+		// "src/generateConfigration.xml"
+		GenerateConfiguration genConfig = toObject("codegen/src/main/resources/generateConfigration.xml", GenerateConfiguration.class);
+
+		Configuration config = genConfig.getDbConfiguration();
+
+		CrudSessionFactory sessionFactory = config.buildCrudSessionFactory();
+		CrudSession session = sessionFactory.openSession();
+		List<Table> tables = session.getTables();
+		String srcBase = genConfig.getSrcBase();
+		String pojoPackageName = genConfig.getPojoPackageName();
+		String daoPackageName = genConfig.getDaoPackageName();
+		String servicePackageName = genConfig.getServicePackageName();
+		String sqlmapPackageName = genConfig.getSqlmapPackageName();
+		String sqlmapConfigPackageName = genConfig.getSqlmapConfigPackageName();
+		for (Table table : tables) {
+			try {
+				session.reverse(table, srcBase, pojoPackageName, sqlmapPackageName, daoPackageName, servicePackageName);
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+		}
+		// 生成sqlmapConfig
+		session.generateSqlmapConfig(tables, srcBase, sqlmapConfigPackageName, sqlmapPackageName);
+		session.closeSession();
+	}
+
+	public static <T> T toObject(String systemId, Class<T> clazz) throws JAXBException {
+		JAXBContext jc = JAXBContext.newInstance(clazz);
+		Unmarshaller unmarshaller = jc.createUnmarshaller();
+		StreamSource xml = new StreamSource(systemId);
+		JAXBElement<T> je = unmarshaller.unmarshal(xml, clazz);
+		return je.getValue();
+	}
+}

+ 111 - 0
toolset/codegen/src/main/java/com/yonge/toolset/crud/core/Configuration.java

@@ -0,0 +1,111 @@
+package com.yonge.toolset.crud.core;
+
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Configuration {
+
+	private static final Logger LOGGER = LoggerFactory
+			.getLogger(Configuration.class);
+
+	private String driverClass;
+
+	private String url;
+
+	private String username;
+
+	private String password;
+
+	private String catalog;
+
+	private String schema;
+
+	public Configuration() {
+		// TODO Auto-generated constructor stub
+	}
+
+	public Configuration(String driverClass, String url, String username,
+			String password, String catalog, String schema) {
+		if (StringUtils.isBlank(driverClass)) {
+			LOGGER.warn("driverClass不能为空");
+			return;
+		}
+		if (StringUtils.isBlank(url)) {
+			LOGGER.warn("url不能为空");
+			return;
+		}
+		if (StringUtils.isBlank(username)) {
+			LOGGER.warn("username不能为空");
+			return;
+		}
+		if (StringUtils.isBlank(password)) {
+			LOGGER.warn("password不能为空");
+			return;
+		}
+		if (StringUtils.isBlank(schema)) {
+			LOGGER.warn("schema不能为空");
+			return;
+		}
+		this.driverClass = driverClass;
+		this.url = url;
+		this.username = username;
+		this.password = password;
+		if (catalog != null) {
+			this.catalog = catalog.toUpperCase();
+		}
+		this.schema = schema.toUpperCase();
+	}
+
+	public String getDriverClass() {
+		return driverClass;
+	}
+
+	public void setDriverClass(String driverClass) {
+		this.driverClass = driverClass;
+	}
+
+	public String getUrl() {
+		return url;
+	}
+
+	public void setUrl(String url) {
+		this.url = url;
+	}
+
+	public String getUsername() {
+		return username;
+	}
+
+	public void setUsername(String username) {
+		this.username = username;
+	}
+
+	public String getPassword() {
+		return password;
+	}
+
+	public void setPassword(String password) {
+		this.password = password;
+	}
+
+	public String getCatalog() {
+		return catalog;
+	}
+
+	public void setCatalog(String catalog) {
+		this.catalog = catalog;
+	}
+
+	public String getSchema() {
+		return schema;
+	}
+
+	public void setSchema(String schema) {
+		this.schema = schema;
+	}
+
+	public CrudSessionFactory buildCrudSessionFactory() {
+		return new CrudSessionFactory(this);
+	}
+}

+ 144 - 0
toolset/codegen/src/main/java/com/yonge/toolset/crud/core/CrudSession.java

@@ -0,0 +1,144 @@
+package com.yonge.toolset.crud.core;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.SQLException;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.yonge.toolset.crud.core.db.DatabaseIntrospector;
+import com.yonge.toolset.crud.core.db.model.Table;
+import com.yonge.toolset.crud.core.generator.ModuleGenerateIntrospector;
+
+public class CrudSession {
+
+	private static final Logger LOGGER = LoggerFactory
+			.getLogger(CrudSession.class);
+
+	private Connection connection;
+
+	private DatabaseMetaData dbMetaData;
+
+	private String catalog;
+
+	private String schema;
+
+	private CrudSessionFactory sessionFactory;
+
+	CrudSession(Connection connection, String catalog, String schema,
+			CrudSessionFactory sessionFactory) {
+		if (connection == null) {
+			LOGGER.warn("没有获取连接,不能打开session");
+			return;
+		}
+		this.connection = connection;
+		this.catalog = catalog;
+		this.schema = schema;
+		this.sessionFactory = sessionFactory;
+		try {
+			this.dbMetaData = connection.getMetaData();
+		} catch (SQLException e) {
+			LOGGER.warn("获取数据库连接的元数据失败", e);
+		}
+	}
+
+	/**
+	 * 关闭会话
+	 */
+	public void closeSession() {
+		if (connection != null) {
+			try {
+				connection.close();
+			} catch (SQLException e) {
+				LOGGER.warn("数据库连接关闭失败", e);
+			}
+		}
+	}
+
+	/**
+	 * 获取工厂信息
+	 * 
+	 * @return
+	 */
+	public CrudSessionFactory getFactory() {
+		return sessionFactory;
+	}
+
+	/**
+	 * 获取所有表信息
+	 * 
+	 * @return
+	 */
+	public List<Table> getTables() {
+		DatabaseIntrospector dbIntrospector = new DatabaseIntrospector(
+				dbMetaData);
+		return dbIntrospector.getTables(catalog, schema);
+	}
+
+	/**
+	 * 数据库表的反向工程
+	 * 
+	 * @param table
+	 *            表对象
+	 * @param srcBase
+	 *            生成目录的根路径
+	 * @param pojoPackageName
+	 *            存放pojo的包名称
+	 * @param sqlmapPackageName
+	 *            存放sqlmap的包名称
+	 * @param daoPackageName
+	 *            存放dao的包名称
+	 */
+	public void reverse(Table table, String srcBase, String pojoPackageName,
+			String sqlmapPackageName, String daoPackageName,
+			String servicePackageName) {
+		ModuleGenerateIntrospector
+				.generatePOJO(table, srcBase, pojoPackageName);
+		ModuleGenerateIntrospector.generatSqlmap(this.getFactory()
+				.getMetadata().getDriverClass(), table, srcBase,
+				sqlmapPackageName, daoPackageName);
+		ModuleGenerateIntrospector.generateDaoAndService(table, srcBase,
+				daoPackageName, servicePackageName);
+	}
+
+	/**
+	 * 生成spring的配置文件
+	 * 
+	 * @param tables
+	 *            需要生成spring配置文件对应的表
+	 * @param srcBase
+	 *            根目录
+	 * @param packageName
+	 *            配置文件的包路径
+	 * @param daoPackageName
+	 *            dao的包路径
+	 * @param servicePackageName
+	 *            service的包路径
+	 */
+	public void generateSpringConfig(List<Table> tables, String srcBase,
+			String packageName, String daoPackageName, String servicePackageName) {
+		ModuleGenerateIntrospector.generateSpring(tables, srcBase, packageName,
+				daoPackageName, servicePackageName);
+	}
+
+	/**
+	 * 生成sqlmapConfig文件
+	 * 
+	 * @param tables
+	 *            相关表信息
+	 * @param srcBase
+	 *            生成目标的根目录
+	 * @param packageName
+	 *            sqlmapConfig文件的包路径
+	 * @param sqlmapPackageName
+	 *            sqlmap文件的包路径
+	 */
+	public void generateSqlmapConfig(List<Table> tables, String srcBase,
+			String packageName, String sqlmapPackageName) {
+		ModuleGenerateIntrospector.generateSqlMapConfig(tables, srcBase,
+				sqlmapPackageName, packageName);
+	}
+
+}

+ 60 - 0
toolset/codegen/src/main/java/com/yonge/toolset/crud/core/CrudSessionFactory.java

@@ -0,0 +1,60 @@
+package com.yonge.toolset.crud.core;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.yonge.toolset.crud.core.db.ConnectionFactory;
+
+public class CrudSessionFactory {
+
+	private static final Logger LOGGER = LoggerFactory
+			.getLogger(CrudSessionFactory.class);
+
+	private CrudSession session;
+
+	private Connection connection;
+
+	private String catalog;
+
+	private String schema;
+
+	private Configuration config;
+
+	CrudSessionFactory(Configuration config) {
+		LOGGER.debug("数据库的连接信息:url={} user={} password={}", config.getUrl(),
+				config.getUsername(), config.getPassword());
+		try {
+			this.config = config;
+			this.catalog = config.getCatalog();
+			this.schema = config.getSchema();
+			connection = ConnectionFactory.getInstance().getConnection(
+					config.getDriverClass(), config.getUrl(),
+					config.getUsername(), config.getPassword());
+			session = new CrudSession(connection, catalog, schema, this);
+		} catch (SQLException e) {
+			LOGGER.warn("数据库连接创建失败", e);
+		}
+	}
+
+	/**
+	 * 开启一个会话
+	 */
+	public synchronized CrudSession openSession() {
+		if (session == null) {
+			session = new CrudSession(connection, catalog, schema, this);
+		}
+		return session;
+	}
+
+	/**
+	 * 获取元数据
+	 * 
+	 * @return
+	 */
+	public Configuration getMetadata() {
+		return config;
+	}
+}

+ 93 - 0
toolset/codegen/src/main/java/com/yonge/toolset/crud/core/FreemarkerTemplateEngine.java

@@ -0,0 +1,93 @@
+package com.yonge.toolset.crud.core;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import freemarker.template.Configuration;
+import freemarker.template.DefaultObjectWrapper;
+import freemarker.template.Template;
+
+public class FreemarkerTemplateEngine {
+	private static final Logger LOGGER = LoggerFactory
+			.getLogger(FreemarkerTemplateEngine.class);
+
+	private static Configuration cfg;
+
+	static {
+		cfg = new Configuration();
+		cfg.setOutputEncoding("UTF-8");
+		cfg.setClassForTemplateLoading(FreemarkerTemplateEngine.class,
+				"/template/");
+		cfg.setObjectWrapper(new DefaultObjectWrapper());
+	}
+
+	public void render(Map<String, Object> data, String templateFile,
+			File outputFile) {
+		FileWriter fw = null;
+		BufferedWriter bw = null;
+		try {
+			Template temp = cfg.getTemplate(templateFile);
+			fw = new FileWriter(outputFile);
+			bw = new BufferedWriter(fw);
+			temp.process(data, bw);
+			bw.flush();
+		} catch (Exception e) {
+			LOGGER.warn(String.format("将数据%1$s通过FreeMarker模板%2$s生成文件%3$s失败",
+					data, templateFile, outputFile), e);
+		} finally {
+			if (bw != null) {
+				try {
+					bw.close();
+				} catch (IOException e) {
+					LOGGER.warn("BufferedWriter关闭异常");
+				}
+			}
+			if (fw != null) {
+				try {
+					fw.close();
+				} catch (IOException e) {
+					LOGGER.warn("FileWriter关闭异常");
+				}
+			}
+		}
+	}
+
+	public void render(Map<String, Object> data, String templateFile,
+			String outputFile) {
+		FileWriter fw = null;
+		BufferedWriter bw = null;
+		try {
+			Template temp = cfg.getTemplate(templateFile);
+			File file = new File(outputFile);
+			fw = new FileWriter(file);
+			bw = new BufferedWriter(fw);
+			temp.process(data, bw);
+			bw.flush();
+		} catch (Exception e) {
+			LOGGER.warn(String.format("将数据%1$s通过FreeMarker模板%2$s生成文件%3$s失败",
+					data, templateFile, outputFile), e);
+		} finally {
+			if (bw != null) {
+				try {
+					bw.close();
+				} catch (IOException e) {
+					LOGGER.warn("BufferedWriter关闭异常");
+				}
+			}
+			if (fw != null) {
+				try {
+					fw.close();
+				} catch (IOException e) {
+					LOGGER.warn("FileWriter关闭异常");
+				}
+			}
+		}
+	}
+
+}

+ 84 - 0
toolset/codegen/src/main/java/com/yonge/toolset/crud/core/GenerateConfiguration.java

@@ -0,0 +1,84 @@
+package com.yonge.toolset.crud.core;
+
+public class GenerateConfiguration {
+
+	private Configuration dbConfiguration;
+
+	private String srcBase;
+
+	private String pojoPackageName;
+
+	private String daoPackageName;
+
+	private String servicePackageName;
+
+	private String sqlmapPackageName;
+
+	private String sqlmapConfigPackageName;
+
+	private String springConfigPackageName;
+
+	public Configuration getDbConfiguration() {
+		return dbConfiguration;
+	}
+
+	public void setDbConfiguration(Configuration dbConfiguration) {
+		this.dbConfiguration = dbConfiguration;
+	}
+
+	public String getSrcBase() {
+		return srcBase;
+	}
+
+	public void setSrcBase(String srcBase) {
+		this.srcBase = srcBase;
+	}
+
+	public String getPojoPackageName() {
+		return pojoPackageName;
+	}
+
+	public void setPojoPackageName(String pojoPackageName) {
+		this.pojoPackageName = pojoPackageName;
+	}
+
+	public String getDaoPackageName() {
+		return daoPackageName;
+	}
+
+	public void setDaoPackageName(String daoPackageName) {
+		this.daoPackageName = daoPackageName;
+	}
+
+	public String getServicePackageName() {
+		return servicePackageName;
+	}
+
+	public void setServicePackageName(String servicePackageName) {
+		this.servicePackageName = servicePackageName;
+	}
+
+	public String getSqlmapPackageName() {
+		return sqlmapPackageName;
+	}
+
+	public void setSqlmapPackageName(String sqlmapPackageName) {
+		this.sqlmapPackageName = sqlmapPackageName;
+	}
+
+	public String getSqlmapConfigPackageName() {
+		return sqlmapConfigPackageName;
+	}
+
+	public void setSqlmapConfigPackageName(String sqlmapConfigPackageName) {
+		this.sqlmapConfigPackageName = sqlmapConfigPackageName;
+	}
+
+	public String getSpringConfigPackageName() {
+		return springConfigPackageName;
+	}
+
+	public void setSpringConfigPackageName(String springConfigPackageName) {
+		this.springConfigPackageName = springConfigPackageName;
+	}
+}

+ 59 - 0
toolset/codegen/src/main/java/com/yonge/toolset/crud/core/db/ConnectionFactory.java

@@ -0,0 +1,59 @@
+package com.yonge.toolset.crud.core.db;
+
+import java.sql.Connection;
+import java.sql.Driver;
+import java.sql.SQLException;
+import java.util.Properties;
+
+import org.apache.commons.lang3.StringUtils;
+
+public class ConnectionFactory {
+
+	private static ConnectionFactory instance = new ConnectionFactory();
+
+	private static final String ORACLE_DRIVER = "oracle.jdbc.driver.OracleDriver";
+
+	public static ConnectionFactory getInstance() {
+		return instance;
+	}
+
+	private ConnectionFactory() {
+		super();
+	}
+
+	public Connection getConnection(String driverClass, String url,
+			String username, String password) throws SQLException {
+		Driver driver = getDriver(driverClass);
+
+		Properties props = new Properties();
+
+		props.setProperty("user", username);
+
+		props.setProperty("password", password);
+
+		// 只有oracle才需要这个参数
+		if (StringUtils.equals(driverClass, ORACLE_DRIVER)) {
+			props.setProperty("remarksReporting", "true");
+		}
+
+		Connection conn = driver.connect(url, props);
+
+		if (conn == null) {
+			throw new SQLException("连接获取失败");
+		}
+
+		return conn;
+	}
+
+	private Driver getDriver(String driverClass) {
+		Driver driver = null;
+		try {
+			Class<?> clazz = Class.forName(driverClass);
+			driver = (Driver) clazz.newInstance();
+		} catch (Exception e) {
+			throw new RuntimeException("类加载器加载driver失败", e);
+		}
+
+		return driver;
+	}
+}

+ 117 - 0
toolset/codegen/src/main/java/com/yonge/toolset/crud/core/db/DatabaseIntrospector.java

@@ -0,0 +1,117 @@
+package com.yonge.toolset.crud.core.db;
+
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.yonge.toolset.crud.core.db.model.Column;
+import com.yonge.toolset.crud.core.db.model.Table;
+import com.yonge.toolset.crud.core.util.JavaBeansUtil;
+
+public class DatabaseIntrospector {
+	private static final Logger LOGGER = LoggerFactory.getLogger(DatabaseIntrospector.class);
+
+	private DatabaseMetaData dbMetaData;
+
+	public DatabaseIntrospector(DatabaseMetaData dbMetaData) {
+		this.dbMetaData = dbMetaData;
+	}
+
+	public List<Table> getTables(String catalog, String schema) {
+		List<Table> tables = new ArrayList<Table>();
+		if (dbMetaData == null) {
+			LOGGER.warn("DatabaseMetaData对象不能为空");
+			return tables;
+		}
+		ResultSet resultSet = null;
+		try {
+			resultSet = dbMetaData.getTables(catalog, schema, null, new String[] { "TABLE" });
+			Table table = null;
+			while (resultSet.next()) {
+				table = new Table();
+				table.setName(resultSet.getString("TABLE_NAME"));
+				table.setCatalog(resultSet.getString("TABLE_CAT"));
+				table.setRemarks(resultSet.getString("REMARKS"));
+				table.setSchema(resultSet.getString("TABLE_SCHEM"));
+				table.setClassName(JavaBeansUtil.getCamelCaseString(table.getName(), true));
+
+				table.setColumns(getColumns(table));
+				tables.add(table);
+			}
+		} catch (SQLException e) {
+			LOGGER.warn("获取数据库表失败", e);
+		} finally {
+			if (resultSet != null) {
+				try {
+					resultSet.close();
+				} catch (SQLException e) {
+					LOGGER.warn("关闭ResultSet对象出现异常", e);
+				}
+			}
+		}
+		return tables;
+	}
+
+	private List<Column> getColumns(Table table) {
+		List<Column> columns = new ArrayList<Column>();
+		if (table == null) {
+			LOGGER.warn("参数不能为空");
+			return columns;
+		}
+		String tableName = table.getName();
+		String schema = table.getSchema();
+		String name = tableName.toUpperCase();
+		if (dbMetaData == null) {
+			LOGGER.warn("DatabaseMetaData对象不能为空");
+		}
+		ResultSet resultSet = null;
+		Column column = null;
+		try {
+			resultSet = dbMetaData.getPrimaryKeys(table.getCatalog(), schema, tableName);
+			List<String> keyColumns = new ArrayList<String>();
+			while (resultSet.next()) {
+				keyColumns.add(resultSet.getString("COLUMN_NAME"));
+			}
+
+			resultSet = dbMetaData.getColumns(table.getCatalog(), schema, tableName, null);
+			while (resultSet.next()) {
+				column = new Column();
+				// 获得字段名称
+				column.setFieldName(resultSet.getString("COLUMN_NAME"));
+				// 获得字段类型名称
+				column.setJdbcTypeName(resultSet.getString("TYPE_NAME"));
+				// 数据类型
+				column.setDataType(resultSet.getInt("DATA_TYPE"));
+				// 获得字段大小
+				column.setLength(resultSet.getInt("COLUMN_SIZE"));
+				column.setNullable((resultSet.getInt("NULLABLE") == DatabaseMetaData.columnNullable));
+				column.setScale(resultSet.getInt("DECIMAL_DIGITS"));
+				column.setRemarks(resultSet.getString("REMARKS"));
+				for (String key : keyColumns) {
+					if (StringUtils.equalsIgnoreCase(key, column.getFieldName())) {
+						column.setIsPrimaryKey(true);
+					}
+				}
+				columns.add(column);
+			}
+		} catch (SQLException e) {
+			LOGGER.warn("在" + schema + "中获取" + name + "表字段出现异常", e);
+		} finally {
+			if (resultSet != null) {
+				try {
+					resultSet.close();
+				} catch (SQLException e) {
+					LOGGER.warn("关闭ResultSet对象出现异常", e);
+				}
+			}
+		}
+		return columns;
+	}
+
+}

+ 127 - 0
toolset/codegen/src/main/java/com/yonge/toolset/crud/core/db/model/Column.java

@@ -0,0 +1,127 @@
+package com.yonge.toolset.crud.core.db.model;
+
+public class Column {
+
+	/** 字段名称 */
+	private String fieldName;
+
+	/** 是否是主键 */
+	private boolean isPrimaryKey;
+
+	/** 属性名称 */
+	private String propertyName;
+
+	/** JDBC类型 名称 */
+	private String jdbcTypeName;
+
+	/** java类型 */
+	private String javaTypeName;
+
+	/** 数据类型 */
+	private int dataType;
+
+	/** 字段长度 */
+	private int length;
+
+	/** 是否可以为空 */
+	private boolean nullable;
+
+	private int scale;
+
+	/** 描述 */
+	private String remarks;
+
+	public String getFieldName() {
+		return fieldName;
+	}
+
+	public void setFieldName(String fieldName) {
+		this.fieldName = fieldName;
+	}
+
+	public boolean isPrimaryKey() {
+		return isPrimaryKey;
+	}
+
+	public void setIsPrimaryKey(boolean isPrimaryKey) {
+		this.isPrimaryKey = isPrimaryKey;
+	}
+
+	public String getPropertyName() {
+		return propertyName;
+	}
+
+	public void setPropertyName(String propertyName) {
+		this.propertyName = propertyName;
+	}
+
+	public String getJdbcTypeName() {
+		return jdbcTypeName;
+	}
+
+	public void setJdbcTypeName(String jdbcTypeName) {
+		this.jdbcTypeName = jdbcTypeName;
+	}
+
+	public String getJavaTypeName() {
+		return javaTypeName;
+	}
+
+	public void setJavaTypeName(String javaTypeName) {
+		this.javaTypeName = javaTypeName;
+	}
+
+	public int getDataType() {
+		return dataType;
+	}
+
+	public void setDataType(int dataType) {
+		this.dataType = dataType;
+	}
+
+	public int getLength() {
+		return length;
+	}
+
+	public void setLength(int length) {
+		this.length = length;
+	}
+
+	public boolean isNullable() {
+		return nullable;
+	}
+
+	public void setNullable(boolean nullable) {
+		this.nullable = nullable;
+	}
+
+	public int getScale() {
+		return scale;
+	}
+
+	public void setScale(int scale) {
+		this.scale = scale;
+	}
+
+	public String getRemarks() {
+		return remarks;
+	}
+
+	public void setRemarks(String remarks) {
+		this.remarks = remarks;
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		sb.append("fieldName = " + fieldName)
+				.append(" isPrimaryKey = " + isPrimaryKey)
+				.append(" propertyName = " + propertyName)
+				.append(" jdbcTypeName = " + jdbcTypeName)
+				.append(" javaTypeName = " + javaTypeName)
+				.append(" dataType = " + dataType)
+				.append(" length = " + length)
+				.append(" nullable = " + nullable).append(" scale = " + scale)
+				.append(" remarks = " + remarks);
+		return sb.toString();
+	}
+}

+ 86 - 0
toolset/codegen/src/main/java/com/yonge/toolset/crud/core/db/model/Table.java

@@ -0,0 +1,86 @@
+package com.yonge.toolset.crud.core.db.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Table {
+
+	private String name;
+
+	private String schema;
+
+	private String catalog;
+
+	private String remarks;
+
+	private String className;
+
+	private String packageName;
+
+	private List<Column> columns = new ArrayList<Column>();
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public String getSchema() {
+		return schema;
+	}
+
+	public void setSchema(String schema) {
+		this.schema = schema;
+	}
+
+	public String getCatalog() {
+		return catalog;
+	}
+
+	public void setCatalog(String catalog) {
+		this.catalog = catalog;
+	}
+
+	public String getRemarks() {
+		return remarks;
+	}
+
+	public void setRemarks(String remarks) {
+		this.remarks = remarks;
+	}
+
+	public List<Column> getColumns() {
+		return columns;
+	}
+
+	public void setColumns(List<Column> columns) {
+		this.columns = columns;
+	}
+
+	public String getClassName() {
+		return className;
+	}
+
+	public void setClassName(String className) {
+		this.className = className;
+	}
+
+	public String getPackageName() {
+		return packageName;
+	}
+
+	public void setPackageName(String packageName) {
+		this.packageName = packageName;
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		sb.append("name = " + name).append(" catalog = " + catalog)
+				.append(" schema = " + schema).append(" remarks = " + remarks)
+				.append(" packageName = " + packageName)
+				.append(" className = " + className);
+		return sb.toString();
+	}
+}

+ 234 - 0
toolset/codegen/src/main/java/com/yonge/toolset/crud/core/generator/ModuleGenerateIntrospector.java

@@ -0,0 +1,234 @@
+package com.yonge.toolset.crud.core.generator;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.yonge.toolset.crud.core.db.model.Column;
+import com.yonge.toolset.crud.core.db.model.Table;
+import com.yonge.toolset.crud.core.generator.module.JavaFileGenerator;
+import com.yonge.toolset.crud.core.generator.module.SpringGenerator;
+import com.yonge.toolset.crud.core.generator.module.SqlMapConfigGenerator;
+import com.yonge.toolset.crud.core.util.JavaBeansUtil;
+
+public class ModuleGenerateIntrospector {
+
+	private static final String DAO_TEMPLATE_NAME = "dao.ftl";
+
+	private static final String POJO_TEMPLATE_NAME = "pojo.ftl";
+
+	private static final String SERVICE_IMPL_TEMPLATE_NAME = "service_impl.ftl";
+
+	private static final String SERVICE_TEMPLATE_NAME = "service.ftl";
+
+	private static final String SQLMAP_TEMPLATE_NAME = "sqlmap.ftl";
+
+	private static final String SQLMAPCONFIG_TEMPLATE_NAME = "sqlmapConfig.ftl";
+
+	private static final String SPRING_TEMPLATE = "spring.ftl";
+
+	private static final String POJO_FILE_SUFFIX = ".java";
+
+	private static final String SQLMAP_FILE_PREFIX = "SqlMap_";
+
+	private static final String XML_FILE_SUFFIX = ".xml";
+
+	private static final String DAO_FILE_SUFFIX = "Dao.java";
+
+	private static final String SERVICE_FILE_SUFFIX = "Service.java";
+
+	private static final String SERVICE_IMPL_FILE_SUFFIX = "ServiceImpl.java";
+
+	private static final String SQLMAP_CONFIG_FILE = "SqlMapConfig.xml";
+
+	private static final String SPRING_CONFIG_FILE = "spring-crud.xml";
+
+	public static void generatePOJO(Table table, String srcBase,
+			String packageName) {
+		List<Column> columns = table.getColumns();
+		for (Column col : columns) {
+			// 转换类型
+			col.setJavaTypeName(JavaBeansUtil.fromJdbcToJava(col));
+			// 转换属性名称
+			col.setPropertyName(JavaBeansUtil.getCamelCaseString(
+					col.getFieldName(), false));
+		}
+		table.setColumns(columns);
+		table.setPackageName(packageName);
+		Map<String, Object> params = new HashMap<String, Object>();
+		params.put("props", columns);
+		params.put("table", table);
+		// 生成pojo
+		JavaFileGenerator entiryGenerator = new JavaFileGenerator();
+		entiryGenerator.generate(params, srcBase, packageName,
+				table.getClassName() + POJO_FILE_SUFFIX, POJO_TEMPLATE_NAME);
+	}
+
+	public static void generatSqlmap(String driverClass, Table table,
+			String srcBase, String sqlMapPackageName, String daoPackageName) {
+		Map<String, Object> params = new HashMap<String, Object>();
+		String className = table.getClassName();
+		params.put("namespace", daoPackageName + "." + className + "Dao");
+		params.put("fullClassName", table.getPackageName() + "." + className);
+		params.put("alias", className);
+		params.put("columns", table.getColumns());
+
+		String tableName = table.getName();
+		params.put("tableName", tableName);
+
+		// 构建sql语句
+		String fields = "", properties = "", criteria = "", orderbyStr = "";
+		Map<String, String> fieldPropMapping = new HashMap<String, String>();
+		int keys = 0;
+		for (Column col : table.getColumns()) {
+			fields += (col.getFieldName() + ",");
+			properties += ("#{" + col.getPropertyName() + "},");
+			fieldPropMapping.put(col.getFieldName(), col.getPropertyName());
+			if (col.isPrimaryKey()) {
+				criteria += (col.getFieldName() + " = #{"
+						+ col.getPropertyName() + "} AND ");
+				++keys;
+				orderbyStr += (col.getFieldName() + ",");
+			}
+		}
+		if (keys > 1) {
+			params.put("paramType", Map.class.getName());
+		}
+		// 清除最后一个"AND"
+		if (StringUtils.isNotBlank(criteria)) {
+			criteria = criteria.substring(0, criteria.length() - 4);
+		}
+		// 删除最后一个“,”
+		fields = fields.substring(0, fields.length() - 1);
+		properties = properties.substring(0, properties.length() - 1);
+
+		String queryBaseSQL = "SELECT * FROM " + tableName;
+		// 全查询
+		String queryFullSQL = queryBaseSQL;
+		if (StringUtils.isNotBlank(orderbyStr)) {
+			orderbyStr = orderbyStr.substring(0, orderbyStr.length() - 1);
+			queryFullSQL += " ORDER BY " + orderbyStr;
+		}
+		params.put("queryFullSQL", queryFullSQL);
+		// 插入
+		String insertSQL = "INSERT INTO " + tableName + " (" + fields
+				+ ") VALUES(" + properties + ")";
+		params.put("insertSQL", insertSQL);
+		if (StringUtils.isNotBlank(criteria)) {
+			// 修改
+			String updateSQL = "UPDATE " + tableName + " <set>\n<if test=\"";
+			for (Entry<String, String> entry : fieldPropMapping.entrySet()) {
+				updateSQL += entry.getValue() + " != null\">\n" + (entry.getKey() + " = #{" + entry.getValue() + "},\n</if>\n<if test=\"");
+			}
+			// 删除最后一个“,”
+			updateSQL = updateSQL.substring(0, updateSQL.length() - 10);
+			updateSQL += ("</set> WHERE " + criteria);
+			params.put("updateSQL", updateSQL);
+			// 根据主键查询
+			String querySingleSQL = queryBaseSQL + " WHERE " + criteria;
+			params.put("querySingleSQL", querySingleSQL);
+			// 根据主键删除
+			String deleteSQL = "DELETE FROM " + tableName + " WHERE "
+					+ criteria;
+			params.put("deleteSQL", deleteSQL);
+		}
+		// 分页查询语句
+		String queryPage = "";
+
+		if (StringUtils.equals(driverClass, "com.mysql.jdbc.Driver")) {
+			// mysql
+			queryPage = queryFullSQL + " <include refid=\"global.limit\"/>";
+		} else if (StringUtils.equals(driverClass,
+				"oracle.jdbc.driver.OracleDriver")) {
+			// oracle
+			queryPage = "SELECT * FROM (SELECT A.*,ROWNUM FROM " + tableName
+					+ " A WHERE ROWNUM <= #endLine# ORDER BY " + orderbyStr
+					+ ") WHERE ROWNUM >= #startLine#";
+		} else if (StringUtils.equals(driverClass, "com.ibm.db2.jcc.DB2Driver")) {
+			// db2
+			queryPage = "SELECT * FROM (SELECT B.*,ROWNUMBER() OVER(ORDER BY "
+					+ orderbyStr
+					+ ") AS RN FROM "
+					+ tableName
+					+ " AS B) AS A WHERE A.RN BETWEEN #startLine# AND #endLine#";
+		}
+		if (StringUtils.isNotBlank(queryPage)) {
+			params.put("queryPage", queryPage);
+		}
+		// 生成sqlmap
+		JavaFileGenerator sqlMapGenerator = new JavaFileGenerator();
+		sqlMapGenerator.generate(params, srcBase, sqlMapPackageName,
+				className+"Mapper" + XML_FILE_SUFFIX,
+				SQLMAP_TEMPLATE_NAME);
+	}
+
+	public static void generateSqlMapConfig(List<Table> tables, String srcBase,
+			String sqlmapPackageName, String sqlMapConfigPackageName) {
+		Map<String, Object> params = new HashMap<String, Object>();
+		params.put("sqlmapPackageName", sqlmapPackageName);
+		params.put("tables", tables);
+		// 生成sqlmap-config
+		SqlMapConfigGenerator sqlMapConfigGenerator = new SqlMapConfigGenerator();
+		sqlMapConfigGenerator.createSqlMapConfigFile(sqlmapPackageName, tables,
+				params, srcBase, sqlMapConfigPackageName, SQLMAP_CONFIG_FILE,
+				SQLMAPCONFIG_TEMPLATE_NAME);
+	}
+
+	public static void generateDaoAndService(Table table, String srcBase,
+			String daoPackageName, String servicePackageName) {
+		Map<String, Object> params = new HashMap<String, Object>();
+		String className = table.getClassName();
+		String pojoFullClassName = table.getPackageName() + "."
+				+ table.getClassName();
+
+		List<Column> primarykeys = new ArrayList<Column>();
+		for (Column col : table.getColumns()) {
+			if (col.isPrimaryKey()) {
+				primarykeys.add(col);
+			}
+		}
+		String paramType = null;
+		if (primarykeys.size() == 1) {
+			paramType = primarykeys.get(0).getJavaTypeName();
+		} else if (primarykeys.size() > 1) {
+			paramType = Map.class.getName();
+		}
+		params.put("pojoFullClassName", pojoFullClassName);
+		params.put("className", className);
+		params.put("paramType", paramType);
+		params.put("daoPackageName", daoPackageName);
+
+		JavaFileGenerator daoGenerator = new JavaFileGenerator();
+		daoGenerator.generate(params, srcBase, daoPackageName, className
+				+ DAO_FILE_SUFFIX, DAO_TEMPLATE_NAME);
+
+		params.put("servicePackageName", servicePackageName);
+
+		JavaFileGenerator serviceGenerator = new JavaFileGenerator();
+		serviceGenerator.generate(params, srcBase, servicePackageName,
+				className + SERVICE_FILE_SUFFIX, SERVICE_TEMPLATE_NAME);
+
+		JavaFileGenerator serviceImplGenerator = new JavaFileGenerator();
+		serviceImplGenerator.generate(params, srcBase, servicePackageName
+				+ File.separator + "impl",
+				className + SERVICE_IMPL_FILE_SUFFIX,
+				SERVICE_IMPL_TEMPLATE_NAME);
+	}
+
+	public static void generateSpring(List<Table> tables, String srcBase,
+			String packageName, String daoPackageName, String servicePackageName) {
+		Map<String, Object> params = new HashMap<String, Object>();
+		params.put("daoPackageName", daoPackageName);
+		params.put("servicePackageName", servicePackageName);
+		params.put("tables", tables);
+		SpringGenerator springGenerator = new SpringGenerator();
+		springGenerator.createSpringFile(daoPackageName, servicePackageName,
+				tables, params, srcBase, packageName, SPRING_CONFIG_FILE,
+				SPRING_TEMPLATE);
+	}
+}

+ 41 - 0
toolset/codegen/src/main/java/com/yonge/toolset/crud/core/generator/module/JavaFileGenerator.java

@@ -0,0 +1,41 @@
+package com.yonge.toolset.crud.core.generator.module;
+
+import java.io.File;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.yonge.toolset.crud.core.FreemarkerTemplateEngine;
+
+public final class JavaFileGenerator extends FreemarkerTemplateEngine {
+	private static final Logger LOGGER = LoggerFactory
+			.getLogger(JavaFileGenerator.class);
+
+	public JavaFileGenerator() {
+		super();
+	}
+
+	public void generate(Map<String, Object> data, String srcBase,
+			String packageName, String targetFile, String templateFile) {
+		StringBuilder buf = new StringBuilder();
+		buf.append(srcBase).append(File.separator);
+		buf.append(packageName.replaceAll("\\.", File.separator
+				+ File.separator));// 单个的File.separator会导致无法通过正则表达式解析
+		buf.append(File.separator);
+		File packageDir = new File(buf.toString());
+		if (!packageDir.exists()) {
+			boolean flag = packageDir.mkdirs();
+			if (!flag) {
+				LOGGER.warn("递归创建文件夹{}失败", packageDir);
+				return;
+			}
+		}
+		buf.append(targetFile);
+		String outputFile = buf.toString();
+		LOGGER.debug("根据输入内容[{},{},{}]得到文件名{}", new Object[] { templateFile,
+				srcBase, packageName, outputFile });
+		render(data, templateFile, outputFile);
+	}
+
+}

+ 129 - 0
toolset/codegen/src/main/java/com/yonge/toolset/crud/core/generator/module/SpringGenerator.java

@@ -0,0 +1,129 @@
+package com.yonge.toolset.crud.core.generator.module;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpressionException;
+
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.SAXException;
+
+import com.yonge.toolset.crud.core.FreemarkerTemplateEngine;
+import com.yonge.toolset.crud.core.db.model.Table;
+import com.yonge.toolset.crud.core.util.XmlUtil;
+
+public class SpringGenerator extends FreemarkerTemplateEngine {
+
+	private static final Logger LOGGER = LoggerFactory
+			.getLogger(SpringGenerator.class);
+
+	public SpringGenerator() {
+		super();
+	}
+
+	public void createSpringFile(String daoPackageName,
+			String servicePackageName, List<Table> tables,
+			Map<String, Object> data, String srcBase, String packageName,
+			String targetFile, String templateFile) {
+		StringBuilder buf = new StringBuilder();
+		buf.append(srcBase).append(File.separator);
+		buf.append(packageName.replaceAll("\\.", File.separator
+				+ File.separator));// 单个的File.separator会导致无法通过正则表达式解析
+		buf.append(File.separator);
+		File dbDir = new File(buf.toString());
+		if (!dbDir.exists()) {
+			boolean flag = dbDir.mkdirs();
+			if (!flag) {
+				LOGGER.warn("递归创建文件夹{}失败", dbDir);
+				return;
+			}
+		}
+		buf.append(targetFile);
+		String outputFile = buf.toString();
+		File file = new File(outputFile);
+		if (file.exists()) {
+			Map<String, String> nsMap = new HashMap<String, String>();
+			nsMap.put("ns", "http://www.springframework.org/schema/beans");
+			try {
+				Document doc = XmlUtil.parse(file);
+				for (Table table : tables) {
+					String className = table.getClassName();
+					if (StringUtils.isNotBlank(className)) {
+						String className_firstLower = Character
+								.toLowerCase(className.charAt(0))
+								+ className.substring(1);
+						Object obj = XmlUtil.queryNodeValue(doc,
+								"//ns:beans/ns:bean[@id='"
+										+ className_firstLower + "Dao']",
+								XPathConstants.NODE, nsMap);
+						if (obj == null) {
+							// 创建dao
+							Element element = doc.createElement("bean");
+							element.setAttribute("id", className_firstLower
+									+ "Dao");
+							element.setAttribute("class",
+									"com.erayt.solar2.db.DaoProxyFactoryBean");
+							// 创建property元素
+							Element subElement = doc.createElement("property");
+							subElement.setAttribute("name", "daoInterface");
+							subElement.setAttribute("value", daoPackageName
+									+ "." + className + "Dao");
+							element.appendChild(subElement);
+
+							subElement = doc.createElement("property");
+							subElement.setAttribute("name", "sqlMapClient");
+							subElement.setAttribute("ref", "sqlMapClient");
+							element.appendChild(subElement);
+							doc.getDocumentElement().appendChild(element);
+
+						} else {
+							LOGGER.warn(targetFile + "中已经存在" + className
+									+ "的DAO配置");
+						}
+
+						obj = XmlUtil.queryNodeValue(doc,
+								"//ns:beans/ns:bean[@id='"
+										+ className_firstLower + "Service']",
+								XPathConstants.NODE, nsMap);
+						if (obj == null) {
+							// 创建service
+							Element element = doc.createElement("bean");
+							element.setAttribute("id", className_firstLower
+									+ "Service");
+							element.setAttribute("class", servicePackageName
+									+ ".impl." + className + "ServiceImpl");
+							doc.getDocumentElement().appendChild(element);
+						} else {
+							LOGGER.warn(targetFile + "中已经存在" + className
+									+ "的SERVICE配置");
+						}
+					}
+				}
+				// 将dom写入文件
+				XmlUtil.writeXmlFile(doc, outputFile);
+				return;
+			} catch (ParserConfigurationException e) {
+				LOGGER.warn("xml文件解析失败", e);
+			} catch (SAXException e) {
+				LOGGER.warn("xml文件解析失败", e);
+			} catch (IOException e) {
+				LOGGER.warn("xml文件解析失败", e);
+			} catch (XPathExpressionException e) {
+				LOGGER.warn("xpath表达式异常", e);
+			}
+		}
+		LOGGER.debug("根据输入内容[{},{},{}]得到文件名{}", new Object[] { templateFile,
+				srcBase, packageName, outputFile });
+		render(data, templateFile, outputFile);
+	}
+
+}

+ 82 - 0
toolset/codegen/src/main/java/com/yonge/toolset/crud/core/generator/module/SqlMapConfigGenerator.java

@@ -0,0 +1,82 @@
+package com.yonge.toolset.crud.core.generator.module;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpressionException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.SAXException;
+
+import com.yonge.toolset.crud.core.FreemarkerTemplateEngine;
+import com.yonge.toolset.crud.core.db.model.Table;
+import com.yonge.toolset.crud.core.util.XmlUtil;
+
+public final class SqlMapConfigGenerator extends FreemarkerTemplateEngine {
+	private static final Logger LOGGER = LoggerFactory
+			.getLogger(SqlMapConfigGenerator.class);
+
+	public void createSqlMapConfigFile(String sqlmapPackageName,
+			List<Table> tables, Map<String, Object> data, String srcBase,
+			String packageName, String targetFile, String templateFile) {
+		StringBuilder buf = new StringBuilder();
+		buf.append(srcBase).append(File.separator);
+		buf.append(packageName.replaceAll("\\.", File.separator
+				+ File.separator));// 单个的File.separator会导致无法通过正则表达式解析
+		buf.append(File.separator);
+		File dbDir = new File(buf.toString());
+		if (!dbDir.exists()) {
+			boolean flag = dbDir.mkdirs();
+			if (!flag) {
+				LOGGER.warn("递归创建文件夹{}失败", dbDir);
+				return;
+			}
+		}
+		buf.append(targetFile);
+		String outputFile = buf.toString();
+		// 判断文件是否存在,如果存在,则在原来的基础上追加
+		File file = new File(outputFile);
+		if (file.exists()) {
+			try {
+				Document doc = XmlUtil.parse(file);
+				for (Table table : tables) {
+					String src = sqlmapPackageName.replace('.', '/')
+							+ "/SqlMap_" + table.getName() + ".xml";
+					Object obj = XmlUtil.queryNodeValue(doc,
+							"//sqlMapConfig/sqlMap[@resource='" + src + "']",
+							XPathConstants.NODE, null);
+					if (obj == null) {
+						// 创建一个新的节点
+						Element element = doc.createElement("sqlMap");
+						element.setAttribute("resource", src);
+						doc.getDocumentElement().appendChild(element);
+					} else {
+						LOGGER.warn(targetFile + "中已经存在" + table.getName()
+								+ "配置");
+					}
+				}
+				// 将dom写入文件
+				XmlUtil.writeXmlFile(doc, outputFile);
+				return;
+			} catch (ParserConfigurationException e) {
+				LOGGER.warn("xml文件解析失败", e);
+			} catch (SAXException e) {
+				LOGGER.warn("xml文件解析失败", e);
+			} catch (IOException e) {
+				LOGGER.warn("xml文件解析失败", e);
+			} catch (XPathExpressionException e) {
+				LOGGER.warn("xpath表达式异常", e);
+			}
+		}
+		LOGGER.debug("根据输入内容[{},{},{}]得到文件名{}", new Object[] { data,
+				templateFile, srcBase, outputFile });
+		render(data, templateFile, outputFile);
+	}
+}

+ 160 - 0
toolset/codegen/src/main/java/com/yonge/toolset/crud/core/util/JavaBeansUtil.java

@@ -0,0 +1,160 @@
+package com.yonge.toolset.crud.core.util;
+
+import java.sql.Types;
+import java.util.regex.Pattern;
+
+import com.yonge.toolset.crud.core.db.model.Column;
+
+public class JavaBeansUtil {
+
+	private static final Pattern allowedClassNames = Pattern
+			.compile("[a-zA-Z]+");
+
+	public static String fromJdbcToJava(Column column) {
+		String answer = null;
+		switch (column.getDataType()) {
+		case Types.ARRAY:
+		case Types.DATALINK:
+		case Types.DISTINCT:
+		case Types.JAVA_OBJECT:
+		case Types.NULL:
+		case Types.OTHER:
+		case Types.REF:
+		case Types.STRUCT:
+			answer = "Object";
+			break;
+
+		case Types.BIGINT:
+			answer = "Long";
+			break;
+
+		case Types.BINARY:
+		case Types.BLOB:
+		case Types.LONGVARBINARY:
+		case Types.VARBINARY:
+			answer = "byte[]"; //$NON-NLS-1$
+			break;
+
+		case Types.BIT:
+		case Types.BOOLEAN:
+			answer = "boolean";
+			break;
+		case Types.CHAR:
+		case Types.CLOB:
+		case Types.LONGVARCHAR:
+		case Types.VARCHAR:
+			answer = "String";
+			break;
+
+		case Types.DATE:
+		case Types.TIME:
+		case Types.TIMESTAMP:
+			answer = "java.util.Date";
+			break;
+
+		case Types.DECIMAL:
+			if (column.getScale() > 0 || column.getLength() > 18) {
+				answer = "java.math.BigDecimal";
+			} else if (column.getLength() > 9) {
+				answer = "long";
+			} else if (column.getLength() > 4) {
+				answer = "int";
+			} else {
+				answer = "short";
+			}
+			break;
+
+		case Types.DOUBLE:
+			answer = "double";
+			break;
+
+		case Types.FLOAT:
+		case Types.REAL:
+			answer = "float";
+			break;
+
+		case Types.INTEGER:
+		case Types.TINYINT:
+			answer = "Integer";
+			break;
+
+		case Types.NUMERIC:
+			if (column.getScale() > 0 || column.getLength() > 18) {
+				answer = "java.math.BigDecimal";
+			} else if (column.getLength() > 9) {
+				answer = "long";
+			} else if (column.getLength() > 4) {
+				answer = "int";
+			} else {
+				answer = "short";
+			}
+			break;
+
+		case Types.SMALLINT:
+			answer = "short";
+			break;
+
+
+		default:
+			answer = null;
+			break;
+		}
+
+		return answer;
+	}
+
+	public static String getClassName(String tableName) {
+		String className = tableName;
+		if (allowedClassNames.matcher(className).matches()) {
+			className = tableName;
+		} else {
+			for (String chunk : allowedClassNames.split(tableName)) {
+				className = className.replace(chunk, "");
+			}
+		}
+		if (Character.isLowerCase(className.charAt(0))) {
+			className = className.substring(0, 1).toUpperCase()
+					+ className.substring(1);
+		}
+		return className;
+	}
+
+	public static String getCamelCaseString(String inputString,
+			boolean firstCharacterUppercase) {
+		StringBuilder sb = new StringBuilder();
+
+		boolean nextUpperCase = false;
+		for (int i = 0; i < inputString.length(); i++) {
+			char c = inputString.charAt(i);
+
+			switch (c) {
+			case '_':
+			case '-':
+			case '@':
+			case '$':
+			case '#':
+			case ' ':
+				if (sb.length() > 0) {
+					nextUpperCase = true;
+				}
+				break;
+
+			default:
+				if (nextUpperCase) {
+					sb.append(Character.toUpperCase(c));
+					nextUpperCase = false;
+				} else {
+					sb.append(Character.toLowerCase(c));
+				}
+				break;
+			}
+		}
+
+		if (firstCharacterUppercase) {
+			sb.setCharAt(0, Character.toUpperCase(sb.charAt(0)));
+		}
+
+		return sb.toString();
+	}
+
+}

+ 169 - 0
toolset/codegen/src/main/java/com/yonge/toolset/crud/core/util/XmlUtil.java

@@ -0,0 +1,169 @@
+package com.yonge.toolset.crud.core.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.namespace.QName;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+public class XmlUtil {
+
+	private static final Logger LOGGER = LoggerFactory.getLogger(XmlUtil.class);
+
+	private static final Map<ClassLoader, DocumentBuilderFactory> DOCUMENT_BUILDER_FACTORIES = Collections
+			.synchronizedMap(new WeakHashMap<ClassLoader, DocumentBuilderFactory>());
+
+	/**
+	 * 根据xpath表达式查询目标document中节点的值
+	 * 
+	 * @param doc
+	 *            目标对象
+	 * @param expression
+	 *            xpath表达式
+	 * @param returnType
+	 *            节点值的返回类型(eg:XPathConstants.STRING)
+	 * @param nsMap
+	 *            如果有默认的命名空间,需设置默认的命名空间
+	 * @return
+	 * @throws XPathExpressionException
+	 */
+	public static Object queryNodeValue(final Document doc, String expression,
+			QName returnType, final Map<String, String> nsMap)
+			throws XPathExpressionException {
+		XPathFactory factory = XPathFactory.newInstance();
+		XPath xpath = factory.newXPath();
+
+		xpath.setNamespaceContext(new NamespaceContext() {
+
+			@SuppressWarnings("rawtypes")
+			public Iterator getPrefixes(String namespaceURI) {
+				throw new UnsupportedOperationException();
+			}
+
+			public String getPrefix(String namespaceURI) {
+				throw new UnsupportedOperationException();
+			}
+
+			public String getNamespaceURI(String prefix) {
+				String xmlns = doc.lookupNamespaceURI(prefix);
+				if (StringUtils.isBlank(xmlns)) {
+					xmlns = nsMap.get(prefix);
+				}
+				return xmlns;
+			}
+		});
+
+		XPathExpression expr = xpath.compile(expression);
+
+		return expr.evaluate(doc, returnType);
+	}
+
+	/**
+	 * 将document对象写入filename文件
+	 * 
+	 * @param doc
+	 *            目标对象
+	 * @param filename
+	 *            输出文件名称
+	 */
+	public static void writeXmlFile(Document doc, String filename) {
+		try {
+			// Prepare the DOM document for writing
+			Source source = new DOMSource(doc);
+
+			// Prepare the output file
+			File file = new File(filename);
+			Result result = new StreamResult(file);
+
+			// Write the DOM document to the file
+			Transformer xformer = TransformerFactory.newInstance()
+					.newTransformer();
+			xformer.setOutputProperty(OutputKeys.INDENT, "yes");
+			xformer.transform(source, result);
+		} catch (TransformerException e) {
+			LOGGER.warn("document对象写入文件失败", e);
+		}
+	}
+
+	public static DocumentBuilder getParser()
+			throws ParserConfigurationException {
+		return getDocumentBuilderFactory().newDocumentBuilder();
+	}
+
+	public static Document parse(InputSource is)
+			throws ParserConfigurationException, SAXException, IOException {
+		return getParser().parse(is);
+	}
+
+	public static Document parse(File is) throws ParserConfigurationException,
+			SAXException, IOException {
+		return getParser().parse(is);
+	}
+
+	public static Document parse(InputStream in)
+			throws ParserConfigurationException, SAXException, IOException {
+		if (in == null) {
+			LOGGER.warn("XMLUtils trying to parse a null inputstream");
+		}
+		return getParser().parse(in);
+	}
+
+	public static Document parse(String in)
+			throws ParserConfigurationException, SAXException, IOException {
+		return parse(in.getBytes());
+	}
+
+	public static Document parse(byte[] in)
+			throws ParserConfigurationException, SAXException, IOException {
+		if (in == null) {
+			LOGGER.warn("XMLUtils trying to parse a null bytes");
+			return null;
+		}
+		return getParser().parse(new ByteArrayInputStream(in));
+	}
+
+	private static DocumentBuilderFactory getDocumentBuilderFactory() {
+		ClassLoader loader = Thread.currentThread().getContextClassLoader();
+		if (loader == null) {
+			loader = XmlUtil.class.getClassLoader();
+		}
+		if (loader == null) {
+			return DocumentBuilderFactory.newInstance();
+		}
+		DocumentBuilderFactory factory = DOCUMENT_BUILDER_FACTORIES.get(loader);
+		if (factory == null) {
+			factory = DocumentBuilderFactory.newInstance();
+			factory.setNamespaceAware(true);
+			DOCUMENT_BUILDER_FACTORIES.put(loader, factory);
+		}
+		return factory;
+	}
+}

+ 17 - 0
toolset/codegen/src/main/resources/generateConfigration.xml

@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<GenerateConfiguration>
+	<dbConfiguration>
+		<driverClass>com.mysql.jdbc.Driver</driverClass>
+		<url>jdbc:mysql://47.114.1.200:3306/mec_dev</url>
+		<username>mec_dev</username>
+		<password>dayaDataOnline@2019</password>
+		<catalog>mec_dev</catalog>
+		<schema>mec_dev</schema>
+	</dbConfiguration>
+	<srcBase>/Users/chenxiaoyu/Documents/javabean</srcBase>
+	<pojoPackageName>com.ym.mec.biz.dal.entity</pojoPackageName>
+	<daoPackageName>com.ym.mec.biz.dal.dao</daoPackageName>
+	<servicePackageName>com.ym.mec.biz.service</servicePackageName>
+	<sqlmapPackageName>resources</sqlmapPackageName>
+	<sqlmapConfigPackageName>resources/config</sqlmapConfigPackageName>
+</GenerateConfiguration>

+ 10 - 0
toolset/codegen/src/main/resources/template/dao.ftl

@@ -0,0 +1,10 @@
+[#ftl]
+package ${daoPackageName};
+
+import com.ym.mec.common.dal.BaseDAO;
+import ${pojoFullClassName};
+
+public interface ${className}Dao [#if paramType??]extends BaseDAO<${paramType}, ${className}>[/#if] {
+
+	
+}

+ 44 - 0
toolset/codegen/src/main/resources/template/pojo.ftl

@@ -0,0 +1,44 @@
+[#ftl]
+package ${table.packageName};
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+/**
+ * 对应数据库表(${table.name}):${table.remarks}
+ */
+public class ${table.className} {
+
+	[#list props as prop]
+	[#if prop.remarks??]
+	/** ${prop.remarks} */
+	[/#if]
+	private ${prop.javaTypeName} ${prop.propertyName};
+	
+	[/#list]
+	[#list props as prop]
+		[#if prop.javaTypeName == 'boolean']
+	public void set${prop.propertyName?cap_first}(${prop.javaTypeName} ${prop.propertyName}){
+		this.${prop.propertyName} = ${prop.propertyName};
+	}
+	
+	public boolean is${prop.propertyName?cap_first}(){
+		return this.${prop.propertyName};
+	}
+			
+		[#else]
+	public void set${prop.propertyName?cap_first}(${prop.javaTypeName} ${prop.propertyName}){
+		this.${prop.propertyName} = ${prop.propertyName};
+	}
+	
+	public ${prop.javaTypeName} get${prop.propertyName?cap_first}(){
+		return this.${prop.propertyName};
+	}
+			
+		[/#if]
+	[/#list]
+	@Override
+	public String toString() {
+		return ToStringBuilder.reflectionToString(this);
+	}
+
+}

+ 9 - 0
toolset/codegen/src/main/resources/template/service.ftl

@@ -0,0 +1,9 @@
+[#ftl]
+package ${servicePackageName};
+
+import ${pojoFullClassName};
+import com.ym.mec.common.service.BaseService;
+
+public interface ${className}Service extends BaseService<${paramType}, ${className}> {
+
+}

+ 22 - 0
toolset/codegen/src/main/resources/template/service_impl.ftl

@@ -0,0 +1,22 @@
+[#ftl]
+package ${servicePackageName}.impl;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import com.ym.mec.common.service.impl.BaseServiceImpl;
+import ${pojoFullClassName};
+import ${servicePackageName}.${className}Service;
+import ${daoPackageName}.${className}Dao;
+
+@Service
+public class ${className}ServiceImpl extends BaseServiceImpl<${paramType}, ${className}>  implements ${className}Service {
+	
+	[#assign daoName = className + 'Dao']
+	@Autowired
+	private ${daoName} ${daoName?uncap_first};
+
+	@Override
+	public BaseDAO<${paramType}, ${className}> getDAO() {
+		return ${daoName?uncap_first};
+	}
+	
+}

+ 36 - 0
toolset/codegen/src/main/resources/template/spring.ftl

@@ -0,0 +1,36 @@
+[#ftl]
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+This file is auto generated by Ant & FreeMarker.
+DO NOT MODIFY IT.All modified content will be lost when next auto generate.
+这个文件是用ANT和FreeMarker自动生成的。
+不要修改此文件。所有改动将在下次重新自动生成时丢失。
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
+	xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
+	xmlns:context="http://www.springframework.org/schema/context"
+	xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"
+	default-autowire="byName">
+
+	[#-- 
+	<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
+		<property name="configLocation" value="${sqlmapConfigPackageName}/SqlMap_Config.xml" />
+		<property name="dataSource" ref ="${r"${dataSource}"}" />
+	</bean>
+	--]
+	
+	
+	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
+		<property name="dataSource" ref="dataSource" />
+		<property name="configLocation" value="classpath:SqlMapConfig.xml" />
+	</bean>
+	
+	[#list tables as table]
+	<bean id="${table.className?uncap_first}Dao" class="org.mybatis.spring.mapper.MapperFactoryBean">
+		<property name="mapperInterface" value="${daoPackageName}.${table.className}Dao" />
+		<property name="sqlSessionFactory" ref="sqlSessionFactory" />
+	</bean>
+	
+	[/#list]
+</beans>

+ 64 - 0
toolset/codegen/src/main/resources/template/sqlmap.ftl

@@ -0,0 +1,64 @@
+[#ftl]
+<?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="${namespace}">
+	
+	<resultMap type="${fullClassName}" id="${alias}">
+	[#list columns as col]
+		<result column="${col.fieldName}" property="${col.propertyName}" />
+	[/#list]
+	</resultMap>
+	
+	[#if querySingleSQL??]
+	<!-- 根据主键查询一条记录 -->
+	<select id="get" resultMap="${alias}" [#if paramType??]parameterType="${paramType}"[/#if]>
+		${querySingleSQL}
+	</select>
+	[/#if]
+	
+	<!-- 全查询 -->
+	<select id="findAll" resultMap="${alias}">
+		${queryFullSQL}
+	</select>
+	
+	<!-- 向数据库增加一条记录 -->
+	<insert id="insert" parameterType="${fullClassName}" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
+		<!--
+		<selectKey resultClass="int" keyProperty="id" > 
+		SELECT SEQ_WSDEFINITION_ID.nextval AS ID FROM DUAL 
+		</selectKey>
+		-->
+		${insertSQL}
+	</insert>
+	
+	[#if updateSQL??]
+	<!-- 根据主键查询一条记录 -->
+	<update id="update" parameterType="${fullClassName}">
+		${updateSQL}
+	</update>
+	[/#if]
+	
+	[#if deleteSQL??]
+	<!-- 根据主键删除一条记录 -->
+	<delete id="delete" [#if paramType??]parameterType="${paramType}"[/#if]>
+		${deleteSQL}
+	</delete>
+	[/#if]
+	
+	[#if queryPage??]
+	<!-- 分页查询 -->
+	<select id="queryPage" resultMap="${alias}" parameterType="map">
+		${queryPage}
+	</select>
+	[/#if]
+	
+	<!-- 查询当前表的总记录数 -->
+	<select id="queryCount" resultType="int">
+		SELECT COUNT(*) FROM ${tableName}
+	</select>
+</mapper>
+ 

+ 11 - 0
toolset/codegen/src/main/resources/template/sqlmapConfig.ftl

@@ -0,0 +1,11 @@
+[#ftl]
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD SQL Map Config 3.0//EN"  
+	"http://mybatis.org/dtd/mybatis-3-config.dtd">
+<configuration>
+	<mappers>
+	[#list tables as table]
+		<mapper resource="${sqlmapPackageName?replace(".","/")}/SqlMap_${table.name}.xml" />
+	[/#list]
+	</mappers>
+</configuration>

+ 44 - 0
toolset/dynamic-datasource/pom.xml

@@ -0,0 +1,44 @@
+<?xml version="1.0"?>
+<project
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+	xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<groupId>com.yonge.toolset</groupId>
+		<artifactId>toolset</artifactId>
+		<version>1.0</version>
+	</parent>
+	<groupId>com.yonge.toolset</groupId>
+	<artifactId>dynamic-datasource</artifactId>
+	<version>1.0</version>
+	<name>dynamic-datasource</name>
+	<url>http://maven.apache.org</url>
+	<properties>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+	</properties>
+
+	<dependencies>
+
+		<dependency>
+			<groupId>org.mybatis.spring.boot</groupId>
+			<artifactId>mybatis-spring-boot-starter</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>com.alibaba</groupId>
+			<artifactId>druid-spring-boot-starter</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>javax.servlet</groupId>
+			<artifactId>javax.servlet-api</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>org.apache.commons</groupId>
+			<artifactId>commons-lang3</artifactId>
+			<version>3.8.1</version>
+		</dependency>
+
+	</dependencies>
+</project>

+ 73 - 0
toolset/dynamic-datasource/src/main/java/com/yonge/toolset/datasource/DataSourceConfig.java

@@ -0,0 +1,73 @@
+package com.yonge.toolset.datasource;
+
+import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
+
+import org.mybatis.spring.SqlSessionFactoryBean;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+import org.springframework.jdbc.datasource.DataSourceTransactionManager;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+import javax.sql.DataSource;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@EnableTransactionManagement
+@Configuration
+@MapperScan("com.yonge.datasource.dao")
+public class DataSourceConfig {
+
+	@Value("${mybatis.mapperLocations}")
+	private String resourcePath;
+	@Value("${mybatis.typeAliasesPackage}")
+	private String typeAliasesPackage;
+	@Value("${mybatis.configLocation}")
+	private Resource configLocation;
+
+	@Bean("master")
+	@Primary
+	@ConfigurationProperties(prefix = "spring.datasource") // application.yml中对应属性的前缀
+	public DataSource master() {
+		return DruidDataSourceBuilder.create().build();
+	}
+
+	@Bean("dynamicDataSource")
+	public DataSource dynamicDataSource() {
+		DynamicRoutingDataSource dynamicDataSource = new DynamicRoutingDataSource();
+		Map<Object, Object> dataSourceMap = new HashMap<>();
+		dataSourceMap.put("master", master());
+		// 将 master 数据源作为默认指定的数据源
+		dynamicDataSource.setDefaultTargetDataSource(master());
+		dynamicDataSource.setTargetDataSources(dataSourceMap);
+		return dynamicDataSource;
+	}
+	@Bean
+	public SqlSessionFactoryBean sqlSessionFactoryBean() throws Exception {
+		SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
+		// 配置动态数据源,如果没有将 dynamicDataSource 作为数据源则不能实现切换
+		sqlSessionFactoryBean.setDataSource(dynamicDataSource());
+		
+		PathMatchingResourcePatternResolver pmrpr = new PathMatchingResourcePatternResolver();
+		
+		sqlSessionFactoryBean.setMapperLocations(pmrpr.getResources(resourcePath));
+		sqlSessionFactoryBean.setTypeAliasesPackage(typeAliasesPackage);
+		sqlSessionFactoryBean.setConfigLocation(configLocation);
+
+		return sqlSessionFactoryBean;
+	}
+
+	@Bean
+	public PlatformTransactionManager transactionManager() {
+		// 配置事务管理, 使用事务时在方法头部添加@Transactional注解即可
+		return new DataSourceTransactionManager(dynamicDataSource());
+	}
+
+}

+ 46 - 0
toolset/dynamic-datasource/src/main/java/com/yonge/toolset/datasource/DataSourceContextHolder.java

@@ -0,0 +1,46 @@
+package com.yonge.toolset.datasource;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+public class DataSourceContextHolder {
+	
+	public final static String TENANT_ID = "master";
+
+	private static final ThreadLocal<Object> contextHolder = new ThreadLocal<Object>() {
+		@Override
+		protected String initialValue() {
+			return TENANT_ID;
+		}
+	};
+
+	public static List<Object> dataSourceKeys = new ArrayList<Object>();
+
+	public static void setDataSourceKey(String key) {
+		contextHolder.set(key);
+	}
+
+	/**
+	 * 获取数据源
+	 * @return
+	 */
+	public static Object getDataSourceKey() {
+		return contextHolder.get();
+	}
+
+	/**
+	 * 重置数据源
+	 */
+	public static void clearDataSourceKey() {
+		contextHolder.remove();
+	}
+
+	public static boolean containDataSourceKey(Object key) {
+		return dataSourceKeys.contains(key);
+	}
+
+	public static boolean addDataSourceKeys(Collection<? extends Object> keys) {
+		return dataSourceKeys.addAll(keys);
+	}
+}

+ 22 - 0
toolset/dynamic-datasource/src/main/java/com/yonge/toolset/datasource/DynamicRoutingDataSource.java

@@ -0,0 +1,22 @@
+package com.yonge.toolset.datasource;
+
+import java.util.Map;
+
+import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
+
+public class DynamicRoutingDataSource extends AbstractRoutingDataSource {
+
+	@Override
+	protected Object determineCurrentLookupKey() {
+		return DataSourceContextHolder.getDataSourceKey();
+	}
+
+	@Override
+	public void setTargetDataSources(Map<Object, Object> targetDataSources) {
+		super.setTargetDataSources(targetDataSources);
+		
+		// 将数据源的 key 放到数据源上下文的 key 集合中
+		DataSourceContextHolder.addDataSourceKeys(targetDataSources.keySet());
+	}
+
+}

+ 56 - 0
toolset/dynamic-datasource/src/main/java/com/yonge/toolset/datasource/dao/DatabaseSourceDao.java

@@ -0,0 +1,56 @@
+package com.yonge.toolset.datasource.dao;
+
+import java.util.List;
+import java.util.Map;
+
+import com.yonge.toolset.datasource.entity.DatabaseSource;
+
+
+public interface DatabaseSourceDao  {
+
+	/**
+	 * 通过主键id获取对象
+	 * @param id
+	 * @return DatabaseSource
+	 */
+	public DatabaseSource geDatabaseSource(final Integer id);
+
+	/**
+	 * 更新实体对象
+	 * @param bean
+	 * @return inDatabaseSource
+	 */
+	public int updaDatabaseSourcee(DatabaseSource bean);
+
+	/**
+	 * 通过主键id删除对象
+	 * @param id
+	 * @return inDatabaseSource
+	 */
+	public int deleDatabaseSourcee(final Integer id);
+	
+	/**
+	 * 写入实体对象
+	 * @param bean
+	 * @return inDatabaseSource
+	 */
+	public long inserDatabaseSource(DatabaseSource bean);
+	/**
+	 * 通过参数查找所有结果集
+	 * @param params
+	 * @return
+	 */
+	public List<DatabaseSource> findAll(Map<String, Object> params);
+	/**
+	 * 通过参数查找结果集,适合分页场景
+	 * @param params
+	 * @return
+	 */
+	public List<DatabaseSource> queryPage(Map<String, Object> params);
+	/**
+	 * 通过参数查找结果集数目
+	 * @param params
+	 * @return
+	 */
+	public int queryCounDatabaseSource(Map<String, Object> params);
+}

+ 125 - 0
toolset/dynamic-datasource/src/main/java/com/yonge/toolset/datasource/entity/DatabaseSource.java

@@ -0,0 +1,125 @@
+package com.yonge.toolset.datasource.entity;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+/**
+ * 对应数据库表(database_source):
+ */
+public class DatabaseSource {
+
+	/**  */
+	private Integer id;
+	
+	/** 租户ID */
+	private String tenantId;
+	
+	/** 驱动 */
+	private String driver;
+	
+	/** 连接信息 */
+	private String url;
+	
+	/** 用户名 */
+	private String username;
+	
+	/** 密码 */
+	private String password;
+	
+	/** 数据库类型 */
+	private String type;
+	
+	/**  */
+	private String memo;
+	
+	/**  */
+	private java.util.Date createTime;
+	
+	/**  */
+	private java.util.Date updateTime;
+	
+	public void setId(Integer id){
+		this.id = id;
+	}
+	
+	public Integer getId(){
+		return this.id;
+	}
+			
+	public void setTenantId(String tenantId){
+		this.tenantId = tenantId;
+	}
+	
+	public String getTenantId(){
+		return this.tenantId;
+	}
+			
+	public void setDriver(String driver){
+		this.driver = driver;
+	}
+	
+	public String getDriver(){
+		return this.driver;
+	}
+			
+	public void setUrl(String url){
+		this.url = url;
+	}
+	
+	public String getUrl(){
+		return this.url;
+	}
+			
+	public void setUsername(String username){
+		this.username = username;
+	}
+	
+	public String getUsername(){
+		return this.username;
+	}
+			
+	public void setPassword(String password){
+		this.password = password;
+	}
+	
+	public String getPassword(){
+		return this.password;
+	}
+			
+	public void setType(String type){
+		this.type = type;
+	}
+	
+	public String getType(){
+		return this.type;
+	}
+			
+	public void setMemo(String memo){
+		this.memo = memo;
+	}
+	
+	public String getMemo(){
+		return this.memo;
+	}
+			
+	public void setCreateTime(java.util.Date createTime){
+		this.createTime = createTime;
+	}
+	
+	public java.util.Date getCreateTime(){
+		return this.createTime;
+	}
+			
+	public void setUpdateTime(java.util.Date updateTime){
+		this.updateTime = updateTime;
+	}
+	
+	public java.util.Date getUpdateTime(){
+		return this.updateTime;
+	}
+			
+	@Override
+	public String toString() {
+		return ToStringBuilder.reflectionToString(this);
+	}
+
+}

+ 36 - 0
toolset/dynamic-datasource/src/main/java/com/yonge/toolset/datasource/interceptor/DataSourceInterceptor.java

@@ -0,0 +1,36 @@
+package com.yonge.toolset.datasource.interceptor;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
+
+import com.yonge.toolset.datasource.DataSourceContextHolder;
+
+public class DataSourceInterceptor extends HandlerInterceptorAdapter {
+
+	private static final String DATA_SOURCE_ID = "datasourceId";
+
+	@Override
+	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
+		String tenantId = request.getHeader(DATA_SOURCE_ID);
+		if (StringUtils.isBlank(tenantId)) {
+			tenantId = request.getParameter(DATA_SOURCE_ID);
+		}
+		if (StringUtils.isBlank(tenantId)) {
+			tenantId = (String) request.getAttribute(DATA_SOURCE_ID);
+		}
+		if(StringUtils.isNotBlank(tenantId)){
+			DataSourceContextHolder.setDataSourceKey(tenantId);
+		}
+
+		return true;
+	}
+
+	@Override
+	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
+		DataSourceContextHolder.clearDataSourceKey();
+	}
+
+}

+ 61 - 0
toolset/dynamic-datasource/src/main/java/com/yonge/toolset/datasource/interceptor/TenantSqlInterceptor.java

@@ -0,0 +1,61 @@
+package com.yonge.toolset.datasource.interceptor;
+
+import java.lang.reflect.Field;
+import java.util.Properties;
+
+import org.apache.ibatis.executor.statement.StatementHandler;
+import org.apache.ibatis.mapping.BoundSql;
+import org.apache.ibatis.mapping.MappedStatement;
+import org.apache.ibatis.mapping.SqlCommandType;
+import org.apache.ibatis.plugin.Interceptor;
+import org.apache.ibatis.plugin.Invocation;
+import org.apache.ibatis.plugin.Plugin;
+
+public class TenantSqlInterceptor implements Interceptor {
+
+	@Override
+	public Object intercept(Invocation invocation) throws Throwable {
+		StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
+		BoundSql boundSql = statementHandler.getBoundSql();
+		// HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+
+		// 获取 SQL 命令
+		MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
+		SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType();
+
+		// 获取参数
+		Object parameter = invocation.getArgs()[1];
+		
+		if (SqlCommandType.INSERT.equals(sqlCommandType) || SqlCommandType.UPDATE.equals(sqlCommandType)) {
+			
+		}
+
+		// 获取到原始sql语句
+		String originalSql = boundSql.getSql();
+		String lastSql = "";
+		String strsql = originalSql.replace(" ", "");
+		if (strsql.indexOf("cid=") == -1) {
+			if (originalSql.indexOf("where") != -1) {
+				lastSql = originalSql + " and tenant_id_ =";
+			} else {
+				lastSql = originalSql + " where and tenant_id_=";
+			}
+		}
+		// 通过反射修改sql语句
+		Field field = boundSql.getClass().getDeclaredField("sql");
+		field.setAccessible(true);
+		field.set(boundSql, lastSql);
+		return invocation.proceed();
+	}
+
+	@Override
+	public Object plugin(Object target) {
+		return Plugin.wrap(target, this);
+	}
+
+	@Override
+	public void setProperties(Properties properties) {
+
+	}
+
+}

+ 6 - 0
toolset/dynamic-datasource/src/main/java/com/yonge/toolset/datasource/service/DatabaseSourceService.java

@@ -0,0 +1,6 @@
+package com.yonge.toolset.datasource.service;
+
+
+public interface DatabaseSourceService {
+	
+}

+ 63 - 0
toolset/dynamic-datasource/src/main/java/com/yonge/toolset/datasource/service/impl/DatabaseSourceServiceImpl.java

@@ -0,0 +1,63 @@
+package com.yonge.toolset.datasource.service.impl;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Service;
+
+import com.alibaba.druid.pool.DruidDataSource;
+import com.yonge.toolset.datasource.DynamicRoutingDataSource;
+import com.yonge.toolset.datasource.dao.DatabaseSourceDao;
+import com.yonge.toolset.datasource.entity.DatabaseSource;
+import com.yonge.toolset.datasource.service.DatabaseSourceService;
+
+@Service
+public class DatabaseSourceServiceImpl implements DatabaseSourceService, ApplicationContextAware,
+		InitializingBean {
+	
+	private final static String DEFAULT_DATA_SOURCE_KEY = "master";
+
+	@Autowired
+	private DatabaseSourceDao databaseSourceDao;
+
+	private ApplicationContext applicationContext;
+
+	@Override
+	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+		this.applicationContext = applicationContext;
+	}
+
+	@Override
+	public void afterPropertiesSet() throws Exception {
+
+		DynamicRoutingDataSource dynamicDataSource = (DynamicRoutingDataSource) applicationContext.getBean("dynamicDataSource");
+		DruidDataSource master = (DruidDataSource) applicationContext.getBean(DEFAULT_DATA_SOURCE_KEY);
+		Map<Object, Object> dataSourceMap = new HashMap<>();
+		dataSourceMap.put("master", master);
+
+		List<DatabaseSource> dbSourceList = databaseSourceDao.findAll(null);
+		for (DatabaseSource ds : dbSourceList) {
+			DruidDataSource dataSource = new DruidDataSource();
+
+			dataSource.setDriverClassName(ds.getDriver());
+			dataSource.setUrl(ds.getUrl());
+			dataSource.setUsername(ds.getUsername());
+			dataSource.setPassword(ds.getPassword());
+			dataSource.setConnectProperties(master.getConnectProperties());
+
+			dataSourceMap.put(ds.getTenantId(), dataSource);
+		}
+
+		dynamicDataSource.setTargetDataSources(dataSourceMap);
+
+		// 必须执行此操作,才会重新初始化AbstractRoutingDataSource 中的 resolvedDataSources,也只有这样,动态切换才会起效
+		dynamicDataSource.afterPropertiesSet();
+	}
+
+}

+ 95 - 0
toolset/dynamic-datasource/src/main/resources/config/mybatis/DatabaseSourceMapper.xml

@@ -0,0 +1,95 @@
+<?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.yonge.datasource.dao.DatabaseSourceDao">
+
+	<resultMap type="com.yonge.datasource.entity.DatabaseSource"
+		id="DatabaseSource">
+		<result column="id_" property="id" />
+		<result column="tenant_id_" property="tenantId" />
+		<result column="driver_" property="driver" />
+		<result column="url_" property="url" />
+		<result column="username_" property="username" />
+		<result column="password_" property="password" />
+		<result column="type_" property="type" />
+		<result column="memo_" property="memo" />
+		<result column="create_time_" property="createTime" />
+		<result column="update_time_" property="updateTime" />
+	</resultMap>
+
+	<!-- 根据主键查询一条记录 -->
+	<select id="get" resultMap="DatabaseSource">
+		SELECT * FROM
+		database_source WHERE id_ = #{id}
+	</select>
+
+	<!-- 全查询 -->
+	<select id="findAll" resultMap="DatabaseSource">
+		SELECT * FROM database_source
+		ORDER BY id_
+	</select>
+
+	<!-- 向数据库增加一条记录 -->
+	<insert id="insert" parameterType="com.yonge.datasource.entity.DatabaseSource"
+		useGeneratedKeys="true" keyColumn="id" keyProperty="id">
+		<!-- <selectKey resultClass="int" keyProperty="id" > SELECT SEQ_WSDEFINITION_ID.nextval 
+			AS ID FROM DUAL </selectKey> -->
+		INSERT INTO database_source
+		(id_,tenant_id_,driver_,url_,username_,password_,type_,memo_,create_time_,update_time_)
+		VALUES(#{id},#{tenantId},#{driver},#{url},#{username},#{password},#{type},#{memo},#{createTime},#{updateTime})
+	</insert>
+
+	<!-- 根据主键查询一条记录 -->
+	<update id="update" parameterType="com.yonge.datasource.entity.DatabaseSource">
+		UPDATE database_source
+		<set>
+			<if test="driver != null">
+				driver_ = #{driver},
+			</if>
+			<if test="id != null">
+				id_ = #{id},
+			</if>
+			<if test="tenantId != null and tenantId != 0">
+				tenant_id_ = #{tenantId},
+			</if>
+			<if test="url != null">
+				url_ = #{url},
+			</if>
+			<if test="updateTime != null">
+				update_time_ = #{updateTime},
+			</if>
+			<if test="password != null">
+				password_ = #{password},
+			</if>
+			<if test="memo != null">
+				memo_ = #{memo},
+			</if>
+			<if test="username != null">
+				username_ = #{username},
+			</if>
+			<if test="type != null">
+				type_ = #{type},
+			</if>
+			<if test="createTime != null">
+				create_time_ = #{createTime},
+			</if>
+		</set>
+		WHERE id_ = #{id}
+	</update>
+
+	<!-- 根据主键删除一条记录 -->
+	<delete id="delete">
+		DELETE FROM database_source WHERE id_ =
+		#{id}
+	</delete>
+
+	<!-- 分页查询 -->
+	<select id="queryPage" resultMap="DatabaseSource" parameterType="map">
+		SELECT * FROM database_source ORDER BY id_
+	</select>
+
+	<!-- 查询当前表的总记录数 -->
+	<select id="queryCount" resultType="int">
+		SELECT COUNT(*) FROM database_source
+	</select>
+</mapper>

+ 30 - 0
toolset/mongo-db/pom.xml

@@ -0,0 +1,30 @@
+<?xml version="1.0"?>
+<project
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+	xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<groupId>com.yonge.toolset</groupId>
+		<artifactId>toolset</artifactId>
+		<version>1.0</version>
+	</parent>
+	<groupId>com.yonge.toolset</groupId>
+	<artifactId>mongo-db</artifactId>
+	<version>1.0</version>
+	<name>mongo-db</name>
+	<url>http://maven.apache.org</url>
+	<properties>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+	</properties>
+	<dependencies>
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-data-mongodb</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>com.yonge.toolset</groupId>
+			<artifactId>utils</artifactId>
+		</dependency>
+	</dependencies>
+</project>

+ 153 - 0
toolset/mongo-db/src/main/java/com/yonge/toolset/mongodb/PageInfo.java

@@ -0,0 +1,153 @@
+/**
+ * PageInfo.java 
+ * Copyright © 2015-2015
+ * 
+ * @author pengdc
+ * @create 2015年7月14日
+ */
+package com.yonge.toolset.mongodb;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 分页对象
+ */
+public class PageInfo<T> implements Serializable {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = -5951140453033647399L;
+
+	private int pageNo;
+	private int offset;
+	private int limit;
+	private long total = 0;
+	private int totalPage = 0;
+
+	/**
+	 * 分页信息
+	 */
+	protected List<T> rows = new ArrayList<T>();
+
+	protected List<T> footer = new ArrayList<T>();
+
+	/** 默认构造函数 */
+	public PageInfo() {
+	}
+
+	public PageInfo(Integer pageNo) {
+		if (pageNo == null || pageNo < 1)
+			pageNo = 1;
+		this.setPageNo(pageNo);
+	}
+
+	/** 构造函数 */
+	public PageInfo(Integer pageNo, int pageSize) {
+		if (pageNo == null || pageNo < 1)
+			pageNo = 1;
+		this.setPageNo(pageNo);
+		this.limit = pageSize;
+		this.offset = (pageNo - 1) * limit;
+	}
+
+	/**
+	 * 是否还有上一页
+	 * @return
+	 */
+	public boolean hasPre() {
+		return (pageNo > 1);
+	}
+
+	/**
+	 * 是否还有下一页.
+	 */
+	public boolean hasNext() {
+		return (pageNo < totalPage);
+	}
+
+	/**
+	 * 取得上页的页号, 序号从1开始. 当前页为首页时返回首页序号.
+	 */
+	public int getPrePage() {
+		if (hasPre()) {
+			return pageNo - 1;
+		} else {
+			return pageNo;
+		}
+	}
+
+	/**
+	 * 取得下页的页号, 序号从1开始. 当前页为尾页时仍返回尾页序号.
+	 */
+	public int getNextPage() {
+		if (hasNext()) {
+			return pageNo + 1;
+		} else {
+			return pageNo;
+		}
+	}
+
+	public int getPageNo() {
+		return pageNo;
+	}
+
+	public void setPageNo(int pageNo) {
+		if (pageNo > 0) {
+			this.pageNo = pageNo;
+		}
+	}
+
+	public int getOffset() {
+		return offset;
+	}
+
+	public void setOffset(int offset) {
+		this.offset = offset;
+	}
+
+	public int getLimit() {
+		return limit;
+	}
+
+	public void setLimit(int limit) {
+		this.limit = limit;
+	}
+
+	public void setTotalPage(int totalPage) {
+		this.totalPage = totalPage;
+	}
+
+	public int getTotalPage() {
+		return totalPage;
+	}
+
+	public long getTotal() {
+		return total;
+	}
+
+	public void setTotal(long total) {
+		this.total = total;
+		this.totalPage=new BigDecimal(total).divide(new BigDecimal(limit),0,BigDecimal.ROUND_CEILING).intValue();
+	}
+
+	public List<T> getRows() {
+		return rows;
+	}
+
+	public void setRows(List<T> rows) {
+		this.rows = rows;
+	}
+
+	public List<T> getFooter() {
+		return footer;
+	}
+
+	public void setFooter(List<T> footer) {
+		this.footer = footer;
+	}
+
+}

+ 79 - 0
toolset/mongo-db/src/main/java/com/yonge/toolset/mongodb/QueryInfo.java

@@ -0,0 +1,79 @@
+/**
+ * QueryInfo.java 
+ * Copyright © 2015-2015
+ * 
+ * @author pengdc
+ * @create 2015年7月14日
+ */
+package com.yonge.toolset.mongodb;
+
+/**
+ * 查询对象基类
+ */
+public class QueryInfo {
+	/**
+	 * 默认当前页码
+	 */
+	private int page = 1;
+	/**
+	 * 默认页码大小
+	 */
+	private int rows = 20;
+	/**
+	 * 默认排序列
+	 */
+	private String sort = "create_time_";
+	/**
+	 * 默认排序方向
+	 */
+	private String order = "desc";
+
+	public QueryInfo() {
+	}
+
+	public QueryInfo(int page, int rows, String sort, String order) {
+		super();
+		this.page = page;
+		this.rows = rows;
+		this.sort = sort;
+		this.order = order;
+	}
+
+	public QueryInfo(int page, int rows) {
+		super();
+		this.page = page;
+		this.rows = rows;
+	}
+
+	public int getPage() {
+		return page;
+	}
+
+	public void setPage(int page) {
+		this.page = page;
+	}
+
+	public int getRows() {
+		return rows;
+	}
+
+	public void setRows(int rows) {
+		this.rows = rows;
+	}
+
+	public String getSort() {
+		return sort;
+	}
+
+	public void setSort(String sort) {
+		this.sort = sort;
+	}
+
+	public String getOrder() {
+		return order;
+	}
+
+	public void setOrder(String order) {
+		this.order = order;
+	}
+}

+ 153 - 0
toolset/mongo-db/src/main/java/com/yonge/toolset/mongodb/dao/BaseDaoWithMongo.java

@@ -0,0 +1,153 @@
+package com.yonge.toolset.mongodb.dao;
+
+import java.io.Serializable;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.annotation.Resource;
+
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.data.mongodb.core.query.Update;
+
+import com.yonge.toolset.mongodb.PageInfo;
+
+public abstract class BaseDaoWithMongo<PK, T extends Serializable> {
+
+	@Resource
+	private MongoTemplate mongoTemplate;
+
+	public abstract Class<T> getClassEntity();
+
+	/**
+	 * 通过主键id获取对象
+	 * @param id
+	 * @return T
+	 */
+	public T get(PK id) {
+		Query query = new Query(Criteria.where("_id").is(id));
+		return mongoTemplate.findOne(query, getClassEntity());
+	}
+
+	/**
+	 * 更新实体对象
+	 * @param bean
+	 */
+	public long update(PK id, T bean) {
+		Query query = new Query(Criteria.where("_id").is(id));
+
+		Update update = new Update();
+
+		Field[] fieldList = bean.getClass().getDeclaredFields();
+		for (Field field : fieldList) {
+			field.setAccessible(true);
+			try {
+				update.set(field.getName(), field.get(bean));
+			} catch (IllegalArgumentException e) {
+				e.printStackTrace();
+			} catch (IllegalAccessException e) {
+				e.printStackTrace();
+			}
+		}
+
+		return mongoTemplate.updateFirst(query, update, getClassEntity()).getModifiedCount();
+	}
+
+	/**
+	 * 通过主键id删除对象
+	 * @param id
+	 */
+	public long delete(final PK id) {
+		Query query = new Query(Criteria.where("_id").is(id));
+		return mongoTemplate.remove(query, getClassEntity()).getDeletedCount();
+	}
+
+	/**
+	 * 写入实体对象
+	 * @param bean
+	 */
+	public void insert(T bean) {
+		mongoTemplate.insert(bean);
+	}
+
+	/**
+	 * 写入实体对象
+	 * @param batchBean
+	 * @param clazz
+	 */
+	public void batchInsert(List<T> batchBean, Class clazz) {
+		mongoTemplate.insert(batchBean,clazz);
+	}
+
+	/**
+	 * 通过参数查找所有结果集
+	 * @param params
+	 * @return
+	 */
+	public List<T> findAll(Map<String, Object> params) {
+		Query query = new Query();
+
+		Criteria criteria = new Criteria();
+		if (params != null) {
+			for (Entry<String, Object> entry : params.entrySet()) {
+				criteria.and(entry.getKey()).is(entry.getValue());
+			}
+		}
+		query.addCriteria(criteria);
+		return mongoTemplate.find(query, getClassEntity());
+	}
+
+	/**
+	 * 通过参数查找结果集,适合分页场景
+	 * @param params
+	 * @return
+	 */
+	public PageInfo<T> queryPage(int page, int size, Map<String, Object> params) {
+		PageInfo<T> pageInfo = new PageInfo<T>(page, size);
+
+		List<T> dataList = null;
+		long total = this.queryCount(params);
+		if (total > 0) {
+			pageInfo.setTotal(total);
+
+			Query query = new Query();
+			Criteria criteria = new Criteria();
+			if (params != null) {
+				for (Entry<String, Object> entry : params.entrySet()) {
+					criteria.and(entry.getKey()).is(entry.getValue());
+				}
+			}
+			query.addCriteria(criteria);
+			query.skip(pageInfo.getOffset()).limit(pageInfo.getLimit());
+			dataList = mongoTemplate.find(query, getClassEntity());
+		}
+		if (total == 0) {
+			dataList = new ArrayList<T>();
+		}
+		pageInfo.setRows(dataList);
+		return pageInfo;
+	}
+
+	/**
+	 * 通过参数查找结果集数目
+	 * @param params
+	 * @return
+	 */
+	public long queryCount(Map<String, Object> params) {
+		Query query = new Query();
+
+		Criteria criteria = new Criteria();
+		if (params != null) {
+			for (Entry<String, Object> entry : params.entrySet()) {
+				criteria.and(entry.getKey()).is(entry.getValue());
+			}
+		}
+		query.addCriteria(criteria);
+		return mongoTemplate.count(query, getClassEntity());
+	}
+}

+ 25 - 0
toolset/mongo-db/src/main/java/com/yonge/toolset/mongodb/service/BaseServiceWithMongo.java

@@ -0,0 +1,25 @@
+package com.yonge.toolset.mongodb.service;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+
+import com.yonge.toolset.mongodb.PageInfo;
+import com.yonge.toolset.mongodb.QueryInfo;
+
+public interface BaseServiceWithMongo<PK, T extends Serializable> {
+
+	public T get(PK id);
+	
+	public long update(PK id, T bean);
+	
+	public long delete(final PK id);
+	
+	public void insert(T bean);
+	
+	public List<T> findAll(Map<String, Object> params);
+	
+	public PageInfo<T> queryPage(QueryInfo queryInfo);
+	
+	public long queryCount(Map<String, Object> params);
+}

+ 75 - 0
toolset/mongo-db/src/main/java/com/yonge/toolset/mongodb/service/impl/BaseServiceImplWithMongo.java

@@ -0,0 +1,75 @@
+package com.yonge.toolset.mongodb.service.impl;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.yonge.toolset.mongodb.PageInfo;
+import com.yonge.toolset.mongodb.QueryInfo;
+import com.yonge.toolset.mongodb.dao.BaseDaoWithMongo;
+import com.yonge.toolset.mongodb.service.BaseServiceWithMongo;
+import com.yonge.toolset.utils.collection.MapUtil;
+
+public abstract class BaseServiceImplWithMongo<PK, T extends Serializable> implements BaseServiceWithMongo<PK, T> {
+
+	public abstract BaseDaoWithMongo<PK, T> getDAO();
+
+	public T get(PK id) {
+		return getDAO().get(id);
+	}
+
+	/**
+	 * 更新实体对象
+	 * @param bean
+	 */
+	public long update(PK id, T bean) {
+		return getDAO().update(id, bean);
+	}
+
+	/**
+	 * 通过主键id删除对象
+	 * @param id
+	 */
+	public long delete(final PK id) {
+		return getDAO().delete(id);
+	}
+
+	/**
+	 * 写入实体对象
+	 * @param bean
+	 */
+	public void insert(T bean) {
+		getDAO().insert(bean);
+	}
+
+	/**
+	 * 通过参数查找所有结果集
+	 * @param params
+	 * @return
+	 */
+	public List<T> findAll(Map<String, Object> params) {
+		return getDAO().findAll(params);
+	}
+
+	/**
+	 * 通过参数查找结果集,适合分页场景
+	 * @param params
+	 * @return
+	 */
+	public PageInfo<T> queryPage(QueryInfo queryInfo) {
+		Map<String, Object> params = new HashMap<String, Object>();
+		MapUtil.populateMap(params, queryInfo, "page", "rows", "sort", "order");
+		return getDAO().queryPage(queryInfo.getPage(), queryInfo.getRows(), params);
+	}
+
+	/**
+	 * 通过参数查找结果集数目
+	 * @param params
+	 * @return
+	 */
+	public long queryCount(Map<String, Object> params) {
+		return getDAO().queryCount(params);
+	}
+
+}

+ 35 - 0
toolset/pom.xml

@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<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>
+
+	<parent>
+		<groupId>com.yonge.cooleshow</groupId>
+		<artifactId>cooleshow</artifactId>
+		<version>1.0</version>
+	</parent>
+
+	<groupId>com.yonge.toolset</groupId>
+	<artifactId>toolset</artifactId>
+	<version>1.0</version>
+	<packaging>pom</packaging>
+
+	<name>toolset</name>
+	<url>http://maven.apache.org</url>
+
+	<properties>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+	</properties>
+
+	<dependencies>
+	</dependencies>
+	
+	<modules>
+		<module>audit-log</module>
+		<module>codegen</module>
+		<module>dynamic-datasource</module>
+		<module>thirdparty-component</module>
+		<module>utils</module>
+		<module>mongo-db</module>
+	</modules>
+</project>

BIN
toolset/thirdparty-component/libs/tech-sdk-2.1.20.jar


+ 68 - 0
toolset/thirdparty-component/pom.xml

@@ -0,0 +1,68 @@
+<?xml version="1.0"?>
+<project
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+	xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+	<modelVersion>4.0.0</modelVersion>
+	
+	<parent>
+		<groupId>com.yonge.toolset</groupId>
+		<artifactId>toolset</artifactId>
+		<version>1.0</version>
+	</parent>
+	<groupId>com.yonge.toolset</groupId>
+	<artifactId>thirdparty-component</artifactId>
+	<version>1.0</version>
+	<name>thirdparty-component</name>
+	<url>http://maven.apache.org</url>
+	<properties>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+	</properties>
+	<dependencies>
+
+		<dependency>
+			<groupId>com.yonge.toolset</groupId>
+			<artifactId>utils</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>com.aliyun.oss</groupId>
+			<artifactId>aliyun-sdk-oss</artifactId>
+			<version>2.8.3</version>
+		</dependency>
+
+		<dependency>
+			<groupId>org.apache.commons</groupId>
+			<artifactId>commons-email</artifactId>
+			<version>1.5</version>
+		</dependency>
+
+		<dependency>
+			<groupId>org.springframework.cloud</groupId>
+			<artifactId>spring-cloud-starter-openfeign</artifactId>
+		</dependency>
+		<!-- https://mvnrepository.com/artifact/io.github.openfeign.form/feign-form-spring -->
+		<dependency>
+			<groupId>io.github.openfeign.form</groupId>
+			<artifactId>feign-form-spring</artifactId>
+		</dependency>
+		<!-- https://mvnrepository.com/artifact/io.github.openfeign.form/feign-form-spring -->
+		<dependency>
+			<groupId>io.github.openfeign.form</groupId>
+			<artifactId>feign-form-spring</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>com.ksyun</groupId>
+			<artifactId>ks3-kss-java-sdk</artifactId>
+			<version>0.8.14</version>
+		</dependency>
+		
+		<dependency>
+			<groupId>com.timevale</groupId>
+			<artifactId>tech-sdk</artifactId>
+			<version>2.1.20</version>
+			<scope>system</scope>
+			<systemPath>${project.basedir}/libs/tech-sdk-2.1.20.jar</systemPath>
+		</dependency>
+	</dependencies>
+</project>

+ 96 - 0
toolset/thirdparty-component/src/main/java/com/ym/mec/thirdparty/entity/SysEmail.java

@@ -0,0 +1,96 @@
+package com.ym.mec.thirdparty.entity;
+
+import java.io.Serializable;
+
+/**
+ * (SysEmail)表实体类
+ *
+ * @author makejava
+ * @since 2022-01-04 17:07:43
+ */
+public class SysEmail implements Serializable {
+    private Integer id;
+    
+    private String hostName;
+    
+    private Integer smtpPort;
+    
+    private String userName;
+    
+    private String password;
+    
+    private String from;
+    
+    private String fromName;
+    
+    private Integer tenantId;
+    
+    private static final long serialVersionUID = 1L;
+    
+    public Integer getId() {
+        return id;
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    public String getHostName() {
+        return hostName;
+    }
+
+    public void setHostName(String hostName) {
+        this.hostName = hostName;
+    }
+
+    public Integer getSmtpPort() {
+        return smtpPort;
+    }
+
+    public void setSmtpPort(Integer smtpPort) {
+        this.smtpPort = smtpPort;
+    }
+
+    public String getUserName() {
+        return userName;
+    }
+
+    public void setUserName(String userName) {
+        this.userName = userName;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    public String getFrom() {
+        return from;
+    }
+
+    public void setFrom(String from) {
+        this.from = from;
+    }
+
+    public String getFromName() {
+        return fromName;
+    }
+
+    public void setFromName(String fromName) {
+        this.fromName = fromName;
+    }
+
+    public Integer getTenantId() {
+        return tenantId;
+    }
+
+    public void setTenantId(Integer tenantId) {
+        this.tenantId = tenantId;
+    }
+
+
+}
+

+ 103 - 0
toolset/thirdparty-component/src/main/java/com/ym/mec/thirdparty/eseal/ESealPlugin.java

@@ -0,0 +1,103 @@
+package com.ym.mec.thirdparty.eseal;
+
+public interface ESealPlugin {
+
+    /**
+     * 创建用户账户(个人)
+     *
+     * @param realName 姓名
+     * @param idcard   身份证号码
+     * @param mobile   手机号码
+     * @return 账户唯一标识
+     */
+    public String createUserAccount(String realName, String idcard, String mobile);
+    
+    /**
+     * 更新用户账户(个人)
+     * @param accountId 账户唯一标识
+     * @param realName 姓名
+     * @param idcard 身份证号码
+     * @param mobile 手机号码
+     * @return
+     */
+    public boolean updateUserAccount(String accountId, String realName, String idcard, String mobile);
+
+    /**
+     * 创建用户账户(企业)
+     *
+     * @param orgName   机构名称
+     * @param organCode 统一社会信用代码
+     * @return 账户唯一标识
+     */
+    public String createOrganAccount(String orgName, String organCode);
+
+    /**
+     * 修改用户账户(企业)
+     *
+     * @param accountId   账户唯一标识
+     * @param orgName   机构名称
+     * @param organCode 统一社会信用代码
+     * @return
+     */
+    public boolean updateOrganAccount(String accountId, String orgName, String organCode);
+
+    /**
+     * 创建个人印章
+     *
+     * @param accountId 账户唯一标识
+     * @return 电子印章数据
+     */
+    public String createUserSeal(String accountId);
+
+    /**
+     * 创建企业印章
+     *
+     * @param accountId 账户唯一标识
+     * @param hText     生成印章中的横向文内容
+     * @param qText     生成印章中的下弦文内容
+     * @return 电子印章数据
+     */
+    public String createOrganSeal(String accountId, String hText, String qText);
+
+    /**
+     * 平台自身PDF摘要签署(印章标识)
+     *
+     * @param srcPdfPath  源文件
+     * @param destPdfPath 签名后的目标文件
+     * @return
+     */
+    public boolean platformSign(String srcPdfPath, String destPdfPath);
+
+    /**
+     * 企业PDF摘要签署(印章图片)
+     *
+     * @param sealData    电子印章数据
+     * @param srcPdfPath  源文件
+     * @param destPdfPath 签名后的目标文件
+     * @return
+     */
+    public boolean organSign(String sealData, String srcPdfPath, String destPdfPath);
+
+    /**
+     * 用户签名
+     *
+     * @param accountId   账户唯一标识
+     * @param sealData    电子印章数据
+     * @param srcPdfPath  平台签名后的源文件
+     * @param destPdfPath 平台、用户都签名后的文件地址
+     * @return
+     */
+    public boolean userSign(String accountId, String sealData, String srcPdfPath, String destPdfPath);
+
+    /**
+     * 用户签名
+     *
+     * @param accountId   账户唯一标识
+     * @param sealData    电子印章数据
+     * @param keyWorld    印章关键字
+     * @param srcPdfPath  平台签名后的源文件
+     * @param destPdfPath 平台、用户都签名后的文件地址
+     * @return
+     */
+     boolean userSign(String accountId, String sealData, String keyWorld, String srcPdfPath, String destPdfPath);
+}

+ 65 - 0
toolset/thirdparty-component/src/main/java/com/ym/mec/thirdparty/eseal/ESealPluginContext.java

@@ -0,0 +1,65 @@
+package com.ym.mec.thirdparty.eseal;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+
+import com.ym.mec.thirdparty.eseal.provider.TsignPlugin;
+import com.ym.mec.thirdparty.exception.ThirdpartyException;
+
+@Component
+public class ESealPluginContext implements ApplicationContextAware, InitializingBean {
+	
+	@Value("${thirdparty.eSealPluginName:Tsign}")
+	private String eSealPluginName;
+	
+	private ApplicationContext applicationContext;
+
+	private final Map<String, String> mapper = new HashMap<String, String>() {
+		/**
+		 * 
+		 */
+		private static final long serialVersionUID = -9071481806931421021L;
+
+		{
+			put(TsignPlugin.getName(), StringUtils.uncapitalize(TsignPlugin.class.getSimpleName()));
+		}
+	};
+
+	private ESealPlugin eSealPlugin;
+
+	@Override
+	public void afterPropertiesSet() throws Exception {
+		if (StringUtils.isBlank(eSealPluginName)) {
+			throw new ThirdpartyException("存储插件变量thirdparty.eSealPluginName不能为空");
+		}
+
+		eSealPlugin = getStoragePlugin(eSealPluginName);
+
+		if (eSealPlugin == null) {
+			throw new ThirdpartyException("电子签章插件{}不存在", eSealPluginName);
+		}
+	}
+
+	@Override
+	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+		this.applicationContext = applicationContext;
+	}
+
+	private ESealPlugin getStoragePlugin(String vendors) {
+		String beanId = mapper.get(vendors);
+
+		if (StringUtils.isBlank(beanId)) {
+			throw new ThirdpartyException("电子签章提供商不存在");
+		}
+
+		return applicationContext.getBean(beanId, ESealPlugin.class);
+	}
+}

+ 177 - 0
toolset/thirdparty-component/src/main/java/com/ym/mec/thirdparty/eseal/provider/BytedancePlugin.java

@@ -0,0 +1,177 @@
+package com.ym.mec.thirdparty.eseal.provider;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.codec.digest.DigestUtils;
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Value;
+
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson.JSONPath;
+import com.ym.mec.thirdparty.exception.ThirdpartyException;
+import com.yonge.toolset.utils.http.HttpUtil;
+import com.yonge.toolset.utils.sort.SortUtil;
+import com.yonge.toolset.utils.string.ValueUtil;
+
+public class BytedancePlugin implements InitializingBean, DisposableBean {
+
+	@Value("${eseal.bytedance.projectid:E6894439939350463244}")
+	public String projectId = "E6894439939350463244";
+
+	@Value("${eseal.bytedance.projectSecret:F%#1*#3^z61GEvH0Nf2N1u68v!vvU5n9C^3RE!z3Q^H$UD3521625&&q!H43QnNf}")
+	public String projectSecret = "F%#1*#3^z61GEvH0Nf2N1u68v!vvU5n9C^3RE!z3Q^H$UD3521625&&q!H43QnNf";
+
+	@Value("${eseal.bytedance.apisUrl:http://sandbox.letsign.com}")
+	public String apisUrl = "http://sandbox.letsign.com";
+
+	public static String getName() {
+		return "ByteDance";
+	}
+
+	@Override
+	public void afterPropertiesSet() throws Exception {
+
+	}
+
+	@Override
+	public void destroy() throws Exception {
+
+	}
+
+	/**
+	 * 创建用户账户(个人)
+	 * @param userId 用户编号
+	 * @param realName 姓名
+	 * @param idcard 身份证号码
+	 * @param mobile 手机号码
+	 * @return 账户唯一标识
+	 * @throws IOException 
+	 */
+	public String createUserAccount(String userId, String realName, String idcard, String mobile) throws IOException {
+		String path = "/open-api/certification/noUser/person3/";
+		String url = apisUrl + path;
+		Map<String, Object> params = new HashMap<String, Object>();
+
+		// 基础参数
+		params.put("appCode", projectId);
+		params.put("timestamp", "" + System.currentTimeMillis());
+		params.put("version", "v1");
+
+		// 业务参数
+		params.put("personOpenCode", userId);
+		params.put("personMobile", mobile);
+		params.put("personName", realName);
+		params.put("personIdCard", idcard);
+
+		// token
+		String token = generateToken(params, projectSecret);
+		params.put("token", token);
+
+		params.put("personIdCardFrontFile", "");
+		params.put("personIdCardBackFile", "");
+
+		String result = HttpUtil.postForHttp(url, params);
+		System.out.println(result);
+
+		JSONObject jsonObject = JSONObject.parseObject(result);
+		if (jsonObject.getInteger("code") == 0) {
+			return userId;
+		}
+		throw new ThirdpartyException("创建个人账户失败:{}", jsonObject.getString("description"));
+	}
+
+	/**
+	 * 创建用户账户(企业)
+	 * @param orgName  机构名称
+	 * @param organCode 统一社会信用代码
+	 * @return e签宝账户唯一标识
+	 */
+	public String createOrganAccount(String orgName, String organCode) {
+
+		return null;
+	}
+
+	/**
+	 * 文件上传
+	 * @param contractFile 协议文件
+	 * @param userId 用户账号
+	 * @return
+	 * @throws IOException
+	 */
+	public String uploadFile(File contractFile, String userId) throws IOException {
+		String path = "/open-api/contract/opt/upload";
+		String url = apisUrl + path;
+		Map<String, Object> params = new HashMap<String, Object>();
+
+		// 基础参数
+		params.put("appCode", projectId);
+		params.put("timestamp", "" + System.currentTimeMillis());
+		params.put("version", "v1");
+
+		// 业务参数
+		params.put("companyOpenCode", "");
+		params.put("personOpenCode", userId);
+		params.put("signType", 1);
+		params.put("canRefuse", 0);
+
+		// token
+		String token = generateToken(params, projectSecret);
+		params.put("token", token);
+
+		params.put("contractFile", contractFile);
+
+		String result = HttpUtil.postForHttp(url, params);
+		System.out.println(result);
+
+		JSONObject jsonObject = JSONObject.parseObject(result);
+		if (jsonObject.getInteger("code") == 0) {
+			return (String) JSONPath.eval(jsonObject, "$.data.contractCode");
+		}
+		throw new ThirdpartyException("上传文件失败:{}", jsonObject.getString("description"));
+	}
+
+	/**
+	 * 企业PDF摘要签署(印章图片)
+	 * @param sealData 电子印章数据
+	 * @param srcPdfPath 源文件
+	 * @param destPdfPath 签名后的目标文件
+	 * @return
+	 */
+	public boolean organSign(String sealData, String srcPdfPath, String destPdfPath) {
+		return true;
+	}
+
+	/**
+	 * 用户签名
+	 * @param accountId e签宝账户唯一标识
+	 * @param sealData 电子印章数据
+	 * @param srcPdfPath 平台签名后的源文件
+	 * @param destPdfPath 平台、用户都签名后的文件地址
+	 * @return
+	 */
+	public boolean userSign(String accountId, String sealData, String srcPdfPath, String destPdfPath) {
+
+		return true;
+	}
+
+	private String generateToken(Map<String, Object> params, String secret) {
+
+		params = SortUtil.sortWithAscII(params);
+		String paramsStr = ValueUtil.joinKeyValue(params, "", "", "", true);
+		String md5Str = new String(DigestUtils.md5(paramsStr.getBytes()));
+
+		paramsStr = md5Str + secret;
+
+		return DigestUtils.sha1Hex(paramsStr);
+	}
+
+	public static void main(String[] args) throws IOException {
+		BytedancePlugin plugin = new BytedancePlugin();
+		plugin.createUserAccount("1", "高勇", "421125198708123313", "13720176797");
+	}
+
+}

+ 337 - 0
toolset/thirdparty-component/src/main/java/com/ym/mec/thirdparty/eseal/provider/TsignPlugin.java

@@ -0,0 +1,337 @@
+package com.ym.mec.thirdparty.eseal.provider;
+
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import com.timevale.esign.sdk.tech.bean.AccountProfile;
+import com.timevale.esign.sdk.tech.bean.OrganizeBean;
+import com.timevale.esign.sdk.tech.bean.PersonBean;
+import com.timevale.esign.sdk.tech.bean.PosBean;
+import com.timevale.esign.sdk.tech.bean.SignPDFFileBean;
+import com.timevale.esign.sdk.tech.bean.UpdateOrganizeBean;
+import com.timevale.esign.sdk.tech.bean.UpdatePersonBean;
+import com.timevale.esign.sdk.tech.bean.result.AddAccountResult;
+import com.timevale.esign.sdk.tech.bean.result.AddSealResult;
+import com.timevale.esign.sdk.tech.bean.result.FileDigestSignResult;
+import com.timevale.esign.sdk.tech.bean.result.GetAccountProfileResult;
+import com.timevale.esign.sdk.tech.bean.result.Result;
+import com.timevale.esign.sdk.tech.bean.seal.OrganizeTemplateType;
+import com.timevale.esign.sdk.tech.bean.seal.PersonTemplateType;
+import com.timevale.esign.sdk.tech.bean.seal.SealColor;
+import com.timevale.esign.sdk.tech.impl.constants.LegalAreaType;
+import com.timevale.esign.sdk.tech.impl.constants.LicenseQueryType;
+import com.timevale.esign.sdk.tech.impl.constants.OrganRegType;
+import com.timevale.esign.sdk.tech.impl.constants.SignType;
+import com.timevale.esign.sdk.tech.service.AccountService;
+import com.timevale.esign.sdk.tech.service.SealService;
+import com.timevale.esign.sdk.tech.service.SelfSignService;
+import com.timevale.esign.sdk.tech.service.UserSignService;
+import com.timevale.esign.sdk.tech.v3.client.ServiceClient;
+import com.timevale.esign.sdk.tech.v3.client.ServiceClientManager;
+import com.timevale.tech.sdk.bean.ProjectConfig;
+import com.ym.mec.thirdparty.eseal.ESealPlugin;
+import com.ym.mec.thirdparty.exception.ThirdpartyException;
+
+/**
+ * 接口文档地址  https://open.esign.cn/doc/detail?id=opendoc%2Fpaas_sdk%2Fbzu9e8&namespace=opendoc%2Fpaas_sdk&searchText=
+ */
+@Service
+public class TsignPlugin implements ESealPlugin, InitializingBean, DisposableBean {
+
+    @Value("${eseal.tsign.projectid:4438776254}")
+    public String projectId; // = "1111563517";
+
+    @Value("${eseal.tsign.projectSecret:a94cf63d6361084d232f345d71321691}")
+    public String projectSecret; // = "95439b0863c241c63a861b87d1e647b7";
+
+    @Value("${eseal.tsign.apisUrl:http://smlitsm.tsign.cn:8080/tgmonitor/rest/app!getAPIInfo2}")
+    public String apisUrl; // = "http://smlitsm.tsign.cn:8080/tgmonitor/rest/app!getAPIInfo2";
+
+    private ServiceClient serviceClient;
+
+    public static String getName() {
+        return "Tsign";
+    }
+
+    @Override
+    public void afterPropertiesSet() {
+        ProjectConfig projectconfig = new ProjectConfig();
+        projectconfig.setProjectId(projectId);
+        projectconfig.setProjectSecret(projectSecret);
+        projectconfig.setItsmApiUrl(apisUrl);
+        Result result = ServiceClientManager.registClient(projectconfig, null, null);
+        if (result.getErrCode() != 0) {
+            //throw new ThirdpartyException("e签宝客户端注册失败:{}", result.getMsg());
+        }
+
+        serviceClient = ServiceClientManager.get(projectId);
+        if (serviceClient == null) {
+            //throw new ThirdpartyException("获取e签宝客户端失败");
+        }
+    }
+
+    @Override
+    public void destroy() throws Exception {
+        ServiceClientManager.shutdown(projectId);
+    }
+
+    /**
+     * 创建用户账户(个人)
+     *
+     * @param realName 姓名
+     * @param idcard   身份证号码
+     * @param mobile   手机号码
+     * @return e签宝账户唯一标识
+     */
+    public String createUserAccount(String realName, String idcard, String mobile) {
+        PersonBean personbean = new PersonBean();
+        personbean.setName(realName);
+        personbean.setIdNo(idcard);
+        personbean.setMobile(mobile);
+        personbean.setPersonArea(LegalAreaType.MAINLAND);
+        // personbean.setPersonArea(4);
+        AccountService service = serviceClient.accountService();
+        AddAccountResult result = service.addAccount(personbean);
+        if (result.getErrCode() == 0) {
+            return result.getAccountId();
+        } else if (result.getErrCode() == 1500012) {
+            return queryAccountIdByIdNo(idcard);
+        }
+        throw new ThirdpartyException(result.getMsg());
+    }
+
+    @Override
+	public boolean updateUserAccount(String accountId, String realName, String idcard, String mobile) {
+    	
+    	UpdatePersonBean updatePersonBean = new UpdatePersonBean();
+        updatePersonBean.setMobile(mobile);// 手机号码,可空
+        updatePersonBean.setName(realName);// 姓名,可空
+        
+        AccountService service = serviceClient.accountService();
+        Result result = service.updateAccount(accountId, updatePersonBean, null);
+        
+        if (result.getErrCode() == 0) {
+            return true;
+        }
+        throw new ThirdpartyException(result.getMsg());
+	}
+
+	/**
+     * 创建用户账户(企业)
+     *
+     * @param orgName   机构名称
+     * @param organCode 统一社会信用代码
+     * @return e签宝账户唯一标识
+     */
+    public String createOrganAccount(String orgName, String organCode) {
+        OrganizeBean organizeBean = new OrganizeBean();
+        organizeBean.setName(orgName);
+        organizeBean.setOrganCode(organCode);
+        organizeBean.setRegType(OrganRegType.MERGE);
+        organizeBean.setUserType(0);
+
+        AccountService service = serviceClient.accountService();
+        AddAccountResult result = service.addAccount(organizeBean);
+        if (result.getErrCode() == 0) {
+            return result.getAccountId();
+        }
+        throw new ThirdpartyException("创建企业账户接口调用失败code=" + result.getErrCode() + "msg=" + result.getMsg());
+    }
+
+	@Override
+	public boolean updateOrganAccount(String accountId, String orgName, String organCode) {
+		
+		UpdateOrganizeBean updateOrganizeBean = new UpdateOrganizeBean();
+        updateOrganizeBean.setName(orgName);//机构名称,可空
+
+        AccountService service = serviceClient.accountService();
+        Result result = service.updateAccount(accountId, updateOrganizeBean, null);
+        
+        if (result.getErrCode() == 0) {
+            return true;
+        }
+        throw new ThirdpartyException(result.getMsg());
+		
+	}
+
+    /**
+     * 创建印章
+     *
+     * @param accountId e签宝账户唯一标识
+     * @return 电子印章数据
+     */
+    public String createUserSeal(String accountId) {
+        // 生成模板印章的颜色
+        SealColor color = SealColor.RED;
+        SealService service = serviceClient.sealService();
+        AddSealResult result = service.addTemplateSeal(accountId, PersonTemplateType.RECTANGLE, color);
+        if (0 == result.getErrCode()) {
+            return result.getSealData();
+        }
+        throw new ThirdpartyException("个人模板印章接口调用失败code=" + result.getErrCode() + "msg=" + result.getMsg());
+    }
+
+    @Override
+    public String createOrganSeal(String accountId, String hText, String qText) {
+        // 生成模板印章的颜色
+        SealColor color = SealColor.RED;
+        SealService service = serviceClient.sealService();
+        AddSealResult result = service.addTemplateSeal(accountId, OrganizeTemplateType.STAR, color, hText, qText);
+        if (0 == result.getErrCode()) {
+            return result.getSealData();
+        }
+        throw new ThirdpartyException("企业模板印章接口调用失败code=" + result.getErrCode() + "msg=" + result.getMsg());
+    }
+
+    /**
+     * 平台自身PDF摘要签署(印章标识)
+     *
+     * @param srcPdfPath  源文件
+     * @param destPdfPath 签名后的目标文件
+     * @return
+     */
+    public boolean platformSign(String srcPdfPath, String destPdfPath) {
+        PosBean posBean = new PosBean();
+        // 签章类型,Single-单页签章、Multi-多页签章、Edges-骑缝章、Key-关键字签章
+        SignType signType = SignType.Key;
+        // 接口调用方(平台方)的印章,请在www.tsign.cn官网中设置默认印章其sealId值为0
+        int sealId = 0;
+        // 设置接口调用方(平台方)签章位置信息
+        posBean.setPosPage("1");// 签署页码,若为多页签章,支持页码格式“1-3,5,8“,若为坐标定位时,不可空
+        posBean.setKey("甲方签章");
+        // 签署位置X坐标,默认值为0,以pdf页面的左下角作为原点,控制距离页面左端的横向移动距离,单位为px
+        posBean.setPosX(100);
+        // 签署位置Y坐标,默认值为0,以pdf页面的左下角作为原点,控制距离页面底端的纵向移动距离,单位为px
+        posBean.setPosY(0);
+        // 印章图片在PDF文件中的等比缩放大小,公章标准大小为4.2厘米即159px
+        posBean.setWidth(100);
+        SignPDFFileBean PDFbean = new SignPDFFileBean();
+        PDFbean.setSrcPdfFile(srcPdfPath);
+        PDFbean.setDstPdfFile(destPdfPath);
+
+        SelfSignService service = serviceClient.selfSignService();
+        FileDigestSignResult result = service.localSignPdf(PDFbean, posBean, sealId, signType);
+        if (0 != result.getErrCode()) {
+            throw new ThirdpartyException("平台自身PDF摘要签署接口调用失败!Code=" + result.getErrCode() + "MSG=" + result.getMsg());
+        }
+        return true;
+    }
+
+    /**
+     * 企业PDF摘要签署(印章图片)
+     *
+     * @param sealData    电子印章数据
+     * @param srcPdfPath  源文件
+     * @param destPdfPath 签名后的目标文件
+     * @return
+     */
+    public boolean organSign(String sealData, String srcPdfPath, String destPdfPath) {
+        PosBean posBean = new PosBean();
+        // 签章类型,Single-单页签章、Multi-多页签章、Edges-骑缝章、Key-关键字签章
+        SignType signType = SignType.Key;
+        // 设置接口调用方(平台方)签章位置信息
+        posBean.setPosPage("1");// 签署页码,若为多页签章,支持页码格式“1-3,5,8“,若为坐标定位时,不可空
+        posBean.setKey("甲方签章");
+        // 签署位置X坐标,默认值为0,以pdf页面的左下角作为原点,控制距离页面左端的横向移动距离,单位为px
+        posBean.setPosX(100);
+        // 签署位置Y坐标,默认值为0,以pdf页面的左下角作为原点,控制距离页面底端的纵向移动距离,单位为px
+        posBean.setPosY(0);
+        // 印章图片在PDF文件中的等比缩放大小,公章标准大小为4.2厘米即159px
+        posBean.setWidth(100);
+        SignPDFFileBean PDFbean = new SignPDFFileBean();
+        PDFbean.setSrcPdfFile(srcPdfPath);
+        PDFbean.setDstPdfFile(destPdfPath);
+
+        SelfSignService service = serviceClient.selfSignService();
+        FileDigestSignResult result = service.localSignPdf(PDFbean, posBean, sealData, signType);
+        if (0 != result.getErrCode()) {
+            throw new ThirdpartyException("平台自身PDF摘要签署接口调用失败!Code=" + result.getErrCode() + "MSG=" + result.getMsg());
+        }
+        return true;
+    }
+
+    /**
+     * 用户签名
+     *
+     * @param accountId   e签宝账户唯一标识
+     * @param sealData    电子印章数据
+     * @param srcPdfPath  平台签名后的源文件
+     * @param destPdfPath 平台、用户都签名后的文件地址
+     * @return
+     */
+    public boolean userSign(String accountId, String sealData, String srcPdfPath, String destPdfPath) {
+
+        SignPDFFileBean signPDFStreamBean = new SignPDFFileBean();
+        // C:test_signed.pdf为平台自身签署后路径
+        signPDFStreamBean.setSrcPdfFile(srcPdfPath);
+        signPDFStreamBean.setDstPdfFile(destPdfPath);
+        PosBean posBean = new PosBean();
+        posBean.setPosPage("1");
+        posBean.setPosType(1);
+        posBean.setWidth(80);
+        posBean.setKey("乙方签章");
+        posBean.setPosX(100);
+        posBean.setPosY(0);
+
+        // 签章类型,Single-单页签章、Multi-多页签章、Edges-骑缝章、Key-关键字签章
+        SignType signtype = SignType.Key;
+        UserSignService service = serviceClient.userSignService();
+        FileDigestSignResult result = service.localSignPDF(accountId, sealData, signPDFStreamBean, posBean, signtype);
+        if (result.getErrCode() == 0) {
+            return true;
+        }
+        throw new ThirdpartyException("平台用户PDF摘要签署接口调用失败" + result.getErrCode() + "msg=" + result.getMsg());
+    }
+
+    private String queryAccountIdByIdNo(String idcardNo) {
+
+        AccountService service = serviceClient.accountService();
+
+        GetAccountProfileResult result = service.getAccountInfoByIdNo(idcardNo, LicenseQueryType.MAINLAND);
+
+        if (result != null) {
+            AccountProfile accountProfile = result.getAccountInfo();
+            if (accountProfile != null) {
+                return accountProfile.getAccountUid();
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * 用户签名
+     *
+     * @param accountId   e签宝账户唯一标识
+     * @param sealData    电子印章数据
+     * @param keyWorld    印章关键字
+     * @param srcPdfPath  平台签名后的源文件
+     * @param destPdfPath 平台、用户都签名后的文件地址
+     * @return
+     */
+    public boolean userSign(String accountId, String sealData, String keyWorld, String srcPdfPath, String destPdfPath) {
+
+        SignPDFFileBean signPDFStreamBean = new SignPDFFileBean();
+        // C:test_signed.pdf为平台自身签署后路径
+        signPDFStreamBean.setSrcPdfFile(srcPdfPath);
+        signPDFStreamBean.setDstPdfFile(destPdfPath);
+        PosBean posBean = new PosBean();
+        posBean.setPosPage("1");
+        posBean.setPosType(1);
+        posBean.setWidth(80);
+        posBean.setKey(keyWorld);
+        posBean.setPosX(100);
+        posBean.setPosY(0);
+
+        // 签章类型,Single-单页签章、Multi-多页签章、Edges-骑缝章、Key-关键字签章
+        SignType signtype = SignType.Key;
+        UserSignService service = serviceClient.userSignService();
+        FileDigestSignResult result = service.localSignPDF(accountId, sealData, signPDFStreamBean, posBean, signtype);
+        if (result.getErrCode() == 0) {
+            return true;
+        }
+        throw new ThirdpartyException("平台用户PDF摘要签署接口调用失败" + result.getErrCode() + "msg=" + result.getMsg());
+    }
+}

+ 36 - 0
toolset/thirdparty-component/src/main/java/com/ym/mec/thirdparty/exception/ThirdpartyException.java

@@ -0,0 +1,36 @@
+package com.ym.mec.thirdparty.exception;
+
+import com.yonge.toolset.utils.string.MessageFormatter;
+
+public class ThirdpartyException extends RuntimeException {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = -4562885563376566463L;
+
+	public ThirdpartyException() {
+		super();
+	}
+
+	public ThirdpartyException(String message) {
+		super(message);
+	}
+
+	public ThirdpartyException(Throwable cause) {
+		super(cause);
+	}
+
+	public ThirdpartyException(String message, Throwable cause) {
+		super(message, cause);
+	}
+
+	public ThirdpartyException(String message, Object... arguments) {
+		super(MessageFormatter.arrayFormat(message, arguments));
+	}
+
+	public ThirdpartyException(String message, Throwable cause, Object... args) {
+		super(MessageFormatter.arrayFormat(message, args), cause);
+	}
+
+}

+ 128 - 0
toolset/thirdparty-component/src/main/java/com/ym/mec/thirdparty/lingxinpay/ContractSignService.java

@@ -0,0 +1,128 @@
+package com.ym.mec.thirdparty.lingxinpay;
+
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson.JSONPath;
+import com.ym.mec.thirdparty.exception.ThirdpartyException;
+import com.yonge.toolset.utils.http.HttpUtil;
+
+@Service
+public class ContractSignService {
+
+	private static final Logger logger = LoggerFactory.getLogger(ContractSignService.class);
+
+	@Value("${teacher.contract.publicKey:MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCYT5eCY6r8sGWgbiId/VqSZmS6XkBNGMkzUqTIkpkecOzsFBxFXTQmgDeR991YfgqmyOaHsJ/ons/H+e8l+RmHsOm4eErFU+9qXFq+k195YFV1vAR9O7MIG+FR5vmLDuhgimPsgqscWhUrGinc8RUpi5KwClgx7d+d8ZJ4GmkR0QIDAQAB}")
+	private String publicKey;
+
+	private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+
+	@Value("${teacher.contract.contractNo:1164462240733069312}")
+	private String contractNo;// 模板协议号
+
+	@Value("${teacher.contract.memberNo:1491663782974988288}")
+	private String outMemberNo;// 商户号
+	
+	@Value("${teacher.contract.notifyUrl:http://www.baidu.com}")
+	private String notifyUrl;
+	
+	@Value("${teacher.contract.apiUrl:http://39.107.15.64:8095}")
+	private String apiUrl;
+
+	public boolean signContract(String realName, String idcard, String mobileNo, String serialNo) {
+		JSONObject jsonObject = new JSONObject();
+		jsonObject.put("signType", "RSA");
+		jsonObject.put("service", "bpotop.zx.contract");
+		jsonObject.put("charset", "UTF-8");
+		jsonObject.put("version", "1.0");
+		jsonObject.put("createTime", sdf.format(new Date()));
+
+		jsonObject.put("outMemberNo", outMemberNo);// 公司商户号
+		jsonObject.put("serialNo", serialNo);// 流水号(商户唯一标识)
+		jsonObject.put("contractNo", contractNo);// 合同模板号
+		jsonObject.put("notifyUrl", notifyUrl);// 返回结果异步通知地址
+
+		JSONObject jsonObject2 = new JSONObject();
+		jsonObject2.put("name", realName);
+		jsonObject2.put("phone", mobileNo);
+		jsonObject2.put("identityId", idcard);
+		jsonObject2.put("citizenship", "0");
+		jsonObject2.put("signTime", sdf.format(new Date()));
+		jsonObject.put("contractSignInfo", jsonObject2);
+		String jsonStr = JSONObject.toJSONString(jsonObject);
+
+		try {
+			String encryptStr = RSA.encryptPub(jsonStr, publicKey);
+			jsonObject.put("sign", encryptStr);
+		} catch (Exception e) {
+			logger.error("加密失败", e);
+			throw new ThirdpartyException("加密失败:{}", e.getMessage());
+		}
+		logger.info("[合同签署]请求参数:{}", jsonObject.toJSONString());
+		try {
+			String s = HttpUtil.postForHttp(apiUrl + "/api/signContract", jsonObject.toJSONString(), null);
+			logger.info("请求[合同签署]响应参数:{}", s);
+
+			jsonObject = JSONObject.parseObject(s);
+			if (StringUtils.equals(jsonObject.getString("return_code"), "T")) {
+				return true;
+			}
+
+			throw new ThirdpartyException("合同签署失败:{}", jsonObject.getString("content"));
+
+		} catch (IOException e) {
+			logger.error("请求[合同签署]接口报错", e);
+			throw new ThirdpartyException("请求[合同签署]接口报错:{}", e.getMessage());
+		}
+	}
+
+	public String querySignContractResult(String serialNo) {
+		JSONObject jsonObject = new JSONObject();
+		jsonObject.put("outMemberNo", outMemberNo);
+		jsonObject.put("serialNo", serialNo);
+		jsonObject.put("contractNo", contractNo);
+		try {
+			String encryptStr = RSA.encryptPub(JSONObject.toJSONString(jsonObject), publicKey);
+			jsonObject.put("sign", encryptStr);
+		} catch (Exception e) {
+			logger.error("加密失败", e);
+			throw new ThirdpartyException("加密失败:{}", e.getMessage());
+		}
+		jsonObject.put("signType", "RSA");
+		jsonObject.put("service", "bpotop.zx.contract");
+		jsonObject.put("charset", "UTF-8");
+		jsonObject.put("version", "1.0");
+		jsonObject.put("createTime", sdf.format(new Date()));
+		try {
+			String s = HttpUtil.postForHttp(apiUrl + "/api/queryContractInfo", jsonObject.toJSONString(), null);
+
+			logger.info("[合同查询]响应参数:{}", s);
+
+			jsonObject = JSONObject.parseObject(s);
+			if (StringUtils.equals(jsonObject.getString("return_code"), "T")) {
+				return (String) JSONPath.eval(jsonObject, "$.content.contractUrl");
+			}
+
+			//throw new ThirdpartyException("查询合同签署结果失败:{}", JSONPath.eval(jsonObject, "$.content.message"));
+		} catch (IOException e) {
+			logger.error("请求[合同查询]接口报错", e);
+			//throw new ThirdpartyException("请求[合同查询]接口报错:{}", e.getMessage());
+		}
+		return null;
+	}
+
+	public static void main(String[] args) {
+		ContractSignService service = new ContractSignService();
+		// service.signContract("何亮", "130423199206192818", "17600220933","11");
+
+		service.querySignContractResult("11");
+	}
+}

+ 443 - 0
toolset/thirdparty-component/src/main/java/com/ym/mec/thirdparty/lingxinpay/RSA.java

@@ -0,0 +1,443 @@
+package com.ym.mec.thirdparty.lingxinpay;
+
+import org.apache.commons.codec.binary.Base64;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.crypto.Cipher;
+import java.io.ByteArrayOutputStream;
+import java.io.UnsupportedEncodingException;
+import java.security.*;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ *
+ * <p>
+ * RSA签名,加解密处理核心文件,注意:密钥长度1024
+ * </p>
+ * 
+ * @author leelun
+ * @version $Id: RSA.java, v 0.1 2013-11-15 下午2:33:53 lilun Exp $
+ */
+public class RSA {
+
+	/**
+	 * 签名算法
+	 */
+	public static final String SIGNATURE_ALGORITHM = "SHA1withRSA";
+	/**
+	 * 加密算法RSA
+	 */
+	public static final String KEY_ALGORITHM = "RSA";
+	/**
+	 * RSA最大加密明文大小
+	 */
+	private static final int MAX_ENCRYPT_BLOCK = 117;
+
+	/**
+	 * RSA最大解密密文大小
+	 */
+	private static final int MAX_DECRYPT_BLOCK = 128;
+
+	/**
+	 * 获取公钥的key
+	 */
+	public static final String PUBLIC_KEY = "RSAPublicKey";
+
+	/**
+	 * 获取私钥的key
+	 */
+	public static final String PRIVATE_KEY = "RSAPrivateKey";
+
+	private static Logger logger = LoggerFactory.getLogger(RSA.class);
+
+	/**
+	 * <p>
+	 * 生成密钥对(公钥和私钥)
+	 * </p>
+	 *
+	 * @return
+	 * @throws Exception
+	 */
+	public static Map<String, Object> genKeyPair() throws Exception {
+		KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
+		keyPairGen.initialize(1024);
+		KeyPair keyPair = keyPairGen.generateKeyPair();
+		RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
+		RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
+		Map<String, Object> keyMap = new HashMap<String, Object>(2);
+		keyMap.put(PUBLIC_KEY, publicKey);
+		keyMap.put(PRIVATE_KEY, privateKey);
+		return keyMap;
+
+	}
+
+	/**
+	 * 签名字符串
+	 *
+	 * @param text
+	 *            需要签名的字符串
+	 * @param privateKey
+	 *            私钥(BASE64编码)
+	 *
+	 * @param input_charset
+	 *            编码格式
+	 * @return 签名结果(BASE64编码)
+	 */
+	public static String sign(String text, String privateKey, String charset) throws Exception {
+
+		byte[] keyBytes = Base64.decodeBase64(privateKey);
+		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
+		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
+		PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);
+		Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
+		signature.initSign(privateK);
+		signature.update(getContentBytes(text, charset));
+		byte[] result = signature.sign();
+		return Base64.encodeBase64String(result);
+
+	}
+
+	/**
+	 * 签名字符串
+	 *
+	 * @param text
+	 *            需要签名的字符串
+	 * @param sign
+	 *            客户签名结果
+	 * @param publicKey
+	 *            公钥(BASE64编码)
+	 * @param input_charset
+	 *            编码格式
+	 * @return 验签结果
+	 */
+	public static boolean verify(String text, String sign, String publicKey, String charset) throws Exception {
+		byte[] keyBytes = Base64.decodeBase64(publicKey);
+		X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
+		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
+		PublicKey publicK = keyFactory.generatePublic(keySpec);
+
+		Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
+		signature.initVerify(publicK);
+		signature.update(getContentBytes(text, charset));
+		return signature.verify(Base64.decodeBase64(sign));
+
+	}
+
+	/**
+	 * <P>
+	 * 私钥解密
+	 * </p>
+	 *
+	 * @param encryptedData
+	 *            已加密数据
+	 * @param privateKey
+	 *            私钥(BASE64编码)
+	 * @return
+	 * @throws Exception
+	 */
+	public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey) throws Exception {
+		byte[] keyBytes = Base64.decodeBase64(privateKey);
+		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
+		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
+		Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
+		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
+		cipher.init(Cipher.DECRYPT_MODE, privateK);
+		int inputLen = encryptedData.length;
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		int offSet = 0;
+		byte[] cache;
+		int i = 0;
+		// 对数据分段解密
+		while (inputLen - offSet > 0) {
+			if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
+				cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
+			} else {
+				cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
+			}
+			out.write(cache, 0, cache.length);
+			i++;
+			offSet = i * MAX_DECRYPT_BLOCK;
+		}
+		byte[] decryptedData = out.toByteArray();
+		out.close();
+		return decryptedData;
+
+	}
+
+	/**
+	 * <p>
+	 * 公钥解密
+	 * </p>
+	 *
+	 * @param encryptedData
+	 *            已加密数据
+	 * @param publicKey
+	 *            公钥(BASE64编码)
+	 * @return
+	 * @throws Exception
+	 */
+	public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey) throws Exception {
+		byte[] keyBytes = Base64.decodeBase64(publicKey);
+		X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
+		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
+		Key publicK = keyFactory.generatePublic(x509KeySpec);
+		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
+		cipher.init(Cipher.DECRYPT_MODE, publicK);
+		int inputLen = encryptedData.length;
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		int offSet = 0;
+		byte[] cache;
+		int i = 0;
+		// 对数据分段解密
+		while (inputLen - offSet > 0) {
+			if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
+				cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
+			} else {
+				cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
+			}
+			out.write(cache, 0, cache.length);
+			i++;
+			offSet = i * MAX_DECRYPT_BLOCK;
+		}
+		byte[] decryptedData = out.toByteArray();
+		out.close();
+		return decryptedData;
+
+	}
+
+	/**
+	 * <p>
+	 * 公钥加密
+	 * </p>
+	 *
+	 * @param data
+	 *            源数据
+	 * @param publicKey
+	 *            公钥(BASE64编码)
+	 * @return
+	 * @throws Exception
+	 */
+	public static byte[] encryptByPublicKey(byte[] data, String publicKey) throws Exception {
+		byte[] keyBytes = Base64.decodeBase64(publicKey);
+		X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
+		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
+		Key publicK = keyFactory.generatePublic(x509KeySpec);
+		// 对数据加密
+		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
+		cipher.init(Cipher.ENCRYPT_MODE, publicK);
+		int inputLen = data.length;
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		int offSet = 0;
+		byte[] cache;
+		int i = 0;
+		// 对数据分段加密
+		while (inputLen - offSet > 0) {
+			if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
+				cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
+			} else {
+				cache = cipher.doFinal(data, offSet, inputLen - offSet);
+			}
+			out.write(cache, 0, cache.length);
+			i++;
+			offSet = i * MAX_ENCRYPT_BLOCK;
+		}
+		byte[] encryptedData = out.toByteArray();
+		out.close();
+		return encryptedData;
+
+	}
+
+	/**
+	 * <p>
+	 * 私钥加密
+	 * </p>
+	 *
+	 * @param data
+	 *            源数据
+	 * @param privateKey
+	 *            私钥(BASE64编码)
+	 * @return
+	 * @throws Exception
+	 */
+	public static byte[] encryptByPrivateKey(byte[] data, String privateKey) throws Exception {
+		byte[] keyBytes = Base64.decodeBase64(privateKey);
+		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
+		KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
+		Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
+		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
+		cipher.init(Cipher.ENCRYPT_MODE, privateK);
+		int inputLen = data.length;
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		int offSet = 0;
+		byte[] cache;
+		int i = 0;
+		// 对数据分段加密
+		while (inputLen - offSet > 0) {
+			if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
+				cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
+			} else {
+				cache = cipher.doFinal(data, offSet, inputLen - offSet);
+			}
+			out.write(cache, 0, cache.length);
+			i++;
+			offSet = i * MAX_ENCRYPT_BLOCK;
+		}
+		byte[] encryptedData = out.toByteArray();
+		out.close();
+		return encryptedData;
+
+	}
+
+	/**
+	 * @param content
+	 * @param charset
+	 * @return
+	 * @throws SignatureException
+	 * @throws UnsupportedEncodingException
+	 */
+	private static byte[] getContentBytes(String content, String charset) {
+		if (charset == null || "".equals(charset)) {
+			return content.getBytes();
+		}
+		try {
+			return content.getBytes(charset);
+		} catch (UnsupportedEncodingException e) {
+			throw new RuntimeException("签名过程中出现错误,指定的编码集不对,您目前指定的编码集是:" + charset);
+		}
+	}
+
+	/**
+	 * <p>
+	 * 获取私钥
+	 * </p>
+	 *
+	 * @param keyMap
+	 *            密钥对
+	 * @return
+	 * @throws Exception
+	 */
+	public static String getPrivateKey(Map<String, Object> keyMap) throws Exception {
+		Key key = (Key) keyMap.get(PRIVATE_KEY);
+		return Base64.encodeBase64String(key.getEncoded());
+	}
+
+	/**
+	 * <p>
+	 * 获取公钥
+	 * </p>
+	 *
+	 * @param keyMap
+	 *            密钥对
+	 * @return
+	 * @throws Exception
+	 */
+	public static String getPublicKey(Map<String, Object> keyMap) throws Exception {
+		Key key = (Key) keyMap.get(PUBLIC_KEY);
+		return Base64.encodeBase64String(key.getEncoded());
+	}
+
+	public static void main(String[] args) throws Exception {
+		Map<String, Object> stringObjectMap = genKeyPair();
+		String publicKey = getPublicKey(stringObjectMap);
+		String privateKey = getPrivateKey(stringObjectMap);
+
+		System.out.println(publicKey);
+		System.out.println(privateKey);
+		// String jiami =
+		String jiami = "{'cardAttribute':'1','cardType':'DC','certificateNo':'340323199401163311','charset':'UTF-8','md5Key':'819ee10adc87e33486c8df1aa299c0b6','mobile':'18621542144','name':'崔','notifyUrl':'test','outMemberNo':'1136225387043356673','outerOrderNo':'111111','payAccount':'12345678','payType':'1','predictAmount':10,'projectName':'测试','salaryType':'1','service':'1dada','signType':'RSA','version':'1.0'}";
+		//String jiami = "{'cardAttribute':'1'}";
+
+		/*
+		 * byte[] bytes1 = encryptByPublicKey(jiami.getBytes(), publicKey); String bytes
+		 * = RSAUtils.decryptByPrivateKey(bytes1, privateKey);
+		 * System.out.println(bytes);
+		 */
+
+		/*
+		 * byte[] encryptPub = encryptByPublicKey(jiami.getBytes(), publicKey); byte[]
+		 * decryptPri =
+		 * decryptByPrivateKey(Base64.decodeBase64(Base64.encodeBase64(encryptPub)),
+		 * privateKey); System.out.println(decryptPri);
+		 */
+		/*String encryptPub = encryptPub(jiami, publicKey);
+		String decryptPri = decryptPri(encryptPub, privateKey);
+*/
+		String encryptPub = encryptPub(jiami, publicKey);
+		String decryptPri = decryptPri(encryptPub, privateKey);
+		System.out.println(decryptPri);
+
+	}
+
+	public static String encryptPub(String str, String publicKey) throws Exception {
+		// base64编码的公钥
+		byte[] decoded = Base64.decodeBase64(publicKey);
+		RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA")
+				.generatePublic(new X509EncodedKeySpec(decoded));
+		// RSA加密
+		Cipher cipher = Cipher.getInstance("RSA");
+		cipher.init(Cipher.ENCRYPT_MODE, pubKey);
+		int inputLen = str.getBytes("utf-8").length;
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		int offSet = 0;
+		byte[] cache;
+		int i = 0;
+		// 对数据分段加密
+		while (inputLen - offSet > 0) {
+			if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
+				cache = cipher.doFinal(str.getBytes("UTF-8"), offSet, MAX_ENCRYPT_BLOCK);
+			} else {
+				cache = cipher.doFinal(str.getBytes("UTF-8"), offSet, inputLen - offSet);
+			}
+			out.write(cache, 0, cache.length);
+			i++;
+			offSet = i * MAX_ENCRYPT_BLOCK;
+		}
+		byte[] encryptedData = out.toByteArray();
+		out.close();
+		// String outStr =
+		// Base64.encodeBase64String(cipher.doFinal(str.getBytes("UTF-8")));
+		String outStr = Base64.encodeBase64String(encryptedData);
+		return outStr;
+	}
+
+	public static String decryptPri(String str, String privateKey) throws Exception {
+		// 64位解码加密后的字符串
+		byte[] inputByte = Base64.decodeBase64(str.getBytes("UTF-8"));
+		// base64编码的私钥
+		byte[] decoded = Base64.decodeBase64(privateKey);
+		RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA")
+				.generatePrivate(new PKCS8EncodedKeySpec(decoded));
+		// RSA解密
+		Cipher cipher = Cipher.getInstance("RSA");
+		cipher.init(Cipher.DECRYPT_MODE, priKey);
+
+		int inputLen = inputByte.length;
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		int offSet = 0;
+		byte[] cache;
+		int i = 0;
+		// 对数据分段解密
+		while (inputLen - offSet > 0) {
+			if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
+				cache = cipher.doFinal(inputByte, offSet, MAX_DECRYPT_BLOCK);
+			} else {
+				cache = cipher.doFinal(inputByte, offSet, inputLen - offSet);
+			}
+			out.write(cache, 0, cache.length);
+			i++;
+			offSet = i * MAX_DECRYPT_BLOCK;
+		}
+		byte[] decryptedData = out.toByteArray();
+		out.close();
+		// String outStr = new String(cipher.doFinal(inputByte));
+		String outStr = new String(decryptedData);
+		return outStr;
+	}
+
+}

+ 30 - 0
toolset/thirdparty-component/src/main/java/com/ym/mec/thirdparty/message/MessageSenderPlugin.java

@@ -0,0 +1,30 @@
+package com.ym.mec.thirdparty.message;
+
+import java.io.IOException;
+
+public interface MessageSenderPlugin {
+	
+	/**
+	 * 发送消息至目的地
+	 * @param subject 消息主题
+	 * @param content 消息内容
+	 * @param receiver 收件人
+	 * @param url 链接地址
+	 * @param jpushType 极光应用类型
+	 * @return 是否发送成功
+	 * @throws IOException
+	 */
+	public boolean send(String subject, String content, String receiver, String url, String jpushType,String sound,String channelId) throws Exception;
+
+	/**
+	 * 批量发送消息至目的地
+	 * @param subject 消息主题
+	 * @param content 消息内容
+	 * @param receivers 收件人列表
+	 * @param url 链接地址
+	 * @param jpushType 极光应用类型
+	 * @return 是否发送成功
+	 * @throws IOException
+	 */
+	public boolean batchSend(String subject, String content, String[] receivers, String url, String jpushType,String sound,String channelId) throws Exception;
+}

+ 138 - 0
toolset/thirdparty-component/src/main/java/com/ym/mec/thirdparty/message/MessageSenderPluginContext.java

@@ -0,0 +1,138 @@
+package com.ym.mec.thirdparty.message;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import com.ym.mec.thirdparty.entity.SysEmail;
+import com.ym.mec.thirdparty.message.provider.*;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+
+import com.ym.mec.thirdparty.exception.ThirdpartyException;
+
+@Component
+public class MessageSenderPluginContext implements ApplicationContextAware {
+
+	public SysEmail sysEmail = new SysEmail();
+
+	public enum MessageSender {
+
+		JIGUANG("PUSH"), MOXINGTONG("SMS"), SHIYUAN("SMS"), YIMEI("SMS"), AWSMS("SMS"), EMAIL("EMAIL");
+
+		/**
+		 * 发送模式(SMS,PUSH,EMAIL)
+		 */
+		private String sendMode;
+
+		private MessageSender(String sendMode) {
+			this.sendMode = sendMode;
+		}
+
+		public String getSendMode() {
+			return sendMode;
+		}
+	}
+
+	private MessageSenderPlugin messageSenderPlugin;
+
+	private ApplicationContext applicationContext;
+
+	private final Map<String, String> mapper = new HashMap<String, String>() {
+		private static final long serialVersionUID = -3964872523891264522L;
+		{
+			put(StringUtils.lowerCase(JiguangPushPlugin.getName()), StringUtils.uncapitalize(JiguangPushPlugin.class.getSimpleName()));
+			put(StringUtils.lowerCase(MOxintongSMSPlugin.getName()), StringUtils.uncapitalize(MOxintongSMSPlugin.class.getSimpleName()));
+			put(StringUtils.lowerCase(ShiyuanSMSPlugin.getName()), StringUtils.uncapitalize(ShiyuanSMSPlugin.class.getSimpleName()));
+			put(StringUtils.lowerCase(YimeiSmsPlugin.getName()), StringUtils.uncapitalize(YimeiSmsPlugin.class.getSimpleName()));
+			put(StringUtils.lowerCase(AwSmsPlugin.getName()), StringUtils.uncapitalize(AwSmsPlugin.class.getSimpleName()));
+			put(StringUtils.lowerCase(CommEmailPlugin.getName()), StringUtils.uncapitalize(CommEmailPlugin.class.getSimpleName()));
+		}
+	};
+
+	/**
+	 * 发送消息至目的地
+	 * @param messageSender 消息发送方
+	 * @param subject 消息主题
+	 * @param content 消息内容
+	 * @param receiver 收件人
+	 * @param url 链接地址
+	 * @return 是否发送成功
+	 * @throws IOException
+	 */
+	public boolean send(MessageSender messageSender, String subject, String content, String receiver, String url, String jpushType,String sound,String channelId) throws Exception {
+		ExecutorService executor = Executors.newFixedThreadPool(5);
+		CompletableFuture<Boolean> future = CompletableFuture.supplyAsync(()->{
+			messageSenderPlugin = getMessageSenderPlugin(messageSender);
+			try {
+				return messageSenderPlugin.send(subject, content, receiver, url, jpushType,sound,channelId);
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+			return false;
+		},executor);
+		executor.shutdown();
+		return future.join();
+	}
+
+	/**
+	 * 批量发送消息至目的地
+	 * @param messageSender 消息发送方
+	 * @param subject 消息主题
+	 * @param content 消息内容
+	 * @param receivers 收件人列表
+	 * @param url 链接地址
+	 * @return 是否发送成功
+	 * @throws IOException
+	 */
+	public boolean batchSend(MessageSender messageSender, String subject, String content, String[] receivers, String url, String jpushType,String sound,String channelId) throws Exception {
+		ExecutorService executor = Executors.newFixedThreadPool(5);
+		CompletableFuture<Boolean> future = CompletableFuture.supplyAsync(()->{
+			messageSenderPlugin = getMessageSenderPlugin(messageSender);
+			try {
+				return messageSenderPlugin.batchSend(subject, content, receivers, url, jpushType,sound,channelId);
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+			return false;
+		},executor);
+		executor.shutdown();
+		return future.join();
+	}
+
+	@Override
+	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+		this.applicationContext = applicationContext;
+	}
+
+	private MessageSenderPlugin getMessageSenderPlugin(MessageSender messageSender) {
+		String beanId = mapper.get(StringUtils.lowerCase(messageSender.name()));
+
+		if (StringUtils.isBlank(beanId)) {
+			throw new ThirdpartyException("消息提供方:{}不存在", beanId);
+		}
+		MessageSenderPlugin messageSenderPlugin = applicationContext.getBean(beanId, MessageSenderPlugin.class);
+		injectEmailAttribute(messageSenderPlugin);
+		return messageSenderPlugin;
+	}
+
+	private void injectEmailAttribute(MessageSenderPlugin messageSenderPlugin) {
+		if (messageSenderPlugin.getClass() == CommEmailPlugin.class) {
+			CommEmailPlugin commEmailPlugin = (CommEmailPlugin) messageSenderPlugin;
+			commEmailPlugin.setHostName(sysEmail.getHostName());
+			commEmailPlugin.setSmtpPort(sysEmail.getSmtpPort());
+			commEmailPlugin.setUserName(sysEmail.getUserName());
+			commEmailPlugin.setPassword(sysEmail.getPassword());
+			commEmailPlugin.setFrom(sysEmail.getFrom());
+			commEmailPlugin.setFromName(sysEmail.getFromName());
+		}
+	}
+
+}

+ 127 - 0
toolset/thirdparty-component/src/main/java/com/ym/mec/thirdparty/message/provider/AwSmsPlugin.java

@@ -0,0 +1,127 @@
+package com.ym.mec.thirdparty.message.provider;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.stereotype.Service;
+
+import com.alibaba.fastjson.JSONObject;
+import com.ym.mec.thirdparty.exception.ThirdpartyException;
+import com.ym.mec.thirdparty.message.MessageSenderPlugin;
+import com.yonge.toolset.utils.http.HttpUtil;
+
+/**
+ * 昂网短信
+ */
+@Service
+public class AwSmsPlugin implements MessageSenderPlugin, InitializingBean {
+	/**
+	 * 请求地址
+	 */
+	private String reqURL = "http://47.104.84.72:8513/sms/Api/ReturnJson/Send.do";
+
+	private String appId = "2045";
+
+	/**
+	 * 账号
+	 */
+	private String account = "jmylyzm";
+
+	/**
+	 * 密码
+	 */
+	private String pswd = "9#O!9hSJ";
+
+	private String signature = "【管乐迷】";
+
+	public static String getName() {
+		return "awsms";
+	}
+
+	@Override
+	public void afterPropertiesSet() throws Exception {
+		// 参数检查
+		if (StringUtils.isBlank(reqURL)) {
+			throw new RuntimeException("Init parameter [reqURL] can not blank");
+		}
+		if (StringUtils.isBlank(account)) {
+			throw new RuntimeException("Init parameter [account] can not blank");
+		}
+		if (StringUtils.isBlank(pswd)) {
+			throw new RuntimeException("Init parameter [pswd] can not blank");
+		}
+	}
+
+	public void setReqURL(String reqURL) {
+		this.reqURL = reqURL;
+	}
+
+	public void setAccount(String account) {
+		this.account = account;
+	}
+
+	public void setPswd(String pswd) {
+		this.pswd = pswd;
+	}
+
+	@Override
+	public boolean send(String subject, String content, String receiver, String url, String jpushType,String sound,String channelId) throws IOException {
+		try {
+			Map<String, Object> reqParams = new HashMap<String, Object>();
+			reqParams.put("SpCode", appId);
+			reqParams.put("LoginName", account);
+			reqParams.put("Password", pswd);
+			reqParams.put("MessageContent", signature + content);
+			reqParams.put("UserNumber", receiver);
+			// reqParams.put("SerialNumber", "");
+			// reqParams.put("ScheduleTime", "");
+			// reqParams.put("subPort", "");
+			String resultParams = HttpUtil.postForHttp(reqURL, reqParams);
+			JSONObject jsonObject = JSONObject.parseObject(resultParams);
+			if (jsonObject.get("result").equals("0")) {
+				return true;
+			} else {
+				throw new ThirdpartyException("短信发送失败:{}", jsonObject.get("description"));
+			}
+		} catch (Exception e) {
+			throw new ThirdpartyException("Failed to invoke awsms service", e);
+		}
+	}
+
+	@Override
+	public boolean batchSend(String subject, String content, String[] receivers, String url, String jpushType,String sound,String channelId) throws IOException {
+		StringBuilder stringBuilder = new StringBuilder("");
+		for (int i = 0; i < receivers.length - 1; i++) {
+			stringBuilder.append(receivers[i]).append(",");
+		}
+		stringBuilder.append(receivers[receivers.length - 1]);
+		try {
+			Map<String, Object> reqParams = new HashMap<String, Object>();
+			reqParams.put("SpCode", appId);
+			reqParams.put("LoginName", account);
+			reqParams.put("Password", pswd);
+			reqParams.put("MessageContent", signature + content);
+			reqParams.put("UserNumber", stringBuilder.toString().trim());
+			// reqParams.put("SerialNumber", "");
+			// reqParams.put("ScheduleTime", "");
+			// reqParams.put("subPort", "");
+			String resultParams = HttpUtil.postForHttp(reqURL, reqParams);
+			JSONObject jsonObject = JSONObject.parseObject(resultParams);
+			if (jsonObject.get("result").equals("0")) {
+				return true;
+			} else {
+				throw new ThirdpartyException("短信发送失败:{}", jsonObject.get("description"));
+			}
+		} catch (Exception e) {
+			throw new ThirdpartyException("Failed to invoke awsms service", e);
+		}
+	}
+
+//	public static void main(String[] args) throws IOException {
+//		AwSmsPlugin plugin = new AwSmsPlugin();
+//		plugin.send("测试", "您的验证码为274160(5分钟内有效),您正在进行商户认证,请不要向他人透露验证码", "13720176797", "", "");
+//	}
+}

+ 144 - 0
toolset/thirdparty-component/src/main/java/com/ym/mec/thirdparty/message/provider/CommEmailPlugin.java

@@ -0,0 +1,144 @@
+package com.ym.mec.thirdparty.message.provider;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.mail.DefaultAuthenticator;
+import org.apache.commons.mail.Email;
+import org.apache.commons.mail.EmailException;
+import org.apache.commons.mail.SimpleEmail;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.stereotype.Service;
+
+import com.ym.mec.thirdparty.message.MessageSenderPlugin;
+
+@Service
+public class CommEmailPlugin implements MessageSenderPlugin, InitializingBean {
+
+	private final static Logger log = LoggerFactory.getLogger(CommEmailPlugin.class);
+
+	private String hostName;
+
+	private int smtpPort;
+
+	private String userName;
+
+	private String password;
+
+	private String from;
+
+	private String fromName;
+
+	public void setHostName(String hostName) {
+		this.hostName = hostName;
+	}
+
+	public void setSmtpPort(int smtpPort) {
+		this.smtpPort = smtpPort;
+	}
+
+	public void setUserName(String userName) {
+		this.userName = userName;
+	}
+
+	public void setPassword(String password) {
+		this.password = password;
+	}
+
+	public void setFrom(String from) {
+		this.from = from;
+	}
+
+	public void setFromName(String fromName) {
+		this.fromName = fromName;
+	}
+
+	public static String getName() {
+		return "email";
+	}
+
+	@Override
+	public void afterPropertiesSet() throws Exception {
+
+	}
+
+	private boolean checkProperties() {
+		if (StringUtils.isBlank(hostName)) {
+			throw new RuntimeException("SMTP服务器没有配置");
+		}
+
+		if (smtpPort == 0) {
+			throw new RuntimeException("SMTP服务器端口没有配置");
+		}
+
+		if (StringUtils.isBlank(userName)) {
+			throw new RuntimeException("SMTP服务器认证用户名没有配置");
+		}
+
+		if (StringUtils.isBlank(password)) {
+			throw new RuntimeException("SMTP服务器认证密码没有配置");
+		}
+
+		if (StringUtils.isBlank(from)) {
+			throw new RuntimeException("发件人邮箱没有配置");
+		}
+
+		// 落款名字
+		if (StringUtils.isBlank(fromName)) {
+			fromName = from;
+		}
+		return true;
+	}
+
+	public static void main(String[] args) throws Exception {
+		CommEmailPlugin cep = new CommEmailPlugin();
+		cep.setUserName("lexiaoyavip@163.com");
+		cep.setHostName("smtp.163.com");
+		cep.setSmtpPort(465);
+		cep.setPassword("HMBJPGYXFOLEBGIP");
+		cep.setFrom("lexiaoyavip@163.com");
+		cep.setFromName("乐小雅");
+		cep.send("测试邮件",
+				 "<b style='color:red'>测试邮件内容</b>",
+				 "yanite1234@sina.com",
+				 null, null, null, null);
+	}
+
+	@Override
+	public boolean send(String subject, String content, String receiver, String url, String jpushType, String sound, String channelId) throws Exception {
+		if (hostName == null || hostName.equals("")) {
+			log.error("邮件配置未能加载");
+			return false;
+		}
+		this.checkProperties();
+		Email email = new SimpleEmail();
+		email.setHostName(hostName);
+		email.setDebug(true);
+		email.setSslSmtpPort(smtpPort + "");
+		email.setAuthenticator(new DefaultAuthenticator(userName, password));
+		email.setSSLOnConnect(true);
+		try {
+			email.setFrom(from, fromName);
+			email.setSubject(subject);
+			email.setContent(content, "text/html;charset=utf8");
+			email.addTo(receiver);
+			email.send();
+			return true;
+		} catch (EmailException e) {
+			throw new RuntimeException("发送邮件出现异常", e);
+		}
+	}
+
+	@Override
+	public boolean batchSend(String subject, String content, String[] receivers, String url, String jpushType, String sound, String channelId) throws Exception {
+		for (String rev : receivers) {
+			try {
+				send(subject, content, rev, url, jpushType, sound, channelId);
+			} catch(EmailException e) {
+				throw new RuntimeException("发送邮件出现异常", e);
+			}
+		}
+		return true;
+	}
+
+}

+ 256 - 0
toolset/thirdparty-component/src/main/java/com/ym/mec/thirdparty/message/provider/JiguangPushPlugin.java

@@ -0,0 +1,256 @@
+package com.ym.mec.thirdparty.message.provider;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.stream.Collectors;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.ym.mec.thirdparty.exception.ThirdpartyException;
+import com.ym.mec.thirdparty.message.MessageSenderPlugin;
+import com.yonge.toolset.utils.http.HttpUtil;
+
+/**
+ * 极光推送
+ */
+@Service
+public class JiguangPushPlugin implements MessageSenderPlugin, InitializingBean {
+
+	@Value("${push.jiguang.appKey.student}")
+	private String studentAppKey;
+	@Value("${push.jiguang.masterSecret.student}")
+	private String studentMasterSecret;
+
+	@Value("${push.jiguang.appKey.teacher}")
+	private String teacherAppKey;
+	@Value("${push.jiguang.masterSecret.teacher}")
+	private String teacherMasterSecret;
+
+	@Value("${push.jiguang.appKey.system}")
+	private String systemAppKey;
+	@Value("${push.jiguang.masterSecret.system}")
+	private String systemMasterSecret;
+
+	@Value("${push.jiguang.apns_production:false}")
+	private boolean apns_production = true; // 推送环境 True 表示推送生产环境,False 表示要推送开发环境
+
+	@Value("${push.jiguang.time_to_live:86400}")
+	private int time_to_live = 86400; // 离线保留时长 秒为单位 默认1天 最大10天
+
+	@Value("${push.jiguang.reqURL:https://api.jpush.cn/v3/push}")
+	private String reqURL = "https://api.jpush.cn/v3/push";// 请求极光地址
+
+	public static String getName() {
+		return "jiguang";
+	}
+
+	/**
+	 * 组装推送Json串
+	 *
+	 * @param alias 别名推送
+	 * @param alert 消息
+	 * @param content 消息内容
+	 * @return json对象
+	 */
+	private JSONObject generateJson(String[] alias, String alert, String content, String url,String sound,String channelId) {
+		JSONObject json = new JSONObject();
+		JSONArray platform = new JSONArray();// 平台
+		platform.add("android");
+		platform.add("ios");
+
+		JSONObject audience = new JSONObject();// 推送目标
+		JSONArray aliasJsonArr = new JSONArray();
+		for (String alia : alias) {
+			aliasJsonArr.add(alia);
+		}
+		audience.put("alias", aliasJsonArr);
+
+		JSONObject notification = new JSONObject();// 通知内容
+		JSONObject android = new JSONObject();// android通知内容
+		android.put("alert", alert);
+		android.put("sound", sound.split("\\.")[0]);
+		JSONObject options = new JSONObject();// 设置参数
+		if(StringUtils.isNotEmpty(channelId)){
+			JSONObject thirdParty = new JSONObject();
+			JSONObject xiaomi = new JSONObject();
+			xiaomi.put("distribution","secondary_push");
+			xiaomi.put("channel_id",channelId);
+			thirdParty.put("xiaomi",xiaomi);
+			options.put("third_party_channel",thirdParty);
+		}
+		android.put("builder_id", 1);
+		JSONObject android_extras = new JSONObject();// android额外参数
+		android_extras.put("type", "infomation");
+		android_extras.put("url", url);
+		android_extras.put("memo", url);
+		android.put("extras", android_extras);
+
+		JSONObject ios = new JSONObject();// ios通知内容
+		ios.put("alert", alert);
+		ios.put("sound", sound);
+		ios.put("badge", "+1");
+		JSONObject ios_extras = new JSONObject();// ios额外参数
+		ios_extras.put("type", "infomation");
+		ios_extras.put("url", url);
+		ios_extras.put("memo", url);
+		ios.put("extras", ios_extras);
+		notification.put("android", android);
+		notification.put("ios", ios);
+
+		JSONObject message = new JSONObject();// 通知消息内容
+		message.put("title", alert);
+		message.put("msg_content", content);
+		message.put("content_type","text");
+
+		options.put("time_to_live", this.time_to_live);
+		options.put("apns_production", this.apns_production);
+
+		json.put("platform", platform);
+		json.put("audience", audience);
+		json.put("notification", notification);
+		json.put("options", options);
+		json.put("message", message);
+		return json;
+
+	}
+
+	/**
+	 * 调用极光api
+	 * @param alias 推送对象别名
+	 * @param alert 推送消息
+	 * @param content 推送内容
+	 */
+	private String push(String[] alias, String alert, String content, String url,String type,String sound,String channelId) {
+		String base64_auth_string = "";
+		switch (type){
+			case "STUDENT":
+				base64_auth_string = encryptBASE64(this.studentAppKey + ":" + this.studentMasterSecret);
+				break;
+			case "TEACHER":
+				base64_auth_string = encryptBASE64(this.teacherAppKey + ":" + this.teacherMasterSecret);
+				break;
+			default:
+				base64_auth_string = encryptBASE64(this.systemAppKey + ":" + this.systemMasterSecret);
+				break;
+		}
+		String authorization = "Basic " + base64_auth_string;
+		return sendPostRequest(generateJson(alias, alert, content, url,sound,channelId).toString(), authorization);
+	}
+
+	/**
+	 * 发送Post请求(json格式)
+	 *
+	 * @param data //封装的json串
+	 * @param authorization 验签
+	 * @return result 返回一个json字符串
+	 */
+	private String sendPostRequest(String data, String authorization) {
+		String result = "";
+		HashMap<String, String> reqHeader = new HashMap<>();
+		reqHeader.put("Authorization", authorization.trim());
+		try {
+			result = HttpUtil.postForHttps(this.reqURL, data, reqHeader);
+		} catch (Exception e) {
+			throw new ThirdpartyException("HttpUtil Connection Exception", e);
+		}
+		return result;
+	}
+
+	/**
+	 *     * BASE64加密工具
+	 */
+	private String encryptBASE64(String str) {
+		byte[] key = str.getBytes();
+		String strs = Base64.encodeBase64String(key);
+		return strs;
+	}
+
+	@Override
+	public void afterPropertiesSet() throws Exception {
+		// 参数检查
+		/*if (StringUtils.isBlank(appKey)) {
+			throw new RuntimeException("Init parameter [appKey] can not blank");
+		}
+		if (StringUtils.isBlank(masterSecret)) {
+			throw new RuntimeException("Init parameter [masterSecret] can not blank");
+		}
+		if (StringUtils.isBlank(reqURL)) {
+			throw new RuntimeException("Init parameter [reqURL] can not blank");
+		}*/
+	}
+
+	@Override
+	public boolean send(String subject, String content, String receiver, String url, String type,String sound,String channelId) throws IOException {
+		String[] alias = { receiver };
+		String result = this.push(alias, subject, content, url,type,sound,channelId);
+		JSONObject json = JSONObject.parseObject(result);
+		if (json.containsKey("error")) {
+			JSONObject jsonObject = json.getJSONObject("error");
+			throw new ThirdpartyException(jsonObject.get("message").toString());
+		}
+		return true;
+	}
+
+	@Override
+	public boolean batchSend(String subject, String content, String[] receivers, String url, String type,String sound,String channelId) throws IOException {
+		String result = this.push(receivers, subject, content, url,type,sound,channelId);
+		JSONObject json = JSONObject.parseObject(result);
+		if (json.containsKey("error")) {
+			JSONObject jsonObject = json.getJSONObject("error");
+			throw new ThirdpartyException(jsonObject.get("message").toString()+"["+Arrays.stream(receivers).collect(Collectors.joining(","))+"]");
+		}
+		return true;
+	}
+
+	public void setStudentAppKey(String studentAppKey) {
+		this.studentAppKey = studentAppKey;
+	}
+
+	public void setStudentMasterSecret(String studentMasterSecret) {
+		this.studentMasterSecret = studentMasterSecret;
+	}
+
+	public void setTeacherAppKey(String teacherAppKey) {
+		this.teacherAppKey = teacherAppKey;
+	}
+
+	public void setTeacherMasterSecret(String teacherMasterSecret) {
+		this.teacherMasterSecret = teacherMasterSecret;
+	}
+
+	public String getSystemAppKey() {
+		return systemAppKey;
+	}
+
+	public void setSystemAppKey(String systemAppKey) {
+		this.systemAppKey = systemAppKey;
+	}
+
+	public String getSystemMasterSecret() {
+		return systemMasterSecret;
+	}
+
+	public void setSystemMasterSecret(String systemMasterSecret) {
+		this.systemMasterSecret = systemMasterSecret;
+	}
+
+	public void setApns_production(boolean apns_production) {
+		this.apns_production = apns_production;
+	}
+
+	public void setTime_to_live(int time_to_live) {
+		this.time_to_live = time_to_live;
+	}
+
+	public void setReqURL(String reqURL) {
+		this.reqURL = reqURL;
+	}
+
+}

+ 114 - 0
toolset/thirdparty-component/src/main/java/com/ym/mec/thirdparty/message/provider/MOxintongSMSPlugin.java

@@ -0,0 +1,114 @@
+package com.ym.mec.thirdparty.message.provider;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.ym.mec.thirdparty.exception.ThirdpartyException;
+import com.ym.mec.thirdparty.message.MessageSenderPlugin;
+import com.yonge.toolset.utils.http.HttpUtil;
+
+/**
+ * MO信通短信验证码接口
+ */
+@Service
+public class MOxintongSMSPlugin implements MessageSenderPlugin, InitializingBean {
+
+	private static ObjectMapper MAPPER = new ObjectMapper();
+
+	@Value("${Moxintong.username:1}")
+	private String username;
+	
+	@Value("${Moxintong.pwd:1}")
+	private String pwd;
+	
+	@Value("${Moxintong.reqUrl:1}")
+	private String reqUrl;
+
+	public static String getName() {
+		return "moxintong";
+	}
+
+	@Override
+	public boolean send(String subject, String content, String receiver, String url, String jpushType,String sound,String channelId) throws IOException {
+		Map<String, Object> reqParams = new HashMap<String, Object>();
+		reqParams.put("username", username);
+		reqParams.put("pwd", pwd);
+		reqParams.put("mobile", receiver);
+		reqParams.put("content", "【袋鼠卡】" + content);
+
+		String result = "";
+		try {
+			result = HttpUtil.postForHttps(reqUrl, reqParams);
+		} catch (Exception e) {
+			throw new ThirdpartyException("短信发送失败!", e);
+		}
+		HashMap jsonObject = MAPPER.readValue(result, HashMap.class);
+		if (jsonObject.get("code").toString().equals("0")) {
+			return true;
+		} else {
+			throw new ThirdpartyException(jsonObject.get("msg").toString());
+		}
+	}
+
+	@Override
+	public boolean batchSend(String subject, String content, String[] receivers, String url, String jpushType,String sound,String channelId) throws IOException {
+		StringBuilder stringBuilder = new StringBuilder();
+		for (int i = 0; i < receivers.length - 1; i++) {
+			stringBuilder.append(receivers[i]).append(",");
+		}
+		stringBuilder.append(receivers[receivers.length - 1]);
+
+		Map<String, Object> reqParams = new HashMap<String, Object>();
+		reqParams.put("username", username);
+		reqParams.put("pwd", pwd);
+		reqParams.put("mobile", stringBuilder.toString());
+		reqParams.put("content", "【兰鲸分期】" + content);
+
+		String result = "";
+		try {
+			result = HttpUtil.postForHttps(reqUrl, reqParams);
+		} catch (Exception e) {
+			throw new ThirdpartyException("短信发送失败!", e);
+		}
+		HashMap jsonObject = MAPPER.readValue(result, HashMap.class);
+		if (jsonObject.get("code").toString().equals("0")) {
+			return true;
+		} else {
+			throw new ThirdpartyException(jsonObject.get("msg").toString());
+		}
+	}
+
+	@Override
+	public void afterPropertiesSet() throws Exception {
+		// 参数检查
+		if (StringUtils.isBlank(reqUrl)) {
+			throw new RuntimeException("Init parameter [reqUrl] can not blank");
+		}
+		if (StringUtils.isBlank(username)) {
+			throw new RuntimeException("Init parameter [username] can not blank");
+		}
+		if (StringUtils.isBlank(pwd)) {
+			throw new RuntimeException("Init parameter [pwd] can not blank");
+		}
+	}
+
+	public void setUsername(String username) {
+		this.username = username;
+	}
+
+	public void setPwd(String pwd) {
+		this.pwd = pwd;
+	}
+
+	public void setReqUrl(String reqUrl) {
+		this.reqUrl = reqUrl;
+	}
+
+}

+ 124 - 0
toolset/thirdparty-component/src/main/java/com/ym/mec/thirdparty/message/provider/ShiyuanSMSPlugin.java

@@ -0,0 +1,124 @@
+package com.ym.mec.thirdparty.message.provider;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import com.alibaba.fastjson.JSONObject;
+import com.ym.mec.thirdparty.exception.ThirdpartyException;
+import com.ym.mec.thirdparty.message.MessageSenderPlugin;
+import com.yonge.toolset.utils.http.HttpUtil;
+
+/**
+ * 示远短信验证码接口
+ */
+@Service
+public class ShiyuanSMSPlugin implements MessageSenderPlugin, InitializingBean {
+	/**
+	 * 示远请求地址
+	 */
+	@Value("${sms.shiyuan.reqURL:1}")
+	private String reqURL;
+	/**
+	 * 示远账号
+	 */
+	@Value("${sms.shiyuan.account:1}")
+	private String account;
+	/**
+	 * 示远密码
+	 */
+	@Value("${sms.shiyuan.pwd:1}")
+	private String pswd;
+
+	// private boolean needstatus = true;//是否需要状态报告,需要true,不需要false
+	// private String product = "";//产品ID(不用填写)
+	// private String extno = "";//扩展码(不用填写)
+
+	public static String getName() {
+		return "shiyuan";
+	}
+
+	@Override
+	public void afterPropertiesSet() throws Exception {
+		// 参数检查
+		if (StringUtils.isBlank(reqURL)) {
+			throw new RuntimeException("Init parameter [reqURL] can not blank");
+		}
+		if (StringUtils.isBlank(account)) {
+			throw new RuntimeException("Init parameter [account] can not blank");
+		}
+		if (StringUtils.isBlank(pswd)) {
+			throw new RuntimeException("Init parameter [pswd] can not blank");
+		}
+	}
+
+	public void setReqURL(String reqURL) {
+		this.reqURL = reqURL;
+	}
+
+	public void setAccount(String account) {
+		this.account = account;
+	}
+
+	public void setPswd(String pswd) {
+		this.pswd = pswd;
+	}
+
+	@Override
+	public boolean send(String subject, String content, String receiver, String url,String jpushType,String sound,String channelId) throws IOException {
+		try {
+			Map<String, Object> reqParams = new HashMap<String, Object>();
+			reqParams.put("account", account);
+			reqParams.put("pswd", pswd);
+			reqParams.put("mobile", receiver);
+			reqParams.put("msg", content);
+			reqParams.put("needstatus", true);
+			reqParams.put("product", "");
+			reqParams.put("extno", "");
+			reqParams.put("resptype", "json");
+			String resultParams = HttpUtil.postForHttp(reqURL, reqParams);
+			JSONObject jsonObject = JSONObject.parseObject(resultParams);
+			if (jsonObject.get("result").equals("0")) {
+				return true;
+			}
+		} catch (Exception e) {
+			throw new ThirdpartyException("Failed to invoke shiyuan service", e);
+		}
+		return false;
+	}
+
+	@Override
+	public boolean batchSend(String subject, String content, String[] receivers, String url,String jpushType,String sound,String channelId) throws IOException {
+		StringBuilder stringBuilder = new StringBuilder("");
+		for (int i = 0; i < receivers.length - 1; i++) {
+			stringBuilder.append(receivers[i]).append(",");
+		}
+		stringBuilder.append(receivers[receivers.length - 1]);
+		try {
+			Map<String, Object> reqParams = new HashMap<>();
+			reqParams.put("account", account);
+			reqParams.put("pswd", pswd);
+			reqParams.put("mobile", stringBuilder.toString().trim());
+			reqParams.put("msg", content);
+			reqParams.put("needstatus", true);
+			reqParams.put("product", "");
+			reqParams.put("extno", "");
+			reqParams.put("resptype", "json");
+			// 发起请求
+			String resultParams = HttpUtil.postForHttp(reqURL, reqParams);
+			JSONObject jsonObject = JSONObject.parseObject(resultParams);
+			if (jsonObject.get("result").equals("0")) {
+				return true;
+			}
+			throw new ThirdpartyException("示远科技短信验证码发送失败");
+		} catch (Exception e) {
+			throw new ThirdpartyException("Failed to invoke shiyuan service", e);
+		}
+	}
+
+}

+ 89 - 0
toolset/thirdparty-component/src/main/java/com/ym/mec/thirdparty/message/provider/YimeiSmsPlugin.java

@@ -0,0 +1,89 @@
+package com.ym.mec.thirdparty.message.provider;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+
+import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import com.alibaba.fastjson.JSONObject;
+import com.ym.mec.thirdparty.exception.ThirdpartyException;
+import com.ym.mec.thirdparty.message.MessageSenderPlugin;
+import com.yonge.toolset.utils.date.DateUtil;
+import com.yonge.toolset.utils.http.HttpUtil;
+
+/**
+ * 亿美短信
+ */
+@Service
+public class YimeiSmsPlugin implements MessageSenderPlugin, InitializingBean {
+
+	private Logger logger = LoggerFactory.getLogger(YimeiSmsPlugin.class);
+
+	@Value("${com.properties.sms-appId:EUCP-EMY-SMS1-DX0Y9}")
+	private String appId;
+	@Value("${com.properties.sms-secretKey:B0C8230D0F2ACC64}")
+	private String secretKey;
+	@Value("${com.properties.sms-host-dev:http://bjmtn.b2m.cn}")
+	private String host;
+
+	public static String getName() {
+		return "yimei";
+	}
+
+	private String getParam(String subject, String content, String receiver, String host) {
+		try {
+			HashMap<String, Object> param = new HashMap();
+			param.put("appId", appId);
+			String timestamp = DateUtil.format(new Date(), new SimpleDateFormat("yyyyMMddHHmmss"));
+			param.put("timestamp", timestamp);
+			param.put("sign", DigestUtils.md5Hex(appId + secretKey + timestamp));
+			param.put("content", content);
+			param.put("mobiles", receiver);
+			
+			long startTime = System.currentTimeMillis();
+			String result =  HttpUtil.postForHttp(host, param);
+			logger.info("调用亿美接口共消耗{}毫秒",System.currentTimeMillis() - startTime);
+			
+			return result;
+		} catch (Exception e) {
+			throw new ThirdpartyException("调用发送短信接口出现异常", e);
+		}
+	}
+
+	@Override
+	public boolean send(String subject, String content, String receiver, String url,String jpushType,String sound,String channelId) throws Exception {
+		String result = getParam(subject, content, receiver, host + "/simpleinter/sendSMS");
+		JSONObject json = JSONObject.parseObject(result);
+		if ("SUCCESS".equals(json.get("code"))) {
+
+			return true;
+		} else {
+			throw new Exception(json.getString("code"));
+		}
+	}
+
+	@Override
+	public boolean batchSend(String subject, String content, String[] receivers, String url,String jpushType,String sound,String channelId) throws Exception {
+		String join = StringUtils.join(receivers, ",");
+		String result = getParam(subject, content, join, host + "/simpleinter/sendSMS");
+		logger.info("调用短信接口返回:{}", result);
+		JSONObject json = JSONObject.parseObject(result);
+		if ("SUCCESS".equals(json.get("code"))) {
+			return true;
+		} else {
+			throw new Exception(json.getString("code"));
+		}
+	}
+
+	@Override
+	public void afterPropertiesSet() throws Exception {
+
+	}
+}

+ 35 - 0
toolset/thirdparty-component/src/main/java/com/ym/mec/thirdparty/storage/StoragePlugin.java

@@ -0,0 +1,35 @@
+package com.ym.mec.thirdparty.storage;
+
+import java.io.File;
+import java.io.IOException;
+
+public interface StoragePlugin {
+	
+	String getName();
+
+	/**
+	 * 上传文件
+	 * @param folderName 文件夹
+	 * @param file 需要上传的文件
+	 * @return 返回文件路径
+	 */
+	String uploadFile(String folderName, File file);
+
+	/**
+	 * 上传文件
+	 * @param folderName 文件夹
+	 * @param file 需要上传的文件
+	 * @param delLocalFile 删除本地文件
+	 * @return 返回文件路径
+	 */
+	String asyncUploadFile(String folderName, File file, boolean delLocalFile);
+
+	/**
+	 * 下载文件
+	 * @param folderName 文件夹
+	 * @param fileName 文件名称
+	 * @return 返回文件内容
+	 * @throws IOException
+	 */
+	byte[] getFile(String folderName, String fileName) throws IOException;
+}

+ 43 - 0
toolset/thirdparty-component/src/main/java/com/ym/mec/thirdparty/storage/StoragePluginContext.java

@@ -0,0 +1,43 @@
+package com.ym.mec.thirdparty.storage;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.springframework.stereotype.Component;
+
+import com.ym.mec.thirdparty.exception.ThirdpartyException;
+
+@Component
+public class StoragePluginContext {
+
+	private static final Map<String, StoragePlugin> mapper = new HashMap<String, StoragePlugin>();
+	
+	public static void addStoragePlugin(StoragePlugin storagePlugin) {
+		if (mapper.containsKey(storagePlugin.getName())) {
+			throw new ThirdpartyException("存储插件:{}已存在", storagePlugin.getName());
+		}
+		mapper.put(storagePlugin.getName(), storagePlugin);
+	}
+	
+	public String uploadFile(String storagePluginName, String folderName, File file){
+		StoragePlugin StoragePlugin = getStoragePlugin(storagePluginName);
+		return StoragePlugin.uploadFile(folderName, file);
+	}
+	
+	public String asyncUploadFile(String storagePluginName, String folderName, File file, boolean delLocalFile){
+		StoragePlugin StoragePlugin = getStoragePlugin(storagePluginName);
+		return StoragePlugin.asyncUploadFile(folderName, file, delLocalFile);
+	}
+
+	private StoragePlugin getStoragePlugin(String storagePluginName) {
+		StoragePlugin storagePlugin = mapper.get(storagePluginName);
+
+		if (storagePlugin == null) {
+			throw new ThirdpartyException("存储插件:{}不存在", storagePluginName);
+		}
+
+		return storagePlugin;
+	}
+
+}

+ 160 - 0
toolset/thirdparty-component/src/main/java/com/ym/mec/thirdparty/storage/provider/AliyunOssStoragePlugin.java

@@ -0,0 +1,160 @@
+package com.ym.mec.thirdparty.storage.provider;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.poi.util.IOUtils;
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import com.aliyun.oss.ClientConfiguration;
+import com.aliyun.oss.OSSClient;
+import com.aliyun.oss.model.OSSObject;
+import com.ym.mec.thirdparty.exception.ThirdpartyException;
+import com.ym.mec.thirdparty.storage.StoragePlugin;
+import com.ym.mec.thirdparty.storage.StoragePluginContext;
+
+@Component
+public class AliyunOssStoragePlugin implements StoragePlugin, InitializingBean, DisposableBean {
+
+	public final static String PLUGIN_NAME = "Aliyun";
+
+	@Value("${storage.oss.endpoint:oss-cn-beijing.aliyuncs.com}")
+	private String endpoint;
+
+	@Value("${storage.oss.accessKeyId:LTAI4Fdhxwfo7FsBDZKK8Wfv}")
+	private String accessKeyId;
+
+	@Value("${storage.oss.accessKeySecret:ERRma4P9VWbD98n93gspnZXmoq7rn5}")
+	private String accessKeySecret;
+
+	@Value("${storage.oss.bucketName:daya-online}")
+	private String bucketName;
+
+	private OSSClient ossClient;
+
+	public String getName() {
+		return PLUGIN_NAME;
+	}
+
+	@Override
+	public void afterPropertiesSet() throws Exception {
+		// 创建ClientConfiguration。ClientConfiguration是OSSClient的配置类,可配置代理、连接超时、最大连接数等参数。
+		ClientConfiguration conf = new ClientConfiguration();
+
+		// 设置OSSClient允许打开的最大HTTP连接数,默认为1024个。
+		conf.setMaxConnections(200);
+		// 设置Socket层传输数据的超时时间,默认为50000毫秒。
+		conf.setSocketTimeout(10000);
+		// 设置建立连接的超时时间,默认为50000毫秒。
+		conf.setConnectionTimeout(10000);
+		// 设置从连接池中获取连接的超时时间(单位:毫秒),默认不超时。
+		conf.setConnectionRequestTimeout(1000);
+		// 设置连接空闲超时时间。超时则关闭连接,默认为60000毫秒。
+		conf.setIdleConnectionTime(10000);
+		// 设置失败请求重试次数,默认为3次。
+		conf.setMaxErrorRetry(5);
+		// 设置是否支持将自定义域名作为Endpoint,默认支持。
+		conf.setSupportCname(true);
+
+		ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret, conf);
+		
+		StoragePluginContext.addStoragePlugin(this);
+	}
+
+	@Override
+	public String uploadFile(String folderName, File file) {
+		if (!file.exists()) {
+			throw new ThirdpartyException("需要上传的文件[{}]不存在", file.getAbsolutePath());
+		}
+
+		if (folderName.endsWith("/")) {
+			folderName = folderName.substring(0, folderName.length() - 1);
+		}
+
+		ossClient.putObject(bucketName, folderName + "/" + file.getName(), file);
+
+		return "https://" + bucketName + "." + endpoint + "/" + folderName + "/" + file.getName();
+	}
+
+	@Override
+	public String asyncUploadFile(String folderName, File file, boolean delLocalFile) {
+		if (!file.exists()) {
+			throw new ThirdpartyException("需要上传的文件[{}]不存在", file.getAbsolutePath());
+		}
+
+		if (folderName.endsWith("/")) {
+			folderName = folderName.substring(0, folderName.length() - 1);
+		}
+		
+		final String dir = folderName;
+		
+		Thread thread = new Thread(new Runnable() {
+			
+			@Override
+			public void run() {
+				ossClient.putObject(bucketName, dir + "/" + file.getName(), file);
+				if(delLocalFile){
+					FileUtils.deleteQuietly(file);
+				}
+			}
+		});
+		thread.start();
+
+		return "https://" + bucketName + "." + endpoint + "/" + folderName + "/" + file.getName();
+	}
+
+	@Override
+	public byte[] getFile(String folderName, String fileName) throws IOException {
+		OSSObject ossObject = ossClient.getObject(bucketName, folderName + "/" + fileName);
+		try {
+			return IOUtils.toByteArray(ossObject.getObjectContent());
+		} finally {
+			if (ossObject != null) {
+				ossObject.close();
+			}
+		}
+	}
+
+	@Override
+	public void destroy() throws Exception {
+		if (ossClient != null) {
+			ossClient.shutdown();
+		}
+	}
+
+	public void setEndpoint(String endpoint) {
+		this.endpoint = endpoint;
+	}
+
+	public void setAccessKeyId(String accessKeyId) {
+		this.accessKeyId = accessKeyId;
+	}
+
+	public void setAccessKeySecret(String accessKeySecret) {
+		this.accessKeySecret = accessKeySecret;
+	}
+
+	public void setBucketName(String bucketName) {
+		this.bucketName = bucketName;
+	}
+
+	public static void main(String[] args) throws Exception {
+		AliyunOssStoragePlugin aliyunOssStorageService = new AliyunOssStoragePlugin();
+		aliyunOssStorageService.setAccessKeyId("LTAIwZW9XqrfsZ4r");
+		aliyunOssStorageService.setAccessKeySecret("5uDsNZmHMxcnxav8w9byII4zcPpu5G");
+		aliyunOssStorageService.setBucketName("yooma-test");
+		aliyunOssStorageService.setEndpoint("oss-cn-beijing.aliyuncs.com");
+		aliyunOssStorageService.afterPropertiesSet();
+
+		File file = new File("e:/var/2.jpg");
+		System.out.println(aliyunOssStorageService.uploadFile("aaa", file));
+
+		System.err.println("***********" + aliyunOssStorageService.getFile("aaa", file.getName()).length);
+
+		aliyunOssStorageService.destroy();
+	}
+}

+ 176 - 0
toolset/thirdparty-component/src/main/java/com/ym/mec/thirdparty/storage/provider/KS3StoragePlugin.java

@@ -0,0 +1,176 @@
+package com.ym.mec.thirdparty.storage.provider;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.poi.util.IOUtils;
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import com.ksyun.ks3.dto.CannedAccessControlList;
+import com.ksyun.ks3.dto.GetObjectResult;
+import com.ksyun.ks3.dto.Ks3Object;
+import com.ksyun.ks3.http.HttpClientConfig;
+import com.ksyun.ks3.service.Ks3;
+import com.ksyun.ks3.service.Ks3Client;
+import com.ksyun.ks3.service.Ks3ClientConfig;
+import com.ksyun.ks3.service.Ks3ClientConfig.PROTOCOL;
+import com.ksyun.ks3.service.request.GetObjectRequest;
+import com.ksyun.ks3.service.request.PutObjectRequest;
+import com.ym.mec.thirdparty.exception.ThirdpartyException;
+import com.ym.mec.thirdparty.storage.StoragePlugin;
+import com.ym.mec.thirdparty.storage.StoragePluginContext;
+
+@Component
+public class KS3StoragePlugin implements StoragePlugin, InitializingBean, DisposableBean {
+
+	public final static String PLUGIN_NAME = "Ksyun";
+
+	@Value("${storage.oss.endpoint:ks3-cn-beijing.ksyun.com}")
+	private String endpoint;
+
+	@Value("${storage.oss.accessKeyId:AKLTtTeIbadpRG-pil4S0Q4m-Q}")
+	private String accessKeyId;
+
+	@Value("${storage.oss.accessKeySecret:OB1HmNOfDNW95wHoxMkP6IPFZXormk2ngA800TkvKAw7ozhiJGRqrMnnV8ZrAU3WRQ==}")
+	private String accessKeySecret;
+
+	@Value("${storage.oss.bucketName:daya}")
+	private String bucketName;
+
+	private Ks3 client;
+
+	public String getName() {
+		return PLUGIN_NAME;
+	}
+
+	@Override
+	public void afterPropertiesSet() throws Exception {
+		Ks3ClientConfig config = new Ks3ClientConfig();
+		config.setEndpoint(endpoint);// 如果使用自定义域名,设置endpoint为自定义域名,同时设置domainMode为true
+		/**
+		 * true:表示以自定义域名访问 
+		 * false:表示以KS3的外网域名或内网域名访问
+		 * 默认为false
+		 */
+		config.setDomainMode(false);
+		config.setProtocol(PROTOCOL.http);
+
+		/**
+		 * true表示以   endpoint/{bucket}/{key}的方式访问
+		 * false表示以  {bucket}.endpoint/{key}的方式访问
+		 * 如果domainMode设置为true,pathStyleAccess可忽略设置
+		 */
+		config.setPathStyleAccess(false);
+		HttpClientConfig hconfig = new HttpClientConfig();
+		// 在HttpClientConfig中可以设置httpclient的相关属性,比如代理,超时,重试等。
+		config.setHttpClientConfig(hconfig);
+		client = new Ks3Client(accessKeyId, accessKeySecret, config);
+
+		StoragePluginContext.addStoragePlugin(this);
+	}
+
+	@Override
+	public String uploadFile(String folderName, File file) {
+		if (!file.exists()) {
+			throw new ThirdpartyException("需要上传的文件[{}]不存在", file.getAbsolutePath());
+		}
+
+		if (folderName.endsWith("/")) {
+			folderName = folderName.substring(0, folderName.length() - 1);
+		}
+
+		PutObjectRequest request = new PutObjectRequest(bucketName, folderName + "/" + file.getName(), file);
+
+		// 上传一个公开文件
+		request.setCannedAcl(CannedAccessControlList.PublicRead);
+
+		client.putObject(request);
+
+		return "https://" + bucketName + "." + endpoint + "/" + folderName + "/" + file.getName();
+	}
+
+	@Override
+	public String asyncUploadFile(String folderName, File file, boolean delLocalFile) {
+		if (!file.exists()) {
+			throw new ThirdpartyException("需要上传的文件[{}]不存在", file.getAbsolutePath());
+		}
+
+		if (folderName.endsWith("/")) {
+			folderName = folderName.substring(0, folderName.length() - 1);
+		}
+
+		PutObjectRequest request = new PutObjectRequest(bucketName, folderName + "/" + file.getName(), file);
+
+		// 上传一个公开文件
+		request.setCannedAcl(CannedAccessControlList.PublicRead);
+		
+		Thread thread = new Thread(new Runnable() {
+			
+			@Override
+			public void run() {
+				client.putObject(request);
+				if(delLocalFile){
+					FileUtils.deleteQuietly(file);
+				}
+			}
+		});
+		thread.start();
+
+		return "https://" + bucketName + "." + endpoint + "/" + folderName + "/" + file.getName();
+	}
+
+	@Override
+	public byte[] getFile(String folderName, String fileName) throws IOException {
+		GetObjectRequest request = new GetObjectRequest(bucketName, folderName + "/" + fileName);
+		GetObjectResult result = client.getObject(request);
+
+		Ks3Object object = result.getObject();
+		try {
+			return IOUtils.toByteArray(object.getObjectContent());
+		} finally {
+			if (object != null) {
+				object.close();
+			}
+		}
+	}
+
+	@Override
+	public void destroy() throws Exception {
+	}
+
+	public void setEndpoint(String endpoint) {
+		this.endpoint = endpoint;
+	}
+
+	public void setAccessKeyId(String accessKeyId) {
+		this.accessKeyId = accessKeyId;
+	}
+
+	public void setAccessKeySecret(String accessKeySecret) {
+		this.accessKeySecret = accessKeySecret;
+	}
+
+	public void setBucketName(String bucketName) {
+		this.bucketName = bucketName;
+	}
+
+	public static void main(String[] args) throws Exception {
+		KS3StoragePlugin aliyunOssStorageService = new KS3StoragePlugin();
+		aliyunOssStorageService.setAccessKeyId("LTAIwZW9XqrfsZ4r");
+		aliyunOssStorageService.setAccessKeySecret("5uDsNZmHMxcnxav8w9byII4zcPpu5G");
+		aliyunOssStorageService.setBucketName("yooma-test");
+		aliyunOssStorageService.setEndpoint("oss-cn-beijing.aliyuncs.com");
+		aliyunOssStorageService.afterPropertiesSet();
+
+		File file = new File("e:/var/2.jpg");
+		System.out.println(aliyunOssStorageService.uploadFile("aaa", file));
+
+		System.err.println("***********" + aliyunOssStorageService.getFile("aaa", file.getName()).length);
+
+		aliyunOssStorageService.destroy();
+	}
+}

+ 63 - 0
toolset/thirdparty-component/src/main/java/com/ym/mec/thirdparty/union/GenerateNum.java

@@ -0,0 +1,63 @@
+package com.ym.mec.thirdparty.union;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * 生成订单号类
+ */
+public class GenerateNum {
+    // 使用单例模式,不允许直接创建实例
+    private GenerateNum() {}
+
+    // 创建一个空实例对象,类需要用的时候才赋值
+    private static GenerateNum g = null;
+
+    // 单例模式--懒汉模式
+    public static synchronized GenerateNum getInstance() {
+        if (g == null) {
+            g = new GenerateNum();
+        }
+        return g;
+    }
+
+    // 全局自增数
+    private static int count = 0;
+
+    // 每毫秒秒最多生成多少订单(最好是像9999这种准备进位的值)
+    private static final int total = 9999;
+
+    // 格式化的时间字符串
+    private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
+
+    // 获取当前时间年月日时分秒毫秒字符串
+    private static String getNowDateStr() {
+        return sdf.format(new Date());
+    }
+
+    // 记录上一次的时间,用来判断是否需要递增全局数
+    private static String now = null;
+
+    /*
+     * 生成一个订单号
+     */
+    public synchronized String GenerateOrderNo() {
+        String datastr = getNowDateStr();
+        if (datastr.equals(now)) {
+            count++;// 自增
+        } else {
+            count = 1;
+            now = datastr;
+        }
+        int countInteger = String.valueOf(total).length() - String.valueOf(count).length();// 算补位
+        String bu = "";// 补字符串
+        for (int i = 0; i < countInteger; i++) {
+            bu += "0";
+        }
+        bu += String.valueOf(count);
+        if (count >= total) {
+            count = 0;
+        }
+        return datastr + bu;
+    }
+}

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