Przeglądaj źródła

biz-common 初始化

liyang 1 rok temu
commit
8401f3ccec
54 zmienionych plików z 3948 dodań i 0 usunięć
  1. 3 0
      .idea/.gitignore
  2. 18 0
      .idea/compiler.xml
  3. 7 0
      .idea/encodings.xml
  4. 20 0
      .idea/jarRepositories.xml
  5. 14 0
      .idea/misc.xml
  6. 124 0
      .idea/uiDesigner.xml
  7. 6 0
      .idea/vcs.xml
  8. 9 0
      .idea/ywt-biz-common.iml
  9. 71 0
      README.md
  10. 8 0
      anytxn-biz-common.iml
  11. 133 0
      pom.xml
  12. 16 0
      src/main/java/com/ywt/biz/common/annotation/EncryptField.java
  13. 16 0
      src/main/java/com/ywt/biz/common/annotation/EncryptModel.java
  14. 31 0
      src/main/java/com/ywt/biz/common/config/db/Datasources.java
  15. 67 0
      src/main/java/com/ywt/biz/common/config/db/YwtLog.java
  16. 71 0
      src/main/java/com/ywt/biz/common/config/db/Ywtcenter.java
  17. 78 0
      src/main/java/com/ywt/biz/common/constant/AnyTxnCommonRespCode.java
  18. 31 0
      src/main/java/com/ywt/biz/common/constant/GlobalConstants.java
  19. 16 0
      src/main/java/com/ywt/biz/common/constant/PropsConstants.java
  20. 135 0
      src/main/java/com/ywt/biz/common/constant/RespCodePrefix.java
  21. 96 0
      src/main/java/com/ywt/biz/common/dto/PageResultDTO.java
  22. 12 0
      src/main/java/com/ywt/biz/common/exception/AppMessageException.java
  23. 18 0
      src/main/java/com/ywt/biz/common/exception/NullOrEmptyException.java
  24. 63 0
      src/main/java/com/ywt/biz/common/exception/YwtCommonException.java
  25. 117 0
      src/main/java/com/ywt/biz/common/exception/YwtException.java
  26. 75 0
      src/main/java/com/ywt/biz/common/handler/GlobalExceptionHandler.java
  27. 68 0
      src/main/java/com/ywt/biz/common/structs/MultipleTree.java
  28. 92 0
      src/main/java/com/ywt/biz/common/structs/TreeNode.java
  29. 203 0
      src/main/java/com/ywt/biz/common/structs/TrieTree.java
  30. 79 0
      src/main/java/com/ywt/biz/common/swagger/ApiInfoProperties.java
  31. 38 0
      src/main/java/com/ywt/biz/common/swagger/DocketProperties.java
  32. 143 0
      src/main/java/com/ywt/biz/common/swagger/SwaggerConfiguration.java
  33. 55 0
      src/main/java/com/ywt/biz/common/swagger/SwaggerProperties.java
  34. 15 0
      src/main/java/com/ywt/biz/common/util/Checksum.java
  35. 68 0
      src/main/java/com/ywt/biz/common/util/CollectionUtil.java
  36. 74 0
      src/main/java/com/ywt/biz/common/util/DateUtil.java
  37. 232 0
      src/main/java/com/ywt/biz/common/util/ImageUtil.java
  38. 86 0
      src/main/java/com/ywt/biz/common/util/PhoneNumChecker.java
  39. 117 0
      src/main/java/com/ywt/biz/common/util/PinYinUtil.java
  40. 88 0
      src/main/java/com/ywt/biz/common/util/RandomUtil.java
  41. 133 0
      src/main/java/com/ywt/biz/common/util/StringHelper.java
  42. 56 0
      src/main/java/com/ywt/biz/common/util/serializers/JsonSerializer.java
  43. 97 0
      src/main/java/com/ywt/biz/common/util/serializers/XMLSerializer.java
  44. 30 0
      src/main/java/com/ywt/biz/common/validator/Values.java
  45. 36 0
      src/main/java/com/ywt/biz/common/validator/ValuesValidator.java
  46. 14 0
      src/main/java/com/ywt/biz/common/web/BizBaseController.java
  47. 24 0
      src/main/java/com/ywt/biz/common/web/LocalDateTimeSerializerConfig.java
  48. 127 0
      src/main/java/com/ywt/biz/common/web/YwtHttpResponse.java
  49. 107 0
      src/test/java/jrx/anytxn/biz/common/util/CustomThreadPoolExecutor.java
  50. 33 0
      src/test/java/jrx/anytxn/biz/common/util/CvvTest.java
  51. 20 0
      src/test/java/jrx/anytxn/biz/common/util/DateHelperTest.java
  52. 532 0
      src/test/java/jrx/anytxn/biz/common/util/DateUtilsTest.java
  53. 78 0
      src/test/java/jrx/anytxn/biz/common/util/NumberUtilsTest.java
  54. 48 0
      src/test/java/jrx/anytxn/biz/common/util/PinTest.java

+ 3 - 0
.idea/.gitignore

@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml

+ 18 - 0
.idea/compiler.xml

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

+ 7 - 0
.idea/encodings.xml

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

+ 20 - 0
.idea/jarRepositories.xml

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

+ 14 - 0
.idea/misc.xml

@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ExternalStorageConfigurationManager" enabled="true" />
+  <component name="MavenProjectsManager">
+    <option name="originalFiles">
+      <list>
+        <option value="$PROJECT_DIR$/pom.xml" />
+      </list>
+    </option>
+  </component>
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
+    <output url="file://$PROJECT_DIR$/out" />
+  </component>
+</project>

+ 124 - 0
.idea/uiDesigner.xml

@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="Palette2">
+    <group name="Swing">
+      <item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
+      </item>
+      <item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
+      </item>
+      <item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
+      </item>
+      <item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
+        <default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
+      </item>
+      <item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
+        <initial-values>
+          <property name="text" value="Button" />
+        </initial-values>
+      </item>
+      <item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
+        <initial-values>
+          <property name="text" value="RadioButton" />
+        </initial-values>
+      </item>
+      <item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
+        <initial-values>
+          <property name="text" value="CheckBox" />
+        </initial-values>
+      </item>
+      <item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
+        <initial-values>
+          <property name="text" value="Label" />
+        </initial-values>
+      </item>
+      <item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
+          <preferred-size width="150" height="-1" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
+          <preferred-size width="150" height="-1" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
+          <preferred-size width="150" height="-1" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
+      </item>
+      <item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
+          <preferred-size width="200" height="200" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
+          <preferred-size width="200" height="200" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
+      </item>
+      <item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
+      </item>
+      <item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
+      </item>
+      <item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
+      </item>
+      <item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
+          <preferred-size width="-1" height="20" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
+      </item>
+      <item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
+      </item>
+    </group>
+  </component>
+</project>

+ 6 - 0
.idea/vcs.xml

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

+ 9 - 0
.idea/ywt-biz-common.iml

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

+ 71 - 0
README.md

@@ -0,0 +1,71 @@
+
+# 工程名称
+# 医务通系统-公共工程
+
+## 工程用途及介绍
+## 交易服务工程
+> 该工程主要包含个工程使用依赖,各工程所需常量、枚举、异常及工具类
+- 提供各工程所需常量、枚举、异常及工具类
+- 提供自定义异常,可统一处理异常
+- 提供各种工具类
+- 提供web controller基类及http返回数据结构等
+## 使用用户群
+- 开发
+- 运维
+- 测试
+
+## 用户术语
+
+
+## 工程结构说明
+> 工程目录结构,包结构说明
+- ywt-biz-common(anytxn 基础包)
+    + 包结构说明
+    ```text
+      - java
+         - com.ywt.biz.common      
+            - config        系统配置类包,主要是redis配置
+             - ErrorCode 错误码定义
+             - RedisConfig redis配置
+             - RedisService 外部直接使用此类进行
+           - constant      系统常量定义
+             - order         订单常量定义
+             - payment         支付常量定义
+             - ...
+           - dto           基础dto定义,如查询返回结果dto
+             - PageResultDTO
+           - exception     自定义异常,包括统一异常
+           - handler       全局异常处理器
+             - GlobalExceptionHandler
+           - util          一些工具类
+             - encryption  加解密相关
+             - AmountUtil
+             - ...
+           - validator     取值校验器
+             - Values
+             - ValuesValidator
+           - web           定义了controller基类/http返回数据结构/LocalDateTime序列化
+             - BizBaseController
+             - HttpApiResponse
+             - LocalDateTimeSerializerConfig
+
+    ```
+               
+
+
+## 配置文件说明
+
+## 服务发布
+- 上传至maven仓库  
+  ```text
+  1. 在工程根目录下执行如下命令上传至maven仓库
+   mvn clean deploy 
+  2. 使用方式
+            <dependency>
+                <groupId>com.ywt</groupId>
+                <artifactId>anytxn-biz-common</artifactId>
+                <version>${anytxn-biz-common.version}</version>
+            </dependency>
+   ```
+  
+## 参考文档

+ 8 - 0
anytxn-biz-common.iml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module version="4">
+  <component name="FacetManager">
+    <facet type="Spring" name="Spring">
+      <configuration />
+    </facet>
+  </component>
+</module>

+ 133 - 0
pom.xml

@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+
+	<parent>
+		<groupId>com.ywt</groupId>
+		<artifactId>ywt-parent</artifactId>
+		<version>1.0.0-SNAPSHOT</version>
+	</parent>
+
+	<artifactId>ywt-biz-common</artifactId>
+	<name>ywt-biz-common</name>
+	<description>医务通-业务公共工程</description>
+	<packaging>jar</packaging>
+	<!-- 公共属性 -->
+	<properties>
+		<java.version>1.8</java.version>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+	</properties>
+
+	<dependencies>
+
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-data-jpa</artifactId>
+			<exclusions>
+				<exclusion>
+					<groupId>org.slf4j</groupId>
+					<artifactId>jcl-over-slf4j</artifactId>
+				</exclusion>
+				<exclusion>
+					<groupId>org.slf4j</groupId>
+					<artifactId>jul-to-slf4j</artifactId>
+				</exclusion>
+
+			</exclusions>
+		</dependency>
+		<dependency>
+			<groupId>javax.validation</groupId>
+			<artifactId>validation-api</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>org.springframework</groupId>
+			<artifactId>spring-jdbc</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>com.fasterxml.jackson.core</groupId>
+			<artifactId>jackson-databind</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>com.fasterxml.jackson.datatype</groupId>
+			<artifactId>jackson-datatype-jsr310</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>com.google.guava</groupId>
+			<artifactId>guava</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>org.apache.commons</groupId>
+			<artifactId>commons-lang3</artifactId>
+		</dependency>
+		
+
+		<dependency>
+		    <groupId>org.slf4j</groupId>
+		    <artifactId>slf4j-api</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>com.zaxxer</groupId>
+			<artifactId>HikariCP</artifactId>
+		</dependency>
+
+
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-autoconfigure</artifactId>
+			<scope>provided</scope>
+		</dependency>
+
+		<dependency>
+			<groupId>io.springfox</groupId>
+			<artifactId>springfox-swagger2</artifactId>
+			<scope>provided</scope>
+		</dependency>
+
+		<dependency>
+			<groupId>org.springframework</groupId>
+			<artifactId>spring-web</artifactId>
+			<scope>provided</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.springframework</groupId>
+			<artifactId>spring-tx</artifactId>
+			<scope>provided</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.springframework</groupId>
+			<artifactId>spring-jdbc</artifactId>
+			<scope>provided</scope>
+		</dependency>
+		<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
+		<dependency>
+			<groupId>javax.servlet</groupId>
+			<artifactId>javax.servlet-api</artifactId>
+			<version>4.0.1</version>
+			<scope>provided</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.projectlombok</groupId>
+			<artifactId>lombok</artifactId>
+			<scope>provided</scope>
+		</dependency>
+		<dependency>
+			<groupId>com.belerweb</groupId>
+			<artifactId>pinyin4j</artifactId>
+			<version>2.5.1</version>
+		</dependency>
+		<dependency>
+			<groupId>com.google.guava</groupId>
+			<artifactId>guava</artifactId>
+		</dependency>
+
+	</dependencies>
+
+</project>

+ 16 - 0
src/main/java/com/ywt/biz/common/annotation/EncryptField.java

@@ -0,0 +1,16 @@
+package com.ywt.biz.common.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * @Author wangshuguan
+ * @Description 字段加解密
+ * @Date 2020-09-13
+ * @Version
+ */
+@Documented
+@Inherited
+@Target({ ElementType.FIELD })
+@Retention(RetentionPolicy.RUNTIME)
+public @interface EncryptField {
+}

+ 16 - 0
src/main/java/com/ywt/biz/common/annotation/EncryptModel.java

