From 43393f2bb11cbf9e6af40077bbc5284660e8a754 Mon Sep 17 00:00:00 2001
From: 测试用户 <gaozhangwei@prec-tech.com>
Date: 星期四, 13 四月 2023 14:50:12 +0800
Subject: [PATCH] 仓库初始化

---
 src/main/java/com/deloitte/system/model/CacheList.java                        |   21 
 src/main/java/com/common/core/utils/PdfConverUtils.java                       |   50 
 src/main/java/com/deloitte/system/service/LoanerUserService.java              |  128 
 src/main/java/com/deloitte/system/request/TxConfirmDto.java                   |   29 
 src/main/java/com/common/core/utils/GsonUtils.java                            |   69 
 src/main/java/com/common/annotation/Sign.java                                 |   14 
 src/main/java/com/common/component/RedisCache.java                            |   35 
 src/main/java/com/deloitte/system/service/UserFaultInfoService.java           |  132 
 src/main/java/com/deloitte/system/request/LoanerApplicationDto.java           |   50 
 src/main/java/com/deloitte/system/controller/TSRepairController.java          |   76 
 src/main/java/com/deloitte/system/model/LoanerApplication.java                |  122 
 src/main/java/com/common/core/service/SFService.java                          |  142 
 src/main/java/com/deloitte/system/controller/TestController.java              |   24 
 src/main/java/com/deloitte/system/request/TSRepairDto.java                    |   24 
 src/main/java/com/deloitte/system/service/OpportunityService.java             |  190 
 src/main/java/com/deloitte/system/job/GuaranteedTask.java                     |  353 +
 src/main/java/com/deloitte/system/model/Contact.java                          |  258 
 src/main/java/com/common/configure/EncryptionPropertyConfig.java              |   40 
 src/main/java/com/common/core/utils/RestUtil.java                             |  310 
 src/main/java/com/common/annotation/NoEncryption.java                         |   10 
 src/main/java/com/common/filter/RequestCachingFilter.java                     |   78 
 src/main/java/com/deloitte/system/request/OperatorQueryDto.java               |   18 
 encrypted_data_key.txt                                                        |    0 
 src/main/java/com/deloitte/system/service/CampaignUserService.java            |  206 
 src/main/java/com/deloitte/system/request/CampaignUserAllDto.java             |   40 
 src/main/java/com/common/configure/Swagger2Config.java                        |   58 
 src/main/java/com/deloitte/system/request/QuotesDto.java                      |   46 
 src/main/java/com/common/security/utils/SecurityHolderUtils.java              |   20 
 src/main/java/com/deloitte/system/request/SFFileAddressVo.java                |   16 
 src/main/java/com/common/security/utils/SecurityUtils.java                    |   37 
 src/main/java/com/deloitte/system/controller/ConfirmTxController.java         |   42 
 src/main/java/com/deloitte/system/job/CleanCacheTask.java                     |   23 
 src/main/java/com/common/annotation/NoToken.java                              |   13 
 src/main/java/com/common/core/service/CryptoService.java                      |  431 +
 src/main/java/com/common/annotation/NoLog.java                                |   13 
 src/main/resources/prod1/application.yml                                      |    1 
 src/main/java/com/deloitte/sbg/controller/SapSBGRest.groovy                   |  174 
 src/main/java/com/deloitte/system/controller/LoanerUserController.java        |   74 
 src/main/java/com/deloitte/system/model/AppPermissionConfig.java              |   39 
 src/main/java/com/deloitte/system/request/UserFaultInfoDto.java               |   27 
 src/main/java/com/deloitte/system/model/Quotes.java                           |   90 
 src/main/java/com/common/core/crypto/CryptoHandler.java                       |   14 
 src/main/java/com/deloitte/system/model/Opportunity.java                      |   98 
 src/main/java/com/common/core/utils/ArrayUtils.java                           |    9 
 src/main/java/com/deloitte/system/service/MailService.java                    |  889 ++
 src/main/java/com/deloitte/system/controller/TokenController.java             |  108 
 src/main/java/com/common/redis/serializer/KryoRedisSerializer.java            |   94 
 src/main/resources/stg/logback.xml                                            |   66 
 src/main/java/com/deloitte/system/model/UserFaultInfo.java                    |   61 
 pom.xml                                                                       |  396 +
 src/main/java/com/common/core/constant/GlobalConst.java                       |   24 
 src/main/java/com/common/core/utils/SecretsManagerUtils.java                  |  105 
 src/main/java/com/common/aspect/CustomResponseAdvice.java                     |   70 
 src/main/resources/local/application.yml                                      |    1 
 src/main/java/com/common/core/utils/DesensitiveUtils.java                     |  217 
 src/main/java/com/deloitte/system/service/QuotesService.java                  |  143 
 src/main/java/com/deloitte/system/model/AppConfig.java                        |   37 
 src/main/java/com/deloitte/system/model/Repair.java                           |   52 
 src/main/java/com/common/core/service/JsonCryptoService.java                  |   31 
 src/main/java/com/deloitte/system/request/SFMessageVo.java                    |   47 
 src/main/java/com/common/filter/CorsFilter.java                               |   21 
 src/main/java/com/deloitte/system/service/ConfirmTxService.java               |  155 
 src/main/java/com/deloitte/system/model/TSRepair.java                         |   49 
 src/main/java/com/common/core/constant/Constants.java                         |   63 
 src/main/java/com/common/filter/JwtAuthenticationTokenFilter.java             |   94 
 src/main/java/com/deloitte/system/controller/RepairController.java            |   77 
 src/main/java/com/deloitte/system/controller/CampaignUserController.java      |   86 
 src/main/java/com/common/core/utils/RegexUtils.java                           |   28 
 src/main/java/com/common/configure/ClassPathTableScanner.java                 |   68 
 src/main/java/com/deloitte/system/service/FileService.java                    |  377 +
 src/main/java/com/common/core/utils/UUID.java                                 |  484 +
 src/main/java/com/common/aspect/LogReturnAspect.java                          |   55 
 src/main/java/com/common/redis/config/CommonRedisConfig.java                  |   62 
 src/main/java/com/deloitte/system/request/SFTokenDto.java                     |   26 
 src/main/java/com/common/component/DruidPlugin.java                           |  353 +
 src/main/java/com/deloitte/system/request/RepairDto.java                      |   24 
 src/main/java/com/deloitte/system/controller/UserFaultInfoController.java     |   76 
 src/main/java/com/common/core/utils/DynamicBean.java                          |   43 
 src/main/java/com/common/annotation/NoAuthorize.java                          |   10 
 src/main/java/com/deloitte/system/controller/MailController.java              |   47 
 src/main/java/com/deloitte/system/controller/ContactController.java           |   96 
 src/main/java/com/deloitte/system/controller/OrderController.java             |   95 
 src/main/java/com/common/configure/JfinalProperties.java                      |    1 
 src/main/java/com/common/security/configure/AppDetails.java                   |   72 
 Encoded_content.json                                                          |    0 
 src/main/java/com/common/aspect/DesensitiveAspect.java                        |   32 
 src/main/java/com/common/core/utils/KitClassUtils.java                        |   13 
 src/main/java/com/deloitte/system/request/SwoDto.java                         |   58 
 src/main/java/com/Application.java                                            |  239 
 src/main/java/com/common/annotation/Table.java                                |   24 
 src/main/resources/local/logback.xml                                          |   66 
 src/main/java/com/common/configure/CommonConfig.java                          |   12 
 src/main/java/com/common/core/crypto/ColumnHandler.java                       |   41 
 src/main/java/com/common/annotation/RequestLimit.java                         |   32 
 src/main/java/com/deloitte/system/model/CampaignUser.java                     |   65 
 src/main/java/com/deloitte/system/request/SearchDto.java                      |   16 
 src/main/java/com/deloitte/system/controller/QuotesController.java            |   76 
 src/main/java/com/common/core/utils/DateUtils.java                            |  962 +++
 src/main/java/com/common/core/beans/Result.java                               |   61 
 src/main/java/com/deloitte/system/model/LoanerUser.java                       |   46 
 src/main/java/com/common/core/utils/StringUtils.java                          |  293 
 src/main/java/com/common/annotation/JfinalModelScan.java                      |   20 
 src/main/java/com/deloitte/system/request/CampaignUserDto.java                |   27 
 src/main/java/com/common/annotation/DesensitiveInfo.java                      |   29 
 src/main/java/com/deloitte/system/controller/OpportunityController.java       |   96 
 src/main/resources/stg/application.yml                                        |    1 
 doc/modify.sql                                                                |  288 
 src/main/java/com/common/security/configure/RoleBasedVoter.java               |  100 
 src/main/java/com/deloitte/system/service/SwoService.java                     |  150 
 src/main/java/com/common/core/utils/TemplateUtils.groovy                      |   48 
 src/main/java/com/common/core/domain/DesensitiveType.java                     |  111 
 src/main/java/com/common/core/utils/IdUtils.java                              |  202 
 src/main/resources/prod2/application.yml                                      |    1 
 src/main/java/com/common/core/domain/EntityModel.java                         |  205 
 src/main/java/com/common/security/configure/RestAuthenticationEntryPoint.java |   36 
 src/main/java/com/common/servlet/JFinalStatViewServlet.java                   |   96 
 src/main/java/com/common/core/utils/BeanHelper.java                           | 1076 +++
 src/main/java/com/common/configure/FilterConfig.java                          |   59 
 src/main/java/com/common/core/enums/ResultCodeEnum.java                       |  147 
 src/main/java/com/common/core/utils/JwtTokenUtil.java                         |  167 
 src/main/java/com/deloitte/system/request/LoanerUserDto.java                  |   24 
 src/main/java/com/deloitte/system/service/RepairService.java                  |  132 
 src/main/java/com/common/aspect/RequestLimitAspect.java                       |   85 
 src/main/java/com/deloitte/system/request/ContactDto.java                     |   96 
 README.md                                                                     |    9 
 src/main/java/com/common/core/domain/BaseModel.java                           |  125 
 src/main/java/com/deloitte/system/job/MailSyncTask.java                       |   38 
 src/main/java/com/deloitte/system/service/OrderService.java                   |  218 
 src/main/java/com/common/annotation/DesensitiveApi.java                       |   17 
 src/main/java/com/common/aspect/LogAspect.java                                |  113 
 src/main/java/com/common/aspect/ResponseHeaderAspect.java                     |   47 
 src/main/java/com/common/security/configure/SecurityConfig.java               |  128 
 src/main/java/com/common/core/enums/TableNameEnum.java                        |   71 
 src/main/java/com/deloitte/system/model/Swo.java                              |  119 
 src/main/java/com/deloitte/system/request/OrderDto.java                       |  143 
 src/main/java/com/deloitte/system/service/MailMergeService.java               |  153 
 src/main/java/com/common/aws/util/S3Util.java                                 |  137 
 src/main/java/com/common/configure/TableScannerRegistrar.java                 |   54 
 src/main/java/com/common/aspect/SignatureAspect.java                          |   81 
 src/main/java/com/deloitte/system/service/TSRepairService.java                |  130 
 src/main/java/com/deloitte/system/controller/MailMergeController.java         |   77 
 src/main/resources/prod1/logback.xml                                          |   66 
 .gitignore                                                                    |   39 
 src/main/java/com/common/core/utils/SignUtil.java                             |   73 
 src/main/java/com/deloitte/sbg/controller/SfSBGRest.groovy                    |  182 
 src/main/java/com/deloitte/system/request/ContactSearchDto.java               |   16 
 src/main/java/com/common/aspect/TokenAspect.java                              |   57 
 src/main/resources/prod2/logback.xml                                          |   66 
 src/main/java/com/common/security/configure/RestfulAccessDeniedHandler.java   |   35 
 src/main/java/com/deloitte/system/request/MessageVo.java                      |   28 
 src/main/java/com/common/core/utils/JsonUtils.java                            |   75 
 src/main/java/com/common/configure/ThreadPoolTaskConfig.java                  |   49 
 src/main/java/com/deloitte/system/model/Account.java                          |   55 
 src/main/java/com/deloitte/system/service/LoanerApplicationService.java       |  149 
 src/main/java/com/deloitte/system/model/SysLog.java                           |   29 
 src/main/java/com/common/core/utils/BASE64DecodedMultipartFile.java           |   86 
 src/main/java/com/common/core/enums/YesNoEnum.java                            |   39 
 src/main/java/com/deloitte/system/request/MailMergeDto.java                   |  102 
 src/main/java/com/common/redis/util/RedisUtil.java                            |  283 
 src/main/java/com/common/security/utils/IpUtil.java                           |   48 
 src/main/java/com/common/core/service/BaseCryptoService.java                  |   83 
 src/main/java/com/common/core/utils/ThreadUtils.java                          |   18 
 src/main/java/com/common/core/exception/BizException.java                     |   36 
 src/main/java/com/common/core/utils/DistributedLock.java                      |   36 
 src/main/java/com/common/core/utils/ModelUtils.java                           |  120 
 src/main/java/com/common/core/utils/SpringContextUtils.java                   |   83 
 src/main/java/com/common/sign/BufferedHttpServletRequest.java                 |   86 
 src/main/java/com/deloitte/system/model/MailMerge.java                        |  340 +
 src/main/java/com/deloitte/system/controller/LoanerApplicationController.java |   77 
 src/main/java/com/deloitte/system/controller/FileController.java              |  103 
 src/main/java/com/deloitte/system/request/FileRequest.java                    |   22 
 src/main/java/com/deloitte/system/controller/SwoController.java               |   75 
 src/main/resources/dev/application.yml                                        |    1 
 src/main/java/com/common/core/utils/SM4Utils.java                             |   53 
 src/main/java/com/deloitte/system/model/Order.java                            |  402 +
 src/main/java/com/deloitte/system/request/OpportunityDto.java                 |   44 
 src/main/java/com/deloitte/system/service/ContactService.java                 |  268 
 src/main/resources/dev/logback.xml                                            |   66 
 src/main/resources/sqls/theme.sql                                             |    5 
 src/main/java/com/common/redis/util/RedisLockUtil.java                        |  182 
 src/main/java/com/common/core/beans/BaseResult.java                           |   48 
 src/main/java/com/deloitte/system/request/SfCompositeRequest.java             |   57 
 182 files changed, 19,019 insertions(+), 2 deletions(-)

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..10073e1
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,39 @@
+# Build output
+target/
+*.class
+
+# Log file
+*.log
+
+# BlueJ files
+*.ctxt
+
+# Mobile Tools for Java (J2ME)
+.mtj.tmp/
+
+# Package Files #
+*.jar
+*.war
+*.ear
+#*.zip
+*.tar.gz
+*.rar
+
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
+
+# IDE
+.idea/
+*.iml
+.settings/
+.project
+.classpath
+.vscode/
+
+# macOS
+.DS_Store
+
+# Azure Functions
+#local.settings.json
+bin/
+obj/
diff --git a/Encoded_content.json b/Encoded_content.json
new file mode 100644
index 0000000..a129f21
--- /dev/null
+++ b/Encoded_content.json
Binary files differ
diff --git a/README.md b/README.md
index d2cde80..8ca10b7 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,9 @@
-## SSBG_PIPL
+### 
 
-SSBG_PIPL_AWSCode
+s3
+rds
 
+ec2
+kms
+rsd
+redis
\ No newline at end of file
diff --git a/doc/modify.sql b/doc/modify.sql
new file mode 100644
index 0000000..a7b07e9
--- /dev/null
+++ b/doc/modify.sql
@@ -0,0 +1,288 @@
+CREATE TABLE `app_config` (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `appid` varchar(100) COLLATE utf8_bin DEFAULT NULL,
+  `appsecret` varchar(100) COLLATE utf8_bin DEFAULT NULL,
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin
+INSERT INTO app_config
+(id, app_id, app_secret, app_name)
+VALUES(1, '6LzizcRf7h8yLx28', '5033dcbfbc6509b91b7f51ecf8a4b3c13276d0297bf09e429ae3213ef9cff3280a4797ac47c8ce301aebd3a9c49fb6343a64fe7287c3e9e65ad8f8ab5ebaedef', 'SalesForce');
+INSERT INTO app_config
+(id, app_id, app_secret, app_name)
+VALUES(2, 'xLjAH3Bc8sKVzfZG', '4517b457fefc0c59437c2ece7fe1800e08a3c09dfbce876fe5bdd5fe64e2329cfd400e7fed2c5e258e10171a41cddd2d60dbeada9745d5be4717f088d9c50b77', 'SAP');
+INSERT INTO app_config
+(id, app_id, app_secret, app_name)
+VALUES(3, 'ovfbOZvxKqi0Hx6t', '1c24efb7c4253209101ef037ea605907301f8b332aefefbcea40c901c29d6e2680487309c3abc5121a363dafc5c59dd1ffc6d2da79715192d40483d0d3115af5', 'SPO');
+INSERT INTO app_config
+(id, app_id, app_secret, app_name)
+VALUES(4, 'hzS6VlraGh7tjXKo', 'e7325ca5b7b673a3e0e9ceabf72090d68605cf7cda3c0392202e584cb52965fd041416842f7ce1cc2ea35c1d2d17c0b25641361c9f52854b21bdc91c6d040935', '鍗冮噷椹�');
+INSERT INTO app_config
+(id, app_id, app_secret, app_name)
+VALUES(5, 'axkUARv7nzMqRzkO', 'b48833bc48592bdfecad68a75b275aab80b29b7af9aa5f553f8fb503e6edb3fd2f2682907be2549c1ad0c12314db4cbd368e0b61e2fd9a29e33012108527b7cb', '灏忕▼搴�');
+INSERT INTO app_config
+(id, app_id, app_secret, app_name)
+VALUES(6, '8LzKI9btg5eq3QiW', 'bb4e50bac195ae65833d1f8fdbefdb2ecbe32f483e6dfc9405d0bd4506b3e18df9d04a753495cb046418fcfe1d903341c85e4f06a4e2afe5943e9489bdc4fa60', '鍏遍�氬钩鍙�');
+INSERT INTO app_config
+(id, app_id, app_secret, app_name)
+VALUES(7, 'FlcS0v228lzsn9cN', '6522e3f835acfadbf8da05d01cfc9885ccfaef6b9c7ac189aa9747f7066610e33adef181378d11265fd2d19f46c2dac7ce1c5063fbc8768f274147929806c95a', 'OBPM');
+
+CREATE TABLE `app_permission_config` (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `appid` varchar(45) COLLATE utf8_bin DEFAULT NULL,
+  `url` varchar(45) COLLATE utf8_bin DEFAULT NULL,
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin
+
+
+CREATE TABLE `sys_log` (
+  `id` int NOT NULL AUTO_INCREMENT,
+  `ret_content` tinytext COLLATE utf8_bin,
+  `ip` varchar(45) COLLATE utf8_bin DEFAULT NULL,
+  `is_delete` int DEFAULT NULL,
+  `create_time` datetime DEFAULT NULL,
+  `update_time` datetime DEFAULT NULL,
+  `uri` varchar(45) COLLATE utf8_bin DEFAULT NULL,
+  `create_by` varchar(100) COLLATE utf8_bin DEFAULT NULL,
+  `update_by` varchar(100) COLLATE utf8_bin DEFAULT NULL,
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=81 DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin
+
+CREATE TABLE `lead` (
+                        `id` bigint(20) NOT NULL,
+                        `last_name` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                        `phone` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                        `email` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                        `create_by` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                        `create_time` datetime DEFAULT NULL,
+                        `update_by` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                        `update_time` datetime DEFAULT NULL,
+                        `is_delete` int(3) DEFAULT NULL,
+                        `sf_record_id` varchar(255) DEFAULT NULL,
+                        PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
+
+CREATE TABLE `contact` (
+                           `id` bigint(20) NOT NULL,
+                           `last_name` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                           `phone` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                           `email` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                           `create_by` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                           `create_time` datetime DEFAULT NULL,
+                           `update_by` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                           `update_time` datetime DEFAULT NULL,
+                           `is_delete` int(3) DEFAULT NULL,
+                           `sf_record_id` varchar(255) DEFAULT NULL,
+                           PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+-- pipl.consum_apply definition
+
+CREATE TABLE `consum_apply` (
+                                `id` bigint NOT NULL,
+                                `phone_number` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
+                                `direct_shippment_address` varchar(500) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
+                                `create_by` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
+                                `create_time` datetime DEFAULT NULL,
+                                `update_by` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
+                                `update_time` datetime DEFAULT NULL,
+                                `is_delete` int DEFAULT NULL,
+                                `sf_record_id` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                                PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
+CREATE TABLE pipl.`consum_apply_equipment_set_detail` (
+                                                          `id` bigint(20) NOT NULL,
+                                                          `trial_user` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                                                          `create_by` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                                                          `create_time` datetime DEFAULT NULL,
+                                                          `update_by` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                                                          `update_time` datetime DEFAULT NULL,
+                                                          `is_delete` int(3) DEFAULT NULL,
+                                                          `sf_record_id` varchar(255) DEFAULT NULL,
+                                                          PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
+CREATE TABLE pipl.`repair` (
+                                                          `id` bigint(20) NOT NULL,
+                                                          `address_contacts` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                                                          `address_telephone` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                                                          `detailed_address` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                                                          `address_contacts_name` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                                                          `repair_applicant` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                                                          `address_zip_code` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                                                          `create_by` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                                                          `create_time` datetime DEFAULT NULL,
+                                                          `update_by` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                                                          `update_time` datetime DEFAULT NULL,
+                                                          `is_delete` int(3) DEFAULT NULL,
+                                                          `sf_record_id` varchar(255) DEFAULT NULL,
+                                                          PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
+alter table contact add column title varchar(255);
+alter table contact add column oly_assistant_type varchar(255);
+alter table contact add column job_category_picklist varchar(255);
+alter table contact add column contact_address varchar(255);
+alter table contact add column type varchar(255);
+alter table contact add column doctor_division1 varchar(255);
+alter table contact add column contact_type varchar(255);
+alter table contact add column medical_staff_full_name varchar(255);
+alter table contact add column mobile_phone varchar(255);
+alter table contact add column unique_number varchar(255);
+
+CREATE TABLE `aseactivity` (
+                               `id` bigint(20) NOT NULL,
+                               `visit_staff` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                               `reporter_ase` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                               `create_by` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                               `create_time` datetime DEFAULT NULL,
+                               `update_by` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                               `update_time` datetime DEFAULT NULL,
+                               `is_delete` int(3) DEFAULT NULL,
+                               `sf_record_id` varchar(255) DEFAULT NULL,
+                               PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
+CREATE TABLE `address` (
+                           `id` bigint(20) NOT NULL,
+                           `telephone` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                           `zip_code` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                           `detailed_address` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                           `create_by` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                           `create_time` datetime DEFAULT NULL,
+                           `update_by` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                           `update_time` datetime DEFAULT NULL,
+                           `is_delete` int(3) DEFAULT NULL,
+                           `sf_record_id` varchar(255) DEFAULT NULL,
+                           PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
+CREATE TABLE `campaign_member` (
+                                   `id` bigint(20) NOT NULL,
+                                   `contact` bigint(20) COLLATE utf8_bin DEFAULT NULL,
+                                   `create_by` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                                   `create_time` datetime DEFAULT NULL,
+                                   `update_by` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                                   `update_time` datetime DEFAULT NULL,
+                                   `is_delete` int(3) DEFAULT NULL,
+                                   `sf_record_id` varchar(255) DEFAULT NULL,
+                                   PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
+alter table campaign_member modify column contact varchar(255) COLLATE utf8_bin DEFAULT NULL;
+
+
+CREATE TABLE `report`  (
+  `id` bigint(20) NOT NULL,
+  `voc_informer_name` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+  `caller_phone` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+  `voc_informer_contact` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+  `person_in_charge_text` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+  `professor_sigh_text` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+  `staff_info_manual` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+  `responsible_person_HP` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+  `practitioner1_part` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+  `practitioner2_part` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+  `practitioner3_part` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+  `practitioner4_part` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+  `practitioner5_part` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+  `age` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+  `medical_history` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+  `sex` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+  `create_by` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+  `create_time` datetime DEFAULT NULL,
+  `update_by` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+  `update_time` datetime DEFAULT NULL,
+  `is_delete` int(3) DEFAULT NULL,
+  `sf_record_id` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
+
+
+CREATE TABLE pipl.`inquiry_form` (
+   `id` bigint(20) NOT NULL,
+   `phone` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+	 `email` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+   `create_by` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+   `create_time` datetime DEFAULT NULL,
+   `update_by` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+   `update_time` datetime DEFAULT NULL,
+   `is_delete` int(3) DEFAULT NULL,
+   `sf_record_id` varchar(255) DEFAULT NULL,
+   PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
+
+CREATE TABLE `agency_contact` (
+                                   `id` bigint(20) NOT NULL,
+                                   `name` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                                   `doctor_division1` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                                   `type` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                                   `create_by` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                                   `create_time` datetime DEFAULT NULL,
+                                   `update_by` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                                   `update_time` datetime DEFAULT NULL,
+                                   `is_delete` int(3) DEFAULT NULL,
+                                   `sf_record_id` varchar(255) DEFAULT NULL,
+                                   PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
+
+CREATE TABLE `qis_report` (
+                                  `id` bigint(20) NOT NULL,
+                                  `caller_phone` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                                  `responsible_person_h_p` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                                  `create_by` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                                  `create_time` datetime DEFAULT NULL,
+                                  `update_by` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                                  `update_time` datetime DEFAULT NULL,
+                                  `is_delete` int(3) DEFAULT NULL,
+                                  `sf_record_id` varchar(255) DEFAULT NULL,
+                                  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
+
+CREATE TABLE `sample_order_list` (
+   `id` bigint(20) NOT NULL,
+   `delivery_address` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+	 `delivery_contact` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+	 `delivery_phone` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+   `create_by` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+   `create_time` datetime DEFAULT NULL,
+   `update_by` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+   `update_time` datetime DEFAULT NULL,
+   `is_delete` int(3) DEFAULT NULL,
+   `sf_record_id` varchar(255) DEFAULT NULL,
+   PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
+CREATE TABLE `tender_information` (
+                                      `id` bigint(20) NOT NULL,
+                                      `zhao_relation_name` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                                      `zhao_relation_way` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                                      `zhong_relation_name` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                                      `zhong_relation_way` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                                      `agent_relation_name` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                                      `agent_relation_way` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                                      `create_by` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                                      `create_time` datetime DEFAULT NULL,
+                                      `update_by` varchar(255) COLLATE utf8_bin DEFAULT NULL,
+                                      `update_time` datetime DEFAULT NULL,
+                                      `is_delete` int(3) DEFAULT NULL,
+                                      `sf_record_id` varchar(255) DEFAULT NULL,
+                                      PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
+
+ALTER TABLE ase_activity ADD CustomerTel varchar(100) NULL;
+ALTER TABLE ase_activity ADD WorkPlace varchar(100) NULL;
+
+CREATE TABLE `campaign_user` (  `id` bigint NOT NULL,  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,  `email` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,  `phone` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,  `create_by` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,  `create_time` datetime DEFAULT NULL,  `update_by` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,  `update_time` datetime DEFAULT NULL,  `is_delete` int DEFAULT NULL,  `sf_record_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,  PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC
+
+INSERT INTO app_permission_config(id, app_id, url)VALUES(180, 'M2os1A1gC8GH4S9v', '/ssbgapi/campaignuser/query');
+INSERT INTO app_permission_config(id, app_id, url)VALUES(181, 'M2os1A1gC8GH4S9v', '/ssbgapi/campaignuser/insert');
+INSERT INTO app_permission_config(id, app_id, url)VALUES(182, 'M2os1A1gC8GH4S9v', '/ssbgapi/campaignuser/update');
+INSERT INTO app_permission_config(id, app_id, url)VALUES(183, 'M2os1A1gC8GH4S9v', '/ssbgapi/campaignuser/delete');
+INSERT INTO app_permission_config(id, app_id, url)VALUES(184, 'M2os1A1gC8GH4S9v', '/ssbgapi/campaignuser/undelete');
+INSERT INTO app_permission_config(id, app_id, url)VALUES(185, 'M2os1A1gC8GH4S9v', '/ssbgapi/campaignuser/search');
+INSERT INTO app_permission_config(id, app_id, url)VALUES(186, 'M2os1A1gC8GH4S9v', '/ssbgapi/campaignuser/batchupload');
diff --git a/encrypted_data_key.txt b/encrypted_data_key.txt
new file mode 100644
index 0000000..a9e1672
--- /dev/null
+++ b/encrypted_data_key.txt
Binary files differ
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..30b0a5e
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,396 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>com.deloitte.system</groupId>
+    <artifactId>Arch</artifactId>
+    <version>1.0-SNAPSHOT</version>
+    <packaging>jar</packaging>
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>2.7.0</version>
+    </parent>
+    <properties>
+        <kryo.version>4.0.2</kryo.version>
+        <netty.version>4.1.77.Final</netty.version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-text</artifactId>
+            <version>1.9</version>
+        </dependency>
+        <dependency>
+            <groupId>org.hibernate.validator</groupId>
+            <artifactId>hibernate-validator</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>redis.clients</groupId>
+            <artifactId>jedis</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.esotericsoftware</groupId>
+            <artifactId>kryo-shaded</artifactId>
+            <version>${kryo.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.redisson</groupId>
+            <artifactId>redisson</artifactId>
+            <version>3.17.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>commons-lang</groupId>
+            <artifactId>commons-lang</artifactId>
+            <version>2.6</version>
+        </dependency>
+        <!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
+        <dependency>
+            <groupId>commons-codec</groupId>
+            <artifactId>commons-codec</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>5.8.2</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.bouncycastle</groupId>
+            <artifactId>bcpkix-jdk15on</artifactId>
+            <version>1.70</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.github.ulisesbocchio</groupId>
+            <artifactId>jasypt-spring-boot-starter</artifactId>
+            <version>3.0.4</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-configuration-processor</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-jdbc</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-jpa</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-log4j12</artifactId>
+        </dependency>
+        <!-- IMPORTANT log4j鍗囩骇-->
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-to-slf4j</artifactId>
+        </dependency>
+        <!-- IMPORTANT log4j鍗囩骇-->
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <optional>true</optional>
+        </dependency>
+
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>2.0.3</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.codehaus.groovy</groupId>
+            <artifactId>groovy-all</artifactId>
+            <version>2.6.0-alpha-2</version>
+        </dependency>
+
+        <dependency>
+            <groupId>javax.validation</groupId>
+            <artifactId>validation-api</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>joda-time</groupId>
+            <artifactId>joda-time</artifactId>
+            <version>2.10.14</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>2.11.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-security</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>eu.bitwalker</groupId>
+            <artifactId>UserAgentUtils</artifactId>
+            <version>1.21</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+            <version>31.1-jre</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpcore</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>druid</artifactId>
+            <version>1.2.9</version>
+        </dependency>
+
+        <dependency>
+            <groupId>io.jsonwebtoken</groupId>
+            <artifactId>jjwt</artifactId>
+            <version>0.9.1</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.jfinal</groupId>
+            <artifactId>activerecord</artifactId>
+            <version>5.0.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>cglib</groupId>
+            <artifactId>cglib-nodep</artifactId>
+            <version>3.3.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.aspectj</groupId>
+            <artifactId>aspectjweaver</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>software.amazon.awssdk</groupId>
+            <artifactId>auth</artifactId>
+            <version>2.17.191</version>
+        </dependency>
+        <dependency>
+            <groupId>software.amazon.awssdk</groupId>
+            <artifactId>aws-core</artifactId>
+            <version>2.17.191</version>
+        </dependency>
+        <dependency>
+            <groupId>software.amazon.awssdk</groupId>
+            <artifactId>s3</artifactId>
+            <version>2.17.191</version>
+        </dependency>
+        <dependency>
+            <groupId>software.amazon.awssdk</groupId>
+            <artifactId>ses</artifactId>
+            <version>2.17.191</version>
+        </dependency>
+        <dependency>
+            <groupId>software.amazon.awssdk</groupId>
+            <artifactId>secretsmanager</artifactId>
+            <version>2.17.191</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-mail</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.squareup.okhttp3</groupId>
+            <artifactId>okhttp</artifactId>
+        </dependency>
+
+        <!--Swagger-UI API鏂囨。鐢熶骇宸ュ叿-->
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-swagger2</artifactId>
+            <version>2.9.2</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.github.xiaoymin</groupId>
+            <artifactId>swagger-bootstrap-ui</artifactId>
+            <version>1.9.6</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.j256.simplemagic</groupId>
+            <artifactId>simplemagic</artifactId>
+            <version>1.17</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.opencsv</groupId>
+            <artifactId>opencsv</artifactId>
+            <version>5.6</version>
+        </dependency>
+
+    </dependencies>
+
+    <build>
+        <resources>
+            <resource>
+                <directory>src/main/resources/${env}</directory>
+                <filtering>true</filtering>
+            </resource>
+            <resource>
+                <directory>src/main/resources</directory>
+                <filtering>true</filtering>
+                <excludes>
+                    <exclude>dev/*</exclude>
+                    <exclude>local/*</exclude>
+                    <exclude>stg/*</exclude>
+                    <exclude>prod1/*</exclude>
+                    <exclude>prod2/*</exclude>
+                </excludes>
+            </resource>
+        </resources>
+        <plugins>
+            <plugin>
+                <groupId>org.owasp</groupId>
+                <artifactId>dependency-check-maven</artifactId>
+                <version>7.1.0</version>
+                <configuration>
+                    <autoUpdate>true</autoUpdate>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>check</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.gmavenplus</groupId>
+                <artifactId>gmavenplus-plugin</artifactId>
+                <version>1.5</version>
+                <executions>
+                    <execution>
+                        <id>groovy-compile</id>
+                        <goals>
+                            <goal>addSources</goal>
+                            <goal>addTestSources</goal>
+                            <goal>generateStubs</goal>
+                            <goal>compile</goal>
+                            <goal>testGenerateStubs</goal>
+                            <goal>testCompile</goal>
+                            <goal>removeStubs</goal>
+                            <goal>removeTestStubs</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <sources>
+                        <!-- 鍦ㄦ鑺傜偣涓嬮厤缃簮鐮佺洰褰�,鍙厤缃涓� -->
+                        <source>
+                            <directory>${project.basedir}/src/main/java</directory>
+                            <includes>
+                                <include>**/*.groovy</include>
+                            </includes>
+                        </source>
+                        <source>
+                            <directory>${project.basedir}/src/main/groovy</directory>
+                            <includes>
+                                <include>**/*.groovy</include>
+                            </includes>
+                        </source>
+                    </sources>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <profiles>
+        <profile>
+            <id>dev</id>
+            <properties>
+                <env>dev</env>
+            </properties>
+        </profile>
+        <profile>
+            <id>stg</id>
+            <properties>
+                <env>stg</env>
+            </properties>
+        </profile>
+        <profile>
+            <id>prod1</id>
+            <properties>
+                <env>prod1</env>
+            </properties>
+        </profile>
+        <profile>
+            <id>prod2</id>
+            <properties>
+                <env>prod2</env>
+            </properties>
+        </profile>
+        <profile>
+            <id>local</id>
+            <properties>
+                <env>local</env>
+            </properties>
+            <activation>
+                <activeByDefault>true</activeByDefault>
+            </activation>
+        </profile>
+    </profiles>
+</project>
\ No newline at end of file
diff --git a/src/main/java/com/Application.java b/src/main/java/com/Application.java
new file mode 100644
index 0000000..faa22a0
--- /dev/null
+++ b/src/main/java/com/Application.java
@@ -0,0 +1,239 @@
+package com;
+
+import com.alibaba.druid.filter.stat.StatFilter;
+import com.alibaba.druid.util.JdbcConstants;
+import com.alibaba.druid.wall.WallFilter;
+import com.alibaba.fastjson.JSONObject;
+import com.common.annotation.JfinalModelScan;
+import com.common.annotation.Table;
+import com.common.component.DruidPlugin;
+import com.common.component.RedisCache;
+import com.common.configure.JfinalProperties;
+import com.common.core.utils.KitClassUtils;
+import com.common.core.utils.SecretsManagerUtils;
+import com.common.core.utils.SpringContextUtils;
+import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
+import com.jfinal.plugin.activerecord.CaseInsensitiveContainerFactory;
+import com.jfinal.plugin.activerecord.IContainerFactory;
+import com.jfinal.plugin.activerecord.cache.ICache;
+import com.jfinal.plugin.activerecord.dialect.*;
+import com.jfinal.template.source.StringSource;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.boot.jdbc.DatabaseDriver;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.env.Environment;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+import org.springframework.core.io.support.ResourcePatternResolver;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.util.ObjectUtils;
+import org.springframework.util.ReflectionUtils;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.reflect.Method;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.*;
+
+
+/**
+ * @author 寤栨尟閽�
+ * @Date 2022-01-11 10:24
+ * */
+
+@Slf4j
+@Configuration
+@SpringBootApplication(exclude ={DataSourceAutoConfiguration.class} )
+@JfinalModelScan(basePackages = {"com.deloitte"})
+@EnableAsync
+@EnableScheduling // 寮�鍚畾鏃朵换鍔″姛鑳�
+public class Application {
+
+    public static void main(String[] args) {
+        SpringApplication.run(Application.class, args);
+        log.info("(鈾モ棤鈥库棤)锞夛緸  绯荤粺鍚姩鎴愬姛   醿�(麓凇`醿�)锞�  \n");
+        log.info("swagger鏂囨。鍦板潃  http://"+getHost()+":"+SpringContextUtils.getEnvParam("server.port")+SpringContextUtils.getEnvParam("server.servlet.context-path")+"/doc.html");
+    }
+
+    public static String getHost(){
+        try {
+            InetAddress addr = InetAddress.getLocalHost();
+            return addr.getHostAddress();
+        } catch (UnknownHostException e) {
+            log.error("鍚姩澶辫触",e);
+        }
+        return "";
+    }
+
+
+    private Map<DatabaseDriver, Dialect> dialectMap = new HashMap<>();
+
+    @Autowired
+    private Environment env;
+
+    @Autowired
+    private JfinalProperties jfinalProperties;
+
+    @Autowired
+    private SecretsManagerUtils secretsManagerUtils;
+
+    @Bean
+    public DruidPlugin getDruidPlugin(){
+        System.setProperty("druid.mysql.usePingMethod", "false");
+        JSONObject object = secretsManagerUtils.getSecret(env.getProperty("aws.secrets.mysql"));
+        String port = object.getString("port");
+        String host = object.getString("host");
+        String dbname = object.getString("dbname");
+        String username = object.getString("username");
+        String password = object.getString("password");
+        String url = "jdbc:mysql://" + host + ":" + port + "/" + dbname + "?characterEncoding=utf8&useSSL=true&zeroDateTimeBehavior=convertToNull&tinyInt1isBit=false&useUnicode=true&serverTimezone=Asia/Shanghai";
+        DruidPlugin dbPlugin=new DruidPlugin(url , username, password);
+        // 閰嶇疆闃茬伀澧欏姞寮烘暟鎹簱瀹夊叏
+        WallFilter wallFilter = new WallFilter();
+        wallFilter.setDbType(JdbcConstants.MYSQL);
+        dbPlugin.addFilter(wallFilter);
+
+        //閰嶇疆鐩戞帶
+        StatFilter statFilter=new StatFilter();
+        statFilter.setMergeSql(true);
+        statFilter.setLogSlowSql(true);
+        statFilter.setSlowSqlMillis(1500);
+
+        // 娣诲姞 StatFilter 鎵嶄細鏈夌粺璁℃暟鎹�
+        dbPlugin.addFilter(statFilter);
+        dbPlugin.start();
+        return dbPlugin;
+    }
+
+    @Bean
+    @ConditionalOnMissingBean(ICache.class)
+    @ConditionalOnClass(name = "org.springframework.cache.CacheManager")
+    public ICache cache() {
+        return SpringContextUtils.getBean(RedisCache.class);
+    }
+
+    @Bean
+    @ConditionalOnMissingBean(IContainerFactory.class)
+    public IContainerFactory containerFactory() {
+        // 涓嶅尯鍒嗗ぇ灏忓啓 浣嗘槸鏈�鍚庡瓧娈靛悕缁熶竴灏忓啓
+        return new CaseInsensitiveContainerFactory(true);
+    }
+
+    @Bean
+    public ActiveRecordPlugin activeRecordPlugin(ICache cache,
+                                                 DruidPlugin dataSource,
+                                      IContainerFactory containerFactory) {
+        dialectMap.put(DatabaseDriver.MYSQL, new MysqlDialect());
+        dialectMap.put(DatabaseDriver.ORACLE, new OracleDialect());
+        dialectMap.put(DatabaseDriver.SQLSERVER, new SqlServerDialect());
+        dialectMap.put(DatabaseDriver.SQLITE, new Sqlite3Dialect());
+        dialectMap.put(DatabaseDriver.POSTGRESQL, new PostgreSqlDialect());
+        ActiveRecordPlugin activeRecordPlugin = new ActiveRecordPlugin(dataSource);
+        activeRecordPlugin.setCache(cache);
+        try {
+            DatabaseDriver databaseDriver = DatabaseDriver.fromJdbcUrl(dataSource.getDataSource().getConnection().getMetaData().getURL());
+            Dialect dialect;
+            if (!ObjectUtils.isEmpty(jfinalProperties.getDialect())) {
+                dialect = jfinalProperties.getDialect().newInstance();
+            } else {
+                dialect = dialectMap.get(databaseDriver);
+            }
+            if (ObjectUtils.isEmpty(dialect)) {
+                throw new IllegalArgumentException("dialect not be found!");
+            }
+            activeRecordPlugin.setDialect(dialect);
+        } catch (Exception e) {
+            log.error("鍚姩澶辫触",e);
+        }
+        if (!ObjectUtils.isEmpty(jfinalProperties.getShowSql())) {
+            activeRecordPlugin.setShowSql(jfinalProperties.getShowSql());
+        }
+        if (!ObjectUtils.isEmpty(jfinalProperties.getDevMode())) {
+            activeRecordPlugin.setDevMode(jfinalProperties.getDevMode());
+        }
+        if (!ObjectUtils.isEmpty(jfinalProperties.getTransactionLevel())) {
+            activeRecordPlugin.setTransactionLevel(jfinalProperties.getTransactionLevel());
+        }
+        activeRecordPlugin.setContainerFactory(containerFactory);
+        getSqlTemplates(activeRecordPlugin, jfinalProperties.getSqlTemplates());
+        getMappingKet(activeRecordPlugin, jfinalProperties.getKitClasses());
+        autoMappingTable(activeRecordPlugin);
+        activeRecordPlugin.start();
+        return activeRecordPlugin;
+    }
+
+    private void autoMappingTable(ActiveRecordPlugin activeRecordPlugin){
+        KitClassUtils.tableclass.forEach(clazz->{
+            Table table = (Table)clazz.getAnnotation(Table.class);
+            activeRecordPlugin.addMapping(table.tableName(), table.primaryKey(), table.clazz());
+        });
+    }
+
+    private void getSqlTemplates(ActiveRecordPlugin arp, List<String> sqlTemplates) {
+        ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
+        List<Resource> resources = new ArrayList<Resource>();
+        if (!ObjectUtils.isEmpty(sqlTemplates)) {
+            sqlTemplates.forEach(sqlTemplate -> {
+                if (sqlTemplate != null) {
+                    try {
+                        Resource[] templates = resourceResolver.getResources(sqlTemplate);
+                        resources.addAll(Arrays.asList(templates));
+                    } catch (IOException e) {
+                        log.warn("{} path not found in classpath", sqlTemplate);
+                    }
+                    resources.forEach(resource -> {
+                        StringBuilder content = null;
+                        try {
+                            content = getContentByStream(resource.getInputStream());
+                            arp.addSqlTemplate(new StringSource(content, true));
+                        } catch (IOException e) {
+                            log.error("鍚姩澶辫触",e);
+                        }
+                    });
+                }
+            });
+        }
+    }
+
+    private void getMappingKet(ActiveRecordPlugin activeRecordPlugin, List<String> kitClasses) {
+        if (!ObjectUtils.isEmpty(kitClasses)) {
+            kitClasses.forEach(kitClass -> {
+                try {
+                    Class<?> mappingKitClass = Class.forName(kitClass);
+                    Object mappingKit = mappingKitClass.newInstance();
+                    Method mappingMethod = ReflectionUtils.findMethod(mappingKitClass, "mapping",
+                            activeRecordPlugin.getClass());
+                    ReflectionUtils.invokeMethod(mappingMethod, mappingKit, activeRecordPlugin);
+                } catch (Exception e) {
+                    log.warn("{} not found in classpath", kitClass);
+                }
+            });
+        }
+    }
+
+    private StringBuilder getContentByStream(InputStream inputStream) {
+        StringBuilder stringBuilder = new StringBuilder();
+        try {
+            BufferedReader br = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
+            String line;
+            while ((line = br.readLine()) != null) {
+                stringBuilder.append(line);
+            }
+        } catch (Exception e) {
+            log.error("鍚姩澶辫触",e);
+        }
+        return stringBuilder;
+    }
+
+}
diff --git a/src/main/java/com/common/annotation/DesensitiveApi.java b/src/main/java/com/common/annotation/DesensitiveApi.java
new file mode 100644
index 0000000..2af2237
--- /dev/null
+++ b/src/main/java/com/common/annotation/DesensitiveApi.java
@@ -0,0 +1,17 @@
+package com.common.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * @description: 鑴辨晱鎺ュ彛娉ㄨВ
+ * @author: holden
+ * @time: 2022-01-20 09:50
+ */
+@Target({ElementType.METHOD,ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface DesensitiveApi {
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/common/annotation/DesensitiveInfo.java b/src/main/java/com/common/annotation/DesensitiveInfo.java
new file mode 100644
index 0000000..152cadd
--- /dev/null
+++ b/src/main/java/com/common/annotation/DesensitiveInfo.java
@@ -0,0 +1,29 @@
+package com.common.annotation;
+
+
+import com.common.core.domain.DesensitiveType;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * @description: 鑴辨晱瀛楁娉ㄨВ
+ * @author: holden
+ * @time: 2022-01-20 11:46
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface DesensitiveInfo {
+
+    DesensitiveType value() default DesensitiveType.BASIC;
+
+    String separator() default "";
+
+    String padStr() default "*";
+
+    int retainLeft() default -1;
+    int retainRight() default  -1;
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/common/annotation/JfinalModelScan.java b/src/main/java/com/common/annotation/JfinalModelScan.java
new file mode 100644
index 0000000..eca0bee
--- /dev/null
+++ b/src/main/java/com/common/annotation/JfinalModelScan.java
@@ -0,0 +1,20 @@
+package com.common.annotation;
+
+import com.common.configure.TableScannerRegistrar;
+import org.springframework.context.annotation.Import;
+import java.lang.annotation.*;
+
+/**
+ * 瀹氫箟Model scan
+ * @author 寤栨尟閽�
+ * @date 2019-08-01
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+@Documented
+@Import(TableScannerRegistrar.class)
+public @interface JfinalModelScan {
+
+    String[] basePackages() default {};
+
+}
diff --git a/src/main/java/com/common/annotation/NoAuthorize.java b/src/main/java/com/common/annotation/NoAuthorize.java
new file mode 100644
index 0000000..65e41aa
--- /dev/null
+++ b/src/main/java/com/common/annotation/NoAuthorize.java
@@ -0,0 +1,10 @@
+package com.common.annotation;
+
+
+import java.lang.annotation.*;
+
+@Target({ElementType.PARAMETER, ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface NoAuthorize {
+}
diff --git a/src/main/java/com/common/annotation/NoEncryption.java b/src/main/java/com/common/annotation/NoEncryption.java
new file mode 100644
index 0000000..13f2f96
--- /dev/null
+++ b/src/main/java/com/common/annotation/NoEncryption.java
@@ -0,0 +1,10 @@
+package com.common.annotation;
+
+
+import java.lang.annotation.*;
+
+@Target({ElementType.PARAMETER, ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface NoEncryption {
+}
diff --git a/src/main/java/com/common/annotation/NoLog.java b/src/main/java/com/common/annotation/NoLog.java
new file mode 100644
index 0000000..5d22a46
--- /dev/null
+++ b/src/main/java/com/common/annotation/NoLog.java
@@ -0,0 +1,13 @@
+package com.common.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * @author 寤栨尟閽�
+ * @date 2022-02-18
+ * */
+@Target({ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface NoLog {
+}
diff --git a/src/main/java/com/common/annotation/NoToken.java b/src/main/java/com/common/annotation/NoToken.java
new file mode 100644
index 0000000..6842985
--- /dev/null
+++ b/src/main/java/com/common/annotation/NoToken.java
@@ -0,0 +1,13 @@
+package com.common.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * @author 寤栨尟閽�
+ * @date 2022-01-17
+ * */
+@Target({ElementType.PARAMETER, ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface NoToken {
+}
diff --git a/src/main/java/com/common/annotation/RequestLimit.java b/src/main/java/com/common/annotation/RequestLimit.java
new file mode 100644
index 0000000..0395933
--- /dev/null
+++ b/src/main/java/com/common/annotation/RequestLimit.java
@@ -0,0 +1,32 @@
+package com.common.annotation;
+
+import java.lang.annotation.*;
+
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+/**
+ * one minutes request frequency is Fifty times, exceeding the wait five minutes
+ * @author Administrator
+ *
+ */
+public @interface RequestLimit {
+    int DEFAULT_TIME= 60;//60绉�
+    int DEFAULT_COUNT= 1000;//1000娆�
+    int DEFAULT_SIZE= 5;//5M
+    /**
+     * 鏃堕棿鑼冨洿
+     * @return
+     */
+    int time() default DEFAULT_TIME;
+    /**
+     * 鏃堕棿鑼冨洿鍐呮鏁�
+     * @return
+     */
+    int count() default DEFAULT_COUNT;
+    /**
+     * 璇锋眰浣撳ぇ灏�
+     * @return
+     */
+    int size() default DEFAULT_SIZE;
+}
\ No newline at end of file
diff --git a/src/main/java/com/common/annotation/Sign.java b/src/main/java/com/common/annotation/Sign.java
new file mode 100644
index 0000000..05a2f2d
--- /dev/null
+++ b/src/main/java/com/common/annotation/Sign.java
@@ -0,0 +1,14 @@
+package com.common.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * @author 寤栨尟閽�
+ * @date 2022-01-17
+ */
+@Target({ElementType.PARAMETER, ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface Sign {
+
+}
diff --git a/src/main/java/com/common/annotation/Table.java b/src/main/java/com/common/annotation/Table.java
new file mode 100644
index 0000000..11dc90d
--- /dev/null
+++ b/src/main/java/com/common/annotation/Table.java
@@ -0,0 +1,24 @@
+package com.common.annotation;
+
+import com.common.core.domain.BaseModel;
+import com.jfinal.plugin.activerecord.Model;
+
+import java.lang.annotation.*;
+
+/**
+ * @author 寤栨尟閽�
+ * @date 2017-08-01
+ * */
+
+@Target({ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Inherited
+public @interface Table {
+
+    String tableName();
+
+    Class<? extends BaseModel<?>> clazz();
+
+    String primaryKey() default "id";
+}
diff --git a/src/main/java/com/common/aspect/CustomResponseAdvice.java b/src/main/java/com/common/aspect/CustomResponseAdvice.java
new file mode 100644
index 0000000..01ddaba
--- /dev/null
+++ b/src/main/java/com/common/aspect/CustomResponseAdvice.java
@@ -0,0 +1,70 @@
+package com.common.aspect;
+
+
+import com.common.core.beans.Result;
+import com.common.core.enums.ResultCodeEnum;
+import com.common.core.exception.BizException;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.http.HttpStatus;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.core.MethodParameter;
+import org.springframework.http.MediaType;
+import org.springframework.http.server.ServerHttpRequest;
+import org.springframework.http.server.ServerHttpResponse;
+import org.springframework.web.bind.MethodArgumentNotValidException;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * 鍏ㄥ眬寮傚父澶勭悊
+ */
+@RestControllerAdvice(basePackages = {
+        "com.deloitte.system.controller"})
+@Slf4j
+public class CustomResponseAdvice {
+
+    private Logger logger = LoggerFactory.getLogger(getClass());
+    //瀹氫箟涓嶅悓鐨勬柟娉曞鐞嗕笉鍚岀被鍨嬬殑寮傚父
+
+
+    @ExceptionHandler(Error.class)
+    public Result<Object> baseErrorHandler(HttpServletRequest request, HttpServletResponse response, Error e) {
+        log.error(e.getMessage(),e);
+        response.setStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR);
+        return Result.respErr(ResultCodeEnum.RT_ERROR);
+    }
+
+    @ExceptionHandler(OutOfMemoryError.class)
+    public Result<Object> baseErrorHandler(HttpServletRequest request, HttpServletResponse response, OutOfMemoryError e) {
+        log.error(e.getMessage(),e);
+        response.setStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR);
+        return Result.respErr(ResultCodeEnum.RT_ERROR);
+    }
+
+    @ExceptionHandler(Exception.class)
+    public Result<Object> errorHandler(HttpServletRequest request, HttpServletResponse response, Exception e) {
+        log.error(e.getMessage(),e);
+        response.setStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR);
+        return Result.respErr(ResultCodeEnum.RT_ERROR);
+    }
+
+    @ExceptionHandler({BizException.class})
+    @ResponseBody
+    public Result<String> handleBusinessException(HttpServletRequest request, HttpServletResponse response, BizException e){
+        log.error(e.getMessage(),e);
+        return Result.resp(e.getCode(), e.getMessage());
+    }
+
+    @ExceptionHandler({MethodArgumentNotValidException.class})
+    @ResponseBody
+    public Result<String> handleException(MethodArgumentNotValidException e){
+        log.error(e.getMessage(),e);
+        return Result.resp(ResultCodeEnum.RT_PARAM_ERROR);
+    }
+}
diff --git a/src/main/java/com/common/aspect/DesensitiveAspect.java b/src/main/java/com/common/aspect/DesensitiveAspect.java
new file mode 100644
index 0000000..2cd8fb5
--- /dev/null
+++ b/src/main/java/com/common/aspect/DesensitiveAspect.java
@@ -0,0 +1,32 @@
+package com.common.aspect;
+
+import com.common.core.utils.DesensitiveUtils;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.springframework.stereotype.Component;
+
+/**
+ * @description: 瀹氫箟鍒囬潰鏉ュ鐞嗘晱鎰熸暟鎹帴鍙�
+ * @author: duanyashu
+ * @time: 2021-03-10 14:16
+ */
+@Aspect
+@Component
+public class DesensitiveAspect {
+
+    @Pointcut("@annotation(com.common.annotation.DesensitiveApi) || @within(com.common.annotation.DesensitiveApi)")
+    public void operation(){}
+
+
+    @Around("operation()")
+    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
+        Object obj = joinPoint.proceed();
+        if (obj != null && !DesensitiveUtils.isPrimitive(obj.getClass())) {
+            //杩涜鑴辨晱澶勭悊
+            DesensitiveUtils.format(obj);
+        }
+        return  obj;
+    }
+}
diff --git a/src/main/java/com/common/aspect/LogAspect.java b/src/main/java/com/common/aspect/LogAspect.java
new file mode 100644
index 0000000..dee7b9e
--- /dev/null
+++ b/src/main/java/com/common/aspect/LogAspect.java
@@ -0,0 +1,113 @@
+package com.common.aspect;
+
+import cn.hutool.core.collection.CollectionUtil;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson.serializer.SerializeFilter;
+import com.alibaba.fastjson.serializer.SimplePropertyPreFilter;
+import com.alibaba.fastjson.serializer.ValueFilter;
+import com.common.security.utils.IpUtil;
+import com.deloitte.system.model.SysLog;
+import com.deloitte.system.request.FileRequest;
+import eu.bitwalker.useragentutils.UserAgent;
+import lombok.extern.slf4j.Slf4j;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.AfterReturning;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
+import org.aspectj.lang.annotation.Pointcut;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletRequest;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * @author 寤栨尟閽�
+ * @date 2022-01-14
+ */
+@Slf4j
+@Aspect
+@Component
+@Order(1)
+public class LogAspect {
+
+    @Pointcut("execution(* com..controller..*.*(..)) && (@annotation(org.springframework.web.bind.annotation.RequestMapping)" +
+            "|| @annotation(org.springframework.web.bind.annotation.GetMapping)" +
+            "|| @annotation(org.springframework.web.bind.annotation.PostMapping)" +
+            "|| @annotation(org.springframework.web.bind.annotation.DeleteMapping)" +
+            "|| @annotation(org.springframework.web.bind.annotation.PatchMapping))"+
+            "&& !@annotation(com.common.annotation.NoLog)")
+    public void controllerMethodPointcut() {
+    }
+
+    @Before("controllerMethodPointcut()")
+    public void doBefore(JoinPoint point) {
+        try {
+            handleLog(point);
+        } catch (Throwable e) {
+            log.error("LogAspect>>>>>>>>", e);
+            throw e;
+        }
+    }
+
+    protected void handleLog(JoinPoint point) {
+        HttpServletRequest request = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest();
+        String uri = request.getRequestURI();
+        UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("user-agent"));
+        String clientType = userAgent.getOperatingSystem().getDeviceType().toString();
+        log.info("clientType = " + clientType);   //瀹㈡埛绔被鍨�  鎵嬫満銆佺數鑴戙�佸钩鏉�
+        String os = userAgent.getOperatingSystem().getName();
+        log.info("os = " + os);    //鎿嶄綔绯荤粺绫诲瀷
+        String ip = IpUtil.getIpAddr(request);
+        log.info("ip = " + ip);    //璇锋眰ip
+        String browser = userAgent.getBrowser().toString();
+        log.info("browser = " + browser);    //娴忚鍣ㄧ被鍨�
+//        log.info(Thread.currentThread().getName()+",requestparam="+ JSONObject.toJSONString(point.getArgs()));
+        SysLog sysLog = new SysLog();
+        if(uri.endsWith("/file/upload")){
+            FileRequest param=(FileRequest)point.getArgs()[0];
+            JSONObject jsonObject=new JSONObject();
+            jsonObject.put("fileName",param.getFileName());
+            jsonObject.put("size",param.getSize());
+            sysLog.ip(ip).retContent("request:" + jsonObject).uri(uri);
+        }else if(uri.endsWith("/file/batchupload")){
+            List<FileRequest> param=(List<FileRequest>)point.getArgs()[0];
+            JSONArray jsonArray=new JSONArray();
+            if(CollectionUtil.isNotEmpty(param)) {
+                for (int i = 0; i < param.size(); i++) {
+                    JSONObject jsonObject = new JSONObject();
+                    jsonObject.put("fileName", param.get(i).getFileName());
+                    jsonObject.put("size", param.get(i).getSize());
+                    jsonArray.add(jsonObject);
+                }
+                sysLog.ip(ip).retContent("request:" + jsonArray).uri(uri);
+            }
+        }else{
+            SerializeFilter filter=new ValueFilter() {
+                @Override
+                public Object process(Object o, String s, Object o1) {
+                    if(o instanceof MultipartFile){
+                        return null;
+                    }
+                    if(o1 instanceof MultipartFile){
+                        return null;
+                    }
+                    return o1;
+                }
+            };
+
+            sysLog.ip(ip).retContent("request:" + JSONObject.toJSONString(point.getArgs(),filter)).uri(uri);
+        }
+        sysLog.save();
+    }
+}
diff --git a/src/main/java/com/common/aspect/LogReturnAspect.java b/src/main/java/com/common/aspect/LogReturnAspect.java
new file mode 100644
index 0000000..0dcb9fa
--- /dev/null
+++ b/src/main/java/com/common/aspect/LogReturnAspect.java
@@ -0,0 +1,55 @@
+package com.common.aspect;
+
+import com.alibaba.fastjson.JSONObject;
+import com.common.security.utils.IpUtil;
+import com.deloitte.system.model.SysLog;
+import eu.bitwalker.useragentutils.UserAgent;
+import lombok.extern.slf4j.Slf4j;
+import org.aspectj.lang.annotation.AfterReturning;
+import org.aspectj.lang.annotation.Aspect;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * @author 寤栨尟閽�
+ * @date 2022-02-17
+ * @company deloitte
+ */
+@Slf4j
+@Aspect
+@Component
+@Order(1)
+public class LogReturnAspect {
+
+    @AfterReturning(pointcut = "execution(* com..controller..*.*(..))" +
+            "&& (@annotation(org.springframework.web.bind.annotation.RequestMapping)" +
+            "|| @annotation(org.springframework.web.bind.annotation.GetMapping)" +
+            "|| @annotation(org.springframework.web.bind.annotation.PostMapping)" +
+            "|| @annotation(org.springframework.web.bind.annotation.DeleteMapping)" +
+            "|| @annotation(org.springframework.web.bind.annotation.PatchMapping))"+
+            "&& !@annotation(com.common.annotation.NoLog)", returning = "objectReturn")
+    public void doAfterCalssReturning(Object objectReturn) throws Throwable {
+        try {
+            handleLog(objectReturn);
+        } catch (Throwable e) {
+            log.error("LogReturnAspect>>>>>>>>", e);
+            throw e;
+        }
+    }
+
+    protected void handleLog(Object objectReturn) {
+        HttpServletRequest request = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest();
+        String uri = request.getRequestURI();
+        String ip = IpUtil.getIpAddr(request);
+//        log.info(Thread.currentThread().getName()+",returnContent=" + JSONObject.toJSONString(objectReturn));
+        SysLog sysLog = new SysLog();
+        if (null != objectReturn) {
+            sysLog.ip(ip).retContent("response:"+ JSONObject.toJSONString(objectReturn)).uri(uri);
+            sysLog.save();
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/common/aspect/RequestLimitAspect.java b/src/main/java/com/common/aspect/RequestLimitAspect.java
new file mode 100644
index 0000000..86d3552
--- /dev/null
+++ b/src/main/java/com/common/aspect/RequestLimitAspect.java
@@ -0,0 +1,85 @@
+package com.common.aspect;
+
+import com.common.annotation.RequestLimit;
+import com.common.core.enums.ResultCodeEnum;
+import com.common.core.exception.BizException;
+import com.common.core.utils.DateUtils;
+import com.common.redis.util.RedisUtil;
+import com.common.security.utils.IpUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import java.lang.reflect.Method;
+import java.security.SecureRandom;
+import java.util.Set;
+
+@Aspect
+@Component
+@Order(1)
+@Slf4j
+public class RequestLimitAspect {
+
+    @Autowired
+    private RedisUtil redisUtil;
+
+    private static final String REQ_LIMIT = "req_limit:%s:%s:";
+    private static final String REQ_LIMIT_FREQUENCY = "req_limit_frequency_%s_%s";
+
+    /**
+     * 瀹氫箟鎷︽埅瑙勫垯锛氭嫤鎴猚om.springboot.bcode.api鍖呬笅闈㈢殑鎵�鏈夌被涓紝鏈堾RequestLimit Annotation娉ㄨВ鐨勬柟娉�
+     * 銆�
+     */
+    @Pointcut("@within(org.springframework.web.bind.annotation.RestController) ")
+    public void pointcut() {
+    }
+
+    @Around("pointcut()")
+    public Object method(ProceedingJoinPoint joinPoint) throws Throwable {
+        Object[] args = joinPoint.getArgs();
+
+        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
+        Method method = signature.getMethod(); // 鑾峰彇琚嫤鎴殑鏂规硶
+        RequestLimit limt = method.getAnnotation(RequestLimit.class);
+        int time,count,size;
+        if (limt == null) {
+            time = RequestLimit.DEFAULT_TIME;
+            count = RequestLimit.DEFAULT_COUNT;
+            size = RequestLimit.DEFAULT_SIZE;
+        }else{
+            time = limt.time();
+            count = limt.count();
+            size = limt.size();
+        }
+        HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
+
+
+        String ip = IpUtil.getIpAddr(request);
+        String url = request.getRequestURI();
+
+        // judge condition
+        //澶у皬闄愬埗
+        if(request.getContentLength() > size*1024*1024){
+            throw new BizException(ResultCodeEnum.LARGE_REQUEST_ERROR);
+        }
+        //棰戞闄愬埗
+        String key = String.format(REQ_LIMIT, url, ip);
+        Set<String> valueList = redisUtil.getKeys(key + "*");
+        //灏嗘湁鏁堢殑杩囨护鍑烘潵锛岃繃鏈熸椂闂村湪褰撳墠鏃堕棿鍚庣殑
+        if (!CollectionUtils.isEmpty(valueList) && count>-1 && valueList.size() >= count) {
+            throw new BizException(ResultCodeEnum.BUSY_REQUEST_ERROR);
+        }
+        redisUtil.set(key+ new SecureRandom().nextLong(), DateUtils.now().getTime(),time);
+        return joinPoint.proceed();
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/common/aspect/ResponseHeaderAspect.java b/src/main/java/com/common/aspect/ResponseHeaderAspect.java
new file mode 100644
index 0000000..1b54109
--- /dev/null
+++ b/src/main/java/com/common/aspect/ResponseHeaderAspect.java
@@ -0,0 +1,47 @@
+package com.common.aspect;
+
+import lombok.extern.slf4j.Slf4j;
+import org.aspectj.lang.annotation.AfterReturning;
+import org.aspectj.lang.annotation.Aspect;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * @author 璋㈡花鐠�
+ * @date 2022-08-04
+ * @company deloitte
+ */
+@Slf4j
+@Aspect
+@Component
+@Order(-1)
+public class ResponseHeaderAspect {
+
+    @AfterReturning(pointcut = "execution(* com..controller..*.*(..))" +
+            "&& (@annotation(org.springframework.web.bind.annotation.RequestMapping)" +
+            "|| @annotation(org.springframework.web.bind.annotation.GetMapping)" +
+            "|| @annotation(org.springframework.web.bind.annotation.PostMapping)" +
+            "|| @annotation(org.springframework.web.bind.annotation.DeleteMapping)" +
+            "|| @annotation(org.springframework.web.bind.annotation.PatchMapping))", returning = "objectReturn")
+    public void doAfterCalssReturning(Object objectReturn) throws Throwable {
+        try {
+            handleLog(objectReturn);
+        } catch (Throwable e) {
+            log.error("LogReturnAspect>>>>>>>>", e);
+            throw e;
+        }
+    }
+
+    protected void handleLog(Object objectReturn) {
+        HttpServletResponse response = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getResponse();
+        response.addHeader("Content-Security-Policy","default-src 'self'");
+        response.addHeader("Strict-Transport-Security","max-age=31536000; includeSubdomains");
+        response.addHeader("Referrer-Policy","no-referrer-when-downgrade");
+        response.addHeader("X-Permitted-Cross-Domain-Policies","all");
+        response.addHeader("X-Download-Options","noopen");
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/common/aspect/SignatureAspect.java b/src/main/java/com/common/aspect/SignatureAspect.java
new file mode 100644
index 0000000..7ef4d76
--- /dev/null
+++ b/src/main/java/com/common/aspect/SignatureAspect.java
@@ -0,0 +1,81 @@
+package com.common.aspect;
+
+import com.common.core.utils.SignUtil;
+import com.common.sign.BufferedHttpServletRequest;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.context.request.RequestAttributes;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+import org.springframework.web.context.request.ServletWebRequest;
+import org.springframework.web.servlet.HandlerMapping;
+import javax.servlet.http.HttpServletRequest;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+
+/**
+ * @author 寤栨尟閽�
+ * @date 2022-01-14
+ */
+@Aspect
+@Component
+@Order(2)   //浼樺厛绾у簲璇ヤ綆浜嶭og璁板綍鍒囬潰
+public class SignatureAspect {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(StringUtils.class);
+
+    @Around("execution(* com..controller..*.*(..)) && @annotation(com.common.annotation.Sign)")
+    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
+        try {
+            this.checkSign();
+            return pjp.proceed();
+        } catch (Throwable e) {
+            LOGGER.error("SignatureAspect>>>>>>>>", e);
+            throw e;
+        }
+    }
+
+    private void checkSign() throws Exception {
+        HttpServletRequest request = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest();
+        String oldSign = request.getHeader("X-SIGN");
+        if (StringUtils.isBlank(oldSign)) {
+            throw new RuntimeException("鍙栨秷绛惧悕Header[X-SIGN]淇℃伅");
+        }
+        //鑾峰彇body锛堝搴擛RequestBody锛�
+        String body = null;
+        if (request instanceof BufferedHttpServletRequest) {
+            body = IOUtils.toString(request.getInputStream(), StandardCharsets.UTF_8);
+        }
+
+        //鑾峰彇parameters锛堝搴擛RequestParam锛�
+        Map<String, String[]> params = null;
+        if (!CollectionUtils.isEmpty(request.getParameterMap())) {
+            params = request.getParameterMap();
+        }
+
+        //鑾峰彇path variable锛堝搴擛PathVariable锛�
+        String[] paths = null;
+        ServletWebRequest webRequest = new ServletWebRequest(request, null);
+        Map<String, String> uriTemplateVars = (Map<String, String>) webRequest.getAttribute(
+                HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, RequestAttributes.SCOPE_REQUEST);
+        if (!CollectionUtils.isEmpty(uriTemplateVars)) {
+            paths = uriTemplateVars.values().toArray(new String[]{});
+        }
+        try {
+            String newSign = SignUtil.sign(body, params, paths);
+            if (!newSign.equals(oldSign)) {
+                throw new RuntimeException("绛惧悕涓嶄竴鑷�...");
+            }
+        } catch (Exception e) {
+            throw new RuntimeException("楠岀鍑洪敊...", e);
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/common/aspect/TokenAspect.java b/src/main/java/com/common/aspect/TokenAspect.java
new file mode 100644
index 0000000..94d5160
--- /dev/null
+++ b/src/main/java/com/common/aspect/TokenAspect.java
@@ -0,0 +1,57 @@
+package com.common.aspect;
+
+
+import com.common.core.utils.JwtTokenUtil;
+import com.common.security.utils.SecurityHolderUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * @author 寤栨尟閽�
+ * @date 2022-01-17
+ */
+@Slf4j
+@Aspect
+@Component
+@Order(0)   //TOKEN璁板綍鍒囬潰浼樺厛绾ф渶楂�
+public class TokenAspect {
+
+    @Autowired
+    private JwtTokenUtil jwtTokenUtil;
+
+
+    @Around("execution(* com..controller..*.*(..))" +
+            "&& (@annotation(org.springframework.web.bind.annotation.RequestMapping)" +
+            "|| @annotation(org.springframework.web.bind.annotation.GetMapping)" +
+            "|| @annotation(org.springframework.web.bind.annotation.PostMapping)" +
+            "|| @annotation(org.springframework.web.bind.annotation.DeleteMapping)" +
+            "|| @annotation(org.springframework.web.bind.annotation.PatchMapping))" +
+            "&& !@annotation(com.common.annotation.NoToken)")
+    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
+        try {
+            this.checkToken();
+            return pjp.proceed();
+        } catch (Throwable e) {
+            log.error("LogAspect>>>>>>>>", e);
+            throw e;
+        }
+    }
+
+    private void checkToken(){
+        HttpServletRequest request = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest();
+        String token = request.getHeader("pi-token");
+        Object useridobject = jwtTokenUtil.getClaim(token).get(JwtTokenUtil.CLAIM_KEY_USERID);
+        if(useridobject != null){
+            String userid = useridobject.toString();
+            SecurityHolderUtils.setUserId(userid);
+        }
+    }
+}
diff --git a/src/main/java/com/common/aws/util/S3Util.java b/src/main/java/com/common/aws/util/S3Util.java
new file mode 100644
index 0000000..df5dc99
--- /dev/null
+++ b/src/main/java/com/common/aws/util/S3Util.java
@@ -0,0 +1,137 @@
+package com.common.aws.util;
+
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.multipart.MultipartFile;
+import software.amazon.awssdk.auth.credentials.InstanceProfileCredentialsProvider;
+import software.amazon.awssdk.core.ResponseBytes;
+import software.amazon.awssdk.core.sync.RequestBody;
+import software.amazon.awssdk.services.s3.S3Client;
+import software.amazon.awssdk.services.s3.model.*;
+import sun.misc.BASE64Encoder;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * @author Ben Pi
+ * @date 2022-01-21
+ */
+@Slf4j
+public class S3Util {
+
+
+
+    // 鍒涘缓s3瀵硅薄
+    private static final S3Client s3Client = S3Client.builder()
+            .credentialsProvider(InstanceProfileCredentialsProvider.builder().build())
+            .build();
+
+
+//    public static final S3Client getS3ClientUsingEC2Instance(){
+//        return S3Client.builder()
+//        .credentialsProvider(InstanceProfileCredentialsProvider.builder().build())
+//        .build();
+//    }
+
+    /**
+     * 涓婁紶鏂囦欢
+     *
+     * @param key 涓婁紶璺緞
+     */
+    public static String uploadFile(MultipartFile file,String key,String bucketName) {
+        try {
+            log.info("鏂囦欢涓婁紶key:{}",key);
+            // 璁剧疆鏂囦欢涓婁紶瀵硅薄
+            PutObjectRequest putObjectRequest = PutObjectRequest.builder().bucket(bucketName).key(key).build();
+            // 涓婁紶鏂囦欢
+            PutObjectResponse putObjectResponse = s3Client.putObject(putObjectRequest, RequestBody.fromBytes(file.getBytes()));
+            if (null != putObjectResponse) {
+                log.info("鏂囦欢涓婁紶鎴愬姛:{}",key);
+                return key;
+            }
+            return null;
+        } catch (Exception e) {
+            log.error("upload file error",e);
+        }
+        return null;
+    }
+
+    /**
+     * 鏂囦欢涓嬭浇
+     * @param key 鏂囦欢鐨刱ey
+     * @return
+     */
+    public static ResponseBytes<GetObjectResponse> downloadFile(String key,String bucketName){
+        GetObjectRequest objectRequest = GetObjectRequest
+                    .builder()
+                    .key(key)
+                    .bucket(bucketName)
+                    .build();
+        ResponseBytes<GetObjectResponse> objectBytes = s3Client.getObjectAsBytes(objectRequest);
+        return objectBytes;
+    }
+
+
+    /**
+     * s3鏂囦欢棰勮
+     * @param key
+     */
+    public static String  DownloadFromS3(String key,String bucketName) {
+        BASE64Encoder encoder = new BASE64Encoder();
+        GetObjectRequest objectRequest = GetObjectRequest
+                .builder()
+                .key(key)
+                .bucket(bucketName)
+                .build();
+        ResponseBytes<GetObjectResponse> objectBytes = s3Client.getObjectAsBytes(objectRequest);
+        byte[] data = objectBytes.asByteArray();
+        // 杞崲鎴恇ase64鏂囦欢娴�,鐢ㄤ簬鍓嶇鏁版嵁瑙f瀽
+        return encoder.encodeBuffer(data).trim();
+    }
+
+
+    public static String getURL(String keyName,String bucketName) {
+        String url = null;
+        try {
+            GetUrlRequest request = GetUrlRequest.builder()
+                    .bucket(bucketName)
+                    .key(keyName)
+                    .build();
+            url =s3Client.utilities().getUrl(request).toString();
+            return url;
+        } catch (S3Exception e) {
+            e.awsErrorDetails().errorMessage();
+        }
+        return url;
+    }
+
+
+    public static DeleteObjectResponse deleteByKey(String key,String bucketName){
+        DeleteObjectRequest build = DeleteObjectRequest
+                .builder()
+                .key(key)
+                .bucket(bucketName)
+                .build();
+        return s3Client.deleteObject(build);
+    }
+
+    public static void deleteByKeys(List<String> keys, String bucketName){
+        ArrayList<ObjectIdentifier> to_delete = new ArrayList<ObjectIdentifier>();
+        for (String key : keys) {
+            to_delete.add(ObjectIdentifier.builder().key(key).build());
+        }
+        try{
+        DeleteObjectsRequest build = DeleteObjectsRequest.builder()
+                .bucket(bucketName)
+                .delete(Delete.builder().objects(to_delete).build())
+                .build();
+         s3Client.deleteObjects(build);
+        }catch (S3Exception e){
+            log.warn("AWS S3 鍒犻櫎澶氬璞″紓甯�:"+e);
+            throw e;
+        }
+    }
+
+}
diff --git a/src/main/java/com/common/component/DruidPlugin.java b/src/main/java/com/common/component/DruidPlugin.java
new file mode 100644
index 0000000..c5bf84b
--- /dev/null
+++ b/src/main/java/com/common/component/DruidPlugin.java
@@ -0,0 +1,353 @@
+package com.common.component;
+
+import com.alibaba.druid.filter.Filter;
+import com.alibaba.druid.pool.DruidDataSource;
+import com.jfinal.kit.StrKit;
+import com.jfinal.plugin.IPlugin;
+import com.jfinal.plugin.activerecord.IDataSourceProvider;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import javax.sql.DataSource;
+
+public class DruidPlugin implements IPlugin, IDataSourceProvider {
+    protected String name = null;
+    protected String url;
+    protected String username;
+    protected String password;
+    protected String publicKey;
+    protected String driverClass = null;
+    protected int initialSize = 1;
+    protected int minIdle = 10;
+    protected int maxActive = 32;
+    protected long maxWait = -1L;
+    protected long timeBetweenEvictionRunsMillis = 60000L;
+    protected long minEvictableIdleTimeMillis = 1800000L;
+    protected long timeBetweenConnectErrorMillis = 30000L;
+    protected String validationQuery = "select 1";
+    protected String connectionInitSql = null;
+    protected String connectionProperties = null;
+    protected boolean testWhileIdle = true;
+    protected boolean testOnBorrow = false;
+    protected boolean testOnReturn = false;
+    protected boolean removeAbandoned = false;
+    protected long removeAbandonedTimeoutMillis = 300000L;
+    protected boolean logAbandoned = false;
+    protected int maxPoolPreparedStatementPerConnectionSize = -1;
+    protected Integer defaultTransactionIsolation = null;
+    protected Integer validationQueryTimeout = null;
+    protected Integer timeBetweenLogStatsMillis = null;
+    protected Boolean keepAlive = null;
+    protected String filters;
+    protected List<Filter> filterList;
+    protected DruidDataSource ds;
+    protected volatile boolean isStarted = false;
+
+    public DruidPlugin(String url, String username, String password) {
+        this.url = url;
+        this.username = username;
+        this.password = password;
+        this.validationQuery = autoCheckValidationQuery(url);
+    }
+
+    public DruidPlugin(String url, String username, String password, String driverClass) {
+        this.url = url;
+        this.username = username;
+        this.password = password;
+        this.driverClass = driverClass;
+        this.validationQuery = autoCheckValidationQuery(url);
+    }
+
+    public DruidPlugin(String url, String username, String password, String driverClass, String filters) {
+        this.url = url;
+        this.username = username;
+        this.password = password;
+        this.driverClass = driverClass;
+        this.filters = filters;
+        this.validationQuery = autoCheckValidationQuery(url);
+    }
+
+    private static String autoCheckValidationQuery(String url) {
+        if (url.startsWith("jdbc:oracle")) {
+            return "select 1 from dual";
+        } else if (url.startsWith("jdbc:db2")) {
+            return "select 1 from sysibm.sysdummy1";
+        } else if (url.startsWith("jdbc:hsqldb")) {
+            return "select 1 from INFORMATION_SCHEMA.SYSTEM_USERS";
+        } else {
+            return url.startsWith("jdbc:derby") ? "select 1 from INFORMATION_SCHEMA.SYSTEM_USERS" : "select 1";
+        }
+    }
+
+    public void setConnectionInitSql(String sql) {
+        this.connectionInitSql = sql;
+    }
+
+    public final String getName() {
+        return this.name;
+    }
+
+    public final void setName(String name) {
+        this.name = name;
+    }
+
+    public DruidPlugin setFilters(String filters) {
+        this.filters = filters;
+        return this;
+    }
+
+    public synchronized DruidPlugin addFilter(Filter filter) {
+        if (this.filterList == null) {
+            this.filterList = new ArrayList();
+        }
+
+        this.filterList.add(filter);
+        return this;
+    }
+
+    public boolean start() {
+        if (this.isStarted) {
+            return true;
+        } else {
+            this.ds = new DruidDataSource();
+            if (this.name != null) {
+                this.ds.setName(this.name);
+            }
+
+            this.ds.setUrl(this.url);
+            this.ds.setUsername(this.username);
+            this.ds.setPassword(this.password);
+            if (this.driverClass != null) {
+                this.ds.setDriverClassName(this.driverClass);
+            }
+
+            this.ds.setInitialSize(this.initialSize);
+            this.ds.setMinIdle(this.minIdle);
+            this.ds.setMaxActive(this.maxActive);
+            this.ds.setMaxWait(this.maxWait);
+            this.ds.setTimeBetweenConnectErrorMillis(this.timeBetweenConnectErrorMillis);
+            this.ds.setTimeBetweenEvictionRunsMillis(this.timeBetweenEvictionRunsMillis);
+            this.ds.setMinEvictableIdleTimeMillis(this.minEvictableIdleTimeMillis);
+            this.ds.setValidationQuery(this.validationQuery);
+            if (StrKit.notBlank(this.connectionInitSql)) {
+                List<String> connectionInitSqls = new ArrayList();
+                connectionInitSqls.add(this.connectionInitSql);
+                this.ds.setConnectionInitSqls(connectionInitSqls);
+            }
+            this.ds.setConnectionErrorRetryAttempts(5);
+            this.ds.setTestWhileIdle(this.testWhileIdle);
+            this.ds.setTestOnBorrow(this.testOnBorrow);
+            this.ds.setTestOnReturn(this.testOnReturn);
+            this.ds.setRemoveAbandoned(this.removeAbandoned);
+            this.ds.setRemoveAbandonedTimeoutMillis(this.removeAbandonedTimeoutMillis);
+            this.ds.setLogAbandoned(this.logAbandoned);
+            this.ds.setMaxPoolPreparedStatementPerConnectionSize(this.maxPoolPreparedStatementPerConnectionSize);
+            if (this.defaultTransactionIsolation != null) {
+                this.ds.setDefaultTransactionIsolation(this.defaultTransactionIsolation);
+            }
+
+            if (this.validationQueryTimeout != null) {
+                this.ds.setValidationQueryTimeout(this.validationQueryTimeout);
+            }
+
+            if (this.timeBetweenLogStatsMillis != null) {
+                this.ds.setTimeBetweenLogStatsMillis((long)this.timeBetweenLogStatsMillis);
+            }
+
+            if (this.keepAlive != null) {
+                this.ds.setKeepAlive(this.keepAlive);
+            }
+
+            boolean hasSetConnectionProperties = false;
+            if (StrKit.notBlank(this.filters)) {
+                try {
+                    this.ds.setFilters(this.filters);
+                    if (this.filters.contains("config")) {
+                        if (StrKit.isBlank(this.publicKey)) {
+                            throw new RuntimeException("Druid杩炴帴姹犵殑filter璁惧畾浜哻onfig鏃讹紝蹇呴』璁惧畾publicKey");
+                        }
+
+                        String decryptStr = "config.decrypt=true;config.decrypt.key=" + this.publicKey;
+                        String cp = this.connectionProperties;
+                        if (StrKit.isBlank(cp)) {
+                            cp = decryptStr;
+                        } else {
+                            cp = cp + ";" + decryptStr;
+                        }
+
+                        this.ds.setConnectionProperties(cp);
+                        hasSetConnectionProperties = true;
+                    }
+                } catch (SQLException var4) {
+                    throw new RuntimeException(var4);
+                }
+            }
+
+            if (!hasSetConnectionProperties && StrKit.notBlank(this.connectionProperties)) {
+                this.ds.setConnectionProperties(this.connectionProperties);
+            }
+
+            this.addFilterList(this.ds);
+            this.isStarted = true;
+            return true;
+        }
+    }
+
+    private void addFilterList(DruidDataSource ds) {
+        if (this.filterList != null) {
+            List<Filter> targetList = ds.getProxyFilters();
+            Iterator var3 = this.filterList.iterator();
+
+            while(var3.hasNext()) {
+                Filter add = (Filter)var3.next();
+                boolean found = false;
+                Iterator var6 = targetList.iterator();
+
+                while(var6.hasNext()) {
+                    Filter target = (Filter)var6.next();
+                    if (add.getClass().equals(target.getClass())) {
+                        found = true;
+                        break;
+                    }
+                }
+
+                if (!found) {
+                    targetList.add(add);
+                }
+            }
+        }
+
+    }
+
+    public boolean stop() {
+        if (this.ds != null) {
+            this.ds.close();
+        }
+
+        this.ds = null;
+        this.isStarted = false;
+        return true;
+    }
+
+    public DataSource getDataSource() {
+        return this.ds;
+    }
+
+    public DruidPlugin set(int initialSize, int minIdle, int maxActive) {
+        this.initialSize = initialSize;
+        this.minIdle = minIdle;
+        this.maxActive = maxActive;
+        return this;
+    }
+
+    public DruidPlugin setDriverClass(String driverClass) {
+        this.driverClass = driverClass;
+        return this;
+    }
+
+    public DruidPlugin setInitialSize(int initialSize) {
+        this.initialSize = initialSize;
+        return this;
+    }
+
+    public DruidPlugin setMinIdle(int minIdle) {
+        this.minIdle = minIdle;
+        return this;
+    }
+
+    public DruidPlugin setMaxActive(int maxActive) {
+        this.maxActive = maxActive;
+        return this;
+    }
+
+    public DruidPlugin setMaxWait(long maxWait) {
+        this.maxWait = maxWait;
+        return this;
+    }
+
+    public DruidPlugin setDefaultTransactionIsolation(int defaultTransactionIsolation) {
+        this.defaultTransactionIsolation = defaultTransactionIsolation;
+        return this;
+    }
+
+    public DruidPlugin setValidationQueryTimeout(int validationQueryTimeout) {
+        this.validationQueryTimeout = validationQueryTimeout;
+        return this;
+    }
+
+    public DruidPlugin setTimeBetweenLogStatsMillis(int timeBetweenLogStatsMillis) {
+        this.timeBetweenLogStatsMillis = timeBetweenLogStatsMillis;
+        return this;
+    }
+
+    public DruidPlugin setKeepAlive(boolean keepAlive) {
+        this.keepAlive = keepAlive;
+        return this;
+    }
+
+    public DruidPlugin setTimeBetweenEvictionRunsMillis(long timeBetweenEvictionRunsMillis) {
+        this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
+        return this;
+    }
+
+    public DruidPlugin setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) {
+        this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
+        return this;
+    }
+
+    public DruidPlugin setValidationQuery(String validationQuery) {
+        this.validationQuery = validationQuery;
+        return this;
+    }
+
+    public DruidPlugin setTestWhileIdle(boolean testWhileIdle) {
+        this.testWhileIdle = testWhileIdle;
+        return this;
+    }
+
+    public DruidPlugin setTestOnBorrow(boolean testOnBorrow) {
+        this.testOnBorrow = testOnBorrow;
+        return this;
+    }
+
+    public DruidPlugin setTestOnReturn(boolean testOnReturn) {
+        this.testOnReturn = testOnReturn;
+        return this;
+    }
+
+    public DruidPlugin setMaxPoolPreparedStatementPerConnectionSize(int maxPoolPreparedStatementPerConnectionSize) {
+        this.maxPoolPreparedStatementPerConnectionSize = maxPoolPreparedStatementPerConnectionSize;
+        return this;
+    }
+
+    public final DruidPlugin setTimeBetweenConnectErrorMillis(long timeBetweenConnectErrorMillis) {
+        this.timeBetweenConnectErrorMillis = timeBetweenConnectErrorMillis;
+        return this;
+    }
+
+    public final DruidPlugin setRemoveAbandoned(boolean removeAbandoned) {
+        this.removeAbandoned = removeAbandoned;
+        return this;
+    }
+
+    public final DruidPlugin setRemoveAbandonedTimeoutMillis(long removeAbandonedTimeoutMillis) {
+        this.removeAbandonedTimeoutMillis = removeAbandonedTimeoutMillis;
+        return this;
+    }
+
+    public final DruidPlugin setLogAbandoned(boolean logAbandoned) {
+        this.logAbandoned = logAbandoned;
+        return this;
+    }
+
+    public final DruidPlugin setConnectionProperties(String connectionProperties) {
+        this.connectionProperties = connectionProperties;
+        return this;
+    }
+
+    public final DruidPlugin setPublicKey(String publicKey) {
+        this.publicKey = publicKey;
+        return this;
+    }
+}
diff --git a/src/main/java/com/common/component/RedisCache.java b/src/main/java/com/common/component/RedisCache.java
new file mode 100644
index 0000000..bc242fb
--- /dev/null
+++ b/src/main/java/com/common/component/RedisCache.java
@@ -0,0 +1,35 @@
+package com.common.component;
+
+import com.common.redis.util.RedisUtil;
+import com.jfinal.plugin.activerecord.cache.ICache;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class RedisCache implements ICache {
+
+    @Autowired
+    private RedisUtil redisUtil;
+
+    public  RedisCache(){}
+
+    @Override
+    public <T> T get(String s, Object o) {
+        return (T) redisUtil.hashSingleGet(s, o);
+    }
+
+    @Override
+    public void put(String s, Object o, Object o1) {
+        redisUtil.hset(s, o, o1);
+    }
+
+    @Override
+    public void remove(String s, Object o) {
+        redisUtil.hDelFields(s, o);
+    }
+
+    @Override
+    public void removeAll(String s) {
+        redisUtil.deleteKey(s);
+    }
+}
diff --git a/src/main/java/com/common/configure/ClassPathTableScanner.java b/src/main/java/com/common/configure/ClassPathTableScanner.java
new file mode 100644
index 0000000..d483f6a
--- /dev/null
+++ b/src/main/java/com/common/configure/ClassPathTableScanner.java
@@ -0,0 +1,68 @@
+package com.common.configure;
+
+import com.common.core.utils.KitClassUtils;
+import lombok.Data;
+import org.springframework.beans.factory.config.BeanDefinitionHolder;
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
+import org.springframework.core.env.Environment;
+import org.springframework.core.io.ResourceLoader;
+import org.springframework.core.type.filter.AnnotationTypeFilter;
+import org.springframework.lang.Nullable;
+import java.lang.annotation.Annotation;
+import java.util.Arrays;
+import java.util.Set;
+
+
+/**
+ * @author 寤栨尟閽�
+ */
+@Data
+public class ClassPathTableScanner   extends ClassPathBeanDefinitionScanner {
+
+    private Class<? extends Annotation> annotationClass;
+
+    public ClassPathTableScanner(BeanDefinitionRegistry registry) {
+        super(registry);
+    }
+
+    public ClassPathTableScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters) {
+        super(registry, useDefaultFilters);
+    }
+
+    public ClassPathTableScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters, Environment environment) {
+        super(registry, useDefaultFilters, environment);
+    }
+
+    public ClassPathTableScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters, Environment environment, @Nullable ResourceLoader resourceLoader) {
+        super(registry, useDefaultFilters, environment, resourceLoader);
+    }
+
+    public void registerFilters() {
+        if (this.annotationClass != null) {
+            addIncludeFilter(new AnnotationTypeFilter(this.annotationClass));
+        }
+
+    }
+
+    @Override
+    public Set<BeanDefinitionHolder> doScan(String... basePackages) {
+        Set<BeanDefinitionHolder> beanDefinitions = super.doScan(basePackages);
+
+        beanDefinitions.forEach(beanDefinition->{
+            String beanclassname = beanDefinition.getBeanDefinition().getBeanClassName();
+            try {
+                Class onwClass = Class.forName(beanclassname);
+                KitClassUtils.tableclass.add(onwClass);
+            }catch (Exception e){
+                e.printStackTrace();
+            }
+        });
+
+        if (beanDefinitions.isEmpty()) {
+            logger.warn("娌℃湁鎵惧埌 '" + Arrays.toString(basePackages) + "'鍖咃紝璇锋鏌ヤ綘鐨勯厤缃�.");
+        }
+
+        return beanDefinitions;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/common/configure/CommonConfig.java b/src/main/java/com/common/configure/CommonConfig.java
new file mode 100644
index 0000000..3b1acbf
--- /dev/null
+++ b/src/main/java/com/common/configure/CommonConfig.java
@@ -0,0 +1,12 @@
+package com.common.configure;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@ComponentScan(value = "com.deloitte.system")
+public class CommonConfig {
+
+
+}
diff --git a/src/main/java/com/common/configure/EncryptionPropertyConfig.java b/src/main/java/com/common/configure/EncryptionPropertyConfig.java
new file mode 100644
index 0000000..34ec7e1
--- /dev/null
+++ b/src/main/java/com/common/configure/EncryptionPropertyConfig.java
@@ -0,0 +1,40 @@
+package com.common.configure;
+
+import com.common.core.utils.SM4Utils;
+import com.ulisesbocchio.jasyptspringboot.EncryptablePropertyResolver;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @author 寤栨尟閽�
+ * @date 21/12/2021 15:36
+ * @desc 鑷姩瑙e瘑
+ */
+@Configuration
+public class EncryptionPropertyConfig {
+
+    @Bean(name = "encryptablePropertyResolver")
+    public EncryptablePropertyResolver encryptablePropertyResolver() {
+        return new EncryptionPropertyResolver();
+    }
+
+    class EncryptionPropertyResolver implements EncryptablePropertyResolver {
+
+        public String resolvePropertyValue(String value) {
+            if (StringUtils.isBlank(value)) {
+                return value;
+            }
+            if (value.startsWith("DES@")) {
+                return resolveDESValue(value.substring(4));
+            }
+            return value;
+        }
+
+        private String resolveDESValue(String value) {
+
+            return SM4Utils.decryptStr(value);
+        }
+
+    }
+}
diff --git a/src/main/java/com/common/configure/FilterConfig.java b/src/main/java/com/common/configure/FilterConfig.java
new file mode 100644
index 0000000..5ae01d9
--- /dev/null
+++ b/src/main/java/com/common/configure/FilterConfig.java
@@ -0,0 +1,59 @@
+package com.common.configure;
+
+import com.alibaba.druid.support.http.StatViewServlet;
+import com.alibaba.fastjson.JSONObject;
+import com.common.core.utils.SecretsManagerUtils;
+import com.common.filter.RequestCachingFilter;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
+import org.springframework.boot.web.servlet.ServletRegistrationBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.env.Environment;
+
+
+/**
+ * @author 寤栨尟閽�
+ * @date 2022-01-14
+ */
+@Configuration
+public class FilterConfig {
+//    @Bean
+    public RequestCachingFilter requestCachingFilter() {
+        return new RequestCachingFilter();
+    }
+
+//    @Bean
+    public FilterRegistrationBean requestCachingFilterRegistration(
+            RequestCachingFilter requestCachingFilter) {
+        FilterRegistrationBean bean = new FilterRegistrationBean(requestCachingFilter);
+        bean.setOrder(1);
+        return bean;
+    }
+
+    @Bean
+    public FilterRegistrationBean<com.alibaba.druid.support.http.WebStatFilter> regFilter() {
+        FilterRegistrationBean<com.alibaba.druid.support.http.WebStatFilter> regFilter = new FilterRegistrationBean(new com.alibaba.druid.support.http.WebStatFilter());
+        regFilter.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
+        regFilter.addUrlPatterns("/*");
+        return regFilter ;
+    }
+
+    @Autowired
+    private Environment env;
+    @Autowired
+    private SecretsManagerUtils secretsManagerUtils;
+    @Bean
+    public ServletRegistrationBean<StatViewServlet> druidStatViewServlet() {
+        ServletRegistrationBean<StatViewServlet> registrationBean = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");
+        registrationBean.addInitParameter("allow", "");// IP鐧藉悕鍗� (娌℃湁閰嶇疆鎴栬�呬负绌猴紝鍒欏厑璁告墍鏈夎闂�)
+        registrationBean.addInitParameter("deny", "");// IP榛戝悕鍗� (瀛樺湪鍏卞悓鏃讹紝deny浼樺厛浜巃llow)
+        JSONObject object = secretsManagerUtils.getSecret(env.getProperty("aws.secrets.mysql"));
+        String username = object.getString("username");
+        String password = object.getString("password");
+        registrationBean.addInitParameter("loginUsername", username);
+        registrationBean.addInitParameter("loginPassword", password);
+        registrationBean.addInitParameter("resetEnable", "false");
+        return registrationBean;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/common/configure/JfinalProperties.java b/src/main/java/com/common/configure/JfinalProperties.java
new file mode 100644
index 0000000..69e5104
--- /dev/null
+++ b/src/main/java/com/common/configure/JfinalProperties.java
@@ -0,0 +1 @@
+/**
 * $Id: JfinalProperties.java,v 1.0 2019-07-14 00:46 chenmin Exp $
 */
package com.common.configure;

import com.jfinal.plugin.activerecord.dialect.Dialect;
import lombok.Data;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.annotation.Validated;
import java.util.ArrayList;
import java.util.List;

/**
 * @author 寤栨尟閽�
 * @date 2019-01-11
 */
@Slf4j
@Component
@Data
@Validated
@Accessors(chain = true)
@ConfigurationProperties(prefix = "jfinal")
public class JfinalProperties {
    /**
     * SQL妯℃澘璺緞
     */
//    private List<String> sqlTemplates = Lists.newArrayList();
    private List<String> sqlTemplates = new ArrayList<>();
    /**
     * kit绫诲叏璺緞
     */
//    private List<String> kitClasses = Lists.newArrayList();
    private List<String> kitClasses = new ArrayList<>();

    /**
     * 鏄惁鎵撳紑寮�鍙戞ā寮�
     */
    private Boolean devMode = false;
    /**
     * 鏄惁鏄剧ず鏌ヨSQL
     */
    private Boolean showSql;
    /**
     * 鏁版嵁搴撴柟瑷�:榛樿鏀寔MYSQL,ORACLE,SQLSERVER,SQLITE,POSTGRESQL
     */
    private Class<? extends Dialect> dialect;
    private Boolean injectDependency = false;
    private String baseUploadPath;
    private String baseDownloadPath;
    private Integer maxPostSize;
    private Integer delayInSeconds;
    private String defaultBaseName;
    private String defaultLocale;
    private Boolean injectSuperClass;
    private Boolean reportAfterInvocation;
    private String datePattern;
    private String urlParaSeparator;
    private String viewExtension;
    private Boolean clearAfterMapping;
    private Boolean mappingSuperClass;
    private Boolean createSession;
    private String baseTemplatePath;
    private Boolean sessionInView;
    /**
     * 鏄惁鍏佽瑕嗙洊Request
     */
    private Boolean allowRequestOverride;
    /**
     * 鏄惁鍏佽瑕嗙洊Session
     */
    private Boolean allowSessionOverride;
    /**
     * 浜嬪姟绾у埆
     */
    private Integer transactionLevel;
    /**
     * 鎻掍欢鍔犺浇椤哄簭
     */
    private Integer configPluginOrder;
    @Data
    @Accessors(chain = true)
    public static class TaskInfo {

        private String cron;

        private String task;
        /**
         * 鏄惁寮�鍚畧鎶よ繘绋�
         */
        private Boolean daemon;
        /**
         * 鏄惁寮�鍚换鍔�,榛樿寮�鍚�
         */
        private Boolean enable = true;

        public TaskInfo() {
        }

        public TaskInfo(String cron, String task, boolean daemon, boolean enable) {
            if (ObjectUtils.isEmpty(cron)) {
                throw new IllegalArgumentException("cron 涓嶈兘涓虹┖.");
            }
            if (ObjectUtils.isEmpty(task)) {
                throw new IllegalArgumentException("task 涓嶈兘涓� null.");
            }

            this.cron = cron.trim();
            this.task = task;
            this.daemon = daemon;
            this.enable = enable;
        }
    }

}
\ No newline at end of file
diff --git a/src/main/java/com/common/configure/Swagger2Config.java b/src/main/java/com/common/configure/Swagger2Config.java
new file mode 100644
index 0000000..c09cfda
--- /dev/null
+++ b/src/main/java/com/common/configure/Swagger2Config.java
@@ -0,0 +1,58 @@
+package com.common.configure;
+
+import org.springframework.context.annotation.*;
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.SpringfoxWebMvcConfiguration;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger.configuration.SwaggerCommonConfiguration;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+/**
+ * @author zhliao
+ * @date 2022-02-16
+ * @description swagger鏂囨。閰嶇疆
+ * */
+@Import({ SpringfoxWebMvcConfiguration.class, SwaggerCommonConfiguration.class,springfox.documentation.schema.configuration.ModelsConfiguration.class })
+@ComponentScan(basePackages = {
+        "springfox.documentation.swagger.readers.parameter",
+        "springfox.documentation.swagger2.web",
+        "springfox.documentation.swagger2.mappers"
+})
+@Configuration
+@EnableSwagger2
+public class Swagger2Config {
+    @Bean
+    public Docket createRestApi() {
+        return new Docket(DocumentationType.SWAGGER_2)
+                .groupName("SBG鎺ュ彛")
+                .apiInfo(apiInfo())
+                .select()
+                .apis(RequestHandlerSelectors.basePackage("com.deloitte.sbg"))
+                .paths(PathSelectors.any())
+                .build();
+    }
+
+    @Bean
+    public Docket createRestApi2() {
+        return new Docket(DocumentationType.SWAGGER_2)
+                .groupName("鍚庡彴绯荤粺鎺ュ彛")
+                .apiInfo(apiInfo())
+                .select()
+                .apis(RequestHandlerSelectors.basePackage("com.deloitte.system"))
+                .paths(PathSelectors.any())
+                .build();
+    }
+
+    private ApiInfo apiInfo() {
+        return new ApiInfoBuilder()
+                .title("AWS鎺ュ彛鏂囨。")
+                .description("AWS鎺ュ彛鏂囨。")
+                .termsOfServiceUrl("AWS鎺ュ彛鏂囨。")
+                .version("1.0")
+                .build();
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/common/configure/TableScannerRegistrar.java b/src/main/java/com/common/configure/TableScannerRegistrar.java
new file mode 100644
index 0000000..1f938a5
--- /dev/null
+++ b/src/main/java/com/common/configure/TableScannerRegistrar.java
@@ -0,0 +1,54 @@
+package com.common.configure;
+
+import com.common.annotation.JfinalModelScan;
+import com.common.annotation.Table;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+import org.springframework.context.EnvironmentAware;
+import org.springframework.context.ResourceLoaderAware;
+import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
+import org.springframework.core.annotation.AnnotationAttributes;
+import org.springframework.core.env.Environment;
+import org.springframework.core.io.ResourceLoader;
+import org.springframework.core.type.AnnotationMetadata;
+import org.springframework.util.StringUtils;
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * @author 寤栨尟閽�
+ * @date 2022-01-14
+ */
+@Slf4j
+@Data
+public class TableScannerRegistrar implements ImportBeanDefinitionRegistrar, ResourceLoaderAware, EnvironmentAware {
+
+    private ResourceLoader resourceLoader;
+
+    private Environment environment;
+
+    @Override
+    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
+
+        AnnotationAttributes annoAttrs = AnnotationAttributes.fromMap(importingClassMetadata.getAnnotationAttributes(JfinalModelScan.class.getName()));
+        ClassPathTableScanner scanner = new ClassPathTableScanner(registry);
+        if (resourceLoader != null) {
+            scanner.setResourceLoader(resourceLoader);
+        }
+
+        scanner.setAnnotationClass(Table.class);
+
+        List<String> basePackages = new ArrayList<String>();
+        for (String pkg : annoAttrs.getStringArray("basePackages")) {
+            if (StringUtils.hasText(pkg)) {
+                basePackages.add(pkg);
+            }
+        }
+
+        scanner.registerFilters();
+        scanner.doScan(StringUtils.toStringArray(basePackages));
+    }
+
+}
diff --git a/src/main/java/com/common/configure/ThreadPoolTaskConfig.java b/src/main/java/com/common/configure/ThreadPoolTaskConfig.java
new file mode 100644
index 0000000..cf6f4a5
--- /dev/null
+++ b/src/main/java/com/common/configure/ThreadPoolTaskConfig.java
@@ -0,0 +1,49 @@
+package com.common.configure;
+
+import cn.hutool.core.thread.NamedThreadFactory;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+
+/**
+ * @auther:寤栨尟閽�
+ * @date: 2022-01-04
+ * */
+@Configuration
+public class ThreadPoolTaskConfig {
+
+    private static final int corePoolSize = 10;       		// 鏍稿績绾跨▼鏁帮紙榛樿绾跨▼鏁帮級
+    private static final int maxPoolSize = 100;			    // 鏈�澶х嚎绋嬫暟
+    private static final int keepAliveTime = 10;			// 鍏佽绾跨▼绌洪棽鏃堕棿锛堝崟浣嶏細榛樿涓虹锛�
+    private static final int queueCapacity = 200;			// 缂撳啿闃熷垪鏁�
+    private static final String threadNamePrefix = "Async-Service-"; // 绾跨▼姹犲悕鍓嶇紑
+
+    @Bean("taskExecutor") // bean鐨勫悕绉帮紝榛樿涓洪瀛楁瘝灏忓啓鐨勬柟娉曞悕
+    public ThreadPoolTaskExecutor getAsyncExecutor(){
+        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+        executor.setCorePoolSize(corePoolSize);
+        executor.setMaxPoolSize(maxPoolSize);
+        executor.setQueueCapacity(queueCapacity);
+        executor.setKeepAliveSeconds(keepAliveTime);
+        executor.setThreadNamePrefix(threadNamePrefix);
+
+        // 绾跨▼姹犲鎷掔粷浠诲姟鐨勫鐞嗙瓥鐣�
+        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
+        // 鍒濆鍖�
+        executor.initialize();
+        return executor;
+    }
+
+    @Bean
+    public ThreadPoolExecutor ThreadPoolExecutor(){
+        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
+                60L, TimeUnit.SECONDS,
+                new SynchronousQueue<Runnable>(),new NamedThreadFactory("cacha-thread-pool", true));
+    }
+}
diff --git a/src/main/java/com/common/core/beans/BaseResult.java b/src/main/java/com/common/core/beans/BaseResult.java
new file mode 100644
index 0000000..854e982
--- /dev/null
+++ b/src/main/java/com/common/core/beans/BaseResult.java
@@ -0,0 +1,48 @@
+package com.common.core.beans;
+
+
+import com.common.core.enums.ResultCodeEnum;
+import com.common.core.utils.DateUtils;
+
+import java.io.Serializable;
+
+/**
+ * BaseResult
+ *
+ * @author xiaobzhou
+ * date 2020-02-28 22:25
+ */
+public abstract class BaseResult implements Serializable {
+
+    private String status;
+    private String message;
+    private Long timestamp = DateUtils.nowTimestamp();
+
+    public String getStatus() {
+        return status;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public Long getTimestamp() {
+        return timestamp;
+    }
+
+    public void setTimestamp(Long timestamp) {
+        this.timestamp = timestamp;
+    }
+
+    public boolean isSuccess() {
+        return ResultCodeEnum.RT_SUCCESS.getCode().equals(this.getStatus());
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/common/core/beans/Result.java b/src/main/java/com/common/core/beans/Result.java
new file mode 100644
index 0000000..b6952de
--- /dev/null
+++ b/src/main/java/com/common/core/beans/Result.java
@@ -0,0 +1,61 @@
+package com.common.core.beans;
+
+import com.common.core.enums.ResultCodeEnum;
+import com.common.core.utils.DateUtils;
+
+import java.util.List;
+
+/**
+ * Result
+ *
+ * @author xiaobzhou
+ * date 2018-04-18 15:45
+ */
+public class Result<T> extends BaseResult {
+    private String txId;
+    private T object;
+
+    private Result() {
+
+    }
+
+    public static <T> Result<T> resp(String code, String message) {
+        Result<T> result = new Result<>();
+        result.setStatus(code);
+        result.setMessage(message);
+        result.setTimestamp(DateUtils.nowTimestamp());
+        return result;
+    }
+
+    public static <T> Result<T> resp(ResultCodeEnum resultCodeEnum) {
+        Result<T> result = new Result<>();
+        result.setStatus(resultCodeEnum.getCode());
+        result.setMessage(resultCodeEnum.name());
+        result.setTimestamp(DateUtils.nowTimestamp());
+        return result;
+    }
+
+    public static <T> Result<T> respErr(ResultCodeEnum resultCodeEnum) {
+        Result<T> result = new Result<>();
+        result.setStatus(resultCodeEnum.getCode());
+        result.setMessage(resultCodeEnum.getMsg());
+        result.setTimestamp(DateUtils.nowTimestamp());
+        return result;
+    }
+
+    public String getTxId() {
+        return txId;
+    }
+
+    public void setTxId(String txId) {
+        this.txId = txId;
+    }
+
+    public T getObject() {
+        return object;
+    }
+
+    public void setObject(T object) {
+        this.object = object;
+    }
+}
diff --git a/src/main/java/com/common/core/constant/Constants.java b/src/main/java/com/common/core/constant/Constants.java
new file mode 100644
index 0000000..0952e73
--- /dev/null
+++ b/src/main/java/com/common/core/constant/Constants.java
@@ -0,0 +1,63 @@
+package com.common.core.constant;
+
+/**
+ * @auther:寤栨尟閽�
+ * @date: 2022-01-11
+ * */
+public class Constants
+{
+    /**
+     * UTF-8 瀛楃闆�
+     */
+    public static final String UTF8 = "UTF-8";
+
+    /**
+     * GBK 瀛楃闆�
+     */
+    public static final String GBK = "GBK";
+
+    /**
+     * http璇锋眰
+     */
+    public static final String HTTP = "http://";
+
+    /**
+     * https璇锋眰
+     */
+    public static final String HTTPS = "https://";
+
+    /**
+     * 鎴愬姛鏍囪
+     */
+    public static final Integer SUCCESS = 200;
+
+    /**
+     * 澶辫触鏍囪
+     */
+    public static final Integer FAIL = 500;
+
+    /**
+     * 褰撳墠璁板綍璧峰绱㈠紩
+     */
+    public static final String PAGE_NUM = "pageNum";
+
+    /**
+     * 姣忛〉鏄剧ず璁板綍鏁�
+     */
+    public static final String PAGE_SIZE = "pageSize";
+
+    /**
+     * 鎺掑簭鍒�
+     */
+    public static final String ORDER_BY_COLUMN = "orderByColumn";
+
+    /**
+     * 鎺掑簭鐨勬柟鍚� "desc" 鎴栬�� "asc".
+     */
+    public static final String IS_ASC = "isAsc";
+
+    /** 琛屼负鎿嶄綔 **/
+    public final static String ACTION_CREATE = "create"; //鍒涘缓
+    public final static String ACTION_UPDATE = "update";//鏇存柊
+
+}
diff --git a/src/main/java/com/common/core/constant/GlobalConst.java b/src/main/java/com/common/core/constant/GlobalConst.java
new file mode 100644
index 0000000..ff8096e
--- /dev/null
+++ b/src/main/java/com/common/core/constant/GlobalConst.java
@@ -0,0 +1,24 @@
+package com.common.core.constant;
+
+/**
+ * @author binhuang
+ */
+public class GlobalConst {
+    public static final Long TOKEN_EXPIRE = 3600*2L;
+    public static final Long TOKEN_EXPIRE_BUFF = 3600L;
+    public static final Long DATA_EXPIRE = 600L;
+    public static final Long SF_TOKEN_EXPIRE = 3600L;
+    /**
+     * 绯荤粺鏀朵繚鎶よ祫婧恟edis缂撳瓨key
+     */
+    public static final String TOKEN_KEY = "pipl:token:";
+    public static final String TOKEN_KEY_TMP = "pipl:token:tmp:";
+    public static final String SF_TOKEN_KEY = "pipl:sf:token";
+    public static final String PIPL_UNCONFIRM_LOCK ="pipl:unconfirm:lock:";
+    public static final String PIPL_UNCONFIRM_INSERT ="pipl:unconfirm:insert:";
+
+    public static final String PIPL_UNCONFIRM_UPDATE ="pipl:unconfirm:update:";
+
+    public static final String PIPL_UNCONFIRM_FILE ="pipl:unconfirm:file:";
+
+}
diff --git a/src/main/java/com/common/core/crypto/ColumnHandler.java b/src/main/java/com/common/core/crypto/ColumnHandler.java
new file mode 100644
index 0000000..107e676
--- /dev/null
+++ b/src/main/java/com/common/core/crypto/ColumnHandler.java
@@ -0,0 +1,41 @@
+package com.common.core.crypto;
+
+
+import com.common.core.utils.SM4Utils;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * @author 寤栨尟閽�
+ * @Date 2022-01-11 19:02
+ * */
+
+@Slf4j
+public class ColumnHandler implements CryptoHandler<String, String>{
+
+    public String encrypto(String src){
+        if(null == src){
+            return null;
+        }
+        try{
+            return SM4Utils.encryptStr(src);
+        }
+        catch(Exception e){
+            log.error(e.getMessage(), e);
+            throw new RuntimeException(e.getMessage());
+        }
+    }
+
+    public String decrypto(String src){
+        if(null == src){
+            return null;
+        }
+        try{
+            return SM4Utils.decryptStr(src);
+        }
+        catch(Exception e){
+            log.error(e.getMessage(), e);
+            throw new RuntimeException(e.getMessage());
+        }
+    }
+
+}
diff --git a/src/main/java/com/common/core/crypto/CryptoHandler.java b/src/main/java/com/common/core/crypto/CryptoHandler.java
new file mode 100644
index 0000000..d3be0c0
--- /dev/null
+++ b/src/main/java/com/common/core/crypto/CryptoHandler.java
@@ -0,0 +1,14 @@
+package com.common.core.crypto;
+
+/**
+ * @author 寤栨尟閽�
+ * @Date 2022-01-11 19:24
+ * */
+public interface CryptoHandler<S, T> {
+    // 鍔犲瘑
+    T encrypto(S src);
+
+    // 瑙e瘑
+    T decrypto(S src);
+
+}
diff --git a/src/main/java/com/common/core/domain/BaseModel.java b/src/main/java/com/common/core/domain/BaseModel.java
new file mode 100644
index 0000000..48c2f8c
--- /dev/null
+++ b/src/main/java/com/common/core/domain/BaseModel.java
@@ -0,0 +1,125 @@
+package com.common.core.domain;
+
+import com.common.annotation.Table;
+import com.common.core.utils.DateUtils;
+import com.common.security.utils.SecurityUtils;
+import com.jfinal.kit.StrKit;
+import com.jfinal.plugin.activerecord.Model;
+import com.jfinal.plugin.activerecord.Page;
+
+import java.util.*;
+
+/**
+ * @author 寤栨尟閽�
+ * @date 20/12/2021
+ */
+public abstract class BaseModel<M extends BaseModel> extends Model<M> {
+
+    public void setId(Long id) {
+        set("id", id);
+    }
+
+    public Long getId() {
+        return getLong("id");
+    }
+
+    public void setIsDelete(Integer isDelete) {
+        set("is_delete", isDelete);
+    }
+
+    public Integer getIsDelete() {
+        return getInt("is_delete");
+    }
+
+    public void setCreateBy(String createBy) {
+        set("create_by", createBy);
+    }
+
+    public String getCreateBy(){
+        return get("create_by");
+    }
+
+    public void setUpdateBy(String UpdateBy) {
+        set("update_by", UpdateBy);
+    }
+
+    public String getUpdateBy(){
+        return get("update_by");
+    }
+
+    public void setCreateTime(Date createTime) {
+        set("create_time", createTime);
+    }
+
+    public Date getCreateTime() {
+        return getDate("create_time");
+    }
+
+    public void setUpdateTime(Date updateTime) {
+        set("update_time", updateTime);
+    }
+
+    public Date getUpdateTime() {
+        return getDate("update_time");
+    }
+
+    public Page<M> pageQuery(int cpage, int pageSize, String orderField, String orderDirection,
+                                               String where, int dataright) {
+        String sql_select = "select *";
+        StringBuffer conf = new StringBuffer(" from "+getTableName()+" where is_delete=? ");
+        List<String> params = new ArrayList<String>();
+        params.add("0");
+        if(StrKit.notBlank(where)){
+            conf.append(where);
+        }
+
+        if (StrKit.notBlank(orderField, orderDirection)) {
+            conf.append(" ORDER BY ").append(" ").append(orderField).append(" ").append(orderDirection);
+        }
+
+        Page<M> page = paginate(cpage, pageSize, sql_select, conf.toString(), params.toArray());
+        return page;
+    }
+
+
+
+    @Override
+    public boolean save(){
+        String appid = SecurityUtils.byId();
+        setIsDelete(0);
+        setCreateTime(DateUtils.now());
+        setUpdateTime(DateUtils.now());
+        setCreateBy(appid);
+        setUpdateBy(appid);
+        return super.save();
+    }
+
+    @Override
+    public boolean update(){
+        String appid = SecurityUtils.byId();
+        setUpdateTime(DateUtils.now());
+        setUpdateBy(appid);
+        return super.update();
+    }
+
+    public String getTableName(){
+        Table table = getClass().getAnnotation(Table.class);
+        return table.tableName();
+    }
+
+    public List<M> findList(){
+        return dao().find("select * from "+getTableName()+ " where is_delete = '0'");
+    }
+
+    public List<M> findList(String where){
+        return dao().find("select * from "+getTableName()+ " where is_delete = '0' "+where);
+    }
+
+    public boolean saveOrUpdate(){
+        if(null == getId()){
+            return this.save();
+        } else{
+            return this.update();
+        }
+    }
+}
diff --git a/src/main/java/com/common/core/domain/DesensitiveType.java b/src/main/java/com/common/core/domain/DesensitiveType.java
new file mode 100644
index 0000000..d380501
--- /dev/null
+++ b/src/main/java/com/common/core/domain/DesensitiveType.java
@@ -0,0 +1,111 @@
+package com.common.core.domain;
+
+/**
+ * @description: 鑴辨晱鍙傛暟
+ * @author: holden
+ * @time: 2022-01-20 10:50
+ */
+public enum DesensitiveType {
+
+    /**
+     * 涓枃鍚�
+     */
+    CHINESE_NAME(1,0, 3,null),
+
+    /**
+     * 韬唤璇佸彿
+     */
+    ID_CARD(8,3,10,null),
+    /**
+     * 鎵嬫満鍙�
+     */
+    MOBILE_PHONE(3,2,11,null),
+    /**
+     * 鍦板潃
+     */
+    ADDRESS(6,0,10,null),
+    /**
+     * 鐢靛瓙閭欢
+     */
+    EMAIL(0,0,5,"@"),
+    /**
+     * 閾惰鍗�
+     */
+    BANK_CARD(6,4,10,null),
+    /**
+     * 鍏徃寮�鎴烽摱琛岃仈鍙�
+     */
+    CNAPS_CODE(2,0,10,null),
+    /**
+     * 閭斂缂栫爜
+     */
+    ZIP_CODE(1,1,6,null),
+    /**
+     * 骞撮緞
+     */
+    AGE(1,1,2,null),
+    /**
+     * 鑱屽姟
+     */
+    TITLE_TYPE(1,1,5,null),
+
+    /**
+     * 鍏朵粬鏂囨湰瀛楁绫诲瀷
+     */
+    BASIC(1,1,10,null),
+
+    /**
+     * 鏃ユ湡
+     */
+    Date(1,1,6,null),
+
+    /**
+     * 鎬у埆
+     */
+    SEX(1,0, 1,null);
+
+    private Integer retainLeft;
+    private Integer retainRight;
+    private Integer padSize;
+    private  String separator;
+
+    DesensitiveType(Integer retainLeft, Integer retainRight, Integer padSize, String separator) {
+        this.retainLeft = retainLeft;
+        this.retainRight = retainRight;
+        this.padSize = padSize;
+        this.separator=separator;
+    }
+
+
+    public void setRetainLeft(Integer retainLeft) {
+        this.retainLeft = retainLeft;
+    }
+
+    public void setRetainRight(Integer retainRight) {
+        this.retainRight = retainRight;
+    }
+
+    public Integer getRetainLeft() {
+        return retainLeft;
+    }
+
+    public Integer getRetainRight() {
+        return retainRight;
+    }
+
+    public Integer getPadSize(){
+        return padSize;
+    }
+
+    public void setPadSize(Integer padSize){
+        this.padSize = padSize;
+    }
+
+    public String getSeparator() {
+        return separator;
+    }
+
+    public void setSeparator(String separator) {
+        this.separator = separator;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/common/core/domain/EntityModel.java b/src/main/java/com/common/core/domain/EntityModel.java
new file mode 100644
index 0000000..a8c6806
--- /dev/null
+++ b/src/main/java/com/common/core/domain/EntityModel.java
@@ -0,0 +1,205 @@
+package com.common.core.domain;
+
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson.annotation.JSONType;
+import com.common.core.exception.BizException;
+import com.common.core.utils.DateUtils;
+import com.common.security.utils.SecurityUtils;
+import com.jfinal.plugin.activerecord.TableMapping;
+import lombok.extern.slf4j.Slf4j;
+import java.lang.reflect.Field;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @author 寤栨尟閽�
+ * @date 2022-01-29
+ */
+@Slf4j
+@JSONType(ignores = {"tableName","id","isDelete","updateTime","createTime","createBy","updateBy"})
+public abstract class EntityModel<M extends EntityModel> extends BaseModel<M> {
+
+    @Override
+    public boolean save(){
+        Field[] fields = getClass().getDeclaredFields();
+        for(Field f : fields){
+            f.setAccessible(true);
+            try {
+                Object o = f.get(this);
+                if(null != o) {
+                    if (RecordAttrHas(humpToLine2(f.getName()))) {
+                        set(humpToLine2(f.getName()), f.get(this));
+                    } else if (RecordAttrHas(f.getName())) {
+                        set(f.getName(), f.get(this));
+                    }
+                }
+            } catch (IllegalAccessException e) {
+
+            }
+        }
+        String appid = SecurityUtils.byId();
+        setIsDelete(0);
+        setCreateTime(DateUtils.now());
+        setUpdateTime(DateUtils.now());
+        setCreateBy(appid);
+        setUpdateBy(appid);
+        return super.save();
+    }
+
+    @Override
+    public boolean update(){
+        Field[] fields = getClass().getDeclaredFields();
+        for(Field f : fields){
+            f.setAccessible(true);
+            if(!"id".equals(f.getName())) {
+                try {
+                    Object o = f.get(this);
+                    if(null != o) {
+                        if (RecordAttrHas(humpToLine2(f.getName()))) {
+                            set(humpToLine2(f.getName()), f.get(this));
+                        } else if (RecordAttrHas(f.getName())) {
+                            set(f.getName(), f.get(this));
+                        }
+                    }
+                } catch (IllegalAccessException e) {
+                    log.error(e.getMessage(), e);
+                }
+            }
+        }
+        String appid = SecurityUtils.byId();
+        setIsDelete(0);
+        setCreateTime(DateUtils.now());
+        setUpdateTime(DateUtils.now());
+        setCreateBy(appid);
+        setUpdateBy(appid);
+        return super.update();
+    }
+
+    @Override
+    public boolean saveOrUpdate(){
+        if(null == getId()){
+            return this.save();
+        } else{
+            return this.update();
+        }
+    }
+
+    @Override
+    public M findFirst(String sql){
+        M m  = super.findFirst(sql);
+        if(null == m){
+            return null;
+        }
+        RelectionField(m);
+        return m;
+    }
+
+    @Override
+    public M findFirst(String sql,Object...params){
+        M m  = super.findFirst(sql, params);
+        if(null == m){
+            return null;
+        }
+        RelectionField(m);
+        return m;
+    }
+
+    @Override
+    public M findById(Object id){
+        return this.findFirst("select * from "+getTableName()+" where id = ? and is_delete='0'",id);
+    }
+
+    @Override
+    public List<M> findAll(){
+        List<M> list = super.findAll();
+        List<M> returnlist = new ArrayList<M>();
+        for(M m : list){
+            RelectionField(m);
+            returnlist.add(m);
+        }
+        return returnlist;
+    }
+
+    @Override
+    public List<M> find(String sql){
+        List<M> list  = super.find(sql);
+        List<M> returnlist = Collections.emptyList();
+        for(M m : list){
+            RelectionField(m);
+            returnlist.add(m);
+        }
+        return returnlist;
+    }
+
+    @Override
+    public List<M> find(String sql,Object...params){
+        List<M> list  = super.find(sql, params);
+        List<M> returnlist = new ArrayList<M>();
+        for(M m : list){
+            RelectionField(m);
+            returnlist.add(m);
+        }
+        return returnlist;
+    }
+
+    private void RelectionField(M m){
+        Field[] fields = m.getClass().getDeclaredFields();
+        for(Field f : fields) {
+            f.setAccessible(true);
+            try {
+                if(RecordAttrHas(humpToLine2(f.getName()))){
+                    f.set(m, m.get(humpToLine2(f.getName())));
+                }else if(RecordAttrHas(f.getName())){
+                    f.set(m, m.get(f.getName()));
+                }
+            } catch (IllegalAccessException e) {
+
+            }
+        }
+    }
+
+
+
+
+    private String humpToLine2(String str) {
+        Pattern humpPattern = Pattern.compile("[A-Z]");
+        Matcher matcher = humpPattern.matcher(str);
+        StringBuffer sb = new StringBuffer();
+        while (matcher.find()) {
+            matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase());
+        }
+        matcher.appendTail(sb);
+        return sb.toString();
+
+    }
+
+    private String lineToHump(String str) {
+        Pattern linePattern = Pattern.compile("_(\\w)");
+        str = str.toLowerCase();
+        Matcher matcher = linePattern.matcher(str);
+        StringBuffer sb = new StringBuffer();
+        while (matcher.find()) {
+            matcher.appendReplacement(sb, matcher.group(1).toUpperCase());
+        }
+        matcher.appendTail(sb);
+        return sb.toString();
+    }
+
+    private Boolean RecordAttrHas(String columnName){
+        Set<String> names = TableMapping.me().getTable(this.getClass()).getColumnNameSet();
+        if(names.contains(columnName)){
+            return true;
+        }
+        return false;
+    }
+
+    public String json(){
+        return JSONObject.toJSONString(this);
+    }
+
+    public JSONObject jsonObject(){
+        return JSONObject.parseObject(json());
+    }
+
+}
diff --git a/src/main/java/com/common/core/enums/ResultCodeEnum.java b/src/main/java/com/common/core/enums/ResultCodeEnum.java
new file mode 100644
index 0000000..c54d1ba
--- /dev/null
+++ b/src/main/java/com/common/core/enums/ResultCodeEnum.java
@@ -0,0 +1,147 @@
+package com.common.core.enums;
+/**
+ * @DESCRIPTION:  缁撴灉浠g爜
+ * @USER: binhuang
+ * @DATE: 10/12/2021
+ */
+public enum ResultCodeEnum {
+
+
+
+    /**
+     * 鎴愬姛鐘舵��
+     */
+    RT_SUCCESS("0", "Success"),
+
+    /**
+     * 鏃犳晥token
+     */
+    RT_INVALID_TOKEN("401", "Time out, Please Login again"),
+
+    /**
+     *  娌℃湁鍙戠幇
+     */
+    RT_NOT_FOUND("404", "Invalid request url"),
+    /**
+     *  绯荤粺閿欒
+     */
+    RT_ERROR("500", "System exception"),
+    /**
+     *  绯荤粺閿欒
+     */
+    AWS_RT_ERROR("501", "AWS System exception"),
+    /**
+     *  璁块棶娆℃暟棰戠箒
+     */
+    BUSY_REQUEST_ERROR("502", "Busy request, please try it later!"),
+    /**
+     *  璁块棶娆℃暟棰戠箒
+     */
+    LARGE_REQUEST_ERROR("502", "Large request, please reduce your request body size!"),
+    /**
+     *  璁块棶娆℃暟棰戠箒
+     */
+    LOGIN_FAILED("503", "Login failed, please confirm your app id and secret!"),
+
+    /**
+     * 澶辫触
+     */
+    RT_FAILED("100", "Failed"),
+
+    /**
+     * 鍙傛暟閿欒
+     */
+    RT_PARAM_ERROR("101", "Request parameter check is invalid"),
+
+    /**
+     * 鎷掔粷璁块棶
+     */
+    RT_ACCESS_DENIED("120", "Access Denied"),
+
+    /**
+     * 绌哄紓甯�
+     */
+    RT_ACCESS_NULL("199", "Java Null Exception"),
+
+    /**
+     * 娌℃湁鏁版嵁
+     */
+    NO_DATA("112", "No %s data"),
+
+    /**
+     * 寰湇鍔″嚭閿�
+     */
+    RT_OUT_OF_SERVICE("130", "The server is under maintenance, please try again later"),
+
+    /**
+     * NOT NULL
+     */
+    PARA_NOT_NULL("140", "Parameters %s can not be null . please confirm again ."),
+
+    /**
+     * token鏃犳晥
+     */
+    TOKEN_INVALID("101", "Invalid token, Please confirm again"),
+
+    /**
+     * token涓虹┖
+     */
+    TOKEN_NULL("102", "Can not get token value, Please confirm again"),
+
+    /**
+     * token杩囨湡
+     */
+    TOKEN_EXPIRED("103", "Token expired, Please confirm again"),
+
+    /**
+     * 娌℃湁鏉冮檺
+     */
+    NO_PERMISSION("104", "No permission, Please confirm again"),
+    /** HTTP璋冪敤寮傚父 */
+    HTTP_INVOKE_ERROR("105","Http invoke error"),
+    /** HTTP璋冪敤寮傚父 */
+    QLM_TOKEN_ERROR("106","Can not get qianlima token, please contact administrator"),
+    
+
+    OPERATION_FAIL("115", "%s Operation failed"),
+
+    EXECUTE_FAIL("113", "Execute fail: %s"),
+
+    DUPLICATE_RESULT("114", "Warn,There is duplicate %s ."),
+    NOT_EXIT("115", "does not exist"),
+
+    IS_NULL("116","%s is null."),
+
+    EXCEED_FIELD_LENGTH("117","%s length exceed %s char"),
+    INTEGER_FIELD("118","%s must be an integer"),
+    SORT_INVALID("119","Sort order must be desc/asc"),
+    TIMEZONE_DATE_INVALID("126","Parameter %s must match pattern yyyy-MM-dd'T'HH:mm:ssXXX"),
+    FIELD_CONTENT_ERROR("121","Parameter field content error"),
+    SORT_NAME_INVALID("122","Sort name input error,please check"),
+    LOCK_FAIL("123","Lock failed, please retry later."),
+    DECRYPT_ERROR("124","Decryption error, please contact administrator."),
+    FILE_SIZE_EXCEED("125","File size exceeds 30M."),
+    EMAIL_ERROR("127","Send email failed, please contact administrator."),
+    ;
+
+
+    private String code;
+
+    /**
+     * 瀵瑰簲娑堟伅
+     */
+    private String msg;
+
+    ResultCodeEnum(String code, String msg) {
+        this.code = code;
+        this.msg = msg;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/common/core/enums/TableNameEnum.java b/src/main/java/com/common/core/enums/TableNameEnum.java
new file mode 100644
index 0000000..ed2d3a7
--- /dev/null
+++ b/src/main/java/com/common/core/enums/TableNameEnum.java
@@ -0,0 +1,71 @@
+package com.common.core.enums;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Ali
+ * Created on 10/05/2022
+ */
+public enum TableNameEnum {
+
+    //ACCOUNT("account","Account"), account涓嶆秹鍙妏i鏀归��
+    //瀹㈡埛浜哄憳
+    CONTACT("contact", "Contact"),
+    loanerApplication("loaner_application","loaner_application__c"),
+    loanerUser("loaner_user","loaner_user__c"),
+    mailMerge("mail_merge","Mail_Merge__c"),
+    opportunity("opportunity","Opportunity"),
+    ORDER("order","Order"),
+    QUOTES("quotes","Quotes__c"),
+    REPAIR("repair","Repair__c"),
+    SWO("swo","SWO__c"),
+    tsRepair("ts_repair","BusinessActivity__c"),
+    userFaultInfo("user_fault_info","User_FaultInfo__c");
+
+    //aws 琛ㄥ悕
+    private String awsTableName;
+    // sf 琛ㄥ悕
+    private String sfTableName;
+
+    public String getAwsTableName() {
+        return awsTableName;
+    }
+
+    public String getSfTableName() {
+        return sfTableName;
+    }
+
+    TableNameEnum(String awsTableName, String sfTableName) {
+        this.awsTableName = awsTableName;
+        this.sfTableName = sfTableName;
+    }
+
+    /**
+     * 鑾峰彇鍏ㄩ儴awsTableName鍊�
+     *
+     * @return List<String>
+     */
+    public static List<String> getAllAwsTableName() {
+        List<String> list = new ArrayList<String>();
+        for (TableNameEnum item : values()) {
+            list.add(item.getAwsTableName());
+        }
+        return list;
+    }
+
+    /**
+     * 閫氳繃aws琛ㄥ悕鑾峰彇sf琛ㄥ悕
+     *
+     * @param awsTableName
+     * @return
+     */
+    public static String getSfTableNameByAwsTableName(String awsTableName) {
+        for (TableNameEnum item : values()) {
+            if (item.getAwsTableName().equals(awsTableName)) {
+                return item.sfTableName;
+            }
+        }
+        return null;
+    }
+}
diff --git a/src/main/java/com/common/core/enums/YesNoEnum.java b/src/main/java/com/common/core/enums/YesNoEnum.java
new file mode 100644
index 0000000..e65d598
--- /dev/null
+++ b/src/main/java/com/common/core/enums/YesNoEnum.java
@@ -0,0 +1,39 @@
+package com.common.core.enums;
+
+/**
+ * @PROJECT_NAME: dtt-cdp-parent
+ * @DESCRIPTION: 鏄惁
+ * @USER: shengli
+ * @DATE: 27/09/2020 20:13
+ */
+public enum YesNoEnum {
+    NO(0, "NO"),
+    YES(1, "YES");
+
+    private Integer code;
+    private String remark;
+
+    YesNoEnum(Integer code, String remark) {
+        this.code = code;
+        this.remark = remark;
+    }
+
+    public Integer getCode() {
+        return code;
+    }
+
+    public String getRemark() {
+        return remark;
+    }
+
+    public static YesNoEnum parse(Integer code) {
+        if (code != null) {
+            for (YesNoEnum enumA : values()) {
+                if (enumA.getCode().compareTo(code) == 0) {
+                    return enumA;
+                }
+            }
+        }
+        return null;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/common/core/exception/BizException.java b/src/main/java/com/common/core/exception/BizException.java
new file mode 100644
index 0000000..98e8a52
--- /dev/null
+++ b/src/main/java/com/common/core/exception/BizException.java
@@ -0,0 +1,36 @@
+package com.common.core.exception;
+
+import com.common.core.enums.ResultCodeEnum;
+
+/**
+ * @author binhuang
+ * @desc 鑷畾涔夊紓甯�
+ * @date 10/12/2021
+ */
+public class BizException extends RuntimeException{
+    private String code;
+
+    /**
+     * @param message 寮傚父娑堟伅
+     */
+    public BizException(String message) {
+        this("100", message);
+    }
+
+    public BizException(ResultCodeEnum resultCodeEnum) {
+        this(resultCodeEnum.getCode(),resultCodeEnum.getMsg());
+    }
+
+    /**
+     * @param code    寮傚父浠g爜
+     * @param message 寮傚父娑堟伅
+     */
+    public BizException(String code, String message) {
+        super(message);
+        this.code = code;
+    }
+
+    public String getCode() {
+        return code;
+    }
+}
diff --git a/src/main/java/com/common/core/service/BaseCryptoService.java b/src/main/java/com/common/core/service/BaseCryptoService.java
new file mode 100644
index 0000000..e670688
--- /dev/null
+++ b/src/main/java/com/common/core/service/BaseCryptoService.java
@@ -0,0 +1,83 @@
+package com.common.core.service;
+
+import com.common.annotation.Table;
+import com.common.core.domain.BaseModel;
+
+import java.util.List;
+
+
+/**
+ * @author 寤栨尟閽�
+ * @Date 2022-01-12
+ * */
+public abstract class BaseCryptoService<M extends BaseModel<M>> extends CryptoService{
+
+    protected final M dao;
+
+    protected BaseCryptoService(M dao) {
+        this.dao = dao;
+    }
+
+
+    public String getTableName(){
+        Table table = dao.getClass().getAnnotation(Table.class);
+        return table.tableName();
+    }
+
+    /**
+     * 鏂板
+     * @return	鏄惁鏂板鎴愬姛
+     */
+    public boolean save(M model) {
+        model = encryptoModel(model);
+        return model.save();
+    }
+
+    /**
+     * 淇敼
+     * @return	鏄惁淇敼鎴愬姛
+     */
+    public boolean update(M model) {
+        model = encryptoModel(model);
+        return model.update();
+    }
+
+
+    /**
+     * 鏂板or淇敼
+     * @return	鏄惁鏂板or淇敼鎴愬姛
+     */
+    public boolean saveOrUpdate(M model){
+        if(null == model.getId()){
+            return save(model);
+        }else{
+            return update(model);
+        }
+    }
+
+    /**
+     *
+     * */
+    public boolean LogicDeleteById(Object id){
+        M m = findById(id);
+        m.setIsDelete(1);
+        return m.update();
+    }
+
+    /**
+     *
+     * */
+    public M findById(Object id){
+        M m = dao.findById(id);;
+        return decryptoModel(m);
+    }
+
+    /**
+     *
+     * */
+    public List<M> find(String sql, Object... objects){
+        List<M> listmodel = dao.find(sql,objects);
+        return decryptoModel(listmodel);
+    }
+
+}
diff --git a/src/main/java/com/common/core/service/CryptoService.java b/src/main/java/com/common/core/service/CryptoService.java
new file mode 100644
index 0000000..1e22a2e
--- /dev/null
+++ b/src/main/java/com/common/core/service/CryptoService.java
@@ -0,0 +1,431 @@
+package com.common.core.service;
+
+import com.common.annotation.NoEncryption;
+import com.common.core.crypto.ColumnHandler;
+import com.common.core.crypto.CryptoHandler;
+import com.common.core.enums.ResultCodeEnum;
+import com.common.core.exception.BizException;
+import com.jfinal.plugin.activerecord.Model;
+import com.jfinal.plugin.activerecord.Record;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @author 寤栨尟閽�
+ * @Date 2022-01-11 20:05
+ * */
+@Slf4j
+@Service
+public class CryptoService {
+    // 鐢ㄤ簬鏁版嵁搴撶殑鏌愪簺瀛楁鍔犲瘑瑙e瘑
+    public static final CryptoHandler<String, String> CRYPTO_HANDLER = new ColumnHandler();
+
+    /**
+     * @Title: 瀵箁ecord鏌愪簺鍒楄В瀵�
+     */
+    public List<Record> decryptoColumnRecord(List<Record> list, String[] columns){
+        int size = list.size();
+        for(int i = 0; i < size; i++){
+            Record record = list.get(i);
+            decryptoColumnRecord(record, columns);
+        }
+        return list;
+    }
+
+    public List<Record> decryptoColumnRecord(List<Record> list){
+        int size = list.size();
+        for(int i = 0; i < size; i++){
+            Record record = list.get(i);
+            decryptoRecord(record);
+        }
+        return list;
+    }
+
+    /**
+     * @Title: 瀵箁ecord鏌愪簺鍒楄В瀵�
+     */
+    public Record decryptoColumnRecord(Record record, String[] columns){
+        for(String column : columns){
+            if(isSM(column)) {
+                record.set(column, CRYPTO_HANDLER.decrypto(record.getStr(column)));
+            }
+        }
+        return record;
+    }
+
+    public Record decryptoRecord(Record record){
+        String[] columns = record.getColumnNames();
+        for(String column : columns){
+            if(isSM(column)) {
+                record.set(column, CRYPTO_HANDLER.decrypto(record.getStr(column)));
+            }
+        }
+        return record;
+    }
+
+    /** ========================     model鍔犲瘑 start  ======================== **/
+
+    /**
+     * @Title: 瀵筸odel鍏ㄩ儴鍒楀姞瀵�
+     */
+    public <T extends Model<T>> List<T> encryptoModel(List<T> list){
+        int size = list.size();
+        for(int i = 0; i < size; i++){
+            T model = list.get(i);
+            encryptoModel(model);
+        }
+        return list;
+    }
+
+    /**
+     * @Title: 瀵筸odel鏌愪簺鍒楀姞瀵�
+     */
+//    public <T extends Model<T>> List<T> encryptoColumnModel(List<T> list, String[] columns){
+//        int size = list.size();
+//        for(int i = 0; i < size; i++){
+//            T model = list.get(i);
+//            encryptoColumnModel(model, columns);
+//        }
+//        return list;
+//    }
+
+    /**
+     * @Title: 瀵筸odel鍏ㄩ儴鍒楀姞瀵�
+     */
+    public <T extends Model<T>> T encryptoModel(T model){
+        String[] columnNames = model._getAttrNames();
+        for(String column : columnNames){
+            if(isSM(column)) {
+                model.set(column, CRYPTO_HANDLER.encrypto(model.getStr(column)));
+            }
+        }
+        return model;
+    }
+
+    /**
+     * @Title: 瀵筸odel鏌愪簺鍒楀姞瀵�
+     */
+    public <T extends Model<T>> T encryptoColumnModel(T model, String[] columns){
+        for(String column : columns){
+            if(isSM(column)) {
+                model.set(column, CRYPTO_HANDLER.encrypto(model.getStr(column)));
+            }
+        }
+        return model;
+    }
+
+    /**
+     *
+     * @param model
+     * @param <T>
+     * @param columns
+     * @return
+     */
+//    public <T> T encryptColumnModel(T model, String[] columns){
+//        List<T> modelList = new ArrayList<>();
+//        if (model instanceof Object) {
+////            modelList.add(models);
+//            T t = encryptColumn(model, columns);
+//            return t;
+//        }else if (model instanceof List) {
+//            List models= (List) model;
+//            modelList.addAll(models);
+//            for(int i = 0; i < modelList.size(); i++){
+//                T modelOne = modelList.get(i);
+//                T t = encryptColumn(modelOne, columns);
+//            modelList.add(t);
+//            }
+//            return (T) modelList;
+//        }
+////        int size = modelList.size();
+////        List<T> ts = new ArrayList<>();
+////        for(int i = 0; i < size; i++){
+////            T model = modelList.get(i);
+////            T t = encryptColumn(model, columns);
+//////            modelList.add(t);
+////        }
+//
+//        return null;
+//    }
+
+    /**
+     * @Title: 瀵筸odel鏌愪簺鍒楀姞瀵�
+     */
+    public <T> List<T> encryptColumnModel(List<T> list, String[] columns) {
+        List<T> modelList = new ArrayList<>();
+        int size = list.size();
+        for(int i = 0; i < size; i++){
+            T model = list.get(i);
+            T t = encryptColumn(model, columns);
+            modelList.add(t);
+        }
+        return modelList;
+    }
+
+    /**
+     * @Title: 瀵筸odel鏌愪簺鍒楀姞瀵�
+     */
+    public <T> T encryptColumnModel(T model, String[] columns)  {
+        T t = encryptColumn(model, columns);
+        return t;
+    }
+
+    /**
+     *  瀵筸odel瀛楁鍔犲瘑
+     * @param model
+     * @param columns
+     * @param <T>
+     * @return
+     */
+    public <T> T encryptColumn(T model, String[] columns)  {
+        Field[] fields = model.getClass().getDeclaredFields();
+        for(String column : columns){
+            if(isSM(column)) {
+                for (int i = 0; i < fields.length; i++) {
+                    if (column.equals(fields[i].getName())) {
+                        String encrypto = CRYPTO_HANDLER.encrypto((String) getFieldValueByName(fields[i].getName(), model));
+                        fields[i].setAccessible(true);
+                        try {
+                            fields[i].set(model,encrypto);
+                        } catch (IllegalAccessException e) {
+                            log.error("encryptColumn failed",e);
+                        }
+                    }
+                }
+            }
+        }
+        return model;
+    }
+
+    /**
+     *  瀵筸odel娌℃湁@NoEncryption瀛楁鍔犲瘑
+     * @param model
+     * @param <T>
+     * @return
+     */
+    public <T> T encryptModelColumns(T model) {
+        Field[] fields = model.getClass().getDeclaredFields();
+        for (Field field : fields) {
+            if (isSM(field.getName()) && !field.isAnnotationPresent(NoEncryption.class)) {
+                Object value=getFieldValueByName(field.getName(), model);
+                if(value!=null && value.getClass().isArray()){
+                    String[] valueArray=(String[])value;
+                    ArrayList<String> list=new ArrayList();
+                    for (String s : valueArray) {
+                        list.add(CRYPTO_HANDLER.encrypto(s));
+                    }
+                    field.setAccessible(true);
+                    try {
+                        field.set(model, list.toArray(new String[0]));
+                    } catch (IllegalAccessException e) {
+                        log.error("encryptModelColumns failed",e);
+                    }
+                }else {
+                    String encrypto = CRYPTO_HANDLER.encrypto((String) value);
+                    field.setAccessible(true);
+                    try {
+                        field.set(model, encrypto);
+                    } catch (IllegalAccessException e) {
+                        log.error("encryptModelColumns failed",e);
+                    }
+                }
+            }
+        }
+        return model;
+    }
+
+    /**
+     *  瀵筸odel瀛楁瑙e瘑
+     * @param model
+     * @param columns
+     * @param <T>
+     * @return
+     */
+    public <T> T decryptColumn(T model, String[] columns) {
+        try {
+            Field[] fields = model.getClass().getDeclaredFields();
+            for (String column : columns) {
+                if (isSM(column)) {
+                    for (int i = 0; i < fields.length; i++) {
+                        if (column.equals(fields[i].getName())) {
+                            String encrypto = CRYPTO_HANDLER.decrypto((String) getFieldValueByName(fields[i].getName(), model));
+                            fields[i].setAccessible(true);
+                            fields[i].set(model, encrypto);
+                        }
+                    }
+                }
+            }
+            return model;
+        }catch (Exception e){
+            throw new BizException(ResultCodeEnum.DECRYPT_ERROR);
+        }
+    }
+
+    /**
+     *  瀵筸odel娌℃湁@NoEncryption瀛楁瑙e瘑
+     * @param model
+     * @param <T>
+     * @return
+     */
+    public <T> T decryptModelColumns(T model,Class clz) {
+        Field[] fields = clz.getDeclaredFields();
+        for (Field field : fields) {
+            if (isSM(field.getName()) && !field.isAnnotationPresent(NoEncryption.class)) {
+                String decrypto = CRYPTO_HANDLER.decrypto((String) getFieldValueByName(field.getName(), model));
+                field.setAccessible(true);
+                try {
+                    if(decrypto!=null)
+                    field.set(model, decrypto);
+                } catch (IllegalAccessException e) {
+                    log.error("decryptModelColumns failed",e);
+                }
+            }
+        }
+        return model;
+    }
+
+    /**
+     *  瀵筁ist<Model>娌℃湁@NoEncryption瀛楁瑙e瘑
+     * @param models
+     * @return
+     */
+    public <T> List<T> decryptModelListColumns(List<T> models,Class clz) {
+        return models.stream().map(model -> decryptModelColumns(model,clz)).collect(Collectors.toList());
+    }
+
+    /**
+     * 鏍规嵁灞炴�у悕鑾峰彇灞炴�у��
+     * @param fieldName
+     * @param o
+     * @return
+     */
+    private Object getFieldValueByName(String fieldName, Object o) {
+        try {
+            String firstLetter = fieldName.substring(0, 1).toUpperCase();
+            String getter = "get" + firstLetter + fieldName.substring(1);
+            Method method = o.getClass().getMethod(getter, new Class[]{});
+            Object value = method.invoke(o, new Object[]{});
+            return value;
+        } catch (Exception e) {
+            log.error("getFieldValueByName failed",e);
+        }
+        return null;
+    }
+
+    /** ========================     model鍔犲瘑 end  ======================== **/
+
+
+
+    /** ========================     model瑙e瘑 start  ======================== **/
+
+    /**
+     * @param <T>
+     * @Title: 瀵筸odel鍏ㄩ儴鍒楄В瀵�
+     */
+
+    public <T extends Model<T>> List<T> decryptoModel(List<T> list){
+        int size = list.size();
+        for(int i = 0; i < size; i++){
+            T model = list.get(i);
+            decryptoModel(model);
+        }
+        return list;
+    }
+
+    /**
+     * @param <T>
+     * @Title: 瀵筸odel鏌愪簺鍒楄В瀵�
+     */
+
+    public <T extends Model<T>> List<T> decryptoColumnModel(List<T> list, String[] columns){
+        int size = list.size();
+        for(int i = 0; i < size; i++){
+            T model = list.get(i);
+            decryptoColumnModel(model, columns);
+        }
+        return list;
+    }
+
+    /**
+     * @Title: 瀵筸odel鍏ㄩ儴鍒楄В瀵�
+     */
+    public <T extends Model<T>> T decryptoModel(T model){
+        String[] columnNames = model._getAttrNames();
+        for(String column : columnNames){
+            if(isSM(column)) {
+                model.set(column, CRYPTO_HANDLER.decrypto(model.getStr(column)));
+            }
+        }
+        return model;
+    }
+
+    /**
+     * @Title: 瀵筸odel鏌愪簺鍒楄В瀵�
+     */
+    public <T extends Model<T>> T decryptoColumnModel(T model, String[] columns){
+        for(String column : columns){
+            if(isSM(column)) {
+                model.set(column, CRYPTO_HANDLER.decrypto(model.getStr(column)));
+            }
+        }
+        return model;
+    }
+
+    public boolean isSM(String column){
+        if(!"id".equals(column) && !"create_time".equals(column) && !"update_time".equals(column) && !"is_delete".equals(column)
+                && !"dataId".equals(column)&& !"isDelete".equals(column)&& !"sfRecordId".equals(column)) {
+            return true;
+        }else{
+            return false;
+        }
+    }
+
+
+   /** ========================     model瑙e瘑 end  ======================== **/
+
+
+   public Object convertor(Object src, Object target){
+       Class<?> srcClass = src.getClass();
+       Class<?> targetClass = target.getClass();
+       Field[] fields = srcClass.getDeclaredFields();
+       for (Field field : fields) {
+           if (isSM(field.getName()) && !field.getName().contains("Encrypt")) {
+               field.setAccessible(true);
+               Object value = null;
+               try {
+                   value = field.get(src);
+                   Class<?> methodParamTypes = getMethodParamTypes(target, "set" + captureName(field.getName())+"Encrypt");
+                   Method method = targetClass.getDeclaredMethod("set" +captureName(field.getName())+"Encrypt",methodParamTypes);
+                   method.setAccessible(true);
+                   method.invoke(target,value);
+               } catch (Exception e) {
+                   log.error("convertor failed",e);
+               }
+           }
+       }
+       return target;
+   }
+
+    public String captureName(String name){
+        name = name.substring(0,1).toUpperCase()+name.substring(1);
+        return name;
+    }
+
+    public Class<?> getMethodParamTypes(Object classInstance,String methodName){
+        Method[] methods = classInstance.getClass().getMethods();
+        Class<?> param = null;
+        for (int i = 0; i < methods.length; i++) {
+            if (methodName.equals(methods[i].getName())) {
+                param = methods[i].getParameterTypes()[0];
+            }
+        }
+        return param;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/common/core/service/JsonCryptoService.java b/src/main/java/com/common/core/service/JsonCryptoService.java
new file mode 100644
index 0000000..0fe3164
--- /dev/null
+++ b/src/main/java/com/common/core/service/JsonCryptoService.java
@@ -0,0 +1,31 @@
+package com.common.core.service;
+
+import com.alibaba.fastjson.JSONObject;
+import com.common.core.crypto.ColumnHandler;
+import com.common.core.crypto.CryptoHandler;
+import org.springframework.stereotype.Service;
+
+import java.lang.reflect.Field;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @author 寤栨尟閽�
+ * @Date 2022-01-20
+ * */
+@Service
+public class JsonCryptoService {
+
+    public static final CryptoHandler<String, String> CRYPTO_HANDLER = new ColumnHandler();
+
+
+    public void encryptoJson(JSONObject object){
+
+    }
+
+    public void encryptoColumnJson(JSONObject object, String[] columns) {
+
+    }
+
+}
diff --git a/src/main/java/com/common/core/service/SFService.java b/src/main/java/com/common/core/service/SFService.java
new file mode 100644
index 0000000..985591f
--- /dev/null
+++ b/src/main/java/com/common/core/service/SFService.java
@@ -0,0 +1,142 @@
+package com.common.core.service;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.common.core.constant.GlobalConst;
+import com.common.core.exception.BizException;
+import com.common.core.utils.JsonUtils;
+import com.common.core.utils.RestUtil;
+import com.common.core.utils.SecretsManagerUtils;
+import com.common.core.utils.StringUtils;
+import com.common.redis.util.RedisUtil;
+import com.deloitte.system.request.SFTokenDto;
+import lombok.extern.slf4j.Slf4j;
+import okhttp3.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.env.Environment;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+
+import java.util.concurrent.TimeUnit;
+
+
+@Service
+@Slf4j
+public class SFService {
+    @Value("${salesforce.tokenUrl}")
+    private String tokenUrl;
+
+    private OkHttpClient okHttpClient;
+    @Autowired
+    private Environment env;
+    @Autowired
+    private SecretsManagerUtils secretsManagerUtils;
+    @Autowired
+    private RedisUtil redisUtil;
+    @Value("${salesforce.baseUrl}")
+    private String baseUrl;
+
+    /**
+     * 鑾峰彇salesforce token
+     * @return
+     */
+    public SFTokenDto getToken() {
+        SFTokenDto sfTokenDto = redisUtil.getObject(GlobalConst.SF_TOKEN_KEY,SFTokenDto.class);
+        okHttpClient= new OkHttpClient.Builder()
+                .connectTimeout(60*5, TimeUnit.SECONDS)
+                .readTimeout(60*5, TimeUnit.SECONDS)
+                .build();
+        JSONObject object = secretsManagerUtils.getSecret(env.getProperty("aws.secrets.systemauth"));
+        String sfGrantType = object.getString("sf_grant_type");
+        String sfClientId = object.getString("sf_client_id");
+        String sfClientSecret = object.getString("sf_client_secret");
+        String sfUsername = object.getString("sf_username");
+        String sfPassword = object.getString("sf_password");
+        // 璁剧疆璇锋眰浣�
+        RequestBody body = new FormBody.Builder()
+                .add("grant_type",sfGrantType )
+                .add("client_id",sfClientId )
+                .add("username", sfUsername)
+                .add("password", sfPassword)
+                .add("client_secret", sfClientSecret).build();
+        Request.Builder reqBuilder = new Request.Builder()
+                .url(tokenUrl)
+                .post(body)
+                .header("Accept", "application/json");
+        Call call = okHttpClient.newCall(reqBuilder.build());
+        Response response=null;
+        String responseBody =null;
+        try{
+            response = call.execute();
+            responseBody=response.body().string();
+            log.info("salesforce token ->respData: {}", responseBody);
+            if (StringUtils.isBlank(JsonUtils.string2Object(responseBody, SFTokenDto.class).getAccessToken())) {
+                log.error("鑾峰彇Salesforce token澶辫触, AccessToken涓虹┖");
+            }else {
+                sfTokenDto = JsonUtils.string2Object(responseBody, SFTokenDto.class);
+                redisUtil.set(GlobalConst.SF_TOKEN_KEY, sfTokenDto, GlobalConst.SF_TOKEN_EXPIRE);
+            }
+        }catch (Exception e){
+            log.error("鑾峰彇Salesforce token澶辫触: ",e);
+        }
+        return sfTokenDto;
+    }
+
+    public JSONArray querySFData(String sql) {
+        SFTokenDto tokenDto = getToken();
+        String accessToken = tokenDto.getAccessToken();
+        HttpHeaders header = new HttpHeaders();
+        header.add("Authorization", "Bearer " + accessToken);
+        StringBuilder idString = new StringBuilder();
+        // 鎷兼帴URL
+        StringBuilder queryUrl = idString.append(baseUrl).append("services/data/v54.0/query/?q=").append(sql);
+        // 璇锋眰鏁版嵁
+        JSONArray jsonArray = null;
+        try {
+            JSONObject jsonObject = RestUtil.get(queryUrl.toString(),header);
+            Object totalSize = jsonObject.get("totalSize");
+            Boolean done =(Boolean) jsonObject.get("done");
+            String nextRecordsUrl = jsonObject.getString("nextRecordsUrl");
+            jsonArray = jsonObject.getJSONArray("records");
+            if (totalSize == null) {
+                log.warn("璇锋眰Salesforce鏁版嵁澶辫触,result:{}",jsonObject);
+                throw new BizException("璇锋眰Salesforce鏁版嵁澶辫触");
+            }
+        }catch (Exception e){
+            log.error("璇锋眰Salesforce鏁版嵁澶辫触",e);
+            throw  e;
+        }
+        return jsonArray;
+    }
+
+    /**
+     * 璇锋眰SF鏇存柊鏁版嵁鎺ュ彛
+     *
+     * @param tableName 琛ㄥ悕
+     * @param recordId
+     * @param params
+     * @return 鏇存柊鏄惁鎴愬姛
+     */
+    public void updateSFData(String tableName,String recordId,JSONObject params) {
+        SFTokenDto tokenDto = getToken();
+        String accessToken = tokenDto.getAccessToken();
+        HttpHeaders header = new HttpHeaders();
+        header.add("Authorization", "Bearer " + accessToken);
+        header.add("Content-Type","application/json");
+        StringBuilder idString = new StringBuilder();
+        // 鎷兼帴URL
+        StringBuilder url = idString.append(baseUrl).append("services/data/v54.0/sobjects/").append(tableName).append("/").append(recordId);
+        log.info("updateSFData 璇锋眰鍦板潃锛歿}",url.toString());
+        // 璇锋眰鏁版嵁
+        ResponseEntity sfRes = RestUtil.patchNative(url.toString(), header, null, params.toJSONString());
+        log.info("鏇存柊Salesforce鏁版嵁,result:{}",sfRes.toString());
+        int statusCodeValue = sfRes.getStatusCodeValue();
+        //璇锋眰鎴愬姛 http status:204
+        if(statusCodeValue!=204){
+            log.error("鏇存柊Salesforce鏁版嵁澶辫触,result:{}",sfRes.toString());
+            throw new BizException("鏇存柊Salesforce鏁版嵁澶辫触");
+        }
+    }
+}
diff --git a/src/main/java/com/common/core/utils/ArrayUtils.java b/src/main/java/com/common/core/utils/ArrayUtils.java
new file mode 100644
index 0000000..3e63789
--- /dev/null
+++ b/src/main/java/com/common/core/utils/ArrayUtils.java
@@ -0,0 +1,9 @@
+package com.common.core.utils;
+
+/**
+ * @author xiaobzhou
+ * date 2020-01-21 15:33
+ */
+public class ArrayUtils extends org.apache.commons.lang3.ArrayUtils {
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/common/core/utils/BASE64DecodedMultipartFile.java b/src/main/java/com/common/core/utils/BASE64DecodedMultipartFile.java
new file mode 100644
index 0000000..5f520d8
--- /dev/null
+++ b/src/main/java/com/common/core/utils/BASE64DecodedMultipartFile.java
@@ -0,0 +1,86 @@
+package com.common.core.utils;
+
+import org.springframework.web.multipart.MultipartFile;
+import sun.misc.BASE64Decoder;
+
+import java.io.*;
+
+/**
+ * @Author holfeng
+ * @Date 15:21 10/02/2022
+ * @Version 1.0
+ **/
+public class BASE64DecodedMultipartFile implements MultipartFile {
+
+    private byte[] fileContent;
+    private String header;
+
+    public BASE64DecodedMultipartFile(byte[] fileContent, String header) {
+        this.fileContent = fileContent;
+        this.header = header.split(";")[0];
+    }
+
+    @Override
+    public String getName() {
+        return header.split("/")[1];
+    }
+
+    @Override
+    public String getOriginalFilename() {
+        return header.split("/")[1];
+    }
+
+    @Override
+    public String getContentType() {
+        return header.split(":")[1];
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return fileContent == null || fileContent.length == 0;
+    }
+
+    @Override
+    public long getSize() {
+        return fileContent.length;
+    }
+
+    @Override
+    public byte[] getBytes() throws IOException {
+        return fileContent;
+    }
+
+    @Override
+    public InputStream getInputStream() throws IOException {
+        return new ByteArrayInputStream(fileContent);
+    }
+
+    @Override
+    public void transferTo(File dest) throws IOException, IllegalStateException {
+        FileOutputStream stream=null;
+        try {
+            stream = new FileOutputStream(dest);
+            stream.write(fileContent);
+        }catch (Exception e){
+            throw e;
+        }finally {
+            if(stream!=null)stream.close();
+        }
+    }
+
+
+    public static MultipartFile base64ToMultipart(String base64) throws IOException {
+        String[] baseStrs = base64.split(",");
+        BASE64Decoder decoder = new BASE64Decoder();
+        byte[] b = new byte[0];
+        b = decoder.decodeBuffer(baseStrs[1]);
+        for (int i = 0; i < b.length; ++i) {
+            if (b[i] < 0) {
+                b[i] += 256;
+            }
+        }
+        return new BASE64DecodedMultipartFile(b, baseStrs[0]);
+    }
+
+
+}
diff --git a/src/main/java/com/common/core/utils/BeanHelper.java b/src/main/java/com/common/core/utils/BeanHelper.java
new file mode 100644
index 0000000..bbd9377
--- /dev/null
+++ b/src/main/java/com/common/core/utils/BeanHelper.java
@@ -0,0 +1,1076 @@
+package com.common.core.utils;
+
+import org.hibernate.Hibernate;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.FatalBeanException;
+import org.springframework.util.Assert;
+import org.springframework.util.ReflectionUtils;
+
+import javax.persistence.Column;
+import javax.persistence.Id;
+import javax.validation.constraints.NotNull;
+import java.beans.PropertyDescriptor;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.UUID;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * Bean宸ュ叿绫�.
+ *
+ * @author LuoGang
+ * @date 2019-04-13 16:53
+ */
+public class BeanHelper {
+
+    /**
+     * 鍒嗛殧绗﹀彿
+     */
+    public static final char UNDERLINE = '_';
+
+    /**
+     * 绗﹀彿.
+     */
+    public static final String POINT = ".";
+
+    /**
+     * 绯荤粺鐨勬崲琛岀
+     */
+    public static final String LINE_SEPARATOR = System.getProperty("line.separator", "\n");
+
+    /**
+     * 鏍规嵁class缂撳瓨鍏舵墍鏈夌殑PropertyDescriptor
+     */
+    private static Map<Class<?>, PropertyDescriptor[]> propertyDescriptorsCache = new HashMap<>();
+
+    /**
+     * 寰楀埌cls瀹氫箟鐨勬墍鏈夊瓧娈碉紝涓嶅寘鍚玞lass
+     *
+     * @param cls Class
+     * @return cls涓嬪畾涔夌殑瀛楁
+     */
+    public static PropertyDescriptor[] getPropertyDescriptors(Class<?> cls) {
+        PropertyDescriptor[] cache = propertyDescriptorsCache.get(cls);
+        if (cache == null) {
+            List<PropertyDescriptor> pds = new ArrayList<>();
+            PropertyDescriptor[] arr = BeanUtils.getPropertyDescriptors(cls);
+            for (PropertyDescriptor pd : arr) {
+                if ("class".equals(pd.getName())) {
+                    // 涓嶉渶瑕乧lass杩欎釜灞炴��
+                    continue;
+                }
+
+                pds.add(pd);
+            }
+
+            cache = pds.toArray(new PropertyDescriptor[pds.size()]);
+            propertyDescriptorsCache.put(cls, cache);
+        }
+
+        return cache;
+    }
+
+    /**
+     * 寰楀埌obj瀵硅薄瀹氫箟鐨勬墍鏈夊瓧娈点�傛敞鎰弌bj鍙兘鏄疕ibernate鐨勬墭绠″璞★紝瑕佸鐞�
+     *
+     * @param obj
+     * @return obj瀹氫箟鐨勫瓧娈�
+     * @see {@link Hibernate#getClass(Object)}
+     */
+    public static PropertyDescriptor[] getPropertyDescriptors(Object obj) {
+        Class<?> cls = Hibernate.getClass(obj);
+        return getPropertyDescriptors(cls);
+    }
+
+    /**
+     * 寰楀埌灞炴�х殑绫诲瀷锛岃繑鍥瀋lass name.
+     *
+     * @param entity       瀹炰綋绫�
+     * @param propertyName 瀛楁鍚�
+     * @return
+     */
+    public static final String getPropertyType(Object entity, String propertyName) {
+        PropertyDescriptor pd = BeanUtils.getPropertyDescriptor(Hibernate.getClass(entity), propertyName);
+        if (null != pd) {
+            return pd.getPropertyType().getName();
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * 寰楀埌灞炴�х殑PropertyDescriptor
+     *
+     * @param entity       瀹炰綋瀵硅薄
+     * @param propertyName 瀛楁鍚�
+     * @return 瀛楁鐨凱ropertyDescriptor瀵硅薄
+     */
+    public static final PropertyDescriptor getPropertyDescriptor(Object entity, String propertyName) {
+        PropertyDescriptor pd = BeanUtils.getPropertyDescriptor(Hibernate.getClass(entity), propertyName);
+        return pd;
+    }
+
+    /**
+     * 涓哄璞ntity璁剧疆value.
+     *
+     * @param entity       瀹炰綋绫�
+     * @param propertyName 瀛楁鍚�
+     * @param value        鍊�
+     */
+    public static final void setPropertyValue(Object entity, String propertyName, Object value) {
+        if (propertyName.indexOf(POINT) > -1) {
+            String[] propertyNames = StringUtils.split(propertyName, '.');
+            for (int i = 0, l = propertyNames.length - 1; i < l; i++) {
+                entity = getPropertyValue(entity, propertyNames[i]);
+                if (entity == null) {
+                    return;
+                }
+            }
+            propertyName = propertyNames[propertyNames.length - 1];
+        }
+        PropertyDescriptor pd = BeanUtils.getPropertyDescriptor(Hibernate.getClass(entity), propertyName);
+        if (pd != null) {
+            setPropertyValue(entity, pd, value);
+        }
+    }
+
+    public static final void setPropertyValue(Object entity, String propertyName, Object value,Class clazz) {
+        PropertyDescriptor pd = BeanUtils.getPropertyDescriptor(clazz, propertyName);
+        if (pd != null) {
+            setPropertyValue(entity, pd, value);
+        }
+    }
+    /**
+     * 涓哄璞ntity璁剧疆value.
+     *
+     * @param entity 瀹炰綋绫�
+     * @param pd     瑕佽鍙栫殑灞炴�ropertyDescriptord瀵硅薄
+     * @param value  鍊�
+     */
+    public static final void setPropertyValue(@NotNull Object entity, @NotNull PropertyDescriptor pd, Object value) {
+        Method writeMethod = pd.getWriteMethod();
+        if (writeMethod != null) {
+            try {
+                value = BeanHelper.convert(value, pd.getPropertyType());
+                if (value == null || pd.getPropertyType().isAssignableFrom(value.getClass())) { // 蹇呴』鏄悓鏍风被鍨嬬殑鎵嶅尮閰�,鍚﹀垯涓嶅鐞�
+                    ReflectionUtils.invokeMethod(writeMethod, entity, value);
+                }
+            } catch (Exception e) {
+                throw new RuntimeException(entity.getClass() + POINT + pd.getName() + "鍐欏叆鍊硷細" + value + "鍑虹幇寮傚父\n" + e.getMessage(), e);
+            }
+        }
+    }
+
+    /**
+     * 寰楀埌entity涓璸ropertyName灞炴�х殑鍊�.
+     *
+     * @param entity       瀹炰綋瀵硅薄
+     * @param propertyName 瑕佽鍙栫殑灞炴�у悕
+     * @return 寰楀埌鐨勫��
+     */
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    public static final <T> T getPropertyValue(Object entity, String propertyName) {
+        if (entity == null) {
+            return null;
+        }
+        if (entity instanceof Map) {
+            return (T) ((Map) entity).get(propertyName);
+        }
+
+        if (propertyName.indexOf(POINT) > 0) {
+            String[] propertyNames = StringUtils.split(propertyName, '.');
+            for (String name : propertyNames) {
+                entity = getPropertyValue(entity, name);
+            }
+            return (T) entity;
+        }
+
+        PropertyDescriptor pd = BeanUtils.getPropertyDescriptor(Hibernate.getClass(entity), propertyName);
+        if (pd == null) {
+            Field field = ReflectionUtils.findField(Hibernate.getClass(entity), propertyName);
+            if (field != null) {
+                Method setAccessible = ReflectionUtils.findMethod(field.getClass(), "setAccessible", Boolean.TYPE);
+                ReflectionUtils.invokeMethod(setAccessible, field, true);
+                return (T) ReflectionUtils.getField(field, entity);
+            }
+        }
+        return getPropertyValue(entity, pd);
+    }
+
+    /**
+     * 寰楀埌entity涓璓ropertyDescriptor灞炴�х殑鍊�.
+     *
+     * @param entity 瀹炰綋瀵硅薄
+     * @param pd     瑕佽鍙栫殑灞炴�ropertyDescriptord瀵硅薄
+     * @return 寰楀埌鐨勫��
+     */
+    @SuppressWarnings("unchecked")
+    public static final <T> T getPropertyValue(Object entity, PropertyDescriptor pd) {
+        if (entity == null || pd == null || pd.getReadMethod() == null) {
+            return null;
+        }
+        Method readMethod = pd.getReadMethod();
+        try {
+            // if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
+            // readMethod.setAccessible(true);
+            // }
+            // return (T) readMethod.invoke(entity);
+            return (T) ReflectionUtils.invokeMethod(readMethod, entity);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+
+    }
+
+    /**
+     * 寰楀埌缁勬垨Collection涓笅鏍噄ndex鐨勫��.
+     *
+     * @param array 鏁扮粍鎴朇ollection
+     * @param index 涓嬫爣,0寮�濮�
+     * @return 寰楀埌鐨勫��
+     */
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    public static final <T> T getValue(Object array, int index) {
+        if (array == null || index < 0) {
+            return null;
+        }
+
+        if (array instanceof Collection) { // 闆嗗悎
+            if (((Collection) array).size() <= index) { // 涓嬫爣瓒婄晫
+                return null;
+            }
+
+            if (array instanceof List) {
+                return (T) (((List) array).get(index));
+            }
+
+            Iterator it = ((Collection) array).iterator();
+            while (index-- > 0) {
+                it.next();
+            }
+
+            return (T) it.next();
+        }
+
+        if (array.getClass().isArray()) { // 鏁扮粍
+            if (Array.getLength(array) <= index) { // 涓嬫爣瓒婄晫
+                return null;
+            }
+            return (T) Array.get(array, index);
+        }
+        return null;
+    }
+
+    /**
+     * 鏂板缓clazz瀵硅薄,骞跺鍒秙ource涓殑灞炴��
+     *
+     * @param source
+     * @param clazz
+     * @return
+     */
+    public static <T> T copyAs(Object source, Class<T> clazz) {
+        T target = BeanUtils.instantiateClass(clazz);
+        copy(source, target);
+        return target;
+    }
+
+    /**
+     * 澶嶅埗涓�涓摼琛紝鐩爣閾捐〃鑺傜偣绫诲瀷鏄寚瀹氱殑Class
+     *
+     * @param list  婧愭暟鎹�
+     * @param clazz 鐩爣閾捐〃鑺傜偣绫诲瀷
+     * @return
+     */
+    public static <T> List<T> copyAs(Collection<?> list, Class<T> clazz) {
+        return list.stream().map(source -> copyAs(source, clazz)).collect(Collectors.toList());
+    }
+
+    /**
+     * 瀵圭粰瀹氱殑source瀵硅薄鍒濆鍖栨墍鏈変繚鐣欑被鍨嬬殑瀛楁榛樿鍊笺�傚叾涓暟瀛楅粯璁や负0锛宐oolean榛樿涓篺alse.
+     *
+     * @param source           瑕佸鐞嗙殑瀵硅薄
+     * @param ignoreProperties 涓嶉渶瑕佸鐞嗙殑瀛楁
+     */
+    public static final <T> void initPrimitiveFields(T source, String... ignoreProperties) {
+        Class<?> cls = Hibernate.getClass(source);
+        PropertyDescriptor[] targetPds = getPropertyDescriptors(cls);
+        List<String> ignoreList = (ignoreProperties != null) ? Arrays.asList(ignoreProperties) : Collections.emptyList();
+        Class<?> propertyClass;
+        for (PropertyDescriptor pd : targetPds) {
+            if (ignoreList.contains(pd.getName()) || pd.getWriteMethod() == null || getPropertyValue(source, pd) != null) {
+                continue;
+            }
+            propertyClass = pd.getPropertyType();
+            if (Boolean.class.equals(propertyClass) || Boolean.TYPE.equals(propertyClass)) {
+                // boolean绫诲瀷榛樿涓篺alse
+                setPropertyValue(source, pd, false);
+            } else if (Number.class.isAssignableFrom(propertyClass)) {
+                // 鏁板瓧绫诲瀷榛樿涓�0
+                setPropertyValue(source, pd, 0);
+            }
+        }
+    }
+
+    /**
+     * 鐩存帴clone涓�涓璞�
+     *
+     * @param source           瑕佸鍒剁殑瀵硅薄
+     * @param ignoreProperties 蹇界暐鐨勫瓧娈�
+     * @return 澶嶅埗鐨勫璞�
+     */
+    @SuppressWarnings("unchecked")
+    public static final <T> T copy(T source, String... ignoreProperties) {
+        Class<T> cls = Hibernate.getClass(source);
+        T obj = BeanUtils.instantiateClass(cls);
+        return BeanHelper.copy(source, obj, ignoreProperties);
+    }
+
+    /**
+     * 灏唖ource涓墍鏈変笉涓簄ull鐨勫�糲opy鍒皌arget涓�.
+     * 涓巤@link BeanUtils#copyProperties(Object, Object, String...)}涓嶅悓涔嬪鍦ㄤ簬鏈柟娉曚笉copy涓簄ull鐨勫睘鎬�
+     *
+     * @param source           瑕佸鍒剁殑婧愬璞�
+     * @param target           鐩爣瀵硅薄
+     * @param ignoreProperties 闇�瑕佸拷鐣ョ殑瀛楁
+     * @return 杩斿洖target
+     * @see BeanUtils#copyProperties(Object, Object, String...)
+     */
+    public static final <T> T copy(Object source, T target, String... ignoreProperties) {
+        return BeanHelper.copy(source, target, false, ignoreProperties);
+    }
+
+    /**
+     * 灏唖ource涓墍鏈変笉涓簄ull鐨凟ncrypt鍊糲opy鍒皌arget涓�.(eg:copy soure.nameEncrypt to target.name)
+     * 涓巤@link BeanUtils#copyProperties(Object, Object, String...)}涓嶅悓涔嬪鍦ㄤ簬鏈柟娉曚笉copy涓簄ull鐨勫睘鎬�
+     *
+     * @param source           瑕佸鍒剁殑婧愬璞�
+     * @param target           鐩爣瀵硅薄
+     * @param ignoreProperties 闇�瑕佸拷鐣ョ殑瀛楁
+     * @return 杩斿洖target
+     * @see BeanUtils#copyProperties(Object, Object, String...)
+     */
+    public static final <T> T copyEncrypt(Object source, T target, String... ignoreProperties) {
+        return BeanHelper.copyEncrypt(source, target, false,"Encrypt", ignoreProperties);
+    }
+
+    /**
+     * 灏唖ource涓墍鏈変笉涓簄ull鐨勫�糲opy鍒皌arget涓�.
+     * 浠呭鍒跺熀纭�绫诲瀷鐨勬暟鎹�,鍙JAVA淇濈暀绫诲瀷/鏁板瓧/String/Date浠ュ強鍏舵暟缁勭殑鏁版嵁杩涜澶嶅埗
+     * 涓巤@link BeanUtils#copyProperties(Object, Object, String...)}涓嶅悓涔嬪鍦ㄤ簬鏈柟娉曚笉copy涓簄ull鐨勫睘鎬�
+     *
+     * @param source           瑕佸鍒剁殑婧愬璞�
+     * @param target           鐩爣瀵硅薄
+     * @param ignoreProperties 闇�瑕佸拷鐣ョ殑瀛楁
+     * @return 杩斿洖target
+     * @see BeanUtils#copyProperties(Object, Object, String...)
+     */
+    public static final <T> T copyBasic(Object source, T target, String... ignoreProperties) {
+        return BeanHelper.copy(source, target, true, ignoreProperties);
+    }
+
+    /**
+     * 鍒ゆ柇鎸囧畾鐨刢lazz鏄惁涓哄熀纭�鏁版嵁绫诲瀷
+     *
+     * @param clazz
+     * @return
+     */
+    public static boolean isBasicClass(Class<?> clazz) {
+        if (clazz.isArray()) {
+            clazz = clazz.getComponentType();
+        }
+        if ((clazz.isPrimitive()// JAVA鐨勪繚鐣欑被鍨�,boolean, byte, char, short, int, long, float, double.
+                || Number.class.isAssignableFrom(clazz) // 鏁板瓧
+                || Boolean.class.isAssignableFrom(clazz) // Boolean
+                || Character.class.isAssignableFrom(clazz) // Character
+                || CharSequence.class.isAssignableFrom(clazz) // 瀛楃涓�
+                || Date.class.isAssignableFrom(clazz))// 鏃ユ湡
+        ) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * 灏唖ource涓墍鏈変笉涓簄ull鐨勫�糲opy鍒皌arget涓�.
+     * 涓巤@link BeanUtils#copyProperties(Object, Object, String...)}涓嶅悓涔嬪鍦ㄤ簬鏈柟娉曚笉copy涓簄ull鐨勫睘鎬�
+     *
+     * @param source           瑕佸鍒剁殑婧愬璞�
+     * @param target           鐩爣瀵硅薄
+     * @param basicOnly        鏄惁浠呭鍒跺熀纭�绫诲瀷鐨勬暟鎹�,濡傛灉涓簍rue,鍒欏彧瀵笿AVA淇濈暀绫诲瀷/鏁板瓧/String/Date浠ュ強鍏舵暟缁勭殑鏁版嵁杩涜澶嶅埗
+     * @param ignoreProperties 闇�瑕佸拷鐣ョ殑瀛楁
+     * @return 杩斿洖target
+     * @see BeanUtils#copyProperties(Object, Object, String...)
+     */
+    public static final <T> T copy(Object source, T target, boolean basicOnly, String... ignoreProperties) {
+        Assert.notNull(source, "Source must not be null");
+        Assert.notNull(target, "Target must not be null");
+
+        Class<?> cls = Hibernate.getClass(source);
+        Class<?> actualEditable = Hibernate.getClass(target);
+
+        PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);
+        List<String> ignoreList = (ignoreProperties != null) ? Arrays.asList(ignoreProperties) : null;
+
+        for (PropertyDescriptor targetPd : targetPds) {
+            if (basicOnly) {
+                Class<?> propertyType = targetPd.getPropertyType();
+                if (propertyType.isArray()) {
+                    propertyType = propertyType.getComponentType();
+                }
+                if (!isBasicClass(propertyType)) {
+                    // 澶嶆潅瀵硅薄涓嶅鐞�
+                    continue;
+                }
+            }
+
+            Method writeMethod = targetPd.getWriteMethod();
+            if (writeMethod != null && (ignoreList == null || (!ignoreList.contains(targetPd.getName())))) {
+                PropertyDescriptor sourcePd = BeanUtils.getPropertyDescriptor(cls, targetPd.getName());
+                if (sourcePd != null) {
+                    Method readMethod = sourcePd.getReadMethod();
+                    if (readMethod != null) {// && ClassUtils.isAssignable(writeMethod.getParameterTypes()[0], readMethod.getReturnType())) {
+                        try {
+                            // if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
+                            // readMethod.setAccessible(true);
+                            // }
+                            Object value = ReflectionUtils.invokeMethod(readMethod, source);
+                            if (value == null) {
+                                // 涓簄ull鐨勫�间笉澶勭悊
+                                continue;
+                            }
+
+                            setPropertyValue(target, targetPd, value);
+
+                        } catch (Throwable ex) {
+                            throw new FatalBeanException("Could not copy property '" + targetPd.getName() + "' from source to target", ex);
+                        }
+                    }
+                }
+            }
+        }
+
+        return target;
+    }
+
+    /**
+     * 灏唖ource涓墍鏈変笉涓簄ull鐨勫�糲opy鍒皌arget涓�.
+     * 涓巤@link BeanUtils#copyProperties(Object, Object, String...)}涓嶅悓涔嬪鍦ㄤ簬鏈柟娉曚笉copy涓簄ull鐨勫睘鎬�
+     *
+     * @param source           瑕佸鍒剁殑婧愬璞�
+     * @param target           鐩爣瀵硅薄
+     * @param basicOnly        鏄惁浠呭鍒跺熀纭�绫诲瀷鐨勬暟鎹�,濡傛灉涓簍rue,鍒欏彧瀵笿AVA淇濈暀绫诲瀷/鏁板瓧/String/Date浠ュ強鍏舵暟缁勭殑鏁版嵁杩涜澶嶅埗
+     * @param suffix           瑕佸鍒剁殑瀛楁娣诲姞鍚庣紑
+     * @param ignoreProperties 闇�瑕佸拷鐣ョ殑瀛楁
+     * @return 杩斿洖target
+     * @see BeanUtils#copyProperties(Object, Object, String...)
+     */
+    public static final <T> T copyEncrypt(Object source, T target, boolean basicOnly,String suffix, String... ignoreProperties) {
+        Assert.notNull(source, "Source must not be null");
+        Assert.notNull(target, "Target must not be null");
+
+        Class<?> cls = Hibernate.getClass(source);
+        Class<?> actualEditable = Hibernate.getClass(target);
+
+        PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);
+        List<String> ignoreList = (ignoreProperties != null) ? Arrays.asList(ignoreProperties) : null;
+
+        for (PropertyDescriptor targetPd : targetPds) {
+            if (basicOnly) {
+                Class<?> propertyType = targetPd.getPropertyType();
+                if (propertyType.isArray()) {
+                    propertyType = propertyType.getComponentType();
+                }
+                if (!isBasicClass(propertyType)) {
+                    // 澶嶆潅瀵硅薄涓嶅鐞�
+                    continue;
+                }
+            }
+
+            Method writeMethod = targetPd.getWriteMethod();
+            if (writeMethod != null && (ignoreList == null || (!ignoreList.contains(targetPd.getName())))) {
+                PropertyDescriptor sourcePd = BeanUtils.getPropertyDescriptor(cls, targetPd.getName()+suffix);
+                if (sourcePd != null) {
+                    Method readMethod = sourcePd.getReadMethod();
+                    if (readMethod != null) {// && ClassUtils.isAssignable(writeMethod.getParameterTypes()[0], readMethod.getReturnType())) {
+                        try {
+                            // if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
+                            // readMethod.setAccessible(true);
+                            // }
+                            Object value = ReflectionUtils.invokeMethod(readMethod, source);
+                            if (value == null) {
+                                // 涓簄ull鐨勫�间笉澶勭悊
+                                continue;
+                            }
+
+                            setPropertyValue(target, targetPd, value);
+
+                        } catch (Throwable ex) {
+                            throw new FatalBeanException("Could not copy property '" + targetPd.getName() + "' from source to target", ex);
+                        }
+                    }
+                }
+            }
+        }
+
+        return target;
+    }
+
+    /**
+     * 鐢熸垚32浣嶇殑uuid.娌℃湁鐭í绾�"-".
+     *
+     * @return 娌℃湁鐭í绾跨殑UUID
+     * @see UUID#randomUUID()
+     */
+    public static final String uuid() {
+        return UUID.randomUUID().toString().replace("-", "");
+    }
+
+    /**
+     * 鍒ゆ柇a鏄惁鍜宐鐩哥瓑.
+     * 濡傛灉鍧囨槸绌虹櫧瀛楃,瑙嗕负鐩哥瓑; null鍜岀┖鐧藉瓧绗﹁涓虹浉绛�; 濡傛灉a,b鍧囦负瀛楃涓�,鍖哄垎澶у皬鍐�.蹇界暐瀛楃涓插墠鍚庣殑绌烘牸
+     *
+     * @param a
+     * @param b
+     * @return a鏄惁绛変簬b
+     */
+    public static boolean equals(Object a, Object b) {
+        if (Objects.equals(a, b)) {
+            return true;
+        }
+        if (a == null) {
+            return b instanceof String && StringUtils.isBlank((String) b);
+        }
+        if (b == null) {
+            return a instanceof String && StringUtils.isBlank((String) a);
+        }
+
+        if (a instanceof String && b instanceof String) {
+            // 涓や釜鍧囦负瀛楃涓�
+            if (StringUtils.isBlank((String) a) && StringUtils.isBlank((String) b)) {
+                return true;
+            }
+            if (((String) a).trim().equals(((String) b).trim())) {
+                return true;
+            }
+        }
+        if (a instanceof Date && b instanceof Date) {
+            return ((Date) a).getTime() == ((Date) b).getTime();
+        }
+
+        if (a instanceof Number && b instanceof Number) {
+            return new BigDecimal(a.toString()).equals(new BigDecimal(b.toString()));
+        }
+
+        if (a.getClass().equals(b.getClass())) {
+            PropertyDescriptor[] pds = getPropertyDescriptors(a.getClass());
+            for (PropertyDescriptor pd : pds) {
+                if (!equals(getPropertyValue(a, pd), getPropertyValue(b, pd))) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * 鍒ゆ柇a鏄惁鍜宐鐩哥瓑.蹇界暐瀛楃涓插墠鍚庣殑绌烘牸
+     * 濡傛灉鍧囨槸绌虹櫧瀛楃,瑙嗕负鐩哥瓑; null鍜岀┖鐧藉瓧绗﹁涓虹浉绛�; 濡傛灉a,b鍧囦负瀛楃涓�,涓嶅尯鍒嗗ぇ灏忓啓.
+     *
+     * @param a
+     * @param b
+     * @return a鏄惁绛変簬b
+     */
+    public static boolean equalsIgnoreCase(Object a, Object b) {
+        if (a instanceof String && b instanceof String) { // 涓や釜鍧囦负瀛楃涓�
+            if (StringUtils.isBlank((String) a) && StringUtils.isBlank((String) b)) {
+                return true;
+            }
+            if (((String) a).trim().equalsIgnoreCase(((String) b).trim())) {
+                return true;
+            }
+        } else {
+            return equals(a, b);
+        }
+
+        return false;
+    }
+
+    /**
+     * 姣旇緝鏁扮粍鏄惁鐩稿悓锛屽鏋滄槸瀛楃涓�,蹇界暐澶у皬鍐欏拰鍓嶅悗鐨勭┖鏍�
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static boolean equalsIgnoreCase(Object[] a, Object[] b) {
+        if (a == b) {
+            return true;
+        }
+        if (a == null || b == null) {
+            return false;
+        }
+
+        int length = a.length;
+        if (b.length != length) {
+            return false;
+        }
+
+        for (int i = 0; i < length; i++) {
+            if (!equalsIgnoreCase(a[i], b[i])) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * 姣旇緝鏁扮粍鐨勫墠length涓暟鎹槸鍚︾浉鍚岋紝濡傛灉鏄瓧绗︿覆,蹇界暐澶у皬鍐欏拰鍓嶅悗鐨勭┖鏍�
+     *
+     * @param a
+     * @param b
+     * @return
+     */
+    public static boolean equalsIgnoreCase(Object[] a, Object[] b, int length) {
+        if (a.length > length) {
+            a = ArrayUtils.subarray(a, 0, length);
+        }
+        if (b.length > length) {
+            b = ArrayUtils.subarray(b, 0, length);
+        }
+        return equalsIgnoreCase(a, b);
+    }
+
+    /**
+     * 杈撳嚭寮傚父鐨勫爢鏍堜俊鎭�.
+     *
+     * @param e 寮傚父淇℃伅
+     * @return
+     */
+    public static String toString(Throwable e) {
+        StringWriter w = new StringWriter();
+        PrintWriter pw = new PrintWriter(w);
+        e.printStackTrace(pw);
+        return w.toString();
+    }
+
+    /**
+     * 灏嗗垪鍚嶈浆鎹负鎸夐┘宄板懡鍚嶇殑灞炴�у悕.
+     *
+     * @param columnName 鍒楀悕
+     * @return JAVA椹煎嘲鍛藉悕瑙勮寖鐨勫睘鎬у悕
+     */
+    public static String columnToProperty(String columnName) {
+        char[] chars = columnName.toLowerCase().toCharArray();
+        StringBuilder buf = new StringBuilder();
+        boolean flag = false;
+        for (int i = 0, l = chars.length; i < l; i++) {
+            char c = chars[i];
+            if (c == '_' || c == '-' || c == ' ') { // 涓嬩竴涓崟璇嶅ぇ鍐�
+                flag = buf.length() > 0;
+            } else {
+                buf.append(flag ? Character.toUpperCase(c) : c);
+                flag = false;
+            }
+        }
+        return buf.toString();
+    }
+
+    /**
+     * java瀛楁鍚嶈浆鎹负鍒楀悕.鍗曡瘝涔嬮棿鐢ㄤ笅鍒掔嚎_闅斿紑.
+     *
+     * @param propertyName 灞炴�у悕
+     * @return 杞崲鍚庣殑鍒楀悕
+     */
+    public static String propertyToColumn(String propertyName) {
+        char[] chars = propertyName.toCharArray();
+        StringBuilder buf = new StringBuilder();
+        for (int i = 0, l = chars.length; i < l; i++) {
+            char c = chars[i];
+            if (Character.isUpperCase(c)) {
+                // 鍗曡瘝澶у啓
+                if (buf.length() > 0) {
+                    buf.append('_');
+                }
+            }
+            buf.append(c);
+        }
+        return buf.toString().toLowerCase();
+    }
+
+    /**
+     * 寰楀埌pd灞炴�х殑鍒楀悕.
+     *
+     * @param pd 瑕佸緱鍒板垪鍚嶇殑灞炴��
+     * @return 鍒楀悕
+     */
+    public static String getColumnName(PropertyDescriptor pd) {
+        Column column = pd.getReadMethod() == null ? null : pd.getReadMethod().getAnnotation(Column.class);
+        if (column == null && pd.getWriteMethod() != null) {
+            // getter鏂规硶娌℃湁@Column娉ㄨВ,閫氳繃setter鏂规硶璇诲彇
+            column = pd.getWriteMethod().getAnnotation(Column.class);
+        }
+
+        if (column != null && !column.name().isEmpty()) {
+            return column.name();
+        }
+        return propertyToColumn(pd.getName());
+    }
+
+    /**
+     * 灏哅ap涓殑鏁版嵁璇诲彇鍒板埌瀹炰綋瀵硅薄涓�.
+     *
+     * @param data   Map鏁版嵁.
+     * @param entity 瀹炰綋瀵硅薄.
+     * @return 鍙傛暟entity鏈韩.
+     */
+    public static void readValue(Map<?, ?> data, Object entity) {
+        data.entrySet().forEach(entry -> {
+            String key = entry.getKey().toString();
+            Object value = entry.getValue();
+            if (!key.contains(String.valueOf(UNDERLINE))) {
+                Class<?> clazz = Hibernate.getClass(entity);
+                PropertyDescriptor pd = BeanUtils.getPropertyDescriptor(clazz, key);
+                if (pd != null) {
+                    setPropertyValue(entity, pd, value);
+                    return;
+                }
+            }
+            setPropertyValueByColumn(entity, key, value);
+        });
+    }
+
+    /**
+     * 灏嗗疄浣撹浆鎹负map涓殑鏁版嵁.鍙寘鍚笉涓簄ull鐨勫瓧娈�
+     *
+     * @param map
+     * @param entity
+     * @param <K>    String 鎴� Object
+     */
+    @SuppressWarnings({"unchecked"})
+    public static <K> void putValue(Map<K, Object> map, Object entity) {
+        if (entity == null) {
+            return;
+        }
+        PropertyDescriptor[] pds = getPropertyDescriptors(entity);
+        Arrays.stream(pds).forEach(pd -> {
+            // String key = pd.getName();
+            Object value = getPropertyValue(entity, pd);
+            if (value != null) {
+                map.put((K) pd.getName(), value);
+            }
+        });
+    }
+
+    /**
+     * 灏嗗疄浣撳璞¤浆鎹负Map.杩斿洖鐨刴ap涓彧鍖呭惈涓嶄负null鐨勫瓧娈�
+     *
+     * @param entity
+     * @param <K>    String 鎴� Object
+     * @return
+     */
+    public static <K> Map<K, Object> toMap(Object entity) {
+        Map<K, Object> map = new HashMap<>();
+        putValue(map, entity);
+        return map;
+    }
+
+    /**
+     * 鏍规嵁鍒楀悕,灏嗘暟鎹畍alue鍐欏叆鍒板疄浣揺ntity涓�.浼氭牴鎹垪鍚嶇殑涓嬪垝绾垮垎闅旂鍐欏叆鍒板瓙瀵硅薄涓�.
+     *
+     * @param entity     瀹炰綋瀵硅薄
+     * @param columnName SQL璇诲彇鐨勫垪鍚�
+     * @param value      瑕佸啓鍏ョ殑鏁版嵁鍊�
+     * @return 鏄惁鏈夎缃��.
+     */
+    public static boolean setPropertyValueByColumn(Object entity, String columnName, Object value) {
+        columnName = StringUtils.strip(columnName, "_");
+        Class<?> clazz = Hibernate.getClass(entity);
+        String propertyName = columnToProperty(columnName);
+        PropertyDescriptor pd = BeanUtils.getPropertyDescriptor(clazz, propertyName);
+        if (pd != null) {
+            setPropertyValue(entity, pd, value);
+            return true;
+        }
+
+        // 鍙兘鏄寘鍚瓙瀵硅薄
+        int p = columnName.indexOf("_"); // 浠ヤ笅鍒掔嚎鍒嗛殧鐨勫瓧娈靛悕
+        String field;
+        while (p > 0) {
+            field = columnName.substring(0, p);
+            propertyName = columnToProperty(field);
+            pd = BeanUtils.getPropertyDescriptor(clazz, propertyName);
+            if (pd != null) {
+                break;
+            }
+            p = columnName.indexOf("_", p + 1);
+        }
+        if (pd == null) {
+            return false;
+        }
+
+        Object e = getPropertyValue(entity, pd);
+        boolean flag = e == null;
+        if (flag) {
+            e = BeanUtils.instantiateClass(pd.getPropertyType());
+        }
+        boolean change = setPropertyValueByColumn(e, columnName.substring(p + 1), value);
+        if (flag && change) {
+            setPropertyValue(entity, pd, e);
+        }
+        return change;
+    }
+
+    /**
+     * 灏唎bj瀵硅薄杞崲涓烘寚瀹氱殑cls绫诲瀷.濡傛灉娌℃湁杞崲鍒欒繑鍥瀘bj
+     *
+     * @param obj 瑕佽浆鎹㈢殑鏁版嵁锛屼竴鑸寚浠庢暟鎹簱璇诲彇鐨勬暟鎹�
+     * @param cls 瑕佽浆鎹负鐨勭被鍨嬶紝涓�鑸负瀹炰綋绫荤殑瀛楁class
+     * @return
+     */
+    public static Object convert(Object obj, Class<?> cls) {
+        if (obj == null) {
+            return null;
+        }
+        if (cls.isAssignableFrom(obj.getClass())) {
+            return obj;
+        }
+        if (String.class.equals(cls)) {
+            return obj.toString();
+        }
+
+        if (Date.class.equals(cls)) {
+            return DateUtils.parse(obj.toString());
+        }
+        if (Double.class.equals(cls) || Double.TYPE.equals(cls) || Float.class.equals(cls) || Float.TYPE.equals(cls) || Long.class.equals(cls)
+                || Long.TYPE.equals(cls) || Integer.class.equals(cls) || Integer.TYPE.equals(cls) || Short.class.equals(cls) || Short.TYPE.equals(cls)
+                || Byte.class.equals(cls) || Byte.TYPE.equals(cls)) {
+            // 鏁板瓧绫诲瀷
+            BigDecimal bd;
+            if (obj instanceof Number) {
+                bd = new BigDecimal(obj.toString());
+            } else if (obj instanceof Date) {
+                bd = new BigDecimal(((Date) obj).getTime());
+            } else {
+                bd = new BigDecimal(obj.toString());
+            }
+
+            if (Double.TYPE.equals(cls)||Double.class.equals(cls)) {
+                return bd.doubleValue();
+            }
+
+            if (Float.TYPE.equals(cls)||Float.class.equals(cls)) {
+                return bd.floatValue();
+            }
+
+            if (Long.TYPE.equals(cls)||Long.class.equals(cls)) {
+                return bd.longValue();
+            }
+
+            if (Integer.TYPE.equals(cls)||Integer.class.equals(cls)) {
+                return bd.intValue();
+            }
+
+            if (Short.TYPE.equals(cls)||Short.class.equals(cls)) {
+                return bd.shortValue();
+            }
+
+            if (Byte.TYPE.equals(cls)||Byte.class.equals(cls)) {
+                return bd.byteValue();
+            }
+        }
+
+        if (BigDecimal.class.isAssignableFrom(cls)) {
+            // 澶ф暟绫诲瀷
+            if (obj instanceof Long || obj instanceof Integer || obj instanceof Short || obj instanceof Byte) {
+                return BigDecimal.valueOf(((Number) obj).longValue());
+            } else if (obj instanceof Number) {
+                return BigDecimal.valueOf(((Number) obj).doubleValue());
+            } else if (obj instanceof Date) {
+                return BigDecimal.valueOf(((Date) obj).getTime());
+            } else {
+                return new BigDecimal(obj.toString());
+            }
+        }
+
+        if (BigInteger.class.isAssignableFrom(cls)) {
+            // 澶ф暣鏁扮被鍨�
+            if (obj instanceof Number) {
+                return BigInteger.valueOf(((Number) obj).longValue());
+            } else if (obj instanceof Date) {
+                return BigInteger.valueOf(((Date) obj).getTime());
+            } else {
+                return new BigInteger(obj.toString());
+            }
+        }
+
+        return obj;
+    }
+
+    /**
+     * 灏嗗師鐢熸暟鎹暟缁勮浆鎹负Object[]
+     *
+     * @param primitives boolean[]/byte[]/short[]/char[]/int[]/long[]/float[]/double[]绛夌被鍨嬬殑鏁扮粍
+     * @return Object[]鏁扮粍
+     */
+    public static Object[] toObject(Object primitives) {
+        if (primitives == null) {
+            return null;
+        }
+        if (!primitives.getClass().isArray()) {
+            return new Object[]{primitives};
+        }
+        // final Class<?> cls = primitives.getClass().getComponentType();
+        if (primitives instanceof boolean[]) {
+            return ArrayUtils.toObject((boolean[]) primitives);
+        }
+        if (primitives instanceof byte[]) {
+            return ArrayUtils.toObject((byte[]) primitives);
+        }
+        if (primitives instanceof short[]) {
+            return ArrayUtils.toObject((char[]) primitives);
+        }
+        if (primitives instanceof char[]) {
+            return ArrayUtils.toObject((char[]) primitives);
+        }
+        if (primitives instanceof int[]) {
+            return ArrayUtils.toObject((int[]) primitives);
+        }
+        if (primitives instanceof long[]) {
+            return ArrayUtils.toObject((long[]) primitives);
+        }
+        if (primitives instanceof float[]) {
+            return ArrayUtils.toObject((float[]) primitives);
+        }
+        if (primitives instanceof double[]) {
+            return ArrayUtils.toObject((double[]) primitives);
+        }
+
+        return (Object[]) primitives;
+    }
+
+    /**
+     * 灏嗕笅鍒掔嚎鐨勫瓧娈垫敼涓洪┘宄板懡鍚�
+     *
+     * @param param
+     * @return
+     */
+    public static String underlineToCamel(String param) {
+        if (param == null || "".equals(param.trim())) {
+            return "";
+        }
+        int len = param.length();
+        StringBuilder sb = new StringBuilder(len);
+        for (int i = 0; i < len; i++) {
+            char c = param.charAt(i);
+            if (c == UNDERLINE) {
+                if (++i < len) {
+                    sb.append(Character.toUpperCase(param.charAt(i)));
+                }
+            } else {
+                sb.append(c);
+            }
+        }
+        return sb.toString();
+    }
+
+    /**
+     * 棣栧瓧姣嶈浆灏忓啓
+     *
+     * @param s
+     * @return
+     */
+    public static String toLowerCaseFirstOne(String s) {
+        if (Character.isLowerCase(s.charAt(0))) {
+            return s;
+        } else {
+            return (new StringBuilder()).append(Character.toLowerCase(s.charAt(0))).append(s.substring(1)).toString();
+        }
+    }
+
+
+    /**
+     * @param name 杞崲鍓嶇殑椹煎嘲寮忓懡鍚嶇殑瀛楃涓�
+     * @return 杞崲鍚庝笅鍒掔嚎澶у啓鏂瑰紡鍛藉悕鐨勫瓧绗︿覆
+     */
+    public static String humpToDivide(String name, String connStr) {
+        StringBuilder result = new StringBuilder();
+        if (name != null && name.length() > 0) {
+            // 灏嗙涓�涓瓧绗﹀鐞嗘垚澶у啓
+            result.append(name.substring(0, 1).toUpperCase());
+            // 寰幆澶勭悊鍏朵綑瀛楃
+            for (int i = 1; i < name.length(); i++) {
+                String s = name.substring(i, i + 1);
+                // 鍦ㄥぇ鍐欏瓧姣嶅墠娣诲姞涓嬪垝绾�
+                if (s.equals(s.toUpperCase()) && !Character.isDigit(s.charAt(0))) {
+                    result.append(connStr);
+                }
+                // 鍏朵粬瀛楃鐩存帴杞垚澶у啓
+                result.append(s);
+            }
+        }
+        return result.toString().toLowerCase(Locale.ENGLISH);
+    }
+
+    /**
+     * 鍒ゆ柇瀵硅薄鏄惁涓簄ull/empty/blan
+     *
+     * @param value
+     * @return
+     */
+    public static boolean isBlank(Object value) {
+        if (value == null) {
+            return true;
+        }
+        if (value instanceof CharSequence) {
+            return StringUtils.isBlank((CharSequence) value);
+        }
+        if (value.getClass().isArray() && Array.getLength(value) < 1) {
+            return true;
+        }
+        if (value instanceof Collection && ((Collection<?>) value).isEmpty()) {
+            return true;
+        }
+        if (value instanceof Map && ((Map<?, ?>) value).isEmpty()) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * 鍒ゆ柇瀵硅薄鏄惁涓簄ull/empty/blan
+     *
+     * @param value
+     * @return
+     */
+    public static boolean isEmpty(Object value) {
+        if (value == null) {
+            return true;
+        }
+        if (value instanceof CharSequence) {
+            return StringUtils.isEmpty((CharSequence) value);
+        }
+        if (value.getClass().isArray() && Array.getLength(value) < 1) {
+            return true;
+        }
+        if (value instanceof Collection && ((Collection<?>) value).isEmpty()) {
+            return true;
+        }
+        if (value instanceof Map && ((Map<?, ?>) value).isEmpty()) {
+            return true;
+        }
+
+        return false;
+    }
+}
diff --git a/src/main/java/com/common/core/utils/DateUtils.java b/src/main/java/com/common/core/utils/DateUtils.java
new file mode 100644
index 0000000..fcfeb2b
--- /dev/null
+++ b/src/main/java/com/common/core/utils/DateUtils.java
@@ -0,0 +1,962 @@
+package com.common.core.utils;
+
+import org.apache.commons.lang3.StringUtils;
+import org.joda.time.DateTime;
+
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.time.ZoneOffset;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class DateUtils {
+    /**
+     * 骞�-鏈�-鏃� 鏃�:鍒�:绉� 鏃堕棿鏍煎紡
+     */
+    public static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
+    /**
+     * 骞�-鏈�-鏃� 鏃�:鍒� 鏃堕棿鏍煎紡
+     */
+    public static final String DATE_TIME_MINUTE_FORMAT = "yyyy-MM-dd HH:mm";
+    /**
+     * 骞�/鏈�/鏃� 鏃�:鍒� 鏃堕棿鏍煎紡
+     */
+    public static final String DATE_TIME_MINUTE_FORMAT1 = "yyyy/MM/dd HH:mm";
+    /**
+     * 鏃�/鏈�/骞� 鏃�:鍒� 鏃堕棿鏍煎紡
+     */
+    public static final String DATE_TIME_MINUTE_FORMAT2 = "dd/MM/yyyy HH:mm";
+    /**
+     * 2020-08-09T02:35:20.000+0000 鏍兼灄濞佹不鏃堕棿
+     */
+    public static final String DATE_TIME_GL_ST_FORMAT = "yyyy-MM-dd'T'hh:mm:ss.SSSZ";
+
+    public static final String DATE_TIME_GL_ST_FORMAT_ZT = "yyyy-MM-dd'T'HH:mm:ssXXX";
+    public static final String DATE_TIME_GL_ST_FORMAT_ZT_1 = "yyyy-MM-dd'T'HH:mm:ss'Z'";
+    /**
+     * 骞�-鏈�-鏃� 鏃堕棿鏍煎紡
+     */
+    public static final String DATE_FORMAT = "yyyy-MM-dd";
+
+    /**
+     * 骞�-鏈�-鏃� 鏃堕棿鏍煎紡
+     */
+    public static final String YEAR_MONTH_FORMAT = "yyyy-MM-";
+
+    /**
+     * 灏忔椂鏍煎紡
+     */
+    public static final String HOUR_FORMAT = "HH";
+    /**
+     * 骞存湀鏃� 鏃堕棿鏍煎紡
+     */
+    public static final String DATE_FORMAT_NO_SPACER = "yyyyMMdd";
+    /**
+     * 鏈堟棩 鏃堕棿鏍煎紡
+     */
+    public static final String MONTH_DAY_FORMAT_NO_SPACER = "MMdd";
+    /**
+     * 骞存湀 鏃堕棿鏍煎紡
+     */
+    public static final String YEAR_MONTH_FORMAT_NO_SPACER = "yyyyMM";
+
+    public static final String YEAR_FORMAT = "yyyy";
+
+    public static final String MONTH_FORMAT = "MM";
+
+    public static final String DAY_OF_MONTH_FORMAT = "dd";
+
+    public static final String BJ_TIME_ZONE = "+8";
+
+    /**
+     * 榛樿鏍煎紡鍖栫被鍨嬮泦鍚�
+     */
+    public static final Map<Pattern, String> SUPPORT_FORMAT_MAP;
+    /**
+     * 骞�-鏈�-鏃鏃�:鍒�:绉�+鏃�:鍒� 鏃堕棿鏍煎紡姝e垯鍖归厤琛ㄨ揪寮�
+     */
+    private static final Pattern DATE_TIME_PATTERN_ZT = Pattern.compile("^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\\b\\+[0-9]{2}:[0-9]{2}$");
+    /**
+     * 骞�-鏈�-鏃� 鏃�:鍒�:绉� 鏃堕棿鏍煎紡姝e垯鍖归厤琛ㄨ揪寮�
+     */
+    private static final Pattern DATE_TIME_PATTERN = Pattern.compile("^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}$");
+    /**
+     * 骞�-鏈�-鏃� 鏃�:鍒� 鏃堕棿鏍煎紡姝e垯鍖归厤琛ㄨ揪寮�
+     */
+    private static final Pattern DATE_TIME_MINUTE_PATTERN = Pattern.compile("^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}$");
+    /**
+     * 骞�/鏈�/鏃� 鏃�:鍒� 鏃堕棿鏍煎紡姝e垯鍖归厤琛ㄨ揪寮�
+     */
+    private static final Pattern DATE_TIME_MINUTE_PATTERN1 = Pattern.compile("^[0-9]{4}/[0-9]{2}/[0-9]{2} [0-9]{2}:[0-9]{2}$");
+    /**
+     * 鏃�/鏈堝勾 鏃�:鍒� 鏃堕棿鏍煎紡姝e垯鍖归厤琛ㄨ揪寮�
+     */
+    private static final Pattern DATE_TIME_MINUTE_PATTERN2 = Pattern.compile("[0-9]{2}/[0-9]{2}/^[0-9]{4} [0-9]{2}:[0-9]{2}$");
+
+    /**
+     * 骞�-鏈�-鏃� 鏃堕棿鏍煎紡姝e垯鍖归厤琛ㄨ揪寮�
+     */
+    private static final Pattern DATE_PATTERN = Pattern.compile("^[0-9]{4}-[0-9]{2}-[0-9]{2}$");
+    /**
+     * 骞存湀鏃� 鏃堕棿鏍煎紡姝e垯鍖归厤琛ㄨ揪寮�
+     */
+    private static final Pattern DATE_PATTERN_NO_SPACER = Pattern.compile("^[0-9]{4}[0-9]{2}[0-9]{2}$");
+    /**
+     * 鏈堟棩 鏃堕棿鏍煎紡姝e垯鍖归厤琛ㄨ揪寮�
+     */
+    private static final Pattern MONTH_DAY_PATTERN_NO_SPACER = Pattern.compile("^[0-9]{2}[0-9]{2}$");
+    /**
+     * 骞存棩 鏃堕棿鏍煎紡姝e垯鍖归厤琛ㄨ揪寮�
+     */
+    private static final Pattern YEAR_MONTH_PATTERN_NO_SPACER = Pattern.compile("^[0-9]{4}[0-9]{2}$");
+
+    /**
+     * 3
+     */
+    private static final Integer NUM_3 = 3;
+
+    /**
+     * 5
+     */
+    private static final Integer NUM_5 = 5;
+
+    static {
+        SUPPORT_FORMAT_MAP = new ConcurrentHashMap<Pattern, String>();
+        SUPPORT_FORMAT_MAP.put(DATE_TIME_PATTERN, DATE_TIME_FORMAT);
+        SUPPORT_FORMAT_MAP.put(DATE_TIME_MINUTE_PATTERN, DATE_TIME_MINUTE_FORMAT);
+        SUPPORT_FORMAT_MAP.put(DATE_TIME_MINUTE_PATTERN1, DATE_TIME_MINUTE_FORMAT1);
+        SUPPORT_FORMAT_MAP.put(DATE_TIME_MINUTE_PATTERN2, DATE_TIME_MINUTE_FORMAT2);
+        SUPPORT_FORMAT_MAP.put(DATE_PATTERN, DATE_FORMAT);
+        SUPPORT_FORMAT_MAP.put(DATE_PATTERN_NO_SPACER, DATE_FORMAT_NO_SPACER);
+        SUPPORT_FORMAT_MAP.put(YEAR_MONTH_PATTERN_NO_SPACER, YEAR_MONTH_FORMAT_NO_SPACER);
+        SUPPORT_FORMAT_MAP.put(MONTH_DAY_PATTERN_NO_SPACER, MONTH_DAY_FORMAT_NO_SPACER);
+        SUPPORT_FORMAT_MAP.put(DATE_TIME_PATTERN_ZT, DATE_TIME_GL_ST_FORMAT_ZT);
+    }
+
+    /**
+     * 瀛楃涓茶浆鏃ユ湡绫诲瀷
+     *
+     * @param dateString
+     * @return
+     */
+    public static Date convert(String dateString) {
+        Date date = null;
+        if (StringUtils.isEmpty(dateString)) {
+            return null;
+        }
+        for (Pattern pattern : SUPPORT_FORMAT_MAP.keySet()) {
+            Matcher matcher = pattern.matcher(dateString);
+            if (matcher.matches()) {
+                try {
+                    String format = SUPPORT_FORMAT_MAP.get(pattern);
+                    SimpleDateFormat sdf = new SimpleDateFormat(format);
+                    sdf.setLenient(false);
+                    date = sdf.parse(dateString);
+                } catch (ParseException ignored) {
+
+                }
+                break;
+            }
+        }
+        return date;
+    }
+
+    /**
+     * 甯︽椂鍖哄瓧绗︿覆杞棩鏈熺被鍨�
+     *
+     * @param dateString
+     * @return
+     */
+    public static Date timeZoneConvert(String dateString) {
+        Date date = null;
+        if (StringUtils.isNotBlank(dateString)) {
+            Matcher matcher = DATE_TIME_PATTERN_ZT.matcher(dateString);
+            if (matcher.matches()) {
+                try {
+                    String format = SUPPORT_FORMAT_MAP.get(DATE_TIME_PATTERN_ZT);
+                    SimpleDateFormat sdf = new SimpleDateFormat(format);
+                    sdf.setLenient(false);
+                    date = sdf.parse(dateString);
+                } catch (ParseException ignored) {
+                }
+            }
+        }
+        return date;
+    }
+
+    /**
+     * 鏍规嵁鏍煎紡锛岃浆鍖栧瓧绗︿覆涓烘棩鏈�
+     *
+     * @param dateString
+     * @param format
+     * @return
+     */
+    public static Date convert(String dateString, String format) {
+        if (StringUtils.isBlank(dateString)) {
+            return null;
+        }
+        boolean matches = false;
+        for (String fmt : SUPPORT_FORMAT_MAP.values()) {
+            if (fmt.equals(format)) {
+                matches = true;
+                break;
+            }
+        }
+        if (!matches) {
+            throw new IllegalArgumentException(format + " is not a valid date format");
+        }
+        Date date = null;
+        try {
+            date = new SimpleDateFormat(format).parse(dateString);
+        } catch (ParseException ignored) {
+
+        }
+        return date;
+    }
+
+    /**
+     * 鏍规嵁鏍煎紡锛岃浆鍖栧瓧绗︿覆涓烘棩鏈�
+     *
+     * @param dateString
+     * @param format
+     * @return
+     */
+    public static Date convertSimple(String dateString, String format) {
+        if (StringUtils.isBlank(dateString)) {
+            return null;
+        }
+        Date date = null;
+        try {
+            date = new SimpleDateFormat(format).parse(dateString);
+        } catch (ParseException ignored) {
+
+        }
+        return date;
+    }
+
+    /**
+     * 鏍规嵁鏃堕棿瀛楃涓茶В鏋愭垚Date瀵硅薄锛岃鏂规硶浼氳嚜閫傚簲鏃堕棿瀛楃涓叉牸寮�
+     *
+     * @param dateText 鏃堕棿瀛楃涓�
+     */
+    public static Date parse(String dateText) {
+        return DateUtils.convert(dateText);
+    }
+
+    /**
+     * 鏍规嵁鏃堕棿瀛楃涓诧紝瑙f瀽鎴愭寚瀹氭牸寮忕殑鐨凞ate瀵硅薄
+     *
+     * @param dateText 鏃堕棿瀛楃涓�
+     * @param format   鎸囧畾瑙f瀽鏍煎紡
+     */
+    public static Date parse(String dateText, String format) {
+        return DateUtils.convert(dateText, format);
+    }
+
+    /**
+     * 鏍煎紡鍖栨棩鏈熶负yyyy-MM-dd HH:mm:ss鏍煎紡瀛楃涓�
+     *
+     * @param date 鏃ユ湡瀵硅薄
+     */
+    public static String format(Date date) {
+        SimpleDateFormat simpleDateFormat = new SimpleDateFormat();
+        simpleDateFormat.applyPattern(DATE_TIME_FORMAT);
+        return simpleDateFormat.format(date);
+    }
+
+    /**
+     * 鏍煎紡鍖栨棩鏈熶负鎸囧畾鏍煎紡瀛楃涓�
+     *
+     * @param date 鏃ユ湡瀵硅薄
+     */
+    public static String format(Date date, String pattern) {
+        SimpleDateFormat simpleDateFormat = new SimpleDateFormat();
+        simpleDateFormat.applyPattern(pattern);
+        return simpleDateFormat.format(date);
+    }
+
+    /**
+     * 鏍煎紡鍖栨棩鏈熶负鎸囧畾鏍煎紡瀛楃涓�
+     *
+     * @param date 鏃ユ湡瀵硅薄
+     */
+    public static String formatToUtc(Date date, String pattern) {
+        SimpleDateFormat df = new SimpleDateFormat(pattern);
+        df.setTimeZone(new SimpleTimeZone(0, "UTC"));
+        return df.format(date);
+    }
+
+    /**
+     * 鏍煎紡鍖栨棩鏈熶负yyyy-MM-dd HH:mm:ss鏍煎紡瀛楃涓�
+     *
+     * @param timestamp 鏃堕棿鎴�
+     */
+    public static String format(long timestamp) {
+        SimpleDateFormat simpleDateFormat = new SimpleDateFormat();
+        simpleDateFormat.applyPattern(DATE_TIME_FORMAT);
+        return simpleDateFormat.format(DateUtils.newDate(timestamp));
+    }
+
+    /**
+     * 鏍煎紡鍖栨棩鏈熶负鎸囧畾鏍煎紡瀛楃涓�
+     *
+     * @param timestamp 鏃堕棿鎴�
+     */
+    public static String format(long timestamp, String pattern) {
+        SimpleDateFormat simpleDateFormat = new SimpleDateFormat();
+        simpleDateFormat.applyPattern(pattern);
+        return simpleDateFormat.format(DateUtils.newDate(timestamp));
+    }
+
+    /**
+     * 鏍煎紡鍖栨棩鏈熶负鏃堕棿鎴�
+     */
+    public static long format(String dateText) {
+        if (StringUtils.isEmpty(dateText)) {
+            return 0L;
+        }
+        Date date=DateUtils.convert(dateText);
+        return date==null ? 0L : date.getTime();
+    }
+
+    /**
+     * 鑾峰彇褰撳墠鏃堕棿鐨勬棩鏈熷璞�
+     */
+    public static Date now() {
+        return DateUtils.newDate(DateUtils.nowTimestamp());
+    }
+
+    /**
+     * 鑾峰彇褰撳墠鏃堕棿鏃堕棿鎴�
+     */
+    public static long nowTimestamp() {
+        return System.currentTimeMillis();
+    }
+
+    /**
+     * 鏍规嵁鏃堕棿鎴冲垱寤烘棩鏈熷璞�
+     *
+     * @param timestamp 鏃堕棿鎴�
+     */
+    public static Date newDate(long timestamp) {
+        return new Date(timestamp);
+    }
+
+    /**
+     * 鏍规嵁鎸囧畾鏃堕棿鍒涘缓鏃ユ湡瀵硅薄
+     *
+     * @param year        骞�
+     * @param month       鏈�
+     * @param day         鏃�
+     * @param hour        鏃�
+     * @param minute      鍒�
+     * @param second      绉�
+     * @param millisecond 姣
+     */
+    public static Date newDate(int year, int month, int day, int hour, int minute, int second, int millisecond) {
+        DateTime dateTime = new DateTime(year, month, day, hour, minute, second, millisecond);
+        return dateTime.toDate();
+    }
+
+    /**
+     * 鏍规嵁鎸囧畾鏃堕棿鍒涘缓鏃ユ湡瀵硅薄
+     *
+     * @param year   骞�
+     * @param month  鏈�
+     * @param day    鏃�
+     * @param hour   鏃�
+     * @param minute 鍒�
+     * @param second 绉�
+     */
+    public static Date newDate(int year, int month, int day, int hour, int minute, int second) {
+        return DateUtils.newDate(year, month, day, hour, minute, second, 0);
+    }
+
+    /**
+     * 鏍规嵁鎸囧畾鏃堕棿鍒涘缓鏃ユ湡瀵硅薄
+     *
+     * @param year   骞�
+     * @param month  鏈�
+     * @param day    鏃�
+     * @param hour   鏃�
+     * @param minute 鍒�
+     */
+    public static Date newDate(int year, int month, int day, int hour, int minute) {
+        return DateUtils.newDate(year, month, day, hour, minute, 0, 0);
+    }
+
+    /**
+     * 鏍规嵁鎸囧畾鏃堕棿鍒涘缓鏃ユ湡瀵硅薄
+     *
+     * @param year  骞�
+     * @param month 鏈�
+     * @param day   鏃�
+     * @param hour  鏃�
+     */
+    public static Date newDate(int year, int month, int day, int hour) {
+        return DateUtils.newDate(year, month, day, hour, 0, 0, 0);
+    }
+
+    /**
+     * 鏍规嵁鎸囧畾鏃堕棿鍒涘缓鏃ユ湡瀵硅薄
+     *
+     * @param year  骞�
+     * @param month 鏈�
+     * @param day   鏃�
+     */
+    public static Date newDate(int year, int month, int day) {
+        return DateUtils.newDate(year, month, day, 0, 0, 0, 0);
+    }
+
+    /**
+     * 鏃ユ湡鍔犲噺 骞存湀鏃ユ椂鍒嗙姣鏁� 姝f暟鍔犺礋鏁板噺
+     *
+     * @param date         鏃ユ湡
+     * @param years        鍔犲噺骞存暟
+     * @param months       鍔犲噺鏈堟暟
+     * @param days         鍔犲噺澶╂暟
+     * @param hours        鍔犲噺灏忔椂鏁�
+     * @param minutes      鍔犲噺鍒嗛挓鏁�
+     * @param seconds      鍔犲噺绉掓暟
+     * @param milliseconds 鍔犲噺姣鏁�
+     */
+    public static Date add(Date date, int years, int months, int days, int hours, int minutes, int seconds, int milliseconds) {
+        return DateUtils.add(date.getTime(), years, months, days, hours, minutes, seconds, milliseconds);
+    }
+
+    /**
+     * 鏃ユ湡鍔犲噺 骞存湀鏃ユ椂鍒嗙姣鏁� 姝f暟鍔犺礋鏁板噺
+     *
+     * @param timestamp    鏃堕棿鎴�
+     * @param years        鍔犲噺骞存暟锛屽锛�1銆�-1
+     * @param months       鍔犲噺鏈堟暟锛屽锛�1銆�-1
+     * @param days         鍔犲噺澶╂暟锛屽锛�1銆�-1
+     * @param hours        鍔犲噺灏忔椂鏁帮紝濡傦細1銆�-1
+     * @param minutes      鍔犲噺鍒嗛挓鏁帮紝濡傦細1銆�-1
+     * @param seconds      鍔犲噺绉掓暟锛屽锛�1銆�-1
+     * @param milliseconds 鍔犲噺姣鏁帮紝濡傦細1銆�-1
+     */
+    public static Date add(long timestamp, int years, int months, int days, int hours, int minutes, int seconds, int milliseconds) {
+        int zero = 0;
+        DateTime dateTime = new DateTime(timestamp);
+        if (zero != years) {
+            dateTime = dateTime.plusYears(years);
+        }
+        if (zero != months) {
+            dateTime = dateTime.plusMonths(months);
+        }
+        if (zero != days) {
+            dateTime = dateTime.plusDays(days);
+        }
+        if (zero != hours) {
+            dateTime = dateTime.plusHours(hours);
+        }
+        if (zero != minutes) {
+            dateTime = dateTime.plusMinutes(minutes);
+        }
+        if (zero != seconds) {
+            dateTime = dateTime.plusSeconds(seconds);
+        }
+        if (zero != milliseconds) {
+            dateTime = dateTime.plusMillis(milliseconds);
+        }
+        return dateTime.toDate();
+    }
+
+    /**
+     * 鑾峰彇鏈懆鐨勭涓�澶�
+     *
+     * @return Long
+     **/
+    public static Long getWeekStart(long timestamp) {
+        Calendar cal = Calendar.getInstance();
+        cal.setTimeInMillis(timestamp);
+        Integer date = cal.get(Calendar.DATE);
+        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
+        if (cal.get(Calendar.DATE) > date) {
+            cal.add(Calendar.DATE, -7);
+        }
+        Date time = cal.getTime();
+        return format(new SimpleDateFormat("yyyy-MM-dd").format(time) + " 00:00:00");
+    }
+
+    /**
+     * 鑾峰彇鏈懆鐨勬渶鍚庝竴澶�
+     *
+     * @return Long
+     **/
+    public static Long getWeekEnd(long timestamp) {
+        Calendar cal = Calendar.getInstance();
+        cal.setTimeInMillis(timestamp);
+        Integer date = cal.get(Calendar.DATE);
+        cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
+        if (cal.get(Calendar.DATE) < date) {
+            cal.add(Calendar.DATE, 7);
+        }
+        Date time = cal.getTime();
+        return format(new SimpleDateFormat("yyyy-MM-dd").format(time) + " 23:59:59");
+    }
+
+    /**
+     * 鑾峰彇鏈ぉ鐨勬渶鍚庝竴绉�
+     *
+     * @return Long
+     **/
+    public static Date getDayEnd(Date date) {
+        if (date == null) {
+            return null;
+        }
+        return parse(new SimpleDateFormat("yyyy-MM-dd").format(date.getTime()) + " 23:59:59");
+    }
+
+    /**
+     * 鑾峰彇鏈ぉ鐨勭涓�绉�
+     *
+     * @return Long
+     **/
+    public static Date getDayStart(Date date) {
+        if (date == null) {
+            return null;
+        }
+        return parse(new SimpleDateFormat("yyyy-MM-dd").format(date.getTime()) + " 00:00:00");
+    }
+
+    /**
+     * 鏍规嵁鏃堕棿鎴宠幏鍙栫増鏈彿锛孋alendar鍙栧懆鏄粠鍛ㄦ棩寮�濮嬭绠楋紝闇�瑕佽繘琛屼慨鏀逛负浠ュ懆涓�涓哄噯
+     *
+     * @param timestamp 鏃堕棿鎴�
+     * @return 鐗堟湰鍙�
+     */
+    public static Integer getDateVersion(long timestamp) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTimeInMillis(timestamp);
+        calendar.setFirstDayOfWeek(Calendar.MONDAY);
+        calendar.setMinimalDaysInFirstWeek(4);
+        return calendar.get(Calendar.YEAR) * 1000 + calendar.get(Calendar.WEEK_OF_YEAR);
+    }
+
+    /**
+     * 鑾峰彇褰撳墠鏃堕棿鐨勭増鏈彿
+     *
+     * @return 鐗堟湰鍙�
+     */
+    public static Integer getNowVersion() {
+        return getDateVersion(nowTimestamp());
+    }
+
+
+    /**
+     * 鑾峰彇骞存湀鍛�
+     *
+     * @return String
+     **/
+    public static Map<String, String> getYearMonthWeekStr(long timestamp) {
+        // 褰撴湀绗竴澶�
+        Calendar firstDay = Calendar.getInstance();
+        firstDay.setTimeInMillis(timestamp);
+        firstDay.set(Calendar.DAY_OF_MONTH, 1);
+
+        // 褰撴湀鏈�鍚庝竴澶�
+        Calendar lastDay = Calendar.getInstance();
+        lastDay.setTimeInMillis(timestamp);
+        lastDay.add(Calendar.MONTH, 1);
+        lastDay.set(Calendar.DAY_OF_MONTH, 0);
+
+        // 绗竴涓懆鏃�
+        Calendar firsSunday = Calendar.getInstance();
+        firsSunday.setTimeInMillis(firstDay.getTimeInMillis());
+        firsSunday.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
+        if (firsSunday.getTimeInMillis() != firstDay.getTimeInMillis()) {
+            firsSunday.add(Calendar.DATE, 7);
+        }
+
+
+        // 鏈�鍚庝竴涓懆涓�
+        Calendar lastMonday = Calendar.getInstance();
+        lastMonday.setTimeInMillis(lastDay.getTimeInMillis());
+        lastMonday.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
+        if (lastMonday.getTimeInMillis() > lastDay.getTimeInMillis()) {
+            lastMonday.add(Calendar.DATE, -7);
+        }
+
+        String year = "";
+        String month = "";
+        String week = "";
+        DateFormat df = new SimpleDateFormat("MMM", Locale.ENGLISH);
+        if (firsSunday.getTimeInMillis() >= timestamp) {
+            // 涓夊ぉ浠ヤ笂绠楁湰鏈�
+            if (firsSunday.get(Calendar.DATE) > NUM_3) {
+                Calendar cal = Calendar.getInstance();
+                cal.setTimeInMillis(timestamp);
+                year = cal.get(Calendar.YEAR) + "";
+                month = df.format(cal.getTime());
+
+                week = cal.get(Calendar.WEEK_OF_MONTH) + "th Week";
+            } else {
+                // 涓夊ぉ浠ュ唴绠椾笂鏈�
+                // 涓婃湀绗竴澶�
+                Calendar preFirstDay = Calendar.getInstance();
+                preFirstDay.setTimeInMillis(timestamp);
+                preFirstDay.set(Calendar.DAY_OF_MONTH, 1);
+                preFirstDay.add(Calendar.MONTH, -1);
+
+                // 涓婃湀绗竴涓懆鏃�
+                Calendar preFirsSunday = Calendar.getInstance();
+                preFirsSunday.setTimeInMillis(preFirstDay.getTimeInMillis());
+                preFirsSunday.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
+                if (preFirsSunday.getTimeInMillis() != preFirstDay.getTimeInMillis()) {
+                    preFirsSunday.add(Calendar.DATE, 7);
+                }
+
+                // 涓婃湀鏈�鍚庝竴澶�
+                Calendar preLastDay = Calendar.getInstance();
+                preLastDay.setTimeInMillis(firstDay.getTimeInMillis());
+                preLastDay.add(Calendar.DATE, -1);
+
+                year = preLastDay.get(Calendar.YEAR) + "";
+                month = df.format(preLastDay.getTime());
+                if (preFirsSunday.get(Calendar.DATE) > NUM_3) {
+                    week = preLastDay.get(Calendar.WEEK_OF_MONTH) + "th Week";
+                } else {
+                    week = (preLastDay.get(Calendar.WEEK_OF_MONTH) - 1) + "th Week";
+                }
+            }
+        } else if (lastMonday.getTimeInMillis() <= timestamp) {
+            // 鏈湀鍦ㄦ渶鍚庝竴鍛ㄥ崰4澶╁強浠ヤ笂
+            if (lastDay.get(Calendar.DAY_OF_WEEK) >= NUM_5 || lastDay.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
+                Calendar cal = Calendar.getInstance();
+                cal.setTimeInMillis(timestamp);
+                year = cal.get(Calendar.YEAR) + "";
+                month = df.format(cal.getTime());
+                if (firsSunday.get(Calendar.DATE) > NUM_3) {
+                    week = cal.get(Calendar.WEEK_OF_MONTH) + "th Week";
+                } else {
+                    week = (cal.get(Calendar.WEEK_OF_MONTH) - 1) + "th Week";
+                }
+            } else {
+                // 涓嬫湀绗竴澶�
+                Calendar nextFirstDay = Calendar.getInstance();
+                nextFirstDay.setTimeInMillis(timestamp);
+                nextFirstDay.add(Calendar.MONTH, 1);
+                nextFirstDay.set(Calendar.DAY_OF_MONTH, 1);
+
+                year = nextFirstDay.get(Calendar.YEAR) + "";
+                month = df.format(nextFirstDay.getTime());
+                week = nextFirstDay.get(Calendar.WEEK_OF_MONTH) + "th Week";
+            }
+        } else {
+            Calendar cal = Calendar.getInstance();
+            cal.setTimeInMillis(timestamp);
+
+            year = cal.get(Calendar.YEAR) + "";
+            month = df.format(cal.getTime());
+            if (firsSunday.get(Calendar.DATE) > NUM_3) {
+                week = cal.get(Calendar.WEEK_OF_MONTH) + "th Week";
+            } else {
+                week = (cal.get(Calendar.WEEK_OF_MONTH) - 1) + "th Week";
+            }
+        }
+
+        Map<String, String> result = new HashMap<String, String>();
+        result.put("year", year);
+        result.put("month", month);
+        result.put("week", week);
+        return result;
+    }
+
+    /**
+     * 娣诲姞骞翠唤
+     *
+     * @param date
+     * @param years
+     * @return
+     */
+    public static Date addYears(Date date, int years) {
+        return DateUtils.addYears(date.getTime(), years);
+    }
+
+    /**
+     * 娣诲姞骞翠唤
+     *
+     * @param timestamp
+     * @param years
+     * @return
+     */
+    public static Date addYears(long timestamp, int years) {
+        return DateUtils.add(timestamp, years, 0, 0, 0, 0, 0, 0);
+    }
+
+    /**
+     * 娣诲姞鏈堜唤
+     *
+     * @param date
+     * @param months
+     * @return
+     */
+    public static Date addMonths(Date date, int months) {
+        return DateUtils.addMonths(date.getTime(), months);
+    }
+
+    /**
+     * 娣诲姞鏈堜唤
+     *
+     * @param timestamp
+     * @param months
+     * @return
+     */
+    public static Date addMonths(long timestamp, int months) {
+        return DateUtils.add(timestamp, 0, months, 0, 0, 0, 0, 0);
+    }
+
+    /**
+     * 娣诲姞鏃ユ湡
+     *
+     * @param date
+     * @param days
+     * @return
+     */
+    public static Date addDays(Date date, int days) {
+        return DateUtils.addDays(date.getTime(), days);
+    }
+
+    /**
+     * 娣诲姞鏃ユ湡
+     *
+     * @param timestamp
+     * @param days
+     * @return
+     */
+    public static Date addDays(long timestamp, int days) {
+        return DateUtils.add(timestamp, 0, 0, days, 0, 0, 0, 0);
+    }
+
+    /**
+     * 娣诲姞灏忔椂
+     *
+     * @param date
+     * @param hours
+     * @return
+     */
+    public static Date addHours(Date date, int hours) {
+        return DateUtils.addHours(date.getTime(), hours);
+    }
+
+    /**
+     * 娣诲姞灏忔椂
+     *
+     * @param timestamp
+     * @param hours
+     * @return
+     */
+    public static Date addHours(long timestamp, int hours) {
+        return DateUtils.add(timestamp, 0, 0, 0, hours, 0, 0, 0);
+    }
+
+    /**
+     * 娣诲姞鍒嗛挓
+     *
+     * @param date
+     * @param minutes
+     * @return
+     */
+    public static Date addMinutes(Date date, int minutes) {
+        return DateUtils.addMinutes(date.getTime(), minutes);
+    }
+
+    /**
+     * 娣诲姞鍒嗛挓
+     *
+     * @param timestamp
+     * @param minutes
+     * @return
+     */
+    public static Date addMinutes(long timestamp, int minutes) {
+        return DateUtils.add(timestamp, 0, 0, 0, 0, minutes, 0, 0);
+    }
+
+    /**
+     * 鑾峰彇褰撳墠鏈堜唤
+     *
+     * @return
+     */
+    public static int getCurrentMonth() {
+        DateTime dateTime = DateTime.now();
+        return dateTime.getMonthOfYear();
+    }
+
+    /**
+     * 閫氳繃鏃堕棿绉掓绉掓暟鍒ゆ柇涓や釜鏃堕棿鐨勯棿闅�
+     *
+     * @param date1
+     * @param date2
+     * @return
+     */
+    public static int differentDaysByMillisecond(Date date1, Date date2) {
+        int days = (int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24));
+        return days;
+    }
+
+    /**
+     * 鍙栦袱涓棩鏈熺殑涓棿鏃ユ湡,榛樿鍙栧ぇ
+     *
+     * @param start
+     * @param end
+     * @return
+     */
+    public static Date getMeddleDate(Date start, Date end) {
+        int days = (int) ((end.getTime() - start.getTime()) / (1000 * 3600 * 24));
+        return DateUtils.addDays(start, (int) Math.floor(Double.valueOf(days) / 2));
+    }
+
+    /**
+     * 閫氳繃鏃堕棿绉掓绉掓暟鍒ゆ柇涓や釜鏃堕棿鐨勯棿闅�
+     *
+     * @param date1
+     * @param date2
+     * @return
+     */
+    public static int differentSeconds(Date date1, Date date2) {
+        int days = (int) ((date2.getTime() - date1.getTime()) / (1000));
+        return days;
+    }
+
+    /**
+     * 鎸夋棩鏈熼�掑瑙勫垯鐢熸垚鍒嗗尯鍒楄〃
+     *
+     * @param start
+     * @param end
+     * @return
+     */
+    public static List<String> generateDayList(String start, String end, String pattern) {
+        List<String> partitionList = new ArrayList<String>();
+        partitionList.add(start);
+        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
+        Date startDate;
+        Date endDate;
+        try {
+            startDate = sdf.parse(start);
+            endDate = sdf.parse(end);
+        } catch (Exception e) {
+
+            return null;
+        }
+        Calendar startCal = Calendar.getInstance();
+        Calendar endCal = Calendar.getInstance();
+        startCal.setTime(startDate);
+        endCal.setTime(endDate);
+        while (startCal.before(endCal)) {
+            startCal.add(Calendar.DAY_OF_MONTH, 1);
+            partitionList.add(sdf.format(startCal.getTime()));
+        }
+        return partitionList;
+    }
+
+    /**
+     * 鏍煎紡鍖杣tc鏃堕棿
+     *
+     * @param utcDate
+     * @return
+     */
+    public static String formatUtcDate(String utcDate) {
+        DateFormat df = new SimpleDateFormat(DateUtils.DATE_TIME_GL_ST_FORMAT);
+        DateFormat df2 = new SimpleDateFormat(DateUtils.DATE_TIME_FORMAT);
+
+        Date date = null;
+        try {
+            date = df.parse(utcDate);
+        } catch (ParseException e) {
+            return utcDate;
+        }
+        return df2.format(date);
+    }
+
+    /**
+     * 鍙樻洿鏃ユ湡瀛楃涓叉牸寮�
+     *
+     * @return
+     */
+    public static String convertDateStrPattern(String dateStr, String sourcePattern, String targetPattern) {
+        DateFormat df = new SimpleDateFormat(sourcePattern);
+        DateFormat df2 = new SimpleDateFormat(targetPattern);
+
+        Date date = null;
+        try {
+            date = df.parse(dateStr);
+        } catch (ParseException e) {
+            return null;
+        }
+        return df2.format(date);
+    }
+
+    /**
+     * 鏍煎紡鍖杣tc鏃堕棿
+     *
+     * @param localDate
+     * @return
+     */
+    public static Date localToUTC(Date localDate) {
+        long localTimeInMillis = localDate.getTime();
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTimeInMillis(localTimeInMillis);
+        int zoneOffset = calendar.get(Calendar.ZONE_OFFSET);
+        int dstOffset = calendar.get(Calendar.DST_OFFSET);
+        calendar.add(Calendar.MILLISECOND, -(zoneOffset + dstOffset));
+        Date utcDate = new Date(calendar.getTimeInMillis());
+        return utcDate;
+    }
+
+    /**
+     * @param date1
+     * @param date2
+     * @return
+     */
+    public static int differentDays(Date date1, Date date2) {
+        Calendar cal1 = Calendar.getInstance();
+        cal1.setTime(date1);
+
+        Calendar cal2 = Calendar.getInstance();
+        cal2.setTime(date2);
+        int day1 = cal1.get(Calendar.DAY_OF_YEAR);
+        int day2 = cal2.get(Calendar.DAY_OF_YEAR);
+
+        int year1 = cal1.get(Calendar.YEAR);
+        int year2 = cal2.get(Calendar.YEAR);
+        if (year1 != year2) {
+            int timeDistance = 0;
+            for (int i = year1; i < year2; i++) {
+                if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0) {//闂板勾
+                    timeDistance += 366;
+                } else {//涓嶆槸闂板勾
+                    timeDistance += 365;
+                }
+            }
+            return timeDistance + (day2 - day1);
+        } else { //涓嶅悓骞�
+
+            System.out.println("鍒ゆ柇day2 - day1 : " + (day2 - day1));
+            return day2 - day1;
+        }
+    }
+
+    public static Long timestamp2dateLong(Long timestamp) {
+        return DateUtils.format(DateUtils.format(timestamp).substring(0, 10));
+    }
+
+    public static boolean isValidDate(String str, String pattern) {
+        boolean convertSuccess = true;
+        SimpleDateFormat format = new SimpleDateFormat(pattern);
+        try {
+            // 璁剧疆lenient涓篺alse. 鍚﹀垯SimpleDateFormat浼氭瘮杈冨鏉惧湴楠岃瘉鏃ユ湡锛屾瘮濡�2007/02/29浼氳鎺ュ彈锛屽苟杞崲鎴�2007/03/01
+            format.setLenient(false);
+            format.parse(str);
+        } catch (ParseException e) {
+            convertSuccess = false;
+        }
+        return convertSuccess;
+    }
+}
diff --git a/src/main/java/com/common/core/utils/DesensitiveUtils.java b/src/main/java/com/common/core/utils/DesensitiveUtils.java
new file mode 100644
index 0000000..46c75a3
--- /dev/null
+++ b/src/main/java/com/common/core/utils/DesensitiveUtils.java
@@ -0,0 +1,217 @@
+package com.common.core.utils;
+
+
+import com.common.annotation.DesensitiveInfo;
+import com.common.core.domain.DesensitiveType;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.util.ReflectionUtils;
+
+import java.lang.reflect.Field;
+import java.math.BigDecimal;
+import java.time.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Map;
+
+/**
+ * @description: 鑴辨晱宸ュ叿绫�
+ * @author: holden
+ * @time: 2022-01-20 09:10
+ */
+public class DesensitiveUtils {
+
+    private DesensitiveUtils() {
+    }
+
+    /**
+     * 鎵弿鏂规硶娉ㄨВ锛岃劚鏁�
+     *
+     * @param obj
+     */
+    public static void format(Object obj) {
+        DesensitiveUtils.formatMethod(obj);
+    }
+
+    /**
+     *  鍒ゆ柇瀵硅薄绫诲瀷锛岃繘琛屽垎绫诲鐞�
+     *
+     * @param obj   闇�瑕佸弽灏勫璞�
+     */
+    private static void formatMethod(Object obj) {
+        if (obj == null || isPrimitive(obj.getClass())) {
+            return;
+        }
+        if (obj.getClass().isArray()) {
+            for (Object object : (Object[]) obj) {
+                formatMethod(object);
+            }
+        } else if (Collection.class.isAssignableFrom(obj.getClass())) {
+            for (Object o : ((Collection) obj)) {
+                formatMethod(o);
+            }
+        } else if (Map.class.isAssignableFrom(obj.getClass())) {
+            for (Object o : ((Map) obj).values()) {
+                formatMethod(o);
+            }
+        } else {
+            objFormat(obj);
+        }
+    }
+
+    /**
+     * 鍙湁瀵硅薄鎵嶆牸寮忓寲鏁版嵁
+     *
+     * @param obj
+     */
+    private static void objFormat(Object obj) {
+        for (Field field : obj.getClass().getDeclaredFields()) {
+            if (isPrimitive(field.getType())||field.getType().isArray()) {
+                fieldSetSensitiveValue(obj, field);
+            }else{
+                //瀵硅薄绫诲瀷杩涜涓嬩竴绾у鐞�
+                ReflectionUtils.makeAccessible(field);
+                Object fieldValue = ReflectionUtils.getField(field, obj);
+                if (fieldValue != null) {
+                    formatMethod(fieldValue);
+                }
+            }
+        }
+    }
+
+    /**
+     * 杩涜鑴辨晱澶勭悊鐨勬柟娉�
+     * @param obj
+     * @param field
+     */
+    private static void fieldSetSensitiveValue(Object obj, Field field)  {
+        DesensitiveInfo annotation = field.getAnnotation(DesensitiveInfo.class);
+        if (annotation!=null){
+            ReflectionUtils.makeAccessible(field);
+            Object fieldValue = ReflectionUtils.getField(field, obj);
+            String padStr = annotation.padStr();
+            DesensitiveType type = annotation.value();
+            Integer padSize = type.getPadSize();
+            if (fieldValue!=null && !"".equals(fieldValue.toString())){
+                if(DesensitiveType.EMAIL.name().equals(type.name())){
+                    if(String.class.isAssignableFrom(field.getType())) {
+                        ReflectionUtils.setField(field, obj, generatePad(padSize, padStr) + "@company.com");
+                    }
+                    if(field.getType().isArray()){
+                        ArrayList<String> list=new ArrayList();
+                        for (String s : (String[])fieldValue) {
+                            // 瀵圭┖瀛楃鍘熸牱澶勭悊
+                            if(s==null || s.isEmpty()){
+                                list.add(s);
+                            }else {
+                                list.add(generatePad(padSize, padStr) + "@company.com");
+                            }
+                        }
+                        ReflectionUtils.setField(field, obj, list.toArray(new String[0]));
+                    }
+                }else {
+                    if(String.class.isAssignableFrom(field.getType())) {
+                        ReflectionUtils.setField(field, obj, generatePad(padSize, padStr));
+                    }
+                    if(field.getType().isArray()){
+                        ArrayList<String> list=new ArrayList();
+                        for (String s : (String[])fieldValue) {
+                            // 瀵圭┖瀛楃鍘熸牱澶勭悊
+                            if(s==null || s.isEmpty()){
+                                list.add(s);
+                            }else {
+                                list.add(generatePad(padSize, padStr));
+                            }
+                        }
+                        ReflectionUtils.setField(field, obj, list.toArray(new String[0]));
+                    }
+                }
+            }
+//            else{
+//                if(DesensitiveType.EMAIL.name().equals(type.name())){
+//                    if(String.class.isAssignableFrom(field.getType())) {
+//                        ReflectionUtils.setField(field, obj, generatePad(padSize, padStr) + "@company.com");
+//                    }
+//                    if(field.getType().isArray()){
+//                        ArrayList<String> list=new ArrayList();
+//                        list.add(generatePad(padSize, padStr) + "@company.com");
+//                        ReflectionUtils.setField(field, obj, list.toArray(new String[0]));
+//                    }
+//                }else {
+//                    if(String.class.isAssignableFrom(field.getType())) {
+//                        ReflectionUtils.setField(field, obj, generatePad(padSize, padStr));
+//                    }
+//                    if(field.getType().isArray()){
+//                        ArrayList<String> list=new ArrayList();
+//                        list.add(generatePad(padSize, padStr));
+//                        ReflectionUtils.setField(field, obj, list.toArray(new String[0]));
+//                    }
+//                }
+//            }
+        }
+    }
+
+    public static String getFieldDesensitive(Object t, Field field){
+        DesensitiveInfo annotation = field.getAnnotation(DesensitiveInfo.class);
+        if (annotation!=null){
+            DesensitiveType type = annotation.value();
+            String padStr = annotation.padStr();
+            Integer padSize = type.getPadSize();
+            return generatePad(padSize, padStr);
+        }
+        return null;
+    }
+
+
+    public static String getFieldDesensitive(DesensitiveType field){
+        String padStr = "*";
+        Integer padSize = field.getPadSize();
+        if(DesensitiveType.EMAIL.name().equals(field.name())) {
+            return generatePad(padSize, padStr)+"@company.com";
+        }else{
+            return generatePad(padSize, padStr);
+        }
+    }
+
+    public static String getFieldDesensitive(Object t, DesensitiveType field){
+        if(null == t || "".equals(t.toString())){
+            return "";
+        }
+        String padStr = "*";
+        Integer padSize = field.getPadSize();
+        if(DesensitiveType.EMAIL.name().equals(field.name())) {
+            return generatePad(padSize, padStr)+"@company.com";
+        }else{
+            return generatePad(padSize, padStr);
+        }
+    }
+
+    public static String generatePad(Integer padSize,String pad){
+        String padstr = "";
+        for(int i = 0; i < padSize; i++){
+            padstr += pad;
+        }
+        return padstr;
+    }
+
+    /**
+     * 鍩烘湰鏁版嵁绫诲瀷鍜孲tring绫诲瀷鍒ゆ柇
+     *
+     * @param clz
+     * @return
+     */
+    public static boolean isPrimitive(Class<?> clz) {
+        try {
+            if (String.class.isAssignableFrom(clz) || Date.class.isAssignableFrom(clz)|| BigDecimal.class.isAssignableFrom(clz) || LocalDateTime.class.isAssignableFrom(clz)
+                    || LocalDate.class.isAssignableFrom(clz)  || LocalTime.class.isAssignableFrom(clz)  || Year.class.isAssignableFrom(clz)
+                    || YearMonth.class.isAssignableFrom(clz)  || Month.class.isAssignableFrom(clz) || clz.isPrimitive()) {
+                return true;
+            } else {
+                return ((Class) clz.getField("TYPE").get(null)).isPrimitive();
+            }
+        } catch (Exception e) {
+            return false;
+        }
+    }
+
+}
diff --git a/src/main/java/com/common/core/utils/DistributedLock.java b/src/main/java/com/common/core/utils/DistributedLock.java
new file mode 100644
index 0000000..f407054
--- /dev/null
+++ b/src/main/java/com/common/core/utils/DistributedLock.java
@@ -0,0 +1,36 @@
+package com.common.core.utils;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.stereotype.Component;
+
+import java.util.concurrent.TimeUnit;
+
+@Component
+public class DistributedLock {
+    @Autowired
+    private RedisTemplate redisTemplate;
+
+    public boolean getLock(String lockId, long millisecond) {
+        Boolean success = redisTemplate.opsForValue().setIfAbsent(lockId, "lock",
+                millisecond, TimeUnit.MILLISECONDS);
+        return success != null && success;
+    }
+    public boolean waitLock(String lockId, long millisecond) {
+        do {
+            if(this.getLock(lockId,millisecond)){
+                return true;
+            }else{
+                try {
+                    Thread.sleep(1000);
+                } catch (InterruptedException e) {
+                    Thread.currentThread().interrupt();
+                }
+            }
+        }while(true);
+    }
+    public void releaseLock(String lockId) {
+        redisTemplate.delete(lockId);
+    }
+}
diff --git a/src/main/java/com/common/core/utils/DynamicBean.java b/src/main/java/com/common/core/utils/DynamicBean.java
new file mode 100644
index 0000000..2b08e04
--- /dev/null
+++ b/src/main/java/com/common/core/utils/DynamicBean.java
@@ -0,0 +1,43 @@
+package com.common.core.utils;
+
+
+import net.sf.cglib.beans.BeanGenerator;
+import net.sf.cglib.beans.BeanMap;
+
+import java.util.Map;
+
+class DynamicBean {
+
+    private Object target;
+
+    private BeanMap beanMap;
+
+    public DynamicBean(Class superclass, Map<String, Class> propertyMap) {
+        this.target = generateBean(superclass, propertyMap);
+        this.beanMap = BeanMap.create(this.target);
+    }
+
+    public void setValue(String property, Object value) {
+        beanMap.put(property, value);
+    }
+
+    public Object getValue(String property) {
+        return beanMap.get(property);
+    }
+
+    public Object getTarget() {
+        return this.target;
+    }
+
+    /**
+     * 鏍规嵁灞炴�х敓鎴愬璞�
+     */
+    private Object generateBean(Class superclass, Map<String, Class> propertyMap) {
+        BeanGenerator generator = new BeanGenerator();
+        if (null != superclass) {
+            generator.setSuperclass(superclass);
+        }
+        BeanGenerator.addProperties(generator, propertyMap);
+        return generator.create();
+    }
+}
diff --git a/src/main/java/com/common/core/utils/GsonUtils.java b/src/main/java/com/common/core/utils/GsonUtils.java
new file mode 100644
index 0000000..178f65a
--- /dev/null
+++ b/src/main/java/com/common/core/utils/GsonUtils.java
@@ -0,0 +1,69 @@
+package com.common.core.utils;
+
+import com.common.core.exception.BizException;
+import com.google.gson.Gson;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.text.StringEscapeUtils;
+
+/**
+ * @Author: 寤栨尟閽�
+ * @description: gonsutils
+ * @date 2022-01-06:10:45
+ * */
+@Slf4j
+public class GsonUtils {
+
+    public static Gson g = new Gson();
+
+
+    public static <T> T fromJson(String json, Class<? extends  T> t, int layer){
+        if(layer < 5) {
+            try {
+                if(layer == 0){
+                    return g.fromJson(json, t);
+                }else if (layer == 1){
+                    String tmp_json = StringEscapeUtils.unescapeJson(StringEscapeUtils.unescapeHtml4(json));
+                    return  g.fromJson(tmp_json, t);
+                }else  if (layer == 2){
+                    String tmp_json = StringEscapeUtils.unescapeJson(StringEscapeUtils.unescapeHtml4(json));
+                    String overjson = toJsonString(tmp_json);
+                    return g.fromJson(overjson, t);
+                }else  if (layer == 3){
+                    String overjson=json.replaceAll("\"}\",", "\"/}\",");
+                    return g.fromJson(overjson, t);
+                }else{
+                    String overjson = toJsonString(json);
+                    return  g.fromJson(overjson, t);
+                }
+            } catch (Exception e) {
+                return fromJson(json, t, layer + 1);
+            }
+        }else{
+            log.error("GSON瑙f瀽寮傚父:"+json);
+            throw new BizException("JSON瑙f瀽寮傚父");
+        }
+    }
+
+    private static String toJsonString(String s) {
+        char[] tempArr = s.toCharArray();
+        int tempLength = tempArr.length;
+        for (int i = 0; i < tempLength; i++) {
+            if (tempArr[i] == ':' && tempArr[i + 1] == '"') {
+                for (int j = i + 2; j < tempLength; j++) {
+                    if (tempArr[j] == '"') {
+                        if (tempArr[j + 1] != ',' && tempArr[j + 1] != '}') {
+                            tempArr[j] = '鈥�'; // 灏唙alue涓殑 鍙屽紩鍙锋浛鎹负涓枃鍙屽紩鍙�
+                        } else if (tempArr[j + 1] == ',' || tempArr[j + 1] == '}') {
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+        return new String(tempArr);
+    }
+
+    public static String toJson(Object o){
+        return g.toJson(g);
+    }
+}
diff --git a/src/main/java/com/common/core/utils/IdUtils.java b/src/main/java/com/common/core/utils/IdUtils.java
new file mode 100644
index 0000000..886ce37
--- /dev/null
+++ b/src/main/java/com/common/core/utils/IdUtils.java
@@ -0,0 +1,202 @@
+package com.common.core.utils;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Twitter_Snowflake<br>
+ * SnowFlake鐨勭粨鏋勫涓�(姣忛儴鍒嗙敤-鍒嗗紑):<br>
+ * 0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000 <br>
+ * 1浣嶆爣璇嗭紝鐢变簬long鍩烘湰绫诲瀷鍦↗ava涓槸甯︾鍙风殑锛屾渶楂樹綅鏄鍙蜂綅锛屾鏁版槸0锛岃礋鏁版槸1锛屾墍浠d涓�鑸槸姝f暟锛屾渶楂樹綅鏄�0<br>
+ * 41浣嶆椂闂存埅(姣绾�)锛屾敞鎰忥紝41浣嶆椂闂存埅涓嶆槸瀛樺偍褰撳墠鏃堕棿鐨勬椂闂存埅锛岃�屾槸瀛樺偍鏃堕棿鎴殑宸�硷紙褰撳墠鏃堕棿鎴� - 寮�濮嬫椂闂存埅)
+ * 寰楀埌鐨勫�硷級锛岃繖閲岀殑鐨勫紑濮嬫椂闂存埅锛屼竴鑸槸鎴戜滑鐨刬d鐢熸垚鍣ㄥ紑濮嬩娇鐢ㄧ殑鏃堕棿锛岀敱鎴戜滑绋嬪簭鏉ユ寚瀹氱殑锛堝涓嬩笅闈㈢▼搴廔dWorker绫荤殑startTime灞炴�э級銆�41浣嶇殑鏃堕棿鎴紝鍙互浣跨敤69骞达紝骞碩 = (1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69<br>
+ * 10浣嶇殑鏁版嵁鏈哄櫒浣嶏紝鍙互閮ㄧ讲鍦�1024涓妭鐐癸紝鍖呮嫭5浣峝atacenterId鍜�5浣峸orkerId<br>
+ * 12浣嶅簭鍒楋紝姣鍐呯殑璁℃暟锛�12浣嶇殑璁℃暟椤哄簭鍙锋敮鎸佹瘡涓妭鐐规瘡姣(鍚屼竴鏈哄櫒锛屽悓涓�鏃堕棿鎴�)浜х敓4096涓狪D搴忓彿<br>
+ * 鍔犺捣鏉ュ垰濂�64浣嶏紝涓轰竴涓狶ong鍨嬨��<br>
+ * SnowFlake鐨勪紭鐐规槸锛屾暣浣撲笂鎸夌収鏃堕棿鑷鎺掑簭锛屽苟涓旀暣涓垎甯冨紡绯荤粺鍐呬笉浼氫骇鐢烮D纰版挒(鐢辨暟鎹腑蹇僆D鍜屾満鍣↖D浣滃尯鍒�)锛屽苟涓旀晥鐜囪緝楂橈紝缁忔祴璇曪紝SnowFlake姣忕鑳藉浜х敓26涓嘔D宸﹀彸銆�
+ */
+@Component
+public class IdUtils {
+
+    // ==============================Fields===========================================
+    /** 寮�濮嬫椂闂存埅 (2015-01-01) */
+    private static final long twepoch = 1420041600000L;
+
+    /** 鏈哄櫒id鎵�鍗犵殑浣嶆暟 */
+    private static final long workerIdBits = 5L;
+
+    /** 鏁版嵁鏍囪瘑id鎵�鍗犵殑浣嶆暟 */
+    private static final long datacenterIdBits = 5L;
+
+    /** 鏀寔鐨勬渶澶ф満鍣╥d锛岀粨鏋滄槸31 (杩欎釜绉讳綅绠楁硶鍙互寰堝揩鐨勮绠楀嚭鍑犱綅浜岃繘鍒舵暟鎵�鑳借〃绀虹殑鏈�澶у崄杩涘埗鏁�) */
+    private static final long maxWorkerId = -1L ^ (-1L << workerIdBits);
+
+    /** 鏀寔鐨勬渶澶ф暟鎹爣璇唅d锛岀粨鏋滄槸31 */
+    private static final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
+
+    /** 搴忓垪鍦╥d涓崰鐨勪綅鏁� */
+    private static final long sequenceBits = 12L;
+
+    /** 鏈哄櫒ID鍚戝乏绉�12浣� */
+    private static final long workerIdShift = sequenceBits;
+
+    /** 鏁版嵁鏍囪瘑id鍚戝乏绉�17浣�(12+5) */
+    private static final long datacenterIdShift = sequenceBits + workerIdBits;
+
+    /** 鏃堕棿鎴悜宸︾Щ22浣�(5+5+12) */
+    private static final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
+
+    /** 鐢熸垚搴忓垪鐨勬帺鐮侊紝杩欓噷涓�4095 (0b111111111111=0xfff=4095) */
+    private static final long sequenceMask = -1L ^ (-1L << sequenceBits);
+
+    /** 宸ヤ綔鏈哄櫒ID(0~31) */
+    @Value("${custom.worker-id}")
+    private long workerId;
+
+    /** 鏁版嵁涓績ID(0~31) */
+    @Value("${custom.datacenter-id}")
+    private long datacenterId;
+
+    /** 姣鍐呭簭鍒�(0~4095) */
+    private long sequence = 0L;
+
+    /** 涓婃鐢熸垚ID鐨勬椂闂存埅 */
+    private long lastTimestamp = -1L;
+    public IdUtils(){
+
+    }
+
+    //==============================Constructors=====================================
+    /**
+     * 鏋勯�犲嚱鏁�
+     * @param workerId 宸ヤ綔ID (0~31)
+     * @param datacenterId 鏁版嵁涓績ID (0~31)
+     */
+    public IdUtils(long workerId, long datacenterId) {
+        if (workerId > maxWorkerId || workerId < 0) {
+            throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
+        }
+        if (datacenterId > maxDatacenterId || datacenterId < 0) {
+            throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
+        }
+        this.workerId = workerId;
+        this.datacenterId = datacenterId;
+    }
+
+    // ==============================Methods==========================================
+    /**
+     * 鑾峰緱涓嬩竴涓狪D (璇ユ柟娉曟槸绾跨▼瀹夊叏鐨�)
+     * @return SnowflakeId
+     */
+    public synchronized String nextId() {
+        long timestamp = timeGen();
+
+        //濡傛灉褰撳墠鏃堕棿灏忎簬涓婁竴娆D鐢熸垚鐨勬椂闂存埑锛岃鏄庣郴缁熸椂閽熷洖閫�杩囪繖涓椂鍊欏簲褰撴姏鍑哄紓甯�
+        if (timestamp < lastTimestamp) {
+            throw new RuntimeException(
+                    String.format("Clock moved backwards.  Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
+        }
+
+        //濡傛灉鏄悓涓�鏃堕棿鐢熸垚鐨勶紝鍒欒繘琛屾绉掑唴搴忓垪
+        if (lastTimestamp == timestamp) {
+            sequence = (sequence + 1) & sequenceMask;
+            //姣鍐呭簭鍒楁孩鍑�
+            if (sequence == 0) {
+                //闃诲鍒颁笅涓�涓绉�,鑾峰緱鏂扮殑鏃堕棿鎴�
+                timestamp = tilNextMillis(lastTimestamp);
+            }
+        }
+        //鏃堕棿鎴虫敼鍙橈紝姣鍐呭簭鍒楅噸缃�
+        else {
+            sequence = 0L;
+        }
+
+        //涓婃鐢熸垚ID鐨勬椂闂存埅
+        lastTimestamp = timestamp;
+        System.out.println(timestamp);
+
+        //绉讳綅骞堕�氳繃鎴栬繍绠楁嫾鍒颁竴璧风粍鎴�64浣嶇殑ID
+        long nextId= ((timestamp - twepoch) << timestampLeftShift) //
+                | (datacenterId << datacenterIdShift) //
+                | (workerId << workerIdShift) //
+                | sequence;
+        return String.valueOf(nextId);
+    }
+
+    /**
+     * 闃诲鍒颁笅涓�涓绉掞紝鐩村埌鑾峰緱鏂扮殑鏃堕棿鎴�
+     * @param lastTimestamp 涓婃鐢熸垚ID鐨勬椂闂存埅
+     * @return 褰撳墠鏃堕棿鎴�
+     */
+    protected long tilNextMillis(long lastTimestamp) {
+        long timestamp = timeGen();
+        while (timestamp <= lastTimestamp) {
+            timestamp = timeGen();
+        }
+        return timestamp;
+    }
+
+
+    /**
+     * 杩斿洖浠ユ绉掍负鍗曚綅鐨勫綋鍓嶆椂闂�
+     * @return
+     */
+    public long inverseDate(Long id) {
+        return (id >> timestampLeftShift) + twepoch;
+    }
+
+    /**
+     * 杩斿洖浠ユ绉掍负鍗曚綅鐨勫綋鍓嶆椂闂�
+     * @return 褰撳墠鏃堕棿(姣)
+     */
+    protected long timeGen() {
+        return System.currentTimeMillis();
+    }
+
+    //==============================Test=============================================
+    /** 娴嬭瘯 */
+    public static void main(String[] args) {
+        IdUtils idWorker = new IdUtils(0, 0);
+//        System.out.println(idWorker.inverseDate(Long.parseLong("1645595070821")));
+//        System.out.println(idWorker.inverseDate(Long.parseLong("1645595070820")));
+//        System.out.println(idWorker.inverseDate(Long.parseLong("1645595070819")));
+//        System.out.println(idWorker.inverseDate(Long.parseLong("1645595070818")));
+//        System.out.println(idWorker.inverseDate(Long.parseLong("1645595070801")));
+//        System.out.println(idWorker.inverseDate(Long.parseLong("1445595060102")));
+
+//        for (int i = 0; i < 100; i++) {
+//            String id = idWorker.nextId();
+//            System.out.println("id="+id);
+//            System.out.println("inverse_time="+idWorker.inverseDate((Long.valueOf(id))));
+//        }
+//        IdUtils idWorker = new IdUtils(0, 0);
+//
+//        for (int i = 0; i < 100; i++) {
+//            String id = idWorker.nextId();
+////            System.out.println(Long.toBinaryString(Long.valueOf(id)));
+////            System.out.println(id);
+//        }
+        String [] s = new String[]{
+                "1645595070820",
+                "1645595070821",
+                "1645595070822",
+                "1645595070819",
+                "1645595070823"};
+        IdUtils idUtils = new IdUtils();
+        List<String>  sortkeysets =  Arrays.stream(s).sorted(new Comparator<String>(){
+            @Override
+            public int compare(String o1, String o2) {
+                Long o1L = Long.parseLong(o1);
+                Long o2L = Long.parseLong(o2);
+                Long v = o1L-o2L; //鍊掑簭
+                return v.intValue();
+            }
+        }).collect(Collectors.toList());
+        sortkeysets.forEach( e -> System.out.println(e));
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/common/core/utils/JsonUtils.java b/src/main/java/com/common/core/utils/JsonUtils.java
new file mode 100644
index 0000000..505bc2e
--- /dev/null
+++ b/src/main/java/com/common/core/utils/JsonUtils.java
@@ -0,0 +1,75 @@
+package com.common.core.utils;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * Json杞崲宸ュ叿绫�
+ */
+@Slf4j
+public class JsonUtils {
+
+    public static final ObjectMapper objectMapper = new ObjectMapper();
+
+    /**
+     * 瀛楃涓茶浆瀵硅薄
+     *
+     * @param jsonStr json瀛楃涓�
+     * @param clazz   杞崲绫诲瀷
+     * @param <T>
+     * @return
+     */
+    public static <T> T string2Object(String jsonStr, Class<T> clazz) throws IOException {
+        return objectMapper.readValue(jsonStr, clazz);
+    }
+
+    /**
+     * 瀛楃涓茶浆鍒楄〃
+     *
+     * @param jsonStr json瀛楃涓�
+     * @param clazz   绫诲瀷
+     * @param <T>
+     * @return
+     * @throws JsonProcessingException
+     */
+    public static <T> Collection<T> string2List(String jsonStr, Class<T> clazz) throws IOException {
+        JavaType javaType = objectMapper.getTypeFactory().constructParametricType(Collection.class, clazz);
+        return (Collection<T>) objectMapper.readValue(jsonStr, javaType);
+    }
+
+    /**
+     * 瀵硅薄杞瓧绗︿覆
+     *
+     * @param object 瀵硅薄
+     * @return
+     * @throws JsonProcessingException
+     */
+    public static String object2String(Object object) {
+        if (object == null) {
+            return null;
+        }
+        try {
+            return objectMapper.writeValueAsString(object);
+        } catch (JsonProcessingException e) {
+            log.warn("瀵硅薄杞瓧绗︿覆", e);
+        }
+        return null;
+    }
+
+
+    public static String list2String(List object){
+        try {
+            return objectMapper.writeValueAsString(object);
+        } catch (JsonProcessingException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+}
diff --git a/src/main/java/com/common/core/utils/JwtTokenUtil.java b/src/main/java/com/common/core/utils/JwtTokenUtil.java
new file mode 100644
index 0000000..62741bb
--- /dev/null
+++ b/src/main/java/com/common/core/utils/JwtTokenUtil.java
@@ -0,0 +1,167 @@
+package com.common.core.utils;
+
+import com.common.core.constant.GlobalConst;
+import com.common.redis.util.RedisUtil;
+import com.common.security.configure.AppDetails;
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.SignatureAlgorithm;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.stereotype.Component;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+
+/**
+ * @author 寤栨尟閽�
+ * @date 2022-01-17
+ */
+@Slf4j
+@Component
+public class JwtTokenUtil {
+    @Autowired
+    private RedisUtil redisUtil;
+    public static final String CLAIM_KEY_APPID = "appid";
+    public static final String CLAIM_KEY_USERID = "userid";
+    private static final String CLAIM_KEY_CREATED = "created";
+    private Long expiration = GlobalConst.TOKEN_EXPIRE+GlobalConst.TOKEN_EXPIRE_BUFF;
+
+    /**
+     * 鏍规嵁璐熻矗鐢熸垚JWT鐨則oken
+     */
+    private String generateToken(Map<String, Object> claims) {
+        return Jwts.builder()
+                .setClaims(claims)
+                .setExpiration(generateExpirationDate())
+                .signWith(SignatureAlgorithm.HS512, SM4Utils.getPassword())
+                .compact();
+    }
+
+    /**
+     * 浠巘oken涓幏鍙朖WT涓殑璐熻浇
+     */
+    private Claims getClaimsFromToken(String token) {
+        Claims claims = Jwts.parser()
+                    .setSigningKey(SM4Utils.getPassword())
+                    .parseClaimsJws(token)
+                    .getBody();
+        return claims;
+    }
+
+    /**
+     * 鐢熸垚token鐨勮繃鏈熸椂闂�
+     */
+    private Date generateExpirationDate() {
+        return new Date(System.currentTimeMillis() + expiration * 1000);
+    }
+
+    /**
+     * 浠巘oken涓幏鍙栫櫥褰曠敤鎴峰悕
+     */
+    public String getAppidFromToken(String token) {
+        String appid;
+        try {
+            Claims claims = getClaimsFromToken(token);
+            appid = claims.get(CLAIM_KEY_APPID).toString();
+        } catch (Exception e) {
+            log.error("getAppidFromToken error:",e);
+            appid = null;
+        }
+        return appid;
+    }
+    /**
+     * 浠巘oken涓幏鍙栫櫥褰曠敤鎴峰悕
+     */
+    public String getUseridFromToken(String token) {
+        String userid;
+        try {
+            Claims claims = getClaimsFromToken(token);
+            userid = claims.get(CLAIM_KEY_USERID)==null? "" : claims.get(CLAIM_KEY_USERID).toString();
+        } catch (Exception e) {
+            log.error("getUseridFromToken error:",e);
+            userid = null;
+        }
+        return userid;
+    }
+
+    public Claims getClaim(String token) {
+        try {
+            Claims claims = getClaimsFromToken(token);
+            return claims;
+        } catch (Exception e) {
+            log.error("getClaim error:",e);
+            return null;
+        }
+    }
+
+    /**
+     * 楠岃瘉token鏄惁杩樻湁鏁�
+     *
+     * @param token       瀹㈡埛绔紶鍏ョ殑token
+     * @param userDetails 浠庢暟鎹簱涓煡璇㈠嚭鏉ョ殑鐢ㄦ埛淇℃伅
+     */
+    public boolean validateToken(String token, UserDetails userDetails) {
+        String key= GlobalConst.TOKEN_KEY+userDetails.getUsername();
+        String tmpKey= GlobalConst.TOKEN_KEY_TMP+userDetails.getUsername();
+        Object useridobject = getClaim(token).get(JwtTokenUtil.CLAIM_KEY_USERID);
+        if(!Objects.isNull(useridobject)){
+            key +=":"+useridobject.toString();
+            tmpKey +=":"+useridobject.toString();
+        }
+        return (redisUtil.get(key) !=null && token.equals(redisUtil.get(key).toString()) && !isTokenExpired(token))
+                ||(redisUtil.get(tmpKey) !=null && token.equals(redisUtil.get(tmpKey).toString()) && !isTokenExpired(token));
+    }
+
+    /**
+     * 鍒ゆ柇token鏄惁宸茬粡澶辨晥
+     */
+    private boolean isTokenExpired(String token) {
+        Date expiredDate = getExpiredDateFromToken(token);
+        return expiredDate.before(new Date());
+    }
+
+    /**
+     * 浠巘oken涓幏鍙栬繃鏈熸椂闂�
+     */
+    private Date getExpiredDateFromToken(String token) {
+        Claims claims = getClaimsFromToken(token);
+        return claims.getExpiration();
+    }
+
+    /**
+     * 鏍规嵁鐢ㄦ埛淇℃伅鐢熸垚token
+     */
+    public String generateToken(AppDetails userDetails) {
+        Map<String, Object> claims = new HashMap<>();
+        claims.put(CLAIM_KEY_APPID, userDetails.getUsername());
+        if(StringUtils.isNotEmpty(userDetails.getUserid())){
+            claims.put(CLAIM_KEY_USERID, userDetails.getUserid());
+
+        }
+        claims.put(CLAIM_KEY_CREATED, new Date());
+        return generateToken(claims);
+    }
+
+    /**
+     * 鍒ゆ柇token鏄惁鍙互琚埛鏂�
+     */
+    public boolean canRefresh(String token) {
+        return !isTokenExpired(token);
+    }
+
+    /**
+     * 鍒锋柊token
+     */
+    public String refreshToken(String token) {
+        Claims claims = getClaimsFromToken(token);
+        claims.put(CLAIM_KEY_CREATED, new Date());
+        return generateToken(claims);
+    }
+}
diff --git a/src/main/java/com/common/core/utils/KitClassUtils.java b/src/main/java/com/common/core/utils/KitClassUtils.java
new file mode 100644
index 0000000..7f87469
--- /dev/null
+++ b/src/main/java/com/common/core/utils/KitClassUtils.java
@@ -0,0 +1,13 @@
+package com.common.core.utils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author 寤栨尟閽�
+ * @date 2022-01-14
+ */
+public class KitClassUtils {
+
+    public static List<Class<?>> tableclass = new ArrayList<>();
+}
diff --git a/src/main/java/com/common/core/utils/ModelUtils.java b/src/main/java/com/common/core/utils/ModelUtils.java
new file mode 100644
index 0000000..d098368
--- /dev/null
+++ b/src/main/java/com/common/core/utils/ModelUtils.java
@@ -0,0 +1,120 @@
+package com.common.core.utils;
+
+import com.alibaba.fastjson.JSONObject;
+import com.common.core.constant.Constants;
+import com.common.core.domain.BaseModel;
+import com.common.security.utils.SecurityUtils;
+import com.jfinal.plugin.activerecord.Model;
+import com.jfinal.plugin.activerecord.TableMapping;
+import lombok.extern.slf4j.Slf4j;
+
+import java.lang.reflect.Field;
+import java.math.BigDecimal;
+import java.time.*;
+import java.util.Date;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @Author: 寤栨尟閽�
+ * @description: ModelUtils
+ * @date 2022-01-03:10:36
+ * */
+@Slf4j
+public class ModelUtils {
+
+    public static <T extends BaseModel> T MapToModel(Map<String, Object> map, T t){
+        for(String key : map.keySet()){
+            t.set(key, map.get(key));
+        }
+        return t;
+    }
+
+    public static <T extends BaseModel> T ObjectToModel(Object object, T t) {
+        Field[] declaredFields = object.getClass().getDeclaredFields();
+        for (int i = 0; i < declaredFields.length; i++) {
+            String name = declaredFields[i].getName();
+            Field f = declaredFields[i];
+            f.setAccessible(true);
+            try {
+                t.set(name, f.get(object));
+            } catch (IllegalAccessException e) {
+                log.error(e.getMessage(), e);
+            }
+        }
+        return t;
+    }
+
+    public static <T extends BaseModel> T JsonToModel(JSONObject json, T t) {
+        for(String key : json.keySet()){
+            if(json.get(key)==null){
+                continue;
+            }
+            if(key.equalsIgnoreCase("dataid")){
+                t.set("id", json.get(key));
+            }else if(isPrimitive(json.get(key).getClass())){
+                if(recordAttrHas(BeanHelper.propertyToColumn(key),t.getClass())){
+                    t.set(BeanHelper.propertyToColumn(key), json.get(key));
+                }else if(recordAttrHas(key,t.getClass())){
+                    t.set(key, json.get(key));
+                }
+            }else {
+                if(recordAttrHas(BeanHelper.propertyToColumn(key),t.getClass())){
+                    t.set(BeanHelper.propertyToColumn(key), JSONObject.toJSONString(json.get(key)));
+                }else if(recordAttrHas(key,t.getClass())){
+                    t.set(key, JSONObject.toJSONString(json.get(key)));
+                }
+            }
+        }
+        return t;
+    }
+
+    private static Boolean recordAttrHas(String columnName,Class<? extends Model> clz){
+        Set<String> names = TableMapping.me().getTable(clz).getColumnNameSet();
+        if(names.contains(columnName)){
+            return true;
+        }
+        return false;
+    }
+    /**
+     * 鍩烘湰鏁版嵁绫诲瀷鍜孲tring绫诲瀷鍒ゆ柇
+     *
+     * @param clz
+     * @return
+     */
+    public static boolean isPrimitive(Class<?> clz) {
+        try {
+            if (String.class.isAssignableFrom(clz) || Date.class.isAssignableFrom(clz)|| BigDecimal.class.isAssignableFrom(clz) || LocalDateTime.class.isAssignableFrom(clz)
+                    || LocalDate.class.isAssignableFrom(clz)  || LocalTime.class.isAssignableFrom(clz)  || Year.class.isAssignableFrom(clz)
+                    || YearMonth.class.isAssignableFrom(clz)  || Month.class.isAssignableFrom(clz) || clz.isPrimitive()) {
+                return true;
+            } else {
+                return ((Class) clz.getField("TYPE").get(null)).isPrimitive();
+            }
+        } catch (Exception e) {
+            return false;
+        }
+    }
+
+    /**
+     * 璁剧疆鍏叡淇℃伅
+     * @param baseModel
+     * @param action
+     */
+    public static void generateCommonInfo(BaseModel baseModel,String action){
+        String appid = SecurityUtils.byId();
+        if (action.equals(Constants.ACTION_CREATE)) {
+            baseModel.setCreateBy(appid);
+            baseModel.setCreateTime(DateUtils.now());
+            baseModel.setUpdateTime(DateUtils.now());
+            baseModel.setUpdateBy(appid);
+            baseModel.setIsDelete(0);
+        }else if(action.equals(Constants.ACTION_UPDATE)){
+            baseModel.setUpdateTime(DateUtils.now());
+            baseModel.setUpdateBy(appid);
+        }else {
+            baseModel.setUpdateTime(new Date());
+            baseModel.setUpdateBy(appid);
+        }
+    }
+}
diff --git a/src/main/java/com/common/core/utils/PdfConverUtils.java b/src/main/java/com/common/core/utils/PdfConverUtils.java
new file mode 100644
index 0000000..1ca62f0
--- /dev/null
+++ b/src/main/java/com/common/core/utils/PdfConverUtils.java
@@ -0,0 +1,50 @@
+package com.common.core.utils;
+
+/**
+ * @author 寤栨尟閽�
+ * @date 2022-01-13 11:31
+ */
+public class PdfConverUtils {
+
+    /**
+     * @param
+     *     wordPath
+     * @param
+     *     pdfPath
+     * */
+    public static void wordToPdf(String wordPath, String pdfPath){
+
+    }
+
+    /**
+     * @param
+     *     htmlPath
+     * @param
+     *     pdfPath
+     * */
+    public static void htmlToPdf(String htmlPath, String pdfPath){
+
+    }
+
+
+    /**
+     * @param
+     *     textPath
+     * @param
+     *     pdfPath
+     * */
+    public static void textToPdf(String textPath, String pdfPath){
+
+    }
+
+
+    /**
+     * @param
+     *     imgDirPath
+     * @param
+     *     pdfPath
+     * */
+    public static void imageToPdf(String imgDirPath, String pdfPath){
+
+    }
+}
diff --git a/src/main/java/com/common/core/utils/RegexUtils.java b/src/main/java/com/common/core/utils/RegexUtils.java
new file mode 100644
index 0000000..fed16e2
--- /dev/null
+++ b/src/main/java/com/common/core/utils/RegexUtils.java
@@ -0,0 +1,28 @@
+package com.common.core.utils;
+
+
+import java.util.regex.Pattern;
+
+/**
+ * @Author holfeng
+ * @Date 10:18 28/03/2022
+ * @Version 1.0
+ **/
+public class RegexUtils {
+
+
+
+    /**
+     * 鍒ゆ柇鏄惁鏄墜鏈哄彿
+     * @param tel 鎵嬫満鍙�
+     * @return boolean true:鏄�  false:鍚�
+     */
+    public static boolean isMobile(String tel) {
+        Pattern p = Pattern.compile("((\\+86|0086)?\\s*)((134[0-8]\\d{7})|(((13([0-3]|[5-9]))|(14[5-9])|15([0-3]|[5-9])|(16(2|[5-7]))|17([0-3]|[5-8])|18[0-9]|19(1|[8-9]))\\d{8})|(14(0|1|4)0\\d{7})|(1740([0-5]|[6-9]|[10-12])\\d{7}))");
+        if(p.matcher(tel).matches()){
+            return true;
+        }
+        return false;
+    }
+
+}
diff --git a/src/main/java/com/common/core/utils/RestUtil.java b/src/main/java/com/common/core/utils/RestUtil.java
new file mode 100644
index 0000000..6e6b3b2
--- /dev/null
+++ b/src/main/java/com/common/core/utils/RestUtil.java
@@ -0,0 +1,310 @@
+package com.common.core.utils;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.http.*;
+import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
+import org.springframework.http.converter.StringHttpMessageConverter;
+import org.springframework.web.client.RestTemplate;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Optional;
+
+
+@Slf4j
+public class RestUtil {
+
+    private static String domain = null;
+
+
+    public static String getString(String s, String defval) {
+        if (isEmpty(s)) {
+            return (defval);
+        }
+        return (s.trim());
+    }
+
+    public static boolean isEmpty(Object object) {
+        if (object == null) {
+            return (true);
+        }
+        if ("".equals(object)) {
+            return (true);
+        }
+        if ("null".equals(object)) {
+            return (true);
+        }
+        return (false);
+    }
+
+    /**
+     * RestAPI 璋冪敤鍣�
+     */
+    private final static RestTemplate RT;
+
+    static {
+        HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
+        requestFactory.setConnectTimeout(1000*60*5);
+        requestFactory.setReadTimeout(1000*60*5);
+        RT = new RestTemplate(requestFactory);
+        // 瑙e喅涔辩爜闂
+        RT.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
+    }
+
+    public static RestTemplate getRestTemplate() {
+        return RT;
+    }
+
+    /**
+     * 鍙戦�� get 璇锋眰
+     */
+    public static JSONObject get(String url) {
+        return getNative(url, null, null).getBody();
+    }
+
+    /**
+     * 鍙戦�� get 璇锋眰
+     */
+    public static JSONObject get(String url, JSONObject variables) {
+        return getNative(url, variables, null).getBody();
+    }
+
+    /**
+     * 鍙戦�� get 璇锋眰
+     */
+    public static JSONObject get(String url, JSONObject variables, JSONObject params) {
+        return getNative(url, variables, params).getBody();
+    }
+
+    /**
+     * 鍙戦�� get 璇锋眰锛岃繑鍥炲師鐢� ResponseEntity 瀵硅薄
+     */
+    public static ResponseEntity<JSONObject> getNative(String url, JSONObject variables, JSONObject params) {
+        return request(url, HttpMethod.GET, variables, params);
+    }
+    public static ResponseEntity<JSONObject> getNative(String url, HttpHeaders headers) {
+        return request(url, headers, HttpMethod.GET);
+    }
+
+    public static JSONObject get(String url, HttpHeaders headers) {
+        return request(url, headers, HttpMethod.GET).getBody();
+    }
+
+    /**
+     * 鍙戦�� Post 璇锋眰
+     */
+    public static JSONObject post(String url) {
+        return postNative(url, null, new JSONObject()).getBody();
+    }
+
+    /**
+     * 鍙戦�� Post 璇锋眰
+     */
+    public static JSONObject post(String url, JSONObject params) {
+        return postNative(url, null, params).getBody();
+    }
+
+    /**
+     * 鍙戦�� Post 璇锋眰
+     */
+    public static JSONObject post(String url, JSONObject variables, JSONObject params) {
+        return postNative(url, variables, params).getBody();
+    }
+
+    public static JSONObject post(String url, HttpHeaders headers, JSONObject variables, Object params) {
+        return request(url, headers, HttpMethod.POST, variables, params).getBody();
+    }
+
+    /**
+     * 鍙戦�� POST 璇锋眰锛岃繑鍥炲師鐢� ResponseEntity 瀵硅薄
+     */
+    public static ResponseEntity<JSONObject> postNative(String url, HttpHeaders headers, JSONObject variables, Object params) {
+        return request(url, headers, HttpMethod.POST, variables, params);
+    }
+    public static ResponseEntity<JSONObject> postNative(String url, HttpHeaders headers, JSONObject variables, String params) {
+        return request(url, headers, HttpMethod.POST, variables, params);
+    }
+
+    public static ResponseEntity<Object> postNativeObject(String url, HttpHeaders headers, JSONObject variables, String params) {
+        return requestObject(url, headers, HttpMethod.POST, variables, params);
+    }
+    public static ResponseEntity<JSONObject> postNative(String url, JSONObject variables, JSONObject params) {
+        return request(url, HttpMethod.POST, variables, params);
+    }
+
+    public static ResponseEntity<JSONObject> postNative(String url, JSONObject variables, JSONArray params) {
+        return request(url, HttpMethod.POST, variables, params);
+    }
+
+    /**
+     * 鍙戦�� PATCH 璇锋眰锛岃繑鍥炲師鐢� ResponseEntity 瀵硅薄
+     */
+    public static ResponseEntity<JSONObject> patchNative(String url, HttpHeaders headers, JSONObject variables, String params) {
+        return request(url, headers, HttpMethod.PATCH, variables, params);
+    }
+
+    /**
+     * 鍙戦�� put 璇锋眰
+     */
+    public static JSONObject put(String url) {
+        return putNative(url, null, null).getBody();
+    }
+
+    /**
+     * 鍙戦�� put 璇锋眰
+     */
+    public static JSONObject put(String url, JSONObject params) {
+        return putNative(url, null, params).getBody();
+    }
+
+    /**
+     * 鍙戦�� put 璇锋眰
+     */
+    public static JSONObject put(String url, JSONObject variables, JSONObject params) {
+        return putNative(url, variables, params).getBody();
+    }
+
+    /**
+     * 鍙戦�� put 璇锋眰锛岃繑鍥炲師鐢� ResponseEntity 瀵硅薄
+     */
+    public static ResponseEntity<JSONObject> putNative(String url, JSONObject variables, JSONObject params) {
+        return request(url, HttpMethod.PUT, variables, params);
+    }
+
+    /**
+     * 鍙戦�� delete 璇锋眰
+     */
+    public static JSONObject delete(String url) {
+        return deleteNative(url, null, null).getBody();
+    }
+
+    /**
+     * 鍙戦�� delete 璇锋眰
+     */
+    public static JSONObject delete(String url, JSONObject variables, JSONObject params) {
+        return deleteNative(url, variables, params).getBody();
+    }
+
+    /**
+     * 鍙戦�� delete 璇锋眰锛岃繑鍥炲師鐢� ResponseEntity 瀵硅薄
+     */
+    public static ResponseEntity<JSONObject> deleteNative(String url, JSONObject variables, JSONObject params) {
+        return request(url, HttpMethod.DELETE, null, variables, params, JSONObject.class);
+    }
+
+    /**
+     * 鍙戦�佽姹�
+     */
+    public static ResponseEntity<JSONObject> request(String url, HttpMethod method, JSONObject variables, JSONObject params) {
+        return request(url, method, getHeaderApplicationJson(), variables, params, JSONObject.class);
+    }
+
+    public static ResponseEntity<JSONObject> request(String url, HttpMethod method, JSONObject variables, JSONArray params) {
+        return request(url, method, getHeaderApplicationJson(), variables, params, JSONObject.class);
+    }
+
+
+    public static ResponseEntity<JSONObject> request(String url, HttpHeaders headers, HttpMethod method, JSONObject variables, Object params) {
+        return request(url, method, headers, variables, params, JSONObject.class);
+    }
+
+    public static ResponseEntity<Object> requestObject(String url, HttpHeaders headers, HttpMethod method, JSONObject variables, Object params) {
+        return request(url, method, headers, variables, params, Object.class);
+    }
+
+    public static ResponseEntity<JSONObject> request(String url, HttpHeaders headers,HttpMethod method) {
+        return request(url, method, headers, null, null, JSONObject.class);
+    }
+
+    /**
+     * 鍙戦�佽姹�
+     *
+     * @param url          璇锋眰鍦板潃
+     * @param method       璇锋眰鏂瑰紡
+     * @param headers      璇锋眰澶�  鍙┖
+     * @param variables    璇锋眰url鍙傛暟 鍙┖
+     * @param params       璇锋眰body鍙傛暟 鍙┖
+     * @param responseType 杩斿洖绫诲瀷
+     * @return ResponseEntity<responseType>
+     */
+    public static <T> ResponseEntity<T> request(String url, HttpMethod method, HttpHeaders headers, JSONObject variables, Object params, Class<T> responseType) {
+        log.info(" RestUtil  --- request ---  url = "+ url);
+        if (StringUtils.isEmpty(url)) {
+            throw new RuntimeException("url 涓嶈兘涓虹┖");
+        }
+        if (method == null) {
+            throw new RuntimeException("method 涓嶈兘涓虹┖");
+        }
+        if (headers == null) {
+            headers = new HttpHeaders();
+        }
+        // 璇锋眰浣�
+        String body = "";
+        if (params != null) {
+            log.info(url+",json="+params.toString());
+            if (params instanceof JSONObject) {
+                body = ((JSONObject) params).toJSONString();
+
+            } else {
+                body = params.toString();
+            }
+        }
+        // 鎷兼帴 url 鍙傛暟
+        if (variables != null) {
+            log.info(url+",variables:"+asUrlVariables(variables));
+            url += ("?" + asUrlVariables(variables));
+        }
+        // 鍙戦�佽姹�
+        HttpEntity<String> request = new HttpEntity<>(body, headers);
+        ResponseEntity<T> resp = RT.exchange(url, method, request, responseType);
+        Optional o = Optional.ofNullable(resp.getBody());
+        if(o.isPresent()) {
+            log.info(url + ": reponsebody=" + o.get());
+        }
+        return resp;
+    }
+
+    /**
+     * 鑾峰彇JSON璇锋眰澶�
+     */
+    public static HttpHeaders getHeaderApplicationJson() {
+        return getHeader(MediaType.APPLICATION_JSON_UTF8_VALUE);
+    }
+
+    /**
+     * 鑾峰彇璇锋眰澶�
+     */
+    public static HttpHeaders getHeader(String mediaType) {
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.parseMediaType(mediaType));
+        headers.add("Accept", mediaType);
+        return headers;
+    }
+
+    /**
+     * 灏� JSONObject 杞负 a=1&b=2&c=3...&n=n 鐨勫舰寮�
+     */
+    public static String asUrlVariables(JSONObject variables) {
+        Map<String, Object> source = variables.getInnerMap();
+        Iterator<String> it = source.keySet().iterator();
+        StringBuilder urlVariables = new StringBuilder();
+        while (it.hasNext()) {
+            String key = it.next();
+            String value = "";
+            Object object = source.get(key);
+            if (object != null) {
+                if (!StringUtils.isEmpty(object.toString())) {
+                    value = object.toString();
+                }
+            }
+            urlVariables.append("&").append(key).append("=").append(value);
+        }
+        // 鍘绘帀绗竴涓�&
+        return urlVariables.substring(1);
+    }
+
+}
diff --git a/src/main/java/com/common/core/utils/SM4Utils.java b/src/main/java/com/common/core/utils/SM4Utils.java
new file mode 100644
index 0000000..76e6e8c
--- /dev/null
+++ b/src/main/java/com/common/core/utils/SM4Utils.java
@@ -0,0 +1,53 @@
+package com.common.core.utils;
+
+import cn.hutool.crypto.SmUtil;
+import cn.hutool.crypto.symmetric.SymmetricCrypto;
+import org.springframework.core.env.Environment;
+
+/**
+ * @author 寤栨尟閽�
+ * @date 20/12/2021
+ */
+public class SM4Utils {
+    private static String password = "";
+
+    public static String getPassword() {
+        getInit();
+        return password;
+    }
+
+    public static void getInit(){
+        if(StringUtils.isBlank(password)) {
+            SecretsManagerUtils secretsManagerUtils = SpringContextUtils.getBean(SecretsManagerUtils.class);
+            Environment env = SpringContextUtils.getBean(Environment.class);
+            password = secretsManagerUtils.getSecret(env.getProperty("aws.secrets.sm4")).getString("SM4Secret");
+        }
+    }
+
+    public static String decrypt(String text){
+        getInit();
+        if(text.startsWith("DES@")) {
+            SymmetricCrypto sm4 = SmUtil.sm4(password.getBytes());
+            return sm4.decryptStr(text);
+        }
+        return text;
+    }
+
+    public static String decryptStr(String text){
+        if(null == text || "".equals(text)){
+            return text;
+        }
+        getInit();
+        SymmetricCrypto sm4 = SmUtil.sm4(password.getBytes());
+        return sm4.decryptStr(text);
+    }
+
+    public static String encryptStr(String text){
+        if(null == text || "".equals(text)){
+            return text;
+        }
+        getInit();
+        SymmetricCrypto sm4 = SmUtil.sm4(password.getBytes());
+        return sm4.encryptHex(text);
+    }
+}
diff --git a/src/main/java/com/common/core/utils/SecretsManagerUtils.java b/src/main/java/com/common/core/utils/SecretsManagerUtils.java
new file mode 100644
index 0000000..ac7fad7
--- /dev/null
+++ b/src/main/java/com/common/core/utils/SecretsManagerUtils.java
@@ -0,0 +1,105 @@
+package com.common.core.utils;
+
+import com.alibaba.fastjson.JSONObject;
+import com.common.core.enums.ResultCodeEnum;
+import com.common.core.exception.BizException;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
+import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
+import software.amazon.awssdk.auth.credentials.InstanceProfileCredentialsProvider;
+import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
+import software.amazon.awssdk.regions.Region;
+import software.amazon.awssdk.services.secretsmanager.SecretsManagerClient;
+import software.amazon.awssdk.services.secretsmanager.model.*;
+
+import java.util.Base64;
+
+@Slf4j
+@Component
+public class SecretsManagerUtils {
+    @Value("${aws.region}")
+    private String regionStr;
+    @Value("${aws.secrets.systemauth}")
+    private String systemauthName;
+    @Value("${aws.secrets.mysql}")
+    private String mysqlsecretName;
+    @Value("${aws.secrets.sm4}")
+    private String SM4SecretName;
+    @Value("${aws.secrets.mailauth}")
+    private String mailauthName;
+
+    private static JSONObject systemAuth;
+    private static JSONObject mysqlsecret;
+    private static JSONObject SM4Secret;
+    private static JSONObject mailauth;
+
+    private void getInit() {
+        if(systemAuth==null){
+            systemAuth=this.getSecretByName(systemauthName);
+        }
+        if(mysqlsecret==null){
+            mysqlsecret=this.getSecretByName(mysqlsecretName);
+        }
+        if(SM4Secret==null){
+            SM4Secret=this.getSecretByName(SM4SecretName);
+        }
+        if(mailauth==null){
+            mailauth=this.getSecretByName(mailauthName);
+        }
+    }
+    public JSONObject getSecretByName(String secretName) {
+        String key_id = System.getenv("AWS_ACCESS_KEY_ID");
+        String access_key = System.getenv("AWS_SECRET_ACCESS_KEY");
+        Region region = Region.of(regionStr);
+        SecretsManagerClient client = null;
+        if(StringUtils.isNotEmpty(key_id) && StringUtils.isNotEmpty(access_key)){
+            AwsBasicCredentials awsCreds = AwsBasicCredentials.create(key_id,access_key);
+            client = SecretsManagerClient.builder().credentialsProvider(StaticCredentialsProvider.create(awsCreds))
+                    .region(region)
+                    .build();
+        }else {
+            AwsCredentialsProvider credentialsProvider = InstanceProfileCredentialsProvider.builder().build();
+            client = SecretsManagerClient.builder().credentialsProvider(credentialsProvider)
+                    .region(region)
+                    .build();
+        }
+        String secret, decodedBinarySecret;
+        GetSecretValueRequest getSecretValueRequest = GetSecretValueRequest.builder()
+                .secretId(secretName)
+                .build();
+        GetSecretValueResponse getSecretValueResponse = null;
+
+        try {
+            getSecretValueResponse = client.getSecretValue(getSecretValueRequest);
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+            throw new BizException(ResultCodeEnum.AWS_RT_ERROR);
+        }
+        if (getSecretValueResponse.secretString() != null) {
+            return JSONObject.parseObject(getSecretValueResponse.secretString());
+        }
+        else {
+            decodedBinarySecret = new String(Base64.getDecoder().decode(getSecretValueResponse.secretBinary().asByteBuffer()).array());
+            return JSONObject.parseObject(getSecretValueResponse.secretString());
+        }
+    }
+    public JSONObject getSecret(String secretName) {
+        this.getInit();
+        if(secretName.equals(systemauthName)){
+            return systemAuth;
+        }
+        if(secretName.equals(mysqlsecretName)){
+            return mysqlsecret;
+        }
+        if(secretName.equals(SM4SecretName)){
+            return SM4Secret;
+        }
+        if(secretName.equals(mailauthName)){
+            return mailauth;
+        }
+        return getSecretByName(secretName);
+    }
+}
diff --git a/src/main/java/com/common/core/utils/SignUtil.java b/src/main/java/com/common/core/utils/SignUtil.java
new file mode 100644
index 0000000..8b4edcc
--- /dev/null
+++ b/src/main/java/com/common/core/utils/SignUtil.java
@@ -0,0 +1,73 @@
+package com.common.core.utils;
+
+import org.apache.commons.codec.digest.HmacUtils;
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.util.CollectionUtils;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author 寤栨尟閽�
+ * @date 2022-01-14
+ */
+public class SignUtil {
+    private static final String DEFAULT_SECRET = "1qaz@WSX#$%&";
+    public static String sign(String body, Map<String, String[]> params, String[] paths) {
+
+        StringBuilder sb = new StringBuilder();
+
+        if (StringUtils.isNotBlank(body)) {
+            sb.append(body).append('#');
+        }
+
+        if (!CollectionUtils.isEmpty(params)) {
+            params.entrySet().stream().sorted(Map.Entry.comparingByKey()).forEach(paramEntry -> {
+                String paramValue = String.join(",", Arrays.stream(paramEntry.getValue()).sorted().toArray(String[]::new));
+                sb.append(paramEntry.getKey()).append("=").append(paramValue).append('#');
+            });
+        }
+
+        if (ArrayUtils.isNotEmpty(paths)) {
+            String pathValues = String.join(",", Arrays.stream(paths).sorted().toArray(String[]::new));
+            sb.append(pathValues);
+        }
+
+        String createSign = HmacUtils.hmacSha256Hex(DEFAULT_SECRET, sb.toString());
+        return createSign;
+    }
+
+    public static String sign(String secret, String body, Map<String, String[]> params, String[] paths) {
+
+        StringBuilder sb = new StringBuilder();
+
+        if (StringUtils.isNotBlank(body)) {
+            sb.append(body).append('#');
+        }
+
+        if (!CollectionUtils.isEmpty(params)) {
+            params.entrySet().stream().sorted(Map.Entry.comparingByKey()).forEach(paramEntry -> {
+                String paramValue = String.join(",", Arrays.stream(paramEntry.getValue()).sorted().toArray(String[]::new));
+                sb.append(paramEntry.getKey()).append("=").append(paramValue).append('#');
+            });
+        }
+
+        if (ArrayUtils.isNotEmpty(paths)) {
+            String pathValues = String.join(",", Arrays.stream(paths).sorted().toArray(String[]::new));
+            sb.append(pathValues);
+        }
+
+        String createSign = HmacUtils.hmacSha256Hex(secret, sb.toString());
+        return createSign;
+    }
+
+    public static void main(String[] args) {
+        String body = "{\n" + "\t\"name\": \"hjzgg\",\n" + "\t\"age\": 26\n" + "}";
+        Map<String, String[]> params = new HashMap<>();
+        params.put("var3", new String[]{"3"});
+        params.put("var4", new String[]{"4"});
+        String[] paths = new String[]{"1", "2"};
+        System.out.println(sign(body, params, paths));
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/common/core/utils/SpringContextUtils.java b/src/main/java/com/common/core/utils/SpringContextUtils.java
new file mode 100644
index 0000000..80f51dd
--- /dev/null
+++ b/src/main/java/com/common/core/utils/SpringContextUtils.java
@@ -0,0 +1,83 @@
+package com.common.core.utils;
+import javax.servlet.http.HttpServletRequest;
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+@Component
+public class SpringContextUtils implements ApplicationContextAware {
+
+    /**
+     * 涓婁笅鏂囧璞″疄渚�
+     */
+    private static ApplicationContext applicationContext;
+
+    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+        SpringContextUtils.applicationContext = applicationContext;
+    }
+
+    /**
+     * 鑾峰彇applicationContext
+     *
+     * @return
+     */
+    public static ApplicationContext getApplicationContext() {
+        return applicationContext;
+    }
+
+    /**
+     * 鑾峰彇HttpServletRequest
+     */
+    public static HttpServletRequest getHttpServletRequest() {
+        return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+    }
+
+
+    public static String getOrigin(){
+        HttpServletRequest request = getHttpServletRequest();
+        return request.getHeader("Origin");
+    }
+
+    /**
+     * 閫氳繃name鑾峰彇 Bean.
+     *
+     * @param name
+     * @return
+     */
+    public static Object getBean(String name) {
+        return getApplicationContext().getBean(name);
+    }
+
+    /**
+     * 閫氳繃class鑾峰彇Bean.
+     *
+     * @param clazz
+     * @param       <T>
+     * @return
+     */
+    public static <T> T getBean(Class<T> clazz) {
+        return getApplicationContext().getBean(clazz);
+    }
+
+    /**
+     * 閫氳繃name,浠ュ強Clazz杩斿洖鎸囧畾鐨凚ean
+     *
+     * @param name
+     * @param clazz
+     * @param       <T>
+     * @return
+     */
+    public static <T> T getBean(String name, Class<T> clazz) {
+        return getApplicationContext().getBean(name, clazz);
+    }
+
+    public static String getEnvParam(String key){
+        Environment env = getBean(Environment.class);
+        return env.getProperty(key);
+    }
+}
+
diff --git a/src/main/java/com/common/core/utils/StringUtils.java b/src/main/java/com/common/core/utils/StringUtils.java
new file mode 100644
index 0000000..e4e0a25
--- /dev/null
+++ b/src/main/java/com/common/core/utils/StringUtils.java
@@ -0,0 +1,293 @@
+package com.common.core.utils;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @author : zhouxb
+ * date: 2017-10-25 23:54
+ */
+public class StringUtils extends org.apache.commons.lang3.StringUtils {
+
+    /**
+     * SQL鏍煎紡鍖栬〃鍚嶅拰瀛楁鍚嶅姞"`"
+     *
+     * @param fieldName
+     * @return
+     */
+    public static String formatFieldNameColumn(String fieldName) {
+        return new StringBuffer("`").append(fieldName).append("`").toString();
+    }
+
+    public static String formatStringFiledVal(String fieldName) {
+        return new StringBuffer("'").append(fieldName).append("'").toString();
+    }
+
+    public static String formatFieldNameColumn4Rdb(String fieldName) {
+        return new StringBuffer("\"").append(fieldName).append("\"").toString();
+    }
+
+    /**
+     * 鍘绘帀瀛楃涓叉寚瀹氬墠缂�閮ㄥ垎
+     *
+     * @param source 瀛楃涓�
+     * @param prefix 鍓嶇紑
+     */
+    public static String cutPrefix(String source, String prefix) {
+        if (isNotBlank(source)) {
+            if (isNotEmpty(prefix)) {
+                if (source.startsWith(prefix)) {
+                    int prefixLen = prefix.length();
+                    source = source.substring(prefixLen);
+                }
+            }
+        }
+        return source;
+    }
+
+    /**
+     * 鍘绘帀瀛楃涓叉寚瀹氬悗缂�閮ㄥ垎
+     *
+     * @param source 瀛楃涓�
+     * @param suffix 鍚庣紑
+     */
+    public static String cutSuffix(String source, String suffix) {
+        if (isNotBlank(source)) {
+            if (isNotEmpty(suffix)) {
+                int suffixLen = suffix.length();
+                source = source.substring(0, source.length() - suffixLen);
+            }
+        }
+        return source;
+    }
+
+    /**
+     * 鍘绘帀瀛楃涓蹭腑鎸囧畾瀛楃鍙婂叾鍚庨潰閮ㄥ垎
+     *
+     * @param source    瀛楃涓�
+     * @param separator 鎸囧畾瀛楃
+     */
+    public static String cutLaterOfCharacter(String source, String separator) {
+        if (isNotBlank(source)) {
+            if (isNotEmpty(separator)) {
+                int index = source.indexOf(separator);
+                if (index > -1) {
+                    source = source.substring(0, index);
+                }
+            }
+        }
+        return source;
+    }
+
+    /**
+     * sql璇彞like閮ㄥ垎
+     * 澧炲姞瀵�%杞箟
+     *
+     * @param in
+     * @return
+     */
+    public static String sqlLike(String in) {
+//        if (StringUtils.isNotEmpty(in) && in.contains("%")) {
+//            in = in.replace("\\", "\\\\");
+//            in = in.replace("%", "\\%");
+//            in = in.replace("_", "\\_");
+//        }
+        return "%" + sqlLikeXML(in) + "%";
+    }
+
+    public static String sqlLikeXML(String in) {
+        if (StringUtils.isNotEmpty(in) && (in.contains("%") || in.contains("_") || in.contains("\\"))) {
+            in = in.replace("\\", "\\\\");
+            in = in.replace("%", "\\%");
+            in = in.replace("_", "\\_");
+        }
+        return in;
+    }
+
+    /**
+     * 鎸夋寚瀹氬垎鍓茬鍒嗗壊瀛楃涓�,杩斿洖缁撴灉涓笉鍖呭惈绌哄瓧绗︿覆
+     */
+    public static String[] tokenizeToStringArray(String cs, String delimiters) {
+        String[] csAry = org.springframework.util.StringUtils.tokenizeToStringArray(cs, delimiters);
+        List<String> result = new ArrayList<>(csAry.length);
+        for (String csa : csAry) {
+            if (isNotBlank(csa)) {
+                result.add(csa);
+            }
+        }
+        return result.toArray(new String[result.size()]);
+    }
+
+    /**
+     * 鎷嗗垎token鏂规硶
+     *
+     * @param cs
+     * @return
+     */
+    public static String[] tokenizeToStringArray(String cs) {
+        return tokenizeToStringArray(cs, ",");
+    }
+
+    /**
+     * 灏嗛泦鍚堢敤杞崲涓烘寚瀹氬垎闅旂杩炴帴鐨勫瓧绗︿覆
+     *
+     * @param coll
+     * @param delimiter
+     * @return
+     */
+    public static String collectionToDelimitedString(Collection<?> coll, String delimiter) {
+        return org.springframework.util.StringUtils.collectionToDelimitedString(coll, delimiter);
+    }
+
+    /**
+     * 灏嗛泦鍚堢敤","杩炴帴鐨勫瓧绗︿覆
+     *
+     * @param coll
+     * @return
+     */
+    public static String collectionToDelimitedString(Collection<?> coll) {
+        return collectionToDelimitedString(coll, ",");
+    }
+
+    /**
+     * 灏嗘暟缁勮浆鎹负鐢�","杩炴帴鐨勫瓧绗︿覆
+     *
+     * @param ary
+     * @return
+     */
+//    public static String arrayToCommaDelimitedString(Object[] ary) {
+//        return arrayToDelimitedString(ary, ",");
+//    }
+//
+//    /**
+//     * 灏嗘暟缁勮浆鎹负鐢ㄦ寚瀹氬垎闅旂杩炴帴鐨勫瓧绗︿覆
+//     *
+//     * @param ary
+//     * @param delimiter
+//     * @return
+//     */
+//    public static String arrayToDelimitedString(Object[] ary, String delimiter) {
+//        if (ObjectUtils.isEmpty(ary)) {
+//            return "";
+//        }
+//        if (ary.length == 1) {
+//            return ObjectUtils.nullSafeToString(ary[0]);
+//        }
+//
+//        StringBuilder sb = new StringBuilder();
+//        for (int i = 0; i < ary.length; i++) {
+//            if (i > 0) {
+//                sb.append(delimiter);
+//            }
+//            sb.append(ary[i]);
+//        }
+//        return sb.toString();
+//    }
+
+    /**
+     * 鏍规嵁瀛楁绫诲瀷杩斿洖瀛楁浣滀负where鏉′欢鏌ヨ鍒ゆ柇瀛楁鏃朵娇鐢ㄧ殑鍒嗛殧绗�
+     *
+     * @param type
+     * @return
+     */
+    public static String getSeparator(String type) {
+        if ("string".equalsIgnoreCase(type)) {
+            return "'";
+        } else {
+            return "";
+        }
+    }
+
+    /**
+     * 杩斿洖闅愯棌淇℃伅鐨凷tring
+     *
+     * @param input
+     * @return
+     */
+    public static String getConcealStr(String input) {
+        String ss = "*";
+        String ds = "***";
+        if (StringUtils.isNotBlank(input)) {
+            if (input.length() <= 2) {
+                int i = input.length() / 2;
+                if (i == 0) {
+                    return ss;
+                } else {
+                    return input.substring(0, i) + ss;
+                }
+            } else {
+                int i = input.length() / 3;
+                return input.substring(0, i) + ds + input.substring(input.length() - i);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * 鏁版嵁鑴辨晱鏂规硶
+     *
+     * @param input
+     * @return
+     */
+    public static String concealString(String input) {
+        if (StringUtils.isEmpty(input)) {
+            return input;
+        }
+
+        return StringUtils.collectionToDelimitedString(Arrays.stream(input.split(",")).map(e -> concealStringSingle(e)).collect(Collectors.toList()));
+
+    }
+
+    /**
+     * 鍗曚釜瀛楃涓叉暟鎹劚鏁忔柟娉�
+     *
+     * @param input
+     * @return
+     */
+    public static String concealStringSingle(String input) {
+        if (input.startsWith("Untagged") || input.startsWith("Other tag")) {
+            return input;
+        }
+        if (1 == input.length()) {
+            return "*";
+        }
+
+        int i = (int) Math.ceil((double) input.length() / 3);
+
+        int j = (int) Math.floor((double) input.length() / 3);
+        StringBuffer sbf = new StringBuffer(input.substring(0, i));
+        for (int x = 0; x < input.length() - i - j; x++) {
+            sbf.append("*");
+        }
+
+        return sbf.append(input.substring(input.length() - j)).toString();
+    }
+
+
+//    public static String formatList2SqlInString(List<String> propertyList) {
+//        if (CollectionUtils.isNotEmpty(propertyList)) {
+//            return propertyList.stream().map(e -> new StringBuffer().append("'").append(e).append("'").toString()).collect(Collectors.joining(CommonSqlConst.F_COMMA));
+//        }
+//        return null;
+//    }
+
+//    public static String formatSqlFieldNotBlank(String fieldName) {
+//        if (StringUtils.isNotBlank(fieldName)) {
+//            return new StringBuffer().append(fieldName).append(" is not null ").append(CommonSqlConst.SQL_AND).append(fieldName).append(" !='' ").toString();
+//        }
+//        return null;
+//    }
+
+    public static String formatSqlCondition(String sql) {
+        sql = sql.replace("&&", "and").replace("||", "or").replace("`", "");
+
+        return sql;
+    }
+
+    public static String formatByMap(String content, Map<String, String> varValueMap) {
+        for(Map.Entry<String,String> entry:varValueMap.entrySet()){
+            content=content.replace("{"+entry.getKey()+"}",entry.getValue());
+        }
+        return content;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/common/core/utils/TemplateUtils.groovy b/src/main/java/com/common/core/utils/TemplateUtils.groovy
new file mode 100644
index 0000000..e081405
--- /dev/null
+++ b/src/main/java/com/common/core/utils/TemplateUtils.groovy
@@ -0,0 +1,48 @@
+package com.common.core.utils
+
+import com.jfinal.plugin.activerecord.Db
+import com.jfinal.plugin.activerecord.Record
+
+import java.util.stream.Collectors
+
+/**
+ *
+ * @author 寤栨尟閽�
+ * @date 2021-02-09
+ * @company deloitte
+ * */
+class TemplateUtils {
+    def static generateTemp(def text, def params){
+        def template = new groovy.text.StreamingTemplateEngine().createTemplate(text)
+        return template.make(params).toString()
+    }
+
+    def static ExecuteSqlToList(def sql, def params){
+        List<Record> recordList= Db.find(TemplateUtils.generateTemp(sql, params))
+        def list = recordList.stream().map({ record -> record.getColumns() }).collect(Collectors.toList())
+        return list
+    }
+
+    def static ExecuteSqlToMapEntity(def sql, def params){
+        Record record= Db.findFirst(TemplateUtils.generateTemp(sql, params))
+        if(null == record){
+            return null
+        }else {
+            def map = record.getColumns();
+            return map
+        }
+    }
+
+    def static ExecuteSqlToEntity(def sql, def params){
+        Record record= Db.findFirst(TemplateUtils.generateTemp(sql, params))
+        if(null == record){
+            return null
+        }else {
+            def map = record.getColumns().values();
+            if (map.size() == 1) {
+                return map[0]
+            }
+            return map
+        }
+    }
+}
diff --git a/src/main/java/com/common/core/utils/ThreadUtils.java b/src/main/java/com/common/core/utils/ThreadUtils.java
new file mode 100644
index 0000000..2e7ea26
--- /dev/null
+++ b/src/main/java/com/common/core/utils/ThreadUtils.java
@@ -0,0 +1,18 @@
+package com.common.core.utils;
+
+import lombok.SneakyThrows;
+
+import java.lang.reflect.Method;
+import java.util.concurrent.ThreadPoolExecutor;
+
+
+/**
+ * @author 寤栨尟閽�
+ * @date 2022-01-14
+ */
+public class ThreadUtils {
+
+    public static ThreadPoolExecutor executor(){
+        return SpringContextUtils.getBean(ThreadPoolExecutor.class);
+    }
+}
diff --git a/src/main/java/com/common/core/utils/UUID.java b/src/main/java/com/common/core/utils/UUID.java
new file mode 100644
index 0000000..35b21e3
--- /dev/null
+++ b/src/main/java/com/common/core/utils/UUID.java
@@ -0,0 +1,484 @@
+package com.common.core.utils;
+
+import com.common.core.exception.BizException;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.util.Random;
+import java.util.concurrent.ThreadLocalRandom;
+
+/**
+ * 鎻愪緵閫氱敤鍞竴璇嗗埆鐮侊紙universally unique identifier锛夛紙UUID锛夊疄鐜�
+ *
+ */
+public final class UUID implements java.io.Serializable, Comparable<UUID>
+{
+    private static final long serialVersionUID = -1185015143654744140L;
+
+    /**
+     * SecureRandom 鐨勫崟渚�
+     *
+     */
+    private static class Holder
+    {
+        static final SecureRandom numberGenerator = getSecureRandom();
+    }
+
+    /** 姝UID鐨勬渶楂�64鏈夋晥浣� */
+    private final long mostSigBits;
+
+    /** 姝UID鐨勬渶浣�64鏈夋晥浣� */
+    private final long leastSigBits;
+
+    /**
+     * 绉佹湁鏋勯��
+     * 
+     * @param data 鏁版嵁
+     */
+    private UUID(byte[] data)
+    {
+        long msb = 0;
+        long lsb = 0;
+        assert data.length == 16 : "data must be 16 bytes in length";
+        for (int i = 0; i < 8; i++)
+        {
+            msb = (msb << 8) | (data[i] & 0xff);
+        }
+        for (int i = 8; i < 16; i++)
+        {
+            lsb = (lsb << 8) | (data[i] & 0xff);
+        }
+        this.mostSigBits = msb;
+        this.leastSigBits = lsb;
+    }
+
+    /**
+     * 浣跨敤鎸囧畾鐨勬暟鎹瀯閫犳柊鐨� UUID銆�
+     *
+     * @param mostSigBits 鐢ㄤ簬 {@code UUID} 鐨勬渶楂樻湁鏁� 64 浣�
+     * @param leastSigBits 鐢ㄤ簬 {@code UUID} 鐨勬渶浣庢湁鏁� 64 浣�
+     */
+    public UUID(long mostSigBits, long leastSigBits)
+    {
+        this.mostSigBits = mostSigBits;
+        this.leastSigBits = leastSigBits;
+    }
+
+    /**
+     * 鑾峰彇绫诲瀷 4锛堜吉闅忔満鐢熸垚鐨勶級UUID 鐨勯潤鎬佸伐鍘傘�� 浣跨敤鍔犲瘑鐨勬湰鍦扮嚎绋嬩吉闅忔満鏁扮敓鎴愬櫒鐢熸垚璇� UUID銆�
+     * 
+     * @return 闅忔満鐢熸垚鐨� {@code UUID}
+     */
+    public static UUID fastUUID()
+    {
+        return randomUUID(false);
+    }
+
+    /**
+     * 鑾峰彇绫诲瀷 4锛堜吉闅忔満鐢熸垚鐨勶級UUID 鐨勯潤鎬佸伐鍘傘�� 浣跨敤鍔犲瘑鐨勫己浼殢鏈烘暟鐢熸垚鍣ㄧ敓鎴愯 UUID銆�
+     * 
+     * @return 闅忔満鐢熸垚鐨� {@code UUID}
+     */
+    public static UUID randomUUID()
+    {
+        return randomUUID(true);
+    }
+
+    /**
+     * 鑾峰彇绫诲瀷 4锛堜吉闅忔満鐢熸垚鐨勶級UUID 鐨勯潤鎬佸伐鍘傘�� 浣跨敤鍔犲瘑鐨勫己浼殢鏈烘暟鐢熸垚鍣ㄧ敓鎴愯 UUID銆�
+     * 
+     * @param isSecure 鏄惁浣跨敤{@link SecureRandom}濡傛灉鏄彲浠ヨ幏寰楁洿瀹夊叏鐨勯殢鏈虹爜锛屽惁鍒欏彲浠ュ緱鍒版洿濂界殑鎬ц兘
+     * @return 闅忔満鐢熸垚鐨� {@code UUID}
+     */
+    public static UUID randomUUID(boolean isSecure)
+    {
+        final Random ng = isSecure ? Holder.numberGenerator : getRandom();
+
+        byte[] randomBytes = new byte[16];
+        ng.nextBytes(randomBytes);
+        randomBytes[6] &= 0x0f; /* clear version */
+        randomBytes[6] |= 0x40; /* set to version 4 */
+        randomBytes[8] &= 0x3f; /* clear variant */
+        randomBytes[8] |= 0x80; /* set to IETF variant */
+        return new UUID(randomBytes);
+    }
+
+    /**
+     * 鏍规嵁鎸囧畾鐨勫瓧鑺傛暟缁勮幏鍙栫被鍨� 3锛堝熀浜庡悕绉扮殑锛塙UID 鐨勯潤鎬佸伐鍘傘��
+     *
+     * @param name 鐢ㄤ簬鏋勯�� UUID 鐨勫瓧鑺傛暟缁勩��
+     *
+     * @return 鏍规嵁鎸囧畾鏁扮粍鐢熸垚鐨� {@code UUID}
+     */
+    public static UUID nameUUIDFromBytes(byte[] name)
+    {
+        MessageDigest md;
+        try
+        {
+            md = MessageDigest.getInstance("MD5");
+        }
+        catch (NoSuchAlgorithmException nsae)
+        {
+            throw new InternalError("MD5 not supported");
+        }
+        byte[] md5Bytes = md.digest(name);
+        md5Bytes[6] &= 0x0f; /* clear version */
+        md5Bytes[6] |= 0x30; /* set to version 3 */
+        md5Bytes[8] &= 0x3f; /* clear variant */
+        md5Bytes[8] |= 0x80; /* set to IETF variant */
+        return new UUID(md5Bytes);
+    }
+
+    /**
+     * 鏍规嵁 {@link #toString()} 鏂规硶涓弿杩扮殑瀛楃涓叉爣鍑嗚〃绀哄舰寮忓垱寤簕@code UUID}銆�
+     *
+     * @param name 鎸囧畾 {@code UUID} 瀛楃涓�
+     * @return 鍏锋湁鎸囧畾鍊肩殑 {@code UUID}
+     * @throws IllegalArgumentException 濡傛灉 name 涓� {@link #toString} 涓弿杩扮殑瀛楃涓茶〃绀哄舰寮忎笉绗︽姏鍑烘寮傚父
+     *
+     */
+    public static UUID fromString(String name)
+    {
+        String[] components = name.split("-");
+        if (components.length != 5)
+        {
+            throw new IllegalArgumentException("Invalid UUID string: " + name);
+        }
+        for (int i = 0; i < 5; i++)
+        {
+            components[i] = "0x" + components[i];
+        }
+
+        long mostSigBits = Long.decode(components[0]).longValue();
+        mostSigBits <<= 16;
+        mostSigBits |= Long.decode(components[1]).longValue();
+        mostSigBits <<= 16;
+        mostSigBits |= Long.decode(components[2]).longValue();
+
+        long leastSigBits = Long.decode(components[3]).longValue();
+        leastSigBits <<= 48;
+        leastSigBits |= Long.decode(components[4]).longValue();
+
+        return new UUID(mostSigBits, leastSigBits);
+    }
+
+    /**
+     * 杩斿洖姝� UUID 鐨� 128 浣嶅�间腑鐨勬渶浣庢湁鏁� 64 浣嶃��
+     *
+     * @return 姝� UUID 鐨� 128 浣嶅�间腑鐨勬渶浣庢湁鏁� 64 浣嶃��
+     */
+    public long getLeastSignificantBits()
+    {
+        return leastSigBits;
+    }
+
+    /**
+     * 杩斿洖姝� UUID 鐨� 128 浣嶅�间腑鐨勬渶楂樻湁鏁� 64 浣嶃��
+     *
+     * @return 姝� UUID 鐨� 128 浣嶅�间腑鏈�楂樻湁鏁� 64 浣嶃��
+     */
+    public long getMostSignificantBits()
+    {
+        return mostSigBits;
+    }
+
+    /**
+     * 涓庢 {@code UUID} 鐩稿叧鑱旂殑鐗堟湰鍙�. 鐗堟湰鍙锋弿杩版 {@code UUID} 鏄浣曠敓鎴愮殑銆�
+     * <p>
+     * 鐗堟湰鍙峰叿鏈変互涓嬪惈鎰�:
+     * <ul>
+     * <li>1 鍩轰簬鏃堕棿鐨� UUID
+     * <li>2 DCE 瀹夊叏 UUID
+     * <li>3 鍩轰簬鍚嶇О鐨� UUID
+     * <li>4 闅忔満鐢熸垚鐨� UUID
+     * </ul>
+     *
+     * @return 姝� {@code UUID} 鐨勭増鏈彿
+     */
+    public int version()
+    {
+        // Version is bits masked by 0x000000000000F000 in MS long
+        return (int) ((mostSigBits >> 12) & 0x0f);
+    }
+
+    /**
+     * 涓庢 {@code UUID} 鐩稿叧鑱旂殑鍙樹綋鍙枫�傚彉浣撳彿鎻忚堪 {@code UUID} 鐨勫竷灞�銆�
+     * <p>
+     * 鍙樹綋鍙峰叿鏈変互涓嬪惈鎰忥細
+     * <ul>
+     * <li>0 涓� NCS 鍚戝悗鍏煎淇濈暀
+     * <li>2 <a href="http://www.ietf.org/rfc/rfc4122.txt">IETF&nbsp;RFC&nbsp;4122</a>(Leach-Salz), 鐢ㄤ簬姝ょ被
+     * <li>6 淇濈暀锛屽井杞悜鍚庡吋瀹�
+     * <li>7 淇濈暀渚涗互鍚庡畾涔変娇鐢�
+     * </ul>
+     *
+     * @return 姝� {@code UUID} 鐩稿叧鑱旂殑鍙樹綋鍙�
+     */
+    public int variant()
+    {
+        // This field is composed of a varying number of bits.
+        // 0 - - Reserved for NCS backward compatibility
+        // 1 0 - The IETF aka Leach-Salz variant (used by this class)
+        // 1 1 0 Reserved, Microsoft backward compatibility
+        // 1 1 1 Reserved for future definition.
+        return (int) ((leastSigBits >>> (64 - (leastSigBits >>> 62))) & (leastSigBits >> 63));
+    }
+
+    /**
+     * 涓庢 UUID 鐩稿叧鑱旂殑鏃堕棿鎴冲�笺��
+     *
+     * <p>
+     * 60 浣嶇殑鏃堕棿鎴冲�兼牴鎹 {@code UUID} 鐨� time_low銆乼ime_mid 鍜� time_hi 瀛楁鏋勯�犮��<br>
+     * 鎵�寰楀埌鐨勬椂闂存埑浠� 100 姣井绉掍负鍗曚綅锛屼粠 UTC锛堥�氱敤鍗忚皟鏃堕棿锛� 1582 骞� 10 鏈� 15 鏃ラ浂鏃跺紑濮嬨��
+     *
+     * <p>
+     * 鏃堕棿鎴冲�间粎鍦ㄥ湪鍩轰簬鏃堕棿鐨� UUID锛堝叾 version 绫诲瀷涓� 1锛変腑鎵嶆湁鎰忎箟銆�<br>
+     * 濡傛灉姝� {@code UUID} 涓嶆槸鍩轰簬鏃堕棿鐨� UUID锛屽垯姝ゆ柟娉曟姏鍑� UnsupportedOperationException銆�
+     *
+     * @throws UnsupportedOperationException 濡傛灉姝� {@code UUID} 涓嶆槸 version 涓� 1 鐨� UUID銆�
+     */
+    public long timestamp() throws UnsupportedOperationException
+    {
+        checkTimeBase();
+        return (mostSigBits & 0x0FFFL) << 48//
+                | ((mostSigBits >> 16) & 0x0FFFFL) << 32//
+                | mostSigBits >>> 32;
+    }
+
+    /**
+     * 涓庢 UUID 鐩稿叧鑱旂殑鏃堕挓搴忓垪鍊笺��
+     *
+     * <p>
+     * 14 浣嶇殑鏃堕挓搴忓垪鍊兼牴鎹 UUID 鐨� clock_seq 瀛楁鏋勯�犮�俢lock_seq 瀛楁鐢ㄤ簬淇濊瘉鍦ㄥ熀浜庢椂闂寸殑 UUID 涓殑鏃堕棿鍞竴鎬с��
+     * <p>
+     * {@code clockSequence} 鍊间粎鍦ㄥ熀浜庢椂闂寸殑 UUID锛堝叾 version 绫诲瀷涓� 1锛変腑鎵嶆湁鎰忎箟銆� 濡傛灉姝� UUID 涓嶆槸鍩轰簬鏃堕棿鐨� UUID锛屽垯姝ゆ柟娉曟姏鍑�
+     * UnsupportedOperationException銆�
+     *
+     * @return 姝� {@code UUID} 鐨勬椂閽熷簭鍒�
+     *
+     * @throws UnsupportedOperationException 濡傛灉姝� UUID 鐨� version 涓嶄负 1
+     */
+    public int clockSequence() throws UnsupportedOperationException
+    {
+        checkTimeBase();
+        return (int) ((leastSigBits & 0x3FFF000000000000L) >>> 48);
+    }
+
+    /**
+     * 涓庢 UUID 鐩稿叧鐨勮妭鐐瑰�笺��
+     *
+     * <p>
+     * 48 浣嶇殑鑺傜偣鍊兼牴鎹 UUID 鐨� node 瀛楁鏋勯�犮�傛瀛楁鏃ㄥ湪鐢ㄤ簬淇濆瓨鏈哄櫒鐨� IEEE 802 鍦板潃锛岃鍦板潃鐢ㄤ簬鐢熸垚姝� UUID 浠ヤ繚璇佺┖闂村敮涓�鎬с��
+     * <p>
+     * 鑺傜偣鍊间粎鍦ㄥ熀浜庢椂闂寸殑 UUID锛堝叾 version 绫诲瀷涓� 1锛変腑鎵嶆湁鎰忎箟銆�<br>
+     * 濡傛灉姝� UUID 涓嶆槸鍩轰簬鏃堕棿鐨� UUID锛屽垯姝ゆ柟娉曟姏鍑� UnsupportedOperationException銆�
+     *
+     * @return 姝� {@code UUID} 鐨勮妭鐐瑰��
+     *
+     * @throws UnsupportedOperationException 濡傛灉姝� UUID 鐨� version 涓嶄负 1
+     */
+    public long node() throws UnsupportedOperationException
+    {
+        checkTimeBase();
+        return leastSigBits & 0x0000FFFFFFFFFFFFL;
+    }
+
+    /**
+     * 杩斿洖姝@code UUID} 鐨勫瓧绗︿覆琛ㄧ幇褰㈠紡銆�
+     *
+     * <p>
+     * UUID 鐨勫瓧绗︿覆琛ㄧず褰㈠紡鐢辨 BNF 鎻忚堪锛�
+     * 
+     * <pre>
+     * {@code
+     * UUID                   = <time_low>-<time_mid>-<time_high_and_version>-<variant_and_sequence>-<node>
+     * time_low               = 4*<hexOctet>
+     * time_mid               = 2*<hexOctet>
+     * time_high_and_version  = 2*<hexOctet>
+     * variant_and_sequence   = 2*<hexOctet>
+     * node                   = 6*<hexOctet>
+     * hexOctet               = <hexDigit><hexDigit>
+     * hexDigit               = [0-9a-fA-F]
+     * }
+     * </pre>
+     * 
+     * </blockquote>
+     *
+     * @return 姝@code UUID} 鐨勫瓧绗︿覆琛ㄧ幇褰㈠紡
+     * @see #toString(boolean)
+     */
+    @Override
+    public String toString()
+    {
+        return toString(false);
+    }
+
+    /**
+     * 杩斿洖姝@code UUID} 鐨勫瓧绗︿覆琛ㄧ幇褰㈠紡銆�
+     *
+     * <p>
+     * UUID 鐨勫瓧绗︿覆琛ㄧず褰㈠紡鐢辨 BNF 鎻忚堪锛�
+     * 
+     * <pre>
+     * {@code
+     * UUID                   = <time_low>-<time_mid>-<time_high_and_version>-<variant_and_sequence>-<node>
+     * time_low               = 4*<hexOctet>
+     * time_mid               = 2*<hexOctet>
+     * time_high_and_version  = 2*<hexOctet>
+     * variant_and_sequence   = 2*<hexOctet>
+     * node                   = 6*<hexOctet>
+     * hexOctet               = <hexDigit><hexDigit>
+     * hexDigit               = [0-9a-fA-F]
+     * }
+     * </pre>
+     * 
+     * </blockquote>
+     *
+     * @param isSimple 鏄惁绠�鍗曟ā寮忥紝绠�鍗曟ā寮忎负涓嶅甫'-'鐨刄UID瀛楃涓�
+     * @return 姝@code UUID} 鐨勫瓧绗︿覆琛ㄧ幇褰㈠紡
+     */
+    public String toString(boolean isSimple)
+    {
+        final StringBuilder builder = new StringBuilder(isSimple ? 32 : 36);
+        // time_low
+        builder.append(digits(mostSigBits >> 32, 8));
+        if (false == isSimple)
+        {
+            builder.append('-');
+        }
+        // time_mid
+        builder.append(digits(mostSigBits >> 16, 4));
+        if (false == isSimple)
+        {
+            builder.append('-');
+        }
+        // time_high_and_version
+        builder.append(digits(mostSigBits, 4));
+        if (false == isSimple)
+        {
+            builder.append('-');
+        }
+        // variant_and_sequence
+        builder.append(digits(leastSigBits >> 48, 4));
+        if (false == isSimple)
+        {
+            builder.append('-');
+        }
+        // node
+        builder.append(digits(leastSigBits, 12));
+
+        return builder.toString();
+    }
+
+    /**
+     * 杩斿洖姝� UUID 鐨勫搱甯岀爜銆�
+     *
+     * @return UUID 鐨勫搱甯岀爜鍊笺��
+     */
+    @Override
+    public int hashCode()
+    {
+        long hilo = mostSigBits ^ leastSigBits;
+        return ((int) (hilo >> 32)) ^ (int) hilo;
+    }
+
+    /**
+     * 灏嗘瀵硅薄涓庢寚瀹氬璞℃瘮杈冦��
+     * <p>
+     * 褰撲笖浠呭綋鍙傛暟涓嶄负 {@code null}銆佽�屾槸涓�涓� UUID 瀵硅薄銆佸叿鏈変笌姝� UUID 鐩稿悓鐨� varriant銆佸寘鍚浉鍚岀殑鍊硷紙姣忎竴浣嶅潎鐩稿悓锛夋椂锛岀粨鏋滄墠涓� {@code true}銆�
+     *
+     * @param obj 瑕佷笌涔嬫瘮杈冪殑瀵硅薄
+     *
+     * @return 濡傛灉瀵硅薄鐩稿悓锛屽垯杩斿洖 {@code true}锛涘惁鍒欒繑鍥� {@code false}
+     */
+    @Override
+    public boolean equals(Object obj)
+    {
+        if ((null == obj) || (obj.getClass() != UUID.class))
+        {
+            return false;
+        }
+        UUID id = (UUID) obj;
+        return (mostSigBits == id.mostSigBits && leastSigBits == id.leastSigBits);
+    }
+
+    // Comparison Operations
+
+    /**
+     * 灏嗘 UUID 涓庢寚瀹氱殑 UUID 姣旇緝銆�
+     *
+     * <p>
+     * 濡傛灉涓や釜 UUID 涓嶅悓锛屼笖绗竴涓� UUID 鐨勬渶楂樻湁鏁堝瓧娈靛ぇ浜庣浜屼釜 UUID 鐨勫搴斿瓧娈碉紝鍒欑涓�涓� UUID 澶т簬绗簩涓� UUID銆�
+     *
+     * @param val 涓庢 UUID 姣旇緝鐨� UUID
+     *
+     * @return 鍦ㄦ UUID 灏忎簬銆佺瓑浜庢垨澶т簬 val 鏃讹紝鍒嗗埆杩斿洖 -1銆�0 鎴� 1銆�
+     *
+     */
+    @Override
+    public int compareTo(UUID val)
+    {
+        // The ordering is intentionally set up so that the UUIDs
+        // can simply be numerically compared as two numbers
+        return (this.mostSigBits < val.mostSigBits ? -1 : //
+                (this.mostSigBits > val.mostSigBits ? 1 : //
+                        (this.leastSigBits < val.leastSigBits ? -1 : //
+                                (this.leastSigBits > val.leastSigBits ? 1 : //
+                                        0))));
+    }
+
+    // -------------------------------------------------------------------------------------------------------------------
+    // Private method start
+    /**
+     * 杩斿洖鎸囧畾鏁板瓧瀵瑰簲鐨刪ex鍊�
+     * 
+     * @param val 鍊�
+     * @param digits 浣�
+     * @return 鍊�
+     */
+    private static String digits(long val, int digits)
+    {
+        long hi = 1L << (digits * 4);
+        return Long.toHexString(hi | (val & (hi - 1))).substring(1);
+    }
+
+    /**
+     * 妫�鏌ユ槸鍚︿负time-based鐗堟湰UUID
+     */
+    private void checkTimeBase()
+    {
+        if (version() != 1)
+        {
+            throw new UnsupportedOperationException("Not a time-based UUID");
+        }
+    }
+
+    /**
+     * 鑾峰彇{@link SecureRandom}锛岀被鎻愪緵鍔犲瘑鐨勫己闅忔満鏁扮敓鎴愬櫒 (RNG)
+     * 
+     * @return {@link SecureRandom}
+     */
+    public static SecureRandom getSecureRandom()
+    {
+        try
+        {
+            return SecureRandom.getInstance("SHA1PRNG");
+        }
+        catch (NoSuchAlgorithmException e)
+        {
+            throw new BizException(e.getMessage());
+        }
+    }
+
+    /**
+     * 鑾峰彇闅忔満鏁扮敓鎴愬櫒瀵硅薄<br>
+     * ThreadLocalRandom鏄疛DK 7涔嬪悗鎻愪緵骞跺彂浜х敓闅忔満鏁帮紝鑳藉瑙e喅澶氫釜绾跨▼鍙戠敓鐨勭珵浜変簤澶恒��
+     * 
+     * @return {@link ThreadLocalRandom}
+     */
+    public static ThreadLocalRandom getRandom()
+    {
+        return ThreadLocalRandom.current();
+    }
+}
diff --git a/src/main/java/com/common/filter/CorsFilter.java b/src/main/java/com/common/filter/CorsFilter.java
new file mode 100644
index 0000000..1e792c2
--- /dev/null
+++ b/src/main/java/com/common/filter/CorsFilter.java
@@ -0,0 +1,21 @@
+package com.common.filter;
+
+import org.springframework.web.filter.OncePerRequestFilter;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+public class CorsFilter extends OncePerRequestFilter {
+
+    @Override
+    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
+        response.addHeader("Access-Control-Allow-Origin", "*");
+        response.addHeader("Access-Control-Allow-Methods", "*");
+        response.addHeader("Access-Control-Allow-Headers", "content-type,pi-token");
+        response.addHeader("Access-Control-Max-Age", "1800");//30 min
+        filterChain.doFilter(request, response);
+    }
+}
diff --git a/src/main/java/com/common/filter/JwtAuthenticationTokenFilter.java b/src/main/java/com/common/filter/JwtAuthenticationTokenFilter.java
new file mode 100644
index 0000000..f726ee2
--- /dev/null
+++ b/src/main/java/com/common/filter/JwtAuthenticationTokenFilter.java
@@ -0,0 +1,94 @@
+package com.common.filter;
+
+import com.common.annotation.NoToken;
+import com.common.core.utils.JwtTokenUtil;
+import com.common.core.utils.SpringContextUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpMethod;
+import org.springframework.security.authentication.AuthenticationServiceException;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
+import org.springframework.web.filter.OncePerRequestFilter;
+import org.springframework.web.method.HandlerMethod;
+import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition;
+import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
+import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.*;
+import java.util.stream.Collectors;
+
+
+/**
+ * @author 寤栨尟閽�
+ * @date 2022-01-17
+ */
+@Slf4j
+public class JwtAuthenticationTokenFilter extends OncePerRequestFilter
+{
+    @Autowired
+    private JwtTokenUtil jwtTokenUtil;
+
+    @Autowired
+    private UserDetailsService userDetailsService;
+    @Override
+    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
+        Map<RequestMappingInfo, HandlerMethod> handlerMethods = ((RequestMappingHandlerMapping)SpringContextUtils.getBean("requestMappingHandlerMapping")).getHandlerMethods();
+        Set<String> anonymousUrls = new HashSet<>();
+        for (Map.Entry<RequestMappingInfo, HandlerMethod> infoEntry : handlerMethods.entrySet()) {
+            // 鑾峰彇鎵�鏈夋帴鍙g殑鏂规硶
+            HandlerMethod handlerMethod = infoEntry.getValue();
+            if ( handlerMethod.hasMethodAnnotation(NoToken.class)) {
+                final PatternsRequestCondition requestCondition = infoEntry.getKey().getPatternsCondition();
+                Optional.ofNullable(requestCondition).orElseThrow(RuntimeException::new);
+                anonymousUrls.addAll(requestCondition.getPatterns().stream().map(m -> SpringContextUtils.getEnvParam("server.servlet.context-path")+m).collect(Collectors.toList()));
+            }
+        }
+
+        String uri = request.getRequestURI();
+        boolean visit = true;
+        for(String item : Arrays.asList(new String[]{
+                ".html",
+                ".css",
+                ".js",
+                ".png",
+                ".ttf",
+                ".ico",
+                ".woff",
+                "/swagger-resources",
+                "/v2/api-docs",
+                "/druid"
+        })){
+            if(uri.contains(item)){
+                visit = false;
+            }
+        }
+        if(!anonymousUrls.contains(uri) && !HttpMethod.OPTIONS.matches(request.getMethod()) && visit) {
+            String token = request.getHeader("pi-token");
+            log.info("TOKEN:"+token);
+            if(StringUtils.isEmpty(token)){
+                throw new AuthenticationServiceException("TOKEN涓虹┖");
+            }
+            String appid = jwtTokenUtil.getAppidFromToken(token);
+            if (appid != null && SecurityContextHolder.getContext().getAuthentication() == null) {
+                UserDetails userDetails = this.userDetailsService.loadUserByUsername(appid);
+                if (jwtTokenUtil.validateToken(token, userDetails)) {
+                    UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
+                    authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
+                    SecurityContextHolder.getContext().setAuthentication(authentication);
+                }else{
+                    throw new AuthenticationServiceException("TOKEN鏃犳晥");
+                }
+            }
+        }
+        chain.doFilter(request,response);
+    }
+}
diff --git a/src/main/java/com/common/filter/RequestCachingFilter.java b/src/main/java/com/common/filter/RequestCachingFilter.java
new file mode 100644
index 0000000..27b4e94
--- /dev/null
+++ b/src/main/java/com/common/filter/RequestCachingFilter.java
@@ -0,0 +1,78 @@
+package com.common.filter;
+
+import com.alibaba.fastjson.JSONObject;
+import com.common.sign.BufferedHttpServletRequest;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.web.filter.OncePerRequestFilter;
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.Collections;
+
+
+/**
+ * @author 寤栨尟閽�
+ * @date 2022-01-14
+ */
+public class RequestCachingFilter extends OncePerRequestFilter {
+    private static Logger LOGGER = LoggerFactory.getLogger(RequestCachingFilter.class);
+
+    @Override
+    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
+        boolean isFirstRequest = !isAsyncDispatch(request);
+        HttpServletRequest requestToUse = request;
+        if (isFirstRequest && !(request instanceof BufferedHttpServletRequest)) {
+            requestToUse = new BufferedHttpServletRequest(request, 1024);
+        }
+        try {
+            filterChain.doFilter(requestToUse, response);
+        } catch (Exception e) {
+            LOGGER.error("RequestCachingFilter>>>>>>>>>", e);
+        } finally {
+//            this.printRequest(requestToUse); TODO
+            if (requestToUse instanceof BufferedHttpServletRequest) {
+                ((BufferedHttpServletRequest) requestToUse).release();
+            }
+        }
+    }
+
+    private void printRequest(HttpServletRequest request) {
+        String body = StringUtils.EMPTY;
+        try {
+            if (request instanceof BufferedHttpServletRequest) {
+                body = IOUtils.toString(request.getInputStream(), StandardCharsets.UTF_8);
+            }
+        } catch (IOException e) {
+            LOGGER.error("printRequest 鑾峰彇body寮傚父...", e);
+        }
+
+        JSONObject requestJ = new JSONObject();
+        JSONObject headers = new JSONObject();
+        Collections.list(request.getHeaderNames())
+                .stream()
+                .forEach(name -> headers.put(name, request.getHeader(name)));
+        requestJ.put("headers", headers);
+        requestJ.put("parameters", request.getParameterMap());
+        requestJ.put("body", body);
+        requestJ.put("remote-user", request.getRemoteUser());
+        requestJ.put("remote-addr", request.getRemoteAddr());
+        requestJ.put("remote-host", request.getRemoteHost());
+        requestJ.put("remote-port", request.getRemotePort());
+        requestJ.put("uri", request.getRequestURI());
+        requestJ.put("url", request.getRequestURL());
+        requestJ.put("servlet-path", request.getServletPath());
+        requestJ.put("method", request.getMethod());
+        requestJ.put("query", request.getQueryString());
+        requestJ.put("path-info", request.getPathInfo());
+        requestJ.put("context-path", request.getContextPath());
+
+//        LOGGER.info("Request-Info: " + JSON.toJSONString(requestJ, SerializerFeature.PrettyFormat));
+    }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/common/redis/config/CommonRedisConfig.java b/src/main/java/com/common/redis/config/CommonRedisConfig.java
new file mode 100644
index 0000000..dcaa249
--- /dev/null
+++ b/src/main/java/com/common/redis/config/CommonRedisConfig.java
@@ -0,0 +1,62 @@
+package com.common.redis.config;
+
+import com.common.redis.util.RedisUtil;
+import com.common.redis.serializer.KryoRedisSerializer;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.RedisSerializer;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+
+/**
+ * @author xiaobzhou
+ * date 2019-07-10 19:00
+ * {@link RedisAutoConfiguration}
+ */
+@Configuration
+@ConditionalOnProperty(value = "spring.redis.host")
+public class CommonRedisConfig {
+
+    /**
+     * 璁剧疆redis閰嶇疆椤�
+     *
+     * @param connectionFactory
+     * @return
+     */
+    @Bean
+    @ConditionalOnMissingBean(name = "template")
+    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
+
+        RedisTemplate<String, Object> template = new RedisTemplate<>();
+
+        RedisSerializer valueSerializer = new KryoRedisSerializer(Object.class);
+
+
+        template.setConnectionFactory(connectionFactory);
+        template.setKeySerializer(new StringRedisSerializer());
+        template.setHashKeySerializer(new StringRedisSerializer());
+        template.setHashValueSerializer(valueSerializer);
+        template.setValueSerializer(valueSerializer);
+        template.afterPropertiesSet();
+
+        return template;
+    }
+
+    /**
+     * 鑾峰彇redis 宸ュ叿绫�
+     *
+     * @param template
+     * @return
+     */
+    @Bean
+    @ConditionalOnMissingBean
+    public RedisUtil redisUtil(RedisTemplate<String, Object> template) {
+        return new RedisUtil(template);
+    }
+
+
+}
diff --git a/src/main/java/com/common/redis/serializer/KryoRedisSerializer.java b/src/main/java/com/common/redis/serializer/KryoRedisSerializer.java
new file mode 100644
index 0000000..97f66b0
--- /dev/null
+++ b/src/main/java/com/common/redis/serializer/KryoRedisSerializer.java
@@ -0,0 +1,94 @@
+package com.common.redis.serializer;
+
+import com.esotericsoftware.kryo.Kryo;
+import com.esotericsoftware.kryo.io.Input;
+import com.esotericsoftware.kryo.io.Output;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.data.redis.serializer.RedisSerializer;
+import org.springframework.data.redis.serializer.SerializationException;
+
+import java.io.ByteArrayOutputStream;
+
+/**
+ * @author xiaobzhou
+ * date 2019-07-10 19:00
+ */
+public class KryoRedisSerializer<T> implements RedisSerializer<T> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(KryoRedisSerializer.class);
+
+    public static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
+
+    /**
+     * 鍒濆鍖朘RYO瀵硅薄
+     */
+    private static final ThreadLocal<Kryo> KRYO = ThreadLocal.withInitial(Kryo::new);
+
+    private Class<T> classType;
+
+    public void cleanKryo() {
+        KRYO.remove();
+    }
+    public KryoRedisSerializer(Class<T> classType) {
+        super();
+        this.classType = classType;
+    }
+
+    /**
+     * Kryo搴忓垪鍖栨柟娉�
+     *
+     * @param o
+     * @return
+     * @throws SerializationException
+     */
+    @Override
+    public byte[] serialize(T o) throws SerializationException {
+
+        if (o == null) {
+            return EMPTY_BYTE_ARRAY;
+        }
+
+        Kryo kryo = KRYO.get();
+        kryo.setReferences(false);
+        kryo.register(classType);
+
+        try {
+            ByteArrayOutputStream byteOps = new ByteArrayOutputStream();
+            Output output = new Output(byteOps);
+            kryo.writeClassAndObject(output, o);
+            output.flush();
+            return byteOps.toByteArray();
+        } catch (Exception ex) {
+            LOG.error(ex.getMessage(), ex);
+        }
+
+        return EMPTY_BYTE_ARRAY;
+    }
+
+    /**
+     * Kryo鍙嶅簭鍒楀寲鏂规硶
+     *
+     * @param bytes
+     * @return
+     * @throws SerializationException
+     */
+    @Override
+    public T deserialize(byte[] bytes) throws SerializationException {
+
+        if (bytes != null) {
+            Kryo kryo = KRYO.get();
+            kryo.setReferences(false);
+            kryo.register(classType);
+
+            try {
+                Input input = new Input(bytes);
+                return (T) kryo.readClassAndObject(input);
+            } catch (Exception ex) {
+                LOG.error(ex.getMessage(), ex);
+            }
+        }
+
+        return null;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/common/redis/util/RedisLockUtil.java b/src/main/java/com/common/redis/util/RedisLockUtil.java
new file mode 100644
index 0000000..d90ad6e
--- /dev/null
+++ b/src/main/java/com/common/redis/util/RedisLockUtil.java
@@ -0,0 +1,182 @@
+package com.common.redis.util;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.dao.DataAccessException;
+import org.springframework.data.redis.connection.RedisConnection;
+import org.springframework.data.redis.core.RedisCallback;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+
+import java.util.Objects;
+
+public class RedisLockUtil {
+
+    private final static Logger log = LoggerFactory.getLogger(RedisLockUtil.class);
+
+
+    private RedisTemplate<String, Object> redisTemplate;
+
+    public RedisLockUtil(RedisTemplate<String, Object> template) {
+        this.redisTemplate = template;
+    }
+
+    private static final int DEFAULT_ACQUIRY_RESOLUTION_MILLIS = 100;
+
+
+    /**
+     * 閿佽秴鏃舵椂闂达紝闃叉绾跨▼鍦ㄥ叆閿佷互鍚庯紝鏃犻檺鐨勬墽琛岀瓑寰�
+     */
+    private int expireMsecs = 60 * 1000;
+
+    /**
+     * 閿佺瓑寰呮椂闂达紝闃叉绾跨▼楗ラタ
+     */
+    private int timeoutMsecs = 10 * 1000;
+
+    private volatile boolean locked = false;
+
+
+    private String get(final String key) {
+        Object obj = null;
+        try {
+            obj = redisTemplate.execute(new RedisCallback<Object>() {
+                @Override
+                public Object doInRedis(RedisConnection connection) throws DataAccessException {
+                    StringRedisSerializer serializer = new StringRedisSerializer();
+                    byte[] data = connection.get(serializer.serialize(key));
+                    connection.close();
+                    if (data == null) {
+                        return null;
+                    }
+                    return serializer.deserialize(data);
+                }
+            });
+        } catch (Exception e) {
+            log.error("get redis error, key : {}", key);
+        }
+        return obj != null ? obj.toString() : null;
+    }
+
+    private boolean setNX(final String key, final String value) {
+        Object obj = null;
+        try {
+            obj = redisTemplate.execute(new RedisCallback<Object>() {
+                @Override
+                public Object doInRedis(RedisConnection connection) throws DataAccessException {
+                    StringRedisSerializer serializer = new StringRedisSerializer();
+                    Boolean success = connection.setNX(serializer.serialize(key), serializer.serialize(value));
+                    connection.close();
+                    return success;
+                }
+            });
+        } catch (Exception e) {
+            log.error("setNX redis error, key : {}", key);
+        }
+        return obj != null ? (Boolean) obj : false;
+    }
+
+    private String getSet(final String key, final String value) {
+        Object obj = null;
+        try {
+            obj = redisTemplate.execute(new RedisCallback<Object>() {
+                @Override
+                public Object doInRedis(RedisConnection connection) throws DataAccessException {
+                    StringRedisSerializer serializer = new StringRedisSerializer();
+                    byte[] ret = connection.getSet(serializer.serialize(key), serializer.serialize(value));
+                    connection.close();
+                    return serializer.deserialize(ret);
+                }
+            });
+        } catch (Exception e) {
+            log.error("setNX redis error, key : {}", key);
+        }
+        return obj != null ? (String) obj : null;
+    }
+
+    /**
+     * 鑾峰緱 lock.
+     * 瀹炵幇鎬濊矾: 涓昏鏄娇鐢ㄤ簡redis 鐨剆etnx鍛戒护,缂撳瓨浜嗛攣.
+     * reids缂撳瓨鐨刱ey鏄攣鐨刱ey,鎵�鏈夌殑鍏变韩, value鏄攣鐨勫埌鏈熸椂闂�(娉ㄦ剰:杩欓噷鎶婅繃鏈熸椂闂存斁鍦╲alue浜�,娌℃湁鏃堕棿涓婅缃叾瓒呮椂鏃堕棿)
+     * 鎵ц杩囩▼:
+     * 1.閫氳繃setnx灏濊瘯璁剧疆鏌愪釜key鐨勫��,鎴愬姛(褰撳墠娌℃湁杩欎釜閿�)鍒欒繑鍥�,鎴愬姛鑾峰緱閿�
+     * 2.閿佸凡缁忓瓨鍦ㄥ垯鑾峰彇閿佺殑鍒版湡鏃堕棿,鍜屽綋鍓嶆椂闂存瘮杈�,瓒呮椂鐨勮瘽,鍒欒缃柊鐨勫��
+     *
+     * @return true if lock is acquired, false acquire timeouted
+     * @throws InterruptedException in case of thread interruption
+     */
+    public synchronized boolean lock(String lockKey) throws InterruptedException {
+        int timeout = timeoutMsecs;
+        while (timeout >= 0) {
+            long expires = System.currentTimeMillis() + expireMsecs + 1;
+            String expiresStr = String.valueOf(expires); //閿佸埌鏈熸椂闂�
+            if (this.setNX(lockKey, expiresStr)) {
+                // lock acquired
+                locked = true;
+                return true;
+            }
+
+            String currentValueStr = this.get(lockKey); //redis閲岀殑鏃堕棿
+            if (currentValueStr != null && Long.parseLong(currentValueStr) < System.currentTimeMillis()) {
+                //鍒ゆ柇鏄惁涓虹┖锛屼笉涓虹┖鐨勬儏鍐典笅锛屽鏋滆鍏朵粬绾跨▼璁剧疆浜嗗�硷紝鍒欑浜屼釜鏉′欢鍒ゆ柇鏄繃涓嶅幓鐨�
+                // lock is expired
+
+                String oldValueStr = this.getSet(lockKey, expiresStr);
+                //鑾峰彇涓婁竴涓攣鍒版湡鏃堕棿锛屽苟璁剧疆鐜板湪鐨勯攣鍒版湡鏃堕棿锛�
+                //鍙湁涓�涓嚎绋嬫墠鑳借幏鍙栦笂涓�涓嚎涓婄殑璁剧疆鏃堕棿锛屽洜涓簀edis.getSet鏄悓姝ョ殑
+                if (oldValueStr != null && oldValueStr.equals(currentValueStr)) {
+                    //闃叉璇垹锛堣鐩栵紝鍥犱负key鏄浉鍚岀殑锛変簡浠栦汉鐨勯攣鈥斺�旇繖閲岃揪涓嶅埌鏁堟灉锛岃繖閲屽�间細琚鐩栵紝浣嗘槸鍥犱负浠�涔堢浉宸簡寰堝皯鐨勬椂闂达紝鎵�浠ュ彲浠ユ帴鍙�
+
+                    //[鍒嗗竷寮忕殑鎯呭喌涓媇:濡傝繃杩欎釜鏃跺�欙紝澶氫釜绾跨▼鎭板ソ閮藉埌浜嗚繖閲岋紝浣嗘槸鍙湁涓�涓嚎绋嬬殑璁剧疆鍊煎拰褰撳墠鍊肩浉鍚岋紝浠栨墠鏈夋潈鍒╄幏鍙栭攣
+                    // lock acquired
+                    locked = true;
+                    return true;
+                }
+            }
+            timeout -= DEFAULT_ACQUIRY_RESOLUTION_MILLIS;
+
+            /*
+                寤惰繜100 姣,  杩欓噷浣跨敤闅忔満鏃堕棿鍙兘浼氬ソ涓�鐐�,鍙互闃叉楗ラタ杩涚▼鐨勫嚭鐜�,鍗�,褰撳悓鏃跺埌杈惧涓繘绋�,
+                鍙細鏈変竴涓繘绋嬭幏寰楅攣,鍏朵粬鐨勯兘鐢ㄥ悓鏍风殑棰戠巼杩涜灏濊瘯,鍚庨潰鏈夋潵浜嗕竴浜涜繘琛�,涔熶互鍚屾牱鐨勯鐜囩敵璇烽攣,杩欏皢鍙兘瀵艰嚧鍓嶉潰鏉ョ殑閿佸緱涓嶅埌婊¤冻.
+                浣跨敤闅忔満鐨勭瓑寰呮椂闂村彲浠ヤ竴瀹氱▼搴︿笂淇濊瘉鍏钩鎬�
+             */
+            Thread.sleep(DEFAULT_ACQUIRY_RESOLUTION_MILLIS);
+
+        }
+        return false;
+    }
+
+
+    /**
+     * Acqurired lock release.
+     */
+    public synchronized void unlock(String lockKey) {
+        if (locked) {
+            redisTemplate.delete(lockKey);
+            locked = false;
+        }
+    }
+
+    public boolean lock(String lockKey, long lockExpireMils) {
+        return (Boolean) redisTemplate.execute((RedisCallback) connection -> {
+            long nowTime = System.currentTimeMillis();
+            Boolean acquire = connection.set(lockKey.getBytes(), String.valueOf(nowTime + lockExpireMils + 1).getBytes());
+            if (acquire) {
+                return Boolean.TRUE;
+            } else {
+                byte[] value = connection.get(lockKey.getBytes());
+                if (Objects.nonNull(value) && value.length > 0) {
+                    long oldTime = Long.parseLong(new String(value));
+                    if (oldTime < nowTime) {
+                        //connection.getSet锛氳繑鍥炶繖涓猭ey鐨勬棫鍊煎苟璁剧疆鏂板�笺��
+                        byte[] oldValue = connection.getSet(lockKey.getBytes(), String.valueOf(nowTime + lockExpireMils + 1).getBytes());
+                        //褰搆ey涓嶅瓨鏃朵細杩斿洖绌猴紝琛ㄧずkey涓嶅瓨鍦ㄦ垨鑰呭凡鍦ㄧ閬撲腑浣跨敤
+                        return oldValue == null ? false : Long.parseLong(new String(oldValue)) < nowTime;
+                    }
+                }
+            }
+            return Boolean.FALSE;
+        });
+    }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/common/redis/util/RedisUtil.java b/src/main/java/com/common/redis/util/RedisUtil.java
new file mode 100644
index 0000000..6ab4bb8
--- /dev/null
+++ b/src/main/java/com/common/redis/util/RedisUtil.java
@@ -0,0 +1,283 @@
+package com.common.redis.util;
+
+import org.springframework.dao.DataAccessException;
+import org.springframework.data.redis.connection.RedisConnection;
+import org.springframework.data.redis.core.RedisCallback;
+import org.springframework.data.redis.core.RedisTemplate;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * redis宸ュ叿绫�
+ *
+ * @author lisheng
+ * @Date 2020/08/9 15:31
+ */
+public class RedisUtil {
+
+    private RedisTemplate<String, Object> template;
+
+    public RedisUtil(RedisTemplate<String, Object> template) {
+        this.template = template;
+    }
+
+    /**
+     * 璁剧疆杩囨湡鏃堕棿
+     *
+     * @param key
+     * @param timeout
+     * @return
+     */
+    public boolean expire(String key, long timeout) {
+        try {
+            if (timeout > 0) {
+                template.expire(key, timeout, TimeUnit.SECONDS);
+            }
+            return true;
+        } catch (Exception ex) {
+            return false;
+        }
+    }
+
+    /**
+     * 鑾峰彇杩囨湡鏃堕棿
+     *
+     * @param key
+     * @return
+     */
+    public long getExpire(String key) {
+        return template.getExpire(key, TimeUnit.SECONDS);
+    }
+
+    /**
+     * key鏄惁瀛樺湪
+     *
+     * @param key
+     * @return
+     */
+    public boolean hasKey(String key) {
+        try {
+            return template.hasKey(key);
+        } catch (Exception e) {
+            return false;
+        }
+    }
+
+    /**
+     * 鍒犻櫎key
+     *
+     * @param key
+     */
+    public void deleteKey(String... key) {
+        if (key != null && key.length > 0) {
+            if (key.length == 1) {
+                template.delete(key[0]);
+            } else {
+                template.delete(Arrays.asList(key));
+            }
+        }
+    }
+
+    /**
+     * 鏍规嵁key鑾峰彇value
+     *
+     * @param key
+     * @return
+     */
+    public Object get(String key) {
+        if (key == null) {
+            return null;
+        }
+        return template.opsForValue().get(key);
+    }
+
+    /**
+     * 鏍规嵁key鍜岀被鍨嬭幏鍙杤alue
+     *
+     * @param key
+     * @param classType
+     * @param <T>
+     * @return
+     */
+    public <T> T getObject(String key, Class<T> classType) {
+        return (T) this.get(key);
+    }
+
+    /**
+     * 鏍规嵁key鍜岀被鍨嬭幏鍙杤alue list
+     *
+     * @param key
+     * @param classType
+     * @param <T>
+     * @return
+     */
+    public <T> List<T> getObjects(String key, Class<T> classType) {
+        return (List<T>) get(key);
+    }
+
+    /**
+     * 璁剧疆缂撳瓨
+     *
+     * @param key
+     * @param value
+     * @return
+     */
+    public boolean set(String key, Object value) {
+        try {
+            template.opsForValue().set(key, value);
+            return true;
+        } catch (Exception ex) {
+            return false;
+        }
+    }
+
+    /**
+     * 璁剧疆杩囨湡鏃堕棿缂撳瓨
+     *
+     * @param key
+     * @param value
+     * @param timeout
+     * @return
+     */
+    public boolean set(String key, Object value, long timeout) {
+        try {
+            if (timeout > 0) {
+                template.opsForValue().set(key, value, timeout, TimeUnit.SECONDS);
+            } else {
+                return set(key, value);
+            }
+            return true;
+        } catch (Exception ex) {
+            return false;
+        }
+    }
+
+    /**
+     * 鑾峰彇Redis鍒楄〃
+     *
+     * @param key
+     * @return
+     */
+    public Object lGet(String key) {
+        if (key == null) {
+            return null;
+        }
+        return template.opsForList().rightPop(key);
+    }
+
+    /**
+     * 璁剧疆缂撳瓨鍒楄〃绫诲瀷
+     *
+     * @param key
+     * @param values
+     * @return
+     */
+    public boolean lSet(String key, List<?> values) {
+        try {
+            template.opsForList().rightPush(key, values);
+            return true;
+        } catch (Exception ex) {
+            return false;
+        }
+    }
+
+    /**
+     * 璁剧疆hashmap绫诲瀷缂撳瓨
+     *
+     * @param key
+     * @param field
+     * @param value
+     * @param <T>
+     * @return
+     */
+    public <T> boolean hset(String key, String field, T value) {
+        template.opsForHash().put(key, field, value);
+        return true;
+    }
+
+    public <T> boolean hset(String key, Object field, T value) {
+        template.opsForHash().put(key, field, value);
+        return true;
+    }
+
+
+    /**
+     * 鎸塰ashmap key鑾峰彇缂撳瓨涓殑鏁版嵁
+     *
+     * @param key
+     * @param fields
+     * @return
+     */
+    public List<Object> hashMultiGet(String key, Collection<Object> fields) {
+        if (key == null) {
+            return null;
+        }
+        return template.opsForHash().multiGet(key, fields);
+    }
+
+    /**
+     * 鑾峰彇鍗曚釜hashmap涓殑鍊�
+     *
+     * @param key
+     * @param field
+     * @return
+     */
+    public Object hashSingleGet(String key, Object field) {
+        if (key == null) {
+            return null;
+        }
+
+        return template.opsForHash().get(key, field);
+    }
+
+    /**
+     * 鑾峰彇鍗曚釜hashmap涓殑鍊�
+     *
+     * @param key
+     * @return
+     */
+    public Map<Object, Object> hashGetAll(String key) {
+        if (key == null) {
+            return null;
+        }
+
+        return template.opsForHash().entries(key);
+    }
+
+
+    /**
+     * delete 鎸囧畾鏌愪簺hashmap涓殑鍊�
+     *
+     * @param key
+     * @param fields
+     * @return
+     */
+    public Object hDelFields(String key, Object... fields) {
+        if (key == null) {
+            return null;
+        }
+
+        return template.opsForHash().delete(key, fields);
+    }
+
+    /**
+     * 缂撳瓨鑷
+     *
+     * @param key
+     * @param delta
+     * @return
+     */
+    public Long incr(String key, long delta) {
+        return template.opsForValue().increment(key, delta);
+    }
+
+
+    public Set<String> getKeys(String prex){
+        return template.keys(prex);
+    }
+}
diff --git a/src/main/java/com/common/security/configure/AppDetails.java b/src/main/java/com/common/security/configure/AppDetails.java
new file mode 100644
index 0000000..2ced0fb
--- /dev/null
+++ b/src/main/java/com/common/security/configure/AppDetails.java
@@ -0,0 +1,72 @@
+package com.common.security.configure;
+
+import com.deloitte.system.model.AppConfig;
+import com.deloitte.system.model.AppPermissionConfig;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+import java.util.Collection;
+import java.util.stream.Collectors;
+
+/**
+ * @author 寤栨尟閽�
+ * @date 2022-01-17
+ */
+public class AppDetails implements UserDetails {
+
+    private AppConfig appConfig;
+
+    private String userid;
+
+    public AppDetails(AppConfig appConfig){
+        this.appConfig = appConfig;
+    }
+
+    @Override
+    public Collection<? extends GrantedAuthority> getAuthorities() {
+        return AppPermissionConfig.dao.findByAppidList(appConfig.appid()).stream()
+                .filter(app -> app.url() != null)
+                .map(app -> new SimpleGrantedAuthority(app.url()))
+                .collect(Collectors.toList());
+    }
+
+    @Override
+    public String getPassword() {
+        return appConfig.appsecret();
+    }
+
+    @Override
+    public String getUsername() {
+        return appConfig.appid();
+    }
+
+    public void setUserid(String userid){
+        this.userid = userid;
+    }
+
+    public String getUserid(){
+        return userid;
+    }
+
+
+
+    @Override
+    public boolean isAccountNonExpired() {
+        return true;
+    }
+
+    @Override
+    public boolean isAccountNonLocked() {
+        return true;
+    }
+
+    @Override
+    public boolean isCredentialsNonExpired() {
+        return true;
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return true;
+    }
+}
diff --git a/src/main/java/com/common/security/configure/RestAuthenticationEntryPoint.java b/src/main/java/com/common/security/configure/RestAuthenticationEntryPoint.java
new file mode 100644
index 0000000..70f9aa5
--- /dev/null
+++ b/src/main/java/com/common/security/configure/RestAuthenticationEntryPoint.java
@@ -0,0 +1,36 @@
+package com.common.security.configure;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.common.core.beans.Result;
+import com.common.core.enums.ResultCodeEnum;
+import com.common.core.exception.BizException;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.web.AuthenticationEntryPoint;
+import org.springframework.stereotype.Component;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * @author 寤栨尟閽�
+ * @date 2022-01-17
+ * token澶辨晥璁块棶鎺ュ彛鏃讹紝鑷畾涔夌殑杩斿洖缁撴灉
+ */
+@Component
+public class RestAuthenticationEntryPoint  implements AuthenticationEntryPoint {
+    @Override
+    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException {
+        response.setCharacterEncoding("UTF-8");
+        response.setContentType("application/json");
+        response.addHeader("Content-Security-Policy","default-src 'self'");
+        response.addHeader("Strict-Transport-Security","max-age=31536000; includeSubdomains");
+        response.addHeader("Referrer-Policy","no-referrer-when-downgrade");
+        response.addHeader("X-Permitted-Cross-Domain-Policies","all");
+        response.addHeader("X-Download-Options","noopen");
+        Result res=Result.respErr(ResultCodeEnum.RT_INVALID_TOKEN);
+        response.getWriter().println(JSONObject.toJSONString(res));
+        response.getWriter().flush();
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/common/security/configure/RestfulAccessDeniedHandler.java b/src/main/java/com/common/security/configure/RestfulAccessDeniedHandler.java
new file mode 100644
index 0000000..ac72bd8
--- /dev/null
+++ b/src/main/java/com/common/security/configure/RestfulAccessDeniedHandler.java
@@ -0,0 +1,35 @@
+package com.common.security.configure;
+import com.alibaba.fastjson.JSONObject;
+import com.common.core.beans.Result;
+import com.common.core.enums.ResultCodeEnum;
+import com.common.core.exception.BizException;
+import org.springframework.security.access.AccessDeniedException;
+import org.springframework.security.web.access.AccessDeniedHandler;
+import org.springframework.stereotype.Component;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * @author 寤栨尟閽�
+ * @date 2022-01-17
+ */
+@Component
+public class RestfulAccessDeniedHandler implements AccessDeniedHandler {
+    @Override
+    public void handle(HttpServletRequest request,
+                       HttpServletResponse response,
+                       AccessDeniedException e) throws IOException, ServletException {
+        response.setCharacterEncoding("UTF-8");
+        response.setContentType("application/json");
+        response.addHeader("Content-Security-Policy","default-src 'self'");
+        response.addHeader("Strict-Transport-Security","max-age=31536000; includeSubdomains");
+        response.addHeader("Referrer-Policy","no-referrer-when-downgrade");
+        response.addHeader("X-Permitted-Cross-Domain-Policies","all");
+        response.addHeader("X-Download-Options","noopen");
+        Result res=Result.respErr(ResultCodeEnum.RT_ACCESS_DENIED);
+        response.getWriter().println(JSONObject.toJSONString(res));
+        response.getWriter().flush();
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/common/security/configure/RoleBasedVoter.java b/src/main/java/com/common/security/configure/RoleBasedVoter.java
new file mode 100644
index 0000000..665670a
--- /dev/null
+++ b/src/main/java/com/common/security/configure/RoleBasedVoter.java
@@ -0,0 +1,100 @@
+package com.common.security.configure;
+
+import com.common.annotation.NoAuthorize;
+import com.common.annotation.NoToken;
+import com.common.core.utils.SpringContextUtils;
+import org.aopalliance.intercept.MethodInvocation;
+import org.springframework.security.access.AccessDecisionVoter;
+import org.springframework.security.access.ConfigAttribute;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.web.FilterInvocation;
+import org.springframework.web.method.HandlerMethod;
+import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition;
+import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
+import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.*;
+import java.util.stream.Collectors;
+
+
+public class RoleBasedVoter implements AccessDecisionVoter<Object> {
+
+    @Override
+    public boolean supports(ConfigAttribute attribute) {
+        return true;
+    }
+
+    @Override
+    public int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) {
+        FilterInvocation fi = (FilterInvocation) object;
+        HttpServletRequest fiRequest = fi.getRequest();
+        String requestURI = fiRequest.getRequestURI();
+        Map<RequestMappingInfo, HandlerMethod> handlerMethods = ((RequestMappingHandlerMapping)SpringContextUtils.getBean("requestMappingHandlerMapping")).getHandlerMethods();
+        Set<String> anonymousUrls = new HashSet<>();
+        for (Map.Entry<RequestMappingInfo, HandlerMethod> infoEntry : handlerMethods.entrySet()) {
+            // 鑾峰彇鎵�鏈夋帴鍙g殑鏂规硶
+            HandlerMethod handlerMethod = infoEntry.getValue();
+            if ( handlerMethod.hasMethodAnnotation(NoAuthorize.class)) {
+                PatternsRequestCondition requestCondition = infoEntry.getKey().getPatternsCondition();
+                Optional.ofNullable(requestCondition).orElseThrow(RuntimeException::new);
+                anonymousUrls.addAll(requestCondition.getPatterns().stream().map(m -> SpringContextUtils.getEnvParam("server.servlet.context-path")+m).collect(Collectors.toList()));
+            }
+            if ( handlerMethod.hasMethodAnnotation(NoToken.class)) {
+                PatternsRequestCondition requestCondition = infoEntry.getKey().getPatternsCondition();
+                Optional.ofNullable(requestCondition).orElseThrow(RuntimeException::new);
+                anonymousUrls.addAll(requestCondition.getPatterns().stream().map(m -> SpringContextUtils.getEnvParam("server.servlet.context-path")+m).collect(Collectors.toList()));
+            }
+        }
+
+        for(String item : Arrays.asList(new String[]{
+                ".html",
+                ".css",
+                ".js",
+                ".png",
+                ".ttf",
+                ".ico",
+                ".woff",
+                "/swagger-resources",
+                "/v2/api-docs",
+                "/druid"
+        })){
+            if(requestURI.contains(item)){
+                return ACCESS_GRANTED;
+            }
+        }
+
+        if(anonymousUrls.contains(requestURI)){
+            return ACCESS_GRANTED;
+        }
+        if(authentication == null) {
+            return ACCESS_DENIED;
+        }
+        int result = ACCESS_ABSTAIN;
+        Collection<? extends GrantedAuthority> authorities = extractAuthorities(authentication);
+        for (ConfigAttribute attribute : attributes) {
+            if (this.supports(attribute)) {
+                //TODO 鐩墠鏄墍鏈夎姹傞兘瑕佸垽鏂潈闄愶紝濡傚悗缁湁涓嶉渶瑕佸垽鏂殑锛屽彲浠ュ惎鍔ㄦ椂浠庢暟鎹簱鍔犺浇鍒扮紦瀛�
+                result = ACCESS_DENIED;
+                // Attempt to find a matching granted authority
+                for (GrantedAuthority authority : authorities) {
+                    if (requestURI.equals(authority.getAuthority())) {
+                        return ACCESS_GRANTED;
+                    }
+                }
+            }
+        }
+        return result;
+    }
+
+    Collection<? extends GrantedAuthority> extractAuthorities(
+        Authentication authentication) {
+        return authentication.getAuthorities();
+    }
+
+    @Override
+    public boolean supports(Class clazz) {
+        return true;
+    }
+}
diff --git a/src/main/java/com/common/security/configure/SecurityConfig.java b/src/main/java/com/common/security/configure/SecurityConfig.java
new file mode 100644
index 0000000..c080cc7
--- /dev/null
+++ b/src/main/java/com/common/security/configure/SecurityConfig.java
@@ -0,0 +1,128 @@
+package com.common.security.configure;
+
+import com.common.annotation.NoToken;
+import com.common.core.utils.SpringContextUtils;
+import com.common.filter.CorsFilter;
+import com.common.filter.JwtAuthenticationTokenFilter;
+import com.deloitte.system.model.AppConfig;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.HttpMethod;
+import org.springframework.security.access.AccessDecisionManager;
+import org.springframework.security.access.AccessDecisionVoter;
+import org.springframework.security.access.vote.AuthenticatedVoter;
+import org.springframework.security.access.vote.UnanimousBased;
+import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.config.http.SessionCreationPolicy;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.web.access.expression.WebExpressionVoter;
+import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
+import org.springframework.web.method.HandlerMethod;
+import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition;
+import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
+import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @author 寤栨尟閽�
+ * @date 2022-01-14
+ */
+@Configuration
+@EnableWebSecurity
+@EnableGlobalMethodSecurity(prePostEnabled = true)
+public class SecurityConfig extends WebSecurityConfigurerAdapter {
+
+    @Autowired
+    private RestfulAccessDeniedHandler restfulAccessDeniedHandler;
+    @Autowired
+    private RestAuthenticationEntryPoint restAuthenticationEntryPoint;
+
+    // 鏀捐鎵�鏈夎姹�
+    @Override
+    protected void configure(HttpSecurity httpSecurity) throws Exception {
+        Map<RequestMappingInfo, HandlerMethod> handlerMethods = ((RequestMappingHandlerMapping)SpringContextUtils.getBean("requestMappingHandlerMapping")).getHandlerMethods();
+        Set<String> anonymousUrls = new HashSet<>();
+        for (Map.Entry<RequestMappingInfo, HandlerMethod> infoEntry : handlerMethods.entrySet()) {
+            // 鑾峰彇鎵�鏈夋帴鍙g殑鏂规硶
+            HandlerMethod handlerMethod = infoEntry.getValue();
+            if (handlerMethod.hasMethodAnnotation(NoToken.class)) {
+                PatternsRequestCondition requestCondition = infoEntry.getKey().getPatternsCondition();
+                Optional.ofNullable(requestCondition).orElseThrow(RuntimeException::new);
+                anonymousUrls.addAll(requestCondition.getPatterns().stream().map(m -> m).collect(Collectors.toList()));
+            }
+        }
+
+        anonymousUrls.add("/druid/**");
+
+
+        httpSecurity.csrf()
+                .disable()
+                .sessionManagement()// 鍩轰簬token锛屾墍浠ヤ笉闇�瑕乻ession
+                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
+                .and()
+                .authorizeRequests()
+                .antMatchers(HttpMethod.GET, // 鍏佽瀵逛簬缃戠珯闈欐�佽祫婧愮殑鏃犳巿鏉冭闂�
+                        "/",
+                        "/*.html",
+                        "/**/*.html",
+                        "/**/*.css",
+                        "/**/*.js",
+                        "/swagger-resources/**",
+                        "/v2/api-docs/**",
+                        "/druid/**"
+                )
+                .permitAll()
+                .antMatchers(anonymousUrls.toArray(new String[0]))
+                .anonymous()
+                .anyRequest()// 闄や笂闈㈠鐨勬墍鏈夎姹傚叏閮ㄩ渶瑕侀壌鏉冭璇�
+                .authenticated()
+                // 鑷畾涔塧ccessDecisionManager
+                .accessDecisionManager(accessDecisionManager());
+                ;//鏀捐option璇锋眰
+        // 绂佺敤缂撳瓨
+        httpSecurity.headers().cacheControl();
+        // 娣诲姞JWT filter
+        httpSecurity.addFilterBefore(jwtAuthenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class);
+        // 娣诲姞璺ㄥ煙 filter
+        httpSecurity.addFilterBefore(corsFilter(), JwtAuthenticationTokenFilter.class);
+        //娣诲姞鑷畾涔夋湭鎺堟潈鍜屾湭鐧诲綍缁撴灉杩斿洖
+        httpSecurity.exceptionHandling()
+                .accessDeniedHandler(restfulAccessDeniedHandler)
+                .authenticationEntryPoint(restAuthenticationEntryPoint);
+    }
+
+    @Bean
+    public JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter() {
+        return new JwtAuthenticationTokenFilter();
+    }
+
+    @Bean
+    public CorsFilter corsFilter() {
+        return new CorsFilter();
+    }
+    @Bean
+    public UserDetailsService userDetailsService() {
+        //鑾峰彇鐧诲綍鐢ㄦ埛淇℃伅
+        return username -> {
+            AppConfig appConfig = AppConfig.dao.findByAppid(username);
+            return new AppDetails(appConfig);
+        };
+    }
+
+    @Bean
+    public AccessDecisionManager accessDecisionManager() {
+        List<AccessDecisionVoter<? extends Object>> decisionVoters
+                = Arrays.asList(
+                new WebExpressionVoter(),
+                // new RoleVoter(),
+                new RoleBasedVoter(),
+                new AuthenticatedVoter());
+        return new UnanimousBased(decisionVoters);
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/common/security/utils/IpUtil.java b/src/main/java/com/common/security/utils/IpUtil.java
new file mode 100644
index 0000000..ca8b304
--- /dev/null
+++ b/src/main/java/com/common/security/utils/IpUtil.java
@@ -0,0 +1,48 @@
+package com.common.security.utils;
+
+import lombok.extern.slf4j.Slf4j;
+import javax.servlet.http.HttpServletRequest;
+
+
+/**
+ * @author 寤栨尟閽�
+ * @date 2022-01-14
+ */
+@Slf4j
+public class IpUtil {
+
+    public static String getIpAddr(HttpServletRequest request) {
+
+        String ip = request.getHeader("x-forwarded-for");
+
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("X-Real-IP");
+        }
+
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("http_client_ip");
+        }
+
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getRemoteAddr();
+        }
+
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("Proxy-Client-IP");
+        }
+
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("WL-Proxy-Client-IP");
+        }
+
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
+        }
+
+        if (ip != null && ip.indexOf(",") != -1) {
+            ip = ip.substring(ip.lastIndexOf(",") + 1, ip.length()).trim();
+        }
+
+        return ip;
+    }
+}
diff --git a/src/main/java/com/common/security/utils/SecurityHolderUtils.java b/src/main/java/com/common/security/utils/SecurityHolderUtils.java
new file mode 100644
index 0000000..f3f610d
--- /dev/null
+++ b/src/main/java/com/common/security/utils/SecurityHolderUtils.java
@@ -0,0 +1,20 @@
+package com.common.security.utils;
+
+/**
+ * @author 寤栨尟閽�
+ * @date 2022-01-19
+ */
+public class SecurityHolderUtils {
+    private static final ThreadLocal<String> USER_ID = new ThreadLocal<>();
+
+    public static void setUserId(String userid){
+        USER_ID.set(userid);
+    }
+
+    public static String getUserId(){
+        return USER_ID.get();
+    }
+    public static void cleanUserId(){
+        USER_ID.remove();
+    }
+}
diff --git a/src/main/java/com/common/security/utils/SecurityUtils.java b/src/main/java/com/common/security/utils/SecurityUtils.java
new file mode 100644
index 0000000..9cf004d
--- /dev/null
+++ b/src/main/java/com/common/security/utils/SecurityUtils.java
@@ -0,0 +1,37 @@
+package com.common.security.utils;
+
+import com.common.security.configure.AppDetails;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContext;
+import org.springframework.security.core.context.SecurityContextHolder;
+
+/**
+ * @author 寤栨尟閽�
+ * @date 2022-01-19
+ */
+public class SecurityUtils {
+
+    public static AppDetails getAppDetails(){
+        try {
+            SecurityContext ctx = SecurityContextHolder.getContext();
+            Authentication auth = ctx.getAuthentication();
+            AppDetails details = (AppDetails) auth.getPrincipal();
+            return details;
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    public static String getAppid(){
+        AppDetails appDetails=getAppDetails();
+        return appDetails ==null ? null : appDetails.getUsername();
+    }
+
+    public static String getUserId(){
+        return SecurityHolderUtils.getUserId();
+    }
+
+    public static String byId(){
+        return SecurityHolderUtils.getUserId() == null ? getAppid() : SecurityHolderUtils.getUserId();
+    }
+}
diff --git a/src/main/java/com/common/servlet/JFinalStatViewServlet.java b/src/main/java/com/common/servlet/JFinalStatViewServlet.java
new file mode 100644
index 0000000..bcda6a2
--- /dev/null
+++ b/src/main/java/com/common/servlet/JFinalStatViewServlet.java
@@ -0,0 +1,96 @@
+package com.common.servlet;
+
+import com.alibaba.druid.support.http.StatViewServlet;
+import com.jfinal.plugin.druid.IDruidStatViewAuth;
+import javax.servlet.ServletException;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+
+/**
+ * @author 寤栨尟閽�
+ * @date 2022-01-17
+ */
+@WebServlet
+public class JFinalStatViewServlet extends StatViewServlet {
+    private static final long serialVersionUID = 2898674199964021798L;
+
+    private IDruidStatViewAuth auth = new IDruidStatViewAuth(){
+        public boolean isPermitted(HttpServletRequest request) {
+            return true;
+        }
+    };
+
+    private String visitPath = "/admin/druid/monitor";
+
+    public JFinalStatViewServlet() {
+    }
+
+    public boolean isPermittedRequest(HttpServletRequest request) {
+        return this.auth.isPermitted(request);
+    }
+
+    public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+        String contextPath = request.getContextPath();
+        String requestURI = request.getRequestURI();
+        response.setCharacterEncoding("utf-8");
+        if (contextPath == null) {
+            contextPath = "";
+        }
+
+        int index = contextPath.length() + this.visitPath.length();
+        String uri = requestURI.substring(0, index);
+        String path = requestURI.substring(index);
+        if (!this.isPermittedRequest(request)) {
+            path = "/nopermit.html";
+            this.returnResourceFile(path, uri, response);
+        } else {
+            String fullUrl;
+            if ("/submitLogin".equals(path)) {
+                fullUrl = request.getParameter("loginUsername");
+                String passwordParam = request.getParameter("loginPassword");
+                response.getWriter().print("success");
+//                if (this.handler.username.equals(fullUrl) && this.handler.password.equals(passwordParam)) {
+//                    request.getSession().setAttribute("druid-user", this.handler.username);
+//                    response.getWriter().print("success");
+//                } else {
+//                    response.getWriter().print("error");
+//                }
+
+            } else if (this.isRequireAuth() && !this.ContainsUser(request) && !"/login.html".equals(path) && !path.startsWith("/css") && !path.startsWith("/js") && !path.startsWith("/img")) {
+                if (contextPath != null && !contextPath.equals("") && !contextPath.equals("/")) {
+                    if ("".equals(path)) {
+                        response.sendRedirect("druid/login.html");
+                    } else {
+                        response.sendRedirect("login.html");
+                    }
+                } else {
+                    response.sendRedirect("/druid/login.html");
+                }
+
+            } else if (!"".equals(path)) {
+                if ("/".equals(path)) {
+                    response.sendRedirect("index.html");
+                } else if (path.indexOf(".json") >= 0) {
+                    fullUrl = path;
+                    if (request.getQueryString() != null && request.getQueryString().length() > 0) {
+                        fullUrl = path + "?" + request.getQueryString();
+                    }
+
+                    response.getWriter().print(this.process(fullUrl));
+                } else {
+                    this.returnResourceFile(path, uri, response);
+                }
+            } else {
+                if (contextPath != null && !contextPath.equals("") && !contextPath.equals("/")) {
+                    response.sendRedirect("druid/index.html");
+                } else {
+                    response.sendRedirect("/druid/index.html");
+                }
+
+            }
+        }
+    }
+}
diff --git a/src/main/java/com/common/sign/BufferedHttpServletRequest.java b/src/main/java/com/common/sign/BufferedHttpServletRequest.java
new file mode 100644
index 0000000..e0e6e8c
--- /dev/null
+++ b/src/main/java/com/common/sign/BufferedHttpServletRequest.java
@@ -0,0 +1,86 @@
+package com.common.sign;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import javax.servlet.ReadListener;
+import javax.servlet.ServletInputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import java.io.IOException;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * @author 寤栨尟閽�
+ * @date 2022-01-14
+ */
+public class BufferedHttpServletRequest extends HttpServletRequestWrapper {
+
+    private ByteBuf buffer;
+    private final AtomicBoolean isCached = new AtomicBoolean();
+    public BufferedHttpServletRequest(HttpServletRequest request, int initialCapacity) {
+        super(request);
+        int contentLength = request.getContentLength();
+        int min = Math.min(initialCapacity, contentLength);
+        if (min < 0) {
+            buffer = Unpooled.buffer(0);
+        } else {
+            buffer = Unpooled.buffer(min, contentLength);
+        }
+    }
+
+    //TODO NettyServletInputStream find
+    @Override
+    public ServletInputStream getInputStream() throws IOException {
+        //Only returning data from buffer if it is readonly, which means the underlying stream is EOF or closed.
+//        if (isCached.get()) {
+//            return new NettyServletInputStream(buffer);
+//        }
+        return new ContentCachingInputStream(super.getInputStream());
+    }
+
+    public void release() {
+        buffer.release();
+    }
+
+    private class ContentCachingInputStream extends ServletInputStream {
+        private final ServletInputStream is;
+        public ContentCachingInputStream(ServletInputStream is) {
+            this.is = is;
+        }
+
+        @Override
+        public int read() throws IOException {
+            int ch = this.is.read();
+            if (ch != -1) { //Stream is EOF, set this buffer to readonly state
+                buffer.writeByte(ch);
+            } else {
+                isCached.compareAndSet(false, true);
+            }
+            return ch;
+        }
+
+        @Override
+        public void close() throws IOException {
+            //Stream is closed, set this buffer to readonly state
+            try {
+                is.close();
+            } finally {
+                isCached.compareAndSet(false, true);
+            }
+        }
+
+        @Override
+        public boolean isFinished() {
+            throw new UnsupportedOperationException("Not yet implemented!");
+        }
+
+        @Override
+        public boolean isReady() {
+            throw new UnsupportedOperationException("Not yet implemented!");
+        }
+
+        @Override public void setReadListener(ReadListener readListener) {
+            throw new UnsupportedOperationException("Not yet implemented!");
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/deloitte/sbg/controller/SapSBGRest.groovy b/src/main/java/com/deloitte/sbg/controller/SapSBGRest.groovy
new file mode 100644
index 0000000..1a3715c
--- /dev/null
+++ b/src/main/java/com/deloitte/sbg/controller/SapSBGRest.groovy
@@ -0,0 +1,174 @@
+package com.deloitte.sbg.controller
+
+import cn.hutool.core.util.StrUtil
+import com.alibaba.fastjson.JSON
+import com.alibaba.fastjson.JSONObject
+import com.common.annotation.NoToken
+import com.common.core.enums.ResultCodeEnum
+import com.common.core.exception.BizException
+import com.alibaba.fastjson.serializer.SerializerFeature
+import com.common.core.utils.IdUtils
+import com.common.core.utils.RestUtil
+import com.common.core.utils.SecretsManagerUtils
+import com.common.core.utils.SpringContextUtils
+import com.deloitte.system.model.Contact
+import com.deloitte.system.model.Opportunity
+import groovy.util.logging.Log
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.beans.factory.annotation.Value
+import org.springframework.core.env.Environment
+import org.springframework.http.HttpHeaders
+import org.springframework.http.ResponseEntity
+import org.springframework.web.bind.annotation.RequestBody
+import org.springframework.web.bind.annotation.RequestMapping
+import org.springframework.web.bind.annotation.RequestMethod
+import org.springframework.web.bind.annotation.RestController
+import org.springframework.web.client.HttpServerErrorException
+import org.springframework.web.context.request.RequestContextHolder
+import org.springframework.web.context.request.ServletRequestAttributes
+
+import javax.servlet.http.HttpServletResponse
+import java.util.logging.Level
+
+/**
+ * @Author: Ben Pi
+ * @Date: 23/02/2022 13:50
+ */
+
+
+@RestController
+@RequestMapping("/sbg")
+@Log("log")
+class SapSBGRest {
+
+    @Value("\${sap.url}")
+    private String sapurl;
+
+    @Autowired
+    private IdUtils idUtils;
+    @Autowired
+    private Environment env;
+    @Autowired
+    private SecretsManagerUtils secretsManagerUtils;
+
+    @RequestMapping(value = "/001", method = RequestMethod.POST)
+    def sbg001(@RequestBody def body) {
+        log.info("001鎺ュ彛璇锋眰=====================body:"+body)
+        HttpServletResponse resp = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse()
+        JSONObject object = secretsManagerUtils.getSecret(env.getProperty("aws.secrets.systemauth"));
+        String saptoken = object.getString("sap_token");
+        try {
+            for (int i = 0; i < body.SSBDCustomerContacts.SSBDCustomerContact.size(); i++) {
+                //鍒ゆ柇鏄鎴疯繕鏄仈绯讳汉锛屽鎴蜂俊鎭疌ustomerCode鍜孋ontactCode鐩哥瓑锛屼笉闇�瑕佸仛瑙e瘑
+                String customerCode = body.SSBDCustomerContacts.SSBDCustomerContact[i].CustomerCode
+                String contactCode = body.SSBDCustomerContacts.SSBDCustomerContact[i].ContactCode
+                if(customerCode.equals(contactCode)){
+                    if (body.SSBDCustomerContacts.SSBDCustomerContact[i].DataId != null) {
+                        body.SSBDCustomerContacts.SSBDCustomerContact[i].remove("DataId")
+                    }
+                    continue
+                }
+
+                Contact contact = new Contact().findById(body.SSBDCustomerContacts.SSBDCustomerContact[i].DataId.toString())
+                if (!contact) {
+                    throw new BizException("鏃犳晥鐨刣ataId")
+                }
+                String contactOffice = contact.getLastName()
+                String telephoneMobile = (StrUtil.isBlank(contact.getPhone())?"":contact.getPhone())+","+(StrUtil.isBlank(contact.getMobilePhone())?"":contact.getMobilePhone())
+                String address = contact.getAddress1()
+                String postalCode = contact.getPostcode()
+                String faxEmail = (StrUtil.isBlank(contact.getFax())?"":contact.getFax())+","+(StrUtil.isBlank(contact.getEmail())?"":contact.getEmail())
+                body.SSBDCustomerContacts.SSBDCustomerContact[i].ContactOffice = contactOffice
+                body.SSBDCustomerContacts.SSBDCustomerContact[i].TelephoneMobile = telephoneMobile
+                body.SSBDCustomerContacts.SSBDCustomerContact[i].Address = address
+                body.SSBDCustomerContacts.SSBDCustomerContact[i].PostalCode = postalCode
+                body.SSBDCustomerContacts.SSBDCustomerContact[i].FaxEmail = faxEmail
+                if (body.SSBDCustomerContacts.SSBDCustomerContact[i].DataId != null) {
+                    body.SSBDCustomerContacts.SSBDCustomerContact[i].remove("DataId")
+                }
+            }
+            HttpHeaders header = new HttpHeaders()
+            header.add("Authorization", "Basic " + saptoken)
+            ResponseEntity sapRes= RestUtil.postNative(sapurl + "SBG001", header, null, JSONObject.toJSONString(body, SerializerFeature.WriteMapNullValue))
+            resp.setStatus(sapRes.getStatusCodeValue())
+            return "success"
+        } catch(HttpServerErrorException e){
+            log.log(new Level("ERROR", Integer.MAX_VALUE, "ch.qos.logback.classic.Logger"), "001璇锋眰寮傚父", e)
+            resp.setStatus(e.getRawStatusCode())
+            return JSON.parse(e.getResponseBodyAsString())
+        } catch (Exception e) {
+            log.log(new Level("ERROR",Integer.MAX_VALUE, "ch.qos.logback.classic.Logger"), "001璇锋眰寮傚父", e)
+            resp.setStatus(Integer.valueOf(ResultCodeEnum.AWS_RT_ERROR.getCode()))
+            throw new BizException(ResultCodeEnum.AWS_RT_ERROR)
+        }
+    }
+
+    @RequestMapping(value = "/027", method = RequestMethod.POST)
+    def sbg027(@RequestBody def body) {
+        log.info("027鎺ュ彛璇锋眰=====================body:"+body)
+        HttpServletResponse resp = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse()
+        JSONObject object = secretsManagerUtils.getSecret(env.getProperty("aws.secrets.systemauth"));
+        String saptoken = object.getString("sap_token");
+        log.info("saptoken:"+saptoken);
+        try {
+            def datas = body.GeDatas
+            for (int i = 0; i < datas.GeData.size(); i++) {
+                Opportunity opportunity = new Opportunity().findById(datas.GeData[i].DataId)
+                if (!opportunity) {
+                    throw new BizException("鏃犳晥鐨刣ataId")
+                }
+                datas.GeData[i].DealerSalesStaffName = opportunity.getDealerSalesStaffName()
+                if (datas.GeData[i].DataId != null) {
+                    datas.GeData[i].remove("DataId")
+                }
+            }
+            HttpHeaders header = new HttpHeaders()
+            header.add("Authorization", "Basic " + saptoken)
+            ResponseEntity sapRes = RestUtil.postNativeObject(sapurl + "SBG027", header, null, JSONObject.toJSONString(body, SerializerFeature.WriteMapNullValue))
+            resp.setStatus(sapRes.getStatusCodeValue())
+            return "success"
+        } catch(HttpServerErrorException e){
+            log.log(new Level("ERROR", Integer.MAX_VALUE, "ch.qos.logback.classic.Logger"), "027璇锋眰寮傚父", e)
+            resp.setStatus(e.getRawStatusCode())
+            return JSON.parse(e.getResponseBodyAsString())
+        } catch (Exception e) {
+            log.log(new Level("ERROR",Integer.MAX_VALUE, "ch.qos.logback.classic.Logger"), "027璇锋眰寮傚父", e)
+            resp.setStatus(Integer.valueOf(ResultCodeEnum.AWS_RT_ERROR.getCode()))
+            throw new BizException(ResultCodeEnum.AWS_RT_ERROR)
+        }
+    }
+
+    @RequestMapping(value = "/007", method = RequestMethod.POST)
+    def sbg007(@RequestBody def body) {
+        log.info("007鎺ュ彛璇锋眰=====================body:"+body)
+        HttpServletResponse resp = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse()
+        JSONObject object = secretsManagerUtils.getSecret(env.getProperty("aws.secrets.systemauth"));
+        String saptoken = object.getString("sap_token");
+        try {
+            def datas = body.GeDatas
+            for (int i = 0; i < datas.GeData.size(); i++) {
+                Opportunity opportunity = new Opportunity().findById(datas.GeData[i].DataId)
+                if (!opportunity) {
+                    throw new BizException("鏃犳晥鐨刣ataId")
+                }
+                datas.GeData[i].DealerSalesStaffName = opportunity.getDealerSalesStaffName()
+                if (datas.GeData[i].DataId != null) {
+                    datas.GeData[i].remove("DataId")
+                }
+            }
+            HttpHeaders header = new HttpHeaders()
+            header.add("Authorization", "Basic " + saptoken)
+            ResponseEntity sapRes = RestUtil.postNative(sapurl + "SBG007", header, null, JSONObject.toJSONString(body, SerializerFeature.WriteMapNullValue))
+            resp.setStatus(sapRes.getStatusCodeValue())
+            return "success"
+        } catch(HttpServerErrorException e){
+            log.log(new Level("ERROR", Integer.MAX_VALUE, "ch.qos.logback.classic.Logger"), "007璇锋眰寮傚父", e)
+            resp.setStatus(e.getRawStatusCode())
+            return JSON.parse(e.getResponseBodyAsString())
+        } catch (Exception e) {
+            log.log(new Level("ERROR",Integer.MAX_VALUE, "ch.qos.logback.classic.Logger"), "007璇锋眰寮傚父", e)
+            resp.setStatus(Integer.valueOf(ResultCodeEnum.AWS_RT_ERROR.getCode()))
+            throw new BizException(ResultCodeEnum.AWS_RT_ERROR)
+        }
+    }
+}
diff --git a/src/main/java/com/deloitte/sbg/controller/SfSBGRest.groovy b/src/main/java/com/deloitte/sbg/controller/SfSBGRest.groovy
new file mode 100644
index 0000000..4d225b4
--- /dev/null
+++ b/src/main/java/com/deloitte/sbg/controller/SfSBGRest.groovy
@@ -0,0 +1,182 @@
+package com.deloitte.sbg.controller
+
+import com.alibaba.fastjson.JSON
+import com.alibaba.fastjson.JSONArray
+import com.alibaba.fastjson.JSONObject
+import com.alibaba.fastjson.serializer.SerializerFeature
+import com.common.core.domain.DesensitiveType
+import com.common.core.enums.ResultCodeEnum
+import com.common.core.service.SFService
+import com.common.core.utils.DesensitiveUtils
+import com.common.core.utils.IdUtils
+import com.common.core.utils.RestUtil
+import com.common.core.utils.StringUtils
+import com.deloitte.system.model.Contact
+import com.deloitte.system.request.SFTokenDto
+import groovy.util.logging.Log
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.beans.factory.annotation.Value
+import org.springframework.http.ResponseEntity
+import org.springframework.web.bind.annotation.RequestBody
+import org.springframework.web.bind.annotation.RequestMapping
+import org.springframework.web.bind.annotation.RequestMethod
+import org.springframework.web.bind.annotation.RestController
+import org.springframework.web.client.HttpServerErrorException
+import org.springframework.web.context.request.RequestContextHolder
+import org.springframework.web.context.request.ServletRequestAttributes
+import org.springframework.http.HttpHeaders
+
+import javax.servlet.http.HttpServletResponse
+import java.util.logging.Level
+
+import static com.jfinal.plugin.activerecord.Db.tx
+
+/**
+ * @Author: Ben Pi
+ * @Date: 22/02/2022 14:14
+ */
+
+
+@RestController
+@RequestMapping("/sbg")
+@Log("log")
+class SfSBGRest {
+    @Autowired
+    private SFService sfService;
+
+    @Autowired
+    private IdUtils idUtils;
+
+    @Value("\${salesforce.sbgurl}")
+    private String uri;
+
+    @RequestMapping(value = "/203", method = RequestMethod.POST)
+    def sbg203(@RequestBody def body) {
+        log.info("203鎺ュ彛璇锋眰=====================body:"+body)
+        HttpServletResponse resp = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse()
+        def result;
+        tx({ ->
+            SFTokenDto tokenDto = sfService.getToken()
+            String accessToken = tokenDto.getAccessToken()
+            HttpHeaders header = new HttpHeaders()
+            header.add("Authorization", "Bearer " + accessToken)
+            try {
+                for (int i = 0; i < body.Partners.size(); i++) {
+                    body.Partners[i].other1 = body.Partners[i].RegisterAddress
+                    if(null == body.Partners[i].Consignee_Info){
+                        continue;
+                    }
+                    String registerAddress = body.Partners[i].RegisterAddress
+                    String englishAddress = body.Partners[i].STR_SUPPL1
+                    String bpType = body.Partners[i].BPType
+
+                    //缃┖瀛楁
+                    body.Partners[i].Invoice_phone = ""
+                    body.Partners[i].Incorporator = ""
+                    for (int k = 0; k < body.Partners[i].Consignee_Info.size(); k++) {
+                        if (StringUtils.isNotBlank(body.Partners[i].Consignee_Info[k].ContactName)) {
+                            //缃┖瀛楁
+                            body.Partners[i].Consignee_Info[k].ContactMobilePhone = ""
+                            if(null != body.Partners[i].License_Info){
+                                for(int j = 0 ; j < body.Partners[i].License_Info.size(); j++){
+                                    body.Partners[i].License_Info[j].Principal = ""
+                                    body.Partners[i].License_Info[j].BusinessAddress = ""
+                                }
+                            }
+                            if ("23" == bpType){
+                                //bpType 涓�23鏃朵笉鍔犲瘑
+                                continue
+                            }
+
+                            def contactDataId = idUtils.nextId()
+                            Contact contact = new Contact()
+                            String name = body.Partners[i].Consignee_Info[k].ContactName
+                            String contactPhone = body.Partners[i].Consignee_Info[k].ContactPhone
+                            String contactAddress = body.Partners[i].Consignee_Info[k].ContactAddress
+                            String contactEnglishName = body.Partners[i].Consignee_Info[k].ContactEnglishName
+                            // 閭斂缂栫爜
+                            String postalCode = body.Partners[i].Consignee_Info[k].PostalCode
+                            contact.setDataId(Long.parseLong(contactDataId))
+                            contact.setMobilePhone(contactPhone)
+                            contact.setMobilePhoneD(contactPhone)
+                            if (StringUtils.isNotBlank(contactEnglishName) && "22".equals(bpType)) {
+                                contact.setLastName(name + '(' + contactEnglishName + ')')
+                                contact.setContactEnglishName(contactEnglishName)
+                                contact.setFirstName(null)
+                            } else {
+                                contact.setLastName(name)
+                                contact.setFirstName(null)
+                            }
+                            contact.setAddress1("22".equals(bpType) ? registerAddress : contactAddress)
+                            contact.setAddress1D("22".equals(bpType) ? registerAddress : contactAddress)
+                            contact.setEnglishAddress("22".equals(bpType) ? englishAddress : null)
+                            body.Partners[i].RegisterAddress = StringUtils.isNotBlank(registerAddress) ? DesensitiveUtils.getFieldDesensitive(DesensitiveType.ADDRESS) : ""
+                            body.Partners[i].Consignee_Info[k].ContactName = StringUtils.isNotBlank(name) ? DesensitiveUtils.getFieldDesensitive(DesensitiveType.CHINESE_NAME) : ""
+                            body.Partners[i].Consignee_Info[k].ContactPhone = StringUtils.isNotBlank(contactPhone) ? DesensitiveUtils.getFieldDesensitive(DesensitiveType.MOBILE_PHONE) : ""
+                            body.Partners[i].Consignee_Info[k].ContactEnglishName = StringUtils.isNotBlank(contactEnglishName) ? DesensitiveUtils.getFieldDesensitive(DesensitiveType.CHINESE_NAME) : ""
+                            //body.Partners[i].Consignee_Info[k].EnglishAddress = null//StringUtils.isNotBlank(contact.getEnglishAddress()) ? DesensitiveUtils.getFieldDesensitive(DesensitiveType.ADDRESS) : ""
+                            body.Partners[i].Consignee_Info[k].remove("EnglishAddress")
+                            body.Partners[i].Consignee_Info[k].ContactAddress = StringUtils.isNotBlank(contactAddress) ? DesensitiveUtils.getFieldDesensitive(DesensitiveType.ADDRESS) : ""
+                            body.Partners[i].Consignee_Info[k].PostalCode = StringUtils.isNotBlank(postalCode) ? DesensitiveUtils.getFieldDesensitive(DesensitiveType.ZIP_CODE) : ""
+
+                            body.Partners[i].RegisterAddressEncrypted = com.common.core.utils.SM4Utils.encryptStr(registerAddress)
+                            body.Partners[i].Consignee_Info[k].ContactNameEncrypted = com.common.core.utils.SM4Utils.encryptStr(name)
+                            body.Partners[i].Consignee_Info[k].ContactPhoneEncrypted = com.common.core.utils.SM4Utils.encryptStr(contactPhone)
+                            body.Partners[i].Consignee_Info[k].ContactAddressEncrypted = com.common.core.utils.SM4Utils.encryptStr(contactAddress)
+                            body.Partners[i].Consignee_Info[k].ContactEnglishNameEncrypted = StringUtils.isNotBlank(contactEnglishName) ? com.common.core.utils.SM4Utils.encryptStr(contactEnglishName) : ""
+                            //body.Partners[i].Consignee_Info[k].EnglishAddressEncrypted = null//StringUtils.isNotBlank(contact.getEnglishAddress()) ? com.common.core.utils.SM4Utils.encryptStr(englishAddress) : ""
+                            body.Partners[i].Consignee_Info[k].remove("EnglishAddressEncrypted")
+                            body.Partners[i].Consignee_Info[k].PostalCodeEncrypted = com.common.core.utils.SM4Utils.encryptStr(postalCode)
+                            body.Partners[i].Consignee_Info[k].DataId = contactDataId
+                            contact.save()
+                        }
+                    }
+                }
+
+                ResponseEntity sfRes = RestUtil.postNative(uri + "SBG203/execute", header, null, JSONObject.toJSONString(body,SerializerFeature.WriteMapNullValue))
+                resp.setStatus(sfRes.getStatusCodeValue())
+                result = sfRes.getBody().getJSONObject("staticResponse")
+                Boolean sfStatus = sfRes.getBody().get("SFStatus")
+                if (!sfStatus) {
+                    return false
+                }
+                return true
+            } catch(HttpServerErrorException e){
+                log.log(new Level("ERROR", Integer.MAX_VALUE, "ch.qos.logback.classic.Logger"), "203璇锋眰寮傚父", e)
+                resp.setStatus(e.getRawStatusCode())
+                result = JSON.parse(e.getResponseBodyAsString())
+                return false
+            } catch (Exception e) {
+                log.log(new Level("ERROR",Integer.MAX_VALUE, "ch.qos.logback.classic.Logger"), "203璇锋眰寮傚父", e)
+                resp.setStatus(Integer.valueOf(ResultCodeEnum.AWS_RT_ERROR.getCode()))
+                result = [[errorCode: 500, message: e.getMessage()]] as JSONArray
+                return false
+            }
+        })
+        return result
+    }
+
+    @RequestMapping(value = "/comparaEncrypt", method = RequestMethod.POST)
+    def comparaEncrypt(@RequestBody encryptBody){
+        def root = new ArrayList()
+        for(int i = 0 ; i  < encryptBody.size() ; i++){
+            def node = [:]
+            def encrypt = encryptBody[i];
+            node.encryptStr = encrypt.encryptStr
+            node.unencryptStr = encrypt.unencryptStr
+            boolean flag = false;
+            try{
+                flag = com.common.core.utils.SM4Utils.decryptStr(encrypt.encryptStr.toString()).equals(encrypt.unencryptStr.toString())
+            }catch(Exception e){
+                flag = false;
+            }
+            if(flag){
+                node.ismatch = "true"
+            }else{
+                node.ismatch = "false"
+            }
+            root.add(node)
+        }
+        return root
+    }
+}
diff --git a/src/main/java/com/deloitte/system/controller/CampaignUserController.java b/src/main/java/com/deloitte/system/controller/CampaignUserController.java
new file mode 100644
index 0000000..299c096
--- /dev/null
+++ b/src/main/java/com/deloitte/system/controller/CampaignUserController.java
@@ -0,0 +1,86 @@
+package com.deloitte.system.controller;
+
+import com.common.annotation.RequestLimit;
+import com.common.core.beans.Result;
+import com.common.core.enums.ResultCodeEnum;
+import com.common.core.utils.IdUtils;
+import com.deloitte.system.request.CampaignUserAllDto;
+import com.deloitte.system.request.SearchDto;
+import com.deloitte.system.request.CampaignUserDto;
+import com.deloitte.system.service.CampaignUserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import java.util.List;
+
+@RestController
+@RequestMapping("/campaignuser")
+public class CampaignUserController {
+    @Autowired
+    CampaignUserService campaignUserService;
+
+    @Autowired
+    private IdUtils idWorker;
+
+    @RequestMapping(value = "/query", method = RequestMethod.GET)
+    public Result<CampaignUserDto> query(@RequestParam("dataId") String dataId) {
+        CampaignUserDto dto = campaignUserService.queryForOne(dataId);
+        Result<CampaignUserDto> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(dto);
+        return res;
+    }
+    @RequestMapping(value = "/insert", method = RequestMethod.POST)
+    public Result<List<CampaignUserDto>> insert(@RequestBody List<CampaignUserDto> campaignUserDtoList) {
+        String txId = idWorker.nextId();
+        List<CampaignUserDto> respList = campaignUserService.insertList(campaignUserDtoList, txId);
+        Result<List<CampaignUserDto>> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setTxId(txId);
+        res.setObject(respList);
+        return res;
+    }
+    @RequestMapping(value = "/update", method = RequestMethod.POST)
+    public Result<List<CampaignUserDto>> update(@RequestBody List<CampaignUserDto> campaignUserDtoList) {
+        String txId = idWorker.nextId();
+        List<CampaignUserDto> respList = campaignUserService.updateList(campaignUserDtoList, txId);
+        Result<List<CampaignUserDto>> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setTxId(txId);
+        res.setObject(respList);
+        return res;
+    }
+
+    @RequestMapping(value = "/delete", method = RequestMethod.POST)
+    public Result<Boolean> delete(@RequestParam("dataId") String dataId) {
+        Boolean flag = campaignUserService.deleteOne(dataId);
+        Result<Boolean> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(flag);
+        return res;
+    }
+
+    @RequestMapping(value = "/undelete", method = RequestMethod.POST)
+    public Result<Boolean> undelete(@RequestParam("dataId") String dataId) {
+        Boolean flag = campaignUserService.undeleteOne(dataId);
+        Result<Boolean> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(flag);
+        return res;
+    }
+
+    @RequestMapping(value = "/search", method = RequestMethod.POST)
+    public Result<List<CampaignUserDto>> search(@RequestBody SearchDto searchDto){
+        List<CampaignUserDto> dtoList = campaignUserService.search(searchDto.getDataIds());
+        Result<List<CampaignUserDto>> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(dtoList);
+        return res;
+    }
+
+    @RequestLimit(size = 30)
+    @RequestMapping(value = "/batchupload", method = RequestMethod.POST)
+    public Result<List<CampaignUserAllDto>> batchUpload(@RequestParam(value = "file") MultipartFile[] files){
+        String txId = idWorker.nextId();
+        List<CampaignUserAllDto> list=campaignUserService.batchUpload(files,txId);
+        Result<List<CampaignUserAllDto>> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setTxId(txId);
+        res.setObject(list);
+        return res;
+    }
+
+}
diff --git a/src/main/java/com/deloitte/system/controller/ConfirmTxController.java b/src/main/java/com/deloitte/system/controller/ConfirmTxController.java
new file mode 100644
index 0000000..c3bf650
--- /dev/null
+++ b/src/main/java/com/deloitte/system/controller/ConfirmTxController.java
@@ -0,0 +1,42 @@
+package com.deloitte.system.controller;
+
+import com.common.core.beans.Result;
+import com.common.core.enums.ResultCodeEnum;
+import com.common.core.exception.BizException;
+import com.deloitte.system.request.TxConfirmDto;
+import com.deloitte.system.service.ConfirmTxService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/tx")
+public class ConfirmTxController {
+
+    @Autowired
+    private ConfirmTxService confirmTxService;
+
+    @RequestMapping(value = "/confirm", method = RequestMethod.POST)
+    public Result confirm(@RequestBody TxConfirmDto dto) {
+        try {
+            Result res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+            confirmTxService.confirm(dto);
+            return res;
+        }catch (BizException e){
+            return Result.resp("500", e.getMessage());
+        }
+    }
+
+    @RequestMapping(value = "/confirmfile", method = RequestMethod.POST)
+    public Result confirmFile(@RequestBody TxConfirmDto dto) {
+        try {
+            Result res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+            confirmTxService.confirmFile(dto);
+            return res;
+        }catch (BizException e){
+            return Result.resp("500", e.getMessage());
+        }
+    }
+}
diff --git a/src/main/java/com/deloitte/system/controller/ContactController.java b/src/main/java/com/deloitte/system/controller/ContactController.java
new file mode 100644
index 0000000..ddbd293
--- /dev/null
+++ b/src/main/java/com/deloitte/system/controller/ContactController.java
@@ -0,0 +1,96 @@
+package com.deloitte.system.controller;
+
+import com.common.core.beans.Result;
+import com.common.core.enums.ResultCodeEnum;
+import com.common.core.utils.IdUtils;
+import com.deloitte.system.request.ContactDto;
+
+import com.deloitte.system.request.ContactSearchDto;
+import com.deloitte.system.service.ContactService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+
+
+@RestController
+@RequestMapping("/contact")
+public class ContactController {
+
+    @Autowired
+    ContactService contactService;
+
+    @Autowired
+    private IdUtils idWorker;
+
+    @RequestMapping(value = "/query", method = RequestMethod.GET)
+    public Result<ContactDto> query(@RequestParam("dataId") String dataId) {
+        ContactDto dto = contactService.queryForOne(dataId);
+        Result<ContactDto> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(dto);
+        return res;
+    }
+
+    @RequestMapping(value = "/insert", method = RequestMethod.POST)
+    public Result<List<ContactDto>> insert(@RequestBody List<ContactDto> contactList) {
+        String txId = idWorker.nextId();
+        List<ContactDto> respList = contactService.insertList(contactList, txId);
+        Result<List<ContactDto>> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setTxId(txId);
+        res.setObject(respList);
+        return res;
+    }
+
+    /** 涓嶅瓨缂撳瓨锛岀洿鎺ュ叆搴� **/
+    @RequestMapping(value = "/batchInsert", method = RequestMethod.POST)
+    public Result<List<ContactDto>> batchInsert(@RequestBody List<ContactDto> contactList) {
+        List<ContactDto> respList = contactService.batchInsert(contactList);
+        Result<List<ContactDto>> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(respList);
+        return res;
+    }
+
+    @RequestMapping(value = "/update", method = RequestMethod.POST)
+    public Result<List<ContactDto>> update(@RequestBody List<ContactDto> contactList) {
+        String txId = idWorker.nextId();
+        List<ContactDto> respList = contactService.updateList(contactList, txId);
+        Result<List<ContactDto>> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setTxId(txId);
+        res.setObject(respList);
+        return res;
+    }
+
+    @RequestMapping(value = "/delete", method = RequestMethod.POST)
+    public Result<Boolean> delete(@RequestParam("dataId") String dataId) {
+        Boolean flag = contactService.deleteOne(dataId);
+        Result<Boolean> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(flag);
+        return res;
+    }
+
+    @RequestMapping(value = "/undelete", method = RequestMethod.POST)
+    public Result<Boolean> undelete(@RequestParam("dataId") String dataId) {
+        Boolean flag = contactService.undeleteOne(dataId);
+        Result<Boolean> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(flag);
+        return res;
+    }
+
+    @RequestMapping(value = "/search", method = RequestMethod.POST)
+    public Result<List<ContactDto>> search(@RequestBody ContactSearchDto contactSearchDto) {
+        List<ContactDto> dtos = contactService.searchList(contactSearchDto);
+        Result<List<ContactDto>> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(dtos);
+        return res;
+    }
+
+    @RequestMapping(value = "/decryptupdate",method = RequestMethod.POST)
+    public Result<List<ContactDto>> decryptUpdate(@RequestBody List<ContactDto> contactList){
+        List<ContactDto> respList=contactService.decryptUpdate(contactList);
+        Result<List<ContactDto>> res =Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(respList);
+        return res;
+    }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/deloitte/system/controller/FileController.java b/src/main/java/com/deloitte/system/controller/FileController.java
new file mode 100644
index 0000000..2fb556c
--- /dev/null
+++ b/src/main/java/com/deloitte/system/controller/FileController.java
@@ -0,0 +1,103 @@
+package com.deloitte.system.controller;
+
+import com.common.annotation.NoToken;
+import com.common.annotation.RequestLimit;
+import com.common.core.beans.Result;
+import com.common.core.enums.ResultCodeEnum;
+import com.common.core.exception.BizException;
+import com.common.core.utils.IdUtils;
+import com.deloitte.system.request.FileRequest;
+import com.deloitte.system.service.FileService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.Valid;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * @ClassName FileController
+ * @Author holfeng
+ * @Date 11:23 27/01/2022
+ * @Version 1.0
+ **/
+@RestController
+@RequestMapping("/file")
+@Slf4j
+public class FileController {
+    @Autowired
+    private FileService fileService;
+
+    @Autowired
+    private IdUtils idWorker;
+
+    @RequestLimit(size = 30)
+    @PostMapping("/upload")
+    public Result<String> upload(@RequestBody @Valid FileRequest fileRequest) {
+        String txId = idWorker.nextId();
+        String key=fileService.upload(txId,fileRequest);
+        Result<String> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(key);
+        res.setTxId(txId);
+        return res;
+    }
+
+    @RequestLimit(size = 500)
+    @PostMapping("/batchupload")
+    public Result<List<String>> batchUpload(@RequestBody @Valid List<FileRequest> fileList) {
+        String txId = idWorker.nextId();
+        List<String> keys=fileService.batchUpload(txId,fileList);
+        Result<List<String>> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(keys);
+        res.setTxId(txId);
+        return res;
+    }
+
+    @GetMapping("/preview")
+    @NoToken
+    public void preview(@RequestParam("key") String key){
+        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
+        fileService.preview(request,response,key);
+    }
+
+    @GetMapping("/download")
+    @NoToken
+    public void download(@RequestParam("key") String key){
+        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
+        fileService.download(request,response,key);
+    }
+    @RequestLimit(size = 30)
+    @PostMapping("/convert")
+    @NoToken
+    public void convert(){
+        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
+        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+
+        fileService.convert(request,response);
+    }
+
+    @GetMapping("/convert")
+    @NoToken
+    public void convertget(@RequestParam("from") String from) {
+        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
+        try {
+            response.sendRedirect(from);
+        } catch (IOException e) {
+            throw new BizException(ResultCodeEnum.AWS_RT_ERROR);
+        }
+    }
+
+    @PostMapping("/delete")
+    public Result deleteFile(@RequestBody List<String> keys){
+        fileService.deleteFile(keys);
+        return Result.resp(ResultCodeEnum.RT_SUCCESS);
+    }
+
+}
diff --git a/src/main/java/com/deloitte/system/controller/LoanerApplicationController.java b/src/main/java/com/deloitte/system/controller/LoanerApplicationController.java
new file mode 100644
index 0000000..832499d
--- /dev/null
+++ b/src/main/java/com/deloitte/system/controller/LoanerApplicationController.java
@@ -0,0 +1,77 @@
+package com.deloitte.system.controller;
+
+
+import com.common.core.beans.Result;
+import com.common.core.enums.ResultCodeEnum;
+import com.common.core.utils.IdUtils;
+import com.deloitte.system.request.LoanerApplicationDto;
+import com.deloitte.system.request.SearchDto;
+import com.deloitte.system.service.LoanerApplicationService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/loanerapplication")
+public class LoanerApplicationController {
+
+    @Autowired
+    LoanerApplicationService loanerApplicationService;
+
+    @Autowired
+    private IdUtils idWorker;
+
+    @RequestMapping(value = "/query", method = RequestMethod.GET)
+    public Result<LoanerApplicationDto> query(@RequestParam("dataId") String dataId) {
+        LoanerApplicationDto dto = loanerApplicationService.queryForOne(dataId);
+        Result<LoanerApplicationDto> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(dto);
+        return res;
+    }
+
+    @RequestMapping(value = "/insert", method = RequestMethod.POST)
+    public Result<List<LoanerApplicationDto>> insert(@RequestBody List<LoanerApplicationDto> loanerApplicationList) {
+        String txId = idWorker.nextId();
+        List<LoanerApplicationDto> respList = loanerApplicationService.insertList(loanerApplicationList, txId);
+        Result<List<LoanerApplicationDto>> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setTxId(txId);
+        res.setObject(respList);
+        return res;
+    }
+
+    @RequestMapping(value = "/update", method = RequestMethod.POST)
+    public Result<List<LoanerApplicationDto>> update(@RequestBody List<LoanerApplicationDto> loanerApplicationList) {
+        String txId = idWorker.nextId();
+        List<LoanerApplicationDto> respList = loanerApplicationService.updateList(loanerApplicationList, txId);
+        Result<List<LoanerApplicationDto>> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setTxId(txId);
+        res.setObject(respList);
+        return res;
+    }
+
+    @RequestMapping(value = "/delete", method = RequestMethod.POST)
+    public Result<Boolean> delete(@RequestParam("dataId") String dataId) {
+        Boolean flag = loanerApplicationService.deleteOne(dataId);
+        Result<Boolean> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(flag);
+        return res;
+    }
+
+    @RequestMapping(value = "/undelete", method = RequestMethod.POST)
+    public Result<Boolean> undelete(@RequestParam("dataId") String dataId) {
+        Boolean flag = loanerApplicationService.undeleteOne(dataId);
+        Result<Boolean> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(flag);
+        return res;
+    }
+
+    //鏍规嵁澶氫釜id鍜宎pply_person妯$硦鎼滅储鎺ュ彛锛坣ame=apply_person锛�
+    @RequestMapping(value = "/search", method = RequestMethod.POST)
+    public Result<List<LoanerApplicationDto>> search(@RequestBody SearchDto contactSearchDto) {
+        List<LoanerApplicationDto> dtos = loanerApplicationService.searchList(contactSearchDto);
+        Result<List<LoanerApplicationDto>> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(dtos);
+        return res;
+    }
+}
diff --git a/src/main/java/com/deloitte/system/controller/LoanerUserController.java b/src/main/java/com/deloitte/system/controller/LoanerUserController.java
new file mode 100644
index 0000000..fbe3a22
--- /dev/null
+++ b/src/main/java/com/deloitte/system/controller/LoanerUserController.java
@@ -0,0 +1,74 @@
+package com.deloitte.system.controller;
+
+import com.common.core.beans.Result;
+import com.common.core.enums.ResultCodeEnum;
+import com.common.core.utils.IdUtils;
+import com.deloitte.system.request.LoanerUserDto;
+import com.deloitte.system.request.SearchDto;
+import com.deloitte.system.service.LoanerUserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/loaneruser")
+public class LoanerUserController {
+
+    @Autowired
+    LoanerUserService loanerUserService;
+
+    @Autowired
+    private IdUtils idWorker;
+
+    @RequestMapping(value = "/query", method = RequestMethod.GET)
+    public Result<LoanerUserDto> query(@RequestParam("dataId") String dataId) {
+        LoanerUserDto dto = loanerUserService.queryForOne(dataId);
+        Result<LoanerUserDto> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(dto);
+        return res;
+    }
+
+    @RequestMapping(value = "/insert", method = RequestMethod.POST)
+    public Result<List<LoanerUserDto>> insert(@RequestBody List<LoanerUserDto> loanerUserDtoList) {
+        String txId = idWorker.nextId();
+        List<LoanerUserDto> respList = loanerUserService.insertList(loanerUserDtoList, txId);
+        Result<List<LoanerUserDto>> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setTxId(txId);
+        res.setObject(respList);
+        return res;
+    }
+
+    @RequestMapping(value = "/update", method = RequestMethod.POST)
+    public Result<List<LoanerUserDto>> update(@RequestBody List<LoanerUserDto> loanerUserDtoList) {
+        String txId = idWorker.nextId();
+        List<LoanerUserDto> respList = loanerUserService.updateList(loanerUserDtoList, txId);
+        Result<List<LoanerUserDto>> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setTxId(txId);
+        res.setObject(respList);
+        return res;
+    }
+    @RequestMapping(value = "/delete", method = RequestMethod.POST)
+    public Result<Boolean> delete(@RequestParam("dataId") String dataId) {
+        Boolean flag = loanerUserService.deleteOne(dataId);
+        Result<Boolean> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(flag);
+        return res;
+    }
+
+    @RequestMapping(value = "/undelete", method = RequestMethod.POST)
+    public Result<Boolean> undelete(@RequestParam("dataId") String dataId) {
+        Boolean flag = loanerUserService.undeleteOne(dataId);
+        Result<Boolean> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(flag);
+        return res;
+    }
+
+    @RequestMapping(value = "/search", method = RequestMethod.POST)
+    public Result<List<LoanerUserDto>> search(@RequestBody SearchDto searchDto){
+        List<LoanerUserDto> dtoList = loanerUserService.search(searchDto.getDataIds());
+        Result<List<LoanerUserDto>> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(dtoList);
+        return res;
+    }
+}
diff --git a/src/main/java/com/deloitte/system/controller/MailController.java b/src/main/java/com/deloitte/system/controller/MailController.java
new file mode 100644
index 0000000..4b7cb25
--- /dev/null
+++ b/src/main/java/com/deloitte/system/controller/MailController.java
@@ -0,0 +1,47 @@
+package com.deloitte.system.controller;
+
+import com.common.core.beans.Result;
+import com.common.core.enums.ResultCodeEnum;
+import com.common.core.utils.IdUtils;
+import com.deloitte.system.request.MessageVo;
+import com.deloitte.system.service.MailService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * @ClassName FileController
+ * @Author holfeng
+ * @Date 11:23 27/01/2022
+ * @Version 1.0
+ **/
+@RestController
+@RequestMapping("/mail")
+@Slf4j
+public class MailController {
+    @Autowired
+    private MailService mailService;
+
+    @Autowired
+    private IdUtils idWorker;
+
+    @PostMapping("/sendEmail")
+    public Result<Object> sendEmail(@RequestBody MessageVo messageVo) {
+        String txId = idWorker.nextId();
+        String sfMailMergeId=mailService.sendEmail(txId,messageVo);
+        Result<Object> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(sfMailMergeId);
+        res.setTxId(txId);
+        return res;
+    }
+
+//    @GetMapping("/sync")
+//    public Result<Object>  syncEmail() {
+//        String txId = idWorker.nextId();
+//        mailService.receiveImapMail();
+//        Result<Object> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+//        res.setTxId(txId);
+//        return res;
+//    }
+
+}
diff --git a/src/main/java/com/deloitte/system/controller/MailMergeController.java b/src/main/java/com/deloitte/system/controller/MailMergeController.java
new file mode 100644
index 0000000..c592318
--- /dev/null
+++ b/src/main/java/com/deloitte/system/controller/MailMergeController.java
@@ -0,0 +1,77 @@
+package com.deloitte.system.controller;
+
+import com.common.core.beans.Result;
+import com.common.core.enums.ResultCodeEnum;
+import com.common.core.utils.IdUtils;
+import com.deloitte.system.request.SearchDto;
+import com.deloitte.system.request.MailMergeDto;
+import com.deloitte.system.service.MailMergeService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/mailmerge")
+public class MailMergeController {
+
+    @Autowired
+    MailMergeService mailMergeService;
+
+    @Autowired
+    private IdUtils idWorker;
+
+    @RequestMapping(value = "/query", method = RequestMethod.GET)
+    public Result<MailMergeDto> query(@RequestParam("dataId") String dataId) {
+        MailMergeDto dto = mailMergeService.queryForOne(dataId);
+        Result<MailMergeDto> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(dto);
+        return res;
+    }
+
+    @RequestMapping(value = "/insert", method = RequestMethod.POST)
+    public Result<List<MailMergeDto>> insert(@RequestBody List<MailMergeDto> mailMergeDtoList) {
+        String txId = idWorker.nextId();
+        List<MailMergeDto> respList = mailMergeService.insertList(mailMergeDtoList, txId);
+        Result<List<MailMergeDto>> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setTxId(txId);
+        res.setObject(respList);
+        return res;
+    }
+
+    @RequestMapping(value = "/update", method = RequestMethod.POST)
+    public Result<List<MailMergeDto>> update(@RequestBody List<MailMergeDto> mailMergeDtoList) {
+        String txId = idWorker.nextId();
+        List<MailMergeDto> respList = mailMergeService.updateList(mailMergeDtoList, txId);
+        Result<List<MailMergeDto>> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setTxId(txId);
+        res.setObject(respList);
+        return res;
+    }
+
+    @RequestMapping(value = "/delete", method = RequestMethod.POST)
+    public Result<Boolean> delete(@RequestParam("dataId") String dataId) {
+        Boolean flag = mailMergeService.deleteOne(dataId);
+        Result<Boolean> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(flag);
+        return res;
+    }
+
+    @RequestMapping(value = "/undelete", method = RequestMethod.POST)
+    public Result<Boolean> undelete(@RequestParam("dataId") String dataId) {
+        Boolean flag = mailMergeService.undeleteOne(dataId);
+        Result<Boolean> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(flag);
+        return res;
+    }
+
+    @RequestMapping(value = "/search", method = RequestMethod.POST)
+    public Result<List<MailMergeDto>> search(@RequestBody SearchDto searchDto){
+        List<MailMergeDto> dtoList = mailMergeService.search(searchDto.getDataIds());
+        Result<List<MailMergeDto>> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(dtoList);
+        return res;
+    }
+
+
+}
diff --git a/src/main/java/com/deloitte/system/controller/OpportunityController.java b/src/main/java/com/deloitte/system/controller/OpportunityController.java
new file mode 100644
index 0000000..e17dd65
--- /dev/null
+++ b/src/main/java/com/deloitte/system/controller/OpportunityController.java
@@ -0,0 +1,96 @@
+package com.deloitte.system.controller;
+
+
+import com.common.annotation.NoToken;
+import com.common.core.beans.Result;
+import com.common.core.enums.ResultCodeEnum;
+import com.common.core.utils.IdUtils;
+import com.deloitte.system.request.OpportunityDto;
+
+import com.deloitte.system.request.QuotesDto;
+import com.deloitte.system.request.SearchDto;
+import com.deloitte.system.service.OpportunityService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/opportunity")
+public class OpportunityController {
+
+    @Autowired
+    OpportunityService opportunityService;
+
+    @Autowired
+    private IdUtils idWorker;
+
+    @RequestMapping(value = "/query", method = RequestMethod.GET)
+    public Result<OpportunityDto> query(@RequestParam("dataId") String dataId) {
+        OpportunityDto dto = opportunityService.queryForOne(dataId);
+        Result<OpportunityDto> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(dto);
+        return res;
+    }
+
+    @RequestMapping(value = "/insert", method = RequestMethod.POST)
+    public Result<List<OpportunityDto>> insert(@RequestBody List<OpportunityDto> opportunityList) {
+        String txId = idWorker.nextId();
+        List<OpportunityDto> respList = opportunityService.insertList(opportunityList, txId);
+        Result<List<OpportunityDto>> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setTxId(txId);
+        res.setObject(respList);
+        return res;
+    }
+
+    @RequestMapping(value = "/decryptinsert",method = RequestMethod.POST)
+    public Result<List<OpportunityDto>> decryptInsert(@RequestBody List<OpportunityDto> opportunityList){
+        List<OpportunityDto> respList = opportunityService.decryptInsert(opportunityList);
+        Result<List<OpportunityDto>> res =Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(respList);
+        return res;
+    }
+
+    @RequestMapping(value = "/update", method = RequestMethod.POST)
+    public Result<List<OpportunityDto>> update(@RequestBody List<OpportunityDto> opportunityList) {
+        String txId = idWorker.nextId();
+        List<OpportunityDto> respList = opportunityService.updateList(opportunityList, txId);
+        Result<List<OpportunityDto>> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setTxId(txId);
+        res.setObject(respList);
+        return res;
+    }
+
+    @RequestMapping(value = "/delete", method = RequestMethod.POST)
+    public Result<Boolean> delete(@RequestParam("dataId") String dataId) {
+        Boolean flag = opportunityService.deleteOne(dataId);
+        Result<Boolean> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(flag);
+        return res;
+    }
+
+    @RequestMapping(value = "/undelete", method = RequestMethod.POST)
+    public Result<Boolean> undelete(@RequestParam("dataId") String dataId) {
+        Boolean flag = opportunityService.undeleteOne(dataId);
+        Result<Boolean> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(flag);
+        return res;
+    }
+
+    @RequestMapping(value = "/search", method = RequestMethod.POST)
+    public Result<List<OpportunityDto>> search(@RequestBody SearchDto searchDto){
+        List<OpportunityDto> dtoList = opportunityService.search(searchDto.getDataIds());
+        Result<List<OpportunityDto>> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(dtoList);
+        return res;
+    }
+
+    @RequestMapping(value = "/decryptupdate",method = RequestMethod.POST)
+    public Result<List<OpportunityDto>> decryptUpdate(@RequestBody List<OpportunityDto> opportunityList){
+        List<OpportunityDto> respList=opportunityService.decryptUpdate(opportunityList);
+        Result<List<OpportunityDto>> res =Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(respList);
+        return res;
+    }
+
+}
diff --git a/src/main/java/com/deloitte/system/controller/OrderController.java b/src/main/java/com/deloitte/system/controller/OrderController.java
new file mode 100644
index 0000000..0b3aad1
--- /dev/null
+++ b/src/main/java/com/deloitte/system/controller/OrderController.java
@@ -0,0 +1,95 @@
+package com.deloitte.system.controller;
+
+
+import com.common.core.beans.Result;
+import com.common.core.enums.ResultCodeEnum;
+import com.common.core.utils.IdUtils;
+import com.deloitte.system.request.OpportunityDto;
+import com.deloitte.system.request.OrderDto;
+import com.deloitte.system.request.SearchDto;
+import com.deloitte.system.service.OrderService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/order")
+public class OrderController {
+
+    @Autowired
+    OrderService orderService;
+
+    @Autowired
+    private IdUtils idWorker;
+
+    @RequestMapping(value = "/query", method = RequestMethod.GET)
+    public Result<OrderDto> query(@RequestParam("dataId") String dataId) {
+        OrderDto dto = orderService.queryForOne(dataId);
+        Result<OrderDto> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(dto);
+        return res;
+    }
+
+    @RequestMapping(value = "/insert", method = RequestMethod.POST)
+    public Result<List<OrderDto>> insert(@RequestBody List<OrderDto> orderList) {
+        String txId = idWorker.nextId();
+        List<OrderDto> respList = orderService.insertList(orderList, txId);
+        Result<List<OrderDto>> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setTxId(txId);
+        res.setObject(respList);
+        return res;
+    }
+
+    @RequestMapping(value = "/decryptinsert",method = RequestMethod.POST)
+    public Result<List<OrderDto>> decryptInsert(@RequestBody List<OrderDto> orderList){
+        List<OrderDto> respList=orderService.decryptInsert(orderList);
+        Result<List<OrderDto>> res =Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(respList);
+        return res;
+    }
+
+
+    @RequestMapping(value = "/update", method = RequestMethod.POST)
+    public Result<List<OrderDto>> update(@RequestBody List<OrderDto> orderList) {
+        String txId = idWorker.nextId();
+        List<OrderDto> respList = orderService.updateList(orderList, txId);
+        Result<List<OrderDto>> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setTxId(txId);
+        res.setObject(respList);
+        return res;
+    }
+
+    @RequestMapping(value = "/delete", method = RequestMethod.POST)
+    public Result<Boolean> delete(@RequestParam("dataId") String dataId) {
+        Boolean flag = orderService.deleteOne(dataId);
+        Result<Boolean> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(flag);
+        return res;
+    }
+
+    @RequestMapping(value = "/undelete", method = RequestMethod.POST)
+    public Result<Boolean> undelete(@RequestParam("dataId") String dataId) {
+        Boolean flag = orderService.undeleteOne(dataId);
+        Result<Boolean> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(flag);
+        return res;
+    }
+
+    @RequestMapping(value = "/search", method = RequestMethod.POST)
+    public Result<List<OrderDto>> search(@RequestBody SearchDto searchDto){
+        List<OrderDto> dtoList = orderService.search(searchDto.getDataIds());
+        Result<List<OrderDto>> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(dtoList);
+        return res;
+    }
+
+    @RequestMapping(value = "/decryptupdate",method = RequestMethod.POST)
+    public Result<List<OrderDto>> decryptUpdate(@RequestBody List<OrderDto> orderList){
+        List<OrderDto> respList=orderService.decryptUpdate(orderList);
+        Result<List<OrderDto>> res =Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(respList);
+        return res;
+    }
+
+}
diff --git a/src/main/java/com/deloitte/system/controller/QuotesController.java b/src/main/java/com/deloitte/system/controller/QuotesController.java
new file mode 100644
index 0000000..da28c70
--- /dev/null
+++ b/src/main/java/com/deloitte/system/controller/QuotesController.java
@@ -0,0 +1,76 @@
+package com.deloitte.system.controller;
+
+import com.common.core.beans.Result;
+import com.common.core.enums.ResultCodeEnum;
+import com.common.core.utils.IdUtils;
+import com.deloitte.system.request.LoanerUserDto;
+import com.deloitte.system.request.QuotesDto;
+import com.deloitte.system.request.SearchDto;
+import com.deloitte.system.service.QuotesService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/quotes")
+public class QuotesController {
+
+    @Autowired
+    QuotesService quotesService;
+
+    @Autowired
+    private IdUtils idWorker;
+
+    @RequestMapping(value = "/query", method = RequestMethod.GET)
+    public Result<QuotesDto> query(@RequestParam("dataId") String dataId) {
+        QuotesDto dto = quotesService.queryForOne(dataId);
+        Result<QuotesDto> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(dto);
+        return res;
+    }
+
+    @RequestMapping(value = "/insert", method = RequestMethod.POST)
+    public Result<List<QuotesDto>> insert(@RequestBody List<QuotesDto> quotesDtoList) {
+        String txId = idWorker.nextId();
+        List<QuotesDto> respList = quotesService.insertList(quotesDtoList, txId);
+        Result<List<QuotesDto>> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setTxId(txId);
+        res.setObject(respList);
+        return res;
+    }
+
+    @RequestMapping(value = "/update", method = RequestMethod.POST)
+    public Result<List<QuotesDto>> update(@RequestBody List<QuotesDto> quotesDtoList) {
+        String txId = idWorker.nextId();
+        List<QuotesDto> respList = quotesService.updateList(quotesDtoList, txId);
+        Result<List<QuotesDto>> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setTxId(txId);
+        res.setObject(respList);
+        return res;
+    }
+    @RequestMapping(value = "/delete", method = RequestMethod.POST)
+    public Result<Boolean> delete(@RequestParam("dataId") String dataId) {
+        Boolean flag = quotesService.deleteOne(dataId);
+        Result<Boolean> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(flag);
+        return res;
+    }
+
+    @RequestMapping(value = "/undelete", method = RequestMethod.POST)
+    public Result<Boolean> undelete(@RequestParam("dataId") String dataId) {
+        Boolean flag = quotesService.undeleteOne(dataId);
+        Result<Boolean> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(flag);
+        return res;
+    }
+
+    @RequestMapping(value = "/search", method = RequestMethod.POST)
+    public Result<List<QuotesDto>> search(@RequestBody SearchDto searchDto){
+        List<QuotesDto> dtoList = quotesService.search(searchDto.getDataIds());
+        Result<List<QuotesDto>> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(dtoList);
+        return res;
+    }
+
+}
diff --git a/src/main/java/com/deloitte/system/controller/RepairController.java b/src/main/java/com/deloitte/system/controller/RepairController.java
new file mode 100644
index 0000000..d00d286
--- /dev/null
+++ b/src/main/java/com/deloitte/system/controller/RepairController.java
@@ -0,0 +1,77 @@
+package com.deloitte.system.controller;
+
+
+import com.common.core.beans.Result;
+import com.common.core.enums.ResultCodeEnum;
+import com.common.core.utils.IdUtils;
+import com.deloitte.system.request.OrderDto;
+import com.deloitte.system.request.RepairDto;
+import com.deloitte.system.request.SearchDto;
+import com.deloitte.system.service.RepairService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/repair")
+public class RepairController {
+
+    @Autowired
+    RepairService repairService;
+
+    @Autowired
+    private IdUtils idWorker;
+
+    @RequestMapping(value = "/query", method = RequestMethod.GET)
+    public Result<RepairDto> query(@RequestParam("dataId") String dataId) {
+        RepairDto dto = repairService.queryForOne(dataId);
+        Result<RepairDto> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(dto);
+        return res;
+    }
+
+    @RequestMapping(value = "/insert", method = RequestMethod.POST)
+    public Result<List<RepairDto>> insert(@RequestBody List<RepairDto> repairList) {
+        String txId = idWorker.nextId();
+        List<RepairDto> respList = repairService.insertList(repairList, txId);
+        Result<List<RepairDto>> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setTxId(txId);
+        res.setObject(respList);
+        return res;
+    }
+
+    @RequestMapping(value = "/update", method = RequestMethod.POST)
+    public Result<List<RepairDto>> update(@RequestBody List<RepairDto> repairList) {
+        String txId = idWorker.nextId();
+        List<RepairDto> respList = repairService.updateList(repairList, txId);
+        Result<List<RepairDto>> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setTxId(txId);
+        res.setObject(respList);
+        return res;
+    }
+
+    @RequestMapping(value = "/delete", method = RequestMethod.POST)
+    public Result<Boolean> delete(@RequestParam("dataId") String dataId) {
+        Boolean flag = repairService.deleteOne(dataId);
+        Result<Boolean> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(flag);
+        return res;
+    }
+
+    @RequestMapping(value = "/undelete", method = RequestMethod.POST)
+    public Result<Boolean> undelete(@RequestParam("dataId") String dataId) {
+        Boolean flag = repairService.undeleteOne(dataId);
+        Result<Boolean> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(flag);
+        return res;
+    }
+
+    @RequestMapping(value = "/search", method = RequestMethod.POST)
+    public Result<List<RepairDto>> search(@RequestBody SearchDto searchDto){
+        List<RepairDto> dtoList = repairService.search(searchDto.getDataIds());
+        Result<List<RepairDto>> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(dtoList);
+        return res;
+    }
+}
diff --git a/src/main/java/com/deloitte/system/controller/SwoController.java b/src/main/java/com/deloitte/system/controller/SwoController.java
new file mode 100644
index 0000000..5893f17
--- /dev/null
+++ b/src/main/java/com/deloitte/system/controller/SwoController.java
@@ -0,0 +1,75 @@
+package com.deloitte.system.controller;
+
+import com.common.core.beans.Result;
+import com.common.core.enums.ResultCodeEnum;
+import com.common.core.utils.IdUtils;
+import com.deloitte.system.request.OrderDto;
+import com.deloitte.system.request.SearchDto;
+import com.deloitte.system.request.SwoDto;
+import com.deloitte.system.service.SwoService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/swo")
+public class SwoController {
+    @Autowired
+    SwoService swoService;
+
+    @Autowired
+    private IdUtils idWorker;
+
+    @RequestMapping(value = "/query", method = RequestMethod.GET)
+    public Result<SwoDto> query(@RequestParam("dataId") String dataId) {
+        SwoDto dto = swoService.queryForOne(dataId);
+        Result<SwoDto> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(dto);
+        return res;
+    }
+
+    @RequestMapping(value = "/insert", method = RequestMethod.POST)
+    public Result<List<SwoDto>> insert(@RequestBody List<SwoDto> swoDtoList) {
+        String txId = idWorker.nextId();
+        List<SwoDto> respList = swoService.insertList(swoDtoList, txId);
+        Result<List<SwoDto>> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setTxId(txId);
+        res.setObject(respList);
+        return res;
+    }
+
+    @RequestMapping(value = "/update", method = RequestMethod.POST)
+    public Result<List<SwoDto>> update(@RequestBody List<SwoDto> swoDtoList) {
+        String txId = idWorker.nextId();
+        List<SwoDto> respList = swoService.updateList(swoDtoList, txId);
+        Result<List<SwoDto>> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setTxId(txId);
+        res.setObject(respList);
+        return res;
+    }
+
+    @RequestMapping(value = "/delete", method = RequestMethod.POST)
+    public Result<Boolean> delete(@RequestParam("dataId") String dataId) {
+        Boolean flag = swoService.deleteOne(dataId);
+        Result<Boolean> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(flag);
+        return res;
+    }
+
+    @RequestMapping(value = "/undelete", method = RequestMethod.POST)
+    public Result<Boolean> undelete(@RequestParam("dataId") String dataId) {
+        Boolean flag = swoService.undeleteOne(dataId);
+        Result<Boolean> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(flag);
+        return res;
+    }
+
+    @RequestMapping(value = "/search", method = RequestMethod.POST)
+    public Result<List<SwoDto>> search(@RequestBody SearchDto searchDto){
+        List<SwoDto> dtoList = swoService.search(searchDto.getDataIds());
+        Result<List<SwoDto>> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(dtoList);
+        return res;
+    }
+}
diff --git a/src/main/java/com/deloitte/system/controller/TSRepairController.java b/src/main/java/com/deloitte/system/controller/TSRepairController.java
new file mode 100644
index 0000000..049058c
--- /dev/null
+++ b/src/main/java/com/deloitte/system/controller/TSRepairController.java
@@ -0,0 +1,76 @@
+package com.deloitte.system.controller;
+
+import com.common.core.beans.Result;
+import com.common.core.enums.ResultCodeEnum;
+import com.common.core.utils.IdUtils;
+import com.deloitte.system.request.SearchDto;
+import com.deloitte.system.request.SwoDto;
+import com.deloitte.system.request.TSRepairDto;
+import com.deloitte.system.service.TSRepairService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/tsrepair")
+public class TSRepairController {
+    @Autowired
+    TSRepairService tsRepairService;
+
+    @Autowired
+    private IdUtils idWorker;
+
+    @RequestMapping(value = "/query", method = RequestMethod.GET)
+    public Result<TSRepairDto> query(@RequestParam("dataId") String dataId) {
+        TSRepairDto dto = tsRepairService.queryForOne(dataId);
+        Result<TSRepairDto> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(dto);
+        return res;
+    }
+
+    @RequestMapping(value = "/insert", method = RequestMethod.POST)
+    public Result<List<TSRepairDto>> insert(@RequestBody List<TSRepairDto> tsRepairDtoList) {
+        String txId = idWorker.nextId();
+        List<TSRepairDto> respList = tsRepairService.insertList(tsRepairDtoList, txId);
+        Result<List<TSRepairDto>> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setTxId(txId);
+        res.setObject(respList);
+        return res;
+    }
+
+    @RequestMapping(value = "/update", method = RequestMethod.POST)
+    public Result<List<TSRepairDto>> update(@RequestBody List<TSRepairDto> tsRepairDtoList) {
+        String txId = idWorker.nextId();
+        List<TSRepairDto> respList = tsRepairService.updateList(tsRepairDtoList, txId);
+        Result<List<TSRepairDto>> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setTxId(txId);
+        res.setObject(respList);
+        return res;
+    }
+
+    @RequestMapping(value = "/delete", method = RequestMethod.POST)
+    public Result<Boolean> delete(@RequestParam("dataId") String dataId) {
+        Boolean flag = tsRepairService.deleteOne(dataId);
+        Result<Boolean> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(flag);
+        return res;
+    }
+
+    @RequestMapping(value = "/undelete", method = RequestMethod.POST)
+    public Result<Boolean> undelete(@RequestParam("dataId") String dataId) {
+        Boolean flag = tsRepairService.undeleteOne(dataId);
+        Result<Boolean> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(flag);
+        return res;
+    }
+
+    @RequestMapping(value = "/search", method = RequestMethod.POST)
+    public Result<List<TSRepairDto>> search(@RequestBody SearchDto searchDto){
+        List<TSRepairDto> dtoList = tsRepairService.search(searchDto.getDataIds());
+        Result<List<TSRepairDto>> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(dtoList);
+        return res;
+    }
+
+}
diff --git a/src/main/java/com/deloitte/system/controller/TestController.java b/src/main/java/com/deloitte/system/controller/TestController.java
new file mode 100644
index 0000000..d7d8202
--- /dev/null
+++ b/src/main/java/com/deloitte/system/controller/TestController.java
@@ -0,0 +1,24 @@
+package com.deloitte.system.controller;
+
+import com.common.annotation.NoLog;
+import com.common.annotation.NoToken;
+import com.common.core.beans.Result;
+import com.common.core.enums.ResultCodeEnum;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/test")
+public class TestController{
+    /**
+     * 鐩戞帶妫�娴嬫帴鍙o紝鍕垮姩
+     * */
+    @NoLog
+    @NoToken
+    @RequestMapping(value = "/text4", method = RequestMethod.GET)
+    public Result index4(){
+        return Result.resp(ResultCodeEnum.RT_SUCCESS);
+    }
+
+}
diff --git a/src/main/java/com/deloitte/system/controller/TokenController.java b/src/main/java/com/deloitte/system/controller/TokenController.java
new file mode 100644
index 0000000..1662f58
--- /dev/null
+++ b/src/main/java/com/deloitte/system/controller/TokenController.java
@@ -0,0 +1,108 @@
+package com.deloitte.system.controller;
+
+import com.common.annotation.NoAuthorize;
+import com.common.annotation.NoToken;
+import com.common.annotation.RequestLimit;
+import com.common.core.beans.Result;
+import com.common.core.constant.GlobalConst;
+import com.common.core.enums.ResultCodeEnum;
+import com.common.core.exception.BizException;
+import com.common.core.utils.DistributedLock;
+import com.common.core.utils.JwtTokenUtil;
+import com.common.redis.util.RedisUtil;
+import com.common.security.configure.AppDetails;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.authentication.BadCredentialsException;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @author 寤栨尟閽�
+ * @date 2022-01-17
+ */
+@Slf4j
+@RestController
+@RequestMapping("/token")
+public class TokenController {
+
+    @Autowired
+    private UserDetailsService userDetailsService;
+
+    @Autowired
+    private JwtTokenUtil jwtTokenUtil;
+    @Autowired
+    private RedisUtil redisUtil;
+    @Autowired
+    private DistributedLock distributedLock;
+
+    @NoToken
+    @NoAuthorize
+    @RequestLimit(count = -1)
+    @RequestMapping(value = "/getToken", method = RequestMethod.GET)
+    public Result<String> getToken(@RequestParam("app_id") String appId, @RequestParam("app_secret") String appSecret, @RequestParam(value = "user_id", required = false) String userid){
+        String token = null;
+        Result<String> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        String key="";
+        try {
+            if(StringUtils.isEmpty(appSecret)){
+                throw new BadCredentialsException("appid, secret涓嶆纭�");
+            }
+            AppDetails userDetails = (AppDetails)userDetailsService.loadUserByUsername(appId);
+            String password = userDetails.getPassword();
+            if (!appSecret.equals(password)) {
+                throw new BadCredentialsException("appid, secret涓嶆纭�");
+            }
+            if(StringUtils.isNotEmpty(userid)) {
+                userDetails.setUserid(userid);
+            }
+            Authentication authentication = new UsernamePasswordAuthenticationToken(
+                    userDetails, null, userDetails.getAuthorities());
+            SecurityContextHolder.getContext().setAuthentication(authentication);
+
+            key=GlobalConst.TOKEN_KEY+appId;
+            String keyTmp=GlobalConst.TOKEN_KEY_TMP+appId;
+            if(StringUtils.isNotEmpty(userid)){
+                key +=":"+userid;
+                keyTmp+=":"+userid;
+            }
+
+            Object tokenCache=redisUtil.get(key);
+            long expire=redisUtil.getExpire(key);
+            if(tokenCache!=null && StringUtils.isNotEmpty(tokenCache.toString())&& expire>GlobalConst.TOKEN_EXPIRE_BUFF){
+                token = tokenCache.toString();
+            } else {
+                try {
+                    if (distributedLock.waitLock(key + ":lock", 300 * 1000)) {
+                        tokenCache = redisUtil.get(key);
+                        expire = redisUtil.getExpire(key);
+                        if (tokenCache != null && StringUtils.isNotEmpty(tokenCache.toString()) && expire > GlobalConst.TOKEN_EXPIRE_BUFF) {
+                            token = tokenCache.toString();
+                        } else if (tokenCache != null && StringUtils.isNotEmpty(tokenCache.toString()) && expire <= GlobalConst.TOKEN_EXPIRE_BUFF) {
+                            token = jwtTokenUtil.generateToken(userDetails);
+                            redisUtil.set(key, token, GlobalConst.TOKEN_EXPIRE + GlobalConst.TOKEN_EXPIRE_BUFF);
+                            redisUtil.set(keyTmp, tokenCache.toString(), expire);
+                        } else {
+                            token = jwtTokenUtil.generateToken(userDetails);
+                            redisUtil.set(key, token, GlobalConst.TOKEN_EXPIRE + GlobalConst.TOKEN_EXPIRE_BUFF);
+                        }
+                    }
+                } finally {
+                    distributedLock.releaseLock(key+":lock");
+                }
+            }
+        } catch (Exception e) {
+            log.warn("鐧诲綍寮傚父:{}", e.getMessage());
+            throw new BizException(ResultCodeEnum.LOGIN_FAILED);
+        }
+        res.setObject(token);
+        return res;
+    }
+}
diff --git a/src/main/java/com/deloitte/system/controller/UserFaultInfoController.java b/src/main/java/com/deloitte/system/controller/UserFaultInfoController.java
new file mode 100644
index 0000000..7af6604
--- /dev/null
+++ b/src/main/java/com/deloitte/system/controller/UserFaultInfoController.java
@@ -0,0 +1,76 @@
+package com.deloitte.system.controller;
+
+import com.common.core.beans.Result;
+import com.common.core.enums.ResultCodeEnum;
+import com.common.core.utils.IdUtils;
+
+import com.deloitte.system.request.SearchDto;
+import com.deloitte.system.request.TSRepairDto;
+import com.deloitte.system.request.UserFaultInfoDto;
+import com.deloitte.system.service.UserFaultInfoService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/userfaultinfo")
+public class UserFaultInfoController {
+    @Autowired
+    UserFaultInfoService userFaultInfoService;
+
+    @Autowired
+    private IdUtils idWorker;
+
+    @RequestMapping(value = "/query", method = RequestMethod.GET)
+    public Result<UserFaultInfoDto> query(@RequestParam("dataId") String dataId) {
+        UserFaultInfoDto dto = userFaultInfoService.queryForOne(dataId);
+        Result<UserFaultInfoDto> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(dto);
+        return res;
+    }
+    @RequestMapping(value = "/insert", method = RequestMethod.POST)
+    public Result<List<UserFaultInfoDto>> insert(@RequestBody List<UserFaultInfoDto> userFaultInfoDtoList) {
+        String txId = idWorker.nextId();
+        List<UserFaultInfoDto> respList = userFaultInfoService.insertList(userFaultInfoDtoList, txId);
+        Result<List<UserFaultInfoDto>> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setTxId(txId);
+        res.setObject(respList);
+        return res;
+    }
+    @RequestMapping(value = "/update", method = RequestMethod.POST)
+    public Result<List<UserFaultInfoDto>> update(@RequestBody List<UserFaultInfoDto> userFaultInfoDtoList) {
+        String txId = idWorker.nextId();
+        List<UserFaultInfoDto> respList = userFaultInfoService.updateList(userFaultInfoDtoList, txId);
+        Result<List<UserFaultInfoDto>> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setTxId(txId);
+        res.setObject(respList);
+        return res;
+    }
+
+    @RequestMapping(value = "/delete", method = RequestMethod.POST)
+    public Result<Boolean> delete(@RequestParam("dataId") String dataId) {
+        Boolean flag = userFaultInfoService.deleteOne(dataId);
+        Result<Boolean> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(flag);
+        return res;
+    }
+
+    @RequestMapping(value = "/undelete", method = RequestMethod.POST)
+    public Result<Boolean> undelete(@RequestParam("dataId") String dataId) {
+        Boolean flag = userFaultInfoService.undeleteOne(dataId);
+        Result<Boolean> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(flag);
+        return res;
+    }
+
+    @RequestMapping(value = "/search", method = RequestMethod.POST)
+    public Result<List<UserFaultInfoDto>> search(@RequestBody SearchDto searchDto){
+        List<UserFaultInfoDto> dtoList = userFaultInfoService.search(searchDto.getDataIds());
+        Result<List<UserFaultInfoDto>> res = Result.resp(ResultCodeEnum.RT_SUCCESS);
+        res.setObject(dtoList);
+        return res;
+    }
+
+
+}
diff --git a/src/main/java/com/deloitte/system/job/CleanCacheTask.java b/src/main/java/com/deloitte/system/job/CleanCacheTask.java
new file mode 100644
index 0000000..5a0747e
--- /dev/null
+++ b/src/main/java/com/deloitte/system/job/CleanCacheTask.java
@@ -0,0 +1,23 @@
+package com.deloitte.system.job;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import java.beans.Introspector;
+
+/**
+ * @author 璋㈡花鐠�
+ * @company deloitte
+ * @date 2022-04-13
+ * @descrition: 瀹氭椂娓呯悊cache
+ * */
+@Slf4j
+@Component
+public class CleanCacheTask {
+
+    @Scheduled(cron = "0 0 */1 * * ?")
+    public void execute() {
+        Introspector.flushCaches();
+    }
+}
diff --git a/src/main/java/com/deloitte/system/job/GuaranteedTask.java b/src/main/java/com/deloitte/system/job/GuaranteedTask.java
new file mode 100644
index 0000000..e5b7ca2
--- /dev/null
+++ b/src/main/java/com/deloitte/system/job/GuaranteedTask.java
@@ -0,0 +1,353 @@
+package com.deloitte.system.job;
+
+import cn.hutool.core.collection.CollUtil;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.common.core.constant.GlobalConst;
+import com.common.core.enums.TableNameEnum;
+import com.common.core.enums.YesNoEnum;
+import com.common.core.exception.BizException;
+import com.common.core.service.SFService;
+import com.common.core.utils.DistributedLock;
+import com.common.core.utils.RestUtil;
+import com.common.redis.util.RedisUtil;
+import com.deloitte.system.request.SFTokenDto;
+import com.deloitte.system.request.TxConfirmDto;
+import com.deloitte.system.service.ConfirmTxService;
+import com.deloitte.system.service.FileService;
+import com.jfinal.plugin.activerecord.Db;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpHeaders;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @author 寤栨尟閽�
+ * @company deloitte
+ * @date 2022-01-26
+ * @descrition:
+ *     鍏滃簳鏈哄埗瀹氭椂浠诲姟TODO
+ * */
+@Slf4j
+@Component
+public class GuaranteedTask {
+    @Autowired
+    private FileService fileService;
+    @Autowired
+    private SFService sfService;
+
+    @Autowired
+    private ConfirmTxService confirmTxService;
+
+    @Autowired
+    private RedisUtil redisUtil;
+
+    @Autowired
+    private DistributedLock distributedLock;
+    @Value("${salesforce.baseUrl}")
+    private String baseUrl;
+    /**
+     * 姣忓垎閽熻窇涓�娆�
+     */
+    @Scheduled(cron = "0 * * * * ?")
+    public void execute() {
+        boolean isLock = false;
+        boolean masterisLock = distributedLock.getLock("guaranteedLock-master",3600 * 1000);
+        if(!masterisLock){
+            isLock = distributedLock.getLock("guaranteedLock-slave",3600 * 1000);
+        }
+        if(masterisLock || isLock) {  //纭繚涓ゅ彴鏈嶅姟鍣ㄩ兘鑳藉悓鏃惰窇鍙堜笉浼氶噸澶嶈窇
+            try {
+                List<String> sets = new ArrayList<>();
+                Set<String> insertsets = redisUtil.getKeys(GlobalConst.PIPL_UNCONFIRM_INSERT + "*");
+                Set<String> updatesets = redisUtil.getKeys(GlobalConst.PIPL_UNCONFIRM_UPDATE + "*");
+                sets.addAll(insertsets);
+                sets.addAll(updatesets);
+                Map<String, String> hashmap = new HashMap<>();
+                for (String key : sets) {
+                    String[] keys = key.split(":");
+                    hashmap.put(keys[keys.length - 1], key);
+                }
+                List<String> sortkeysets = hashmap.keySet().stream().sorted(new Comparator<String>(){
+                    @Override
+                    public int compare(String o1, String o2) {
+                        Long o1L = Long.parseLong(o1);
+                        Long o2L = Long.parseLong(o2);
+                        Long v = o2L-o1L; //鍊掑簭
+//                        Long v = o1L-o2L; //椤哄簭
+                        if(v > 0){
+                            return 1;
+                        }else if(v < 0){
+                            return -1;
+                        }else {
+                            return 0;
+                        }
+                    }
+                }).limit(50).collect(Collectors.toList());
+                if (CollUtil.isEmpty(sortkeysets)) {
+                    return;
+                }
+                // 璋冪敤SF鏌ヨ浜嬪姟鐘舵�佺殑鎺ュ彛锛屼紶鍏xId List锛屽皢鏌ヨ鐨勭姸鎬佺粨鏋滄斁鍦╩ap锛宬ey涓簍xId锛寁alue涓哄鐞嗙姸鎬�
+                Map<String, Map<String,String>> statusMap = queryTransactionStatus(sortkeysets);
+//                Map<String, Map<String, String>> statusMap = query();
+                for (String key : sortkeysets) {
+                    boolean isExecute = distributedLock.getLock("guaranteed:"+key+":lock",3600 * 1000);//鍒ゆ柇鏄惁鏈夋満鍣ㄥ湪鎵ц浜嬪姟
+                    //濡傛灉redis閲岄潰涓嶅瓨鍦ㄨ繖涓猭ey涓庢病鏈夋満鍣ㄥ湪鎵ц璇ヤ簨鍔$‘璁�,灏辨墽琛岀‘璁や簨鍔�,闃叉澶氬彴鏈嶅姟鍣ㄩ噸澶嶈窇
+                    if((redisUtil.getKeys(GlobalConst.PIPL_UNCONFIRM_INSERT + "*").contains(GlobalConst.PIPL_UNCONFIRM_INSERT + key)
+                    || redisUtil.getKeys(GlobalConst.PIPL_UNCONFIRM_UPDATE + "*").contains(GlobalConst.PIPL_UNCONFIRM_UPDATE + key))
+                    && isExecute){
+                        String txid = hashmap.get(key);
+                        try {
+                            // 鑾峰彇璇XID鐨勫鐞嗙姸鎬侊紝濡傛灉鎴愬姛锛屽垯纭浜嬪姟锛屽鏋滃け璐ュ垯鍒犻櫎key
+                            List<String> collect = statusMap.keySet().stream().filter(i -> i.equals(key)).collect(Collectors.toList());
+                            if (CollUtil.isNotEmpty(collect)) {
+                                String tId = collect.get(0);
+                                Map<String, String> stringStringMap = statusMap.get(tId);
+                                String status = stringStringMap.get("status");
+                                String sfRecordId = stringStringMap.get("sfRecordId");
+                                if ("success".equals(status)) {
+                                    TxConfirmDto dto=new TxConfirmDto(key,sfRecordId, YesNoEnum.YES.getCode(),null);
+                                    confirmTxService.confirm(dto);
+                                }else {
+                                    redisUtil.deleteKey(txid);
+                                }
+                            }
+                        } catch (BizException e) {
+                            log.error(e.getMessage(), e);
+                        }finally {
+                            distributedLock.releaseLock("guaranteed:"+key+":lock");
+                        }
+                    }
+                }
+            } catch (Exception e) {
+                log.error(e.getMessage(), e);
+            }finally {
+                if(masterisLock){
+                    distributedLock.releaseLock("guaranteedLock-master");
+                }
+                if (isLock){
+                    distributedLock.releaseLock("guaranteedLock-slave");
+                }
+            }
+        }
+    }
+    /**
+     * 姣忓垎閽熻窇涓�娆�
+     */
+    @Scheduled(cron = "0 * * * * ?")
+    public void executeFile() {
+        boolean isLock = false;
+        boolean masterisLock = distributedLock.getLock("guaranteedLock-master-file",3600 * 1000);
+        if(!masterisLock){
+            isLock = distributedLock.getLock("guaranteedLock-slave-file",3600 * 1000);
+        }
+        if(masterisLock || isLock) {  //纭繚涓ゅ彴鏈嶅姟鍣ㄩ兘鑳藉悓鏃惰窇鍙堜笉浼氶噸澶嶈窇
+            try{
+                List<String> sets = new ArrayList<>();
+                Set<String> fileKeys = redisUtil.getKeys(GlobalConst.PIPL_UNCONFIRM_FILE + "*");
+                sets.addAll(fileKeys);
+                Map<String, String> hashmap = new HashMap<>();
+                for (String key : sets) {
+                    String[] keys = key.split(":");
+                    hashmap.put(keys[keys.length - 1], key);
+                }
+                List<String> sortkeysets = hashmap.keySet().stream().sorted(new Comparator<String>(){
+                    @Override
+                    public int compare(String o1, String o2) {
+                        Long o1L = Long.parseLong(o1);
+                        Long o2L = Long.parseLong(o2);
+                        Long v = o2L-o1L; //鍊掑簭
+//                        Long v = o1L-o2L; //椤哄簭
+                        if(v > 0){
+                            return 1;
+                        }else if(v < 0){
+                            return -1;
+                        }else {
+                            return 0;
+                        }
+                    }
+                }).limit(50).collect(Collectors.toList());
+                if (CollUtil.isEmpty(sortkeysets)) {
+                    return;
+                }
+                Map<String, Map<String, String>> statusMap = queryTransactionStatus(sortkeysets);
+//                Map<String, String> statusMap = query();
+                for (String key : sortkeysets) {
+                    boolean isExecute = distributedLock.getLock("guaranteed:"+key+":lock",3600 * 1000);//鍒ゆ柇鏄惁鏈夋満鍣ㄥ湪鎵ц浜嬪姟
+                    //濡傛灉redis閲岄潰涓嶅瓨鍦ㄨ繖涓猭ey涓庢病鏈夋満鍣ㄥ湪鎵ц璇ヤ簨鍔$‘璁�,灏辨墽琛岀‘璁や簨鍔�,闃叉澶氬彴鏈嶅姟鍣ㄩ噸澶嶈窇
+                    if((redisUtil.getKeys(GlobalConst.PIPL_UNCONFIRM_FILE + "*").contains(GlobalConst.PIPL_UNCONFIRM_FILE + key))
+                            && isExecute) {
+                        String txid = hashmap.get(key);
+                        try {
+                            //鑾峰彇璇XID鐨勫鐞嗙姸鎬侊紝濡傛灉鎴愬姛锛屽垯纭浜嬪姟锛屽鏋滃け璐ュ垯鍒犻櫎key
+                            List<String> collect = statusMap.keySet().stream().filter(i -> i.equals(key)).collect(Collectors.toList());
+                            if (CollUtil.isNotEmpty(collect)) {
+                                String tId = collect.get(0);
+                                Map<String, String> stringStringMap = statusMap.get(tId);
+                                String status = stringStringMap.get("status");
+                                String sfRecordId = stringStringMap.get("sfRecordId");
+                                if ("success".equals(status)) {
+//                                    confirmTxService.confirmFile(key);
+                                    redisUtil.deleteKey(txid);
+                                }else {
+                                    List<String> keyList = redisUtil.getObjects(txid, String.class);
+                                    try {
+                                        fileService.cleanS3File(keyList);
+                                    }catch (Exception e){
+                                        log.error(e.getMessage(), e);
+                                        throw new BizException("clean s3 file fail");
+                                    }
+                                    redisUtil.deleteKey(txid);
+                                }
+                            }
+                        } catch (BizException e) {
+                            log.error(e.getMessage(), e);
+                        }finally {
+                            distributedLock.releaseLock("guaranteed:"+key+":lock");
+                        }
+                    }
+                }
+            }catch (Exception e){
+                log.error(e.getMessage(), e);
+            }finally {
+                if(masterisLock){
+                    distributedLock.releaseLock("guaranteedLock-master-file");
+                }
+                if (isLock){
+                    distributedLock.releaseLock("guaranteedLock-slave-file");
+                }
+            }
+        }
+    }
+
+
+    /**
+     * 鍚屾琛ㄤ腑鐨剆fid(姣忓ぉ涓ょ偣鎵ц)
+     */
+    @Scheduled(cron = "0 0 2 * * ?")
+    public void executeSyncSfid() {
+        boolean isLock = false;
+        boolean masterisLock = distributedLock.getLock("guaranteedLock-syncSfid-master",3600 * 1000);
+        if(!masterisLock){
+            isLock = distributedLock.getLock("guaranteedLock-syncSfid-slave",3600 * 1000);
+        }
+        if(masterisLock || isLock) {  //纭繚涓ゅ彴鏈嶅姟鍣ㄩ兘鑳藉悓鏃惰窇鍙堜笉浼氶噸澶嶈窇
+            ArrayList<String> lockKeys = new ArrayList<>();
+            try {
+                //aws tableName涓巗f tableName鐨勬槧灏�
+                List<String> allAwsTableName = TableNameEnum.getAllAwsTableName();
+                for (String awsTableName:allAwsTableName) {
+                    List<Long> ids = Db.query("select id from `"+awsTableName+"` where is_delete = '0' and create_time>date_add(now(),interval -2 MONTH) and sf_record_id is null");
+                    log.info("鍚屾琛▄}锛屾煡璇㈠埌sf_id涓虹┖鐨勬暟鎹叡{}鏉�",awsTableName,ids.size());
+                    if (CollUtil.isEmpty(ids)) {
+                        continue;
+                    }
+                    //鍔犺〃鍚嶉攣锛岄樆姝㈠涓湇鍔″悓鏃舵洿鏂颁竴寮犺〃
+                    //鍒ゆ柇鏄惁鏈夋満鍣ㄥ湪鎵ц浜嬪姟
+                    boolean isExecute = distributedLock.getLock("guaranteed-syncSfid:"+awsTableName+":lock",3600 * 1000);
+                    if(isExecute) {
+                        lockKeys.add(awsTableName);
+                        String sfTableName = TableNameEnum.getSfTableNameByAwsTableName(awsTableName);
+                        //鎴彇ids姣�50鏉℃墽琛屼竴娆�
+                        int skip = 0;
+                        int sub = 50;
+                        List<String> collect = null;
+                        String idColumn = "AWS_Data_Id__c";
+                        while (collect==null||collect.size()>=sub) {
+                            collect = ids.stream().skip(skip).limit(sub).map(String::valueOf).collect(Collectors.toList());
+                            skip += sub;
+                            String sql = "select Id,"+idColumn+"  from "+sfTableName+" where "+idColumn+" in "+collect.stream().collect(Collectors.joining("','", "('", "')"));
+                            JSONArray jsonArray = sfService.querySFData(sql);
+                            if (jsonArray != null && jsonArray.size() != 0) {
+                                for (int i = 0;i<jsonArray.size();i++) {
+                                    JSONObject data = jsonArray.getJSONObject(i);
+                                    String sfId = data.getString("Id");
+                                    String awsId = data.getString(idColumn);
+                                    Db.update("update `"+awsTableName+"` set sf_record_id = '"+ sfId +"' where id = "+awsId);
+                                    log.info("鏇存柊{} sfid,id:{},sfid:{}",awsTableName,awsId,sfId);
+                                }
+                            }
+                        }
+                    }
+                }
+            } catch (Exception e) {
+                log.error("鍚屾contact sfid寮傚父锛�"+e.getMessage(), e);
+            }finally {
+                if(masterisLock){
+                    distributedLock.releaseLock("guaranteedLock-syncSfid-master");
+                }
+                if (isLock){
+                    distributedLock.releaseLock("guaranteedLock-syncSfid-slave");
+                }
+                //閲婃斁鏁版嵁閿�
+                if(CollUtil.isNotEmpty(lockKeys)){
+                    for (String awsTableName:lockKeys) {
+                        distributedLock.releaseLock("guaranteed-syncSfid:"+awsTableName+":lock");
+                    }
+                }
+            }
+        }
+    }
+
+
+    public Map<String,Map<String,String>> queryTransactionStatus(List<String> sortkeysets){
+        SFTokenDto tokenDto = sfService.getToken();
+        String accessToken = tokenDto.getAccessToken();
+        HttpHeaders header = new HttpHeaders();
+        header.add("Authorization", "Bearer " + accessToken);
+        StringBuilder idString = new StringBuilder();
+        // 鎷兼帴URL
+        String ids = sortkeysets.stream().collect(Collectors.joining("','", "('", "')"));
+        idString.append(baseUrl).append("services/data/v53.0/query/?q=Select Status__c,TransId__c,SFRecordId__c from Transaction_Log__c Where TransId__c in ").append(ids);
+        // 璇锋眰鏁版嵁
+        JSONObject jsonObject = RestUtil.get(idString.toString(),header);
+        Map<String, Map<String,String>> map = new HashMap<>();
+        List<JSONObject> objects = new ArrayList<>();
+        Object totalSize = jsonObject.get("totalSize");
+        Boolean done =(Boolean) jsonObject.get("done");
+        String nextRecordsUrl = jsonObject.getString("nextRecordsUrl");
+        JSONArray jsonArray = jsonObject.getJSONArray("records");
+
+        if (totalSize == null) {
+            log.info("璇锋眰浜嬪姟纭鏁版嵁澶辫触,result:{}",jsonObject);
+            throw new BizException("璇锋眰浜嬪姟纭鏁版嵁澶辫触");
+        }
+        for (int i = 0; i <jsonArray.size() ; i++) {
+            JSONObject data = jsonArray.getJSONObject(i);
+            String status = data.getString("Status__c");
+            String transId = data.getString("TransId__c");
+            String sfRecordId = data.getString("SFRecordId__c");
+            Map<String, String> mapStatus = new HashMap<>();
+            mapStatus.put("status",status);
+            mapStatus.put("sfRecordId",sfRecordId);
+            map.put(transId,mapStatus);
+        }
+        return map;
+    }
+
+    public Map<String, String> queryNextRecords(String nextRecordsUrl,Map<String,String> map){
+        SFTokenDto tokenDto = sfService.getToken();
+        String accessToken = tokenDto.getAccessToken();
+        HttpHeaders header = new HttpHeaders();
+        header.add("Authorization", "Bearer " + accessToken);
+        JSONObject jsonObject = RestUtil.get(nextRecordsUrl,header);
+        Boolean done =(Boolean) jsonObject.get("done");
+        JSONArray jsonArray = jsonObject.getJSONArray("records");
+        Object totalSize = jsonObject.get("totalSize");
+        if (totalSize == null) {
+            return map;
+        }
+        for (int i = 0; i <jsonArray.size() ; i++) {
+            JSONObject data = jsonArray.getJSONObject(i);
+            String status = data.getString("Status__c");
+            String transId = data.getString("TransId__c");
+            map.put(transId,status);
+        }
+        return map;
+    }
+}
diff --git a/src/main/java/com/deloitte/system/job/MailSyncTask.java b/src/main/java/com/deloitte/system/job/MailSyncTask.java
new file mode 100644
index 0000000..023e149
--- /dev/null
+++ b/src/main/java/com/deloitte/system/job/MailSyncTask.java
@@ -0,0 +1,38 @@
+package com.deloitte.system.job;
+
+import com.common.core.utils.DistributedLock;
+import com.common.redis.util.RedisUtil;
+import com.deloitte.system.service.MailService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+/**
+ *  閭欢鍚屾浠诲姟
+ */
+@Slf4j
+@Component
+public class MailSyncTask {
+    @Autowired
+    private MailService mailService;
+    @Autowired
+    private DistributedLock distributedLock;
+
+    @Scheduled(cron = "1 * * * * ?")
+    public void execute() {
+        boolean isLock = false;
+        isLock = distributedLock.getLock("mailSyncLock",3600 * 1000);
+
+        if(isLock) {
+            try {
+                mailService.receiveImapMail();
+            } catch (Exception e) {
+                log.error(e.getMessage(), e);
+            }finally {
+                distributedLock.releaseLock("mailSyncLock");
+            }
+        }
+    }
+
+}
diff --git a/src/main/java/com/deloitte/system/model/Account.java b/src/main/java/com/deloitte/system/model/Account.java
new file mode 100644
index 0000000..ef77c32
--- /dev/null
+++ b/src/main/java/com/deloitte/system/model/Account.java
@@ -0,0 +1,55 @@
+package com.deloitte.system.model;
+
+import com.common.annotation.Table;
+import com.common.core.domain.BaseModel;
+
+/**
+ * @Author: Ben Pi
+ * @Date: 22/02/2022 15:59
+ */
+
+@Table(tableName = "account", clazz = Account.class)
+public class Account extends BaseModel<Account> {
+    public static final Account dao = new Account();
+
+    public Long getDataId() {
+
+        return getLong("id");
+    }
+
+    public Account setDataId(Long dataId) {
+        set("id", dataId);
+        return this;
+    }
+
+    public String getMobilePhoneNumber(){
+        return getStr("mobile_phone_number");
+    }
+
+    public Account setMobilePhoneNumber(String mobilePhoneNumber){
+        set("mobile_phone_number", mobilePhoneNumber);
+        return this;
+    }
+
+    public String getPhoneD(){
+        return getStr("phone_d");
+    }
+
+    public Account setPhoneD(String phoneD){
+        set("phone_d", phoneD);
+        return this;
+    }
+
+    public String getSfRecordId(){
+        return getStr("sf_record_id");
+    }
+
+    public Account setSfRecordId(String sfRecordId){
+        set("sf_record_id", sfRecordId);
+        return this;
+    }
+
+    public Account findById(String dataId){
+        return this.dao.findFirst("select * from `" + getTableName() + "` where id=? ", dataId);
+    }
+}
diff --git a/src/main/java/com/deloitte/system/model/AppConfig.java b/src/main/java/com/deloitte/system/model/AppConfig.java
new file mode 100644
index 0000000..e703695
--- /dev/null
+++ b/src/main/java/com/deloitte/system/model/AppConfig.java
@@ -0,0 +1,37 @@
+package com.deloitte.system.model;
+
+import com.common.annotation.Table;
+import com.common.core.domain.BaseModel;
+
+/**
+ * @author 寤栨尟閽�
+ * @date 2022-01-17
+ */
+
+@Table(tableName = "app_config", clazz = AppConfig.class)
+public class AppConfig extends BaseModel<AppConfig> {
+
+    public static final AppConfig dao = new AppConfig();
+
+    public String appid(){
+        return getStr("app_id");
+    }
+
+    public AppConfig appid(String appid){
+        set("app_id", appid);
+        return this;
+    }
+
+    public String appsecret(){
+        return getStr("app_secret");
+    }
+
+    public AppConfig appsecret(String appsecret){
+        set("app_secret", appsecret);
+        return this;
+    }
+
+    public AppConfig findByAppid(String appid){
+        return this.dao.findFirst("select * from " + getTableName() + " where app_id=? ",appid);
+    }
+}
diff --git a/src/main/java/com/deloitte/system/model/AppPermissionConfig.java b/src/main/java/com/deloitte/system/model/AppPermissionConfig.java
new file mode 100644
index 0000000..554799a
--- /dev/null
+++ b/src/main/java/com/deloitte/system/model/AppPermissionConfig.java
@@ -0,0 +1,39 @@
+package com.deloitte.system.model;
+
+import com.common.annotation.Table;
+import com.common.core.domain.BaseModel;
+
+import java.util.List;
+
+/**
+ * @author 寤栨尟閽�
+ * @date 2022-01-17
+ */
+@Table(tableName = "app_permission_config", clazz = AppPermissionConfig.class)
+public class AppPermissionConfig extends BaseModel<AppPermissionConfig> {
+
+    public static final AppPermissionConfig dao = new AppPermissionConfig();
+
+    public String appid(){
+        return getStr("app_id");
+    }
+
+    public AppPermissionConfig appid(String appid){
+        set("app_id", appid);
+        return this;
+    }
+
+
+    public String url(){
+        return getStr("url");
+    }
+
+    public AppPermissionConfig url(String url){
+        set("url", url);
+        return this;
+    }
+
+    public List<AppPermissionConfig> findByAppidList(String appid){
+        return this.dao.find("select * from "+ getTableName() + " where app_id=?",appid);
+    }
+}
diff --git a/src/main/java/com/deloitte/system/model/CacheList.java b/src/main/java/com/deloitte/system/model/CacheList.java
new file mode 100644
index 0000000..fabf234
--- /dev/null
+++ b/src/main/java/com/deloitte/system/model/CacheList.java
@@ -0,0 +1,21 @@
+package com.deloitte.system.model;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+/**
+ * @Author: Ben Pi
+ * @Date: 24/01/2022 15:58
+ * @Description:   鐢ㄤ簬瀛樺叆鐨凩ist锛屽甫鏈夎〃鍚嶅睘鎬�
+ */
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class CacheList<V>{
+    private List<V> data;
+    private String tableName;
+}
diff --git a/src/main/java/com/deloitte/system/model/CampaignUser.java b/src/main/java/com/deloitte/system/model/CampaignUser.java
new file mode 100644
index 0000000..fab5daf
--- /dev/null
+++ b/src/main/java/com/deloitte/system/model/CampaignUser.java
@@ -0,0 +1,65 @@
+package com.deloitte.system.model;
+
+import com.common.annotation.Table;
+import com.common.core.domain.BaseModel;
+
+import java.util.List;
+
+@Table(tableName = "campaign_user", clazz = CampaignUser.class)
+public class CampaignUser extends BaseModel<CampaignUser> {
+    public static final CampaignUser dao=new CampaignUser();
+
+    public Long getDataId(){
+
+        return getLong("id");
+    }
+
+    public CampaignUser setDataId(Long dataId) {
+        set("id", dataId);
+        return this;
+    }
+
+    public String getName(){
+        return getStr("name");
+    }
+
+    public CampaignUser setName(String name){
+        set("name", name);
+        return this;
+    }
+
+    public String getPhone(){
+        return getStr("phone");
+    }
+
+    public CampaignUser setPhone(String phone){
+        set("phone", phone);
+        return this;
+    }
+
+    public String getEmail(){
+        return getStr("email");
+    }
+
+    public CampaignUser setEmail(String email){
+        set("email", email);
+        return this;
+    }
+
+    public String getSfRecordId(){
+        return getStr("sf_record_id");
+    }
+
+    public CampaignUser setSfRecordId(String sfRecordId){
+        set("sf_record_id", sfRecordId);
+        return this;
+    }
+
+    public CampaignUser findById(String dataId){
+        return this.dao.findFirst("select * from `" + getTableName() + "` where id=? ", dataId);
+    }
+
+    public List<CampaignUser> findListBySql(String sql){
+        return this.dao.find(sql);
+    }
+}
diff --git a/src/main/java/com/deloitte/system/model/Contact.java b/src/main/java/com/deloitte/system/model/Contact.java
new file mode 100644
index 0000000..762e7e1
--- /dev/null
+++ b/src/main/java/com/deloitte/system/model/Contact.java
@@ -0,0 +1,258 @@
+package com.deloitte.system.model;
+
+import com.common.annotation.Table;
+import com.common.core.domain.BaseModel;
+
+@Table(tableName = "contact", clazz = Contact.class)
+public class Contact extends BaseModel<Contact> {
+    public static final Contact dao = new Contact();
+
+    public Long getDataId(){
+
+        return getLong("id");
+    }
+
+    public Contact setDataId(Long dataId){
+        set("id", dataId);
+        return this;
+    }
+
+    public String getFirstName(){
+        return getStr("first_name");
+    }
+
+    public Contact setFirstName(String firstName){
+        set("first_name", firstName);
+        return this;
+    }
+
+    public String getLastName(){
+        return getStr("last_name");
+    }
+
+    public Contact setLastName(String lastName){
+        set("last_name", lastName);
+        return this;
+    }
+
+    public String getPostcode(){
+        return getStr("postcode");
+    }
+
+    public Contact setPostcode(String postcode){
+        set("postcode", postcode);
+        return this;
+    }
+
+    public String getPostcodeD(){
+        return getStr("postcode_d");
+    }
+
+    public Contact setPostcodeD(String postcodeD){
+        set("postcode_d", postcodeD);
+        return this;
+    }
+
+    public String getTitleD(){
+        return getStr("title_d");
+    }
+
+    public Contact setTitleD(String titleD){
+        set("title_d", titleD);
+        return this;
+    }
+
+    public String getTitle(){
+        return getStr("title");
+    }
+
+    public Contact setTitle(String title){
+        set("title", title);
+        return this;
+    }
+
+    public String getContactEnglishName(){
+        return getStr("contact_english_name");
+    }
+
+    public Contact setContactEnglishName(String contactEnglishName){
+        set("contact_english_name", contactEnglishName);
+        return this;
+    }
+
+    public String getEnglishAddress(){
+        return getStr("english_address");
+    }
+
+    public Contact setEnglishAddress(String englishAddress){
+        set("english_address", englishAddress);
+        return this;
+    }
+
+    public String getAddress1(){
+        return getStr("address1");
+    }
+
+    public Contact setAddress1(String address1){
+        set("address1", address1);
+        return this;
+    }
+
+    public String getAddress2(){
+        return getStr("address2");
+    }
+
+    public Contact setAddress2(String address2){
+        set("address2", address2);
+        return this;
+    }
+
+    public String getAddress3(){
+        return getStr("address3");
+    }
+
+    public Contact setAddress3(String address3){
+        set("address3", address3);
+        return this;
+    }
+
+    public String getAddress1D(){
+        return getStr("address1_d");
+    }
+
+    public Contact setAddress1D(String address1D){
+        set("address1_d", address1D);
+        return this;
+    }
+
+    public String getAddress2D(){
+        return getStr("address2_d");
+    }
+
+    public Contact setAddress2D(String address2D){
+        set("address2_d", address2D);
+        return this;
+    }
+
+    public String getAddress3D(){
+        return getStr("address3_d");
+    }
+
+    public Contact setAddress3D(String address3D){
+        set("address3_d", address3D);
+        return this;
+    }
+
+    public String getFax(){
+        return getStr("fax");
+    }
+
+    public Contact setFax(String fax){
+        set("fax", fax);
+        return this;
+    }
+
+    public String getFaxD(){
+        return getStr("fax_d");
+    }
+
+    public Contact setFaxD(String faxD){
+        set("fax_d", faxD);
+        return this;
+    }
+
+    public String getEmailD(){
+        return getStr("email_d");
+    }
+
+    public Contact setEmailD(String emailD){
+        set("email_d", emailD);
+        return this;
+    }
+
+    public String getEmail(){
+        return getStr("email");
+    }
+
+    public Contact setEmail(String email){
+        set("email", email);
+        return this;
+    }
+
+    public String getMobilePhoneD(){
+        return getStr("mobile_phone_d");
+    }
+
+    public Contact setMobilePhoneD(String mobilePhoneD){
+        set("mobile_phone_d", mobilePhoneD);
+        return this;
+    }
+
+    public String getOtherPhoneD(){
+        return getStr("other_phone_d");
+    }
+
+    public Contact setOtherPhoneD(String otherPhoneD){
+        set("other_phone_d", otherPhoneD);
+        return this;
+    }
+
+    public String getPhoneD(){
+        return getStr("phone_d");
+    }
+
+    public Contact setPhoneD(String phoneD){
+        set("phone_d", phoneD);
+        return this;
+    }
+
+    public String getHomePhone(){
+        return getStr("home_phone");
+    }
+
+    public Contact setHomePhone(String homePhone){
+        set("home_phone", homePhone);
+        return this;
+    }
+
+    public String getMobilePhone(){
+        return getStr("mobile_phone");
+    }
+
+    public Contact setMobilePhone(String mobilePhone){
+        set("mobile_phone", mobilePhone);
+        return this;
+    }
+
+    public String getOtherPhone(){
+        return getStr("other_phone");
+    }
+
+    public Contact setOtherPhone(String otherPhone){
+        set("other_phone", otherPhone);
+        return this;
+    }
+
+    public String getPhone(){
+        return getStr("phone");
+    }
+
+    public Contact setPhone(String Phone){
+        set("phone", Phone);
+        return this;
+    }
+
+
+    public String getSfRecordId(){
+        return getStr("sf_record_id");
+    }
+
+    public Contact setSfRecordId(String sfRecordId){
+        set("sf_record_id", sfRecordId);
+        return this;
+    }
+
+    public Contact findById(String dataId){
+        return this.dao.findFirst("select * from `" + getTableName() + "` where id=? ", dataId);
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/deloitte/system/model/LoanerApplication.java b/src/main/java/com/deloitte/system/model/LoanerApplication.java
new file mode 100644
index 0000000..ea30011
--- /dev/null
+++ b/src/main/java/com/deloitte/system/model/LoanerApplication.java
@@ -0,0 +1,122 @@
+package com.deloitte.system.model;
+
+import com.common.annotation.Table;
+import com.common.core.domain.BaseModel;
+
+@Table(tableName = "loaner_application", clazz = LoanerApplication.class)
+public class LoanerApplication extends BaseModel<LoanerApplication> {
+    public static final LoanerApplication dao = new LoanerApplication();
+
+    public Long getDataId(){
+
+        return getLong("id");
+    }
+
+    public LoanerApplication setDataId(Long dataId){
+        set("id", dataId);
+        return this;
+    }
+
+    public String getApplyPerson(){
+        return getStr("apply_person");
+    }
+
+    public LoanerApplication setApplyPerson(String applyPerson){
+        set("apply_person", applyPerson);
+        return this;
+    }
+
+    public String getApplyPersonPhone(){
+        return getStr("apply_person_phone");
+    }
+
+    public LoanerApplication setApplyPersonPhone(String applyPersonPhone){
+        set("apply_person_phone", applyPersonPhone);
+        return this;
+    }
+
+    public String getApplicantMailbox(){
+        return getStr("applicant_mailbox");
+    }
+
+    public LoanerApplication setApplicantMailbox(String applicantMailbox){
+        set("applicant_mailbox", applicantMailbox);
+        return this;
+    }
+
+    public String getLoanerReceiveStaff(){
+        return getStr("loaner_receive_staff");
+    }
+
+    public LoanerApplication setLoanerReceiveStaff(String loanerReceiveStaff){
+        set("loaner_receive_staff", loanerReceiveStaff);
+        return this;
+    }
+
+    public String getDirectShippmentAddress(){
+        return getStr("direct_shippment_address");
+    }
+
+    public LoanerApplication setdirectShippmentAddress(String directShippmentAddress){
+        set("direct_shippment_address", directShippmentAddress);
+        return this;
+    }
+
+    public String getLoanerReceiveStaffPhone(){
+        return getStr("loaner_receive_staff_phone");
+    }
+
+    public LoanerApplication setLoanerReceiveStaffPhone(String loanerReceiveStaffPhone){
+        set("loaner_receive_staff_phone", loanerReceiveStaffPhone);
+        return this;
+    }
+
+    public String getReturnTrakeStaff(){
+        return getStr("return_trake_staff");
+    }
+
+    public LoanerApplication setReturnTrakeStaff(String returnTrakeStaff){
+        set("return_trake_staff", returnTrakeStaff);
+        return this;
+    }
+
+    public String getReturnNumber(){
+        return getStr("return_number");
+    }
+
+    public LoanerApplication setReturnNumber(String returnNumber){
+        set("return_number", returnNumber);
+        return this;
+    }
+
+    public String getLoanerSer(){
+        return getStr("loaner_ser");
+    }
+
+    public LoanerApplication setLoanerSer(String loanerSer){
+        set("loaner_ser", loanerSer);
+        return this;
+    }
+
+    public String getPostCode(){
+        return getStr("post_code");
+    }
+
+    public LoanerApplication setPostCode(String postCode){
+        set("post_code", postCode);
+        return this;
+    }
+
+    public String getSfRecordId(){
+        return getStr("sf_record_id");
+    }
+
+    public LoanerApplication setSfRecordId(String sfRecordId){
+        set("sf_record_id", sfRecordId);
+        return this;
+    }
+
+    public LoanerApplication findById(String dataId){
+        return this.dao.findFirst("select * from `" + getTableName() + "` where id=? ", dataId);
+    }
+}
diff --git a/src/main/java/com/deloitte/system/model/LoanerUser.java b/src/main/java/com/deloitte/system/model/LoanerUser.java
new file mode 100644
index 0000000..3dcf1fe
--- /dev/null
+++ b/src/main/java/com/deloitte/system/model/LoanerUser.java
@@ -0,0 +1,46 @@
+package com.deloitte.system.model;
+
+
+import com.common.annotation.Table;
+import com.common.core.domain.BaseModel;
+
+@Table(tableName = "loaner_user",clazz = LoanerUser.class)
+public class LoanerUser extends BaseModel<LoanerUser> {
+    public static final LoanerUser dao =new LoanerUser();
+
+    public Long getDataId(){
+        return getLong("id");
+    }
+
+    public LoanerUser setDataId(Long dataId){
+        set("id", dataId);
+        return this;
+    }
+
+    public String getContact(){
+        return getStr("contact");
+    }
+    public LoanerUser setContact(String contact){
+        set("contact",contact);
+        return this;
+    }
+    public String getContactNumber(){
+        return getStr("contact_number");
+    }
+    public LoanerUser setContactNumber(String contactNumber){
+        set("contact_number",contactNumber);
+        return this;
+    }
+    public String getSfRecordId(){
+        return getStr("sf_record_id");
+    }
+
+    public LoanerUser setSfRecordId(String sfRecordId){
+        set("sf_record_id", sfRecordId);
+        return this;
+    }
+
+    public LoanerUser findById(String dataId){
+        return this.dao.findFirst("select * from `" + getTableName() + "` where id=? ", dataId);
+    }
+}
diff --git a/src/main/java/com/deloitte/system/model/MailMerge.java b/src/main/java/com/deloitte/system/model/MailMerge.java
new file mode 100644
index 0000000..3e92362
--- /dev/null
+++ b/src/main/java/com/deloitte/system/model/MailMerge.java
@@ -0,0 +1,340 @@
+package com.deloitte.system.model;
+
+import com.common.annotation.Table;
+import com.common.core.domain.BaseModel;
+
+import java.util.Date;
+
+@Table(tableName = "mail_merge",clazz = MailMerge.class)
+public class MailMerge extends BaseModel<MailMerge> {
+
+    public static final MailMerge dao =new MailMerge();
+
+    public Long getDataId(){
+        return getLong("id");
+    }
+
+    public MailMerge setDataId(Long dataId){
+        set("id", dataId);
+        return this;
+    }
+
+    public String getSfRecordId(){
+        return getStr("sf_record_id");
+    }
+
+    public MailMerge setSfRecordId(String sfRecordId){
+        set("sf_record_id", sfRecordId);
+        return this;
+    }
+
+    public String getName() {
+        return getStr("name");
+    }
+
+    public MailMerge setName(String name) {
+        set("name", name);
+        return this;
+    }
+
+    public String getCc() {
+        return getStr("cc");
+    }
+
+    public MailMerge setCc(String cc) {
+        set("cc", cc);
+        return this;
+    }
+
+    public String getBcc() {
+        return getStr("bcc");
+    }
+
+    public MailMerge setBcc(String bcc) {
+        set("bcc", bcc);
+        return this;
+    }
+
+    public String getAuthor() {
+        return getStr("author");
+    }
+
+    public MailMerge setAuthor(String author) {
+        set("author", author);
+        return this;
+    }
+
+    public String getAllMember() {
+        return getStr("all_member");
+    }
+
+    public MailMerge setAllMember(String allMember) {
+        set("all_member", allMember);
+        return this;
+    }
+
+    public String getAllMemberType() {
+        return getStr("all_member_type");
+    }
+
+    public MailMerge setAllMemberType(String allMemberType) {
+        set("all_member_type", allMemberType);
+        return this;
+    }
+
+    public String getToName() {
+        return getStr("to_name");
+    }
+
+    public MailMerge setToName(String toName) {
+        set("to_name", toName);
+        return this;
+    }
+
+    public String getAllMemberName() {
+        return getStr("all_member_name");
+    }
+
+    public MailMerge setAllMemberName(String allMemberName) {
+        set("all_member_name", allMemberName);
+        return this;
+    }
+
+    public String getMailType() {
+        return getStr("mail_type");
+    }
+
+    public MailMerge setMailType(String mailType) {
+        set("mail_type", mailType);
+        return this;
+    }
+
+    public String getCcName() {
+        return getStr("cc_name");
+    }
+
+    public MailMerge setCcName(String ccName) {
+        set("cc_name", ccName);
+        return this;
+    }
+
+    public String getBccName() {
+        return getStr("bcc_name");
+    }
+
+    public MailMerge setBccName(String bccName) {
+        set("bcc_name", bccName);
+        return this;
+    }
+
+    public String getType() {
+        return getStr("type");
+    }
+
+    public MailMerge setType(String type) {
+        set("type", type);
+        return this;
+    }
+
+    public String getSubject() {
+        return getStr("subject");
+    }
+
+    public MailMerge setSubject(String subject) {
+        set("subject", subject);
+        return this;
+    }
+
+    public String getSubjectCopy() {
+        return getStr("subject_copy");
+    }
+
+    public MailMerge setSubjectCopy(String subjectCopy) {
+        set("subject_copy", subjectCopy);
+        return this;
+    }
+
+    public String getRecord() {
+        return getStr("record");
+    }
+
+    public MailMerge setRecord(String record) {
+        set("record", record);
+        return this;
+    }
+
+    public String getRecordType() {
+        return getStr("record_type");
+    }
+
+    public MailMerge setRecordType(String recordType) {
+        set("record_type", recordType);
+        return this;
+    }
+
+    public String getRecipient() {
+        return getStr("recipient");
+    }
+
+    public MailMerge setRecipient(String recipient) {
+        set("recipient", recipient);
+        return this;
+    }
+
+    public String getPremaryRecipient() {
+        return getStr("premary_recipient");
+    }
+
+    public MailMerge setPremaryRecipient(String premaryRecipient) {
+        set("premary_recipient", premaryRecipient);
+        return this;
+    }
+
+    public String getFiles() {
+        return getStr("files");
+    }
+
+    public MailMerge setFiles(String files) {
+        set("files", files);
+        return this;
+    }
+
+    public String getEmalSent() {
+        return getStr("emal_sent");
+    }
+
+    public MailMerge setEmalSent(String emalSent) {
+        set("emal_sent", emalSent);
+        return this;
+    }
+
+    public String getEmailSent() {
+        return getStr("email_sent");
+    }
+
+    public MailMerge setEmailSent(String emailSent) {
+        set("email_sent", emailSent);
+        return this;
+    }
+
+    public String getCurrencyIsoCode() {
+        return getStr("currency_iso_code");
+    }
+
+    public MailMerge setCurrencyIsoCode(String currencyIsoCode) {
+        set("currency_iso_code", currencyIsoCode);
+        return this;
+    }
+
+    public String getInternalOnly() {
+        return getStr("internal_only");
+    }
+
+    public MailMerge setInternalOnly(String internalOnly) {
+        set("internal_only", internalOnly);
+        return this;
+    }
+
+    public String getOwnerId() {
+        return getStr("owner_id");
+    }
+
+    public MailMerge setOwnerId(String ownerId) {
+        set("owner_id", ownerId);
+        return this;
+    }
+
+    public String getLastModifiedById() {
+        return getStr("last_modified_by_id");
+    }
+
+    public MailMerge setLastModifiedById(String lastModifiedById) {
+        set("last_modified_by_id", lastModifiedById);
+        return this;
+    }
+
+    public String getCreatedById() {
+        return getStr("created_by_id");
+    }
+
+    public MailMerge setCreatedById(String createdById) {
+        set("created_by_id", createdById);
+        return this;
+    }
+
+    public String getSwo() {
+        return getStr("swo");
+    }
+
+    public MailMerge setSwo(String swo) {
+        set("swo", swo);
+        return this;
+    }
+
+    public String getQuotes() {
+        return getStr("quotes");
+    }
+
+    public MailMerge setQuotes(String quotes) {
+        set("quotes", quotes);
+        return this;
+    }
+
+    public String getSend() {
+        return getStr("send");
+    }
+
+    public MailMerge setSend(String send) {
+        set("send", send);
+        return this;
+    }
+
+    public String getCaseF() {
+        return getStr("case_f");
+    }
+
+    public MailMerge setCaseF(String caseF) {
+        set("case_f", caseF);
+        return this;
+    }
+
+    public String getFrom() {
+        return getStr("from");
+    }
+
+    public MailMerge setFrom(String from) {
+        set("from", from);
+        return this;
+    }
+
+    public Date getDate() {
+        return getDate("date");
+    }
+
+    public MailMerge setDate(Date date) {
+        set("date", date);
+        return this;
+    }
+
+    public String getMessage() {
+        return getStr("message");
+    }
+
+    public MailMerge setMessage(String message) {
+        set("message", message);
+        return this;
+    }
+
+    public String getSfFileAddressId() {
+        return getStr("sf_file_address_id");
+    }
+
+    public MailMerge setSfFileAddressId(String sfFileAddressId) {
+        set("sf_file_address_id", sfFileAddressId);
+        return this;
+    }
+
+    public MailMerge findById(String dataId){
+        return this.dao.findFirst("select * from `" + getTableName() + "` where id=? ", dataId);
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/deloitte/system/model/Opportunity.java b/src/main/java/com/deloitte/system/model/Opportunity.java
new file mode 100644
index 0000000..464ab4e
--- /dev/null
+++ b/src/main/java/com/deloitte/system/model/Opportunity.java
@@ -0,0 +1,98 @@
+package com.deloitte.system.model;
+
+import com.common.annotation.Table;
+import com.common.core.domain.BaseModel;
+
+@Table(tableName = "opportunity", clazz = Opportunity.class)
+public class Opportunity extends BaseModel<Opportunity> {
+    public static final Opportunity dao=new Opportunity();
+
+    public Long getDataId(){
+
+        return getLong("id");
+    }
+
+    public Opportunity setDataId(Long dataId) {
+        set("id", dataId);
+        return this;
+    }
+
+    public String getDealerServiceD(){
+        return getStr("dealer_service_d");
+    }
+
+    public Opportunity setDealerServiceD(String dealerServiceD){
+        set("dealer_service_d", dealerServiceD);
+        return this;
+    }
+
+    public String getDealerService(){
+        return getStr("dealer_service");
+    }
+
+    public Opportunity setDealerService(String dealerService){
+        set("dealer_service", dealerService);
+        return this;
+    }
+
+    public String getDealerSalesStaffNameD(){
+        return getStr("dealer_sales_staff_name_d");
+    }
+
+    public Opportunity setDealerSalesStaffNameD(String dealerSalesStaffNameD){
+        set("dealer_sales_staff_name_d", dealerSalesStaffNameD);
+        return this;
+    }
+
+    public String getDealerSalesStaffName(){
+        return getStr("dealer_sales_staff_name");
+    }
+
+    public Opportunity setDealerSalesStaffName(String dealerSalesStaffName){
+        set("dealer_sales_staff_name", dealerSalesStaffName);
+        return this;
+    }
+
+
+    public String getExpectedDeliveryDate(){
+        return getStr("expected_delivery_date");
+    }
+
+    public Opportunity setExpectedDeliveryDate(String expectedDeliveryDate){
+        set("expected_delivery_date", expectedDeliveryDate);
+        return this;
+    }
+
+    public String getSalesAccountCode(){
+        return getStr("sales_account_code");
+    }
+
+    public Opportunity setSalesAccountCode(String salesAccountCode){
+        set("sales_account_code", salesAccountCode);
+        return this;
+    }
+
+    public String getSpecialDeliveryAddress(){
+        return getStr("special_delivery_address");
+    }
+
+    public Opportunity setSpecialDeliveryAddress(String specialDeliveryAddress){
+        set("special_delivery_address", specialDeliveryAddress);
+        return this;
+    }
+
+    public String getSfRecordId(){
+        return getStr("sf_record_id");
+    }
+
+    public Opportunity setSfRecordId(String sfRecordId){
+        set("sf_record_id", sfRecordId);
+        return this;
+    }
+
+    public Opportunity findById(String dataId){
+        return this.dao.findFirst("select * from `" + getTableName() + "` where id=? ", dataId);
+    }
+
+
+}
diff --git a/src/main/java/com/deloitte/system/model/Order.java b/src/main/java/com/deloitte/system/model/Order.java
new file mode 100644
index 0000000..5e964b5
--- /dev/null
+++ b/src/main/java/com/deloitte/system/model/Order.java
@@ -0,0 +1,402 @@
+package com.deloitte.system.model;
+
+import com.common.annotation.Table;
+import com.common.core.domain.BaseModel;
+
+@Table(tableName = "order", clazz = Order.class)
+public class Order extends BaseModel<Order> {
+    public static final Order dao = new Order();
+
+    public Long getDataId(){
+
+        return getLong("id");
+    }
+
+    public Order setDataId(Long dataId){
+        set("id", dataId);
+        return this;
+    }
+
+    public String getSpecialDeliveryPhone(){
+        return getStr("special_delivery_phone");
+    }
+
+    public Order setSpecialDeliveryPhone(String specialDeliveryPhone){
+        set("special_delivery_phone", specialDeliveryPhone);
+        return this;
+    }
+
+    public String getSpecialDeliveryPhoneD(){
+        return getStr("special_delivery_phone_d");
+    }
+
+    public Order setSpecialDeliveryPhoneD(String specialDeliveryPhoneD){
+        set("special_delivery_phone_d", specialDeliveryPhoneD);
+        return this;
+    }
+
+    public String getShippingRecieverEmailAdr(){
+        return getStr("shipping_reciever_email_adr");
+    }
+
+    public Order setShippingRecieverEmailAdr(String shippingRecieverEmailAdr){
+        set("shipping_reciever_email_adr", shippingRecieverEmailAdr);
+        return this;
+    }
+
+    public String getShipToContactId(){
+        return getStr("ship_to_contact_id");
+    }
+
+    public Order setShipToContactId(String shipToContactId){
+        set("ship_to_contact_id", shipToContactId);
+        return this;
+    }
+
+    public String getCustomerAuthorizedById(){
+        return getStr("customer_authorized_by_id");
+    }
+
+    public Order setCustomerAuthorizedById(String customerAuthorizedById){
+        set("customer_authorized_by_id", customerAuthorizedById);
+        return this;
+    }
+
+    public String getBillToContactId(){
+        return getStr("bill_to_contact_id");
+    }
+
+    public Order setBillToContactId(String billToContactId){
+        set("bill_to_contact_id", billToContactId);
+        return this;
+    }
+
+    public String getSpecialDeliveryContact2(){
+        return getStr("special_delivery_contact2");
+    }
+
+    public Order setSpecialDeliveryContact2(String specialDeliveryContact2){
+        set("special_delivery_contact2", specialDeliveryContact2);
+        return this;
+    }
+
+    public String getSpecialDeliveryContactText(){
+        return getStr("special_delivery_contact_text");
+    }
+
+    public Order setSpecialDeliveryContactText(String specialDeliveryContactText){
+        set("special_delivery_contact_text", specialDeliveryContactText);
+        return this;
+    }
+
+    public String getShippingAddressText(){
+        return getStr("shipping_address_text");
+    }
+
+    public Order setShippingAddressText(String shippingAddressText){
+        set("shipping_address_text", shippingAddressText);
+        return this;
+    }
+
+    public String getSpecialDeliveryContact2D(){
+        return getStr("special_delivery_contact2_d");
+    }
+
+    public Order setSpecialDeliveryContact2D(String specialDeliveryContact2D){
+        set("special_delivery_contact2_d", specialDeliveryContact2D);
+        return this;
+    }
+
+    public String getEndUser(){
+        return getStr("end_user");
+    }
+
+    public Order setEndUser(String endUser){
+        set("end_user", endUser);
+        return this;
+    }
+
+    public String getEndUserD(){
+        return getStr("end_user_d");
+    }
+
+    public Order setEndUserD(String endUserD){
+        set("end_user_d", endUserD);
+        return this;
+    }
+
+    public String getSpecialDeliveryContact(){
+        return getStr("special_delivery_contact");
+    }
+
+    public Order setSpecialDeliveryContact(String specialDeliveryContact){
+        set("special_delivery_contact", specialDeliveryContact);
+        return this;
+    }
+
+    public String getSpecialDeliveryContactD(){
+        return getStr("special_delivery_contact_d");
+    }
+
+    public Order setSpecialDeliveryContactD(String specialDeliveryContactD){
+        set("special_delivery_contact_d", specialDeliveryContactD);
+        return this;
+    }
+
+    public String getPdfNNotifyParty(){
+        return getStr("pdf_n_notify_party");
+    }
+
+    public Order setPdfNNotifyParty(String pdfNNotifyParty){
+        set("pdf_n_notify_party", pdfNNotifyParty);
+        return this;
+    }
+
+    public String getPdfNFax(){
+        return getStr("pdf_n_fax");
+    }
+
+    public Order setPdfNFax(String pdfNFax){
+        set("pdf_n_fax", pdfNFax);
+        return this;
+    }
+
+    public String getPdfNContact(){
+        return getStr("pdf_n_contact");
+    }
+
+    public Order setPdfNContact(String pdfNContact){
+        set("pdf_n_contact", pdfNContact);
+        return this;
+    }
+
+    public String getPdfSTel(){
+        return getStr("pdf_s_tel");
+    }
+
+    public Order setPdfSTel(String pdfSTel){
+        set("pdf_s_tel", pdfSTel);
+        return this;
+    }
+
+    public String getPdfSPhone(){
+        return getStr("pdf_s_phone");
+    }
+
+    public Order setPdfSPhone(String pdfSPhone){
+        set("pdf_s_phone", pdfSPhone);
+        return this;
+    }
+
+    public String getPdfSName(){
+        return getStr("pdf_s_name");
+    }
+
+    public Order setPdfSName(String pdfSName){
+        set("pdf_s_name", pdfSName);
+        return this;
+    }
+
+    public String getPdfSFax(){
+        return getStr("pdf_s_fax");
+    }
+
+    public Order setPdfSFax(String pdfSFax){
+        set("pdf_s_fax", pdfSFax);
+        return this;
+    }
+
+    public String getPdfFTel(){
+        return getStr("pdf_f_tel");
+    }
+
+    public Order setPdfFTel(String pdfFTel){
+        set("pdf_f_tel", pdfFTel);
+        return this;
+    }
+
+    public String getPdfFFax(){
+        return getStr("pdf_f_fax");
+    }
+
+    public Order setPdfFFax(String pdfFFax){
+        set("pdf_f_fax", pdfFFax);
+        return this;
+    }
+
+    public String getPdfFContactPerson(){
+        return getStr("pdf_f_contact_person");
+    }
+
+    public Order setPdfFContactPerson(String pdfFContactPerson){
+        set("pdf_f_contact_person", pdfFContactPerson);
+        return this;
+    }
+
+    public String getPdfSAdds(){
+        return getStr("pdf_s_adds");
+    }
+
+    public Order setPdfSAdds(String pdfSAdds){
+        set("pdf_s_adds", pdfSAdds);
+        return this;
+    }
+
+    public String getPdfSAddress(){
+        return getStr("pdf_s_address");
+    }
+
+    public Order setPdfSAddress(String pdfSAddress){
+        set("pdf_s_address", pdfSAddress);
+        return this;
+    }
+
+    public String getPdfSeller(){
+        return getStr("pdf_seller");
+    }
+
+    public Order setPdfSeller(String pdfSeller){
+        set("pdf_seller", pdfSeller);
+        return this;
+    }
+
+    public String getPdfCTheconsigne(){
+        return getStr("pdf_c_theconsigne");
+    }
+
+    public Order setPdfCTheconsigne(String pdfCTheconsigne){
+        set("pdf_c_theconsigne", pdfCTheconsigne);
+        return this;
+    }
+
+    public String getPdfCTel(){
+        return getStr("pdf_c_tel");
+    }
+
+    public Order setPdfCTel(String pdfCTel){
+        set("pdf_c_tel", pdfCTel);
+        return this;
+    }
+
+    public String getPdfCFax(){
+        return getStr("pdf_c_fax");
+    }
+
+    public Order setPdfCFax(String pdfCFax){
+        set("pdf_c_fax", pdfCFax);
+        return this;
+    }
+
+    public String getPdfCConsignee(){
+        return getStr("pdf_c_consignee");
+    }
+
+    public Order setPdfCConsignee(String pdfCConsignee){
+        set("pdf_c_consignee", pdfCConsignee);
+        return this;
+    }
+
+    public String getPdfCContact(){
+        return getStr("pdf_c_contact");
+    }
+
+    public Order setPdfCContact(String pdfCContact){
+        set("pdf_c_contact", pdfCContact);
+        return this;
+    }
+
+    public String getPdfCAddr(){
+        return getStr("pdf_c_addr");
+    }
+
+    public Order setPdfCAddr(String pdfCAddr){
+        set("pdf_c_addr", pdfCAddr);
+        return this;
+    }
+
+    public String getSpecialDeliveryAddress(){
+        return getStr("special_delivery_address");
+    }
+
+    public Order setSpecialDeliveryAddress(String specialDeliveryAddress){
+        set("special_delivery_address", specialDeliveryAddress);
+        return this;
+    }
+
+    public String getSpecialDeliveryAddressD(){
+        return getStr("special_delivery_address_d");
+    }
+
+    public Order setSpecialDeliveryAddressD(String specialDeliveryAddressD){
+        set("special_delivery_address_d", specialDeliveryAddressD);
+        return this;
+    }
+
+    public String getDealerSalesStaffNameA(){
+        return getStr("dealer_sales_staff_name_a");
+    }
+
+    public Order setDealerSalesStaffNameA(String dealerSalesStaffNameA){
+        set("dealer_sales_staff_name_a", dealerSalesStaffNameA);
+        return this;
+    }
+
+    public String getPdfSignTitle(){
+        return getStr("pdf_sign_title");
+    }
+
+    public Order setPdfSignTitle(String pdfSignTitle){
+        set("pdf_sign_title", pdfSignTitle);
+        return this;
+    }
+
+    public String getPdfSignName(){
+        return getStr("pdf_sign_name");
+    }
+
+    public Order setPdfSignName(String pdfSignName){
+        set("pdf_sign_name", pdfSignName);
+        return this;
+    }
+
+    public String getPdfSignaturePlaces(){
+        return getStr("pdf_signature_places");
+    }
+
+    public Order setPdfSignaturePlaces(String pdfSignaturePlaces){
+        set("pdf_signature_places", pdfSignaturePlaces);
+        return this;
+    }
+
+    public String getPdfByTel(){
+        return getStr("pdf_by_tel");
+    }
+
+    public Order setPdfByTel(String pdfByTel){
+        set("pdf_by_tel", pdfByTel);
+        return this;
+    }
+
+    public String getPdfByAdd(){
+        return getStr("pdf_by_add");
+    }
+
+    public Order setPdfByAdd(String pdfByAdd){
+        set("pdf_by_add", pdfByAdd);
+        return this;
+    }
+
+    public String getSfRecordId(){
+        return getStr("sf_record_id");
+    }
+
+    public Order setSfRecordId(String sfRecordId){
+        set("sf_record_id", sfRecordId);
+        return this;
+    }
+
+    public Order findById(String dataId){
+        return this.dao.findFirst("select * from `" + getTableName() + "` where id=? ", dataId);
+    }
+
+}
diff --git a/src/main/java/com/deloitte/system/model/Quotes.java b/src/main/java/com/deloitte/system/model/Quotes.java
new file mode 100644
index 0000000..9f7836f
--- /dev/null
+++ b/src/main/java/com/deloitte/system/model/Quotes.java
@@ -0,0 +1,90 @@
+package com.deloitte.system.model;
+
+import com.common.annotation.Table;
+import com.common.core.domain.BaseModel;
+
+@Table(tableName = "quotes",clazz = Quotes.class)
+public class Quotes extends BaseModel<Quotes> {
+    public static final Quotes dao =new Quotes();
+
+    public Long getDataId(){
+        return getLong("id");
+    }
+    public Quotes setDataId(Long dataId){
+        set("id", dataId);
+        return this;
+    }
+    public String getContactName(){
+        return getStr("contact_name");
+    }
+    public Quotes setContactName(String contactName){
+        set("contact_name",contactName);
+        return this;
+    }
+    public String getContactPhone(){
+        return getStr("contact_phone");
+    }
+    public Quotes setContactPhone(String contactPhone){
+        set("contact_phone",contactPhone);
+        return this;
+    }
+    public String getContactFax(){
+        return getStr("contact_fax");
+    }
+    public Quotes setContactFax(String contactFax){
+        set("contact_fax",contactFax);
+        return this;
+    }
+    public String getContactEmail(){
+        return getStr("contact_email");
+    }
+    public Quotes setContactEmail(String contactEmail){
+        set("contact_email",contactEmail);
+        return this;
+    }
+    public String getBillTo(){
+        return getStr("bill_to");
+    }
+    public Quotes setBllTo(String billTo){
+        set("bill_to",billTo);
+        return this;
+    }
+    public String getShipTo(){
+        return getStr("ship_to");
+    }
+    public Quotes setShipTo(String shipTo ){
+        set("ship_to",shipTo);
+        return this;
+    }
+    public String getAuthor(){
+        return getStr("author");
+    }
+    public Quotes setAuthor(String author){
+        set("author",author);
+        return this;
+    }
+    public String getMessage(){
+        return getStr("message");
+    }
+    public Quotes setMessage(String message){
+        set("message",message);
+        return this;
+    }
+    public String getPrimaryRecipient(){
+        return getStr("primaryRecipient");
+    }
+    public Quotes setPrimaryRecipient(String primaryRecipient){
+        set("primary_recipient",primaryRecipient);
+        return this;
+    }
+    public String getSfRecordId(){
+        return getStr("sf_record_id");
+    }
+    public Quotes setSfRecordId(String sfRecordId){
+        set("sf_record_id", sfRecordId);
+        return this;
+    }
+    public Quotes findById(String dataId){
+        return this.dao.findFirst("select * from " + getTableName() + " where id=? ", dataId);
+    }
+}
diff --git a/src/main/java/com/deloitte/system/model/Repair.java b/src/main/java/com/deloitte/system/model/Repair.java
new file mode 100644
index 0000000..5ca1d68
--- /dev/null
+++ b/src/main/java/com/deloitte/system/model/Repair.java
@@ -0,0 +1,52 @@
+package com.deloitte.system.model;
+
+import com.common.annotation.Table;
+import com.common.core.domain.BaseModel;
+
+@Table(tableName = "repair", clazz = Repair.class)
+public class Repair extends BaseModel<Repair>{
+    public static final Repair dao = new Repair();
+
+    public Long getDataId(){
+
+        return getLong("id");
+    }
+
+    public Repair setDataId(Long dataId){
+        set("id", dataId);
+        return this;
+    }
+
+    public String getTelephonen(){
+        return getStr("telephonen");
+    }
+
+    public Repair setTelephonen(String telephonen){
+        set("telephonen", telephonen);
+        return this;
+    }
+
+
+    public String getContactD(){
+        return getStr("contact_d");
+    }
+
+    public Repair setContactD(String contactD){
+        set("contact_d", contactD);
+        return this;
+    }
+
+
+    public String getSfRecordId(){
+        return getStr("sf_record_id");
+    }
+
+    public Repair setSfRecordId(String sfRecordId){
+        set("sf_record_id", sfRecordId);
+        return this;
+    }
+
+    public Repair findById(String dataId){
+        return this.dao.findFirst("select * from `" + getTableName() + "` where id=? ", dataId);
+    }
+}
diff --git a/src/main/java/com/deloitte/system/model/Swo.java b/src/main/java/com/deloitte/system/model/Swo.java
new file mode 100644
index 0000000..c8a9c74
--- /dev/null
+++ b/src/main/java/com/deloitte/system/model/Swo.java
@@ -0,0 +1,119 @@
+package com.deloitte.system.model;
+
+import com.common.annotation.Table;
+import com.common.core.domain.BaseModel;
+
+@Table(tableName = "swo",clazz = Swo.class)
+public class Swo extends BaseModel<Swo> {
+    public static final Swo dao= new Swo();
+
+    public Long getDataId(){
+        return getLong("id");
+    }
+
+    public Swo setDataId(Long dataId){
+        set("id", dataId);
+        return this;
+    }
+    public String getContactNameHidden(){
+        return getStr("contact_name_hidden");
+    }
+    public Swo setContactNameHidden(String contactNameHidden){
+        set("contact_name_hidden",contactNameHidden);
+        return this;
+    }
+    public String getEmail(){
+        return getStr("email");
+    }
+    public Swo setEmail(String email){
+        set("email",email);
+        return this;
+    }
+    public String getContact(){
+        return getStr("contact");
+    }
+    public Swo setContact(String contact){
+        set("contact",contact);
+        return this;
+    }
+    public String getAuthor(){
+        return getStr("author");
+    }
+    public Swo setAuthor(String author){
+        set("author",author);
+        return this;
+    }
+    public String getMessage(){
+        return getStr("message");
+    }
+    public Swo setMessage(String message){
+        set("message",message);
+        return this;
+    }
+    public String getPrimaryRecipient(){
+        return getStr("primary_recipient");
+    }
+    public Swo setPrimaryRecipient(String primaryRecipient){
+        set("primary_recipient",primaryRecipient);
+        return this;
+    }
+    public String getSend(){
+        return getStr("send");
+    }
+    public Swo setSend(String send){
+        set("send",send);
+        return this;
+    }
+    public String getCc(){
+        return getStr("cc");
+    }
+    public Swo setCc(String cc){
+        set("cc",cc);
+        return this;
+    }
+    public String getCcName(){
+        return get("cc_name");
+    }
+    public Swo setCcName(String ccName){
+        set("cc_name",ccName);
+        return this;
+    }
+    public String getBcc(){
+        return getStr("bcc");
+    }
+    public Swo setBcc(String bcc){
+        set("bcc",bcc);
+        return this;
+    }
+    public String getBccName(){
+        return getStr("bcc_name");
+    }
+    public Swo setBccName(String bccName){
+        set("bcc_name",bccName);
+        return this;
+    }
+    public String getRecipient(){
+        return getStr("recipient");
+    }
+    public Swo setRecipient(String recipient){
+        set("recipient",recipient);
+        return this;
+    }
+    public String getToName(){
+        return getStr("to_name");
+    }
+    public Swo setToName(String toName){
+        set("to_name",toName);
+        return this;
+    }
+    public String getSfRecordId(){
+        return getStr("sf_record_id");
+    }
+    public Swo setSfRecordId(String sfRecordId){
+        set("sf_record_id", sfRecordId);
+        return this;
+    }
+    public Swo findById(String dataId){
+        return this.dao.findFirst("select * from `" + getTableName() + "` where id=? ", dataId);
+    }
+}
diff --git a/src/main/java/com/deloitte/system/model/SysLog.java b/src/main/java/com/deloitte/system/model/SysLog.java
new file mode 100644
index 0000000..409a698
--- /dev/null
+++ b/src/main/java/com/deloitte/system/model/SysLog.java
@@ -0,0 +1,29 @@
+package com.deloitte.system.model;
+
+import com.common.annotation.Table;
+import com.common.core.domain.BaseModel;
+
+
+/**
+ * @author 寤栨尟閽�
+ * @date 2022-01-14
+ */
+@Table(tableName="sys_log", clazz = SysLog.class)
+public class SysLog extends BaseModel<SysLog> {
+    public final static SysLog dao = new SysLog();
+
+    public SysLog ip(String ip){
+        set("ip", ip);
+        return this;
+    }
+
+    public SysLog uri(String uri){
+        set("uri", uri);
+        return this;
+    }
+
+    public SysLog retContent(String retContent){
+        set("ret_content", retContent);
+        return this;
+    }
+}
diff --git a/src/main/java/com/deloitte/system/model/TSRepair.java b/src/main/java/com/deloitte/system/model/TSRepair.java
new file mode 100644
index 0000000..8736ad4
--- /dev/null
+++ b/src/main/java/com/deloitte/system/model/TSRepair.java
@@ -0,0 +1,49 @@
+package com.deloitte.system.model;
+
+import com.common.annotation.Table;
+import com.common.core.domain.BaseModel;
+
+@Table(tableName = "ts_repair",clazz = TSRepair.class)
+public class TSRepair extends BaseModel<TSRepair> {
+    public static final TSRepair dao =new TSRepair();
+
+    public Long getDataId(){
+        return getLong("id");
+    }
+
+    public TSRepair setDataId(Long dataId){
+        set("id", dataId);
+        return this;
+    }
+    public String getBusinessAContact(){
+        return getStr("business_a_contact");
+    }
+
+    public TSRepair setBusinessAContact(String businessAContact){
+        set("business_A_contact", businessAContact);
+        return this;
+    }
+
+    public String getBusinessAPhone(){
+        return getStr("business_a_phone");
+    }
+
+    public TSRepair setBusinessAPhone(String businessAPhone){
+        set("business_a_phone",businessAPhone);
+        return this;
+    }
+
+    public String getSfRecordId(){
+        return getStr("sf_record_id");
+    }
+
+    public TSRepair setSfRecordId(String sfRecordId){
+        set("sf_record_id", sfRecordId);
+        return this;
+    }
+
+    public TSRepair findById(String dataId){
+        return this.dao.findFirst("select * from `" + getTableName() + "` where id=? ", dataId);
+    }
+
+}
diff --git a/src/main/java/com/deloitte/system/model/UserFaultInfo.java b/src/main/java/com/deloitte/system/model/UserFaultInfo.java
new file mode 100644
index 0000000..36a5379
--- /dev/null
+++ b/src/main/java/com/deloitte/system/model/UserFaultInfo.java
@@ -0,0 +1,61 @@
+package com.deloitte.system.model;
+
+import com.common.annotation.Table;
+import com.common.core.domain.BaseModel;
+
+@Table(tableName = "user_fault_info",clazz = UserFaultInfo.class)
+public class UserFaultInfo extends BaseModel<UserFaultInfo> {
+
+    public static  final UserFaultInfo dao =new UserFaultInfo();
+
+    public Long getDataId(){
+
+        return getLong("id");
+    }
+
+    public UserFaultInfo setDataId(Long dataId){
+        set("id", dataId);
+        return this;
+    }
+
+    public String getUfContact(){
+        return getStr("uf_contact");
+    }
+
+    public UserFaultInfo setUfContact(String ufContact){
+        set("uf_contact",ufContact);
+        return this;
+    }
+
+    public String getInboundEmailAddress(){
+        return getStr("inbound_email_address");
+    }
+    public UserFaultInfo setInboundEmailAddress(String inboundEmailAddress){
+        set("inbound_email_address",inboundEmailAddress);
+        return this;
+    }
+
+    public String getUfPhone(){
+        return getStr("uf_phone");
+    }
+
+    public UserFaultInfo setUfPhone(String ufPhone){
+        set("uf_phone",ufPhone);
+        return this;
+    }
+
+    public String getSfRecordId(){
+        return getStr("sf_record_id");
+    }
+
+    public UserFaultInfo setSfRecordId(String sfRecordId){
+        set("sf_record_id", sfRecordId);
+        return this;
+    }
+
+    public UserFaultInfo findById(String dataId){
+        return this.dao.findFirst("select * from `" + getTableName() + "` where id=? ", dataId);
+    }
+
+
+}
diff --git a/src/main/java/com/deloitte/system/request/CampaignUserAllDto.java b/src/main/java/com/deloitte/system/request/CampaignUserAllDto.java
new file mode 100644
index 0000000..d83cf5c
--- /dev/null
+++ b/src/main/java/com/deloitte/system/request/CampaignUserAllDto.java
@@ -0,0 +1,40 @@
+package com.deloitte.system.request;
+
+import com.common.annotation.DesensitiveInfo;
+import com.common.core.domain.DesensitiveType;
+import com.opencsv.bean.CsvBindByName;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class CampaignUserAllDto {
+    private String dataId;
+    @CsvBindByName(column = "deptName")
+    private String deptName;
+    @CsvBindByName(column = "productDemand")
+    private String productDemand;
+    @CsvBindByName(column = "province")
+    private String province;
+    @CsvBindByName(column = "remarks")
+    private String remarks;
+    @CsvBindByName(column = "time")
+    private String time;
+    private String exhibition;
+
+    @CsvBindByName(column = "name")
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String name;
+    @CsvBindByName(column = "email")
+    @DesensitiveInfo(DesensitiveType.EMAIL)
+    private String email;
+    @CsvBindByName(column = "phone")
+    @DesensitiveInfo(DesensitiveType.MOBILE_PHONE)
+    private String phone;
+
+    private String nameEncrypt;
+    private String emailEncrypt;
+    private String phoneEncrypt;
+}
diff --git a/src/main/java/com/deloitte/system/request/CampaignUserDto.java b/src/main/java/com/deloitte/system/request/CampaignUserDto.java
new file mode 100644
index 0000000..2aaacbf
--- /dev/null
+++ b/src/main/java/com/deloitte/system/request/CampaignUserDto.java
@@ -0,0 +1,27 @@
+package com.deloitte.system.request;
+
+import com.common.annotation.DesensitiveInfo;
+import com.common.core.domain.DesensitiveType;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class CampaignUserDto {
+    private String dataId;
+    private Integer isDelete;
+    private String sfRecordId;
+
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String name;
+    @DesensitiveInfo(DesensitiveType.EMAIL)
+    private String email;
+    @DesensitiveInfo(DesensitiveType.MOBILE_PHONE)
+    private String phone;
+
+    private String nameEncrypt;
+    private String emailEncrypt;
+    private String phoneEncrypt;
+}
diff --git a/src/main/java/com/deloitte/system/request/ContactDto.java b/src/main/java/com/deloitte/system/request/ContactDto.java
new file mode 100644
index 0000000..4e6a2e2
--- /dev/null
+++ b/src/main/java/com/deloitte/system/request/ContactDto.java
@@ -0,0 +1,96 @@
+package com.deloitte.system.request;
+
+
+import com.common.annotation.DesensitiveInfo;
+import com.common.core.domain.DesensitiveType;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class ContactDto {
+    private String dataId;
+    private Integer isDelete;
+    private String sfRecordId;
+
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String firstName;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String lastName;
+    @DesensitiveInfo(DesensitiveType.CNAPS_CODE)
+    private String postcode;
+    @DesensitiveInfo(DesensitiveType.CNAPS_CODE)
+    private String postcodeD;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String titleD;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String title;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String contactEnglishName;
+    @DesensitiveInfo(DesensitiveType.ADDRESS)
+    private String englishAddress;
+    @DesensitiveInfo(DesensitiveType.ADDRESS)
+    private String address1;
+    @DesensitiveInfo(DesensitiveType.ADDRESS)
+    private String address2;
+    @DesensitiveInfo(DesensitiveType.ADDRESS)
+    private String address3;
+    @DesensitiveInfo(DesensitiveType.ADDRESS)
+    private String address1D;
+    @DesensitiveInfo(DesensitiveType.ADDRESS)
+    private String address2D;
+    @DesensitiveInfo(DesensitiveType.ADDRESS)
+    private String address3D;
+    @DesensitiveInfo(DesensitiveType.BASIC)
+    private String fax;
+    @DesensitiveInfo(DesensitiveType.BASIC)
+    private String faxD;
+    @DesensitiveInfo(DesensitiveType.EMAIL)
+    private String emailD;
+    @DesensitiveInfo(DesensitiveType.EMAIL)
+    private String email;
+    @DesensitiveInfo(DesensitiveType.MOBILE_PHONE)
+    private String mobilePhoneD;
+    @DesensitiveInfo(DesensitiveType.MOBILE_PHONE)
+    private String otherPhoneD;
+    @DesensitiveInfo(DesensitiveType.MOBILE_PHONE)
+    private String phoneD;
+    @DesensitiveInfo(DesensitiveType.MOBILE_PHONE)
+    private String homePhone;
+    @DesensitiveInfo(DesensitiveType.MOBILE_PHONE)
+    private String mobilePhone;
+    @DesensitiveInfo(DesensitiveType.MOBILE_PHONE)
+    private String otherPhone;
+    @DesensitiveInfo(DesensitiveType.MOBILE_PHONE)
+    private String phone;
+
+
+    private String firstNameEncrypt;
+    private String lastNameEncrypt;
+    private String postcodeEncrypt;
+    private String postcodeDEncrypt;
+    private String titleDEncrypt;
+    private String titleEncrypt;
+    private String contactEnglishNameEncrypt;
+    private String englishAddressEncrypt;
+    private String address1Encrypt;
+    private String address2Encrypt;
+    private String address3Encrypt;
+    private String address1DEncrypt;
+    private String address2DEncrypt;
+    private String address3DEncrypt;
+    private String faxEncrypt;
+    private String faxDEncrypt;
+    private String emailDEncrypt;
+    private String emailEncrypt;
+    private String mobilePhoneDEncrypt;
+    private String otherPhoneDEncrypt;
+    private String phoneDEncrypt;
+    private String homePhoneEncrypt;
+    private String mobilePhoneEncrypt;
+    private String otherPhoneEncrypt;
+    private String phoneEncrypt;
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/deloitte/system/request/ContactSearchDto.java b/src/main/java/com/deloitte/system/request/ContactSearchDto.java
new file mode 100644
index 0000000..f2f6915
--- /dev/null
+++ b/src/main/java/com/deloitte/system/request/ContactSearchDto.java
@@ -0,0 +1,16 @@
+package com.deloitte.system.request;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class ContactSearchDto {
+    private List<String> dataIds;
+    private String contactName;
+}
\ No newline at end of file
diff --git a/src/main/java/com/deloitte/system/request/FileRequest.java b/src/main/java/com/deloitte/system/request/FileRequest.java
new file mode 100644
index 0000000..18d0614
--- /dev/null
+++ b/src/main/java/com/deloitte/system/request/FileRequest.java
@@ -0,0 +1,22 @@
+package com.deloitte.system.request;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * @Author holfeng
+ * @Date 11:38 11/02/2022
+ * @Version 1.0
+ **/
+
+@Data
+public class FileRequest {
+
+    @NotNull(message = "鏂囦欢涓嶈兘涓虹┖")
+    private String file;
+    @NotNull(message = "鏂囦欢澶у皬涓嶈兘涓虹┖")
+    private Integer size;
+    @NotNull(message = "鏂囦欢鍚嶄笉鑳戒负绌�")
+    private String fileName;
+}
diff --git a/src/main/java/com/deloitte/system/request/LoanerApplicationDto.java b/src/main/java/com/deloitte/system/request/LoanerApplicationDto.java
new file mode 100644
index 0000000..4a31384
--- /dev/null
+++ b/src/main/java/com/deloitte/system/request/LoanerApplicationDto.java
@@ -0,0 +1,50 @@
+package com.deloitte.system.request;
+
+
+import com.common.annotation.DesensitiveInfo;
+import com.common.core.domain.DesensitiveType;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class LoanerApplicationDto {
+    private String dataId;
+    private Integer isDelete;
+    private String sfRecordId;
+
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String applyPerson;
+    @DesensitiveInfo(DesensitiveType.MOBILE_PHONE)
+    private String applyPersonPhone;
+    @DesensitiveInfo(DesensitiveType.EMAIL)
+    private String applicantMailbox;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String loanerReceiveStaff;
+    @DesensitiveInfo(DesensitiveType.ADDRESS)
+    private String directShippmentAddress;
+    @DesensitiveInfo(DesensitiveType.MOBILE_PHONE)
+    private String loanerReceiveStaffPhone;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String returnTrakeStaff;
+    @DesensitiveInfo(DesensitiveType.MOBILE_PHONE)
+    private String returnNumber;
+    @DesensitiveInfo(DesensitiveType.ZIP_CODE)
+    private String postCode;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String loanerSer;
+
+
+    private String applyPersonEncrypt;
+    private String applyPersonPhoneEncrypt;
+    private String applicantMailboxEncrypt;
+    private String loanerReceiveStaffEncrypt;
+    private String directShippmentAddressEncrypt;
+    private String loanerReceiveStaffPhoneEncrypt;
+    private String returnTrakeStaffEncrypt;
+    private String returnNumberEncrypt;
+    private String postCodeEncrypt;
+    private String loanerSerEncrypt;
+}
diff --git a/src/main/java/com/deloitte/system/request/LoanerUserDto.java b/src/main/java/com/deloitte/system/request/LoanerUserDto.java
new file mode 100644
index 0000000..667f4bd
--- /dev/null
+++ b/src/main/java/com/deloitte/system/request/LoanerUserDto.java
@@ -0,0 +1,24 @@
+package com.deloitte.system.request;
+
+import com.common.annotation.DesensitiveInfo;
+import com.common.core.domain.DesensitiveType;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class LoanerUserDto {
+    private String dataId;
+    private Integer isDelete;
+    private String sfRecordId;
+
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String contact;
+    @DesensitiveInfo(DesensitiveType.MOBILE_PHONE)
+    private String contactNumber;
+
+    private String contactEncrypt;
+    private String contactNumberEncrypt;
+}
diff --git a/src/main/java/com/deloitte/system/request/MailMergeDto.java b/src/main/java/com/deloitte/system/request/MailMergeDto.java
new file mode 100644
index 0000000..969f227
--- /dev/null
+++ b/src/main/java/com/deloitte/system/request/MailMergeDto.java
@@ -0,0 +1,102 @@
+package com.deloitte.system.request;
+
+import com.common.annotation.DesensitiveInfo;
+import com.common.annotation.NoEncryption;
+import com.common.core.domain.DesensitiveType;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Date;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class MailMergeDto {
+
+    private String dataId;
+    private Integer isDelete;
+    private String sfRecordId;
+
+    @NoEncryption
+    private String name;
+    @DesensitiveInfo(DesensitiveType.EMAIL)
+    private String cc;
+    @DesensitiveInfo(DesensitiveType.EMAIL)
+    private String bcc;
+    @DesensitiveInfo(DesensitiveType.EMAIL)
+    private String author;
+    @DesensitiveInfo(DesensitiveType.BASIC)
+    private String allMember;
+    @NoEncryption
+    private String allMemberType;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String toName;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String allMemberName;
+    @NoEncryption
+    private String mailType;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String ccName;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String bccName;
+    @NoEncryption
+    private String type;
+    @NoEncryption
+    private String subject;
+    @NoEncryption
+    private String subjectCopy;
+    @NoEncryption
+    private String record;
+    @NoEncryption
+    private String recordType;
+    @DesensitiveInfo(DesensitiveType.BASIC)
+    private String recipient;
+    @DesensitiveInfo(DesensitiveType.BASIC)
+    private String premaryRecipient;
+    @NoEncryption
+    private String files;
+    @NoEncryption
+    private String emalSent;
+    @NoEncryption
+    private String emailSent;
+    @NoEncryption
+    private String currencyIsoCode;
+    @NoEncryption
+    private String internalOnly;
+    @NoEncryption
+    private String ownerId;
+    @NoEncryption
+    private String lastModifiedById;
+    @NoEncryption
+    private String createdById;
+    @NoEncryption
+    private String swo;
+    @NoEncryption
+    private String quotes;
+    @DesensitiveInfo(DesensitiveType.EMAIL)
+    private String send;
+    @NoEncryption
+    private String caseF;
+    @DesensitiveInfo(DesensitiveType.EMAIL)
+    private String from;
+    @NoEncryption
+    private Date date;
+    @DesensitiveInfo(DesensitiveType.BASIC)
+    private String message;
+
+    private String ccEncrypt;
+    private String bccEncrypt;
+    private String authorEncrypt;
+    private String allMemberEncrypt;
+    private String toNameEncrypt;
+    private String allMemberNameEncrypt;
+    private String ccNameEncrypt;
+    private String bccNameEncrypt;
+    private String recipientEncrypt;
+    private String premaryRecipientEncrypt;
+    private String sendEncrypt;
+    private String fromEncrypt;
+    private String messageEncrypt;
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/deloitte/system/request/MessageVo.java b/src/main/java/com/deloitte/system/request/MessageVo.java
new file mode 100644
index 0000000..350553e
--- /dev/null
+++ b/src/main/java/com/deloitte/system/request/MessageVo.java
@@ -0,0 +1,28 @@
+package com.deloitte.system.request;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+import java.util.Map;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class MessageVo {
+    //鍒嗗彿鍒嗗壊
+    private String bcc;
+    private String cc;
+    private String recipient;//to鏀朵欢浜�
+    private String from;
+    private String message;
+    private String recordType;//SWO,Case,Quotes
+    private String recordId;//SWO,Case,Quotes
+    private String subjectCopy;
+    private String bccName;
+    private String ccName;
+    private String toName;
+    private String fromName;
+    private Map<String,String> fileMap;
+}
diff --git a/src/main/java/com/deloitte/system/request/OperatorQueryDto.java b/src/main/java/com/deloitte/system/request/OperatorQueryDto.java
new file mode 100644
index 0000000..8b9aeef
--- /dev/null
+++ b/src/main/java/com/deloitte/system/request/OperatorQueryDto.java
@@ -0,0 +1,18 @@
+package com.deloitte.system.request;
+
+import lombok.Data;
+
+/**
+ * 甯︽搷浣滅鐨勬煡璇㈡潯浠�
+ *
+ * @author changzheng
+ * Created on 16/09/2022
+ * {"name":"sfRecordId","operator":"in","value":["0031000000SFB0C","0031000001VIfpJ"]}
+ */
+
+@Data
+public class OperatorQueryDto {
+    String name;
+    String operator;
+    Object value;
+}
diff --git a/src/main/java/com/deloitte/system/request/OpportunityDto.java b/src/main/java/com/deloitte/system/request/OpportunityDto.java
new file mode 100644
index 0000000..9c6b783
--- /dev/null
+++ b/src/main/java/com/deloitte/system/request/OpportunityDto.java
@@ -0,0 +1,44 @@
+package com.deloitte.system.request;
+
+import com.common.annotation.DesensitiveInfo;
+import com.common.core.domain.DesensitiveType;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class OpportunityDto {
+    private String dataId;
+    private Integer isDelete;
+    private String sfRecordId;
+
+
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String dealerServiceD;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String dealerService;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String dealerSalesStaffNameD;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String dealerSalesStaffName;
+    @DesensitiveInfo(DesensitiveType.Date)
+    private String expectedDeliveryDate;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String salesAccountCode;
+    @DesensitiveInfo(DesensitiveType.ADDRESS)
+    private String specialDeliveryAddress;
+
+
+
+
+    private String dealerServiceDEncrypt;
+    private String dealerServiceEncrypt;
+    private String dealerSalesStaffNameDEncrypt;
+    private String dealerSalesStaffNameEncrypt;
+    private String expectedDeliveryDateEncrypt;
+    private String salesAccountCodeEncrypt;
+    private String specialDeliveryAddressEncrypt;
+}
diff --git a/src/main/java/com/deloitte/system/request/OrderDto.java b/src/main/java/com/deloitte/system/request/OrderDto.java
new file mode 100644
index 0000000..5aa7e19
--- /dev/null
+++ b/src/main/java/com/deloitte/system/request/OrderDto.java
@@ -0,0 +1,143 @@
+package com.deloitte.system.request;
+
+
+import com.common.annotation.DesensitiveInfo;
+import com.common.core.domain.DesensitiveType;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class OrderDto {
+    private String dataId;
+    private Integer isDelete;
+    private String sfRecordId;
+
+    @DesensitiveInfo(DesensitiveType.MOBILE_PHONE)
+    private String specialDeliveryPhone;
+    @DesensitiveInfo(DesensitiveType.MOBILE_PHONE)
+    private String specialDeliveryPhoneD;
+    @DesensitiveInfo(DesensitiveType.EMAIL)
+    private String shippingRecieverEmailAdr;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String shipToContactId;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String customerAuthorizedById;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String billToContactId;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String specialDeliveryContact2;
+    @DesensitiveInfo(DesensitiveType.TITLE_TYPE)
+    private String specialDeliveryContactText;
+    @DesensitiveInfo(DesensitiveType.TITLE_TYPE)
+    private String shippingAddressText;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String specialDeliveryContact2D;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String endUser;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String endUserD;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String specialDeliveryContact;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String specialDeliveryContactD;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String pdfNNotifyParty;
+    @DesensitiveInfo(DesensitiveType.TITLE_TYPE)
+    private String pdfNFax;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String pdfNContact;
+    @DesensitiveInfo(DesensitiveType.MOBILE_PHONE)
+    private String pdfSTel;
+    @DesensitiveInfo(DesensitiveType.MOBILE_PHONE)
+    private String pdfSPhone;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String pdfSName;
+    @DesensitiveInfo(DesensitiveType.TITLE_TYPE)
+    private String pdfSFax;
+    @DesensitiveInfo(DesensitiveType.MOBILE_PHONE)
+    private String pdfFTel;
+    @DesensitiveInfo(DesensitiveType.TITLE_TYPE)
+    private String pdfFFax;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String pdfFContactPerson;
+    @DesensitiveInfo(DesensitiveType.ADDRESS)
+    private String pdfSAdds;
+    @DesensitiveInfo(DesensitiveType.ADDRESS)
+    private String pdfSAddress;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String pdfSeller;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String pdfCTheconsigne;
+    @DesensitiveInfo(DesensitiveType.MOBILE_PHONE)
+    private String pdfCTel;
+    @DesensitiveInfo(DesensitiveType.TITLE_TYPE)
+    private String pdfCFax;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String pdfCConsignee;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String pdfCContact;
+    @DesensitiveInfo(DesensitiveType.ADDRESS)
+    private String pdfCAddr;
+    @DesensitiveInfo(DesensitiveType.ADDRESS)
+    private String specialDeliveryAddress;
+    @DesensitiveInfo(DesensitiveType.ADDRESS)
+    private String specialDeliveryAddressD;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String dealerSalesStaffNameA;
+    @DesensitiveInfo(DesensitiveType.TITLE_TYPE)
+    private String pdfSignTitle;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String pdfSignName;
+    @DesensitiveInfo(DesensitiveType.TITLE_TYPE)
+    private String pdfSignaturePlaces;
+    @DesensitiveInfo(DesensitiveType.MOBILE_PHONE)
+    private String pdfByTel;
+    @DesensitiveInfo(DesensitiveType.MOBILE_PHONE)
+    private String pdfByAdd;
+
+
+    private String specialDeliveryPhoneEncrypt;
+    private String specialDeliveryPhoneDEncrypt;
+    private String shippingRecieverEmailAdrEncrypt;
+    private String shipToContactIdEncrypt;
+    private String customerAuthorizedByIdEncrypt;
+    private String billToContactIdEncrypt;
+    private String specialDeliveryContact2Encrypt;
+    private String specialDeliveryContactTextEncrypt;
+    private String shippingAddressTextEncrypt;
+    private String specialDeliveryContact2DEncrypt;
+    private String endUserEncrypt;
+    private String endUserDEncrypt;
+    private String specialDeliveryContactEncrypt;
+    private String specialDeliveryContactDEncrypt;
+    private String pdfNNotifyPartyEncrypt;
+    private String pdfNFaxEncrypt;
+    private String pdfNContactEncrypt;
+    private String pdfSTelEncrypt;
+    private String pdfSPhoneEncrypt;
+    private String pdfSNameEncrypt;
+    private String pdfSFaxEncrypt;
+    private String pdfFTelEncrypt;
+    private String pdfFFaxEncrypt;
+    private String pdfFContactPersonEncrypt;
+    private String pdfSAddsEncrypt;
+    private String pdfSAddressEncrypt;
+    private String pdfSellerEncrypt;
+    private String pdfCTheconsigneEncrypt;
+    private String pdfCTelEncrypt;
+    private String pdfCFaxEncrypt;
+    private String pdfCConsigneeEncrypt;
+    private String pdfCContactEncrypt;
+    private String pdfCAddrEncrypt;
+    private String specialDeliveryAddressEncrypt;
+    private String specialDeliveryAddressDEncrypt;
+    private String dealerSalesStaffNameAEncrypt;
+    private String pdfSignTitleEncrypt;
+    private String pdfSignNameEncrypt;
+    private String pdfSignaturePlacesEncrypt;
+    private String pdfByTelEncrypt;
+    private String pdfByAddEncrypt;
+}
diff --git a/src/main/java/com/deloitte/system/request/QuotesDto.java b/src/main/java/com/deloitte/system/request/QuotesDto.java
new file mode 100644
index 0000000..106bb53
--- /dev/null
+++ b/src/main/java/com/deloitte/system/request/QuotesDto.java
@@ -0,0 +1,46 @@
+package com.deloitte.system.request;
+
+import com.common.annotation.DesensitiveInfo;
+import com.common.core.domain.DesensitiveType;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class QuotesDto {
+    private String dataId;
+    private Integer isDelete;
+    private String sfRecordId;
+
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String contactName;
+    @DesensitiveInfo(DesensitiveType.MOBILE_PHONE)
+    private String contactPhone;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String contactFax;
+    @DesensitiveInfo(DesensitiveType.EMAIL)
+    private String contactEmail;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String billTo;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String shipTo;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String author;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String message;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String primaryRecipient;
+
+
+    private String contactNameEncrypt;
+    private String contactPhoneEncrypt;
+    private String contactFaxEncrypt;
+    private String contactEmailEncrypt;
+    private String billToEncrypt;
+    private String shipToEncrypt;
+    private String authorEncrypt;
+    private String messageEncrypt;
+    private String primaryRecipientEncrypt;
+}
diff --git a/src/main/java/com/deloitte/system/request/RepairDto.java b/src/main/java/com/deloitte/system/request/RepairDto.java
new file mode 100644
index 0000000..a7db2a6
--- /dev/null
+++ b/src/main/java/com/deloitte/system/request/RepairDto.java
@@ -0,0 +1,24 @@
+package com.deloitte.system.request;
+
+import com.common.annotation.DesensitiveInfo;
+import com.common.core.domain.DesensitiveType;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class RepairDto {
+    private String dataId;
+    private Integer isDelete;
+    private String sfRecordId;
+
+    @DesensitiveInfo(DesensitiveType.MOBILE_PHONE)
+    private String telephonen;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String contactD;
+
+    private String telephonenEncrypt;
+    private String contactDEncrypt;
+}
diff --git a/src/main/java/com/deloitte/system/request/SFFileAddressVo.java b/src/main/java/com/deloitte/system/request/SFFileAddressVo.java
new file mode 100644
index 0000000..ece6a83
--- /dev/null
+++ b/src/main/java/com/deloitte/system/request/SFFileAddressVo.java
@@ -0,0 +1,16 @@
+package com.deloitte.system.request;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class SFFileAddressVo {
+    private String AWS_File_Key__c;
+    private String FileName__c;
+    private String DownloadLink__c;
+    private String ParentRecordId__c;
+    private String ViewLink__c;
+}
diff --git a/src/main/java/com/deloitte/system/request/SFMessageVo.java b/src/main/java/com/deloitte/system/request/SFMessageVo.java
new file mode 100644
index 0000000..377da06
--- /dev/null
+++ b/src/main/java/com/deloitte/system/request/SFMessageVo.java
@@ -0,0 +1,47 @@
+package com.deloitte.system.request;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class SFMessageVo {
+    private String Name;
+    private String ALL_MEMBER_NAME__c;
+    private String ALL_MEMBER_TYPE__c;
+    private String ALL_MEMBER__c;
+    private String BCC__c;
+    private String CC__c;
+    private String FROM__c;
+    private String MESSAGE__c;
+    private String RECIPIENT__c;
+    private String RECORD__c;
+    private String RECORD_TYPE__c;
+    private String SUBJECTCOPY__c;
+    private String SUBJECT__c;
+    private String TYPE__c;
+    private String bccName__c;
+    private String ccName__c;
+    private String toName__c;
+    private String AWS_Data_Id__c;
+    private String DATE__c;
+
+    private String ALL_MEMBER_NAME_Encrypted__c;
+    private String ALL_MEMBER_Encrypted__c;
+    private String BCC_Encrypted__c ;
+    private String CC_Encrypted__c;
+    private String FROM_Encrypted__c;
+    private String RECIPIENT_Encrypted__c;
+    private String bccName_Encrypted__c;
+    private String ccName_Encrypted__c;
+    private String toName_Encrypted__c;
+
+    private String SWO__c;
+    private String Quotes__c;
+    private String CaseF__c;
+
+    private String EMAIL_SENT__c;
+
+}
diff --git a/src/main/java/com/deloitte/system/request/SFTokenDto.java b/src/main/java/com/deloitte/system/request/SFTokenDto.java
new file mode 100644
index 0000000..a62d833
--- /dev/null
+++ b/src/main/java/com/deloitte/system/request/SFTokenDto.java
@@ -0,0 +1,26 @@
+package com.deloitte.system.request;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class SFTokenDto {
+    /** 鎺ュ彛璋冪敤鍑瘉 access_token */
+    @JsonProperty("access_token")
+    private String accessToken;
+    /** 鏈嶅姟鍣ㄥ湴鍧�*/
+    @JsonProperty("instance_url")
+    private String instanceUrl;
+    /** 褰撳墠璇锋眰鐢ㄦ埛鐨勮韩浠�*/
+    private String id;
+    /** 鏈嶅姟鍣ㄥ湴鍧�*/
+    @JsonProperty("token_type")
+    private String tokenType;
+    /** 鐢熸垚绛惧悕鐨勬椂闂�*/
+    @JsonProperty("issued_at")
+    private String issuedAt;
+    /** 鐢╟lient secret瀵嗛挜*/
+    private String signature;
+}
diff --git a/src/main/java/com/deloitte/system/request/SearchDto.java b/src/main/java/com/deloitte/system/request/SearchDto.java
new file mode 100644
index 0000000..00c5c99
--- /dev/null
+++ b/src/main/java/com/deloitte/system/request/SearchDto.java
@@ -0,0 +1,16 @@
+package com.deloitte.system.request;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class SearchDto {
+    private List<String> dataIds;
+    private String name;
+}
\ No newline at end of file
diff --git a/src/main/java/com/deloitte/system/request/SfCompositeRequest.java b/src/main/java/com/deloitte/system/request/SfCompositeRequest.java
new file mode 100644
index 0000000..6689311
--- /dev/null
+++ b/src/main/java/com/deloitte/system/request/SfCompositeRequest.java
@@ -0,0 +1,57 @@
+package com.deloitte.system.request;
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.Data;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 閭欢鍐呭鍚屾鑷砈F request
+ *
+ * @author Ali
+ * Created on 22/03/2022
+ */
+@Data
+public class SfCompositeRequest {
+
+    private boolean allOrNone = true;
+
+    private List<JSONObject> compositeRequest = new ArrayList<>();
+
+    private List<SFFileAddressVo> fileAddressList = new ArrayList<>();
+
+    public void addMailMerge(SFMessageVo messageVo){
+        JSONObject jsonObject = new JSONObject();
+        jsonObject.put("method","POST");
+        jsonObject.put("referenceId","NewMailMerge");
+        jsonObject.put("url","/services/data/v53.0/sobjects/Mail_Merge__c/");
+        jsonObject.put("body",messageVo);
+        compositeRequest.add(jsonObject);
+    }
+
+    public void addFileAddress(List<SFFileAddressVo> fileAddressVos){
+        for (SFFileAddressVo fileAddressVo:fileAddressVos) {
+            JSONObject jsonObject = new JSONObject();
+            jsonObject.put("method","POST");
+            String referenceId = "NewFileAddress";
+            if(fileAddressList!=null && fileAddressList.size()>0){
+                referenceId+=fileAddressList.size();
+            }
+            jsonObject.put("referenceId",referenceId);
+            jsonObject.put("url","/services/data/v53.0/sobjects/FileAddress__c");
+            jsonObject.put("body",fileAddressVo);
+            fileAddressList.add(fileAddressVo);
+            compositeRequest.add(jsonObject);
+        }
+    }
+
+    // 鑾峰彇璇锋眰json
+    public String toJsonString() {
+        return "{" +
+                "\"allOrNone\":" + allOrNone +
+                ", \"compositeRequest\":" + compositeRequest +
+                '}';
+    }
+
+}
diff --git a/src/main/java/com/deloitte/system/request/SwoDto.java b/src/main/java/com/deloitte/system/request/SwoDto.java
new file mode 100644
index 0000000..55ddc39
--- /dev/null
+++ b/src/main/java/com/deloitte/system/request/SwoDto.java
@@ -0,0 +1,58 @@
+package com.deloitte.system.request;
+
+import com.common.annotation.DesensitiveInfo;
+import com.common.core.domain.DesensitiveType;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class SwoDto {
+    private String dataId;
+    private Integer isDelete;
+    private String sfRecordId;
+
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String contactNameHidden;
+    @DesensitiveInfo(DesensitiveType.EMAIL)
+    private String email;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String contact;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String author;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String message;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String primaryRecipient;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String send;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String cc;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String ccName;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String bcc;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String bccName;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String recipient;
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String toName;
+
+
+    private String contactNameHiddenEncrypt;
+    private String emailEncrypt;
+    private String contactEncrypt;
+    private String authorEncrypt;
+    private String messageEncrypt;
+    private String primaryRecipientEncrypt;
+    private String sendEncrypt;
+    private String ccEncrypt;
+    private String ccNameEncrypt;
+    private String bccEncrypt;
+    private String bccNameEncrypt;
+    private String recipientEncrypt;
+    private String toNameEncrypt;
+}
diff --git a/src/main/java/com/deloitte/system/request/TSRepairDto.java b/src/main/java/com/deloitte/system/request/TSRepairDto.java
new file mode 100644
index 0000000..dabba2b
--- /dev/null
+++ b/src/main/java/com/deloitte/system/request/TSRepairDto.java
@@ -0,0 +1,24 @@
+package com.deloitte.system.request;
+
+import com.common.annotation.DesensitiveInfo;
+import com.common.core.domain.DesensitiveType;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class TSRepairDto {
+    private String dataId;
+    private Integer isDelete;
+    private String sfRecordId;
+
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String businessAContact;
+    @DesensitiveInfo(DesensitiveType.MOBILE_PHONE)
+    private String businessAPhone;
+
+    private String businessAPhoneEncrypt;
+    private String businessAContactEncrypt;
+}
diff --git a/src/main/java/com/deloitte/system/request/TxConfirmDto.java b/src/main/java/com/deloitte/system/request/TxConfirmDto.java
new file mode 100644
index 0000000..bdcae2f
--- /dev/null
+++ b/src/main/java/com/deloitte/system/request/TxConfirmDto.java
@@ -0,0 +1,29 @@
+package com.deloitte.system.request;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class TxConfirmDto {
+    private String txId;
+    private String sfRecordId;
+    private Integer isSuccess;
+    private List<ConfimrListDto> idList;
+
+    public TxConfirmDto(String txId, String sfRecordId, Integer isSuccess) {
+        this.txId = txId;
+        this.sfRecordId = sfRecordId;
+        this.isSuccess = isSuccess;
+    }
+
+    @Data
+    public static class ConfimrListDto{
+        private String sfRecordId;
+        private String awsId;
+    }
+}
diff --git a/src/main/java/com/deloitte/system/request/UserFaultInfoDto.java b/src/main/java/com/deloitte/system/request/UserFaultInfoDto.java
new file mode 100644
index 0000000..1a1f115
--- /dev/null
+++ b/src/main/java/com/deloitte/system/request/UserFaultInfoDto.java
@@ -0,0 +1,27 @@
+package com.deloitte.system.request;
+
+import com.common.annotation.DesensitiveInfo;
+import com.common.core.domain.DesensitiveType;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class UserFaultInfoDto {
+    private String dataId;
+    private Integer isDelete;
+    private String sfRecordId;
+
+    @DesensitiveInfo(DesensitiveType.CHINESE_NAME)
+    private String ufContact;
+    @DesensitiveInfo(DesensitiveType.ADDRESS)
+    private String inboundEmailAddress;
+    @DesensitiveInfo(DesensitiveType.MOBILE_PHONE)
+    private String ufPhone;
+
+    private String ufContactEncrypt;
+    private String inboundEmailAddressEncrypt;
+    private String ufPhoneEncrypt;
+}
diff --git a/src/main/java/com/deloitte/system/service/CampaignUserService.java b/src/main/java/com/deloitte/system/service/CampaignUserService.java
new file mode 100644
index 0000000..2cf50df
--- /dev/null
+++ b/src/main/java/com/deloitte/system/service/CampaignUserService.java
@@ -0,0 +1,206 @@
+package com.deloitte.system.service;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.text.csv.CsvUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.alibaba.fastjson.JSONArray;
+import com.common.core.constant.GlobalConst;
+import com.common.core.enums.ResultCodeEnum;
+import com.common.core.exception.BizException;
+import com.common.core.service.CryptoService;
+import com.common.core.utils.BeanHelper;
+import com.common.core.utils.DateUtils;
+import com.common.core.utils.DesensitiveUtils;
+import com.common.core.utils.IdUtils;
+import com.common.core.utils.StringUtils;
+import com.common.redis.util.RedisUtil;
+import com.deloitte.system.model.CacheList;
+import com.deloitte.system.model.CampaignUser;
+import com.deloitte.system.model.Contact;
+import com.deloitte.system.request.CampaignUserAllDto;
+import com.deloitte.system.request.CampaignUserDto;
+import com.deloitte.system.request.ContactDto;
+import com.deloitte.system.request.OperatorQueryDto;
+import com.opencsv.bean.CsvToBean;
+import com.opencsv.bean.CsvToBeanBuilder;
+import com.opencsv.bean.HeaderColumnNameMappingStrategy;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static com.common.core.constant.GlobalConst.PIPL_UNCONFIRM_INSERT;
+import static com.common.core.constant.GlobalConst.PIPL_UNCONFIRM_UPDATE;
+
+@Slf4j
+@Service
+public class CampaignUserService {
+
+    private String tableName="campaign_user";
+
+    @Autowired
+    private CryptoService cryptoService;
+
+    @Autowired
+    private IdUtils idWorker;
+
+    @Autowired
+    private RedisUtil redisUtil;
+
+    public CampaignUserDto queryForOne(String dataId) {
+        CampaignUser campaignUser =CampaignUser.dao.findById(dataId);
+        if (!ObjectUtil.isEmpty(campaignUser)){
+            CampaignUserDto dto = BeanHelper.copyAs(campaignUser, CampaignUserDto.class);
+            return dto;
+        }
+        return null;
+
+    }
+
+    public List<CampaignUserDto> insertList(List<CampaignUserDto> campaignUserDtoList, String txId) {
+        List<CampaignUserDto> respList = new ArrayList<>();
+        CacheList<CampaignUserDto> dtoCacheList = new CacheList<>();
+        dtoCacheList.setTableName(tableName);
+        List<CampaignUserDto> dtoItemList = new ArrayList<>();
+        campaignUserDtoList.forEach(e -> {
+            String dataId = idWorker.nextId();
+            CampaignUserDto cacheItem = BeanHelper.copyAs(e, CampaignUserDto.class);
+            cacheItem.setDataId(dataId);
+            dtoItemList.add(cacheItem);
+
+            CampaignUserDto target = BeanHelper.copyAs(e, CampaignUserDto.class);
+            target.setDataId(dataId);
+            CampaignUserDto dto = cryptoService.encryptModelColumns(e);
+            dto.setDataId(dataId);
+            target.setNameEncrypt(dto.getName());
+            target.setPhoneEncrypt(dto.getPhone());
+            target.setEmailEncrypt(dto.getEmail());
+            DesensitiveUtils.format(target);
+            respList.add(target);
+        });
+        dtoCacheList.setData(dtoItemList);
+        String insertJsonString = JSONArray.toJSONString(dtoCacheList);
+        String insertKey = PIPL_UNCONFIRM_INSERT + txId;
+        boolean redisFlag = redisUtil.set(insertKey, insertJsonString, GlobalConst.DATA_EXPIRE);
+        if (!redisFlag){
+            throw new BizException("缂撳瓨鍐欏叆澶辫触");
+        }
+        return respList;
+    }
+
+    public List<CampaignUserDto> updateList(List<CampaignUserDto> campaignUserDtoList, String txId) {
+        List<CampaignUserDto> respList = new ArrayList<>();
+        CacheList<CampaignUserDto> dtoCacheList = new CacheList<>();
+        dtoCacheList.setTableName(tableName);
+        List<CampaignUserDto> dtoItemList = new ArrayList<>();
+        campaignUserDtoList.forEach(e -> {
+            CampaignUser campaignUser = CampaignUser.dao.findById(e.getDataId());
+            CampaignUserDto cacheItem = BeanHelper.copyAs(e, CampaignUserDto.class);
+            dtoItemList.add(cacheItem);
+            CampaignUserDto dto = BeanHelper.copyAs(BeanHelper.copy(cacheItem,campaignUser),CampaignUserDto.class);
+            CampaignUserDto target = BeanHelper.copyAs(dto, CampaignUserDto.class);
+            dto = cryptoService.encryptModelColumns(dto);
+            target.setNameEncrypt(dto.getName());
+            target.setPhoneEncrypt(dto.getPhone());
+            target.setEmailEncrypt(dto.getEmail());
+            DesensitiveUtils.format(target);
+            respList.add(target);
+        });
+        dtoCacheList.setData(dtoItemList);
+        String updateJsonString = JSONArray.toJSONString(dtoCacheList);
+        String updateKey = PIPL_UNCONFIRM_UPDATE + txId;
+        boolean redisFlag = redisUtil.set(updateKey, updateJsonString,GlobalConst.DATA_EXPIRE);
+        if (!redisFlag){
+            throw new BizException("缂撳瓨鍐欏叆澶辫触");
+        }
+        return respList;
+    }
+
+    public Boolean deleteOne(String dataId) {
+        CampaignUser campaignUser = CampaignUser.dao.findById(dataId);
+        campaignUser.setIsDelete(1);
+        return campaignUser.saveOrUpdate();
+    }
+
+    public Boolean undeleteOne(String dataId) {
+        CampaignUser campaignUser = CampaignUser.dao.findById(dataId);
+        campaignUser.setIsDelete(0);
+        return campaignUser.saveOrUpdate();
+    }
+
+    public List<CampaignUserDto> search(List<String> idList){
+        if (CollUtil.isEmpty(idList)) {
+            return null;
+        }
+        StringBuilder queryParam = new StringBuilder();
+        queryParam.append("and id in ").append(idList.stream().collect(Collectors.joining(", ", "(", ")")));
+        List<CampaignUser> quotesList = CampaignUser.dao.findList(queryParam.toString());
+        return quotesList.stream()
+                .map(quotes -> BeanHelper.copyAs(quotes, CampaignUserDto.class)).collect(Collectors.toList());
+
+    }
+    public List<CampaignUserAllDto> batchUpload(MultipartFile[] files,String txId) {
+        List<CampaignUserAllDto> listAll= null;
+        try {
+            InputStreamReader in = null;
+            in = new InputStreamReader(files[0].getInputStream(), FileService.getFilecharset(files[0].getInputStream()));
+            HeaderColumnNameMappingStrategy<CampaignUserAllDto> strategy = new HeaderColumnNameMappingStrategy<>();
+            strategy.setType(CampaignUserAllDto.class);
+            CsvToBean<CampaignUserAllDto> csvToBean = new CsvToBeanBuilder<CampaignUserAllDto>(in)
+                    .withSeparator(',')
+                    .withQuoteChar('\'')
+                    .withMappingStrategy(strategy).build();
+            listAll= csvToBean.parse();
+
+            List<CampaignUserDto> userList=BeanHelper.copyAs(listAll,CampaignUserDto.class);
+            List<CampaignUserDto> userList2 = this.insertList(userList,txId);
+            for (int i = 0; i < listAll.size(); i++) {
+                BeanHelper.copy(userList2.get(i),listAll.get(i));
+            }
+        } catch (Exception e) {
+            log.error("CampaignUser batchUpload failed:",e);
+            throw new BizException(ResultCodeEnum.AWS_RT_ERROR);
+        }
+        //鏃ユ湡杞崲
+        /*if(null!=listAll && !listAll.isEmpty()){
+            listAll.forEach(e->{
+                Date date = DateUtils.convert(e.getDateTime(),DateUtils.DATE_TIME_MINUTE_FORMAT2);
+                e.setDateTime(DateUtils.format(date,DateUtils.DATE_TIME_MINUTE_FORMAT1));
+            });
+        }*/
+        return listAll;
+    }
+
+    public List<CampaignUserDto> searchListByOperator(List<OperatorQueryDto> queryDtos) {
+
+        StringBuilder queryParam = new StringBuilder();
+        for (OperatorQueryDto queryDto: queryDtos) {
+            String queryName = queryDto.getName();
+            //name椹煎嘲杞笅鍒掔嚎
+            String name = BeanHelper.propertyToColumn(queryName);
+            String operator = queryDto.getOperator();
+            Object value = queryDto.getValue();
+            if(StringUtils.isNotEmpty(operator)){
+                if("=".equals(operator)||"!=".equals(operator)){
+                    queryParam.append(" and c."+name).append(" "+operator+" ").append("'"+value+"'");
+                }else if("like".equals(operator)||"not like".equals(operator)){
+                    queryParam.append(" and c."+name).append(" "+operator+" ").append("\'%").append(value).append("%\'");
+                }else if("in".equals(operator)||"not in".equals(operator)){
+                    List<String> value1 = (ArrayList<String>)value;
+                    queryParam.append(" and c."+name).append(" "+operator+" ").append(value1.stream().collect(Collectors.joining("','", "('", "')")));
+                }else {
+                    throw new BizException("鏃犳晥鐨剆ql璇锋眰锛�");
+                }
+            }
+        }
+        queryParam.append(" and c.sf_record_id is not null");
+        String sql = "select c.* from campaign_user c WHERE c.is_delete = '0' "+queryParam.toString();
+        List<CampaignUser> campaignUserList = CampaignUser.dao.findListBySql(sql);
+        return campaignUserList.stream().map(e->BeanHelper.copyAs(e,CampaignUserDto.class)).collect(Collectors.toList());
+    }
+}
diff --git a/src/main/java/com/deloitte/system/service/ConfirmTxService.java b/src/main/java/com/deloitte/system/service/ConfirmTxService.java
new file mode 100644
index 0000000..73dcce8
--- /dev/null
+++ b/src/main/java/com/deloitte/system/service/ConfirmTxService.java
@@ -0,0 +1,155 @@
+package com.deloitte.system.service;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.common.annotation.Table;
+import com.common.aws.util.S3Util;
+import com.common.core.constant.Constants;
+import com.common.core.constant.GlobalConst;
+import com.common.core.domain.BaseModel;
+import com.common.core.enums.ResultCodeEnum;
+import com.common.core.enums.YesNoEnum;
+import com.common.core.exception.BizException;
+import com.common.core.utils.DistributedLock;
+import com.common.core.utils.KitClassUtils;
+import com.common.core.utils.ModelUtils;
+import com.common.core.utils.StringUtils;
+import com.common.redis.util.RedisUtil;
+import com.deloitte.system.request.TxConfirmDto;
+import com.jfinal.plugin.activerecord.Db;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Service
+public class ConfirmTxService {
+
+    @Autowired
+    private RedisUtil redisUtil;
+
+    @Autowired
+    private DistributedLock distributedLock;
+    @Value("${aws.s3.bucketName}")
+    private String bucketName;
+
+    public void confirm(TxConfirmDto dto) {
+        String txid=dto.getTxId();
+        String sfRecordId = dto.getSfRecordId();
+        if(null== redisUtil.get(GlobalConst.PIPL_UNCONFIRM_INSERT + txid) && null == redisUtil.get(GlobalConst.PIPL_UNCONFIRM_UPDATE + txid)){
+            throw new BizException("涓嶅瓨鍦ㄧ殑浜嬪姟ID锛坱xid锛�");
+        }
+        //閬嶅巻insert
+        Object object = redisUtil.get(GlobalConst.PIPL_UNCONFIRM_INSERT + txid);
+        if(object!=null && StringUtils.isNotEmpty(object.toString()) && distributedLock.getLock(GlobalConst.PIPL_UNCONFIRM_LOCK +txid,3600 * 1000)) {
+            try {
+                log.info(object.toString());
+                if(YesNoEnum.YES.getCode().equals(dto.getIsSuccess())) {
+                    List<BaseModel> models = generateModelInfo(object, sfRecordId,dto.getIdList(), true);
+                    Db.tx(() -> {
+                        for (BaseModel model : models) {
+                            if(!model.save()) return false;
+                        }
+                        return true;
+                    });
+                }
+                redisUtil.deleteKey(GlobalConst.PIPL_UNCONFIRM_INSERT + txid);
+            }catch (Exception e){
+                log.error(e.getMessage(), e);
+                throw new BizException(ResultCodeEnum.RT_ERROR);
+            }finally {
+                distributedLock.releaseLock(GlobalConst.PIPL_UNCONFIRM_LOCK +txid);
+            }
+        }
+
+        //閬嶅巻update
+        object = redisUtil.get(GlobalConst.PIPL_UNCONFIRM_UPDATE + txid);
+        if(object!=null && StringUtils.isNotEmpty(object.toString()) && distributedLock.getLock(GlobalConst.PIPL_UNCONFIRM_LOCK +txid,3600 * 1000)) {
+            try {
+                log.info(object.toString());
+                if(YesNoEnum.YES.getCode().equals(dto.getIsSuccess())) {
+                    List<BaseModel> models = generateModelInfo(object,sfRecordId,dto.getIdList(),false);
+                    Db.tx(() -> {
+                        for (BaseModel model : models) {
+                            if(!model.update()) return false;
+                        }
+                        return true;
+                    });
+                }
+                redisUtil.deleteKey(GlobalConst.PIPL_UNCONFIRM_UPDATE + txid);
+            }catch (Exception e){
+                log.error(e.getMessage(), e);
+                throw new BizException(ResultCodeEnum.RT_ERROR);
+            }finally {
+                distributedLock.releaseLock(GlobalConst.PIPL_UNCONFIRM_LOCK +txid);
+            }
+        }
+    }
+
+    public void confirmFile(TxConfirmDto dto) {
+        String txid = dto.getTxId();
+        if(null== redisUtil.get(GlobalConst.PIPL_UNCONFIRM_FILE + txid)){
+            throw new BizException("涓嶅瓨鍦ㄧ殑浜嬪姟ID锛坱xid锛�");
+        }
+        Object object = redisUtil.get(GlobalConst.PIPL_UNCONFIRM_FILE + txid);
+        if(object!=null && StringUtils.isNotEmpty(object.toString()) && distributedLock.getLock(GlobalConst.PIPL_UNCONFIRM_LOCK +txid,3600 * 1000)) {
+           try {
+               if(YesNoEnum.NO.getCode().equals(dto.getIsSuccess())) {
+                   List<String> keys = JSONArray.parseArray(object.toString(),String.class);
+                   S3Util.deleteByKeys(keys,bucketName);
+               }
+               redisUtil.deleteKey(GlobalConst.PIPL_UNCONFIRM_FILE + txid);
+           }catch (Exception e){
+               log.error(e.getMessage(), e);
+               throw new BizException(ResultCodeEnum.RT_ERROR);
+           }finally {
+               distributedLock.releaseLock(GlobalConst.PIPL_UNCONFIRM_LOCK +txid);
+           }
+        }
+    }
+
+    private List<BaseModel> generateModelInfo(Object object, String sfRecordId, List<TxConfirmDto.ConfimrListDto> idList,boolean isCreate) throws InstantiationException, IllegalAccessException {
+        JSONObject jsonobject = JSONObject.parseObject(object.toString());
+        JSONArray dataArray = jsonobject.getJSONArray("data");
+        String table_name = jsonobject.getString("tableName");
+        List<BaseModel> models = new ArrayList<>();
+        Map<String,String> idMap= null;
+        if(CollectionUtil.isNotEmpty(idList)){
+            idMap=idList.stream().collect(Collectors.toMap(TxConfirmDto.ConfimrListDto::getAwsId, TxConfirmDto.ConfimrListDto::getSfRecordId));
+        }
+        for (Class<?> clazz : KitClassUtils.tableclass) {
+            Table table = clazz.getAnnotation(Table.class);
+            String tablename = table.tableName();
+            if (tablename.equals(table_name)) {
+                Class<? extends BaseModel<?>> classmodel = table.clazz();
+                for (int i = 0; i < dataArray.size(); i++) {
+                    JSONObject jsonObject = dataArray.getJSONObject(i);
+                    BaseModel baseModel = ModelUtils.JsonToModel(jsonObject, classmodel.newInstance());
+                    if(idMap!=null && CollectionUtil.isNotEmpty(idMap)){
+                        baseModel.set("sf_record_id",idMap.get(baseModel.getStr("id")));
+                    }else {
+                        if (StrUtil.isNotBlank(sfRecordId)) {
+                            baseModel.set("sf_record_id", sfRecordId);
+                        }
+                    }
+                    if(isCreate){
+                        ModelUtils.generateCommonInfo(baseModel, Constants.ACTION_CREATE);
+                    }else {
+                        ModelUtils.generateCommonInfo(baseModel, Constants.ACTION_UPDATE);
+                    }
+                    models.add(baseModel);
+                }
+            }
+        }
+        return models;
+    }
+}
diff --git a/src/main/java/com/deloitte/system/service/ContactService.java b/src/main/java/com/deloitte/system/service/ContactService.java
new file mode 100644
index 0000000..0afc3e6
--- /dev/null
+++ b/src/main/java/com/deloitte/system/service/ContactService.java
@@ -0,0 +1,268 @@
+package com.deloitte.system.service;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.alibaba.fastjson.JSONArray;
+import com.common.core.constant.GlobalConst;
+import com.common.core.enums.ResultCodeEnum;
+import com.common.core.exception.BizException;
+import com.common.core.service.CryptoService;
+import com.common.core.utils.*;
+import com.common.redis.util.RedisUtil;
+import com.deloitte.system.model.CacheList;
+import com.deloitte.system.model.Contact;
+import com.deloitte.system.request.ContactDto;
+import com.deloitte.system.request.ContactSearchDto;
+import com.jfinal.plugin.activerecord.Db;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static com.common.core.constant.GlobalConst.PIPL_UNCONFIRM_INSERT;
+import static com.common.core.constant.GlobalConst.PIPL_UNCONFIRM_UPDATE;
+
+
+
+@Service
+public class ContactService {
+
+    private String tableName = "contact";
+
+    @Autowired
+    private CryptoService cryptoService;
+
+    @Autowired
+    private IdUtils idWorker;
+
+    @Autowired
+    private RedisUtil redisUtil;
+
+
+    public ContactDto queryForOne(String dataId) {
+        Contact contact = Contact.dao.findById(dataId);
+        if (!ObjectUtil.isEmpty(contact)) {
+            return BeanHelper.copyAs(contact,ContactDto.class);
+        }
+        return null;
+    }
+
+    public List<ContactDto> insertList(List<ContactDto> contactList, String txId) {
+        List<ContactDto> respList = new ArrayList<>();
+        CacheList<ContactDto> dtoCacheList = new CacheList<>();
+        dtoCacheList.setTableName(tableName);
+        List<ContactDto> dtoItemList = new ArrayList<>();
+        contactList.forEach(e -> {
+            String dataId = idWorker.nextId();
+            ContactDto cacheItem = BeanHelper.copyAs(e, ContactDto.class);
+            cacheItem.setDataId(dataId);
+            dtoItemList.add(cacheItem);
+
+            ContactDto target = BeanHelper.copyAs(e, ContactDto.class);
+            target.setDataId(dataId);
+            ContactDto dto = cryptoService.encryptModelColumns(e);
+            dto.setDataId(dataId);
+            target.setFirstNameEncrypt(dto.getFirstName());
+            target.setLastNameEncrypt(dto.getLastName());
+            target.setPostcodeEncrypt(dto.getPostcode());
+            target.setPostcodeDEncrypt(dto.getPostcodeD());
+            target.setTitleDEncrypt(dto.getTitleD());
+            target.setTitleEncrypt(dto.getTitle());
+            target.setContactEnglishNameEncrypt(dto.getContactEnglishName());
+            target.setEnglishAddressEncrypt(dto.getEnglishAddress());
+            target.setAddress1Encrypt(dto.getAddress1());
+            target.setAddress2Encrypt(dto.getAddress2());
+            target.setAddress3Encrypt(dto.getAddress3());
+            target.setAddress1DEncrypt(dto.getAddress1D());
+            target.setAddress2DEncrypt(dto.getAddress2D());
+            target.setAddress3DEncrypt(dto.getAddress3D());
+            target.setFaxEncrypt(dto.getFax());
+            target.setFaxDEncrypt(dto.getFaxD());
+            target.setEmailDEncrypt(dto.getEmailD());
+            target.setEmailEncrypt(dto.getEmail());
+            target.setMobilePhoneDEncrypt(dto.getMobilePhoneD());
+            target.setOtherPhoneDEncrypt(dto.getOtherPhoneD());
+            target.setOtherPhoneDEncrypt(dto.getOtherPhoneD());
+            target.setPhoneDEncrypt(dto.getPhoneD());
+            target.setHomePhoneEncrypt(dto.getHomePhone());
+            target.setMobilePhoneEncrypt(dto.getMobilePhone());
+            target.setOtherPhoneEncrypt(dto.getOtherPhone());
+            target.setPhoneEncrypt(dto.getPhone());
+            DesensitiveUtils.format(target);
+            respList.add(target);
+        });
+        dtoCacheList.setData(dtoItemList);
+        String insertJsonString = JSONArray.toJSONString(dtoCacheList);
+        String insertKey = PIPL_UNCONFIRM_INSERT + txId;
+        boolean redisFlag = redisUtil.set(insertKey, insertJsonString, GlobalConst.DATA_EXPIRE);
+        if (!redisFlag) {
+            throw new BizException("缂撳瓨鍐欏叆澶辫触");
+        }
+        return respList;
+    }
+
+    /** 涓嶅瓨缂撳瓨锛岀洿鎺ュ叆搴� **/
+    public List<ContactDto> batchInsert(List<ContactDto> contactList) {
+        List<ContactDto> respList = new ArrayList<>();
+        CacheList<ContactDto> dtoCacheList = new CacheList<>();
+        dtoCacheList.setTableName(tableName);
+        Db.tx(() -> {
+            for (ContactDto e : contactList) {
+                String dataId = idWorker.nextId();
+                e.setDataId(dataId);
+                Contact item= BeanHelper.copyAs(e, Contact.class);
+                item.set("id", dataId);
+                if (!item.save()) {
+                    throw new BizException(ResultCodeEnum.RT_ERROR);
+                }
+                ContactDto target = BeanHelper.copyAs(e, ContactDto.class);
+                target.setDataId(dataId);
+                ContactDto dto = cryptoService.encryptModelColumns(e);
+                dto.setDataId(dataId);
+                target.setFirstNameEncrypt(dto.getFirstName());
+                target.setLastNameEncrypt(dto.getLastName());
+                target.setPostcodeEncrypt(dto.getPostcode());
+                target.setPostcodeDEncrypt(dto.getPostcodeD());
+                target.setTitleDEncrypt(dto.getTitleD());
+                target.setTitleEncrypt(dto.getTitle());
+                target.setContactEnglishNameEncrypt(dto.getContactEnglishName());
+                target.setEnglishAddressEncrypt(dto.getEnglishAddress());
+                target.setAddress1Encrypt(dto.getAddress1());
+                target.setAddress2Encrypt(dto.getAddress2());
+                target.setAddress3Encrypt(dto.getAddress3());
+                target.setAddress1DEncrypt(dto.getAddress1D());
+                target.setAddress2DEncrypt(dto.getAddress2D());
+                target.setAddress3DEncrypt(dto.getAddress3D());
+                target.setFaxEncrypt(dto.getFax());
+                target.setFaxDEncrypt(dto.getFaxD());
+                target.setEmailDEncrypt(dto.getEmailD());
+                target.setEmailEncrypt(dto.getEmail());
+                target.setMobilePhoneDEncrypt(dto.getMobilePhoneD());
+                target.setOtherPhoneDEncrypt(dto.getOtherPhoneD());
+                target.setOtherPhoneDEncrypt(dto.getOtherPhoneD());
+                target.setPhoneDEncrypt(dto.getPhoneD());
+                target.setHomePhoneEncrypt(dto.getHomePhone());
+                target.setMobilePhoneEncrypt(dto.getMobilePhone());
+                target.setOtherPhoneEncrypt(dto.getOtherPhone());
+                target.setPhoneEncrypt(dto.getPhone());
+                DesensitiveUtils.format(target);
+                respList.add(target);
+            }
+            return true;
+        });
+        return respList;
+    }
+
+    public List<ContactDto> updateList(List<ContactDto> contactList, String txId) {
+        List<ContactDto> respList = new ArrayList<>();
+        CacheList<ContactDto> dtoCacheList = new CacheList<>();
+        dtoCacheList.setTableName(tableName);
+        List<ContactDto> dtoItemList = new ArrayList<>();
+        contactList.forEach(e -> {
+            Contact contact = Contact.dao.findById(e.getDataId());
+            ContactDto cacheItem = BeanHelper.copyAs(e, ContactDto.class);
+            dtoItemList.add(cacheItem);
+            ContactDto dto =BeanHelper.copyAs(BeanHelper.copy(cacheItem,contact),ContactDto.class);
+            ContactDto target = BeanHelper.copyAs(dto, ContactDto.class);
+            dto = cryptoService.encryptModelColumns(dto);
+            target.setFirstNameEncrypt(dto.getFirstName());
+            target.setLastNameEncrypt(dto.getLastName());
+            target.setPostcodeEncrypt(dto.getPostcode());
+            target.setPostcodeDEncrypt(dto.getPostcodeD());
+            target.setTitleDEncrypt(dto.getTitleD());
+            target.setTitleEncrypt(dto.getTitle());
+            target.setContactEnglishNameEncrypt(dto.getContactEnglishName());
+            target.setEnglishAddressEncrypt(dto.getEnglishAddress());
+            target.setAddress1Encrypt(dto.getAddress1());
+            target.setAddress2Encrypt(dto.getAddress2());
+            target.setAddress3Encrypt(dto.getAddress3());
+            target.setAddress1DEncrypt(dto.getAddress1D());
+            target.setAddress2DEncrypt(dto.getAddress2D());
+            target.setAddress3DEncrypt(dto.getAddress3D());
+            target.setFaxEncrypt(dto.getFax());
+            target.setFaxDEncrypt(dto.getFaxD());
+            target.setEmailDEncrypt(dto.getEmailD());
+            target.setEmailEncrypt(dto.getEmail());
+            target.setMobilePhoneDEncrypt(dto.getMobilePhoneD());
+            target.setOtherPhoneDEncrypt(dto.getOtherPhoneD());
+            target.setPhoneDEncrypt(dto.getPhoneD());
+            target.setPhoneEncrypt(dto.getPhone());
+            target.setHomePhoneEncrypt(dto.getHomePhone());
+            target.setMobilePhoneEncrypt(dto.getMobilePhone());
+            target.setOtherPhoneEncrypt(dto.getOtherPhone());
+
+
+            DesensitiveUtils.format(target);
+            respList.add(target);
+        });
+        dtoCacheList.setData(dtoItemList);
+        String updateJsonString = JSONArray.toJSONString(dtoCacheList);
+        String updateKey = PIPL_UNCONFIRM_UPDATE + txId;
+        boolean redisFlag = redisUtil.set(updateKey, updateJsonString,GlobalConst.DATA_EXPIRE);
+        if (!redisFlag) {
+            throw new BizException("缂撳瓨鍐欏叆澶辫触");
+        }
+        return respList;
+    }
+
+    public Boolean deleteOne(String dataId) {
+        Contact contact = Contact.dao.findById(dataId);
+        contact.setIsDelete(1);
+        return contact.saveOrUpdate();
+    }
+
+    public Boolean undeleteOne(String dataId) {
+        Contact contact = Contact.dao.findById(dataId);
+        contact.setIsDelete(0);
+        return contact.saveOrUpdate();
+    }
+
+    public List<ContactDto> searchList(ContactSearchDto searchDto) {
+        List<String> dataIds = searchDto.getDataIds();
+        String contactName = searchDto.getContactName();
+        StringBuilder queryParam = new StringBuilder();
+        if (CollectionUtil.isEmpty(dataIds) && StringUtils.isEmpty(contactName)) {
+            //鍙傛暟閮戒负绌猴紝鐩存帴杩斿洖Null
+            return null;
+        } else {
+            if(CollectionUtil.isNotEmpty(dataIds)){
+                queryParam.append("and id in").append(dataIds.stream().collect(Collectors.joining(", ", "(", ")")));
+            }
+            if(StringUtils.isNotEmpty(contactName)) {
+                queryParam.append("and last_name like ").append("\'%").append(contactName).append("%\'");
+            }
+            List<Contact> contactList = Contact.dao.findList(queryParam.toString());
+            return contactList.stream()
+                    .map(contact -> BeanHelper.copyAs(contact,ContactDto.class)).collect(Collectors.toList());
+        }
+    }
+
+    public List<ContactDto> decryptUpdate(List<ContactDto> contactList) {
+        List<ContactDto> respList =new ArrayList<>();
+        String[] decryptColumn =new String[]{"first_name","last_name","postcode","postcode_d","title_d","title","phone","address3_d","address2_d","address1_d","address3","address2","address1",
+        "english_address","contact_english_name","other_phone","mobile_phone","home_phone","phone_d","other_phone_d","mobile_phone_d","email","email_d","fax_d","fax"};
+        Db.tx(() -> {
+            for (ContactDto e : contactList) {
+                Contact contact =Contact.dao.findById(e.getDataId());
+                if (contact == null) {
+                    throw new BizException("鏃犳晥鐨凞ataId");
+                }
+                Contact item=new Contact();
+                BeanHelper.copyEncrypt(e,item);
+                cryptoService.decryptoColumnModel(item,decryptColumn);
+                BeanHelper.copy(item, contact);
+                contact.setSfRecordId(e.getSfRecordId());
+                if (!contact.saveOrUpdate()) {
+                    throw new BizException(ResultCodeEnum.RT_ERROR);
+                }
+
+                respList.add(e);
+            }
+            return true;
+        });
+        return respList;
+    }
+
+}
diff --git a/src/main/java/com/deloitte/system/service/FileService.java b/src/main/java/com/deloitte/system/service/FileService.java
new file mode 100644
index 0000000..3c87b73
--- /dev/null
+++ b/src/main/java/com/deloitte/system/service/FileService.java
@@ -0,0 +1,377 @@
+package com.deloitte.system.service;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSONArray;
+import com.common.aws.util.S3Util;
+import com.common.core.constant.GlobalConst;
+import com.common.core.enums.ResultCodeEnum;
+import com.common.core.exception.BizException;
+import com.common.core.utils.UUID;
+import com.common.core.utils.*;
+import com.common.redis.util.RedisUtil;
+import com.deloitte.system.request.FileRequest;
+import com.j256.simplemagic.ContentInfoUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.codec.binary.Base64;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.MediaType;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+import software.amazon.awssdk.core.ResponseBytes;
+import software.amazon.awssdk.services.s3.model.GetObjectResponse;
+import software.amazon.awssdk.services.s3.model.S3Exception;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.bind.DatatypeConverter;
+import java.io.*;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+import static com.common.core.constant.GlobalConst.PIPL_UNCONFIRM_FILE;
+
+@Slf4j
+@Service
+public class FileService {
+    @Autowired
+    private RedisUtil redisUtil;
+    @Value("${salesforce.referer}")
+    private String refererUrl;
+    @Value("${aws.s3.bucketName}")
+    private String bucketName;
+
+    public String upload(String txId,FileRequest fileRequest){
+        log.info("涓婁紶鏂囦欢txId:"+txId);
+        String key=uploadFile(fileRequest);
+        String keyName = PIPL_UNCONFIRM_FILE + txId;
+        redisUtil.set(keyName, new JSONArray(Arrays.asList(key)), GlobalConst.DATA_EXPIRE);
+        return key;
+    }
+
+    public List<String> batchUpload(String txId, List<FileRequest> fileList) {
+        log.info("涓婁紶鏂囦欢txId:"+txId);
+        List<String> keys=new ArrayList<>();
+        try {
+            fileList.forEach(fileRequest -> {
+                String key = uploadFile(fileRequest);
+                keys.add(key);
+            });
+            String keyName = PIPL_UNCONFIRM_FILE + txId;
+            redisUtil.set(keyName, new JSONArray((List)keys), GlobalConst.DATA_EXPIRE);
+        }catch (Exception e){
+            this.cleanS3File(keys);
+            throw e;
+        }
+        return keys;
+    }
+
+    public String uploadFile(FileRequest fileRequest){
+        if (fileRequest == null) {
+            throw new BizException(ResultCodeEnum.NO_DATA);
+        }
+        log.info("fileName:{}", fileRequest.getFileName());
+        //鏂囦欢澶у皬闄愬埗锛屾渶澶у崟鏂囦欢30M
+        if(fileRequest.getSize()>31457280){
+            throw new BizException(ResultCodeEnum.FILE_SIZE_EXCEED);
+        }
+        if(fileRequest.getFile().startsWith("base64,")){
+            String contentType= ContentInfoUtil.findExtensionMatch(fileRequest.getFileName())==null?
+                    "text/plain": ContentInfoUtil.findExtensionMatch(fileRequest.getFileName()).getMimeType();
+            fileRequest.setFile("data:"+contentType+";"+fileRequest.getFile());
+        }
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
+        String oldFileName = fileRequest.getFileName();
+        String suffix=oldFileName.lastIndexOf(".")==-1?"":oldFileName.substring(oldFileName.lastIndexOf("."));
+        String newFileName = UUID.randomUUID().toString().replace("-","")+suffix;
+        String key = sdf.format(new Date()) + "/" + newFileName;
+        // 灏嗘枃浠禸ase64瀛樺叆缂撳瓨
+        MultipartFile multipartFile = null;
+        try {
+            multipartFile = BASE64DecodedMultipartFile.base64ToMultipart(fileRequest.getFile());
+        } catch (IOException e) {
+            log.error("涓婁紶鏂囦欢澶辫触锛�",e);
+        }
+        if (multipartFile == null) {
+            throw new BizException("鏈壘鍒版枃浠�");
+        }
+        String bucketName = SpringContextUtils.getEnvParam("aws.s3.bucketName");
+        S3Util.uploadFile(multipartFile, key,bucketName);
+        return key;
+    }
+
+    public String uploadFileNoSize(FileRequest fileRequest){
+        if (fileRequest == null) {
+            throw new BizException(ResultCodeEnum.NO_DATA);
+        }
+        log.info("fileName:{}", fileRequest.getFileName());
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
+        String oldFileName = fileRequest.getFileName();
+        String suffix=oldFileName.lastIndexOf(".")==-1?"":oldFileName.substring(oldFileName.lastIndexOf("."));
+        String newFileName = UUID.randomUUID().toString().replace("-","")+suffix;
+        String key = sdf.format(new Date()) + "/" + newFileName;
+        // 灏嗘枃浠禸ase64瀛樺叆缂撳瓨
+        MultipartFile multipartFile = null;
+        try {
+            multipartFile = BASE64DecodedMultipartFile.base64ToMultipart(fileRequest.getFile());
+        } catch (IOException e) {
+            log.error("涓婁紶鏂囦欢澶辫触锛�",e);
+        }
+        if (multipartFile == null) {
+            throw new BizException("鏈壘鍒版枃浠�");
+        }
+        String bucketName = SpringContextUtils.getEnvParam("aws.s3.bucketName");
+        S3Util.uploadFile(multipartFile, key,bucketName);
+        return key;
+    }
+
+    public void cleanS3File(Collection<String> keyList){
+        if (!keyList.isEmpty()){
+            String bucketName = SpringContextUtils.getEnvParam("aws.s3.bucketName");
+            S3Util.deleteByKeys(new ArrayList<String>(keyList),bucketName);
+        }
+    }
+
+    private boolean checkReferer(String referer){
+        String[] refererUrls=refererUrl.split(",");
+        for (String str : refererUrls) {
+            if(str.equalsIgnoreCase(referer)||str.substring(0,str.length()-1).equalsIgnoreCase(referer)){
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public void preview(HttpServletRequest request,HttpServletResponse response,String key){
+        String referer = request.getHeader("Referer");
+        if (StrUtil.isBlank(referer)) {
+            throw new BizException(ResultCodeEnum.NO_PERMISSION);
+        }
+        //referer 鎴彇
+        String replace = referer.replace("https://", "");
+        String newReferer = "https://"+replace.substring(0, replace.indexOf("/")+1);
+        if (!checkReferer(newReferer)) {
+            throw new BizException(ResultCodeEnum.NO_PERMISSION);
+        }
+        String fileName = key.substring(key.lastIndexOf("/")+1);
+        log.info("鏂囦欢棰勮key:{},fileName:{}",key,fileName);
+        OutputStream out = null;
+        try {
+            response.setCharacterEncoding("utf-8");
+            String s = ContentInfoUtil.findExtensionMatch(fileName).getMimeType();
+            log.info("鏂囦欢棰勮key:{},contentType:{}",key,s);
+            if (StrUtil.isNotBlank(s)) {
+                response.setContentType(s);
+            } else{
+                response.setContentType(MediaType.ALL_VALUE);
+            }
+            String agent = request.getHeader("User-Agent");
+            if(agent.toLowerCase().contains("firefox")) {
+                response.setHeader("Content-Disposition", "inline; filename==?UTF-8?B?" + new String(Base64.encodeBase64(fileName.getBytes("UTF-8")))+"?=");
+            }else {
+                response.setHeader("Content-Disposition", "inline; filename=" +  new String(fileName.getBytes("gbk"),"iso8859-1"));
+            }
+            ResponseBytes<GetObjectResponse> objectBytes = S3Util.downloadFile(key,bucketName);
+            InputStream inputStream = objectBytes.asInputStream();
+            BufferedInputStream bufInputStream = new BufferedInputStream(inputStream);
+            out = response.getOutputStream();
+            byte[] buf = new byte[1024];
+            int len;
+            while ((len = bufInputStream.read(buf)) > 0) {
+                out.write(buf, 0, len);
+            }
+            response.flushBuffer();
+            out.close();
+        } catch (IOException e) {
+            log.error("鏂囦欢棰勮澶辫触锛�",e);
+            throw new BizException(ResultCodeEnum.RT_ERROR);
+        }catch (S3Exception e) {
+            log.error("鏂囦欢棰勮澶辫触锛�",e);
+            throw new BizException(e.getMessage());
+        }
+
+    }
+    
+    public void download(HttpServletRequest request,HttpServletResponse response,String key){
+        String referer = request.getHeader("Referer");
+
+        log.info("referer:"+referer);
+
+        if (StrUtil.isBlank(referer)) {
+            throw new BizException(ResultCodeEnum.NO_PERMISSION);
+        }
+        //referer 鎴彇
+        String replace = referer.replace("https://", "");
+        String newReferer = "https://"+replace.substring(0, replace.indexOf("/")+1);
+        if (!checkReferer(newReferer)) {
+            throw new BizException(ResultCodeEnum.NO_PERMISSION);
+        }
+
+        OutputStream out = null;
+        try {
+            String fileName = request.getParameter("fileName");
+            if (StrUtil.isBlank(fileName)) {
+                throw new BizException("fileName涓嶈兘涓虹┖");
+            }
+            log.info("鏂囦欢涓嬭浇key:{},fileName:{}",key,fileName);
+            response.setHeader("Pragma", "No-cache");
+            response.setHeader("Cache-Control", "No-cache");
+            response.setDateHeader("Expires", 0);
+            response.setContentType("application/octet-stream");
+            String agent = request.getHeader("User-Agent");
+            if (null != agent && agent.contains("MSIE") || null != agent && agent.contains("Trident") || null != agent && agent.contains("Edge")) {
+                // ie娴忚鍣ㄥ強Edge娴忚鍣�
+               fileName = java.net.URLEncoder.encode(fileName, "UTF-8");
+            } else if (null != agent && agent.contains("Mozilla")) {
+                // 鐏嫄,Chrome绛夋祻瑙堝櫒
+                fileName = new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
+            }else {
+                // 鍏跺畠娴忚鍣�
+                fileName = URLEncoder.encode(fileName, "utf-8");
+            }
+            response.setHeader("Content-Disposition", "attachment; filename="+fileName);
+            ResponseBytes<GetObjectResponse> objectBytes = S3Util.downloadFile(key,bucketName);
+            InputStream inputStream = objectBytes.asInputStream();
+            BufferedInputStream bufInputStream = new BufferedInputStream(inputStream);
+            out = response.getOutputStream();
+            byte[] buf = new byte[1024];
+            int len;
+            while ((len = bufInputStream.read(buf)) > 0) {
+                out.write(buf, 0, len);
+            }
+            response.flushBuffer();
+            out.close();
+        } catch (IOException e) {
+            log.error("鏂囦欢涓嬭浇澶辫触锛�",e);
+            throw new BizException(ResultCodeEnum.RT_ERROR);
+        }catch (S3Exception e) {
+            log.error("鏂囦欢涓嬭浇澶辫触锛�",e);
+            throw new BizException(e.getMessage());
+        }
+
+    }
+
+    public void deleteFile(List<String> keys){
+        if (CollUtil.isEmpty(keys)) {
+            throw new BizException(ResultCodeEnum.NO_DATA);
+        }
+        String bucketName = SpringContextUtils.getEnvParam("aws.s3.bucketName");
+        S3Util.deleteByKeys(keys,bucketName);
+    }
+
+    public void convert(HttpServletRequest request,HttpServletResponse response) {
+        //浠巔aram鍙傛暟涓幏鍙杅ileName,濡傛灉涓虹┖鍒欏彇褰撳墠鏃堕棿涓烘枃浠跺悕
+        String fileName = request.getParameter("fileName");
+        fileName = fileName==null? DateUtils.format(new Date()) : fileName;
+        response.setContentType("application/pdf");
+        //瑕佷繚瀛樼殑鏂囦欢鍚�
+        response.setHeader("Content-Disposition", "inline;filename=" + fileName + ".pdf");
+        response.addHeader("Pargam", "no-cache");
+        response.addHeader("Cache-Control", "no-cache");
+
+        ServletOutputStream outputStream = null;
+        BufferedReader bufferReader=null;
+        String base64Str="";
+        try {
+            if(StringUtils.isNotBlank(request.getParameter("base64Str"))){
+                base64Str=request.getParameter("base64Str");
+            }else {
+                bufferReader = new BufferedReader(request.getReader());
+                StringBuilder sb = new StringBuilder();
+                String line = null;
+                while ((line = bufferReader.readLine()) != null) {
+                    sb.append(line);
+                }
+                String body = sb.toString();
+                String[] strings = body.split("&");
+                Map<String, String> valueMap = new HashMap<>();
+                for (String string : strings) {
+                    String[] keyValue = string.split("=", 2);
+                    String key = keyValue[0];
+                    String value = keyValue[1];
+                    valueMap.put(URLDecoder.decode(key, "UTF-8"), URLDecoder.decode(value, "UTF-8"));
+                }
+                base64Str = valueMap.get("base64Str");
+            }
+            outputStream = response.getOutputStream();
+            byte[] b = DatatypeConverter.parseBase64Binary(base64Str);
+            outputStream.write(b, 0, b.length);
+        } catch (IOException e) {
+            log.error("鏂囦欢杞崲寮傚父锛�",e);
+            throw new BizException(ResultCodeEnum.RT_ERROR);
+        }finally {
+            try {
+                if(bufferReader!=null)bufferReader.close();
+            } catch (IOException e) {
+            }
+        }
+    }
+
+    public static String getFilecharset(InputStream inputStream) {
+        //榛樿GBK
+        String charset = "GBK";
+        byte[] first3Bytes = new byte[3];
+        try(BufferedInputStream bis = new BufferedInputStream(inputStream)) {
+            bis.mark(0);
+            int read = bis.read(first3Bytes, 0, 3);
+            // 鏂囦欢缂栫爜涓� ANSI
+            if (read == -1) {
+                return charset;
+            }
+            // 鏂囦欢缂栫爜涓� Unicode
+            if (first3Bytes[0] == (byte) 0xFF && first3Bytes[1] == (byte) 0xFE) {
+                return  "UTF-16LE";
+            }
+            // 鏂囦欢缂栫爜涓� Unicode big endian
+            if (first3Bytes[0] == (byte) 0xFE && first3Bytes[1] == (byte) 0xFF) {
+                return "UTF-16BE";
+            }
+            // 鏂囦欢缂栫爜涓� UTF-8
+            if (first3Bytes[0] == (byte) 0xEF && first3Bytes[1] == (byte) 0xBB && first3Bytes[2] == (byte) 0xBF) {
+                return "UTF-8";
+            }
+            bis.reset();
+
+            int loc = 0;
+            while ((read = bis.read()) != -1) {
+                loc++;
+                if (read >= 0xF0) {
+                    break;
+                }
+                // 鍗曠嫭鍑虹幇BF浠ヤ笅鐨勶紝涔熺畻鏄疓BK
+                if (0x80 <= read && read <= 0xBF) {
+                    break;
+                }
+                if (0xC0 <= read && read <= 0xDF) {
+                    read = bis.read();
+                    // 鍙屽瓧鑺� (0xC0 - 0xDF)
+                    if (0x80 <= read && read <= 0xBF) {
+                        // (0x80
+                        // - 0xBF),涔熷彲鑳藉湪GB缂栫爜鍐�
+                        continue;
+                    }
+                    break;
+                }
+                // 涔熸湁鍙兘鍑洪敊锛屼絾鏄嚑鐜囪緝灏�
+                if (0xE0 <= read && read <= 0xEF) {
+                    read = bis.read();
+                    if (0x80 <= read && read <= 0xBF) {
+                        read = bis.read();
+                        if (0x80 <= read && read <= 0xBF) {
+                            charset = "UTF-8";
+                        }
+                    }
+                    break;
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return charset;
+    }
+}
diff --git a/src/main/java/com/deloitte/system/service/LoanerApplicationService.java b/src/main/java/com/deloitte/system/service/LoanerApplicationService.java
new file mode 100644
index 0000000..1d6248f
--- /dev/null
+++ b/src/main/java/com/deloitte/system/service/LoanerApplicationService.java
@@ -0,0 +1,149 @@
+package com.deloitte.system.service;
+
+
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.alibaba.fastjson.JSONArray;
+import com.common.core.constant.GlobalConst;
+import com.common.core.exception.BizException;
+import com.common.core.service.CryptoService;
+import com.common.core.utils.BeanHelper;
+import com.common.core.utils.DesensitiveUtils;
+import com.common.core.utils.IdUtils;
+import com.common.core.utils.StringUtils;
+import com.common.redis.util.RedisUtil;
+import com.deloitte.system.model.CacheList;
+import com.deloitte.system.model.LoanerApplication;
+import com.deloitte.system.model.Repair;
+import com.deloitte.system.request.ContactSearchDto;
+import com.deloitte.system.request.LoanerApplicationDto;
+import com.deloitte.system.request.SearchDto;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static com.common.core.constant.GlobalConst.PIPL_UNCONFIRM_INSERT;
+import static com.common.core.constant.GlobalConst.PIPL_UNCONFIRM_UPDATE;
+
+@Service
+public class LoanerApplicationService {
+    private String tableName = "loaner_application";
+
+    @Autowired
+    private CryptoService cryptoService;
+
+    @Autowired
+    private IdUtils idWorker;
+
+    @Autowired
+    private RedisUtil redisUtil;
+
+    public LoanerApplicationDto queryForOne(String dataId) {
+        LoanerApplication loanerApplication = LoanerApplication.dao.findById(dataId);
+        if (!ObjectUtil.isEmpty(loanerApplication)) {
+           LoanerApplicationDto dto =  BeanHelper.copyAs(loanerApplication,LoanerApplicationDto.class);
+        return  dto;
+        }
+        return null;
+    }
+
+    public List<LoanerApplicationDto> insertList(List<LoanerApplicationDto> loanerApplicationList, String txId) {
+        List<LoanerApplicationDto> respList = new ArrayList<>();
+        CacheList<LoanerApplicationDto> dtoCacheList = new CacheList<>();
+        dtoCacheList.setTableName(tableName);
+        List<LoanerApplicationDto> dtoItemList = new ArrayList<>();
+        loanerApplicationList.forEach(e -> {
+            String dataId = idWorker.nextId();
+            LoanerApplicationDto cacheItem = BeanHelper.copyAs(e, LoanerApplicationDto.class);
+            cacheItem.setDataId(dataId);
+            dtoItemList.add(cacheItem);
+
+            LoanerApplicationDto target = BeanHelper.copyAs(e, LoanerApplicationDto.class);
+            target.setDataId(dataId);
+            LoanerApplicationDto dto = cryptoService.encryptModelColumns(e);
+            dto.setDataId(dataId);
+            cryptoService.convertor(dto,target);
+            DesensitiveUtils.format(target);
+            respList.add(target);
+        });
+        dtoCacheList.setData(dtoItemList);
+        String insertJsonString = JSONArray.toJSONString(dtoCacheList);
+        String insertKey = PIPL_UNCONFIRM_INSERT + txId;
+        boolean redisFlag = redisUtil.set(insertKey, insertJsonString,GlobalConst.DATA_EXPIRE);
+        if (!redisFlag) {
+            throw new BizException("缂撳瓨鍐欏叆澶辫触");
+        }
+        return respList;
+    }
+
+    public List<LoanerApplicationDto> updateList(List<LoanerApplicationDto> loanerApplicationList, String txId) {
+        List<LoanerApplicationDto> respList = new ArrayList<>();
+        CacheList<LoanerApplicationDto> dtoCacheList = new CacheList<>();
+        dtoCacheList.setTableName(tableName);
+        List<LoanerApplicationDto> dtoItemList = new ArrayList<>();
+        loanerApplicationList.forEach(e -> {
+            LoanerApplication loanerApplication = LoanerApplication.dao.findById(e.getDataId());
+            LoanerApplicationDto cacheItem = BeanHelper.copyAs(e, LoanerApplicationDto.class);
+            dtoItemList.add(cacheItem);
+            LoanerApplicationDto dto = BeanHelper.copyAs(BeanHelper.copy(cacheItem,loanerApplication),LoanerApplicationDto.class);
+            LoanerApplicationDto target = BeanHelper.copyAs(dto, LoanerApplicationDto.class);
+            dto = cryptoService.encryptModelColumns(dto);
+            target.setApplyPersonEncrypt(dto.getApplyPerson());
+            target.setApplyPersonPhoneEncrypt(dto.getApplyPersonPhone());
+            target.setApplicantMailboxEncrypt(dto.getApplicantMailbox());
+            target.setLoanerReceiveStaffEncrypt(dto.getLoanerReceiveStaff());
+            target.setDirectShippmentAddressEncrypt(dto.getDirectShippmentAddress());
+            target.setLoanerReceiveStaffPhoneEncrypt(dto.getLoanerReceiveStaffPhone());
+            target.setReturnTrakeStaffEncrypt(dto.getReturnTrakeStaff());
+            target.setReturnNumberEncrypt(dto.getReturnNumber());
+            target.setPostCodeEncrypt(dto.getPostCode());
+            target.setLoanerSerEncrypt(dto.getLoanerSer());
+            DesensitiveUtils.format(target);
+            respList.add(target);
+        });
+        dtoCacheList.setData(dtoItemList);
+        String updateJsonString = JSONArray.toJSONString(dtoCacheList);
+        String updateKey = PIPL_UNCONFIRM_UPDATE + txId;
+        boolean redisFlag = redisUtil.set(updateKey, updateJsonString,GlobalConst.DATA_EXPIRE);
+        if (!redisFlag) {
+            throw new BizException("缂撳瓨鍐欏叆澶辫触");
+        }
+        return respList;
+    }
+
+    public Boolean deleteOne(String dataId) {
+        LoanerApplication loanerApplication = LoanerApplication.dao.findById(dataId);
+        loanerApplication.setIsDelete(1);
+        return loanerApplication.saveOrUpdate();
+    }
+
+    public Boolean undeleteOne(String dataId) {
+        LoanerApplication loanerApplication = LoanerApplication.dao.findById(dataId);
+        loanerApplication.setIsDelete(0);
+        return loanerApplication.saveOrUpdate();
+    }
+
+    public List<LoanerApplicationDto> searchList(SearchDto searchDto) {
+        List<String> dataIds = searchDto.getDataIds();
+        String contactName = searchDto.getName();
+        StringBuilder queryParam = new StringBuilder();
+        if (CollectionUtil.isEmpty(dataIds) && StringUtils.isEmpty(contactName)) {
+            //鍙傛暟閮戒负绌猴紝鐩存帴杩斿洖Null
+            return null;
+        } else {
+            if(CollectionUtil.isNotEmpty(dataIds)){
+                queryParam.append("and id in").append(dataIds.stream().collect(Collectors.joining(", ", "(", ")")));
+            }
+            if(StringUtils.isNotEmpty(contactName)) {
+                queryParam.append("and apply_person like ").append("\'%").append(contactName).append("%\'");
+            }
+            List<LoanerApplication> contactList = LoanerApplication.dao.findList(queryParam.toString());
+            return contactList.stream()
+                    .map(contact -> BeanHelper.copyAs(contact,LoanerApplicationDto.class)).collect(Collectors.toList());
+        }
+    }
+}
diff --git a/src/main/java/com/deloitte/system/service/LoanerUserService.java b/src/main/java/com/deloitte/system/service/LoanerUserService.java
new file mode 100644
index 0000000..5279a50
--- /dev/null
+++ b/src/main/java/com/deloitte/system/service/LoanerUserService.java
@@ -0,0 +1,128 @@
+package com.deloitte.system.service;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.alibaba.fastjson.JSONArray;
+import com.common.core.constant.GlobalConst;
+import com.common.core.exception.BizException;
+import com.common.core.service.CryptoService;
+import com.common.core.utils.BeanHelper;
+import com.common.core.utils.DesensitiveUtils;
+import com.common.core.utils.IdUtils;
+import com.common.redis.util.RedisUtil;
+import com.deloitte.system.model.CacheList;
+import com.deloitte.system.model.LoanerUser;
+import com.deloitte.system.request.LoanerUserDto;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static com.common.core.constant.GlobalConst.PIPL_UNCONFIRM_INSERT;
+import static com.common.core.constant.GlobalConst.PIPL_UNCONFIRM_UPDATE;
+@Service
+public class LoanerUserService {
+    private String tableName="loaner_user";
+
+    @Autowired
+    private CryptoService cryptoService;
+
+    @Autowired
+    private IdUtils idWorker;
+
+    @Autowired
+    private RedisUtil redisUtil;
+
+    public LoanerUserDto queryForOne(String dataId) {
+        LoanerUser loanerUser =LoanerUser.dao.findById(dataId);
+        if (!ObjectUtil.isEmpty(loanerUser)){
+            LoanerUserDto dto = BeanHelper.copyAs(loanerUser, LoanerUserDto.class);
+            return dto;
+        }
+        return null;
+    }
+
+    public List<LoanerUserDto> insertList(List<LoanerUserDto> loanerUserDtoList, String txId) {
+        List<LoanerUserDto> respList = new ArrayList<>();
+        CacheList<LoanerUserDto> dtoCacheList = new CacheList<>();
+        dtoCacheList.setTableName(tableName);
+        List<LoanerUserDto> dtoItemList = new ArrayList<>();
+        loanerUserDtoList.forEach(e -> {
+            String dataId = idWorker.nextId();
+            LoanerUserDto cacheItem = BeanHelper.copyAs(e, LoanerUserDto.class);
+            cacheItem.setDataId(dataId);
+            dtoItemList.add(cacheItem);
+            LoanerUserDto target = BeanHelper.copyAs(e, LoanerUserDto.class);
+            target.setDataId(dataId);
+            LoanerUserDto dto =  cryptoService.encryptModelColumns(e);
+            dto.setDataId(dataId);
+            target.setContactEncrypt(dto.getContact());
+            target.setContactNumberEncrypt(dto.getContactNumber());
+            DesensitiveUtils.format(target);
+            respList.add(target);
+        });
+        dtoCacheList.setData(dtoItemList);
+        String insertJsonString = JSONArray.toJSONString(dtoCacheList);
+        String insertKey = PIPL_UNCONFIRM_INSERT + txId;
+        boolean redisFlag = redisUtil.set(insertKey, insertJsonString, GlobalConst.DATA_EXPIRE);
+        if (!redisFlag){
+            throw new BizException("缂撳瓨鍐欏叆澶辫触");
+        }
+        return respList;
+    }
+
+    public List<LoanerUserDto> updateList(List<LoanerUserDto> loanerUserDtoList, String txId) {
+        List<LoanerUserDto> respList = new ArrayList<>();
+        CacheList<LoanerUserDto> dtoCacheList = new CacheList<>();
+        dtoCacheList.setTableName(tableName);
+        List<LoanerUserDto> dtoItemList = new ArrayList<>();
+        loanerUserDtoList.forEach(e -> {
+            LoanerUser loanerUser = LoanerUser.dao.findById(e.getDataId());
+            LoanerUserDto cacheItem = BeanHelper.copyAs(e, LoanerUserDto.class);
+            dtoItemList.add(cacheItem);
+            LoanerUserDto dto = BeanHelper.copyAs(BeanHelper.copy(cacheItem,loanerUser),LoanerUserDto.class);
+            LoanerUserDto target = BeanHelper.copyAs(dto, LoanerUserDto.class);
+            dto = cryptoService.encryptModelColumns(dto);
+            target.setContactEncrypt(dto.getContact());
+            target.setContactNumberEncrypt(dto.getContactNumber());
+            DesensitiveUtils.format(target);
+            respList.add(target);
+        });
+        dtoCacheList.setData(dtoItemList);
+        String updateJsonString = JSONArray.toJSONString(dtoCacheList);
+        String updateKey = PIPL_UNCONFIRM_UPDATE + txId;
+        boolean redisFlag = redisUtil.set(updateKey, updateJsonString,GlobalConst.DATA_EXPIRE);
+        if (!redisFlag){
+            throw new BizException("缂撳瓨鍐欏叆澶辫触");
+        }
+        return respList;
+    }
+
+    public Boolean deleteOne(String dataId) {
+        LoanerUser loanerUser = LoanerUser.dao.findById(dataId);
+        loanerUser.setIsDelete(1);
+        return loanerUser.saveOrUpdate();
+    }
+
+    public Boolean undeleteOne(String dataId) {
+        LoanerUser loanerUser = LoanerUser.dao.findById(dataId);
+        loanerUser.setIsDelete(0);
+        return loanerUser.saveOrUpdate();
+    }
+
+
+    public List<LoanerUserDto> search(List<String> idList){
+        if (CollUtil.isEmpty(idList)) {
+            return null;
+        }
+        StringBuilder queryParam = new StringBuilder();
+        queryParam.append("and id in ").append(idList.stream().collect(Collectors.joining(", ", "(", ")")));
+        List<LoanerUser> loanerUsers = LoanerUser.dao.findList(queryParam.toString());
+        return loanerUsers.stream()
+                .map(loanerUser -> BeanHelper.copyAs(loanerUser, LoanerUserDto.class)).collect(Collectors.toList());
+
+    }
+
+}
diff --git a/src/main/java/com/deloitte/system/service/MailMergeService.java b/src/main/java/com/deloitte/system/service/MailMergeService.java
new file mode 100644
index 0000000..8090899
--- /dev/null
+++ b/src/main/java/com/deloitte/system/service/MailMergeService.java
@@ -0,0 +1,153 @@
+package com.deloitte.system.service;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.alibaba.fastjson.JSONArray;
+import com.common.core.constant.GlobalConst;
+import com.common.core.exception.BizException;
+import com.common.core.service.CryptoService;
+import com.common.core.utils.BeanHelper;
+import com.common.core.utils.DesensitiveUtils;
+import com.common.core.utils.IdUtils;
+import com.common.redis.util.RedisUtil;
+import com.deloitte.system.model.CacheList;
+import com.deloitte.system.model.MailMerge;
+import com.deloitte.system.request.MailMergeDto;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static com.common.core.constant.GlobalConst.PIPL_UNCONFIRM_INSERT;
+import static com.common.core.constant.GlobalConst.PIPL_UNCONFIRM_UPDATE;
+
+@Service
+public class MailMergeService {
+
+    private String tableName="mail_merge";
+
+    @Autowired
+    private CryptoService cryptoService;
+
+    @Autowired
+    private IdUtils idWorker;
+
+    @Autowired
+    private RedisUtil redisUtil;
+
+    public MailMergeDto queryForOne(String dataId) {
+        MailMerge mailMerge =MailMerge.dao.findById(dataId);
+        if (!ObjectUtil.isEmpty(mailMerge)){
+            MailMergeDto dto = BeanHelper.copyAs(mailMerge, MailMergeDto.class);
+            return dto;
+        }
+        return null;
+
+    }
+
+    public List<MailMergeDto> insertList(List<MailMergeDto> mailMergeDtoList, String txId) {
+        List<MailMergeDto> respList = new ArrayList<>();
+        CacheList<MailMergeDto> dtoCacheList = new CacheList<>();
+        dtoCacheList.setTableName(tableName);
+        List<MailMergeDto> dtoItemList = new ArrayList<>();
+        mailMergeDtoList.forEach(e -> {
+            String dataId = idWorker.nextId();
+            MailMergeDto cacheItem = BeanHelper.copyAs(e, MailMergeDto.class);
+            cacheItem.setDataId(dataId);
+            dtoItemList.add(cacheItem);
+
+            MailMergeDto target = BeanHelper.copyAs(e, MailMergeDto.class);
+            target.setDataId(dataId);
+            MailMergeDto dto = cryptoService.encryptModelColumns(e);
+            dto.setDataId(dataId);
+            target.setCcEncrypt(dto.getCc());
+            target.setBccEncrypt(dto.getBcc());
+            target.setAuthorEncrypt(dto.getAuthor());
+            target.setAllMemberEncrypt(dto.getAllMember());
+            target.setToNameEncrypt(dto.getToName());
+            target.setAllMemberNameEncrypt(dto.getAllMemberName());
+            target.setCcNameEncrypt(dto.getCcName());
+            target.setBccNameEncrypt(dto.getBccName());
+            target.setRecipientEncrypt(dto.getRecipient());
+            target.setPremaryRecipientEncrypt(dto.getPremaryRecipient());
+            target.setSendEncrypt(dto.getSend());
+            target.setFromEncrypt(dto.getFrom());
+            target.setMessageEncrypt(dto.getMessage());
+            DesensitiveUtils.format(target);
+            respList.add(target);
+        });
+        dtoCacheList.setData(dtoItemList);
+        String insertJsonString = JSONArray.toJSONString(dtoCacheList);
+        String insertKey = PIPL_UNCONFIRM_INSERT + txId;
+        boolean redisFlag = redisUtil.set(insertKey, insertJsonString, GlobalConst.DATA_EXPIRE);
+        if (!redisFlag){
+            throw new BizException("缂撳瓨鍐欏叆澶辫触");
+        }
+        return respList;
+    }
+
+    public List<MailMergeDto> updateList(List<MailMergeDto> mailMergeDtoList, String txId) {
+        List<MailMergeDto> respList = new ArrayList<>();
+        CacheList<MailMergeDto> dtoCacheList = new CacheList<>();
+        dtoCacheList.setTableName(tableName);
+        List<MailMergeDto> dtoItemList = new ArrayList<>();
+        mailMergeDtoList.forEach(e -> {
+            MailMerge mailMerge = MailMerge.dao.findById(e.getDataId());
+            MailMergeDto cacheItem = BeanHelper.copyAs(e, MailMergeDto.class);
+            dtoItemList.add(cacheItem);
+            MailMergeDto dto = BeanHelper.copyAs(BeanHelper.copy(cacheItem,mailMerge),MailMergeDto.class);
+            MailMergeDto target = BeanHelper.copyAs(dto, MailMergeDto.class);
+            dto = cryptoService.encryptModelColumns(dto);
+            target.setCcEncrypt(dto.getCc());
+            target.setBccEncrypt(dto.getBcc());
+            target.setAuthorEncrypt(dto.getAuthor());
+            target.setAllMemberEncrypt(dto.getAllMember());
+            target.setToNameEncrypt(dto.getToName());
+            target.setAllMemberNameEncrypt(dto.getAllMemberName());
+            target.setCcNameEncrypt(dto.getCcName());
+            target.setBccNameEncrypt(dto.getBccName());
+            target.setRecipientEncrypt(dto.getRecipient());
+            target.setPremaryRecipientEncrypt(dto.getPremaryRecipient());
+            target.setSendEncrypt(dto.getSend());
+            target.setFromEncrypt(dto.getFrom());
+            target.setMessageEncrypt(dto.getMessage());
+            DesensitiveUtils.format(target);
+            respList.add(target);
+        });
+        dtoCacheList.setData(dtoItemList);
+        String updateJsonString = JSONArray.toJSONString(dtoCacheList);
+        String updateKey = PIPL_UNCONFIRM_UPDATE + txId;
+        boolean redisFlag = redisUtil.set(updateKey, updateJsonString,GlobalConst.DATA_EXPIRE);
+        if (!redisFlag){
+            throw new BizException("缂撳瓨鍐欏叆澶辫触");
+        }
+        return respList;
+    }
+
+    public Boolean deleteOne(String dataId) {
+        MailMerge mailMerge = MailMerge.dao.findById(dataId);
+        mailMerge.setIsDelete(1);
+        return mailMerge.saveOrUpdate();
+    }
+
+    public Boolean undeleteOne(String dataId) {
+        MailMerge mailMerge = MailMerge.dao.findById(dataId);
+        mailMerge.setIsDelete(0);
+        return mailMerge.saveOrUpdate();
+    }
+
+    public List<MailMergeDto> search(List<String> idList){
+        if (CollUtil.isEmpty(idList)) {
+            return null;
+        }
+        StringBuilder queryParam = new StringBuilder();
+        queryParam.append("and id in ").append(idList.stream().collect(Collectors.joining(", ", "(", ")")));
+        List<MailMerge> quotesList = MailMerge.dao.findList(queryParam.toString());
+        return quotesList.stream()
+                .map(quotes -> BeanHelper.copyAs(quotes, MailMergeDto.class)).collect(Collectors.toList());
+
+    }
+}
diff --git a/src/main/java/com/deloitte/system/service/MailService.java b/src/main/java/com/deloitte/system/service/MailService.java
new file mode 100644
index 0000000..c6c2a2a
--- /dev/null
+++ b/src/main/java/com/deloitte/system/service/MailService.java
@@ -0,0 +1,889 @@
+package com.deloitte.system.service;
+
+import cn.hutool.core.collection.CollectionUtil;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.common.aws.util.S3Util;
+import com.common.core.domain.DesensitiveType;
+import com.common.core.enums.ResultCodeEnum;
+import com.common.core.exception.BizException;
+import com.common.core.service.SFService;
+import com.common.core.utils.*;
+import com.deloitte.system.model.MailMerge;
+import com.deloitte.system.request.*;
+import com.j256.simplemagic.ContentInfoUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.env.Environment;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.ResponseEntity;
+import org.springframework.mail.javamail.JavaMailSender;
+import org.springframework.mail.javamail.JavaMailSenderImpl;
+import org.springframework.stereotype.Service;
+import org.springframework.util.ObjectUtils;
+import software.amazon.awssdk.core.ResponseBytes;
+import software.amazon.awssdk.services.s3.model.GetObjectResponse;
+
+import javax.activation.DataHandler;
+import javax.activation.DataSource;
+import javax.mail.*;
+import javax.mail.internet.*;
+import javax.mail.search.FlagTerm;
+import javax.mail.util.ByteArrayDataSource;
+import javax.transaction.Transactional;
+import java.io.*;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+/**
+ * @Author: Ben Pi
+ * @Date: 08/02/2022 15:16
+ */
+@Slf4j
+@Service
+public class MailService {
+
+    @Value("${aws.s3.bucketName}")
+    private String bucketName;
+
+    @Value("${mail.default-encoding}")
+    private String defaultEncoding;
+
+    @Value("${mail.smtp.host}")
+    private String smtpHost;
+    @Value("${mail.smtp.port}")
+    private Integer smtpPort;
+    @Value("${mail.smtp.protocol}")
+    private String smtpProtocol;
+
+    @Value("${mail.imap.host}")
+    private String imapHost;
+    @Value("${mail.imap.port}")
+    private String imapPort;
+    @Value("${mail.imap.protocol}")
+    private String imapProtocol;
+
+    @Value("${salesforce.baseUrl}")
+    private String sfUrl;
+
+    @Value("${file.url}")
+    private String fileUrl;
+
+    @Autowired
+    private IdUtils idWorker;
+
+    @Autowired
+    FileService fileService;
+
+    @Autowired
+    private SFService sfService;
+
+    public String sendEmail(String txId,MessageVo messageVo) {
+        try {
+            JavaMailSender mailSender=getMailSender();
+            log.info("寮�濮嬪彂閫侀偖浠讹細from["+messageVo.getFrom()+"]"+"subject["+messageVo.getSubjectCopy()+"]");
+            MimeMessage message = mailSender.createMimeMessage();
+            generateMessage(message,messageVo);
+            // 鏇存柊notSaveEmail鐘舵�佷负true
+            updateSFRecord(messageVo.getRecordType(),messageVo.getRecordId());
+            // 澶勭悊閭欢鏁版嵁锛屽彂閫乻f mailMerge
+            Map<String,String> idMap=handleEmail(message,messageVo.getRecordId(),messageVo.getRecordType().substring(0,1).toUpperCase(),true,messageVo.getFileMap());
+            //鍙戦�侀偖浠�
+            mailSender.send(message);
+            log.info("缁撴潫鍙戦�侀偖浠讹細from["+messageVo.getFrom()+"]"+"subject["+messageVo.getSubjectCopy()+"]");
+            // 杩斿洖sf mailMerge id
+            return idMap.get("mailMergeId");
+        } catch (Exception e) {
+            log.error("鍙戦�侀偖浠跺け璐ワ細",e);
+            throw new BizException(ResultCodeEnum.EMAIL_ERROR);
+        }
+    }
+    private JavaMailSender getMailSender(){
+        this.getInit();
+        JavaMailSenderImpl sender = new JavaMailSenderImpl();
+        sender.setHost(smtpHost);
+        sender.setDefaultEncoding(defaultEncoding);
+        sender.setPort(smtpPort);
+        sender.setProtocol(smtpProtocol);
+        sender.setUsername(username);
+        sender.setPassword(password);
+        Properties p = new Properties();
+        p.setProperty("mail.smtp.auth", "true");
+        p.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
+        p.setProperty("mail.smtp.socketFactory.fallback", "false");
+        p.setProperty("mail.smtp.socketFactory.port", smtpPort.toString());
+        sender.setJavaMailProperties(p);
+        return sender;
+    }
+
+    /**
+     * 鏇存柊閭欢notSaveEmail鐘舵��
+     *
+     * @param recordType
+     * @param recordId
+     */
+    private void updateSFRecord(String recordType, String recordId) {
+        //鏇存柊SWO鎴栧叾浠栬〃鐨� notSaveEmail 鏍囪瘑绗�
+        JSONObject jsonObject = new JSONObject();
+        //鏍囪璺宠繃閭欢鍥炲鐩戝惉
+        jsonObject.put("notSaveEmail__c",true);
+        String tableName = "";
+        if("SWO".equalsIgnoreCase(recordType)){
+            tableName = "SWO__c";
+        }
+        if("Case".equalsIgnoreCase(recordType)){
+            tableName = "User_FaultInfo__c";
+        }
+        if("Quotes".equals(recordType)){
+            String sql="select Id,Name,notSaveEmail__c,SWO__c,SWO__r.Quotation_send__c from Quotes__c where Id= '"+recordId+"'";
+            JSONObject quotes=sfService.querySFData(sql).getJSONObject(0);
+            tableName = "Quotes__c";
+            if (StringUtils.isNotBlank(quotes.getString("SWO__c")) && quotes.get("SWO__r.Quotation_send__c") == null) {
+                JSONObject swo = new JSONObject();
+                String swoRecordId = quotes.getString("SWO__c");
+                swo.put("Quotation_send__c",new Date());
+                // update swo;
+                sfService.updateSFData("SWO__c",swoRecordId,swo);
+            }
+        }
+        sfService.updateSFData(tableName,recordId,jsonObject);
+    }
+
+    @Autowired
+    private Environment env;
+    @Autowired
+    private SecretsManagerUtils secretsManagerUtils;
+    public void receiveImapMail() {
+        try {
+            this.getInit();
+            // 鍑嗗杩炴帴鏈嶅姟鍣ㄧ殑浼氳瘽淇℃伅
+            Properties props = new Properties();
+            props.setProperty("mail.store.protocol", imapProtocol);
+            props.setProperty("mail.imap.host", imapHost);
+            props.setProperty("mail.imap.port", imapPort);
+            props.setProperty("mail.imap.ssl.enable", "true");
+            props.setProperty("mail.imap.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
+            // 鍒涘缓Session瀹炰緥瀵硅薄
+            Session session = Session.getDefaultInstance(props, new Authenticator(){
+                @Override
+                protected PasswordAuthentication getPasswordAuthentication() {
+                    return new PasswordAuthentication(username, password);
+                }
+            });
+            session.setDebug(false);
+            // 杩炴帴閭欢鏈嶅姟鍣�
+            Store store = session.getStore(imapProtocol);
+            store.connect(imapHost,Integer.valueOf(imapPort), username, password);
+            Folder folder = store.getFolder("INBOX");
+            folder.open(Folder.READ_WRITE);
+
+            // 鑾峰緱鏀朵欢绠辩殑閭欢鍒楄〃
+            FlagTerm ft = new FlagTerm(new Flags(Flags.Flag.SEEN), false);
+            Message[] messages = folder.search(ft);
+            log.info("------------------------寮�濮嬭В鏋愰偖浠�----------------------------------");
+            log.info("-----------------鎮ㄧ殑閭鍏辨湁鏂伴偖浠讹細" + messages.length + " 灏�--------------");
+            for (int i = 0; i < messages.length; i++) {
+                try {
+                    Message msg = messages[i];
+                    //涓氬姟澶勭悊 1.鍐欏叆mail merge 2.瀛樺偍闄勪欢
+                    processReceiveEmail(msg);
+                    // 閭欢鍦ㄥ鐞嗗畬鎴愬悗鏇存柊閭欢鐘舵�佷负宸茶
+                    msg.setFlag(Flags.Flag.SEEN, true);
+                }catch (Exception e){
+                    log.error("鍚屾閭欢澶辫触锛�",e);
+                }
+            }
+            log.info("----------------End------------------");
+            // 鍏抽棴璧勬簮
+            folder.close(false);
+            store.close();
+        }catch (Exception e){
+            log.error("鍚屾閭欢澶辫触锛�",e);
+        }
+    }
+
+    /**
+     * 鎺ユ敹閭欢澶勭悊
+     *
+     * @param msg
+     * @return 杩斿洖褰撳墠閭欢鏄惁闇�瑕佹帴鏀舵爣璇嗭紙闇�瑕佹帴鏀讹細true,涓嶉渶瑕佹帴鏀讹細false锛�
+     * @throws Exception
+     */
+    private void processReceiveEmail(Message msg) throws Exception {
+        log.info("鎺ユ敹閭欢锛�" + msg.getSubject());
+        if(StringUtils.isEmpty(msg.getSubject())){
+            return;
+        }
+        //[EXT]Sandbox: 鍥炲:h45h54h54~SWO:Test By Bubba
+        String[] str = msg.getSubject().split("~");
+        if(str.length < 2){
+            log.info("褰撳墠閭欢涓嶅仛澶勭悊锛歿}",msg.getSubject());
+            return;
+        }
+        String type= null;
+        String recordId= null;
+        //SWO:Test By Bubba
+        String nameAll = str[1];
+        //S
+        type = nameAll.substring(0,1);
+        String tableName = type.equalsIgnoreCase("s") ? "SWO__c":
+                (type.equalsIgnoreCase("c") ? "User_FaultInfo__c": (type.equalsIgnoreCase("q") ? "Quotes__c" : ""));
+        //Test By Bubba
+        String name = nameAll.substring(nameAll.indexOf(":")+1);
+        if(StringUtils.isEmpty(tableName)||StringUtils.isEmpty(name)){
+            log.info("瑙f瀽tableName鎴杗ame涓虹┖锛宻ubject:{}",msg.getSubject());
+            return;
+        }
+        String sql="select Id,notSaveEmail__c,Name from "+tableName+" where Name= '"+name+"'";
+        JSONArray jsonArray=sfService.querySFData(sql);
+        if(jsonArray==null || jsonArray.size()==0){
+            log.info("閭欢锛歿},鏌ヨnotSaveEmail缁撴灉涓虹┖锛宼ableName:{},name:{}",msg.getSubject(),tableName,name);
+            return;
+        }
+        recordId = jsonArray.getJSONObject(0).getString("Id");
+        if( jsonArray.getJSONObject(0).getBoolean("notSaveEmail__c")){
+            log.info("璺宠繃閭欢鏈嶅姟鐩戝惉锛�" + msg.getSubject()+","+recordId);
+            // 鏇存柊notSaveEmail__c鏍囪瘑
+            JSONObject jsonObject = new JSONObject();
+            //鏍囪璺宠繃閭欢鍥炲鐩戝惉
+            jsonObject.put("notSaveEmail__c",false);
+            sfService.updateSFData(tableName,recordId,jsonObject);
+            // 姝ゅ涓鸿嚜宸辨妱閫佺粰鑷繁鐨勯偖浠讹紝璁剧疆涓哄凡璇�
+            return;
+        }
+        handleEmail(msg, recordId, type,false,null);
+    }
+
+    /**
+     * 澶勭悊email鏂规硶
+     *
+     * @param msg 閭欢瀵硅薄
+     * @param recordId 鍏宠仈id eg:swo_id
+     * @param type 閭欢绫诲瀷 eg:swo
+     * @param isSend 鏄惁涓哄彂鍑虹殑閭欢锛堝彂鍑猴細true,鎺ユ敹锛歠alse锛�
+     * @param fileMap 闄勪欢淇℃伅锛坘ey锛歴3鏂囦欢Key,value:fileName锛�
+     * @return
+     * @throws Exception
+     */
+    @Transactional
+    public Map<String, String> handleEmail(Message msg, String recordId, String type, boolean isSend, Map<String, String> fileMap) throws MessagingException {
+
+        log.info("------------- save email -------------");
+        try {
+            //淇濆瓨閭欢
+            MailMerge mailMerge = saveMailMerge(msg, recordId, type, isSend);
+
+            //鎺ユ敹鍒扮殑閭欢->淇濆瓨闄勪欢鍒皊3
+            if (!isSend) {
+                //瑙f瀽鍒伴偖浠朵腑鐨勯檮浠讹紝key涓洪檮浠�,value涓篺ilename
+                Map<BodyPart,String> parsedFileMap = new HashMap<>();
+                parseAttachMent(msg, parsedFileMap);
+                //閬嶅巻淇濆瓨闄勪欢鏂囦欢鍒皊3
+                for (BodyPart bodyPart : parsedFileMap.keySet()) {
+                    String fileName = parsedFileMap.get(bodyPart);
+                    String key = saveFile(fileName,bodyPart);
+                    fileMap = new HashMap<>();
+                    fileMap.put(key,fileName);
+                }
+            }
+
+            //鎺ㄩ�侀偖浠跺拰闄勪欢淇℃伅鍒癝F  idMap -> key锛歮ailMergeId/fileAddressId,value:salesforce淇濆瓨鍚庤繑鍥炵殑id,濡傛灉鏈夊涓檮浠讹紝id鐢�","鍒嗛殧
+            Map<String, String> idMap = postMailToSF(mailMerge, fileMap);
+            // 鍥炲啓sfid
+            updateMailMerge(idMap,mailMerge.getDataId());
+            return idMap;
+        } catch (Exception e) {
+            log.error("淇濆瓨閭欢寮傚父锛寋}",e.getMessage(),e);
+            // 淇敼Message鐘舵�佷负鏈
+            msg.setFlag(Flags.Flag.SEEN,false);
+            throw new BizException("淇濆瓨閭欢寮傚父");
+        }
+    }
+
+    /**
+     * 淇濆瓨mailmerge
+     *
+     * @param msg 閭欢瀵硅薄
+     * @param recordId 鍏宠仈id eg:swo_id
+     * @param type 閭欢绫诲瀷 eg:swo
+     * @param isSend 鏄惁涓哄彂鍑虹殑閭欢锛堝彂鍑猴細true,鎺ユ敹锛歠alse锛�
+     * @return
+     * @throws Exception
+     */
+    private MailMerge saveMailMerge(Message msg, String recordId, String type,boolean isSend) throws Exception {
+        MailMerge mailMerge = new MailMerge();
+        String dataId = idWorker.nextId();
+        mailMerge.setDataId(Long.parseLong(dataId));
+        mailMerge.setRecord(recordId);
+        //閭欢鏍囬
+        if(StringUtils.isNotBlank(msg.getSubject())){
+            mailMerge.setSubjectCopy(msg.getSubject());
+            String[] str = msg.getSubject().split("~");
+            mailMerge.setSubject(str[0]);
+            mailMerge.setName(str[0]);
+        }else{
+            mailMerge.setSubjectCopy("");
+            mailMerge.setSubject("");
+            mailMerge.setName("");
+        }
+        if("S".equals(type)){
+            mailMerge.setSwo(recordId);
+            mailMerge.setRecordType("SWO");
+        }
+        if("C".equals(type)){
+            mailMerge.setCaseF(recordId);
+            mailMerge.setRecordType("Case");
+        }
+        if("Q".equals(type)){
+            mailMerge.setQuotes(recordId);
+            mailMerge.setRecordType("Quotes");
+        }
+        //鍙戜欢浜哄湴鍧�
+        InternetAddress address[];
+        if(isSend) {
+            address = (InternetAddress[]) msg.getReplyTo();
+        }else{
+            address = (InternetAddress[]) msg.getFrom();
+        }
+        String author = (address!=null && address.length>0) ?address[0].getAddress():"";
+        mailMerge.setFrom(author);
+        mailMerge.setAuthor(author);
+        //鏀朵欢浜哄湴鍧�
+        mailMerge.setRecipient(getMailAddress(msg,"TO"));
+        //鎶勯�佷汉
+        mailMerge.setCc(getMailAddress(msg,"CC"));
+        //绉樻妱閫佷汉
+        mailMerge.setBcc(getMailAddress(msg,"BCC"));
+
+        setAllMember(mailMerge,getMailAddressMap(msg,"TO"),getMailAddressMap(msg,"CC"),getMailAddressMap(msg,"BCC"));
+        //閭欢淇℃伅
+        StringBuffer bodytext = new StringBuffer();
+        Multipart multipart = (msg.getContent() instanceof String) ? null : (Multipart) msg.getContent();
+        String mailContent;
+        if(multipart==null){
+            mailContent=msg.getContent().toString();
+        }else {
+            int counts = multipart.getCount();
+            for (int i = 0; i < counts; i++) {
+                getMailContent(multipart.getBodyPart(i), bodytext);
+            }
+            mailContent = bodytext.toString();
+        }
+        mailMerge.setMessage(mailContent);
+        //鏀跺彇鍥炲閭欢鏃堕棿
+        mailMerge.setDate(new Date());
+
+        if(isSend){
+            mailMerge.setType("send");
+        }else {
+            mailMerge.setType("reply");
+        }
+        mailMerge.setEmailSent("YES");
+
+        log.info("淇濆瓨mail merge:{}",mailMerge.toString());
+        mailMerge.save();
+
+        return mailMerge;
+    }
+
+    /**
+     * 鏇存柊sf杩斿洖鐨刴ailMergeId鍜宖ileAddressId鍒癿ail_merge琛�
+     *
+     * @param idMap
+     */
+    public void updateMailMerge(Map<String,String> idMap,Long dataId){
+        MailMerge mailMerge = new MailMerge();
+        mailMerge.setDataId(dataId);
+        String mailMergeId = idMap.get("mailMergeId");
+        String fileAddressId = idMap.get("fileAddressId");
+        mailMerge.setSfRecordId(mailMergeId);
+        mailMerge.setSfFileAddressId(fileAddressId);
+        log.info("update mail_merge---------->id:{},mailMergeId:{},fileAddressId:{}",dataId,mailMergeId,fileAddressId);
+        mailMerge.update();
+    }
+
+    /**
+     * 瑙f瀽闄勪欢
+     */
+    private void parseAttachMent(Part part,Map fileMap) throws Exception {
+
+        String fileName = "";
+        if (part.isMimeType("multipart/*")) {
+            Multipart mp = (Multipart) part.getContent();
+            for (int i = 0; i < mp.getCount(); i++) {
+                BodyPart mpart = mp.getBodyPart(i);
+                String disposition = mpart.getDisposition();
+                if ((disposition != null)
+                        && ((disposition.equals(Part.ATTACHMENT)) || (disposition
+                        .equals(Part.INLINE)))) {
+                    fileName = mpart.getFileName();
+                    if(StringUtils.isBlank(fileName) && "message/rfc822".equalsIgnoreCase(mpart.getHeader("Content-Type")[0])){
+                        Properties props = new Properties();
+                        Session session = Session.getInstance(props, null);
+                        MimeMessage msg=new MimeMessage(session,mpart.getInputStream());
+                        fileName=msg.getSubject()+".eml";
+                    }
+                    fileName = MimeUtility.decodeText(fileName);
+                    //闄勪欢鍐欏叆map
+                    fileMap.put(mpart,fileName);
+                } else if (mpart.isMimeType("multipart/*")) {
+                    parseAttachMent(mpart,fileMap);
+                } else {
+                    fileName = mpart.getFileName();
+                    if (fileName != null) {
+                        fileName = MimeUtility.decodeText(fileName);
+                        fileMap.put(mpart,fileName);
+                    }
+                }
+            }
+        } else if (part.isMimeType("message/rfc822")) {
+            parseAttachMent((Part) part.getContent(),fileMap);
+        }
+
+    }
+
+    /**
+     * 淇濆瓨鏂囦欢鍒皊3
+     */
+    private String saveFile(String fileName,BodyPart bodyPart) throws IOException, MessagingException {
+        log.info("淇濆瓨闄勪欢锛�"+fileName);
+        FileRequest fileRequest = new FileRequest();
+        fileRequest.setFileName(fileName);
+        String contentType= ContentInfoUtil.findExtensionMatch(fileName)==null?"text/plain": ContentInfoUtil.findExtensionMatch(fileName).getMimeType();
+        String basePrefix="data:"+contentType+";base64,";
+        int size = bodyPart.getSize();
+        byte [] buffer = new byte[size];
+        InputStream instream;
+        instream = bodyPart.getInputStream();
+        instream.read(buffer,0,size);
+        fileRequest.setFile(basePrefix+ Base64.getEncoder().encodeToString(buffer));
+        String key = fileService.uploadFileNoSize(fileRequest);
+        log.info("闄勪欢涓婁紶鑷硈3瀹屾垚,key:"+key);
+        return key;
+    }
+
+
+    /**
+     * 鑾峰緱閭欢鐨勬敹浠朵汉锛屾妱閫侊紝鍜屽瘑閫佺殑鍦板潃锛屾牴鎹墍浼犻�掔殑鍙傛暟鐨勪笉鍚� "to"----鏀朵欢浜� "cc"---鎶勯�佷汉鍦板潃 "bcc"---瀵嗛�佷汉鍦板潃
+     */
+    public String getMailAddress(Message msg,String type) throws Exception {
+        StringBuilder mailaddr = new StringBuilder();
+        Map<String, String> mailAddressMap = getMailAddressMap(msg, type);
+        Set<String> addressSet = mailAddressMap.keySet();
+        for (String address:addressSet) {
+            mailaddr.append(address).append(";");
+        }
+        return mailaddr.toString();
+    }
+
+    /**
+     * 鑾峰緱閭欢鐨勬敹浠朵汉锛屾妱閫侊紝鍜屽瘑閫佺殑鍦板潃锛屾牴鎹墍浼犻�掔殑鍙傛暟鐨勪笉鍚� "to"----鏀朵欢浜� "cc"---鎶勯�佷汉鍦板潃 "bcc"---瀵嗛�佷汉鍦板潃
+     *
+     * @return key:閭欢鍦板潃,value:鍙戦�佷汉鍚嶇О
+     */
+    public Map<String,String> getMailAddressMap(Message msg,String type) throws Exception {
+        HashMap<String,String> addressMap = new HashMap<>();
+        String addtype = type.toUpperCase();
+        InternetAddress[] address = null;
+        if ("TO".equals(addtype) || "CC".equals(addtype)|| "BCC".equals(addtype)) {
+            if ("TO".equals(addtype)) {
+                address = (InternetAddress[]) msg.getRecipients(Message.RecipientType.TO);
+            } else if ("CC".equals(addtype)) {
+                address = (InternetAddress[]) msg.getRecipients(Message.RecipientType.CC);
+            } else {
+                address = (InternetAddress[]) msg.getRecipients(Message.RecipientType.BCC);
+            }
+            if (address != null) {
+                for (int i = 0; i < address.length; i++) {
+                    String email = address[i].getAddress();
+                    if (email == null) {
+                        email = "";
+                    } else {
+                        email = MimeUtility.decodeText(email);
+                    }
+                    String personal = address[i].getPersonal();
+                    if (personal == null) {
+                        personal = "";
+                    } else {
+                        personal = MimeUtility.decodeText(personal);
+                    }
+                    addressMap.put(email,personal);
+                }
+            }
+        } else {
+            throw new Exception("Error emailaddr type!");
+        }
+        return addressMap;
+    }
+
+    /**
+     * 瑙f瀽閭欢锛屾妸寰楀埌鐨勯偖浠跺唴瀹逛繚瀛樺埌涓�涓猄tringBuffer瀵硅薄涓紝瑙f瀽閭欢 鏍规嵁MimeType绫诲瀷鐨勪笉鍚屾墽琛屼笉鍚岀殑鎿嶄綔
+     */
+    public String getMailContent(Part part,StringBuffer bodytext) throws Exception {
+
+        String contenttype = part.getContentType();
+        int nameindex = contenttype.indexOf("name");
+        boolean conname = false;
+        if (nameindex != -1) {
+            conname = true;
+        }
+        if (part.isMimeType("text/plain") && !conname) {
+            if (part.getContent() instanceof InputStream) {
+                return null;
+            }
+            // 鍙繚瀛樻枃鏈唴瀹�
+            bodytext.append((String) part.getContent());
+            log.info("娣诲姞閭欢鏂囨湰锛歿}",part.getContent().toString());
+        } else if (part.isMimeType("multipart/*")) {
+            Multipart multipart = (Multipart) part.getContent();
+            int counts = multipart.getCount();
+            for (int i = 0; i < counts; i++) {
+                getMailContent(multipart.getBodyPart(i),bodytext);
+            }
+        } else if (part.isMimeType("message/rfc822")) {
+            getMailContent((Part) part.getContent(),bodytext);
+        } else {
+            //鍏朵粬绫诲瀷鏆備笉澶勭悊
+        }
+        return bodytext.toString();
+    }
+
+    private void setAllMember(MailMerge mailMerge,Map<String,String> toAddress,Map<String,String> ccAddresses,Map<String,String> bccAddresses) {
+        mailMerge.setAllMember("");
+        mailMerge.setAllMemberName("");
+        mailMerge.setAllMemberType("");
+        if(toAddress !=null && toAddress.keySet().size()!=0){
+            for(String address : toAddress.keySet()){
+                //閭欢鍦板潃涔嬮棿鐢ㄢ��;鈥濋殧寮�锛屽彂閫侀偖浠堕〉浼氱敤鈥�;鈥濆垎鍓插瓧绗︿覆
+                mailMerge.setAllMember(mailMerge.getAllMember() + address + ";");
+                //鍚嶅瓧鏆傛椂閮界敤鈥�-鈥濓紝閭欢椤甸潰鍒嗗壊鍑衡��-鈥濅細鐢ㄧ┖浠f浛
+                mailMerge.setAllMemberName(mailMerge.getAllMemberName() + toAddress.get(address)+ ";");
+                mailMerge.setAllMemberType(mailMerge.getAllMemberType() + "to;");
+            }
+        }
+        if(ccAddresses !=null && ccAddresses.keySet().size()!=0){
+            for(String address : ccAddresses.keySet()){
+                if(address.startsWith("email@") || "".equals(address)){
+                    continue;
+                }
+                //閭欢鍦板潃涔嬮棿鐢ㄢ��;鈥濋殧寮�锛屽彂閫侀偖浠堕〉浼氱敤鈥�;鈥濆垎鍓插瓧绗︿覆
+                mailMerge.setAllMember(mailMerge.getAllMember() + address + ';');
+                //鍚嶅瓧鏆傛椂閮界敤鈥�-鈥濓紝閭欢椤甸潰鍒嗗壊鍑衡��-鈥濅細鐢ㄧ┖浠f浛
+                mailMerge.setAllMemberName(mailMerge.getAllMemberName() + "-;");
+                mailMerge.setAllMemberType(mailMerge.getAllMemberType() + "cc;");
+            }
+        }
+        if(bccAddresses !=null && bccAddresses.keySet().size()!=0){
+            for(String address : bccAddresses.keySet()){
+                if(address.startsWith("email@") || "".equals(address)){
+                    continue;
+                }
+                //閭欢鍦板潃涔嬮棿鐢ㄢ��;鈥濋殧寮�锛屽彂閫侀偖浠堕〉浼氱敤鈥�;鈥濆垎鍓插瓧绗︿覆
+                mailMerge.setAllMember(mailMerge.getAllMember() + address + ';');
+                //鍚嶅瓧鏆傛椂閮界敤鈥�-鈥濓紝閭欢椤甸潰鍒嗗壊鍑衡��-鈥濅細鐢ㄧ┖浠f浛
+                mailMerge.setAllMemberName(mailMerge.getAllMemberName() + "-;");
+                mailMerge.setAllMemberType(mailMerge.getAllMemberType() + "bcc;");
+            }
+        }
+    }
+
+
+    /**
+     * 璋冪敤salesforce 閭欢淇濆瓨鎺ュ彛
+     *
+     * @return Map<String,String> key锛歮ailMergeId/fileAddressId,value:salesforce淇濆瓨鍚庤繑鍥炵殑id,濡傛灉鏈夊涓檮浠讹紝id鐢�","鍒嗛殧
+     */
+    public Map<String,String> postMailToSF(MailMerge mailMerge,Map<String,String> fileMap){
+
+        HashMap<String, String> idMap = new HashMap<>();
+
+        SfCompositeRequest request = new SfCompositeRequest();
+        //mailMerge to SFMessageVo
+        SFMessageVo sfMessageVo = mailMergeToSFMessageVo(mailMerge);
+        request.addMailMerge(sfMessageVo);
+        // fileMap to SFFileAddressVo
+        if (fileMap!=null && fileMap.size()>0) {
+            List<SFFileAddressVo> sfFileAddressVos = fileMapToSFFileAddressVo(fileMap);
+            request.addFileAddress(sfFileAddressVos);
+        }
+
+        SFTokenDto tokenDto = sfService.getToken();
+        String accessToken = tokenDto.getAccessToken();
+        HttpHeaders header = new HttpHeaders();
+        header.add("Authorization", "Bearer " + accessToken);
+        header.add("Content-Type","application/json");
+
+        try {
+            String requestBody = request.toJsonString();
+            log.info("鎺ㄩ�乻f閭欢鎺ュ彛,request锛歿}",requestBody);
+            ResponseEntity sfRes = RestUtil.postNative(sfUrl + "services/data/v53.0/composite", header, null, request.toJsonString());
+            log.info("鎺ㄩ�乻f閭欢鎺ュ彛,response:{}",Objects.requireNonNull(sfRes.getBody()).toString());
+            int statusCodeValue = sfRes.getStatusCodeValue();
+            JSONObject body = (JSONObject)sfRes.getBody();
+            JSONArray responseBody = body.getJSONArray("compositeResponse");
+            responseBody.forEach(object -> {
+                LinkedHashMap map = (LinkedHashMap) object;
+                // 鍒ゆ柇杩斿洖鐘舵��
+                if(!map.get("httpStatusCode").toString().startsWith("2")){
+                    log.error("鎺ㄩ�乻alesforce閭欢鎺ュ彛杩斿洖寮傚父,response:"+sfRes.getBody());
+                    throw new BizException("鎺ㄩ�乻alesforce閭欢鎺ュ彛杩斿洖鐘舵�佸紓甯�");
+                }
+                // 鑾峰彇杩斿洖鍙傛暟涓殑mailMergeId
+                if ("NewMailMerge".equals(map.get("referenceId"))) {
+                    LinkedHashMap body1 = (LinkedHashMap) map.get("body");
+                    String mailMergeId = body1.get("id").toString();
+                    idMap.put("mailMergeId",mailMergeId);
+                }
+                // 鑾峰彇杩斿洖鍙傛暟涓殑NewFileAddress锛屽鏋滄槸澶氫釜锛岀敤','鎷兼帴
+                StringBuilder fileAddressIdBuilder = new StringBuilder();
+                if (map.get("referenceId").toString().startsWith("NewFileAddress")) {
+                    LinkedHashMap body1 = (LinkedHashMap) map.get("body");
+                    String fileAddressId = body1.get("id").toString();
+                    fileAddressIdBuilder.append(",").append(fileAddressId);
+                }
+                if(fileAddressIdBuilder.length()>0){
+                    String substring = fileAddressIdBuilder.substring(1);
+                    idMap.put("fileAddressId",substring);
+                }
+            });
+            if(!Integer.toString(statusCodeValue).startsWith("2")){
+                throw new BizException("璇锋眰SF鏈嶅姟淇濆瓨閭欢寮傚父,response code:"+statusCodeValue);
+            }
+        } catch (Exception e) {
+            log.error("璇锋眰SF鏈嶅姟寮傚父",e);
+            throw new BizException("璇锋眰SF鏈嶅姟淇濆瓨閭欢寮傚父");
+        }
+        return idMap;
+    }
+
+    //mailMerge to SFMessageVo
+    public SFMessageVo mailMergeToSFMessageVo(MailMerge mailMerge){
+
+        SFMessageVo sfMessageVo = new SFMessageVo();
+        sfMessageVo.setName(mailMerge.getName());
+
+        Map<String, String> desensitiveAllMemberNameMap = parseStringToDesensitive(mailMerge.getAllMemberName(),DesensitiveType.CHINESE_NAME);
+        sfMessageVo.setALL_MEMBER_NAME__c(desensitiveAllMemberNameMap.get("desensitive"));
+        sfMessageVo.setALL_MEMBER_NAME_Encrypted__c(desensitiveAllMemberNameMap.get("encrypt"));
+
+        sfMessageVo.setALL_MEMBER_TYPE__c(mailMerge.getAllMemberType());
+
+        Map<String, String> desensitiveAllMemberMap = parseStringToDesensitive(mailMerge.getAllMember(),DesensitiveType.EMAIL);
+        sfMessageVo.setALL_MEMBER__c(desensitiveAllMemberMap.get("desensitive"));
+        sfMessageVo.setALL_MEMBER_Encrypted__c(desensitiveAllMemberMap.get("encrypt"));
+
+        Map<String, String> desensitiveCcMap = parseStringToDesensitive(mailMerge.getCc(),DesensitiveType.EMAIL);
+        sfMessageVo.setCC__c(desensitiveCcMap.get("desensitive"));
+        sfMessageVo.setCC_Encrypted__c(desensitiveCcMap.get("encrypt"));
+
+        Map<String, String> desensitiveBccMap = parseStringToDesensitive(mailMerge.getBcc(),DesensitiveType.EMAIL);
+        sfMessageVo.setBCC__c(desensitiveBccMap.get("desensitive"));
+        sfMessageVo.setBCC_Encrypted__c(desensitiveBccMap.get("encrypt"));
+
+        Map<String, String> desensitiveFromMap = parseStringToDesensitive(mailMerge.getFrom(),DesensitiveType.EMAIL);
+        sfMessageVo.setFROM__c(desensitiveFromMap.get("desensitive"));
+        sfMessageVo.setFROM_Encrypted__c(desensitiveFromMap.get("encrypt"));
+
+        sfMessageVo.setMESSAGE__c(mailMerge.getMessage());
+
+        Map<String, String> desensitiveRecipientMap = parseStringToDesensitive(mailMerge.getRecipient(),DesensitiveType.EMAIL);
+        sfMessageVo.setRECIPIENT__c(desensitiveRecipientMap.get("desensitive"));
+        sfMessageVo.setRECIPIENT_Encrypted__c(desensitiveRecipientMap.get("encrypt"));
+
+        sfMessageVo.setRECORD_TYPE__c(mailMerge.getRecordType());
+        sfMessageVo.setSUBJECTCOPY__c(mailMerge.getSubjectCopy());
+        sfMessageVo.setSUBJECT__c(mailMerge.getSubject());
+        sfMessageVo.setTYPE__c(mailMerge.getType());
+
+        Map<String, String> desensitiveBccNameMap = parseStringToDesensitive(mailMerge.getBccName(),DesensitiveType.CHINESE_NAME);
+        sfMessageVo.setBccName__c(desensitiveBccNameMap.get("desensitive"));
+        sfMessageVo.setBccName_Encrypted__c(desensitiveBccNameMap.get("encrypt"));
+
+        Map<String, String> desensitiveCcNameMap = parseStringToDesensitive(mailMerge.getCcName(),DesensitiveType.CHINESE_NAME);
+        sfMessageVo.setCcName__c(desensitiveCcNameMap.get("desensitive"));
+        sfMessageVo.setCcName_Encrypted__c(desensitiveCcNameMap.get("encrypt"));
+
+        Map<String, String> desensitiveToNameMap = parseStringToDesensitive(mailMerge.getToName(),DesensitiveType.CHINESE_NAME);
+        sfMessageVo.setToName__c(desensitiveToNameMap.get("desensitive"));
+        sfMessageVo.setToName_Encrypted__c(desensitiveToNameMap.get("encrypt"));
+
+        sfMessageVo.setAWS_Data_Id__c(mailMerge.getDataId().toString());
+        sfMessageVo.setDATE__c(mailMerge.getDate()==null?null:DateUtils.formatToUtc(mailMerge.getDate(),DateUtils.DATE_TIME_GL_ST_FORMAT_ZT_1));
+        sfMessageVo.setRECORD__c(mailMerge.getRecord());
+        sfMessageVo.setRECORD_TYPE__c(mailMerge.getRecordType());
+        sfMessageVo.setSWO__c(mailMerge.getSwo());
+        sfMessageVo.setCaseF__c(mailMerge.getCaseF());
+        sfMessageVo.setQuotes__c(mailMerge.getQuotes());
+
+        sfMessageVo.setEMAIL_SENT__c(mailMerge.getEmailSent());
+
+        return sfMessageVo;
+    }
+
+
+    //fileMap to SFFileAddressVo
+    private List<SFFileAddressVo> fileMapToSFFileAddressVo(Map<String, String> fileMap){
+
+        ArrayList<SFFileAddressVo> sfFileAddressVos = new ArrayList<>();
+        for (String fileKey:fileMap.keySet()) {
+            SFFileAddressVo sfFileAddressVo = new SFFileAddressVo();
+            String fileName = fileMap.get(fileKey);
+            sfFileAddressVo.setAWS_File_Key__c(fileKey);
+            sfFileAddressVo.setFileName__c(fileName);
+            sfFileAddressVo.setParentRecordId__c("@{NewMailMerge.id}");
+            sfFileAddressVo.setDownloadLink__c(fileUrl+"download?key="+fileKey+"&fileName="+fileName);
+            sfFileAddressVo.setViewLink__c(fileUrl+"preview?key="+fileKey);
+            sfFileAddressVos.add(sfFileAddressVo);
+        }
+        return sfFileAddressVos;
+    }
+
+    /**
+     * 灏哠tring杞崲涓鸿劚鏁忓瓧绗︿覆鍜屽姞瀵嗗瓧绗︿覆
+     *
+     * @param s
+     * @return
+     */
+    private static Map<String,String> parseStringToDesensitive(String s,DesensitiveType desensitiveType){
+
+        HashMap<String, String> map = new HashMap<>();
+        if("".equals(s) || s==null){
+            map.put("desensitive",s);
+            map.put("encrypt",s);
+            return map;
+        }
+
+        // 鑴辨晱鍐呭
+        StringBuilder desensitiveS = new StringBuilder();
+        // 鍔犲瘑鍐呭
+        StringBuilder encryptS = new StringBuilder();
+        //twtyypmb;twtyypmb66;-;-;
+        String[] split = s.split(";");
+        for (String name:split) {
+            if(!"-".equals(name)){
+                desensitiveS.append(DesensitiveUtils.getFieldDesensitive(desensitiveType)).append(";");
+                String encryptStr = SM4Utils.encryptStr(name);
+                encryptS.append(encryptStr).append(";");
+            }else {
+                desensitiveS.append(name).append(";");
+                encryptS.append(name).append(";");
+            }
+        }
+        // 鍒ゆ柇鏄惁闇�瑕佸姞;
+        if(!s.endsWith(";") && s.length()>0){
+            desensitiveS.delete(desensitiveS.length()-1,desensitiveS.length());
+            encryptS.delete(encryptS.length()-1,encryptS.length());
+        }
+        map.put("desensitive",desensitiveS.toString());
+        map.put("encrypt",encryptS.toString());
+        return map;
+    }
+
+
+    private void generateMessage(MimeMessage message,MessageVo messageVo) throws Exception {
+        this.getInit();
+        message.setSubject(messageVo.getSubjectCopy(), "UTF-8");
+        message.setFrom(new InternetAddress(username));
+        if(!ObjectUtils.isEmpty(messageVo.getFrom())) {
+            message.addHeader("Sender", messageVo.getFrom());
+            message.addHeader("Return-Path", messageVo.getFrom());
+            message.setReplyTo(new InternetAddress[]{new InternetAddress(messageVo.getFrom(), messageVo.getFromName()),new InternetAddress(username, "-")});
+//            message.addHeader("In-Reply-To", messageVo.getFrom());
+//            message.addHeader("Reply-To", messageVo.getFrom());
+        }
+        if(StringUtils.isNotEmpty(messageVo.getRecipient())) {
+            String[] addressList=messageVo.getRecipient().split(";");
+            String[] nameList=messageVo.getToName().split(";");
+            for (int i = 0; i < addressList.length; i++) {
+                try {
+                    message.addRecipient(Message.RecipientType.TO, new InternetAddress(addressList[i],nameList[i]));
+                } catch (Exception e) {
+                    log.error("娣诲姞鏀朵欢浜哄け璐�,from:"+messageVo.getFrom()+",to:"+addressList[i]+",subject:"+messageVo.getSubjectCopy());
+                    log.error("娣诲姞鏀朵欢浜哄け璐�",e);
+                }
+            }
+        }
+        if(StringUtils.isNotEmpty(messageVo.getRecipient())) {
+            // 娣诲姞鐩戝惉閭欢
+            String cc = messageVo.getCc();
+            String ccName = messageVo.getCcName();
+            if(cc==null || "".equals(cc)){
+                cc = username;
+                ccName = username.substring(0,username.indexOf("@"));
+            }else if(!cc.contains(username)){
+                // cc鍒楄〃涓病鏈塷lympus鍏偖锛屽皢鍏偖娣诲姞鍒癱c涓�
+                cc += ";"+username;
+                ccName += ";"+username.substring(0,username.indexOf("@"));
+            }
+            String[] addressList=cc.split(";");
+            String[] nameList=ccName.split(";");
+            for (int i = 0; i < addressList.length; i++) {
+                try {
+                    message.addRecipient(Message.RecipientType.CC, new InternetAddress(addressList[i],nameList[i]));
+                } catch (Exception e) {
+                    log.error("娣诲姞CC鏀朵欢浜哄け璐�,from:"+messageVo.getFrom()+",cc:"+addressList[i]+",subject:"+messageVo.getSubjectCopy());
+                    log.error("娣诲姞鏀朵欢浜哄け璐�",e);
+                }
+            }
+        }
+        if(StringUtils.isNotEmpty(messageVo.getBcc())) {
+            String[] addressList=messageVo.getBcc().split(";");
+            String[] nameList=messageVo.getBccName().split(";");
+            for (int i = 0; i < addressList.length; i++) {
+                try {
+                    message.addRecipient(Message.RecipientType.BCC, new InternetAddress(addressList[i],nameList[i]));
+                } catch (Exception e) {
+                    log.error("娣诲姞鏀朵欢浜哄け璐�,from:"+messageVo.getFrom()+",bcc:"+addressList[i]+",subject:"+messageVo.getSubjectCopy());
+                    log.error("娣诲姞鏀朵欢浜哄け璐�",e);
+                }
+            }
+        }
+
+        // Create a wrapper for the HTML and text parts
+        MimeBodyPart wrap = new MimeBodyPart();
+
+        // Add the child container to the wrapper object
+        wrap.setContent(messageVo.getMessage(), "text/plain; charset=UTF-8");
+
+        // Create a multipart/mixed parent container
+        MimeMultipart msg = new MimeMultipart("mixed");
+
+        // Add the multipart/alternative part to the message
+        msg.addBodyPart(wrap);
+        // Define the attachment
+        if(CollectionUtil.isNotEmpty(messageVo.getFileMap())){
+            messageVo.getFileMap().forEach((fileKey,fileName) ->{
+                try {
+                    ResponseBytes<GetObjectResponse> objectBytes = S3Util.downloadFile(fileKey, bucketName);
+                    byte[] fileContent = objectBytes.asByteArray();
+                    MimeBodyPart att = new MimeBodyPart();
+                    DataSource fds = new ByteArrayDataSource(fileContent, ContentInfoUtil.findExtensionMatch(fileName).getMimeType());
+                    att.setDataHandler(new DataHandler(fds));
+                    att.setFileName(fileName);
+                    // Add the attachment to the message.
+                    MimeBodyPart attachFileBodypart = new MimeBodyPart();
+                    MimeMultipart attachFileMMP = new MimeMultipart("related");
+                    attachFileMMP.addBodyPart(att);
+                    attachFileBodypart.setContent(attachFileMMP,"text/html;charset=UTF-8");
+                    msg.addBodyPart(attachFileBodypart);
+                }catch (Exception e){
+                    log.error("娣诲姞闄勪欢澶辫触,from:"+messageVo.getFrom()+",to:"+messageVo.getRecipient()+",subject:"+messageVo.getSubjectCopy()+",fileName:"+fileName+",fileKey:"+fileKey);
+                    log.error("娣诲姞闄勪欢澶辫触锛�",e);
+                }
+            });
+        }
+        // Add the parent container to the message
+        message.setContent(msg);
+        message.saveChanges();
+    }
+    private String username = "";
+    private String password = "";
+    private void getInit(){
+        if(StringUtils.isBlank(username) || StringUtils.isBlank(password)) {
+            JSONObject object = secretsManagerUtils.getSecret(env.getProperty("aws.secrets.mailauth"));
+            username = object.getString("mail_username");
+            password = object.getString("mail_password");
+        }
+    }
+}
diff --git a/src/main/java/com/deloitte/system/service/OpportunityService.java b/src/main/java/com/deloitte/system/service/OpportunityService.java
new file mode 100644
index 0000000..8af9cbb
--- /dev/null
+++ b/src/main/java/com/deloitte/system/service/OpportunityService.java
@@ -0,0 +1,190 @@
+package com.deloitte.system.service;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.alibaba.fastjson.JSONArray;
+import com.common.core.constant.GlobalConst;
+import com.common.core.enums.ResultCodeEnum;
+import com.common.core.exception.BizException;
+import com.common.core.service.CryptoService;
+import com.common.core.utils.*;
+import com.common.redis.util.RedisUtil;
+import com.deloitte.system.model.CacheList;
+import com.deloitte.system.model.Opportunity;
+import com.deloitte.system.model.Quotes;
+import com.deloitte.system.request.OpportunityDto;
+import com.deloitte.system.request.QuotesDto;
+import com.jfinal.plugin.activerecord.Db;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static com.common.core.constant.GlobalConst.PIPL_UNCONFIRM_INSERT;
+import static com.common.core.constant.GlobalConst.PIPL_UNCONFIRM_UPDATE;
+
+@Service
+public class OpportunityService {
+    private String tableName = "opportunity";
+
+    @Autowired
+    private CryptoService cryptoService;
+
+    @Autowired
+    private IdUtils idWorker;
+
+    @Autowired
+    private RedisUtil redisUtil;
+
+    public OpportunityDto queryForOne(String dataId) {
+        Opportunity opportunity = Opportunity.dao.findById(dataId);
+        if (!ObjectUtil.isEmpty(opportunity)) {
+            return BeanHelper.copyAs(opportunity,OpportunityDto.class);
+        }
+        return null;
+    }
+
+    public List<OpportunityDto> insertList(List<OpportunityDto> opportunityList, String txId) {
+        List<OpportunityDto> respList = new ArrayList<>();
+        CacheList<OpportunityDto> dtoCacheList = new CacheList<>();
+        dtoCacheList.setTableName(tableName);
+        List<OpportunityDto> dtoItemList = new ArrayList<>();
+        opportunityList.forEach(e -> {
+            String dataId = idWorker.nextId();
+            OpportunityDto cacheItem = BeanHelper.copyAs(e, OpportunityDto.class);
+            cacheItem.setDataId(dataId);
+            dtoItemList.add(cacheItem);
+
+            OpportunityDto target = BeanHelper.copyAs(e, OpportunityDto.class);
+            target.setDataId(dataId);
+            OpportunityDto dto = cryptoService.encryptModelColumns(e);
+            dto.setDataId(dataId);
+            target.setDealerServiceDEncrypt(dto.getDealerServiceD());
+            target.setDealerServiceEncrypt(dto.getDealerService());
+            target.setDealerSalesStaffNameDEncrypt(dto.getDealerSalesStaffNameD());
+            target.setDealerSalesStaffNameEncrypt(dto.getDealerSalesStaffName());
+            target.setExpectedDeliveryDateEncrypt(dto.getExpectedDeliveryDate());
+            target.setSalesAccountCodeEncrypt(dto.getSalesAccountCode());
+            target.setSpecialDeliveryAddressEncrypt(dto.getSpecialDeliveryAddress());
+            DesensitiveUtils.format(target);
+            respList.add(target);
+        });
+        dtoCacheList.setData(dtoItemList);
+        String insertJsonString = JSONArray.toJSONString(dtoCacheList);
+        String insertKey = PIPL_UNCONFIRM_INSERT + txId;
+        boolean redisFlag = redisUtil.set(insertKey, insertJsonString, GlobalConst.DATA_EXPIRE);
+        if (!redisFlag) {
+            throw new BizException("缂撳瓨鍐欏叆澶辫触");
+        }
+        return respList;
+    }
+
+    public List<OpportunityDto> updateList(List<OpportunityDto> opportunityList, String txId) {
+        List<OpportunityDto> respList = new ArrayList<>();
+        CacheList<OpportunityDto> dtoCacheList = new CacheList<>();
+        dtoCacheList.setTableName(tableName);
+        List<OpportunityDto> dtoItemList = new ArrayList<>();
+        opportunityList.forEach(e -> {
+            Opportunity opportunity = Opportunity.dao.findById(e.getDataId());
+            OpportunityDto cacheItem = BeanHelper.copyAs(e, OpportunityDto.class);
+            dtoItemList.add(cacheItem);
+            OpportunityDto dto = BeanHelper.copyAs(BeanHelper.copy(cacheItem,opportunity),OpportunityDto.class);
+            OpportunityDto target = BeanHelper.copyAs(dto, OpportunityDto.class);
+             dto = cryptoService.encryptModelColumns(dto);
+            target.setDealerServiceDEncrypt(dto.getDealerServiceD());
+            target.setDealerServiceEncrypt(dto.getDealerService());
+            target.setDealerSalesStaffNameDEncrypt(dto.getDealerSalesStaffNameD());
+            target.setDealerSalesStaffNameEncrypt(dto.getDealerSalesStaffName());
+            target.setExpectedDeliveryDateEncrypt(dto.getExpectedDeliveryDate());
+            target.setSalesAccountCodeEncrypt(dto.getSalesAccountCode());
+            target.setSpecialDeliveryAddressEncrypt(dto.getSpecialDeliveryAddress());
+            DesensitiveUtils.format(target);
+            respList.add(target);
+        });
+        dtoCacheList.setData(dtoItemList);
+        String updateJsonString = JSONArray.toJSONString(dtoCacheList);
+        String updateKey = PIPL_UNCONFIRM_UPDATE + txId;
+        boolean redisFlag = redisUtil.set(updateKey, updateJsonString,GlobalConst.DATA_EXPIRE);
+        if (!redisFlag) {
+            throw new BizException("缂撳瓨鍐欏叆澶辫触");
+        }
+        return respList;
+    }
+
+    public Boolean deleteOne(String dataId) {
+        Opportunity opportunity = Opportunity.dao.findById(dataId);
+        opportunity.setIsDelete(1);
+        return opportunity.saveOrUpdate();
+    }
+
+    public Boolean undeleteOne(String dataId) {
+        Opportunity opportunity = Opportunity.dao.findById(dataId);
+        opportunity.setIsDelete(0);
+        return opportunity.saveOrUpdate();
+    }
+
+    public List<OpportunityDto> search(List<String> idList){
+        if (CollUtil.isEmpty(idList)) {
+            return null;
+        }
+        StringBuilder queryParam = new StringBuilder();
+        queryParam.append("and id in ").append(idList.stream().collect(Collectors.joining(", ", "(", ")")));
+        List<Opportunity> quotesList = Opportunity.dao.findList(queryParam.toString());
+        return quotesList.stream()
+                .map(quotes -> BeanHelper.copyAs(quotes, OpportunityDto.class)).collect(Collectors.toList());
+
+    }
+
+    public List<OpportunityDto> decryptUpdate(List<OpportunityDto> opportunityList) {
+        List<OpportunityDto> respList =new ArrayList<>();
+        String[] decryptColumn =new String[]{"expected_delivery_date","sales_account_code","special_delivery_address","dealer_service_d","dealer_service","dealer_sales_staff_name_d","dealer_sales_staff_name"};
+        Db.tx(() -> {
+            for (OpportunityDto e : opportunityList) {
+                Opportunity opportunity =Opportunity.dao.findById(e.getDataId());
+                if (opportunity == null) {
+                    throw new BizException("鏃犳晥鐨凞ataId");
+                }
+                Opportunity item=new Opportunity();
+                BeanHelper.copyEncrypt(e, item);
+                cryptoService.decryptoColumnModel(item,decryptColumn);
+                BeanHelper.copy(item, opportunity);
+                opportunity.setSfRecordId(e.getSfRecordId());
+                if (!opportunity.saveOrUpdate()) {
+                    throw new BizException(ResultCodeEnum.RT_ERROR);
+                }
+
+                respList.add(e);
+            }
+            return true;
+        });
+        return respList;
+    }
+
+    public List<OpportunityDto> decryptInsert(List<OpportunityDto> opportunityList) {
+
+        List<OpportunityDto> respList =new ArrayList<>();
+        Db.tx(() -> {
+            for (OpportunityDto e : opportunityList) {
+                Opportunity opportunity = new Opportunity();
+                String dataId =idWorker.nextId();
+                BeanHelper.copyEncrypt(e, opportunity);
+                cryptoService.decryptoModel(opportunity);
+                opportunity.setSfRecordId(e.getSfRecordId());
+                opportunity.setDataId(Long.valueOf(dataId));
+                if(!opportunity.save()) {
+                    throw new BizException(ResultCodeEnum.RT_ERROR);
+                }
+                e.setDataId(dataId);
+                respList.add(e);
+            }
+            return true;
+        });
+        return respList;
+    }
+
+}
+
+
+
diff --git a/src/main/java/com/deloitte/system/service/OrderService.java b/src/main/java/com/deloitte/system/service/OrderService.java
new file mode 100644
index 0000000..005d78a
--- /dev/null
+++ b/src/main/java/com/deloitte/system/service/OrderService.java
@@ -0,0 +1,218 @@
+package com.deloitte.system.service;
+
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.alibaba.fastjson.JSONArray;
+import com.common.core.constant.GlobalConst;
+import com.common.core.enums.ResultCodeEnum;
+import com.common.core.exception.BizException;
+import com.common.core.service.CryptoService;
+import com.common.core.utils.BeanHelper;
+import com.common.core.utils.DesensitiveUtils;
+import com.common.core.utils.IdUtils;
+import com.common.redis.util.RedisUtil;
+import com.deloitte.system.model.CacheList;
+import com.deloitte.system.model.Opportunity;
+import com.deloitte.system.model.Order;
+import com.deloitte.system.request.OpportunityDto;
+import com.deloitte.system.request.OrderDto;
+import com.jfinal.plugin.activerecord.Db;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static com.common.core.constant.GlobalConst.PIPL_UNCONFIRM_INSERT;
+import static com.common.core.constant.GlobalConst.PIPL_UNCONFIRM_UPDATE;
+
+@Service
+public class OrderService {
+    private String tableName = "order";
+
+    @Autowired
+    private CryptoService cryptoService;
+
+    @Autowired
+    private IdUtils idWorker;
+
+    @Autowired
+    private RedisUtil redisUtil;
+
+    public OrderDto queryForOne(String dataId) {
+        Order order = Order.dao.findById(dataId);
+        if (!ObjectUtil.isEmpty(order)) {
+            return BeanHelper.copyAs(order,OrderDto.class);
+        }
+        return null;
+    }
+
+    public List<OrderDto> insertList(List<OrderDto> orderList, String txId) {
+        List<OrderDto> respList = new ArrayList<>();
+        CacheList<OrderDto> dtoCacheList = new CacheList<>();
+        dtoCacheList.setTableName(tableName);
+        List<OrderDto> dtoItemList = new ArrayList<>();
+        orderList.forEach(e -> {
+            String dataId = idWorker.nextId();
+            OrderDto cacheItem = BeanHelper.copyAs(e, OrderDto.class);
+            cacheItem.setDataId(dataId);
+            dtoItemList.add(cacheItem);
+
+            OrderDto target = BeanHelper.copyAs(e, OrderDto.class);
+            target.setDataId(dataId);
+            OrderDto dto = cryptoService.encryptModelColumns(e);
+            dto.setDataId(dataId);
+            cryptoService.convertor(dto,target);
+            DesensitiveUtils.format(target);
+            respList.add(target);
+        });
+        dtoCacheList.setData(dtoItemList);
+        String insertJsonString = JSONArray.toJSONString(dtoCacheList);
+        String insertKey = PIPL_UNCONFIRM_INSERT + txId;
+        boolean redisFlag = redisUtil.set(insertKey, insertJsonString, GlobalConst.DATA_EXPIRE);
+        if (!redisFlag) {
+            throw new BizException("缂撳瓨鍐欏叆澶辫触");
+        }
+        return respList;
+    }
+
+    public List<OrderDto> updateList(List<OrderDto> orderList, String txId) {
+        List<OrderDto> respList = new ArrayList<>();
+        CacheList<OrderDto> dtoCacheList = new CacheList<>();
+        dtoCacheList.setTableName(tableName);
+        List<OrderDto> dtoItemList = new ArrayList<>();
+        orderList.forEach(e -> {
+            Order order = Order.dao.findById(e.getDataId());
+            OrderDto cacheItem = BeanHelper.copyAs(e, OrderDto.class);
+            dtoItemList.add(cacheItem);
+            OrderDto dto = BeanHelper.copyAs(BeanHelper.copy(cacheItem,order),OrderDto.class);
+            OrderDto target = BeanHelper.copyAs(dto, OrderDto.class);
+            dto = cryptoService.encryptModelColumns(dto);
+            target.setSpecialDeliveryPhoneEncrypt(dto.getSpecialDeliveryPhone());
+            target.setSpecialDeliveryPhoneDEncrypt(dto.getSpecialDeliveryPhoneD());
+            target.setShippingRecieverEmailAdrEncrypt(dto.getShippingRecieverEmailAdr());
+            target.setShipToContactIdEncrypt(dto.getShipToContactId());
+            target.setCustomerAuthorizedByIdEncrypt(dto.getCustomerAuthorizedById());
+            target.setBillToContactIdEncrypt(dto.getBillToContactId());
+            target.setSpecialDeliveryContact2Encrypt(dto.getSpecialDeliveryContact2());
+            target.setSpecialDeliveryContactTextEncrypt(dto.getSpecialDeliveryContact());
+            target.setShippingAddressTextEncrypt(dto.getShippingAddressText());
+            target.setSpecialDeliveryContact2DEncrypt(dto.getSpecialDeliveryContact2D());
+            target.setEndUserEncrypt(dto.getEndUser());
+            target.setEndUserDEncrypt(dto.getEndUserD());
+            target.setSpecialDeliveryContactEncrypt(dto.getSpecialDeliveryContact());
+            target.setSpecialDeliveryContactDEncrypt(dto.getSpecialDeliveryContactD());
+            target.setPdfNNotifyPartyEncrypt(dto.getPdfNNotifyParty());
+            target.setPdfNFaxEncrypt(dto.getPdfNFax());
+            target.setPdfNContactEncrypt(dto.getPdfNContact());
+            target.setPdfSTelEncrypt(dto.getPdfSTel());
+            target.setPdfSPhoneEncrypt(dto.getPdfSPhone());
+            target.setPdfSNameEncrypt(dto.getPdfSName());
+            target.setPdfSFaxEncrypt(dto.getPdfSFax());
+            target.setPdfFTelEncrypt(dto.getPdfFTel());
+            target.setPdfFFaxEncrypt(dto.getPdfFFax());
+            target.setPdfFContactPersonEncrypt(dto.getPdfFContactPerson());
+            target.setPdfSAddsEncrypt(dto.getPdfSAdds());
+            target.setPdfSAddressEncrypt(dto.getPdfSAddress());
+            target.setPdfSellerEncrypt(dto.getPdfSeller());
+            target.setPdfCTheconsigneEncrypt(dto.getPdfCTheconsigne());
+            target.setPdfCTelEncrypt(dto.getPdfCTel());
+            target.setPdfCFaxEncrypt(dto.getPdfCFax());
+            target.setPdfCConsigneeEncrypt(dto.getPdfCConsignee());
+            target.setPdfCContactEncrypt(dto.getPdfCContact());
+            target.setPdfCAddrEncrypt(dto.getPdfCAddr());
+            target.setSpecialDeliveryAddressEncrypt(dto.getSpecialDeliveryAddress());
+            target.setSpecialDeliveryAddressDEncrypt(dto.getSpecialDeliveryAddressD());
+            target.setDealerSalesStaffNameAEncrypt(dto.getDealerSalesStaffNameA());
+            target.setPdfSignTitleEncrypt(dto.getPdfSignTitle());
+            target.setPdfSignNameEncrypt(dto.getPdfSignName());
+            target.setPdfSignaturePlacesEncrypt(dto.getPdfSignaturePlaces());
+            target.setPdfByTelEncrypt(dto.getPdfByTel());
+            target.setPdfByAddEncrypt(dto.getPdfByAdd());
+            DesensitiveUtils.format(target);
+            respList.add(target);
+        });
+        dtoCacheList.setData(dtoItemList);
+        String updateJsonString = JSONArray.toJSONString(dtoCacheList);
+        String updateKey = PIPL_UNCONFIRM_UPDATE + txId;
+        boolean redisFlag = redisUtil.set(updateKey, updateJsonString,GlobalConst.DATA_EXPIRE);
+        if (!redisFlag) {
+            throw new BizException("缂撳瓨鍐欏叆澶辫触");
+        }
+        return respList;
+    }
+
+    public Boolean deleteOne(String dataId) {
+        Order order = Order.dao.findById(dataId);
+        order.setIsDelete(1);
+        return order.saveOrUpdate();
+    }
+
+    public Boolean undeleteOne(String dataId) {
+        Order order = Order.dao.findById(dataId);
+        order.setIsDelete(0);
+        return order.saveOrUpdate();
+    }
+
+    public List<OrderDto> search(List<String> idList){
+        if (CollUtil.isEmpty(idList)) {
+            return null;
+        }
+        StringBuilder queryParam = new StringBuilder();
+        queryParam.append("and id in ").append(idList.stream().collect(Collectors.joining(", ", "(", ")")));
+        List<Order> quotesList = Order.dao.findList(queryParam.toString());
+        return quotesList.stream()
+                .map(quotes -> BeanHelper.copyAs(quotes, OrderDto.class)).collect(Collectors.toList());
+
+    }
+
+    public List<OrderDto> decryptUpdate(List<OrderDto> orderList) {
+        List<OrderDto> respList =new ArrayList<>();
+        String[] decryptColumn =new String[]{"expected_delivery_date","sales_account_code","special_delivery_address","dealer_service_d","dealer_service","dealer_sales_staff_name_d","dealer_sales_staff_name"};
+        Db.tx(() -> {
+            for (OrderDto e : orderList) {
+                Order order =Order.dao.findById(e.getDataId());
+                if (order == null) {
+                    throw new BizException("鏃犳晥鐨凞ataId");
+                }
+                Order item=new Order();
+                BeanHelper.copyEncrypt(e, item);
+                cryptoService.decryptoColumnModel(item,decryptColumn);
+                BeanHelper.copyEncrypt(item, order);
+                order.setSfRecordId(e.getSfRecordId());
+                if (!order.saveOrUpdate()) {
+                    throw new BizException(ResultCodeEnum.RT_ERROR);
+                }
+
+                respList.add(e);
+            }
+            return true;
+        });
+        return respList;
+    }
+
+
+    public List<OrderDto> decryptInsert(List<OrderDto> orderList) {
+        List<OrderDto> respList =new ArrayList<>();
+        Db.tx(() -> {
+            for (OrderDto e : orderList) {
+                Order order = new Order();
+                String dataId =idWorker.nextId();
+                BeanHelper.copyEncrypt(e, order);
+                cryptoService.decryptoModel(order);
+                order.setSfRecordId(e.getSfRecordId());
+                order.setDataId(Long.valueOf(dataId));
+                if(!order.save()) {
+                    throw new BizException(ResultCodeEnum.RT_ERROR);
+                }
+                e.setDataId(dataId);
+                respList.add(e);
+            }
+            return true;
+        });
+        return respList;
+    }
+
+}
diff --git a/src/main/java/com/deloitte/system/service/QuotesService.java b/src/main/java/com/deloitte/system/service/QuotesService.java
new file mode 100644
index 0000000..b3eee8d
--- /dev/null
+++ b/src/main/java/com/deloitte/system/service/QuotesService.java
@@ -0,0 +1,143 @@
+package com.deloitte.system.service;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.alibaba.fastjson.JSONArray;
+import com.common.core.constant.GlobalConst;
+import com.common.core.exception.BizException;
+import com.common.core.service.CryptoService;
+import com.common.core.utils.BeanHelper;
+import com.common.core.utils.DesensitiveUtils;
+import com.common.core.utils.IdUtils;
+import com.common.redis.util.RedisUtil;
+import com.deloitte.system.model.CacheList;
+import com.deloitte.system.model.Quotes;
+import com.deloitte.system.request.QuotesDto;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static com.common.core.constant.GlobalConst.PIPL_UNCONFIRM_INSERT;
+import static com.common.core.constant.GlobalConst.PIPL_UNCONFIRM_UPDATE;
+
+@Service
+public class QuotesService {
+    private  String tableName="quotes";
+
+    @Autowired
+    private CryptoService cryptoService;
+
+    @Autowired
+    private IdUtils idWorker;
+
+    @Autowired
+    private RedisUtil redisUtil;
+
+    public QuotesDto queryForOne(String dataId) {
+         Quotes quotes =Quotes.dao.findById(dataId);
+        if (!ObjectUtil.isEmpty(quotes)){
+            QuotesDto dto = BeanHelper.copyAs(quotes, QuotesDto.class);
+            return dto;
+        }
+        return null;
+    }
+
+    public List<QuotesDto> insertList(List<QuotesDto> quotesDtoList, String txId) {
+        List<QuotesDto> respList = new ArrayList<>();
+        CacheList<QuotesDto> dtoCacheList = new CacheList<>();
+        dtoCacheList.setTableName(tableName);
+        List<QuotesDto> dtoItemList = new ArrayList<>();
+        quotesDtoList.forEach(e -> {
+            String dataId = idWorker.nextId();
+            QuotesDto cacheItem = BeanHelper.copyAs(e, QuotesDto.class);
+            cacheItem.setDataId(dataId);
+            dtoItemList.add(cacheItem);
+            QuotesDto target = BeanHelper.copyAs(e, QuotesDto.class);
+            target.setDataId(dataId);
+
+            QuotesDto dto =  cryptoService.encryptModelColumns(e);
+            dto.setDataId(dataId);
+            target.setAuthorEncrypt(dto.getAuthor());
+            target.setMessageEncrypt(dto.getMessage());
+            target.setContactEmailEncrypt(dto.getContactEmail());
+            target.setContactFaxEncrypt(dto.getContactFax());
+            target.setContactNameEncrypt(dto.getContactName());
+            target.setContactPhoneEncrypt(dto.getContactPhone());
+            target.setPrimaryRecipientEncrypt(dto.getPrimaryRecipient());
+            target.setShipToEncrypt(dto.getShipTo());
+            target.setBillToEncrypt(dto.getBillTo());
+            DesensitiveUtils.format(target);
+            respList.add(target);
+        });
+        dtoCacheList.setData(dtoItemList);
+        String insertJsonString = JSONArray.toJSONString(dtoCacheList);
+        String insertKey = PIPL_UNCONFIRM_INSERT + txId;
+        boolean redisFlag = redisUtil.set(insertKey, insertJsonString, GlobalConst.DATA_EXPIRE);
+        if (!redisFlag){
+            throw new BizException("缂撳瓨鍐欏叆澶辫触");
+        }
+        return respList;
+    }
+
+    public List<QuotesDto> updateList(List<QuotesDto> quotesDtoList, String txId) {
+        List<QuotesDto> respList = new ArrayList<>();
+        CacheList<QuotesDto> dtoCacheList = new CacheList<>();
+        dtoCacheList.setTableName(tableName);
+        List<QuotesDto> dtoItemList = new ArrayList<>();
+        quotesDtoList.forEach(e -> {
+            Quotes quotes = Quotes.dao.findById(e.getDataId());
+            QuotesDto cacheItem = BeanHelper.copyAs(e, QuotesDto.class);
+            dtoItemList.add(cacheItem);
+            QuotesDto dto = BeanHelper.copyAs(BeanHelper.copy(cacheItem,quotes),QuotesDto.class);
+            QuotesDto target = BeanHelper.copyAs(dto, QuotesDto.class);
+            cryptoService.encryptModelColumns(dto);
+            target.setAuthorEncrypt(dto.getAuthor());
+            target.setMessageEncrypt(dto.getMessage());
+            target.setContactEmailEncrypt(dto.getContactEmail());
+            target.setContactFaxEncrypt(dto.getContactFax());
+            target.setContactNameEncrypt(dto.getContactName());
+            target.setContactPhoneEncrypt(dto.getContactPhone());
+            target.setPrimaryRecipientEncrypt(dto.getPrimaryRecipient());
+            target.setShipToEncrypt(dto.getShipTo());
+            target.setBillToEncrypt(dto.getBillTo());
+            DesensitiveUtils.format(target);
+            respList.add(target);
+        });
+        dtoCacheList.setData(dtoItemList);
+        String updateJsonString = JSONArray.toJSONString(dtoCacheList);
+        String updateKey = PIPL_UNCONFIRM_UPDATE + txId;
+        boolean redisFlag = redisUtil.set(updateKey, updateJsonString,GlobalConst.DATA_EXPIRE);
+        if (!redisFlag){
+            throw new BizException("缂撳瓨鍐欏叆澶辫触");
+        }
+        return respList;
+    }
+
+    public Boolean deleteOne(String dataId) {
+        Quotes quotes = Quotes.dao.findById(dataId);
+        quotes.setIsDelete(1);
+        return quotes.saveOrUpdate();
+    }
+
+    public Boolean undeleteOne(String dataId) {
+        Quotes quotes = Quotes.dao.findById(dataId);
+        quotes.setIsDelete(0);
+        return quotes.saveOrUpdate();
+    }
+
+
+    public List<QuotesDto> search(List<String> idList){
+        if (CollUtil.isEmpty(idList)) {
+            return null;
+        }
+        StringBuilder queryParam = new StringBuilder();
+        queryParam.append("and id in ").append(idList.stream().collect(Collectors.joining(", ", "(", ")")));
+        List<Quotes> quotesList = Quotes.dao.findList(queryParam.toString());
+        return quotesList.stream()
+                .map(quotes -> BeanHelper.copyAs(quotes, QuotesDto.class)).collect(Collectors.toList());
+
+    }
+}
diff --git a/src/main/java/com/deloitte/system/service/RepairService.java b/src/main/java/com/deloitte/system/service/RepairService.java
new file mode 100644
index 0000000..219f853
--- /dev/null
+++ b/src/main/java/com/deloitte/system/service/RepairService.java
@@ -0,0 +1,132 @@
+package com.deloitte.system.service;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.alibaba.fastjson.JSONArray;
+import com.common.core.constant.GlobalConst;
+import com.common.core.exception.BizException;
+import com.common.core.service.CryptoService;
+import com.common.core.utils.*;
+import com.common.redis.util.RedisUtil;
+import com.deloitte.system.model.CacheList;
+import com.deloitte.system.model.Order;
+import com.deloitte.system.model.Repair;
+import com.deloitte.system.request.OrderDto;
+import com.deloitte.system.request.RepairDto;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static com.common.core.constant.GlobalConst.PIPL_UNCONFIRM_INSERT;
+import static com.common.core.constant.GlobalConst.PIPL_UNCONFIRM_UPDATE;
+
+@Service
+public class RepairService {
+    private String tableName = "repair";
+
+    @Autowired
+    private CryptoService cryptoService;
+
+    @Autowired
+    private IdUtils idWorker;
+
+    @Autowired
+    private RedisUtil redisUtil;
+
+    public RepairDto queryForOne(String dataId) {
+        Repair repair = Repair.dao.findById(dataId);
+        if (!ObjectUtil.isEmpty(repair)) {
+            return BeanHelper.copyAs(repair,RepairDto.class);
+        }
+        return null;
+    }
+
+    public List<RepairDto> insertList(List<RepairDto> repairList, String txId) {
+        List<RepairDto> respList = new ArrayList<>();
+        CacheList<RepairDto> dtoCacheList = new CacheList<>();
+        dtoCacheList.setTableName(tableName);
+        List<RepairDto> dtoItemList = new ArrayList<>();
+        repairList.forEach(e -> {
+            String dataId = idWorker.nextId();
+            RepairDto cacheItem = BeanHelper.copyAs(e, RepairDto.class);
+            cacheItem.setDataId(dataId);
+            dtoItemList.add(cacheItem);
+
+            RepairDto target = BeanHelper.copyAs(e, RepairDto.class);
+            target.setDataId(dataId);
+            RepairDto dto = cryptoService.encryptModelColumns(e);
+            dto.setDataId(dataId);
+            target.setTelephonenEncrypt(dto.getTelephonen());
+            target.setContactDEncrypt(dto.getContactD());
+            DesensitiveUtils.format(target);
+            respList.add(target);
+        });
+        dtoCacheList.setData(dtoItemList);
+        String insertJsonString = JSONArray.toJSONString(dtoCacheList);
+        String insertKey = PIPL_UNCONFIRM_INSERT + txId;
+        boolean redisFlag = redisUtil.set(insertKey, insertJsonString, GlobalConst.DATA_EXPIRE);
+        if (!redisFlag) {
+            throw new BizException("缂撳瓨鍐欏叆澶辫触");
+        }
+        return respList;
+    }
+
+    public List<RepairDto> updateList(List<RepairDto> repairList, String txId) {
+        List<RepairDto> respList = new ArrayList<>();
+        CacheList<RepairDto> dtoCacheList = new CacheList<>();
+        dtoCacheList.setTableName(tableName);
+        List<RepairDto> dtoItemList = new ArrayList<>();
+        repairList.forEach(e -> {
+            Repair repair = Repair.dao.findById(e.getDataId());
+            RepairDto cacheItem = BeanHelper.copyAs(e, RepairDto.class);
+            dtoItemList.add(cacheItem);
+            RepairDto dto = BeanHelper.copyAs(BeanHelper.copy(cacheItem,repair),RepairDto.class);
+            RepairDto target = BeanHelper.copyAs(dto, RepairDto.class);
+            dto = cryptoService.encryptModelColumns(dto);
+            target.setTelephonenEncrypt(dto.getTelephonen());
+            target.setContactDEncrypt(dto.getContactD());
+            DesensitiveUtils.format(target);
+            respList.add(target);
+        });
+        dtoCacheList.setData(dtoItemList);
+        String updateJsonString = JSONArray.toJSONString(dtoCacheList);
+        String updateKey = PIPL_UNCONFIRM_UPDATE + txId;
+        boolean redisFlag = redisUtil.set(updateKey, updateJsonString,GlobalConst.DATA_EXPIRE);
+        if (!redisFlag) {
+            throw new BizException("缂撳瓨鍐欏叆澶辫触");
+        }
+        return respList;
+    }
+
+    public Boolean deleteOne(String dataId) {
+        Repair repair = Repair.dao.findById(dataId);
+        repair.setIsDelete(1);
+        return repair.saveOrUpdate();
+    }
+
+    public Boolean undeleteOne(String dataId) {
+        Repair repair = Repair.dao.findById(dataId);
+        repair.setIsDelete(0);
+        return repair.saveOrUpdate();
+    }
+
+    public List<RepairDto> search(List<String> idList){
+        if (CollUtil.isEmpty(idList)) {
+            return null;
+        }
+        StringBuilder queryParam = new StringBuilder();
+        queryParam.append("and id in ").append(idList.stream().collect(Collectors.joining(", ", "(", ")")));
+        List<Repair> quotesList = Repair.dao.findList(queryParam.toString());
+        return quotesList.stream()
+                .map(quotes -> BeanHelper.copyAs(quotes, RepairDto.class)).collect(Collectors.toList());
+
+    }
+
+}
+
+
+
+
diff --git a/src/main/java/com/deloitte/system/service/SwoService.java b/src/main/java/com/deloitte/system/service/SwoService.java
new file mode 100644
index 0000000..204273c
--- /dev/null
+++ b/src/main/java/com/deloitte/system/service/SwoService.java
@@ -0,0 +1,150 @@
+package com.deloitte.system.service;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.alibaba.fastjson.JSONArray;
+import com.common.core.constant.GlobalConst;
+import com.common.core.exception.BizException;
+import com.common.core.service.CryptoService;
+import com.common.core.utils.BeanHelper;
+import com.common.core.utils.DesensitiveUtils;
+import com.common.core.utils.IdUtils;
+import com.common.redis.util.RedisUtil;
+import com.deloitte.system.model.CacheList;
+import com.deloitte.system.model.Swo;
+import com.deloitte.system.request.SwoDto;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static com.common.core.constant.GlobalConst.PIPL_UNCONFIRM_INSERT;
+import static com.common.core.constant.GlobalConst.PIPL_UNCONFIRM_UPDATE;
+
+@Service
+public class SwoService {
+
+    private String tableName="swo";
+
+    @Autowired
+    private CryptoService cryptoService;
+
+    @Autowired
+    private IdUtils idWorker;
+
+    @Autowired
+    private RedisUtil redisUtil;
+
+    public SwoDto queryForOne(String dataId) {
+        Swo swo =Swo.dao.findById(dataId);
+        if (!ObjectUtil.isEmpty(swo)){
+            SwoDto dto = BeanHelper.copyAs(swo, SwoDto.class);
+            return dto;
+        }
+        return null;
+    }
+
+    public List<SwoDto> insertList(List<SwoDto> swoDtoList, String txId) {
+        List<SwoDto> respList = new ArrayList<>();
+        CacheList<SwoDto> dtoCacheList = new CacheList<>();
+        dtoCacheList.setTableName(tableName);
+        List<SwoDto> dtoItemList = new ArrayList<>();
+        swoDtoList.forEach(e -> {
+            String dataId = idWorker.nextId();
+            SwoDto cacheItem = BeanHelper.copyAs(e, SwoDto.class);
+            cacheItem.setDataId(dataId);
+            dtoItemList.add(cacheItem);
+            SwoDto target = BeanHelper.copyAs(e, SwoDto.class);
+            target.setDataId(dataId);
+            SwoDto dto =  cryptoService.encryptModelColumns(e);
+            dto.setDataId(dataId);
+            target.setAuthorEncrypt(dto.getAuthor());
+            target.setBccEncrypt(dto.getBcc());
+            target.setBccNameEncrypt(dto.getBccName());
+            target.setCcEncrypt(dto.getCc());
+            target.setCcNameEncrypt(dto.getCcName());
+            target.setContactEncrypt(dto.getContact());
+            target.setContactNameHiddenEncrypt(dto.getContactNameHidden());
+            target.setEmailEncrypt(dto.getEmail());
+            target.setMessageEncrypt(dto.getMessage());
+            target.setPrimaryRecipientEncrypt(dto.getPrimaryRecipient());
+            target.setRecipientEncrypt(dto.getRecipient());
+            target.setSendEncrypt(dto.getSend());
+            target.setToNameEncrypt(dto.getToName());
+            DesensitiveUtils.format(target);
+            respList.add(target);
+        });
+        dtoCacheList.setData(dtoItemList);
+        String insertJsonString = JSONArray.toJSONString(dtoCacheList);
+        String insertKey = PIPL_UNCONFIRM_INSERT + txId;
+        boolean redisFlag = redisUtil.set(insertKey, insertJsonString, GlobalConst.DATA_EXPIRE);
+        if (!redisFlag){
+            throw new BizException("缂撳瓨鍐欏叆澶辫触");
+        }
+        return respList;
+    }
+
+    public List<SwoDto> updateList(List<SwoDto> swoDtoList, String txId) {
+        List<SwoDto> respList = new ArrayList<>();
+        CacheList<SwoDto> dtoCacheList = new CacheList<>();
+        dtoCacheList.setTableName(tableName);
+        List<SwoDto> dtoItemList = new ArrayList<>();
+        swoDtoList.forEach(e -> {
+            Swo swo = Swo.dao.findById(e.getDataId());
+            SwoDto cacheItem = BeanHelper.copyAs(e, SwoDto.class);
+            dtoItemList.add(cacheItem);
+            SwoDto dto = BeanHelper.copyAs(BeanHelper.copy(cacheItem,swo),SwoDto.class);
+            SwoDto target = BeanHelper.copyAs(dto, SwoDto.class);
+            dto = cryptoService.encryptModelColumns(dto);
+            target.setAuthorEncrypt(dto.getAuthor());
+            target.setBccEncrypt(dto.getBcc());
+            target.setBccNameEncrypt(dto.getBccName());
+            target.setCcEncrypt(dto.getCc());
+            target.setCcNameEncrypt(dto.getCcName());
+            target.setContactEncrypt(dto.getContact());
+            target.setContactNameHiddenEncrypt(dto.getContactNameHidden());
+            target.setEmailEncrypt(dto.getEmail());
+            target.setMessageEncrypt(dto.getMessage());
+            target.setPrimaryRecipientEncrypt(dto.getPrimaryRecipient());
+            target.setRecipientEncrypt(dto.getRecipient());
+            target.setSendEncrypt(dto.getSend());
+            target.setToNameEncrypt(dto.getToName());
+            DesensitiveUtils.format(target);
+            respList.add(target);
+        });
+        dtoCacheList.setData(dtoItemList);
+        String updateJsonString = JSONArray.toJSONString(dtoCacheList);
+        String updateKey = PIPL_UNCONFIRM_UPDATE + txId;
+        boolean redisFlag = redisUtil.set(updateKey, updateJsonString,GlobalConst.DATA_EXPIRE);
+        if (!redisFlag){
+            throw new BizException("缂撳瓨鍐欏叆澶辫触");
+        }
+        return respList;
+    }
+
+    public Boolean deleteOne(String dataId) {
+        Swo swo = Swo.dao.findById(dataId);
+        swo.setIsDelete(1);
+        return swo.saveOrUpdate();
+    }
+
+    public Boolean undeleteOne(String dataId) {
+        Swo swo = Swo.dao.findById(dataId);
+        swo.setIsDelete(1);
+        return swo.saveOrUpdate();
+    }
+
+    public List<SwoDto> search(List<String> idList){
+        if (CollUtil.isEmpty(idList)) {
+            return null;
+        }
+        StringBuilder queryParam = new StringBuilder();
+        queryParam.append("and id in ").append(idList.stream().collect(Collectors.joining(", ", "(", ")")));
+        List<Swo> quotesList = Swo.dao.findList(queryParam.toString());
+        return quotesList.stream()
+                .map(quotes -> BeanHelper.copyAs(quotes, SwoDto.class)).collect(Collectors.toList());
+
+    }
+}
diff --git a/src/main/java/com/deloitte/system/service/TSRepairService.java b/src/main/java/com/deloitte/system/service/TSRepairService.java
new file mode 100644
index 0000000..5f9a443
--- /dev/null
+++ b/src/main/java/com/deloitte/system/service/TSRepairService.java
@@ -0,0 +1,130 @@
+package com.deloitte.system.service;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.alibaba.fastjson.JSONArray;
+import com.common.core.constant.GlobalConst;
+import com.common.core.exception.BizException;
+import com.common.core.service.CryptoService;
+import com.common.core.utils.BeanHelper;
+import com.common.core.utils.DesensitiveUtils;
+import com.common.core.utils.IdUtils;
+import com.common.redis.util.RedisUtil;
+import com.deloitte.system.model.CacheList;
+import com.deloitte.system.model.TSRepair;
+import com.deloitte.system.request.TSRepairDto;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static com.common.core.constant.GlobalConst.PIPL_UNCONFIRM_INSERT;
+import static com.common.core.constant.GlobalConst.PIPL_UNCONFIRM_UPDATE;
+
+
+@Service
+public class TSRepairService {
+
+    private  String tableName = "ts_repair";
+    @Autowired
+    private CryptoService cryptoService;
+
+    @Autowired
+    private IdUtils idWorker;
+
+    @Autowired
+    private RedisUtil redisUtil;
+
+    public TSRepairDto queryForOne(String dataId) {
+        TSRepair tsRepair =TSRepair.dao.findById(dataId);
+        if (!ObjectUtil.isEmpty(tsRepair)){
+            TSRepairDto dto = BeanHelper.copyAs(tsRepair, TSRepairDto.class);
+            return dto;
+        }
+        return null;
+    }
+
+    public List<TSRepairDto> insertList(List<TSRepairDto> tsRepairDtoList, String txId) {
+        List<TSRepairDto> respList = new ArrayList<>();
+        CacheList<TSRepairDto> dtoCacheList = new CacheList<>();
+        dtoCacheList.setTableName(tableName);
+        List<TSRepairDto> dtoItemList = new ArrayList<>();
+        tsRepairDtoList.forEach(e -> {
+            String dataId = idWorker.nextId();
+            TSRepairDto cacheItem = BeanHelper.copyAs(e, TSRepairDto.class);
+            cacheItem.setDataId(dataId);
+            dtoItemList.add(cacheItem);
+
+            TSRepairDto target = BeanHelper.copyAs(e, TSRepairDto.class);
+            target.setDataId(dataId);
+            TSRepairDto dto =  cryptoService.encryptModelColumns(e);
+            dto.setDataId(dataId);
+            target.setBusinessAContactEncrypt(dto.getBusinessAContact());
+            target.setBusinessAPhoneEncrypt(dto.getBusinessAPhone());
+            DesensitiveUtils.format(target);
+            respList.add(target);
+        });
+        dtoCacheList.setData(dtoItemList);
+        String insertJsonString = JSONArray.toJSONString(dtoCacheList);
+        String insertKey = PIPL_UNCONFIRM_INSERT + txId;
+        boolean redisFlag = redisUtil.set(insertKey, insertJsonString, GlobalConst.DATA_EXPIRE);
+        if (!redisFlag){
+            throw new BizException("缂撳瓨鍐欏叆澶辫触");
+        }
+        return respList;
+    }
+
+    public List<TSRepairDto> updateList(List<TSRepairDto> tsRepairDtoList, String txId) {
+        List<TSRepairDto> respList = new ArrayList<>();
+        CacheList<TSRepairDto> dtoCacheList = new CacheList<>();
+        dtoCacheList.setTableName(tableName);
+        List<TSRepairDto> dtoItemList = new ArrayList<>();
+        tsRepairDtoList.forEach(e -> {
+            TSRepair tsRepair = TSRepair.dao.findById(e.getDataId());
+            TSRepairDto cacheItem = BeanHelper.copyAs(e, TSRepairDto.class);
+            dtoItemList.add(cacheItem);
+            TSRepairDto dto = BeanHelper.copyAs(BeanHelper.copy(cacheItem,tsRepair),TSRepairDto.class);
+            TSRepairDto target = BeanHelper.copyAs(dto, TSRepairDto.class);
+             dto  = cryptoService.encryptModelColumns(dto);
+            target.setBusinessAPhoneEncrypt(dto.getBusinessAPhone());
+            target.setBusinessAContactEncrypt(dto.getBusinessAContact());
+            DesensitiveUtils.format(target);
+            respList.add(target);
+        });
+        dtoCacheList.setData(dtoItemList);
+        String updateJsonString = JSONArray.toJSONString(dtoCacheList);
+        String updateKey = PIPL_UNCONFIRM_UPDATE + txId;
+        boolean redisFlag = redisUtil.set(updateKey, updateJsonString,GlobalConst.DATA_EXPIRE);
+        if (!redisFlag){
+            throw new BizException("缂撳瓨鍐欏叆澶辫触");
+        }
+        return respList;
+
+    }
+
+    public Boolean deleteOne(String dataId) {
+        TSRepair tsRepair = TSRepair.dao.findById(dataId);
+        tsRepair.setIsDelete(1);
+        return tsRepair.saveOrUpdate();
+    }
+
+    public Boolean undeleteOne(String dataId) {
+        TSRepair tsRepair = TSRepair.dao.findById(dataId);
+        tsRepair.setIsDelete(0);
+        return tsRepair.saveOrUpdate();
+    }
+
+    public List<TSRepairDto> search(List<String> idList){
+        if (CollUtil.isEmpty(idList)) {
+            return null;
+        }
+        StringBuilder queryParam = new StringBuilder();
+        queryParam.append("and id in ").append(idList.stream().collect(Collectors.joining(", ", "(", ")")));
+        List<TSRepair> quotesList = TSRepair.dao.findList(queryParam.toString());
+        return quotesList.stream()
+                .map(quotes -> BeanHelper.copyAs(quotes, TSRepairDto.class)).collect(Collectors.toList());
+
+    }
+}
diff --git a/src/main/java/com/deloitte/system/service/UserFaultInfoService.java b/src/main/java/com/deloitte/system/service/UserFaultInfoService.java
new file mode 100644
index 0000000..5efd4da
--- /dev/null
+++ b/src/main/java/com/deloitte/system/service/UserFaultInfoService.java
@@ -0,0 +1,132 @@
+package com.deloitte.system.service;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.alibaba.fastjson.JSONArray;
+import com.common.core.constant.GlobalConst;
+import com.common.core.exception.BizException;
+import com.common.core.service.CryptoService;
+import com.common.core.utils.BeanHelper;
+import com.common.core.utils.DesensitiveUtils;
+import com.common.core.utils.IdUtils;
+import com.common.redis.util.RedisUtil;
+import com.deloitte.system.model.CacheList;
+import com.deloitte.system.model.UserFaultInfo;
+import com.deloitte.system.request.UserFaultInfoDto;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static com.common.core.constant.GlobalConst.PIPL_UNCONFIRM_INSERT;
+import static com.common.core.constant.GlobalConst.PIPL_UNCONFIRM_UPDATE;
+
+@Service
+public class UserFaultInfoService {
+
+    private String tableName="user_fault_info";
+
+    @Autowired
+    private CryptoService cryptoService;
+
+    @Autowired
+    private IdUtils idWorker;
+
+    @Autowired
+    private RedisUtil redisUtil;
+
+    public UserFaultInfoDto queryForOne(String dataId) {
+        UserFaultInfo userFaultInfo =UserFaultInfo.dao.findById(dataId);
+        if (!ObjectUtil.isEmpty(userFaultInfo)){
+            UserFaultInfoDto dto = BeanHelper.copyAs(userFaultInfo, UserFaultInfoDto.class);
+            return dto;
+        }
+        return null;
+
+    }
+
+    public List<UserFaultInfoDto> insertList(List<UserFaultInfoDto> userFaultInfoDtoList, String txId) {
+        List<UserFaultInfoDto> respList = new ArrayList<>();
+        CacheList<UserFaultInfoDto> dtoCacheList = new CacheList<>();
+        dtoCacheList.setTableName(tableName);
+        List<UserFaultInfoDto> dtoItemList = new ArrayList<>();
+        userFaultInfoDtoList.forEach(e -> {
+            String dataId = idWorker.nextId();
+            UserFaultInfoDto cacheItem = BeanHelper.copyAs(e, UserFaultInfoDto.class);
+            cacheItem.setDataId(dataId);
+            dtoItemList.add(cacheItem);
+
+            UserFaultInfoDto target = BeanHelper.copyAs(e, UserFaultInfoDto.class);
+            target.setDataId(dataId);
+            UserFaultInfoDto dto = cryptoService.encryptModelColumns(e);
+            dto.setDataId(dataId);
+            target.setUfContactEncrypt(dto.getUfContact());
+            target.setUfPhoneEncrypt(dto.getUfPhone());
+            target.setInboundEmailAddressEncrypt(dto.getInboundEmailAddress());
+            DesensitiveUtils.format(target);
+            respList.add(target);
+        });
+        dtoCacheList.setData(dtoItemList);
+        String insertJsonString = JSONArray.toJSONString(dtoCacheList);
+        String insertKey = PIPL_UNCONFIRM_INSERT + txId;
+        boolean redisFlag = redisUtil.set(insertKey, insertJsonString, GlobalConst.DATA_EXPIRE);
+        if (!redisFlag){
+            throw new BizException("缂撳瓨鍐欏叆澶辫触");
+        }
+        return respList;
+    }
+
+    public List<UserFaultInfoDto> updateList(List<UserFaultInfoDto> userFaultInfoDtoList, String txId) {
+        List<UserFaultInfoDto> respList = new ArrayList<>();
+        CacheList<UserFaultInfoDto> dtoCacheList = new CacheList<>();
+        dtoCacheList.setTableName(tableName);
+        List<UserFaultInfoDto> dtoItemList = new ArrayList<>();
+        userFaultInfoDtoList.forEach(e -> {
+            UserFaultInfo userFaultInfo = UserFaultInfo.dao.findById(e.getDataId());
+            UserFaultInfoDto cacheItem = BeanHelper.copyAs(e, UserFaultInfoDto.class);
+            dtoItemList.add(cacheItem);
+            UserFaultInfoDto dto = BeanHelper.copyAs(BeanHelper.copy(cacheItem,userFaultInfo),UserFaultInfoDto.class);
+            UserFaultInfoDto target = BeanHelper.copyAs(dto, UserFaultInfoDto.class);
+            dto = cryptoService.encryptModelColumns(dto);
+            target.setUfContactEncrypt(dto.getUfContact());
+            target.setUfPhoneEncrypt(dto.getUfPhone());
+            target.setInboundEmailAddressEncrypt(dto.getInboundEmailAddress());
+            DesensitiveUtils.format(target);
+            respList.add(target);
+        });
+        dtoCacheList.setData(dtoItemList);
+        String updateJsonString = JSONArray.toJSONString(dtoCacheList);
+        String updateKey = PIPL_UNCONFIRM_UPDATE + txId;
+        boolean redisFlag = redisUtil.set(updateKey, updateJsonString,GlobalConst.DATA_EXPIRE);
+        if (!redisFlag){
+            throw new BizException("缂撳瓨鍐欏叆澶辫触");
+        }
+        return respList;
+    }
+
+    public Boolean deleteOne(String dataId) {
+        UserFaultInfo userFaultInfo = UserFaultInfo.dao.findById(dataId);
+        userFaultInfo.setIsDelete(1);
+        return userFaultInfo.saveOrUpdate();
+    }
+
+    public Boolean undeleteOne(String dataId) {
+        UserFaultInfo userFaultInfo = UserFaultInfo.dao.findById(dataId);
+        userFaultInfo.setIsDelete(0);
+        return userFaultInfo.saveOrUpdate();
+    }
+
+    public List<UserFaultInfoDto> search(List<String> idList){
+        if (CollUtil.isEmpty(idList)) {
+            return null;
+        }
+        StringBuilder queryParam = new StringBuilder();
+        queryParam.append("and id in ").append(idList.stream().collect(Collectors.joining(", ", "(", ")")));
+        List<UserFaultInfo> quotesList = UserFaultInfo.dao.findList(queryParam.toString());
+        return quotesList.stream()
+                .map(quotes -> BeanHelper.copyAs(quotes, UserFaultInfoDto.class)).collect(Collectors.toList());
+
+    }
+}
diff --git a/src/main/resources/dev/application.yml b/src/main/resources/dev/application.yml
new file mode 100644
index 0000000..accf034
--- /dev/null
+++ b/src/main/resources/dev/application.yml
@@ -0,0 +1 @@
+server:
  port: 8889
  servlet:
    context-path: /ssbgapi

#swagger绂佺敤
swagger:
  production: true
spring:
  mvc:
    pathmatch:
      matching-strategy: ant_path_matcher
  redis:
    host: sfpi-redis-ssbg.q82q8k.ng.0001.cnw1.cache.amazonaws.com.cn
    port: 6379
    database: 0
    password:
mail:
  smtp:
    host: smtp.qiye.aliyun.com
    port: 465
    protocol: smtp
  imap:
    host: imap.qiye.aliyun.com
    port: 993
    protocol: imap
  default-encoding: utf-8
  properties:
    mail:
      smtp:
        auth: true

jfinal:
  dialect: com.jfinal.plugin.activerecord.dialect.MysqlDialect
  sql-templates:
    - classpath:sqls/*.sql
  show-sql: true

custom:
  datacenter-id: 0
  worker-id: 0

aws:
  region: cn-northwest-1
  secrets:
    mysql: test/mysqlsecretssbg
    sm4: test/SM4Secret
    systemauth: test/systemauthssbg
    mailauth: test/mailauthssbg
  s3:
    bucketName: ssbgbucketdev

salesforce:
  tokenUrl: https://ssbg--pipl.my.salesforce.com/services/oauth2/token
  baseUrl: https://ssbg--pipl.my.salesforce.com/
  sbgurl: https://ssbg--pipl.my.salesforce.com/services/apexrest/
  referer: https://ssbg--pipl.my.salesforce.com/,https://ssbg--pipl--c.visualforce.com/


sap:
  url: https://wdp.olympus.com.cn:44301/RESTAdapter/

# s3鏂囦欢鏌ヨ鍦板潃
file:
  url: https://sfpi-ssbg-test.olympuschina.com:8080/ssbgapi/file/
\ No newline at end of file
diff --git a/src/main/resources/dev/logback.xml b/src/main/resources/dev/logback.xml
new file mode 100644
index 0000000..a1e2142
--- /dev/null
+++ b/src/main/resources/dev/logback.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration debug="false">
+    <!--瀹氫箟鏃ュ織鏂囦欢鐨勫瓨鍌ㄥ湴鍧� 鍕垮湪 LogBack 鐨勯厤缃腑浣跨敤鐩稿璺緞-->
+    <property name="LOG_HOME" value="/home/ec2-user/deploy/dev/ssbglog"/>
+    <!-- 瀹氫箟鏃ュ織鏍煎紡  -->
+    <property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] [%thread] [%-30.30logger{30}] %msg%n"/>
+    <!-- 鎺у埗鍙拌緭鍑� -->
+    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <!--鏍煎紡鍖栬緭鍑猴細%d琛ㄧず鏃ユ湡锛�%thread琛ㄧず绾跨▼鍚嶏紝%-5level锛氱骇鍒粠宸︽樉绀�5涓瓧绗﹀搴�%msg锛氭棩蹇楁秷鎭紝%n鏄崲琛岀-->
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
+            <charset>UTF-8</charset>
+        </encoder>
+    </appender>
+    <appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>${LOG_HOME}/sys-info.log</file>
+        <!-- 寰幆鏀跨瓥锛氬熀浜庢椂闂村垱寤烘棩蹇楁枃浠� -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 鏃ュ織鏂囦欢鍚嶆牸寮� -->
+            <fileNamePattern>${LOG_HOME}/sys-info.%d{yyyy-MM-dd}.zip</fileNamePattern>
+            <maxHistory>30</maxHistory>
+        </rollingPolicy>
+        <encoder>
+            <pattern>${LOG_PATTERN}</pattern>
+            <charset>UTF-8</charset>
+        </encoder>
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <!-- 杩囨护鐨勭骇鍒� -->
+            <level>INFO</level>
+            <!-- 鍖归厤鏃剁殑鎿嶄綔锛氭帴鏀讹紙璁板綍锛� -->
+            <onMatch>ACCEPT</onMatch>
+            <!-- 涓嶅尮閰嶆椂鐨勬搷浣滐細鎷掔粷锛堜笉璁板綍锛� -->
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>${LOG_HOME}/sys-error.log</file>
+        <!-- 寰幆鏀跨瓥锛氬熀浜庢椂闂村垱寤烘棩蹇楁枃浠� -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 鏃ュ織鏂囦欢鍚嶆牸寮� -->
+            <fileNamePattern>${LOG_HOME}/sys-error.%d{yyyy-MM-dd}.zip</fileNamePattern>
+            <maxHistory>30</maxHistory>
+        </rollingPolicy>
+        <encoder>
+            <pattern>${LOG_PATTERN}</pattern>
+        </encoder>
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <!-- 杩囨护鐨勭骇鍒� -->
+            <level>ERROR</level>
+            <!-- 鍖归厤鏃剁殑鎿嶄綔锛氭帴鏀讹紙璁板綍锛� -->
+            <onMatch>ACCEPT</onMatch>
+            <!-- 涓嶅尮閰嶆椂鐨勬搷浣滐細鎷掔粷锛堜笉璁板綍锛� -->
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <!-- 鏃ュ織杈撳嚭绾у埆 -->
+    <logger name="org.springframework" level="info"/>
+    <logger name="com.deloitte" level="info"/>
+    <root level="info">
+        <appender-ref ref="CONSOLE"/>
+        <appender-ref ref="file_info"/>
+        <appender-ref ref="file_error"/>
+    </root>
+</configuration>
\ No newline at end of file
diff --git a/src/main/resources/local/application.yml b/src/main/resources/local/application.yml
new file mode 100644
index 0000000..24137f0
--- /dev/null
+++ b/src/main/resources/local/application.yml
@@ -0,0 +1 @@
+server:
  port: 8889
  servlet:
    context-path: /ssbgapi

#swagger鍚敤
swagger:
  production: false
spring:
  profiles:
    active: local
  mvc:
    pathmatch:
      matching-strategy: ant_path_matcher
  redis:
    host: localhost
    port: 6379
    database: 7
    password:
mail:
  smtp:
    host: smtp.qiye.aliyun.com
    port: 465
    protocol: smtp
  imap:
    host: imap.qiye.aliyun.com
    port: 993
    protocol: imap
  default-encoding: utf-8
  properties:
    mail:
      smtp:
        auth: true
jfinal:
  dialect: com.jfinal.plugin.activerecord.dialect.MysqlDialect
  sql-templates:
    - classpath:sqls/*.sql
  show-sql: true

custom:
  datacenter-id: 0
  worker-id: 0

aws:
  region: cn-northwest-1
  secrets:
    mysql: test/mysqlsecretssbg
    sm4: test/SM4Secret
    systemauth: test/systemauthssbg
    mailauth: test/mailauthssbg
  s3:
    bucketName: ssbgbucketdev


salesforce:
  tokenUrl: https://ssbg--pipl.my.salesforce.com/services/oauth2/token
  baseUrl: https://ssbg--pipl.my.salesforce.com/
  sbgurl: https://ssbg--pipl.my.salesforce.com/services/apexrest/
  referer: https://ssbg--pipl.my.salesforce.com/,https://ssbg--pipl--c.visualforce.com/


sap:
  url: https://wdp.olympus.com.cn:44301/RESTAdapter/

# s3鏂囦欢鏌ヨ鍦板潃
file:
  url: https://sfpi-mebg-test.olympuschina.com:8080/ssbgapi/file/
\ No newline at end of file
diff --git a/src/main/resources/local/logback.xml b/src/main/resources/local/logback.xml
new file mode 100644
index 0000000..717a67e
--- /dev/null
+++ b/src/main/resources/local/logback.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration debug="false">
+    <!--瀹氫箟鏃ュ織鏂囦欢鐨勫瓨鍌ㄥ湴鍧� 鍕垮湪 LogBack 鐨勯厤缃腑浣跨敤鐩稿璺緞-->
+    <property name="LOG_HOME" value="/home/ec2-user/ssbglog"/>
+    <!-- 瀹氫箟鏃ュ織鏍煎紡  -->
+    <property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] [%thread] [%-30.30logger{30}] %msg%n"/>
+    <!-- 鎺у埗鍙拌緭鍑� -->
+    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <!--鏍煎紡鍖栬緭鍑猴細%d琛ㄧず鏃ユ湡锛�%thread琛ㄧず绾跨▼鍚嶏紝%-5level锛氱骇鍒粠宸︽樉绀�5涓瓧绗﹀搴�%msg锛氭棩蹇楁秷鎭紝%n鏄崲琛岀-->
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
+            <charset>UTF-8</charset>
+        </encoder>
+    </appender>
+    <appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>${LOG_HOME}/sys-info.log</file>
+        <!-- 寰幆鏀跨瓥锛氬熀浜庢椂闂村垱寤烘棩蹇楁枃浠� -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 鏃ュ織鏂囦欢鍚嶆牸寮� -->
+            <fileNamePattern>${LOG_HOME}/sys-info.%d{yyyy-MM-dd}.zip</fileNamePattern>
+            <maxHistory>30</maxHistory>
+        </rollingPolicy>
+        <encoder>
+            <pattern>${LOG_PATTERN}</pattern>
+            <charset>UTF-8</charset>
+        </encoder>
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <!-- 杩囨护鐨勭骇鍒� -->
+            <level>INFO</level>
+            <!-- 鍖归厤鏃剁殑鎿嶄綔锛氭帴鏀讹紙璁板綍锛� -->
+            <onMatch>ACCEPT</onMatch>
+            <!-- 涓嶅尮閰嶆椂鐨勬搷浣滐細鎷掔粷锛堜笉璁板綍锛� -->
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>${LOG_HOME}/sys-error.log</file>
+        <!-- 寰幆鏀跨瓥锛氬熀浜庢椂闂村垱寤烘棩蹇楁枃浠� -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 鏃ュ織鏂囦欢鍚嶆牸寮� -->
+            <fileNamePattern>${LOG_HOME}/sys-error.%d{yyyy-MM-dd}.zip</fileNamePattern>
+            <maxHistory>30</maxHistory>
+        </rollingPolicy>
+        <encoder>
+            <pattern>${LOG_PATTERN}</pattern>
+        </encoder>
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <!-- 杩囨护鐨勭骇鍒� -->
+            <level>ERROR</level>
+            <!-- 鍖归厤鏃剁殑鎿嶄綔锛氭帴鏀讹紙璁板綍锛� -->
+            <onMatch>ACCEPT</onMatch>
+            <!-- 涓嶅尮閰嶆椂鐨勬搷浣滐細鎷掔粷锛堜笉璁板綍锛� -->
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <!-- 鏃ュ織杈撳嚭绾у埆 -->
+    <logger name="org.springframework" level="info"/>
+    <logger name="com.deloitte" level="info"/>
+    <root level="info">
+        <appender-ref ref="CONSOLE"/>
+        <appender-ref ref="file_info"/>
+        <appender-ref ref="file_error"/>
+    </root>
+</configuration>
\ No newline at end of file
diff --git a/src/main/resources/prod1/application.yml b/src/main/resources/prod1/application.yml
new file mode 100644
index 0000000..822ee90
--- /dev/null
+++ b/src/main/resources/prod1/application.yml
@@ -0,0 +1 @@
+server:
  port: 8891
  servlet:
    context-path: /ssbgapi

#swagger绂佺敤
swagger:
  production: true
spring:
  mvc:
    pathmatch:
      matching-strategy: ant_path_matcher
  redis:
    host: sfpi-redis-ssbg.q82q8k.ng.0001.cnw1.cache.amazonaws.com.cn
    port: 6379
    database: 2
    password:
mail:
  smtp:
    host: smtp.qiye.aliyun.com
    port: 465
    protocol: smtp
  imap:
    host: imap.qiye.aliyun.com
    port: 993
    protocol: imap
  default-encoding: utf-8
  properties:
    mail:
      smtp:
        auth: true

jfinal:
  dialect: com.jfinal.plugin.activerecord.dialect.MysqlDialect
  sql-templates:
    - classpath:sqls/*.sql
  show-sql: true

custom:
  datacenter-id: 0
  worker-id: 0

aws:
  region: cn-northwest-1
  secrets:
    mysql: prod/mysqlsecretssbg
    sm4: prod/SM4Secret
    systemauth: prod/systemauthssbg
    mailauth: prod/mailauthssbg
  s3:
    bucketName: ssbgbucketpro

salesforce:
  tokenUrl: https://ap6.salesforce.com/services/oauth2/token
  baseUrl: https://ssbg.my.salesforce.com/
  sbgurl: https://ssbg.my.salesforce.com/services/apexrest/
  referer: https://ssbg.my.salesforce.com/,https://ssbg--c.ap6.visual.force.com/,https://ssbgdealer.force.com/,https://ssbg--c.ap26.visual.force.com/


sap:
  url: https://wdp.olympus.com.cn:44302/RESTAdapter/

# s3鏂囦欢鏌ヨ鍦板潃
file:
  url: https://sfpi-prod.evidentscientific.com.cn:8082/ssbgapi/file/
\ No newline at end of file
diff --git a/src/main/resources/prod1/logback.xml b/src/main/resources/prod1/logback.xml
new file mode 100644
index 0000000..0d69a2e
--- /dev/null
+++ b/src/main/resources/prod1/logback.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration debug="false">
+    <!--瀹氫箟鏃ュ織鏂囦欢鐨勫瓨鍌ㄥ湴鍧� 鍕垮湪 LogBack 鐨勯厤缃腑浣跨敤鐩稿璺緞-->
+    <property name="LOG_HOME" value="/home/ec2-user/deploy/prod/ssbglog"/>
+    <!-- 瀹氫箟鏃ュ織鏍煎紡  -->
+    <property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] [%thread] [%-30.30logger{30}] %msg%n"/>
+    <!-- 鎺у埗鍙拌緭鍑� -->
+    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <!--鏍煎紡鍖栬緭鍑猴細%d琛ㄧず鏃ユ湡锛�%thread琛ㄧず绾跨▼鍚嶏紝%-5level锛氱骇鍒粠宸︽樉绀�5涓瓧绗﹀搴�%msg锛氭棩蹇楁秷鎭紝%n鏄崲琛岀-->
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
+            <charset>UTF-8</charset>
+        </encoder>
+    </appender>
+    <appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>${LOG_HOME}/sys-info.log</file>
+        <!-- 寰幆鏀跨瓥锛氬熀浜庢椂闂村垱寤烘棩蹇楁枃浠� -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 鏃ュ織鏂囦欢鍚嶆牸寮� -->
+            <fileNamePattern>${LOG_HOME}/sys-info.%d{yyyy-MM-dd}.zip</fileNamePattern>
+            <maxHistory>90</maxHistory>
+        </rollingPolicy>
+        <encoder>
+            <pattern>${LOG_PATTERN}</pattern>
+            <charset>UTF-8</charset>
+        </encoder>
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <!-- 杩囨护鐨勭骇鍒� -->
+            <level>INFO</level>
+            <!-- 鍖归厤鏃剁殑鎿嶄綔锛氭帴鏀讹紙璁板綍锛� -->
+            <onMatch>ACCEPT</onMatch>
+            <!-- 涓嶅尮閰嶆椂鐨勬搷浣滐細鎷掔粷锛堜笉璁板綍锛� -->
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>${LOG_HOME}/sys-error.log</file>
+        <!-- 寰幆鏀跨瓥锛氬熀浜庢椂闂村垱寤烘棩蹇楁枃浠� -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 鏃ュ織鏂囦欢鍚嶆牸寮� -->
+            <fileNamePattern>${LOG_HOME}/sys-error.%d{yyyy-MM-dd}.zip</fileNamePattern>
+            <maxHistory>90</maxHistory>
+        </rollingPolicy>
+        <encoder>
+            <pattern>${LOG_PATTERN}</pattern>
+        </encoder>
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <!-- 杩囨护鐨勭骇鍒� -->
+            <level>ERROR</level>
+            <!-- 鍖归厤鏃剁殑鎿嶄綔锛氭帴鏀讹紙璁板綍锛� -->
+            <onMatch>ACCEPT</onMatch>
+            <!-- 涓嶅尮閰嶆椂鐨勬搷浣滐細鎷掔粷锛堜笉璁板綍锛� -->
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <!-- 鏃ュ織杈撳嚭绾у埆 -->
+    <logger name="org.springframework" level="info"/>
+    <logger name="com.deloitte" level="info"/>
+    <root level="info">
+        <appender-ref ref="CONSOLE"/>
+        <appender-ref ref="file_info"/>
+        <appender-ref ref="file_error"/>
+    </root>
+</configuration>
\ No newline at end of file
diff --git a/src/main/resources/prod2/application.yml b/src/main/resources/prod2/application.yml
new file mode 100644
index 0000000..2bd02b7
--- /dev/null
+++ b/src/main/resources/prod2/application.yml
@@ -0,0 +1 @@
+server:
  port: 8891
  servlet:
    context-path: /ssbgapi

#swagger绂佺敤
swagger:
  production: true
spring:
  mvc:
    pathmatch:
      matching-strategy: ant_path_matcher
  redis:
    host: sfpi-redis-ssbg.q82q8k.ng.0001.cnw1.cache.amazonaws.com.cn
    port: 6379
    database: 2
    password:
mail:
  smtp:
    host: smtp.qiye.aliyun.com
    port: 465
    protocol: smtp
  imap:
    host: imap.qiye.aliyun.com
    port: 993
    protocol: imap
  default-encoding: utf-8
  properties:
    mail:
      smtp:
        auth: true

jfinal:
  dialect: com.jfinal.plugin.activerecord.dialect.MysqlDialect
  sql-templates:
    - classpath:sqls/*.sql
  show-sql: true

custom:
  datacenter-id: 0
  worker-id: 1

aws:
  region: cn-northwest-1
  secrets:
    mysql: prod/mysqlsecretssbg
    sm4: prod/SM4Secret
    systemauth: prod/systemauthssbg
    mailauth: prod/mailauthssbg
  s3:
    bucketName: ssbgbucketpro

salesforce:
  tokenUrl: https://ap6.salesforce.com/services/oauth2/token
  baseUrl: https://ssbg.my.salesforce.com/
  sbgurl: https://ssbg.my.salesforce.com/services/apexrest/
  referer: https://ssbg.my.salesforce.com/,https://ssbg--c.ap6.visual.force.com/,https://ssbgdealer.force.com/,https://ssbg--c.ap26.visual.force.com/


sap:
  url: https://wdp.olympus.com.cn:44302/RESTAdapter/

# s3鏂囦欢鏌ヨ鍦板潃
file:
  url: https://sfpi-prod.evidentscientific.com.cn:8082/ssbgapi/file/
\ No newline at end of file
diff --git a/src/main/resources/prod2/logback.xml b/src/main/resources/prod2/logback.xml
new file mode 100644
index 0000000..0d69a2e
--- /dev/null
+++ b/src/main/resources/prod2/logback.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration debug="false">
+    <!--瀹氫箟鏃ュ織鏂囦欢鐨勫瓨鍌ㄥ湴鍧� 鍕垮湪 LogBack 鐨勯厤缃腑浣跨敤鐩稿璺緞-->
+    <property name="LOG_HOME" value="/home/ec2-user/deploy/prod/ssbglog"/>
+    <!-- 瀹氫箟鏃ュ織鏍煎紡  -->
+    <property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] [%thread] [%-30.30logger{30}] %msg%n"/>
+    <!-- 鎺у埗鍙拌緭鍑� -->
+    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <!--鏍煎紡鍖栬緭鍑猴細%d琛ㄧず鏃ユ湡锛�%thread琛ㄧず绾跨▼鍚嶏紝%-5level锛氱骇鍒粠宸︽樉绀�5涓瓧绗﹀搴�%msg锛氭棩蹇楁秷鎭紝%n鏄崲琛岀-->
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
+            <charset>UTF-8</charset>
+        </encoder>
+    </appender>
+    <appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>${LOG_HOME}/sys-info.log</file>
+        <!-- 寰幆鏀跨瓥锛氬熀浜庢椂闂村垱寤烘棩蹇楁枃浠� -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 鏃ュ織鏂囦欢鍚嶆牸寮� -->
+            <fileNamePattern>${LOG_HOME}/sys-info.%d{yyyy-MM-dd}.zip</fileNamePattern>
+            <maxHistory>90</maxHistory>
+        </rollingPolicy>
+        <encoder>
+            <pattern>${LOG_PATTERN}</pattern>
+            <charset>UTF-8</charset>
+        </encoder>
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <!-- 杩囨护鐨勭骇鍒� -->
+            <level>INFO</level>
+            <!-- 鍖归厤鏃剁殑鎿嶄綔锛氭帴鏀讹紙璁板綍锛� -->
+            <onMatch>ACCEPT</onMatch>
+            <!-- 涓嶅尮閰嶆椂鐨勬搷浣滐細鎷掔粷锛堜笉璁板綍锛� -->
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>${LOG_HOME}/sys-error.log</file>
+        <!-- 寰幆鏀跨瓥锛氬熀浜庢椂闂村垱寤烘棩蹇楁枃浠� -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 鏃ュ織鏂囦欢鍚嶆牸寮� -->
+            <fileNamePattern>${LOG_HOME}/sys-error.%d{yyyy-MM-dd}.zip</fileNamePattern>
+            <maxHistory>90</maxHistory>
+        </rollingPolicy>
+        <encoder>
+            <pattern>${LOG_PATTERN}</pattern>
+        </encoder>
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <!-- 杩囨护鐨勭骇鍒� -->
+            <level>ERROR</level>
+            <!-- 鍖归厤鏃剁殑鎿嶄綔锛氭帴鏀讹紙璁板綍锛� -->
+            <onMatch>ACCEPT</onMatch>
+            <!-- 涓嶅尮閰嶆椂鐨勬搷浣滐細鎷掔粷锛堜笉璁板綍锛� -->
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <!-- 鏃ュ織杈撳嚭绾у埆 -->
+    <logger name="org.springframework" level="info"/>
+    <logger name="com.deloitte" level="info"/>
+    <root level="info">
+        <appender-ref ref="CONSOLE"/>
+        <appender-ref ref="file_info"/>
+        <appender-ref ref="file_error"/>
+    </root>
+</configuration>
\ No newline at end of file
diff --git a/src/main/resources/sqls/theme.sql b/src/main/resources/sqls/theme.sql
new file mode 100644
index 0000000..8deee7f
--- /dev/null
+++ b/src/main/resources/sqls/theme.sql
@@ -0,0 +1,5 @@
+#namespace("user")
+  #sql("queryUser")
+    select * from user t where t.User like concat('%',#para(title),'%')
+  #end
+#end
diff --git a/src/main/resources/stg/application.yml b/src/main/resources/stg/application.yml
new file mode 100644
index 0000000..fe608af
--- /dev/null
+++ b/src/main/resources/stg/application.yml
@@ -0,0 +1 @@
+server:
  port: 8890
  servlet:
    context-path: /ssbgapi

#swagger绂佺敤
swagger:
  production: true
spring:
  mvc:
    pathmatch:
      matching-strategy: ant_path_matcher
  redis:
    host: sfpi-redis-ssbg.q82q8k.ng.0001.cnw1.cache.amazonaws.com.cn
    port: 6379
    database: 1
    password:
mail:
  smtp:
    host: smtp.qiye.aliyun.com
    port: 465
    protocol: smtp
  imap:
    host: imap.qiye.aliyun.com
    port: 993
    protocol: imap
  default-encoding: utf-8
  properties:
    mail:
      smtp:
        auth: true

jfinal:
  dialect: com.jfinal.plugin.activerecord.dialect.MysqlDialect
  sql-templates:
    - classpath:sqls/*.sql
  show-sql: true

custom:
  datacenter-id: 0
  worker-id: 0

aws:
  region: cn-northwest-1
  secrets:
    mysql: stg/mysqlsecretssbg
    sm4: stg/SM4Secret
    systemauth: stg/systemauthssbg
    mailauth: test/mailauthssbg
  s3:
    bucketName: ssbgbucketstg

salesforce:
  tokenUrl: https://ssbg--ssbgtest.my.salesforce.com/services/oauth2/token
  baseUrl: https://ssbg--ssbgtest.my.salesforce.com/
  sbgurl: https://ssbg--ssbgtest.my.salesforce.com/services/apexrest/
  referer: https://ssbg--ssbgtest.my.salesforce.com/,https://ssbg--ssbgtest--c.visualforce.com/,https://ssbgtest-ssbgdealer.cs112.force.com/


sap:
  url: http://wdp.olympus.com.cn:8089/RESTAdapter/

# s3鏂囦欢鏌ヨ鍦板潃
file:
  url: https://sfpi-test.Evidentscientific.com.cn:8081/ssbgapi/file/
\ No newline at end of file
diff --git a/src/main/resources/stg/logback.xml b/src/main/resources/stg/logback.xml
new file mode 100644
index 0000000..7850d08
--- /dev/null
+++ b/src/main/resources/stg/logback.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration debug="false">
+    <!--瀹氫箟鏃ュ織鏂囦欢鐨勫瓨鍌ㄥ湴鍧� 鍕垮湪 LogBack 鐨勯厤缃腑浣跨敤鐩稿璺緞-->
+    <property name="LOG_HOME" value="/home/ec2-user/deploy/stg/ssbglog"/>
+    <!-- 瀹氫箟鏃ュ織鏍煎紡  -->
+    <property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] [%thread] [%-30.30logger{30}] %msg%n"/>
+    <!-- 鎺у埗鍙拌緭鍑� -->
+    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <!--鏍煎紡鍖栬緭鍑猴細%d琛ㄧず鏃ユ湡锛�%thread琛ㄧず绾跨▼鍚嶏紝%-5level锛氱骇鍒粠宸︽樉绀�5涓瓧绗﹀搴�%msg锛氭棩蹇楁秷鎭紝%n鏄崲琛岀-->
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
+            <charset>UTF-8</charset>
+        </encoder>
+    </appender>
+    <appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>${LOG_HOME}/sys-info.log</file>
+        <!-- 寰幆鏀跨瓥锛氬熀浜庢椂闂村垱寤烘棩蹇楁枃浠� -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 鏃ュ織鏂囦欢鍚嶆牸寮� -->
+            <fileNamePattern>${LOG_HOME}/sys-info.%d{yyyy-MM-dd}.zip</fileNamePattern>
+            <maxHistory>30</maxHistory>
+        </rollingPolicy>
+        <encoder>
+            <pattern>${LOG_PATTERN}</pattern>
+            <charset>UTF-8</charset>
+        </encoder>
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <!-- 杩囨护鐨勭骇鍒� -->
+            <level>INFO</level>
+            <!-- 鍖归厤鏃剁殑鎿嶄綔锛氭帴鏀讹紙璁板綍锛� -->
+            <onMatch>ACCEPT</onMatch>
+            <!-- 涓嶅尮閰嶆椂鐨勬搷浣滐細鎷掔粷锛堜笉璁板綍锛� -->
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>${LOG_HOME}/sys-error.log</file>
+        <!-- 寰幆鏀跨瓥锛氬熀浜庢椂闂村垱寤烘棩蹇楁枃浠� -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 鏃ュ織鏂囦欢鍚嶆牸寮� -->
+            <fileNamePattern>${LOG_HOME}/sys-error.%d{yyyy-MM-dd}.zip</fileNamePattern>
+            <maxHistory>30</maxHistory>
+        </rollingPolicy>
+        <encoder>
+            <pattern>${LOG_PATTERN}</pattern>
+        </encoder>
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <!-- 杩囨护鐨勭骇鍒� -->
+            <level>ERROR</level>
+            <!-- 鍖归厤鏃剁殑鎿嶄綔锛氭帴鏀讹紙璁板綍锛� -->
+            <onMatch>ACCEPT</onMatch>
+            <!-- 涓嶅尮閰嶆椂鐨勬搷浣滐細鎷掔粷锛堜笉璁板綍锛� -->
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <!-- 鏃ュ織杈撳嚭绾у埆 -->
+    <logger name="org.springframework" level="info"/>
+    <logger name="com.deloitte" level="info"/>
+    <root level="info">
+        <appender-ref ref="CONSOLE"/>
+        <appender-ref ref="file_info"/>
+        <appender-ref ref="file_error"/>
+    </root>
+</configuration>
\ No newline at end of file

--
Gitblit v1.9.1