@@ -0,0 +1,16 @@
+package com.ywt.biz.common.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * @Author wangshuguan
+ * @Description 需要加解密的对象
+ * @Date 2020-09-13
+ * @Version
+ */
+@Documented
+@Inherited
+@Target({ ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+public @interface EncryptModel {
+}

+ 31 - 0
src/main/java/com/ywt/biz/common/config/db/Datasources.java

@@ -0,0 +1,31 @@
+package com.ywt.biz.common.config.db;
+
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.jdbc.DataSourceBuilder ;
+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 javax.sql.DataSource;
+
+/**
+ * Created by huangguoping.
+ */
+@Configuration
+public class Datasources {
+    @Bean(name = "ywtCenterDataSource")
+    @Qualifier("ywtCenterDataSource")
+    @ConfigurationProperties(prefix="spring.datasource.ywtcenter")
+    @Primary
+    public DataSource ywtCenterDataSource(){
+        return DataSourceBuilder.create().build();
+    }
+
+    @Bean(name = "ywtLogDataSource")
+    @Qualifier("ywtLogDataSource")
+    @ConfigurationProperties(prefix="spring.datasource.ywtlog")
+    public DataSource ywtLogDataSource(){
+        return DataSourceBuilder.create().build();
+    }
+}

+ 67 - 0
src/main/java/com/ywt/biz/common/config/db/YwtLog.java

@@ -0,0 +1,67 @@
+package com.ywt.biz.common.config.db;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties;
+import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings;
+import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+import org.springframework.orm.jpa.JpaTransactionManager;
+import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+import javax.persistence.EntityManager;
+import javax.sql.DataSource;
+import java.util.Map;
+
+/**
+ * @author Walker
+ * Created on 2021/3/4
+ */
+@Configuration
+@EnableTransactionManagement
+@EnableJpaRepositories(
+        entityManagerFactoryRef = "entityManagerFactoryLog",
+        transactionManagerRef = "transactionManagerLog",
+        basePackages = {"com.ywt.rpc.domain.entities_log"}
+)
+public class YwtLog {
+    @Autowired
+    @Qualifier("ywtLogDataSource")
+    private DataSource ywtLogDataSource;
+
+    @Bean(name = "entityManagerLog")
+    public EntityManager entityManager(EntityManagerFactoryBuilder builder,@Qualifier("ywtLogJpaProperties") JpaProperties jpaProperties) {
+        return entityManagerFactory(builder, jpaProperties).getObject().createEntityManager();
+    }
+
+    @Bean(name = "entityManagerFactoryLog")
+    public LocalContainerEntityManagerFactoryBean entityManagerFactory (EntityManagerFactoryBuilder builder,
+                                                                        @Qualifier("ywtLogJpaProperties") JpaProperties jpaProperties) {
+        return builder
+                .dataSource(ywtLogDataSource)
+                .properties(jpaProperties.getProperties())
+                .properties(new HibernateProperties()
+                        .determineHibernateProperties(
+                                jpaProperties.getProperties(), new HibernateSettings()))
+                .packages("com.ywt.rpc.domain.entities_log") //设置实体类所在位置
+                .persistenceUnit("ywtLogPersistenceUnit")
+                .build();
+    }
+
+    @Bean(name = "ywtLogJpaProperties")
+    @ConfigurationProperties(prefix = "spring.jpa.ywtLog")
+    public JpaProperties jpaProperties() {
+        return new JpaProperties();
+    }
+
+    @Bean(name = "transactionManagerLog")
+    public PlatformTransactionManager transactionManager(EntityManagerFactoryBuilder builder, @Qualifier("ywtLogJpaProperties") JpaProperties jpaProperties) {
+        return new JpaTransactionManager(entityManagerFactory(builder,jpaProperties).getObject());
+    }
+}

+ 71 - 0
src/main/java/com/ywt/biz/common/config/db/Ywtcenter.java

@@ -0,0 +1,71 @@
+package com.ywt.biz.common.config.db;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties;
+import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings;
+import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+import org.springframework.orm.jpa.JpaTransactionManager;
+import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+import javax.persistence.EntityManager;
+import javax.sql.DataSource;
+import java.util.Map;
+
+/**
+ * Created by huangguoping.
+ */
+@Configuration
+@EnableTransactionManagement
+@EnableJpaRepositories(
+        entityManagerFactoryRef = "entityManagerFactory",
+        transactionManagerRef = "transactionManager",
+        basePackages = {"com.ywt.rpc.domain.entities"}
+)
+public class Ywtcenter {
+    @Autowired
+    @Qualifier("ywtCenterDataSource")
+    private DataSource ywtCenterDataSource;
+
+    @Primary
+    @Bean(name = "entityManager")
+    public EntityManager entityManager(EntityManagerFactoryBuilder builder,@Qualifier("ywtLogJpaProperties") JpaProperties jpaProperties) {
+        return entityManagerFactory(builder,jpaProperties).getObject().createEntityManager();
+    }
+
+    @Primary
+    @Bean(name = "entityManagerFactory")
+    public LocalContainerEntityManagerFactoryBean entityManagerFactory (EntityManagerFactoryBuilder builder, @Qualifier("ywtLogJpaProperties") JpaProperties jpaProperties) {
+        return builder
+                .dataSource(ywtCenterDataSource)
+                .properties(jpaProperties.getProperties())
+                .properties(new HibernateProperties()
+                        .determineHibernateProperties(
+                                jpaProperties.getProperties(), new HibernateSettings()))
+                .packages("com.ywt.rpc.domain.entities") //设置实体类所在位置
+                .persistenceUnit("ywtcenterPersistenceUnit")
+                .build();
+    }
+
+    @Bean(name = "ywtCenterJpaProperties")
+    @ConfigurationProperties(prefix = "spring.jpa.ywtCenter")
+    public JpaProperties jpaProperties() {
+        return new JpaProperties();
+    }
+
+
+
+    @Primary
+    @Bean(name = "transactionManager")
+    public PlatformTransactionManager transactionManager(EntityManagerFactoryBuilder builder,@Qualifier("ywtLogJpaProperties") JpaProperties jpaProperties) {
+        return new JpaTransactionManager(entityManagerFactory(builder,jpaProperties).getObject());
+    }
+}

+ 78 - 0
src/main/java/com/ywt/biz/common/constant/AnyTxnCommonRespCode.java

@@ -0,0 +1,78 @@
+package com.ywt.biz.common.constant;
+
+/**
+ * BIZ-COMMON工程专有响应码枚举类
+ * 作为自定义异常对象的入参,为使用自定义异常必须针对异常进系枚举定义.这里的XXX/YYY均需要替换成各个真实的变量.
+ * 变量的命名规则:保证简介无歧义,不可过长(>10)也不能太短导致无法辨识含义
+ * 
+ * 具体可参考Message工程案例(目前在dev_adjust_20200203,后续会迁移至develop)
+ * @author fhp
+ *
+ */
+public enum AnyTxnCommonRespCode implements RespCodePrefix {
+	/**
+	 * 正常响应码枚举定义
+	 */
+	REQ_SUCCESS(PREFIX_BIZ_COMMON_N, "响应正常", "response success"),
+	/**
+	 * 参数类型响应码枚举定义
+	 */
+	P_ERR(PREFIX_BIZ_COMMON_P + "10000", "参数异常", "parameter exception"),
+	P_CLASS_CAST_ERR(PREFIX_BIZ_COMMON_P + "10001", "对象类型转换异常", "class cast exception"),
+
+	/**
+	 * 数据类型响应码枚举定义
+	 */
+	D_ERR(PREFIX_BIZ_COMMON_D + "20000", "数据异常", "data exception"),
+	D_DUPLICATEKEY(PREFIX_BIZ_COMMON_D + "20001", "违反唯一约束", ""),
+
+	U_TYPE_NOT_SUPPORTED(PREFIX_BIZ_COMMON_S + "30007", "不支持的枚举类型", ""),
+
+	/**
+	 * 物理资源类型响应码枚举定义
+	 */
+	R_DISK_FULL(PREFIX_BIZ_COMMON_R + "40001", "磁盘空间满", ""),
+	R_OFFLINE(PREFIX_BIZ_COMMON_R + "40002", "网络不通", ""),
+	R_PORT_IN_USER(PREFIX_BIZ_COMMON_R + "40003", "端口被占用", ""),
+
+	/**
+	 * 未知异常枚举定义
+	 */
+	UNKONWN_ERR(MAX_RESPONSE_CODE+RESPONSE_UNKNOWN, "其他错误", "");
+
+	/**
+	 * 响应码编码,格式为 3位业务编码+2位响应码类型编码+5位具体响应码
+	 */
+	private String code;
+	/**
+	 * 中文通用描述
+	 */
+	private String msg;
+	/**
+	 * 需要提供具体数据时使用.
+	 * 方便后续分析查看.
+	 * 可以在抛出异常处通过对此属性进行赋值记录现场
+	 */
+	private String detail;
+	AnyTxnCommonRespCode(String code, String msg, String detail ) {
+		this.code = code;
+		this.msg = msg;
+		this.detail = detail;
+	}
+
+	@Override
+	public String getCode() {
+		return code;
+	}
+
+	@Override
+	public String getMsg() {
+		return msg;
+	}
+
+	@Override
+	public String getDetail() {
+		return detail;
+	}
+
+}

+ 31 - 0
src/main/java/com/ywt/biz/common/constant/GlobalConstants.java

@@ -0,0 +1,31 @@
+package com.ywt.biz.common.constant;
+
+import java.time.LocalDate;
+
+/**
+ * 全局常量
+ */
+public class GlobalConstants {
+
+    private GlobalConstants() {
+
+    }
+
+    /**
+     * 默认系统编号
+     */
+    public static final String DEFAULT_SYSTEM_ID = "0000";
+
+    /**
+     * 默认机构编号
+     */
+    public static final String DEFAULT_ORG_NUMBER = "0001";
+
+    /** 禁用 */
+    public static final String DISABLED = "0";
+
+    /** 启用 */
+    public static final String ENABLED = "1";
+
+
+}

+ 16 - 0
src/main/java/com/ywt/biz/common/constant/PropsConstants.java

@@ -0,0 +1,16 @@
+package com.ywt.biz.common.constant;
+
+/**
+ *  参数配置常量
+ * @author liy
+ * @version 2.2.0
+ * @date 2020-02-18
+ */
+public class PropsConstants {
+    private PropsConstants() {
+
+    }
+
+    /** 所有的业务配置前缀 */
+    public static final String PROPS_PREFIX="ywt";
+}

+ 135 - 0
src/main/java/com/ywt/biz/common/constant/RespCodePrefix.java

@@ -0,0 +1,135 @@
+package com.ywt.biz.common.constant;
+/**
+ * 响应码常量定义,所有工程均再次定义各自的前缀
+ * @author fhp
+ *
+ */
+public interface RespCodePrefix {
+
+	//////////////////////////////////////////////////////////////////////////////////////////////////////
+	// 所有业务响应码前缀定义
+	//////////////////////////////////////////////////////////////////////////////////////////////////////
+	/**
+	 * 全局统一正常响应码前缀
+	 */
+	String PREFIX_COMMON = "100";
+	/**
+	 * BIZ-COMMON响应码前缀
+	 */
+	String PREFIX_BIZ_COMMON = "101";
+	/**
+	 * GATEWAY响应码前缀
+	 */
+	String PREFIX_GATEWAY = "107";
+	/**
+	 * 处方响应码前缀
+	 */
+	String PREFIX_PRESCRIPTION = "108";
+	/**
+	 * PAYMENT响应码前缀
+	 */
+	String PREFIX_PAYMENT = "109";
+	/**
+	 * ORDER响应码前缀
+	 */
+	String PREFIX_ORDER = "110";
+
+
+	//////////////////////////////////////////////////////////////////////////////////////////////////////
+	// 所有响应码类型定义
+	//////////////////////////////////////////////////////////////////////////////////////////////////////
+	/**
+	 * 正常类型响应码前缀
+	 */
+	String PREFIX_N = "00";
+	/**
+	 * 参数类型响应码前缀
+	 */
+	String PREFIX_P = "10";
+	/**
+	 * 数据类型响应码前缀
+	 */
+	String PREFIX_D = "20";
+	/**
+	 * 服务类型响应码前缀
+	 */
+	String PREFIX_S = "30";
+	/**
+	 * 资源类型响应码前缀
+	 */
+	String PREFIX_R = "40";
+
+	//////////////////////////////////////////////////////////////////////////////////////////////////////
+	// 特定响应码定义
+	//////////////////////////////////////////////////////////////////////////////////////////////////////
+
+	/**
+	 * 最大响应码,所有响应码不能超过此值(保证不超过Integer.MAX_VALUE=2147483647)
+	 */
+	String MAX_RESPONSE_CODE = "2109999999";
+	/**
+	 * 请求应答未知异常-后5位
+	 */
+	String RESPONSE_UNKNOWN = "99999";
+	/**
+	 * 请求应答正常-后5位
+	 */
+	String RESPONSE_SUCESS = "00000";
+
+	/**
+	 * 全局统一正常类型响应码为1000000000
+	 */
+	String NORMAL_RESP = PREFIX_COMMON+PREFIX_N+RESPONSE_SUCESS;
+
+	//////////////////////////////////////////////////////////////////////////////////////////////////////
+	// BIZ-COMMON响应码前两段,正常响应码为全部
+	//////////////////////////////////////////////////////////////////////////////////////////////////////
+	/**
+	 * BIZ-COMMON正常类型响应码为全部
+	 */
+	String PREFIX_BIZ_COMMON_N = PREFIX_COMMON+PREFIX_N+RESPONSE_SUCESS;
+	/**
+	 * BIZ-COMMON参数类型响应码前两段
+	 */
+	String PREFIX_BIZ_COMMON_P = PREFIX_BIZ_COMMON+PREFIX_P;
+	/**
+	 * BIZ-COMMON数据类型响应码前两段
+	 */
+	String PREFIX_BIZ_COMMON_D = PREFIX_BIZ_COMMON+PREFIX_D;
+	/**
+	 * BIZ-COMMON服务类型响应码前两段
+	 */
+	String PREFIX_BIZ_COMMON_S = PREFIX_BIZ_COMMON+PREFIX_S;
+	/**
+	 * BIZ-COMMON资源类型响应码前两段
+	 */
+	String PREFIX_BIZ_COMMON_R = PREFIX_BIZ_COMMON+PREFIX_R;
+
+
+	//////////////////////////////////////////////////////////////////////////////////////////////////////
+	// ORDER响应码前两段,正常响应码为全部
+	//////////////////////////////////////////////////////////////////////////////////////////////////////
+	String PREFIX_NUMBER_N = PREFIX_COMMON+PREFIX_N+RESPONSE_SUCESS;
+	String PREFIX_NUMBER_P = PREFIX_ORDER+PREFIX_P;
+	String PREFIX_NUMBER_D = PREFIX_ORDER+PREFIX_D;
+	String PREFIX_NUMBER_S = PREFIX_ORDER+PREFIX_S;
+	String PREFIX_NUMBER_R = PREFIX_ORDER+PREFIX_R;
+
+	/**
+	 * 返回状态码
+	 * @return
+	 */
+	String getCode();
+
+	/**
+	 * 返回消息
+	 * @return
+	 */
+	String getMsg();
+
+	/**
+	 * 返回明细描述
+	 * @return
+	 */
+	String getDetail();
+}

+ 96 - 0
src/main/java/com/ywt/biz/common/dto/PageResultDTO.java

@@ -0,0 +1,96 @@
+package com.ywt.biz.common.dto;
+
+import java.util.List;
+
+/**
+ * 使用spring mvc中的page翻页
+ * @author  Aning
+ * @date 2018-11-09
+ */
+public class PageResultDTO<T> {
+
+
+    /**
+     * 页码
+     */
+    private Integer page;
+    /**
+     * 页容量
+     */
+    private Integer rows;
+
+    /**
+     * 总数量
+     */
+    private Long total;
+    /**
+     * 总页数
+     */
+    private Long totalPage;
+    /**
+     * 总数据
+     */
+    private List<T> data;
+
+    public PageResultDTO() {
+    }
+
+    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 long getTotal() {
+        return total;
+    }
+
+    public void setTotal(long total) {
+        this.total = total;
+    }
+
+    public long getTotalPage() {
+        return totalPage;
+    }
+
+    public void setTotalPage(long totalPage) {
+        this.totalPage = totalPage;
+    }
+
+    public List<T> getData() {
+        return data;
+    }
+
+    public void setData(List<T> data) {
+        this.data = data;
+    }
+
+    public PageResultDTO(int page, int rows, long total, long totalPage, List<T> data) {
+        this.page = page;
+        this.rows = rows;
+        this.total = total;
+        this.totalPage = totalPage;
+        this.data = data;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder("PageResultDTO{");
+        sb.append("page=").append(page);
+        sb.append(", rows=").append(rows);
+        sb.append(", total=").append(total);
+        sb.append(", totalPage=").append(totalPage);
+        sb.append('}');
+        return sb.toString();
+    }
+}

+ 12 - 0
src/main/java/com/ywt/biz/common/exception/AppMessageException.java

@@ -0,0 +1,12 @@
+package com.ywt.biz.common.exception;
+
+/**
+ * Created by huangguoping.
+ */
+@Deprecated
+public class AppMessageException extends Exception {
+    public AppMessageException(){}
+    public AppMessageException(String msg){
+        super(msg);
+    }
+}

+ 18 - 0
src/main/java/com/ywt/biz/common/exception/NullOrEmptyException.java

@@ -0,0 +1,18 @@
+package com.ywt.biz.common.exception;
+
+/**
+ * Created by huangguoping.
+ */
+@Deprecated
+public class NullOrEmptyException extends Exception {
+    private String message = "";
+    public NullOrEmptyException(){}
+    public NullOrEmptyException(String msg){
+        this.message = msg;
+    }
+
+    @Override
+    public String getMessage() {
+        return this.message;
+    }
+}

+ 63 - 0
src/main/java/com/ywt/biz/common/exception/YwtCommonException.java

@@ -0,0 +1,63 @@
+package com.ywt.biz.common.exception;
+
+import com.ywt.biz.common.constant.AnyTxnCommonRespCode;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+/**
+ * <p>自定义异常类,如果使用此类,请注意不同构造函数适用的场景
+ * 场景一:由于业务逻辑,需要主动生成一个异常对象
+ * 场景二:catch住程序运行过程中抛出的异常,转换为自定义异常
+ * 
+ * 各个工程中均需要定义自己工程内的异常,并继承AnyTxnException
+ *
+ * @author zcli
+ */
+public class YwtCommonException extends YwtException {
+
+	private static final long serialVersionUID = -8243161236301013355L;
+
+    /**
+     * <p>此方法适用于场景一:由于业务逻辑,需要主动生成一个异常对象,
+     * 不适用于将原始异常转为自己封装异常场景
+     * @param e	自定义枚举对象
+     */
+	public YwtCommonException(AnyTxnCommonRespCode e) {
+		this(e, "");
+	}
+    /**
+     * <p>此方法适用于场景一:由于业务逻辑,需要主动生成一个异常对象,
+     * 不适用于将原始异常转为自己封装异常场景
+     * @param e	自定义枚举对象
+     * @param detail 手动设置的具体信息,比如参数/上下文环境,方便排查问题
+     */
+	public YwtCommonException(AnyTxnCommonRespCode e, String detail) {
+		this(e, detail, null);
+	}
+
+    /**
+     * <p>此方法适用于场景二:catch住程序运行过程中抛出的异常,转换为自定义异常。
+     * 代码中捕获了异常后转换为自己异常的处理均须调用此方法,必须保证原始异常的堆栈信息不丢失(将原始异常作为参数传入)
+     * @param e	自定义枚举对象
+     * @param cause	原始异常
+     */
+	public YwtCommonException(AnyTxnCommonRespCode e, Throwable cause) {
+		this(e, "", cause);
+	}
+    /**
+     * <p>此方法适用于场景二:catch住程序运行过程中抛出的异常,转换为自定义异常。
+     * 代码中捕获了异常后转换为自己异常的处理均须调用此方法,必须保证原始异常的堆栈信息不丢失(将原始异常作为参数传入)
+     * @param e	自定义枚举对象
+     * @param detail 手动设置的具体信息,比如参数/上下文环境,方便排查问题
+     * @param cause	原始异常
+     */
+	public YwtCommonException(AnyTxnCommonRespCode e, String detail, Throwable cause) {
+        super(e.getCode(),e.getMsg(),detail,cause);
+	}
+	
+	@Override
+	public String toString() {
+		return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
+	}
+	
+}

+ 117 - 0
src/main/java/com/ywt/biz/common/exception/YwtException.java

@@ -0,0 +1,117 @@
+/**
+ * 
+ */
+package com.ywt.biz.common.exception;
+
+import com.ywt.biz.common.constant.RespCodePrefix;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+/**
+ * <p>自定义异常类,如果使用此类,请注意不同构造函数适用的场景
+ * 场景一:由于业务逻辑,需要主动生成一个异常对象
+ * 场景二:catch住程序运行过程中抛出的异常,转换为自定义异常
+ * 
+ * 此异常仅被各个工程自定义异常时继承,各个工程中不能直接使用
+ * 各个工程中均需要定义自己工程内的异常,并继承AnyTxnException
+ * 
+ * @author fhp
+ */
+public class YwtException extends RuntimeException {
+
+	private static final long serialVersionUID = -8243161197901013355L;
+	/**
+	 * 自定义异常码
+	 */
+	protected String errCode;
+	/**
+	 * 自定义异常描述
+	 */
+	protected String errMsg;
+	/**
+	 * 自定义异常明细
+	 * 提供具体数据时使用,便于后续分析查看问题
+	 * 需要在抛出异常处通过对此属性进行赋值记录现场
+	 */
+	protected String errDetail;
+
+    /**
+     * 
+     * <p>此方法适用于场景一:由于业务逻辑,需要主动生成一个异常对象,
+     * 不适用于将原始异常转为自己封装异常场景
+     * @param errCode 自定义枚举对象的响应码
+     * @param errMsg 自定义枚举对象的响应信息
+     * @param errDetail 自定义枚举对象的具体描述(比如上下文信息等,需要在生成异常时手动设置)
+     */
+	protected YwtException(String errCode, String errMsg, String errDetail) {
+		this(errCode, errMsg, errDetail, null);
+	}
+
+    /**
+     * <p>此方法适用于场景二:catch住程序运行过程中抛出的异常,转换为自定义异常。
+     * 代码中捕获了异常后转换为自己异常的处理均须调用此方法,必须保证原始异常的堆栈信息不丢失(将原始异常作为参数传入)
+     * @param errCode 自定义枚举对象的响应码
+     * @param errMsg 自定义枚举对象的响应信息
+     * @param errDetail 自定义枚举对象的具体描述(比如上下文信息等,需要在生成异常时手动设置)
+     * @param cause 原始异常
+     */
+	protected YwtException(String errCode, String errMsg, String errDetail, Throwable cause) {
+        super(cause);
+		this.errCode = errCode;
+		if (null != errDetail && !"".contentEquals(errDetail)) {
+			this.errMsg = errMsg;
+			if(null != errMsg){
+                this.errDetail = errMsg + ":" + errDetail;
+			}else{
+				this.errDetail = errDetail;
+			}
+		} else {
+			this.errMsg = errMsg;
+			this.errDetail = errMsg;
+		}
+	}
+
+	/**
+	 * 按异常类型
+	 * @param respCodePrefix
+	 */
+	public YwtException(RespCodePrefix respCodePrefix){
+		this(respCodePrefix.getCode(),respCodePrefix.getMsg(),respCodePrefix.getDetail());
+	}
+
+	public YwtException(RespCodePrefix respCodePrefix, String detail){
+		this(respCodePrefix.getCode(),respCodePrefix.getMsg(),detail);
+	}
+	
+	public  String getErrCode() {
+		return errCode;
+	}
+	public String getErrMsg() {
+		return errMsg;
+	}
+	public String getErrDetail() {
+		return errDetail;
+	}
+
+	@Override
+	public String toString() {
+		return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
+	}
+
+	/**
+	 * 输出堆栈信息到log err
+	 *
+	 * @param t
+	 */
+	public static String getTrace(Throwable t) {
+		StringWriter stringWriter = new StringWriter();
+		PrintWriter writer = new PrintWriter(stringWriter);
+		t.printStackTrace(writer);
+		StringBuffer buffer = stringWriter.getBuffer();
+		return buffer.toString();
+	}
+	
+}

+ 75 - 0
src/main/java/com/ywt/biz/common/handler/GlobalExceptionHandler.java

@@ -0,0 +1,75 @@
+package com.ywt.biz.common.handler;
+
+import com.ywt.biz.common.constant.AnyTxnCommonRespCode;
+import com.ywt.biz.common.exception.YwtException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+
+import com.ywt.biz.common.web.YwtHttpResponse;
+
+
+/**
+ * 全局异常处理器, 应用端在configuration的自定类中 集成基础类,扩展注解方法
+ * @author
+ */
+@RestControllerAdvice
+public class GlobalExceptionHandler {
+
+	private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
+
+	/**
+	 * error级别异常拦截
+	 * @param e
+	 * @throws
+	 * @return
+	 */
+	@ResponseBody
+	@ExceptionHandler(value = Throwable.class)
+	public YwtHttpResponse<?> txnExceptionHandler(Throwable e) {
+		logger.error("服务异常,throwable:{}",e.getMessage(),e);
+		return YwtHttpResponse.fail(AnyTxnCommonRespCode.UNKONWN_ERR.getCode(),AnyTxnCommonRespCode.UNKONWN_ERR.getMsg(),e.toString());
+	}
+
+	/**
+	 * 对不能单独处理的异常进行统一处理
+	 * @param e
+	 * @return
+	 */
+	@ResponseBody
+	@ExceptionHandler(value = Exception.class)
+	public YwtHttpResponse<?> txnExceptionHandler(Exception e) {
+		logger.error("服务异常,Exception:{},堆栈信息:{}",e.getMessage(),e);
+		return YwtHttpResponse.fail(AnyTxnCommonRespCode.UNKONWN_ERR.getCode(),AnyTxnCommonRespCode.UNKONWN_ERR.getMsg(),e.toString());
+	}
+	/**
+	 * 对不能单独处理的异常进行统一处理
+	 * @param e
+	 * @return
+	 */
+	@ResponseBody
+	@ExceptionHandler(value = RuntimeException.class)
+	public YwtHttpResponse<?> runTimeExceptionHandler(RuntimeException e) {
+		logger.error("服务异常,Exception:{}",e.getMessage(),e);
+		if (e instanceof YwtException) {
+			YwtException ae = (YwtException)e;
+			return YwtHttpResponse.fail(ae.getErrCode(), ae.getErrMsg(), ae.getErrDetail());
+		}
+		return YwtHttpResponse.fail(AnyTxnCommonRespCode.UNKONWN_ERR.getCode(),AnyTxnCommonRespCode.UNKONWN_ERR.getMsg(),e.toString());
+	}
+
+	/**
+	 * 对业务异常进行处理
+	 * @param e
+	 * @return
+	 */
+	@ResponseBody
+	@ExceptionHandler(value = YwtException.class)
+	public YwtHttpResponse<?> txnExceptionHandler(YwtException e){
+
+		return YwtHttpResponse.fail(e.getErrCode(),e.getErrMsg(),e.getErrDetail());
+	}
+
+}

+ 68 - 0
src/main/java/com/ywt/biz/common/structs/MultipleTree.java

@@ -0,0 +1,68 @@
+package com.ywt.biz.common.structs;
+
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * 多叉树类
+ */
+public class MultipleTree {
+
+    /**
+     * 多叉树根节点
+     */
+    private TreeNode root;
+
+    private List<TreeNode> tempNodeList;
+
+
+    public MultipleTree() {
+    }
+
+    public MultipleTree(List<TreeNode> treeNodeList) {
+        tempNodeList = treeNodeList;
+        generateTree();
+    }
+
+    public TreeNode getRoot() {
+        return root;
+    }
+
+    public void setRoot(TreeNode root) {
+        this.root = root;
+    }
+
+    /**
+     * 生成多叉树
+     */
+    public void generateTree() {
+        int maxId = Integer.MAX_VALUE;
+        HashMap<String, TreeNode> map = new HashMap<>();
+
+        for(TreeNode treeNode : tempNodeList){
+            if(treeNode.getId() < maxId){
+                maxId = treeNode.getId();
+                this.root = treeNode;
+            }
+
+            map.put(String.valueOf(treeNode.getId()), treeNode);
+        }
+
+        for (String key : map.keySet()) {
+            TreeNode treeNode = map.get(key);
+            int parentId = treeNode.getParentId();
+            String parentKeyId = String.valueOf(parentId);
+
+            if (map.containsKey(parentKeyId)) {
+                TreeNode parentNode = map.get(parentKeyId);
+
+                if (parentNode == null) {
+                    //节点不能构成一棵多叉树
+                    return;
+                } else {
+                    parentNode.addChildNode(treeNode);
+                }
+            }
+        }
+    }
+}

+ 92 - 0
src/main/java/com/ywt/biz/common/structs/TreeNode.java

@@ -0,0 +1,92 @@
+package com.ywt.biz.common.structs;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+/**
+ * 树节点类
+ */
+public class TreeNode implements Serializable {
+    private int parentId;
+    private int id;
+    private String label;
+    private List<TreeNode> children;
+
+    public TreeNode() {
+        initChildren();
+    }
+
+
+    public void addChildNode(TreeNode treeNode) {
+        initChildren();
+        children.add(treeNode);
+    }
+
+    private void initChildren() {
+        if (children == null) {
+            children = new ArrayList<>();
+        }
+    }
+
+    public List<TreeNode> getChildren() {
+        return children;
+    }
+
+    public void setChildren(List<TreeNode> children) {
+        this.children = children;
+    }
+
+    public int getParentId() {
+        return parentId;
+    }
+
+    public void setParentId(int parentId) {
+        this.parentId = parentId;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public String getLabel() {
+        return label;
+    }
+
+    public void setLabel(String label) {
+        this.label = label;
+    }
+
+    // 孩子节点排序
+    public void sortChildren() {
+        Collections.sort(children, new IdComparator());
+
+        // 对节点的子节点进行排序
+        for(TreeNode node : children){
+            node.sortChildren();
+        }
+//        for (Iterator it = children.iterator(); it.hasNext(); ) {
+//            ((TreeNode) it.next()).sortChildren();
+//        }
+    }
+
+    /**
+     * 节点比较器
+     */
+    class IdComparator implements Comparator {
+        // 按照节点编号比较
+        public int compare(Object o1, Object o2) {
+            int j1 = (((TreeNode) o1).getId());
+            int j2 = (((TreeNode) o2).getId());
+            return (j1 < j2 ? -1 : (j1 == j2 ? 0 : 1));
+        }
+    }
+
+}
+

+ 203 - 0
src/main/java/com/ywt/biz/common/structs/TrieTree.java

@@ -0,0 +1,203 @@
+package com.ywt.biz.common.structs;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Trie 树
+ * Created by huangguoping on 16/9/13.
+ */
+public class TrieTree<T extends Serializable> implements Serializable {
+
+    private Node<T> root;
+    public TrieTree(){
+        root = new Node<>();
+    }
+
+    public void insert(String key, T data){
+        if (key == null || key.equals("")) return;
+        Node<T> tempNode = root;
+        for (int i = 0; i < key.length(); i++){
+            if (tempNode.getChildren() == null) tempNode.setChildren(new HashMap<Character, Node<T>>());
+            Character c = key.charAt(i);
+            //System.out.println(c);
+            if (tempNode.getChildren().containsKey(c)){
+                //System.out.println(c);
+                tempNode = tempNode.getChildren().get(c);
+            }else{
+                Node<T> node_t = new Node<>();
+                tempNode.getChildren().put(c, node_t);
+                tempNode = node_t;
+            }
+        }
+        tempNode.setHitNum(tempNode.getHitNum() + 1);
+        tempNode.setData(data);
+        tempNode.setIshit(true);
+    }
+
+    private int _search(Node<T> node, String content, int next_i, int len, List<T> hitNodeDatas, List<String> hitKeys, StringBuffer stringBuffer){
+        if (next_i >= len) return next_i;
+        Character c = content.charAt(next_i);
+        stringBuffer.append(c);
+        if (node.getChildren().containsKey(c)){
+            Node<T> nextNode = node.children.get(c);
+            if (nextNode.ishit){
+                hitKeys.add(stringBuffer.toString());
+                hitNodeDatas.add(nextNode.data);
+            }
+            if (nextNode.children == null || nextNode.children.size() == 0){
+                return next_i + 1;
+            }
+            return _search(nextNode, content, next_i + 1, len, hitNodeDatas, hitKeys, stringBuffer);
+        }else {
+            return next_i;
+        }
+    }
+
+    public SearchResult<T> search(String content){
+        SearchResult<T> searchResult = new SearchResult<>();
+
+        if (content == null) return searchResult;
+        int len = content.length();
+        if (len == 0) return searchResult;
+
+        StringBuffer stringBuffer = null;
+
+        if(root.getChildren() == null || root.getChildren().size() == 0) return searchResult;
+        List<T> hitNodeDataLstAll = new LinkedList<>();
+        List<T> hitNodeDatasTemp = new LinkedList<>();
+        List<String> hitKeysTemp = new LinkedList<>();
+        Map<String, Integer> hitsCount = new HashMap<>();
+        int curr_i = 0;
+        while (curr_i < len){
+            hitNodeDatasTemp.clear();
+            hitKeysTemp.clear();
+            stringBuffer = new StringBuffer();
+            int next_i = this._search(root, content, curr_i, len, hitNodeDatasTemp, hitKeysTemp, stringBuffer);
+            if (next_i > curr_i) {
+                if (hitNodeDatasTemp.size() > 0) {
+                    String key_t = hitKeysTemp.get(hitKeysTemp.size() - 1);
+                    curr_i += key_t.length();
+                    if (hitsCount.containsKey(key_t)){
+                        hitsCount.replace(key_t, hitsCount.get(key_t) + 1);
+                    }else {
+                        hitNodeDataLstAll.add(hitNodeDatasTemp.get(hitNodeDatasTemp.size() - 1));
+                        hitsCount.put(key_t, 1);
+                    }
+                } else {
+                    curr_i++;
+                }
+            }
+            else
+                curr_i++;
+        }
+
+        searchResult.setHitsCount(hitsCount);
+        searchResult.setHitNodeDatas(hitNodeDataLstAll);
+        return searchResult;
+    }
+
+    public List<T> searchByPrefix(String prefix){
+        if(prefix == null || prefix.length() == 0) return null;
+        int len = prefix.length();
+        int curr_i = 0;
+
+        if (root.children == null || root.children.size() == 0) return null;
+        Node<T> tempNode = root;
+        while (curr_i < len) {
+            Character c = prefix.charAt(curr_i);
+            if (tempNode.children.containsKey(c)) {
+                curr_i++;
+                tempNode = tempNode.children.get(c);
+                if (tempNode.children == null || tempNode.children.size() == 0) break;
+            } else {
+                break;
+            }
+        }
+
+        List<T> hitNodeDataLstAll = new LinkedList<>();
+        if (curr_i > 0 && curr_i == len){
+            traversal(tempNode, hitNodeDataLstAll);
+        }
+        return hitNodeDataLstAll;
+    }
+
+    private void traversal(Node<T> node, List<T> hitNodeDatas){
+        if (node.ishit){
+            hitNodeDatas.add(node.data);
+        }
+        if (node.children == null || node.children.size() == 0) return;
+        for (Map.Entry<Character, Node<T>> entry : node.children.entrySet()){
+            traversal(entry.getValue(), hitNodeDatas);
+        }
+    }
+
+    public class Node<T extends Serializable> implements Serializable {
+        private T data;
+        private int hitNum;
+        private boolean ishit = false;
+
+        private Map<Character, Node<T>> children = null;
+
+        public T getData() {
+            return data;
+        }
+
+        public void setData(T data) {
+            this.data = data;
+        }
+
+        public int getHitNum() {
+            return hitNum;
+        }
+
+        public void setHitNum(int hitNum) {
+            this.hitNum = hitNum;
+        }
+
+        public Map<Character, Node<T>> getChildren() {
+            return children;
+        }
+
+        public void setChildren(Map<Character, Node<T>> children) {
+            this.children = children;
+        }
+
+        public boolean isIshit() {
+            return ishit;
+        }
+
+        public void setIshit(boolean ishit) {
+            this.ishit = ishit;
+        }
+    }
+
+    public class SearchResult<T extends Serializable> {
+        private List<T> hitNodeDatas = null;
+        private Map<String, Integer> hitsCount = null;
+
+        public SearchResult(){
+            this.hitNodeDatas = new LinkedList<>();
+            this.hitsCount = new HashMap<>();
+        }
+
+        public List<T> getHitNodeDatas() {
+            return hitNodeDatas;
+        }
+
+        public void setHitNodeDatas(List<T> hitNodeDatas) {
+            this.hitNodeDatas = hitNodeDatas;
+        }
+
+        public Map<String, Integer> getHitsCount() {
+            return hitsCount;
+        }
+
+        public void setHitsCount(Map<String, Integer> hitsCount) {
+            this.hitsCount = hitsCount;
+        }
+    }
+}

+ 79 - 0
src/main/java/com/ywt/biz/common/swagger/ApiInfoProperties.java

@@ -0,0 +1,79 @@
+package com.ywt.biz.common.swagger;
+
+
+/**
+ * swagger的apiInfo定义
+ * @author yxy
+ * @date 2018/6/4
+ */
+public class ApiInfoProperties {
+
+    private String title;
+    private String description;
+    private String termsOfServiceUrl;
+    private String license;
+    private String licenseUrl;
+    private String version;
+
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public String getTermsOfServiceUrl() {
+        return termsOfServiceUrl;
+    }
+
+    public void setTermsOfServiceUrl(String termsOfServiceUrl) {
+        this.termsOfServiceUrl = termsOfServiceUrl;
+    }
+
+    public String getLicense() {
+        return license;
+    }
+
+    public void setLicense(String license) {
+        this.license = license;
+    }
+
+    public String getLicenseUrl() {
+        return licenseUrl;
+    }
+
+    public void setLicenseUrl(String licenseUrl) {
+        this.licenseUrl = licenseUrl;
+    }
+
+    public String getVersion() {
+        return version;
+    }
+
+    public void setVersion(String version) {
+        this.version = version;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder("ApiInfoProperties{");
+        sb.append("title='").append(title).append('\'');
+        sb.append(", description='").append(description).append('\'');
+        sb.append(", termsOfServiceUrl='").append(termsOfServiceUrl).append('\'');
+        sb.append(", license='").append(license).append('\'');
+        sb.append(", licenseUrl='").append(licenseUrl).append('\'');
+        sb.append(", version='").append(version).append('\'');
+        sb.append('}');
+        return sb.toString();
+    }
+}

+ 38 - 0
src/main/java/com/ywt/biz/common/swagger/DocketProperties.java

@@ -0,0 +1,38 @@
+package com.ywt.biz.common.swagger;
+
+/**
+ * swagger的docket属性
+ * @author liy
+ * @date 2018/6/4
+ */
+public class DocketProperties {
+
+    private String groupName;
+    private String basePackage;
+
+
+    public String getGroupName() {
+        return groupName;
+    }
+
+    public void setGroupName(String groupName) {
+        this.groupName = groupName;
+    }
+
+    public String getBasePackage() {
+        return basePackage;
+    }
+
+    public void setBasePackage(String basePackage) {
+        this.basePackage = basePackage;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder("DocketProperties{");
+        sb.append("groupName='").append(groupName).append('\'');
+        sb.append(", basePackage='").append(basePackage).append('\'');
+        sb.append('}');
+        return sb.toString();
+    }
+}

+ 143 - 0
src/main/java/com/ywt/biz/common/swagger/SwaggerConfiguration.java

@@ -0,0 +1,143 @@
+package com.ywt.biz.common.swagger;
+
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.ywt.biz.common.constant.PropsConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.bind.annotation.RequestMethod;
+import springfox.documentation.RequestHandler;
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.ResponseMessageBuilder;
+import springfox.documentation.schema.ModelRef;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.service.ResponseMessage;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+
+/**
+ * @author liy
+ * @version 2.0
+ * @date 2020/3/12
+ */
+@Configuration
+@ConditionalOnProperty(name = PropsConstants.PROPS_PREFIX +".swagger.enable")
+@EnableSwagger2
+@EnableConfigurationProperties(SwaggerProperties.class)
+public class SwaggerConfiguration {
+
+
+    private static final Logger logger = LoggerFactory.getLogger(SwaggerConfiguration.class);
+
+    private SwaggerProperties swaggerProperties;
+
+    public SwaggerConfiguration(SwaggerProperties swaggerProperties){
+        this.swaggerProperties = swaggerProperties;
+    }
+
+    /**
+     * 通过 createRestApi函数来构建一个DocketBean
+     * 函数名,可以随意命名,喜欢什么命名就什么命名
+     */
+    @Bean
+    public Docket createReportApi() {
+        logger.info("build swagger docket,{}",swaggerProperties);
+        Set<String> contentTypes = new HashSet<>();
+        contentTypes.add("application/json");
+
+        List<ResponseMessage> messages = new ArrayList<>();
+        ResponseMessage message1 = new ResponseMessageBuilder().code(200).message("操作成功")
+                .responseModel(new ModelRef("操作成功")).build();
+        ResponseMessage message2 = new ResponseMessageBuilder().code(400).message("非法请求")
+                .responseModel(new ModelRef("非法请求")).build();
+        ResponseMessage message3 = new ResponseMessageBuilder().code(501).message("如请求路径拼写不正确")
+                .responseModel(new ModelRef("如请求路径拼写不正确")).build();
+        ResponseMessage message4 = new ResponseMessageBuilder().code(502).message("服务器过载引起的错误")
+                .responseModel(new ModelRef("服务器过载引起的错误")).build();
+        messages.add(message1);
+        messages.add(message2);
+        messages.add(message3);
+        messages.add(message4);
+
+        return new Docket(DocumentationType.SWAGGER_2).groupName(swaggerProperties.getDocket().getGroupName())
+                .useDefaultResponseMessages(true)
+                .consumes(contentTypes)
+                .produces(contentTypes)
+                .globalResponseMessage(RequestMethod.POST,messages)
+                //调用apiInfo方法,创建一个ApiInfo实例,里面是展示在文档页面信息内容
+                .apiInfo(apiInfo())
+                .select()
+                //控制暴露出去的路径下的实例
+                //如果某个接口不想暴露,可以使用以下注解
+                //@ApiIgnore 这样,该接口就不会暴露在 swagger2 的页面下
+                .apis(basePackage(swaggerProperties.getDocket().getBasePackage()))
+//                .apis(RequestHandlerSelectors.basePackage(swaggerProperties.getDocket().getBasePackage()))
+                .paths(PathSelectors.any())
+                .build();
+    }
+
+    /**
+     * 构建 api文档的详细信息函数
+     */
+    private ApiInfo apiInfo() {
+        ApiInfoProperties apiInfoProperties = swaggerProperties.getApiInfo();
+
+        return new ApiInfoBuilder()
+                //页面标题
+                .title(apiInfoProperties.getTitle())
+                //创建人
+                //版本号
+                .version(apiInfoProperties.getVersion())
+                //描述
+                .description(apiInfoProperties.getDescription())
+                .license(apiInfoProperties.getLicense())
+                .licenseUrl(apiInfoProperties.getLicenseUrl())
+                .termsOfServiceUrl(apiInfoProperties.getTermsOfServiceUrl())
+                .build();
+    }
+
+    private static Predicate<RequestHandler> basePackage(final String basePackage) {
+        return input -> declaringClass(input).transform(handlerPackage(basePackage)).or(true);
+    }
+
+
+    /**
+     * 处理包路径配置规则,支持多路径扫描匹配以逗号隔开
+     *
+     * @param basePackage 扫描包路径
+     * @return Function
+     */
+    private static Function<Class<?>, Boolean> handlerPackage(final String basePackage) {
+        return input -> {
+            for (String strPackage : basePackage.split(",")) {
+                boolean isMatch = input.getPackage().getName().startsWith(strPackage);
+                if (isMatch) {
+                    return true;
+                }
+            }
+            return false;
+        };
+    }
+
+    /**
+     * @param input RequestHandler
+     * @return Optional
+     */
+    private static Optional<? extends Class<?>> declaringClass(RequestHandler input) {
+        return Optional.fromNullable(input.declaringClass());
+    }
+
+}

+ 55 - 0
src/main/java/com/ywt/biz/common/swagger/SwaggerProperties.java

@@ -0,0 +1,55 @@
+package com.ywt.biz.common.swagger;
+
+import com.ywt.biz.common.constant.PropsConstants;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.context.properties.NestedConfigurationProperty;
+
+/**
+ * swagger属性配置
+ * @author liy
+ * @date 2018/6/4
+ */
+@ConfigurationProperties(prefix = PropsConstants.PROPS_PREFIX+".swagger")
+public class SwaggerProperties {
+
+    private Boolean enable;
+    @NestedConfigurationProperty
+    private ApiInfoProperties apiInfo;
+
+    @NestedConfigurationProperty
+    private DocketProperties docket;
+
+    public Boolean getEnable() {
+        return enable;
+    }
+
+    public void setEnable(Boolean enable) {
+        this.enable = enable;
+    }
+
+    public ApiInfoProperties getApiInfo() {
+        return apiInfo;
+    }
+
+    public void setApiInfo(ApiInfoProperties apiInfo) {
+        this.apiInfo = apiInfo;
+    }
+
+    public DocketProperties getDocket() {
+        return docket;
+    }
+
+    public void setDocket(DocketProperties docket) {
+        this.docket = docket;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder("SwaggerProperties{");
+        sb.append("enable=").append(enable);
+        sb.append(", apiInfo=").append(apiInfo);
+        sb.append(", docket=").append(docket);
+        sb.append('}');
+        return sb.toString();
+    }
+}

+ 15 - 0
src/main/java/com/ywt/biz/common/util/Checksum.java

@@ -0,0 +1,15 @@
+package com.ywt.biz.common.util;
+
+import java.util.zip.CRC32;
+
+/**
+ * Created by huangguoping.
+ */
+public class Checksum {
+    public static long crc32(byte[] bytes){
+        CRC32 crc32 = new CRC32();
+        crc32.update(bytes);
+        long hash_num = crc32.getValue() & 0xffffffffL;
+        return hash_num;
+    }
+}

+ 68 - 0
src/main/java/com/ywt/biz/common/util/CollectionUtil.java

@@ -0,0 +1,68 @@
+package com.ywt.biz.common.util;
+
+import java.util.*;
+import java.util.function.Function;
+
+/**
+ * Created by huangguoping.
+ */
+public class CollectionUtil {
+
+    public static <T> List<T> toList(Iterable<T> iterable) {
+        if (iterable == null) return null;
+        List<T> ts = new LinkedList<>();
+        iterable.forEach(t1 -> ts.add(t1));
+        return ts;
+    }
+
+    public static <K, V> Map<K, V> toMap(List<V> list, Function<V, K> keyFunc) {
+        if (list == null) return null;
+        Map<K, V> map = new HashMap<K, V>();
+        list.stream().forEach(v -> map.put(keyFunc.apply(v), v));
+        return map;
+    }
+
+    public static <K, V> Map<K, V> toMap(V[] arr, Function<V, K> keyFunc) {
+        if (arr == null) return null;
+        Map<K, V> map = new HashMap<K, V>();
+        for (V v : arr){
+            map.put(keyFunc.apply(v), v);
+        }
+        return map;
+    }
+
+    public static <K, V> Map<K, V> toMap(Iterable<V> iterable, Function<V, K> keyFunc) {
+        if (iterable == null) return null;
+        Map<K, V> map = new HashMap<K, V>();
+        iterable.forEach(v -> map.put(keyFunc.apply(v), v));
+        return map;
+    }
+
+    public static <K, V> Map<K, V> toMap(Iterator<V> iterator, Function<V, K> keyFunc) {
+        if (iterator == null) return null;
+        Map<K, V> map = new HashMap<K, V>();
+        while (iterator.hasNext()){
+            V v = iterator.next();
+            map.put(keyFunc.apply(v), v);
+        }
+        return map;
+    }
+
+    public static <T, V> Set<V> toSet(List<T> list, Function<T, V> vFun){
+        if (list == null) return null;
+        Set<V> set = new HashSet<V>();
+        for (T t : list){
+            set.add(vFun.apply(t));
+        }
+        return set;
+    }
+
+    public static <T, V> Set<V> toSet(Set<T> s, Function<T, V> vFun){
+        if (s == null) return null;
+        Set<V> set = new HashSet<V>();
+        for (T t : s){
+            set.add(vFun.apply(t));
+        }
+        return set;
+    }
+}

+ 74 - 0
src/main/java/com/ywt/biz/common/util/DateUtil.java

@@ -0,0 +1,74 @@
+package com.ywt.biz.common.util;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+
+public class DateUtil {
+    public static final String DATE_FORMAT_YMD = "yyyy-MM-dd";
+    /**
+     * 将时间戳转换成日期字符串格式
+     * @param timestamp 时间戳
+     * @param pattern 日期格式
+     * @return
+     */
+    public static String convertTimestampToDateString(long timestamp, String pattern) {
+        Date date = new Date(timestamp);
+        return convertToString(date, pattern);
+    }
+
+
+    public static String convertToString(Date date, String pattern){
+        if(StringHelper.isNullOrEmpty(pattern)){
+            pattern = "yyyy-MM-dd HH:mm:ss";
+        }
+
+        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
+        return sdf.format(date);
+    }
+
+    /**
+     * 计算当前时间和指定时间之间相差的小时
+     *
+     * @param smdate
+     *            指定的时间
+     * @throws ParseException
+     */
+    public static int hourBetween(String smdate) {
+        Date start = new Date();
+        Date end = stringToDate(smdate);
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(start);
+        long time1 = cal.getTimeInMillis();
+        cal.setTime(end);
+        long time2 = cal.getTimeInMillis();
+
+        long between_days = (time2 - time1) / (1000 * 3600);
+
+        return Integer.parseInt(String.valueOf(between_days));
+    }
+
+    /**
+     * String转Date
+     *
+     * @param strDate
+     * @return
+     */
+    public static Date stringToDate(String strDate, String pattern) {
+        if (null == strDate) {
+            return null;
+        }
+        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
+        try {
+            return sdf.parse(strDate);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    public static Date stringToDate(String strDate) {
+        return stringToDate(strDate, "yyyy-MM-dd HH:mm:ss");
+    }
+}

+ 232 - 0
src/main/java/com/ywt/biz/common/util/ImageUtil.java

@@ -0,0 +1,232 @@
+package com.ywt.biz.common.util;
+
+
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.awt.image.ImageObserver;
+import java.io.*;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.*;
+import java.util.List;
+
+
+//import com.sun.image.codec.jpeg.JPEGCodec;
+//import com.sun.image.codec.jpeg.JPEGImageEncoder;
+
+import javax.imageio.ImageIO;
+
+public class ImageUtil {
+
+//    private static void createImage(String fileLocation, BufferedImage image) {
+//        try {
+//            File outputfile = new File(fileLocation);
+//            ImageIO.write(image, "png", outputfile);
+//
+////            ByteArrayOutputStream out = new ByteArrayOutputStream();
+////            ImageIO.write(image, "png", out);
+////            byte[] b = out.toByteArray();
+//
+////            ServiceResult serviceResult = imService.uploadSessionMessageFile(filename, messageList);
+//
+//
+//        } catch (Exception e) {
+//            e.printStackTrace();
+//        }
+//    }
+
+    private static final int paddingLeft = 35;
+
+    private static final int paddingTop = 50;
+
+    private static final int paddingBottom = 25;
+
+    private static final int wordsPerRow = 22;
+
+    private static final int rectWidth = 690;
+
+
+    private static void drawString(Graphics graphics, String content, int num) {
+        graphics.drawString(content, paddingLeft, num);
+    }
+
+    private static int drawLine(Graphics graphics, int num) {
+        num += paddingBottom;
+
+        Color color = new Color(204, 204, 204);
+        graphics.setColor(color);
+        graphics.drawLine(paddingLeft, num, 1150, num);
+        graphics.setColor(Color.BLACK);
+
+        num += paddingTop;
+
+        return num;
+    }
+
+    private static int drawRowInfo(Graphics graphics, String content, int num) {
+        drawString(graphics, content, num);
+        return drawLine(graphics, num);
+    }
+
+    public static BufferedImage graphicsGeneration(String name, String strSex, int age, String fromHospital, String toHospital,
+                                                   String toDoctorName, String toDoctorTitle, String diagnosis, String suggestion, String signUrl) throws IOException {
+
+        int imageWidth = 750;// 图片的宽度
+
+        int imageHeight = 1175;// 图片的初始高度(至"会诊意见"一行)
+
+
+        int suggestionRowCount = suggestion.length() / wordsPerRow + (suggestion.length() % wordsPerRow == 0 ? 0 : 1);
+        int suggestionHeight = (suggestionRowCount + 1) * 60;
+
+        imageHeight += suggestionHeight;    //"会诊意见"一栏高度
+        imageHeight += 160; //空行高度
+
+        BufferedImage bufferedImage;
+        int signImageHeight = 0;
+
+        try {
+            URL url = new URL(signUrl);
+            bufferedImage = ImageIO.read(url);
+            signImageHeight = bufferedImage.getHeight() * rectWidth / bufferedImage.getWidth();
+
+        } catch (Exception e) {
+            throw e;
+        }
+
+        imageHeight += signImageHeight; //签名图片高度
+        imageHeight += 400;     //日期、备注高度
+
+        BufferedImage image = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB);
+        Graphics graphics = image.getGraphics();
+        graphics.setColor(Color.white);
+        graphics.fillRect(0, 0, imageWidth, imageHeight);
+        graphics.setColor(Color.BLACK);
+        graphics.setFont(new Font("微软雅黑", Font.PLAIN, 30));
+
+
+        int num = 80;
+//        graphics.drawString(, paddingLeft, num);
+        List<String> contentList = Arrays.asList(
+                "患者姓名      " + name,
+                "性别        " + strSex,
+                "年龄        " + age,
+                "申请单位      " + fromHospital,
+                "会诊单位      " + toHospital,
+                "会诊专家      " + toDoctorName,
+                "职称        " + toDoctorTitle
+        );
+
+        for (String content : contentList) {
+            num = drawRowInfo(graphics, content, num);
+        }
+
+
+        num += 40;
+        graphics.drawString("初步诊断      ", paddingLeft, num);
+        num += 50;
+        graphics.drawRect(paddingLeft, num, rectWidth, 340);
+
+        num += 30;
+
+        int len = diagnosis.length() / wordsPerRow + (diagnosis.length() % wordsPerRow == 0 ? 0 : 1);
+        int start = 0;
+
+        for (int i = 0; i < len; i++) {
+            start = i * wordsPerRow;
+            if (i > 0) {
+                start = start - 1;
+            }
+
+            int l = start + wordsPerRow;
+
+            if (l > diagnosis.length()) {
+                l = diagnosis.length() - 1;
+            }
+
+            String t = diagnosis.substring(start, l);
+            num += 30;
+            graphics.drawString(t, 50, num);
+            num += 30;
+        }
+
+        if(len < 5){
+            num += (5 - len) * 60;
+        }
+
+        num += 100;
+        graphics.drawString("会诊意见", paddingLeft, num);
+        num += 50;
+
+//        int tttt = num;
+
+
+        graphics.drawRect(paddingLeft, num, rectWidth, suggestionHeight);
+        num += 30;
+        start = 0;
+
+        for (int i = 0; i < suggestionRowCount; i++) {
+            start = i * 22;
+            if (i > 0) {
+                start = start - 1;
+            }
+
+            int l = start + 22;
+
+            if (l > suggestion.length()) {
+                l = suggestion.length() - 1;
+            }
+
+            String t = suggestion.substring(start, l);
+            num += 30;
+            graphics.drawString(t, 50, num);
+            num += 30;
+        }
+
+
+        num += 100;
+
+        graphics.drawString("会诊医生签名", paddingLeft, num);
+        num += 50;
+
+
+        graphics.drawImage(bufferedImage, paddingLeft, num, rectWidth, signImageHeight, new ImageObserver() {
+            @Override
+            public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) {
+                return false;
+            }
+        });
+
+        num += signImageHeight + 50;
+        graphics.drawString("日期: " + DateUtil.convertToString(new Date(), "yyyy年MM月dd日"), paddingLeft, num);
+        num += 50;
+        graphics.drawString("注:专家会诊意见,仅供申请单位参考。", paddingLeft, num);
+
+
+//        createImage("/Users/bobotang/Desktop/test5.png", image);
+        return image;
+    }
+
+//    public static void main(String[] args) {
+//        String dig = "进入填写会诊报告页面(若医生填写部分,然进入填写会诊报告页面(若医生填写部分,然进入填写会诊报告页面(若医生填写部分,然进入填写会诊报告页面(若医生填写部分,然进入填写会诊报告页面(若医生填写部分,然";
+//        String suggestion = "进入填写会诊报告页面(若医生填写部分,然进入填写会诊报告页面(若医生填写部分,然进入填写会诊报告页面(若医生填写部分,然进入填写会诊报告页面(若医生填写部分,然进入填写会诊报告页面(若医生填写部分,然" +
+//                "进入填写会诊报告页面(若医生填写部分,然进入填写会诊报告页面(若医生填写部分,然进入填写会诊报告页面(若医生填写部分,然进入填写会诊报告页面(若医生填写部分,然进入填写会诊报告页面(若医生填写部分,然"
+//                + "进入填写会诊报告页面(若医生填写部分,然进入填写会诊报告页面(若医生填写部分,然进入填写会诊报告页面(若医生填写部分,然进入填写会诊报告页面(若医生填写部分,然进入填写会诊报告页面(若医生填写部分,然"
+//                + "进入填写会诊报告页面(若医生填写部分,然进入填写会诊报告页面(若医生填写部分,然进入填写会诊报告页面(若医生填写部分,然进入填写会诊报告页面(若医生填写部分,然进入填写会诊报告页面(若医生填写部分,然"
+//                + "进入填写会诊报告页面(若医生填写部分,然进入填写会诊报告页面(若医生填写部分,然进入填写会诊报告页面(若医生填写部分,然进入填写会诊报告页面(若医生填写部分,然进入填写会诊报告页面(若医生填写部分,然"
+//                + "进入填写会诊报告页面(若医生填写部分,然进入填写会诊报告页面(若医生填写部分,然进入填写会诊报告页面(若医生填写部分,然进入填写会诊报告页面(若医生填写部分,然进入填写会诊报告页面(若医生填写部分,然"
+//                + "进入填写会诊报告页面(若医生填写部分,然进入填写会诊报告页面(若医生填写部分,然进入填写会诊报告页面(若医生填写部分,然进入填写会诊报告页面(若医生填写部分,然进入填写会诊报告页面(若医生填写部分,然"
+//                + "进入填写会诊报告页面(若医生填写部分,然进入填写会诊报告页面(若医生填写部分,然进入填写会诊报告页面(若医生填写部分,然进入填写会诊报告页面(若医生填写部分,然进入填写会诊报告页面(若医生填写部分,然"
+//
+//                + "进入填写会诊报告页面(若医生填写部分,然进入填写会诊报告页面(若医生填写部分,然进入填写会诊报告页面(若医生填写部分,然进入填写会诊报告页面(若医生填写部分,然进入填写会诊报告页面(若医生填写部分,然"
+//                + "进入填写会诊报告页面(若医生填写部分,然进入填写会诊报告页面(若医生填写部分,然进入填写会诊报告页面(若医生填写部分,然进入填写会诊报告页面(若医生填写部分,然进入填写会诊报告页面(若医生填写部分,然";
+//
+////        suggestion = "进入填进入填进入填进入填进入填进入填进入填填";
+//        String signUrl = "http://ywt-image.oss-cn-shenzhen.aliyuncs.com/doc/iu.png";
+//        try {
+//            graphicsGeneration("锋哥小号", "男", 23, "深圳市福田区第二人民医院", "南方医科大学南方医院", "郭城锋", "主任医师", dig, suggestion, signUrl);
+//        } catch (IOException e) {
+//            e.printStackTrace();
+//        }
+//    }
+}

+ 86 - 0
src/main/java/com/ywt/biz/common/util/PhoneNumChecker.java

@@ -0,0 +1,86 @@
+package com.ywt.biz.common.util;
+
+import java.util.regex.Pattern;
+
+/**
+ * 手机号码校验类
+ * 目前的号码段截止至 2016年12月
+ */
+public class PhoneNumChecker {
+    /**
+     * 中国电信号码格式正则表达式
+     * 中国电信号码段:133,153,180,181,189,177,1700,173
+     */
+    private static final String CHINA_TELECOM_PATTERN = "(^1(33|53|7[37]|8[019])\\d{8}$)|(^1700\\d{7}$)";
+
+    /**
+     * 中国联通号码格式正则表达式
+     * 中国联通号码段:130,131,132,155,156,185,186,145,176,1707,1708,1709
+     */
+    private static final String CHINA_UNICOM_PATTERN = "(^1(3[0-2]|4[5]|5[56]|7[6]|8[56])\\d{8}$)|(^170[7-9]\\d{7}$)";
+
+    /**
+     * 中国移动号码格式正则表达式
+     * 中国移动号码段:134,135,136,137,138,139,150,151,152,157,158,159,182,183,184,187,188,147,178,1705
+     */
+    private static final String CHINA_MOBILE_PATTERN = "(^1(3[4-9]|4[7]|5[0-27-9]|7[8]|8[2-478])\\d{8}$)|(^1705\\d{7}$)";
+
+    /**
+     * 手机号格式正则表达式
+     */
+    private static final String MOBILE_NUM_PATTERN=new StringBuilder(300)
+            .append(CHINA_MOBILE_PATTERN)
+            .append("|")
+            .append(CHINA_TELECOM_PATTERN)
+            .append("|")
+            .append(CHINA_UNICOM_PATTERN)
+            .toString();
+
+    /**
+     * 手机号码校验
+     * @param mobile
+     * @return
+     */
+    public static boolean isPhoneNum(String mobile){
+        return match(MOBILE_NUM_PATTERN, mobile);
+    }
+
+
+    /**
+     * 电信手机号码校验
+     * @param mobile
+     * @return
+     */
+    public static boolean isChinaTelecomPhoneNum(String mobile) {
+        return match(CHINA_TELECOM_PATTERN, mobile);
+    }
+
+    /**
+     * 联通手机号码校验
+     * @param mobile
+     * @return
+     */
+    public static boolean isChinaUnicomPhoneNum(String mobile) {
+        return  match(CHINA_UNICOM_PATTERN, mobile);
+    }
+
+    /**
+     * 移动手机号码校验
+     * @param mobile
+     * @return
+     */
+    public static boolean isChinaMobilePhoneNum(String mobile) {
+        return  match(CHINA_MOBILE_PATTERN,mobile);
+    }
+
+    /**
+     *
+     * @param regex
+     * @param mobile
+     * @return
+     */
+    private static boolean match(String regex, String mobile) {
+        return Pattern.matches(regex, mobile);
+    }
+
+}

+ 117 - 0
src/main/java/com/ywt/biz/common/util/PinYinUtil.java

@@ -0,0 +1,117 @@
+package com.ywt.biz.common.util;
+
+import net.sourceforge.pinyin4j.PinyinHelper;
+import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
+import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
+import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
+import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
+import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
+
+public class PinYinUtil {
+    public static String getOneFirstSpell(String chinese) {
+        String result = getFirstSpell(chinese);
+        if (result.length() > 0) {
+            result = result.substring(0, 1);
+        } else {
+            result = "Z";
+        }
+        return result.toUpperCase();
+    }
+
+    /**
+     * 获取汉字串拼音首字母,英文字符不变
+     * @param chineseCharacts 汉字串
+     * @return 汉语拼音首字母
+     */
+    public static String getFirstSpell(String chineseCharacts) {
+        String result = "";//如果没有查到,默认返回Z
+        if (null == chineseCharacts) {
+            return "";
+        }
+        chineseCharacts = chineseCharacts.trim();
+
+        try {
+            StringBuffer pybf = new StringBuffer();
+            char[] arr = chineseCharacts.toCharArray();
+            HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();
+            defaultFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);
+            defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
+            for (int i = 0; i < arr.length; i++) {
+                if (arr[i] > 128) {
+                    try {
+                        String[] temp = PinyinHelper.toHanyuPinyinStringArray(arr[i], defaultFormat);
+                        if (temp != null) {
+                            pybf.append(temp[0].charAt(0));
+                        }
+                    } catch (BadHanyuPinyinOutputFormatCombination e) {
+                        e.printStackTrace();
+                    }
+                } else {
+                    pybf.append(arr[i]);
+                }
+            }
+            result = pybf.toString().replaceAll("\\W", "");
+            result = null == result ? "" : result.trim();
+        } catch (Exception ex) {
+        }
+        return result;
+    }
+
+    /**
+     * 中文转为拼音
+     * @param chineseCharacts
+     * @return
+     */
+    public static String getPingYin(String chineseCharacts) {
+        if (null == chineseCharacts || "".equals(chineseCharacts)) {
+            return "";
+        }
+        chineseCharacts = chineseCharacts.trim();
+
+        HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
+        format.setCaseType(HanyuPinyinCaseType.LOWERCASE);
+        format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
+        format.setVCharType(HanyuPinyinVCharType.WITH_V);
+
+        char[] input = chineseCharacts.trim().toCharArray();
+        String output = "";
+
+        try {
+            for (int i = 0; i < input.length; i++) {
+                if (Character.toString(input[i]).matches("[\\u4E00-\\u9FA5]+")) {
+                    String[] temp = PinyinHelper.toHanyuPinyinStringArray(input[i], format);
+                    output += temp[0];
+                } else
+                    output += Character.toString(input[i]);
+            }
+        } catch (BadHanyuPinyinOutputFormatCombination e) {
+            e.printStackTrace();
+        }
+        return output;
+    }
+
+    /**
+     * 获取汉字串拼音,英文字符不变
+     * @param chineseCharacts 汉字串
+     * @return 汉语拼音
+     */
+    public static String getFullSpell(String chineseCharacts) {
+        StringBuffer pybf = new StringBuffer();
+        char[] arr = chineseCharacts.toCharArray();
+        HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();
+        defaultFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);
+        defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
+        for (int i = 0; i < arr.length; i++) {
+            if (arr[i] > 128) {
+                try {
+                    pybf.append(PinyinHelper.toHanyuPinyinStringArray(arr[i], defaultFormat)[0]);
+                } catch (BadHanyuPinyinOutputFormatCombination e) {
+                    e.printStackTrace();
+                }
+            } else {
+                pybf.append(arr[i]);
+            }
+        }
+        return pybf.toString();
+    }
+}

+ 88 - 0
src/main/java/com/ywt/biz/common/util/RandomUtil.java

@@ -0,0 +1,88 @@
+package com.ywt.biz.common.util;
+
+import java.util.Random;
+
+public class RandomUtil {
+
+    //数字+字母
+    private static final String CHARS = "1234560987qazxswedcvfrtgbnhyujmkliopPLOKMIJNUHBYGVCFTRDXZSEWAQ";
+
+    //字母
+    private static final String LETTERS = "QAZXSWEDCVFRTGBNHYUIOPJKLMqwertyuioplkjhgfdsazxcvbnm";
+
+
+    /**
+     * 获取由随机数组成的字符串
+     *
+     * @param length 字符串长度
+     * @param type   随机数组成类型,1-数字,2-字母,3-数字字母混合
+     * @return
+     */
+    public static String getRandomCode(int length, int type) {
+        switch (type) {
+            case 1:
+                return getDigitCode(length);
+            case 2:
+                return getLetterCode(length);
+            case 3:
+                return getCharCode(length);
+            default:
+                return "";
+        }
+    }
+
+    /**
+     * 获取数字验证码
+     * @param length
+     * @return
+     */
+    private static String getDigitCode(int length) {
+        String code = "";
+        Random random = new Random();
+
+        for (int i = 0; i < length; i++) {
+            code += random.nextInt(10);
+        }
+
+        return code;
+    }
+
+    /**
+     * 获取字母验证码
+     * @param length
+     * @return
+     */
+    private static String getLetterCode(int length) {
+        String code = "";
+        Random random = new Random();
+        int bound = LETTERS.length();
+
+        for (int i = 0; i < length; i++) {
+            code += LETTERS.charAt(random.nextInt(bound));
+        }
+
+        return code;
+    }
+
+    /**
+     * 获取字符验证码(数字+字母)
+     * @param length
+     * @return
+     */
+    private static String getCharCode(int length) {
+        String code = "";
+        Random random = new Random();
+        int bound = CHARS.length();
+
+        for (int i = 0; i < length; i++) {
+            code += CHARS.charAt(random.nextInt(bound));
+        }
+
+        return code;
+    }
+
+    public static int getRandomInt(int bound) {
+        Random random = new Random();
+        return random.nextInt(bound);
+    }
+}

+ 133 - 0
src/main/java/com/ywt/biz/common/util/StringHelper.java

@@ -0,0 +1,133 @@
+package com.ywt.biz.common.util;
+
+import java.util.UUID;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Created by Jiangxiong.
+ */
+public class StringHelper {
+    public static final String scriptReg = "<script[\\s\\S]+?</script>";
+    public static final String iframeReg = "<iframe[\\s\\S]+?</iframe>";
+
+    /**
+     * 非负整数正则表达式
+     */
+    private static final String NON_NEGATIVE_INTEGER_REGEX = "^\\d+$";
+
+    public static String clearHtmlTag(String content) {
+        if (!isNullOrEmpty(content)) {
+            content = clearSpecialContent(content, scriptReg);
+            content = clearSpecialContent(content, iframeReg);
+            content = clearSpecialContent(content, "(<[^>\\s]*\\b(\\w)+\\b[^>]*>)|([\\s]+)|(<>)|(&nbsp;)");
+            content = content.replace("\"", "").replace("<", "").replace(">", "");
+        }
+        return content;
+    }
+
+    public static String clearImageAndScript(String content) {
+        String regexExpression = "<script[\\s\\S]+</script *>|<s*img[^>]*>";
+        return clearSpecialContent(content, regexExpression);
+    }
+
+    public static String clearSpecialContent(String content, String regexExpression) {
+        if (isNullOrEmpty(content)) {
+            return "";
+        }
+        Pattern pattern = Pattern.compile(regexExpression, Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
+        Matcher matcher = pattern.matcher(content);
+        content = matcher.replaceAll("");
+        return content;
+    }
+
+    public static String replaceSpecialContent(String sourceStr, String targetStr, String regexExp, int flags) {
+        Pattern pattern = Pattern.compile(regexExp, flags);
+        Matcher matcher = pattern.matcher(sourceStr);
+        sourceStr = matcher.replaceAll(targetStr);
+        return sourceStr;
+    }
+
+    public static String substringContent(String sourceStr, String regexExp, int flags){
+        Pattern pattern = Pattern.compile(regexExp, flags);
+        Matcher matcher = pattern.matcher(sourceStr);
+        return matcher.find() ? matcher.group() : "";
+    }
+
+    public static boolean isNullOrEmpty(String value) {
+        return value == null || "".equals(value);
+    }
+
+    /**
+     * 判断传入的value是null还是空白的字符串
+     * @param value
+     * @return
+     */
+    public static boolean isNullOrWhiteSpace(String value){
+        return value == null || "".equals(value)||"".equals(value.trim());
+    }
+
+
+    /**
+     * 转半角的函数
+     * @param value 任意字符串
+     * @return 半角字符串
+     */
+    public static String toDBC(String value)
+    {
+        char[] c = value.toCharArray();
+        for (int i = 0; i < c.length; i++)
+        {
+            if (c[i] == 12288)
+            {
+                c[i] = (char) 32;
+                continue;
+            }
+            if (c[i] > 65280 && c[i] < 65375)
+                c[i] = (char) (c[i] - 65248);
+        }
+        return new String(c);
+    }
+
+    /**
+     * 获取没有连字号的UUID
+     * @return
+     */
+    public static String getUUIDWithoutHyphen(){
+        return UUID.randomUUID().toString().replaceAll("-", "");
+    }
+
+    public static String trimStart(String source, char element){
+//        source.replaceFirst()
+        boolean beginIndexFlag = true;
+        boolean endIndexFlag = true;
+        do{
+            int beginIndex = source.indexOf(element) == 0 ? 1 : 0;
+            int endIndex = source.lastIndexOf(element) + 1 == source.length() ? source.lastIndexOf(element) : source.length();
+            source = source.substring(beginIndex, endIndex);
+            beginIndexFlag = (source.indexOf(element) == 0);
+            endIndexFlag = (source.lastIndexOf(element) + 1 == source.length());
+        } while (beginIndexFlag || endIndexFlag);
+        return source;
+    }
+
+    public static String toString(Object obj, String defaultValue) {
+        return obj != null ? obj.toString() : defaultValue;
+    }
+
+    public static String toString(Object obj) {
+        return toString(obj, "");
+    }
+
+    /**
+     * 判断字符串是否为非负整数
+     *
+     * @param str
+     * @return
+     */
+    public static boolean isNonNegativeInteger(String str) {
+        Pattern pattern = Pattern.compile(NON_NEGATIVE_INTEGER_REGEX);
+        Matcher matcher = pattern.matcher(str);
+        return matcher.matches();
+    }
+}

+ 56 - 0
src/main/java/com/ywt/biz/common/util/serializers/JsonSerializer.java

@@ -0,0 +1,56 @@
+package com.ywt.biz.common.util.serializers;
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.introspect.VisibilityChecker;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.io.StringWriter;
+
+/**
+ * Created by huangguoping
+ */
+public class JsonSerializer {
+    private static Logger logger = LoggerFactory.getLogger(JsonSerializer.class);
+    static ObjectMapper mapper = new ObjectMapper();
+    public static String toJson(Object object){
+        try {
+            StringWriter str = new StringWriter();
+            mapper.writeValue(str,object);
+            return str.toString();
+        } catch (JsonProcessingException e) {
+            //e.printStackTrace();
+        } catch (IOException e) {
+            //e.printStackTrace();
+        }
+        return null;
+    }
+
+    public static <T>T from(String json, Class<T> type){
+        mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
+        mapper.setVisibilityChecker(VisibilityChecker.Std.defaultInstance().withFieldVisibility(JsonAutoDetect.Visibility.ANY));
+        try {
+            mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true) ;
+            T t = mapper.readValue(json, type);
+            return t;
+        } catch (IOException e) {
+            //e.printStackTrace();
+        }
+        return null;
+    }
+
+    public static JsonNode readToNode (String json){
+        try{
+            return mapper.readTree(json);
+        }catch (Exception e) {
+          logger.error("JsonSerializer#readToNode(): {}", e.getMessage(), e);
+        }
+        return null;
+    }
+}

+ 97 - 0
src/main/java/com/ywt/biz/common/util/serializers/XMLSerializer.java

@@ -0,0 +1,97 @@
+package com.ywt.biz.common.util.serializers;
+
+import org.xml.sax.InputSource;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
+import java.io.*;
+
+/**
+ * Created by huangguoping.
+ */
+public class XMLSerializer {
+    public static byte[] objectToBytes(Object obj) {
+        byte[] result = null;
+        ByteArrayOutputStream byteOutputStream = null;
+        ObjectOutputStream objectOutputStream = null;
+
+        try {
+            byteOutputStream = new ByteArrayOutputStream();
+            objectOutputStream = new ObjectOutputStream(byteOutputStream);
+
+            objectOutputStream.writeObject(obj);
+            objectOutputStream.flush();
+
+            result = byteOutputStream.toByteArray();
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            if (null != objectOutputStream) {
+                try {
+                    objectOutputStream.close();
+                    byteOutputStream.close();
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+
+        return result;
+    }
+
+    public static Object bytesToObject(byte[] bytes) {
+        Object obj = null;
+
+        if (bytes == null) {
+            return null;
+        }
+
+        ByteArrayInputStream byteInputStream = null;
+        ObjectInputStream objectInputStream = null;
+
+        try {
+            byteInputStream = new ByteArrayInputStream(bytes);
+            objectInputStream = new ObjectInputStream(byteInputStream);
+            obj = objectInputStream.readObject();
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            if (null != objectInputStream) {
+                try {
+                    objectInputStream.close();
+                    byteInputStream.close();
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+
+        return obj;
+    }
+
+    public static <T> T xmlToObject(String xml, Class<T> clazz) throws IllegalAccessException, InstantiationException, JAXBException {
+        if (xml == null || xml.equals("")) {
+            return clazz.newInstance();
+        }
+
+        StringReader xmlString = new StringReader(xml);
+        InputSource source = new InputSource(xmlString);
+
+        JAXBContext jc = JAXBContext.newInstance(clazz);
+        Unmarshaller u = jc.createUnmarshaller();
+        return (T) u.unmarshal(source);
+    }
+
+    public static <T> String objectToXml(T t, Class<T> clazz) throws JAXBException {
+        Writer writer = new StringWriter();
+        JAXBContext context = JAXBContext.newInstance(clazz);
+        Marshaller marshaller = context.createMarshaller();
+
+        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
+        marshaller.marshal(t, writer);
+
+        return writer.toString();
+    }
+}

+ 30 - 0
src/main/java/com/ywt/biz/common/validator/Values.java

@@ -0,0 +1,30 @@
+package com.ywt.biz.common.validator;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+
+import java.lang.annotation.*;
+
+/**
+ * 取值范围注解
+ * @author zhangyingxuan
+ * @date 2018-08-20
+ **/
+@Documented
+@Constraint(validatedBy = ValuesValidator.class)
+@Target({ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Values {
+    /**
+     * 验证失败显示的信息
+     */
+    String message() default "";
+
+    /**
+     * 取值范围
+     */
+    String[] value() default {};
+
+    Class<?>[] groups() default { };
+    Class<? extends Payload>[] payload() default { };
+}

+ 36 - 0
src/main/java/com/ywt/biz/common/validator/ValuesValidator.java

@@ -0,0 +1,36 @@
+package com.ywt.biz.common.validator;
+
+import org.springframework.util.StringUtils;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+
+/**
+ * 取值范围校验器, 被注解的字段的值, 需是{values}中的值
+ * @author zhangyingxuan
+ * @date 2018-08-20
+ **/
+public class ValuesValidator implements ConstraintValidator<Values,String> {
+
+    private String[] values;
+
+    @Override
+    public void initialize(Values constraintAnnotation) {
+        values = constraintAnnotation.value();
+    }
+
+    @Override
+    public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {
+        if (StringUtils.isEmpty(value)) {
+            return true;
+        }
+
+        for (String v : values) {
+            if(v.equals(value)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+}

+ 14 - 0
src/main/java/com/ywt/biz/common/web/BizBaseController.java

@@ -0,0 +1,14 @@
+package com.ywt.biz.common.web;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 各工程controller继承此类,主要是设置uri前缀
+ *
+ * @author zcli
+ */
+@RestController
+@RequestMapping(value="/anytxn/v2/api")
+public class BizBaseController {
+}

+ 24 - 0
src/main/java/com/ywt/biz/common/web/LocalDateTimeSerializerConfig.java

@@ -0,0 +1,24 @@
+package com.ywt.biz.common.web;
+
+import java.time.format.DateTimeFormatter;
+
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
+
+/**
+ * Json数据中的LocalDateTime的序列化
+ * @author yxy
+ */
+public class LocalDateTimeSerializerConfig {
+    private String pattern = "yyyy-MM-dd HH:mm:ss";
+
+
+    public LocalDateTimeSerializer localDateTimeSerializer() {
+        return new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(pattern));
+    }
+
+    public LocalDateTimeDeserializer localDateTimeDeserializer() {
+        return new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(pattern));
+    }
+
+}

+ 127 - 0
src/main/java/com/ywt/biz/common/web/YwtHttpResponse.java

@@ -0,0 +1,127 @@
+/**
+ * 
+ */
+package com.ywt.biz.common.web;
+
+import com.ywt.biz.common.constant.AnyTxnCommonRespCode;
+import lombok.Data;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+
+
+/**
+ * 通用的http请求返回结果封装.
+ * 由于此类为公用类,无法使用工程内定义的枚举对象作为入参,这里只能使用字符串类型参数
+ * @author fhp
+ *
+ */
+@Data
+public class YwtHttpResponse<T> {
+	/**
+	 * 响应码
+	 */
+    private String code;
+    /**
+     * 通用显示信息
+     */
+    private String message;
+    /**
+     * 具体错误信息(通常会显示上下文信息,如参数)
+     * 仅在返回错误时使用
+     */
+    private String detail;
+    /**
+     * 正常返回的数据
+     */
+    private T data;
+
+    /**
+     * 请求成功(适用于不需要返回具体数据,且前端不关注提示信息场景)
+     * 如果操作完成后前端页面不关注提示信息,或者不需要提示信息可以使用
+     * @return AnyTxnHttpResponse<T>
+     */
+    public static <T> YwtHttpResponse<T> success() {
+    	return new YwtHttpResponse<>();
+    }
+    /**
+     * 请求成功(适用于不需要返回具体数据,且前端会关注提示信息场景)
+     * 操作完成,前端需要展示提示信息
+     * @param <T>
+     * @param detail 返回给下=前端的提示信息
+     * @return
+     */
+    public static <T> YwtHttpResponse<T> successDetail(String detail) {
+    	YwtHttpResponse<T> resp = new YwtHttpResponse<>();
+    	resp.setDetail(detail);
+    	return resp;
+    }
+    /**
+     * 请求成功(适用于需要返回具体数据的操作,且不关注提示信息)
+     * 类似场景分页列表,点击上下页,直接返回页面数据即可
+     * @param data 返回具体数据
+     * @return AnyTxnHttpResponse
+     */
+    public static <T> YwtHttpResponse<T> success(T data) {
+        return new YwtHttpResponse<>(data);
+    }
+    /**
+     * 请求成功(适用于需要返回具体数据的操作,且关注提示信息)
+     * @param data 返回具体数据
+     * @param detail
+     * @return AnyTxnHttpResponse
+     */
+    public static <T> YwtHttpResponse<T> success(T data, String detail) {
+    	YwtHttpResponse<T> resp = new YwtHttpResponse<>(data);
+    	resp.setDetail(detail);
+    	return resp;
+    }
+    /**
+     * 请求发生异常(不需要返回具体上下文信息)
+     * 此方法适用于该响应码是专用响应码,也就是为每个具体错误定义类对应具体响应码.
+     * 通过响应码的msg就可以对错误进行准确描述
+     * 一句话,人比较勤快,针对各种错误都定义了具体对应的响应码就用这个方法
+     * @param code 响应码
+     * @param msg 响应信息
+     * @return AnyTxnHttpResponse
+     */
+    public static <T> YwtHttpResponse<T> fail(String code, String msg) {
+        return fail(code, msg, null);
+    }
+    /**
+     * 请求发生异常(需要返回具体上下文信息,需要在抛出自定义异常时自己设置)
+     * 此方法适用于该响应码会负责多种错误信息的处理,而相应码自身的msg不能对每种错误进行专有描述,这时候需要通过detail来弥补
+     * 一句话,相对于上面不够勤快,想通过少量的响应码满足所有错误场景,那就需要通过这个方法设置detail来弥补
+     * @param code 响应码
+     * @param msg 响应信息
+     * @param detail 在抛出自定义异常时自己设置的信息
+     * @return AnyTxnHttpResponse
+     */
+    public static <T> YwtHttpResponse<T> fail(String code, String msg, String detail) {
+        return new YwtHttpResponse<>(code, msg, detail);
+    }
+
+    private YwtHttpResponse() {
+        this(AnyTxnCommonRespCode.REQ_SUCCESS, null);
+    }
+    private YwtHttpResponse(T data) {
+        this(AnyTxnCommonRespCode.REQ_SUCCESS, data);
+    }
+    private YwtHttpResponse(AnyTxnCommonRespCode rc, T data) {
+        this.code = rc.getCode();
+        this.message = rc.getMsg();
+        this.data = data;
+        this.detail = null;
+    }
+    private YwtHttpResponse(String code, String message, String detail) {
+        this.code = code;
+        this.message = message;
+        this.detail = detail;
+        this.data = null;
+    }
+    
+	@Override
+    public String toString() {
+    	return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
+    }
+}

+ 107 - 0
src/test/java/jrx/anytxn/biz/common/util/CustomThreadPoolExecutor.java

@@ -0,0 +1,107 @@
+package jrx.anytxn.biz.common.util;
+
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.RejectedExecutionHandler;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class CustomThreadPoolExecutor {
+
+	private ThreadPoolExecutor pool;
+
+	CustomThreadPoolExecutor () {
+		init();
+	}
+	CustomThreadPoolExecutor (int coreThread, int maxThread, long keepAliveTime, TimeUnit unit,
+			BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) {
+		pool = new ThreadPoolExecutor(coreThread, maxThread, keepAliveTime, unit, workQueue, threadFactory, handler);
+	}
+	/**
+	 * 线程池初始化方法
+	 * 
+	 * corePoolSize 核心线程池大小----10 
+	 * maximumPoolSize 最大线程池大小----30 
+	 * keepAliveTime 线程池中超过corePoolSize数目的空闲线程最大存活时间----30+
+	 * 单位TimeUnit TimeUnit
+	 * keepAliveTime时间单位----TimeUnit.MINUTES 
+	 * workQueue 阻塞队列----new ArrayBlockingQueue<Runnable>(10)====10容量的阻塞队列 
+	 * threadFactory 新建线程工厂----new CustomThreadFactory()====定制的线程工厂 
+	 * rejectedExecutionHandler 当提交任务数超过maxmumPoolSize+workQueue之和时,即当提交第41个任务时(前面线程都没有执行完,此测试方法中用sleep(100)), 任务会交给RejectedExecutionHandler来处理
+	 */
+	public void init() {
+		pool = new ThreadPoolExecutor(10, 30, 30, TimeUnit.MINUTES, new ArrayBlockingQueue<Runnable>(10),
+				new CustomThreadFactory(), new CustomRejectedExecutionHandler());
+	}
+
+//	public void init(int coreThread, int maxThread, long keepAliveTime, TimeUnit unit,
+//			BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) {
+//		pool = new ThreadPoolExecutor(coreThread, maxThread, keepAliveTime, unit, workQueue, threadFactory, handler);
+//	}
+
+	public void destory() {
+		if (pool != null) {
+			pool.shutdownNow();
+		}
+	}
+
+	public ExecutorService getCustomThreadPoolExecutor() {
+		return this.pool;
+	}
+
+	private class CustomThreadFactory implements ThreadFactory {
+
+		private AtomicInteger count = new AtomicInteger(0);
+
+		@Override
+		public Thread newThread(Runnable r) {
+			Thread t = new Thread(r);
+			String threadName = CustomThreadPoolExecutor.class.getSimpleName() + count.addAndGet(1);
+			t.setName(threadName);
+			return t;
+		}
+	}
+
+	private class CustomRejectedExecutionHandler implements RejectedExecutionHandler {
+
+		@Override
+		public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
+			// 记录异常
+			// 报警处理等
+		}
+	}
+
+	// 测试构造的线程池
+	public static void main(String[] args) {
+		ExecutorService es = Executors.newCachedThreadPool();
+
+		CustomThreadPoolExecutor exec = new CustomThreadPoolExecutor();
+		// 1.初始化
+		exec.init();
+
+		ExecutorService pool = exec.getCustomThreadPoolExecutor();
+		for (int i = 1; i < 100; i++) {
+			pool.execute(new Runnable() {
+				@Override
+				public void run() {
+//					try {
+//						Thread.sleep(3000);
+//					} catch (InterruptedException e) {
+//					}
+				}
+			});
+		}
+
+		// 2.销毁----此处不能销毁,因为任务没有提交执行完,如果销毁线程池,任务也就无法执行了
+		// exec.destory();
+
+//		try {
+//			Thread.sleep(10000);
+//		} catch (InterruptedException e) {
+//		}
+	}
+}

+ 33 - 0
src/test/java/jrx/anytxn/biz/common/util/CvvTest.java

@@ -0,0 +1,33 @@
+package jrx.anytxn.biz.common.util;
+
+import jrx.anytxn.biz.common.util.encryption.CvvUtils;
+import jrx.anytxn.biz.common.util.encryption.UnionResponse;
+import org.junit.Test;
+
+import java.nio.charset.StandardCharsets;
+
+/**
+ * 测试CVV、CVV2
+ *
+ * @author ping
+ * @date 2019-11-22
+ **/
+public class CvvTest {
+
+    @Test
+    public void cvvTest1() {
+        CvvUtils api = new CvvUtils("10.0.13.99",28102, 3, 0);
+        String cvk="X181A9A44CB63CB636FAADDF4F33A072F";
+        String cardNumber="6221660020003829";
+        String expireDate="1212";
+        String serviceCode="567";
+
+        UnionResponse response = api.createCvvByCw(cvk,cardNumber,expireDate,serviceCode);
+        if (response.getCheckValue()==null) {
+
+        }else {
+            String checkValue = new String(response.getCheckValue(), StandardCharsets.UTF_8);
+        }
+
+    }
+}

+ 20 - 0
src/test/java/jrx/anytxn/biz/common/util/DateHelperTest.java

@@ -0,0 +1,20 @@
+package jrx.anytxn.biz.common.util;
+
+import org.junit.Test;
+
+import java.time.LocalDate;
+
+/**
+ * @author peidong.meng
+ * @date 2020/6/18
+ */
+public class DateHelperTest {
+
+    @Test
+    public void toLocalDateTime(){
+
+        LocalDate a1 = DateHelper.toLocalDateTime("20200518000000", "yyyyMMddHHmmss").toLocalDate();
+        LocalDate a2 = DateHelper.toLocalDateTime("20200619000000", "yyyyMMddHHmmss").toLocalDate();
+
+    }
+}

+ 532 - 0
src/test/java/jrx/anytxn/biz/common/util/DateUtilsTest.java

@@ -0,0 +1,532 @@
+//package jrx.anytxn.biz.common.uitl;
+//
+//import org.junit.Before;
+//import org.junit.Test;
+//
+//import java.time.LocalDate;
+//import java.util.Date;
+//
+//import static org.junit.Assert.assertEquals;
+//
+///**
+// * DateUtils Tester.
+// *
+// * @author ${user}
+// * @version 1.0
+// * @since <pre>九月 19, 2018</pre>
+// */
+//
+//public class DateUtilsTest {
+//
+//
+//    @Test
+//    public void testDateUtilsLocalDateConvertToDate() throws Exception {
+//        LocalDate localDate=LocalDate.now();
+//    }
+//
+//    /**
+//     * Method: format(Date date)
+//     */
+//    @Test
+//    public void testFormatDate() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: format(Date date, String pattern)
+//     */
+//    @Test
+//    public void testFormatForDatePattern() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: date(int year, int month, int date)
+//     */
+//    @Test
+//    public void testDate() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: localDateConvertToDate(LocalDate localDate)
+//     */
+//    @Test
+//    public void testLocalDateConvertToDate() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: dateConvertToLocalDate(Date date)
+//     */
+//    @Test
+//    public void testDateConvertToLocalDate() throws Exception {
+//        /*
+//        java.sql.Date sqlDate = new java.sql.Date(2019,9,9);
+//
+//        LocalDate date1 = DateUtils.dateConvertToLocalDate(sqlDate);
+//        LocalDate date = DateUtils.dateConvertToLocalDate(new Date());
+//        */
+//    }
+//
+//    /**
+//     * Method: compareDateWithLocalDate(Date date1, Date date2)
+//     */
+//    @Test
+//    public void testCompareDateWithLocalDate() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: parse(String date)
+//     */
+//    @Test
+//    public void testParse() throws Exception {
+//        LocalDate parse = DateUtils.parse("2017-09-09");
+//        assertEquals("日期解析", LocalDate.of(2017, 9, 9), parse);
+//        assertEquals("时间解析", LocalDate.of(2017, 9, 9),
+//                DateUtils.parse("     2017-09-09 " + "23:04:34"));
+//    }
+//
+//    /**
+//     * Method: format(String str)
+//     */
+//    @Test
+//    public void testFormatStr() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: getBeforeDay(Date date)
+//     */
+//    @Test
+//    public void testGetBeforeDay() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: compareDate(Date date, Date date1)
+//     */
+//    @Test
+//    public void testCompareDate() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: formatDate(Date date, String pattern)
+//     */
+//    @Test
+//    public void testFormatDateForDatePattern() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: formatDateTime(Date date)
+//     */
+//    @Test
+//    public void testFormatDateTimeDate() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: formatDateTime()
+//     */
+//    @Test
+//    public void testFormatDateTime() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: formatDateTime2()
+//     */
+//    @Test
+//    public void testFormatDateTime2() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: formatDate(Date date)
+//     */
+//    @Test
+//    public void testFormatDateDate() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: formatDate2()
+//     */
+//    @Test
+//    public void testFormatDate2() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: formatDate2(Date date)
+//     */
+//    @Test
+//    public void testFormatDate2Date() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: formatTime(Date date)
+//     */
+//    @Test
+//    public void testFormatTimeDate() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: formatTime()
+//     */
+//    @Test
+//    public void testFormatTime() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: formatTime2()
+//     */
+//    @Test
+//    public void testFormatTime2() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: now()
+//     */
+//    @Test
+//    public void testNow() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: nowLocalDate()
+//     */
+//    @Test
+//    public void testNowLocalDate() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: nowLocalDateTime()
+//     */
+//    @Test
+//    public void testNowLocalDateTime() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: parseDateTime(String datetime)
+//     */
+//    @Test
+//    public void testParseDateTime() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: parseDate(String date, String format)
+//     */
+//    @Test
+//    public void testParseDateForDateFormat() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: parseDate(String date)
+//     */
+//    @Test
+//    public void testParseDateDate() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: parseDate(Date datetime)
+//     */
+//    @Test
+//    public void testParseDateDatetime() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: formatDate(Object o)
+//     */
+//    @Test
+//    public void testFormatDateO() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: formatDateTime(Object o)
+//     */
+//    @Test
+//    public void testFormatDateTimeO() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: add(Date date, int field, int amount)
+//     */
+//    @Test
+//    public void testAdd() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: addMilliSecond(Date date, int amount)
+//     */
+//    @Test
+//    public void testAddMilliSecond() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: addSecond(Date date, int amount)
+//     */
+//    @Test
+//    public void testAddSecond() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: addMiunte(Date date, int amount)
+//     */
+//    @Test
+//    public void testAddMiunte() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: addHour(Date date, int amount)
+//     */
+//    @Test
+//    public void testAddHour() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: addDay(Date date, int amount)
+//     */
+//    @Test
+//    public void testAddDay() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: addMonth(Date date, int amount)
+//     */
+//    @Test
+//    public void testAddMonth() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: addYear(Date date, int amount)
+//     */
+//    @Test
+//    public void testAddYear() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: getDate()
+//     */
+//    @Test
+//    public void testGetDate() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: getDateTime()
+//     */
+//    @Test
+//    public void testGetDateTime() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: between(Date date, int offset, TimeUnit unit)
+//     */
+//    @Test
+//    public void testBetween() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: getDate(Date date, int interval)
+//     */
+//    @Test
+//    public void testGetDateForDateInterval() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: getDateByMonth(Date date, int interval)
+//     */
+//    @Test
+//    public void testGetDateByMonth() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: getDateByMinute(Date date, int interval)
+//     */
+//    @Test
+//    public void testGetDateByMinute() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: compare(Date date1, Date date2)
+//     */
+//    @Test
+//    public void testCompare() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: getDaysBetween(Date date1, Date date2)
+//     */
+//    @Test
+//    public void testGetDaysBetween() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: getDiffDays(Date startdate, Date enddate)
+//     */
+//    @Test
+//    public void testGetDiffDays() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: getYearAndMonthAndDay(Date date)
+//     */
+//    @Test
+//    public void testGetYearAndMonthAndDay() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: getYear(Date date)
+//     */
+//    @Test
+//    public void testGetYear() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: getMonth(Date date)
+//     */
+//    @Test
+//    public void testGetMonth() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: getDay(Date date)
+//     */
+//    @Test
+//    public void testGetDay() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: sameYear(long thisTime, long thatTime)
+//     */
+//    @Test
+//    public void testSameYear() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: sameMonth(long thisTime, long thatTime)
+//     */
+//    @Test
+//    public void testSameMonth() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: sameDate(long thisTime, long thatTime)
+//     */
+//    @Test
+//    public void testSameDate() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: toYear(Date date, int year)
+//     */
+//    @Test
+//    public void testToYear() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: getMonthStartTime(Date date)
+//     */
+//    @Test
+//    public void testGetMonthStartTime() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: getMonthEndTime(Date date)
+//     */
+//    @Test
+//    public void testGetMonthEndTime() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: getMonthStartEnd(Date d1, int months)
+//     */
+//    @Test
+//    public void testGetMonthStartEnd() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: getWorkingDate()
+//     */
+//    @Test
+//    public void testGetWorkingDate() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: getDateByCurrDateAndDays(Date currDate, int days)
+//     */
+//    @Test
+//    public void testGetDateByCurrDateAndDays() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: getDayTerm(Date date)
+//     */
+//    @Test
+//    public void testGetDayTermDate() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: getDayTerm(Date d1, Date d2)
+//     */
+//    @Test
+//    public void testGetDayTermForD1D2() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//    /**
+//     * Method: beforeDay(Date date1, Date date2)
+//     */
+//    @Test
+//    public void testBeforeDay() throws Exception {
+//        //TODO: Test goes here...
+//    }
+//
+//
+//}

+ 78 - 0
src/test/java/jrx/anytxn/biz/common/util/NumberUtilsTest.java

@@ -0,0 +1,78 @@
+//package jrx.anytxn.biz.common.uitl;
+//
+//import org.junit.Test;
+//
+//import java.math.BigDecimal;
+//import java.util.ArrayList;
+//import java.util.List;
+//
+//import static org.junit.Assert.*;
+//
+///**
+// * NumberUtils Tester.
+// *
+// * @author ${user}
+// * @version 1.0
+// * @since <pre>九月 15, 2018</pre>
+// */
+//
+//
+//public class NumberUtilsTest {
+//    private BigDecimal bigDecimal = new BigDecimal("3");
+//    private BigDecimal bigDecimal1 = new BigDecimal("9");
+//
+//
+//    /**
+//     * Method: compareBigDecimal(BigDecimal num1, BigDecimal num2)
+//     */
+//    @Test
+//    public void testCompareToBigDecimal() {
+//        assertTrue(NumberUtils.compareBigDecimal(bigDecimal1, bigDecimal));
+//        assertFalse(NumberUtils.compareBigDecimal(bigDecimal, bigDecimal1));
+//        try {
+//            NumberUtils.compareBigDecimal(null, bigDecimal);
+//        } catch (NullPointerException e) {
+//            assertEquals("null异常", e.getMessage(), "num1");
+//        }
+//        try {
+//            NumberUtils.compareBigDecimal(bigDecimal1, null);
+//        } catch (NullPointerException e) {
+//            assertEquals("null异常", e.getMessage(), "num2");
+//        }
+//
+//    }
+//
+//    /**
+//     * Method: sum(Collection<BigDecimal> collection)
+//     */
+//    @Test
+//    public void testSumCollection() {
+//        List<BigDecimal> list = null;
+//        try {
+//            NumberUtils.sum(list);
+//        } catch (UnsupportedOperationException e) {
+//            assertEquals("测试异常", "不支持空集合操作", e.getMessage());
+//        }
+//        list = new ArrayList<>();
+//        list.add(bigDecimal);
+//        list.add(bigDecimal1);
+//        assertEquals("测试求和", new BigDecimal("12"), NumberUtils.sum(list));
+//    }
+//
+//    /**
+//     * Method: sum(BigDecimal... bigDecimals)
+//     */
+//    @Test
+//    public void testSumBigDecimals() {
+//        BigDecimal[] bigDecimals = null;
+//        try {
+//            NumberUtils.sum(bigDecimals);
+//        } catch (UnsupportedOperationException e) {
+//            assertEquals("测试异常", "不支持空数组操作", e.getMessage());
+//        }
+//        bigDecimals = new BigDecimal[]{bigDecimal, bigDecimal1};
+//        assertEquals("数组求和", new BigDecimal("12"), NumberUtils.sum(bigDecimals));
+//    }
+//
+//
+//}

+ 48 - 0
src/test/java/jrx/anytxn/biz/common/util/PinTest.java

@@ -0,0 +1,48 @@
+package jrx.anytxn.biz.common.util;
+
+import jrx.anytxn.biz.common.util.encryption.PinUtils;
+import org.junit.Test;
+
+/**
+ * @author ping
+ * @date 2019-11-27
+ **/
+public class PinTest {
+    @Test
+    public void createPinOffsetRandom(){
+        String number="166002000058";
+        String pvk="XCA4ED29A0FD70EE156C1C0D4637C825C";
+        String pinLen="06";
+        String decimalConvetTable="0123456789012345";
+        String pinCheckData="01234567890N";
+        PinUtils pinUtils = new PinUtils("10.0.13.99", 28102, 3, 0);
+        String offset = pinUtils.createPinOffsetByRandom(number, pvk, pinLen, decimalConvetTable, pinCheckData);
+    }
+
+    @Test
+    public void createPinOffsetByPin(){
+        String number="166002000058";
+        String pvk="XCA4ED29A0FD70EE156C1C0D4637C825C";
+        String pin="116101F";
+        String pinLen="06";
+        String decimalConvetTable="0123456789012345";
+        String pinCheckData="01234567890N";
+        PinUtils pinUtils = new PinUtils("10.0.13.99", 28102, 3, 0);
+        String offset = pinUtils.createPinOffsetByPin(pin,number, pvk, pinLen, decimalConvetTable, pinCheckData);
+    }
+
+    @Test
+    public void checkPassword(){
+        String number="166002000058";
+        String zpk="X8B4ECCAE01B4B17AAC951121A98DB14E";
+        String pvk="XCA4ED29A0FD70EE156C1C0D4637C825C";
+        String pin="C230D3C3E131BEC9";
+        String pinLen="06";
+        String pinType="01";
+        String decimalConvetTable="0123456789012345";
+        String pinCheckData="01234567890N";
+        String pinOffset="088088FFFFFF";
+        PinUtils pinUtils = new PinUtils("10.0.13.99", 28102, 3, 0);
+        boolean offset = pinUtils.checkPassword(zpk,pvk,pin,number, pinType, pinLen, decimalConvetTable, pinCheckData,pinOffset);
+    }
+}