From 33321f5486fd586fda6fd3f46b7e71754fede28b Mon Sep 17 00:00:00 2001
From: dangsn <dangsn@chicecm.com>
Date: 星期四, 06 六月 2024 14:40:20 +0800
Subject: [PATCH] 调整项目,新增基础模块

---
 Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/bo/SheetDataSet.java                                   |   59 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/undo/UndoTaskPlugin.java               |   68 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/Md5.java                                     |  120 
 Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/aspose/words/zzZLS.java                                                |  231 
 Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/word/util/WordUtil.java                                    |  429 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/interceptor/VciLogStorageI.java                   |   24 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/undo/query/UndoTaskQuery.java                         |  147 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/constant/CommonReturnCodeConstant.java            |   60 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/BeanUtil.java                                |  222 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/wrapper/VciReferFieldInfo.java                    |  128 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/yml/YamlPropertySourceFactory.java                |   50 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/clientutil/ClientUtilProcesser.java               |   18 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/autoconfigure/DubboConfig.java                    |    9 
 Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/bo/ReadExcelOption.java                                |  100 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/revision/provider/CommonLifeCycleProvider.java        |   32 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/autoconfigure/AppAutoConfigure.java               |  113 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/interceptor/VciSecurityInterceptor.java           |  198 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/TreeGrid.java                           |   86 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/undo/bo/UndoTaskBO.java                               |   63 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/config/VciConfigModule.java            |   47 
 Source/plt-web/plt-web-parent/plt-starter/pom.xml                                                                              |   56 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/PortalTodoPublishImpl.java         |   10 
 Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/bo/VciCellStyle.java                                   |   86 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/LangCodeEnum.java                         |   85 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciUseRefer.java                       |   26 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciLinkType.java                       |   57 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/permission/VciReferPermission.java     |   20 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/MessageUtils.java                            |   54 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/LifeCycleEvent.java                    |   26 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/toolmodel/StringEscapeEditor.java                 |   75 
 Source/plt-web/plt-web-parent/plt-poi/pom.xml                                                                                  |   53 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/resources/application-web.yml                                              |   24 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/service/BaseService.java                          |   10 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/common/log/VciComponentLogAspect.java                 |  212 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/log/VciBusinessLog.java                |   44 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/constant/RevisionConstant.java                    |   19 
 Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/annotation/ExcelTitle.java                             |   21 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/undo/UndoTaskMethod.java               |   18 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/workflow/WorkflowEventField.java       |   22 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciLogoutAfter.java                |   17 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciChangeDocument.java             |   55 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/BaseModelVO.java                        |  502 +
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/interceptor/VciSessionForLoginI.java              |   71 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/revision/bo/TreeWrapperOptions.java                   |  194 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/interceptor/VciLogAfterInterceptor.java           |   65 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/ImportResult.java                       |  163 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciLifeCycle.java                      |   44 
 Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/bo/ExcelColumnMap.java                                 |  109 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/interceptor/VciNoticePopLoginI.java               |   19 
 Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/bo/WriteExcelOption.java                               |  154 
 Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/bo/VciPoiFont.java                                     |  116 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/constant/RegExpConstant.java                      |   84 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciChangeDataAfter.java            |   29 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/VciChangeDocumentTypeEnum.java            |  120 
 Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/annotation/ExcelRefer.java                             |   20 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/log/VciUnLog.java                      |   16 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/SessionInfo.java                        |  669 +
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/constant/SpecialCharacterConstant.java            |   60 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/workflow/pagemodel/WFWorkflowTaskHisVO.java           |  345 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/Transient.java                         |   23 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciLogoutPlugin.java               |   28 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/service/LanguageServiceI.java                     |   27 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciNoUseBaseResult.java            |   16 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciLifeCycleTranEvent.java             |   28 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciTaskPlugin.java                 |   28 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/ResultCodeEnum.java                       |   57 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/autoconfigure/FeignConfig.java                    |  223 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciPlatformScan.java                   |   21 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/PageHelper.java                         |  416 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/wrapper/VciQueryWrapperForDO.java                 | 1613 +++
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciUseEnum.java                        |   42 
 Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/bo/WriteExcelData.java                                 |  400 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/LogLevelEnum.java                         |   39 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/constant/FrameWorkLcStatusConstant.java           |   24 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciChangeDataBefore.java           |   29 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/Lunar.java                                   |  282 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciLoginPlugin.java                |   28 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/Id.java                                |   11 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/undo/vo/UndoTaskVO.java                               |  145 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/RequestClientInfo.java                  |  131 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/revision/model/ReleasedObjDO.java                     |   76 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/wrapper/VciQueryWrapperOption.java                |  117 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/revision/service/RevisionModelUtil.java               | 1616 +++
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/UserSecretEnum.java                       |  119 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/workflow/WorkflowEvent.java            |   51 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/DataBaseEnum.java                         |  148 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/controller/VciUnCheckRight.java        |   22 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/autoconfigure/SpringMVCConfig.java                |  421 
 Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/util/PoiTemplateProcesser.java                         |   22 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/VciTaskBusTypeEnum.java                   |  116 
 Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/util/ExcelUtil.java                                    | 1662 +++
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/service/VciSecretServiceI.java                    |   43 
 Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/annotation/ExcelColumn.java                            |   70 
 Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/bo/DownloadTempOption.java                             |   60 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciFieldType.java                      |   22 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/toolmodel/String2DateConverterForSpringMvc.java   |   26 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/exception/VciBaseException.java                   |  160 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/BooleanEnum.java                          |   41 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/model/BaseLinkModel.java                          |  255 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/controller/VciReturnErrorUseFile.java  |   18 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/BaseResult.java                         |  393 
 Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/util/PoiImportProcesser.java                           |   21 
 Source/plt-web/plt-web-parent/plt-web/pom.xml                                                                                  |   47 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/exception/ExceptionAdviceHandler.java             |  173 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/VciDateUtil.java                             | 1090 ++
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/autoconfigure/ResponseModifyAdvice.java           |  149 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/properties/VciSessionProperties.java              |  148 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/toolmodel/DateConverter.java                      |  307 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciLifeCycleTrans.java                 |   41 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciLoginAfter.java                 |   16 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/controller/VciUnUseResponseAdvice.java |   22 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/autoconfigure/VciAsyncConfig.java                 |  109 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/model/BaseModel.java                              |  545 +
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/constant/TokenKeyConstant.java                    |   40 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/BaseEnum.java                             |   22 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciEnum.java                           |   38 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/TreeQueryObject.java                    |  203 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/LangBaseUtil.java                            |   41 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/config/VciConfigFieldSelect.java       |   44 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/BaseQueryObject.java                    |  239 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/WebThreadLocalUtil.java                      |   44 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/properties/CorsProperties.java                    |  130 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/VciBaseUtil.java                             | 1932 ++++
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/SessionStorageTypeEnum.java               |   93 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/DataGrid.java                           |  177 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/BeanUtilForVCI.java                          |  258 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/workflow/dto/WFWorkflowRuntimeDTO.java                |   94 
 Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/bo/AppendDataExcelOption.java                          |   87 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/undo/UndoTaskCount.java                |   18 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/Column.java                            |  101 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciTaskBefore.java                 |   23 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/SOAService.java                        |   32 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/permission/VciPermission.java          |  137 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/permission/VciUseReferMethod.java      |   19 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciTaskAfter.java                  |   22 
 Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/word/bo/WordMergeStartTableDataBO.java                     |   88 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/common/log/autoconfigure/VciAutoLogConfigure.java     |   48 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciRevisionRule.java                   |   62 
 Source/plt-web/plt-web-parent/plt-web-base/pom.xml                                                                             |   51 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/BaseEnumInt.java                          |   23 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/BusAnnotationUtil.java                       |   52 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/VciReturnFileTypeEnum.java                |  100 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/config/VciConfigField.java             |   61 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/constant/VciSystemVarConstants.java               |  152 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/BaseLinkModelVO.java                    |  229 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/Tree.java                               |  406 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/revision/provider/CommonRevisionRuleProvider.java     |   25 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/KeyValue.java                           |   68 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/clientutil/BaseClientUtil.java                    |  103 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/revision/service/VciRevisionServiceI.java             |  104 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/ControllerUtil.java                          |  326 
 Source/plt-web/plt-web-parent/pom.xml                                                                                          |  192 
 Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/constant/ExcelLangCodeConstant.java                    |   68 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/interceptor/VciLocaleInterceptor.java             |   82 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/autoconfigure/VciThreadPoolTaskExecutor.java      |  113 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/DataSecretEnum.java                       |  122 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciColumnDefinition.java               |   20 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/constant/QueryOptionConstant.java                 |   76 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/revision/provider/CommonAnnotationProvider.java       |   25 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/VciFieldTypeEnum.java                     |  134 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/ClassUtil.java                               |   85 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/LocalFileUtil.java                           |  386 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/interceptor/VciLogBeforeInterceptor.java          |   75 
 Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/word/bo/WordMergeListDataSource.java                       |  181 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/constant/FileExtensionConstant.java               |   79 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciLogoutBefore.java               |   16 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/ApplicationContextProvider.java              |  107 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/revision/model/RevisionInfo.java                      |  221 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciLoginBefore.java                |   18 
 Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/bo/SheetRowData.java                                   |   61 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciBtmType.java                        |  143 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/XmlType.java                           |   22 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciChangeDataPlugin.java           |   40 
 Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/wrapper/VciParentQueryOption.java                 |  182 
 174 files changed, 25,739 insertions(+), 112 deletions(-)

diff --git a/Source/plt-web/plt-web-parent/plt-poi/pom.xml b/Source/plt-web/plt-web-parent/plt-poi/pom.xml
new file mode 100644
index 0000000..6f12e73
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-poi/pom.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.vci</groupId>
+        <artifactId>plt-web-parent</artifactId>
+        <version>2024.1-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>plt-poi</artifactId>
+
+    <properties>
+        <maven.compiler.source>8</maven.compiler.source>
+        <maven.compiler.target>8</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <poi.version>4.1.0</poi.version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.aspose</groupId>
+            <artifactId>aspose-words</artifactId>
+            <version>18.10.RELEASE</version>
+        </dependency>
+        <dependency>
+            <groupId>com.vci</groupId>
+            <artifactId>plt-web-base</artifactId>
+        </dependency>
+        <dependency><!--闇�瑕佽鍙杄xcel-->
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi</artifactId>
+            <version>${poi.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi-excelant</artifactId>
+            <version>${poi.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi-ooxml-schemas</artifactId>
+            <version>${poi.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi-ooxml</artifactId>
+            <version>${poi.version}</version>
+        </dependency>
+    </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/aspose/words/zzZLS.java b/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/aspose/words/zzZLS.java
new file mode 100644
index 0000000..7354a91
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/aspose/words/zzZLS.java
@@ -0,0 +1,231 @@
+package com.aspose.words;
+
+import com.aspose.words.internal.zz29;
+import com.aspose.words.internal.zz2H;
+import com.aspose.words.internal.zz2I;
+import com.aspose.words.internal.zz6M;
+import com.aspose.words.internal.zz97;
+import com.aspose.words.internal.zzQB;
+import com.aspose.words.internal.zzZ;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.InputStream;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * 鐮磋Вaspose-word
+ * @author weidy
+ */
+final class zzZLS
+{
+    private String[] zzYRe;
+    private String zzYRd;
+    private Date zzYRc;
+    private Date zzYRb;
+
+    final void zzY(String var1, Class var2)
+            throws Exception
+    {
+        if (!"".equals(var1)) {
+            zz2H var10000;
+            File var8;
+            if ((var8 = new File(var1)).exists()) {
+                var10000 = new zz2H(var8);
+            } else {
+                String var9 = zz29.zzC(this.getClass());
+                if ((var8 = new File(var9, var1)).exists()) {
+                    var10000 = new zz2H(var8);
+                } else {
+                    var9 = zz29.zzC(var2);
+                    if (!(var8 = new File(var9, var1)).exists()) {
+                        throw new IllegalStateException("Cannot find license '" + var1 + "'.");
+                    }
+
+                    var10000 = new zz2H(var8);
+                }
+            }
+
+            zz2H var3 = var10000;
+
+            try {
+                this.zzW(var3);
+            } finally {
+                var3.close();
+            }
+        } else {
+            zzYR9 = this;
+        }
+    }
+
+    final void zzW(InputStream paramInputStream)
+            throws Exception
+    {
+        this.zzYRa = 1;zzYR9 = this;
+    }
+
+    static int zzZIV()
+    {
+        return 1;
+    }
+
+    static int zzZIU()
+    {
+        return 1;
+    }
+
+    private void zzV(InputStream paramInputStream)
+            throws Exception
+    {
+        byte[] arrayOfByte1 = zzZ.getBytesFromStream(paramInputStream);byte[] arrayOfByte2 = zz6M.zzZ(zz6M.zzBZ(), zz6M.zzUF(1252), arrayOfByte1);
+        DocumentBuilderFactory localDocumentBuilderFactory;
+        DocumentBuilder localDocumentBuilder;
+        Document localDocument;
+        Element localElement1;
+        Element localElement2 = zzX(localElement1 = (localDocument = (localDocumentBuilder = (localDocumentBuilderFactory = zz97.zzEc()).newDocumentBuilder()).parse(new ByteArrayInputStream(arrayOfByte2))).getDocumentElement(), "Data");Element localElement3 = zzX(localElement1, "Signature");zzZ(localElement2, localElement3);
+        Element localElement4;
+        NodeList localNodeList = (localElement4 = zzX(localElement2, "Products")).getElementsByTagName("Product");this.zzYRe = new String[localNodeList.getLength()];
+        for (int i = 0; i < this.zzYRe.length; i++) {
+            this.zzYRe[i] = localNodeList.item(i).getFirstChild().getNodeValue();
+        }
+        String str = zzZ(localElement2, "EditionType");
+        if ((!"Professional".equals(str)) && (!"Enterprise".equals(str))) {
+            throw new IllegalStateException("Invalid edition type.");
+        }
+        this.zzYRd = zzZ(localElement2, "SerialNumber");this.zzYRc = zzY(localElement2, "SubscriptionExpiry");this.zzYRb = zzY(localElement2, "LicenseExpiry");
+    }
+
+    private static void zzZ(Node var0, Node var1)
+            throws Exception
+    {
+        byte[] var2;
+        if (var0 != null) {
+            StringBuilder var3;
+            zzZ(var3 = new StringBuilder(), var0);
+            var2 = var3.toString().getBytes("UTF-16LE");
+        } else {
+            var2 = new byte[0];
+        }
+
+        byte[] var6;
+        if (var1 != null) {
+            var6 = zz2I.decode(var1.getFirstChild().getNodeValue());
+        } else {
+            var6 = new byte[0];
+        }
+
+        zzZ(var2, var6, "0nRuwNEddXwLfXB7pw66G71MS93gW8mNzJ7vuh3Sf4VAEOBfpxtHLCotymv1PoeukxYe31K441Ivq0Pkvx1yZZG4O1KCv3Omdbs7uqzUB4xXHlOub4VsTODzDJ5MWHqlRCB1HHcGjlyT2sVGiovLt0Grvqw5+QXBuinoBY0suX0=");
+        if (zzYS0.zzZ9e() > 0) {
+            zzYS0.clear();
+            zzZ(var2, var6, "qKFqqhFovZvEYCHeD3N8Oy+AuxrOA8cVvIl4u4qIBMQlzejGyXkiTUjoryuzlhlS2bG80FGmFsH+wUKbYiEkW/4zseZCV/Ej/usbu6yHACQKO/SCy3pYw68Pcv901pvywUnoaYCI2ccCG29+XM+FwpFQuiPb2H7YbI/++SQs6Hk=");
+        }
+
+        if (zzYS0.zzZ9e() > 0) {
+            zzYS0.clear();
+            zzZ(var2, var6, "3ki45T6C4lt12J5MbKfrADBCZcE8OTefdngc9IDKg+lzCGYLuxJFDt16awhJFnA23sX+kQ4/eZQ5pNAYjc+ZJ0+pWwvQR4h8GJ3eWvecdFs7KSWwNmFXZCSN+sbrxwEjzzns1kIHuLNf5r+Zaggns+8rqXR19RSJBOcuFqVipIHv56lF53Hc+hx+y9URIaadO1W8dkTqgwExyfjnbDOaCBEH0CqUL1YIICS/wIUTEKhM0ZlwEcIcHl8XTHLVx96DMX4bbVajj78L4KzevQc442DX28KGDJTveEB1pSKWsr0d4FTx7wKS36RBnWv5lwsRErtTZb5ciVIG1iIJrp87VQ==");
+        }
+    }
+
+    private static void zzZ(byte[] paramArrayOfByte1, byte[] paramArrayOfByte2, String paramString)
+            throws Exception
+    {
+        String str;
+        byte[] arrayOfByte1 = zz2I.decode(str = "AQAB");
+        byte[] arrayOfByte2 = zz2I.decode(str = paramString);
+        zzZ3V localzzZ3V;
+        (localzzZ3V = new zzZ3V(arrayOfByte2, arrayOfByte1)).zzS(paramArrayOfByte1, paramArrayOfByte2);
+    }
+
+    private static synchronized zzQB<String> zzPl(String paramString)
+            throws Exception
+    {
+        InputStream localInputStream;
+        if ((localInputStream = License.class.getResourceAsStream("/com/aspose/words/resources/" + paramString + ".Real.xml")) == null) {
+            throw new IllegalStateException("Cannot find black listed licenses resource. Please report this error to Aspose.");
+        }
+        try
+        {
+            DocumentBuilderFactory localDocumentBuilderFactory;
+            DocumentBuilder localDocumentBuilder;
+            Document localDocument;
+            Element localElement1;
+            Element localElement2 = zzX(localElement1 = (localDocument = (localDocumentBuilder = (localDocumentBuilderFactory = zz97.zzEc()).newDocumentBuilder()).parse(localInputStream)).getDocumentElement(), "Data");Element localElement3 = zzX(localElement1, "Signature");zzZ(localElement2, localElement3);zzQB localzzQB1 = new zzQB();
+
+            NodeList localNodeList = localElement2.getElementsByTagName("SN");
+            for (int i = 0; i < localNodeList.getLength(); i++) {
+                localzzQB1.add(localNodeList.item(i).getFirstChild().getNodeValue());
+            }
+            return localzzQB1;
+        }
+        finally
+        {
+            localInputStream.close();
+        }
+    }
+
+    private static String zzZ(Element paramElement, String paramString)
+    {
+        Element localElement;
+        if ((localElement = zzX(paramElement, paramString)) != null) {
+            return localElement.getFirstChild().getNodeValue();
+        }
+        return "";
+    }
+
+    private static Date zzY(Element paramElement, String paramString)
+            throws ParseException
+    {
+        String str = zzZ(paramElement, paramString);
+        if (!"".equals(str)) {
+            return new SimpleDateFormat("yyyyMMdd").parse(str);
+        }
+        return new Date(253402300799999L);
+    }
+
+    private static Element zzX(Element paramElement, String paramString)
+    {
+        NodeList localNodeList;
+        if ((localNodeList = paramElement.getElementsByTagName(paramString)).getLength() > 0) {
+            return (Element)localNodeList.item(0);
+        }
+        return null;
+    }
+
+    private static void zzZ(StringBuilder paramStringBuilder, Node paramNode)
+    {
+        if (paramNode.getNodeType() == 1)
+        {
+            paramStringBuilder.append('<');paramStringBuilder.append(paramNode.getNodeName());paramStringBuilder.append('>');
+            NodeList localNodeList1;
+            NodeList localNodeList2;
+            Node localNode2;
+            if ((((localNodeList2 = localNodeList1 = paramNode.getChildNodes()) != null) && (localNodeList2.getLength() == 1) && ((localNode2 = localNodeList2.item(0)) != null) && (localNode2.getNodeType() == 3) ? 1 : 0) != 0)
+            {
+                Node localNode1;
+                String str = (str = (str = (str = (localNode1 = localNodeList1.item(0)).getNodeValue()).replace("&", "&amp;")).replace("<", "&lt;")).replace(">", "&gt;");paramStringBuilder.append(str);
+            }
+            else
+            {
+                for (int i = 0; i < localNodeList1.getLength(); i++) {
+                    zzZ(paramStringBuilder, localNodeList1.item(i));
+                }
+            }
+            paramStringBuilder.append('<');paramStringBuilder.append('/');
+
+            paramStringBuilder.append(paramNode.getNodeName());paramStringBuilder.append('>');
+        }
+    }
+
+    private int zzYRa = 0;
+    private static zzZLS zzYR9 = null;
+    private static zzQB<String> zzYR8;
+    private static zzQB<String> zzYR7;
+}
diff --git a/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/annotation/ExcelColumn.java b/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/annotation/ExcelColumn.java
new file mode 100644
index 0000000..b52d681
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/annotation/ExcelColumn.java
@@ -0,0 +1,70 @@
+package com.vci.starter.poi.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * excel閲岀殑鍒�
+ * @author weidy
+ * @date 2020/5/9
+ */
+@Target({ java.lang.annotation.ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ExcelColumn {
+
+    /**
+     * 瀵瑰簲excel閲岀殑鍒�
+     * @return excel涓殑鍒楀悕
+     */
+    String value() ;
+
+    /**
+     * 鍊兼槸鍚﹀彲浠ヤ负绌�
+     * @return true
+     */
+    boolean nullable() default true;
+
+    /**
+     * 鎵�灞炴灇涓剧殑缂栧彿
+     * @return 鏋氫妇缂栧彿
+     */
+    String enumId() default "";
+
+    /**
+     * 鏍¢獙鐨勬鍒欒〃杈惧紡
+     * @return 鏈夋鍒欒〃杈惧紡鐨勬椂鍊欙紝浼氱洿鎺ユ牎楠屾槸鍚︽纭�
+     */
+    String regExg() default "";
+
+    /**
+     * 涓嶆弧瓒虫鍒欒〃杈惧紡鐨勬椂鍊欑殑鎻愮ず鍊硷紝鍙互鏄璇█缂栧彿
+     * @return 榛樿涓虹┖
+     */
+    String regExgTitle() default "";
+
+    /**
+     * 灞炴�у垎缁勶紝甯哥敤浜庢墿灞曞睘鎬х殑鏂瑰紡
+     * @return 鍒嗙粍淇℃伅
+     */
+    String group() default "";
+
+    /**
+     * 鏄惁涓鸿鍙风殑鍒�
+     * @return true琛ㄧず浼氬皢鍐呭鍔犲埌琛屽彿涓�
+     */
+    boolean rowIndexColumn() default false;
+
+    /**
+     * 鍙-瀵煎嚭鐨勬椂鍊欎娇鐢�
+     * @return true琛ㄧず鍙
+     */
+    boolean readOnly() default false;
+
+    /**
+     * 鍗曞厓鏍煎搴�,鍗曚綅鏄帢绫筹紝宸笉澶氭槸html涓婅〃鏍肩殑瀹藉害闄や互10
+     * @return 瀹藉害
+     */
+    int width() default 0;
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/annotation/ExcelRefer.java b/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/annotation/ExcelRefer.java
new file mode 100644
index 0000000..d80c735
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/annotation/ExcelRefer.java
@@ -0,0 +1,20 @@
+package com.vci.starter.poi.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 浣跨敤鍏朵粬鐨勫璞℃潵鑾峰彇excel鐨勫唴瀹�
+ * @author weidy
+ * @date 2020/6/18
+ */
+@Target({ java.lang.annotation.ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ExcelRefer {
+    /**
+     * 鍖呭惈鐨勫叧鑱旂被锛屽彧鑳芥槸涓�涓紝鍚﹀垯鏃犳硶鍖哄垎鍐呭
+     * @return 绫�
+     */
+    Class<?> value();
+}
diff --git a/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/annotation/ExcelTitle.java b/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/annotation/ExcelTitle.java
new file mode 100644
index 0000000..689bd25
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/annotation/ExcelTitle.java
@@ -0,0 +1,21 @@
+package com.vci.starter.poi.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 瀵煎嚭鍒癳xcel鐨勬爣棰樿缃�
+ * @author weidy
+ * @date 2020/5/30
+ */
+@Target({ ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ExcelTitle {
+    /**
+     * 鏍囬鎵�鍦ㄧ殑琛屽彿
+     * @return
+     */
+    int rowIndexForTitle() default 1;
+}
diff --git a/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/bo/AppendDataExcelOption.java b/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/bo/AppendDataExcelOption.java
new file mode 100644
index 0000000..7ae36ca
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/bo/AppendDataExcelOption.java
@@ -0,0 +1,87 @@
+package com.vci.starter.poi.bo;
+
+import java.util.List;
+
+/**
+ * 杩藉姞鏁版嵁鍒癳xcel涓殑閰嶇疆
+ * @author weidy
+ * @date 2022/10/15
+ */
+public class AppendDataExcelOption implements java.io.Serializable{
+
+    /**
+     * 鏍囬鎵�鍦ㄧ殑琛�
+     */
+    private int titleRowIndex = 0;
+
+    /**
+     * 鍐欏叆鏁版嵁鐨別xcel琛ㄦ牸
+     */
+    private String sheetName;
+
+    /**
+     * 鍐欑殑瀛楁
+     */
+    private List<String> writeFields;
+
+    /**
+     * 鍙鐨勫瓧娈�
+     */
+    private List<String> readOnlyFields;
+
+    /**
+     * 浠庡瓧娈典笂鍘绘壘鍙灞炴��
+     */
+    private boolean readOnlyFromField =false;
+
+    public int getTitleRowIndex() {
+        return titleRowIndex;
+    }
+
+    public void setTitleRowIndex(int titleRowIndex) {
+        this.titleRowIndex = titleRowIndex;
+    }
+
+    public String getSheetName() {
+        return sheetName;
+    }
+
+    public void setSheetName(String sheetName) {
+        this.sheetName = sheetName;
+    }
+
+    public List<String> getWriteFields() {
+        return writeFields;
+    }
+
+    public void setWriteFields(List<String> writeFields) {
+        this.writeFields = writeFields;
+    }
+
+    public List<String> getReadOnlyFields() {
+        return readOnlyFields;
+    }
+
+    public void setReadOnlyFields(List<String> readOnlyFields) {
+        this.readOnlyFields = readOnlyFields;
+    }
+
+    public boolean isReadOnlyFromField() {
+        return readOnlyFromField;
+    }
+
+    public void setReadOnlyFromField(boolean readOnlyFromField) {
+        this.readOnlyFromField = readOnlyFromField;
+    }
+
+    @Override
+    public String toString() {
+        return "AppendDataExcelOption{" +
+                "titleRowIndex=" + titleRowIndex +
+                ", sheetName='" + sheetName + '\'' +
+                ", writeFields=" + writeFields +
+                ", readOnlyFields=" + readOnlyFields +
+                ", readOnlyFromField=" + readOnlyFromField +
+                '}';
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/bo/DownloadTempOption.java b/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/bo/DownloadTempOption.java
new file mode 100644
index 0000000..e422e58
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/bo/DownloadTempOption.java
@@ -0,0 +1,60 @@
+package com.vci.starter.poi.bo;
+
+/**
+ * 涓嬭浇妯℃澘鐨勬椂鍊欑殑閰嶇疆
+ * @author weidy
+ * @date 2022/9/28
+ */
+public class DownloadTempOption implements java.io.Serializable{
+
+    /**
+     * 榛樿1000鏉$殑锛屽彧鏈夊湪鏈変笅鎷夌殑鏃跺�欐墠鑳戒綋鐜�
+     */
+    private Integer defaultRowSize = 1000;
+
+    /**
+     * 鏂囦欢鐨勫悕绉�
+     */
+    private String excelName;
+
+    /**
+     * 宸ヤ綔琛ㄧ殑鍚嶇О
+     */
+    private String sheetName;
+
+    public DownloadTempOption(String excelName){
+        this.excelName = excelName;
+    }
+
+    public String getExcelName() {
+        return excelName;
+    }
+
+    public void setExcelName(String excelName) {
+        this.excelName = excelName;
+    }
+
+    public Integer getDefaultRowSize() {
+        return defaultRowSize;
+    }
+
+    public void setDefaultRowSize(Integer defaultRowSize) {
+        this.defaultRowSize = defaultRowSize;
+    }
+
+    public String getSheetName() {
+        return sheetName;
+    }
+
+    public void setSheetName(String sheetName) {
+        this.sheetName = sheetName;
+    }
+
+
+    @Override
+    public String toString() {
+        return "DownloadTempOption{" +
+                "defaultRowSize=" + defaultRowSize +
+                '}';
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/bo/ExcelColumnMap.java b/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/bo/ExcelColumnMap.java
new file mode 100644
index 0000000..7a334ef
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/bo/ExcelColumnMap.java
@@ -0,0 +1,109 @@
+package com.vci.starter.poi.bo;
+
+/**
+ * 閽堝map鐨勬柟寮忕殑璇诲彇鏃讹紝鍐呭
+ * @author weidy
+ * @date 2020/6/18
+ */
+public class ExcelColumnMap {
+
+    /**
+     * 鏍囬涓枃
+     */
+    private String title;
+
+    /**
+     * 鑻辨枃鍚嶇О
+     */
+    private String columnName;
+
+    /**
+     * 鏄惁鍙互涓虹┖
+     */
+    private  boolean nullable = true;
+
+    /**
+     * 姝e垯琛ㄨ揪寮�
+     */
+    private String regExg;
+
+    /**
+     * 涓嶆弧瓒虫鍒欒〃杈惧紡鐨勬椂鍊欑殑鎻愮ず鍊硷紝鍙互鏄璇█缂栧彿
+     * @return 榛樿涓虹┖
+     */
+    private String regExgTitle;
+
+    /**
+     * 灞炴�у垎缁�
+     */
+    private String group;
+
+    public ExcelColumnMap(){
+
+    }
+
+    public ExcelColumnMap(String title,String columnName){
+        this.title = title;
+        this.columnName = columnName;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getColumnName() {
+        return columnName;
+    }
+
+    public void setColumnName(String columnName) {
+        this.columnName = columnName;
+    }
+
+    public boolean isNullable() {
+        return nullable;
+    }
+
+    public void setNullable(boolean nullable) {
+        this.nullable = nullable;
+    }
+
+    public String getRegExg() {
+        return regExg;
+    }
+
+    public void setRegExg(String regExg) {
+        this.regExg = regExg;
+    }
+
+    public String getRegExgTitle() {
+        return regExgTitle;
+    }
+
+    public void setRegExgTitle(String regExgTitle) {
+        this.regExgTitle = regExgTitle;
+    }
+
+    public String getGroup() {
+        return group;
+    }
+
+    public void setGroup(String group) {
+        this.group = group;
+    }
+
+    @Override
+    public String toString() {
+        return "ExcelColumnMap{" +
+                "title='" + title + '\'' +
+                ", columnName='" + columnName + '\'' +
+                ", nullable=" + nullable +
+                ", regExg='" + regExg + '\'' +
+                ", regExgTitle='" + regExgTitle + '\'' +
+                ", group='" + group + '\'' +
+                '}';
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/bo/ReadExcelOption.java b/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/bo/ReadExcelOption.java
new file mode 100644
index 0000000..16e8da6
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/bo/ReadExcelOption.java
@@ -0,0 +1,100 @@
+package com.vci.starter.poi.bo;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 璇诲彇excel鐨勯�夐」
+ * @author weidy
+ * @date 2020/5/9
+ */
+public class ReadExcelOption {
+
+    /**
+     * 棣栬锛岄粯璁や负绗簩琛岋紝鍥犱负涓�鑸琛岄兘鏄爣棰�
+     */
+    private int fristRow = 1;
+
+    /**
+     * 璇诲彇閭d釜宸ヤ綔琛�
+     */
+    private int sheetIndex = 0;
+
+    /**
+     * 璇诲彇閭d釜鍚嶇О鐨勫伐浣滆〃
+     */
+    private String sheetName ;
+
+    /**
+     * 鏄惁璇诲彇鍏ㄩ儴鐨勫伐浣滆〃
+     */
+    private boolean readAllSheet = false;
+
+    /**
+     * 鎵╁睍灞炴�х殑鏄犲皠閰嶇疆锛宲o瀵硅薄涓婂睘鎬ф槸map鐨勫舰寮忔椂浣跨敤锛宬ey涓巈xcelColumn娉ㄨВ鐨剉alue()鐩稿悓锛屽�兼槸瀵瑰簲鐨勬爣棰�
+     */
+    private Map<String, List<ExcelColumnMap>> extendAttrMap ;
+
+    public String getSheetName() {
+        return sheetName;
+    }
+
+    public void setSheetName(String sheetName) {
+        this.sheetName = sheetName;
+    }
+
+    public ReadExcelOption(){
+
+    }
+    public ReadExcelOption(int fristRow){
+        this.fristRow = fristRow;
+    }
+
+    public ReadExcelOption(int fristRow,boolean readAllSheet){
+        this.fristRow = fristRow;
+        this.readAllSheet = readAllSheet;
+    }
+
+    public int getFristRow() {
+        return fristRow;
+    }
+
+    public void setFristRow(int fristRow) {
+        this.fristRow = fristRow;
+    }
+
+    public int getSheetIndex() {
+        return sheetIndex;
+    }
+
+    public void setSheetIndex(int sheetIndex) {
+        this.sheetIndex = sheetIndex;
+    }
+
+    public boolean isReadAllSheet() {
+        return readAllSheet;
+    }
+
+    public void setReadAllSheet(boolean readAllSheet) {
+        this.readAllSheet = readAllSheet;
+    }
+
+    public Map<String, List<ExcelColumnMap>> getExtendAttrMap() {
+        return extendAttrMap;
+    }
+
+    public void setExtendAttrMap(Map<String, List<ExcelColumnMap>> extendAttrMap) {
+        this.extendAttrMap = extendAttrMap;
+    }
+
+    @Override
+    public String toString() {
+        return "ReadExcelOption{" +
+                "fristRow=" + fristRow +
+                ", sheetIndex=" + sheetIndex +
+                ", sheetName='" + sheetName + '\'' +
+                ", readAllSheet=" + readAllSheet +
+                ", extendAttrMap=" + extendAttrMap +
+                '}';
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/bo/SheetDataSet.java b/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/bo/SheetDataSet.java
new file mode 100644
index 0000000..b9c8dba
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/bo/SheetDataSet.java
@@ -0,0 +1,59 @@
+package com.vci.starter.poi.bo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 宸ヤ綔琛ㄦ暟鎹殑闆嗗悎
+ * @author weidy
+ */
+public class SheetDataSet {
+	/**
+	 * 宸ヤ綔琛ㄥ悕绉�
+	 */
+	private String sheetName;
+	
+	public String getSheetName() {
+		return sheetName;
+	}
+
+	public void setSheetName(String sheetName) {
+		this.sheetName = sheetName;
+	}
+
+	public List<SheetRowData> getRowData() {
+		return rowData;
+	}
+
+	public void setRowData(List<SheetRowData> rowData) {
+		this.rowData = rowData;
+	}
+
+	/**
+	 * 鍒楃殑鍚嶇О
+	 */
+	private List<String> colName = new ArrayList<String>();
+	
+
+	public List<String> getColName() {
+		return colName;
+	}
+
+	public void setColName(List<String> colName) {
+		this.colName = colName;
+	}
+
+	/**
+	 * 鍖呭惈鏁版嵁
+	 */
+	private List<SheetRowData> rowData = new ArrayList<SheetRowData>();
+
+	@Override
+	public String toString() {
+		return "SheetDataSet{" +
+				"sheetName='" + sheetName + '\'' +
+				", colName=" + colName +
+				", rowData=" + rowData +
+				'}';
+	}
+}
diff --git a/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/bo/SheetRowData.java b/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/bo/SheetRowData.java
new file mode 100644
index 0000000..a2d842e
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/bo/SheetRowData.java
@@ -0,0 +1,61 @@
+package com.vci.starter.poi.bo;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * excel姣忚鐨勬暟鎹�
+ * @author weidy
+ */
+public class SheetRowData {
+
+	/**
+	 * 琛屽彿
+	 */
+	private String rowIndex;
+
+	/**
+	 * 鏁版嵁锛宬ey鏄垪鍙凤紝浠�0寮�濮嬶紝value鏄叿浣撶殑鍊�
+	 */
+	private Map<Integer,String> data = new HashMap<Integer,String>();
+
+	/**
+	 * 鑾峰彇琛屽彿
+	 * @return 琛屽彿
+	 */
+	public String getRowIndex() {
+		return rowIndex;
+	}
+
+	/**
+	 * 璁剧疆琛屽彿
+	 * @param rowIndex 琛屽彿
+	 */
+	public void setRowIndex(String rowIndex) {
+		this.rowIndex = rowIndex;
+	}
+
+	/**
+	 * 鑾峰彇鏁版嵁瀵硅薄
+	 * @return 琛岀殑鏁版嵁
+	 */
+	public Map<Integer, String> getData() {
+		return data;
+	}
+
+	/**
+	 * 璁剧疆琛岀殑鏁版嵁
+	 * @param data 鏁版嵁,key鏄垪鍙凤紝浠�0寮�濮嬶紝value鏄崟鍏冩牸鐨勫��
+	 */
+	public void setData(Map<Integer, String> data) {
+		this.data = data;
+	}
+
+	@Override
+	public String toString() {
+		return "SheetRowData{" +
+				"rowIndex='" + rowIndex + '\'' +
+				", data=" + data +
+				'}';
+	}
+}
diff --git a/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/bo/VciCellStyle.java b/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/bo/VciCellStyle.java
new file mode 100644
index 0000000..70709f5
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/bo/VciCellStyle.java
@@ -0,0 +1,86 @@
+package com.vci.starter.poi.bo;
+
+import org.apache.poi.ss.usermodel.*;
+
+/**
+ * 鍗曞厓鏍肩殑鏍峰紡锛屽洜涓篜oi閲屽摕浣跨敤workbook.createCellStyle锛岃�宲oi閲岀殑CellStyle涓嶈兘new鍜宻etGet
+ * @author weidy
+ * @date 2022/12/19
+ */
+public class VciCellStyle implements java.io.Serializable{
+
+    /**
+     * 姘村钩瀵归綈
+     */
+    private HorizontalAlignment alignment;
+
+    /**
+     * 鍨傜洿瀵归綈
+     */
+    private VerticalAlignment verticalAlignment;
+
+    /**
+     * 鏄惁鑷姩鎹㈣
+     */
+    private Boolean wrapText;
+
+    /**
+     * 鑳屾櫙鑹�
+     */
+    private IndexedColors fillForegroundColor;
+
+    /**
+     * 濉厖妯″紡
+     */
+    private FillPatternType fillPattern;
+
+    /**
+     * 瀛椾綋鏍峰紡
+     */
+    private VciPoiFont font;
+
+    /**
+     * 椤堕儴杈规
+     */
+    private BorderStyle borderTop;
+
+    /**
+     * 鍙充晶杈规
+     */
+    private BorderStyle borderRight;
+
+    /**
+     * 搴曢儴杈规
+     */
+    private BorderStyle borderBottom;
+
+    /**
+     * 宸﹁竟杈规
+     */
+    private BorderStyle borderLeft;
+
+    /**
+     * 椤堕儴杈规棰滆壊
+     */
+    private IndexedColors topBorderColor;
+
+    /**
+     * 鍙充晶杈规棰滆壊
+     */
+    private IndexedColors rightBorderColor;
+
+    /**
+     * 搴曢儴杈规棰滆壊
+     */
+    private IndexedColors bottomBorderColor;
+
+    /**
+     * 宸﹁竟杈规棰滆壊
+     */
+    private IndexedColors leftBorderColor;
+
+
+
+
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/bo/VciPoiFont.java b/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/bo/VciPoiFont.java
new file mode 100644
index 0000000..ae29342
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/bo/VciPoiFont.java
@@ -0,0 +1,116 @@
+package com.vci.starter.poi.bo;
+
+import org.apache.poi.ss.usermodel.Font;
+import org.apache.poi.ss.usermodel.IndexedColors;
+
+/**
+ * poi鐨勫瓧浣撳璞�
+ * @author weidy
+ * @date 2022/12/19
+ */
+public class VciPoiFont implements java.io.Serializable{
+
+    /**
+     * 瀛椾綋鍚嶇О
+     */
+    private String fontName;
+
+    /**
+     * 瀛椾綋澶у皬
+     */
+    private Short fontHeight;
+
+    /**
+     * 瀛椾綋棰滆壊
+     */
+    private IndexedColors color;
+
+    /**
+     * 鏄惁鍔犵矖
+     */
+    private Boolean bold;
+
+    /**
+     * 鏂滀綋
+     */
+    private Boolean italic;
+
+    /**
+     * 涓嬪垝绾�,浣跨敤Font.U_NONE,Font.U_SINGLE,Font.U_DOUBLE
+     */
+    private byte underLine = Font.U_NONE;
+
+    /**
+     * 瀛椾綋涓婃爣涓嬫爣 , Font.SS_NONE, Font.SS_SUPER, Font.SS_SUB
+     */
+    private byte typeOffset  = Font.SS_NONE;
+
+    /**
+     * 鍒犻櫎绾�
+     */
+    private Boolean strikeout;
+
+    public String getFontName() {
+        return fontName;
+    }
+
+    public void setFontName(String fontName) {
+        this.fontName = fontName;
+    }
+
+    public Short getFontHeight() {
+        return fontHeight;
+    }
+
+    public void setFontHeight(Short fontHeight) {
+        this.fontHeight = fontHeight;
+    }
+
+    public IndexedColors getColor() {
+        return color;
+    }
+
+    public void setColor(IndexedColors color) {
+        this.color = color;
+    }
+
+    public Boolean getBold() {
+        return bold;
+    }
+
+    public void setBold(Boolean bold) {
+        this.bold = bold;
+    }
+
+    public Boolean getItalic() {
+        return italic;
+    }
+
+    public void setItalic(Boolean italic) {
+        this.italic = italic;
+    }
+
+    public byte getUnderLine() {
+        return underLine;
+    }
+
+    public void setUnderLine(byte underLine) {
+        this.underLine = underLine;
+    }
+
+    public byte getTypeOffset() {
+        return typeOffset;
+    }
+
+    public void setTypeOffset(byte typeOffset) {
+        this.typeOffset = typeOffset;
+    }
+
+    public Boolean getStrikeout() {
+        return strikeout;
+    }
+
+    public void setStrikeout(Boolean strikeout) {
+        this.strikeout = strikeout;
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/bo/WriteExcelData.java b/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/bo/WriteExcelData.java
new file mode 100644
index 0000000..34ab1ba
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/bo/WriteExcelData.java
@@ -0,0 +1,400 @@
+package com.vci.starter.poi.bo;
+
+import org.apache.poi.ss.usermodel.CellStyle;
+import org.apache.poi.ss.usermodel.Font;
+
+import java.util.List;
+
+/**
+ * 鍐欏叆鍒癳xcel閲岀殑鏁版嵁
+ * @author weidy
+ */
+public class WriteExcelData {
+
+	//榛樿鐨勫睘鎬�
+	/**
+	 * 琛屽彿锛屼粠0寮�濮�
+	 */
+	private int row;
+	/**
+	 * 鍒楀彿锛屼粠0寮�濮�
+	 */
+	private int col;
+	/**
+	 * 璇诲彇鎴栬�呭啓鍏ョ殑鍊煎璞�
+	 */
+	private Object obj;
+
+	//鍚堝苟鍜屾牱寮�
+	/**
+	 * 鏄惁闇�瑕佸悎骞跺崟鍏冩牸
+	 */
+	private boolean merged = false;
+	/**
+	 * 鍚堝苟琛岀殑鐩爣琛屽彿锛屼粠0寮�濮�
+	 */
+	private int rowTo;
+	/**
+	 * 鍚堝苟鍒楃殑鐩爣鍒楀彿锛屼粠0寮�濮�
+	 */
+	private int colTo;
+	/**
+	 * 鏄惁鎷疯礉鏍峰紡
+	 */
+	private boolean copyStyle = false;
+	/**
+	 * 鎷疯礉鏍峰紡鐨勮
+	 */
+	private int copyStyleRow;
+	/**
+	 * 鎷疯礉鏍峰紡鐨勫垪
+	 */
+	private int copyStyleCol;
+	/**
+	 * 鏄惁灞呬腑
+	 */
+	private boolean center;
+
+
+	//鍏紡
+
+	/**
+	 * 鏄惁涓哄叕寮�,鍏紡鐨勫�艰缃埌obj灞炴�т笂
+	 */
+	private boolean formula = false;
+
+	//鍚嶇О绠$悊鍣�
+
+	/**
+	 * 鍚嶇О绠$悊鍣紝绾ц仈閫夋嫨鐨勬椂鍊欏畾涔夛紝鍚嶇О涓簅bj灞炴�э紝鑼冨洿鏄痳ow,rowto,col,colto
+	 */
+	private boolean nameRefer = false;
+
+	//鏁版嵁鏈夋晥鎬�
+	/**
+	 * 鏁版嵁鏈夋晥鎬�,鍏紡鏄疧bj灞炴�э紝鑼冨洿鏄痳ow,rowto,col,colto
+	 */
+	private boolean validation = false;
+
+	/**
+	 * 鏈夋晥鎬у簭鍒楃殑鍊�
+	 */
+	private List<String> validationDataList;
+
+	/**
+	 * 鏈夋晥鎬ф牎楠屽け璐ョ殑鏃跺�欑殑鎻愮ず淇℃伅锛屽鏋滆缃氨琛ㄧず浼氭樉绀洪敊璇�
+	 */
+	private String validationErrorMsg ;
+
+	/**
+	 * 瀛椾綋棰滆壊
+	 */
+	private String fontColor;
+
+
+	/**
+	 * 鏃堕棿鏍煎紡
+	 */
+	private String dateFormat;
+
+	/**
+	 * 鍙
+	 */
+	private boolean readOnly;
+
+	/**
+	 * 鍗曞厓鏍煎搴�,宸笉澶氭槸html涓婅〃鏍煎搴﹂櫎浠�10
+	 */
+	private Integer width;
+
+
+	public String getFontColor() {
+		return fontColor;
+	}
+
+	public void setFontColor(String fontColor) {
+		this.fontColor = fontColor;
+	}
+
+
+	public List<String> getValidationDataList() {
+		return validationDataList;
+	}
+
+	public void setValidationDataList(List<String> validationDataList) {
+		this.validationDataList = validationDataList;
+	}
+
+	/**
+	 * 榛樿鐨勬瀯閫犳柟娉�
+	 */
+	public WriteExcelData(){
+		
+	}
+
+	/**
+	 * 鏋勯�犳柟娉�
+	 * @param row 琛�
+	 * @param col 鍒�
+	 * @param obj 鍊�
+	 */
+	public WriteExcelData(int row, int col, Object obj){
+		this.row = row;
+		this.col = col;
+		this.obj = obj;
+	}
+
+	/**
+	 * 鍐欏叕寮�
+	 * @param row 琛屽彿 浠�0 寮�濮�
+	 * @param col 鍒楀彿浠�0寮�濮�
+	 * @param foumula 鍏紡鐨勫��
+	 */
+	public void writeFormula(int row,int col, String foumula){
+		this.row = row;
+		this.col = col;
+		this.obj = foumula;
+		this.formula = true;
+	}
+
+	/**
+	 * 鍐欏悕绉扮鐞嗗櫒
+	 * @param row 琛屽彿
+	 * @param col 鍒楀彿
+	 * @param rowTo 缁撴潫琛岀殑琛屽彿
+	 * @param colTo 缁撴潫鍒楃殑鍒楀彿
+	 * @param name 鍚嶇О绠$悊鍣ㄧ殑鍚嶇О
+	 */
+	public void writeNameRefer(int row,int col, int rowTo,int colTo,String name){
+		this.row = row;
+		this.col = col;
+		this.obj = name;
+		this.nameRefer = true;
+		this.rowTo = rowTo;
+		this.colTo = colTo;
+	}
+
+
+	/**
+	 * 鍐欏叆涓嬫媺鍒楄〃鐨勫��
+	 * @param comboBoxData 涓嬫媺鑿滃崟鐨勫��
+	 * @param row  琛屽彿
+	 * @param col 鍒楀彿
+	 * @param rowTo  缁撴潫琛屽彿
+	 * @param colTo 缁撴潫鍒楀彿
+	 */
+	public void writeComboBox( List<String> comboBoxData,int row,int col,int rowTo,int colTo){
+		writeComboBox(comboBoxData,null,row,col,rowTo,colTo);
+	}
+
+	/**
+	 * 鍐欏叆涓嬫媺鍒楄〃鐨勫��
+	 * @param comboBoxData 涓嬫媺鑿滃崟鐨勫��
+	 * @param errorMsg 閿欒鐨勬彁绀轰俊鎭�
+	 * @param row  琛屽彿
+	 * @param col 鍒楀彿
+	 * @param rowTo  缁撴潫琛屽彿
+	 * @param colTo 缁撴潫鍒楀彿
+	 */
+	public void writeComboBox( List<String> comboBoxData,String errorMsg,int row,int col,int rowTo,int colTo){
+		this.validationDataList = comboBoxData;
+		this.validation= true;
+		this.validationErrorMsg = errorMsg;
+		this.row = row;
+		this.col = col;
+		this.rowTo = rowTo;
+		this.colTo = colTo;
+	}
+
+	/**
+	 * 鏈夋晥鎬у簭鍒楀紩鐢ㄥ叾浠栫殑
+	 * @param referFormula 寮曠敤鐨勫叕寮�
+	 * @param row  琛屽彿
+	 * @param col 鍒楀彿
+	 * @param rowTo  缁撴潫琛屽彿
+	 * @param colTo 缁撴潫鍒楀彿
+	 */
+	public void writeUseRefer(String referFormula,int row,int col,int rowTo,int colTo){
+		writeUseRefer(referFormula,null,row,col,rowTo,colTo);
+	}
+
+	/**
+	 * 鏈夋晥鎬у簭鍒楀紩鐢ㄥ叾浠栫殑
+	 * @param referFormula 寮曠敤鐨勫叕寮�
+	 * @param errorMsg 閿欒鐨勬彁绀轰俊鎭�
+	 * @param row  琛屽彿
+	 * @param col 鍒楀彿
+	 * @param rowTo  缁撴潫琛屽彿
+	 * @param colTo 缁撴潫鍒楀彿
+	 */
+	public void writeUseRefer(String referFormula,String errorMsg,int row,int col,int rowTo,int colTo){
+		this.validation= true;
+		this.obj = referFormula;
+		this.validationErrorMsg = errorMsg;
+		this.row = row;
+		this.col = col;
+		this.rowTo = rowTo;
+		this.colTo = colTo;
+	}
+
+
+	public boolean isReadOnly() {
+		return readOnly;
+	}
+
+	public void setReadOnly(boolean readOnly) {
+		this.readOnly = readOnly;
+	}
+
+	public int getRow() {
+		return row;
+	}
+
+	public void setRow(int row) {
+		this.row = row;
+	}
+
+	public int getCol() {
+		return col;
+	}
+
+	public void setCol(int col) {
+		this.col = col;
+	}
+
+	public Object getObj() {
+		return obj;
+	}
+
+	public void setObj(Object obj) {
+		this.obj = obj;
+	}
+
+	public boolean isMerged() {
+		return merged;
+	}
+
+	public void setMerged(boolean merged) {
+		this.merged = merged;
+	}
+
+	public int getRowTo() {
+		return rowTo;
+	}
+
+	public void setRowTo(int rowTo) {
+		this.rowTo = rowTo;
+	}
+
+	public int getColTo() {
+		return colTo;
+	}
+
+	public void setColTo(int colTo) {
+		this.colTo = colTo;
+	}
+
+	public boolean isCopyStyle() {
+		return copyStyle;
+	}
+
+	public void setCopyStyle(boolean copyStyle) {
+		this.copyStyle = copyStyle;
+	}
+
+	public int getCopyStyleRow() {
+		return copyStyleRow;
+	}
+
+	public void setCopyStyleRow(int copyStyleRow) {
+		this.copyStyleRow = copyStyleRow;
+	}
+
+	public int getCopyStyleCol() {
+		return copyStyleCol;
+	}
+
+	public void setCopyStyleCol(int copyStyleCol) {
+		this.copyStyleCol = copyStyleCol;
+	}
+
+	public boolean isCenter() {
+		return center;
+	}
+
+	public void setCenter(boolean center) {
+		this.center = center;
+	}
+
+	public boolean isFormula() {
+		return formula;
+	}
+
+	public void setFormula(boolean formula) {
+		this.formula = formula;
+	}
+
+	public boolean isNameRefer() {
+		return nameRefer;
+	}
+
+	public void setNameRefer(boolean nameRefer) {
+		this.nameRefer = nameRefer;
+	}
+
+	public boolean isValidation() {
+		return validation;
+	}
+
+	public void setValidation(boolean validation) {
+		this.validation = validation;
+	}
+
+	public String getValidationErrorMsg() {
+		return validationErrorMsg;
+	}
+
+	public void setValidationErrorMsg(String validationErrorMsg) {
+		this.validationErrorMsg = validationErrorMsg;
+	}
+
+	public String getDateFormat() {
+		return dateFormat;
+	}
+
+	public void setDateFormat(String dateFormat) {
+		this.dateFormat = dateFormat;
+	}
+
+	public Integer getWidth() {
+		return width;
+	}
+
+	public void setWidth(Integer width) {
+		this.width = width;
+	}
+
+	@Override
+	public String toString() {
+		return "WriteExcelData{" +
+				"row=" + row +
+				", col=" + col +
+				", obj=" + obj +
+				", merged=" + merged +
+				", rowTo=" + rowTo +
+				", colTo=" + colTo +
+				", copyStyle=" + copyStyle +
+				", copyStyleRow=" + copyStyleRow +
+				", copyStyleCol=" + copyStyleCol +
+				", center=" + center +
+				", formula=" + formula +
+				", nameRefer=" + nameRefer +
+				", validation=" + validation +
+				", validationDataList=" + validationDataList +
+				", validationErrorMsg='" + validationErrorMsg + '\'' +
+				", fontColor='" + fontColor + '\'' +
+				", dateFormat='" + dateFormat + '\'' +
+				", readOnly=" + readOnly +
+				'}';
+	}
+}
diff --git a/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/bo/WriteExcelOption.java b/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/bo/WriteExcelOption.java
new file mode 100644
index 0000000..35f127d
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/bo/WriteExcelOption.java
@@ -0,0 +1,154 @@
+package com.vci.starter.poi.bo;
+
+import org.apache.commons.collections4.map.LinkedMap;
+
+import java.util.*;
+
+/**
+ * 鍐欏叆鏁版嵁鍒癳xcel鐨勯厤缃俊鎭�
+ * @author weidy
+ * @date 2020/5/29
+ */
+public class WriteExcelOption {
+
+
+    /**
+     * 瑕佸啓鍏ョ殑鏁版嵁
+     */
+    private LinkedMap<String/**宸ヤ綔琛ㄧ殑鍚嶇О**/, LinkedList<WriteExcelData> /**瑕佸啓鍏ョ殑鏁版嵁**/> writeDataMap ;
+
+    /**
+     * 瑕侀殣钘忕殑宸ヤ綔琛ㄥ悕绉�
+     */
+    private List<String> hideSheetList;
+
+    /**
+     * 鏄惁涓鸿拷鍔犵殑鍐呭锛屽嵆宸ヤ綔琛ㄥ凡缁忓瓨鍦�
+     */
+    private boolean append = false;
+
+    /**
+     * 鏄惁07鐨勭増鏈�
+     */
+    private boolean revision07 = false;
+
+    /**
+     * 鎵╁睍灞炴�х殑鏄犲皠閰嶇疆锛宲o瀵硅薄涓婂睘鎬ф槸map鐨勫舰寮忔椂浣跨敤锛宬ey涓巈xcelColumn娉ㄨВ鐨剉alue()鐩稿悓锛屽�兼槸瀵瑰簲鐨勬爣棰�
+     */
+    private LinkedMap<String,List<ExcelColumnMap>> extendAttrMap ;
+
+    /**
+     * 榛樿鏋勯�犳柟娉�
+     */
+    public WriteExcelOption(){
+
+    }
+
+    /**
+     * 鍖呭惈涓�涓伐浣滆〃鐨勫唴瀹�
+     * @param excelDataList 瑕佸啓鍏ョ殑宸ヤ綔琛ㄥ唴瀹癸紝宸ヤ綔琛ㄧ殑鍚嶇О榛樿涓篠heet1
+     */
+    public  WriteExcelOption(List<WriteExcelData> excelDataList){
+        writeDataMap = new LinkedMap<>();
+        LinkedList newList=new LinkedList();
+        newList.addAll(excelDataList);
+        writeDataMap.put("Sheet1",newList);
+    }
+
+    /**
+     * 鍖呭惈涓�涓伐浣滆〃鐨勫唴瀹�
+     * @param excelDataList 瑕佸啓鍏ョ殑宸ヤ綔琛ㄥ唴瀹癸紝宸ヤ綔琛ㄧ殑鍚嶇О榛樿涓篠heet1
+     */
+    public  WriteExcelOption(LinkedList<WriteExcelData> excelDataList){
+        writeDataMap = new LinkedMap<>();
+        writeDataMap.put("Sheet1",excelDataList);
+    }
+
+    /**
+     * 娣诲姞宸ヤ綔琛ㄧ殑鏁版嵁瀵硅薄
+     * @param sheetName 宸ヤ綔琛ㄥ悕绉�
+     * @param excelDataList 宸ヤ綔琛ㄧ殑鏁版嵁鍒楄〃
+     */
+    public  void addSheetDataList(String sheetName,LinkedList<WriteExcelData> excelDataList){
+        if(writeDataMap == null){
+            writeDataMap = new LinkedMap<>();
+        }
+        writeDataMap.put(sheetName,excelDataList);
+    }
+
+    /**
+     * 娣诲姞宸ヤ綔琛ㄧ殑鏁版嵁瀵硅薄
+     * @param sheetName 宸ヤ綔琛ㄥ悕绉�
+     * @param excelDataList 宸ヤ綔琛ㄧ殑鏁版嵁鍒楄〃
+     */
+    public  void addSheetDataList(String sheetName,List<WriteExcelData> excelDataList){
+        if(writeDataMap == null){
+            writeDataMap = new LinkedMap<>();
+        }
+        LinkedList newList=new LinkedList();
+        newList.addAll(excelDataList);
+        writeDataMap.put(sheetName,newList);
+    }
+
+    /**
+     * 娣诲姞闇�瑕佸奖鍝嶇殑宸ヤ綔琛ㄥ悕绉�
+     * @param sheetName 宸ヤ綔琛ㄥ悕绉�
+     */
+    public void  addHideSheet(String sheetName){
+        if(hideSheetList == null){
+            hideSheetList = new ArrayList<>();
+        }
+        hideSheetList.add(sheetName);
+    }
+
+    public Map<String, LinkedList<WriteExcelData>> getWriteDataMap() {
+        return writeDataMap;
+    }
+
+    public void setWriteDataMap(LinkedMap<String, LinkedList<WriteExcelData>> writeDataMap) {
+        this.writeDataMap = writeDataMap;
+    }
+
+    public List<String> getHideSheetList() {
+        return hideSheetList;
+    }
+
+    public void setHideSheetList(List<String> hideSheetList) {
+        this.hideSheetList = hideSheetList;
+    }
+
+    public boolean isAppend() {
+        return append;
+    }
+
+    public void setAppend(boolean append) {
+        this.append = append;
+    }
+
+    public boolean isRevision07() {
+        return revision07;
+    }
+
+    public void setRevision07(boolean revision07) {
+        this.revision07 = revision07;
+    }
+
+    public LinkedMap<String, List<ExcelColumnMap>> getExtendAttrMap() {
+        return extendAttrMap;
+    }
+
+    public void setExtendAttrMap(LinkedMap<String, List<ExcelColumnMap>> extendAttrMap) {
+        this.extendAttrMap = extendAttrMap;
+    }
+
+    @Override
+    public String toString() {
+        return "WriteExcelOption{" +
+                "writeDataMap=" + writeDataMap +
+                ", hideSheetList=" + hideSheetList +
+                ", append=" + append +
+                ", revision07=" + revision07 +
+                ", extendAttrMap=" + extendAttrMap +
+                '}';
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/constant/ExcelLangCodeConstant.java b/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/constant/ExcelLangCodeConstant.java
new file mode 100644
index 0000000..28b39a0
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/constant/ExcelLangCodeConstant.java
@@ -0,0 +1,68 @@
+package com.vci.starter.poi.constant;
+
+/**
+ * excel鐩稿叧鎿嶄綔鐨勫璇█鐨勪唬鐮�
+ * @author weidy
+ * @date 2020/5/5
+ */
+public class ExcelLangCodeConstant {
+    /**
+     * 璇诲彇瀵煎叆鐨勬枃浠跺嚭閿�
+     */
+    public static final String READ_IMPORT_FILE_FAIL = "readImportFileFail";
+
+    /**
+     * 瀵煎叆鐨勬枃浠跺唴瀹逛负绌�
+     */
+    public static final String IMPORT_CONTENT_NULL = "importContentNull";
+
+    /**
+     * 鏂囦欢涓嶅瓨鍦�
+     */
+    public static final String FILE_NOT_FOUND = "fileNotFound";
+
+    /**
+     * 鏂囦欢鍐欏叆閿欒
+     */
+    public static final String FILE_IO_EXCEPTION = "fileIoException";
+
+    /**
+     * 鏂囦欢鍒涘缓寮傚父
+     */
+    public static final String FILE_CREATE_EXCEPTION = "fileCreateException";
+
+    /**
+     * 杈撳叆娴佹槸绌�
+     */
+    public static final String INPUT_STREAM_IS_NULL = "inputStreamIsNull";
+
+    /**
+     * 杈撳嚭娴佹槸绌�
+     */
+    public static final String OUTPUT_STREAM_IS_NULL = "outputStreamIsNull";
+
+    /**
+     * 宸ヤ綔绨垮垵濮嬪寲澶辫触
+     */
+    public static final String WORKBOOK_INIT_FAIL = "workBookInitFail";
+
+    /**
+     * 鍗曞厓鏍肩殑鍊间笉鑳戒负绌�
+     */
+    public static final String CELL_VALUE_CAN_NOT_NULL = "cellValueCanNotNull";
+
+    /**
+     * 鍥犱负瑕佹牎楠屾鍒欒〃杈惧紡锛屾墍浠ュ崟鍏冩牸鐨勫�间笉鑳戒负绌�
+     */
+    public static final String CELL_VALUE_CAN_NOT_NULL_FOR_REG = "cellValueCanNotNullForReg";
+
+    /**
+     * 鍗曞厓鏍肩殑鍊间笉绗﹀悎姝e垯琛ㄨ揪寮忕殑瑕佹眰
+     */
+    public static final String CELL_VALUE_NOT_EQUAL_REG = "cellValueNotEqualReg";
+
+    /**
+     * 鍗曞厓鏍间笉鏄湁鏁堢殑鏃堕棿鏍煎紡
+     */
+    public static final String CELL_NOT_DATE_FORMATE = "cellNotDateFormate";
+}
diff --git a/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/util/ExcelUtil.java b/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/util/ExcelUtil.java
new file mode 100644
index 0000000..aedbcdf
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/util/ExcelUtil.java
@@ -0,0 +1,1662 @@
+package com.vci.starter.poi.util;
+
+import com.vci.starter.poi.annotation.ExcelColumn;
+import com.vci.starter.poi.annotation.ExcelTitle;
+import com.vci.starter.poi.bo.*;
+import com.vci.starter.web.annotation.VciFieldType;
+import com.vci.starter.web.enumpck.BooleanEnum;
+import com.vci.starter.web.enumpck.VciFieldTypeEnum;
+import com.vci.starter.web.exception.VciBaseException;
+import com.vci.starter.web.util.LangBaseUtil;
+import com.vci.starter.web.util.LocalFileUtil;
+import com.vci.starter.web.util.VciBaseUtil;
+import com.vci.starter.web.util.VciDateUtil;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.poi.hssf.usermodel.*;
+
+import org.apache.poi.hssf.util.HSSFColor;
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.ss.util.CellRangeAddressList;
+import org.apache.poi.xssf.usermodel.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.util.CollectionUtils;
+
+import java.io.*;
+import java.lang.reflect.Field;
+import java.math.BigDecimal;
+import java.nio.channels.FileChannel;
+import java.util.*;
+import java.util.stream.Collectors;
+
+import static com.vci.starter.poi.constant.ExcelLangCodeConstant.*;
+
+/**
+ * excel鎿嶄綔绫�
+ * 2020/5/8锛屽紩鍏�4.1鐗堟湰鐨刾oi锛屽叏閮ㄧ殑鎺ュ彛鍙戠敓鍙樺寲
+ * @author weidy
+ * @date 2020/2/19
+ */
+public  class ExcelUtil {
+
+	/**
+	 * 鏃ュ織
+	 */
+	private static Logger logger = LoggerFactory.getLogger(ExcelUtil.class);
+
+	/**
+	 * 鍦ㄨ鍙栨枃浠剁殑鍐呭鐨勬椂鍊欙紝poi浼氳嚜鍔ㄥ垽鏂枃浠舵槸鍚︿负excel锛屾墍浠ヤ笉闇�瑕佸崟鐙殑鏂规硶锛屽彟澶�07杩樻槸03涔熶笉闇�瑕佹帹鏂�
+	 * 鎻愪緵鍐欏叆鍒癳xcel鐨勬柟娉曪紝鍖呮嫭鎸囨槑鍗曞厓鏍煎拰瀵硅薄鐨勪袱绉嶆柟寮�
+	 * 鎻愪緵璇诲彇excel鐨勬柟娉曪紝鍖呮嫭杩斿洖瀵硅薄鍜宮ap鏁版嵁鐨勪袱绉嶆柟寮�
+	 */
+
+
+	/**
+	 * 鎷疯礉鏂囦欢
+	 *
+	 * @param source 婧愭枃浠�
+	 * @param target 鐩爣鏂囦欢
+	 * @throws VciBaseException 鎷疯礉鏂囦欢鍑虹幇閿欒鎴栬�呮枃浠朵笉瀛樺湪鐨勬椂鍊欎細鎶ラ敊
+	 */
+	public static void copyFile(File source, File target) throws VciBaseException {
+		VciBaseUtil.alertNotNull(source, "鏉ユ簮鏂囦欢", target, "鐩爣鏂囦欢");
+		if (!source.exists()) {
+			throw new VciBaseException(FILE_NOT_FOUND, new String[]{source.getName()});
+		}
+		if (!target.exists()) {
+			File folder = target.getParentFile();
+			folder.mkdirs();
+			try {
+				target.createNewFile();
+			} catch (IOException e) {
+				throw new VciBaseException(FILE_IO_EXCEPTION, new String[]{target.getName()});
+			}
+		}
+		FileInputStream is = null;
+		FileOutputStream os = null;
+		try {
+			is = new FileInputStream(source);
+		} catch (FileNotFoundException e) {
+			throw new VciBaseException(FILE_NOT_FOUND, new String[]{source.getName()});
+		}
+		try {
+			os = new FileOutputStream(target);
+		} catch (FileNotFoundException e) {
+			IOUtils.closeQuietly(is);
+			throw new VciBaseException(FILE_NOT_FOUND, new String[]{target.getName()});
+		}
+		try {
+			copyFile(is, os);
+		} catch (VciBaseException e) {
+			throw e;
+		} catch (Throwable e) {
+			throw new VciBaseException(LangBaseUtil.getErrorMsg(e), new String[]{source.getName(), target.getName()}, e);
+		} finally {
+			//闃叉鍥犱负寮傚父娌℃湁鍏抽棴
+			IOUtils.closeQuietly(is);
+			IOUtils.closeQuietly(os);
+		}
+	}
+
+	/**
+	 * 鎷疯礉鏂囦欢
+	 *
+	 * @param in 鏂囦欢杈撳叆娴�
+	 * @param os 鏂囦欢杈撳嚭娴�
+	 * @throws VciBaseException 鏂囦欢涓嶅瓨鍦ㄦ垨鑰呭啓鍏ラ敊璇殑鏃跺�欎細鎶涘嚭寮傚父
+	 */
+	public static void copyFile(FileInputStream in, FileOutputStream os) throws VciBaseException {
+		try {
+			FileChannel sourceChannel = in.getChannel();
+			FileChannel targetChannel = os.getChannel();
+			int i = 0;
+			int length = 2097152;
+			while (true) {
+				if (sourceChannel.position() == sourceChannel.size()) {
+					sourceChannel.close();
+					targetChannel.close();
+					break;
+				}
+				if ((sourceChannel.size() - sourceChannel.position()) < 20971520) {
+					length = (int) (sourceChannel.size() - sourceChannel.position());
+				} else {
+					length = 20971520;
+				}
+				sourceChannel.transferTo(sourceChannel.position(), length, targetChannel);
+				sourceChannel.position(sourceChannel.position() + length);
+				i++;
+			}
+		} catch (IOException e) {
+			if (logger.isErrorEnabled()) {
+				logger.error("鎷疯礉婧愭枃浠跺埌鐩爣鏂囦欢鍑虹幇浜嗛敊璇�", e);
+			}
+			throw new VciBaseException(LangBaseUtil.getErrorMsg(e), new String[]{}, e);
+		} catch (Throwable e) {
+			if (logger.isErrorEnabled()) {
+				logger.error("鎷疯礉婧愭枃浠跺埌鐩爣鏂囦欢鍑虹幇浜嗛敊璇�", e);
+			}
+			throw new VciBaseException(LangBaseUtil.getErrorMsg(e), new String[]{}, e);
+		} finally {
+			IOUtils.closeQuietly(in);
+			IOUtils.closeQuietly(os);
+		}
+	}
+
+	/**
+	 * 灏唈ar涓殑鏂囦欢鎷疯礉鍒扮洰鏍囨枃浠�
+	 *
+	 * @param filePathInJar 鍦╦ar涓殑鐩稿璺緞
+	 * @param targetFile    鐩爣鏂囦欢
+	 * @throws VciBaseException 鎷疯礉鍑洪敊鐨勬椂鍊欎細鎶涘嚭寮傚父
+	 */
+	public static void copyFileFromJar(String filePathInJar, File targetFile) throws VciBaseException {
+		VciBaseUtil.alertNotNull(filePathInJar, "鏉ユ簮鏂囦欢", targetFile, "鐩爣鏂囦欢");
+		if (!targetFile.exists()) {
+			File folder = targetFile.getParentFile();
+			folder.mkdirs();
+			try {
+				targetFile.createNewFile();
+			} catch (IOException e) {
+				throw new VciBaseException(FILE_IO_EXCEPTION, new String[]{targetFile.getName()});
+			}
+		}
+		FileOutputStream os = null;
+		InputStream ins = null;
+		try {
+			os = new FileOutputStream(targetFile);
+		} catch (FileNotFoundException e) {
+			throw new VciBaseException(FILE_NOT_FOUND, new String[]{targetFile.getName()});
+		}
+		try {
+			ins = ExcelUtil.class.getResourceAsStream(filePathInJar);
+			IOUtils.copy(ins, os);
+		} catch (IOException e) {
+			if (logger.isErrorEnabled()) {
+				logger.error("鎷疯礉婧愭枃浠跺埌鐩爣鏂囦欢鍑虹幇浜嗛敊璇�", e);
+			}
+			throw new VciBaseException(LangBaseUtil.getErrorMsg(e), new String[]{}, e);
+		} catch (Throwable e) {
+			if (logger.isErrorEnabled()) {
+				logger.error("鎷疯礉婧愭枃浠跺埌鐩爣鏂囦欢鍑虹幇浜嗛敊璇�", e);
+			}
+			throw new VciBaseException(LangBaseUtil.getErrorMsg(e), new String[]{}, e);
+		} finally {
+			IOUtils.closeQuietly(ins);
+			IOUtils.closeQuietly(os);
+		}
+	}
+
+	/**
+	 * 鍐欏叆鏁版嵁鍒癳xcel鏂囦欢涓�
+	 *
+	 * @param fileName      鏂囦欢鐨勫悕绉帮紝涓嶈兘鏄痡ar涓殑鏂囦欢锛岃鍖呮嫭缁濆璺緞
+	 * @param writeExcelOption 瑕佸啓鍏ョ殑鏁版嵁鍜岄厤缃�
+	 * @throws VciBaseException 鏂囦欢鏈壘鍒�,鍐欏叆鏁版嵁鍑虹幇浜嗛敊璇�
+	 */
+	public static void writeDataToFile(String fileName, WriteExcelOption writeExcelOption) throws VciBaseException {
+		writeDataToFile(new File(fileName),  writeExcelOption);
+	}
+	/**
+	 * 鍐欏叆鏁版嵁鍒癳xcel鏂囦欢涓�
+	 *
+	 * @param file          鏂囦欢瀵硅薄
+	 * @param writeExcelOption 瑕佸啓鍏ョ殑鏁版嵁鍜岄厤缃�
+	 * @param writeExcelOption 瑕佸啓鍏ョ殑鏁版嵁鍜岄厤缃�
+	 * @throws VciBaseException 鏂囦欢鏈壘鍒�,鍐欏叆鏁版嵁鍑虹幇浜嗛敊璇�
+	 */
+	public static void writeDataToFile(File file, WriteExcelOption writeExcelOption) throws VciBaseException {
+		if (file == null) {
+			throw new VciBaseException("鏂囦欢涓虹┖锛屾棤娉曟壘鍒版枃浠�");
+		}
+		if (!file.exists()) {
+			File folder = file.getParentFile();
+			if (!folder.exists()) {
+				folder.mkdirs();
+			}
+			try {
+				file.createNewFile();
+			} catch (IOException e) {
+				throw new VciBaseException(FILE_NOT_FOUND, new String[]{file.getName()});
+			}
+		}
+		Workbook workbook = null;
+		if(writeExcelOption!=null && writeExcelOption.isAppend()){
+			try {
+				if (file.length() == 0) {
+					workbook = createWorkbook(false);
+				}else {
+					workbook = getWorkbookByInputStream(new FileInputStream(file));
+				}
+			} catch (FileNotFoundException e) {
+				throw new VciBaseException("fileNotExist",new String[]{file.getName()},e);
+			}
+		}
+		OutputStream os = null;
+		try {
+			os = new FileOutputStream(file);
+		} catch (FileNotFoundException e) {
+			throw new VciBaseException(FILE_NOT_FOUND, new String[]{e.getMessage()}, e);
+		}
+		try {
+			writeDataToFile(os, writeExcelOption,workbook);
+		} catch (VciBaseException e) {
+			if (logger.isErrorEnabled()) {
+				logger.error("鍐欏叆鏁版嵁鍒癳xcel鍑洪敊", e);
+			}
+			throw e;
+		} catch (Throwable e) {
+			if (logger.isErrorEnabled()) {
+				logger.error("鍐欏叆鏁版嵁鍒癳xcel鍑洪敊", e);
+			}
+			throw new VciBaseException(LangBaseUtil.getErrorMsg(e), new String[]{}, e);
+		} finally {
+			//闃叉涔嬪墠鍥犱负寮傚父娌℃湁鍏抽棴
+			IOUtils.closeQuietly(os);
+		}
+	}
+
+	/**
+	 * 鍐欏叆鏁版嵁鍒癳xcel鏂囦欢涓�
+	 *
+	 * @param os            鏂囦欢杈撳嚭娴侊紝蹇呴』鏄痚xcel鏂囦欢鐨勮緭鍑烘祦
+	 * @param writeExcelOption 瑕佸啓鍏ョ殑鏁版嵁鍜岄厤缃�
+	 * @throws VciBaseException 鏂囦欢鏈壘鍒�,鍐欏叆鏁版嵁鍑虹幇浜嗛敊璇�
+	 */
+	public static void writeDataToFile(OutputStream os, WriteExcelOption writeExcelOption) throws VciBaseException {
+		writeDataToFile(os,writeExcelOption,null);
+	}
+	/**
+	 * 鍐欏叆鏁版嵁鍒癳xcel鏂囦欢涓�
+	 *
+	 * @param os            鏂囦欢杈撳嚭娴侊紝蹇呴』鏄痚xcel鏂囦欢鐨勮緭鍑烘祦
+	 * @param writeExcelOption 瑕佸啓鍏ョ殑鏁版嵁鍜岄厤缃�
+	 * @param workbook 宸ヤ綔绨垮璞★紝鏄拷鍔犳暟鎹殑鏃跺�欏厛鑾峰彇workbook
+	 * @throws VciBaseException 鏂囦欢鏈壘鍒�,鍐欏叆鏁版嵁鍑虹幇浜嗛敊璇�
+	 */
+	public static void writeDataToFile(OutputStream os, WriteExcelOption writeExcelOption,Workbook workbook) throws VciBaseException {
+		if (os == null) {
+			throw new VciBaseException(OUTPUT_STREAM_IS_NULL);
+		}
+		if (writeExcelOption == null ) {
+			IOUtils.closeQuietly(os);
+		} else {
+			//鏈夋暟鎹墠鎵ц鍐欏叆
+			Workbook wb = null;
+			if(writeExcelOption.isAppend() && workbook !=null){
+				wb = workbook;
+			}else{
+				wb = createWorkbook(writeExcelOption.isRevision07());
+			}
+			Workbook finalWb = wb;
+			writeExcelOption.getWriteDataMap().forEach((sheetName, excelDataList) ->{
+				Sheet sheet = getSheetByWorkbook(finalWb, sheetName);
+				try {
+					writeDataToCell(sheet, excelDataList);
+				} catch (VciBaseException e) {
+					IOUtils.closeQuietly(os);
+					throw e;
+				} catch (Throwable e) {
+					if (logger.isErrorEnabled()) {
+						logger.error("鍐欏叆鏁版嵁鍒板伐浣滅翱鍑洪敊", e);
+					}
+					IOUtils.closeQuietly(os);
+					throw new VciBaseException(LangBaseUtil.getErrorMsg(e), new String[]{}, e);
+				}
+			});
+			//鏄惁鏈夐殣钘忓伐浣滆〃
+			if(!CollectionUtils.isEmpty(writeExcelOption.getHideSheetList())){
+				writeExcelOption.getHideSheetList().stream().forEach(sheetName ->{
+					Sheet sheet = getSheetByWorkbook(finalWb, sheetName);
+					finalWb.setSheetHidden(finalWb.getSheetIndex(sheet),true);
+				});
+			}
+
+			//鍒拌繖閲岃鏄庡凡缁忓啓鍒板伐浣滅翱
+			try {
+				wb.write(os);
+			} catch (IOException e) {
+				if (logger.isErrorEnabled()) {
+					logger.error("鎶婂伐浣滅翱涓婄殑鏁版嵁鍐欏叆鍒版枃浠跺嚭閿�", e);
+				}
+				throw new VciBaseException(LangBaseUtil.getErrorMsg(e), new String[]{}, e);
+			} finally {
+				IOUtils.closeQuietly(os);
+				try {
+					wb.close();
+				} catch (Throwable e) {
+					if (logger.isErrorEnabled()) {
+						logger.error("鍏抽棴宸ヤ綔绨�", e);
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * 鑾峰彇excel鏌愪釜灞炴�ф墍鍦ㄧ殑鍒楃储寮�
+	 * @param excelFileName excel鏂囦欢鐨勫悕绉�
+	 * @param poClass poi瀵煎叆瀵煎嚭瀵硅薄鎵�灞炵殑绫�
+	 * @param poFieldName 瑕佹煡璇㈢殑灞炴�х殑鍚嶇О
+	 * @param sheetName 宸ヤ綔琛ㄧ殑鍚嶇О
+	 * @return 鍒楃殑绱㈠紩锛屼笉瀛樺湪鐨勬椂鍊欒繑鍥�-1
+	 */
+	public static int getCellIndexForPoField(String excelFileName,String sheetName,Class<?> poClass,String poFieldName) throws VciBaseException{
+		return getCellIndexForPoField(new File(excelFileName),sheetName,poClass,poFieldName);
+	}
+
+	/**
+	 * 鑾峰彇excel鏌愪釜灞炴�ф墍鍦ㄧ殑鍒楃储寮�
+	 * @param excelFile excel鏂囦欢鐨勫悕绉�
+	 * @param poClass poi瀵煎叆瀵煎嚭瀵硅薄鎵�灞炵殑绫�
+	 * @param poFieldName 瑕佹煡璇㈢殑灞炴�х殑鍚嶇О
+	 * @param sheetName 宸ヤ綔琛ㄧ殑鍚嶇О
+	 * @return 鍒楃殑绱㈠紩锛屼笉瀛樺湪鐨勬椂鍊欒繑鍥�-1
+	 */
+	public static int getCellIndexForPoField(File excelFile,String sheetName,Class<?> poClass,String poFieldName) throws VciBaseException{
+		VciBaseUtil.alertNotNull(excelFile,"excel鐨勬枃浠�",poClass,"poi瀵煎叆瀵煎嚭瀵硅薄鎵�灞炵殑绫�",poFieldName,"灞炴�х殑鍚嶇О");
+		if(!excelFile.exists()){
+			throw new VciBaseException("fileNotExist",new String[]{excelFile.getAbsolutePath()});
+		}
+		if(StringUtils.isBlank(sheetName)){
+			sheetName = "Sheet1";
+		}
+		Field field = VciBaseUtil.getFieldForObject(poFieldName, poClass);
+		if(field == null){
+			throw new VciBaseException("瀵硅薄涓笉瀛樺湪姝ゅ睘鎬э紝{0}锛寋1}",new String[]{poFieldName,poClass.getName()});
+		}
+		if(field.isAnnotationPresent(ExcelColumn.class)){
+			ExcelColumn ec = getExcelColumnAnnotation(field);
+			String columnName = ec.value();
+			Workbook workbook = null;
+			try {
+				workbook = getWorkbookByInputStream(new FileInputStream(excelFile));
+			} catch (FileNotFoundException e) {
+				throw new VciBaseException("fileNotExist",new String[]{excelFile.getAbsolutePath()});
+			}
+			if(workbook!=null){
+				Sheet sheet = workbook.getSheet(sheetName);
+				if(sheet!=null){
+					Row row = sheet.getRow(getRowIndexForTitle(poClass));
+					if(row!=null){
+						short lastCellNum = row.getLastCellNum();
+						for(short i = 0;i<lastCellNum; i ++){
+							Cell cell = row.getCell(i);
+							if(columnName.equals(cell.getStringCellValue())){
+								try {
+									workbook.close();
+								} catch (IOException e) {
+									logger.error("鍏抽棴宸ヤ綔琛ㄥ嚭鐜伴敊璇�",e);
+								}
+								return  i;
+							}
+						}
+					}
+				}
+			}
+		}
+		return -1;
+	}
+
+	/**
+	 * 璇诲彇po瀵硅薄閲岀殑鍚勪釜灞炴�х殑鎵�鍦ㄥ垪鐨勪綅缃�
+	 * @param excelFile excel鏂囦欢
+	 * @param sheetName 鍒楃殑鍚嶇О
+	 * @param poClass 瀵煎叆瀵煎嚭鐨勫璞�
+	 * @return key鏄睘鎬у悕绉帮紝value鏄垪鎵�鍦ㄧ殑浣嶇疆
+	 * @throws VciBaseException 鏂囦欢涓嶅瓨鍦紝璇诲彇鍑洪敊鐨勬椂鍊欎細鎶涘嚭寮傚父
+	 */
+	public static Map<String,Integer> listCellIndexForPO(File excelFile,String sheetName,Class<?> poClass) throws VciBaseException{
+		VciBaseUtil.alertNotNull(excelFile,"excel鐨勬枃浠�",poClass,"poi瀵煎叆瀵煎嚭瀵硅薄鎵�灞炵殑绫�");
+		if(!excelFile.exists()){
+			throw new VciBaseException("fileNotExist",new String[]{excelFile.getAbsolutePath()});
+		}
+		if(StringUtils.isBlank(sheetName)){
+			sheetName = "Sheet1";
+		}
+		List<Field> fields = VciBaseUtil.getAllFieldForObj(poClass);
+		//鍒楃储寮曟槧灏勶紝key鏄睘鎬х殑鍚嶇О锛寁alue鏄垪绱㈠紩
+		Map<String,Integer> cellIndexMap = new HashMap<>();
+		if(!CollectionUtils.isEmpty(fields)){
+			Workbook workbook = null;
+			try {
+				workbook = getWorkbookByInputStream(new FileInputStream(excelFile));
+			} catch (FileNotFoundException e) {
+				throw new VciBaseException("fileNotExist",new String[]{excelFile.getAbsolutePath()});
+			}
+			if(workbook!=null) {
+				Sheet sheet = workbook.getSheet(sheetName);
+				if (sheet != null) {
+					Row row = sheet.getRow(getRowIndexForTitle(poClass));
+					if (row != null) {
+						Map<String,String> columnNamesMap = new HashMap<>();
+						fields.stream().forEach(field -> {
+							if(field.isAnnotationPresent(ExcelColumn.class)) {
+								ExcelColumn ec = getExcelColumnAnnotation(field);
+								String columnName = ec.value();
+								columnNamesMap.put(columnName,field.getName());
+							}
+						});
+						short lastCellNum = row.getLastCellNum();
+						for(short i = 0;i<lastCellNum; i ++){
+							Cell cell = row.getCell(i);
+							String cellName = cell.getStringCellValue();
+							if(columnNamesMap.containsKey(cellName)){
+								cellIndexMap.put(columnNamesMap.get(cellName),Integer.valueOf(i));
+							}
+						}
+					}
+				}
+				try {
+					workbook.close();
+				} catch (IOException e) {
+					logger.error("鍏抽棴宸ヤ綔琛ㄥ嚭鐜伴敊璇�",e);
+				}
+			}
+		}
+		return cellIndexMap;
+	}
+
+	/**
+	 * 鑾峰彇鏍囬鎵�鍦ㄧ殑琛�
+	 * @param poClass poi瀵煎嚭瀵煎叆瀵硅薄
+	 * @return 琛岀储寮�
+	 */
+	public static int getRowIndexForTitle(Class<?> poClass){
+		if(poClass.isAnnotationPresent(ExcelTitle.class)){
+			ExcelTitle ec = poClass.getAnnotation(ExcelTitle.class);
+			if (ec == null) {
+				ec = poClass.getDeclaredAnnotation(ExcelTitle.class);
+			}
+			if(ec !=null){
+				return ec.rowIndexForTitle();
+			}
+		}
+		return 0;
+	}
+
+	/**
+	 * 鏍规嵁鍒楀簭鍙疯幏鍙栧垪鐨勫悕绉�
+	 * @param colIndex 鍒楀簭鍙�
+	 * @return 鍒楃殑鍚嶇О
+	 */
+	public static String getCellNameByIndex(int colIndex){
+		//A~Z
+		//AA~AZ
+		//BA~BZ
+		if(colIndex<26){
+			return String.valueOf((char)('A' + colIndex));
+		}else{
+			//
+			//澶т簬绛変簬26锛屽彇鍊嶆暟鍜屼綑鏁�
+			int balance = colIndex%26;
+			int multiple = (colIndex-balance)/26;
+			String prefix = String.valueOf((char)('A'  + (multiple-1)));
+			String suffix = String.valueOf((char)('A'  + balance));
+			return prefix+suffix;
+		}
+	}
+
+	/**
+	 * 鍒涘缓宸ヤ綔绨匡紝娉ㄦ剰閮芥槸03鐗堟湰鐨勶紝涓轰簡鍏煎
+	 *
+	 * @return 宸ヤ綔绨垮璞�
+	 */
+	public static Workbook createWorkbook(boolean is07) {
+		Workbook wb = null;
+		if(is07){
+			wb = new XSSFWorkbook();
+		}else{
+			wb = new HSSFWorkbook();
+		}
+		//瀵煎嚭閮芥槸浜�2003鐗堟湰鐨勶紝鐢ㄤ簬鍏煎
+		return wb;
+	}
+
+
+	/**
+	 * 鑾峰彇宸ヤ綔绨垮璞�
+	 *
+	 * @param ins 鏂囦欢杈撳叆娴�
+	 * @return 宸ヤ綔绨匡紝poi3.15浠ヤ笂鐗堟湰涓嶅尯鍒�03杩�07
+	 * @throws VciBaseException 濡傛灉涓嶆槸excel鏂囦欢锛屼細鐩存帴鎶ラ敊
+	 */
+	public static Workbook getWorkbookByInputStream(InputStream ins) throws VciBaseException {
+		Workbook wb = null;
+		try {
+			wb = WorkbookFactory.create(ins);
+		} catch (IOException e) {
+			IOUtils.closeQuietly(ins);
+			throw new VciBaseException(WORKBOOK_INIT_FAIL, new String[]{LangBaseUtil.getErrorMsg(e)});
+		}
+		return wb;
+	}
+
+	/**
+	 * 鑾峰彇宸ヤ綔琛紝濡傛灉宸ヤ綔琛ㄥ悕绉颁笉瀛樺湪锛屽垯浼氬垱寤轰竴涓�
+	 *
+	 * @param wb        宸ヤ綔绨�
+	 * @param sheetName 宸ヤ綔琛ㄧ殑鍚嶇О
+	 * @return 宸ヤ綔琛ㄥ璞�
+	 */
+	private static Sheet getSheetByWorkbook(Workbook wb, String sheetName) {
+		if (StringUtils.isBlank(sheetName)) {
+			sheetName = "Sheet1";
+		}
+		Sheet sheet = wb.getSheet(sheetName);
+		if (sheet == null) {
+			sheet = wb.createSheet(sheetName);
+		}
+		return sheet;
+	}
+
+	/**
+	 * 鑾峰彇琛岀殑瀵硅薄
+	 *
+	 * @param sheet    宸ヤ綔琛ㄥ璞�
+	 * @param rowIndex 琛屽彿锛屼粠0寮�濮�
+	 * @return 琛岀殑瀵硅薄锛屼笉瀛樺湪浼氬垱寤轰竴琛�
+	 */
+	private static Row getRowBySheet(Sheet sheet, int rowIndex) {
+		Row row = sheet.getRow(rowIndex);
+		if (row == null) {
+			//璇存槑杩欎釜鏃跺�欒繕娌℃湁鍒涘缓杩欒--鍗虫病鏈夊��
+			row = sheet.createRow(rowIndex);
+		}
+		return row;
+	}
+
+	/**
+	 * 鏍规嵁琛岃幏鍙栧崟鍏冩牸瀵硅薄
+	 *
+	 * @param row       琛屽璞�
+	 * @param cellIndex 鍒楀簭鍙凤紝浠�0寮�濮�
+	 * @return 鍗曞厓鏍肩殑瀵硅薄锛屼笉瀛樺湪浼氬垱寤�
+	 */
+	private static Cell getCellByRow(Row row, int cellIndex) {
+		Cell cell = row.getCell(cellIndex);
+		if (cell == null) {
+			//璇存槑杩樻病鏈夊垱寤鸿繖涓崟鍏冩牸
+			cell = row.createCell(cellIndex);
+		}
+		return cell;
+	}
+
+	/**
+	 * 鍐欏叆鏁版嵁
+	 *
+	 * @param sheet         琛ㄦ牸瀵硅薄
+	 * @param excelDataList 瑕佸啓鍏ョ殑鏁版嵁瀵硅薄
+	 */
+	private static void writeDataToCell(Sheet sheet, List<WriteExcelData> excelDataList) throws VciBaseException {
+		if (sheet != null && !CollectionUtils.isEmpty(excelDataList)) {
+			List<WriteExcelData> mergedDataList = new ArrayList<>();
+			excelDataList.stream().forEach(ed -> {
+				Row row = getRowBySheet(sheet, ed.getRow());
+				Cell cell = getCellByRow(row, ed.getCol());
+				//鍚堝苟鍗曞厓鏍�
+				if (ed.isMerged() && (ed.getRowTo() > ed.getRow() || ed.getColTo() > ed.getCol())) {
+					mergedDataList.add(ed);
+				}
+				copyStyle(sheet, cell, ed);
+				if(ed.isReadOnly() && ed.getObj() !=null && !(ed.getObj() instanceof RichTextString) && CollectionUtils.isEmpty(ed.getValidationDataList())){
+					//ed.setValidation(true);
+					List<String> list = new ArrayList<>();
+					list.add(ed.getObj().toString());
+					ed.setValidationDataList(list );
+					setValidation(sheet,ed);
+				}
+				centerCell(cell, ed);
+				Object value = ed.getObj();
+				if(StringUtils.isNotBlank(ed.getFontColor())){
+					String rtsValue = value ==null?"":value.toString();
+					RichTextString ts = (cell instanceof HSSFCell)?new HSSFRichTextString(rtsValue):new XSSFRichTextString(rtsValue);
+					Font font = sheet.getWorkbook().createFont();
+					font.setColor(VciBaseUtil.getShort(ed.getFontColor()));
+					ts.applyFont(font);
+					value = ts;
+				}
+				if(ed.isFormula()){
+					//璁剧疆鍏紡锛屽鏋滃嵆鏈夊�硷紝杩樿璁剧疆鍏紡鍒欒缃负涓や釜瀵硅薄
+					setFormula(cell,ed);
+				}else if(ed.isNameRefer()){
+					//璁剧疆鍚嶇О绠$悊鍣紝涓�鑸拰鏈夋晥鎬ч厤鍚堜娇鐢�
+					setNameRefer(sheet,ed);
+				}else if(ed.isValidation()){
+					//璇存槑鏄洿鎺ュ啓鏈夋晥鎬х殑鍊�
+					setValidation(sheet,ed);
+				}else{
+					//鍐欏��
+					setCellValue(cell, value);
+				}
+				if(ed.getWidth()!=null && ed.getWidth()>0){
+					sheet.setColumnWidth(cell.getColumnIndex(),(int)(ed.getWidth() + 0.72)*256);
+				}
+			});
+			mergedRegion(sheet, mergedDataList);
+		}
+	}
+
+	/**
+	 * 涓哄崟鍏冩牸璁剧疆鍏紡
+	 * @param cell 鍗曞厓鏍肩殑瀵硅薄
+	 * @param ed 鏁版嵁瀵硅薄
+	 */
+	private static void setFormula(Cell cell ,WriteExcelData ed){
+		if (ed.getObj() != null) {
+			cell.setCellFormula(ed.getObj().toString());
+		}
+	}
+
+	/**
+	 * 璁剧疆鍚嶇О绠$悊鍣�
+	 * @param sheet 宸ヤ綔琛�
+	 * @param ed 鏁版嵁瀵硅薄
+	 */
+	private static void setNameRefer(Sheet sheet,WriteExcelData ed){
+		if(ed.getObj() !=null){
+			Name name = sheet.getWorkbook().createName();
+			name.setNameName(ed.getObj().toString());
+			name.setRefersToFormula(sheet.getSheetName() + "!"+getRange(ed));
+		}
+	}
+
+	/**
+	 * 璁剧疆鏁版嵁鏈夋晥鎬�
+	 * @param sheet 宸ヤ綔琛�
+	 * @param ed 鏁版嵁瀵硅薄
+	 */
+	private static void setValidation(Sheet sheet,WriteExcelData ed){
+		if(ed.getRowTo()<ed.getRow()){
+			ed.setRowTo(ed.getRow());
+		}
+		if(ed.getColTo()<ed.getCol()){
+			ed.setColTo(ed.getCol());
+		}
+		CellRangeAddressList regions=new CellRangeAddressList(ed.getRow(),ed.getRowTo(),ed.getCol(),ed.getColTo());
+		DataValidation validation = null;
+		if (sheet instanceof XSSFSheet) {
+			XSSFDataValidationHelper dvHelper = new XSSFDataValidationHelper((XSSFSheet)sheet);
+			XSSFDataValidationConstraint dvConstraint = null;
+			if(!CollectionUtils.isEmpty(ed.getValidationDataList())){
+				//璇存槑鏄洿鎺ュ啓鍐呭鐨�
+				dvConstraint = (XSSFDataValidationConstraint)dvHelper.createExplicitListConstraint(ed.getValidationDataList().toArray(new String[0]));
+			}else{
+				VciBaseUtil.alertNotNull(ed.getObj(),"鍐欏叆鏈夋晥鎬х殑鏃跺�欙紝娌℃湁璁剧疆鏈夋晥鎬х殑鍏紡琛ㄨ揪寮�");
+				dvConstraint = (XSSFDataValidationConstraint) dvHelper.createFormulaListConstraint(ed.getObj().toString());
+			}
+			validation = (XSSFDataValidation) dvHelper.createValidation(dvConstraint, regions);
+		}else{
+			HSSFDataValidationHelper dvHelper = new HSSFDataValidationHelper((HSSFSheet)sheet);
+			DataValidationConstraint dvConstraint = null;
+			if(!CollectionUtils.isEmpty(ed.getValidationDataList())){
+				//璇存槑鏄洿鎺ュ啓鍐呭鐨�
+				dvConstraint = dvHelper.createExplicitListConstraint(ed.getValidationDataList().toArray(new String[0]));
+			}else{
+				VciBaseUtil.alertNotNull(ed.getObj(),"鍐欏叆鏈夋晥鎬х殑鏃跺�欙紝娌℃湁璁剧疆鏈夋晥鎬х殑鍏紡琛ㄨ揪寮�");
+				dvConstraint = dvHelper.createFormulaListConstraint(ed.getObj().toString());
+			}
+			validation = (HSSFDataValidation)(new HSSFDataValidation(regions,dvConstraint));
+		}
+		if(validation instanceof XSSFDataValidation) {
+			validation.setSuppressDropDownArrow(true);
+			validation.setShowErrorBox(true);
+		}else {
+			validation.setSuppressDropDownArrow(false);
+		}
+		if(StringUtils.isNotBlank(ed.getValidationErrorMsg())){
+			validation.createErrorBox("error",ed.getValidationErrorMsg());
+		}
+		sheet.addValidationData(validation);
+	}
+
+	/**
+	 * 鑾峰彇鑼冨洿鐨勮〃杈惧紡
+	 * @param excelData 鏁版嵁瀵硅薄
+	 * @return 鑼冨洿鐨勮〃杈惧紡
+	 */
+	private static String getRange(WriteExcelData excelData){
+		//鍒楁槸浠嶢寮�濮嬬殑
+		char start = (char)('A' + excelData.getCol());
+		int rowId = excelData.getRow() + 1;
+		int endRowId = excelData.getRowTo() +1;
+		if (excelData.getColTo() <= 25) {
+			char end = (char)('A' +excelData.getColTo());
+			return "$" + start + "$" + rowId + ":$" + end + "$" + endRowId;
+		} else {
+			char endPrefix = 'A';
+			char endSuffix = 'A';
+			if ((excelData.getColTo() - 25) / 26 == 0 || excelData.getColTo() == 51) {// 26-51涔嬮棿锛屽寘鎷竟鐣岋紙浠呬袱娆″瓧姣嶈〃璁$畻锛�
+				if ((excelData.getColTo() - 25) % 26 == 0) {// 杈圭晫鍊�
+					endSuffix = (char)('A' + 25);
+				} else {
+					endSuffix = (char)('A' + (excelData.getColTo() - 25) % 26 - 1);
+				}
+			} else {// 51浠ヤ笂
+				if ((excelData.getColTo() - 25) % 26 == 0) {
+					endSuffix = (char)('A' + 25);
+					endPrefix = (char)(endPrefix + (excelData.getColTo() - 25) / 26 - 1);
+				} else {
+					endSuffix = (char)('A' + (excelData.getColTo() - 25) % 26 - 1);
+					endPrefix = (char)(endPrefix + (excelData.getColTo() - 25) / 26);
+				}
+			}
+			return "$" + start + "$" + rowId + ":$" + endPrefix + endSuffix + "$" + endRowId;
+		}
+	}
+
+	/**
+	 * 寰�鍗曞厓鏍奸噷鍐欏叆鍊�
+	 *
+	 * @param cell  鍗曞厓鏍煎璞�
+	 * @param value 瑕佸啓鍏ョ殑鍊�
+	 */
+	private static void setCellValue(Cell cell, Object value) {
+		if (value != null) {
+			if (value instanceof Date) {
+				cell.setCellValue((Date) value);
+			} else if (value instanceof String) {
+				cell.setCellValue(value.toString());
+			} else if (value instanceof Boolean) {
+				cell.setCellValue((Boolean)value);
+			} else if (value instanceof Integer) {
+				cell.setCellValue((Integer) value);
+			} else if (value instanceof Long) {
+				cell.setCellValue((Long) value);
+			} else if (value instanceof BigDecimal) {
+				cell.setCellValue(((BigDecimal) value).doubleValue());
+			} else if (value instanceof Double) {
+				cell.setCellValue((Double) value);
+			} else if (value instanceof RichTextString) {
+				cell.setCellValue((RichTextString) value);
+			} else {
+				cell.setCellValue(value.toString());
+			}
+		}
+	}
+
+	/**
+	 * 鎷疯礉鏍峰紡
+	 *
+	 * @param sheet     宸ヤ綔琛�
+	 * @param cell      鍗曞厓鏍�
+	 * @param excelData 瑕佹嫹璐濈殑淇℃伅
+	 */
+	private static void copyStyle(Sheet sheet, Cell cell, WriteExcelData excelData) {
+		if (excelData.isCopyStyle()) {
+			//鎷疯礉鏍峰紡
+			Row copyStyleRow = sheet.getRow(excelData.getCopyStyleRow());
+			if (copyStyleRow != null) {
+				Cell copyStyleCell = copyStyleRow.getCell(excelData.getCopyStyleCol());
+				copyStyleForCell(copyStyleCell,cell);
+				if(StringUtils.isNotBlank(excelData.getDateFormat())){
+					HSSFDataFormat format= (HSSFDataFormat) sheet.getWorkbook().createDataFormat();
+					cell.getCellStyle().setDataFormat(format.getFormat(excelData.getDateFormat()));
+				}
+			}
+		}
+	}
+
+	/**
+	 * 鎷疯礉鍗曞厓鏍肩殑鏍峰紡
+	 * @param fromCell 鏉ユ簮绔崟鍏冩牸
+	 * @param toCell 鐩爣绔崟鍏冩牸
+	 */
+	private static void copyStyleForCell(Cell fromCell,Cell toCell){
+		// 鏍峰紡
+		CellStyle cellStyle = toCell.getCellStyle();
+		CellStyle fromStyle = fromCell.getCellStyle();
+		cellStyle.cloneStyleFrom(fromStyle);
+		cellStyle.setAlignment(fromStyle.getAlignment());
+		cellStyle.setBorderBottom(fromStyle.getBorderBottom());
+		cellStyle.setBorderLeft(fromStyle.getBorderLeft());
+		cellStyle.setBorderRight(fromStyle.getBorderRight());
+		cellStyle.setBorderTop(fromStyle.getBorderTop());
+		cellStyle.setDataFormat(fromStyle.getDataFormat());
+		cellStyle.setFillBackgroundColor(fromStyle.getFillBackgroundColor());
+		cellStyle.setFillForegroundColor(fromStyle.getFillForegroundColor());
+		cellStyle.setFillPattern(fromStyle.getFillPattern());
+		cellStyle.setVerticalAlignment(fromStyle.getVerticalAlignment());
+		cellStyle.setWrapText(fromStyle.getWrapText());
+		cellStyle.setLocked(fromStyle.getLocked());
+		cellStyle.setBottomBorderColor(fromStyle.getBottomBorderColor());
+		cellStyle.setLeftBorderColor(fromStyle.getLeftBorderColor());
+		cellStyle.setTopBorderColor(fromStyle.getTopBorderColor());
+		cellStyle.setRightBorderColor(fromStyle.getRightBorderColor());
+	}
+
+	/**
+	 * 灞呬腑鏁版嵁
+	 *
+	 * @param cell      鍗曞厓鏍�
+	 * @param excelData 瑕佸眳涓殑鍐呭
+	 */
+	private static void centerCell(Cell cell, WriteExcelData excelData) {
+		if (excelData.isCenter()) {
+			CellStyle cellStyle = cell.getCellStyle();
+			cellStyle.setAlignment(HorizontalAlignment.CENTER);//姘村钩灞呬腑
+			cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);//鍨傜洿灞呬腑
+		}
+	}
+
+	/**
+	 * 鍚堝苟鍗曞厓鏍�
+	 *
+	 * @param sheet          宸ヤ綔琛�
+	 * @param mergedDataList 瑕佸悎骞剁殑鏁版嵁淇℃伅
+	 */
+	private static void mergedRegion(Sheet sheet, Collection<WriteExcelData> mergedDataList) {
+		if (!CollectionUtils.isEmpty(mergedDataList)) {
+			mergedDataList.stream().forEach(ed -> {
+				if (ed.getRowTo() < ed.getRow()) {
+					ed.setRowTo(ed.getRow());
+				}
+				if (ed.getColTo() < ed.getCol()) {
+					ed.setColTo(ed.getCol());
+				}
+				sheet.addMergedRegion(new CellRangeAddress(ed.getRow(), ed.getRowTo(), ed.getCol(), ed.getColTo()));
+			});
+		}
+	}
+
+	/**
+	 * 浠巈xcel涓婅鍙栨暟鎹�
+	 *
+	 * @param file 鏂囦欢
+	 * @return 鏁版嵁鍒楄〃
+	 * @throws VciBaseException 鎵ц鍑洪敊鐨勬椂鍊欎細鎶涘嚭寮傚父
+	 */
+	public static  List<SheetDataSet> readDataObjectFromExcel(File file) throws VciBaseException {
+		return readDataObjectFromExcel(file, SheetDataSet.class);
+	}
+
+	/**
+	 * 浠巈xcel涓婅鍙栨暟鎹�
+	 *
+	 * @param file        鏂囦欢
+	 * @param doClass 鏁版嵁瀵硅薄鐨勭被鍨�
+	 * @param <T>         鏁版嵁瀵硅薄鐨勭被鍨�
+	 * @return 鏁版嵁鍒楄〃
+	 * @throws VciBaseException 鎵ц鍑洪敊鐨勬椂鍊欎細鎶涘嚭寮傚父
+	 */
+	public static <T> List<T> readDataObjectFromExcel(File file, Class<T> doClass) throws VciBaseException {
+		return readDataObjectFromExcel(file, doClass, null);
+	}
+
+	/**
+	 * 浠巈xcel涓婅鍙栨暟鎹�
+	 *
+	 * @param file        鏂囦欢
+	 * @param excelOption 璇诲彇鐨勭被鍨嬶紝鍖呮嫭鏁版嵁鐨勯琛岋紝
+	 * @param doClass     鏁版嵁瀵硅薄鐨勭被
+	 * @param <T>         鏁版嵁瀵硅薄鐨勭被鍨�
+	 * @return 鏁版嵁鍒楄〃
+	 * @throws VciBaseException 鎵ц鍑洪敊鐨勬椂鍊欎細鎶涘嚭寮傚父
+	 */
+	public static <T> List<T> readDataObjectFromExcel(File file, Class<T> doClass, ReadExcelOption excelOption) throws VciBaseException {
+		return readDataObjectFromExcel(file, doClass,excelOption, null);
+	}
+
+	/**
+	 * 浠巈xcel涓婅鍙栨暟鎹�
+	 *
+	 * @param file        鏂囦欢
+	 * @param excelOption 璇诲彇鐨勭被鍨嬶紝鍖呮嫭鏁版嵁鐨勯琛岋紝
+	 * @param doClass     鏁版嵁瀵硅薄鐨勭被
+	 * @param <T>         鏁版嵁瀵硅薄鐨勭被鍨�
+	 * @param processer   杞崲鍣�
+	 * @return 鏁版嵁鍒楄〃
+	 * @throws VciBaseException 鎵ц鍑洪敊鐨勬椂鍊欎細鎶涘嚭寮傚父
+	 */
+	public static <T> List<T> readDataObjectFromExcel(File file, Class<T> doClass,ReadExcelOption excelOption,  PoiImportProcesser<T> processer) throws VciBaseException {
+		InputStream ins = null;
+		try {
+			ins = new FileInputStream(file);
+		} catch (Throwable e) {
+			String msg = READ_IMPORT_FILE_FAIL;
+			if (logger.isErrorEnabled()) {
+				logger.error(msg, e);
+			}
+			throw new VciBaseException(msg + LangBaseUtil.getErrorMsg(e), new String[]{}, e);
+		}
+		try {
+			return readDataObjectFromExcel(ins, doClass, excelOption,processer);
+		} catch (VciBaseException e) {
+			throw e;
+		} catch (Throwable e) {
+			throw new VciBaseException(LangBaseUtil.getErrorMsg(e), new String[]{}, e);
+		} finally {
+			IOUtils.closeQuietly(ins);
+		}
+	}
+
+	/**
+	 * 浠巈xcel涓婅鍙栨暟鎹�
+	 *
+	 * @param ins         鏂囦欢娴�
+	 * @param excelOption 璇诲彇鐨勭被鍨嬶紝鍖呮嫭鏁版嵁鐨勯琛岋紙榛樿1锛夛紝宸ヤ綔琛紙榛樿0锛夊拰鏄惁鍏ㄩ儴宸ヤ綔琛紙榛樿鍚︼級
+	 * @param doClass     鏁版嵁鐨勫璞�
+	 * @param <T>         鏁版嵁瀵硅薄鎵�灞炵殑绫诲瀷
+	 * @param processer   杞崲鍣�
+	 * @return 鏁版嵁鍒楄〃
+	 * @throws VciBaseException 鎵ц鍑洪敊鐨勬椂鍊欎細鎶涘嚭寮傚父
+	 */
+	public static <T> List<T> readDataObjectFromExcel(InputStream ins, Class<T> doClass,ReadExcelOption excelOption,  PoiImportProcesser<T> processer) throws VciBaseException {
+		if (ins == null) {
+			throw new VciBaseException(INPUT_STREAM_IS_NULL);
+		}
+		if (doClass == null) {
+			doClass = (Class<T>) SheetDataSet.class;
+		}
+		boolean isDataSet = false;
+		if (doClass.equals(SheetDataSet.class)) {
+			isDataSet = true;
+		}
+		//鑾峰彇瀵硅薄涓婄殑鍒楃殑鍚嶇О
+		Map<Field, ExcelColumn> excelColumnSet = getExcelColumnAnnotations(doClass);
+		Map<String/**鏍囬**/, ExcelColumn> excelTitleMap = Optional.of(excelColumnSet).get().values().stream().collect(Collectors.toMap(s -> s.value(), t -> t));
+		Map<String/**鏍囬**/,Field> excelTitleFieldMap = new HashMap<>();
+		Map<String/**鏍囬**/,ExcelColumnMap> extendAttrTitleMap = new HashMap<>();
+		final Field[] rowIndexFields = {null};
+		ReadExcelOption finalExcelOption = excelOption;
+		excelColumnSet.forEach(((field, excelColumn) -> {
+			excelTitleFieldMap.put(excelColumn.value(),field);
+			if (excelColumn.rowIndexColumn()) {
+				rowIndexFields[0] = field;
+			}
+			field.setAccessible(true);
+			if((field.getType().equals(Map.class) || field.getType().getSuperclass().equals(Map.class))
+					&& !CollectionUtils.isEmpty(finalExcelOption.getExtendAttrMap())
+					&&  finalExcelOption.getExtendAttrMap().containsKey(excelColumn.value())){
+				//璇存槑鏄痬ap绫诲瀷,杩欑涓�鑸槸鎵╁睍灞炴�э紝灏嗕竴鍫嗗睘鎬ц浆鎹负map閲岀殑鍊�
+				List<ExcelColumnMap> excelColumnMaps = finalExcelOption.getExtendAttrMap().get(excelColumn.value());
+				if(!CollectionUtils.isEmpty(excelColumnMaps)){
+					excelColumnMaps.stream().forEach(ss->{
+						excelTitleFieldMap.put(ss.getTitle(),field);
+						extendAttrTitleMap.put(ss.getTitle(),ss);
+					});
+				}
+			}
+		}));
+		Field rowIndexField = null;
+		if (rowIndexFields[0] != null) {
+			rowIndexField = rowIndexFields[0];
+		}
+
+		Workbook workbook = getWorkbookByInputStream(ins);
+		if (excelOption == null) {
+			excelOption = new ReadExcelOption();
+		}
+		FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
+		List<T> dataSet = new ArrayList<>();
+		try {
+			for (int sheetIndex = 0; sheetIndex < workbook.getNumberOfSheets(); sheetIndex++) {
+				Sheet sheet = workbook.getSheetAt(sheetIndex);
+				if(StringUtils.isNotBlank(excelOption.getSheetName())){
+					if(!sheet.getSheetName().equalsIgnoreCase(excelOption.getSheetName())){
+						continue;
+					}
+				}else {
+					if (!excelOption.isReadAllSheet() && sheetIndex != excelOption.getSheetIndex()) {
+						continue;
+					}
+				}
+				SheetDataSet sheetDataSet = new SheetDataSet();
+				sheetDataSet.setSheetName(sheet.getSheetName());
+				if (isDataSet) {
+					dataSet.add((T) sheetDataSet);
+				}
+				//澶勭悊鏍囬
+				Map<Integer, String> colsNameIndexMap = new HashMap<>();
+				if (excelOption.getFristRow() > 0) {
+					//绛変簬0琛ㄧず娌℃湁鎬绘爣棰�
+					try {
+						Row titleRow = sheet.getRow(excelOption.getFristRow()-1);
+						int colsCount = titleRow.getLastCellNum();
+						List<String> titleList = new LinkedList<>();
+						for (int i = 0; i < colsCount; i++) {
+							String title = VciBaseUtil.getStringValueFromObject(getCellValue(titleRow.getCell(i),evaluator));
+							if (StringUtils.isNotBlank(title)) {
+								title= title.replace("*","").replace("鈽�","");
+								colsNameIndexMap.put(i, title);
+								titleList.add(title);
+							}
+						}
+						if (isDataSet) {
+							sheetDataSet.setColName(titleList);
+						}
+					} catch (Exception e) {
+						if (logger.isErrorEnabled()) {
+							logger.error("璇诲彇excel鏂囦欢涓殑鏍囬淇℃伅鍑虹幇浜嗛敊璇�", e);
+						}
+						throw e;
+					}
+				}
+
+				//璇诲彇鍊�
+				List<SheetRowData> rowDataList = new LinkedList<SheetRowData>();
+				if (sheet.getLastRowNum() > 0) {
+					for (int rowIndex = excelOption.getFristRow(); rowIndex <= sheet.getLastRowNum(); rowIndex++) {
+						Row rowDataSet = sheet.getRow(rowIndex);
+						if (rowDataSet == null) {
+							continue;
+						}
+						boolean notValue = false;
+						for (int i = 0; i < rowDataSet.getLastCellNum(); i++) {
+							Cell cellTemp = rowDataSet.getCell(i);
+							Object valueTemp = getCellValue(cellTemp, evaluator);
+							if((valueTemp != null && !(valueTemp instanceof String) )
+									|| (valueTemp instanceof String && valueTemp !=null && StringUtils.isNotBlank(valueTemp.toString())) ){
+								notValue = true;
+								break;
+							}
+						}
+						if(!notValue){
+							//鏁磋閮芥槸绌猴紝鐩存帴璺宠繃
+							continue;
+						}
+						//瀹炰緥鍖栨暟鎹璞�
+						SheetRowData rd = (isDataSet ? new SheetRowData() : null);
+						T obj = null;
+						if (!isDataSet) {
+							try {
+								obj = doClass.newInstance();
+							} catch (Throwable e) {
+								if (logger.isErrorEnabled()) {
+									logger.error("瀹炰緥鍖栨暟鎹璞�", e);
+								}
+								throw new VciBaseException("瀹炰緥鍖栨暟鎹璞�," + LangBaseUtil.getErrorMsg(e));
+							}
+						}
+
+						//澶勭悊琛屽彿
+						if (isDataSet) {
+							rd.setRowIndex(String.valueOf(rowIndex));
+						}
+						if (!isDataSet && rowIndexField != null) {
+							VciBaseUtil.setValueForField(rowIndexField, obj, String.valueOf(rowIndex));
+						}
+
+						//姣忚鐨勬暟鎹�
+						Map<Integer, String> rowDataMap = new HashMap<>();
+						//閬嶅巻杩欒鐨勬瘡涓�涓崟鍏冩牸鐨勬暟鎹�
+						for (int columnIndex = 0; columnIndex < rowDataSet.getLastCellNum(); columnIndex++) {
+							Cell cell = rowDataSet.getCell(columnIndex);
+							Object value = getCellValue(cell, evaluator);
+							//璇存槑鏄璞�
+							String title = colsNameIndexMap.containsKey(columnIndex)?colsNameIndexMap.get(columnIndex):"";
+							//灞炴�ф槸鍚︿负map褰㈠紡
+							boolean isMapField = false;
+							Field thisField = null;
+							if (StringUtils.isNotBlank(title) && excelTitleFieldMap.containsKey(title)) {
+								thisField = excelTitleFieldMap.get(title);
+							}
+							if(thisField!=null){
+								thisField.setAccessible(true);
+								if(thisField.getType().equals(Map.class) || thisField.getType().getSuperclass().equals(Map.class)){
+									isMapField = true;
+								}
+							}
+
+							ExcelColumn excelColumn = null;
+							if (StringUtils.isNotBlank(title) && excelTitleMap.containsKey(title)) {
+								excelColumn = excelTitleMap.get(title);
+							}
+							ExcelColumnMap columnMap = null;
+							if(isMapField){
+								columnMap = extendAttrTitleMap.get(title);
+							}
+							boolean isNull = false;
+							if(value == null || (value instanceof String && StringUtils.isBlank(value.toString()))){
+								isNull = true;
+							}
+							if (!isNull) {
+								if (!isDataSet) {
+									if (thisField != null && (excelColumn != null || columnMap!=null)) {
+										if(!isMapField) {
+											if (value.getClass().equals(thisField.getType())) {
+												try {
+													thisField.set(obj, value);
+												} catch (IllegalAccessException e) {
+													if (logger.isErrorEnabled()) {
+														logger.error("璇诲彇excel鐨勫崟鍏冩牸鐨勫�煎悗锛屼负瀵硅薄璧嬪�煎嚭鐜颁簡閿欒", e);
+													}
+												}
+											} else {
+												VciBaseUtil.setValueForField(thisField, obj, VciBaseUtil.getStringValueFromObject(value));
+											}
+											if (thisField.getType().equals(Date.class) && thisField.get(obj) == null) {
+												throw new VciBaseException(CELL_NOT_DATE_FORMATE, new String[]{title, (rowIndex + 1) + ""});
+											}
+											if (StringUtils.isNotBlank(excelColumn.regExg()) && !VciBaseUtil.getStringValueFromObject(value).matches(excelColumn.regExg())) {
+												throw new VciBaseException(CELL_VALUE_NOT_EQUAL_REG, new String[]{title, (rowIndex + 1) + "", excelColumn.regExgTitle()});
+											}
+										}else{
+											//璇存槑鏄痬ap
+											Object fieldValue = thisField.get(obj);
+											Map<String,String> data ;
+											if(fieldValue==null){
+												data = new HashMap<>();
+											}else{
+												data = (Map<String,String>)fieldValue;
+											}
+											data.put(columnMap.getColumnName(),value==null?"":value.toString());
+											try {
+												thisField.set(obj, data);
+											} catch (IllegalAccessException e) {
+												if (logger.isErrorEnabled()) {
+													logger.error("璁剧疆map绫诲瀷鐨勬暟鎹椂鍊欏嚭鐜颁簡閿欒", e);
+												}
+											}
+										}
+									}
+									if (processer != null && thisField != null) {
+										processer.process(value, obj, thisField);
+									}
+								} else {
+									//璇存槑鍙槸璇诲彇鏁版嵁
+									rowDataMap.put(columnIndex, VciBaseUtil.getStringValueFromObject(value));
+								}
+							}else{
+								//闇�瑕佸垽鏂竴涓嬶紝鏄笉鏄暣琛岄兘鏄┖鐨�
+								if (!isDataSet && thisField != null && excelColumn != null ) {
+									if(!excelColumn.nullable() ) {
+										throw new VciBaseException(CELL_VALUE_CAN_NOT_NULL, new String[]{title, (rowIndex + 1) + ""});
+									}
+									if(StringUtils.isNotBlank(excelColumn.regExg())){
+										throw new VciBaseException(CELL_VALUE_CAN_NOT_NULL_FOR_REG, new String[]{title, (rowIndex + 1) + ""});
+									}
+								}
+							}
+						}
+						if (isDataSet) {
+							rd.setData(rowDataMap);
+							rowDataList.add(rd);
+						} else {
+							dataSet.add(obj);
+						}
+					}
+				}
+				if(isDataSet){
+					sheetDataSet.setRowData(rowDataList);
+				}
+			}
+		}catch (Throwable e){
+			throw new VciBaseException(LangBaseUtil.getErrorMsg(e),new String[0],e);
+		}finally {
+			IOUtils.closeQuietly(ins);
+			try {
+				workbook.close();
+			} catch (IOException e) {
+				if(logger.isErrorEnabled()){
+					logger.error("鍏抽棴宸ヤ綔绨垮嚭鐜颁簡閿欒",e);
+				}
+			}
+		}
+
+		return  dataSet;
+	}
+
+	/**
+	 * 浠巆ell鍗曞厓鏍间笂鑾峰彇鍊�
+	 * @param cell 鍗曞厓鏍煎璞�
+	 * @param evaluator 鍏紡杞崲
+	 * @return 鍗曞厓鏍肩殑鍊硷紝娌℃湁杞崲涓哄瓧绗︿覆
+	 */
+	private static Object getCellValue(Cell cell,FormulaEvaluator evaluator){
+		if(cell !=null ){
+			Object cellValue = null;
+			CellType cellTypeEnum = cell.getCellType();
+			switch (cellTypeEnum){
+				case STRING:
+					String thisCellValue = cell.getStringCellValue();
+					cellValue = StringUtils.isEmpty(thisCellValue)?"":thisCellValue.trim();
+					break;
+				case BOOLEAN:
+					boolean boolValue = cell.getBooleanCellValue();
+					cellValue = boolValue;
+					break;
+				case FORMULA:
+					cellValue = getCellValue(evaluator.evaluate(cell));
+					break;
+				case NUMERIC:
+					if(DateUtil.isCellDateFormatted(cell)){
+						cellValue = cell.getDateCellValue();
+					}else{
+						cellValue = cell.getNumericCellValue();
+					}
+					break;
+				default:
+					cellValue = "";
+					break;
+			}
+			return cellValue;
+		}else{
+			return null;
+		}
+	}
+
+	/**
+	 * 閽堝鍏紡鐨勮绠楀��
+	 * @param cell 鍏紡杞崲鍚庣殑鍗曞厓鏍煎璞�
+	 * @return 鍏紡鐨勫疄闄呭��
+	 */
+	private static Object getCellValue(CellValue cell) {
+		Object cellValue = null;
+		switch (cell.getCellTypeEnum()) {
+			case STRING:
+				String thisCellValue = cell.getStringValue();
+				cellValue = StringUtils.isEmpty(thisCellValue)?"":thisCellValue.trim();
+				break;
+			case NUMERIC:
+				//鍏紡璁$畻涓嶄細鏈夋棩鏈熷瀷
+				cellValue=cell.getNumberValue();
+				break;
+			default:
+				break;
+		}
+
+		return cellValue;
+	}
+
+
+	/**
+	 * 鑾峰彇鐢靛瓙琛ㄦ牸鐩稿叧鐨勬敞瑙�
+	 *
+	 * @param doClass 杩斿洖鐨勭被
+	 * @return 涓嶆槸SheetDataSet鐨勬椂鍊欓渶瑕佽繑鍥炴墍鏈夊寘鍚簡excelcolumn娉ㄨВ鐨勫睘鎬�
+	 */
+	public static <T> Map<Field, ExcelColumn> getExcelColumnAnnotations(Class<T> doClass) {
+		Map<Field, ExcelColumn> excelColumnMap = new HashMap();
+		if (!doClass.equals(SheetDataSet.class)) {
+			List<Field> allFields = VciBaseUtil.getAllFieldForObj(doClass);
+			List<Field> hasExcelColumnFields = allFields.stream().filter(field -> field.isAnnotationPresent(ExcelColumn.class)).collect(Collectors.toList());
+			if (!CollectionUtils.isEmpty(hasExcelColumnFields)) {
+				hasExcelColumnFields.stream().forEach(field -> {
+					ExcelColumn ec = getExcelColumnAnnotation(field);
+					excelColumnMap.put(field, ec);
+				});
+			}
+		}
+		return excelColumnMap;
+	}
+
+	/**
+	 * 鑾峰彇灞炴�т笂鐨別xcelColumn鐨勬敞瑙�
+	 * @param field 灞炴�у璞�
+	 * @return excelColumn
+	 */
+	public static ExcelColumn getExcelColumnAnnotation(Field field){
+		ExcelColumn ec = field.getAnnotation(ExcelColumn.class);
+		if (ec == null) {
+			ec = field.getDeclaredAnnotation(ExcelColumn.class);
+		}
+		return ec;
+	}
+
+	/**
+	 * 鏍规嵁PO瀵硅薄锛屽鍑烘ā鏉�
+	 * @param doClass 瀵煎嚭鐨勫璞�
+	 * @param downloadTempOption 涓嬭浇鐨勯�夐」
+	 * @param processer 璋冪敤鍑芥暟锛岃幏鍙栨灇涓剧殑鍊�
+	 * @param <T> 绫诲瀷
+	 * @return 鏂囦欢鐨勮矾寰�
+	 */
+	public static <T> String downloadImportTempByClass(Class<T> doClass,DownloadTempOption downloadTempOption,PoiTemplateProcesser<T> processer){
+		if(downloadTempOption == null){
+			downloadTempOption = new DownloadTempOption("");
+		}
+		//ok,鍐檈xcel
+		String excelName = LocalFileUtil.getDefaultTempFolder() + File.separator + (StringUtils.isNotBlank(downloadTempOption.getExcelName())?downloadTempOption.getExcelName():"瀵煎叆妯℃澘.xls");
+		try {
+			new File(excelName).createNewFile();
+		} catch (Throwable e) {
+			throw new VciBaseException(LangBaseUtil.getErrorMsg(e), new String[]{excelName}, e);
+		}
+		List<WriteExcelData> excelDataList = new ArrayList<>();
+		//鍏堝鐞嗘爣棰�
+		Map<Field, ExcelColumn> fieldExcelColumnMap = getExcelColumnAnnotations(doClass);
+		Map<String,ExcelColumn> fieldNameExcelColumnMap = new HashMap<>();
+		fieldExcelColumnMap.forEach((field,ec)->{
+			field.setAccessible(true);
+			fieldNameExcelColumnMap.put(field.getName(),ec);
+		});
+		//todo 鍚庨潰澶勭悊鏍囬鐨勫唴瀹�
+		//鑾峰彇椤哄簭锛屽鏋滄槸缁ф壙涓婄骇鐨勶紝灏辨斁鍚庨潰闅忔剰澶勭悊
+		Field fields[] = doClass.getDeclaredFields();
+		Set<String> finedFields = new HashSet<>();
+		Workbook workbook = new HSSFWorkbook();
+		int index = 0;
+		for (int i = 0; i < fields.length; i++) {
+			//TODO, 缁ф壙鐨勮繕娌″鐞�
+			Field field = fields[i];
+			field.setAccessible(true);
+			String fieldName = field.getName();
+			if(fieldNameExcelColumnMap.containsKey(fieldName)){
+				finedFields.add(fieldName);
+				ExcelColumn column = fieldNameExcelColumnMap.get(fieldName);
+				if(column.rowIndexColumn()){
+					continue;
+				}
+				WriteExcelData excelData = new WriteExcelData(0,index,StringUtils.isNotBlank(column.value())?column.value():fieldName);
+				if(!column.nullable()){
+					excelData.setFontColor(String.valueOf(HSSFColor.HSSFColorPredefined.RED.getIndex()));
+					excelData.setObj(excelData.getObj() +"*");
+				}
+				//鏍囬閮戒笉璁╂敼
+				excelData.setReadOnly(true);
+				excelData.setCenter(true);
+				if(column.width()>0){
+					excelData.setWidth(column.width());
+				}
+				/**
+				 * 涓嬮潰鐨勫唴瀹�,鏃堕棿鏍煎紡锛屼笅鎷夎彍鍗曪紝鏄惁寮�鍏�
+				 */
+				List<WriteExcelData> thisRowNextDatas = new ArrayList<>();
+				if(downloadTempOption.getDefaultRowSize() ==null || downloadTempOption.getDefaultRowSize()<0){
+					downloadTempOption.setDefaultRowSize(1);
+				}
+				Integer defaultRowSize = downloadTempOption.getDefaultRowSize();
+				for (int j = 0; j < defaultRowSize; j++) {
+					thisRowNextDatas.add(new WriteExcelData(1+j,index,""));
+				}
+				//鐪嬬湅鏄惁鏈夋灇涓�
+				if(StringUtils.isNotBlank(column.enumId()) && processer!=null){
+					Map<String, String> enumMap = processer.wrapperEnumMap(column.enumId(), doClass, field);
+					if(!CollectionUtils.isEmpty(enumMap)){
+						WriteExcelData thisRowNext = thisRowNextDatas.get(0);
+						thisRowNext.setValidation(true);
+						thisRowNext.setRowTo(defaultRowSize);
+						thisRowNext.setColTo(thisRowNext.getCol());
+						thisRowNext.setValidationDataList(enumMap.values().stream().collect(Collectors.toList()));
+					}
+				}
+				if(field.isAnnotationPresent(VciFieldType.class)){
+					VciFieldType fieldType = field.getDeclaredAnnotation(VciFieldType.class);
+					if(fieldType ==null){
+						fieldType = field.getAnnotation(VciFieldType.class);
+					}
+					if(fieldType!=null){
+						String dateFormat = "";
+						if(VciFieldTypeEnum.VTDateTime.equals(fieldType.value())){
+							dateFormat = VciDateUtil.DateTimeFormat;
+						}else if(VciFieldTypeEnum.VTDate.equals(fieldType.value())){
+							dateFormat = VciDateUtil.DateFormat;
+						}else if(VciFieldTypeEnum.VTTime.equals(fieldType.value())){
+							dateFormat = VciDateUtil.TimeFormat;
+						}
+						if(StringUtils.isNotBlank(dateFormat)){
+							String finalDateFormat = dateFormat;
+							thisRowNextDatas.stream().forEach(thisRowNext->{
+								thisRowNext.setDateFormat(finalDateFormat);
+							});
+						}
+						//boolean绫诲瀷
+						if(VciFieldTypeEnum.VTBoolean.equals(fieldType.value())){
+							List<String> trueFlase = new ArrayList<>();
+							trueFlase.add("鏄�");
+							trueFlase.add("鍚�");
+							WriteExcelData thisRowNext = thisRowNextDatas.get(0);
+							thisRowNext.setValidation(true);
+							thisRowNext.setRowTo(defaultRowSize);
+							thisRowNext.setColTo(thisRowNext.getCol());
+							thisRowNext.setValidationDataList(trueFlase);
+						}
+						//鏋氫妇鍥犱负鏄浐瀹氱殑锛屾墍浠ュ彲浠ラ�愪釜鍘诲鐞嗭紝鍙傜収瀵煎嚭鐨勬椂鍊欙紝涓嶈兘鎶婃暟鎹鍑�
+					}
+				}
+				excelDataList.addAll(thisRowNextDatas);
+				excelDataList.add(excelData);
+				index++;
+			}
+		}
+		WriteExcelOption excelOption = new WriteExcelOption();
+		excelOption.addSheetDataList(StringUtils.isNotBlank(downloadTempOption.getSheetName())?downloadTempOption.getSheetName():"Sheet1",excelDataList);
+		writeDataToFile(excelName, excelOption);
+		return excelName;
+	}
+
+	/**
+	 * * 鍚堝苟澶氫釜ExcelSheet
+	 * https://blog.csdn.net/lingerlan510/article/details/121943788
+	 * @param files 鏂囦欢瀛楃涓�(file.toString)闆嗗悎,鎸夐『搴忚繘琛屽悎骞讹紝鍚堝苟鐨凟xcel涓璖heet鍚嶇О涓嶅彲閲嶅
+	 * @param excelName 鍚堝苟鍚嶦xcel鍚嶇О(鍖呭惈鍚庣紑鍜岃矾寰�)
+	 * @Date: 2020/9/18 15:31
+	 */
+	public static void mergeExcel(List<String> files, String excelName) {
+		Workbook newExcelCreat = excelName.toLowerCase(Locale.ROOT).endsWith(".xlsx")? new XSSFWorkbook():new HSSFWorkbook();
+		// 閬嶅巻姣忎釜婧恊xcel鏂囦欢锛孴mpList涓烘簮鏂囦欢鐨勫悕绉伴泦鍚�
+		for (int i = 0 ; i < files.size(); i ++) {
+			String fromExcelName = files.get(i);
+			try (InputStream in = new FileInputStream(fromExcelName)) {
+				Workbook fromExcel = null;
+				if(fromExcelName.toLowerCase(Locale.ROOT).endsWith(".xlsx")){
+					fromExcel = new XSSFWorkbook(in);
+				}else{
+					fromExcel = new HSSFWorkbook(in);
+				}
+				int length = fromExcel.getNumberOfSheets();
+				if (length <= 1) {       //闀垮害涓�1鏃�
+					Sheet oldSheet = fromExcel.getSheetAt(0);
+					Sheet existSheet = newExcelCreat.getSheet(oldSheet.getSheetName());
+					String newSheetName = oldSheet.getSheetName();
+					if(existSheet!=null){
+						newSheetName += "_" +i;
+					}
+					Sheet newSheet = newExcelCreat.createSheet(newSheetName);
+					copySheet(newExcelCreat, oldSheet, newSheet);
+				} else {
+					for (int j = 0; j < length; j++) {// 閬嶅巻姣忎釜sheet
+						Sheet oldSheet = fromExcel.getSheetAt(j);
+						Sheet existSheet = newExcelCreat.getSheet(oldSheet.getSheetName());
+						String newSheetName = oldSheet.getSheetName();
+						if(existSheet!=null){
+							newSheetName += "_" +i + "_" + j;
+						}
+						Sheet newSheet = newExcelCreat.createSheet(newSheetName);
+						copySheet(newExcelCreat, oldSheet, newSheet);
+					}
+				}
+
+				//鍚嶇О绠$悊鍣�
+				List<? extends Name> allNames = fromExcel.getAllNames();
+				if(!CollectionUtils.isEmpty(allNames)){
+					allNames.stream().forEach(name->{
+						Name name1 = newExcelCreat.createName();
+						name1.setNameName(name.getNameName());
+						name1.setRefersToFormula(name.getRefersToFormula());
+					});
+				}
+			} catch (IOException e) {
+				throw new VciBaseException("鍚堝苟excel鍑洪敊鐨勪簡",new String[]{},e);
+			}
+		}
+		// 瀹氫箟鏂扮敓鎴愮殑xlxs琛ㄦ牸鏂囦欢
+		String allFileName = excelName;
+		try (FileOutputStream fileOut = new FileOutputStream(allFileName)) {
+			newExcelCreat.write(fileOut);
+			fileOut.flush();
+		} catch (IOException e) {
+			e.printStackTrace();
+		} finally {
+			try {
+				newExcelCreat.close();
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+		}
+	}
+
+	/**
+	 * 鍚堝苟鍗曞厓鏍�
+	 *
+	 * @param fromSheet 鏉ユ簮
+	 * @param toSheet 鐩爣
+	 */
+	private static void mergeSheetAllRegion(Sheet fromSheet, Sheet toSheet) {
+		int num = fromSheet.getNumMergedRegions();
+		CellRangeAddress cellR = null;
+		for (int i = 0; i < num; i++) {
+			cellR = fromSheet.getMergedRegion(i);
+			toSheet.addMergedRegion(cellR);
+		}
+	}
+
+	/**
+	 * 澶嶅埗鍗曞厓鏍�
+	 *
+	 * @param fromCell 鏉ユ簮
+	 * @param toCell 鐩爣
+	 */
+	private static void copyCell(Cell fromCell, Cell toCell) {
+
+		copyStyleForCell(fromCell,toCell);
+		if (fromCell.getCellComment() != null) {
+			toCell.setCellComment(fromCell.getCellComment());
+		}
+		// 涓嶅悓鏁版嵁绫诲瀷澶勭悊
+		CellType fromCellType = fromCell.getCellType();
+		toCell.setCellType(fromCellType);
+		if (fromCellType == CellType.NUMERIC) {
+			if (DateUtil.isCellDateFormatted(fromCell)) {
+				toCell.setCellValue(fromCell.getDateCellValue());
+			} else {
+				toCell.setCellValue(fromCell.getNumericCellValue());
+			}
+		} else if (fromCellType == CellType.STRING) {
+			RichTextString value = fromCell.getRichStringCellValue();
+			if(value !=null && StringUtils.isNotBlank(value.toString())){
+				Font fontAt = fromCell.getSheet().getWorkbook().getFontAt(fromCell.getCellStyle().getFontIndexAsInt());
+				value.applyFont(fontAt);
+			}
+			toCell.setCellValue(value);
+		} else if (fromCellType == CellType.BLANK) {
+			// nothing21
+		} else if (fromCellType == CellType.BOOLEAN) {
+			toCell.setCellValue(fromCell.getBooleanCellValue());
+		} else if (fromCellType == CellType.ERROR) {
+			toCell.setCellErrorValue(fromCell.getErrorCellValue());
+		} else if (fromCellType == CellType.FORMULA) {
+			toCell.setCellFormula(fromCell.getCellFormula());
+		} else {
+			// nothing29
+		}
+	}
+
+	/**
+	 * 琛屽鍒跺姛鑳�
+	 *
+	 * @param wb 宸ヤ綔琛�
+	 * @param oldRow 鏉ユ簮
+	 * @param toRow 鐩爣
+	 */
+	private static void copyRow(Workbook wb, Row oldRow, Row toRow) {
+		toRow.setHeight(oldRow.getHeight());
+		for (Iterator cellIt = oldRow.cellIterator(); cellIt.hasNext(); ) {
+			Cell tmpCell = (Cell)cellIt.next();
+			Cell newCell = toRow.createCell(tmpCell.getColumnIndex());
+			copyCell(tmpCell, newCell);
+		}
+	}
+
+	/**
+	 * Sheet澶嶅埗
+	 *
+	 * @param wb 宸ヤ綔琛�
+	 * @param fromSheet 鏉ユ簮
+	 * @param toSheet 鐩爣
+	 */
+	private static void copySheet(Workbook wb, Sheet fromSheet, Sheet toSheet) {
+		mergeSheetAllRegion(fromSheet, toSheet);
+		// 璁剧疆鍒楀
+		int length = fromSheet.getRow(fromSheet.getFirstRowNum()).getLastCellNum();
+		for (int i = 0; i <= length; i++) {
+			toSheet.setColumnWidth(i, fromSheet.getColumnWidth(i));
+		}
+		for (Iterator rowIt = fromSheet.rowIterator(); rowIt.hasNext(); ) {
+			Row oldRow = (Row) rowIt.next();
+			Row newRow = toSheet.createRow(oldRow.getRowNum());
+			copyRow(wb, oldRow, newRow);
+		}
+		//涓嬫媺妗�
+		List<? extends DataValidation> dataValidations = fromSheet.getDataValidations();
+		if(!CollectionUtils.isEmpty(dataValidations)){
+			dataValidations.stream().forEach(dv->{
+				toSheet.addValidationData(dv);
+			});
+		}
+	}
+	/**
+	 * 鍏抽敭灞炴��
+	 */
+	public static final String KEY_ATTR_CHAR = "鈽�";
+
+	/**
+	 * 蹇呰緭
+	 */
+	public static final String REQUIRED_CHAR = "*";
+
+	/**
+	 * 杩藉姞鏁版嵁鍒癳xcel涓紝
+	 * @param data 鏁版嵁锛屽繀椤绘槸po瀵硅薄
+	 * @param excelName 鐩爣鐨勬枃浠跺悕绉�
+	 * @param excelOption 鍐欏叆鐨勭浉鍏抽厤缃�
+	 * @param <T> 瀵硅薄绫诲瀷
+	 */
+	public static <T> void appendDataToExcel(Collection<T> data,String excelName,AppendDataExcelOption excelOption){
+		if(!CollectionUtils.isEmpty(data)){
+			T t1 = data.stream().findFirst().get();
+			//鑾峰彇瀵硅薄涓婄殑鍒楃殑鍚嶇О
+			Map<Field, ExcelColumn> excelColumnSet = getExcelColumnAnnotations(t1.getClass());
+			Map<String/**鏍囬**/,String> excelTitleFieldNameMap =new HashMap<>();
+			Set<String> readOnlyFields = new HashSet<>();
+			excelColumnSet.forEach((field,excelColumn)->{
+				excelTitleFieldNameMap.put(excelColumn.value(),field.getName());
+				if(excelColumn.readOnly()){
+					readOnlyFields.add(field.getName());
+				}
+			});
+
+			//璇诲彇鍐呭
+			ReadExcelOption readExcelOption = new ReadExcelOption();
+			readExcelOption.setSheetName(excelOption.getSheetName());
+			readExcelOption.setFristRow(excelOption.getTitleRowIndex()+1);
+			List<SheetDataSet> sheetDataSets = ExcelUtil.readDataObjectFromExcel(new File(excelName),SheetDataSet.class,readExcelOption);
+			if(!CollectionUtils.isEmpty(sheetDataSets)) {
+				SheetDataSet sheetDataSet = sheetDataSets.get(0);
+				Map<String/**瀛楁**/, Integer> fieldColumnMap = new HashMap<>();
+				List<String> colName = sheetDataSet.getColName();
+				if (!CollectionUtils.isEmpty(colName)) {
+					for (int i = 0; i < colName.size(); i++) {
+						String col= colName.get(i).replace(REQUIRED_CHAR,"").replace(KEY_ATTR_CHAR,"");
+						if(excelTitleFieldNameMap.containsKey(col)){
+							fieldColumnMap.put(excelTitleFieldNameMap.get(col),i);
+						}
+					}
+					//鎴戜滑灏佽鏁版嵁
+					List<WriteExcelData> writeExcelDataList = new ArrayList<>();
+					final Integer[] index = {excelOption.getTitleRowIndex()+1};
+					data.stream().forEach(d->{
+						Map<String, String> dataMap = VciBaseUtil.objectToMapString(d);
+						fieldColumnMap.forEach((field,col)->{
+							if(CollectionUtils.isEmpty(excelOption.getWriteFields()) || excelOption.getWriteFields().contains(field)) {
+								WriteExcelData excelData = new WriteExcelData(index[0], col, dataMap.getOrDefault(field, ""));
+								excelData.setReadOnly((excelOption.isReadOnlyFromField() && readOnlyFields.contains(field))
+								|| (!CollectionUtils.isEmpty(excelOption.getReadOnlyFields()) && excelOption.getReadOnlyFields().contains(field)));
+								writeExcelDataList.add(excelData);
+							}
+						});
+						index[0]++;
+					});
+					WriteExcelOption writeExcelOption = new WriteExcelOption();
+					writeExcelOption.addSheetDataList(excelOption.getSheetName(),writeExcelDataList);
+					writeExcelOption.setAppend(true);
+					writeDataToFile(excelName,writeExcelOption);
+				}
+			}
+		}
+	}
+
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/util/PoiImportProcesser.java b/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/util/PoiImportProcesser.java
new file mode 100644
index 0000000..2538e20
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/util/PoiImportProcesser.java
@@ -0,0 +1,21 @@
+package com.vci.starter.poi.util;
+
+import java.lang.reflect.Field;
+
+/**
+ * 浠巈xcel瀵煎叆鐨勬椂鍊欙紝灞炴�х殑杞崲鍣�
+ * @author weidy
+ * @date 2020/5/5
+ */
+@FunctionalInterface
+public interface PoiImportProcesser<T> {
+
+    /***
+     * 瀵圭壒娈婄殑鐨勭被鍨嬭繘琛屽鐞�.
+     * @param value 璇ュ睘鎬у搴旂殑鍊�
+     * @param obj  javaBean瀵硅薄.
+     * @param field 灞炴�у瓧娈�.
+     * @return 杩斿洖javaBean瀵硅薄.
+     */
+     void process(Object value, T obj, Field field);
+}
diff --git a/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/util/PoiTemplateProcesser.java b/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/util/PoiTemplateProcesser.java
new file mode 100644
index 0000000..d443123
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/poi/util/PoiTemplateProcesser.java
@@ -0,0 +1,22 @@
+package com.vci.starter.poi.util;
+
+import java.lang.reflect.Field;
+import java.util.Map;
+
+/**
+ * 鐢熸垚excel椤圭洰鐨勬ā鏉跨殑鏃跺�欙紝鑾峰彇鏋氫妇鐨勫唴瀹�
+ * @author weidy
+ * @date 2022/09/28
+ */
+@FunctionalInterface
+public interface PoiTemplateProcesser<T> {
+
+    /***
+     * 鑾峰彇鏋氫妇鐨勫唴瀹�
+     * @param enumId 鏋氫妇鐨勭紪鍙�
+     * @param tClass  javaBean瀵硅薄.
+     * @param field 灞炴�у瓧娈�.
+     * @return 鏋氫妇鐨勫唴瀹�
+     */
+    Map<String,String> wrapperEnumMap(String enumId, Class<T> tClass, Field field);
+}
diff --git a/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/word/bo/WordMergeListDataSource.java b/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/word/bo/WordMergeListDataSource.java
new file mode 100644
index 0000000..c2f76e0
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/word/bo/WordMergeListDataSource.java
@@ -0,0 +1,181 @@
+package com.vci.starter.word.bo;
+
+import com.aspose.words.IMailMergeDataSource;
+import com.aspose.words.ref.Ref;
+import com.vci.starter.web.util.VciBaseUtil;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.util.CollectionUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * 鐢ㄤ簬mergeField鐨勮〃鏍煎舰寮忕殑鏁版嵁鍐欏叆瀵硅薄锛屽洜涓篴spose.word涓嶆敮鎸丠ashMap
+ * @author weidy,dangsn
+ */
+public class WordMergeListDataSource implements IMailMergeDataSource {
+    /**
+     * 鏁版嵁瀵硅薄
+     */
+	private List<Map<String, Object>> dataList;
+
+    /**
+     * 绱㈠紩
+     */
+    private int index;
+
+    /**
+     * 琛ㄦ牸鍚嶇О
+     */
+    private String tableName;
+
+    /**
+     * 瀛愯〃鏍肩殑鍚嶇О
+     */
+    private String childTableName;
+
+    /**
+     * @param dataList 鏁版嵁闆� 锛屾暟鎹泦涓璏ap鐨刱ey锛岄渶瑕佽窡TableStart,TableEnd鍖呭惈鐨勫悕绉板搴�
+     * @param tableName 涓庢ā鏉夸腑鐨凾ableStart,TableEnd瀵瑰簲
+     */
+    public WordMergeListDataSource(List<Map<String, Object>> dataList, String tableName) {
+        this.dataList = dataList;
+        this.tableName = tableName;
+        index = -1;
+        this.setChildTableName(listChildTableNameFromData(this.dataList));
+    }
+
+    /**
+     * @param data 鍗曚釜鏁版嵁闆�
+     * @param tableName 涓庢ā鏉夸腑鐨凬ame瀵瑰簲
+     */
+    public WordMergeListDataSource(Map<String, Object> data, String tableName) {
+        if(this.dataList == null) {  
+            this.dataList = new ArrayList<Map<String,Object>>();
+            this.dataList.add(data);  
+        }  
+        this.tableName = tableName;  
+        index = -1;
+        this.setChildTableName(listChildTableNameFromData(this.dataList));
+    }
+
+    /**
+     * 鑾峰彇瀛愯〃鍚嶇О
+     * @return 瀛愯〃鍚嶇О锛屽涓細浠ラ�楀彿鍒嗛殧
+     */
+    public String getChildTableName() {
+        return childTableName;
+    }
+
+    /**
+     * 璁剧疆瀛愯〃鍚嶇О
+     * @param childTableName 瀛愯〃鍚嶇О锛屽涓互閫楀彿鍒嗛殧
+     */
+    public void setChildTableName(String childTableName) {
+        this.childTableName = childTableName;
+    }
+
+    /**
+     * 鑾峰彇缁撴灉闆嗘�绘暟 
+     * @return 涓暟
+     */  
+    public int getCount() {
+        return this.dataList.size();  
+    }
+
+    /**
+     * 鑾峰彇鏁版嵁鍒楄〃
+     * @return 鏁版嵁鍒楄〃
+     */
+    public List<Map<String, Object>> getDataList(){
+        return this.dataList;
+    }
+
+    /**
+     * 鑾峰彇琛ㄦ牸鍚嶇О
+     * @return 琛ㄦ牸鐨勫悕绉�
+     */
+    public String getTableName() {
+        return this.tableName;  
+    }
+
+    /**
+     * 鑾峰彇鍏蜂綋鐨勫�硷紝鎺ュ彛鎵�闇�瑕佺殑
+     * @param key 瀛楁鍚嶇О
+     * @param ref 鍊�
+     * @return 鏄惁鏈夊��
+     * @throws Exception 鑾峰彇鐨勬椂鍊欒兘鍑洪敊
+     */
+    @Override
+    public boolean getValue(String key, Ref<Object> ref) throws Exception {
+        if(index < 0 || index >= this.getCount()){
+            return false;
+        }
+        if(ref != null){
+            ref.set(this.dataList.get(index).get(key));
+            return true;
+        }else{
+            return false;
+        }
+    }
+
+    /**
+     * 浠庢暟鎹腑鎵惧埌list鐨勪綔涓哄瓙琛ㄧ殑瀵硅薄
+     * @param dataList 鏁版嵁鍒楄〃
+     * @return 鍖呭惈瀛愯〃鐨勫悕绉扮殑杩炴帴瀛楃涓�
+     */
+    private String listChildTableNameFromData(List<Map<String,Object>> dataList ){
+        List<String> nextChildNameList = new ArrayList<>();
+        if(!CollectionUtils.isEmpty(dataList)){
+            dataList.get(0).forEach((k,v) ->{
+                if(v != null && v instanceof List){
+                    nextChildNameList.add(k);
+                }
+            });
+        }
+        return nextChildNameList.stream().collect(Collectors.joining(","));
+    }
+
+    /**
+     * 瀹炵幇鐨勬帴鍙�
+     * @param tableName 瀛愯〃鐨勫悕绉�
+     * @return 瀛愯〃瀵硅薄锛屼笉绗﹀悎鐨勪細杩斿洖null
+     * @throws Exception 鑾峰彇鍑洪敊鐨勬椂鍊欎細鎶涘嚭寮傚父
+     */
+    @Override
+    public IMailMergeDataSource getChildDataSource(String tableName) throws Exception {
+        if(StringUtils.isNotBlank(getChildTableName())){
+            List<String> childrenTableName = VciBaseUtil.str2List(getChildTableName());
+            if(childrenTableName.contains(tableName)){
+                Object childData = this.dataList.get(index).get(tableName);
+                if(childData != null && childData instanceof List) {
+                    List<Map<String,Object>> childDataList = (List<Map<String,Object>>)childData;
+                    if(!CollectionUtils.isEmpty(childDataList)) {
+                        WordMergeListDataSource childDataSource = new WordMergeListDataSource(childDataList, tableName);
+                        childDataSource.setChildTableName(listChildTableNameFromData(childDataList));
+                        return childDataSource;
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    /** 
+     * 瀹炵幇鎺ュ彛 
+     * 鍒ゆ柇鏄惁杩樻湁涓嬩竴鏉¤褰�
+     * @return true绉诲姩鍒颁笅涓�鏉�
+     */  
+    @Override
+    public boolean moveNext() {
+        index += 1;  
+        if(index >= this.getCount()) {
+            return false;  
+        }  
+        return true;  
+    }
+
+	
+}
\ No newline at end of file
diff --git a/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/word/bo/WordMergeStartTableDataBO.java b/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/word/bo/WordMergeStartTableDataBO.java
new file mode 100644
index 0000000..0804d88
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/word/bo/WordMergeStartTableDataBO.java
@@ -0,0 +1,88 @@
+package com.vci.starter.word.bo;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 浣跨敤鍩熶唬鐮佺殑鏂瑰紡寰�word鐨勮〃鏍� 閲屽啓鍏ユ暟鎹紝闇�瑕�<TableStart:xxx><aa><bb><TableEnd:xxx>杩欐牱鐨勬柟寮�
+ * @author weidy
+ * @date 2019/8/13 15:47
+ */
+public class WordMergeStartTableDataBO implements java.io.Serializable {
+
+    /**
+     * 绂佹淇敼杩欎釜鍊�
+     */
+    private static final long serialVersionUID = -5247054966349871652L;
+    /**
+     * 琛ㄥ悕锛岄渶瑕佸拰word鐨勫煙浠g爜涓浉瀵瑰簲锛屾瘮濡�<TableStart:xxx><aa><bb><TableEnd:xxx> ,琛ㄥ悕涓簒xx
+     */
+    private String tableName;
+
+    /**
+     * 鍒楄〃鏁版嵁锛屽叾涓瘡涓�琛岀殑鏁版嵁涓殑Map鐨刱ey鏄煙瀛楁鍚嶇О,涓�瀹氳娉ㄦ剰锛屽鏋滄湁瀛愯〃锛屽瓙琛ㄧ殑閭d釜鍊间笉鑳戒负null锛屽惁鍒欐棤娉曞垽鏂�
+     */
+    private List<Map<String,Object>> tableDataList;
+
+    /**
+     * 瑕佸悎骞跺崟鍏冩牸鐨勫垪搴忓彿锛屼粠1寮�濮�
+     */
+    private String mergeColumn ;
+
+    /**
+     * 鑾峰彇琛ㄦ牸鍚嶇О
+     * @return 琛ㄦ牸鍚嶇О
+     */
+    public String getTableName() {
+        return tableName;
+    }
+
+    /**
+     * 璁剧疆琛ㄦ牸鍚嶇О
+     * @param tableName 琛ㄦ牸鍚嶇О
+     */
+    public void setTableName(String tableName) {
+        this.tableName = tableName;
+    }
+
+    /**
+     * 鑾峰彇琛ㄦ牸鐨勬暟鎹�
+     * @return 鑾峰彇琛ㄦ牸鐨勫悕绉�
+     */
+    public List<Map<String, Object>> getTableDataList() {
+        return tableDataList;
+    }
+
+    /**
+     * 璁剧疆琛ㄦ牸鐨勬暟鎹�
+     * @param tableDataList 琛ㄦ牸鏁版嵁
+     */
+    public void setTableDataList(List<Map<String, Object>> tableDataList) {
+        this.tableDataList = tableDataList;
+    }
+
+    /**
+     * 闇�瑕佸悎骞跺崟鍏冩牸鐨勫垪
+     * @return 鍒楀悕绉帮紝澶氫釜浠ラ�楀彿鍒嗛殧
+     */
+    public String getMergeColumn() {
+        return mergeColumn;
+    }
+
+    /**
+     * 璁剧疆瑕佸悎骞剁殑鍗曞厓鏍�
+     * @param mergeColumn 鍗曞厓鏍煎垪鍙凤紝浠�0寮�濮嬶紝澶氫釜浠ラ�楀彿鍒嗛殧
+     */
+    public void setMergeColumn(String mergeColumn) {
+        this.mergeColumn = mergeColumn;
+    }
+
+    @Override
+    public String toString() {
+        return "WordSignMergeTableData{" +
+                "tableName='" + tableName + '\'' +
+                ", tableDataList=" + tableDataList +
+                ", mergeColumn='" + mergeColumn + '\'' +
+                '}';
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/word/util/WordUtil.java b/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/word/util/WordUtil.java
new file mode 100644
index 0000000..cb46501
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-poi/src/main/java/com/vci/starter/word/util/WordUtil.java
@@ -0,0 +1,429 @@
+package com.vci.starter.word.util;
+
+import com.aspose.words.*;
+import com.vci.starter.web.exception.VciBaseException;
+import com.vci.starter.word.bo.WordMergeListDataSource;
+import com.vci.starter.word.bo.WordMergeStartTableDataBO;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.util.CollectionUtils;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.*;
+
+/**
+ * word鎿嶄綔绫�
+ * @author weidy
+ * @date 2020/2/19
+ */
+public class WordUtil {
+
+    /**
+     * 鏃ュ織
+     */
+    private static Logger logger = LoggerFactory.getLogger(WordUtil.class);
+
+    /**
+     * 鎻愮ず鍙傛暟涓虹┖
+     * @param s 鐩稿叧鐨勫弬鏁帮紝涓や袱缁勫悎锛岀涓�涓负鍙傛暟鐨勫璞★紝绗簩涓负鏄剧ず鐨勫悕绉�
+     * @throws VciBaseException 濡傛灉鍙傛暟涓虹┖鐨勬椂鍊欎細鎶涘嚭寮傚父
+     */
+    public static void alertNotNull(Object... s) throws VciBaseException {
+        if(s!=null && s.length>0){
+            for(int i = 0 ; i < s.length ; i ++){
+                Object obj = s[i];
+                if(obj==null || StringUtils.isBlank(obj.toString())){
+                    String param = "";
+                    try{
+                        i++;
+                        param = s[i].toString();
+                    }catch(Exception e){
+
+                    }
+                    throw new VciBaseException("鍙傛暟[{0}]涓嶈兘涓虹┖",new String[]{param});
+                }
+            }
+        }
+    }
+
+
+    /**
+     * 甯﹂�楀彿鐨勫瓧绗︿覆杞负list
+     * @param s 瀛楃涓�
+     * @return 瀛楃涓插垪琛�
+     */
+    public static List<String> str2List(String s){
+        if (isNull(s)) {
+            return null;
+        } else {
+            List<String> l = new ArrayList<String>();
+            Collections.addAll(l,removeComma(s).split(","));
+            return l;
+        }
+    }
+
+    /**
+     * 鍘婚櫎鏈�鍓嶉潰鐨勯�楀彿锛屽幓闄ゅ悗闈㈢殑閫楀彿
+     * @param s 瀛楃涓�
+     * @return 鍘婚櫎鏈熬閫楀彿
+     */
+    public static String removeComma(String s){
+        if(s == null || s.trim().length() == 0) {
+            return s;
+        }
+        else{
+            if(s.startsWith(",")) {
+                s = s.substring(1, s.length());
+            }
+            if(s.endsWith(",")) {
+                s = s.substring(0, s.length() - 1);
+            }
+            return s;
+        }
+    }
+
+    /**
+     * 鍒ゆ柇瀛楃涓叉槸涓嶆槸绌�,涓嶅垽鏂璽rim
+     * @param o 瀛楃涓�
+     * @return true琛ㄧず绌�
+     */
+    public static boolean isNull(String o){
+        return StringUtils.isEmpty(o);
+    }
+
+
+    /**
+     * 寰�word鍐欏叆琛ㄦ牸鏁版嵁锛岃繖绉嶆槸浣跨敤startTable鐨勬柟寮忥紝涓嶄細鑷姩鎷疯礉鏍煎紡
+     * @param fileName 鏂囦欢鍚嶏紝蹇呴』鏄痺ord鏂囦欢
+     * @param tableDataBOList 瑕佸啓鍏ュ埌鏂囦欢鐨勪俊鎭�
+     * @throws FileNotFoundException 鏂囦欢涓嶅瓨鍦ㄧ殑鏃跺�欎細鎶涘嚭寮傚父
+     * @throws VciBaseException 鍐欏叆鏁版嵁鍑洪敊鏃朵細鎶涘嚭寮傚父
+     */
+    public static void setTableDataToWord(String fileName, List<WordMergeStartTableDataBO> tableDataBOList) throws FileNotFoundException, VciBaseException{
+        alertNotNull(fileName,"word鐨勬枃浠跺悕绉�");
+        setTableDataToWord(new File(fileName),tableDataBOList);
+    }
+
+    /**
+     * 寰�word鍐欏叆琛ㄦ牸鏁版嵁锛岃繖绉嶆槸浣跨敤startTable鐨勬柟寮忥紝涓嶄細鑷姩鎷疯礉鏍煎紡
+     * @param file 鏂囦欢,蹇呴』鏄痺ord鏂囦欢
+     * @param tableDataBOList 瑕佸啓鍏ュ埌鏂囦欢鐨勪俊鎭�
+     * @throws FileNotFoundException 鏂囦欢涓嶅瓨鍦ㄧ殑鏃跺�欎細鎶涘嚭寮傚父
+     * @throws VciBaseException 鍐欏叆鏁版嵁鍑洪敊鏃朵細鎶涘嚭寮傚父
+     */
+    public static void setTableDataToWord(File file, List<WordMergeStartTableDataBO> tableDataBOList) throws FileNotFoundException, VciBaseException{
+        alertNotNull(file,"word鏂囦欢");
+        if(!file.exists()){
+            throw new FileNotFoundException(file.getName());
+        }
+        InputStream in = null;
+        Document document = null;
+        try{
+            in = new FileInputStream(file);
+            document = new Document(in);
+        }catch (Exception e){
+            IOUtils.closeQuietly(in);
+            //涓嶈兘鍦╢inally閲屽叧闂紝鍥犱负鍚庨潰杩橀渶瑕佺敤
+            throw new VciBaseException("鍒濆鍖杦ord鏂囨。瀵硅薄鐨勬椂鍊欏嚭鐜颁簡閿欒,{0}",new String[]{file.getAbsolutePath()},e);
+        }
+        try {
+            setTableDataToWord(document, tableDataBOList);
+        }catch (VciBaseException e){
+            throw e;
+        }catch (Throwable e){
+            throw new VciBaseException("鍚憌ord閲屽啓鍏ableStart绫诲瀷鐨勫煙瀛楁鐨勬椂鍊欏嚭閿�,{0}",new String[]{file.getAbsolutePath()},e);
+        }finally {
+            IOUtils.closeQuietly(in);
+        }
+        try{
+            document.save(file.getAbsolutePath());
+        }catch (Exception e) {
+            throw new VciBaseException("灏唚ord鐨勫唴瀹硅繑濉埌鏂囦欢涓嚭鐜颁簡閿欒,{0}",new String[]{file.getAbsolutePath()},e);
+        }
+    }
+
+    /**
+     * 鎶婁俊鎭啓鍏ord涓殑鍩熷瓧娈典腑锛屽煙瀛楁浼氫繚鐣欙紙浣嗘槸鐩墠鎵撳嵃浼氫緷鐒舵樉绀哄煙浠g爜)
+     * @param fileName 鏂囦欢鍚�
+     * @param dataMap 瑕佸啓鍏ョ殑鏁版嵁
+     * @throws FileNotFoundException 鏂囦欢涓嶅瓨鍦ㄦ椂鎶涘嚭寮傚父
+     * @throws VciBaseException 鍐欏叆鍑洪敊鐨勬椂鍊欐姏鍑烘寮傚父
+     */
+    public static void setFieldDataToWord(String fileName,Map<String,String> dataMap) throws FileNotFoundException, VciBaseException{
+        alertNotNull(fileName,"word鐨勬枃浠跺悕绉�");
+        setFieldDataToWord(new File(fileName), dataMap,true);
+    }
+
+    /**
+     * 鎶婁俊鎭啓鍏ord涓殑鍩熷瓧娈典腑,鍩熷瓧娈典細淇濈暀锛堜絾鏄洰鍓嶆墦鍗颁細渚濈劧鏄剧ず鍩熶唬鐮�)
+     * @param file 鏂囦欢
+     * @param dataMap 瑕佸啓鍏ョ殑鏁版嵁
+     * @throws FileNotFoundException 鏂囦欢涓嶅瓨鍦ㄦ椂鎶涘嚭寮傚父
+     * @throws VciBaseException 鍐欏叆鍑洪敊鐨勬椂鍊欐姏鍑烘寮傚父
+     */
+    public static void setFieldDataToWord(File file,Map<String,String> dataMap) throws FileNotFoundException, VciBaseException{
+        setFieldDataToWord(file, dataMap,true);
+    }
+
+    /**
+     * 鎶婁俊鎭啓鍏ord涓殑鍩熷瓧娈典腑,鍩熷瓧娈典細淇濈暀锛堜絾鏄洰鍓嶆墦鍗颁細渚濈劧鏄剧ず鍩熶唬鐮�)
+     * @param file 鏂囦欢
+     * @param dataMap 瑕佸啓鍏ョ殑鏁版嵁
+     * @param retainFieldCode true浼氫繚鐣欏煙瀛楁(浣嗘槸鐩墠鎵撳嵃浼氫緷鐒舵樉绀哄煙浠g爜),false涓嶄細淇濈暀鍩熷瓧娈碉紝鎵撳嵃鏃犻棶棰�
+     * @throws FileNotFoundException 鏂囦欢涓嶅瓨鍦ㄦ椂鎶涘嚭寮傚父
+     * @throws VciBaseException 鍐欏叆鍑洪敊鐨勬椂鍊欐姏鍑烘寮傚父
+     */
+    public static void setFieldDataToWord(File file,Map<String,String> dataMap,boolean retainFieldCode ) throws FileNotFoundException, VciBaseException{
+        alertNotNull(file,"word鏂囦欢");
+        if(!file.exists()){
+            throw new FileNotFoundException(file.getName());
+        }
+        InputStream in = null;
+        Document document = null;
+        try{
+            in = new FileInputStream(file);
+            document = new Document(in);
+        }catch (Exception e){
+            IOUtils.closeQuietly(in);
+            //涓嶈兘鍦╢inally閲屽叧闂紝鍥犱负鍚庨潰杩橀渶瑕佺敤
+            throw new VciBaseException("鍒濆鍖杦ord鏂囨。瀵硅薄鐨勬椂鍊欏嚭鐜颁簡閿欒,{0}",new String[]{file.getAbsolutePath()},e);
+        }
+        try {
+            if(retainFieldCode) {
+                mergeMapForField(document, dataMap);
+            }else{
+                mergeMapForFieldUnFormate(document, dataMap);
+            }
+        }catch (VciBaseException e){
+            throw e;
+        }catch (Throwable e){
+            throw new VciBaseException("鍚憌ord閲岀殑鍩熷瓧娈靛啓鍏ヤ俊鎭殑鏃跺�欏嚭閿�,{0}",new String[]{file.getAbsolutePath()},e);
+        }finally {
+            IOUtils.closeQuietly(in);
+        }
+        try{
+            document.save(file.getAbsolutePath());
+        }catch (Exception e) {
+            throw new VciBaseException("灏唚ord鐨勫唴瀹硅繑濉埌鏂囦欢涓嚭鐜颁簡閿欒,{0}",new String[]{file.getAbsolutePath()},e);
+        }
+    }
+
+    /**
+     * 寰�word鍐欏叆琛ㄦ牸鏁版嵁锛岃繖绉嶆槸浣跨敤startTable鐨勬柟寮忥紝涓嶄細鑷姩鎷疯礉鏍煎紡
+     * @param document word鏂囨。瀵硅薄
+     * @param tableDataBOList 瑕佸啓鍏ュ埌鏂囦欢鐨勪俊鎭�
+     * @throws FileNotFoundException 鏂囦欢涓嶅瓨鍦ㄧ殑鏃跺�欎細鎶涘嚭寮傚父
+     * @throws VciBaseException 鍐欏叆鏁版嵁鍑洪敊鏃朵細鎶涘嚭寮傚父
+     */
+    public static void setTableDataToWord(Document document, List<WordMergeStartTableDataBO> tableDataBOList) throws  VciBaseException{
+        alertNotNull(document,"word鏂囨。瀵硅薄");
+        if(!CollectionUtils.isEmpty(tableDataBOList)){
+            try {
+                mergeBeanListUnFormate(document,tableDataBOList);
+            } catch (Exception e) {
+                logger.error("鍚憌ord閲屽啓鍏ableStart绫诲瀷鐨勫煙瀛楁鐨勬椂鍊欏嚭閿�",e);
+                throw new VciBaseException("鍚憌ord閲屽啓鍏ableStart绫诲瀷鐨勫煙瀛楁鐨勬椂鍊欏嚭閿�,{0}" ,new String[]{e.getLocalizedMessage()},e);
+            }
+        }
+    }
+
+    /**
+     * 鍐欏叆琛ㄦ牸鏁版嵁锛屾柊鐨勬暟鎹鐨勬牸寮忎笉浼氳嚜鍔ㄧ户鎵�
+     * @param doc word鏂囨。
+     * @param wordSignMergeTableDataList 瑕佸啓鍏ョ殑鏁版嵁
+     * @throws Exception 鍐欏叆澶辫触鎴栬�呰〃鏍间笉瀛樺湪鐨勬椂鍊欎細鎶涘嚭寮傚父
+     */
+    public static  void mergeBeanListUnFormate(Document doc, List<WordMergeStartTableDataBO> wordSignMergeTableDataList) throws Exception {
+        if(!CollectionUtils.isEmpty(wordSignMergeTableDataList)) {
+            for (WordMergeStartTableDataBO tableData : wordSignMergeTableDataList) {
+                boolean needMergeColumn = false;
+                String tableName = tableData.getTableName();
+                Table thisTable = null;
+                boolean finedField = false;
+                int startRowIndex = -1;
+                Map<String,Integer> mergeColumnNameIndexMap = new HashMap<String, Integer>();
+                List<String> mergeColumnList = str2List(tableData.getMergeColumn());
+                if (StringUtils.isNotBlank(tableData.getMergeColumn()) && tableData.getTableDataList().size()> 1){
+                    needMergeColumn = true;
+                    //鎵惧埌鎵�鏈夌殑琛ㄦ牸涓殑鍗曞厓鏍硷紝鐪嬫槸鍚︽湁杩欎釜琛ㄦ牸鐨則ableStart鏍囪
+                    NodeCollection tableNodes = doc.getChildNodes(NodeType.TABLE, true);
+                    Iterator tableIt = tableNodes.iterator();
+                    while (tableIt.hasNext()) {
+                        Table table = (Table) tableIt.next();
+                        int rowCount = table.getRows().getCount();
+                        if (rowCount > 0) {
+                            //璇存槑杩欎釜琛ㄦ牸鏈夎
+                            RowCollection rowCollection = table.getRows();
+                            for (int i = 0; i < rowCount; i++) {
+                                Row row = rowCollection.get(i);
+                                CellCollection cellCollection = row.getCells();
+                                if (cellCollection != null) {
+                                    for (int z = 0; z < cellCollection.getCount(); z++) {
+                                        Cell cell = cellCollection.get(z);
+                                        NodeCollection mergeCollection = cell.getChildNodes(NodeType.FIELD_START, true);
+                                        Iterator fieldNodes = mergeCollection.iterator();
+                                        if (mergeCollection.getCount() > 0) {
+                                            while (fieldNodes.hasNext()) {
+                                                FieldStart fdStart = (FieldStart) fieldNodes.next();
+                                                if (fdStart.getFieldType() == FieldType.FIELD_MERGE_FIELD) {
+                                                    FieldMergeField fdMerge = (FieldMergeField) fdStart.getField();
+                                                    String fieldName = fdMerge.getFieldName();
+                                                    if (fieldName.equalsIgnoreCase("TableStart:" + tableName)) {
+                                                        thisTable = table;
+                                                        startRowIndex = i;
+                                                    }
+                                                    if(mergeColumnList.contains(fieldName)){
+                                                        mergeColumnNameIndexMap.put(fieldName,z);
+                                                    }
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                            if(thisTable != null){
+                                finedField = true;
+                                break;
+                            }
+                        }
+                        if(finedField){
+                            break;
+                        }
+                    }
+                }
+                WordMergeListDataSource dataSource = new WordMergeListDataSource(tableData.getTableDataList(),tableName);
+                doc.getMailMerge().executeWithRegions(dataSource);
+                //澶勭悊浜嗗畬鏁版嵁鍚庯紝鏈夊彲鑳介渶瑕佸皢琛屽悎骞跺崟鍏冩牸
+                if (needMergeColumn && thisTable != null && mergeColumnNameIndexMap.size() > 0) {
+                    List<Map<String, Object>> thisTableData = dataSource.getDataList();
+                    for (String mergeColumnName : mergeColumnList) {
+                        //鎵炬墍鏈夌殑鏁版嵁锛岃褰曠浉鍚岃鐨勬暟鎹�
+                        if(mergeColumnNameIndexMap.containsKey(mergeColumnName)) {
+                            int columnIndex = mergeColumnNameIndexMap.get(mergeColumnName) + 1;
+                            Map<Integer, Integer> mergeRowMap = new HashMap<Integer, Integer>();
+                            Object lastRowValue = "";
+                            int lastRowIndex = 0;
+                            for (int i = 0; i < thisTableData.size(); i++) {
+                                Map<String, Object> thisRowData = thisTableData.get(i);
+                                Object thisCellValue = thisRowData.get(mergeColumnName);
+                                if (thisCellValue == null) {
+                                    thisCellValue = "";
+                                }
+                                if (i == 0) {
+                                    lastRowValue = thisCellValue;
+                                    lastRowIndex = startRowIndex;
+                                    //绛変簬璧峰琛岋紝1
+                                } else if (i != thisTableData.size() - 1) {
+                                    if (!thisCellValue.toString().equalsIgnoreCase(lastRowValue.toString())) {
+                                        //璇存槑鍜屼笂涓�琛屼笉涓�鏍蜂簡
+                                        mergeRowMap.put(lastRowIndex, i+startRowIndex-1);
+                                        lastRowValue = thisCellValue;
+                                        lastRowIndex = startRowIndex + i;
+                                    }
+                                } else {
+                                    if (!thisCellValue.toString().equalsIgnoreCase(lastRowValue.toString())) {
+                                        //璇存槑鍜屼笂涓�琛屼笉涓�鏍蜂簡
+                                        mergeRowMap.put(lastRowIndex, i+startRowIndex-1);
+                                        lastRowValue = thisCellValue;
+                                        lastRowIndex = startRowIndex + i;
+                                        // mergeRowMap.put(startRowIndex +i, startRowIndex +i);
+                                    }else{
+                                        mergeRowMap.put(lastRowIndex, startRowIndex +i);
+                                        lastRowValue = thisCellValue;
+                                        lastRowIndex = startRowIndex + i;
+                                    }
+
+                                }
+                            }
+                            //鎵惧埌浜嗘墍鏈夌殑鐩稿悓鐨勫唴瀹癸紝鑲畾浼氭湁鍊�
+                            doMerge(thisTable,mergeRowMap,columnIndex);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * 鎵ц鍚堝苟鍗曞厓鏍�
+     * @param thisTable 琛ㄦ牸瀵硅薄
+     * @param mergeRowMap 瑕佸悎骞剁殑琛岋紝key鏄叾瀹炶锛寁alue鏄粨鏉熻锛屼粠0寮�濮�
+     * @param columnIndex 鍒楃殑闇�瑕侊紝浠�0寮�濮�
+     */
+    private static void doMerge(Table thisTable, Map<Integer, Integer> mergeRowMap, int columnIndex){
+        if (mergeRowMap.size() > 0) {
+            for (Integer startRowIndex : mergeRowMap.keySet()) {
+                Integer endRowIndex = mergeRowMap.get(startRowIndex);
+                for (int x = startRowIndex; x <= endRowIndex; x++) {
+                    //寮�濮嬬殑琛岃缃负FIRST,鍏朵粬鐨勮璁剧疆涓篜REVIOUS
+                    if (x == startRowIndex) {
+                        Cell cell = thisTable.getRows().get(x).getCells().get(columnIndex - 1);
+                        cell.getCellFormat().setVerticalMerge(CellMerge.FIRST);
+                    } else {
+                        Cell cell = thisTable.getRows().get(x).getCells().get(columnIndex - 1);
+                        cell.getCellFormat().setVerticalMerge(CellMerge.PREVIOUS);
+                    }
+                }
+            }
+        }
+    }
+
+
+
+    /**
+     * 璁剧疆鍩熷瓧娈电殑鍊硷紝杩欎釜鍩熷瓧娈典慨鏀瑰悗鍩熶唬鐮佽繕鍦紝涓嶈兘鍒囨崲鍩熶唬鐮侊紝鍚﹀垯鏁版嵁涓㈠け(娉ㄦ剰锛岀洰鍓嶅彂鐜版墦鍗扮殑鏃跺�欒繕鏄樉绀哄煙浠g爜)
+     * @param doc word鏂囨。
+     * @param dataMap 鏁版嵁鏄犲皠
+     * @throws VciBaseException 鍐欏叆澶辫触鏃朵細鎶涘嚭寮傚父
+     */
+    public static void mergeMapForField(Document doc, Map<String, String> dataMap) throws VciBaseException{
+        NodeCollection fieldStartNodes=doc.getChildNodes(NodeType.FIELD_START,true);
+        Iterator fieldNodes=fieldStartNodes.iterator();
+        while(fieldNodes.hasNext()) {
+            FieldStart fdStart = (FieldStart) fieldNodes.next();
+            if (fdStart.getFieldType() == FieldType.FIELD_MERGE_FIELD) {
+                FieldMergeField fdMerge = (FieldMergeField)fdStart.getField();
+                String fieldName = fdMerge.getFieldName();
+                if (dataMap.containsKey(fieldName)) {
+                    try {
+                        fdMerge.setResult(dataMap.get(fieldName));
+                    } catch (Exception e) {
+                        throw new VciBaseException("鍐欏煙瀛楁鐨勫唴瀹瑰嚭閿�,{0}",new String[]{fieldName});
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * 璁剧疆鍩熷瓧娈电殑鍊硷紝杩欎釜鍩熷瓧娈典慨鏀瑰悗鍩熶唬鐮佷笉浼氬啀瀛樺湪锛屼篃灏辨槸涓嶈兘鍐嶆浣跨敤
+     * @param doc word鏂囨。
+     * @param dataMap 鏁版嵁鏄犲皠
+     * @throws VciBaseException 鍐欏叆澶辫触鏃朵細鎶涘嚭寮傚父
+     */
+    public static void mergeMapForFieldUnFormate(Document doc, Map<String, String> dataMap) throws VciBaseException{
+        String[] fieldName = new String[dataMap.size()];
+        Object[] values = new Object[dataMap.size()];
+        int i = 0 ;
+        for(String field:dataMap.keySet()){
+            fieldName[i] = field;
+            values[i] = dataMap.get(field);
+            i++;
+        }
+
+        try {
+            doc.getMailMerge().execute(fieldName,values);
+        } catch (Exception e) {
+            throw new VciBaseException("鍐欏煙瀛楁鐨勫唴瀹瑰嚭閿�",new String[]{},e);
+        }
+    }
+
+
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-starter/pom.xml b/Source/plt-web/plt-web-parent/plt-starter/pom.xml
index 3449e87..a717384 100644
--- a/Source/plt-web/plt-web-parent/plt-starter/pom.xml
+++ b/Source/plt-web/plt-web-parent/plt-starter/pom.xml
@@ -136,20 +136,9 @@
             <version>${plt.version}</version>
         </dependency>
         <dependency>
-            <groupId>org.apache.commons</groupId>
-            <artifactId>commons-lang3</artifactId>
-            <version>3.1</version>
-        </dependency>
-        <!--鎿嶄綔xml闇�瑕�-->
-        <dependency>
             <groupId>dom4j</groupId>
             <artifactId>dom4j</artifactId>
             <version>1.6.1</version>
-        </dependency>
-        <dependency>
-            <groupId>com.alibaba</groupId>
-            <artifactId>fastjson</artifactId>
-            <version>1.2.83</version>
         </dependency>
         <dependency>
             <groupId>org.freemarker</groupId>
@@ -162,55 +151,10 @@
             <version>4.8</version>
         </dependency>
         <dependency>
-            <groupId>org.apache.logging.log4j</groupId>
-            <artifactId>log4j-api</artifactId>
-            <version>2.12.4</version>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.logging.log4j</groupId>
-            <artifactId>log4j-core</artifactId>
-            <version>2.12.4</version>
-        </dependency>
-        <dependency>
             <groupId>javax.mail</groupId>
             <artifactId>mail</artifactId>
             <version>1.4</version>
         </dependency>
-
-        <dependency>
-            <groupId>org.jbpm</groupId>
-            <artifactId>jbpm-core</artifactId>
-            <version>4.3.2</version>
-        </dependency>
-        <!--commons鐨勫嚑涓粍浠�-->
-        <dependency>
-            <groupId>commons-net</groupId>
-            <artifactId>commons-net</artifactId>
-            <version>1.4.1</version>
-        </dependency>
-        <dependency>
-            <groupId>commons-io</groupId>
-            <artifactId>commons-io</artifactId>
-            <version>2.5</version>
-        </dependency>
-        <dependency>
-            <groupId>commons-fileupload</groupId>
-            <artifactId>commons-fileupload</artifactId>
-            <version>1.3.1</version>
-        </dependency>
-        <!---zip鍘嬬缉 鏇挎崲antzip-->
-        <dependency>
-            <groupId>net.lingala.zip4j</groupId>
-            <artifactId>zip4j</artifactId>
-            <version>1.3.2</version>
-        </dependency>
-        <!--zip鍘嬬缉鎵�闇�瑕佺殑jar-->
-        <dependency>
-            <groupId>org.apache.commons</groupId>
-            <artifactId>commons-compress</artifactId>
-            <version>1.9</version>
-        </dependency>
-
 
     </dependencies>
 </project>
\ No newline at end of file
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/pom.xml b/Source/plt-web/plt-web-parent/plt-web-base/pom.xml
new file mode 100644
index 0000000..ae4b444
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/pom.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.vci</groupId>
+        <artifactId>plt-web-parent</artifactId>
+        <version>2024.1-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>plt-web-base</artifactId>
+
+    <properties>
+        <maven.compiler.source>8</maven.compiler.source>
+        <maven.compiler.target>8</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-thymeleaf</artifactId>
+            <version>${spring.version}</version>
+        </dependency>
+        <!--鍗曠嫭浣跨敤feign-->
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-openfeign</artifactId>
+            <version>${spring.version}</version>
+        </dependency>
+        <!--鐢变簬feign鑷甫鐨凥ttp瀹㈡埛绔疄鐜版槸HttpURLConnection,鎵�鏈夋崲鎴恛kHttp鐢ㄤ簬鏀寔杩炴帴姹� -->
+        <!-- https://mvnrepository.com/artifact/io.github.openfeign/feign-okhttp -->
+        <dependency>
+            <groupId>io.github.openfeign</groupId>
+            <artifactId>feign-okhttp</artifactId>
+            <version>10.2.3</version>
+        </dependency>
+        <dependency>
+            <groupId>org.freemarker</groupId>
+            <artifactId>freemarker</artifactId>
+            <version>2.3.23</version>
+        </dependency>
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>5.4.3</version>
+        </dependency>
+    </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/common/log/VciComponentLogAspect.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/common/log/VciComponentLogAspect.java
new file mode 100644
index 0000000..71f8cbb
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/common/log/VciComponentLogAspect.java
@@ -0,0 +1,212 @@
+package com.vci.starter.common.log;
+
+import com.vci.starter.web.annotation.log.VciUnLog;
+import com.vci.starter.common.log.autoconfigure.VciAutoLogConfigure;
+import com.vci.starter.web.enumpck.LogLevelEnum;
+import com.vci.starter.web.util.LangBaseUtil;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.*;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.DefaultParameterNameDiscoverer;
+import org.springframework.core.ParameterNameDiscoverer;
+import org.springframework.stereotype.Component;
+
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * 鏃ュ織璁板綍鍒囬潰
+ * @author weidy
+ * @date 2020/4/10
+ */
+@Aspect
+@Component
+public class VciComponentLogAspect {
+
+    /**
+     * 褰撳墠绫荤殑鏃ュ織杈撳嚭
+     */
+    private Logger logger = LoggerFactory.getLogger(getClass());
+
+    /**
+     * 鏃ュ織鐨勯厤缃�
+     */
+    @Autowired
+    private VciAutoLogConfigure logConfigure;
+
+    /**
+     * 鎵�鏈夌殑controller,component,service閮界洃鎺�
+     */
+    @Pointcut("execution(public * com.vci..*.*(..)) && (@target(org.springframework.web.bind.annotation.RestController) " +
+            "|| @target(org.springframework.stereotype.Controller) || @target(org.springframework.stereotype.Service)" +
+            "|| @target(org.springframework.stereotype.Component)) && !(@target(com.vci.starter.web.annotation.log.VciUnLog)) ")
+    public void vciComponentLog(){}
+
+    /**
+     * 鍦ㄥ垏鍏ョ偣鐨勬柟娉曟墽琛屼箣鍓嶏紝鑾峰彇鏂规硶鐨勫弬鏁�
+     * @param joinPoint 鍒囧叆鐐�
+     */
+    @Before("vciComponentLog()")
+    public void enterMethodLog(JoinPoint joinPoint){
+        Method method = getMethod(joinPoint);
+        try {
+            if (logConfigure.isShowLog() && !checkIsUnLog(method)) {
+                //璇存槑瑕佽褰曟棩蹇�
+                Logger beforeLogger = LoggerFactory.getLogger(joinPoint.getTarget().getClass());
+                //瑕佹妸鍙傛暟鎵撳嵃鍑烘潵
+                ParameterNameDiscoverer pnd = new DefaultParameterNameDiscoverer();
+                if (method != null) {
+                    String[] parameterNames = pnd.getParameterNames(method);
+                    Object[] args = joinPoint.getArgs();
+                    String logMsg = "璋冪敤浜�" + joinPoint.getSignature().getName() + "鏂规硶";
+                    if (parameterNames != null && parameterNames.length > 0) {
+                        logMsg += "锛屽弬鏁颁负绌�";
+                    } else {
+                        for (int i = 0; i < parameterNames.length; i++) {
+                            logMsg += parameterNames[i] + "=" + getParamString(args[i]) + ";";
+                        }
+                    }
+                    if (LogLevelEnum.INFO.name().equalsIgnoreCase(logConfigure.getVciLogLevel()) && beforeLogger.isInfoEnabled()) {
+                        beforeLogger.info(logMsg);
+                    }
+                    if (LogLevelEnum.DEBUG.name().equalsIgnoreCase(logConfigure.getVciLogLevel()) && beforeLogger.isDebugEnabled()) {
+                        beforeLogger.debug(logMsg);
+                    }
+                } else {
+                    if (logger.isInfoEnabled()) {
+                        logger.info(joinPoint.getTarget().getClass() + "." + joinPoint.getSignature().getName() + "杩欎釜鏂规硶娌℃湁鎵惧埌Method瀵硅薄锛屾澶勭▼搴忓彲鑳芥湁闂");
+                    }
+                }
+            }
+        }catch (Throwable e1){
+            //鏃ュ織閿欒浜嗕笉瑕佸奖鍝嶅埆鐨�
+        }
+    }
+
+    /**
+     * 鍦ㄦ姏鍑哄紓甯告椂璁板綍
+     * @param joinPoint 鍒囧叆鐐�
+     * @param e 寮傚父鐨勫彉閲�
+     */
+    @AfterThrowing(pointcut = "vciComponentLog()",throwing = "e")
+    public void exceptionMethodLog(JoinPoint joinPoint,Throwable e){
+        Method method = getMethod(joinPoint);
+        try {
+            if (logConfigure.isShowLog() && !checkIsUnLog(method)) {
+                //璇存槑瑕佽褰曟棩蹇�
+                Logger exceptionLogger = LoggerFactory.getLogger(joinPoint.getTarget().getClass());
+                //瑕佹妸寮傚父鎵撳嵃鍑烘潵
+                if (exceptionLogger.isErrorEnabled()) {
+                    exceptionLogger.error("璋冪敤浜�" + joinPoint.getSignature().getName() + "鏂规硶锛屽嚭鐜颁簡閿欒锛�" + LangBaseUtil.getErrorMsg(e), e);
+                }
+            }
+        }catch (Throwable e1){
+            //鏃ュ織閿欒浜嗕笉瑕佸奖鍝嶅埆鐨�
+        }
+    }
+
+    /**
+     * 鍦ㄨ皟鐢ㄦ垚鍔熷悗鏃惰褰�
+     * @param joinPoint 鍒囧叆鐐�
+     * @param returnVal 杩斿洖鍊�
+     */
+    @AfterReturning(pointcut = "vciComponentLog()",returning = "returnVal")
+    public void returnMethodLog(JoinPoint joinPoint,Object returnVal){
+        Method method = getMethod(joinPoint);
+        try {
+            if (logConfigure.isShowLog() && !checkIsUnLog(method)) {
+                //璇存槑瑕佽褰曟棩蹇�
+                Logger returnLogger = LoggerFactory.getLogger(joinPoint.getTarget().getClass());
+                //鎶婅繑鍥炵粨鏋滄墦鍗板嚭鏉�
+                String logMsg = "璋冪敤" + joinPoint.getSignature().getName() + "鏂规硶鎴愬姛," + getParamString(returnVal);
+                if (LogLevelEnum.INFO.name().equalsIgnoreCase(logConfigure.getVciLogLevel()) && returnLogger.isInfoEnabled()) {
+                    returnLogger.info(logMsg);
+                }
+                if (LogLevelEnum.DEBUG.name().equalsIgnoreCase(logConfigure.getVciLogLevel()) && returnLogger.isDebugEnabled()) {
+                    returnLogger.debug(logMsg);
+                }
+            }
+        }catch (Throwable e){
+            //鏃ュ織閿欒浜嗕笉瑕佸奖鍝嶅埆鐨�
+        }
+    }
+
+    /**
+     * 鑾峰彇琚皟鐢ㄧ殑鏂规硶
+     * @param joinPoint 鍒囧叆鐐�
+     * @return 璋冪敤鐨勬柟娉�
+     */
+    public Method getMethod(JoinPoint joinPoint){
+        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
+        Method method = signature.getMethod();
+        return method;
+    }
+
+    /**
+     * 鑾峰彇鍙傛暟鐨勫唴瀹瑰瓧绗︿覆
+     * @param obj 鍙傛暟瀵硅薄
+     * @return 鍙傛暟杞垚瀛楃涓�
+     */
+    public String getParamString(Object obj){
+        if(obj == null){
+            return "娌℃湁杩斿洖鍊�";
+        }else{
+            //鐪嬬湅鏄惁闆嗗悎
+            if(obj instanceof Collection){
+                final String[] paStr = {"["};
+                ((Collection)obj).stream().limit(10).forEach(s->{
+                    if(s!=null) {
+                        paStr[0] += s.toString() + ",";
+                    }else{
+                        paStr[0] += "null,";
+                    }
+                });
+                return paStr[0]  + "]";
+            }else if(obj instanceof Map){
+                final String[] paStr = {"{"};
+                ((Map)obj).forEach((k,v)->{
+                    if(v!=null) {
+                        paStr[0] += k + ":" + v.toString() + ",";
+                    }else{
+                        paStr[0] += k + ":null,";
+                    }
+                });
+                return paStr[0]  + "}";
+            }else if(obj.getClass().isArray()){
+                //璇存槑鏄暟缁�
+                final String[] paStr = {"["};
+                Arrays.stream(((Object[]) obj)).limit(10).forEach( s->{
+                    if(s instanceof String) {
+                        if (s != null ) {
+                            paStr[0] += s.toString() + ",";
+                        } else {
+                            paStr[0] += "null,";
+                        }
+                    }
+                });
+                return paStr[0]  + "]";
+            }else {
+                return obj.toString();
+            }
+        }
+    }
+
+    /**
+     * 鑾峰彇鏂规硶鏄惁璁板綍鏃ュ織
+     * @param method 琚皟鐢ㄧ殑鏂规硶
+     * @return true 琛ㄧず涓嶈褰曟棩蹇�
+     */
+    private boolean checkIsUnLog(Method method){
+        //濡傛灉鏁翠釜绫绘坊鍔犱簡vciUnLog娉ㄨВ鏃讹紝涓嶄細杩涘叆鍒拌繖涓柟娉曚腑
+        if(method != null && method.isAnnotationPresent(VciUnLog.class)){
+            return true;
+        }
+        return false;
+    }
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/common/log/autoconfigure/VciAutoLogConfigure.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/common/log/autoconfigure/VciAutoLogConfigure.java
new file mode 100644
index 0000000..d819a10
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/common/log/autoconfigure/VciAutoLogConfigure.java
@@ -0,0 +1,48 @@
+package com.vci.starter.common.log.autoconfigure;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * 鏃ュ織鑷姩璇诲彇鐨勯厤缃�
+ * @author weidy
+ * @date 2020/4/14
+ */
+@Configuration
+@ConfigurationProperties(prefix = "logging")
+public class VciAutoLogConfigure {
+
+    /**
+     * 鏄惁鑷姩璁板綍璋冪敤鏃ュ織
+     */
+    private boolean showLog = false;
+
+    /**
+     * 鑷姩璁板綍鐨勬棩蹇楃殑绾у埆锛屽彧鑳芥槸Info鎴栬�卍ebug
+     */
+    private String vciLogLevel = "info";
+
+    public boolean isShowLog() {
+        return showLog;
+    }
+
+    public void setShowLog(boolean showLog) {
+        this.showLog = showLog;
+    }
+
+    public String getVciLogLevel() {
+        return vciLogLevel;
+    }
+
+    public void setVciLogLevel(String vciLogLevel) {
+        this.vciLogLevel = vciLogLevel;
+    }
+
+    @Override
+    public String toString() {
+        return "VciAutoLogConfigure{" +
+                "showLog=" + showLog +
+                ", vciLogLevel='" + vciLogLevel + '\'' +
+                '}';
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/revision/bo/TreeWrapperOptions.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/revision/bo/TreeWrapperOptions.java
new file mode 100644
index 0000000..eefb733
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/revision/bo/TreeWrapperOptions.java
@@ -0,0 +1,194 @@
+package com.vci.starter.revision.bo;
+
+import com.vci.starter.web.pagemodel.TreeQueryObject;
+
+/**
+ * 杞崲涓烘爲鍨嬫暟鎹椂鐨勯厤缃俊鎭�
+ * @author weidy
+ * @date 2020/4/22
+ */
+public class TreeWrapperOptions implements java.io.Serializable{
+    /**
+     * 璇峰嬁淇敼杩欎釜鍊�
+     */
+    private static final long serialVersionUID = 3183500138266494574L;
+
+    /**
+     * 鏄剧ず鏂囨湰鎵�浣跨敤鐨勫睘鎬�
+     */
+    private String textFieldName = "name";
+
+    /**
+     * 澶氫釜鏄剧ず鏂囨湰鐨勫睘鎬ф椂鐨勫垎闅旂锛堟渶缁堟樉绀虹殑鍊肩殑鍒嗛殧绗︼級
+     */
+    private String textValueSep = " ";
+    /**
+     * 涓婄骇鏁版嵁鐨勫睘鎬у悕绉�
+     */
+    private String parentFieldName;
+
+    /**
+     * 涓婚敭鐨勫睘鎬у悕绉�
+     */
+    private String oidFieldName = "oid";
+
+    /**
+     * 澶氫釜鍊煎睘鎬ф椂鐨勫垎闅旂
+     */
+    private String oidValueSep = ",";
+
+    /**
+     * 鏄惁鏌ヨ鎵�鏈夌殑灞炴��
+     */
+    private boolean allAttributes = true;
+
+    /**
+     * 涓婄骇鐨勪富閿殑鍊�
+     */
+    private String parentOid;
+
+    /**
+     * 鏄惁澶氶��
+     */
+    private boolean multipleSelect = false;
+
+    /**
+     * 鏄惁鏄剧ず澶嶉�夋
+     */
+    private boolean showCheckBox = false;
+
+    /**
+     * 鏋勯�犲嚱鏁�
+     */
+    public TreeWrapperOptions(){
+    }
+
+    /**
+     * 甯哥敤鐨勬瀯閫犲嚱鏁帮紝鍙缃笂绾у睘鎬х殑鍚嶇О
+     * @param parentFieldName 涓婄骇灞炴�х殑鍚嶇О
+     */
+    public TreeWrapperOptions(String parentFieldName){
+        this.parentFieldName = parentFieldName;
+    }
+
+    /**
+     * 甯哥敤鐨勬瀯閫犲嚱鏁帮紝璁剧疆鏄剧ずtext鍜屼笂绾у睘鎬х殑鍚嶇О
+     * @param textFieldName 鏄剧ず鏂囨湰灞炴�х殑鍚嶇О
+     * @param parentFieldName 涓婄骇灞炴�х殑鍚嶇О
+     */
+    public TreeWrapperOptions(String textFieldName,String parentFieldName){
+        this.textFieldName = textFieldName;
+        this.parentFieldName = parentFieldName;
+    }
+
+    /**
+     * 甯哥敤鐨勬瀯閫犲嚱鏁帮紝璁剧疆鏄剧ずtext銆佷笂绾у睘鎬х殑鍚嶇О銆�
+     * @param textFieldName 鏄剧ず鏂囨湰灞炴�х殑鍚嶇О
+     * @param parentFieldName 涓婄骇灞炴�х殑鍚嶇О
+     * @param parentOid 涓婄骇涓婚敭
+     */
+    public TreeWrapperOptions(String textFieldName,String parentFieldName,String parentOid){
+        this.textFieldName = textFieldName;
+        this.parentFieldName = parentFieldName;
+        this.parentOid = parentOid;
+    }
+
+    /**
+     * 浠庢爲褰㈡煡璇㈠璞′笂鎷疯礉
+     * @param treeQueryObject 鏍戝舰鏌ヨ瀵硅薄
+     */
+    public void copyFromTreeQuery(TreeQueryObject treeQueryObject){
+        if(treeQueryObject != null){
+            this.parentOid = treeQueryObject.getParentOid();
+            this.multipleSelect = treeQueryObject.isMultipleSelect();
+            this.showCheckBox = treeQueryObject.isShowCheckBox();
+        }
+    }
+
+    public String getTextFieldName() {
+        return textFieldName;
+    }
+
+    public void setTextFieldName(String textFieldName) {
+        this.textFieldName = textFieldName;
+    }
+
+    public String getParentFieldName() {
+        return parentFieldName;
+    }
+
+    public void setParentFieldName(String parentFieldName) {
+        this.parentFieldName = parentFieldName;
+    }
+
+    public String getOidFieldName() {
+        return oidFieldName;
+    }
+
+    public void setOidFieldName(String oidFieldName) {
+        this.oidFieldName = oidFieldName;
+    }
+
+    public boolean isAllAttributes() {
+        return allAttributes;
+    }
+
+    public void setAllAttributes(boolean allAttributes) {
+        this.allAttributes = allAttributes;
+    }
+
+    public String getParentOid() {
+        return parentOid;
+    }
+
+    public void setParentOid(String parentOid) {
+        this.parentOid = parentOid;
+    }
+
+    public boolean isMultipleSelect() {
+        return multipleSelect;
+    }
+
+    public void setMultipleSelect(boolean multipleSelect) {
+        this.multipleSelect = multipleSelect;
+    }
+
+    public boolean isShowCheckBox() {
+        return showCheckBox;
+    }
+
+    public void setShowCheckBox(boolean showCheckBox) {
+        this.showCheckBox = showCheckBox;
+    }
+
+    public String getTextValueSep() {
+        return textValueSep;
+    }
+
+    public void setTextValueSep(String textValueSep) {
+        this.textValueSep = textValueSep;
+    }
+
+    public String getOidValueSep() {
+        return oidValueSep;
+    }
+
+    public void setOidValueSep(String oidValueSep) {
+        this.oidValueSep = oidValueSep;
+    }
+
+    @Override
+    public String toString() {
+        return "TreeWrapperOptions{" +
+                "textFieldName='" + textFieldName + '\'' +
+                ", textValueSep='" + textValueSep + '\'' +
+                ", parentFieldName='" + parentFieldName + '\'' +
+                ", oidFieldName='" + oidFieldName + '\'' +
+                ", oidValueSep='" + oidValueSep + '\'' +
+                ", allAttributes=" + allAttributes +
+                ", parentOid='" + parentOid + '\'' +
+                ", multipleSelect=" + multipleSelect +
+                ", showCheckBox=" + showCheckBox +
+                '}';
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/revision/model/ReleasedObjDO.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/revision/model/ReleasedObjDO.java
new file mode 100644
index 0000000..1a78458
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/revision/model/ReleasedObjDO.java
@@ -0,0 +1,76 @@
+package com.vci.starter.revision.model;
+
+/**
+ * 宸插彂甯冪殑鏁版嵁
+ * 浠呭湪鏈夌増鏈鐞嗙殑涓氬姟绫诲瀷鎵嶅瓨鍌�
+ * @author weidy
+ * @date 2020/3/17
+ */
+public class ReleasedObjDO implements java.io.Serializable{
+    /**
+     * 绂佹淇敼杩欎釜鍊�
+     */
+    private static final long serialVersionUID = -7258896338253286905L;
+
+    /**
+     * 涓婚敭
+     */
+    private String oid;
+
+    /**
+     * 鐗堟湰鐨勪富閿�
+     */
+    private String revisionOid;
+
+    /**
+     * 瀵硅薄鐨勪富閿�
+     */
+    private String nameOid;
+
+    /**
+     * 涓氬姟绫诲瀷
+     */
+    private String btmName;
+
+    public String getOid() {
+        return oid;
+    }
+
+    public void setOid(String oid) {
+        this.oid = oid;
+    }
+
+    public String getRevisionOid() {
+        return revisionOid;
+    }
+
+    public void setRevisionOid(String revisionOid) {
+        this.revisionOid = revisionOid;
+    }
+
+    public String getNameOid() {
+        return nameOid;
+    }
+
+    public void setNameOid(String nameOid) {
+        this.nameOid = nameOid;
+    }
+
+    public String getBtmName() {
+        return btmName;
+    }
+
+    public void setBtmName(String btmName) {
+        this.btmName = btmName;
+    }
+
+    @Override
+    public String toString() {
+        return "ReleasedObjDO{" +
+                "oid='" + oid + '\'' +
+                ", revisionOid='" + revisionOid + '\'' +
+                ", nameOid='" + nameOid + '\'' +
+                ", btmName='" + btmName + '\'' +
+                '}';
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/revision/model/RevisionInfo.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/revision/model/RevisionInfo.java
new file mode 100644
index 0000000..1c45474
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/revision/model/RevisionInfo.java
@@ -0,0 +1,221 @@
+package com.vci.starter.revision.model;
+
+/**
+ * 鐗堟湰鐨勪俊鎭�
+ * @author weidy
+ * @date 2020/4/15
+ */
+public class RevisionInfo implements java.io.Serializable {
+
+    /**
+     * 绂佹淇敼杩欎釜鍊�
+     */
+    private static final long serialVersionUID = 7167255550437885283L;
+
+    /**
+     * 涓婚敭锛屽鏋滆嚜宸辩殑瀵硅薄锛屼笉鏄痮id浣滀负涓婚敭鐨勮瘽锛岄渶瑕佺敤id杩欎釜娉ㄨВ
+     */
+    private String oid;
+
+    /**
+     * 瀵硅薄鐨勪富閿�
+     */
+    private String nameOid;
+
+    /**
+     * 鐗堟湰鐨勪富閿�
+     */
+    private String revisionOid;
+
+    /**
+     * 鏄惁鏈�鍚庣増娆�----鍦ㄩ噰鐢ㄤ簩绾х増鏈鐞嗘椂鎵嶆湁鐗堟锛屽彲浠ョ悊瑙d负灏忕増鏈�
+     */
+    private String lastR;
+
+
+    /**
+     * 鏄惁鏈�鍒濈増娆�
+     */
+    private String firstR;
+
+
+    /**
+     * 鏄惁鏈�鏂扮増鏈�
+     */
+    private String lastV;
+
+
+    /**
+     * 鏄惁鏈�鏃╃増鏈�
+     */
+    private String firstV;
+
+    /**
+     * 鐗堟湰瑙勫垯
+     */
+    private String revisionRule;
+
+
+    /**
+     * 鐗堟湰搴忓彿
+     */
+    private Integer revisionSeq;
+
+    /**
+     * 鐗堟湰鍊�
+     */
+    private String revisionValue;
+
+
+    /**
+     * 鐗堟瑙勫垯
+     */
+    private String versionRule;
+
+    /**
+     * 鐗堟鎺掑簭
+     */
+    private Integer versionSeq;
+
+    /**
+     * 鐗堟鍊�
+     */
+    private String versionValue;
+
+    /**
+     * 涓氬姟绫诲瀷鐨勫悕绉�
+     */
+    private String btmname;
+
+    public String getBtmname() {
+        return btmname;
+    }
+
+    public void setBtmname(String btmname) {
+        this.btmname = btmname;
+    }
+
+    public String getOid() {
+        return oid;
+    }
+
+    public void setOid(String oid) {
+        this.oid = oid;
+    }
+
+    public String getNameOid() {
+        return nameOid;
+    }
+
+    public void setNameOid(String nameOid) {
+        this.nameOid = nameOid;
+    }
+
+    public String getRevisionOid() {
+        return revisionOid;
+    }
+
+    public void setRevisionOid(String revisionOid) {
+        this.revisionOid = revisionOid;
+    }
+
+    public String getLastR() {
+        return lastR;
+    }
+
+    public void setLastR(String lastR) {
+        this.lastR = lastR;
+    }
+
+    public String getFirstR() {
+        return firstR;
+    }
+
+    public void setFirstR(String firstR) {
+        this.firstR = firstR;
+    }
+
+    public String getLastV() {
+        return lastV;
+    }
+
+    public void setLastV(String lastV) {
+        this.lastV = lastV;
+    }
+
+    public String getFirstV() {
+        return firstV;
+    }
+
+    public void setFirstV(String firstV) {
+        this.firstV = firstV;
+    }
+
+    public String getRevisionRule() {
+        return revisionRule;
+    }
+
+    public void setRevisionRule(String revisionRule) {
+        this.revisionRule = revisionRule;
+    }
+
+    public int getRevisionSeq() {
+        return revisionSeq;
+    }
+
+    public void setRevisionSeq(Integer revisionSeq) {
+        this.revisionSeq = revisionSeq;
+    }
+
+    public String getRevisionValue() {
+        return revisionValue;
+    }
+
+    public void setRevisionValue(String revisionValue) {
+        this.revisionValue = revisionValue;
+    }
+
+    public String getVersionRule() {
+        return versionRule;
+    }
+
+    public void setVersionRule(String versionRule) {
+        this.versionRule = versionRule;
+    }
+
+    public int getVersionSeq() {
+        return versionSeq;
+    }
+
+    public void setVersionSeq(Integer versionSeq) {
+        this.versionSeq = versionSeq;
+    }
+
+    public String getVersionValue() {
+        return versionValue;
+    }
+
+    public void setVersionValue(String versionValue) {
+        this.versionValue = versionValue;
+    }
+
+    @Override
+    public String toString() {
+        return "RevisionInfo{" +
+                "oid='" + oid + '\'' +
+                ", nameOid='" + nameOid + '\'' +
+                ", revisionOid='" + revisionOid + '\'' +
+                ", lastR='" + lastR + '\'' +
+                ", firstR='" + firstR + '\'' +
+                ", lastV='" + lastV + '\'' +
+                ", firstV='" + firstV + '\'' +
+                ", revisionRule='" + revisionRule + '\'' +
+                ", revisionSeq=" + revisionSeq +
+                ", revisionValue='" + revisionValue + '\'' +
+                ", versionRule='" + versionRule + '\'' +
+                ", versionSeq=" + versionSeq +
+                ", versionValue='" + versionValue + '\'' +
+                ", btmname='" + btmname + '\'' +
+                '}';
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/revision/provider/CommonAnnotationProvider.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/revision/provider/CommonAnnotationProvider.java
new file mode 100644
index 0000000..7c9f923
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/revision/provider/CommonAnnotationProvider.java
@@ -0,0 +1,25 @@
+package com.vci.starter.revision.provider;
+
+import com.vci.starter.web.pagemodel.BaseQueryObject;
+import com.vci.starter.web.pagemodel.BaseResult;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.PostMapping;
+
+import java.util.Map;
+
+/**
+ * 娉ㄩ噴鐨勮皟鐢ㄥ櫒
+ * @author weidy
+ * @date 2020/4/17
+ */
+@FeignClient(name="commonAnnotationProvider",url="${vciPlatform.objectServiceUrl}",path = "annotationController")
+public interface CommonAnnotationProvider {
+
+    /**
+     * 鎵归噺鑾峰彇绫讳笅闈㈢殑娉ㄩ噴
+     * @param queryObject 鏌ヨ鏉′欢锛屽叾涓鏋滄寚瀹氱被鐨勫悕绉版椂锛屼娇鐢╟lassname鍙傛暟锛屽�肩敤閫楀彿鍒嗛殧锛涘鏋滄寚瀹氬寘鍚嶆椂锛屼娇鐢╬ackagename鍙傛暟锛屽�肩敤閫楀彿鍒嗛殧
+     * @return 鍒ゆ柇success鍚庤幏鍙杁ata灞炴�э紝鍏朵腑灞炴�х殑鍐呭涓篗ap<绫诲叏璺緞,Map<灞炴�ц嫳鏂囧悕绉板皬鍐�,灞炴�т腑鏂囧悕绉�>>鏍煎紡
+     */
+    @PostMapping("/batchListFieldNameAnnotation")
+    BaseResult<Map<String,Map<String,String>>> batchListFieldNameAnnotation(BaseQueryObject queryObject);
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/revision/provider/CommonLifeCycleProvider.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/revision/provider/CommonLifeCycleProvider.java
new file mode 100644
index 0000000..243361e
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/revision/provider/CommonLifeCycleProvider.java
@@ -0,0 +1,32 @@
+package com.vci.starter.revision.provider;
+
+import com.vci.starter.web.pagemodel.BaseResult;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+/**
+ * 閫氱敤鐨勭敓鍛藉懆鏈熺殑璋冪敤
+ * @author weidy
+ * @date 2020/4/15
+ */
+@FeignClient(name="commonLifeCycleProvider",url="${vciPlatform.objectServiceUrl}",path = "lifeCycleController")
+public interface CommonLifeCycleProvider {
+
+    /**
+     * 鑾峰彇鐢熷懡鍛ㄦ湡鐨勮捣濮嬬姸鎬佺殑鍊�
+     * @param lifeCycleId 鐢熷懡鍛ㄦ湡鐨勮嫳鏂囧悕绉帮紝涓嶅尯鍒嗗ぇ灏忓啓
+     * @return 鍏堝垽鏂璼uccess锛岀劧鍚庡彇obj鐨勫��
+     */
+    @GetMapping("/getStartStatus")
+    BaseResult getStartStatus(@RequestParam("lifeCycleId")String lifeCycleId);
+
+    /**
+     * 鏌ヨ鐘舵�佺殑鏂囨湰
+     * @param lcStatus 鐘舵�佺殑鍊�
+     * @param btmTypeId 涓氬姟绫诲瀷鐨勭紪鍙�
+     * @return 鐘舵�佺殑鏄剧ず鏂囨湰
+     */
+    @GetMapping("/getStatusText")
+    BaseResult getStatusText(@RequestParam("lcStatus")String lcStatus,@RequestParam("btmTypeId")String btmTypeId);
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/revision/provider/CommonRevisionRuleProvider.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/revision/provider/CommonRevisionRuleProvider.java
new file mode 100644
index 0000000..396c739
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/revision/provider/CommonRevisionRuleProvider.java
@@ -0,0 +1,25 @@
+package com.vci.starter.revision.provider;
+
+import com.vci.starter.web.pagemodel.BaseResult;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+/**
+ * 鐗堟湰鐨勮皟鐢ㄥ櫒
+ * @author weidy
+ * @date 2020/4/15
+ */
+@FeignClient(name="commonRevisionRuleProvider",url="${vciPlatform.objectServiceUrl}",path = "revisionRuleController")
+public interface CommonRevisionRuleProvider {
+
+    /**
+     * 鏍规嵁瑙勫垯鑾峰彇涓嬩竴涓増鏈彿
+     * @param ruleId 鐗堟湰瑙勫垯鐨勮嫳鏂囧悕绉�
+     * @param currentRevisionValue 褰撳墠鐨勫��
+     * @return 鍏堝垽鏂璼uccess锛屽啀鍙杘bj灞炴��
+     */
+    @GetMapping("/getNextRevisionValue")
+    BaseResult getNextRevisionValue(@RequestParam("ruleId") String ruleId, @RequestParam("currentRevisionValue") String currentRevisionValue);
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/revision/service/RevisionModelUtil.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/revision/service/RevisionModelUtil.java
new file mode 100644
index 0000000..5c5dca8
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/revision/service/RevisionModelUtil.java
@@ -0,0 +1,1616 @@
+package com.vci.starter.revision.service;
+
+import com.sun.org.apache.xpath.internal.operations.Bool;
+import com.vci.starter.revision.bo.TreeWrapperOptions;
+import com.vci.starter.revision.model.*;
+import com.vci.starter.revision.provider.*;
+import com.vci.starter.web.annotation.Column;
+import com.vci.starter.web.annotation.VciBtmType;
+import com.vci.starter.web.annotation.VciColumnDefinition;
+import com.vci.starter.web.constant.RevisionConstant;
+import com.vci.starter.web.constant.RegExpConstant;
+import com.vci.starter.web.enumpck.DataSecretEnum;
+import com.vci.starter.web.enumpck.UserSecretEnum;
+import com.vci.starter.web.exception.VciBaseException;
+import com.vci.starter.web.model.BaseLinkModel;
+import com.vci.starter.web.model.BaseModel;
+import com.vci.starter.web.pagemodel.BaseResult;
+import com.vci.starter.web.pagemodel.PageHelper;
+import com.vci.starter.web.pagemodel.Tree;
+import com.vci.starter.web.pagemodel.TreeQueryObject;
+import com.vci.starter.web.service.VciSecretServiceI;
+import com.vci.starter.web.util.BeanUtil;
+import com.vci.starter.web.util.BeanUtilForVCI;
+import com.vci.starter.web.util.VciBaseUtil;
+import com.vci.starter.web.util.VciDateUtil;
+import com.vci.starter.web.wrapper.VciQueryWrapperForDO;
+import com.vci.starter.web.wrapper.VciQueryWrapperOption;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+import java.lang.reflect.Field;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Function;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+/**
+ * 鐗堟湰鍜屽璞℃ā鍨嬬殑宸ュ叿绫�
+ * @author weidy
+ * @date 2020/4/15
+ */
+@Component
+public class RevisionModelUtil implements VciSecretServiceI {
+
+    /**
+     * 鏃ュ織瀵硅薄
+     */
+    private Logger logger = LoggerFactory.getLogger(getClass());
+
+    /**
+     * 瀛樺偍瀵硅薄绫荤殑灞炴�х殑娉ㄩ噴
+     */
+    public volatile static Map<String, Map<String,String>> modelColumnAnnotationMap = new ConcurrentHashMap<>();
+
+    /**
+     * 瀹炰綋绫诲拰娉ㄨВ鐨勬槧灏勶紝鍦╯pringboot鐑姞杞界殑鏃跺�欎竴瀹氳娓呴櫎
+     */
+    public volatile static Map<String,VciBtmType> modelAnnotationMap = new ConcurrentHashMap<>();
+
+    /**
+     * 鍒ゆ柇骞傜瓑鎬э紝浣跨敤redis
+     */
+    public static boolean CHECK_IDEMPOTENCE = false;
+
+    /**
+     * 鐗堟湰鐨勬暟鎹搷浣滃眰
+     */
+    @Autowired(required = false)
+    private VciRevisionServiceI revisionMapper;
+
+    /**
+     * 鐗堟湰鐨勮皟鐢ㄥ櫒
+     */
+    @Autowired(required = false)
+    private CommonRevisionRuleProvider revisionRuleProvider;
+
+    /**
+     * 鐢熷懡鍛ㄦ湡鐨勮皟鐢ㄥ櫒
+     */
+    @Autowired(required = false)
+    private CommonLifeCycleProvider lifeCycleProvider;
+
+    /**
+     * 娉ㄩ噴鐨勮皟鐢ㄦ帴鍙�
+     */
+    @Autowired(required = false)
+    private CommonAnnotationProvider annotationProvider;
+
+    /**
+     * 鏄渶鏂扮増鏈殑鍊�
+     */
+    public static final String LAST_REV_VALUE = "1";
+
+    /**
+     * 涓嶆槸鏈�鏂扮増鏈殑鍊�
+     */
+    public static final String UN_LAST_REV_VALUE = "0";
+
+
+    /**
+     * 鍦ㄦ暟鎹柊澧炵殑鏃跺�欏皝瑁呭睘鎬э紙鍖呮嫭鍒涘缓鑰呭拰鐢熷懡鍛ㄦ湡绛夛級,骞朵笖鏍¢獙蹇呰緭椤癸紝鍞竴椤�(鍏朵腑鍞竴椤瑰浜庢椂闂存棤娉曞垽鏂級锛屽瘑绾�
+     * @param baseModel 鍩虹鏁版嵁瀵硅薄
+     */
+    public void wrapperForAdd(BaseModel baseModel){
+        wrapperForAddOrUpVersion(baseModel,false,false);
+    }
+
+    /**
+     * 鎵归噺娣诲姞鏁版嵁
+     * @param baseModelCollection 鏁版嵁瀵硅薄闆嗗悎
+     */
+    public  void wrapperForBatchAdd(Collection<? extends BaseModel> baseModelCollection ){
+        VciBaseUtil.alertCollectionNotNull("瑕佹柊澧炵殑鏁版嵁瀵硅薄",baseModelCollection);
+        BaseModel fristModel = baseModelCollection.iterator().next();
+        VciBtmType vciBtmType = getBtmTypeAnnotation(fristModel);
+        if(vciBtmType == null){
+            throw new VciBaseException("瀹炰綋瀵硅薄涓婃病鏈夋坊鍔燰ciBtmType娉ㄨВ");
+        }
+        //鏈塩olumn娉ㄨВ鐨勫睘鎬э紝鏈夎繖涓敞瑙f墠闇�瑕佹牎楠屽繀杈撻」鍜屽敮涓�椤�
+        List<Field> hasColumnAnnoFields =  filterHasColumnAnnoFields(VciBaseUtil.getAllFieldForObj(fristModel.getClass()));
+        //蹇呰緭椤�
+        List<Field> checkNullFields = filterCheckNullFields(hasColumnAnnoFields);
+        //鍞竴椤圭殑锛屽寘鍚笉鍖哄垎澶у皬鍐欏拰鍖哄垎澶у皬鍐欑殑
+        Map<Field/**瑕佹牎楠屽敮涓�椤圭殑灞炴��**/, Boolean/**鏄惁涓嶅尯鍒嗗ぇ灏忓啓**/> checkUniqueFieldsMap = filterCheckUniqueFieldsHasUnCase(fristModel.getClass());
+
+        //鍞竴鐨勫睘鎬х殑鍊�
+        Map<String/**灞炴�х殑鍚嶇О**/,Set<Object>> unqiueFieldValueMap = new HashMap<>();
+
+        String creator = VciBaseUtil.getCurrentUserId();
+        Date currentDate= new Date();
+        String btmName = vciBtmType.name();
+
+        //鑾峰彇榛樿鐨勭増鏈彿锛岀敓鍛藉懆鏈燂紝瀵嗙骇
+
+        wrapperFristRevision(fristModel);
+        wrapperLifeCycle(fristModel);
+        boolean manageRevision = isManageRevision(vciBtmType);
+        boolean manageLifeCycle = isManageLifeCycle(vciBtmType);
+        boolean checkSecret = isCheckSecret(vciBtmType);
+
+        //閬嶅巻锛屽疄闄呬篃鏄瘡涓�涓鐞嗕竴娆★紝鍙槸鐗堟湰鍜岀敓鍛藉懆鏈熺瓑涓嶉噸澶嶈幏鍙�
+        baseModelCollection.stream().forEach(s -> {
+            VciBaseUtil.alertNotNull(s,"瑕佹坊鍔犵殑鏁版嵁瀵硅薄");
+            setBaseFieldValue(s,creator,currentDate,btmName);
+            //鏍¢獙蹇呰緭椤�
+            checkFieldsRequired(checkNullFields,s);
+            //鍏堝垽鏂綋鍓嶉泦鍚堜腑鍞竴椤规槸鍚︽湁閲嶅
+            if(!CollectionUtils.isEmpty(checkUniqueFieldsMap)){
+                checkUniqueFieldsMap.forEach( (field,unCase) ->{
+                    checkUniqueValues(field,unCase,s,unqiueFieldValueMap,false);
+                });
+            }
+
+            //鍥犱负鏂板閮戒竴瀹氭槸绗竴涓増鏈拰鐗堟锛屾墍浠ュ鏋滄病鏈夎缃殑鏃跺�欙紝鍏ㄩ儴鐢ㄥ垵濮嬬増鏈彿
+            if(manageRevision){
+                if(StringUtils.isBlank(s.getNameOid())){
+                    s.setNameOid(VciBaseUtil.getPk());
+                }
+                if(StringUtils.isBlank(s.getRevisionOid())){
+                    s.setRevisionOid(VciBaseUtil.getPk());
+                }
+                s.setRevisionRule(fristModel.getRevisionRule());
+                s.setRevisionValue(fristModel.getRevisionValue());
+                s.setRevisionSeq(1);
+                s.setFirstR("1");
+                s.setLastR("1");
+                s.setVersionRule(fristModel.getVersionRule());
+                s.setVersionValue(fristModel.getVersionValue());
+                s.setVersionSeq(1);
+                s.setLastV("1");
+                s.setFirstV("1");
+            }
+            if(manageLifeCycle && StringUtils.isBlank(s.getLcStatus())){
+                s.setLcStatus(fristModel.getLcStatus());
+            }
+            if(checkSecret){
+                checkDataSecret(s);
+            }
+        });
+    }
+
+    /**
+     * 鍦ㄦ暟鎹慨鏀圭殑鏃跺�欏皝瑁呭睘鎬�
+     * @param baseModel 鍩虹鏁版嵁瀵硅薄
+     */
+    public void wrapperForEdit(BaseModel baseModel){
+        VciBaseUtil.alertNotNull(baseModel,"瑕佷慨鏀圭殑鏁版嵁瀵硅薄",baseModel.getOid(),"鏁版嵁鐨勪富閿�");
+        Date currentDate = new Date();
+        baseModel.setTs(currentDate);
+        baseModel.setLastModifier(VciBaseUtil.getCurrentUserId());
+        baseModel.setLastModifyTime(currentDate);
+        //
+        VciBtmType vciBtmType = getBtmTypeAnnotation(baseModel);
+        if(StringUtils.isBlank(baseModel.getBtmname()) && vciBtmType!=null){
+            baseModel.setBtmname(vciBtmType.name());
+        }
+        //鑾峰彇鍖呭惈浜哻olumn娉ㄨВ鐨勫睘鎬э紝鍥犱负涓嶅寘鍚繖涓敞瑙g殑鏃跺�欐槸榛樿nullable涓簍rue锛寀nique涓篺alse
+        List<Field> hasColumnAnnoFields = filterHasColumnAnnoFields(baseModel);
+        //鍒ゆ柇鏄惁鏈夌┖鐨勫睘鎬�
+        checkFieldsRequired(filterCheckNullFields(hasColumnAnnoFields),baseModel);
+        Map<Field,Boolean> checkUniqueFields = filterCheckUniqueFieldsHasUnCase(hasColumnAnnoFields);
+        if(!CollectionUtils.isEmpty(checkUniqueFields)){
+            checkUniqueFields.forEach((field,unCase) ->{
+                checkUniqueValues(field,unCase,baseModel,new HashMap<>(),true);
+            });
+        }
+        //鏍¢獙瀵嗙骇
+        checkDataSecret(baseModel);
+        //淇敼鐨勬椂鍊欑増鏈彿鍜岀敓鍛藉懆鏈熶笉搴旇鍙樺寲
+    }
+
+    /**
+     * 鎵归噺淇敼鏁版嵁瀵硅薄鏃跺皝瑁呭睘鎬э紝鍖呮嫭鍞竴椤癸紝蹇呰緭椤瑰拰鍩烘湰灞炴�ц缃�
+     * @param baseModelCollection 鏁版嵁瀵硅薄闆嗗悎
+     */
+    public void wrapperForBatchEdit(List<? extends BaseModel> baseModelCollection){
+        VciBaseUtil.alertCollectionNotNull("瑕佷慨鏀圭殑鏁版嵁瀵硅薄",baseModelCollection);
+        BaseModel fristModel = baseModelCollection.iterator().next();
+        VciBtmType vciBtmType = getBtmTypeAnnotation(fristModel);
+        if(vciBtmType == null){
+            throw new VciBaseException("瀹炰綋瀵硅薄涓婃病鏈夋坊鍔燰ciBtmType娉ㄨВ");
+        }
+        //鏈塩olumn娉ㄨВ鐨勫睘鎬э紝鏈夎繖涓敞瑙f墠闇�瑕佹牎楠屽繀杈撻」鍜屽敮涓�椤�
+        List<Field> hasColumnAnnoFields =  filterHasColumnAnnoFields(VciBaseUtil.getAllFieldForObj(fristModel.getClass()));
+        //蹇呰緭椤�
+        List<Field> checkNullFields = filterCheckNullFields(hasColumnAnnoFields);
+        //鍞竴椤圭殑锛屽寘鍚笉鍖哄垎澶у皬鍐欏拰鍖哄垎澶у皬鍐欑殑
+        Map<Field/**瑕佹牎楠屽敮涓�椤圭殑灞炴��**/, Boolean/**鏄惁涓嶅尯鍒嗗ぇ灏忓啓**/> checkUniqueFieldsMap = filterCheckUniqueFieldsHasUnCase(fristModel.getClass());
+
+        //鍞竴鐨勫睘鎬х殑鍊�
+        Map<String/**灞炴�х殑鍚嶇О**/,Set<Object>> unqiueFieldValueMap = new HashMap<>();
+
+        String creator = VciBaseUtil.getCurrentUserId();
+        Date currentDate= new Date();
+        String btmName = vciBtmType.name();
+
+        boolean checkSecret = isCheckSecret(vciBtmType);
+
+        //閬嶅巻锛屽疄闄呬篃鏄瘡涓�涓鐞嗕竴娆★紝鍙槸鐗堟湰鍜岀敓鍛藉懆鏈熺瓑涓嶉噸澶嶈幏鍙�
+        baseModelCollection.stream().forEach(s -> {
+            VciBaseUtil.alertNotNull(s,"瑕佹坊鍔犵殑鏁版嵁瀵硅薄");
+            setBaseFieldValueEdit(s,creator,currentDate);
+            //鏍¢獙蹇呰緭椤�
+            checkFieldsRequired(checkNullFields,s);
+            //鍏堝垽鏂綋鍓嶉泦鍚堜腑鍞竴椤规槸鍚︽湁閲嶅
+            if(!CollectionUtils.isEmpty(checkUniqueFieldsMap)){
+                checkUniqueFieldsMap.forEach( (field,unCase) ->{
+                    checkUniqueValues(field,unCase,s,unqiueFieldValueMap,true);
+                });
+            }
+            //淇敼鐨勬椂鍊欙紝鐗堟湰鍜岀敓鍛藉懆鏈熼兘涓嶈兘淇敼锛屽瘑绾ч渶瑕佷慨鏀癸紝鎵�浠ラ渶瑕佸啀娆℃牎楠�
+            if(checkSecret){
+                checkDataSecret(s);
+            }
+        });
+    }
+
+    /**
+     * 鍗囩増鏈彿
+     * @param baseModel 鏁版嵁瀵硅薄
+     */
+    public void wrapperForUpRevision(BaseModel baseModel){
+        wrapperForAddOrUpVersion(baseModel,true,false);
+    }
+
+    /**
+     * 鍗囩増娆�
+     * @param baseModel 鏁版嵁瀵硅薄
+     */
+    public void wrapperForUpVersion(BaseModel baseModel){
+        wrapperForAddOrUpVersion(baseModel,true,true);
+    }
+
+    /**
+     * 鍦ㄤ慨鏀圭殑鏃跺�欐嫹璐濓紝闃叉鍓嶇娌℃湁浼犻�掗粯璁ょ殑灞炴��
+     * @param dto 鏁版嵁浼犺緭瀵硅薄
+     * @param baseModel 鏁版嵁搴撲腑鐨勬暟鎹璞�
+     */
+    public void copyFromDTO(Object dto,BaseModel baseModel){
+        VciBaseUtil.alertNotNull(dto,"鏁版嵁浼犺緭瀵硅薄",baseModel,"鏁版嵁搴撲腑鐨勬暟鎹璞�");
+        //鍓嶇鍙兘涓嶄細鎶婇粯璁ょ殑鎵�鏈夊睘鎬т紶閫掕繃鏉ワ紝鎵�浠ュ厛浠庢暟鎹簱涓殑鏁版嵁瀵硅薄鎷疯礉鍒颁复鏃剁殑瀵硅薄涓�
+        BaseModel tempModel = new BaseModel();
+        BeanUtil.convert(baseModel,tempModel);
+        BeanUtil.convert(dto,baseModel);
+        //BeanUtil.convert(tempModel,baseModel);
+        //涓嶇煡閬撲负鍟ワ紝绐佺劧BeanUtil.convert(tempModel,baseModel);涓嶅ソ浣夸簡
+        BeanUtilForVCI.copyPropertiesIgnoreCase(tempModel,baseModel);
+        //涓轰簡闃叉鍓嶇娌℃湁浼犻�掗粯璁ょ殑灞炴�э紝鎵�浠ュ緱鍏堟嫹璐濆埌baseModel涓紝鐒跺悗dto鎷疯礉涓�娆″悗锛屽啀鎶婃暟鎹簱涓嫹璐濆洖鏉ャ��
+        //浣嗘槸鍥犱负id,name,description鏋佸ぇ姒傜巼鍓嶇浼氫紶閫掞紝鎵�浠ヨ繖閲屼篃璁剧疆涓�涓�
+        baseModel.setId(VciBaseUtil.getStringValueFromObject(VciBaseUtil.getValueFromField("id",dto)));
+        baseModel.setName(VciBaseUtil.getStringValueFromObject(VciBaseUtil.getValueFromField("name",dto)));
+        baseModel.setDescription(VciBaseUtil.getStringValueFromObject(VciBaseUtil.getValueFromField("description",dto)));
+        tempModel = null;
+    }
+
+    /**
+     * 浠嶥TO涓婃嫹璐濓紝蹇界暐灞炴�уぇ灏忓啓
+     * @param dto DTO瀵硅薄
+     * @param baseModel 鐩爣瀵硅薄
+     */
+    public void copyFromDTOIgnore(Object dto,BaseModel baseModel){
+        VciBaseUtil.alertNotNull(dto,"鏁版嵁浼犺緭瀵硅薄",baseModel,"鏁版嵁搴撲腑鐨勬暟鎹璞�");
+        //鍓嶇鍙兘涓嶄細鎶婇粯璁ょ殑鎵�鏈夊睘鎬т紶閫掕繃鏉ワ紝鎵�浠ュ厛浠庢暟鎹簱涓殑鏁版嵁瀵硅薄鎷疯礉鍒颁复鏃剁殑瀵硅薄涓�
+        BaseModel tempModel = new BaseModel();
+        BeanUtilForVCI.copyPropertiesIgnoreCase(baseModel,tempModel);
+        BeanUtilForVCI.copyPropertiesIgnoreCase(dto,baseModel);
+        BeanUtilForVCI.copyPropertiesIgnoreCase(tempModel,baseModel);
+        //涓轰簡闃叉鍓嶇娌℃湁浼犻�掗粯璁ょ殑灞炴�э紝鎵�浠ュ緱鍏堟嫹璐濆埌baseModel涓紝鐒跺悗dto鎷疯礉涓�娆″悗锛屽啀鎶婃暟鎹簱涓嫹璐濆洖鏉ャ��
+        //浣嗘槸鍥犱负id,name,description鏋佸ぇ姒傜巼鍓嶇浼氫紶閫掞紝鎵�浠ヨ繖閲屼篃璁剧疆涓�涓�
+        baseModel.setId(VciBaseUtil.getStringValueFromObject(VciBaseUtil.getValueFromField("id",dto)));
+        baseModel.setName(VciBaseUtil.getStringValueFromObject(VciBaseUtil.getValueFromField("name",dto)));
+        baseModel.setDescription(VciBaseUtil.getStringValueFromObject(VciBaseUtil.getValueFromField("description",dto)));
+        tempModel = null;
+    }
+
+    /**
+     * 鍦ㄦ暟鎹柊澧炵殑鏃跺�欎负閾炬帴绫诲瀷灏佽灞炴��
+     * @param linkModel 閾炬帴绫诲瀷鏁版嵁瀵硅薄
+     */
+    public void wrapperForAddLink(BaseLinkModel linkModel){
+        VciBaseUtil.alertNotNull(linkModel,"瑕佹柊澧炵殑閾炬帴绫诲瀷鏁版嵁瀵硅薄");
+        if(StringUtils.isBlank(linkModel.getOid())){
+            linkModel.setOid(VciBaseUtil.getPk());
+        }
+        linkModel.setCreator(VciBaseUtil.getCurrentUserId());
+        Date currentDate = new Date();
+        linkModel.setCreateTime(currentDate);
+        linkModel.setTs(currentDate);
+        linkModel.setLastModifier(linkModel.getCreator());
+        linkModel.setLastModifytime(currentDate);
+    }
+
+    /**
+     * 鍦ㄦ柊澧炴暟鎹殑鏃跺�欎负閾炬帴绫诲瀷灏佽灞炴��
+     * @param linkModel 閾炬帴绫诲瀷瀵硅薄
+     * @param fromModel from绔笟鍔℃暟鎹�
+     * @param toModel to绔笟鍔℃暟鎹�
+     */
+    public void wrapperForAddLink(BaseLinkModel linkModel,BaseModel fromModel,BaseModel toModel){
+        wrapperForAddLink(linkModel);
+        VciBaseUtil.alertNotNull(fromModel,"閾炬帴绫诲瀷from绔�",toModel,"閾炬帴绫诲瀷to绔�");
+        linkModel.setFoid(fromModel.getOid());
+        linkModel.setFbtmname(fromModel.getBtmname());
+        linkModel.setFnameoid(fromModel.getNameOid());
+
+        linkModel.setToid(toModel.getOid());
+        linkModel.setTbtmname(toModel.getBtmname());
+        linkModel.setTnameoid(toModel.getNameOid());
+        linkModel.setTrevisionoid(toModel.getRevisionOid());
+    }
+
+    /**
+     * 鍦ㄦ暟鎹慨鏀圭殑鏃跺�欎负閾炬帴绫诲瀷灏佽灞炴��
+     * @param linkModel 鍩虹鏁版嵁瀵硅薄
+     */
+    public void wrapperForEditLink(BaseLinkModel linkModel){
+        VciBaseUtil.alertNotNull(linkModel,"瑕佷慨鏀圭殑閾炬帴绫诲瀷鏁版嵁瀵硅薄");
+        Date currentDate = new Date();
+        linkModel.setTs(currentDate);
+        linkModel.setLastModifier(VciBaseUtil.getCurrentUserId());
+        linkModel.setLastModifytime(currentDate);
+    }
+
+    /**
+     * 鍒ゆ柇鏃堕棿鎴虫槸鍚︾浉鍚�
+     * @param dtoTs 鏁版嵁浼犺緭瀵硅薄涓婄殑ts
+     * @param doTs 鏁版嵁瀵硅薄涓婄殑ts
+     * @return true琛ㄧず鐩稿悓
+     */
+    public boolean checkTs(Date dtoTs,Date doTs){
+        if(dtoTs!=null && doTs!=null){
+            if(dtoTs.getTime() == doTs.getTime()){
+                return true;
+            }
+            String dtoTsString = VciDateUtil.date2Str(dtoTs,VciDateUtil.DateTimeMillFormat);
+            String doTsString = VciDateUtil.date2Str(doTs,VciDateUtil.DateTimeMillFormat);
+            if(dtoTsString.equalsIgnoreCase(doTsString)){
+                return true;
+            }else{
+                throw new VciBaseException("tsNotEqual");
+            }
+        }
+        return false;
+    }
+
+    /**
+     * 鍒ゆ柇瀵嗙骇鏄惁绗﹀悎瑕佹眰
+     * @param baseModel 鏁版嵁瀵硅薄
+     * @return true 琛ㄧず绗﹀悎瑕佹眰
+     * @throws VciBaseException 涓嶇鍚堣姹傛椂浼氭姏鍑哄紓甯�
+     */
+    public boolean checkDataSecret(BaseModel baseModel) throws VciBaseException{
+        VciBaseUtil.alertNotNull(baseModel,"瑕佹牎楠屽瘑绾х殑鏁版嵁瀵硅薄");
+        if(isCheckSecret(baseModel) && VciBaseUtil.getCurrentUserSecret()>0) {
+            if (baseModel.getSecretGrade() == null ) {
+                baseModel.setSecretGrade(DataSecretEnum.NONE.getValue());
+            }
+            Integer userSecret = VciBaseUtil.getCurrentUserSecret();
+            if (!checkUserSecret(baseModel.getSecretGrade())) {
+                throw new VciBaseException("褰撳墠鐢ㄦ埛鐨勫瘑绾т綆浜庢暟鎹殑瀵嗙骇锛岀敤鎴峰瘑绾т负" + UserSecretEnum.getSecretText(userSecret) + ",鏁版嵁瀵嗙骇涓�" + DataSecretEnum.getSecretText(baseModel.getSecretGrade()));
+            }
+        }
+        return true;
+    }
+
+    /**
+     * 鍙戝竷褰撳墠鐗堟湰
+     * @param baseModel 瑕佸彂甯冪殑鏁版嵁瀵硅薄
+     */
+    public void saveRelease(BaseModel baseModel){
+        VciBaseUtil.alertNotNull(baseModel,"鏁版嵁瀵硅薄");
+        VciBtmType btmType = getBtmTypeAnnotation(baseModel);
+        if(isManageRevision(btmType)) {
+            //蹇呴』绠$悊鐗堟湰鎵嶄細鎵ц鍙戝竷
+            VciBaseUtil.alertNotNull( baseModel.getOid(), "鏁版嵁瀵硅薄鐨勪富閿�", baseModel.getNameOid(), "瀵硅薄鐨勪富閿�",baseModel.getRevisionOid(),"鐗堟湰鐨勪富閿�");
+            ReleasedObjDO releasedObjDO = new ReleasedObjDO();
+            BeanUtil.convert(baseModel,releasedObjDO);
+            if(StringUtils.isBlank(releasedObjDO.getBtmName())){
+                releasedObjDO.setBtmName(btmType.name());
+            }
+            revisionMapper.saveReleased(releasedObjDO);
+        }
+    }
+
+    /**
+     * 鏁版嵁鏂板鐨勬椂鍊欏皝瑁呭睘鎬э紝鍙互鍗囩増鏈紝鍙互鍗囩増娆�
+     * @param baseModel 鏁版嵁瀵硅薄
+     * @param upRevsion 鍗囩増鍙�
+     * @param upVersion 鍗囩増娆�
+     */
+    private void wrapperForAddOrUpVersion(BaseModel baseModel,boolean upRevsion,boolean upVersion){
+        VciBaseUtil.alertNotNull(baseModel,"鏁版嵁瀵硅薄");
+        //灏佽鍩烘湰灞炴��
+        setBaseFieldValue(baseModel);
+        //鏍¢獙蹇呰緭椤瑰拰鍞竴椤�
+        List<Field> fields = VciBaseUtil.getAllFieldForObj(baseModel.getClass());
+        if(!CollectionUtils.isEmpty(fields)){
+            //鑾峰彇鍖呭惈浜哻olumn娉ㄨВ鐨勫睘鎬э紝鍥犱负涓嶅寘鍚殑榛樿nullable涓簍rue锛寀nique涓篺alse
+            List<Field> hasColumnAnnoFields = fields.stream().filter(s->s.isAnnotationPresent(Column.class)).distinct().collect(Collectors.toList());
+            if(!CollectionUtils.isEmpty(hasColumnAnnoFields)){
+                //鍒嗙鍑洪渶瑕佸垽鏂槸鍚︿负绌虹殑瀛楁
+                List<Field> notNullFields = filterCheckNullFields(hasColumnAnnoFields);
+                //鍒ゆ柇鏄惁鏈夌┖鐨勫睘鎬�
+                checkFieldsRequired(notNullFields,baseModel);
+                Map<Field,Boolean> checkUniqueFields = filterCheckUniqueFieldsHasUnCase(hasColumnAnnoFields);
+                if(!CollectionUtils.isEmpty(checkUniqueFields)){
+                    checkUniqueFields.forEach((field,unCase) ->{
+                        checkUniqueValues(field,unCase,baseModel,new HashMap<>(),false);
+                    });
+                }
+            }
+        }
+        //鏍¢獙瀵嗙骇
+        checkDataSecret(baseModel);
+        //澶勭悊鐢熷懡鍛ㄦ湡
+        wrapperLifeCycle(baseModel);
+        //濡傛灉鎺у埗鐗堟湰锛屼細鍒涘缓绗竴涓増鏈�
+        if(isManageRevision(baseModel)) {
+            if(!upVersion) {
+                if (StringUtils.isBlank(baseModel.getCopyFromVersion()) && !upRevsion) {
+                    //璇存槑鏄柊澧�
+                    wrapperFristRevision(baseModel);
+                } else {
+                    //璇存槑鏄崌鐗堝彿
+                    wrapperRevisionModel(baseModel);
+                }
+            }else {
+                wrapperVersionModel(baseModel);
+            }
+        }
+    }
+
+    /**
+     *澶勭悊鍩烘湰灞炴��
+     * @param baseModel 鏁版嵁瀵硅薄
+     */
+    public void setBaseFieldValue(BaseModel baseModel){
+        VciBaseUtil.alertNotNull(baseModel,"鏁版嵁瀵硅薄");
+        setBaseFieldValue(baseModel,null,null,null);
+    }
+
+    /**
+     * 澶勭悊鍩烘湰灞炴��
+     * @param currentUserId 褰撳墠鐢ㄦ埛
+     * @param currentDate 褰撳墠鏃堕棿
+     * @param btmName 涓氬姟绫诲瀷鍚嶇О
+     * @param baseModel 鏁版嵁瀵硅薄
+     */
+    public void setBaseFieldValue(BaseModel baseModel,String currentUserId,Date currentDate,String btmName){
+        if(StringUtils.isBlank(currentUserId)){
+            currentUserId = VciBaseUtil.getCurrentUserId();
+        }
+        if(currentDate == null){
+            currentDate = new Date();
+        }
+        if(StringUtils.isBlank(btmName)){
+            btmName = VciBaseUtil.getBtmTypeNameFromDO(baseModel.getClass());
+        }
+        //澶勭悊鍩烘湰灞炴��
+        if(StringUtils.isBlank(baseModel.getOid())){
+            baseModel.setOid(VciBaseUtil.getPk());
+        }
+        if(StringUtils.isBlank(baseModel.getCreator())) {
+            baseModel.setCreator(currentUserId);
+        }
+        baseModel.setCreateTime(currentDate);
+        baseModel.setTs(currentDate);
+        if(StringUtils.isBlank(baseModel.getLastModifier())) {
+            baseModel.setLastModifier(currentUserId);
+        }
+        baseModel.setLastModifyTime(currentDate);
+        if(StringUtils.isBlank(baseModel.getOwner())) {
+            baseModel.setOwner(baseModel.getCreator());
+        }
+        baseModel.setBtmname(btmName);
+    }
+
+    /**
+     * 缂栬緫鐨勬椂鍊欏鐞嗗熀鏈睘鎬�
+     * @param baseModel 鏁版嵁瀵硅薄
+     * @param currentUserId 褰撳墠鐢ㄦ埛
+     * @param currentDate 褰撳墠鏃堕棿
+     */
+    public void setBaseFieldValueEdit(BaseModel baseModel,String currentUserId,Date currentDate){
+        if(StringUtils.isBlank(currentUserId)){
+            currentUserId = VciBaseUtil.getCurrentUserId();
+        }
+        if(currentDate == null){
+            currentDate = new Date();
+        }
+        baseModel.setTs(currentDate);
+        baseModel.setLastModifier(currentUserId);
+        baseModel.setLastModifyTime(currentDate);
+    }
+
+
+
+    /**
+     * 鎵归噺鎵ц鐨勬椂鍊�,鏍¢獙鍞竴椤�
+     * @param field 灞炴��
+     * @param unCase 鏄惁涓嶅尯鍒嗗ぇ灏忓啓
+     * @param baseModel 鏁版嵁瀵硅薄
+     * @param unqiueFieldValueMap 瀛樺湪鐨勬暟鎹泦鍚�
+     * @param edit 鏄惁涓轰慨鏀�
+     */
+    private void checkUniqueValues(Field field,Boolean unCase,BaseModel baseModel, Map<String/**灞炴�х殑鍚嶇О**/,Set<Object>> unqiueFieldValueMap ,boolean edit){
+        field.setAccessible(true);
+        String fieldName = field.getName();
+        Set<Object> fieldValueList ;
+        if(unqiueFieldValueMap.containsKey(fieldName)){
+            fieldValueList = unqiueFieldValueMap.get(fieldName);
+        }else{
+            fieldValueList = new HashSet<>();
+        }
+        Object fieldValue = null;
+        try {
+            fieldValue = field.get(baseModel);
+        } catch (IllegalAccessException e) {
+            if(logger.isDebugEnabled()){
+                logger.debug("鑾峰彇灞炴�х殑鍊煎嚭鐜颁簡閿欒锛寋}",fieldName);
+            }
+        }
+        if(fieldValue!=null){
+            if(unCase !=null && unCase){
+                fieldValue = fieldValue.toString().toLowerCase();
+            }
+            if(fieldValueList.contains(fieldValue) || (unCase?checkFieldNotUniqueUnCase(field,baseModel,edit):checkFieldNotUnique(field,baseModel,edit))){
+                throw new VciBaseException("dataRepeat",new String[]{getColumnChineseText(field),fieldValue.toString()});
+            }else{
+                fieldValueList.add(fieldValue);
+            }
+        }
+        unqiueFieldValueMap.put(fieldName,fieldValueList);
+    }
+
+
+
+
+
+    /**
+     * 灏佽鏂扮殑鐗堟湰淇℃伅锛屼細鑷姩澶勭悊鑰佺殑鐗堟湰鍜屾渶鏂扮増鏈殑闂
+     * @param newModel 鏂扮増鏈殑鏁版嵁瀵硅薄
+     * @throws VciBaseException 鍙傛暟閿欒锛屾棤娉ㄨВ锛屾湇鍔¢厤缃笉姝g‘鐨勬椂鍊欎細鎶涘嚭寮傚父
+     */
+    public void wrapperRevisionModel(BaseModel newModel) throws VciBaseException{
+        setBtmName(newModel);
+        VciBaseUtil.alertNotNull(newModel.getCopyFromVersion(),"寮曠敤鑰佺増鏈殑涓婚敭");
+        if (revisionMapper != null) {
+            RevisionInfo oldRevision = revisionMapper.selectByOid(newModel.getCopyFromVersion(),VciBaseUtil.getTableName(newModel.getBtmname()));
+            if(oldRevision == null || StringUtils.isBlank(oldRevision.getOid()) ){
+                throw new VciBaseException("鑰佺増鏈湪鏁版嵁搴撲腑涓嶅瓨鍦�");
+            }
+            BaseModel oldModel = new BaseModel();
+            BeanUtil.convert(oldRevision,oldModel);
+            wrapperRevisionModel(oldModel,newModel);
+        }else{
+            throw new VciBaseException("娌℃湁鍒濆鍖栫増鏈鍒欑殑鏁版嵁鎿嶄綔灞�,璇峰紑鍙戜汉鍛樻鏌aven鏄惁寮曠敤");
+        }
+    }
+
+    /**
+     * 灏佽鏂扮殑鐗堟淇℃伅锛屼細鑷姩澶勭悊鑰佺殑鐗堟鍜屾渶鏂扮増娆¢棶棰�
+     * @param newModel 鏂扮増娆$殑鏁版嵁瀵硅薄
+     * @throws VciBaseException 鍙傛暟閿欒锛岀己灏戞敞瑙o紝閰嶇疆閿欒閮戒細鎶涘嚭杩欎釜寮傚父
+     */
+    public void wrapperVersionModel(BaseModel newModel) throws VciBaseException{
+        VciBaseUtil.alertNotNull(newModel,"鏂扮増娆$殑鏁版嵁瀵硅薄",newModel.getCopyFromVersion(),"寮曠敤鑰佺増娆$殑涓婚敭");
+        if (revisionMapper != null) {
+            RevisionInfo oldRevision = revisionMapper.selectByOid(newModel.getCopyFromVersion(),VciBaseUtil.getTableName(newModel.getBtmname()));
+            if(oldRevision == null || StringUtils.isBlank(oldRevision.getOid()) ){
+                throw new VciBaseException("鑰佺増娆℃暟鎹湪鏁版嵁搴撲腑涓嶅瓨鍦�");
+            }
+            BaseModel oldModel = new BaseModel();
+            BeanUtil.convert(oldRevision,oldModel);
+            wrapperVersionModel(oldModel,newModel);
+        }else{
+            throw new VciBaseException("娌℃湁鍒濆鍖栫増鏈鍒欑殑鏁版嵁鎿嶄綔灞�,璇峰紑鍙戜汉鍛樻鏌aven鏄惁寮曠敤");
+        }
+    }
+
+
+
+    /**
+     * 鑾峰彇鏁版嵁瀵硅薄涓墍鏈夊寘鍚簡column鍒楃殑灞炴��
+     * @param baseModel 鏁版嵁瀵硅薄
+     * @return 娌℃湁鏃朵細杩斿洖Null
+     */
+    public List<Field> filterHasColumnAnnoFields(BaseModel baseModel){
+        List<Field> fields = VciBaseUtil.getAllFieldForObj(baseModel.getClass());
+        return filterHasColumnAnnoFields(fields);
+    }
+
+    /**
+     * 杩囨护鍖呭惈浜哻olumn鐨勫睘鎬�
+     * @param fields 鎵�鏈夌殑灞炴��
+     * @return 绗﹀悎鏉′欢鐨勫睘鎬э紝涓嶅瓨鍦ㄧ殑鏃跺�欎細杩斿洖null
+     */
+    public List<Field> filterHasColumnAnnoFields( List<Field> fields){
+        if(!CollectionUtils.isEmpty(fields)) {
+            return  fields.stream().filter(s -> s.isAnnotationPresent(Column.class)).distinct().collect(Collectors.toList());
+        }else{
+            return null;
+        }
+    }
+
+    /**
+     * 杩囨护闇�瑕佹牎楠屾槸鍚﹁緭鍏ョ殑灞炴��
+     * @param fields 鍖呭惈鏈塩olumn娉ㄨВ鐨勫睘鎬�
+     * @return 绗﹀悎鏉′欢鐨勫睘鎬э紝涓嶅瓨鍦ㄧ殑鏃跺�欎細杩斿洖null
+     */
+    public List<Field> filterCheckNullFields(List<Field> fields){
+        if(!CollectionUtils.isEmpty(fields)){
+            return  fields.stream().filter(s -> {
+                Column column = getColumnAnnotation(s);
+                //鎸囧畾浜嗕笉鑳戒负绌猴紝鎴栬�呴渶瑕佹牎楠屽敮涓�鐨勪竴瀹氫笉鑳戒负绌�
+                return ((column != null && column.nullable()) == false) || ((column != null && column.unique()) == true);
+            }).collect(Collectors.toList());
+        }
+        return null;
+    }
+
+    /**
+     * 鑾峰彇鏍¢獙鍞竴椤癸紝鍖呭惈 鍖哄垎澶у皬鍐欏敮涓�椤圭殑灞炴��
+     * @param doClass 鏁版嵁瀵硅薄鎵�灞炵殑绫�
+     * @return 灞炴�ф槧灏勶紝key鏄睘鎬у璞★紝value鐨勫�间负true琛ㄧず涓嶅尯鍒嗗ぇ灏忓啓鐨勬柟寮忔牎楠屽敮涓�椤�
+     */
+    public Map<Field/**瑕佹牎楠屽敮涓�椤圭殑灞炴��**/, Boolean/**鏄惁涓嶅尯鍒嗗ぇ灏忓啓**/> filterCheckUniqueFieldsHasUnCase(Class<?> doClass){
+        List<Field> hasColumnAnnoFields =  filterHasColumnAnnoFields(VciBaseUtil.getAllFieldForObj(doClass));
+        return filterCheckUniqueFieldsHasUnCase(hasColumnAnnoFields);
+    }
+
+    /**
+     * 鑾峰彇鏍¢獙鍞竴椤癸紝鍖呭惈 鍖哄垎澶у皬鍐欏敮涓�椤圭殑灞炴��
+     * @param hasColumnAnnoFields 鏁版嵁瀵硅薄鎵�灞炵殑绫�
+     * @return 灞炴�ф槧灏勶紝key鏄睘鎬у璞★紝value鐨勫�间负true琛ㄧず涓嶅尯鍒嗗ぇ灏忓啓鐨勬柟寮忔牎楠屽敮涓�椤�
+     */
+    public Map<Field/**瑕佹牎楠屽敮涓�椤圭殑灞炴��**/, Boolean/**鏄惁涓嶅尯鍒嗗ぇ灏忓啓**/> filterCheckUniqueFieldsHasUnCase(List<Field> hasColumnAnnoFields){
+
+        //鍞竴椤圭殑锛屽寘鍚笉鍖哄垎澶у皬鍐欏拰鍖哄垎澶у皬鍐欑殑
+        Map<Field/**瑕佹牎楠屽敮涓�椤圭殑灞炴��**/, Boolean/**鏄惁涓嶅尯鍒嗗ぇ灏忓啓**/> checkUniqueFieldsMap = new HashMap<>();
+        List<Field> checkUniqueFields = filterCheckUniqueFields(hasColumnAnnoFields);
+        if(!CollectionUtils.isEmpty(checkUniqueFields)){
+            checkUniqueFields.stream().forEach(s -> {
+                checkUniqueFieldsMap.put(s,false);
+            });
+        }
+        List<Field> checkUniqueUnCaseFields = filterCheckUniqueUnCaseFields(hasColumnAnnoFields);
+        if(!CollectionUtils.isEmpty(checkUniqueUnCaseFields)){
+            checkUniqueUnCaseFields.stream().forEach(s -> {
+                //杩欎釜鏄笉鍖哄垎澶у皬鍐�
+                checkUniqueFieldsMap.put(s,true);
+            });
+        }
+        return checkUniqueFieldsMap;
+    }
+
+    /**
+     * 鑾峰彇闇�瑕佹牎楠屽敮涓�鐨勫睘鎬�
+     * @param fields 鍖呭惈鏈塩olumn娉ㄨВ鐨勫睘鎬�
+     * @return 绗﹀悎鏉′欢鐨勫睘鎬э紝涓嶅瓨鍦ㄧ殑鏃跺�欎細杩斿洖null
+     */
+    public List<Field> filterCheckUniqueFields(List<Field> fields){
+        if(!CollectionUtils.isEmpty(fields)){
+            return fields.stream().filter(s -> {
+                Column column = getColumnAnnotation(s);
+                return (column != null && column.unique()) == true;
+            }).collect(Collectors.toList());
+        }
+        return null;
+    }
+
+    /**
+     * 鑾峰彇闇�瑕佹牎楠屽敮涓�鐨勫睘鎬�
+     * @param fields 鍖呭惈鏈塩olumn娉ㄨВ鐨勫睘鎬�
+     * @return 绗﹀悎鏉′欢鐨勫睘鎬э紝涓嶅瓨鍦ㄧ殑鏃跺�欎細杩斿洖null
+     */
+    public List<Field> filterCheckUniqueUnCaseFields(List<Field> fields){
+        if(!CollectionUtils.isEmpty(fields)){
+            return fields.stream().filter(s -> {
+                Column column = getColumnAnnotation(s);
+                return (column != null && column.unique() && column.unUniqueCase()) == true;
+            }).collect(Collectors.toList());
+        }
+        return null;
+    }
+
+    /**
+     * 鏍¢獙灞炴�х殑鍊兼槸鍚﹀敮涓�
+     * @param uniqueFields  闇�瑕佹牎楠屽敮涓�鐨勫睘鎬у��
+     * @param baseModel 鏁版嵁瀵硅薄
+     * @param editFlag 鏄惁涓轰慨鏀规暟鎹紝淇敼鐨勬椂鍊欓渶瑕佹帓闄ゅ綋鍓嶆暟鎹�
+     */
+    public void checkFieldsUnique(List<Field> uniqueFields, BaseModel baseModel, boolean editFlag) {
+        if(!CollectionUtils.isEmpty(uniqueFields)){
+            List<Field> notUniqueFields = uniqueFields.stream().filter( s -> checkFieldNotUnique(s,baseModel,editFlag)).collect(Collectors.toList());
+            if(!CollectionUtils.isEmpty(notUniqueFields)){
+                //鎵惧搴旂殑涓枃鍚嶇О
+                List<String> notUniqueFieldChineseNames = new ArrayList<>();
+                notUniqueFields.stream().forEach( s -> {
+                    //鍏堜粠娉ㄩ噴涓笂鑾峰彇锛屼絾鏄�曠殑鏄箣鍓嶆病鏈夋敞閲婏紝鎵�浠ュ彲鑳藉緱浠庢敞瑙d笂鑾峰彇
+                    notUniqueFieldChineseNames.add(getColumnChineseText(s));
+                });
+                //鎸夌悊璇磋繖涓敊璇俊鎭笉搴旇鍑虹幇鐨勶紝鎵�浠ヤ笉鍋氬璇�
+                throw new VciBaseException("灞炴�" + notUniqueFieldChineseNames.stream().collect(Collectors.joining(",")) + "]瀵瑰簲鐨勬暟鎹湪绯荤粺涓凡缁忓瓨鍦�",notUniqueFieldChineseNames.toArray());
+            }
+        }
+    }
+
+    /**
+     * 鏍¢獙灞炴�х殑鍊兼槸鍚﹀敮涓�,涓嶅尯鍒嗗睘鎬у�肩殑澶у皬鍐�
+     * @param uniqueFields  闇�瑕佹牎楠屽敮涓�鐨勫睘鎬у��
+     * @param baseModel 鏁版嵁瀵硅薄
+     * @param editFlag 鏄惁涓轰慨鏀规暟鎹紝淇敼鐨勬椂鍊欓渶瑕佹帓闄ゅ綋鍓嶆暟鎹�
+     */
+    public void checkFieldsUnUniqueCase(List<Field> uniqueFields, BaseModel baseModel, boolean editFlag){
+        if(!CollectionUtils.isEmpty(uniqueFields)){
+            List<Field> notUniqueFields = uniqueFields.stream().filter( s -> checkFieldNotUniqueUnCase(s,baseModel,editFlag)).collect(Collectors.toList());
+            if(!CollectionUtils.isEmpty(notUniqueFields)){
+                //鎵惧搴旂殑涓枃鍚嶇О
+                List<String> notUniqueFieldChineseNames = new ArrayList<>();
+                notUniqueFields.stream().forEach( s -> {
+                    //鍏堜粠娉ㄩ噴涓笂鑾峰彇锛屼絾鏄�曠殑鏄箣鍓嶆病鏈夋敞閲婏紝鎵�浠ュ彲鑳藉緱浠庢敞瑙d笂鑾峰彇
+                    notUniqueFieldChineseNames.add(getColumnChineseText(s));
+                });
+                //鎸夌悊璇磋繖涓敊璇俊鎭笉搴旇鍑虹幇鐨勶紝鎵�浠ヤ笉鍋氬璇�
+                throw new VciBaseException("灞炴�" + notUniqueFieldChineseNames.stream().collect(Collectors.joining(",")) + "]瀵瑰簲鐨勬暟鎹湪绯荤粺涓凡缁忓瓨鍦�",notUniqueFieldChineseNames.toArray());
+            }
+        }
+    }
+
+    /**
+     * 妫�鏌ュ睘鎬ф槸鍚﹀敮涓�
+     * @param field 闇�瑕佹牎楠岀殑灞炴�у璞�
+     * @param baseModel 鏁版嵁瀵硅薄
+     * @param editFlag 鏄惁涓轰慨鏀规暟鎹紝淇敼鐨勬椂鍊欓渶瑕佹帓闄ゅ綋鍓嶆暟鎹�
+     * @return true琛ㄧず涓嶅敮涓�锛宖alse鍞竴
+     */
+    public boolean checkFieldNotUnique(Field field,BaseModel baseModel,boolean editFlag){
+        return checkFieldNotUnique(field,baseModel,editFlag,false);
+    }
+
+    /**
+     * 妫�鏌ュ睘鎬ф槸鍚﹀敮涓�,骞朵笖涓嶅尯鍒嗗ぇ灏忓啓
+     * @param field 闇�瑕佹牎楠岀殑灞炴�у璞�
+     * @param baseModel 鏁版嵁瀵硅薄
+     * @param editFlag 鏄惁涓轰慨鏀规暟鎹紝淇敼鐨勬椂鍊欓渶瑕佹帓闄ゅ綋鍓嶆暟鎹�
+     * @return true琛ㄧず涓嶅敮涓�锛宖alse鍞竴
+     */
+    public boolean checkFieldNotUniqueUnCase(Field field,BaseModel baseModel,boolean editFlag){
+        return checkFieldNotUnique(field,baseModel,editFlag,true);
+    }
+
+    /**
+     * 妫�鏌ュ睘鎬ф槸鍚﹀敮涓�,鍙互璁剧疆涓嶅尯鍒嗗ぇ灏忓啓
+     * @param field 闇�瑕佹牎楠岀殑灞炴�у璞�
+     * @param baseModel 鏁版嵁瀵硅薄
+     * @param editFlag 鏄惁涓轰慨鏀规暟鎹紝淇敼鐨勬椂鍊欓渶瑕佹帓闄ゅ綋鍓嶆暟鎹�
+     * @param unCase 涓嶅尯鍒嗗ぇ灏忓啓
+     * @return true琛ㄧず涓嶅敮涓�锛宖alse鍞竴
+     */
+    private boolean checkFieldNotUnique(Field field,BaseModel baseModel,boolean editFlag,boolean unCase){
+        String btmType = VciBaseUtil.getBtmTypeNameFromDO(baseModel.getClass());
+        String className = baseModel.getClass().getName();
+        String columnName =VciBaseUtil.getCboAttrNameFromField(field,baseModel.getClass());
+        String tableName = VciBaseUtil.getTableName(btmType);
+        Object columnValue = null;
+        String oid = "";
+        if(editFlag){
+            oid = baseModel.getOid();
+        }
+        field.setAccessible(true);
+        try {
+            columnValue = field.get(baseModel);
+        } catch (IllegalAccessException e) {
+            String msg = "鍒ゆ柇鏌愪釜瀵硅薄鐨勫睘鎬ф槸鍚﹂噸澶嶆椂鍑虹幇浜嗛敊璇�";
+            if(logger.isErrorEnabled()) {
+                logger.error(msg + ",{}.{}", className, field.getName(), e);
+            }
+            throw new VciBaseException(msg + "{0},{1}",new String[]{className,field.getName()},e);
+        }
+        if(unCase && columnValue instanceof String){
+            //鍙湁瀛楃涓叉墠鏈夊ぇ灏忓啓锛屾棩鏈熷拰鏁板瓧杩欎簺涓嶆敮鎸�
+            columnName = "lower(" + columnName + ")";
+            columnValue = columnValue.toString().toLowerCase();
+        }
+        int count;
+        if(editFlag){
+            count=  revisionMapper.countByPropertiesNotIncludeSelf(columnName, columnValue, tableName, oid);
+        }else{
+            count = revisionMapper.countByProperties(columnName,columnValue,tableName);
+        }
+        if(count>0){
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * 鍒ゆ柇鏁版嵁鏄惁涓虹┖
+     * @param notNullFields 闇�瑕佸垽鏂殑灞炴��
+     * @param baseModel 鏁版嵁瀵硅薄
+     */
+    public void checkFieldsRequired(List<Field> notNullFields, BaseModel baseModel) {
+        if(!CollectionUtils.isEmpty(notNullFields)){
+            String className = baseModel.getClass().getName();
+            List<Field> nullValueFields = notNullFields.stream().filter( s -> checkFieldValueNull(s,baseModel)).collect(Collectors.toList());
+            if(!CollectionUtils.isEmpty(nullValueFields)){
+                //鎵惧搴旂殑涓枃鍚嶇О
+                List<String> nullFieldChineseNames = new ArrayList<>();
+                nullValueFields.stream().forEach( s -> {
+                    //鍏堜粠娉ㄩ噴涓笂鑾峰彇锛屼絾鏄�曠殑鏄箣鍓嶆病鏈夋敞閲婏紝鎵�浠ュ彲鑳藉緱浠庢敞瑙d笂鑾峰彇
+                    nullFieldChineseNames.add(getColumnChineseText(s));
+                });
+                //鎸夌悊璇磋繖涓敊璇俊鎭笉搴旇鍑虹幇鐨勶紝鎵�浠ヤ笉鍋氬璇�
+                throw new VciBaseException("灞炴�" + nullFieldChineseNames.stream().collect(Collectors.joining(",")) + "]涓嶈兘涓虹┖",nullFieldChineseNames.toArray());
+            }
+        }
+    }
+
+    /**
+     * 鏍¢獙灞炴�т负绌�
+     * @param field 灞炴�у璞�
+     * @param baseModel 鏁版嵁瀵硅薄
+     * @return true琛ㄧず涓虹┖锛宖alse琛ㄧず涓嶄负绌�
+     */
+    public boolean checkFieldValueNull(Field field,BaseModel baseModel){
+        String className = baseModel.getClass().getName();
+        field.setAccessible(true);
+        try {
+            Object value = field.get(baseModel);
+            if(value == null || (value instanceof String) && StringUtils.isBlank((String)value)){
+                return true;
+            }
+        } catch (IllegalAccessException e) {
+            String msg = "鍒ゆ柇鏌愪釜瀵硅薄鐨勫睘鎬ф槸鍚︿负绌烘椂鍑虹幇浜嗛敊璇�";
+            if(logger.isErrorEnabled()) {
+                logger.error(msg + "锛寋}.{}", className, field.getName(), e);
+            }
+            throw new VciBaseException(msg + "{0},{1}",new String[]{className,field.getName()},e);
+        }
+        return false;
+    }
+
+    /**
+     * 鑾峰彇
+     * @param field 灞炴�у璞�
+     * @return 涓枃鍚嶇О锛屼紭鍏堝彇娉ㄩ噴锛屽惁鍒欏彇娉ㄨВ锛屾渶鍚庤繑鍥炲睘鎬х殑鑻辨枃鍚嶇О
+     */
+    public String getColumnChineseText(Field field){
+        String className = field.getDeclaringClass().getName();
+        if(modelColumnAnnotationMap.containsKey(className) && modelColumnAnnotationMap.get(className.toLowerCase()).containsKey(field.getName().toLowerCase())){
+            return modelColumnAnnotationMap.get(className.toLowerCase()).get(field.getName().toLowerCase());
+        }else{
+            Column column = getColumnAnnotation(field);
+            if(column!=null && StringUtils.isNotBlank(column.columnDefinition())){
+                return column.columnDefinition();
+            }else{
+                //鐪嬬湅columnDefinition娉ㄨВ
+                if(field.isAnnotationPresent(VciColumnDefinition.class)){
+                    VciColumnDefinition columnDefinition = field.getDeclaredAnnotation(VciColumnDefinition.class);
+                    if(columnDefinition == null){
+                        columnDefinition = field.getAnnotation(VciColumnDefinition.class);
+                    }
+                    if(columnDefinition!=null) {
+                        return columnDefinition.value();
+                    }
+                }
+            }
+            return field.getName();
+        }
+    }
+
+    /**
+     * 鑾峰彇鏁版嵁瀵硅薄涓婄殑鍒楁敞瑙�
+     * @param field 瀛楁鐨勫睘鎬у璞�
+     * @return 娌℃湁娉ㄨВ鐨勬椂鍊欒繑鍥炵┖锛屽惁鍒欒繑鍥炲搴旂殑娉ㄨВ
+     */
+    public Column getColumnAnnotation(Field field){
+        if(field.isAnnotationPresent(Column.class)) {
+            Column column = field.getDeclaredAnnotation(Column.class);
+            if (column == null) {
+                column = field.getAnnotation(Column.class);
+            }
+            return column;
+        }
+        return null;
+    }
+
+
+
+    /**
+     * 鏍¢獙鏄惁鎺у埗瀵嗙骇
+     * @param doObject 鏁版嵁瀵硅薄
+     * @return true闇�瑕佹牎楠屽瘑绾�
+     */
+    public boolean isCheckSecret(BaseModel doObject){
+        VciBtmType btmType = getBtmTypeAnnotation(doObject);
+        return isCheckSecret(btmType);
+    }
+
+    /**
+     * 鏍¢獙鏄惁鎺у埗瀵嗙骇
+     * @param btmType 涓氬姟绫诲瀷鐨勬敞瑙�
+     * @return true闇�瑕佹牎楠屽瘑绾�
+     */
+    public boolean isCheckSecret(VciBtmType btmType){
+        if(btmType !=null && btmType.secretAble()){
+            return true;
+        }
+        return false;
+    }
+
+
+    /**
+     * 灏佽鏂扮殑鐗堟湰淇℃伅锛屼細鑷姩澶勭悊鑰佺殑鐗堟湰鍜屾渶鏂扮増鏈殑闂
+     * @param oldModel 鑰佺増鏈殑鏁版嵁瀵硅薄
+     * @param newModel 鏂扮増鏈殑鏁版嵁瀵硅薄
+     * @throws VciBaseException 鍙傛暟閿欒锛岀己灏戞敞瑙o紝閰嶇疆閿欒閮戒細鎶涘嚭杩欎釜寮傚父
+     */
+    public void wrapperRevisionModel(BaseModel oldModel, BaseModel newModel) throws VciBaseException {
+        VciBaseUtil.alertNotNull(oldModel,"鑰佺増鏈殑鏁版嵁瀵硅薄",newModel,"鏂扮増鏈殑鏁版嵁瀵硅薄");
+        VciBtmType btmType = getBtmTypeAnnotation(newModel);
+        if(btmType == null){
+            throw new VciBaseException("娌℃湁VciBtmType娉ㄨВ锛屾棤娉曞垽鏂槸鍚︽帶鍒剁増鏈�");
+        }else {
+            if ( isManageRevision(btmType)) {
+                //鍗囩増鐨勫墠鎻愭槸鏈夌増鏈鍒欙紝骞朵笖濡傛灉鏄墜鍔ㄨ緭鍏ョ殑鏃跺�欙紝蹇呴』浠庡墠绔緭鍏ュ�笺��
+                //1. 涓婚敭涓嶈兘鐩稿悓
+                if (StringUtils.isBlank(newModel.getOid()) || newModel.getOid().equalsIgnoreCase(oldModel.getOid())) {
+                    newModel.setOid(VciBaseUtil.getPk());
+                }
+                //2.nameOid瑕佺浉鍚�
+                newModel.setNameOid(oldModel.getNameOid());
+                //2.1 revisionOid涓嶇浉鍚�
+                newModel.setRevisionOid(VciBaseUtil.getPk());
+                //鏌ユ壘鏈�鍚庝竴涓増鏈殑鐗堟湰鍊�
+                RevisionInfo lastRevision = null;
+                if (revisionMapper != null) {
+                    lastRevision = revisionMapper.selectLastRevision(newModel.getNameOid(),VciBaseUtil.getTableName(btmType.name()));
+                } else {
+                    //娌℃湁杩欎釜锛岄偅灏辩洿鎺ョ敤oldModel鍘昏幏鍙栫増鏈彿
+                    lastRevision = new RevisionInfo();
+                    BeanUtil.convert(oldModel, lastRevision);
+                }
+                newModel.setRevisionRule(lastRevision.getRevisionRule());
+                newModel.setVersionRule(lastRevision.getVersionRule());
+                //3.鐗堟湰鍙�
+                if(StringUtils.isBlank(newModel.getRevisionValue())  &&  !isInputRevision(newModel) && StringUtils.isBlank(lastRevision.getRevisionRule())){
+                    //涓嶅鐞�
+                }else {
+                    if (StringUtils.isBlank(newModel.getRevisionValue())) {
+                        wrapperRevisionValue(newModel, btmType, lastRevision);
+                    }
+                }
+
+                //濡傛灉鏈夌増娆★紝閭h繖涓氨鏄柊鐗堟湰鐨勭涓�涓増娆�
+                if (isManageVersion(btmType)) {
+                    wrapperFristVersion(newModel);
+                }else{
+                    //鍙兘娌℃湁澶勭悊鐗堟锛屼絾鏄繀椤昏娣诲姞涓�
+                    newModel.setFirstV("1");
+                    newModel.setLastV("1");
+                }
+                //4.鏂扮殑鐗堟湰椤哄簭
+                newModel.setRevisionSeq(lastRevision.getRevisionSeq() + 1);
+                newModel.setLastR("1");
+                newModel.setFirstR("0");
+
+                //5.淇敼鑰佺殑鐗堟湰鐨刬sLastR
+                saveOldModel(oldModel);
+                //鑰屼笖鍙兘oldModel涓嶆槸鏈�鍚庣殑閭d釜鐗堟湰
+            }
+            //鏀寔鍙互浣跨敤鐗堟湰瑙勫垯鐢熸垚锛屼篃鍚屾椂鍙互鎵嬪姩杈撳叆锛屾墍浠ュ綋鎵嬪姩杈撳叆鑰屽�煎張娌℃湁鐨勬椂鍊欓渶瑕佹柊鐢熸垚
+        }
+    }
+
+    /**
+     * 灏佽鏂扮殑鐗堟淇℃伅锛屼細鑷姩澶勭悊鑰佺殑鐗堟鍜屾渶鏂扮増娆¢棶棰�
+     * @param oldModel 鑰佺増娆$殑鏁版嵁瀵硅薄
+     * @param newModel 鏂扮増娆$殑鏁版嵁瀵硅薄
+     * @throws VciBaseException 鍙傛暟閿欒锛岀己灏戞敞瑙o紝閰嶇疆閿欒閮戒細鎶涘嚭杩欎釜寮傚父
+     */
+    public void wrapperVersionModel(BaseModel oldModel, BaseModel newModel) throws VciBaseException {
+        VciBaseUtil.alertNotNull(oldModel,"鑰佺増娆$殑鏁版嵁瀵硅薄",newModel,"鏂扮増娆$殑鏁版嵁瀵硅薄");
+        VciBtmType btmType = getBtmTypeAnnotation(newModel);
+        if(btmType == null){
+            throw new VciBaseException("娌℃湁VciBtmType娉ㄨВ锛屾棤娉曞垽鏂槸鍚︽帶鍒剁増娆�");
+        }else {
+            if (isManageVersion(btmType)) {
+                //鎵嶅鐞嗘柊鐨勭増娆�
+                //涓婚敭涓嶈兘鐩稿悓锛宯ameoid鍜宺evisionoid蹇呴』鐩稿悓
+                if (StringUtils.isBlank(newModel.getOid()) || newModel.getOid().equalsIgnoreCase(oldModel.getOid())) {
+                    newModel.setOid(VciBaseUtil.getPk());
+                }
+                if(StringUtils.isBlank(newModel.getNameOid()) || !newModel.getNameOid().equalsIgnoreCase(oldModel.getNameOid())){
+                    newModel.setNameOid(oldModel.getNameOid());
+                }
+                if(StringUtils.isBlank(newModel.getRevisionOid())
+                        || !newModel.getRevisionOid().equalsIgnoreCase(oldModel.getRevisionOid())){
+                    newModel.setRevisionOid(oldModel.getRevisionOid());
+                }
+                //鏌ヨ杩欎釜鐩稿悓鐨勭増鏈笅鐨勬渶鏂扮増娆�
+                RevisionInfo lastRevision = null;
+                if (revisionMapper != null) {
+                    lastRevision = revisionMapper.selectLastVersion(newModel.getNameOid(),newModel.getRevisionOid(),VciBaseUtil.getTableName(btmType.name()));
+                } else {
+                    //娌℃湁杩欎釜锛岄偅灏辩洿鎺ョ敤oldModel鍘昏幏鍙栫増鏈彿
+                    lastRevision = new RevisionInfo();
+                    BeanUtil.convert(oldModel, lastRevision);
+                }
+                //鐗堟鍙�,灏辨暟瀛楀拰瀛楁瘝涓ょ
+                if(oldModel.getVersionValue().matches(RegExpConstant.LETTER)){
+                    //璇存槑鏄瓧姣嶇殑
+                    newModel.setVersionValue(String.valueOf((char)(oldModel.getVersionValue().toCharArray()[0] + 1)));
+                }else{
+                    newModel.setVersionValue(String.valueOf(Integer.valueOf(oldModel.getVersionValue()) + 1));
+                }
+                newModel.setVersionSeq(lastRevision.getVersionSeq() + 1);
+                newModel.setVersionRule(oldModel.getVersionRule());
+                newModel.setLastV("1");
+                newModel.setFirstV("0");
+                //澶勭悊鑰佺増娆�
+                saveOldModelVersion(oldModel);
+            }
+        }
+    }
+
+    /**
+     * 澶勭悊涓氬姟绫诲瀷鐨勫悕绉�
+     * @param baseModel 鏁版嵁瀵硅薄
+     */
+    private void setBtmName(BaseModel baseModel){
+        VciBaseUtil.alertNotNull(baseModel,"鏁版嵁瀵硅薄");
+        if(StringUtils.isBlank(baseModel.getBtmname())){
+            VciBtmType btmType = getBtmTypeAnnotation(baseModel);
+            if(btmType == null){
+                throw new VciBaseException("娌℃湁VciBtmType娉ㄨВ锛屾棤娉曞垽鏂笟鍔$被鍨�");
+            }
+            baseModel.setBtmname(btmType.name());
+        }
+    }
+
+    /**
+     * 淇濆瓨鏃х殑鐗堟湰锛屼細鑷姩鎶婁互鍓嶆渶鏂扮増鏈殑鍝潯鏁版嵁淇敼锛屽悓鏃朵細鎶婅�佺殑杩欐潯鐗堟湰淇敼
+     * @param oldModel 鑰佺増鏈殑鏁版嵁瀵硅薄
+     */
+    public void saveOldModel(BaseModel oldModel){
+        setBtmName(oldModel);
+        if (revisionMapper != null) {
+            revisionMapper.resetLastRevision(oldModel.getNameOid(),VciBaseUtil.getTableName(oldModel.getBtmname()));
+            revisionMapper.resetOldRevision(oldModel.getOid(),VciBaseUtil.getTableName(oldModel.getBtmname()));
+        }else{
+            throw new VciBaseException("娌℃湁鍒濆鍖栫増鏈鍒欑殑鏁版嵁鎿嶄綔灞傦紝璇峰紑鍙戜汉鍛樻鏌aven鏄惁寮曠敤");
+        }
+    }
+
+    /**
+     * 淇濆瓨鏃х殑鐗堟锛屼細鑷姩鎶婁互鍓嶆渶鏂扮増娆$殑鍝潯鏁版嵁淇敼锛屽悓鏃朵細鎶婅�佺殑杩欐潯鐗堟淇敼
+     * @param oldModel 鑰佺増娆$殑鏁版嵁瀵硅薄
+     */
+    public void saveOldModelVersion(BaseModel oldModel){
+        setBtmName(oldModel);
+        if (revisionMapper != null) {
+            revisionMapper.resetLastVersion(oldModel.getNameOid(),oldModel.getRevisionOid(),VciBaseUtil.getTableName(oldModel.getBtmname()));
+            revisionMapper.resetOldVersion(oldModel.getOid(),VciBaseUtil.getTableName(oldModel.getBtmname()));
+        }else{
+            throw new VciBaseException("娌℃湁鍒濆鍖栫増鏈鍒欑殑鏁版嵁鎿嶄綔灞傦紝璇峰紑鍙戜汉鍛樻鏌aven鏄惁寮曠敤");
+        }
+    }
+
+    /**
+     * 灏佽鐗堟湰鐨勪俊鎭紝鏀寔绗竴涓増鏈殑绗竴涓増娆★紝鍜屽崌鐗堢殑鎯呭喌
+     * @param newModel 鏂扮増鏈殑鏁版嵁锛岃鍏堣璁剧疆鐗堟湰瑙勫垯鐨勫�煎湪杩欎釜瀵硅薄涓�
+     * @param btmType 瀵硅薄鐨勬敞瑙�
+     * @param lastRevision 褰撳墠鏈�鏂扮増鏈渶鏂扮増娆$殑瀵硅薄锛屾槸绗竴涓増鏈殑绗竴涓増鏈椂浼犻�抧ull
+     */
+    public void wrapperRevisionValue(BaseModel newModel,VciBtmType btmType,RevisionInfo lastRevision){
+        //娌℃湁鐗堟湰鍙风殑鏃跺�欏繀椤讳娇鐢ㄧ紪鐮佽鍒欐潵鐢熸垚鏂扮殑鐗堟湰鍙�
+        if (RevisionConstant.CHARACTER.equalsIgnoreCase(newModel.getRevisionRule())) {
+            //浣跨敤瀛楁瘝杩欎釜榛樿鐨勫瓧绗�,杩欎釜娌℃湁鍓嶇紑锛屾病鏈夊悗缂�锛屾闀夸负1锛屾病鏈夎烦璺冨瓧绗�
+            newRevisionForLetter(newModel, lastRevision, btmType != null ? btmType.revisionRulePrefix() : "", btmType != null ? btmType.revisionRuleSubfix() : "");
+        } else if (RevisionConstant.NUMBER.equalsIgnoreCase(newModel.getRevisionRule())) {
+            newRevisionForNumber(newModel,lastRevision,btmType != null ? btmType.revisionRulePrefix() : "", btmType != null ? btmType.revisionRuleSubfix() : "");
+        } else {
+            if (revisionRuleProvider != null) {
+                try {
+                    BaseResult nextRevisionResult = revisionRuleProvider.getNextRevisionValue(newModel.getRevisionRule(), lastRevision==null?"":lastRevision.getRevisionValue());
+                    if (nextRevisionResult.isSuccess()) {
+                        newModel.setRevisionValue((String) nextRevisionResult.getObj());
+                    } else {
+                        throw new VciBaseException(nextRevisionResult.getMsg(), nextRevisionResult.getMsgObjs());
+                    }
+                } catch (Throwable e) {
+                    throw new VciBaseException("鑾峰彇涓嬩竴涓増鏈彿鍑虹幇浜嗛敊璇紝{0}", new String[]{newModel.getRevisionRule()}, e);
+                }
+            } else {
+                throw new VciBaseException("娌℃湁鍒濆鍖栫増鏈鍒欑殑璋冪敤鍣�,璇峰紑鍙戜汉鍛樻鏌eign");
+            }
+        }
+    }
+
+    /**
+     * 鏍规嵁鏁板瓧鐨勮鍒欏皝瑁呮柊鐨勭増鏈�
+     * @param baseModel 鍩虹鏁版嵁瀵硅薄
+     * @param lastRevision 鏈�鍚庣殑鐗堟湰瀵硅薄
+     * @param prefix 鍓嶇紑
+     * @param subfix 鍚庣紑
+     */
+    private void newRevisionForNumber(BaseModel baseModel, RevisionInfo lastRevision,String prefix,String subfix) {
+        if(prefix==null){
+            prefix = "";
+        }
+        if(subfix == null){
+            subfix = "";
+        }
+        if(lastRevision == null) {
+            //璇存槑鏄涓�涓増鏈�
+            baseModel.setRevisionValue(prefix + "1" + subfix);
+        }else {
+            String ruleValue = replacePrefixAndSubfix(lastRevision, prefix, subfix);
+            if (ruleValue.matches(RegExpConstant.NUMBER)) {
+                //鏁板瓧鍙互涓嶅仠鍦板姞
+                ruleValue = String.valueOf(Integer.valueOf(ruleValue) + 1);
+                baseModel.setRevisionValue(prefix + ruleValue + subfix);
+            } else {
+                //鏈�鍚庝竴涓増鏈彲鑳芥槸鎵嬪姩杈撳叆鐨勶紝閭e氨鐩存帴鎵句竴涓嬫渶鍚庝竴鎺掓暟瀛楋紝
+                if (ruleValue.matches(RegExpConstant.HAS_NUMBER)) {
+                    String onlyNumber = getNumbers(ruleValue);
+                    String nextNumber = String.valueOf(Integer.valueOf(onlyNumber) + 1);
+                    if (ruleValue.startsWith(onlyNumber)) {
+                        ruleValue = ruleValue.substring(onlyNumber.length());
+                        baseModel.setRevisionValue(prefix + onlyNumber + ruleValue + subfix);
+                    } else if (ruleValue.endsWith(onlyNumber)) {
+                        ruleValue = ruleValue.substring(0, ruleValue.length() - onlyNumber.length() - 1);
+                        baseModel.setRevisionValue(prefix + ruleValue + nextNumber + subfix);
+                    } else {
+                        baseModel.setRevisionValue(prefix + ruleValue.substring(0, ruleValue.lastIndexOf(onlyNumber)) + nextNumber + ruleValue.substring(ruleValue.lastIndexOf(onlyNumber) + 1) + subfix);
+                    }
+                } else {
+                    //涓�涓暟瀛楅兘娌℃湁
+                    baseModel.setRevisionValue(prefix + ruleValue + "1" + subfix);
+                }
+            }
+        }
+    }
+
+    /**
+     * 鑾峰彇瀛楃涓蹭腑鐨勬暟瀛楅儴鍒�
+     * @param content 瀛楃涓插唴瀹�
+     * @return 鏁板瓧鐨勯儴鍒�,鏈�鍚庣殑閭i儴鍒�
+     */
+    private String getNumbers(String content) {
+        Pattern pattern = Pattern.compile("\\d+");
+        Matcher matcher = pattern.matcher(content);
+        while (matcher.find()) {
+            return matcher.group(matcher.groupCount()-1);
+        }
+        return "";
+    }
+
+    /**
+     * 鏇挎崲鍓嶇紑鍜屽悗缂�
+     * @param lastRevision 鏈�鍚庣増鏈殑瀵硅薄
+     * @param prefix 鍓嶇紑
+     * @param subfix 鍚庣紑
+     * @return 鍘婚櫎鍓嶇紑鍜屽悗缂�鐨勭増鏈鍒�
+     */
+    private String replacePrefixAndSubfix(RevisionInfo lastRevision,String prefix,String subfix){
+        String ruleValue = lastRevision.getRevisionValue();
+        if(prefix==null){
+            prefix = "";
+        }
+        if(subfix == null){
+            subfix = "";
+        }
+        if(StringUtils.isNotBlank(prefix) && ruleValue.startsWith(prefix)){
+            ruleValue = ruleValue.substring(prefix.length());
+        }
+        if(StringUtils.isNotBlank(subfix) && ruleValue.endsWith(subfix)){
+            ruleValue = ruleValue.substring(0,ruleValue.length()-subfix.length()-1);
+        }
+        return ruleValue;
+    }
+
+    /**
+     * 鏍规嵁瀛楁瘝鐨勮鍒欏皝瑁呮柊鐨勭増鏈�
+     * @param baseModel 鍩虹鏁版嵁瀵硅薄
+     * @param lastRevision 鏈�鍚庣殑鐗堟湰瀵硅薄
+     * @param prefix 鍓嶇紑
+     * @param subfix 鍚庣紑
+     */
+    private void newRevisionForLetter(BaseModel baseModel,RevisionInfo lastRevision,String prefix,String subfix){
+        if(prefix==null){
+            prefix = "";
+        }
+        if(subfix == null){
+            subfix = "";
+        }
+        if(lastRevision == null){
+            //璇存槑鏄涓�涓増鏈�
+            baseModel.setRevisionValue(prefix + "A" + subfix);
+        }else {
+            String ruleValue = replacePrefixAndSubfix(lastRevision, prefix, subfix);
+            if (ruleValue.matches(RegExpConstant.LETTER)) {
+                //浠嶢鍒癦Z鐨勫舰寮�
+                String lastLetter = ruleValue.substring(ruleValue.length() - 1);
+                if (lastLetter.equalsIgnoreCase("Z")) {
+                    if (lastRevision.getRevisionValue().length() == 1) {
+                        baseModel.setRevisionValue(prefix + "AA" + subfix);
+                    } else {
+                        lastLetter = ruleValue.substring(ruleValue.length() - 2, ruleValue.length() - 1);
+                        lastLetter = String.valueOf((char) (lastLetter.toCharArray()[0] + 1));
+                        baseModel.setRevisionValue(prefix + ruleValue.substring(0, ruleValue.length() - 2) + lastLetter + subfix);
+                    }
+                } else {
+                    lastLetter = String.valueOf((char) (lastLetter.toCharArray()[0] + 1));
+                    baseModel.setRevisionValue(prefix + ruleValue.substring(0, ruleValue.length() - 1) + lastLetter + subfix);
+                }
+            } else {
+                //鏈�鍚庝竴涓増鏈彲鑳芥槸鎵嬪姩杈撳叆鐨勶紝濡傛灉鎴戜滑涔嬮棿瀛樺偍A鐨勮瘽锛屽彲鑳戒細閫犳垚閲嶅锛屾渶鍚庝竴浣嶆槸瀛楁瘝灏卞湪璇ュ瓧姣嶄笂鍔�1锛屾渶鍚庝竴浣嶄笉鏄瓧姣嶏紝灏卞師鍊间笂鍔燗
+                String lastLetter = ruleValue.substring(ruleValue.length() - 1);
+                if (lastLetter.matches(RegExpConstant.LETTER)) {
+                    lastLetter = String.valueOf((char) (lastLetter.toCharArray()[0] + 1));
+                    baseModel.setRevisionValue(prefix + ruleValue.substring(0, ruleValue.length() - 1) + lastLetter + subfix);
+                } else {
+                    baseModel.setRevisionValue(prefix + ruleValue + "A" + subfix);
+                }
+            }
+        }
+    }
+
+    /**
+     * 灏佽鏌愪釜鐗堟湰鐨勭涓�涓増娆�
+     * @param baseModel 鏁版嵁瀵硅薄
+     */
+    public void wrapperFristVersion(BaseModel baseModel){
+        VciBaseUtil.alertNotNull(baseModel,"鏁版嵁瀵硅薄");
+        VciBtmType btmType = getBtmTypeAnnotation(baseModel);
+        if(isManageVersion(btmType)) {
+            //鍙敮鎸佷粠0,1锛屾垨鑰呭瓧姣岮寮�濮�
+            if (StringUtils.isBlank(baseModel.getVersionRule())) {
+                baseModel.setVersionRule(btmType.versionRule().getValue());
+            }
+            if (btmType.versionRule().equals(VciBtmType.VciBtmTypeVersionRule.INTSTART0)) {
+                baseModel.setVersionValue("0");
+            } else if (btmType.versionRule().equals(VciBtmType.VciBtmTypeVersionRule.INTSTART1)) {
+                baseModel.setVersionValue("1");
+            } else {
+                baseModel.setVersionValue("A");
+            }
+        }
+        baseModel.setVersionSeq(1);
+        baseModel.setFirstV("1");
+        baseModel.setLastV("1");
+    }
+
+    /**
+     * 灏佽绗竴涓増鏈殑绗竴涓増娆�
+     * @param baseModel 鏂板鐨勬暟鎹璞★紙绗竴涓増鏈殑绗竴涓増娆�
+     */
+    public void wrapperFristRevision(BaseModel baseModel){
+        VciBaseUtil.alertNotNull(baseModel,"鏁版嵁瀵硅薄");
+        //闇�瑕佸厛鍒ゆ柇鏄惁鎺у埗鐗堟湰
+        VciBtmType btmType = getBtmTypeAnnotation(baseModel);
+        if(isManageRevision(btmType)) {
+            if (StringUtils.isBlank(baseModel.getOid())) {
+                baseModel.setOid(VciBaseUtil.getPk());
+            }
+            //绗竴涓増鏈殑绗竴涓増娆�
+            if (StringUtils.isBlank(baseModel.getNameOid())) {
+                baseModel.setNameOid(VciBaseUtil.getPk());
+            }
+            if (StringUtils.isBlank(baseModel.getRevisionOid())) {
+                baseModel.setRevisionOid(VciBaseUtil.getPk());
+            }
+
+            //绗竴涓増鏈�
+            if (btmType != null) {
+                baseModel.setRevisionRule(btmType.revisionRule());
+                baseModel.setVersionValue(btmType.versionRule().getValue());
+            } else {
+                throw new VciBaseException("娌℃湁VciBtmType娉ㄨВ锛寋0}");
+            }
+            //鏍规嵁鐗堟湰瑙勫垯鐢熸垚鐗堟湰鍙�
+            //3.鐗堟湰鍙�
+            //鐗堟湰鍙蜂负绌猴紝鍙兘鏄墜鍔ㄥ悗杈撳叆鐨勬椂鍊欙紝搴旇鏄敊璇�
+            //鍏朵粬鎯呭喌涓嬬増鏈彿涓虹┖閮借缃増鏈彿
+            if (StringUtils.isBlank(baseModel.getRevisionValue() )&& isInputRevision(baseModel) && StringUtils.isBlank(baseModel.getRevisionRule())){
+                //涓嶅鐞�
+            }else {
+                if (StringUtils.isBlank(baseModel.getRevisionValue())) {
+                    wrapperRevisionValue(baseModel, btmType, null);
+                }
+            }
+            //濡傛灉鏈夌増娆★紝閭h繖涓氨鏄柊鐗堟湰鐨勭涓�涓増娆�
+            if (StringUtils.isNotBlank(baseModel.getVersionRule()) && StringUtils.isBlank(baseModel.getVersionValue())) {
+                wrapperFristVersion(baseModel);
+            } else {
+                baseModel.setFirstV("1");
+                baseModel.setLastV("1");
+            }
+            //4.鐗堟湰椤哄簭
+            baseModel.setRevisionSeq(1);
+            baseModel.setFirstR("1");
+            baseModel.setLastR("1");
+        }
+    }
+
+    /**
+     * 灏佽鐢熷懡鍛ㄦ湡
+     * @param baseModel 鏁版嵁瀵硅薄
+     */
+    public void wrapperLifeCycle(BaseModel baseModel){
+        VciBaseUtil.alertNotNull(baseModel,"鏁版嵁瀵硅薄");
+        VciBtmType btmType = getBtmTypeAnnotation(baseModel);
+        if(StringUtils.isBlank(baseModel.getLcStatus()) &&isManageLifeCycle(btmType) ){
+            //寮�濮嬬殑鏃跺�欒幏鍙栫敓鍛藉懆鏈熺殑鍒濆鐘舵��
+            if(StringUtils.isNotBlank(btmType.startStatus())){
+                baseModel.setLcStatus(btmType.startStatus());
+            }else {
+                if (lifeCycleProvider != null) {
+                    try {
+                        BaseResult lifeCycleResult = lifeCycleProvider.getStartStatus(btmType.lifeCycle());
+                        if (lifeCycleResult.isSuccess()) {
+                            baseModel.setLcStatus((String) lifeCycleResult.getObj());
+                        } else {
+                            throw new VciBaseException(lifeCycleResult.getMsg(), lifeCycleResult.getMsgObjs());
+                        }
+                    } catch (Throwable e) {
+                        throw new VciBaseException("璋冪敤銆愮敓鍛藉懆鏈熴�戞湇鍔¤幏鍙栧垵濮嬬姸鎬佹椂鍑洪敊,{0}", new String[]{btmType.lifeCycle()}, e);
+                    }
+                } else {
+                    throw new VciBaseException("娌℃湁鍒濆鍖栫敓鍛藉懆鏈熺殑璋冪敤鍣�,璇峰紑鍙戜汉鍛樻鏌eign");
+                }
+            }
+        }
+    }
+
+
+
+    /**
+     * 鏄惁绠$悊鐢熷懡鍛ㄦ湡
+     * @param baseModel 鏁版嵁瀵硅薄
+     * @return true琛ㄧず绠$悊
+     */
+    public boolean isManageLifeCycle(BaseModel baseModel){
+        VciBtmType btmType = getBtmTypeAnnotation(baseModel);
+        return isManageLifeCycle(btmType);
+    }
+
+    /**
+     * 鏄惁绠$悊鐢熷懡鍛ㄦ湡
+     * @param btmType 涓氬姟绫诲瀷娉ㄨВ
+     * @return true琛ㄧず绠$悊
+     */
+    public boolean isManageLifeCycle(VciBtmType btmType){
+        if(btmType !=null && (StringUtils.isNotBlank(btmType.lifeCycle()) && !"defaultLC".equalsIgnoreCase(btmType.lifeCycle()))){
+            return true;
+        }else{
+            return false;
+        }
+    }
+
+    /**
+     * 鏄惁绠$悊鐗堟湰
+     * @param baseModel 鏁版嵁瀵硅薄
+     * @return true 琛ㄧず绠$悊鐗堟湰
+     */
+    public boolean isManageRevision(BaseModel baseModel){
+        VciBtmType btmType = getBtmTypeAnnotation(baseModel);
+        return isManageRevision(btmType);
+    }
+
+    /**
+     * 鏄惁绠$悊鐗堟湰
+     * @param btmType 涓氬姟绫诲瀷鐨勬敞瑙�
+     * @return true 琛ㄧず绠$悊鐗堟湰
+     */
+    public boolean isManageRevision(VciBtmType btmType){
+        if(btmType !=null && (btmType.revisionRuleInput() || StringUtils.isNotBlank(btmType.revisionRule()))){
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * 鏄惁绠$悊鐗堟锛屽繀椤荤鐞嗙増鏈墠鍙互绠$悊鐗堟
+     * @param baseModel 鏁版嵁瀵硅薄
+     * @return true 琛ㄧず绠$悊鐗堟湰
+     */
+    public boolean isManageVersion(BaseModel baseModel){
+        VciBtmType btmType = getBtmTypeAnnotation(baseModel);
+        return isManageVersion(btmType);
+    }
+
+    /**
+     * 鏄惁绠$悊鐗堟锛屽繀椤荤鐞嗙増鏈墠鍙互绠$悊鐗堟
+     * @param btmType 涓氬姟绫诲瀷鐨勬敞瑙�
+     * @return true 琛ㄧず绠$悊鐗堟湰
+     */
+    public boolean isManageVersion(VciBtmType btmType){
+        if(isManageRevision(btmType) && !btmType.versionRule().equals(VciBtmType.VciBtmTypeVersionRule.NONE)){
+            return true;
+        }
+        return false;
+    }
+
+
+    /**
+     * 鏄惁鍙互鎵嬪姩杈撳叆鐗堟湰鍙�
+     * @param baseModel 鍩烘湰鏁版嵁瀵硅薄
+     * @return true鍏佽鎵嬪姩杈撳叆鐗堟湰鍙�
+     */
+    public boolean isInputRevision(BaseModel baseModel) {
+        VciBtmType btmType = getBtmTypeAnnotation(baseModel);
+        return isInputRevision(btmType);
+    }
+
+    /**
+     * 鏄惁鍙互鎵嬪姩杈撳叆鐗堟湰鍙�
+     * @param btmType 涓氬姟绫诲瀷鐨勬敞瑙�
+     * @return true鍏佽鎵嬪姩杈撳叆鐗堟湰鍙�
+     */
+    public boolean isInputRevision(VciBtmType btmType) {
+        if(btmType !=null && btmType.revisionRuleInput()){
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * 鑾峰彇鏁版嵁瀵硅薄涓婄殑娉ㄨВ
+     * @param baseModel 鏁版嵁瀵硅薄
+     * @return 涓嶅瓨鍦ㄦ敞瑙g殑鏃跺�欎細杩斿洖null
+     */
+    public VciBtmType getBtmTypeAnnotation(BaseModel baseModel){
+        VciBaseUtil.alertNotNull(baseModel,"鏁版嵁瀵硅薄");
+        return getBtmTypeAnnotation(baseModel.getClass());
+    }
+
+    /**
+     * 鑾峰彇DO瀵硅薄涓婄殑娉ㄨВ
+     * @param doClass do瀵硅薄鐨勭被
+     * @return 涓嶅瓨鍦ㄦ敞瑙g殑鏃跺�欎細杩斿洖null
+     */
+    public VciBtmType getBtmTypeAnnotation(Class<?> doClass){
+        VciBaseUtil.alertNotNull(doClass,"瑕佹牎楠屼笟鍔$被鍨嬬殑绫�");
+        if(modelAnnotationMap.containsKey(doClass.getName())){
+            return modelAnnotationMap.get(doClass.getName());
+        }
+        if(doClass.isAnnotationPresent(VciBtmType.class)){
+            VciBtmType btmType =  (VciBtmType)doClass.getAnnotation(VciBtmType.class);
+            if(btmType == null){
+                btmType = doClass.getDeclaredAnnotation(VciBtmType.class);
+            }
+            modelAnnotationMap.put(doClass.getName(),btmType);
+            return btmType;
+        }
+        return null;
+    }
+
+    /**
+     * 灏佽鏍戝舰鏁版嵁鏌ヨ鍣�.杩欎釜鏂规硶琚簾寮冿紝鏀逛负 VciQueryWrapperForDO閲岀殑 parentQueryChild
+     * @param treeQueryObject 鏍戝舰鏌ヨ瀵硅薄
+     * @param doClass 瀹炰綋鐨勭被
+     * @param parentFieldName 涓婄骇灞炴�х殑瀛楁
+     * @return 鏌ヨ灏佽鍣�
+     */
+    @Deprecated
+    public VciQueryWrapperForDO wrapperForTree(TreeQueryObject treeQueryObject,Class<?> doClass,String parentFieldName){
+        if(doClass == null){
+            throw new VciBaseException("鏁版嵁瀵硅薄鎵�灞炵殑绫讳笉鑳戒负绌猴紝涓嶈兘灏佽鏍戝舰鏌ヨ鍣�");
+        }
+        if (treeQueryObject == null){
+            treeQueryObject = new TreeQueryObject();
+        }
+        VciQueryWrapperOption queryWrapperOption = new VciQueryWrapperOption();
+        if(treeQueryObject.isQueryAllRev()){
+            queryWrapperOption.setThisObjectQueryLastRevision(false);
+            queryWrapperOption.setThisObjectQueryRelease(false);
+        }
+        VciQueryWrapperForDO queryWrapper = new VciQueryWrapperForDO(treeQueryObject.getConditionMap(),doClass,new PageHelper(-1),true,queryWrapperOption);
+        if(StringUtils.isBlank(parentFieldName)){
+            return queryWrapper;
+        }
+        if(StringUtils.isNotBlank(treeQueryObject.getParentOid()) ){
+            //璇存槑浼犻�掍簡涓婄骇鐨�
+            if(treeQueryObject.isQueryAllLevel()){
+                //鍏ㄩ儴鐨勫眰绾ч兘瑕佹煡璇紝鎴戜滑浣跨敤start with鍏堟煡璇㈠嚭缁撴灉鍚庯紝鍐嶅尮閰嶆煡璇㈡潯浠�
+                queryWrapper.in(queryWrapper.getOidFieldName(), "select " + queryWrapper.getOidFieldName() + " from " + queryWrapper.getTableName()
+                        + " start with " + parentFieldName + " = '" + treeQueryObject.getParentOid().trim()
+                        + "' connect by prior " + queryWrapper.getOidFieldName() + " = " +  parentFieldName );
+            }else {
+                queryWrapper.eq(parentFieldName, treeQueryObject.getParentOid());
+            }
+        }else{
+            if(treeQueryObject.isQueryAllLevel()){
+                //鍏ㄩ儴鐨勫眰绾ч兘瑕佹煡璇紝鎴戜滑浣跨敤start with鍏堟煡璇㈠嚭缁撴灉鍚庯紝鍐嶅尮閰嶆煡璇㈡潯浠�
+                queryWrapper.in(queryWrapper.getOidFieldName(), "select " + queryWrapper.getOidFieldName() + "  from " + queryWrapper.getTableName() + " start with " + parentFieldName
+                        + " is null connect by prior " + queryWrapper.getOidFieldName() + " = " + parentFieldName );
+            }else{
+                queryWrapper.isNull(parentFieldName);
+            }
+        }
+        return  queryWrapper;
+    }
+
+    /**
+     * 灏嗘暟鎹璞¤浆鎹负鏍戝舰
+     * @param doList 鏁版嵁瀵硅薄
+     * @param wrapperOptions 灏佽鐨勪俊鎭�
+     * @return 鏍戝垪琛�
+     */
+    public <T,R> List<Tree> doList2Trees(List<T> doList, TreeWrapperOptions wrapperOptions, Function<T,R> f){
+        if(CollectionUtils.isEmpty(doList)){
+            return new ArrayList<>();
+        }
+        List<Tree> allTree = new ArrayList<Tree>();
+        List<Tree> children = new ArrayList<Tree>();
+        for (T doObject: doList) {
+            Tree tree =new Tree();
+            List<String> oidFieldNames = VciBaseUtil.str2List(wrapperOptions.getOidFieldName());
+            List<String> oidValues = new LinkedList<>();
+            oidFieldNames.stream().forEach( s->{
+                oidValues.add(VciBaseUtil.getStringValueFromObject(VciBaseUtil.getValueFromField(s,doObject)));
+            });
+            tree.setOid(oidValues.stream().collect(Collectors.joining(wrapperOptions.getOidValueSep())));
+            if(f !=null){
+                tree.setText((String)f.apply(doObject));
+            }else{
+                List<String> textFieldNames = VciBaseUtil.str2List(wrapperOptions.getTextFieldName());
+                List<String> textValues = new LinkedList<>();
+                textFieldNames.stream().forEach( s->{
+                    textValues.add(VciBaseUtil.getStringValueFromObject(VciBaseUtil.getValueFromField(s,doObject)));
+                });
+                tree.setText(textValues.stream().collect(Collectors.joining(wrapperOptions.getTextValueSep())));
+            }
+            if(StringUtils.isNotBlank(wrapperOptions.getParentFieldName())){
+                tree.setParentId(VciBaseUtil.getStringValueFromObject(VciBaseUtil.getValueFromField(wrapperOptions.getParentFieldName(),doObject)));
+            }
+            if(wrapperOptions.isAllAttributes()) {
+                try {
+                    tree.setAttributes(VciBaseUtil.objectToMapString(doObject));
+                } catch (Exception e) {
+                    //杩欓噷涓嶅仛澶勭悊
+                    if (logger.isErrorEnabled()) {
+                        logger.error("鎶婂璞¤浆鎹负map鏃跺嚭鐜颁簡閿欒锛屼絾鏄笉褰卞搷鏍戠殑灞曠ず锛屽涓氬姟鍙兘鏈夊奖鍝�");
+                    }
+                }
+            }
+            if(wrapperOptions.isMultipleSelect() || wrapperOptions.isShowCheckBox()){
+                tree.setShowCheckbox(true);
+            }
+            if(wrapperOptions.getParentOid() == null){
+                wrapperOptions.setParentOid("");
+            }
+            if(StringUtils.isBlank(tree.getParentId())
+                    || (StringUtils.isNotBlank(wrapperOptions.getParentOid()) && wrapperOptions.getParentOid().equalsIgnoreCase(tree.getParentId()))){
+                allTree.add(tree);
+            }else {
+                children.add(tree);
+            }
+        }
+        new Tree().findChild(allTree,children);
+
+        if(allTree.size()<=0){
+            allTree.addAll(children);
+        }
+        return allTree;
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/revision/service/VciRevisionServiceI.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/revision/service/VciRevisionServiceI.java
new file mode 100644
index 0000000..9eb56e2
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/revision/service/VciRevisionServiceI.java
@@ -0,0 +1,104 @@
+package com.vci.starter.revision.service;
+
+import com.vci.starter.revision.model.*;
+
+/**
+ * 鐗堟湰澶勭悊鎵�闇�瑕佺殑sql鎿嶄綔銆傚洜涓鸿鏌ヨ鏁版嵁搴擄紝鎵�浠ユ斁鍒癲ataBase杩欎釜starter涓�
+ * @author weidy
+ * @date 2020/4/15
+ */
+public interface VciRevisionServiceI {
+
+    /**
+     * 鑾峰彇鏈�鍚庝竴涓増鏈殑淇℃伅
+     * @param nameOid 瀵硅薄涓婚敭
+     * @param tableName 鏁版嵁搴撹〃鏍�
+     * @return 鏈�鍚庝竴涓増鏈俊鎭紝瀹冧笉涓�瀹氭槸鍙戝竷鐨勭増鏈�
+     */
+    RevisionInfo selectLastRevision(String nameOid,String tableName);
+
+    /**
+     * 鑾峰彇鏈�鍚庝竴涓増娆$殑淇℃伅
+     * @param nameOid 瀵硅薄鐨勪富閿�
+     * @param revisionOid 鐗堟湰鐨勪富閿�
+     * @param tableName 鏁版嵁搴撹〃鏍�
+     * @return
+     */
+    RevisionInfo selectLastVersion(String nameOid, String revisionOid,String tableName);
+
+    /**
+     * 鑾峰彇宸插彂甯冪殑鐗堟湰鐨勬暟鎹��
+     * @param nameOid 瀵硅薄鐨勪富閿�
+     * @param btmName 涓氬姟绫诲瀷鐨勫悕绉�
+     * @param tableName 鏁版嵁搴撹〃鏍�
+     * @return 鐗堟湰淇℃伅
+     */
+    RevisionInfo selectRelease(String nameOid, String btmName, String tableName);
+
+    /**
+     * 娣诲姞鍙戝竷鐨勬暟鎹�,濡傛灉瀛樺湪鍒欐洿鏂帮紝濡傛灉涓嶅瓨鍦ㄥ垯鎻掑叆
+     * @param releasedObj 鍙戝竷鐗堟湰鐨勬暟鎹�
+     * @return 鍙楀奖鍝嶇殑琛屾暟
+     */
+    int saveReleased(ReleasedObjDO releasedObj);
+
+    /**
+     * 鎶婃渶鍚庝竴涓増鏈噸缃甶sLastR
+     * @param nameOid 瀵硅薄鐨勪富閿�
+     * @param tableName 琛ㄦ牸鍚嶇О
+     * @return 鍙楀奖鍝嶇殑琛屾暟
+     */
+    int resetLastRevision(String nameOid,String tableName);
+
+    /**
+     * 閲嶇疆鑰佺増鏈殑isLastR
+     * @param oid 鑰佺増鏈殑涓婚敭
+     * @param tableName 琛ㄦ牸鍚嶇О
+     * @return 鍙楀奖鍝嶇殑琛屾暟
+     */
+    int resetOldRevision(String oid,String tableName);
+
+    /**
+     * 閫氳繃鑰佺増鏈殑涓婚敭鏉ヨ幏鍙栫増鏈俊鎭�
+     * @param copyFromVersion 鏂扮増鏈娇鐢ㄧ殑鑰佺増鏈殑涓婚敭
+     * @param tableName 琛ㄦ牸鍚嶇О
+     * @return 鐗堟湰淇℃伅
+     */
+    RevisionInfo selectByOid(String copyFromVersion,String tableName);
+
+    /**
+     * 閲嶇疆浠ュ墠鐨勬渶鏂扮増娆�
+     * @param nameOid 瀵硅薄鐨勪富閿�
+     * @param revisionOid 鐗堟湰鐨勪富閿�
+     * @param tableName 琛ㄦ牸鍚嶇О
+     * @return 鍙楀奖鍝嶇殑琛屾暟
+     */
+    int resetLastVersion(String nameOid, String revisionOid,String tableName);
+
+    /**
+     * 閲嶇疆鑰佺増娆★紙瀹冧笉涓�瀹氭槸鏈�鏂扮殑锛�
+     * @param oid 鑰佺増娆$殑涓婚敭
+     * @param tableName 琛ㄦ牸鍚嶇О
+     * @return 鍙楀奖鍝嶇殑琛屾暟
+     */
+    int resetOldVersion(String oid,String tableName);
+
+    /**
+     * 鏌ヨ灞炴�х瓑浜庢煇涓�肩殑鏁版嵁鏉℃暟锛屽父鐢ㄤ簬鍒ゆ柇鏁版嵁鏄惁閲嶅
+     * @param key 灞炴�х殑鍚嶇О
+     * @param value 灞炴�х殑鍊�
+     * @param tableName 琛ㄦ牸鐨勫悕绉�
+     * @return 涓暟
+     */
+    int countByProperties(String key,Object value,String tableName);
+
+    /**
+     * 鏌ヨ灞炴�х瓑浜庢煇涓�煎苟涓斾笉鏄煇涓富閿殑鏁版嵁鏉℃暟锛屽父鐢ㄤ簬淇敼鏁版嵁鏃跺垽鏂暟鎹槸鍚﹂噸澶�
+     * @param key 灞炴�х殑鍚嶇О
+     * @param value 灞炴�х殑鍊�
+     * @param tableName 琛ㄦ牸鐨勫悕绉�
+     * @param oid 涓婚敭
+     * @return 鏁版嵁涓暟
+     */
+    int countByPropertiesNotIncludeSelf(String key,Object value,String tableName,String oid);
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/undo/bo/UndoTaskBO.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/undo/bo/UndoTaskBO.java
new file mode 100644
index 0000000..6b93412
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/undo/bo/UndoTaskBO.java
@@ -0,0 +1,63 @@
+package com.vci.starter.undo.bo;
+
+import com.vci.starter.web.pagemodel.SessionInfo;
+
+/**
+ * 寰呭姙浠诲姟鐨勫唴瀹�
+ * @author weidy
+ * @date 2022/8/1
+ */
+public class UndoTaskBO implements java.io.Serializable{
+
+    /**
+     * 搴忓垪鍖�
+     */
+    private static final long serialVersionUID = -4189123149238900765L;
+    /**
+     * 鐢ㄦ埛鐨勪細璇濅俊鎭�
+     */
+    private SessionInfo sessionInfo;
+
+    /**
+     * 榛樿鐨勮闂矾寰勫墠缂�锛屾垜浠嚜琛屽喅瀹氱殑
+     */
+    private String defaultUrl;
+
+    /**
+     * 浠诲姟鐨勭被鍨�
+     */
+    private String taskType;
+
+    public SessionInfo getSessionInfo() {
+        return sessionInfo;
+    }
+
+    public void setSessionInfo(SessionInfo sessionInfo) {
+        this.sessionInfo = sessionInfo;
+    }
+
+    public String getDefaultUrl() {
+        return defaultUrl;
+    }
+
+    public void setDefaultUrl(String defaultUrl) {
+        this.defaultUrl = defaultUrl;
+    }
+
+    public String getTaskType() {
+        return taskType;
+    }
+
+    public void setTaskType(String taskType) {
+        this.taskType = taskType;
+    }
+
+    @Override
+    public String toString() {
+        return "UndoTaskBO{" +
+                "sessionInfo=" + sessionInfo +
+                ", defaultUrl='" + defaultUrl + '\'' +
+                ", taskType='" + taskType + '\'' +
+                '}';
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/undo/query/UndoTaskQuery.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/undo/query/UndoTaskQuery.java
new file mode 100644
index 0000000..e555a67
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/undo/query/UndoTaskQuery.java
@@ -0,0 +1,147 @@
+package com.vci.starter.undo.query;
+import com.vci.starter.web.pagemodel.SessionInfo;
+
+/**
+ * 寰呭姙浠诲姟鐨勬煡璇㈠璞�
+ * @author weidy
+ * @date 2022/8/1
+ */
+public class UndoTaskQuery implements java.io.Serializable{
+
+    /**
+     * 搴忓垪鍖�
+     */
+    private static final long serialVersionUID = 6668428964443134603L;
+
+    /**
+     * 褰撳墠椤�
+     */
+    private Integer page;
+
+    /**
+     * 鏌ヨ
+     */
+    private String title;
+
+    /**
+     * 姣忛〉鏄剧ず椤垫暟
+     */
+    private Integer limit = 25;
+
+    /**
+     * 寮�濮嬫椂闂�
+     */
+    private String startTime;
+
+    /**
+     * 寮�濮嬫椂闂�-璧峰
+     */
+    private String startTime_begin;
+
+    /**
+     * 寮�濮嬫椂闂�-缁堟
+     */
+    private String startTime_end;
+
+    /**
+     * 缁撴潫鏃堕棿
+     */
+    private String endTime;
+
+    /**
+     * 缁撴潫鏃堕棿--璧峰
+     */
+    private String endTime_begin;
+
+    /**
+     * 缁撴潫鏃堕棿--缁堟
+     */
+    private String endTime_end;
+
+    public Integer getPage() {
+        return page;
+    }
+
+    public void setPage(Integer page) {
+        this.page = page;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public Integer getLimit() {
+        return limit;
+    }
+
+    public void setLimit(Integer limit) {
+        this.limit = limit;
+    }
+
+    public String getStartTime() {
+        return startTime;
+    }
+
+    public void setStartTime(String startTime) {
+        this.startTime = startTime;
+    }
+
+    public String getStartTime_begin() {
+        return startTime_begin;
+    }
+
+    public void setStartTime_begin(String startTime_begin) {
+        this.startTime_begin = startTime_begin;
+    }
+
+    public String getStartTime_end() {
+        return startTime_end;
+    }
+
+    public void setStartTime_end(String startTime_end) {
+        this.startTime_end = startTime_end;
+    }
+
+    public String getEndTime() {
+        return endTime;
+    }
+
+    public void setEndTime(String endTime) {
+        this.endTime = endTime;
+    }
+
+    public String getEndTime_begin() {
+        return endTime_begin;
+    }
+
+    public void setEndTime_begin(String endTime_begin) {
+        this.endTime_begin = endTime_begin;
+    }
+
+    public String getEndTime_end() {
+        return endTime_end;
+    }
+
+    public void setEndTime_end(String endTime_end) {
+        this.endTime_end = endTime_end;
+    }
+
+    @Override
+    public String toString() {
+        return "UndoTaskQuery{" +
+                ", page=" + page +
+                ", title='" + title + '\'' +
+                ", limit=" + limit +
+                ", startTime='" + startTime + '\'' +
+                ", startTime_begin='" + startTime_begin + '\'' +
+                ", startTime_end='" + startTime_end + '\'' +
+                ", endTime='" + endTime + '\'' +
+                ", endTime_begin='" + endTime_begin + '\'' +
+                ", endTime_end='" + endTime_end + '\'' +
+                "} " + super.toString();
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/undo/vo/UndoTaskVO.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/undo/vo/UndoTaskVO.java
new file mode 100644
index 0000000..c6f6554
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/undo/vo/UndoTaskVO.java
@@ -0,0 +1,145 @@
+package com.vci.starter.undo.vo;
+
+/**
+ * 寰呭姙鐨勪俊鎭�
+ * @author weidy
+ * @date 2022/8/1
+ */
+public class UndoTaskVO implements java.io.Serializable{
+
+    /**
+     * 搴忓垪鍖�
+     */
+    private static final long serialVersionUID = 393050238018013429L;
+    /**
+     * 涓婚敭--鍙互涓虹┖
+     */
+    private String oid;
+
+    /**
+     * 浠诲姟鐨勫悕绉�
+     */
+    private String taskName;
+
+    /**
+     * 澶勭悊浜哄鍚�
+     */
+    private String appSendName;
+
+    /**
+     * 浠诲姟鐨勭被鍨�
+     */
+    private String taskType;
+
+    /**
+     * 鍙戦�佹椂闂�
+     */
+    private String sendTime;
+
+    /**
+     * 缁撴潫鏃堕棿-鍙兘涓虹┖
+     */
+    private String endTime;
+
+    /**
+     * 绱ф�ョ▼搴︼紝0-鐗规�ワ紝1-绱ф�ワ紝2锛�-涓�鑸紝
+     */
+    private Integer priority = 2;
+
+    /**
+     * 寰呭姙鐨勪换鍔″湴鍧�
+     */
+    private String url;
+
+    /**
+     * 寰呭姙鐨勬弿杩�
+     */
+    private String taskDesc;
+
+    public String getOid() {
+        return oid;
+    }
+
+    public void setOid(String oid) {
+        this.oid = oid;
+    }
+
+    public String getTaskName() {
+        return taskName;
+    }
+
+    public void setTaskName(String taskName) {
+        this.taskName = taskName;
+    }
+
+    public String getAppSendName() {
+        return appSendName;
+    }
+
+    public void setAppSendName(String appSendName) {
+        this.appSendName = appSendName;
+    }
+
+    public String getTaskType() {
+        return taskType;
+    }
+
+    public void setTaskType(String taskType) {
+        this.taskType = taskType;
+    }
+
+    public String getSendTime() {
+        return sendTime;
+    }
+
+    public void setSendTime(String sendTime) {
+        this.sendTime = sendTime;
+    }
+
+    public String getEndTime() {
+        return endTime;
+    }
+
+    public void setEndTime(String endTime) {
+        this.endTime = endTime;
+    }
+
+    public Integer getPriority() {
+        return priority;
+    }
+
+    public void setPriority(Integer priority) {
+        this.priority = priority;
+    }
+
+    public String getUrl() {
+        return url;
+    }
+
+    public void setUrl(String url) {
+        this.url = url;
+    }
+
+    public String getTaskDesc() {
+        return taskDesc;
+    }
+
+    public void setTaskDesc(String taskDesc) {
+        this.taskDesc = taskDesc;
+    }
+
+    @Override
+    public String toString() {
+        return "UndoTaskVO{" +
+                "oid='" + oid + '\'' +
+                ", taskName='" + taskName + '\'' +
+                ", appSendName='" + appSendName + '\'' +
+                ", taskType='" + taskType + '\'' +
+                ", sendTime='" + sendTime + '\'' +
+                ", endTime='" + endTime + '\'' +
+                ", priority=" + priority +
+                ", url='" + url + '\'' +
+                ", taskDesc='" + taskDesc + '\'' +
+                '}';
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/Column.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/Column.java
new file mode 100644
index 0000000..351d886
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/Column.java
@@ -0,0 +1,101 @@
+package com.vci.starter.web.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 鏁版嵁搴撶殑瀛楁鏄犲皠,瀵硅薄涓嶣O灞炴�ф槧灏�
+ * @author weidy
+ *
+ */
+@Target({ java.lang.annotation.ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Column {
+	/**
+	 * 鍚嶇О锛屽鏋滅浉鍚岋紙涓嶅尯鍒嗗ぇ灏忓啓锛夊彲浠ヤ笉杈撳叆
+	 * @return 榛樿涓虹┖
+	 */
+     String name() default "";
+    
+    /**
+     * 鏄惁鍞竴
+     * @return 榛樿涓嶅敮涓�
+     */
+     boolean unique() default false;
+
+    /**
+     * 鏍¢獙鍞竴鐨勬椂鍊欙紝涓嶅尯鍒嗗ぇ灏忓啓
+     * @return 榛樿鍖哄垎
+     */
+     boolean unUniqueCase() default  false;
+
+    /**
+     * 鏄惁鍙互涓虹┖ true琛ㄧず鍙互涓虹┖锛沠alse琛ㄧず涓嶈兘涓虹┖
+     * @return 榛樿鍙互涓虹┖
+     */
+    boolean nullable() default true;
+
+    /**
+     * 鎻忚堪
+     * @return 榛樿涓虹┖
+     */
+     String columnDefinition() default "";
+
+    /**
+     * 闀垮害
+     * @return 榛樿涓�0
+     */
+     int length() default 0;
+
+    /**
+     * 绮惧害
+     * @return 榛樿涓�0
+     */
+    int precision() default 0;
+
+    /**
+     * 鍒诲害-double浣跨敤
+     * @return 榛樿涓�2
+     */
+    int scale() default 2;
+
+    
+    /**
+     * 鍙傜収瀛楁鏄剧ず鐨勫瓧娈�
+     * @return 榛樿涓虹┖
+     */
+    String showTextField() default "";
+
+    /**
+     * 浣跨敤鏋氫妇
+     * @return 鏋氫妇鐨勮嫳鏂囧悕绉�
+     */
+     String useEnum() default "";
+
+    /**
+     * 浣跨敤鍙傜収
+     * @return 寮曠敤鐨勪笟鍔$被鍨嬬殑鑻辨枃鍚嶇О
+     */
+    String useRefer() default "";
+
+    /**
+     * 鍊艰寖鍥�
+     * @return 澶氫釜鑼冨洿鐨勫��
+     */
+     String[] range() default "";
+
+    /**
+     * 榛樿鍊硷紝濡傛灉鏄棩鏈熸垨鑰呮暟瀛楀舰寮忕殑鏃跺�欙紝涔熺洿鎺ヨ浆鎹㈠瓧绗︿覆
+     * @return 榛樿涓虹┖
+     */
+    String defaultValue() default "";
+
+    /**
+     * 浣跨敤鍏朵粬鍙傜収瀛楁鐨勫叧鑱斿睘鎬�
+     * @return 榛樿涓虹┖
+     */
+    String referColumnName() default "";
+
+    
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/Id.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/Id.java
new file mode 100644
index 0000000..a0403c3
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/Id.java
@@ -0,0 +1,11 @@
+package com.vci.starter.web.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target({java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Id {
+	boolean value() default true;
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/LifeCycleEvent.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/LifeCycleEvent.java
new file mode 100644
index 0000000..60fa8d9
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/LifeCycleEvent.java
@@ -0,0 +1,26 @@
+package com.vci.starter.web.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 鐢熷懡鍛ㄦ湡浜嬩欢瀹氫箟
+ * @author weidy
+ */
+@Target({java.lang.annotation.ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface LifeCycleEvent {
+    /**
+     * 浜嬩欢鏄剧ず鏂囨湰
+     * @return
+     */
+    String text() ;
+
+    /**
+     * 浜嬩欢鎻忚堪
+     * @return
+     */
+    String description() default "";
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/SOAService.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/SOAService.java
new file mode 100644
index 0000000..8bfb386
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/SOAService.java
@@ -0,0 +1,32 @@
+package com.vci.starter.web.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 鏈嶅姟绔畾涔夛紝鐢ㄦ埛璁剧疆corba绛夋湇鍔$殑鍚嶇О锛岄粯璁や负浣跨敤杩欎釜娉ㄨВ鐨勭被鐨勯瀛楁瘝灏忓啓
+ * @author weidy
+ */
+@Target({java.lang.annotation.ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface SOAService {
+    /**
+     * 鏈嶅姟鐨勫悕瀛�
+     * @return 鏈嶅姟鐨勫悕绉帮紝濡傛灉娌℃湁璁剧疆榛樿涓烘敞瑙g被鐨勯瀛楁瘝灏忓啓
+     */
+    String value() default "";
+
+    /**
+     * 鏈嶅姟鐨勭被鍨�
+     * @return 鏈嶅姟绫诲瀷鏋氫妇
+     */
+    SOASericeType serviceType() default SOASericeType.CORBA;
+
+    /**
+     * 鏈嶅姟鐨勭被鍨嬫灇涓惧畾涔�
+     */
+    public static enum SOASericeType{
+        CORBA,THRIFT,WEBSERVICE,SOCKET
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/Transient.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/Transient.java
new file mode 100644
index 0000000..9626279
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/Transient.java
@@ -0,0 +1,23 @@
+package com.vci.starter.web.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target({java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Transient {
+	boolean value() default true;
+	/**
+	 * 鍙傜収鍒楁垨鑰呮灇涓惧垪;鍙傜収鐨勫垪涓簒xx.name锛涙灇涓惧垪涓烘灇涓剧紪鍙穇鏋氫妇鍊肩殑灞炴��
+	 * @return
+	 */
+	String referColumn() default "";
+
+	/**
+	 * 鍏宠仈鐨勫�肩殑瀛楁锛岄粯璁や负oid
+	 * @return 瀛楁鐨勫悕绉�
+	 */
+	String valueField() default "oid";
+	
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciBtmType.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciBtmType.java
new file mode 100644
index 0000000..783b879
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciBtmType.java
@@ -0,0 +1,143 @@
+package com.vci.starter.web.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target({java.lang.annotation.ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface VciBtmType {
+
+    /**
+     * 鑻辨枃鍚嶇О
+     * @return 鑻辨枃鍚嶇О
+     */
+    String name() default "";
+
+
+    /**
+     * 鏄剧ず鏂囨湰
+     * @return 鏄剧ず鏂囨湰
+     */
+    String text() default "";
+
+    /**
+     * 鎻忚堪
+     * @return 鎻忚堪
+     */
+    String description() default "";
+
+    /**
+     * 琛ㄦ牸鍚嶇О
+     * @return 琛ㄦ牸鍚嶇О
+     */
+    String tableName() default "";
+
+    /**
+     *鏄惁鍙互鎵嬪姩杈撳叆鐗堟湰
+     * @return true琛ㄧず鎵嬪姩杈撳叆鐗堟湰
+     */
+    boolean revisionRuleInput() default false;
+
+    /**
+     * 鐗堟湰瑙勫垯
+     * @return 鐗堟湰瑙勭▼
+     */
+    String revisionRule() default "";
+
+    /**
+     *  鐗堟鍙疯鍒�
+     * @return 鐗堟鍙疯鍒�
+     */
+    VciBtmTypeVersionRule versionRule() default VciBtmTypeVersionRule.NONE;
+
+    /**
+     * 褰撴槸瀛楁瘝鍜屾暟瀛楃殑瑙勫垯鐨勬椂鍊欙紝鍙互璁剧疆鍓嶇紑
+     * @return 鍓嶇紑
+     */
+    String revisionRulePrefix() default "";
+
+    /**
+     * 褰撴槸瀛楁瘝鍜屾暟瀛楃殑瑙勫垯鐨勬椂鍊欙紝鍙互璁剧疆鍚庣紑
+     * @return 鍚庣紑鐨勫��
+     */
+    String revisionRuleSubfix() default "";
+
+    /**
+     * 鎵�灞炵敓鍛藉懆鏈�
+     * @return 涓荤敓鍛藉懆鏈�
+     */
+    String lifeCycle() ;
+
+    /**
+     * 鐢熷懡鍛ㄦ湡鐨勫垵濮嬬殑鍊硷紝杩欎釜娉ㄨВ鐨勪紭鍏堢骇澶т簬鐢熷懡鍛ㄦ湡鐨勮捣濮嬬姸鎬�
+     * @return 鍒濆鐘舵�侊紝浼樺厛绾ф渶楂�
+     */
+    String startStatus() default "";
+
+    /**
+     * 澶囩敤鐢熷懡鍛ㄦ湡
+     * @return 澶囩敤鐢熷懡鍛ㄦ湡鍒楄〃鎴栬�呯┖
+     */
+    String[] subLifeCycle() default "";
+
+    /**
+     * 鏄惁绠$悊瀵嗙骇
+     * @return true琛ㄧず闇�瑕佺鐞�
+     */
+    boolean secretAble() default false;
+
+    /**
+     * 鏄惁鍏煎浠ュ墠鐨勫钩鍙�
+     * @return true琛ㄧず鍏煎锛屼細瀵归粯璁ょ殑灞炴�ф湁涓嶅悓鐨勫鐞�
+     */
+    boolean compatbility() default false;
+
+    /**
+     * 涓婄骇鐨勫瓧娈靛悕瀛�
+     * @return 涓婄骇瀛楁
+     */
+    String parentField() default "";
+
+    /**
+     * 鐗堟鐗堟湰鐨勬灇涓�
+     */
+    public enum VciBtmTypeVersionRule {
+        /**
+         * 浠�1寮�濮嬬殑鑷劧鏁�
+         */
+        INTSTART1("int1"),
+        /**
+         * 浠�0寮�鐨勮嚜鐒舵暟
+         */
+        INTSTART0("int0"),
+        /**
+         * 涓嶄娇鐢ㄧ増娆�
+         */
+        NONE("none"),
+        /**
+         * 澶у啓瀛楁瘝A寮�濮�
+         */
+        LETTER("letter");
+        private String value;
+
+        /**
+         * 鏋氫妇鏋勯�犲嚱鏁�
+         * @param value 鏋氫妇鐨勫��
+         */
+        private VciBtmTypeVersionRule(String value) {
+            this.value = value;
+        }
+
+        /**
+         * 鑾峰彇鏋氫妇鐨勫��
+         * @return 鏋氫妇鐨勫��
+         */
+        public String getValue() {
+            return value;
+        }
+
+    }
+
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciColumnDefinition.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciColumnDefinition.java
new file mode 100644
index 0000000..2855b81
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciColumnDefinition.java
@@ -0,0 +1,20 @@
+package com.vci.starter.web.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 鍒楁弿杩�
+ */
+@Target({ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface VciColumnDefinition {
+
+    /**
+     * 鍏蜂綋鐨勫��
+     * @return
+     */
+    String value();
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciEnum.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciEnum.java
new file mode 100644
index 0000000..fbd0156
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciEnum.java
@@ -0,0 +1,38 @@
+package com.vci.starter.web.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 鏋氫妇瀹氫箟
+ * @author weidy
+ */
+@Target({java.lang.annotation.ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface VciEnum {
+
+    /**
+     * 鑻辨枃鍚嶇О
+     * @return
+     */
+    String name() default "";
+
+    /**
+     * 鍊肩被鍨嬶紝榛樿涓哄瓧绗︿覆
+     * @return
+     */
+    Class valueType() default java.lang.String.class;
+
+    /**
+     * 鏄剧ず鏂囨湰
+     * @return
+     */
+    String text() default "";
+
+    /**
+     * 鎻忚堪
+     * @return
+     */
+    String description() default "";
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciFieldType.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciFieldType.java
new file mode 100644
index 0000000..0a9e6ba
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciFieldType.java
@@ -0,0 +1,22 @@
+package com.vci.starter.web.annotation;
+
+
+import com.vci.starter.web.enumpck.VciFieldTypeEnum;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * VCI骞冲彴涓墍灞炵殑瀛楁绫诲瀷
+ * @author weidy
+ */
+@Target({java.lang.annotation.ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface VciFieldType {
+    /**
+     * 绫诲瀷鐨勫�硷紝榛樿涓哄瓧绗︿覆
+     * @return
+     */
+    VciFieldTypeEnum value() default VciFieldTypeEnum.VTString;
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciLifeCycle.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciLifeCycle.java
new file mode 100644
index 0000000..db452de
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciLifeCycle.java
@@ -0,0 +1,44 @@
+package com.vci.starter.web.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 鐢熷懡鍛ㄦ湡瀵硅薄瀹氫箟锛屽湪鍏朵腑瀹氫箟涓婂熀鏈俊鎭紝鍦ㄤ娇鐢ㄨ繖涓敞瑙g殑瀵硅薄涓婂畾涔夌姸鎬侊紝鍜屾祦鍚�
+ * @author weidy
+ */
+@Target({java.lang.annotation.ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface VciLifeCycle {
+
+    /**
+     * 鑻辨枃鍚嶇О
+     * @return
+     */
+    String name() default "";
+
+    /**
+     * 璧峰鐘舵��
+     * @return
+     */
+    String startStatus() default "";
+
+    /**
+     * 鏄剧ず鏂囨湰
+     * @return
+     */
+    String text() default "";
+
+    /**
+     * 鎻忚堪
+     * @return
+     */
+    String description() default "";
+
+    /**
+     * 杩炴帴绾�
+     * @return
+     */
+    VciLifeCycleTrans[] translations() default @VciLifeCycleTrans(source = "",target = "",name="");
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciLifeCycleTranEvent.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciLifeCycleTranEvent.java
new file mode 100644
index 0000000..3483472
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciLifeCycleTranEvent.java
@@ -0,0 +1,28 @@
+package com.vci.starter.web.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 鐢熷懡鍛ㄦ湡杩炴帴绾跨殑浜嬩欢
+ * @author weidy
+ */
+@Target({ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface VciLifeCycleTranEvent {
+
+    /**
+     * 绫诲叏璺緞
+     * @return 绫昏矾寰勫悕绉�
+     */
+    String classFullName() ;
+
+    /**
+     * 鏄剧ず鍚嶇О
+     * @return 鏄剧ず鍚嶇О
+     */
+    String showName();
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciLifeCycleTrans.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciLifeCycleTrans.java
new file mode 100644
index 0000000..61b4653
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciLifeCycleTrans.java
@@ -0,0 +1,41 @@
+package com.vci.starter.web.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 鐢熷懡鍛ㄦ湡鐘舵�佹祦鍚�
+ * @author weidy
+ */
+@Target({java.lang.annotation.ElementType.TYPE, ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface VciLifeCycleTrans {
+
+    /**
+     * 璧峰鐘舵��
+     * @return
+     */
+    String source() default "";
+
+    /**
+     * 鐩爣鐘舵��
+     * @return
+     */
+    String target() default "";
+
+    /**
+     * 鍚嶇О
+     * @return
+     */
+    String name() ;
+
+    /**
+     * 鎵�闇�浜嬩欢
+     * @return
+     */
+    VciLifeCycleTranEvent[] listeners() default  @VciLifeCycleTranEvent(classFullName = "",showName = "");
+
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciLinkType.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciLinkType.java
new file mode 100644
index 0000000..1402f12
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciLinkType.java
@@ -0,0 +1,57 @@
+package com.vci.starter.web.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 閾炬帴绫诲瀷
+ */
+@Target({java.lang.annotation.ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface VciLinkType {
+
+    /**
+     * 鑻辨枃鍚嶇О
+     * @return
+     */
+    String name() default "";
+
+
+    /**
+     * 鏄剧ず鏂囨湰
+     * @return
+     */
+    String text() default "";
+
+    /**
+     * 鎻忚堪
+     * @return
+     */
+    String description() default "";
+
+    /**
+     * 琛ㄦ牸鍚嶇О
+     * @return
+     */
+    String tableName() default "";
+
+    /**
+     * from绔�
+     * @return
+     */
+    String[] fromBtmTypes() ;
+
+    /**
+     * to绔�
+     * @return
+     */
+    String[] toBtmTypes();
+
+    /**
+     * 鏄惁绠$悊瀵嗙骇
+     * @return true琛ㄧず闇�瑕佺鐞�
+     */
+    boolean secretAble() default false;
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciPlatformScan.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciPlatformScan.java
new file mode 100644
index 0000000..bd0e25d
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciPlatformScan.java
@@ -0,0 +1,21 @@
+package com.vci.starter.web.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * vci骞冲彴鎵弿鐨勫寘锛屼細鑷姩鎵弿涓氬姟绫诲瀷锛岄摼鎺ョ被鍨嬶紝鏋氫妇锛岀敓鍛藉懆鏈燂紝鐗堟湰瑙勫垯
+ * @author weidy
+ */
+@Target({java.lang.annotation.ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface VciPlatformScan {
+
+    /**
+     * 鍖呭悕,鍒颁粈涔堝寘寮�濮嬪氨琛岋紝浼氳嚜鍔ㄦ壘瀹冪殑涓嬬骇鍖�
+     * @return
+     */
+    String[] value();
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciRevisionRule.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciRevisionRule.java
new file mode 100644
index 0000000..7f67a86
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciRevisionRule.java
@@ -0,0 +1,62 @@
+package com.vci.starter.web.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 鐗堟湰瑙勫垯瀹氫箟
+ * @author weidy
+ */
+@Target({java.lang.annotation.ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface VciRevisionRule {
+
+    /**
+     * 鑻辨枃鍚嶇О
+     * @return
+     */
+    String name() ;
+
+    /**
+     * 鏄剧ず鏂囨湰
+     * @return
+     */
+    String text() ;
+
+    /**
+     * 鎻忚堪
+     * @return
+     */
+    String description() default "";
+
+    /**
+     * 璺宠穬瀛楃
+     * @return
+     */
+    String skipChar() default "";
+
+    /**
+     * 鍒濆瀛楃
+     * @return
+     */
+    String startChar() ;
+
+    /**
+     * 姝ラ暱
+     * @return
+     */
+    int stepNumber() default  1;
+
+    /**
+     * 鍓嶇紑
+     * @return
+     */
+    String prefixString() default  "";
+
+    /**
+     * 鍚庣紑
+     * @return
+     */
+    String suffixString() default "";
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciUseEnum.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciUseEnum.java
new file mode 100644
index 0000000..df88842
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciUseEnum.java
@@ -0,0 +1,42 @@
+package com.vci.starter.web.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 浣跨敤鏋氫妇
+ * @author weidy
+ */
+@Target({ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface VciUseEnum {
+
+    /**
+     * 浣跨敤鏋氫妇鐨勮嫳鏂囧悕绉�
+     * @return
+     */
+    String value() ;
+
+    /**
+     * 榛樿鐨勫��
+     * @return
+     */
+    String defaultValue() default "";
+
+    /**
+     * 鏄剧ず鐨勫瓧娈�
+     * @return
+     */
+     String showTextField() ;
+
+    /**
+     * 鏄惁瀛樺偍澶氫釜
+     * @return
+     */
+     boolean multiple() default false;
+
+
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciUseRefer.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciUseRefer.java
new file mode 100644
index 0000000..b402525
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/VciUseRefer.java
@@ -0,0 +1,26 @@
+package com.vci.starter.web.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 浣跨敤鍙傜収鐨勬敞瑙�
+ * @author weidy
+ */
+@Target({ ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface VciUseRefer {
+    /**
+     * 寮曠敤鐨勪笟鍔$被鍨�
+     * @return
+     */
+    String value();
+
+    /**
+     * 鏄剧ず鏂囨湰鐨勫瓧娈�
+     * @return
+     */
+    String showTextField() default "";
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/XmlType.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/XmlType.java
new file mode 100644
index 0000000..7ce60d5
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/XmlType.java
@@ -0,0 +1,22 @@
+package com.vci.starter.web.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 鏄惁涓簒mltype鐨勬牸寮�(鑰佸钩鍙帮級
+ * @author weidy
+ * @date 2022-2-15
+ */
+@Target({ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface XmlType {
+
+    /**
+     * 鍊�
+     * @return 鏄惁
+     */
+    boolean value() default true;
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/PortalTodoPublishImpl.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/PortalTodoPublishImpl.java
new file mode 100644
index 0000000..f8d9bdd
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/PortalTodoPublishImpl.java
@@ -0,0 +1,10 @@
+package com.vci.starter.web.annotation.bus;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target({java.lang.annotation.ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface PortalTodoPublishImpl {
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciChangeDataAfter.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciChangeDataAfter.java
new file mode 100644
index 0000000..81fd738
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciChangeDataAfter.java
@@ -0,0 +1,29 @@
+package com.vci.starter.web.annotation.bus;
+
+import com.vci.starter.web.enumpck.VciChangeDocumentTypeEnum;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 淇敼鏁版嵁鍚庣殑鎵ц鎻掍欢
+ * @author weidy
+ * @date 2020/1/29
+ */
+@Target({ ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface VciChangeDataAfter {
+
+    /**
+     * 瑕佺洃鍚殑涓氬姟绫诲瀷鐨勫悕绉�
+     * @return 涓氬姟绫诲瀷鐨勫悕绉�
+     */
+    String[] btmType() default "";
+
+    /**
+     * 瑕佺洃鍚慨鏀圭殑绫诲瀷
+     */
+    VciChangeDocumentTypeEnum[] changeType() default VciChangeDocumentTypeEnum.ALL;
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciChangeDataBefore.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciChangeDataBefore.java
new file mode 100644
index 0000000..3132bc9
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciChangeDataBefore.java
@@ -0,0 +1,29 @@
+package com.vci.starter.web.annotation.bus;
+
+import com.vci.starter.web.enumpck.VciChangeDocumentTypeEnum;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 淇敼鏁版嵁涔嬪墠鐨勬墽琛屾彃浠�
+ * @author weidy
+ * @date 2020/1/29
+ */
+@Target({ ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface VciChangeDataBefore {
+
+    /**
+     * 瑕佺洃鍚殑涓氬姟绫诲瀷鐨勫悕绉�
+     * @return 涓氬姟绫诲瀷鐨勫悕绉�
+     */
+    String[] btmType() default "";
+
+    /**
+     * 瑕佺洃鍚慨鏀圭殑绫诲瀷
+     */
+    VciChangeDocumentTypeEnum[] changeType() default VciChangeDocumentTypeEnum.ALL;
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciChangeDataPlugin.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciChangeDataPlugin.java
new file mode 100644
index 0000000..29a7b8e
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciChangeDataPlugin.java
@@ -0,0 +1,40 @@
+package com.vci.starter.web.annotation.bus;
+
+import com.vci.starter.web.enumpck.VciChangeDocumentTypeEnum;
+import org.springframework.core.annotation.AliasFor;
+import org.springframework.stereotype.Component;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 鏁版嵁鍙樺寲鐨勬墿灞曟彃浠�
+ * @author weidy
+ * @date 2020/2/23
+ */
+@Target({ ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Component
+public @interface VciChangeDataPlugin {
+    /**
+     * bean鐨勫悕绉�
+     * @return 榛樿涓洪鍐欏瓧姣嶅皬鍐�
+     */
+    @AliasFor(
+            annotation = Component.class
+    )
+    String value() default "";
+
+    /**
+     * 瑕佺洃鍚殑涓氬姟绫诲瀷鐨勫悕绉�
+     * @return 涓氬姟绫诲瀷鐨勫悕绉�
+     */
+    String[] btmType() default "";
+
+    /**
+     * 瑕佺洃鍚慨鏀圭殑绫诲瀷
+     */
+    VciChangeDocumentTypeEnum[] changeType() default VciChangeDocumentTypeEnum.ALL;
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciChangeDocument.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciChangeDocument.java
new file mode 100644
index 0000000..e9c111b
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciChangeDocument.java
@@ -0,0 +1,55 @@
+package com.vci.starter.web.annotation.bus;
+
+
+import com.vci.starter.web.enumpck.VciChangeDocumentTypeEnum;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 娣诲姞锛屼慨鏀癸紝鍒犻櫎鏁版嵁
+ * 缂撳瓨鏇存柊锛屽叏鏂囨绱紝缂栫爜瑙勫垯鐩戞帶绛�
+ * @author weidy
+ * @date 2020/3/29
+ */
+@Target({ ElementType.METHOD,ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface VciChangeDocument {
+    /**
+     * 涓氬姟绫诲瀷鐨勫悕绉�
+     * @return 涓氬姟绫诲瀷鐨勫悕绉�
+     */
+    String[] btmType() default "";
+
+    /**
+     * 涓婚敭鐨勫瓧娈碉紝鏀寔spel(spring鐨勮〃杈惧紡锛屽弬鑰冪紦瀛�
+     * @return 涓婚敭鐨勫瓧娈�
+     */
+    String[] oidField() default "";
+
+    /**
+     * 鍏宠仈鐨勪笟鍔$被鍨�
+     * @return 褰撳墠鐨勪笟鍔$被鍨嬪叧鑱旂殑涓氬姟绫诲瀷
+     */
+    String[] linkBtmType() default "";
+
+    /**
+     * 淇敼鐨勭被鍨�
+     */
+    VciChangeDocumentTypeEnum changeType() default VciChangeDocumentTypeEnum.ADD;
+
+    /**
+     * 涓嶅寘鍚殑琛ㄨ揪寮忥紝鏀寔spel
+     * @return
+     */
+    String unless() default "";
+
+    /**
+     * 鎺ュ彛鍒ゆ柇骞傜瓑鎬�
+     * @return 榛樿鏄紑鍚箓绛夋�э紝鍥犱负鍙瀵规暟鎹繘琛屽彉鏇撮兘搴旇娉ㄦ剰
+     */
+    boolean idempotence() default true;
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciLoginAfter.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciLoginAfter.java
new file mode 100644
index 0000000..f2f764b
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciLoginAfter.java
@@ -0,0 +1,16 @@
+package com.vci.starter.web.annotation.bus;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 鐧诲綍鍚庣殑浜嬩欢
+ * @author weidy
+ * @date 2020/1/29
+ */
+@Target({ ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface VciLoginAfter {
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciLoginBefore.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciLoginBefore.java
new file mode 100644
index 0000000..7953b2c
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciLoginBefore.java
@@ -0,0 +1,18 @@
+package com.vci.starter.web.annotation.bus;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ *
+ * 鐧诲綍涔嬪墠鐨勪簨浠�
+ * @author weidy
+ * @date 2020/1/29
+ */
+@Target({ ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface  VciLoginBefore {
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciLoginPlugin.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciLoginPlugin.java
new file mode 100644
index 0000000..9820834
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciLoginPlugin.java
@@ -0,0 +1,28 @@
+package com.vci.starter.web.annotation.bus;
+
+import org.springframework.core.annotation.AliasFor;
+import org.springframework.stereotype.Component;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 鐧诲綍鐨勬彃浠�
+ * @author weidy
+ * @date 2020/2/23
+ */
+@Target({ ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Component
+public @interface VciLoginPlugin {
+    /**
+     * bean鐨勫悕绉�
+     * @return
+     */
+    @AliasFor(
+            annotation = Component.class
+    )
+    String value() default "";
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciLogoutAfter.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciLogoutAfter.java
new file mode 100644
index 0000000..787da1b
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciLogoutAfter.java
@@ -0,0 +1,17 @@
+package com.vci.starter.web.annotation.bus;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 閫�鍑虹郴缁熶箣鍚�
+ * @author weidy
+ * @date 2020/1/29
+ */
+@Target({ ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface VciLogoutAfter {
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciLogoutBefore.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciLogoutBefore.java
new file mode 100644
index 0000000..abaa981
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciLogoutBefore.java
@@ -0,0 +1,16 @@
+package com.vci.starter.web.annotation.bus;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 閫�鍑虹郴缁熶箣鍓嶄簨浠�
+ * @author weidy
+ * @date 2020/1/29
+ */
+@Target({ ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface VciLogoutBefore {
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciLogoutPlugin.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciLogoutPlugin.java
new file mode 100644
index 0000000..6b7f61a
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciLogoutPlugin.java
@@ -0,0 +1,28 @@
+package com.vci.starter.web.annotation.bus;
+
+import org.springframework.core.annotation.AliasFor;
+import org.springframework.stereotype.Component;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 閫�鍑虹櫥褰曠殑鎻掍欢
+ * @author weidy
+ * @date 2020/2/23
+ */
+@Target({ ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Component
+public @interface VciLogoutPlugin {
+    /**
+     * bean鐨勫悕绉�
+     * @return
+     */
+    @AliasFor(
+            annotation = Component.class
+    )
+    String value() default "";
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciNoUseBaseResult.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciNoUseBaseResult.java
new file mode 100644
index 0000000..0db0a4d
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciNoUseBaseResult.java
@@ -0,0 +1,16 @@
+package com.vci.starter.web.annotation.bus;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 涓嶄娇鐢ㄧ粺涓�鐨勬暟鎹璞¤繑鍥�
+ * @author weidy
+ * @date 2019/12/3 8:36 PM
+ */
+@Target({ java.lang.annotation.ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface VciNoUseBaseResult {
+    boolean value() default true;
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciTaskAfter.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciTaskAfter.java
new file mode 100644
index 0000000..76ae8e9
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciTaskAfter.java
@@ -0,0 +1,22 @@
+package com.vci.starter.web.annotation.bus;
+
+import com.vci.starter.web.enumpck.VciTaskBusTypeEnum;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 浠诲姟鍚庣疆鐨勪簨浠�
+ * @author weidy
+ * @date 2020/1/29
+ */
+@Target({ ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface VciTaskAfter {
+    /**
+     * 鍙樻洿绫诲瀷
+     */
+    VciTaskBusTypeEnum busTypeEnum();
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciTaskBefore.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciTaskBefore.java
new file mode 100644
index 0000000..e895f29
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciTaskBefore.java
@@ -0,0 +1,23 @@
+package com.vci.starter.web.annotation.bus;
+
+import com.vci.starter.web.enumpck.VciTaskBusTypeEnum;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ *
+ * 鎵ц浠诲姟涔嬪墠
+ * @author weidy
+ * @date 2020/1/29
+ */
+@Target({ ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface VciTaskBefore {
+    /**
+     * 鍙樻洿绫诲瀷
+     */
+    VciTaskBusTypeEnum busTypeEnum();
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciTaskPlugin.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciTaskPlugin.java
new file mode 100644
index 0000000..2a230ca
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/bus/VciTaskPlugin.java
@@ -0,0 +1,28 @@
+package com.vci.starter.web.annotation.bus;
+
+import org.springframework.core.annotation.AliasFor;
+import org.springframework.stereotype.Component;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 浠诲姟鐩稿叧鐨勬彃浠�
+ * @author weidy
+ * @date 2020/2/23
+ */
+@Target({ ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Component
+public @interface VciTaskPlugin {
+    /**
+     * bean鐨勫悕绉�
+     * @return 榛樿涓洪鍐欏瓧姣嶅皬鍐�
+     */
+    @AliasFor(
+            annotation = Component.class
+    )
+    String value() default "";
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/config/VciConfigField.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/config/VciConfigField.java
new file mode 100644
index 0000000..cc50bdf
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/config/VciConfigField.java
@@ -0,0 +1,61 @@
+package com.vci.starter.web.annotation.config;
+
+import org.springframework.core.annotation.AliasFor;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 閰嶇疆涓績鐨勬ā鍧椾笅鐨勯厤缃瓧娈�
+ * @author weidy
+ * @date 2020/2/5
+ */
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface VciConfigField {
+    /**
+     * 鍦ㄩ厤缃腑蹇冮噷鐨勯厤缃」
+     * @return
+     */
+    @AliasFor("name")
+    String value() default "";
+
+    /**
+     * 鍦ㄩ厤缃腑蹇冮噷鐨勯厤缃」鍚嶇О
+     * @return
+     */
+    String name() default "";
+
+    /**
+     * 鍦ㄩ厤缃腑蹇冮噷閰嶇疆椤圭殑鏍囬
+     * @return
+     */
+    String title();
+
+    /**
+     * 鎵�灞炴ā鍧楋紝鑷姩缁ф壙杩欎釜娉ㄨВ鎵�灞炵被涓婄殑娉ㄨВ
+     * @return
+     */
+    String model() default "";
+
+    /**
+     * 鏄惁淇敼鍚庣珛鍗崇敓鏁�
+     * @return
+     */
+    boolean effectOnEdit() default false;
+
+    /**
+     * 鏄惁澶氶��
+     * @return
+     */
+    boolean mutliValue() default false;
+
+    /**
+     * 鎻忚堪
+     * @return
+     */
+    String description() default "";
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/config/VciConfigFieldSelect.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/config/VciConfigFieldSelect.java
new file mode 100644
index 0000000..43a57c8
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/config/VciConfigFieldSelect.java
@@ -0,0 +1,44 @@
+package com.vci.starter.web.annotation.config;
+
+import org.springframework.core.annotation.AliasFor;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 閰嶇疆椤圭殑閫夋嫨椤甸潰閰嶇疆
+ * @author weidy
+ * @date 2020/2/5
+ */
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface VciConfigFieldSelect {
+
+    /**
+     * 鏄剧ず鐨刄rl鐨勫��
+     * @return
+     */
+    @AliasFor("url")
+    String value();
+
+    /**
+     * 鏄剧ず閫夋嫨鍊肩殑url
+     * @return
+     */
+    @AliasFor("url")
+    String url();
+
+    /**
+     * 鍊肩殑瀛楁
+     * @return
+     */
+    String valueField() default "oid";
+
+    /**
+     * 鏄剧ず鐨勫瓧娈�
+     * @return
+     */
+    String textField() default "name";
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/config/VciConfigModule.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/config/VciConfigModule.java
new file mode 100644
index 0000000..f5c57e8
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/config/VciConfigModule.java
@@ -0,0 +1,47 @@
+package com.vci.starter.web.annotation.config;
+
+import org.springframework.core.annotation.AliasFor;
+import org.springframework.stereotype.Component;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 閰嶇疆涓績鐨勬ā鍧�
+ * @author weidy
+ * @date 2020/2/5
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Component
+public @interface VciConfigModule {
+    /**
+     * bean鐨勫悕绉�
+     * @return
+     */
+    @AliasFor(
+            annotation = Component.class
+    )
+    String value() default "";
+
+    /**
+     * 鍚嶇О
+     * @return 鍦ㄩ厤缃腑蹇冪殑鍚嶇О
+     */
+    String name();
+
+    /**
+     * 鏍囬
+     * @return 鍦ㄩ厤缃腑蹇冩樉绀虹殑鏍囬
+     */
+    String title();
+
+    /**
+     * 鎻忚堪淇℃伅
+     * @return 鎻忚堪淇℃伅
+     */
+    String description() default "";
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/controller/VciReturnErrorUseFile.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/controller/VciReturnErrorUseFile.java
new file mode 100644
index 0000000..ac9295b
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/controller/VciReturnErrorUseFile.java
@@ -0,0 +1,18 @@
+package com.vci.starter.web.annotation.controller;
+
+import com.vci.starter.web.enumpck.VciReturnFileTypeEnum;
+
+/**
+ * 浣跨敤鏂囦欢杩斿洖閿欒淇℃伅
+ * @author weidy
+ * @date 2020/2/19
+ */
+public @interface VciReturnErrorUseFile {
+
+    /**
+     * 榛樿涓烘枃鏈枃浠�
+     * @return
+     */
+    VciReturnFileTypeEnum value() default VciReturnFileTypeEnum.TXT;
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/controller/VciUnCheckRight.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/controller/VciUnCheckRight.java
new file mode 100644
index 0000000..e2d3f35
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/controller/VciUnCheckRight.java
@@ -0,0 +1,22 @@
+package com.vci.starter.web.annotation.controller;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 涓嶆牎楠屾潈闄愮殑璺緞
+ * @author weidy
+ * @date 2020/2/28
+ */
+@Target({ElementType.METHOD,ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface VciUnCheckRight {
+
+    /**
+     * 鍊硷紝鍙互涓嶈缃�
+     * @return true琛ㄧず涓嶆牎楠�
+     */
+    boolean value() default true;
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/controller/VciUnUseResponseAdvice.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/controller/VciUnUseResponseAdvice.java
new file mode 100644
index 0000000..325f317
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/controller/VciUnUseResponseAdvice.java
@@ -0,0 +1,22 @@
+package com.vci.starter.web.annotation.controller;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 涓嶄娇鐢ㄧ粺涓�鐨勮繑鍥炴帴鍙�
+ * @author weidy
+ * @date 2022/12/06
+ */
+@Target({ElementType.METHOD,ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface VciUnUseResponseAdvice {
+
+    /**
+     * 鍊硷紝鍙互涓嶈缃�
+     * @return true琛ㄧず涓嶆牎楠�
+     */
+    boolean value() default true;
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/log/VciBusinessLog.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/log/VciBusinessLog.java
new file mode 100644
index 0000000..419736e
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/log/VciBusinessLog.java
@@ -0,0 +1,44 @@
+package com.vci.starter.web.annotation.log;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target({java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface VciBusinessLog {
+	/**
+	 * 鎵�灞炲姛鑳芥ā鍧�
+	 * @return
+	 */
+	String modelName() default "";
+	
+	/**
+	 * 鎵�灞炴搷浣滃悕绉�
+	 * @return
+	 */
+	String operateName() default "";
+	
+	/**
+	 * 鏃ュ織绫诲瀷--鐧诲綍鏃ュ織锛屾搷浣滄棩蹇楋紝鎺堟潈鏃ュ織
+	 * @return
+	 */
+	VciLogType logType() default VciLogType.Operate;
+
+	/**
+	 * 鎻忚堪淇℃伅
+	 * @return
+	 */
+	String description() default "";
+
+	/**
+	 * 涓嶅瓨鍌ㄦ棩蹇�
+	 * @return
+	 */
+	boolean notStore() default false;
+	
+	public static enum VciLogType{
+		Login,Operate,Audit
+	}
+	
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/log/VciUnLog.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/log/VciUnLog.java
new file mode 100644
index 0000000..1a3ef91
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/log/VciUnLog.java
@@ -0,0 +1,16 @@
+package com.vci.starter.web.annotation.log;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 涓嶈褰曡繍琛屾棩蹇�
+ * @author weidy
+ * @date 2020/4/10
+ */
+@Target({java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface VciUnLog {
+    boolean value() default true;
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/permission/VciPermission.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/permission/VciPermission.java
new file mode 100644
index 0000000..beebb3b
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/permission/VciPermission.java
@@ -0,0 +1,137 @@
+package com.vci.starter.web.annotation.permission;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 鏉冮檺鎺у埗鐨勬敞瑙�
+ * 鐢ㄤ簬鑷姩鎺у埗鍔熻兘鏉冮檺锛屾寜閽潈闄愶紝鍜屾暟鎹潈闄�--鏁版嵁鏉冮檺浼氶�氳繃AOP鐨勬柟寮忓皢鏁版嵁鏉冮檺鐨勮鍒欐敞鍏ュ埌QueryMap涓�
+ * @author weidy
+ *
+ */
+@Target({java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface VciPermission {
+	/**
+	 * 鎵�灞炲姛鑳芥ā鍧梜ey--涓庡姛鑳借彍鍗曚腑鐨勭紪鍙峰搴�
+	 * @return
+	 */
+	String[] modelKey() default "";
+	
+	/**
+	 * 鎵�灞炴寜閽甼ey--浼氳嚜鍔ㄦ敞鍏ュ埌骞冲彴鐨勬搷浣滅被鍨嬩腑
+	 * @return
+	 */
+	String[] methodKey() default "";
+
+	/**
+	 * 鎵�灞炴寜閽殑鍚嶇О
+	 * @return
+	 */
+	String[] methodName() default "";
+
+	/**
+	 * 鎵�灞炴寜閽殑鍚嶇О
+	 * @return
+	 */
+	String[] methodAlias() default "";
+
+	/**
+	 * 鎵�灞炴寜閽殑鎻忚堪
+	 * @return
+	 */
+	String[] methodDesc() default "";
+
+	/**
+	 * 鎵�灞炴寜閽湪鑿滃崟涓殑鎺掑簭
+	 * @return
+	 */
+	int[] methodOrder() default 0;
+	
+	/**
+	 * 鍥哄畾鐨勮鑹�--瑙掕壊鐨勭紪鐮侊紝澶氫釜浣跨敤閫楀彿鍒嗛殧
+	 * 鏀寔琛ㄨ揪寮�${lt}瑙掕壊鐨勭被鍨嬪�硷紝琛ㄧず璁块棶鐨勭敤鎴风殑瑙掕壊绫诲瀷蹇呴』灏忎簬鏌愮绫诲瀷锛�${eq}琛ㄧず鐩哥瓑锛�${more}琛ㄧず澶т簬
+	 * *鍙互鐢ㄤ簬鍋氶�氶厤绗�
+	 * @return
+	 */
+	String defineRole() default "";
+	
+	/**
+	 * 鍏佽鐨勫瘑绾х瓑绾�
+	 * @return
+	 */
+	int secretGrade() default -1;
+	
+	/**
+	 * 鍏佽ip瀵嗙骇
+	 * @return
+	 */
+	String ipSecret() default "";
+	
+	/**
+	 * 鏂规硶鐨勬潈闄愭帶鍒讹紝濡傛灉涓虹┖鏃跺彇defineRole鐨勫��
+	 * 鍥哄畾鐨勮鑹�--瑙掕壊鐨勭紪鐮侊紝澶氫釜浣跨敤閫楀彿鍒嗛殧
+	 * 鏀寔琛ㄨ揪寮�${lt}瑙掕壊鐨勭被鍨嬪�硷紝琛ㄧず璁块棶鐨勭敤鎴风殑瑙掕壊绫诲瀷蹇呴』灏忎簬鏌愮绫诲瀷锛�${eq}琛ㄧず鐩哥瓑锛�${more}琛ㄧず澶т簬
+	 * *鍙互鐢ㄤ簬鍋氶�氶厤绗�
+	 * @return
+	 */
+	String defineRoleForMethod() default "";
+	
+	/**
+	 * 鏂规硶鐨勬潈闄愬瘑绾ф帶鍒讹紝濡傛灉涓虹┖鏃跺彇secretGrade鐨勫��
+	 * @return
+	 */
+	int secretGradeForMethod() default -2;
+	
+	/**
+	 * 鏂规硶鐨勬潈闄怚P鎺у埗锛屽鏋滀负绌烘椂鍙杋pSecret鐨勫��
+	 * @return
+	 */
+	String ipSecretForMethod() default "";
+
+	/**
+	 * 鏁版嵁鏉冮檺鍒ゆ柇鎵�闇�鐨勪笟鍔$被鍨�
+	 * @return
+	 */
+	String dataPermissionBtmType() default "";
+
+	/**
+	 * 鏁版嵁鏉冮檺鍒ゆ柇鎵�闇�鐨勬柟娉昸ey銆傞粯璁ょ瓑浜巑ethodKey,鎵�浠ヤ笉鐢ㄨ缃�
+	 * @return
+	 */
+	String[] dataPermissionMethodKey() default "";
+
+	/**
+	 * 鏄惁鎺у埗鏁版嵁鏉冮檺,濡傛灉鍦╟onfig.properties閲岄厤缃簡right.switch鍚庯紝榛樿鍊间細澶勭悊涓洪厤缃殑鍊�
+	 * @return
+	 */
+	boolean controlDataPermission() default false;
+	
+	/**
+	 * 鏄惁鎺у埗鍔熻兘鏉冮檺锛屽鏋滃湪config.properties閲岄厤缃簡function.switch鍚庯紝榛樿鍊间細澶勭悊涓洪厤缃殑鍊�
+	 * @return
+	 */
+	boolean controlModelPermission() default true;
+	
+	/**
+	 * 鏄惁鎺у埗鎸夐挳鏉冮檺锛屽鏋滃湪config.properties閲岄厤缃簡ui.right.switch鍚庯紝榛樿鍊间細澶勭悊涓洪厤缃殑鍊�
+	 * @return
+	 */
+	boolean controlMethodPermission() default true;
+	
+	/**
+	 * 鐢ㄦ埛瀵嗙骇
+	 * none--闈炲瘑
+	 * inner--鍐呴儴
+	 * secret--绉樺瘑
+	 * privacy--鏈哄瘑
+	 * @author weidy
+	 *
+	 */
+	public static enum UserSecretGrade{
+		none,inner,secret,privacy
+	}
+	
+	
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/permission/VciReferPermission.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/permission/VciReferPermission.java
new file mode 100644
index 0000000..80b6da0
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/permission/VciReferPermission.java
@@ -0,0 +1,20 @@
+package com.vci.starter.web.annotation.permission;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 鍙傜収鏂规硶娉ㄨВ锛岃〃绀鸿繖涓柟娉曟槸鎻愪緵缁欏叾浠栧湴鏂瑰弬鐓у紩鐢ㄧ殑
+ * @author weidy
+ */
+@Target({ java.lang.annotation.ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface VciReferPermission {
+    /**
+     * 鍙傜収鐨刱ey锛岄渶瑕佸敮涓�鍊硷紝鍦ㄧ郴缁熷惎鍔ㄧ殑鏃跺�欎細鎵弿,寤鸿浣跨敤琚笟鍔$被鍨嬫潵浠f浛
+     * @return
+     */
+    String referedKey()  ;
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/permission/VciUseReferMethod.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/permission/VciUseReferMethod.java
new file mode 100644
index 0000000..47f0662
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/permission/VciUseReferMethod.java
@@ -0,0 +1,19 @@
+package com.vci.starter.web.annotation.permission;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 浣跨敤鍙傜収鐨勬敞瑙�
+ * @author weidy
+ */
+@Target({ java.lang.annotation.ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface VciUseReferMethod {
+    /**
+     * 浣跨敤鍙傜収鐨刱ey
+     * @return
+     */
+    String[] useReferKey() ;
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/undo/UndoTaskCount.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/undo/UndoTaskCount.java
new file mode 100644
index 0000000..0821da3
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/undo/UndoTaskCount.java
@@ -0,0 +1,18 @@
+package com.vci.starter.web.annotation.undo;
+
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 寰呭姙浜嬮」鐨勬煡璇㈡�绘暟鏂规硶
+ * @author weidy
+ * @date 2022/8/1
+ */
+@Target({ ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface UndoTaskCount {
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/undo/UndoTaskMethod.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/undo/UndoTaskMethod.java
new file mode 100644
index 0000000..dad714f
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/undo/UndoTaskMethod.java
@@ -0,0 +1,18 @@
+package com.vci.starter.web.annotation.undo;
+
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 寰呭姙浜嬮」鐨勬煡璇㈡柟娉�
+ * @author weidy
+ * @date 2022/8/1
+ */
+@Target({ ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface UndoTaskMethod {
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/undo/UndoTaskPlugin.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/undo/UndoTaskPlugin.java
new file mode 100644
index 0000000..261ad6f
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/undo/UndoTaskPlugin.java
@@ -0,0 +1,68 @@
+package com.vci.starter.web.annotation.undo;
+
+import org.springframework.stereotype.Component;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 寰呭姙浜嬮」鐨勬煡璇㈢殑鍐呭
+ * 鏉′欢鏄痮r鐨勬柟寮忓垽鏂�
+ * @author weidy
+ * @date 2022/8/1
+ */
+@Target({ ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Component
+public @interface UndoTaskPlugin {
+
+    /**
+     * 鎺掑簭鍙�
+     * @return 鎺掑簭鐨勫唴瀹�
+     */
+    int order() ;
+    /**
+     * 浠诲姟绫诲瀷
+     * @return 浠诲姟绫诲瀷
+     */
+    String name() default "";
+
+    /**
+     * 鏉冮檺鐨勫悕瀛�
+     * @return 鏉冮檺鐨勫悕瀛�
+     */
+    String[] funcNames() default "";
+
+    /**
+     * 鎸囧畾瑙掕壊鐨勫悕绉�
+     * @return 瑙掕壊鍚嶇О
+     */
+    String[] roles() default "";
+
+    /**
+     * 鎸囧畾鐨勯儴闂ㄥ悕绉�
+     * @return 閮ㄩ棬鍚嶇О
+     */
+    String[] depts() default "";
+
+    /**
+     * 鎸囧畾鐨勭敤鎴峰悕
+     * @return 鐢ㄦ埛鍚�
+     */
+    String[] users() default "";
+
+    /**
+     * 鎸囧畾鐨勮鑹茬被鍨�
+     * @return 瑙掕壊绫诲瀷
+     */
+    String[] roleTypes() default "";
+
+    /**
+     * 鎵ц鐨勭敤鎴风被鍨�
+     * @return 鐢ㄦ埛绫诲瀷
+     */
+    String[] userTypes() default "";
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/workflow/WorkflowEvent.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/workflow/WorkflowEvent.java
new file mode 100644
index 0000000..4783395
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/workflow/WorkflowEvent.java
@@ -0,0 +1,51 @@
+package com.vci.starter.web.annotation.workflow;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 娴佺▼浜嬩欢
+ * 鐩墠娴佺▼浜嬩欢鍦ㄩ厤缃枃浠朵腑锛屾�绘槸鍑虹幇閰嶇疆閿欒鐨勬儏鍐碉紝鍥犱负娴佺▼浜嬩欢鍩烘湰鏄浐瀹氱殑锛屽洜姝ゅ紩娉ㄨВ鏉ヤ娇鐢�
+ * @author weidy
+ */
+@Target({java.lang.annotation.ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface WorkflowEvent {
+    /**
+     * key,浜嬩欢鐨勫敮涓�璇嗗埆鐮侊紝榛樿鍙栦娇鐢ㄦ敞瑙g殑绫荤殑鍚嶇О锛堥瀛楁瘝灏忓啓锛�
+     * @return
+     */
+    String value() default "";
+
+    /**
+     * 涓枃鍚嶅瓧锛屽鏋滀负绌虹殑鏃跺�欙紝鍙栦娇鐢ㄦ敞瑙g殑绫荤殑鍚嶇О锛堥瀛楁瘝灏忓啓锛�
+     * @return
+     */
+    String name() default "";
+
+    /**
+     * 鐢ㄤ簬娴佺▼浠诲姟寮�濮嬩簨浠�
+     * @return
+     */
+    boolean useInStart() default true;
+
+    /***
+     * 鐢ㄤ簬娴佺▼浠诲姟瀹屾垚浜嬩欢
+     * @return
+     */
+    boolean useInComplete() default  true;
+
+    /**
+     * 鐢ㄤ簬娴佺▼浠诲姟缁堟浜嬩欢
+     * @return
+     */
+    boolean useInEnd() default true;
+
+    /**
+     * 鐢ㄤ簬璺敱绾夸簨浠�
+     * @return
+     */
+    boolean useInTransition() default true;
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/workflow/WorkflowEventField.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/workflow/WorkflowEventField.java
new file mode 100644
index 0000000..827ac88
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/annotation/workflow/WorkflowEventField.java
@@ -0,0 +1,22 @@
+package com.vci.starter.web.annotation.workflow;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 娴佺▼浜嬩欢涓殑瀛楁
+ * 閰嶅悎WorkflowEvent浣跨敤,鑷姩璇诲彇瀛楁鐨勫悕绉板拰绫诲瀷
+ * @author weidy
+ */
+@Target({ElementType.FIELD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface WorkflowEventField {
+
+    /**
+     * 鏄惁蹇呰緭
+     * @return
+     */
+    boolean required() default false;
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/autoconfigure/AppAutoConfigure.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/autoconfigure/AppAutoConfigure.java
new file mode 100644
index 0000000..fff1039
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/autoconfigure/AppAutoConfigure.java
@@ -0,0 +1,113 @@
+package com.vci.starter.web.autoconfigure;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * 搴旂敤淇℃伅閰嶇疆
+ * @author weidy
+ */
+@Configuration
+@ConfigurationProperties(prefix = "app")
+public class AppAutoConfigure {
+    /**
+     * 鎵�灞炵粍缁�
+     */
+    private String group;
+    /**
+     * 搴旂敤鍚嶇О
+     */
+    private String name;
+    /**
+     * 搴旂敤鎻忚堪
+     */
+    private String description;
+    /**
+     * 浣滆��
+     */
+    private String author;
+    /**
+     * 閭欢
+     */
+    private String email;
+    /**
+     * 閾炬帴鍦板潃
+     */
+    private String url;
+
+    /**
+     * 搴旂敤绉侀挜
+     */
+    private String privateTokenKey;
+
+
+
+    public String getGroup() {
+        return group;
+    }
+
+    public void setGroup(String group) {
+        this.group = group;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public String getAuthor() {
+        return author;
+    }
+
+    public void setAuthor(String author) {
+        this.author = author;
+    }
+
+    public String getEmail() {
+        return email;
+    }
+
+    public void setEmail(String email) {
+        this.email = email;
+    }
+
+    public String getUrl() {
+        return url;
+    }
+
+    public void setUrl(String url) {
+        this.url = url;
+    }
+
+    public String getPrivateTokenKey() {
+        return privateTokenKey;
+    }
+
+    public void setPrivateTokenKey(String privateTokenKey) {
+        this.privateTokenKey = privateTokenKey;
+    }
+
+    @Override
+    public String toString() {
+        return "AppAutoConfigure{" +
+                "group='" + group + '\'' +
+                ", name='" + name + '\'' +
+                ", description='" + description + '\'' +
+                ", author='" + author + '\'' +
+                ", email='" + email + '\'' +
+                ", url='" + url + '\'' +
+                ", privateTokenKey='" + privateTokenKey + '\'' +
+                '}';
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/autoconfigure/DubboConfig.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/autoconfigure/DubboConfig.java
new file mode 100644
index 0000000..5a6f73f
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/autoconfigure/DubboConfig.java
@@ -0,0 +1,9 @@
+package com.vci.starter.web.autoconfigure;
+
+/**
+ * dubbo鐨勮皟鐢ㄥ鐞嗗櫒
+ * @author weidy
+ * @date 2020/6/16
+ */
+public class DubboConfig {
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/autoconfigure/FeignConfig.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/autoconfigure/FeignConfig.java
new file mode 100644
index 0000000..e43a622
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/autoconfigure/FeignConfig.java
@@ -0,0 +1,223 @@
+package com.vci.starter.web.autoconfigure;
+
+import com.alibaba.fastjson.JSONObject;
+import com.vci.starter.web.constant.TokenKeyConstant;
+import com.vci.starter.web.pagemodel.SessionInfo;
+import com.vci.starter.web.util.VciBaseUtil;
+import feign.*;
+import feign.form.spring.SpringFormEncoder;
+import feign.okhttp.OkHttpClient;
+import okhttp3.ConnectionPool;
+import org.slf4j.MDC;
+import org.springframework.beans.factory.ObjectFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
+import org.springframework.cloud.commons.httpclient.OkHttpClientConnectionPoolFactory;
+import org.springframework.cloud.commons.httpclient.OkHttpClientFactory;
+import org.springframework.cloud.openfeign.support.FeignHttpClientProperties;
+import org.springframework.cloud.openfeign.support.ResponseEntityDecoder;
+import org.springframework.cloud.openfeign.support.SpringDecoder;
+import org.springframework.cloud.openfeign.support.SpringEncoder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.i18n.LocaleContextHolder;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.http.converter.StringHttpMessageConverter;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+import javax.annotation.PreDestroy;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * feign瀹㈡埛绔厤缃�
+ * @author weidy
+ * @date 2019/11/5 10:23 AM
+ */
+@AutoConfigureAfter(AppAutoConfigure.class)
+@Configuration
+public class FeignConfig implements RequestInterceptor {
+
+    /**
+     * 浣跨敤okHttpClient鏉ヤ紶杈撴暟鎹�
+     */
+    private okhttp3.OkHttpClient okHttpClient;
+
+    /**
+     * 褰撳墠搴旂敤绋嬪簭鐨勭閽�
+     */
+    @Value("${app.privateTokenKey:}")
+    private String privateTokenKey;
+
+    /**
+     * 瀹㈡埛绔繛鎺ユ睜
+     * @param httpClientProperties http閾炬帴閰嶇疆
+     * @param connectionPoolFactory 杩炴帴姹犲伐绋�
+     * @return 杩炴帴姹�
+     */
+    @Bean
+    @ConditionalOnMissingBean({ConnectionPool.class})
+    public ConnectionPool httpClientConnectionPool(FeignHttpClientProperties httpClientProperties, OkHttpClientConnectionPoolFactory connectionPoolFactory) {
+        Integer maxTotalConnections = httpClientProperties.getMaxConnections();
+        Long timeToLive = httpClientProperties.getTimeToLive();
+        TimeUnit ttlUnit = httpClientProperties.getTimeToLiveUnit();
+        return connectionPoolFactory.create(maxTotalConnections, timeToLive, ttlUnit);
+    }
+
+    /**
+     * 鍒濆鍖杘kHttp鐨勫鎴风瀵硅薄
+     * @param httpClientFactory 瀹㈡埛绔摼鎺ュ伐绋�
+     * @param connectionPool 杩炴帴姹�
+     * @param httpClientProperties 瀹㈡埛绔摼鎺ラ厤缃�
+     * @return
+     */
+    @Bean
+    public okhttp3.OkHttpClient client(OkHttpClientFactory httpClientFactory, ConnectionPool connectionPool, FeignHttpClientProperties httpClientProperties) {
+        Boolean followRedirects = httpClientProperties.isFollowRedirects();
+        Integer connectTimeout = httpClientProperties.getConnectionTimeout();
+        Boolean disableSslValidation = httpClientProperties.isDisableSslValidation();
+        this.okHttpClient = httpClientFactory.createBuilder(disableSslValidation).connectTimeout((long)connectTimeout, TimeUnit.MILLISECONDS).followRedirects(followRedirects).readTimeout(30*60,TimeUnit.SECONDS).connectionPool(connectionPool).build();
+        return this.okHttpClient;
+    }
+
+    /**
+     * 閿�姣佷箣鍓嶅叧闂璷kHttp
+     */
+    @PreDestroy
+    public void destroy() {
+        if (this.okHttpClient != null) {
+            this.okHttpClient.dispatcher().executorService().shutdown();
+            this.okHttpClient.connectionPool().evictAll();
+        }
+
+    }
+
+    /**
+     * 閰嶇疆feign鐨勫鎴风绫�
+     * @param client 瀹㈡埛绔摼鎺ュ璞�
+     * @return 瀹㈡埛绔繛鎺ュ璞�
+     */
+    @Bean
+    @ConditionalOnMissingBean({Client.class})
+    public Client feignClient(okhttp3.OkHttpClient client) {
+        return new OkHttpClient(client);
+    }
+
+    /**
+     * 璁剧疆璇锋眰鐨勮繛鎺ユ椂闂村拰璇诲彇鐨勬椂闂�
+     * @param client 閾炬帴鐨勫鎴风
+     * @return 閾炬帴鐨勫鎴风
+     */
+    @Bean
+    public Request.Options feignOptions(okhttp3.OkHttpClient client) {
+        return new Request.Options(client.connectTimeoutMillis(), client.readTimeoutMillis());
+    }
+
+    /**
+     * 閰嶇疆feign鐨勬棩蹇楃瓑绾�
+     * @return 鏃ュ織绛夌骇
+     */
+    @Bean
+    Logger.Level feignLoggerLevel() {
+        //杩欓噷璁板綍鎵�鏈夛紝鏍规嵁瀹為檯鎯呭喌閫夋嫨鍚堥�傜殑鏃ュ織level
+        return Logger.Level.FULL;
+    }
+
+    /**
+     * 灏唂astjson璁剧疆鍒癲ecoder涓�,瑙g爜鍣�
+     * @return decoder
+     */
+    @Bean
+    public ResponseEntityDecoder feignDecoder(){
+        HttpMessageConverter fastJsonConverter = SpringMVCConfig.createFastJsonConverter();
+        ObjectFactory<HttpMessageConverters> objectFactory = () -> new HttpMessageConverters(new StringHttpMessageConverter(StandardCharsets.UTF_8),fastJsonConverter);
+        return new ResponseEntityDecoder(new SpringDecoder(objectFactory));
+    }
+
+    /**
+     * 灏唂astjson璁剧疆鍒癳ncoder涓紝缂栫爜鍣�
+     * @return encoder
+     */
+    @Bean
+    public SpringFormEncoder feignEncoder(){
+        HttpMessageConverter fastJsonConverter = SpringMVCConfig.createFastJsonConverter();
+        ObjectFactory<HttpMessageConverters> objectFactory = () -> new HttpMessageConverters(new StringHttpMessageConverter(StandardCharsets.UTF_8),fastJsonConverter);
+        return new SpringFormEncoder(new SpringEncoder(objectFactory));
+    }
+
+
+    /**
+     * 鍦ㄥ彂閫佽姹傜殑鏃跺�欙紝璁剧疆鎷︽埅鍣紝灏嗙敤鎴风殑token鍜屽綋鍓嶆湇鍔$殑绉侀挜浼犻�掕繃鍘伙紝骞朵笖浼犻�掑綋鍓嶆湇鍔$殑鍚嶇О鐢ㄤ簬杩芥函鏃ュ織
+     * @param requestTemplate 璇锋眰鐨勭洰鏍�
+     */
+    @Override
+    public void apply(RequestTemplate requestTemplate) {
+        //濡傛灉鏄疓ET锛屼絾鏄痓ody閲屾湁鍐呭
+        Request.Body body = requestTemplate.requestBody();
+        if(RequestMethod.GET.toString().equalsIgnoreCase(requestTemplate.method())
+                && body != null && body.length() > 0){
+            //涓昏鏄垪琛ㄦ煡璇㈠拰鏍戞煡璇㈣繖鍑犱釜鍦版柟,鏀寔map鐨勪紶杈�
+            String bodyString = new String(body.asBytes(),requestTemplate.requestCharset());
+            try{
+                JSONObject jsonObject = JSONObject.parseObject(bodyString);
+                for(String key : jsonObject.keySet()){
+                    Object value = jsonObject.get(key);
+                    if(value == null){
+                        requestTemplate.query(key,"");
+                    }else{
+                        if(value instanceof Map){
+                            //璇存槑杩欎釜灞炴�ф槸map
+                            Map mapValues = (Map)value;
+                            for(Object mapKey : mapValues.keySet()){
+                                Object mapQueryValue = mapValues.get(mapKey);
+                                String mapQueryValueString = "";
+                                if(mapQueryValue == null){
+                                    mapQueryValueString = "";
+                                }else{
+                                    mapQueryValueString = VciBaseUtil.getStringValueFromObject(mapQueryValue);
+                                }
+                                requestTemplate.query(key + "[\"" + mapKey.toString() + "\"]",mapQueryValueString);
+                            }
+                        }else{
+                            requestTemplate.query(key,VciBaseUtil.getStringValueFromObject(value));
+                        }
+                    }
+                }
+                requestTemplate.body(Request.Body.empty());
+            }catch (Throwable e){
+                //鍙兘涓嶆槸json鐨勭被鍨�
+            }
+        }
+
+        //闇�瑕佷紶閫掔敤鎴风殑token
+        //绯荤粺鐨則oken锛岀敤浜庢潈闄愰獙璇�
+        //鏃ュ織鐨勯摼鎺D
+        SessionInfo sessionInfo = VciBaseUtil.getCurrentUserSessionInfoNotException();
+        if(sessionInfo != null){
+            requestTemplate.header(TokenKeyConstant.USER_TOKEN_KEY,sessionInfo.getToken());
+        }else{
+            requestTemplate.header(TokenKeyConstant.USER_TOKEN_KEY,"");
+        }
+        requestTemplate.header(TokenKeyConstant.SYSTEM_PRIVATE_KEY,getPrivateTokenKey());
+
+        String logTraceId = MDC.get(TokenKeyConstant.TRACE_ID);
+        if(logTraceId == null){
+            logTraceId = "";
+        }
+        requestTemplate.header(TokenKeyConstant.LOG_TRACE_ID_KEY,logTraceId);
+        //璁剧疆璇█
+        requestTemplate.header(TokenKeyConstant.LANGUAGE_KEY,LocaleContextHolder.getLocale().toLanguageTag());
+    }
+
+    public String getPrivateTokenKey() {
+        return privateTokenKey;
+    }
+
+    public void setPrivateTokenKey(String privateTokenKey) {
+        this.privateTokenKey = privateTokenKey;
+    }
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/autoconfigure/ResponseModifyAdvice.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/autoconfigure/ResponseModifyAdvice.java
new file mode 100644
index 0000000..65414b8
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/autoconfigure/ResponseModifyAdvice.java
@@ -0,0 +1,149 @@
+package com.vci.starter.web.autoconfigure;
+
+import com.vci.starter.web.annotation.controller.VciUnUseResponseAdvice;
+import com.vci.starter.web.constant.TokenKeyConstant;
+import com.vci.starter.web.pagemodel.BaseResult;
+import com.vci.starter.web.pagemodel.DataGrid;
+import com.vci.starter.web.pagemodel.Tree;
+import com.vci.starter.web.util.MessageUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.MDC;
+import org.springframework.core.MethodParameter;
+import org.springframework.http.MediaType;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.http.server.ServerHttpRequest;
+import org.springframework.http.server.ServerHttpResponse;
+import org.springframework.lang.Nullable;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
+
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 鍦ㄨ繑鍥炵粨鏋滃墠锛屽皝瑁呯粺涓�鐨勬暟鎹璞�
+ * @author weidy
+ * @date 2019/11/7 4:05 PM
+ */
+@ControllerAdvice(annotations = {RestController.class, Controller.class})
+public class ResponseModifyAdvice implements ResponseBodyAdvice<Object>{
+    /**
+     * 杩囨护鍝簺闇�瑕佹嫤鎴鐞�
+     * Whether this component supports the given controller method return type
+     * and the selected {@code HttpMessageConverter} type.
+     *
+     * @param returnType    the return type
+     * @param converterType the selected converter type
+     * @return {@code true} if {@link #beforeBodyWrite} should be invoked;
+     * {@code false} otherwise
+     */
+    @Override
+    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
+        //鍏ㄩ儴閮芥敮鎸�
+        if(returnType.getMethod().isAnnotationPresent(VciUnUseResponseAdvice.class)){
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Invoked after an {@code HttpMessageConverter} is selected and just before
+     * its write method is invoked.
+     *
+     * @param body                  the body to be written
+     * @param returnType            the return type of the controller method
+     * @param selectedContentType   the content type selected through content negotiation
+     * @param selectedConverterType the converter type selected to write to the response
+     * @param request               the current request
+     * @param response              the current response
+     * @return the body that was passed in or a modified (possibly new) instance
+     */
+    @Nullable
+    @Override
+    public Object beforeBodyWrite(@Nullable Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
+        String traceId = MDC.get(TokenKeyConstant.TRACE_ID);
+        if(returnType.getMethod().isAnnotationPresent(VciUnUseResponseAdvice.class)){
+            return body;
+        }
+        String returnTypeName = returnType.getParameterType().getName();
+        if("void".equalsIgnoreCase(returnTypeName)){
+            BaseResult baseResult = BaseResult.success();
+            baseResult.setFinishTime(System.currentTimeMillis());
+            baseResult.setTraceId(traceId);
+            formateMsg(baseResult);
+            return baseResult;
+        }
+        if("com.vci.starter.web.pagemodel.BaseResult".equals(returnTypeName)){
+            BaseResult baseResult = ((BaseResult)body);
+            baseResult.setTraceId(traceId);
+            baseResult.setFinishTime(System.currentTimeMillis());
+            formateMsg(baseResult);
+            return baseResult;
+        }
+        if("com.vci.starter.web.pagemodel.DataGrid".equals(returnTypeName)){
+            DataGrid dataGrid = ((DataGrid)body);
+            BaseResult baseResult = BaseResult.dataGrid(dataGrid);
+            baseResult.setTraceId(traceId);
+            baseResult.setFinishTime(System.currentTimeMillis());
+            formateMsg(baseResult);
+            return baseResult;
+        }
+        if("com.vci.starter.web.pagemodel.Tree".equals(returnTypeName)){
+            //returnType.getP
+            Tree tree = ((Tree)body);
+            List<Tree> treeList = new ArrayList<>();
+            treeList.add(tree);
+            BaseResult baseResult = BaseResult.tree(treeList);
+            baseResult.setTraceId(traceId);
+            baseResult.setFinishTime(System.currentTimeMillis());
+            formateMsg(baseResult);
+            return baseResult;
+        }
+        if(body instanceof Collection){
+            //璇存槑鏄泦鍚�
+            String genericParamterTypeName = returnType.getGenericParameterType().getTypeName();
+            if(genericParamterTypeName.contains("<")
+                    && genericParamterTypeName.contains(">")){
+                String elementTypeName = genericParamterTypeName.substring(genericParamterTypeName.indexOf("<")+ 1,genericParamterTypeName.indexOf(">"));
+                if("com.vci.starter.web.pagemodel.Tree".equalsIgnoreCase(elementTypeName)){
+                    Collection<Tree> treeCollection = ((Collection<Tree>)body);
+                    BaseResult baseResult = BaseResult.tree(treeCollection);
+                    baseResult.setTraceId(traceId);
+                    baseResult.setFinishTime(System.currentTimeMillis());
+                    formateMsg(baseResult);
+                    return baseResult;
+                }else{
+                    //鏀惧埌Obj灞炴�ч噷
+                    Collection<Object> objectCollection = ((Collection<Object>)body);
+                    BaseResult baseResult =  BaseResult.success(objectCollection);
+                    baseResult.setTraceId(traceId);
+                    baseResult.setFinishTime(System.currentTimeMillis());
+                    formateMsg(baseResult);
+                    return baseResult;
+                }
+            }
+        }
+        if(body instanceof Object){
+            BaseResult baseResult = BaseResult.success((Object)body);
+            baseResult.setTraceId(traceId);
+            baseResult.setFinishTime(System.currentTimeMillis());
+            formateMsg(baseResult);
+            return baseResult;
+        }
+        return body;
+    }
+
+    /**
+     * 澶氳鏍煎紡鍖�
+     * @param baseResult 缁撴灉瀵硅薄
+     */
+    private void formateMsg(BaseResult baseResult ){
+        if(baseResult!=null && StringUtils.isNotBlank(baseResult.getMsg())){
+            baseResult.setMsg(MessageUtils.get(baseResult.getMsg(),baseResult.getMsgObjs()));
+        }
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/autoconfigure/SpringMVCConfig.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/autoconfigure/SpringMVCConfig.java
new file mode 100644
index 0000000..244211d
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/autoconfigure/SpringMVCConfig.java
@@ -0,0 +1,421 @@
+package com.vci.starter.web.autoconfigure;
+
+import com.alibaba.fastjson.serializer.SerializerFeature;
+import com.alibaba.fastjson.support.config.FastJsonConfig;
+import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
+import com.vci.starter.web.interceptor.VciLocaleInterceptor;
+import com.vci.starter.web.interceptor.VciLogAfterInterceptor;
+import com.vci.starter.web.interceptor.VciLogBeforeInterceptor;
+import com.vci.starter.web.interceptor.VciSecurityInterceptor;
+import com.vci.starter.web.properties.CorsProperties;
+import com.vci.starter.web.toolmodel.String2DateConverterForSpringMvc;
+import com.vci.starter.web.util.LocalFileUtil;
+import com.vci.starter.web.util.VciDateUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.format.FormatterRegistry;
+import org.springframework.http.CacheControl;
+import org.springframework.http.MediaType;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.http.converter.StringHttpMessageConverter;
+import org.springframework.web.filter.FormContentFilter;
+import org.springframework.web.servlet.LocaleResolver;
+import org.springframework.web.servlet.config.annotation.*;
+import org.springframework.web.servlet.i18n.SessionLocaleResolver;
+
+import java.io.File;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * spring mvc鐨勭浉鍏抽厤缃�
+ *
+ * @author weidy
+ */
+@Configuration
+@EnableWebMvc
+@ConditionalOnProperty(prefix = "vcispringmvc",name="enabled",havingValue = "true",matchIfMissing = true)
+@ConfigurationProperties(prefix = "vcispringmvc")
+public class SpringMVCConfig  implements WebMvcConfigurer {
+
+    /**
+     * 鏃ュ織瀵硅薄
+     */
+    private Logger log = LoggerFactory.getLogger(SpringMVCConfig.class);
+
+    /**
+     * 澶栭儴鏂囦欢澶圭殑鏄犲皠鍦板潃
+     */
+    private Map<String,String> resourceFolderMap ;
+
+    /**
+     * 涓嶆牎楠屽畨鍏ㄧ殑閾炬帴鍦板潃
+     */
+    private List<String> unCheckUrls;
+
+    /**
+     * 涓嶆洿鏂拌姹傛椂闂寸殑閾炬帴鍦板潃
+     */
+    private List<String> unStorageRequestTimeUrls;
+
+    /**
+     * 璺ㄥ煙鐨勯厤缃�
+     */
+    @Autowired(required = false)
+    private CorsProperties corsProperties;
+
+    /**
+     * 榛樿鍏佽鐨勫煙鍚�
+     */
+    private String[] DEFAULT_ORIGINS = {"*"};
+
+    /**
+     * 榛樿鍏佽鐨勫ご
+     */
+    private String[] DEFAULT_ALLOWED_HEADERS = {"*"};
+
+    /**
+     * 榛樿鍏佽鐨勬柟娉�
+     */
+    private String[] DEFAULT_METHODS = {"PUT", "DELETE","GET","POST"};
+
+    /**
+     * 榛樿鏆撮湶鐨勫ご
+     */
+    private String[] DEFAULT_EXPOSEDHEADERS = {"access-control-allow-headers",
+            "access-control-allow-methods",
+            "access-control-allow-origin",
+            "access-control-max-age",
+            "X-Frame-Options"};
+    /**
+     * 榛樿鏄惁鍏佽璇佷功
+     */
+    private boolean DEFAULT_ALLOW_CREDENTIALS = true;
+    /**
+     * 榛樿鐨勬渶澶у��
+     */
+    private long DEFAULT_MAX_AGE = 1800;
+
+    public Map<String, String> getResourceFolderMap() {
+        return resourceFolderMap;
+    }
+
+    public void setResourceFolderMap(Map<String, String> resourceFolderMap) {
+        this.resourceFolderMap = resourceFolderMap;
+    }
+
+    /**
+     * 澧炲姞PUT鍜孌ELETE鐨勬敮鎸�
+     * @return 杩囨护鍣�
+     */
+    @Bean
+    public FormContentFilter formContentFilter() {
+        return new FormContentFilter();
+    }
+
+    /**
+     * 浣跨敤fastjson杩斿洖鍊�
+     * @param converters 鎵�鏈夌殑娑堟伅杞崲鍣�
+     */
+    @Override
+    public void configureMessageConverters(List<HttpMessageConverter<?>> converters){
+        converters.add(new StringHttpMessageConverter(StandardCharsets.UTF_8));
+        converters.add(createFastJsonConverter());
+    }
+
+    /**
+     * 鑾峰彇fastjson鐨勮浆鎹㈠櫒锛屽嵆springmvc鍜宖egin閮戒娇鐢╢astjson鏉ュ簭鍒楀寲
+     * @return fastjson杞崲鍣ㄥ璞★紝鏃ユ湡鏍煎紡閮芥槸yyyy-MM-dd HH:mm:ss.SSS
+     */
+    public static HttpMessageConverter createFastJsonConverter(){
+        FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
+        List<MediaType> supportedMediaTypes = new ArrayList<>();
+        supportedMediaTypes.add(MediaType.APPLICATION_JSON);
+        supportedMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
+        supportedMediaTypes.add(MediaType.APPLICATION_ATOM_XML);
+        supportedMediaTypes.add(MediaType.APPLICATION_FORM_URLENCODED);
+        supportedMediaTypes.add(MediaType.APPLICATION_OCTET_STREAM);
+        supportedMediaTypes.add(MediaType.APPLICATION_PDF);
+        supportedMediaTypes.add(MediaType.APPLICATION_RSS_XML);
+        supportedMediaTypes.add(MediaType.APPLICATION_XHTML_XML);
+        supportedMediaTypes.add(MediaType.APPLICATION_XML);
+        supportedMediaTypes.add(MediaType.IMAGE_GIF);
+        supportedMediaTypes.add(MediaType.IMAGE_JPEG);
+        supportedMediaTypes.add(MediaType.IMAGE_PNG);
+        supportedMediaTypes.add(MediaType.TEXT_EVENT_STREAM);
+        supportedMediaTypes.add(MediaType.TEXT_HTML);
+        supportedMediaTypes.add(MediaType.TEXT_MARKDOWN);
+        //supportedMediaTypes.add(MediaType.TEXT_PLAIN);
+        supportedMediaTypes.add(MediaType.TEXT_XML);
+        fastConverter.setSupportedMediaTypes(supportedMediaTypes);
+        //鍒涘缓閰嶇疆绫�
+        FastJsonConfig fastJsonConfig = new FastJsonConfig();
+        //淇敼閰嶇疆杩斿洖鍐呭鐨勮繃婊�
+        //WriteNullListAsEmpty  锛歀ist瀛楁濡傛灉涓簄ull,杈撳嚭涓篬],鑰岄潪null
+        //WriteNullStringAsEmpty 锛� 瀛楃绫诲瀷瀛楁濡傛灉涓簄ull,杈撳嚭涓�"",鑰岄潪null
+        //DisableCircularReferenceDetect 锛氭秷闄ゅ鍚屼竴瀵硅薄寰幆寮曠敤鐨勯棶棰橈紝榛樿涓篺alse锛堝鏋滀笉閰嶇疆鏈夊彲鑳戒細杩涘叆姝诲惊鐜級
+        //WriteNullBooleanAsFalse锛欱oolean瀛楁濡傛灉涓簄ull,杈撳嚭涓篺alse,鑰岄潪null
+        //WriteMapNullValue锛氭槸鍚﹁緭鍑哄�间负null鐨勫瓧娈�,榛樿涓篺alse
+        fastJsonConfig.setSerializerFeatures(
+                SerializerFeature.DisableCircularReferenceDetect,
+                SerializerFeature.WriteMapNullValue
+        );
+        fastJsonConfig.setDateFormat(VciDateUtil.DateTimeMillFormat);
+        fastConverter.setFastJsonConfig(fastJsonConfig);
+
+
+        return fastConverter;
+    }
+
+    /**
+     * 璁剧疆鏍煎紡杞崲鍣紝鍦ㄦ帴鏀跺埌鍙傛暟灏佽鍒板璞℃椂浣跨敤
+     * @param registry 鏍煎紡娉ㄥ唽鍣�
+     */
+    @Override
+    public void addFormatters(FormatterRegistry registry) {
+        //娣诲姞鏃ユ湡鐨勮浆鎹㈠櫒
+        registry.addConverter(new String2DateConverterForSpringMvc());
+        //registry.addConverter(new StringEscapeEditor());
+
+    }
+
+    /**
+     * 娣诲姞闇�瑕佽浆鎹㈢殑璺緞,甯哥敤浜庤鍙杢omcat澶栭儴鐨勮矾寰�
+     * @param registry 璧勬簮杞崲娉ㄥ唽鍣�
+     */
+    @Override
+    public void addResourceHandlers(ResourceHandlerRegistry registry){
+        if(resourceFolderMap!=null){
+            for(String resourceUrl :resourceFolderMap.keySet() ){
+                String folder = resourceFolderMap.get(resourceUrl);
+                if(folder.contains("$[projectPath]")){
+                    folder = folder.replace("$[projectPath]", LocalFileUtil.getProjectFolder(LocalFileUtil.mainClass));
+                }
+                log.info("娉ㄥ唽浜嗗閮ㄨ矾寰勮浆鎹㈠櫒, " + resourceUrl + ":" + folder);
+                registry.addResourceHandler("/" + resourceUrl + "/**").addResourceLocations("file:" + folder + File.separator);
+            }
+        }
+        String logs = "file:" + LocalFileUtil.getProjectFolder(LocalFileUtil.mainClass) + File.separator + "logs" +File.separator;
+        log.info("鏃ュ織鐨勬枃浠跺す鏄犲皠涓�" + logs);
+        registry.addResourceHandler("/log/**").addResourceLocations( logs);
+        registry.addResourceHandler("/doc/**").addResourceLocations( "classpath:/md/");
+        registry.addResourceHandler("/**")
+                .addResourceLocations("classpath:/META-INF/resources/")
+                .addResourceLocations("classpath:/resources/")
+                .addResourceLocations("classpath:/static/")
+                .addResourceLocations("classpath:/html/")
+                .addResourceLocations("classpath:/public/").setCacheControl(CacheControl.noStore());
+
+    }
+
+    /**
+     * 閰嶇疆index
+     * @param registry 娉ㄥ唽鍣�
+     */
+    @Override
+    public void addViewControllers(ViewControllerRegistry registry) {
+        registry.addViewController("/").setViewName("forward:index.html");
+    }
+    /**
+     * 璁剧疆榛樿鐨勮瑷�涓虹畝浣撲腑鏂�
+     * @return 榛樿璇█瑙f瀽鍣�
+     */
+    @Bean
+    public LocaleResolver localeResolver(){
+        SessionLocaleResolver localeResolver = new SessionLocaleResolver();
+        localeResolver.setDefaultLocale(Locale.SIMPLIFIED_CHINESE);
+        return localeResolver;
+    }
+
+    /**
+     * 閰嶇疆鎷︽埅鍣�
+     * @param registry 鎷︽埅鍣ㄦ敞鍐屽櫒
+     */
+    @Override
+    public void addInterceptors(InterceptorRegistry registry){
+/*        preHandle鎸夋嫤鎴櫒瀹氫箟椤哄簭鍦拌皟鐢�
+        postHandle鎸夋嫤鎴櫒瀹氫箟閫嗗簭鍦拌皟鐢�
+        afterCompletion鎸夋嫤鎴櫒瀹氫箟閫嗗簭鍦拌皟鐢�
+        postHandle鍦ㄦ埅鍣ㄩ摼鍐呮墍鏈夋嫤鎴櫒杩斿洖鎴愬姛璋冪敤
+        afterCompletion鍙湁鍦╬reHandle杩斿洖true鎵嶈皟鐢�*/
+        //1. 闇�瑕侀厤缃璇殑鎷︽埅鍣紝閰嶇疆澶氳鐜
+        //2. 闇�瑕侀厤缃畉oken鐨勬嫤鎴櫒锛岃繖涓繀椤诲湪鏉冮檺鎷︽埅鍣ㄤ箣鍓嶏紝閲岄潰鍖呮嫭鐢ㄦ埛鐨剆ession淇℃伅锛屾棩蹇楃殑
+        //3. 閰嶇疆鏉冮檺鐨勬嫤鎴櫒锛屽鏋滀笉绗﹀悎瑕佹眰鍒欒繑鍥炲紓甯搞�傞渶瑕佸鐞嗙郴缁熻闂殑鏉冮檺锛屾帴鍙h闂殑鏉冮檺锛屾暟鎹闂殑鏉冮檺涓夌绫诲瀷
+        //4. 鏇存柊鐢ㄦ埛璇锋眰鐨勬渶鍚庢椂闂�
+
+        //娣诲姞鏃ュ織鐨凪DC
+        registry.addInterceptor(vciLogBeforeInterceptor());
+        //澶氳瑷�
+        registry.addInterceptor(vciLocaleInterceptor());
+        registry.addInterceptor(vciSecurityInterceptor()).excludePathPatterns("/error").excludePathPatterns("/**.*");
+        //绉婚櫎鏃ュ織鐨凪DC
+        registry.addInterceptor(vciLogAfterInterceptor());
+    }
+
+    /**
+     * 澶氳瑷�鐩稿叧鐨勬嫤鎴櫒
+     * @return 澶氳瑷�鎷︽埅鍣�
+     */
+    @Bean
+    public VciLocaleInterceptor vciLocaleInterceptor(){
+        return new VciLocaleInterceptor();
+    }
+
+    /**
+     * 瀹夊叏鐩稿叧鐨勬嫤鎴櫒
+     * @return 瀹夊叏鐩稿叧鐨勬嫤鎴櫒
+     */
+    @Bean
+    public VciSecurityInterceptor vciSecurityInterceptor(){
+        return new VciSecurityInterceptor();
+    }
+
+
+    /**
+     * 鏃ュ織鐩稿叧鐨勬嫤鎴櫒
+     * @return 鏃ュ織鎷︽埅鍣�
+     */
+    @Bean
+    public VciLogBeforeInterceptor vciLogBeforeInterceptor(){
+        return new VciLogBeforeInterceptor();
+    }
+
+    /**
+     * 鏃ュ織鐩稿叧鐨勬嫤鎴櫒
+     * @return 鏃ュ織鎷︽埅鍣�
+     */
+    @Bean
+    public VciLogAfterInterceptor vciLogAfterInterceptor(){
+        return new VciLogAfterInterceptor();
+    }
+
+
+    /**
+     * 璁剧疆璺ㄥ煙
+     * @param registry 璺ㄥ煙娉ㄥ唽鍣�
+     */
+    @Override
+    public void addCorsMappings(CorsRegistry registry) {
+        log.info("杩涘叆璺ㄥ煙閰嶇疆");
+        if(corsProperties !=null && "true".equalsIgnoreCase(corsProperties.getEnabled())) {
+            log.info("鎵撳紑浜嗚法鍩熷紑鍏�");
+            String[] allowedOrigins = corsProperties.getAllowedOrigins();
+
+            String[] allowedHeaders = corsProperties.getAllowedHeaders();
+
+            String[] allowedMethods = corsProperties.getAllowedMethods();
+
+            String[] exposedHeaders = corsProperties.getExposedHeaders();
+
+            Boolean allowCredentials = corsProperties.getAllowCredentials();
+
+            Long maxAge = corsProperties.getMaxAge();
+            log.info("娉ㄥ唽璺ㄥ煙鍐呭 = [" + allowedOrigins + "]");
+            String mappings = corsProperties.getMappings();
+            if (allowedHeaders == null || allowedHeaders.length == 0) {
+                allowedHeaders = DEFAULT_ALLOWED_HEADERS;
+            }
+            if (allowedOrigins == null || allowedOrigins.length == 0) {
+                allowedOrigins = DEFAULT_ORIGINS;
+            }
+
+            if (exposedHeaders == null || exposedHeaders.length == 0) {
+                exposedHeaders = DEFAULT_EXPOSEDHEADERS;
+            }
+            if (allowedMethods == null || allowedMethods.length == 0){
+                allowedMethods = DEFAULT_METHODS;
+            }
+            if (maxAge == null || maxAge == 0) {
+                maxAge = DEFAULT_MAX_AGE;
+            }
+            if (allowCredentials == null) {
+                allowCredentials = DEFAULT_ALLOW_CREDENTIALS;
+            }
+            if (mappings == null || mappings.trim() == "") {
+                mappings = "/**";
+            }
+            log.info("璺ㄥ煙鏄犲皠鐨刄RL锛�" + mappings);
+            registry.addMapping(mappings)
+                    .allowedOrigins(allowedOrigins)
+                    .allowedMethods(allowedMethods)
+                    .allowedHeaders(allowedHeaders)
+                    .exposedHeaders(exposedHeaders)
+                    .allowCredentials(allowCredentials).maxAge(maxAge);
+        }else{
+            log.info("娌℃湁鎵撳紑璺ㄥ煙寮�鍏�");
+        }
+    }
+
+    public CorsProperties getCorsProperties() {
+        return corsProperties;
+    }
+
+    public void setCorsProperties(CorsProperties corsProperties) {
+        this.corsProperties = corsProperties;
+    }
+
+    public String[] getDEFAULT_ORIGINS() {
+        return DEFAULT_ORIGINS;
+    }
+
+    public void setDEFAULT_ORIGINS(String[] DEFAULT_ORIGINS) {
+        this.DEFAULT_ORIGINS = DEFAULT_ORIGINS;
+    }
+
+    public String[] getDEFAULT_ALLOWED_HEADERS() {
+        return DEFAULT_ALLOWED_HEADERS;
+    }
+
+    public void setDEFAULT_ALLOWED_HEADERS(String[] DEFAULT_ALLOWED_HEADERS) {
+        this.DEFAULT_ALLOWED_HEADERS = DEFAULT_ALLOWED_HEADERS;
+    }
+
+    public String[] getDEFAULT_METHODS() {
+        return DEFAULT_METHODS;
+    }
+
+    public void setDEFAULT_METHODS(String[] DEFAULT_METHODS) {
+        this.DEFAULT_METHODS = DEFAULT_METHODS;
+    }
+
+    public boolean isDEFAULT_ALLOW_CREDENTIALS() {
+        return DEFAULT_ALLOW_CREDENTIALS;
+    }
+
+    public void setDEFAULT_ALLOW_CREDENTIALS(boolean DEFAULT_ALLOW_CREDENTIALS) {
+        this.DEFAULT_ALLOW_CREDENTIALS = DEFAULT_ALLOW_CREDENTIALS;
+    }
+
+    public long getDEFAULT_MAX_AGE() {
+        return DEFAULT_MAX_AGE;
+    }
+
+    public void setDEFAULT_MAX_AGE(long DEFAULT_MAX_AGE) {
+        this.DEFAULT_MAX_AGE = DEFAULT_MAX_AGE;
+    }
+
+    public List<String> getUnCheckUrls() {
+        return unCheckUrls;
+    }
+
+    public void setUnCheckUrls(List<String> unCheckUrls) {
+        this.unCheckUrls = unCheckUrls;
+    }
+
+    public List<String> getUnStorageRequestTimeUrls() {
+        return unStorageRequestTimeUrls;
+    }
+
+    public void setUnStorageRequestTimeUrls(List<String> unStorageRequestTimeUrls) {
+        this.unStorageRequestTimeUrls = unStorageRequestTimeUrls;
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/autoconfigure/VciAsyncConfig.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/autoconfigure/VciAsyncConfig.java
new file mode 100644
index 0000000..27abb72
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/autoconfigure/VciAsyncConfig.java
@@ -0,0 +1,109 @@
+package com.vci.starter.web.autoconfigure;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+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.Executor;
+
+/**
+ * timer闇�瑕佺殑榛樿鐨勭嚎绋嬫睜
+ * @author weidy
+ * @date 2021-2-2
+ */
+@Configuration
+@EnableAsync
+@ConditionalOnProperty(prefix = "vciasync",name="enabled",havingValue = "true",matchIfMissing = false)
+public class VciAsyncConfig {
+
+    /**
+     * 鍒濆鍖栧ぇ灏�
+     */
+    private int corePoolSize;
+
+    /**
+     * 鏈�澶х殑鍊�
+     */
+    private int maxPoolSize;
+
+    /**
+     * 闃熷垪鐨勪釜鏁�
+     */
+    private int queueCapacity;
+
+    /**
+     * 瀛樻椿鏃堕棿
+     */
+    private int keepAliveSeconds = 60;
+
+    /**
+     * 榛樿鐨勭嚎绋嬫睜锛�
+     * @return 绾跨▼姹犲璞�
+     */
+    @Bean
+    @ConditionalOnMissingBean
+    public Executor taskExecutor() {
+        ThreadPoolTaskExecutor executor = new VciThreadPoolTaskExecutor();
+        int cpu =  Runtime.getRuntime().availableProcessors();
+        if(getCorePoolSize() == 0){
+            setCorePoolSize(cpu);
+        }
+        if(getMaxPoolSize() == 0){
+            setMaxPoolSize(2* cpu);
+        }
+        if(getQueueCapacity() == 0){
+            setQueueCapacity(100);
+        }
+        executor.setCorePoolSize(getCorePoolSize());
+        executor.setMaxPoolSize(getMaxPoolSize());
+        executor.setQueueCapacity(getQueueCapacity());
+        executor.setKeepAliveSeconds(getKeepAliveSeconds());
+        executor.initialize();
+        return executor;
+    }
+
+    public int getCorePoolSize() {
+        return corePoolSize;
+    }
+
+    public void setCorePoolSize(int corePoolSize) {
+        this.corePoolSize = corePoolSize;
+    }
+
+    public int getMaxPoolSize() {
+        return maxPoolSize;
+    }
+
+    public void setMaxPoolSize(int maxPoolSize) {
+        this.maxPoolSize = maxPoolSize;
+    }
+
+    public int getQueueCapacity() {
+        return queueCapacity;
+    }
+
+    public void setQueueCapacity(int queueCapacity) {
+        this.queueCapacity = queueCapacity;
+    }
+
+    public int getKeepAliveSeconds() {
+        return keepAliveSeconds;
+    }
+
+    public void setKeepAliveSeconds(int keepAliveSeconds) {
+        this.keepAliveSeconds = keepAliveSeconds;
+    }
+
+    @Override
+    public String toString() {
+        return "VciAsyncConfig{" +
+                "corePoolSize=" + corePoolSize +
+                ", maxPoolSize=" + maxPoolSize +
+                ", queueCapacity=" + queueCapacity +
+                '}';
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/autoconfigure/VciThreadPoolTaskExecutor.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/autoconfigure/VciThreadPoolTaskExecutor.java
new file mode 100644
index 0000000..0c636b0
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/autoconfigure/VciThreadPoolTaskExecutor.java
@@ -0,0 +1,113 @@
+package com.vci.starter.web.autoconfigure;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+import org.springframework.util.concurrent.ListenableFuture;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.Future;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 绾跨▼姹�,澧炲姞鐩戞帶
+ * @author weidy
+ * @date 2021-2-2
+ */
+public class VciThreadPoolTaskExecutor extends ThreadPoolTaskExecutor {
+
+    /**
+     * 鏃ュ織
+     */
+    private static final Logger logger = LoggerFactory.getLogger(VciThreadPoolTaskExecutor.class);
+
+    /**
+     * 鎵撳嵃鏃ュ織
+     * @param prefix 鍓嶇紑
+     */
+    private void printLog(String prefix){
+        ThreadPoolExecutor threadPoolExecutor = getThreadPoolExecutor();
+        if (null == threadPoolExecutor) {
+            return;
+        }
+        logger.info(prefix + ", task_count [" + threadPoolExecutor.getTaskCount()
+                + "], completed_task_count [" + threadPoolExecutor.getCompletedTaskCount()
+                + "], active_thread_count [" + threadPoolExecutor.getActiveCount()
+                + "], blocking_queue_size [" + threadPoolExecutor.getQueue().size()
+                + "], thread_pool_size [" + threadPoolExecutor.getPoolSize()
+                + "], largest_pool_size_ever [" + threadPoolExecutor.getLargestPoolSize()
+                + "], core_thread_pool_size [" + threadPoolExecutor.getCorePoolSize()
+                + "], max_thread_pool_size [" + threadPoolExecutor.getMaximumPoolSize()
+                + "], thread_keep_alive_time [" + threadPoolExecutor.getKeepAliveTime(TimeUnit.SECONDS)
+                + "]");
+    }
+
+    /**
+     * 鎵ц
+     * @param task 浠诲姟鐨勫璞�
+     */
+    @Override
+    public void execute(Runnable task) {
+        printLog("1. do execute 鎵ц浠诲姟");
+        super.execute(task);
+    }
+
+    /**
+     * 鎵ц浠诲姟锛屽苟璁剧疆瓒呮椂
+     * @param task 浠诲姟鐨勫璞�
+     * @param startTimeout 瓒呮椂
+     */
+    @Override
+    public void execute(Runnable task, long startTimeout) {
+        printLog("2. do execute锛屾墽琛屼换鍔★紝骞朵笖璁剧疆瓒呮椂" );
+        super.execute(task, startTimeout);
+    }
+
+    /**
+     * 鎻愪氦
+     * @param task 浠诲姟
+     * @return 鎵ц
+     */
+    @Override
+    public Future<?> submit(Runnable task) {
+        printLog("1. do submit锛屾彁浜�");
+        return super.submit(task);
+    }
+
+    /**
+     * 鎻愪氦
+     * @param task 浠诲姟
+     * @param <T> 绫诲瀷
+     * @return 绫诲瀷
+     */
+    @Override
+    public <T> Future<T> submit(Callable<T> task) {
+        printLog("2. do submit");
+        return super.submit(task);
+    }
+
+    /**
+     * 鎻愪氦鍙洃鍚�
+     * @param task 浠诲姟
+     * @return 鐩戝惉
+     */
+    @Override
+    public ListenableFuture<?> submitListenable(Runnable task) {
+        printLog("1. do submitListenable");
+        return super.submitListenable(task);
+    }
+
+    /**
+     * 鎻愪氦鍙洃鍚�
+     * @param task 浠诲姟
+     * @param <T> 绫诲瀷
+     * @return 鐩戝惉鐨勭被鍨�
+     */
+    @Override
+    public <T> ListenableFuture<T> submitListenable(Callable<T> task) {
+        printLog("2. do submitListenable");
+        return super.submitListenable(task);
+    }
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/clientutil/BaseClientUtil.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/clientutil/BaseClientUtil.java
new file mode 100644
index 0000000..31af26b
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/clientutil/BaseClientUtil.java
@@ -0,0 +1,103 @@
+package com.vci.starter.web.clientutil;
+
+import com.vci.starter.web.exception.VciBaseException;
+import com.vci.starter.web.pagemodel.BaseResult;
+import com.vci.starter.web.pagemodel.DataGrid;
+import com.vci.starter.web.util.LangBaseUtil;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * 榛樿鐨勫鎴风璋冪敤绫�
+ * @author weidy
+ */
+public interface BaseClientUtil{
+
+    /**
+     * 浣跨敤璋冪敤鍣ㄦ煡璇ata绫诲瀷鐨勫睘鎬�
+     * @param interfaceName 鎺ュ彛鐨勫悕绉帮紝鍙互涓嶈澶氳
+     * @param clientUtilProcesser 璋冪敤鍣ㄦ墽琛屽嚱鏁�
+     * @param <T> 杩斿洖缁撴灉鐨勭被鍨�
+     * @return 鍒楄〃鏁版嵁
+     * @throws VciBaseException 鍙傛暟閿欒锛岃皟鐢ㄩ敊璇細鎶涘嚭寮傚父
+     */
+   default <T> List<T> queryData(String interfaceName,ClientUtilProcesser<T> clientUtilProcesser) throws VciBaseException {
+       List<T> dataList = new ArrayList<>();
+       BaseResult<T> result = queryByProvider(interfaceName,clientUtilProcesser);
+       dataList.addAll(result.getData());
+       return dataList;
+   }
+
+    /**
+     * 浣跨敤璋冪敤鍣ㄦ煡璇�
+     * @param interfaceName 鎺ュ彛鐨勫悕绉�
+     * @param clientUtilProcesser 璋冪敤鍣ㄦ墽琛屽嚱鏁�
+     * @param <T> 杩斿洖鐨勭被鍨�
+     * @return 鎵ц鐨勭粨鏋�
+     * @throws VciBaseException 璋冪敤閿欒鐨勬椂鍊欎細鎶涘嚭寮傚父
+     */
+   default <T> BaseResult<T> queryByProvider(String interfaceName,ClientUtilProcesser<T> clientUtilProcesser) throws VciBaseException {
+       try{
+           BaseResult<T> result = null;
+           if (clientUtilProcesser != null ) {
+               result  = clientUtilProcesser.queryByProvider();
+           }
+           if(result == null){
+               throw new VciBaseException("璋冪敤銆恵0}銆戞帴鍙o紝鏈嶅姟绔病鏈夎繑鍥炲��",new String[]{interfaceName});
+           }
+           if(!result.isSuccess()){
+               throw new VciBaseException(result.getMsg(),result.getMsgObjs());
+           }
+           return result;
+       }catch (VciBaseException e){
+           throw e;
+       }catch (Throwable e){
+           throw new VciBaseException(LangBaseUtil.getErrorMsg(e),new String[0],e);
+       }
+   }
+
+    /**
+     * 浣跨敤璋冪敤鏌ヨobj绫诲瀷鐨勫睘鎬�
+     * @param interfaceName 鎺ュ彛鏂规硶鐨勫悕瀛�
+     * @param clientUtilProcesser  璋冪敤鍣ㄦ墽琛屽嚱鏁�
+     * @param <T> 杩斿洖鐨勭粨鏋滅疮鎴愶紝鍙栧喅浜庤皟鐢ㄥ櫒鐨勮繑鍥炲��
+     * @return obj灞炴�х殑鍊�
+     * @throws VciBaseException 璋冪敤閿欒鏃朵細鎶涘嚭寮傚父
+     */
+   default <T> T queryObj(String interfaceName,ClientUtilProcesser<T> clientUtilProcesser) throws VciBaseException {
+       return queryByProvider(interfaceName,clientUtilProcesser).getObj();
+   }
+
+    /**
+     * 鏌ヨ鍒楄〃鏁版嵁
+     * @param interfaceName 鎺ュ彛鏂规硶鐨勫悕瀛�
+     * @param clientUtilProcesser  璋冪敤鍣ㄦ墽琛屽嚱鏁�
+     * @param <T> 杩斿洖鐨勭粨鏋滐紝鍙栧喅浜庤皟鐢ㄥ櫒鐨勮繑鍥炲��
+     * @return 鍒楄〃鏁版嵁
+     * @throws VciBaseException 璋冪敤閿欒鏃朵細鎶涘嚭寮傚父
+     */
+   default <T> DataGrid<T> queryGrid(String interfaceName,ClientUtilProcesser<T> clientUtilProcesser) throws VciBaseException{
+       BaseResult<T> result = queryByProvider(interfaceName,clientUtilProcesser);
+       DataGrid<T> dataGrid = new DataGrid<>();
+       if(result.getData()!=null) {
+           dataGrid.setData(result.getData().stream().collect(Collectors.toList()));
+       }
+       dataGrid.setTotal(result.getTotal());
+       return dataGrid;
+   }
+
+    /**
+     * 鎵ц鏁版嵁锛岃繑鍥炴墽琛岀粨鏋�
+     * @param interfaceName 鎺ュ彛鏂规硶鐨勫悕瀛�
+     * @param clientUtilProcesser  璋冪敤鍣ㄦ墽琛屽嚱鏁�
+     * @param <T> 杩斿洖鐨勭粨鏋滐紝鍙栧喅浜庤皟鐢ㄥ櫒鐨勮繑鍥炲��
+     * @return true琛ㄧず鎴愬姛锛屽け璐ョ殑鏃跺�欎細鐩存帴鎶涘嚭寮傚父
+     * @throws VciBaseException 璋冪敤閿欒鏃朵細鎶涘嚭寮傚父
+     */
+   default <T> boolean executeData(String interfaceName,ClientUtilProcesser<T> clientUtilProcesser) throws VciBaseException{
+       BaseResult<T> result = queryByProvider(interfaceName,clientUtilProcesser);
+       return result.isSuccess();
+   }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/clientutil/ClientUtilProcesser.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/clientutil/ClientUtilProcesser.java
new file mode 100644
index 0000000..f89526a
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/clientutil/ClientUtilProcesser.java
@@ -0,0 +1,18 @@
+package com.vci.starter.web.clientutil;
+
+import com.vci.starter.web.pagemodel.BaseResult;
+
+
+/**
+ * 瀹㈡埛绔皟鐢ㄧ被鐨勯�氱敤
+ * @author weidy
+ */
+@FunctionalInterface
+public interface ClientUtilProcesser<T> {
+
+    /**
+     * 浣跨敤璋冪敤鍣ㄦ煡璇�
+     * @return 鎵ц鐨勭粨鏋�
+     */
+    BaseResult<T> queryByProvider();
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/constant/CommonReturnCodeConstant.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/constant/CommonReturnCodeConstant.java
new file mode 100644
index 0000000..0788396
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/constant/CommonReturnCodeConstant.java
@@ -0,0 +1,60 @@
+package com.vci.starter.web.constant;
+
+/**
+ * 甯哥敤杩斿洖鍊�
+ * @author weidy
+ */
+public class CommonReturnCodeConstant {
+
+    /**
+     * 娌℃湁鐧诲綍
+     */
+    public static final String NO_LOGIN = "NO_LOGIN";
+
+    /**
+     * 娌℃湁鏉冮檺
+     */
+    public static final String NO_RIGHT = "NO_RIGHT";
+
+    /**
+     * 琚己鍒朵笅绾�
+     */
+    public static final String POP_OFFLINE ="POP_OFFLINE";
+
+    /**
+     * 娌℃湁鏁版嵁鏉冮檺
+     */
+    public static final String NO_DATA_RIGHT = "NO_DATA_RIGHT";
+
+    /**
+     * 娌℃湁UI鏉冮檺
+     */
+    public static final String NO_UI_RIGHT = "NO_UI_RIGHT";
+
+    /**
+     * 鐢ㄦ埛瀵嗙骇涓嶅厑璁�
+     */
+    public static final String USER_SECRET_LOW = "USER_SECRET_LOW";
+
+    /**
+     * 璇锋眰璺緞娌℃湁鎵惧埌
+     */
+    public static final String URL_NOT_FOUND = "URL_NOT_FOUND";
+
+    /**
+     * 鍑虹幇浜嗗紓甯�
+     */
+    public static final String EXCEPTION = "EXCEPTION";
+
+    /**
+     * 鍙傛暟閿欒
+     */
+    public static final String PARAM_ERROR="PARAM_ERROR";
+
+    /**
+     * 鏁版嵁閲嶅
+     */
+    public static final String DATA_REPEAT = "dataRepeat";
+
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/constant/FileExtensionConstant.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/constant/FileExtensionConstant.java
new file mode 100644
index 0000000..1d58caa
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/constant/FileExtensionConstant.java
@@ -0,0 +1,79 @@
+package com.vci.starter.web.constant;
+
+/**
+ * 甯哥敤鏂囦欢鐨勫悗缂�鍚�
+ * @author weidy
+ * @date 2020/5/5
+ */
+public class FileExtensionConstant {
+
+    /**
+     * excel2003鏂囦欢
+     */
+    public static final String XLS = "xls";
+
+    /**
+     * excel2007鍙婁互涓婄増鏈枃浠�
+     */
+    public static final String XLSX = "xlsx";
+
+    /**
+     * word2003鏂囦欢
+     */
+    public static final String DOC = "doc";
+
+    /**
+     * word2007鍙婁互涓婄増鏈枃浠�
+     */
+    public static final String DOCX = "docx";
+
+    /**
+     * 骞荤伅鐗�2003鏂囦欢
+     */
+    public static final String PPT = "ppt";
+
+    /**
+     * 骞荤伅鐗�2007鍙婁互涓婄増鏈�
+     */
+    public static final String PPTX = "pptx";
+
+    /**
+     * Pdf鏂囦欢
+     */
+    public static final String PDF = "pdf";
+
+    /**
+     * 鏂囨湰鏂囦欢
+     */
+    public static final String TXT ="txt";
+
+    /**
+     * 缃戦〉鏂囦欢
+     */
+    public static final String HTML = "html";
+
+    /**
+     * 琛ㄥ崟鏂囦欢
+     */
+    public static final String DVF = "dvf";
+
+    /**
+     * 妯℃澘
+     */
+    public static final String DTF = "dtf";
+
+    /**
+     * 鍥剧墖
+     */
+    public static final String PNG = "png";
+
+    /**
+     * jpg鍥剧墖
+     */
+    public static final String JPG = "jpg";
+
+    /**
+     * XPS
+     */
+    public static final String XPS = "xps";
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/constant/FrameWorkLcStatusConstant.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/constant/FrameWorkLcStatusConstant.java
new file mode 100644
index 0000000..e975dcd
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/constant/FrameWorkLcStatusConstant.java
@@ -0,0 +1,24 @@
+package com.vci.starter.web.constant;
+
+/**
+ * 骞冲彴妗嗘灦鐨勭敓鍛藉懆鏈熺殑缂栧彿
+ * @author weidy
+ * @date 2019/12/27
+ */
+public class FrameWorkLcStatusConstant {
+
+    /**
+     * 骞冲彴妗嗘灦鐨勪笟鍔℃。妗堥�氱敤鐨勭敓鍛藉懆鏈�
+     */
+    public static final String FRAME_WORK_LIFE_CYCLE_NAME = "frameworkDataLc";
+
+    /**
+     * 榛樿鐨勭敓鍛藉懆鏈�
+     */
+    public static final String EMTYPE_LIFE_CYCLE = "defaultLC";
+
+    /**
+     * 閫氱敤鐨勫彂甯冪敓鍛藉懆鏈燂紝缂栧埗锛屽鏍革紝鍙戝竷
+     */
+    public static final String RELEASE_LIFE_CYCLE = "releaseDataLc";
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/constant/QueryOptionConstant.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/constant/QueryOptionConstant.java
new file mode 100644
index 0000000..ba3b96c
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/constant/QueryOptionConstant.java
@@ -0,0 +1,76 @@
+package com.vci.starter.web.constant;
+
+/**
+ * 鏌ヨ绫诲瀷
+ * @author weidy
+ */
+public class QueryOptionConstant {
+
+    /**
+     * IN
+     */
+    public  static  final String IN = "\\IN";
+
+    /**
+     * NOT IN
+     */
+    public 	static  final String NOTIN ="\\NOTIN";
+
+    /**
+     * 涓嶇瓑浜�
+     */
+    public  static  final String NOTEQUAL = "!=";
+
+    /**
+     *  澶т簬
+     */
+    public  static  final String MORE=">";
+
+    /**
+     * 澶т簬绛変簬
+     */
+    public  static  final String MORETHAN=">=";
+
+    /**
+     * 灏忎簬
+     */
+    public  static  final String LESS = "<";
+
+    /**
+     * 灏忎簬绛変簬
+     */
+    public  static  final String LESSTHAN = "<=";
+
+    /**
+     * 鎴栬��
+     */
+    public  static  final String OR = "\\OR";
+
+    /**
+     * 绛変簬绌�
+     */
+    public  static  final String ISNULL ="=null";
+
+    /**
+     * 涓嶇瓑浜庣┖
+     */
+    public  static  final String ISNOTNULL="!=null";
+
+    /**
+     * 绛変簬
+     */
+    public static  final String  EQUAL = "=";
+
+    /**
+     * 涓�
+     */
+    public static final String AND = "and";
+
+    /**
+     * 鏃笉鏄痑nd,涔熶笉鏄痮r鐨勬柟寮忋�傝繖绉嶆槸鐩存帴鎷兼帴鍒皐here鍚�
+     */
+    public static final String NO_OR_AND = "${no_or_and}";
+
+
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/constant/RegExpConstant.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/constant/RegExpConstant.java
new file mode 100644
index 0000000..3894673
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/constant/RegExpConstant.java
@@ -0,0 +1,84 @@
+package com.vci.starter.web.constant;
+
+/**
+ * 姝e垯琛ㄨ揪寮�
+ * @author weidy
+ * @date 2019/10/18 17:35
+ */
+public class RegExpConstant {
+
+    /**
+     * 鍖呭惈涓枃
+     */
+    public static final String INCLUDE_CHINESE = "[\u0391-\uFFE5]";
+
+    /**
+     * 鍏ㄩ儴鏄暟瀛�
+     */
+    public static final String NUMBER = "^[0-9]*$";
+
+    /**
+     * 鏁存暟
+     */
+    public static final String INT = "/^-?[1-9]+[0-9]*$/";
+
+    /**
+     * 闀挎暣褰�
+     */
+    public static final String LONG = "/^-?[1-9]+[0-9]*$/";
+
+    /**
+     * 鍙岀簿搴�
+     */
+    public static final String DOUBLE = "[0-9]*(\\.[0-9]*|[eE][+-][0-9]*)$";
+
+    /**
+     * 鍏ㄩ儴閮芥槸瀛楁瘝
+     */
+    public static final String LETTER = "^[A-Za-z]+$";
+
+    /**
+     * 瀛楁瘝鍜屾暟瀛�
+     */
+    public static final String LETTER_AND_NUMBER = "^[A-Za-z0-9]+$";
+
+    /**
+     * 鍏ㄩ儴鏄ぇ鍐欏瓧姣�
+     */
+    public static final String UP_LETTER = "^[A-Z]+$";
+
+    /**
+     * 鍏ㄩ儴鏄皬鍐欏瓧姣�
+     */
+    public static final String LOW_LETTER = "^[a-z]+$";
+
+    /**
+     * 鍏ㄩ儴鐗规畩瀛楃
+     */
+    public static final String SPECIAL_CHARACTER = "^[` ~!@#$%^&*()_\\-+=<>?:\"{}|,.\\/;'\\[\\]路~锛丂#锟�%鈥︹��&*锛堬級鈥斺�擻\-+={}|銆娿�嬶紵锛氣�溾�濄�愩�戙�侊紱鈥樷�欙紝銆傘�乚+$";
+    /**
+     * 鍖呭惈鏈夊瓧姣�
+     */
+    public static final String HAS_LETTER = ".*[a-z][A-Z]{1,}.*";
+
+    /**
+     * 鍖呭惈鏈夊ぇ鍐欏瓧姣�
+     */
+    public static final String HAS_UP_LETTER = ".*[A-Z]{1,}.*";
+
+    /**
+     * 鍖呭惈鏈夊皬鍐欏瓧姣�
+     */
+    public static final String HAS_LOW_LETTER = ".*[a-z]{1,}.*";
+
+    /**
+     * 鍖呭惈鏈夐樋鎷変集鏁板瓧
+     */
+    public static final String HAS_NUMBER  = ".*[0-9]{1,}.*";
+
+    /**
+     * 鍖呭惈鏈夌壒娈婂瓧绗�
+     */
+    public static final String HAS_SPECIAL_CHARACTER = ".*[` ~!@#$%^&*()_\\-+=<>?:\"{}|,.\\/;'\\[\\]路~锛丂#锟�%鈥︹��&*锛堬級鈥斺�擻\-+={}|銆娿�嬶紵锛氣�溾�濄�愩�戙�侊紱鈥樷�欙紝銆傘�乚{1,}.*";
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/constant/RevisionConstant.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/constant/RevisionConstant.java
new file mode 100644
index 0000000..4454b5e
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/constant/RevisionConstant.java
@@ -0,0 +1,19 @@
+package com.vci.starter.web.constant;
+
+/**
+ * 榛樿鐨勭増鏈鍒欑殑鍚嶇О
+ * @author weidy
+ * @date 2020/4/15
+ */
+public class RevisionConstant {
+
+    /**
+     * 浠ュ瓧姣嶅ぇA寮�濮嬬殑缂栫爜瑙勫垯锛屾病鏈夊墠缂�鍜屽悗缂�锛屾闀夸负1锛屽苟涓斾篃娌℃湁璺宠穬瀛楃
+     */
+    public static final String CHARACTER = "characterversionrule";
+
+    /**
+     * 浠ユ暟瀛�
+     */
+    public static final String NUMBER = "numberversionrule";
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/constant/SpecialCharacterConstant.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/constant/SpecialCharacterConstant.java
new file mode 100644
index 0000000..31715ef
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/constant/SpecialCharacterConstant.java
@@ -0,0 +1,60 @@
+package com.vci.starter.web.constant;
+
+/**
+ * 鐗规畩鐨勭鍙�,涓轰簡绗﹀悎瑙勮寖锛岃鍕垮湪鍒ゆ柇璇彞涓洿鎺ュ啓绗﹀彿鍐呭
+ * @author weidy
+ * @date 2020/5/5
+ */
+public class SpecialCharacterConstant {
+
+    /**
+     * 鑻辨枃鍙ュ彿
+     */
+    public static final String POINT = ".";
+
+    /**
+     * 涓嬪垝绾�
+     */
+    public static final String UNDER_LINE = "_";
+
+    /**
+     * 杩炴帴妯嚎
+     */
+    public static final String CONNECTOR = "-";
+
+    /**
+     * 绛夊彿
+     */
+    public static final String EQUAL = "=";
+
+    /**
+     * 鍒嗗彿
+     */
+    public static final String SEMICOLON = ";";
+
+    /**
+     * 閫楀彿
+     */
+    public static final String COMMA = ",";
+
+    /**
+     * 缇庡厓绗﹀彿
+     */
+    public static final String DOLLAR = "$";
+
+    /**
+     * 鏄熷彿
+     */
+    public static final String STAR = "*";
+
+    /**
+     * at绗﹀彿
+     */
+    public static final String AT = "@";
+
+    /**
+     * #鍙�
+     */
+    public static final String SHARP = "#";
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/constant/TokenKeyConstant.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/constant/TokenKeyConstant.java
new file mode 100644
index 0000000..37bdd93
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/constant/TokenKeyConstant.java
@@ -0,0 +1,40 @@
+package com.vci.starter.web.constant;
+
+/**
+ * token鐨勭浉鍏砶ey
+ * @author weidy
+ * @date 2019/11/7 10:10 AM
+ */
+public class TokenKeyConstant {
+
+    /**
+     * 鐢ㄦ埛鐨則oken浼犺緭鏃朵娇鐢ㄧ殑鍚嶇О
+     */
+    public static final String USER_TOKEN_KEY ="AuthorizationToken";
+
+    /**
+     * 绯荤粺鐨則oken浼犺緭鏃朵娇鐢ㄧ殑鍚嶇О
+     */
+    public static final String SYSTEM_PRIVATE_KEY = "AuthorizationSystemToken";
+
+    /**
+     * 绯荤粺鐨勬棩蹇楅摼璺富閿紶杈撴椂浣跨敤鐨勫悕绉�
+     */
+    public static final String LOG_TRACE_ID_KEY = "AuthorizationLogTraceId";
+
+    /**
+     * 鏃ュ織鐨勮拷韪富閿殑鍚嶇О
+     */
+    public static final String TRACE_ID = "logTraceId";
+
+    /**
+     * 绯荤粺鐨勫璇弬鏁板悕绉�
+     */
+    public static final String LANGUAGE_KEY = "vciLanguageCode";
+
+    /**
+     * 璇锋眰鐨勬椂闂村弬鏁�
+     */
+    public static final String REQUEST_TIMESTAMP = "vciHttpStartRequestTime";
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/constant/VciSystemVarConstants.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/constant/VciSystemVarConstants.java
new file mode 100644
index 0000000..05d3b7c
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/constant/VciSystemVarConstants.java
@@ -0,0 +1,152 @@
+package com.vci.starter.web.constant;
+
+
+import com.vci.starter.web.pagemodel.SessionInfo;
+import com.vci.starter.web.util.VciBaseUtil;
+import com.vci.starter.web.util.VciDateUtil;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+/**
+ * 绯荤粺鍙橀噺
+ * @author weidy
+ */
+public  class VciSystemVarConstants {
+
+    /**
+     * 鍒濆鍖栫殑鏃跺�欐斁鍏ユ暟鎹�
+     */
+    public VciSystemVarConstants(){
+        SYSTEM_VAR_KEYNAMEMAP.put(CURRENTTIME,"褰撳墠鏃堕棿");
+        SYSTEM_VAR_KEYNAMEMAP.put(CURRENTDATE,"褰撳墠鏃ユ湡");
+        SYSTEM_VAR_KEYNAMEMAP.put(CURRENTDATETIME,"褰撳墠鏃ユ湡鏃堕棿");
+        SYSTEM_VAR_KEYNAMEMAP.put(CURRENTUSER_OID,"褰撳墠鐢ㄦ埛涓婚敭");
+        SYSTEM_VAR_KEYNAMEMAP.put(CURRENTUSER_ID,"褰撳墠鐢ㄦ埛璐︽埛");
+        SYSTEM_VAR_KEYNAMEMAP.put(CURRENTUSER_NAME,"褰撳墠鐢ㄦ埛濮撳悕");
+        SYSTEM_VAR_KEYNAMEMAP.put(CURRENTUSER_SECRETGRADE,"褰撳墠鐢ㄦ埛瀵嗙骇");
+        SYSTEM_VAR_KEYNAMEMAP.put(CURRENTUSER_IP_SECRET,"褰撳墠鐢ㄦ埛鐨勬満鍣ㄥ瘑绾�");
+        SYSTEM_VAR_KEYNAMEMAP.put(CURRENTUSER_GROUPOID,"褰撳墠鐢ㄦ埛鐨勯儴闂ㄧ殑涓婚敭");
+//        SYSTEM_VAR_KEYNAMEMAP.put(CURRENTUSER_GROUPNUM,"褰撳墠鐢ㄦ埛鎵�灞為儴闂ㄧ紪鍙�");
+        SYSTEM_VAR_KEYNAMEMAP.put(CURRENTUSER_GROUPNAME,"褰撳墠鐢ㄦ埛鎵�灞為儴闂ㄥ悕绉�");
+        SYSTEM_VAR_KEYNAMEMAP.put(CURRENTUSER_EMAIL,"褰撳墠鐢ㄦ埛閭欢鍦板潃");
+        SYSTEM_VAR_KEYNAMEMAP.put(CURRENTUSER_ROLENAME,"褰撳墠鐢ㄦ埛鎵�灞炶鑹插悕绉�");
+        SYSTEM_VAR_KEYNAMEMAP.put(CURRENTUSER_BUSINESS_UNIT,"褰撳墠鐢ㄦ埛鎵�灞炰笟鍔″崟鍏冧富閿�");
+        SYSTEM_VAR_KEYNAMEMAP.put(CURRENTUSER_BUSINESS_UNIT_NAME,"褰撳墠鐢ㄦ埛鎵�灞炰笟鍔″崟鍏�");
+    }
+
+    /**
+     * 褰撳墠鐢ㄦ埛涓婚敭
+     */
+    public static final String CURRENTUSER_OID = "#CURRENTUSER.OID#";
+
+    /**
+     * 褰撳墠鐢ㄦ埛璐︽埛
+     */
+    public static final String CURRENTUSER_ID = "#CURRENTUSER.ID#";
+
+    /**
+     * 褰撳墠鏃堕棿
+     */
+    public static final String CURRENTTIME = "#CURRENTTIME#";
+
+    /**
+     * 褰撳墠鏃ユ湡
+     */
+    public static final String CURRENTDATE = "#CURRENTDATE#";
+
+    /**
+     * 褰撳墠鏃ユ湡鏃堕棿
+     */
+    public static final String CURRENTDATETIME = "#CURRENTDATETIME#";
+
+    /**
+     * 褰撳墠鐢ㄦ埛濮撳悕
+     */
+    public static final String CURRENTUSER_NAME = "#CURRENTUSER_NAME#";
+
+    /**
+     * 褰撳墠鐢ㄦ埛瀵嗙骇
+     */
+    public static final String CURRENTUSER_SECRETGRADE = "#CURRENTUSER.SECRETGRADE#";
+
+    /**
+     * 褰撳墠鐢ㄦ埛鐨処P瀵嗙骇
+     */
+    public static final String CURRENTUSER_IP_SECRET = "#CURRENTUSER.IPSECRET#";
+
+    /**
+     * 褰撳墠鐢ㄦ埛鎵�灞炰笟鍔″崟鍏�
+     */
+    public static final String CURRENTUSER_BUSINESS_UNIT = "#CURRENTUSER.BUSINESSUNIT#";
+
+    /**
+     * 褰撳墠鐢ㄦ埛鎵�灞炰笟鍔″崟鍏冨悕绉�
+     */
+    public static final String CURRENTUSER_BUSINESS_UNIT_NAME = "#CURRENTUSER.BUSINESSUNITNAME#";
+
+//    /**
+//     * 褰撳墠鐢ㄦ埛鎵�灞為儴闂ㄧ紪鍙�
+//     */
+//    public static final String CURRENTUSER_GROUPNUM = "#CURRENTUSER.GROUPNUM#";
+
+    /**
+     * 褰撳墠鐢ㄦ埛鐨勯儴闂ㄤ富閿�
+     */
+    public static final String CURRENTUSER_GROUPOID = "#CURRENTUSER.GROUPOID#";
+
+    /**
+     * 褰撳墠鐢ㄦ埛鎵�灞為儴闂ㄥ悕绉�
+     */
+    public static final String CURRENTUSER_GROUPNAME = "#CURRENTUSER.GROUPNAME#";
+
+    /**
+     * 褰撳墠鐢ㄦ埛閭欢鍦板潃
+     */
+    public static final String CURRENTUSER_EMAIL  ="#CURRENTUSER.EMAIL#";
+
+    /**
+     * 褰撳墠鐢ㄦ埛鎵�灞炶鑹插悕绉�
+     */
+    public static final String CURRENTUSER_ROLENAME = "#CURRENTUSER.ROLENAME#";
+
+    /**
+     * 绯荤粺鍙橀噺鐨勬暟缁�
+     */
+    public static final String[] SYSTEM_VAR_KEYS = {CURRENTUSER_OID,CURRENTUSER_ID,CURRENTDATE,CURRENTTIME,CURRENTDATETIME,CURRENTUSER_GROUPOID,CURRENTUSER_NAME,CURRENTUSER_SECRETGRADE,
+            CURRENTUSER_GROUPNAME,CURRENTUSER_EMAIL,CURRENTUSER_ROLENAME,CURRENTUSER_IP_SECRET,CURRENTUSER_BUSINESS_UNIT,CURRENTUSER_BUSINESS_UNIT_NAME};
+    /**
+     * 绯荤粺鍙橀噺瀵瑰簲鐨勪腑鏂�
+     */
+    public static final Map<String,String> SYSTEM_VAR_KEYNAMEMAP = new HashMap<String, String>();
+
+    /**
+     * 鑾峰彇绯荤粺鐨勫彉閲忕殑鍊�
+     * @return 鍙橀噺鐨勫��
+     */
+    public static Map<String,String> getSystemVarValueMap(){
+        Map<String,String> systemVarMap = new HashMap<>();
+        SessionInfo sessionInfo = VciBaseUtil.getCurrentUserSessionInfo();
+        if(sessionInfo!=null){
+            systemVarMap.put(CURRENTUSER_OID,sessionInfo.getUserOid());
+            systemVarMap.put(CURRENTUSER_ID,sessionInfo.getUserId());
+            systemVarMap.put(CURRENTUSER_NAME,sessionInfo.getUserName());
+            systemVarMap.put(CURRENTDATETIME, VciDateUtil.getNowString());
+            systemVarMap.put(CURRENTDATE,VciDateUtil.getNowString(VciDateUtil.DateFormat));
+            systemVarMap.put(CURRENTTIME,VciDateUtil.getNowString(VciDateUtil.TimeFormat));
+            systemVarMap.put(CURRENTUSER_SECRETGRADE,sessionInfo.getUserSecret());
+            systemVarMap.put(CURRENTUSER_GROUPNAME,sessionInfo.getDeptName());
+            systemVarMap.put(CURRENTUSER_GROUPOID,sessionInfo.getDeptOid());
+            systemVarMap.put(CURRENTUSER_EMAIL,sessionInfo.getEmail());
+            systemVarMap.put(CURRENTUSER_ROLENAME, Optional.ofNullable(sessionInfo.getRolesName().values()).orElseGet(()->new ArrayList<>()).stream().collect(Collectors.joining(",")));
+            systemVarMap.put(CURRENTUSER_IP_SECRET,sessionInfo.getIpSecret());
+            systemVarMap.put(CURRENTUSER_BUSINESS_UNIT,sessionInfo.getOrgsOid());
+            systemVarMap.put(CURRENTUSER_BUSINESS_UNIT_NAME,sessionInfo.getOrgsName());
+        }
+        return systemVarMap;
+
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/BaseEnum.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/BaseEnum.java
new file mode 100644
index 0000000..2e365eb
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/BaseEnum.java
@@ -0,0 +1,22 @@
+package com.vci.starter.web.enumpck;
+
+/**
+ * 鍩烘湰鐨勬灇涓剧被锛岃鐢熷懡鍛ㄦ湡鍜屾灇涓鹃兘瀹炵幇杩欎釜鎺ュ彛锛屽惁鍒欐棤娉曡骞冲彴鎵弿鍒�
+ * @author weidy
+ * @date 2019/10/31 10:38 AM
+ */
+public interface BaseEnum {
+    /**
+     * 鑾峰彇鏋氫妇鍊�
+     * @return 鏋氫妇鍊�
+     */
+    String getValue();
+
+    /**
+     * 鑾峰彇鏄剧ず鏂囨湰
+     * @return 鏄剧ず鏂囨湰
+     */
+    String getText();
+
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/BaseEnumInt.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/BaseEnumInt.java
new file mode 100644
index 0000000..e1c1768
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/BaseEnumInt.java
@@ -0,0 +1,23 @@
+package com.vci.starter.web.enumpck;
+
+/**
+ * 鍩烘湰鐨勬灇涓剧被锛岃鐢熷懡鍛ㄦ湡鍜屾灇涓鹃兘瀹炵幇杩欎釜鎺ュ彛锛屽惁鍒欐棤娉曡骞冲彴鎵弿鍒�
+ * 杩欎釜鏄�间负鏁板瓧鍨�
+ * @author weidy
+ * @date 2019/10/31 10:38 AM
+ */
+public interface BaseEnumInt {
+    /**
+     * 鑾峰彇鏋氫妇鍊�
+     * @return 鏋氫妇鍊�
+     */
+    int getValue();
+
+    /**
+     * 鑾峰彇鏄剧ず鏂囨湰
+     * @return 鏄剧ず鏂囨湰
+     */
+    String getText();
+
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/BooleanEnum.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/BooleanEnum.java
new file mode 100644
index 0000000..b7400b0
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/BooleanEnum.java
@@ -0,0 +1,41 @@
+package com.vci.starter.web.enumpck;
+
+/**
+ * 骞冲彴閲岀殑VIBoolean绫诲瀷瀛楁
+ * @author weidy
+ */
+public enum BooleanEnum {
+    /**
+     * true
+     */
+    TRUE("true"),
+    /**
+     * false
+     */
+    FASLE("false");
+
+    /**
+     * 鏋氫妇鐨勫��
+     */
+    private final String value ;
+
+    /**
+     * 鏋氫妇鍐呴儴鏋勯�犳柟娉�
+     * @param value 鏋氫妇鐨勫��
+     */
+    private BooleanEnum(String value){
+        this.value = value;
+    }
+
+    /**
+     * 鑾峰彇鍊�
+     * @return 鏋氫妇鍊�
+     */
+    public String getValue() {
+        return value;
+    }
+
+
+
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/DataBaseEnum.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/DataBaseEnum.java
new file mode 100644
index 0000000..41ebf84
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/DataBaseEnum.java
@@ -0,0 +1,148 @@
+package com.vci.starter.web.enumpck;
+
+/**
+ * 鏁版嵁搴撶殑绫诲瀷鏋氫妇
+ * @author weidy
+ * @date 2019/10/30 2:46 PM
+ */
+public enum DataBaseEnum implements BaseEnum{
+
+
+    /**
+     * MYSQL
+     */
+    MYSQL("mysql","MYSQL"),
+
+    /**
+     * ORACLE
+     */
+    ORACLE("oracle","ORACLE"),
+
+    /**
+     * POSTGRESQL
+     */
+    POSTGRESQL("postgresql","POSTGRESQL"),
+
+    /**
+     * DB2
+     */
+    DB2("db2","DB2"),
+
+    /**
+     * SQL_SERVER
+     */
+    SQL_SERVER("mssql","SQL_SERVER"),
+
+    /**
+     * 鍥戒骇杈炬ⅵ
+     */
+    DM("dm","杈炬ⅵ"),
+
+    /**
+     * 闃块噷宸村反OceanBase
+     */
+    OCEAN_BASE("oceanbase","闃块噷宸村反OceanBase"),
+
+    /**
+     * sqlite
+     */
+    SQLITE("sqlite","SQLITE");
+
+    /**
+     * 鏋氫妇鐨勫��
+     */
+    private String value;
+
+    /**
+     * 鏋氫妇鏄剧ず鏂囨湰
+     */
+    private String text;
+
+    /**
+     * 鑾峰彇鏋氫妇鍊�
+     * @return 鏋氫妇鍊�
+     */
+    @Override
+    public String getValue() {
+        return value;
+    }
+
+    /**
+     * 璁剧疆鏋氫妇鍊�
+     * @param value 鏋氫妇鍊�
+     */
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    /**
+     * 鑾峰彇鏋氫妇鏄剧ず鏂囨湰
+     * @return  鏄剧ず鏂囨湰
+     */
+    @Override
+    public String getText() {
+        return text;
+    }
+
+    /**
+     * 璁剧疆鏄剧ず鏂囨湰
+     * @param text 鏄剧ず鏂囨湰
+     */
+    public void setText(String text) {
+        this.text = text;
+    }
+
+    /**
+     * 鏋勯�犲嚱鏁�
+     * @param value 鍊�
+     * @param text 鏄剧ず鏂囨湰
+     */
+    private DataBaseEnum(String value, String text){
+        this.value = value;
+        this.text = text;
+    }
+
+    /**
+     * 鏍规嵁鍚嶇О鑾峰彇瀵瑰簲鐨勬灇涓惧��
+     * @param text 鍚嶇О
+     * @return 鏋氫妇鍊�
+     */
+    public static String getValueByText(String text){
+        for(DataBaseEnum wenum : DataBaseEnum.values()){
+            if(wenum.getText().equalsIgnoreCase(text)){
+                return wenum.getValue();
+            }
+        }
+        return "";
+    }
+
+    /**
+     * 鏍规嵁鏋氫妇鍊艰幏鍙栧悕绉�
+     * @param value 鏋氫妇鍊�
+     * @return 鍚嶇О
+     */
+    public static String getTextByValue(String value){
+        for(DataBaseEnum wenum : DataBaseEnum.values()){
+            if(wenum.getValue().equalsIgnoreCase(value)){
+                return wenum.getText();
+            }
+        }
+        return "";
+    }
+
+    /**
+     * 鏍规嵁鏋氫妇鍊艰幏鍙栨灇涓惧璞�
+     * @param value 鏋氫妇鍊�
+     * @return
+     */
+    public static DataBaseEnum forValue(String value){
+        for(DataBaseEnum wenum : DataBaseEnum.values()){
+            if(wenum.getValue().equalsIgnoreCase(value)){
+                return wenum;
+            }
+        }
+        return ORACLE;
+    }
+
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/DataSecretEnum.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/DataSecretEnum.java
new file mode 100644
index 0000000..2d6a603
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/DataSecretEnum.java
@@ -0,0 +1,122 @@
+package com.vci.starter.web.enumpck;
+
+import com.vci.starter.web.annotation.VciEnum;
+
+/**
+ * 瀵嗙骇绠$悊
+ * @author weidy
+ */
+@VciEnum(name="Enumsecretgrade",text = "鏁版嵁瀵嗙骇",description = "榛樿涓洪潪瀵嗭紝鍐呴儴锛岀瀵嗭紝鏈哄瘑锛涙湁浜涘崟浣嶆病鏈夊唴閮紝鍒欏彲浠ュ湪閰嶇疆鏂囦欢涓厤缃畍ciEnum.Enumsecretgrade.inner=false")
+public enum DataSecretEnum implements BaseEnumInt{
+
+    /**
+     * 闈炲瘑
+     */
+    NONE(10,"闈炲瘑"),
+    /**
+     * 鍐呴儴
+     */
+    INNER(15,"鍐呴儴"),
+    /**
+     * 绉樺瘑
+     */
+    SECRET(20,"绉樺瘑"),
+    /**
+     * 鏈哄瘑
+     */
+    PRIVACY(30,"鏈哄瘑");
+
+    /**
+     * 鏋氫妇鍊�
+     */
+    private int value;
+
+    /**
+     * 鏋氫妇鏄剧ず鍊�
+     */
+    private String text;
+
+    /**
+     * 鑾峰彇鏋氫妇鍊�
+     * @return 鏋氫妇鍊�
+     */
+    public int getValue() {
+        return value;
+    }
+
+    /**
+     * 璁剧疆鏋氫妇鍊�
+     * @param value 鏋氫妇鍊�
+     */
+    public void setValue(int value) {
+        this.value = value;
+    }
+
+    /**
+     * 鑾峰彇鏄剧ず鏂囨湰
+     * @return 鏄剧ず鏂囨湰
+     */
+    public String getText() {
+        return text;
+    }
+
+    /**
+     * 璁剧疆鏄剧ず鏂囨湰
+     * @param text 鏄剧ず鏂囨湰
+     */
+    public void setText(String text) {
+        this.text = text;
+    }
+
+    /**
+     * 鏋氫妇鍐呴儴鏋勯�犳柟娉�
+     * @param secret 鏋氫妇鍊�
+     * @param secretText 鏄剧ず鏂囨湰
+     */
+    private DataSecretEnum(int secret,String secretText){
+        this.value = secret;
+        this.text = secretText;
+    }
+
+    /**
+     * 鏍规嵁鏋氫妇鐨勫�艰幏鍙栨樉绀烘枃鏈�
+     * @param secret 鏋氫妇鍊�
+     * @return 鏄剧ず鏂囨湰
+     */
+    public static String getSecretText(int secret){
+        for(DataSecretEnum eu:DataSecretEnum.values()){
+            if(eu.value == secret){
+                return eu.text;
+            }
+        }
+        return NONE.text;
+    }
+
+    /**
+     * 鏍规嵁鏋氫妇鏄剧ず鏂囨湰鑾峰彇鏋氫妇鍊�
+     * @param text 鏄剧ず鏂囨湰
+     * @return 鏋氫妇鍊�
+     */
+    public static int getSecretValueByText(String text){
+        for(DataSecretEnum eu:DataSecretEnum.values()){
+            if(eu.text.equalsIgnoreCase(text)){
+                return eu.value;
+            }
+        }
+        return NONE.value;
+    }
+
+    /**
+     * 鏄惁鏈夋晥鐨勫瘑绾у��
+     * @param secret 瀵嗙骇鍊�
+     * @return 绗﹀悎鑼冨洿瑕佹眰鍒欒繑鍥瀟rue
+     */
+    public static boolean isValid(int secret){
+        for(DataSecretEnum eu:DataSecretEnum.values()){
+            if(eu.value == secret){
+                return true;
+            }
+        }
+        return false;
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/LangCodeEnum.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/LangCodeEnum.java
new file mode 100644
index 0000000..1af5be6
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/LangCodeEnum.java
@@ -0,0 +1,85 @@
+package com.vci.starter.web.enumpck;
+
+
+import com.vci.starter.web.annotation.VciEnum;
+
+/**
+ * 璇█鐨勪唬鐮佸ぇ鍏ㄦ灇涓撅紝鐩墠鍙敮鎸佷腑鏂囧拰鑻辫
+ * @author weidy
+ * @date 2020/1/29
+ */
+@VciEnum(name= "langCode",text = "璇█浠g爜")
+public enum LangCodeEnum implements BaseEnum {
+    /**
+     * 鑻辫
+     */
+    EN_US("en_US","鑻辫"),
+    /**
+     * 绠�浣撲腑鏂�
+     */
+    ZH_CN("zh_CN","绠�浣撲腑鏂�"),
+    /**
+     * 绻佷綋涓枃
+     */
+    ZH_TW("zh_TW","绻佷綋涓枃");
+    /**
+     * 鍊�
+     */
+    private String value;
+
+    /**
+     * 鏄剧ず鏂囨湰
+     */
+    private String text;
+
+    @Override
+    public String getValue() {
+        return value;
+    }
+
+    @Override
+    public String getText() {
+        return text;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    public void setText(String text) {
+        this.text = text;
+    }
+
+    private LangCodeEnum(String value,String text){
+        this.value = value;
+        this.text = text;
+    }
+
+    /**
+     * 鏍规嵁鍚嶇О鑾峰彇瀵瑰簲鐨勬灇涓惧��
+     * @param text 鍚嶇О
+     * @return 鏋氫妇鍊�
+     */
+    public static String getValueByText(String text){
+        for(LangCodeEnum wenum : LangCodeEnum.values()){
+            if(wenum.getText().equalsIgnoreCase(text)){
+                return wenum.getValue();
+            }
+        }
+        return "";
+    }
+
+    /**
+     * 鏍规嵁鏋氫妇鍊艰幏鍙栧悕绉�
+     * @param value 鏋氫妇鍊�
+     * @return 鍚嶇О
+     */
+    public static String getTextByValue(String value){
+        for(LangCodeEnum wenum : LangCodeEnum.values()){
+            if(wenum.getValue().equalsIgnoreCase(value)){
+                return wenum.getText();
+            }
+        }
+        return "";
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/LogLevelEnum.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/LogLevelEnum.java
new file mode 100644
index 0000000..3233960
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/LogLevelEnum.java
@@ -0,0 +1,39 @@
+package com.vci.starter.web.enumpck;
+
+/**
+ * 鏌ョ湅鏃ュ織鐨勭瓑绾�
+ * @author weidy
+ * @date 2020/4/13
+ */
+public enum LogLevelEnum {
+    /**
+     * 杩芥函
+     */
+    TRACE,
+    /**
+     * 璋冭瘯
+     */
+    DEBUG,
+    /**
+     * 淇℃伅
+     */
+    INFO,
+    /**
+     * 璀﹀憡
+     */
+    WARN,
+    /**
+     * 閿欒
+     */
+    ERROR,
+    /**
+     * 鑷村懡
+     */
+    FATAL,
+
+    /**
+     * 鍏抽棴
+     */
+    OFF;
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/ResultCodeEnum.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/ResultCodeEnum.java
new file mode 100644
index 0000000..02144aa
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/ResultCodeEnum.java
@@ -0,0 +1,57 @@
+package com.vci.starter.web.enumpck;
+
+/**
+ * 杩斿洖鐨勭姸鎬佺爜锛屽弬鑰僪ttp鐨勭姸鎬佺爜锛宭ayui绛夊墠绔彲浠ョ洿鎺ヨ幏鍙�
+ * @author weidy
+ * @date 2019/12/3 6:52 PM
+ */
+public enum ResultCodeEnum {
+
+    /**
+     * 鎴愬姛
+     */
+    SUCCESS(200),
+
+    /**
+     *澶辫触
+     */
+    FAIL(400),
+
+    /**
+     * 鏈璇侊紙绛惧悕閿欒锛�,鎴栬�呮病鏈夌敤鎴�
+     */
+    UNAUTHORIZED(401),
+
+    /**
+     * 娌℃湁鏉冮檺
+     */
+    NOT_RIGHT(402),
+
+    /**
+     * 閿欒鐨勫弬鏁版牸寮�
+     */
+    BAD_PARAM(403),
+
+    /**
+     * 鎺ュ彛涓嶅瓨鍦�
+     */
+    NOT_FOUND(404),
+
+    /**
+     * 鏈嶅姟鍣ㄥ唴閮ㄩ敊璇�
+     */
+    INTERNAL_SERVER_ERROR(500);
+
+    /**
+     * 鐘舵�佺爜
+     */
+    public int code;
+
+    /**
+     * 鏋氫妇鍐呴儴鏋勯�犳柟娉�
+     * @param code 鐘舵�佸��
+     */
+    private ResultCodeEnum(int code){
+        this.code = code;
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/SessionStorageTypeEnum.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/SessionStorageTypeEnum.java
new file mode 100644
index 0000000..441c2b9
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/SessionStorageTypeEnum.java
@@ -0,0 +1,93 @@
+package com.vci.starter.web.enumpck;
+
+/**
+ * 浼氳瘽淇℃伅瀛樺偍鐨勬柟寮忥紝瀹為檯涓婂拰spring-session鐨勭鐞嗘柟寮忔槸涓�鏍风殑锛屼絾鏄负浜嗗吋瀹逛互鍓嶇殑椤圭洰锛屽張閲嶅閫犱簡杞瓙
+ * @author weidy
+ * @date 2020/2/5
+ */
+public enum SessionStorageTypeEnum implements BaseEnum {
+    /**
+     * redis绠$悊
+     */
+    REDIS("redis","缂撳瓨"),
+
+    /**
+     * 鏁版嵁搴�
+     */
+    DATABASE("database","鏁版嵁搴�");
+
+    /**
+     * 鍊�
+     */
+    private String value;
+
+    /**
+     * 鏄剧ず鏂囨湰
+     */
+    private String text;
+
+    @Override
+    public String getValue() {
+        return value;
+    }
+
+    @Override
+    public String getText() {
+        return text;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    public void setText(String text) {
+        this.text = text;
+    }
+
+    private SessionStorageTypeEnum(String value,String text){
+        this.value = value;
+        this.text = text;
+    }
+
+    /**
+     * 鏍规嵁鍚嶇О鑾峰彇瀵瑰簲鐨勬灇涓惧��
+     * @param text 鍚嶇О
+     * @return 鏋氫妇鍊�
+     */
+    public static String getValueByText(String text){
+        for(SessionStorageTypeEnum wenum : SessionStorageTypeEnum.values()){
+            if(wenum.getText().equalsIgnoreCase(text)){
+                return wenum.getValue();
+            }
+        }
+        return "";
+    }
+
+    /**
+     * 鏍规嵁鏋氫妇鍊艰幏鍙栧悕绉�
+     * @param value 鏋氫妇鍊�
+     * @return 鍚嶇О
+     */
+    public static String getTextByValue(String value){
+        for(SessionStorageTypeEnum wenum : SessionStorageTypeEnum.values()){
+            if(wenum.getValue().equalsIgnoreCase(value)){
+                return wenum.getText();
+            }
+        }
+        return "";
+    }
+
+    /**
+     * 鍊艰浆鎹负鏋氫妇瀵硅薄
+     * @param value 鍊�
+     * @return 濡傛灉涓嶇鍚堣姹傝繑鍥濶ull
+     */
+    public static SessionStorageTypeEnum forValue(String value){
+        for(SessionStorageTypeEnum wenum : SessionStorageTypeEnum.values()){
+            if(wenum.getValue().equalsIgnoreCase(value)){
+                return wenum;
+            }
+        }
+        return SessionStorageTypeEnum.REDIS;
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/UserSecretEnum.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/UserSecretEnum.java
new file mode 100644
index 0000000..7132aa9
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/UserSecretEnum.java
@@ -0,0 +1,119 @@
+package com.vci.starter.web.enumpck;
+
+import com.vci.starter.web.annotation.VciEnum;
+
+/**
+ * 鐢ㄦ埛瀵嗙骇
+ * @author weidy
+ * @date 2019-07-14
+ */
+@VciEnum(name = "usersecurityenum",text = "浜哄憳瀵嗙骇",description = "鐢ㄦ埛锛屼汉鍛樼殑瀵嗙骇")
+public enum UserSecretEnum implements BaseEnumInt{
+
+    /**
+     * 鍐呴儴
+     */
+    NONE(10,"鍐呴儴"),
+    /**
+     * 涓�鑸�
+     */
+    SECRET(20,"涓�鑸�"),
+    /**
+     * 閲嶈
+     */
+    PRIVACY(30,"閲嶈");
+
+    /**
+     * 鏋氫妇鍊�
+     */
+    private int value;
+
+    /**
+     * 鏋氫妇鏄剧ず鍊�
+     */
+    private String text;
+    /**
+     * 鑾峰彇鏋氫妇鍊�
+     * @return 鏋氫妇鍊�
+     */
+    public int getValue() {
+        return value;
+    }
+
+    /**
+     * 璁剧疆鏋氫妇鍊�
+     * @param value 鏋氫妇鍊�
+     */
+    public void setValue(int value) {
+        this.value = value;
+    }
+
+    /**
+     * 鑾峰彇鏄剧ず鏂囨湰
+     * @return 鏄剧ず鏂囨湰
+     */
+    public String getText() {
+        return text;
+    }
+
+    /**
+     * 璁剧疆鏄剧ず鏂囨湰
+     * @param text 鏄剧ず鏂囨湰
+     */
+    public void setText(String text) {
+        this.text = text;
+    }
+
+    /**
+     * 鏋氫妇鍐呴儴鏋勯�犳柟娉�
+     * @param secret 鏋氫妇鍊�
+     * @param secretText 鏄剧ず鏂囨湰
+     */
+    private UserSecretEnum(int secret, String secretText){
+        this.value = secret;
+        this.text = secretText;
+    }
+
+    /**
+     * 鏍规嵁鏋氫妇鐨勫�艰幏鍙栨樉绀烘枃鏈�
+     * @param secret 鏋氫妇鍊�
+     * @return 鏄剧ず鏂囨湰
+     */
+    public static String getSecretText(int secret){
+        for(UserSecretEnum eu:UserSecretEnum.values()){
+            if(eu.value == secret){
+                return eu.text;
+            }
+        }
+        return NONE.text;
+    }
+
+
+    /**
+     * 鏄惁鏈夋晥鐨勫瘑绾у��
+     * @param secret 瀵嗙骇鍊�
+     * @return 绗﹀悎鑼冨洿瑕佹眰鍒欒繑鍥瀟rue
+     */
+    public static boolean isValid(int secret){
+        for(UserSecretEnum eu:UserSecretEnum.values()){
+            if(eu.value == secret){
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * 鏍规嵁鏋氫妇鏄剧ず鏂囨湰鑾峰彇鏋氫妇鍊�
+     * @param text 鏄剧ず鏂囨湰
+     * @return 鏋氫妇鍊�
+     */
+    public static int getSecretValueByText(String text){
+        for(UserSecretEnum eu:UserSecretEnum.values()){
+            if(eu.text.equalsIgnoreCase(text)){
+                return eu.value;
+            }
+        }
+        return NONE.value;
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/VciChangeDocumentTypeEnum.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/VciChangeDocumentTypeEnum.java
new file mode 100644
index 0000000..6c6e021
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/VciChangeDocumentTypeEnum.java
@@ -0,0 +1,120 @@
+package com.vci.starter.web.enumpck;
+
+
+/**
+ * 鏁版嵁淇敼绫诲瀷
+ * @author weidy
+ * @date 2019/10/10 4:23 PM
+ */
+public  enum VciChangeDocumentTypeEnum {
+    /**
+     * 娣诲姞
+     */
+    ADD,
+    /**
+     * 淇敼
+     */
+    EDIT,
+    /**
+     * 鍒犻櫎
+     */
+    DELETE,
+
+    /**
+     * 鐢熷懡鍛ㄦ湡鍙樺寲
+     */
+    LCSTATUS,
+
+    /**
+     * 鍗囩増
+     */
+    UPREVISION,
+
+    /**
+     * 鎻愪氦娴佺▼
+     */
+    SUBMIT,
+
+    /**
+     * 鍙戝竷
+     */
+    RELEASED,
+    /**
+     * 鍏ㄩ儴
+     */
+    ALL;
+
+    /**
+     * 鏍规嵁鍚嶇О鑾峰彇瀵瑰簲鐨勬灇涓惧��
+     * @param text 鍚嶇О
+     * @return 鏋氫妇鍊�
+     */
+    public static String getValueByText(String text){
+        if(text == null || text.trim().length() == 0){
+            return "";
+        }else{
+            if("鍒犻櫎".equalsIgnoreCase(text)){
+                return DELETE.name();
+            }else if("淇敼".equalsIgnoreCase(text)){
+                return EDIT.name();
+            }else if("鐢熷懡鍛ㄦ湡鍙樻洿".equalsIgnoreCase(text)){
+                return LCSTATUS.name();
+            }else if("鍗囩増".equalsIgnoreCase(text)){
+                return UPREVISION.name();
+            }else if("鎻愪氦娴佺▼".equalsIgnoreCase(text)){
+                return SUBMIT.name();
+            }else if("鍙戝竷".equalsIgnoreCase(text)){
+                return RELEASED.name();
+            }else if("鍏ㄩ儴".equalsIgnoreCase(text)){
+                return ALL.name();
+            }else{
+                return ADD.name();
+            }
+        }
+    }
+
+    /**
+     * 鏍规嵁鏋氫妇鍊艰幏鍙栧悕绉�
+     * @param value 鏋氫妇鍊�
+     * @return 鍚嶇О
+     */
+    public static String getTextByValue(String value){
+        VciChangeDocumentTypeEnum wenum = forValue(value);
+        if(wenum == null){
+            return  "";
+        }
+        switch (wenum){
+            case DELETE:
+                return "鍒犻櫎";
+            case EDIT:
+                return "淇敼";
+            case LCSTATUS:
+                return "鐢熷懡鍛ㄦ湡鍙樻洿";
+            case UPREVISION:
+                return "鍗囩増";
+            case SUBMIT:
+                return "鎻愪氦娴佺▼";
+            case RELEASED:
+                return "鍙戝竷";
+            case ALL:
+                return "鍏ㄩ儴";
+            default:
+                return "娣诲姞";
+        }
+    }
+
+    /**
+     * 鏍规嵁鏋氫妇鍊艰幏鍙栨灇涓惧璞�
+     * @param value 鏋氫妇鍊�
+     * @return 瀵瑰簲鐨勬灇涓惧璞★紝涓嶅尮閰嶇殑鏃跺�欒繑鍥瀗ull
+     */
+    public static VciChangeDocumentTypeEnum forValue(String value){
+        for(VciChangeDocumentTypeEnum wenum : VciChangeDocumentTypeEnum.values()){
+            if(wenum.name().equalsIgnoreCase(value)){
+                return wenum;
+            }
+        }
+        return null;
+    }
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/VciFieldTypeEnum.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/VciFieldTypeEnum.java
new file mode 100644
index 0000000..9ac3a25
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/VciFieldTypeEnum.java
@@ -0,0 +1,134 @@
+package com.vci.starter.web.enumpck;
+
+import com.vci.starter.web.annotation.VciEnum;
+
+/**
+ * 灞炴�х殑绫诲瀷
+ * @author weidy
+ * @date 2019/10/10 4:23 PM
+ */
+@VciEnum(name = "VciFieldType",text = "灞炴�х被鍨�")
+public  enum VciFieldTypeEnum {
+    /**
+     * 瀛楃涓�
+     */
+    VTString,
+    /**
+     * 鏁村舰
+     */
+    VTInteger,
+    /**
+     * 闀挎暣褰�
+     */
+    VTLong,
+    /**
+     * 閲戦/鍙岀簿搴�
+     */
+    VTDouble,
+    /**
+     * 甯冨皵鍨�
+     */
+    VTBoolean,
+    /**
+     * 鏃ユ湡
+     */
+    VTDate,
+    /**
+     * 鏃ユ湡鏃堕棿
+     */
+    VTDateTime,
+    /**
+     * 鏃堕棿
+     */
+    VTTime,
+    /**
+     * 鏂囦欢
+     */
+    VTFilePath,
+    /**
+     * 瓒呴暱鏂囨湰
+     */
+    VTClob;
+
+    /**
+     * 鏍规嵁鍚嶇О鑾峰彇瀵瑰簲鐨勬灇涓惧��
+     * @param text 鍚嶇О
+     * @return 鏋氫妇鍊�
+     */
+    public static String getValueByText(String text){
+        if(text == null || text.trim().length() == 0){
+            return "";
+        }else{
+            if("甯冨皵鍨�".equalsIgnoreCase(text)){
+                return VTBoolean.name();
+            }else if("闀挎枃鏈�".equalsIgnoreCase(text)){
+                return VTClob.name();
+            }else if("鏃ユ湡".equalsIgnoreCase(text)){
+                return VTDate.name();
+            }else if("鏃ユ湡鏃堕棿".equalsIgnoreCase(text)){
+                return VTDateTime.name();
+            }else if("鏃堕棿".equalsIgnoreCase(text)){
+                return VTTime.name();
+            }else if("闀挎暣鍨�".equalsIgnoreCase(text)){
+                return VTLong.name();
+            }else if("閲戦/鍙岀簿搴�".equalsIgnoreCase(text)){
+                return VTDouble.name();
+            }else if("鏁村舰".equalsIgnoreCase(text)){
+                return VTInteger.name();
+            }else if("鏂囦欢".equalsIgnoreCase(text)){
+                return VTFilePath.name();
+            }else{
+                return VTString.name();
+            }
+        }
+    }
+
+    /**
+     * 鏍规嵁鏋氫妇鍊艰幏鍙栧悕绉�
+     * @param value 鏋氫妇鍊�
+     * @return 鍚嶇О
+     */
+    public static String getTextByValue(String value){
+        VciFieldTypeEnum wenum = forValue(value);
+        if(wenum == null){
+            return  "";
+        }
+        switch (wenum){
+            case VTBoolean:
+                return "甯冨皵鍨�";
+            case VTClob:
+                return "闀挎枃鏈�";
+            case VTDate:
+                return "鏃ユ湡";
+            case VTDateTime:
+                return "鏃ユ湡鏃堕棿";
+            case VTTime:
+                return "鏃堕棿";
+            case VTLong:
+                return "闀挎暣鍨�";
+            case VTDouble:
+                return "閲戦/鍙岀簿搴�";
+            case VTInteger:
+                return "鏁村舰";
+            case VTFilePath:
+                return "鏂囦欢";
+            default:
+                return "瀛楃涓�";
+        }
+    }
+
+    /**
+     * 鏍规嵁鏋氫妇鍊艰幏鍙栨灇涓惧璞�
+     * @param value 鏋氫妇鍊�
+     * @return 瀵瑰簲鐨勬灇涓惧璞★紝涓嶅尮閰嶇殑鏃跺�欒繑鍥瀗ull
+     */
+    public static VciFieldTypeEnum forValue(String value){
+        for(VciFieldTypeEnum wenum : VciFieldTypeEnum.values()){
+            if(wenum.name().equalsIgnoreCase(value)){
+                return wenum;
+            }
+        }
+        return null;
+    }
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/VciReturnFileTypeEnum.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/VciReturnFileTypeEnum.java
new file mode 100644
index 0000000..33ccbf9
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/VciReturnFileTypeEnum.java
@@ -0,0 +1,100 @@
+package com.vci.starter.web.enumpck;
+
+/**
+ * controller涓繑鍥炴枃浠剁殑绫诲瀷锛屼竴鑸兘鏄湪涓嬭浇鏂囦欢鍑洪敊鐨勬椂鍊欎娇鐢�
+ * @author weidy
+ * @date 2020/2/19
+ */
+public enum VciReturnFileTypeEnum implements BaseEnum {
+    /**
+     * 鏂囨湰鏂囨。
+     */
+    TXT("txt","鏂囨湰鏂囦欢"),
+    /**
+     * PDF鏂囦欢
+     */
+    PDF("pdf","PDF鏂囦欢"),
+    /**
+     * 鍥剧墖
+     */
+    IMAGE("image","鍥剧墖");
+
+    /**
+     * 鏋氫妇鐨勫��
+     */
+    private String value;
+
+    /**
+     * 鏋氫妇鐨勬樉绀烘枃鏈�
+     */
+    private String text;
+
+    /**
+     * 鍐呴儴鏋勯�犲嚱鏁�
+     * @param value 鏋氫妇鐨勫��
+     */
+    private VciReturnFileTypeEnum(String value,String text){
+        this.value = value;
+        this.text = text;
+    }
+
+    /**
+     * 鏍规嵁鍚嶇О鑾峰彇瀵瑰簲鐨勬灇涓惧��
+     * @param text 鍚嶇О
+     * @return 鏋氫妇鍊�
+     */
+    public static String getValueByText(String text){
+        for(VciReturnFileTypeEnum wenum : VciReturnFileTypeEnum.values()){
+            if(wenum.getText().equalsIgnoreCase(text)){
+                return wenum.getValue();
+            }
+        }
+        return "";
+    }
+
+    /**
+     * 鏍规嵁鏋氫妇鍊艰幏鍙栧悕绉�
+     * @param value 鏋氫妇鍊�
+     * @return 鍚嶇О
+     */
+    public static String getTextByValue(String value){
+        for(VciReturnFileTypeEnum wenum : VciReturnFileTypeEnum.values()){
+            if(wenum.getValue().equalsIgnoreCase(value)){
+                return wenum.getText();
+            }
+        }
+        return "";
+    }
+
+    /**
+     * 鏍规嵁鏋氫妇鍊艰幏鍙栨灇涓惧璞�
+     * @param value 鏋氫妇鍊�
+     * @return
+     */
+    public static VciReturnFileTypeEnum forValue(String value){
+        for(VciReturnFileTypeEnum wenum : VciReturnFileTypeEnum.values()){
+            if(wenum.getValue().equalsIgnoreCase(value)){
+                return wenum;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    @Override
+    public String getText() {
+        return text;
+    }
+
+    public void setText(String text) {
+        this.text = text;
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/VciTaskBusTypeEnum.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/VciTaskBusTypeEnum.java
new file mode 100644
index 0000000..2d3f322
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/enumpck/VciTaskBusTypeEnum.java
@@ -0,0 +1,116 @@
+package com.vci.starter.web.enumpck;
+
+
+/**
+ * 浠诲姟璋冩暣绫诲瀷
+ * @author weidy
+ * @date 2019/10/10 4:23 PM
+ */
+public  enum VciTaskBusTypeEnum {
+    /**
+     * 娣诲姞
+     */
+    ADD,
+    /**
+     * 淇敼
+     */
+    EDIT,
+    /**
+     * 鍒犻櫎
+     */
+    DELETE,
+    /**
+     * 鍐荤粨
+     */
+    FREEZE,
+    /**
+     * 鎭㈠
+     */
+    RECOVER,
+    /**
+     * 瀹屾垚
+     */
+    FINISH,
+    /**
+     * 鍒嗚В
+     */
+    RESOLVE,
+    /**
+     * 鍏ㄩ儴
+     */
+    ALL;
+
+    /**
+     * 鏍规嵁鍚嶇О鑾峰彇瀵瑰簲鐨勬灇涓惧��
+     * @param text 鍚嶇О
+     * @return 鏋氫妇鍊�
+     */
+    public static String getValueByText(String text){
+        if(text == null || text.trim().length() == 0){
+            return "";
+        }else{
+            if("鍒犻櫎".equalsIgnoreCase(text)){
+                return DELETE.name();
+            }else if("淇敼".equalsIgnoreCase(text)){
+                return EDIT.name();
+            }else if("鍐荤粨".equalsIgnoreCase(text)){
+                return FREEZE.name();
+            }else if("鎭㈠".equalsIgnoreCase(text)){
+                return RECOVER.name();
+            }else if("瀹屾垚".equalsIgnoreCase(text)){
+                return FINISH.name();
+            }else if("鍒嗚В".equalsIgnoreCase(text)){
+                return RESOLVE.name();
+            }else if("鍏ㄩ儴".equalsIgnoreCase(text)){
+                return ALL.name();
+            }else{
+                return ADD.name();
+            }
+        }
+    }
+
+    /**
+     * 鏍规嵁鏋氫妇鍊艰幏鍙栧悕绉�
+     * @param value 鏋氫妇鍊�
+     * @return 鍚嶇О
+     */
+    public static String getTextByValue(String value){
+        VciTaskBusTypeEnum wenum = forValue(value);
+        if(wenum == null){
+            return  "";
+        }
+        switch (wenum){
+            case DELETE:
+                return "鍒犻櫎";
+            case EDIT:
+                return "淇敼";
+            case FREEZE:
+                return "鍐荤粨";
+            case RECOVER:
+                return "鎭㈠";
+            case FINISH:
+                return "瀹屾垚";
+            case RESOLVE:
+                return "鍒嗚В";
+            case ALL:
+                return "鍏ㄩ儴";
+            default:
+                return "娣诲姞";
+        }
+    }
+
+    /**
+     * 鏍规嵁鏋氫妇鍊艰幏鍙栨灇涓惧璞�
+     * @param value 鏋氫妇鍊�
+     * @return 瀵瑰簲鐨勬灇涓惧璞★紝涓嶅尮閰嶇殑鏃跺�欒繑鍥瀗ull
+     */
+    public static VciTaskBusTypeEnum forValue(String value){
+        for(VciTaskBusTypeEnum wenum : VciTaskBusTypeEnum.values()){
+            if(wenum.name().equalsIgnoreCase(value)){
+                return wenum;
+            }
+        }
+        return null;
+    }
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/exception/ExceptionAdviceHandler.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/exception/ExceptionAdviceHandler.java
new file mode 100644
index 0000000..5ab9710
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/exception/ExceptionAdviceHandler.java
@@ -0,0 +1,173 @@
+package com.vci.starter.web.exception;
+
+import com.vci.starter.web.constant.TokenKeyConstant;
+import com.vci.starter.web.enumpck.ResultCodeEnum;
+import com.vci.starter.web.pagemodel.BaseResult;
+import com.vci.starter.web.util.LangBaseUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.MDC;
+import org.springframework.beans.TypeMismatchException;
+import org.springframework.http.converter.HttpMessageNotReadableException;
+import org.springframework.util.CollectionUtils;
+import org.springframework.validation.BindException;
+import org.springframework.validation.FieldError;
+import org.springframework.validation.ObjectError;
+import org.springframework.web.HttpRequestMethodNotSupportedException;
+import org.springframework.web.bind.MethodArgumentNotValidException;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.multipart.MultipartException;
+
+import javax.servlet.ServletException;
+import java.util.List;
+
+/**
+ * 鎻愪緵缁檚pring mvc鐨勭粺涓�鐨勯敊璇鐞�
+ * @author weidy
+ */
+@ControllerAdvice
+public class ExceptionAdviceHandler {
+
+    /**
+     * 鏃ュ織瀵硅薄
+     */
+    private Logger logger = LoggerFactory.getLogger(getClass());
+
+    /**
+     * 褰撴姄鍙栧埌Throwable寮傚父鐨勬椂鍊欙紝杩斿洖閿欒淇℃伅
+     * @param e 寮傚父瀵硅薄
+     * @return JSON瀵硅薄锛屼笉璁烘槸鏍戯紝鍒楄〃锛岃繕鏄痯ost鐨勬柟娉曪紝鍓嶇閮藉彲浠ヨ幏鍙杝uccess,code鍜宮sg灞炴��
+     */
+    @ResponseBody
+    @ExceptionHandler(value = Throwable.class)
+    public BaseResult defaultErrorHandler(Exception e){
+        BaseResult baseResult = this.handler(e);
+        String traceId = MDC.get(TokenKeyConstant.TRACE_ID);
+        baseResult.setTraceId(traceId);
+        baseResult.setFinishTime(System.currentTimeMillis());
+        if(logger.isErrorEnabled()) {
+            logger.error(baseResult.toString(), e);
+        }
+        return baseResult;
+    }
+
+    /**
+     * 浠庡紓甯镐笂鑾峰彇淇℃伅骞惰繑鍥�
+     * @param e 寮傚父瀵硅薄
+     * @return JSON瀵硅薄
+     */
+    private BaseResult handler(Exception e) {
+        //涓嶆敮鎸佺殑http鏂规硶
+        if(e instanceof VciBaseException){
+            BaseResult baseResult = BaseResult.error(LangBaseUtil.getErrorMsg(e));
+            baseResult.setExceptionClassName(e.getClass().getName());
+            return  baseResult;
+        } else if (e instanceof HttpRequestMethodNotSupportedException) {
+            return this.httpRequestMethodNotSupportedException(e);
+        } else if (e instanceof HttpMessageNotReadableException) {
+            return this.httpMessageNotReadableException(e);
+        } else if (e instanceof TypeMismatchException || e instanceof MultipartException ||e instanceof ServletException) {
+           return this.parameterException(e);
+        } else if (e instanceof MethodArgumentNotValidException) {
+            return this.methodArgumentNotValidException(e);
+        } else if (e.getClass().getName().equalsIgnoreCase("org.springframework.jdbc.BadSqlGrammarException")) {
+            return this.badSqlGrammarException(e);
+        } else if(e instanceof BindException){
+            return this.bindException((BindException) e);
+        }else {
+            //鍏朵粬鐨�
+            return BaseResult.error(LangBaseUtil.getErrorMsg(e));
+        }
+    }
+
+    /**
+     * 涓嶆敮鎸佺殑http鏂规硶
+     * @param e 寮傚父鐨勫璞�
+     * @return JSON瀵硅薄
+     */
+    private BaseResult httpRequestMethodNotSupportedException(Exception e){
+        String message = "璇峰紑鍙戜汉鍛樻鏌ワ紝涓嶆敮鎸佺殑http鏂规硶";
+        BaseResult baseResult = BaseResult.error(message);
+        baseResult.setExceptionClassName(e.getClass().getName());
+        return  baseResult;
+    }
+
+    /**
+     * 鍙傛暟涓嶈兘琚鍙�
+     * @param e 寮傚父瀵硅薄
+     * @return json瀵硅薄
+     */
+    private BaseResult httpMessageNotReadableException(Exception e){
+        String message = "璇峰紑鍙戜汉鍛樻鏌ヤ綘璇锋眰鐨勫弬鏁板拰鍙傛暟鐨勭被鍨嬫槸鍚︾鍚堝悗鍙版帴鍙g殑瑕佹眰";
+        BaseResult baseResult = BaseResult.makeResult(ResultCodeEnum.BAD_PARAM.code,message,null);
+        baseResult.setExceptionClassName(e.getClass().getName());
+        return  baseResult;
+    }
+
+    /**
+     * 鍙傛暟鐨勭被鍨嬪紓甯�
+     * @param e 寮傚父瀵硅薄
+     * @return  json瀵硅薄
+     */
+    private BaseResult parameterException(Exception e){
+        String message = "璇峰紑鍙戜汉鍛樻鏌ヤ綘鍙傛暟鐨勭被鍨�";
+        BaseResult baseResult = BaseResult.makeResult(ResultCodeEnum.BAD_PARAM.code,message,null);
+        baseResult.setExceptionClassName(e.getClass().getName());
+        return  baseResult;
+    }
+
+    /**
+     * 鏂规硶鐨勫弬鏁版棤鏁�
+     * @param e 寮傚父鐘舵��
+     * @return json瀵硅薄
+     */
+    private BaseResult methodArgumentNotValidException(Exception e){
+        StringBuffer buffer = new StringBuffer();
+        List<ObjectError> list = ((MethodArgumentNotValidException) e).getBindingResult().getAllErrors();
+        list.forEach(error -> {
+            if (error instanceof FieldError) {
+                buffer.append(((FieldError) error).getField()).append(":");
+            }
+            buffer.append(error.getDefaultMessage()).append(",");
+        });
+        buffer.append("璇峰紑鍙戜汉鍛樻鏌ヨ姹傛柟娉曠殑鍙傛暟");
+        BaseResult baseResult = BaseResult.makeResult(ResultCodeEnum.BAD_PARAM.code,buffer.toString(),null);
+        baseResult.setExceptionClassName(e.getClass().getName());
+        return  baseResult;
+    }
+
+    /**
+     * 缁戝畾鍙傛暟閿欒
+     * @param e 寮傚父鐘舵��
+     * @return json瀵硅薄
+     */
+    private BaseResult bindException(BindException e){
+        String message = "璇峰紑鍙戜汉鍛樻鏌ュ弬鏁帮紝鍙傛暟缁戝畾鍑虹幇浜嗛敊璇�";
+        List<ObjectError> objectErrorList = e.getBindingResult().getAllErrors();
+        if(!CollectionUtils.isEmpty(objectErrorList)){
+            ObjectError objectError = objectErrorList.get(0);
+            if(objectError instanceof FieldError){
+                FieldError fieldError = (FieldError) objectError;
+                message = "[" + fieldError.getField() + "]" + fieldError.getDefaultMessage();
+            }
+        }
+        BaseResult baseResult = BaseResult.makeResult(ResultCodeEnum.BAD_PARAM.code,message,null);
+        baseResult.setExceptionClassName(e.getClass().getName());
+        return  baseResult;
+    }
+
+    /**
+     * SQL璇彞閿欒
+     * @param e 寮傚父瀵硅薄
+     * @return json瀵硅薄
+     */
+    private BaseResult badSqlGrammarException(Exception e){
+        String message = "璇峰紑鍙戜汉鍛樻鏌ュ弬鏁版垨鑰呭悗鍙皊ql璇彞," + LangBaseUtil.getErrorMsg(e);
+        BaseResult baseResult = BaseResult.error(message);
+        baseResult.setExceptionClassName(e.getClass().getName());
+        return  baseResult;
+    }
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/exception/VciBaseException.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/exception/VciBaseException.java
new file mode 100644
index 0000000..e556f0d
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/exception/VciBaseException.java
@@ -0,0 +1,160 @@
+package com.vci.starter.web.exception;
+
+import com.vci.starter.web.util.MessageUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import java.text.MessageFormat;
+import java.util.Locale;
+import java.util.ResourceBundle;
+
+/**
+ * 鍩烘湰鐨勫紓甯革紝缁ф壙鑷猂untimeException鍙互琚玸pring鐨勪簨鍔$鐞嗚嚜鍔ㄥ鐞�
+ */
+public class VciBaseException extends RuntimeException {
+
+    /**
+     * 鏃ュ織瀵硅薄
+     */
+    private Logger log = LoggerFactory.getLogger(getClass());
+
+    /**
+     * 鍙傛暟涓虹┖
+     */
+    public static final String paramNull = "com.vci.base.paramNull";
+
+    /**
+     * 瀛楁鐨勫�奸噸澶�
+     */
+    public static final String fieldValueRepeat="com.vci.base.fieldValueRepeat";
+
+    /**
+     * 瀵硅薄娌℃湁鍦ㄧ郴缁熶腑瀛樺湪
+     */
+    public static final String objectNotFoundInDb="com.vci.base.objectNotFoundInDb";
+
+    /**
+     * ts鐨勫�间笉瀛樺湪
+     */
+    public static final String tsNotEqual="com.vci.base.tsNotEqual";
+
+    /**
+     * 鍊间笉绗﹀悎鏃ユ湡鏍煎紡鐨勮姹�
+     */
+    public static final String dateValueFormatError="com.vci.base.dateValueForamtError";
+
+    /**
+     * 娌℃湁鐧诲綍
+     */
+    public static final String notLogin="com.vci.base.notLogin";
+
+    /**
+     * 娌℃湁鏉冮檺
+     */
+    public static final String notRight="com.vci.base.notRight";
+
+    /**
+     * 娌℃湁鏁版嵁鏉冮檺
+     */
+    public static final String notDataRight="com.vci.base.notDataRight";
+
+    /**
+     * 娌℃湁UI鏉冮檺
+     */
+    public static final String notUIRight="com.vci.base.notUIRight";
+
+    /**
+     * 杩炴帴corba鏈嶅姟澶辫触
+     */
+    public static final String connectCorbaFail="com.vci.base.connectCorbaFail";
+
+    /**
+     * corba鏈嶅姟娌℃湁閰嶇疆
+     */
+    public static final String corbaNotConfig="com.vci.base.corbaNotConfig ";
+
+    /**
+     * 閿欒缂栫爜
+     */
+    private String code ;
+
+    /**
+     * 閿欒瀵硅薄
+     */
+    private Object[] objs = new Object[0];
+
+
+    /**
+     * 鏋勯�犳柟娉�
+     * @param code 缂栫爜
+     */
+    public VciBaseException(String code){
+        this.code = code;
+    }
+
+    /**
+     * 鏋勯�犳柟娉�
+     * @param code 缂栫爜
+     * @param objs 閿欒瀵硅薄
+     */
+    public VciBaseException(String code, Object[] objs){
+        this.code= code;
+        this.objs = objs;
+    }
+
+    /**
+     * 鏋勯�犳柟娉�
+     * @param code 閿欒缂栫爜
+     * @param objs 閿欒淇℃伅瀵硅薄
+     * @param e 寮傚父瀵硅薄
+     */
+    public VciBaseException(String code,Object[] objs,Throwable e){
+        super(e);
+        this.code= code;
+        this.objs = objs;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public Object[] getObjs() {
+        return objs;
+    }
+
+    public void setObjs(Object[] objs) {
+        this.objs = objs;
+    }
+
+    /**
+     * 灏嗗紓甯哥殑淇℃伅杞崲涓烘湰鍦板寲璇█
+     * @return 杞崲鍚庣殑鏈湴鍖栦俊鎭�
+     */
+    public String getErrorMsg(){
+        if( this instanceof VciBaseException || this.getClass().getSuperclass().equals(VciBaseException.class)){
+            if(StringUtils.isNotBlank(code)){
+                code = MessageUtils.get(code,this.objs);
+            }
+            code = MessageFormat.format(code,this.objs);
+            return code;
+        }else if( this instanceof Exception){
+            return getMessage();
+        }else{
+            return code;
+        }
+    }
+
+    /**
+     * 鑾峰彇閿欒淇℃伅
+     * @return 閿欒淇℃伅
+     */
+    @Override
+    public String getMessage(){
+        return getCode() +"," + getErrorMsg();
+    }
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/interceptor/VciLocaleInterceptor.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/interceptor/VciLocaleInterceptor.java
new file mode 100644
index 0000000..7c85bda
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/interceptor/VciLocaleInterceptor.java
@@ -0,0 +1,82 @@
+package com.vci.starter.web.interceptor;
+
+import com.vci.starter.web.constant.TokenKeyConstant;
+import com.vci.starter.web.enumpck.LangCodeEnum;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.lang.Nullable;
+import org.springframework.web.servlet.HandlerInterceptor;
+import org.springframework.web.servlet.LocaleResolver;
+import org.springframework.web.servlet.support.RequestContextUtils;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.Locale;
+
+/**
+ * 鏈湴鍖栨帶鍒舵嫤鎴櫒
+ * @author weidy
+ * @date 2019/11/7 12:22 PM
+ */
+public class VciLocaleInterceptor implements HandlerInterceptor {
+
+    /**
+     * 鏃ュ織瀵硅薄
+     */
+    protected final Logger logger = LoggerFactory.getLogger(getClass());
+
+    /**
+     * 鎵ц鎷︽埅
+     * @param request 璇锋眰瀵硅薄
+     * @param response 鐩稿簲瀵硅薄
+     * @param handler 澶勭悊鍣�
+     * @return 鏄惁鎴愬姛,false琛ㄧず澶辫触锛屽叾浠栫殑鎷︽埅鍣ㄥ皢涓嶄細鎵ц
+     * @throws Exception 鎵ц鍑洪敊鏃朵細鎶涘嚭寮傚父
+     */
+    @Override
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
+            throws Exception {
+        //浠庡弬鏁版垨鑰呭ご閲岃幏鍙�
+        String newLocale = request.getParameter(TokenKeyConstant.LANGUAGE_KEY);
+        if(StringUtils.isBlank(newLocale)){
+            newLocale = request.getHeader(TokenKeyConstant.LANGUAGE_KEY);
+            if(logger.isDebugEnabled() && StringUtils.isNotBlank(newLocale)) {
+                logger.debug("鏈湴鍖栧弬鏁板湪鏁版嵁澶翠腑瀛樻斁锛屽綋鍓嶆槸琚皟鐢ㄧ殑鏈嶅姟銆倇}", newLocale);
+            }
+//            if(StringUtils.isBlank(newLocale)){
+//                newLocale = LangCodeEnum.ZH_CN.getValue();
+//            }
+        }
+        //濡傛灉娌℃湁浼犻�掑氨涓嶈缃紝鍥犱负澶氳瑷�鏈夐粯璁ゅ��
+        if (StringUtils.isNotBlank(newLocale)) {
+            LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(request);
+            if (localeResolver == null) {
+                throw new IllegalStateException(
+                        "No LocaleResolver found: not in a DispatcherServlet request?");
+            }
+            try {
+                localeResolver.setLocale(request, response, parseLocaleValue(newLocale));
+                if(logger.isDebugEnabled()) {
+                    logger.debug("鏈湴鍖栦负{}", newLocale);
+                }
+            }catch (IllegalArgumentException ex) {
+                if(logger.isDebugEnabled()) {
+                    logger.debug("Ignoring invalid locale value [{}]:{} " ,newLocale,ex.getMessage());
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * 鏍规嵁璇█鐨勭紪鐮佽幏鍙栨湰鍦板寲瀵硅薄
+     * @param localeValue 鏈湴鍖栫紪鐮�
+     * @return 鏈湴鍖栧璞�
+     */
+    @Nullable
+    protected Locale parseLocaleValue(String localeValue) {
+        return org.springframework.util.StringUtils.parseLocale(localeValue);
+    }
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/interceptor/VciLogAfterInterceptor.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/interceptor/VciLogAfterInterceptor.java
new file mode 100644
index 0000000..334d0a2
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/interceptor/VciLogAfterInterceptor.java
@@ -0,0 +1,65 @@
+package com.vci.starter.web.interceptor;
+
+import com.vci.starter.web.constant.TokenKeyConstant;
+import com.vci.starter.web.util.VciBaseUtil;
+import com.vci.starter.web.util.WebThreadLocalUtil;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.MDC;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.lang.Nullable;
+import org.springframework.web.servlet.HandlerInterceptor;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * 鏃ュ織鐨勯摼璺嫤鎴櫒锛屾渶鍚庣殑鎷︽埅鍣�
+ * @author weidy
+ * @date 2019/11/7 2:52 PM
+ */
+public class VciLogAfterInterceptor implements HandlerInterceptor {
+
+    /**
+     * 鏃ュ織瀛樺偍鐨勬帴鍙�
+     */
+    @Autowired(required = false)
+    private VciLogStorageI logStorage;
+
+
+    /**
+     * 鎵ц鎷︽埅
+     *
+     * @param request  璇锋眰瀵硅薄
+     * @param response 鐩稿簲瀵硅薄
+     * @param handler  澶勭悊鍣�
+     * @return 鏄惁鎴愬姛, false琛ㄧず澶辫触锛屽叾浠栫殑鎷︽埅鍣ㄥ皢涓嶄細鎵ц
+     * @throws Exception 鎵ц鍑洪敊鏃朵細鎶涘嚭寮傚父
+     */
+    @Override
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
+            throws Exception {
+        return true;
+    }
+
+    /**
+     * 鍦ㄦ嫤鎴櫒鎵ц瀹屾垚鍚�
+     * @param request 璇锋眰瀵硅薄
+     * @param response 鐩稿簲瀵硅薄
+     * @param handler 澶勭悊鍣�
+     * @param exception 寮傚父
+     * @throws Exception 鎵ц鍑洪敊鏃朵細鎶涘嚭寮傚父
+     */
+    @Override
+    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception exception) throws Exception {
+        //杩欎釜鎷︽埅鍣ㄧ粨鏉熸椂杩樻湁鍏朵粬鎷︽埅鍣ㄦ病鏈夊畬鎴愩�傛墍浠ヨ繖涓笉娓呴櫎
+        String traceId = MDC.get(TokenKeyConstant.TRACE_ID);
+        //鍒犻櫎閾捐矾ID
+        MDC.remove(TokenKeyConstant.TRACE_ID);
+        //璁板綍鎿嶄綔鏃ュ織
+        String traceIdInRequest = request.getHeader(TokenKeyConstant.LOG_TRACE_ID_KEY);
+        if(StringUtils.isBlank(traceIdInRequest) && logStorage !=null ){
+            //璇存槑杩欎釜涓嶆槸琚湇鍔℃墍璇锋眰鐨勶紝鑰屾槸閫氳繃椤甸潰璇锋眰鐨勶紝鎵�浠ヨ璁板綍鎿嶄綔鏃ュ織
+            logStorage.storageForMvc(traceId,request,response,handler,exception);
+        }
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/interceptor/VciLogBeforeInterceptor.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/interceptor/VciLogBeforeInterceptor.java
new file mode 100644
index 0000000..f95a6c3
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/interceptor/VciLogBeforeInterceptor.java
@@ -0,0 +1,75 @@
+package com.vci.starter.web.interceptor;
+
+import com.vci.starter.web.constant.TokenKeyConstant;
+import com.vci.starter.web.util.VciBaseUtil;
+import com.vci.starter.web.util.WebThreadLocalUtil;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.MDC;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.lang.Nullable;
+import org.springframework.web.servlet.HandlerInterceptor;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * 鏃ュ織鐨勯摼璺嫤鎴櫒--鎵�鏈夋嫤鎴櫒涔嬪墠
+ * @author weidy
+ * @date 2019/11/7 2:52 PM
+ */
+public class VciLogBeforeInterceptor implements HandlerInterceptor {
+
+    /**
+     * 鏃ュ織瀛樺偍鐨勬帴鍙�
+     */
+    @Autowired(required = false)
+    private VciLogStorageI logStorage;
+
+
+    /**
+     * 鎵ц鎷︽埅
+     *
+     * @param request  璇锋眰瀵硅薄
+     * @param response 鐩稿簲瀵硅薄
+     * @param handler  澶勭悊鍣�
+     * @return 鏄惁鎴愬姛, false琛ㄧず澶辫触锛屽叾浠栫殑鎷︽埅鍣ㄥ皢涓嶄細鎵ц
+     * @throws Exception 鎵ц鍑洪敊鏃朵細鎶涘嚭寮傚父
+     */
+    @Override
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
+            throws Exception {
+        //鍥犱负鎷︽埅鍣ㄦ湁椤哄簭锛屾墍浠ヨ缃畉raceId鐨勬椂鍊欓渶瑕佸湪寮�濮嬪氨鎵ц
+        request.setAttribute(TokenKeyConstant.REQUEST_TIMESTAMP,System.currentTimeMillis());
+        //鎴戜滑浠庡ご閮ㄨ幏鍙栫湅鏄惁鏈夋棩蹇楃殑trackId
+        //rpc鐨勬鏋跺湪鍏惰嚜宸辩殑鎷︽埅鍣紙鎴栬�呰繃婊ゅ櫒锛変腑澶勭悊
+        String traceId = request.getHeader(TokenKeyConstant.LOG_TRACE_ID_KEY);
+        if (StringUtils.isBlank(traceId)) {
+            //涓虹┖鏃讹紝琛ㄧず杩欎釜鏄祻瑙堝櫒璇锋眰鐨勶紝鎵�浠ョ洿鎺ョ敓鎴愪竴涓柊鐨処D
+            traceId = VciBaseUtil.getPk();
+        }
+        MDC.put(TokenKeyConstant.TRACE_ID, traceId);
+        return true;
+    }
+
+    /**
+     * 鎷︽埅鍣ㄦ墽琛屽畬鎴愬悗
+     * @param request 璇锋眰瀵硅薄
+     * @param response 鐩稿簲瀵硅薄
+     * @param handler 澶勭悊鍣�
+     * @param exception 寮傚父
+     * @throws Exception 鎵ц鍑洪敊鏃朵細鎶涘嚭寮傚父
+     */
+    @Override
+    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception exception) throws Exception {
+       //杩欎釜鎷︽埅鍣ㄧ粨鏉熸椂杩樻湁鍏朵粬鎷︽埅鍣ㄦ病鏈夊畬鎴愩�傛墍浠ヨ繖涓笉娓呴櫎
+        String traceId = MDC.get(TokenKeyConstant.TRACE_ID);
+        //鍒犻櫎閾捐矾ID
+        MDC.remove(TokenKeyConstant.TRACE_ID);
+        //璁板綍鎿嶄綔鏃ュ織
+        String traceIdInRequest = request.getHeader(TokenKeyConstant.LOG_TRACE_ID_KEY);
+        if(StringUtils.isBlank(traceIdInRequest) && logStorage !=null ){
+            //璇存槑杩欎釜涓嶆槸琚湇鍔℃墍璇锋眰鐨勶紝鑰屾槸閫氳繃椤甸潰璇锋眰鐨勶紝鎵�浠ヨ璁板綍鎿嶄綔鏃ュ織
+            logStorage.storageForMvc(traceId,request,response,handler,exception);
+        }
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/interceptor/VciLogStorageI.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/interceptor/VciLogStorageI.java
new file mode 100644
index 0000000..9007bf8
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/interceptor/VciLogStorageI.java
@@ -0,0 +1,24 @@
+package com.vci.starter.web.interceptor;
+
+import org.springframework.lang.Nullable;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * 鏃ュ織瀛樺偍鐨勬帴鍙�
+ * @author weidy
+ * @date 2019/11/7 3:29 PM
+ */
+public interface VciLogStorageI {
+
+    /**
+     * 鏍规嵁mvc璁板綍鎿嶄綔鏃ュ織
+     * @param traceId 鏈鏃ュ織鎵ц閾捐矾鐨刬d锛屾柟渚夸互鍚庤拷鏌�
+     * @param request 璇锋眰瀵硅薄
+     * @param response 鍝嶅簲瀵硅薄
+     * @param handler 澶勭悊瀵硅薄
+     * @param exception 寮傚父鍐呭
+     */
+    void storageForMvc(String traceId, HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception exception);
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/interceptor/VciNoticePopLoginI.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/interceptor/VciNoticePopLoginI.java
new file mode 100644
index 0000000..30288b3
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/interceptor/VciNoticePopLoginI.java
@@ -0,0 +1,19 @@
+package com.vci.starter.web.interceptor;
+
+import com.vci.starter.web.pagemodel.SessionInfo;
+
+import java.util.List;
+
+/**
+ * 閫氱煡鐧诲綍
+ * @author weidy
+ * @date 2020/2/27
+ */
+public interface VciNoticePopLoginI {
+
+    /**
+     * 閫氱煡鐢ㄦ埛琚涪涓嬬嚎
+     * @param sessionInfoList 鐢ㄦ埛浼氳瘽淇℃伅
+     */
+    void noticePopLogin(List<SessionInfo> sessionInfoList);
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/interceptor/VciSecurityInterceptor.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/interceptor/VciSecurityInterceptor.java
new file mode 100644
index 0000000..5be623c
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/interceptor/VciSecurityInterceptor.java
@@ -0,0 +1,198 @@
+package com.vci.starter.web.interceptor;
+
+
+import com.vci.starter.web.annotation.controller.VciUnCheckRight;
+import com.vci.starter.web.autoconfigure.SpringMVCConfig;
+import com.vci.starter.web.constant.TokenKeyConstant;
+import com.vci.starter.web.enumpck.ResultCodeEnum;
+import com.vci.starter.web.pagemodel.BaseResult;
+import com.vci.starter.web.pagemodel.SessionInfo;
+import com.vci.starter.web.util.LangBaseUtil;
+import com.vci.starter.web.util.VciBaseUtil;
+import com.vci.starter.web.util.WebThreadLocalUtil;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.method.HandlerMethod;
+import org.springframework.web.servlet.HandlerInterceptor;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 鏉冮檺鎷︽埅鍣�
+ * @author weidy
+ * @date 2019/11/7 2:32 PM
+ */
+public class VciSecurityInterceptor implements HandlerInterceptor {
+
+    /**
+     * 鏃ュ織瀵硅薄
+     */
+    private Logger logger = LoggerFactory.getLogger(getClass());
+
+    /**
+     * 寮曞叆閰嶇疆
+     */
+    @Autowired(required = false)
+    private SpringMVCConfig springMVCConfig;
+
+    /**
+     * 浼氳瘽锛屾潈闄愶紝token鐨勬帴鍙�
+     */
+    @Autowired(required = false)
+    private VciSessionForLoginI sessionForLoginI;
+
+    /**
+     * 鎵ц鎷︽埅
+     * @param request 璇锋眰瀵硅薄
+     * @param response 鐩稿簲瀵硅薄
+     * @param handler 澶勭悊鍣�
+     * @return 鏄惁鎴愬姛,false琛ㄧず澶辫触锛屽叾浠栫殑鎷︽埅鍣ㄥ皢涓嶄細鎵ц
+     * @throws ServletException
+     */
+    @Override
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
+            throws Exception {
+        //浠庡ご涓幏鍙杢oken锛岀劧鍚庤皟鐢ㄦ帴鍙g被锛岃幏鍙栫敤鎴风殑淇℃伅锛屽叿浣撳疄鐜扮被鍙互鏄粠redis閲岃幏鍙栵紝涔熷彲浠ユ槸閫氳繃鍏朵粬鐨勬柟寮忚幏鍙�
+        //濡傛灉澶撮噷闈㈡病鏈夌敤鎴风殑token锛岄偅璇存槑娌℃湁鐧诲綍锛�
+        String requestUri = request.getRequestURI();
+        String contextPath = request.getContextPath();
+        String url = requestUri.substring(contextPath.length());
+        String userToken = request.getHeader(TokenKeyConstant.USER_TOKEN_KEY);
+        if(StringUtils.isBlank(userToken)){
+            userToken = request.getParameter(TokenKeyConstant.USER_TOKEN_KEY);
+        }
+        if(!(handler instanceof  HandlerMethod)){
+            return true;
+        }
+        List<String> unCheckUrls = new ArrayList<>();
+        if(springMVCConfig !=null && springMVCConfig.getUnCheckUrls() !=null){
+            unCheckUrls = springMVCConfig.getUnCheckUrls();
+        }
+        SessionInfo sessionInfo = null;
+        if(StringUtils.isNotBlank(userToken)){
+            try{
+                sessionInfo = sessionForLoginI.getSessionInfoByToken(userToken);
+            }catch (Throwable e){
+                logger.error("鑾峰彇token鍑洪敊",e);
+                //sendErrorMsg(response,"鑾峰彇token鐨勪俊鎭嚭閿欙紝" + userToken + "," + LangBaseUtil.getErrorMsg(e),1);
+                //return false;
+            }
+            if(sessionInfo!=null){
+                WebThreadLocalUtil.getCurrentUserSessionInfoInThread().set(sessionInfo);
+            }
+        }
+        if(handler instanceof  HandlerMethod) {
+            HandlerMethod hm = (HandlerMethod)handler;
+            Method method = hm.getMethod();
+            //璁剧疆浜嗕笉鏍¢獙鐨勪細鐩存帴杩斿洖true
+            if (method.isAnnotationPresent(VciUnCheckRight.class)) {
+                return true;
+            }
+            if (method.getDeclaringClass().isAnnotationPresent(VciUnCheckRight.class)) {
+                return true;
+            }
+        }
+        if(url.endsWith(".md")){
+            return true;
+        }
+        if(StringUtils.isBlank(userToken) && !unCheckUrls.contains(url)){
+            //璇存槑鏄病鏈夌敤鎴蜂俊鎭殑锛岃�屼笖涔熷繀椤昏鏍¢獙鏄惁鐧诲綍鐨勬儏鍐�
+            //firefox涓婁紶鏂囦欢渚濈劧浣跨敤澶撮噷瀛樻斁token
+            if(logger.isErrorEnabled()) {
+                logger.error("璇锋眰" + url + "锛屼絾鏄病鏈夌櫥褰�");
+            }
+            sendErrorMsg(response,"娌℃湁鐧诲綍绯荤粺锛岃鍏堢櫥褰�",1);
+            return false;
+            //琚玊涓嬬嚎鐢眞ebsocket鐩存帴鎻愰啋
+        }else{
+            if(sessionInfo == null){
+                //涔熸槸璇存槑涓嶅瓨鍦紝琚玊涓嬬嚎鏃朵篃鑾峰彇涓嶅埌session鐨勪俊鎭簡
+                if(logger.isErrorEnabled()) {
+                    logger.error("token鍊奸潪娉曪紝鎴栬�呯敤鎴峰凡缁忚韪笅绾�," + userToken);
+                }
+                sendErrorMsg(response,"token鍊奸潪娉曪紝鎴栬�呯敤鎴峰凡缁忚韪笅绾�," + userToken,1);
+                return false;
+            }else{
+                if(!unCheckUrls.contains(url)){
+                    if(sessionForLoginI == null){
+                        //璇存槑娌″姙娉曟牎楠�
+                        String msg = "璇锋眰璺緞"+ url +"娌℃潈闄愯闂�";
+                        if(logger.isErrorEnabled()) {
+                            logger.error(msg + userToken);
+                        }
+                        sendErrorMsg(response,msg,2);
+                        return false;
+                    }else{
+                        String systemPrivateToken = request.getHeader(TokenKeyConstant.SYSTEM_PRIVATE_KEY);
+                        try {
+                            if (sessionForLoginI.checkRequestRights(request, systemPrivateToken, sessionInfo, handler)) {
+                                updateRequestTime(url,userToken);
+                            }else{
+                                return false;
+                            }
+                        }catch (Throwable e){
+                            String errorMsg = LangBaseUtil.getErrorMsg(e);
+                            if(logger.isErrorEnabled()) {
+                                logger.error("妫�鏌ヨ姹傛槸鍚︾鍚堟潈闄愬嚭鐜颁簡閿欒," + errorMsg, e);
+                            }
+                            sendErrorMsg(response,errorMsg,1);
+                            return false;
+                        }
+                    }
+                }else{
+                    updateRequestTime(url,userToken);
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * 杩斿洖閿欒淇℃伅
+     * @param response 鐩稿簲瀵硅薄
+     * @param errorMsg 閿欒淇℃伅
+     * @param innerErrorCode 鍐呴儴閿欒锛�1琛ㄧず娌℃湁鐧诲綍锛�2琛ㄧず娌℃湁鏉冮檺
+     * @throws Exception
+     */
+    private void sendErrorMsg(HttpServletResponse response, String errorMsg, int innerErrorCode) throws Exception{
+        BaseResult baseResult = BaseResult.fail(errorMsg);
+        if(innerErrorCode ==1) {
+            baseResult.setCode(ResultCodeEnum.UNAUTHORIZED.code);
+        }else if(innerErrorCode == 2){
+            baseResult.setCode(ResultCodeEnum.NOT_RIGHT.code);
+        }
+        response.setCharacterEncoding("UTF-8");
+        response.getWriter().write(VciBaseUtil.getJSONStringWithDateFormat(baseResult));
+    }
+
+    /**
+     * 鏇存柊鏈�鍚庤姹傛椂闂�
+     * @param url 褰撳墠璇锋眰鐨勮矾寰�
+     * @param userToken 鐢ㄦ埛鐨則oken
+     */
+    private void updateRequestTime(String url,String userToken){
+        //璁板綍鏈�鍚庤闂殑鏃堕棿
+        List<String> unStorageRequestTimeUrls = new ArrayList<>();
+        if(springMVCConfig !=null && springMVCConfig.getUnStorageRequestTimeUrls() != null){
+            unStorageRequestTimeUrls = springMVCConfig.getUnStorageRequestTimeUrls();
+        }
+        if(CollectionUtils.isEmpty(unStorageRequestTimeUrls)){
+            unStorageRequestTimeUrls.add("smSessionController/checkIdleTime");
+        }
+        String url1 = url;
+        while(url1.startsWith("/")){
+            url1 = url1.substring(1);
+        }
+        if(sessionForLoginI != null && !unStorageRequestTimeUrls.contains(url1)){
+            sessionForLoginI.updateRequestTime(userToken);
+        }
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/interceptor/VciSessionForLoginI.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/interceptor/VciSessionForLoginI.java
new file mode 100644
index 0000000..ad50dfc
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/interceptor/VciSessionForLoginI.java
@@ -0,0 +1,71 @@
+package com.vci.starter.web.interceptor;
+
+import com.vci.starter.web.exception.VciBaseException;
+import com.vci.starter.web.pagemodel.SessionInfo;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * 浼氳瘽淇℃伅鐩稿叧鐨勬帴鍙�
+ * @author weidy
+ * @date 2020/2/27
+ */
+public interface VciSessionForLoginI {
+    /**
+     * 妫�鏌ョ敤鎴锋槸鍚︾櫥褰�
+     * @param userId 鐢ㄦ埛鍚�
+     * @return 涓虹┖琛ㄧず娌℃湁鐧诲綍
+     */
+    String checkIsLogined(String userId);
+    /**
+     * 寮哄埗鐢ㄦ埛涓嬬嚎
+     * @param userId 鐢ㄦ埛鍚�
+     */
+    void popUser(String userId);
+
+    /**
+     * 灏嗕細璇濅俊鎭瓨鍌ㄥ埌Redis
+     * @param sessionInfo 浼氳瘽淇℃伅
+     */
+    void saveSessionInfo(SessionInfo sessionInfo);
+
+    /**
+     * 鏍¢獙璇锋眰鏄惁绗﹀悎鏉冮檺楠岃瘉
+     * 鍖呭惈1锛岀郴缁熸槸鍚﹀彲浠ヨ闂綋鍓嶆湇鍔℃垨鑰呮帴鍙�
+     *    2, 鐢ㄦ埛鏄惁鏈夋潈闄愯闂綋鍓嶆湇鍔�
+     *    3, 鐢ㄦ埛鏄惁鏈夋潈闄愯闂綋鍓嶆暟鎹�
+     * @param request 璇锋眰瀵硅薄
+     * @param systemPrivateToken 绯荤粺鐨勮鍙爜
+     * @param sessionInfo 褰撳墠鐢ㄦ埛浼氳瘽瀵硅薄
+     * @param handler 鎵ц瀵硅薄
+     * @return true琛ㄧず鏈夋潈闄愶紝false琛ㄧず娌℃潈闄�
+     * @throws VciBaseException 娌℃湁鏉冮檺鐨勬椂鍊欎細鎶涘嚭寮傚父
+     */
+    boolean checkRequestRights(HttpServletRequest request, String systemPrivateToken, SessionInfo sessionInfo, Object handler) throws VciBaseException;
+
+    /**
+     * 鏇存柊璇锋眰鏃堕棿
+     * @param userToken 鐢ㄦ埛token
+     */
+    void updateRequestTime(String userToken);
+
+    /**
+     * 鏍规嵁token鑾峰彇鐢ㄦ埛鐨勫璞�
+     * @param userToken 鐢ㄦ埛token
+     * @return 鐢ㄦ埛浼氳瘽瀵硅薄
+     */
+    SessionInfo getSessionInfoByToken(String userToken);
+
+    /**
+     * 閫�鍑虹櫥褰�
+     * @param userToken 鐢ㄦ埛鐨勪細璇濊鍙�
+     */
+    void logout(String userToken);
+
+    /**
+     * 鏍规嵁token鑾峰彇鐢ㄦ埛鍦ㄧ郴缁熶腑杩樺彲浠ュ瓨鍦ㄧ殑鏃堕棿
+     * @param userToken userToken 鐢ㄦ埛鐨勪細璇濊鍙�
+     * @return 鐢ㄦ埛鍦ㄧ郴缁熶腑杩樺彲浠ュ瓨鍦ㄧ殑鏃堕棿(姣)
+     */
+    long getCanAliveTime(String userToken);
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/model/BaseLinkModel.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/model/BaseLinkModel.java
new file mode 100644
index 0000000..cc08bbd
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/model/BaseLinkModel.java
@@ -0,0 +1,255 @@
+package com.vci.starter.web.model;
+
+
+import com.vci.starter.web.annotation.Column;
+import com.vci.starter.web.annotation.Transient;
+import com.vci.starter.web.annotation.VciFieldType;
+import com.vci.starter.web.enumpck.VciFieldTypeEnum;
+
+import java.util.Date;
+import java.util.Map;
+
+/**
+ * 榛樿鐨勯摼鎺ョ被鍨�
+ * @author weidy
+ */
+public class BaseLinkModel implements java.io.Serializable{
+    /**
+     * 涓婚敭
+     */
+    @Column(nullable = false)
+    private String oid;
+
+    /**
+     * 鍒涘缓浜�
+     */
+    @Column(length = 50)
+    private String creator;
+
+    /**
+     * 鍒涘缓鏃堕棿
+     */
+    @VciFieldType(VciFieldTypeEnum.VTDateTime)
+    private Date createTime;
+
+    /**
+     * 鏈�鍚庝慨鏀逛汉
+     */
+    @Column(length = 50)
+    private String lastModifier;
+
+    /**
+     * 鏈�鍚庝慨鏀规椂闂�
+     */
+    @VciFieldType(VciFieldTypeEnum.VTDateTime)
+    private Date lastModifyTime;
+
+    /**
+     * from绔富閿�
+     */
+    @Column(name="f_oid",length = 50)
+    private String foid;
+
+    /**
+     * from绔増鏈富閿�
+     */
+    @Column(name="f_revisionoid",length = 50)
+    private String frevisionoid;
+
+    /**
+     * from绔璞′富閿�
+     */
+    @Column(name="f_nameoid",length = 50)
+    private String fnameoid;
+
+    /**
+     * from绔笟鍔$被鍨�
+     */
+    @Column(name="f_btmname",length = 30)
+    private String fbtmname;
+
+    /**
+     * to绔富閿�
+     */
+    @Column(name="t_oid",length = 50)
+    private String toid;
+
+    /**
+     * to绔増鏈富閿�
+     */
+    @Column(name="t_revisionoid",length = 50)
+    private String trevisionoid;
+
+    /**
+     * to绔璞′富閿�
+     */
+    @Column(name="t_nameoid",length = 50)
+    private String tnameoid;
+
+    /**
+     * to绔笟鍔$被鍨�
+     */
+    @Column(name="t_btmname",length = 30)
+    private String tbtmname;
+
+    /**
+     * 鏃堕棿鎴�
+     */
+    private Date ts;
+
+    /**
+     * 鎵╁睍鐨勫睘鎬�
+     */
+    @Transient
+    private Map<String,String> data;
+
+    public String getOid() {
+        return oid;
+    }
+
+    public void setOid(String oid) {
+        this.oid = oid;
+    }
+
+    public String getCreator() {
+        return creator;
+    }
+
+    public void setCreator(String creator) {
+        this.creator = creator;
+    }
+
+    public Date getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(Date createTime) {
+        this.createTime = createTime;
+    }
+
+    public String getLastModifier() {
+        return lastModifier;
+    }
+
+    public void setLastModifier(String lastModifier) {
+        this.lastModifier = lastModifier;
+    }
+
+    public Date getLastModifytime() {
+        return lastModifyTime;
+    }
+
+    public void setLastModifytime(Date lastModifytime) {
+        this.lastModifyTime = lastModifytime;
+    }
+
+    public String getFoid() {
+        return foid;
+    }
+
+    public void setFoid(String foid) {
+        this.foid = foid;
+    }
+
+    public String getFrevisionoid() {
+        return frevisionoid;
+    }
+
+    public void setFrevisionoid(String frevisionoid) {
+        this.frevisionoid = frevisionoid;
+    }
+
+    public String getFnameoid() {
+        return fnameoid;
+    }
+
+    public void setFnameoid(String fnameoid) {
+        this.fnameoid = fnameoid;
+    }
+
+
+    public String getToid() {
+        return toid;
+    }
+
+    public void setToid(String toid) {
+        this.toid = toid;
+    }
+
+    public String getTrevisionoid() {
+        return trevisionoid;
+    }
+
+    public void setTrevisionoid(String trevisionoid) {
+        this.trevisionoid = trevisionoid;
+    }
+
+    public String getTnameoid() {
+        return tnameoid;
+    }
+
+    public void setTnameoid(String tnameoid) {
+        this.tnameoid = tnameoid;
+    }
+
+    public String getFbtmname() {
+        return fbtmname;
+    }
+
+    public void setFbtmname(String fbtmname) {
+        this.fbtmname = fbtmname;
+    }
+
+    public String getTbtmname() {
+        return tbtmname;
+    }
+
+    public void setTbtmname(String tbtmname) {
+        this.tbtmname = tbtmname;
+    }
+
+    public Date getTs() {
+        return ts;
+    }
+
+    public void setTs(Date ts) {
+        this.ts = ts;
+    }
+
+    public Date getLastModifyTime() {
+        return lastModifyTime;
+    }
+
+    public void setLastModifyTime(Date lastModifyTime) {
+        this.lastModifyTime = lastModifyTime;
+    }
+
+    public Map<String, String> getData() {
+        return data;
+    }
+
+    public void setData(Map<String, String> data) {
+        this.data = data;
+    }
+
+    @Override
+    public String toString() {
+        return "BaseLinkModel{" +
+                "oid='" + oid + '\'' +
+                ", creator='" + creator + '\'' +
+                ", createTime=" + createTime +
+                ", lastModifier='" + lastModifier + '\'' +
+                ", lastModifyTime=" + lastModifyTime +
+                ", foid='" + foid + '\'' +
+                ", frevisionoid='" + frevisionoid + '\'' +
+                ", fnameoid='" + fnameoid + '\'' +
+                ", fbtmname='" + fbtmname + '\'' +
+                ", toid='" + toid + '\'' +
+                ", trevisionoid='" + trevisionoid + '\'' +
+                ", tnameoid='" + tnameoid + '\'' +
+                ", tbtmname='" + tbtmname + '\'' +
+                ", ts=" + ts +
+                ", data=" + data +
+                '}';
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/model/BaseModel.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/model/BaseModel.java
new file mode 100644
index 0000000..1d350ad
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/model/BaseModel.java
@@ -0,0 +1,545 @@
+package com.vci.starter.web.model;
+
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.vci.starter.web.annotation.Column;
+import com.vci.starter.web.annotation.Transient;
+import com.vci.starter.web.annotation.VciFieldType;
+import com.vci.starter.web.annotation.VciUseEnum;
+import com.vci.starter.web.enumpck.VciFieldTypeEnum;
+import com.vci.starter.web.util.VciDateUtil;
+
+import java.util.Date;
+import java.util.Map;
+
+/**
+ * 骞冲彴鐨勫熀鏈璞�
+ * @author weidy
+ */
+public class BaseModel implements java.io.Serializable{
+
+
+	/**
+	 * 涓婚敭锛屽鏋滆嚜宸辩殑瀵硅薄锛屼笉鏄痮id浣滀负涓婚敭鐨勮瘽锛岄渶瑕佺敤id杩欎釜娉ㄨВ
+	 */
+	@Column(nullable = false,length = 50)
+	private String oid;
+	
+	/**
+	 * 浠e彿锛涘彲浠ヨ缃睘鎬х殑鏄犲皠锛宯ame琛ㄧず鍦ㄥ钩鍙扮殑涓氬姟绫诲瀷涓殑灞炴�у悕绉帮紝蹇呴』涓哄皬鍐欙紱
+	 */
+	@Column(length = 50)
+	private String id;
+	
+	/**
+	 * 鍚嶇О锛涗篃鍙互涓嶈缃睘鎬ф槧灏勶紝榛樿鏄瓧娈靛悕鐨勫皬鍐�
+	 */
+	@Column(length = 50)
+	private String name;
+	
+	/**
+	 * 鎻忚堪
+	 */
+	@Column(length = 250)
+	private String description;
+	
+	/**
+	 * 鐗堟湰鐨勪富閿�
+	 */
+	@Column(length = 50)
+	private String revisionOid;
+	
+	/**
+	 * 瀵硅薄鐨勪富閿�
+	 */
+	@Column(length = 50)
+	private String nameOid;
+	
+	/**
+	 * 涓氬姟绫诲瀷鐨勫悕绉�
+	 */
+	@Column(length = 30)
+	private String btmname;
+	
+	/**
+	 * 鏄惁鏈�鍚庣増鏈�
+	 */
+	@Column(length=1)
+	private String lastR;
+	
+	
+	/**
+	 * 鏄惁鏈�鍒濈増鏈�
+	 */
+	@Column(length=1)
+	private String firstR;
+	
+    
+	/**
+	 * 鏄惁鏈�鏂扮増娆�
+	 */
+	@Column(length=1)
+	private String lastV;
+	
+	
+	/**
+	 * 鏄惁鏈�鏃╃増娆�
+	 */
+	@Column(length=1)
+	private String firstV;
+	
+	/**
+	 * 鍒涘缓浜�
+	 */
+	@Column(length = 50,nullable = false)
+	private String creator;
+	
+	/**
+	 * 鍒涘缓鏃堕棿
+	 */
+	@Column(nullable = false)
+	@VciFieldType(VciFieldTypeEnum.VTDateTime)
+	private Date createTime;
+	
+	/**
+	 * 鏈�鍚庝慨鏀逛汉
+	 */
+	@Column(length = 50,nullable = false)
+	private String lastModifier;
+	
+	/**
+	 * 鏈�鍚庝慨鏀规椂闂达紝鏍煎紡鏄痽yyy-MM-dd HH:mm:ss.SSS
+	 */
+	@VciFieldType(VciFieldTypeEnum.VTDateTime)
+	private Date lastModifyTime;
+	
+	/**
+	 * 鐗堟湰瑙勫垯
+	 */
+	@Column(length = 50)
+	private String revisionRule;
+
+
+	/**
+	 * 鐗堟湰搴忓彿
+	 */
+	@VciFieldType(VciFieldTypeEnum.VTInteger)
+	private int revisionSeq;
+	
+	/**
+	 * 鐗堟湰鍊�
+	 */
+	@Column(length = 50)
+	private String revisionValue;
+
+
+	/**
+	 * 鐗堟瑙勫垯
+	 */
+	@Column(length = 50)
+	private String versionRule;
+
+	/**
+	 * 鐗堟鎺掑簭
+	 */
+	@VciFieldType(VciFieldTypeEnum.VTInteger)
+	private int versionSeq;
+	
+	/**
+	 * 鐗堟鍊�
+	 */
+	@Column(length = 50)
+	private String versionValue;
+
+	/**
+	 * 鐢熷懡鍛ㄦ湡鐨勭紪鍙�
+	 */
+	@Transient()
+	private String lctid;
+
+	/**
+	 * 鐢熷懡鍛ㄦ湡鍊�
+	 */
+	@Column(length = 50)
+	private String lcStatus;
+	
+	/**
+	 * 鐢熷懡鍛ㄦ湡鏄剧ず鏂囨湰
+	 */
+	@Transient(referColumn="lcStatus_text")
+	private String lcStatusText;
+	
+	/**
+	 * 鏃堕棿鎴筹紝鏍煎紡鏄痽yyy-MM-dd HH:mm:ss.SSS
+	 */
+	@JsonFormat(pattern = VciDateUtil.DateTimeMillFormat)
+	private Date ts;
+	
+	/**
+	 * 鎷ユ湁鑰咃紝涓庡垱寤鸿�呮湁鍖哄埆锛屽父鐢ㄤ簬鎺у埗鏁版嵁鏉冮檺
+	 */
+	@Column(length = 50)
+	private String owner;
+	
+	/**
+	 * 绛惧叆浜�--绛惧叆鍜岀鍑烘暟鎹槸浜掓枼
+	 */
+	@Column(length = 50)
+	private String checkInBy;
+	
+	/**
+	 * 绛惧叆鏃堕棿
+	 */
+	@VciFieldType(VciFieldTypeEnum.VTDateTime)
+	private Date checkInTime;
+	
+	/**
+	 * 绛惧嚭浜�
+	 */
+	@Column(length = 50)
+	private String checkOutBy;
+	
+	/**
+	 * 绛惧嚭鏃堕棿
+	 */
+	@VciFieldType(VciFieldTypeEnum.VTDateTime)
+	private Date checkOutTime;
+	
+	/**
+	 * 浠庡摢涓増鏈嫹璐�
+	 */
+	@Column(length = 50)
+	private String copyFromVersion;
+
+	/**
+	 * 瀵嗙骇
+	 */
+	@VciUseEnum(value = "Enumsecretgrade",showTextField = "secretGradeText" )
+	private Integer secretGrade;
+
+	/**
+	 * 瀵嗙骇鏄剧ず鏂囨湰
+	 */
+	@Transient
+	private String secretGradeText;
+
+	/**
+	 * 鎵╁睍鐨勫睘鎬�
+	 */
+	@Transient
+	private Map<String,String> data;
+
+	public String getOid() {
+		return oid;
+	}
+
+	public void setOid(String oid) {
+		this.oid = oid;
+	}
+
+	public String getId() {
+		return id;
+	}
+
+	public void setId(String id) {
+		this.id = id;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public String getDescription() {
+		return description;
+	}
+
+	public void setDescription(String description) {
+		this.description = description;
+	}
+
+	public String getRevisionOid() {
+		return revisionOid;
+	}
+
+	public void setRevisionOid(String revisionOid) {
+		this.revisionOid = revisionOid;
+	}
+
+	public String getNameOid() {
+		return nameOid;
+	}
+
+	public void setNameOid(String nameOid) {
+		this.nameOid = nameOid;
+	}
+
+	public String getBtmname() {
+		return btmname;
+	}
+
+	public void setBtmname(String btmname) {
+		this.btmname = btmname;
+	}
+
+
+	public String getLastR() {
+		return lastR;
+	}
+
+	public void setLastR(String lastR) {
+		this.lastR = lastR;
+	}
+
+	public String getFirstR() {
+		return firstR;
+	}
+
+	public void setFirstR(String firstR) {
+		this.firstR = firstR;
+	}
+
+	public String getLastV() {
+		return lastV;
+	}
+
+	public void setLastV(String lastV) {
+		this.lastV = lastV;
+	}
+
+	public String getFirstV() {
+		return firstV;
+	}
+
+	public void setFirstV(String firstV) {
+		this.firstV = firstV;
+	}
+
+	public String getCreator() {
+		return creator;
+	}
+
+	public void setCreator(String creator) {
+		this.creator = creator;
+	}
+
+	public String getLastModifier() {
+		return lastModifier;
+	}
+
+	public void setLastModifier(String lastModifier) {
+		this.lastModifier = lastModifier;
+	}
+
+	public Date getLastModifyTime() {
+		return lastModifyTime;
+	}
+
+	public void setLastModifyTime(Date lastModifyTime) {
+		this.lastModifyTime = lastModifyTime;
+	}
+
+	public String getRevisionRule() {
+		return revisionRule;
+	}
+
+	public void setRevisionRule(String revisionRule) {
+		this.revisionRule = revisionRule;
+	}
+
+	public String getVersionRule() {
+		return versionRule;
+	}
+
+	public void setVersionRule(String versionRule) {
+		this.versionRule = versionRule;
+	}
+
+	public int getRevisionSeq() {
+		return revisionSeq;
+	}
+
+	public void setRevisionSeq(int revisionSeq) {
+		this.revisionSeq = revisionSeq;
+	}
+
+	public String getRevisionValue() {
+		return revisionValue;
+	}
+
+	public void setRevisionValue(String revisionValue) {
+		this.revisionValue = revisionValue;
+	}
+
+	public int getVersionSeq() {
+		return versionSeq;
+	}
+
+	public void setVersionSeq(int versionSeq) {
+		this.versionSeq = versionSeq;
+	}
+
+	public String getVersionValue() {
+		return versionValue;
+	}
+
+	public void setVersionValue(String versionValue) {
+		this.versionValue = versionValue;
+	}
+
+	public String getLcStatus() {
+		return lcStatus;
+	}
+
+	public void setLcStatus(String lcStatus) {
+		this.lcStatus = lcStatus;
+	}
+
+	public Date getTs() {
+		return ts;
+	}
+
+	public void setTs(Date ts) {
+		this.ts = ts;
+	}
+
+	public String getOwner() {
+		return owner;
+	}
+
+	public void setOwner(String owner) {
+		this.owner = owner;
+	}
+
+	public String getCheckInBy() {
+		return checkInBy;
+	}
+
+	public void setCheckInBy(String checkInBy) {
+		this.checkInBy = checkInBy;
+	}
+
+	public Date getCheckInTime() {
+		return checkInTime;
+	}
+
+	public void setCheckInTime(Date checkInTime) {
+		this.checkInTime = checkInTime;
+	}
+
+	public String getCheckOutBy() {
+		return checkOutBy;
+	}
+
+	public void setCheckOutBy(String checkOutBy) {
+		this.checkOutBy = checkOutBy;
+	}
+
+	public Date getCheckOutTime() {
+		return checkOutTime;
+	}
+
+	public void setCheckOutTime(Date checkOutTime) {
+		this.checkOutTime = checkOutTime;
+	}
+
+	public String getCopyFromVersion() {
+		return copyFromVersion;
+	}
+
+	public void setCopyFromVersion(String copyFromVersion) {
+		this.copyFromVersion = copyFromVersion;
+	}
+
+	public String getLcStatusText() {
+		return lcStatusText;
+	}
+
+	public void setLcStatusText(String lcStatusText) {
+		this.lcStatusText = lcStatusText;
+	}
+
+	public Date getCreateTime() {
+		return createTime;
+	}
+
+	public void setCreateTime(Date createTime) {
+		this.createTime = createTime;
+	}
+
+	public Integer getSecretGrade() {
+		return secretGrade;
+	}
+
+	public void setSecretGrade(Integer secretGrade) {
+		this.secretGrade = secretGrade;
+	}
+
+	public String getSecretGradeText() {
+		return secretGradeText;
+	}
+
+	public void setSecretGradeText(String secretGradeText) {
+		this.secretGradeText = secretGradeText;
+	}
+
+	public String getLctid() {
+		return lctid;
+	}
+
+	public void setLctid(String lctid) {
+		this.lctid = lctid;
+	}
+
+
+	public Map<String, String> getData() {
+		return data;
+	}
+
+	public void setData(Map<String, String> data) {
+		this.data = data;
+	}
+
+	@Override
+	public String toString() {
+		return "BaseModel{" +
+				"oid='" + oid + '\'' +
+				", id='" + id + '\'' +
+				", name='" + name + '\'' +
+				", description='" + description + '\'' +
+				", revisionOid='" + revisionOid + '\'' +
+				", nameOid='" + nameOid + '\'' +
+				", btmname='" + btmname + '\'' +
+				", lastR='" + lastR + '\'' +
+				", firstR='" + firstR + '\'' +
+				", lastV='" + lastV + '\'' +
+				", firstV='" + firstV + '\'' +
+				", creator='" + creator + '\'' +
+				", createTime=" + createTime +
+				", lastModifier='" + lastModifier + '\'' +
+				", lastModifyTime=" + lastModifyTime +
+				", revisionRule='" + revisionRule + '\'' +
+				", revisionSeq=" + revisionSeq +
+				", revisionValue='" + revisionValue + '\'' +
+				", versionRule='" + versionRule + '\'' +
+				", versionSeq=" + versionSeq +
+				", versionValue='" + versionValue + '\'' +
+				", lctid='" + lctid + '\'' +
+				", lcStatus='" + lcStatus + '\'' +
+				", lcStatusText='" + lcStatusText + '\'' +
+				", ts=" + ts +
+				", owner='" + owner + '\'' +
+				", checkInBy='" + checkInBy + '\'' +
+				", checkInTime=" + checkInTime +
+				", checkOutBy='" + checkOutBy + '\'' +
+				", checkOutTime=" + checkOutTime +
+				", copyFromVersion='" + copyFromVersion + '\'' +
+				", secretGrade=" + secretGrade +
+				", secretGradeText='" + secretGradeText + '\'' +
+				", data=" + data +
+				'}';
+	}
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/BaseLinkModelVO.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/BaseLinkModelVO.java
new file mode 100644
index 0000000..1f7cefb
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/BaseLinkModelVO.java
@@ -0,0 +1,229 @@
+package com.vci.starter.web.pagemodel;
+
+import com.vci.starter.web.annotation.Transient;
+
+import java.util.Date;
+import java.util.Map;
+
+/**
+ * 閾炬帴绫诲瀷鐨勬樉绀哄璞�
+ * @author weidy
+ */
+public class BaseLinkModelVO implements java.io.Serializable{
+    /**
+     * 涓婚敭
+     */
+    private String oid;
+
+    /**
+     * 鍒涘缓浜�
+     */
+    private String creator;
+
+    /**
+     * 鍒涘缓鏃堕棿
+     */
+    private Date createTime;
+
+    /**
+     * 鏈�鍚庝慨鏀逛汉
+     */
+    private String lastModifier;
+
+    /**
+     * 鏈�鍚庝慨鏀规椂闂�
+     */
+    private Date lastModifyTime;
+
+    /**
+     * from绔富閿�
+     */
+    private String foid;
+
+    /**
+     * from绔増鏈富閿�
+     */
+    private String frevisionoid;
+
+    /**
+     * from绔璞′富閿�
+     */
+    private String fnameoid;
+
+    /**
+     * from绔笟鍔$被鍨�
+     */
+    private String fbtmname;
+
+    /**
+     * to绔富閿�
+     */
+    private String toid;
+
+    /**
+     * to绔増鏈富閿�
+     */
+    private String trevisionoid;
+
+    /**
+     * to绔璞′富閿�
+     */
+    private String tnameoid;
+
+    /**
+     * to绔笟鍔$被鍨�
+     */
+    private String tbtmname;
+
+    /**
+     * 鏃堕棿鎴�
+     */
+    private Date ts;
+
+    /**
+     * 鎵╁睍鐨勫睘鎬�
+     */
+    @Transient
+    private Map<String,String> data;
+
+    public String getOid() {
+        return oid;
+    }
+
+    public void setOid(String oid) {
+        this.oid = oid;
+    }
+
+    public String getCreator() {
+        return creator;
+    }
+
+    public void setCreator(String creator) {
+        this.creator = creator;
+    }
+
+    public Date getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(Date createTime) {
+        this.createTime = createTime;
+    }
+
+    public String getLastModifier() {
+        return lastModifier;
+    }
+
+    public void setLastModifier(String lastModifier) {
+        this.lastModifier = lastModifier;
+    }
+
+    public Date getLastModifyTime() {
+        return lastModifyTime;
+    }
+
+    public void setLastModifyTime(Date lastModifyTime) {
+        this.lastModifyTime = lastModifyTime;
+    }
+
+    public String getFoid() {
+        return foid;
+    }
+
+    public void setFoid(String foid) {
+        this.foid = foid;
+    }
+
+    public String getFrevisionoid() {
+        return frevisionoid;
+    }
+
+    public void setFrevisionoid(String frevisionoid) {
+        this.frevisionoid = frevisionoid;
+    }
+
+    public String getFnameoid() {
+        return fnameoid;
+    }
+
+    public void setFnameoid(String fnameoid) {
+        this.fnameoid = fnameoid;
+    }
+
+    public String getFbtmname() {
+        return fbtmname;
+    }
+
+    public void setFbtmname(String fbtmname) {
+        this.fbtmname = fbtmname;
+    }
+
+    public String getToid() {
+        return toid;
+    }
+
+    public void setToid(String toid) {
+        this.toid = toid;
+    }
+
+    public String getTrevisionoid() {
+        return trevisionoid;
+    }
+
+    public void setTrevisionoid(String trevisionoid) {
+        this.trevisionoid = trevisionoid;
+    }
+
+    public String getTnameoid() {
+        return tnameoid;
+    }
+
+    public void setTnameoid(String tnameoid) {
+        this.tnameoid = tnameoid;
+    }
+
+    public String getTbtmname() {
+        return tbtmname;
+    }
+
+    public void setTbtmname(String tbtmname) {
+        this.tbtmname = tbtmname;
+    }
+
+    public Date getTs() {
+        return ts;
+    }
+
+    public void setTs(Date ts) {
+        this.ts = ts;
+    }
+
+    public Map<String, String> getData() {
+        return data;
+    }
+
+    public void setData(Map<String, String> data) {
+        this.data = data;
+    }
+
+    @Override
+    public String toString() {
+        return "BaseLinkModelVO{" +
+                "oid='" + oid + '\'' +
+                ", creator='" + creator + '\'' +
+                ", createTime=" + createTime +
+                ", lastModifier='" + lastModifier + '\'' +
+                ", lastModifyTime=" + lastModifyTime +
+                ", foid='" + foid + '\'' +
+                ", frevisionoid='" + frevisionoid + '\'' +
+                ", fnameoid='" + fnameoid + '\'' +
+                ", fbtmname='" + fbtmname + '\'' +
+                ", toid='" + toid + '\'' +
+                ", trevisionoid='" + trevisionoid + '\'' +
+                ", tnameoid='" + tnameoid + '\'' +
+                ", tbtmname='" + tbtmname + '\'' +
+                ", ts=" + ts +
+                ", data=" + data +
+                '}';
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/BaseModelVO.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/BaseModelVO.java
new file mode 100644
index 0000000..1b0f772
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/BaseModelVO.java
@@ -0,0 +1,502 @@
+package com.vci.starter.web.pagemodel;
+
+import com.vci.starter.web.annotation.Transient;
+
+import java.util.Date;
+import java.util.Map;
+
+/**
+ * 骞冲彴鐨勫熀鏈樉绀哄璞�
+ * @author weidy
+ */
+public class BaseModelVO implements java.io.Serializable{
+
+
+	/**
+	 * 涓婚敭
+	 */
+	private String oid;
+	
+	/**
+	 * 浠e彿
+	 */
+	private String id;
+	
+	/**
+	 * 鍚嶇О
+	 */
+	private String name;
+	
+	/**
+	 * 鎻忚堪
+	 */
+	private String description;
+	
+	/**
+	 * 鐗堟湰鐨勪富閿�
+	 */
+	private String revisionOid;
+	
+	/**
+	 * 鍚嶇О鐨勪富閿�
+	 */
+	private String nameOid;
+	
+	/**
+	 * 涓氬姟绫诲瀷鐨勫悕绉�
+	 */
+	private String btmname;
+	
+	/**
+	 * 鏄惁鏈�鍚庣増娆�
+	 */
+	private String lastR;
+	
+	
+	/**
+	 * 鏄惁鏈�鍒濈増娆�
+	 */
+	private String firstR;
+
+	/**
+	 * 鏄惁鏈�鏂扮増鏈�
+	 */
+	private String lastV;
+	
+	
+	/**
+	 * 鏄惁鏈�鏃╃増鏈�
+	 */
+	private String firstV;
+	
+	/**
+	 * 鍒涘缓浜�
+	 */
+	private String creator;
+	
+	/**
+	 * 鍒涘缓鏃堕棿
+	 */
+	private Date createTime;
+	
+	/**
+	 * 鏈�鍚庝慨鏀逛汉
+	 */
+	private String lastModifier;
+	
+	/**
+	 * 鏈�鍚庝慨鏀规椂闂达紝鏍煎紡鏄痽yyy-MM-dd HH:mm:ss.SSS
+	 */
+	private Date lastModifyTime;
+	
+	/**
+	 * 鐗堟湰瑙勫垯
+	 */
+	private String revisionRule;
+
+	/**
+	 * 鐗堟湰搴忓彿
+	 */
+	private int revisionSeq;
+	
+	/**
+	 * 鐗堟湰鍊�
+	 */
+	private String revisionValue;
+
+
+	/**
+	 * 鐗堟瑙勫垯
+	 */
+	private String versionRule;
+
+	/**
+	 * 鐗堟鎺掑簭
+	 */
+	private int versionSeq;
+	
+	/**
+	 * 鐗堟鍊�
+	 */
+	private String versionValue;
+
+	
+	/**
+	 * 鐢熷懡鍛ㄦ湡鍊�
+	 */
+	private String lcStatus;
+	
+	/**
+	 * 鐢熷懡鍛ㄦ湡鏄剧ず鏂囨湰
+	 */
+	private String lcStatusText;
+	
+	/**
+	 * 鏃堕棿鎴筹紝鏍煎紡鏄痽yyy-MM-dd HH:mm:ss.SSS
+	 */
+	private Date ts;
+	
+	/**
+	 * 鎷ユ湁鑰咃紝涓庡垱寤鸿�呮湁鍖哄埆锛屽父鐢ㄤ簬鎺у埗鏁版嵁鏉冮檺
+	 */
+	private String owner;
+	
+	/**
+	 * 绛惧叆浜�--绛惧叆鍜岀鍑烘暟鎹槸浜掓枼
+	 */
+	private String checkInBy;
+	
+	/**
+	 * 绛惧叆鏃堕棿
+	 */
+	private Date checkInTime;
+	
+	/**
+	 * 绛惧嚭浜�
+	 */
+	private String checkOutBy;
+	
+	/**
+	 * 绛惧嚭鏃堕棿
+	 */
+	private Date checkOutTime;
+	
+	/**
+	 * 浠庡摢涓増鏈嫹璐�
+	 */
+	private String copyFromVersion;
+
+	/**
+	 * 瀵嗙骇
+	 */
+	private Integer secretGrade;
+
+	/**
+	 * 瀵嗙骇鏄剧ず鏂囨湰
+	 */
+	private String secretGradeText;
+
+	/**
+	 * 鐢熷懡鍛ㄦ湡鐨勫悕绉�
+	 */
+	private String lctid;
+
+	/**
+	 * 鎵╁睍鐨勫睘鎬�
+	 */
+	@Transient
+	private Map<String,String> data;
+
+	public String getOid() {
+		return oid;
+	}
+
+	public void setOid(String oid) {
+		this.oid = oid;
+	}
+
+	public String getId() {
+		return id;
+	}
+
+	public void setId(String id) {
+		this.id = id;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public String getDescription() {
+		return description;
+	}
+
+	public void setDescription(String description) {
+		this.description = description;
+	}
+
+	public String getRevisionOid() {
+		return revisionOid;
+	}
+
+	public void setRevisionOid(String revisionOid) {
+		this.revisionOid = revisionOid;
+	}
+
+	public String getNameOid() {
+		return nameOid;
+	}
+
+	public void setNameOid(String nameOid) {
+		this.nameOid = nameOid;
+	}
+
+	public String getBtmname() {
+		return btmname;
+	}
+
+	public void setBtmname(String btmname) {
+		this.btmname = btmname;
+	}
+
+	public String getLastR() {
+		return lastR;
+	}
+
+	public void setLastR(String lastR) {
+		this.lastR = lastR;
+	}
+
+	public String getFirstR() {
+		return firstR;
+	}
+
+	public void setFirstR(String firstR) {
+		this.firstR = firstR;
+	}
+
+	public String getLastV() {
+		return lastV;
+	}
+
+	public void setLastV(String lastV) {
+		this.lastV = lastV;
+	}
+
+	public String getFirstV() {
+		return firstV;
+	}
+
+	public void setFirstV(String firstV) {
+		this.firstV = firstV;
+	}
+
+	public String getCreator() {
+		return creator;
+	}
+
+	public void setCreator(String creator) {
+		this.creator = creator;
+	}
+
+	public String getLastModifier() {
+		return lastModifier;
+	}
+
+	public void setLastModifier(String lastModifier) {
+		this.lastModifier = lastModifier;
+	}
+
+	public Date getLastModifyTime() {
+		return lastModifyTime;
+	}
+
+	public void setLastModifyTime(Date lastModifyTime) {
+		this.lastModifyTime = lastModifyTime;
+	}
+
+	public String getRevisionRule() {
+		return revisionRule;
+	}
+
+	public void setRevisionRule(String revisionRule) {
+		this.revisionRule = revisionRule;
+	}
+
+	public String getVersionRule() {
+		return versionRule;
+	}
+
+	public void setVersionRule(String versionRule) {
+		this.versionRule = versionRule;
+	}
+
+	public int getRevisionSeq() {
+		return revisionSeq;
+	}
+
+	public void setRevisionSeq(int revisionSeq) {
+		this.revisionSeq = revisionSeq;
+	}
+
+	public String getRevisionValue() {
+		return revisionValue;
+	}
+
+	public void setRevisionValue(String revisionValue) {
+		this.revisionValue = revisionValue;
+	}
+
+	public int getVersionSeq() {
+		return versionSeq;
+	}
+
+	public void setVersionSeq(int versionSeq) {
+		this.versionSeq = versionSeq;
+	}
+
+	public String getVersionValue() {
+		return versionValue;
+	}
+
+	public void setVersionValue(String versionValue) {
+		this.versionValue = versionValue;
+	}
+
+
+	public String getLcStatus() {
+		return lcStatus;
+	}
+
+	public void setLcStatus(String lcStatus) {
+		this.lcStatus = lcStatus;
+	}
+
+	public Date getTs() {
+		return ts;
+	}
+
+	public void setTs(Date ts) {
+		this.ts = ts;
+	}
+
+	public String getOwner() {
+		return owner;
+	}
+
+	public void setOwner(String owner) {
+		this.owner = owner;
+	}
+
+	public String getCheckInBy() {
+		return checkInBy;
+	}
+
+	public void setCheckInBy(String checkInBy) {
+		this.checkInBy = checkInBy;
+	}
+
+	public Date getCheckInTime() {
+		return checkInTime;
+	}
+
+	public void setCheckInTime(Date checkInTime) {
+		this.checkInTime = checkInTime;
+	}
+
+	public String getCheckOutBy() {
+		return checkOutBy;
+	}
+
+	public void setCheckOutBy(String checkOutBy) {
+		this.checkOutBy = checkOutBy;
+	}
+
+	public Date getCheckOutTime() {
+		return checkOutTime;
+	}
+
+	public void setCheckOutTime(Date checkOutTime) {
+		this.checkOutTime = checkOutTime;
+	}
+
+	public String getCopyFromVersion() {
+		return copyFromVersion;
+	}
+
+	public void setCopyFromVersion(String copyFromVersion) {
+		this.copyFromVersion = copyFromVersion;
+	}
+
+	public String getLcStatusText() {
+		return lcStatusText;
+	}
+
+	public void setLcStatusText(String lcStatusText) {
+		this.lcStatusText = lcStatusText;
+	}
+
+	public Date getCreateTime() {
+		return createTime;
+	}
+
+	public void setCreateTime(Date createTime) {
+		this.createTime = createTime;
+	}
+
+	public Integer getSecretGrade() {
+		return secretGrade;
+	}
+
+	public void setSecretGrade(Integer secretGrade) {
+		this.secretGrade = secretGrade;
+	}
+
+	public String getSecretGradeText() {
+		return secretGradeText;
+	}
+
+	public void setSecretGradeText(String secretGradeText) {
+		this.secretGradeText = secretGradeText;
+	}
+
+	public String getLctid() {
+		return lctid;
+	}
+
+	public void setLctid(String lctid) {
+		this.lctid = lctid;
+	}
+
+	public Map<String, String> getData() {
+		return data;
+	}
+
+	public void setData(Map<String, String> data) {
+		this.data = data;
+	}
+
+	@Override
+	public String toString() {
+		return "BaseModelVO{" +
+				"oid='" + oid + '\'' +
+				", id='" + id + '\'' +
+				", name='" + name + '\'' +
+				", description='" + description + '\'' +
+				", revisionOid='" + revisionOid + '\'' +
+				", nameOid='" + nameOid + '\'' +
+				", btmname='" + btmname + '\'' +
+				", lastR='" + lastR + '\'' +
+				", firstR='" + firstR + '\'' +
+				", lastV='" + lastV + '\'' +
+				", firstV='" + firstV + '\'' +
+				", creator='" + creator + '\'' +
+				", createTime=" + createTime +
+				", lastModifier='" + lastModifier + '\'' +
+				", lastModifyTime=" + lastModifyTime +
+				", revisionRule='" + revisionRule + '\'' +
+				", revisionSeq=" + revisionSeq +
+				", revisionValue='" + revisionValue + '\'' +
+				", versionRule='" + versionRule + '\'' +
+				", versionSeq=" + versionSeq +
+				", versionValue='" + versionValue + '\'' +
+				", lcStatus='" + lcStatus + '\'' +
+				", lcStatusText='" + lcStatusText + '\'' +
+				", ts=" + ts +
+				", owner='" + owner + '\'' +
+				", checkInBy='" + checkInBy + '\'' +
+				", checkInTime=" + checkInTime +
+				", checkOutBy='" + checkOutBy + '\'' +
+				", checkOutTime=" + checkOutTime +
+				", copyFromVersion='" + copyFromVersion + '\'' +
+				", secretGrade=" + secretGrade +
+				", secretGradeText='" + secretGradeText + '\'' +
+				", lctid='" + lctid + '\'' +
+				", data=" + data +
+				'}';
+	}
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/BaseQueryObject.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/BaseQueryObject.java
new file mode 100644
index 0000000..d7a4d34
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/BaseQueryObject.java
@@ -0,0 +1,239 @@
+package com.vci.starter.web.pagemodel;
+
+
+import com.alibaba.fastjson.annotation.JSONField;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.*;
+
+/**
+ * 鏌ヨ鏉′欢 锛岀粡甯哥敤浜巆ontroller鐨勬柟娉曚腑锛岀敤浜庢帴鏀跺墠绔殑璇锋眰鍙傛暟
+ * 浜掕仈缃戜骇鍝佷笂涓嶆帹鑽愯繖鏍风殑鏂瑰紡锛屼笉鏂逛究缁存姢
+ * 浣嗘槸鍦ㄤ紶缁熻涓氬洜涓鸿�冭檻鍒版煡璇㈡潯浠惰繃澶氾紝鏌ヨ鐨勬柟寮忓鏉傚鏍峰寲锛屽洜姝ゅ缓璁娇鐢ㄨ繖绉嶆柟寮�
+ * 鍓嶇闇�瑕佷紶閫掔殑鍙傛暟鏂瑰紡搴旇涓衡�榗onditionMap['xxxx']=yyy; xxx鏄睘鎬х殑鍚嶇О锛寉yy鏄煡璇㈡潯浠剁殑鍊�
+ * 杩欎釜瀵硅薄閲屽凡缁忓寘鍚簡鍒嗛〉淇℃伅
+ */
+public class BaseQueryObject implements java.io.Serializable{
+
+	/**
+	 * 榛樿鏋勯�犲嚱鏁�
+	 */
+	public BaseQueryObject(){
+
+	}
+
+	/**
+	 * 鏋勯�犲嚱鏁帮紝娣诲姞鏌ヨ鏉′欢
+	 * @param conditionMap 鏌ヨ鏉′欢
+	 */
+	public BaseQueryObject(Map<String,String> conditionMap){
+		this.setConditionMap(conditionMap);
+	}
+
+	/**
+	 * 鏋勯�犲嚱鏁帮紝璁剧疆鍒嗛〉鏁�
+	 * @param limit 姣忛〉鏄剧ず鏈�澶ф暟
+	 */
+	public BaseQueryObject(int limit){
+		this.setLimit(limit);
+	}
+
+	/**
+	 * 鏋勯�犲嚱鏁帮紝娣诲姞鏌ヨ鏉′欢鍜屽垎椤垫暟
+	 * @param conditionMap 鏌ヨ鏉′欢
+	 * @param limit 姣忛〉鏄剧ず鏈�澶ф暟
+	 */
+	public BaseQueryObject(Map<String,String> conditionMap,int limit){
+		this.setConditionMap(conditionMap);
+		this.setLimit(limit);
+	}
+
+	/**
+	 * 绂佹淇敼杩欎釜鍊�
+	 */
+	@JSONField(serialize = false,deserialize = false)
+	private static final long serialVersionUID = 5608634730007623041L;
+	/**
+	 * 鏌ヨ鏉′欢鐨勬槧灏勫叧绯�
+	 */
+	@JSONField()
+	private Map<String,String> conditionMap = new HashMap<String, String>();
+
+	/**
+	 * 褰撳墠椤�
+	 */
+	@JSONField()
+	private int page = 1;
+	// 褰撳墠椤�
+	/**
+	 * 鎺掑簭瀛楁
+	 */
+	@JSONField()
+	private String sort;
+	// 鎺掑簭瀛楁  ---鍓嶇鍙敮鎸佷娇鐢ㄤ竴涓瓧娈垫潵鎺掑簭锛屼絾鏄悗鍙板疄闄呭彲浠ヤ娇鐢ㄥ涓瓧娈垫潵鎺掑簭锛屾墍浠ュ彲浠ヤ娇鐢ㄩ�楀彿鍒嗗壊
+	/**
+	 * 鎺掑簭绫诲瀷
+	 */
+	@JSONField()
+	private String order;
+	// asc/desc,濡傛灉鏈夊涓帓搴忓瓧娈垫椂锛岃繖閲屼篃闇�瑕佺敤閫楀彿鍒嗗壊锛屼笖涓巗ort鐨勪綅缃搴�
+
+	/**
+	 * 姣忛〉鏄剧ず椤垫暟
+	 */
+	@JSONField()
+	private int limit = 25;//姣忛〉鏄剧ず鐨勬潯鏁�
+
+	/**
+	 * 鑾峰彇鏌ヨ鏉′欢
+	 * @return 鏌ヨ鏉′欢鏄犲皠锛宬ey鏄瓧娈佃嫳鏂囧悕绉帮紝value鏄煡璇㈢殑鍊�
+	 */
+	public Map<String, String> getConditionMap() {
+		return conditionMap;
+	}
+
+	/**
+	 * 鏍规嵁鏄电О鑾峰彇鏌ヨ鏉′欢
+	 * @param nick 琛ㄦ牸鐨勬樀绉�
+	 * @return 甯︽湁.鐨勪笉娣诲姞琛ㄦ牸鏄电О
+	 */
+	public Map<String,String> getConditionMapByNick(String nick){
+		if(conditionMap!=null){
+			Map<String,String> conditionMapHasNick = new HashMap<>();
+			conditionMap.forEach( (k,v) -> {
+				if(!k.contains(".")){
+					conditionMapHasNick.put(nick + "." + k,v);
+				}else{
+					conditionMapHasNick.put(k,v);
+				}
+			});
+			return conditionMapHasNick;
+		}
+		return null;
+	}
+
+	/**
+	 * 璁剧疆鏌ヨ鏉′欢
+	 * @param conditionMap 鏌ヨ鏉′欢鐨勬槧灏勫叧绯�
+	 */
+	public void setConditionMap(Map<String, String> conditionMap) {
+		this.conditionMap = conditionMap;
+	}
+
+	public int getPage() {
+		return page;
+	}
+
+	public void setPage(int page) {
+		this.page = page;
+	}
+
+	public String getSort() {
+		return sort;
+	}
+
+	public void setSort(String sort) {
+		this.sort = sort;
+	}
+
+	public String getOrder() {
+		return order;
+	}
+
+	public void setOrder(String order) {
+		this.order = order;
+	}
+
+	public int getLimit() {
+		return limit;
+	}
+
+	public void setLimit(int limit) {
+		this.limit = limit;
+	}
+
+	/**
+	 * 鑾峰彇鏌ヨ瀵硅薄涓殑鍒嗛〉瀵硅薄
+	 * @return 鍒嗛〉瀵硅薄
+	 */
+	@JSONField(serialize = false,deserialize = false)
+	public PageHelper getPageHelper(){
+		PageHelper pageHelper = new PageHelper(limit);
+		pageHelper.setPage(getPage());
+		pageHelper.setSort(getSort());
+		pageHelper.setOrder(getOrder());
+		return pageHelper;
+	}
+
+	/**
+	 * 澧炲姞鎺掑簭
+	 * @param sort 鎺掑簭瀛楁
+	 * @param order 鎺掑簭鏂瑰紡
+	 * @return  褰撳墠瀵硅薄
+	 */
+	public BaseQueryObject addSort(String sort, String order){
+		this.setSort(StringUtils.isBlank(this.getSort())?sort:(this.getSort() + "," + sort) );
+		this.setOrder(StringUtils.isBlank(this.getOrder())?order:(this.getOrder() + "," + order));
+		return this;
+	}
+
+	/**
+	 * 澧炲姞鏌ヨ鏌ヨ鏉′欢
+	 * @param key 鏌ヨ鏉′欢
+	 * @param value 鍊�
+	 * @return  褰撳墠瀵硅薄
+	 */
+	public BaseQueryObject addCondition(String key,String value){
+		if(this.getConditionMap() == null){
+			this.conditionMap = new HashMap<>();
+		}
+		this.conditionMap.put(key,value);
+		return this;
+	}
+
+	/**
+	 * 璁剧疆鍒嗛〉鐨勪俊鎭�
+	 * @param pageHelper 鍒嗛〉瀵硅薄
+	 * @return 褰撳墠瀵硅薄
+	 */
+	public BaseQueryObject page(PageHelper pageHelper){
+		this.setSort(pageHelper.getSort());
+		this.setOrder(pageHelper.getOrder());
+		this.setPage(pageHelper.getPage());
+		this.setLimit(pageHelper.getLimit());
+		return  this;
+	}
+
+	/**
+	 * 鑾峰彇feign璇锋眰鐨勫弬鏁版槧灏勶紝涓�鑸湪get鏂规硶鐨勬椂鍊欐墠浣跨敤
+	 * @return 鏌ヨ鏉′欢锛屽垎椤靛拰鎺掑簭绛変俊鎭紝key鏄弬鏁扮殑瀵硅薄锛寁alue鏄弬鏁扮殑鍊�
+	 */
+	@JSONField(serialize = false,deserialize = false)
+	public Map<String,String> getFeignRequestMap(){
+		Map<String,String> feignRequestMap = new HashMap<>();
+		//鏌ヨ鏉′欢
+		if(this.conditionMap!=null){
+			this.getConditionMap().forEach( (k,v) -> {
+				feignRequestMap.put( "conditionMap[\"" + k + "\"]",v);
+			});
+		}
+		//鍒嗛〉
+		feignRequestMap.put("page",this.getPage() + "");
+		feignRequestMap.put("limit",this.getLimit() + "");
+		//鎺掑簭
+		feignRequestMap.put("sort",this.getSort());
+		feignRequestMap.put("order",this.getOrder());
+		return feignRequestMap;
+	}
+
+	@Override
+	public String toString() {
+		return "BaseQueryObject{" +
+				"conditionMap=" + conditionMap +
+				", page=" + page +
+				", sort='" + sort + '\'' +
+				", order='" + order + '\'' +
+				", limit=" + limit +
+				'}';
+	}
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/BaseResult.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/BaseResult.java
new file mode 100644
index 0000000..d042858
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/BaseResult.java
@@ -0,0 +1,393 @@
+package com.vci.starter.web.pagemodel;
+
+import com.vci.starter.web.enumpck.ResultCodeEnum;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+/**
+ * 缁熶竴鐨勬暟鎹繑鍥炲璞★紝淇濊瘉feign銆乺estTemplate鎴栬�呭叾浠杛est璇锋眰瀹㈡埛绔彲浠ョ粺涓�澶勭悊
+ * @author weidy
+ * @date 2019/12/3 6:57 PM
+ */
+public class BaseResult<T> implements java.io.Serializable{
+
+    /**
+     * 绂佹淇敼杩欎釜鍊�
+     */
+    private static final long serialVersionUID = 4746146117790499683L;
+
+    /**
+     * 鏄惁鎴愬姛
+     */
+    private boolean success = false;
+
+    /**
+     * 鎻愮ず淇℃伅
+     */
+    private String msg = "";
+
+    /**
+     * 鎻愮ず娑堟伅澶氳
+     */
+    private Object[] msgObjs;
+
+    /**
+     * 鍖呭惈鏁版嵁瀵硅薄
+     */
+    private T obj = null;
+
+    /**
+     * 涓氬姟缂栫爜
+     */
+    private int code = ResultCodeEnum.FAIL.code;
+
+    /**
+     * 閾捐矾鐨処D锛岀敤浜庤拷鏌ラ敊璇俊鎭�
+     */
+    private String traceId;
+
+    /**
+     * 璇锋眰閾捐矾鐨処D锛屼笉鏄棩蹇楃殑閾捐矾锛屽彲浠ョ敤浜庢帶鍒跺箓绛夋��
+     */
+    private String requestTraceId;
+
+    /**
+     * 寮傚父鐨勭被鍚嶇О
+     */
+    private String exceptionClassName;
+
+    /**
+     * 寮傚父鐨勭紪鍙�
+     */
+    private String exceptionCode;
+
+    /**
+     * 寮傚父鐨勯敊璇璞�
+     */
+    private Object[] exceptionObjs;
+
+    /**
+     * 瀹屾垚鏃堕棿
+     */
+    private long finishTime;
+
+    /**
+     * 鍒楄〃鎬绘暟,extjs鍜宔asyui浣跨敤total锛宭ayui浣跨敤count,杩欓噷缁熶竴涓簍otal,layui鍙互鍦╰able.js閲屼慨鏀规簮鐮侊紝
+     */
+    private long total = 0;
+
+    /**
+     * 鏁版嵁锛宔asyui浣跨敤鐨剅ows, extjs鍜宭ayui榛樿涓篸ata;easyui涔熷彲浠ヤ慨鏀逛负data锛屽洜姝ゅ潎浣跨敤data
+     */
+    private Collection<T> data ;
+
+    /**
+     * 鏍戠殑鏁版嵁
+     */
+    private Collection<Tree> treeData;
+
+    public Object[] getMsgObjs() {
+        return msgObjs;
+    }
+
+    public void setMsgObjs(Object[] msgObjs) {
+        this.msgObjs = msgObjs;
+    }
+
+    public boolean isSuccess() {
+        return success;
+    }
+
+    public void setSuccess(boolean success) {
+        this.success = success;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    public void setMsg(String msg) {
+        this.msg = msg;
+    }
+
+    public T getObj() {
+        return obj;
+    }
+
+    public void setObj(T obj) {
+        this.obj = obj;
+    }
+
+    public int getCode() {
+        return code;
+    }
+
+    public void setCode(int code) {
+        this.code = code;
+    }
+
+    public String getTraceId() {
+        return traceId;
+    }
+
+    public void setTraceId(String traceId) {
+        this.traceId = traceId;
+    }
+
+    public String getRequestTraceId() {
+        return requestTraceId;
+    }
+
+    public void setRequestTraceId(String requestTraceId) {
+        this.requestTraceId = requestTraceId;
+    }
+
+    public String getExceptionClassName() {
+        return exceptionClassName;
+    }
+
+    public void setExceptionClassName(String exceptionClassName) {
+        this.exceptionClassName = exceptionClassName;
+    }
+
+    public String getExceptionCode() {
+        return exceptionCode;
+    }
+
+    public void setExceptionCode(String exceptionCode) {
+        this.exceptionCode = exceptionCode;
+    }
+
+    public Object[] getExceptionObjs() {
+        return exceptionObjs;
+    }
+
+    public void setExceptionObjs(Object[] exceptionObjs) {
+        this.exceptionObjs = exceptionObjs;
+    }
+
+    public long getFinishTime() {
+        return finishTime;
+    }
+
+    public void setFinishTime(long finishTime) {
+        this.finishTime = finishTime;
+    }
+
+    public long getTotal() {
+        return total;
+    }
+
+    public void setTotal(long total) {
+        this.total = total;
+    }
+
+    public Collection<T> getData() {
+        return data;
+    }
+
+    public void setData(Collection<T> data) {
+        this.data = data;
+    }
+
+    public Collection<Tree> getTreeData() {
+        return treeData;
+    }
+
+    public void setTreeData(Collection<Tree> treeData) {
+        this.treeData = treeData;
+    }
+
+    /**
+     * 鎴愬姛锛屾病鏈変换浣曡繑鍥炰俊鎭�
+     * @return 杩斿洖缁熶竴鏁版嵁瀵硅薄
+     */
+    public static BaseResult success(){
+        return success(null);
+    }
+
+    /**
+     * 鎴愬姛锛屾湁杩斿洖鏁版嵁
+     * @param obj 杩斿洖鐨勬暟鎹�
+     * @param <T> 鏁版嵁绫诲瀷
+     * @return 杩斿洖缁熶竴鏁版嵁瀵硅薄
+     */
+    public static <T> BaseResult<T> success(T obj){
+        BaseResult<T> baseResult = new BaseResult<>();
+        baseResult.setSuccess(true);
+        baseResult.setCode(ResultCodeEnum.SUCCESS.code);
+        baseResult.setObj(obj);
+        return baseResult;
+    }
+
+    /**
+     * 鎴愬姛锛屾湁杩斿洖鏁版嵁
+     * @param obj 杩斿洖鐨勬暟鎹�
+     * @param <T> 鏁版嵁绫诲瀷
+     * @param msg 鎻愮ず淇℃伅
+     * @return 杩斿洖缁熶竴鏁版嵁瀵硅薄
+     */
+    public static <T> BaseResult<T> success(T obj,String msg){
+        BaseResult<T> baseResult = new BaseResult<>();
+        baseResult.setSuccess(true);
+        baseResult.setCode(ResultCodeEnum.SUCCESS.code);
+        baseResult.setObj(obj);
+        baseResult.setMsg(msg);
+        return baseResult;
+    }
+
+    /**
+     * 鎴愬姛锛屾湁杩斿洖鏁版嵁
+     * @param obj 杩斿洖鐨勬暟鎹�
+     * @param <T> 鏁版嵁绫诲瀷
+     * @param msg 鎻愮ず淇℃伅
+     * @param msgObjs 鐢ㄤ簬鏍煎紡鍖栨秷鎭敤鐨勫璞�
+     * @return 杩斿洖缁熶竴鏁版嵁瀵硅薄
+     */
+    public static <T> BaseResult<T> success(T obj,String msg,Object...msgObjs){
+        BaseResult<T> baseResult = new BaseResult<>();
+        baseResult.setSuccess(true);
+        baseResult.setCode(ResultCodeEnum.SUCCESS.code);
+        baseResult.setObj(obj);
+        baseResult.setMsg(msg);
+        return baseResult;
+    }
+
+    /**
+     * 鎴愬姛锛岃�屼笖鏈夋彁绀轰俊鎭�
+     * @param msg 鎻愮ず淇℃伅
+     * @return 杩斿洖缁熶竴鏁版嵁瀵硅薄
+     */
+    public static BaseResult successMsg(String msg){
+        BaseResult baseResult = new BaseResult();
+        baseResult.setSuccess(true);
+        baseResult.setCode(ResultCodeEnum.SUCCESS.code);
+        baseResult.setMsg(msg);
+        return baseResult;
+    }
+
+    /**
+     * 鎴愬姛锛岃�屼笖鏈夋彁绀轰俊鎭�
+     * @param msg 鎻愮ず淇℃伅
+     * @param msgObjs 鐢ㄤ簬鏍煎紡鍖栨秷鎭敤鐨勫璞�
+     * @return 杩斿洖缁熶竴鏁版嵁瀵硅薄
+     */
+    public static BaseResult successMsg(String msg,Object...msgObjs){
+        BaseResult baseResult = new BaseResult();
+        baseResult.setSuccess(true);
+        baseResult.setCode(ResultCodeEnum.SUCCESS.code);
+        baseResult.setMsg(msg);
+        baseResult.setMsgObjs(msgObjs);
+        return baseResult;
+    }
+
+    /**
+     * 澶辫触锛屽寘鍚敊璇俊鎭�
+     * @param msg 娑堟伅鍐呭
+     * @return 杩斿洖缁熶竴鏁版嵁瀵硅薄
+     */
+    public static BaseResult fail(String msg){
+        return makeResult(ResultCodeEnum.FAIL.code,msg,null);
+    }
+
+    /**
+     * 澶辫触锛屽寘鍚敊璇俊鎭�,涓斿寘鍚敤浜庢牸寮忓寲娑堟伅鐢ㄧ殑瀵硅薄
+     * @param msg 娑堟伅鍐呭
+     * @param msgObjs  鐢ㄤ簬鏍煎紡鍖栨秷鎭敤鐨勫璞�
+     * @return 杩斿洖缁熶竴鏁版嵁瀵硅薄
+     */
+    public static BaseResult fail(String msg,Object...msgObjs){
+        BaseResult baseResult = makeResult(ResultCodeEnum.FAIL.code,msg,null);
+        baseResult.setMsgObjs(msgObjs);
+        return baseResult;
+    }
+
+    /**
+     * 閿欒锛屽寘鍚敊璇俊鎭�
+     * @param msg 閿欒娑堟伅
+     * @return 杩斿洖缁熶竴鏁版嵁瀵硅薄
+     */
+    public static BaseResult error(String msg){
+        return makeResult(ResultCodeEnum.INTERNAL_SERVER_ERROR.code,msg,null);
+    }
+
+    /**
+     * 鍒涘缓杩斿洖瀵硅薄
+     * @param code 鐘舵�佺爜
+     * @param msg 閿欒娑堟伅
+     * @param obj 鏁版嵁瀵硅薄
+     * @param <T> 鏁版嵁瀵硅薄鐨勬墍灞炵被鍨�
+     * @return 缁熶竴鏁版嵁瀵硅薄
+     */
+    public static <T> BaseResult<T> makeResult(int code,String msg,T obj){
+        BaseResult<T> baseResult = new BaseResult<>();
+        baseResult.setSuccess(false);
+        baseResult.setCode(code);
+        baseResult.setMsg(msg);
+        baseResult.setObj(obj);
+        return baseResult;
+    }
+
+    /**
+     * 鏍规嵁鍒楄〃鑾峰彇缁熶竴鏁版嵁瀵硅薄
+     * @param dataGrid 鍒楄〃鏁版嵁
+     * @param <T> 鍒楄〃鐨勫厓绱犵被鍨�
+     * @return 缁熶竴鏁版嵁瀵硅薄
+     */
+    public static <T> BaseResult<T> dataGrid(DataGrid<T> dataGrid){
+        BaseResult<T> baseResult = new BaseResult<>();
+        if(dataGrid ==null){
+            baseResult.setCode(ResultCodeEnum.SUCCESS.code);
+            baseResult.setSuccess(true);
+        }else{
+            if(StringUtils.isNotBlank(dataGrid.getMsg())){
+                baseResult.setCode(ResultCodeEnum.FAIL.code);
+                baseResult.setSuccess(false);
+                baseResult.setMsg(dataGrid.getMsg());
+            }else{
+                baseResult.setCode(ResultCodeEnum.SUCCESS.code);
+                baseResult.setSuccess(true);
+                baseResult.setData(dataGrid.getData());
+                baseResult.setTotal(dataGrid.getTotal());
+            }
+        }
+        return baseResult;
+    }
+
+
+
+    /**
+     * 鏍规嵁鍒楄〃鑾峰彇缁熶竴鏁版嵁瀵硅薄
+     * @param treeList 鏍戣妭鐐归泦鍚�
+     * @return 缁熶竴鏁版嵁瀵硅薄
+     */
+    public static BaseResult tree(Collection<Tree> treeList){
+        BaseResult baseResult = new BaseResult<>();
+        baseResult.setCode(ResultCodeEnum.SUCCESS.code);
+        baseResult.setSuccess(true);
+        baseResult.setTreeData(treeList);
+        return baseResult;
+    }
+
+
+    @Override
+    public String toString() {
+        return "BaseResult{" +
+                "success=" + success +
+                ", msg='" + msg + '\'' +
+                ", obj=" + obj +
+                ", code='" + code + '\'' +
+                ", traceId='" + traceId + '\'' +
+                ", requestTraceId='" + requestTraceId + '\'' +
+                ", exceptionClassName='" + exceptionClassName + '\'' +
+                ", exceptionCode='" + exceptionCode + '\'' +
+                ", exceptionObjs=" + Arrays.toString(exceptionObjs) +
+                ", finishTime=" + finishTime +
+                ", total=" + total +
+                ", data=" + data +
+                ", treeData=" + treeData +
+                '}';
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/DataGrid.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/DataGrid.java
new file mode 100644
index 0000000..fe71df6
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/DataGrid.java
@@ -0,0 +1,177 @@
+package com.vci.starter.web.pagemodel;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 鍒楄〃杩斿洖鏁版嵁妯″瀷
+ * 
+ * @author weidy
+ * 
+ */
+
+public class DataGrid<T> implements java.io.Serializable {
+	/**
+	 * 绂佹淇敼杩欎釜鍊�
+	 * @serial
+	 */
+	private static final long serialVersionUID = -5909212697362510055L;
+
+	/**
+	 * 鏋勯�犲嚱鏁�
+	 */
+	public DataGrid(){
+		
+	}
+
+	/**
+	 * 鏋勯�犲嚱鏁�
+	 * @param msg 娑堟伅
+	 */
+	public DataGrid(String msg){
+		this.msg = msg;
+		this.code = 1;
+	}
+
+
+	/**
+	 * 鎬绘暟,extjs鍜宔asyui浣跨敤total锛宭ayui浣跨敤count,杩欓噷缁熶竴涓簍otal,layui鍙互鍦╰able.js閲屼慨鏀规簮鐮侊紝
+	 */
+	private long total = 0;
+	/**
+	 * 鏁版嵁锛宔asyui浣跨敤鐨剅ows, extjs鍜宭ayui榛樿涓篸ata;easyui涔熷彲浠ヤ慨鏀逛负data锛屽洜姝ゅ潎浣跨敤data
+	 */
+	private List<T> data = new ArrayList<T>();
+	/**
+	 * 鏁版嵁寮�濮嬬殑浣嶇疆
+	 */
+	private int start;
+	/**
+	 * 姣忛〉鏄剧ず澶氬皯琛�
+	 */
+	private int limit;
+	/**
+	 * 褰撳墠椤垫暟
+	 */
+	private int page;
+	/**
+	 * 鎺掑簭瀛楁
+	 */
+	private String sort;
+	/**
+	 * 鎺掑簭鏂瑰紡
+	 */
+	private String order;
+	
+	/**
+	 * 杩斿洖缁欏墠绔殑娑堟伅锛�
+	 */
+	private String msg;
+	
+	/**
+	 * 瀹屾垚鐘舵�侊紝layui蹇呴』浣跨敤杩欎釜鐘舵�佹潵鍒ゆ柇鏄惁鎵ц鎴愬姛锛宔xtjs鍜宔asyui鍙互涓嶇敤锛屽洜姝ら粯璁よ繖涓�间负0锛堣〃绀烘垚鍔燂級;
+	 * 浣嗘槸easyui鍜宔xtjs鍙互浣跨敤code鏉ヤ紶閫掔壒娈婄殑鏁版嵁
+	 */
+	private int code = 0;
+
+	/**
+	 * 閾捐矾鐨刬d锛岀敤浜庤拷鏌ユ棩蹇椾俊鎭�
+	 */
+	private String traceId;
+
+	public long getTotal() {
+		return total;
+	}
+
+	public void setTotal(long total) {
+		this.total = total;
+	}
+
+	public List<T> getData() {
+		return data;
+	}
+
+	public void setData(List<T> data) {
+		this.data = data;
+	}
+
+	public int getStart() {
+		return start;
+	}
+
+	public void setStart(int start) {
+		this.start = start;
+	}
+
+	public int getLimit() {
+		return limit;
+	}
+
+	public void setLimit(int limit) {
+		this.limit = limit;
+	}
+
+	public int getPage() {
+		return page;
+	}
+
+	public void setPage(int page) {
+		this.page = page;
+	}
+
+	public String getSort() {
+		return sort;
+	}
+
+	public void setSort(String sort) {
+		this.sort = sort;
+	}
+
+	public String getOrder() {
+		return order;
+	}
+
+	public void setOrder(String order) {
+		this.order = order;
+	}
+
+	public String getMsg() {
+		return msg;
+	}
+
+	public void setMsg(String msg) {
+		this.msg = msg;
+	}
+
+	public int getCode() {
+		return code;
+	}
+
+	public void setCode(int code) {
+		this.code = code;
+	}
+
+	public String getTraceId() {
+		return traceId;
+	}
+
+	public void setTraceId(String traceId) {
+		this.traceId = traceId;
+	}
+
+	@Override
+	public String toString() {
+		return "DataGrid{" +
+				"total=" + total +
+				", data=" + data +
+				", start=" + start +
+				", limit=" + limit +
+				", page=" + page +
+				", sort='" + sort + '\'' +
+				", order='" + order + '\'' +
+				", msg='" + msg + '\'' +
+				", code=" + code +
+				", traceId='" + traceId + '\'' +
+				'}';
+	}
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/ImportResult.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/ImportResult.java
new file mode 100644
index 0000000..07ae878
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/ImportResult.java
@@ -0,0 +1,163 @@
+package com.vci.starter.web.pagemodel;
+
+
+/**
+ * excel瀵煎叆缁撴灉
+ * @author weidy
+ */
+public class ImportResult implements java.io.Serializable {
+
+    /**
+     * 绂佹淇敼杩欎釜鍊�
+     */
+    private static final long serialVersionUID = 9043151147701785650L;
+    /**
+     * 鏂板鏁版嵁涓暟
+     */
+    private int addCount;
+
+    /**
+     * 淇敼鏁版嵁鐨勪釜鏁�
+     */
+    private int editCount;
+
+    /**
+     * 鍒犻櫎鏁版嵁鐨勪釜鏁�
+     */
+    private int deleteCount;
+
+    /**
+     * 蹇界暐鏁版嵁鐨勪釜鏁�
+     */
+    private int unDoCount;
+
+    /**
+     * 鏄惁鎴愬姛
+     */
+    private boolean success;
+
+    /**
+     * 閿欒淇℃伅
+     */
+    private String msg;
+
+    /**
+     * 杩斿洖缁撴灉浠e彿
+     */
+    private String resultCode;
+
+    /**
+     * 杩斿洖缁撴灉瀵硅薄
+     */
+    private Object returnObj;
+
+    /**
+     * 閾捐矾鐨処D
+     */
+    private String traceId;
+
+    /**
+     * 鏋勯�犳柟娉�
+     * @param msg 娑堟伅
+     */
+    public ImportResult(String msg){
+        this.success = false;
+        this.msg = msg;
+    }
+
+    /**
+     * 鏋勯�犳柟娉�
+     * @param success 鏄惁鎴愬姛
+     */
+    public ImportResult(boolean success){
+        this.success = success;
+    }
+
+    public int getAddCount() {
+        return addCount;
+    }
+
+    public void setAddCount(int addCount) {
+        this.addCount = addCount;
+    }
+
+    public int getEditCount() {
+        return editCount;
+    }
+
+    public void setEditCount(int editCount) {
+        this.editCount = editCount;
+    }
+
+    public int getDeleteCount() {
+        return deleteCount;
+    }
+
+    public void setDeleteCount(int deleteCount) {
+        this.deleteCount = deleteCount;
+    }
+
+    public int getUnDoCount() {
+        return unDoCount;
+    }
+
+    public void setUnDoCount(int unDoCount) {
+        this.unDoCount = unDoCount;
+    }
+
+    public boolean isSuccess() {
+        return success;
+    }
+
+    public void setSuccess(boolean success) {
+        this.success = success;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    public void setMsg(String msg) {
+        this.msg = msg;
+    }
+
+    public String getResultCode() {
+        return resultCode;
+    }
+
+    public void setResultCode(String resultCode) {
+        this.resultCode = resultCode;
+    }
+
+    public Object getReturnObj() {
+        return returnObj;
+    }
+
+    public void setReturnObj(Object returnObj) {
+        this.returnObj = returnObj;
+    }
+
+
+    public String getTraceId() {
+        return traceId;
+    }
+
+    public void setTraceId(String traceId) {
+        this.traceId = traceId;
+    }
+
+    @Override
+    public String toString() {
+        return "ImportResult{" +
+                "addCount=" + addCount +
+                ", editCount=" + editCount +
+                ", deleteCount=" + deleteCount +
+                ", unDoCount=" + unDoCount +
+                ", success=" + success +
+                ", msg='" + msg + '\'' +
+                ", resultCode='" + resultCode + '\'' +
+                ", returnObj=" + returnObj +
+                ", traceId='" + traceId + '\'' +
+                '}';
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/KeyValue.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/KeyValue.java
new file mode 100644
index 0000000..f183016
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/KeyValue.java
@@ -0,0 +1,68 @@
+package com.vci.starter.web.pagemodel;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 閿�煎
+ * @author weidy
+ */
+public class KeyValue implements java.io.Serializable {
+
+	/**
+	 * 绂佹淇敼杩欎釜鍊�
+	 */
+	private static final long serialVersionUID = 7708882804529442626L;
+
+	/**
+	 * 閿�
+	 */
+	private String key;
+
+	/**
+	 * 鍊�
+	 */
+	private String value;
+
+	/**
+	 * 鍏朵粬灞炴��
+	 */
+	private Map<String,Object> attributes = new HashMap<String, Object>();
+			
+	public String getKey() {
+		return key;
+	}
+
+	public void setKey(String key) {
+		this.key = key;
+	}
+
+	public String getValue() {
+		return value;
+	}
+
+	public void setValue(String value) {
+		this.value = value;
+	}
+
+	public Map<String, Object> getAttributes() {
+		return attributes;
+	}
+
+	public void setAttributes(Map<String, Object> attributes) {
+		this.attributes = attributes;
+	} 
+	
+	public void addAttr(String attr, Object attrValue){
+		this.attributes.put(attr, attrValue);
+	}
+
+	@Override
+	public String toString() {
+		return "KeyValue{" +
+				"key='" + key + '\'' +
+				", value='" + value + '\'' +
+				", attributes=" + attributes +
+				'}';
+	}
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/PageHelper.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/PageHelper.java
new file mode 100644
index 0000000..7470f76
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/PageHelper.java
@@ -0,0 +1,416 @@
+package com.vci.starter.web.pagemodel;
+
+
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * ExtJs锛宔asyui,layui 鍒嗛〉甯姪绫�
+ * 
+ * @author weidy
+ * 
+ */
+public class PageHelper implements java.io.Serializable {
+	/**
+	 * 搴忓垪鍖�
+	 */
+	private static final long serialVersionUID = -588765760880887850L;
+	/**
+	 * 褰撳墠椤�
+	 */
+	private int page;
+	// 褰撳墠椤�
+	/**
+	 * 鎺掑簭瀛楁
+	 */
+	private String sort;
+	// 鎺掑簭瀛楁  ---鍓嶇鍙敮鎸佷娇鐢ㄤ竴涓瓧娈垫潵鎺掑簭锛屼絾鏄悗鍙板疄闄呭彲浠ヤ娇鐢ㄥ涓瓧娈垫潵鎺掑簭锛屾墍浠ュ彲浠ヤ娇鐢ㄩ�楀彿鍒嗗壊
+	/**
+	 * 鎺掑簭绫诲瀷
+	 */
+	private String order;
+	// asc/desc,濡傛灉鏈夊涓帓搴忓瓧娈垫椂锛岃繖閲屼篃闇�瑕佺敤閫楀彿鍒嗗壊锛屼笖涓巗ort鐨勪綅缃搴�
+	/**
+	 * 璧峰鏁版嵁琛屾暟
+	 */
+	private int start = 0;
+	/**
+	 * 姣忛〉鏄剧ず椤垫暟
+	 */
+	private int limit = 25;
+	//姣忛〉鏄剧ず鐨勬潯鏁�
+	
+    /**
+     * 鏄惁瑕佹敮鎸佹樉绀烘�婚〉鏁板拰鎬绘潯鏁�----鍦ㄦ暟鎹噺宸ㄥぇ鐨勬儏鍐典笅锛屽彲浠ヤ笉鏌ヨ鎬绘暟
+     */
+	private boolean queryTotal = true;
+
+	/**
+	 * 鎺掑簭鐨凷QL
+	 */
+	private String ordersql ;
+
+	/**
+	 * 琛ㄧ殑鏄电О
+	 */
+	private String nick;
+
+	/**
+	 * 鍗囧簭
+	 */
+	public final String asc = "asc";
+
+	/**
+	 * 闄嶅簭
+	 */
+	public final String desc = "desc";
+	/**
+	 * 涓嶄娇鐢ㄨ〃鏄电О鐨勫瓧娈�
+	 */
+	private Set<String> unNickField = new HashSet<>();
+
+	/**
+	 * 榛樿鏋勯�犲嚱鏁�
+	 */
+	public PageHelper(){
+
+	}
+
+	/**
+	 * 鏋勯�犲嚱鏁帮紝璁剧疆鍒嗛〉鏁�
+	 * @param limit 鍒嗛〉鏁�
+	 */
+	public PageHelper(int limit){
+		this.limit = limit;
+		this.page = 1;
+	}
+
+	/**
+	 * 鏋勯�犲嚱鏁帮紝璁剧疆鍒嗛〉鏁板拰鏄惁鏌ヨ鎬绘暟
+	 * @param limit 鍒嗛〉鏁�
+	 * @param queryTotal 鏌ヨ鎬绘暟
+	 */
+	public PageHelper(int limit,boolean queryTotal){
+		this.limit = limit;
+		this.queryTotal = queryTotal;
+	}
+
+	/**
+	 * 鏋勯�犲嚱鏁帮紝杩欑鍗囧簭鐨勬帓搴忓瓧娈�
+	 * @param sort 鍗囧簭鐨勫瓧娈�
+	 */
+	public PageHelper(String sort){
+		this.sort = sort;
+		this.limit = -1;
+		this.order = "asc";
+	}
+
+	/**
+	 * 鏋勯�犲嚱鏁帮紝璁剧疆鎺掑簭瀛楁鍜屾帓搴忔柟寮�
+	 * @param sort 鎺掑簭瀛楁
+	 * @param order 鎺掑簭鏂瑰紡
+	 */
+	public PageHelper(String sort, String order){
+		this.sort = sort;
+		this.limit = -1;
+		this.order = order;
+	}
+
+	/**
+	 * 鏋勯�犲嚱鏁帮紝璁剧疆鍒嗛〉锛屾帓搴忓瓧娈靛拰鎺掑簭鏂瑰紡
+	 * @param limit 鍒嗛〉鏁�
+	 * @param sort 鎺掑簭瀛楁
+	 * @param order 鎺掑簭鏂瑰紡
+	 */
+	public PageHelper(int limit, String sort, String order){
+		this.limit = limit;
+		this.sort = sort;
+		this.order = order;
+	}
+
+	/**
+	 * 鏋勯�犲嚱鏁帮紝璁剧疆鍒嗛〉锛屾帓搴忓瓧娈靛拰鎺掑簭鏂瑰紡
+	 * @param limit 鍒嗛〉鏁�
+	 * @param page 褰撳墠椤�
+	 * @param sort 鎺掑簭瀛楁
+	 * @param order 鎺掑簭鏂瑰紡
+	 */
+	public PageHelper(int limit, int page, String sort, String order){
+		this.limit = limit;
+		this.page = page;
+		this.sort = sort;
+		this.order = order;
+	}
+
+	/**
+	 * 鑾峰彇褰撳墠椤�
+	 * @return 褰撳墠椤垫暟
+	 */
+	public int getPage() {
+		return page;
+	}
+
+	/**
+	 * 璁剧疆褰撳墠椤碉紝浼氳嚜鍔ㄨ绠楁暟鎹捣濮嬭鏁�
+	 * @param page 褰撳墠椤�
+	 */
+	public void setPage(int page) {
+		this.page = page;
+		if(page>0&&this.limit>0){
+			start = (this.page-1)*this.limit;
+		}
+	}
+
+	/**
+	 * 璁剧疆鎺掑簭瀛楁
+	 * @param sort 鎺掑簭瀛楁
+	 */
+	public void setSort(String sort) {
+		this.sort = sort;
+	}
+
+	/**
+	 * 鑾峰彇鎺掑簭鏂瑰紡
+	 * @return 鎺掑簭鏂瑰紡
+	 */
+	public String getOrder() {
+		return order;
+	}
+
+	/**
+	 * 璁剧疆鎺掑簭鏂瑰紡
+	 * @param order 鎺掑簭鏂瑰紡
+	 */
+	public void setOrder(String order) {
+		this.order = order;
+	}
+
+	/**
+	 * 鑾峰彇璧峰鏁�
+	 * @return 琛岃捣濮嬫暟
+	 */
+	public int getStart() {
+		if(this.limit <=0){
+			return 0;
+		}else{
+			return (this.page-1)*this.limit + 1;
+		}
+	}
+
+	/**
+	 * 鏄惁鏌ヨ鎬绘暟
+	 * @return true琛ㄧず鏌ヨ锛岄粯璁や负true
+	 */
+	public boolean isQueryTotal() {
+		return queryTotal;
+	}
+
+	/**
+	 * 鏄惁鏌ヨ鎬绘暟
+	 * @param queryTotal 鏄惁鏌ヨ鎬绘暟
+	 */
+	public void setQueryTotal(boolean queryTotal) {
+		this.queryTotal = queryTotal;
+	}
+
+	/**
+	 * 鑾峰彇姣忛〉鏄剧ず澶氬皯琛�
+	 * @return 姣忛〉鏄剧ず琛屾暟
+	 */
+	public int getLimit() {
+		return limit;
+	}
+
+	/**
+	 * 璁剧疆姣忛〉鏄剧ず琛屾暟
+	 * @param limit 姣忛〉鏄剧ず琛屾暟
+	 */
+	public void setLimit(int limit) {
+		this.limit = limit;
+		if(page>0&&this.limit>0){
+			start = (this.page-1)*this.limit + 1;
+		}
+	}
+
+	/**
+	 * 澧炲姞鎺掑簭
+	 * @param sort 鎺掑簭瀛楁
+	 * @param order 鎺掑簭鏂瑰紡
+	 */
+	public void addSort(String sort, String order){
+		this.setSort(StringUtils.isBlank(this.getSort())?sort:(this.getSort() + "," + sort) );
+		this.setOrder(StringUtils.isBlank(this.getOrder())?order:(this.getOrder() + "," + order));
+	}
+
+	/**
+	 * 澧炲姞鍗囧簭
+	 * @param field 鍗囧簭鐨勫瓧娈�
+	 */
+	public void addAsc(String field){
+		this.addSort(field,asc);
+	}
+
+	/**
+	 * 鍦ㄦ病鏈夋帓搴忕殑鏃跺�欐墠娣诲姞榛樿鐨勫崌搴忔帓鍒楀瓧娈�
+	 * @param field 榛樿鐨勫崌搴忕殑瀛楁
+	 */
+	public void addDefaultAsc(String field){
+		if(StringUtils.isBlank(this.getSort()) && StringUtils.isBlank(this.getOrder())){
+			this.addAsc(field);
+		}
+	}
+
+	/**
+	 * 鍦ㄦ病鏈夋帓搴忕殑鏃跺�欐墠娣诲姞榛樿鐨勯檷搴忔帓鍒楀瓧娈�
+	 * @param field 榛樿鐨勯檷搴忕殑瀛楁
+	 */
+	public void addDefaultDesc(String field){
+		if(StringUtils.isBlank(this.getSort()) && StringUtils.isBlank(this.getOrder())){
+			this.addDesc(field);
+		}
+	}
+
+	/**
+	 * 澧炲姞闄嶅簭
+	 * @param field 闄嶅簭鐨勫瓧娈�
+	 */
+	public void addDesc(String field){
+		this.addSort(field,desc);
+	}
+
+	/**
+	 * 鑾峰彇鎺掑簭瀛楁
+	 * @return 鎺掑簭瀛楁
+	 */
+	public String getSort() {
+		return sort;
+	}
+
+	/**
+	 * 璁剧疆璧峰鏁�
+	 * @param start 璧峰鏁�
+	 */
+	public void setStart(int start) {
+		this.start = start;
+	}
+
+	/**
+	 * 鑾峰彇鎺掑簭鐨凷QL璇彞锛屽湪Hibernate閲屼娇鐢�
+	 * @return 鎺掑簭鐨凷QL
+	 */
+	public String getOrdersql() {
+		if(ordersql == null || ordersql.trim().length() == 0){
+			if(sort !=null && sort.trim().length() >0  && order !=null && order.trim().length() > 0){
+				if(sort.indexOf(",") > -1){
+					String[] sortArray = sort.split(",");
+					String[] orderArray = order.split(",");
+					StringBuilder sb = new StringBuilder();
+					for(int i = 0 ; i < sortArray.length ; i ++){
+						if(StringUtils.isNotBlank(sortArray[i])
+								&& orderArray.length > i
+								&& StringUtils.isNotBlank(orderArray[i])) {
+							if(sortArray[i].indexOf(".")<0) {
+								//涓嶆槸鍙傜収
+								if(!unNickField.contains(sortArray[i].toLowerCase())) {
+									sb.append(StringUtils.isBlank(this.getNick()) ? "" : (this.getNick() + "."));
+								}
+							}
+							sb.append(sortArray[i].toLowerCase());
+							sb.append(" ");
+							sb.append(orderArray[i]);
+							sb.append(",");
+						}
+					}
+					ordersql = " order by " + sb.toString();
+					if(ordersql.endsWith(",")){
+						ordersql = ordersql.substring(0,ordersql.length()-1);
+					}
+				}else {
+					ordersql = " order by " + sort + " " + order;
+				}
+			}
+		}
+		return ordersql;
+	}
+
+	/**
+	 * 鑾峰彇鎺掑簭鐨凷QL璇彞锛屽湪Hibernate閲屼娇鐢�
+	 * @param nick 鏄电О
+	 * @return 鎺掑簭鐨凷QL
+	 */
+	public String getOrderSql(String nick){
+		if(ordersql == null || ordersql.trim().length() == 0){
+			if(sort !=null && sort.trim().length() >0  && order !=null && order.trim().length() > 0){
+				if(sort.indexOf(",") > -1){
+					String[] sortArray = sort.split(",");
+					String[] orderArray = order.split(",");
+					StringBuilder sb = new StringBuilder();
+					for(int i = 0 ; i < sortArray.length ; i ++){
+						if(StringUtils.isNotBlank(sortArray[i])
+								&& orderArray.length > i
+								&& StringUtils.isNotBlank(orderArray[i])) {
+							if(sortArray[i].indexOf(".")<0) {
+								//涓嶆槸鍙傜収
+								sb.append(StringUtils.isBlank(nick) ? "" : (nick + "."));
+							}
+							sb.append(sortArray[i].toLowerCase());
+							sb.append(" ");
+							sb.append(orderArray[i]);
+							sb.append(",");
+						}
+					}
+					ordersql = " order by " + sb.toString();
+					if(ordersql.endsWith(",")){
+						ordersql = ordersql.substring(0,ordersql.length()-1);
+					}
+				}else {
+					ordersql = " order by " + nick + "." + sort + " " + order;
+				}
+			}
+		}
+		return ordersql;
+	}
+
+	public String getNick() {
+		return nick;
+	}
+
+	public void setNick(String nick) {
+		this.nick = nick;
+	}
+
+	/**
+	 * 璁剧疆鎺掑簭鐨勫瓧娈�
+	 * @param ordersql 鎺掑簭瀛楁
+	 */
+	public void setOrdersql(String ordersql) {
+		this.ordersql = ordersql;
+	}
+
+	@Override
+	public String toString() {
+		return "PageHelper{" +
+				"page=" + page +
+				", sort='" + sort + '\'' +
+				", order='" + order + '\'' +
+				", start=" + start +
+				", limit=" + limit +
+				", queryTotal=" + queryTotal +
+				", ordersql='" + ordersql + '\'' +
+				", nick='" + nick + '\'' +
+				", asc='" + asc + '\'' +
+				", desc='" + desc + '\'' +
+				", unNickField=" + unNickField +
+				'}';
+	}
+
+	public Set<String> getUnNickField() {
+		return unNickField;
+	}
+
+	public void setUnNickField(Set<String> unNickField) {
+		this.unNickField = unNickField;
+	}
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/RequestClientInfo.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/RequestClientInfo.java
new file mode 100644
index 0000000..3d75a4b
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/RequestClientInfo.java
@@ -0,0 +1,131 @@
+package com.vci.starter.web.pagemodel;
+
+/**
+ * 瀹㈡埛绔姹備俊鎭�
+ * @author weidy
+ */
+public class RequestClientInfo implements java.io.Serializable{
+
+	/**
+	 * 绂佹淇敼杩欎釜
+	 */
+	private static final long serialVersionUID = -2574607667597721739L;
+
+	/**
+	 * 璇锋眰璁块棶鏂瑰紡锛屾祻瑙堝櫒锛孉PP锛寃ap锛�
+	 */
+	private String requestType = "browser";
+
+	/**
+	 * 娴忚鍣ㄦ柟寮�
+	 */
+	private String browser = "";
+
+	/**
+	 * 娴忚鍣ㄧ殑鐗堟湰
+	 */
+	private String browserversion = "";
+
+	/**
+	 * 绯荤粺鐨勭増鏈�
+	 */
+	private String osversion = "";
+
+	/**
+	 * ip鍦板潃
+	 */
+	private String ipaddress = "";
+
+	/**
+	 * 鏄惁鍗曠偣鐧诲綍
+	 */
+	private boolean sso;
+
+	/**
+	 * 鍗曠偣鐧诲綍鐨勫悕绉�
+	 */
+	private String ssoSystemName;
+
+	/**
+	 * 鍗曠偣鐧诲綍鐨則oken
+	 */
+	private String ssoToken;
+
+	public String getRequestType() {
+		return requestType;
+	}
+
+	public void setRequestType(String requestType) {
+		this.requestType = requestType;
+	}
+
+	public String getBrowser() {
+		return browser;
+	}
+
+	public void setBrowser(String browser) {
+		this.browser = browser;
+	}
+
+	public String getBrowserversion() {
+		return browserversion;
+	}
+
+	public void setBrowserversion(String browserversion) {
+		this.browserversion = browserversion;
+	}
+
+	public String getOsversion() {
+		return osversion;
+	}
+
+	public void setOsversion(String osversion) {
+		this.osversion = osversion;
+	}
+
+	public String getIpaddress() {
+		return ipaddress;
+	}
+
+	public void setIpaddress(String ipaddress) {
+		this.ipaddress = ipaddress;
+	}
+
+	public boolean isSso() {
+		return sso;
+	}
+
+	public void setSso(boolean sso) {
+		this.sso = sso;
+	}
+
+	public String getSsoSystemName() {
+		return ssoSystemName;
+	}
+
+	public void setSsoSystemName(String ssoSystemName) {
+		this.ssoSystemName = ssoSystemName;
+	}
+
+	public String getSsoToken() {
+		return ssoToken;
+	}
+
+	public void setSsoToken(String ssoToken) {
+		this.ssoToken = ssoToken;
+	}
+
+	@Override
+	public String toString() {
+		return "RequestClientInfo{" +
+				"requestType='" + requestType + '\'' +
+				", browser='" + browser + '\'' +
+				", browserversion='" + browserversion + '\'' +
+				", osversion='" + osversion + '\'' +
+				", ipaddress='" + ipaddress + '\'' +
+				", sso=" + sso +
+				", ssoSystemName='" + ssoSystemName + '\'' +
+				", ssoToken='" + ssoToken + '\'' +
+				'}';
+	}
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/SessionInfo.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/SessionInfo.java
new file mode 100644
index 0000000..9147094
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/SessionInfo.java
@@ -0,0 +1,669 @@
+package com.vci.starter.web.pagemodel;
+
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * session淇℃伅妯″瀷
+ * 
+ * @author weidy
+ * 
+ */
+public class SessionInfo implements java.io.Serializable {
+
+	/**
+	 *  绂佹淇敼杩欎釜鍊�
+	 *  @serial
+	 */
+	private static final long serialVersionUID = 7950268190988911233L;
+	/**
+	 * 鐢ㄦ埛鎵�灞炵粍缁囦富閿�
+	 */
+	private String orgsOid;
+	/**
+	 * 鐢ㄦ埛鎵�灞炵粍缁囧悕绉�
+	 */
+	private String orgsName;
+	/**
+	 * 鎵�灞為儴闂ㄤ富閿�
+	 */
+	private String deptOid;
+	/**
+	 * 鎵�灞為儴闂ㄥ悕绉�
+	 */
+	private String deptName;
+	/**
+	 * 鎵�灞炵敤鎴蜂富閿�
+	 */
+	private String userOid;
+	/**
+	 * 鐢ㄦ埛鍚�
+	 */
+	private String userId;
+	/**
+	 * 濮撳悕
+	 */
+	private String userName;
+
+	/**
+	 * 鐢ㄦ埛韬唤涓婚敭
+	 */
+	private String personOid;
+
+	/**
+	 * 韬唤缂栧彿锛堜汉鍛橈級
+	 */
+	private String personId;
+
+	/**
+	 * 鐢ㄦ埛韬唤鍚嶇О
+	 */
+	private String personName;
+
+	/**
+	 * 鎵�灞炶亴鍔�
+	 */
+	private String dutyOid;
+
+	/**
+	 * 鎵�灞炶亴鍔″悕绉�
+	 */
+	private String dutyName;
+	/**
+	 * 鎵�灞炰汉鍛樼粍
+	 */
+	private String workgroupOid;
+	/**
+	 * 鎵�灞炰汉鍛樼粍鍚嶇О
+	 */
+	private String workgroupName;
+
+	/**
+	 * 鎵�灞炲伐绉�
+	 */
+	private String workTypeOid;
+
+	/**
+	 * 鎵�灞炲伐绉嶅悕绉�
+	 */
+	private String workTypeName;
+	/**
+	 * 鐢ㄦ埛绫诲瀷
+	 */
+	private String usertype;
+	/**
+	 * 鐢ㄦ埛绫诲瀷鏂囨湰
+	 */
+	private String usertypeText;
+	/**
+	 * 鎬у埆
+	 */
+	private String sex;
+	/**
+	 * 鎬у埆鍚嶇О
+	 */
+	private String sexText;
+	/**
+	 * 瑙掕壊鍚嶇О
+	 */
+	private Map<String,String> rolesName;
+	/**
+	 * 鎵�鏈夌殑鏉冮檺鍔熻兘涓婚敭
+	 */
+	private List<String> functionOids;//褰撳墠鐢ㄦ埛鐨勬墍鏈夌殑鏉冮檺鐨勪富閿�
+
+	/**
+	 * 鎵�鏈夌殑鏉冮檺鍔熻兘鎿嶄綔
+	 */
+	private Map<String, Integer> functionOperaMap;
+
+	/**
+	 * 澶村儚鍦板潃
+	 */
+	private String photoUrl;
+
+	/**
+	 * IP鍦板潃
+	 */
+	private String ip;//ip鍦板潃
+	/**
+	 * 璇█
+	 */
+	private String language;//璇
+
+	/**
+	 * 鐢ㄦ埛瀵嗙骇
+	 */
+	private String userSecret;
+
+	/**
+	 * 鐢ㄦ埛瀵嗙骇鏂囨湰
+	 */
+	private String userSecretText;
+
+	/**
+	 * ip瀵嗙骇
+	 */
+	private String ipSecret;
+
+	/**
+	 * ip瀵嗙骇鏂囨湰
+	 */
+	private String ipSecretText;
+
+	/**
+	 * 鐧诲綍鏈哄櫒淇℃伅
+	 */
+	private String machine;//鏈哄櫒淇℃伅
+
+	/**
+	 * 鎿嶄綔绯荤粺
+	 */
+	private String os;//鎿嶄綔绯荤粺淇℃伅
+	/**
+	 * 娴忚鍣ㄧ増鏈�
+	 */
+	private String browser;//娴忚鍣ㄤ俊鎭�
+	/**
+	 * 鎿嶄綔绯荤粺鐢ㄦ埛鍚�
+	 */
+	private String osUser;//鎿嶄綔绯荤粺鐢ㄦ埛淇℃伅
+
+	/**
+	 * 绉诲姩璁惧鐨勪俊鎭�
+	 */
+	private List<String> deviceInfo = new ArrayList<String>();
+
+	/**
+	 * 閭欢
+	 */
+	private String email;
+
+	/**
+	 * 鐢佃瘽鍙风爜
+	 */
+	private String phoneNo;
+
+	/**
+	 * RTX璐︽埛
+	 */
+	private String rtxNo;
+
+	/**
+	 * 闂ㄦ埛绯荤粺ID
+	 */
+	private String portalId;
+
+	/**
+	 * 鍗虫椂閫氳ID
+	 */
+	private String IMId;
+
+	/**
+	 * 鏄惁鍗曠偣鐧诲綍
+	 */
+	private boolean sso;
+
+	/**
+	 * 鍗曠偣鐧诲綍鐨勬潵婧愮郴缁熷悕绉�
+	 */
+	private String ssoServiceName;
+
+	/**
+	 * 璁稿彲鐮�
+	 */
+	private String token;
+
+	/**
+	 * 瀵逛簬鐢ㄦ埛鐨勫叏灞�鍙傛暟
+	 */
+	private Map<String,String> globalAttributeMap = new HashMap<String, String>();
+
+	/**
+	 * 宸ュ彿(鐭彿)
+	 */
+	private String workNo;
+
+	/**
+	 * 鏄惁蹇呴』淇敼瀵嗙爜
+	 */
+	private boolean isMustChangePassword = false;
+
+	/**
+	 * 瀵嗙爜淇℃伅
+	 */
+	private String passwordInfo;
+
+	public String getDutyOid() {
+		return dutyOid;
+	}
+
+	public void setDutyOid(String dutyOid) {
+		this.dutyOid = dutyOid;
+	}
+
+	public String getDutyName() {
+		return dutyName;
+	}
+
+	public void setDutyName(String dutyName) {
+		this.dutyName = dutyName;
+	}
+
+	public String getOrgsOid() {
+		return orgsOid;
+	}
+
+	public void setOrgsOid(String orgsOid) {
+		this.orgsOid = orgsOid;
+	}
+
+	public String getOrgsName() {
+		return orgsName;
+	}
+
+	public void setOrgsName(String orgsName) {
+		this.orgsName = orgsName;
+	}
+
+	public String getDeptOid() {
+		return deptOid;
+	}
+
+	public void setDeptOid(String deptOid) {
+		this.deptOid = deptOid;
+	}
+
+	public String getDeptName() {
+		return deptName;
+	}
+
+	public void setDeptName(String deptName) {
+		this.deptName = deptName;
+	}
+
+	public String getUserOid() {
+		return userOid;
+	}
+
+	public void setUserOid(String userOid) {
+		this.userOid = userOid;
+	}
+
+	public String getUserId() {
+		return userId;
+	}
+
+	public void setUserId(String userId) {
+		this.userId = userId;
+	}
+
+	public String getUserName() {
+		return userName;
+	}
+
+	public void setUserName(String userName) {
+		this.userName = userName;
+	}
+
+	public String getPersonOid() {
+		return personOid;
+	}
+
+	public void setPersonOid(String personOid) {
+		this.personOid = personOid;
+	}
+
+	public String getPersonName() {
+		return personName;
+	}
+
+	public void setPersonName(String personName) {
+		this.personName = personName;
+	}
+
+	public String getWorkgroupOid() {
+		return workgroupOid;
+	}
+
+	public void setWorkgroupOid(String workgroupOid) {
+		this.workgroupOid = workgroupOid;
+	}
+
+	public String getWorkgroupName() {
+		return workgroupName;
+	}
+
+	public void setWorkgroupName(String workgroupName) {
+		this.workgroupName = workgroupName;
+	}
+
+	public String getUsertype() {
+		return usertype;
+	}
+
+	public void setUsertype(String usertype) {
+		this.usertype = usertype;
+	}
+
+	public String getUsertypeText() {
+		return usertypeText;
+	}
+
+	public void setUsertypeText(String usertypeText) {
+		this.usertypeText = usertypeText;
+	}
+
+	public String getSex() {
+		return sex;
+	}
+
+	public void setSex(String sex) {
+		this.sex = sex;
+	}
+
+	public List<String> getFunctionOids() {
+		return functionOids;
+	}
+
+	public void setFunctionOids(List<String> functionOids) {
+		this.functionOids = functionOids;
+	}
+
+
+	public String getPhotoUrl() {
+		return photoUrl;
+	}
+
+	public void setPhotoUrl(String photoUrl) {
+		this.photoUrl = photoUrl;
+	}
+
+	public String getIp() {
+		return ip;
+	}
+
+	public void setIp(String ip) {
+		this.ip = ip;
+	}
+
+	public String getLanguage() {
+		return language;
+	}
+
+	public void setLanguage(String language) {
+		this.language = language;
+	}
+
+	public String getUserSecret() {
+		return userSecret;
+	}
+
+	public void setUserSecret(String userSecret) {
+		this.userSecret = userSecret;
+	}
+
+	public String getUserSecretText() {
+		return userSecretText;
+	}
+
+	public void setUserSecretText(String userSecretText) {
+		this.userSecretText = userSecretText;
+	}
+
+	public String getIpSecret() {
+		return ipSecret;
+	}
+
+	public void setIpSecret(String ipSecret) {
+		this.ipSecret = ipSecret;
+	}
+
+	public String getIpSecretText() {
+		return ipSecretText;
+	}
+
+	public void setIpSecretText(String ipSecretText) {
+		this.ipSecretText = ipSecretText;
+	}
+
+	public String getMachine() {
+		return machine;
+	}
+
+	public void setMachine(String machine) {
+		this.machine = machine;
+	}
+
+	public String getOs() {
+		return os;
+	}
+
+	public void setOs(String os) {
+		this.os = os;
+	}
+
+	public String getBrowser() {
+		return browser;
+	}
+
+	public void setBrowser(String browser) {
+		this.browser = browser;
+	}
+
+	public String getOsUser() {
+		return osUser;
+	}
+
+	public void setOsUser(String osUser) {
+		this.osUser = osUser;
+	}
+
+	public List<String> getDeviceInfo() {
+		return deviceInfo;
+	}
+
+	public void setDeviceInfo(List<String> deviceInfo) {
+		this.deviceInfo = deviceInfo;
+	}
+
+	public String getEmail() {
+		return email;
+	}
+
+	public void setEmail(String email) {
+		this.email = email;
+	}
+
+	public String getPhoneNo() {
+		return phoneNo;
+	}
+
+	public void setPhoneNo(String phoneNo) {
+		this.phoneNo = phoneNo;
+	}
+
+	public String getRtxNo() {
+		return rtxNo;
+	}
+
+	public void setRtxNo(String rtxNo) {
+		this.rtxNo = rtxNo;
+	}
+
+	public String getPortalId() {
+		return portalId;
+	}
+
+	public void setPortalId(String portalId) {
+		this.portalId = portalId;
+	}
+
+	public String getIMId() {
+		return IMId;
+	}
+
+	public void setIMId(String IMId) {
+		this.IMId = IMId;
+	}
+
+	public boolean isSso() {
+		return sso;
+	}
+
+	public void setSso(boolean sso) {
+		this.sso = sso;
+	}
+
+	public String getSsoServiceName() {
+		return ssoServiceName;
+	}
+
+	public void setSsoServiceName(String ssoServiceName) {
+		this.ssoServiceName = ssoServiceName;
+	}
+
+	public String getToken() {
+		return token;
+	}
+
+	public void setToken(String token) {
+		this.token = token;
+	}
+
+	public Map<String, String> getGlobalAttributeMap() {
+		return globalAttributeMap;
+	}
+
+	public void setGlobalAttributeMap(Map<String, String> globalAttributeMap) {
+		this.globalAttributeMap = globalAttributeMap;
+	}
+
+	public String getPersonId() {
+		return personId;
+	}
+
+	public void setPersonId(String personId) {
+		this.personId = personId;
+	}
+
+	public String getSexText() {
+		return sexText;
+	}
+
+	public void setSexText(String sexText) {
+		this.sexText = sexText;
+	}
+
+	public Map<String, String> getRolesName() {
+		return rolesName;
+	}
+
+	public void setRolesName(Map<String, String> rolesName) {
+		this.rolesName = rolesName;
+	}
+
+	public String getWorkNo() {
+		return workNo;
+	}
+
+	public void setWorkNo(String workNo) {
+		this.workNo = workNo;
+	}
+
+	public String getWorkTypeOid() {
+		return workTypeOid;
+	}
+
+	public void setWorkTypeOid(String workTypeOid) {
+		this.workTypeOid = workTypeOid;
+	}
+
+	public String getWorkTypeName() {
+		return workTypeName;
+	}
+
+	public void setWorkTypeName(String workTypeName) {
+		this.workTypeName = workTypeName;
+	}
+
+	public boolean isMustChangePassword() {
+		return isMustChangePassword;
+	}
+
+	public void setMustChangePassword(boolean mustChangePassword) {
+		isMustChangePassword = mustChangePassword;
+	}
+
+	public String getPasswordInfo() {
+		return passwordInfo;
+	}
+
+	public void setPasswordInfo(String passwordInfo) {
+		this.passwordInfo = passwordInfo;
+	}
+
+	public Map<String, Integer> getFunctionOperaMap() {
+		return functionOperaMap;
+	}
+
+	public void setFunctionOperaMap(Map<String, Integer> functionOperaMap) {
+		this.functionOperaMap = functionOperaMap;
+	}
+
+	@Override
+	public String toString() {
+		return "SessionInfo{" +
+				"orgsOid='" + orgsOid + '\'' +
+				", orgsName='" + orgsName + '\'' +
+				", deptOid='" + deptOid + '\'' +
+				", deptName='" + deptName + '\'' +
+				", userOid='" + userOid + '\'' +
+				", userId='" + userId + '\'' +
+				", userName='" + userName + '\'' +
+				", personOid='" + personOid + '\'' +
+				", personId='" + personId + '\'' +
+				", personName='" + personName + '\'' +
+				", dutyOid='" + dutyOid + '\'' +
+				", dutyName='" + dutyName + '\'' +
+				", workgroupOid='" + workgroupOid + '\'' +
+				", workgroupName='" + workgroupName + '\'' +
+				", workTypeOid='" + workTypeOid + '\'' +
+				", workTypeName='" + workTypeName + '\'' +
+				", usertype='" + usertype + '\'' +
+				", usertypeText='" + usertypeText + '\'' +
+				", sex='" + sex + '\'' +
+				", sexText='" + sexText + '\'' +
+				", rolesName=" + rolesName +
+				", functionOids=" + functionOids +
+				", functionOperaMap=" + functionOperaMap +
+				", photoUrl='" + photoUrl + '\'' +
+				", ip='" + ip + '\'' +
+				", language='" + language + '\'' +
+				", userSecret='" + userSecret + '\'' +
+				", userSecretText='" + userSecretText + '\'' +
+				", ipSecret='" + ipSecret + '\'' +
+				", ipSecretText='" + ipSecretText + '\'' +
+				", machine='" + machine + '\'' +
+				", os='" + os + '\'' +
+				", browser='" + browser + '\'' +
+				", osUser='" + osUser + '\'' +
+				", deviceInfo=" + deviceInfo +
+				", email='" + email + '\'' +
+				", phoneNo='" + phoneNo + '\'' +
+				", rtxNo='" + rtxNo + '\'' +
+				", portalId='" + portalId + '\'' +
+				", IMId='" + IMId + '\'' +
+				", sso=" + sso +
+				", ssoServiceName='" + ssoServiceName + '\'' +
+				", token='" + token + '\'' +
+				", globalAttributeMap=" + globalAttributeMap +
+				", workNo='" + workNo + '\'' +
+				", isMustChangePassword=" + isMustChangePassword +
+				", passwordInfo='" + passwordInfo + '\'' +
+				'}';
+	}
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/Tree.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/Tree.java
new file mode 100644
index 0000000..53a3ae6
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/Tree.java
@@ -0,0 +1,406 @@
+package com.vci.starter.web.pagemodel;
+
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 鏍戝瀷鏁版嵁,easyui,extjs,layui閫氱敤
+ * @author weidy
+ *
+ */
+public class Tree implements java.io.Serializable{
+
+	/**
+	 * 绂佹淇敼杩欎釜鍊�
+	 * @serial 搴忓垪鍖栧��
+	 */
+	private static final long serialVersionUID = 6886695271635257882L;
+
+	/**
+	 * 鏋勯�犲嚱鏁�
+	 */
+	public Tree(){
+		
+	}
+
+	/**
+	 * 鏋勯�犲嚱鏁�
+	 * @param oid 涓婚敭
+	 * @param text 鏍戣妭鐐规枃鏈�
+	 */
+	public Tree(String oid, String text){
+		setOid(oid);
+		setText(text);
+	}
+	
+	/**
+	 * 涓婚敭
+	 */
+	private String oid;
+	/**
+	 * 鏄剧ず鏂囨湰
+	 */
+	private String text;
+	/**
+	 * 鏄惁鍙跺瓙
+	 */
+	private boolean leaf = false;
+
+	/**
+	 * 鏄惁鏄剧ず澶嶉�夋
+	 */
+	private boolean showCheckbox = false;
+	/**
+	 * 鏄惁榛樿閫変腑
+	 */
+	private boolean checked = false;
+	
+	/**
+	 * 瀛愯妭鐐�
+	 */
+	private List<Tree> children = new ArrayList<Tree>();
+	/**
+	 * 鍥炬爣
+	 */
+	private String icon;
+	/**
+	 * 鍥炬爣鏍峰紡
+	 */
+	private String iconCls;
+	/**
+	 * 涓婄骇鑺傜偣
+	 */
+	private String parentId;
+
+	/**
+	 * 涓婄骇鑺傜偣鐨勫悕绉�
+	 */
+	private String parentName;
+
+	/**
+	 * 涓婄骇鑺傜偣鐨勪笟鍔$被鍨�
+	 */
+	private String parentBtmName;
+	/**
+	 * 鏄惁灞曞紑
+	 */
+	private boolean expanded = false;
+	
+	/**
+	 * 閾炬帴
+	 */
+	private String href;//layui鍜宔xtjs浣跨敤href,easyui浣跨敤url锛岀粺涓�href
+	
+	/**
+	 * 鎺掑簭绱㈠紩
+	 */
+	private String index;//鎺掑簭绱㈠紩
+	
+	/**
+	 * 鍏朵粬鐨勫睘鎬�
+	 */
+	private Map<String,String> attributes = new HashMap<String, String>();//浣跨敤骞冲彴鐨勮瘽锛屾墍鏈夌殑灞炴�ч兘鏄疭tring鐨�
+	
+	/**
+	 * 鑾峰彇涓婚敭
+	 * @return 涓婚敭鐨勫��
+	 */
+	public String getOid() {
+		return oid;
+	}
+
+	/**
+	 * 璁剧疆涓婚敭
+	 * @param oid 涓婚敭鐨勫��
+ 	 */
+	public void setOid(String oid) {
+		this.oid = oid;
+	}
+
+	/**
+	 * 鑾峰彇鏍戣妭鐐规枃鏈�
+	 * @return 鏍戣妭鐐规枃鏈�
+	 */
+	public String getText() {
+		return text;
+	}
+
+	/**
+	 * 璁剧疆鏍戣妭鐐规枃鏈�
+	 * @param text 鏍戣妭鐐规枃鏈�
+	 */
+	public void setText(String text) {
+		this.text = text;
+	}
+
+	/**
+	 * 鏄惁鍙跺瓙鑺傜偣
+	 * @return true 琛ㄧず鍙跺瓙鑺傜偣
+	 */
+	public boolean isLeaf() {
+		return leaf;
+	}
+
+	/**
+	 * 璁剧疆鍙跺瓙鑺傜偣
+	 * @param leaf 鏄惁鍙跺瓙鑺傜偣
+	 */
+	public void setLeaf(boolean leaf) {
+		this.leaf = leaf;
+	}
+
+	/**
+	 * 鏄惁鏄剧ず澶嶉�夋
+	 * @return true琛ㄧず鏄剧ず
+	 */
+	public boolean isShowCheckbox() {
+		return showCheckbox;
+	}
+
+	/**
+	 * 璁剧疆鏄惁鏄剧ず澶嶉�夋
+	 * @param showCheckbox 鏄惁鏄剧ず澶嶉�夋
+	 */
+	public void setShowCheckbox(boolean showCheckbox) {
+		this.showCheckbox = showCheckbox;
+	}
+
+	/**
+	 * 鏄惁鑷姩鍕鹃�変笂
+	 * @return true琛ㄧず闇�瑕佽嚜鍔ㄥ嬀閫�
+	 */
+	public boolean isChecked() {
+		return checked;
+	}
+
+	/**
+	 * 璁剧疆鏄惁鍕鹃��
+	 * @param checked 鏄惁鑷姩鍕鹃��
+	 */
+	public void setChecked(boolean checked) {
+		this.checked = checked;
+	}
+
+	/**
+	 * 鑾峰彇瀛愯妭鐐�
+	 * @return 瀛愯妭鐐瑰垪琛�
+	 */
+	public List<Tree> getChildren() {
+		return children;
+	}
+
+	/**
+	 * 璁剧疆瀛愯妭鐐�
+	 * @param children 瀛愯妭鐐瑰垪琛�
+	 */
+	public void setChildren(List<Tree> children) {
+		this.children = children;
+	}
+
+	/**
+	 * 鑾峰彇鍥炬爣
+	 * @return 鍥炬爣
+	 */
+	public String getIcon() {
+		return icon;
+	}
+
+	/**
+	 * 璁剧疆鍥炬爣
+	 * @param icon 鍥炬爣
+	 */
+	public void setIcon(String icon) {
+		this.icon = icon;
+	}
+
+	/**
+	 * 鑾峰彇鍥炬爣鐨勬樉绀篶ss绫�
+	 * @return css绫荤殑鍚嶇О
+	 */
+	public String getIconCls() {
+		return iconCls;
+	}
+
+	/**
+	 * 璁剧疆鍥炬爣鐨勬樉绀篶ss绫�
+	 * @param iconCls css绫荤殑鍚嶇О
+	 */
+	public void setIconCls(String iconCls) {
+		this.iconCls = iconCls;
+	}
+
+	/**
+	 * 鑾峰彇涓婄骇涓婚敭
+	 * @return 涓婄骇鑺傜偣鐨刼id
+	 */
+	public String getParentId() {
+		return parentId;
+	}
+
+	/**
+	 * 璁剧疆涓婄骇涓婚敭
+	 * @param parentId 涓婄骇鑺傜偣鐨刼id
+	 */
+	public void setParentId(String parentId) {
+		this.parentId = parentId;
+	}
+
+	/**
+	 * 鏄惁鑷姩灞曞紑
+	 * @return true琛ㄧず鑷姩灞曞紑
+	 */
+	public boolean isExpanded() {
+		return expanded;
+	}
+
+	/**
+	 * 璁剧疆鏄惁鑷姩灞曞紑
+	 * @param expanded 鏄惁鑷姩灞曞紑
+	 */
+	public void setExpanded(boolean expanded) {
+		this.expanded = expanded;
+	}
+
+	/**
+	 * 鑾峰彇閾炬帴鍦板潃
+	 * @return 閾炬帴鍦板潃
+	 */
+	public String getHref() {
+		return href;
+	}
+
+	/**
+	 * 璁剧疆閾炬帴鍦板潃
+	 * @param href 閾炬帴鍦板潃
+	 */
+	public void setHref(String href) {
+		this.href = href;
+	}
+
+	/**
+	 * 鑾峰彇鎺掑簭鍙�
+	 * @return 鎺掑簭鍙�
+	 */
+	public String getIndex() {
+		return index;
+	}
+
+	/**
+	 * 璁剧疆鎺掑簭鍙�
+	 * @param index 鎺掑簭鍙�
+	 */
+	public void setIndex(String index) {
+		this.index = index;
+	}
+
+	/**
+	 * 鑾峰彇鏍戣妭鐐规寚浠g殑涓氬姟鏁版嵁鐨勬墍鏈夊睘鎬ф槧灏�
+	 * @return key琛ㄧず灞炴�х殑鍚嶇О锛寁alue琛ㄧず灞炴�х殑鍊�
+	 */
+	public Map<String, String> getAttributes() {
+		return attributes;
+	}
+
+	/**
+	 * 璁剧疆鏍戣妭鐐规寚浠g殑涓氬姟鏁版嵁鐨勬墍鏈夊睘鎬ф槧灏�
+	 * @param attributes key琛ㄧず灞炴�х殑鍚嶇О锛寁alue琛ㄧず灞炴�х殑鍊�
+	 */
+	public void setAttributes(Map<String, String> attributes) {
+		this.attributes = attributes;
+	}
+
+	/**
+	 * 鑾峰彇涓婄骇鐨勮妭鐐圭殑鍚嶇О
+	 * @return 涓婄骇鐨勫悕绉�
+	 */
+	public String getParentName() {
+		return parentName;
+	}
+
+	/**
+	 * 璁剧疆涓婄骇鑺傜偣鐨勫悕绉�
+	 * @param parentName 涓婄骇鐨勫悕绉�
+	 */
+	public void setParentName(String parentName) {
+		this.parentName = parentName;
+	}
+
+	public String getParentBtmName() {
+		return parentBtmName;
+	}
+
+	public void setParentBtmName(String parentBtmName) {
+		this.parentBtmName = parentBtmName;
+	}
+
+	/**
+	 * 鍒╃敤閫掑綊灏嗘爲杞崲涓轰笂涓嬬骇鍏崇郴
+	 * @param rootTree 椤跺眰鑺傜偣
+	 * @param children 瀛愯妭鐐�
+	 * @return 鍚湁涓婁笅绾у叧绯荤殑鏍�
+	 */
+	public static List<Tree> getChildList(List<Tree> rootTree, List<Tree> children){
+		if(rootTree == null ||rootTree.size() == 0){
+			if(children !=null && children.size()>0){
+				rootTree = children.subList(0, children.size());
+			}else{
+				return null;
+			}
+		}
+		Tree bt = new Tree();
+		bt.findChild(rootTree, children);
+		return rootTree;
+	}
+
+	/**
+	 * 鏌ヨ鏍戠殑涓嬬骇
+	 * @param treenode 褰撳墠鑺傜偣
+	 * @param children 鍏朵粬鐨勮妭鐐�
+	 */
+	public void findChild(List<Tree> treenode, List<Tree> children){
+		for (Tree node : treenode) {
+			for (Tree childnode : children) {
+				if (node.getOid().equalsIgnoreCase(childnode.getParentId())) {
+					childnode.setParentName(node.getText());
+					if(StringUtils.isBlank(childnode.getParentBtmName())){
+						childnode.setParentBtmName(node.getAttributes().getOrDefault("btmname",""));
+					}
+					node.getChildren().add(childnode);
+				}
+			}
+			if (node.getChildren().size()>0) {
+				findChild(node.getChildren(), children);
+				node.setLeaf(false);
+			}else {
+				node.setLeaf(true);
+				
+			}
+			this.getChildren().add(node);
+		}
+	}
+
+	@Override
+	public String toString() {
+		return "Tree{" +
+				"oid='" + oid + '\'' +
+				", text='" + text + '\'' +
+				", leaf=" + leaf +
+				", showCheckbox=" + showCheckbox +
+				", checked=" + checked +
+				", children=" + children +
+				", icon='" + icon + '\'' +
+				", iconCls='" + iconCls + '\'' +
+				", parentId='" + parentId + '\'' +
+				", parentName='" + parentName + '\'' +
+				", parentBtmName='" + parentBtmName + '\'' +
+				", expanded=" + expanded +
+				", href='" + href + '\'' +
+				", index='" + index + '\'' +
+				", attributes=" + attributes +
+				'}';
+	}
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/TreeGrid.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/TreeGrid.java
new file mode 100644
index 0000000..fd34e9b
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/TreeGrid.java
@@ -0,0 +1,86 @@
+package com.vci.starter.web.pagemodel;
+
+import java.util.List;
+
+/**
+ * 鏍戣〃鐨勫睍绀哄璞�,鐩墠閫傞厤layui锛岃鍦ㄦ暟鎹噺灏忕殑鏃跺�欎娇鐢紝鏁版嵁閲忓お澶ф椂涓嶅缓璁娇鐢�
+ * @author weidy
+ */
+public class TreeGrid implements java.io.Serializable {
+
+    private static final long serialVersionUID = 5593300788850918425L;
+    /**
+     * 浠e彿
+     */
+    private int code = 0;
+
+    /**
+     * 閿欒娑堟伅
+     */
+    private String msg;
+
+    /**
+     * 鏁版嵁鎻忚堪锛屽叾涓繀椤昏鏈塼reelevel锛屽叾涓渶椤剁骇鏄�-1,鐒跺悗閫愮骇澧炲姞锛屾暟鎹繀椤绘敞鎰忛『搴�
+     */
+    private List data;
+
+    /**
+     * 鎬绘暟
+     */
+    private int total = 0;
+
+    /**
+     * 鎻忚堪淇℃伅
+     */
+    private String description;
+
+
+    public TreeGrid(){
+
+    }
+
+    public TreeGrid(String msg){
+        this.setMsg(msg);
+        this.setCode(1);
+    }
+
+    public int getCode() {
+        return code;
+    }
+
+    public void setCode(int code) {
+        this.code = code;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    public void setMsg(String msg) {
+        this.msg = msg;
+    }
+
+    public List getData() {
+        return data;
+    }
+
+    public int getTotal() {
+        return total;
+    }
+
+    public void setTotal(int total) {
+        this.total = total;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public void setData(List data) {
+        this.data = data;
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/TreeQueryObject.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/TreeQueryObject.java
new file mode 100644
index 0000000..28f0017
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/pagemodel/TreeQueryObject.java
@@ -0,0 +1,203 @@
+package com.vci.starter.web.pagemodel;
+
+import java.util.Map;
+
+/**
+ * 鏍戝舰鏁版嵁鏌ヨ瀵硅薄
+ * @author weidy
+ * @date 2019/10/11 6:42 PM
+ */
+public class TreeQueryObject implements java.io.Serializable{
+
+    /**
+     * 绂佹淇敼杩欎釜鍊�
+     */
+    private static final long serialVersionUID = -7570704940199743059L;
+    /**
+     * 鏌ヨ鏉′欢
+     */
+    private Map<String,String> conditionMap;
+
+    /**
+     * 鏄惁澶氶��
+     */
+    private boolean multipleSelect;
+
+    /**
+     * 鏄惁鏄剧ず澶嶉�夋
+     */
+    private boolean showCheckBox;
+
+    /**
+     * 鏌ヨ鎵�鏈夌殑灞傜骇
+     */
+    private boolean queryAllLevel;
+
+    /**
+     * 涓婄骇涓氬姟鏁版嵁涓婚敭
+     */
+    private String parentOid;
+
+    /**
+     * 涓婄骇涓氬姟绫诲瀷
+     */
+    private String parentBtmName;
+
+    /**
+     * 鍊肩殑瀛楁
+     */
+    private String valueField = "oid";
+
+    /**
+     * 鏍戣妭鐐圭殑琛ㄨ揪寮�
+     */
+    private String textField = "name";
+
+    /**
+     * 涓婄骇鐨勫瓧娈电殑琛ㄨ揪寮�
+     */
+    private String parentFieldName;
+
+    /**
+     * 鎵╁睍鍙傛暟
+     */
+    private Map<String,String> extandParamsMap;
+
+    /**
+     * 鏌ヨ鎵�鏈夌殑鐗堟湰
+     */
+    private boolean queryAllRev;
+
+    /**
+     * 鎺掑簭鐨勫瓧娈�
+     */
+    private String sort;
+
+    /**
+     * 鎺掑簭鐨勭被鍨�
+     */
+    private String order;
+
+    public String getValueField() {
+        return valueField;
+    }
+
+    public void setValueField(String valueField) {
+        this.valueField = valueField;
+    }
+
+    public String getTextField() {
+        return textField;
+    }
+
+    public void setTextField(String textField) {
+        this.textField = textField;
+    }
+
+    public String getParentFieldName() {
+        return parentFieldName;
+    }
+
+    public void setParentFieldName(String parentFieldName) {
+        this.parentFieldName = parentFieldName;
+    }
+
+    public Map<String, String> getConditionMap() {
+        return conditionMap;
+    }
+
+    public void setConditionMap(Map<String, String> conditionMap) {
+        this.conditionMap = conditionMap;
+    }
+
+    public boolean isMultipleSelect() {
+        return multipleSelect;
+    }
+
+    public void setMultipleSelect(boolean multipleSelect) {
+        this.multipleSelect = multipleSelect;
+    }
+
+    public boolean isShowCheckBox() {
+        return showCheckBox;
+    }
+
+    public void setShowCheckBox(boolean showCheckBox) {
+        this.showCheckBox = showCheckBox;
+    }
+
+    public String getParentOid() {
+        return parentOid;
+    }
+
+    public void setParentOid(String parentOid) {
+        this.parentOid = parentOid;
+    }
+
+    public String getParentBtmName() {
+        return parentBtmName;
+    }
+
+    public void setParentBtmName(String parentBtmName) {
+        this.parentBtmName = parentBtmName;
+    }
+
+    public Map<String, String> getExtandParamsMap() {
+        return extandParamsMap;
+    }
+
+    public void setExtandParamsMap(Map<String, String> extandParamsMap) {
+        this.extandParamsMap = extandParamsMap;
+    }
+
+    public boolean isQueryAllLevel() {
+        return queryAllLevel;
+    }
+
+    public void setQueryAllLevel(boolean queryAllLevel) {
+        this.queryAllLevel = queryAllLevel;
+    }
+
+    public boolean isQueryAllRev() {
+        return queryAllRev;
+    }
+
+    public void setQueryAllRev(boolean queryAllRev) {
+        this.queryAllRev = queryAllRev;
+    }
+
+    public String getSort() {
+        return sort;
+    }
+
+    public void setSort(String sort) {
+        this.sort = sort;
+    }
+
+    public String getOrder() {
+        return order;
+    }
+
+    public void setOrder(String order) {
+        this.order = order;
+    }
+
+    @Override
+    public String toString() {
+        return "TreeQueryObject{" +
+                "conditionMap=" + conditionMap +
+                ", multipleSelect=" + multipleSelect +
+                ", showCheckBox=" + showCheckBox +
+                ", queryAllLevel=" + queryAllLevel +
+                ", parentOid='" + parentOid + '\'' +
+                ", parentBtmName='" + parentBtmName + '\'' +
+                ", valueField='" + valueField + '\'' +
+                ", textField='" + textField + '\'' +
+                ", parentFieldName='" + parentFieldName + '\'' +
+                ", extandParamsMap=" + extandParamsMap +
+                ", queryAllRev=" + queryAllRev +
+                ", sort='" + sort + '\'' +
+                ", order='" + order + '\'' +
+                '}';
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/properties/CorsProperties.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/properties/CorsProperties.java
new file mode 100644
index 0000000..c2da6ba
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/properties/CorsProperties.java
@@ -0,0 +1,130 @@
+package com.vci.starter.web.properties;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.util.Arrays;
+
+/**
+ * 璺ㄥ煙閰嶇疆鐨勫睘鎬�
+ * @author weidy
+ */
+@Component
+@ConfigurationProperties(prefix = "cors")
+public class CorsProperties {
+
+    /**
+     * 寮�鍏�
+     */
+    private String enabled;
+
+    /**
+     * 鍏佽鐨勫煙鍚�
+     */
+    private String[] allowedOrigins;
+    /**
+     * 鍏佽鐨勬柟娉�
+     */
+    private String[] allowedMethods;
+    /**
+     * 鍏佽鐨勫ご
+     */
+    private String[] allowedHeaders;
+    /**
+     * 鏆撮湶鐨勫ご
+     */
+    private String[] exposedHeaders;
+
+    /**
+     * 鍏佽鐨勮瘉涔�
+     */
+    private Boolean allowCredentials;
+    /**
+     * 鏄犲皠
+     */
+    private String mappings;
+
+    /**
+     * 鏈�澶ч噺
+     */
+    private Long maxAge;
+
+    public String getEnabled() {
+        return enabled;
+    }
+
+    public void setEnabled(String enabled) {
+        this.enabled = enabled;
+    }
+
+    public String[] getAllowedOrigins() {
+        return allowedOrigins;
+    }
+
+    public void setAllowedOrigins(String[] allowedOrigins) {
+        this.allowedOrigins = allowedOrigins;
+    }
+
+    public String[] getAllowedMethods() {
+        return allowedMethods;
+    }
+
+    public void setAllowedMethods(String[] allowedMethods) {
+        this.allowedMethods = allowedMethods;
+    }
+
+    public String[] getAllowedHeaders() {
+        return allowedHeaders;
+    }
+
+    public void setAllowedHeaders(String[] allowedHeaders) {
+        this.allowedHeaders = allowedHeaders;
+    }
+
+    public String[] getExposedHeaders() {
+        return exposedHeaders;
+    }
+
+    public void setExposedHeaders(String[] exposedHeaders) {
+        this.exposedHeaders = exposedHeaders;
+    }
+
+    public Boolean getAllowCredentials() {
+        return allowCredentials;
+    }
+
+    public void setAllowCredentials(Boolean allowCredentials) {
+        this.allowCredentials = allowCredentials;
+    }
+
+    public String getMappings() {
+        return mappings;
+    }
+
+    public void setMappings(String mappings) {
+        this.mappings = mappings;
+    }
+
+    public Long getMaxAge() {
+        return maxAge;
+    }
+
+    public void setMaxAge(Long maxAge) {
+        this.maxAge = maxAge;
+    }
+
+    @Override
+    public String toString() {
+        return "CorsProperties{" +
+                "enabled='" + enabled + '\'' +
+                ", allowedOrigins=" + Arrays.toString(allowedOrigins) +
+                ", allowedMethods=" + Arrays.toString(allowedMethods) +
+                ", allowedHeaders=" + Arrays.toString(allowedHeaders) +
+                ", exposedHeaders=" + Arrays.toString(exposedHeaders) +
+                ", allowCredentials=" + allowCredentials +
+                ", mappings='" + mappings + '\'' +
+                ", maxAge=" + maxAge +
+                '}';
+    }
+}
+
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/properties/VciSessionProperties.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/properties/VciSessionProperties.java
new file mode 100644
index 0000000..91e2a7d
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/properties/VciSessionProperties.java
@@ -0,0 +1,148 @@
+package com.vci.starter.web.properties;
+
+import com.vci.starter.web.annotation.config.VciConfigField;
+import com.vci.starter.web.enumpck.DataBaseEnum;
+import com.vci.starter.web.enumpck.LangCodeEnum;
+import com.vci.starter.web.enumpck.SessionStorageTypeEnum;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * 浼氳瘽鐩稿叧鐨勯厤缃�
+ * @author weidy
+ * @date 2020/2/27
+ */
+@Configuration
+@ConfigurationProperties(prefix = "session")
+public class VciSessionProperties {
+
+    /**
+     * 绯荤粺绌洪棽鏃堕棿锛屾牴鎹繚瀵嗚姹傞粯璁ゆ槸10鍒嗛挓
+     */
+    private int sessionIdlTime = 10;
+
+    /**
+     * 浼氳瘽淇℃伅瀛樺偍鐨勬柟寮�
+     */
+    private String sessionInfoStorageType = SessionStorageTypeEnum.REDIS.getValue();
+
+    /**
+     * 鏁版嵁搴撶殑绫诲瀷锛屾槸鍦∣bjectService涓缃殑锛�
+     */
+    @VciConfigField(name = "databasePlatform",title = "鏁版嵁搴撶殑绫诲瀷",model = "public")
+    private String databasePlatform = DataBaseEnum.ORACLE.getValue();
+
+    /**
+     * 鍚姩鏈嶅姟鏃舵槸鍚︽竻绌轰細璇濅俊鎭紝鐧诲綍涓哄綋鍓嶅钩鍙版帶鍒舵椂闇�瑕佹坊鍔犱负true锛岀櫥褰曟槸鍏朵粬绯荤粺鎺у埗鏃惰缃负false
+     */
+    private Boolean clearSessionOnStart = false;
+
+    /**
+     * 榛樿鐨勮瑷�缂栫爜
+     */
+    private String defaultLangCode = LangCodeEnum.ZH_CN.getValue();
+
+    /**
+     * 鏄惁寮�鍚鎴风妫�鏌�
+     */
+    private boolean checkSessionTimeout;
+
+    /**
+     * 瀹㈡埛绔垽鏂秴鏃惰疆璇㈡椂闂达紝鍗曚綅涓虹
+     */
+    private int sessionInterval;
+
+    /**
+     * 瓒呮椂鎻愰啋鏃堕棿锛屽崟浣嶄负鍒嗛挓
+     */
+    private int sessionRemind;
+
+    /**
+     * 瀹氭椂鍣ㄩ噷鏄惁娓呴櫎浼氳瘽
+     */
+    private boolean deleteSessionInTimer = false;
+
+
+    public int getSessionIdlTime() {
+        return sessionIdlTime;
+    }
+
+    public void setSessionIdlTime(int sessionIdlTime) {
+        this.sessionIdlTime = sessionIdlTime;
+    }
+
+    public String getSessionInfoStorageType() {
+        return sessionInfoStorageType;
+    }
+
+    public void setSessionInfoStorageType(String sessionInfoStorageType) {
+        this.sessionInfoStorageType = sessionInfoStorageType;
+    }
+
+    public String getDatabasePlatform() {
+        return databasePlatform;
+    }
+
+    public void setDatabasePlatform(String databasePlatform) {
+        this.databasePlatform = databasePlatform;
+    }
+
+    public String getDefaultLangCode() {
+        return defaultLangCode;
+    }
+
+    public void setDefaultLangCode(String defaultLangCode) {
+        this.defaultLangCode = defaultLangCode;
+    }
+
+    public boolean isClearSessionOnStart() {
+        return clearSessionOnStart;
+    }
+
+    public void setClearSessionOnStart(boolean clearSessionOnStart) {
+        this.clearSessionOnStart = clearSessionOnStart;
+    }
+
+    public boolean isCheckSessionTimeout() {
+        return checkSessionTimeout;
+    }
+
+    public void setCheckSessionTimeout(boolean checkSessionTimeout) {
+        this.checkSessionTimeout = checkSessionTimeout;
+    }
+
+    public int getSessionInterval() {
+        return sessionInterval;
+    }
+
+    public void setSessionInterval(int sessionInterval) {
+        this.sessionInterval = sessionInterval;
+    }
+
+    public int getSessionRemind() {
+        return sessionRemind;
+    }
+
+    public void setSessionRemind(int sessionRemind) {
+        this.sessionRemind = sessionRemind;
+    }
+
+    public boolean isDeleteSessionInTimer() {
+        return deleteSessionInTimer;
+    }
+
+    public void setDeleteSessionInTimer(boolean deleteSessionInTimer) {
+        this.deleteSessionInTimer = deleteSessionInTimer;
+    }
+
+    @Override
+    public String toString() {
+        return "VciSessionProperties{" +
+                "sessionIdlTime=" + sessionIdlTime +
+                ", sessionInfoStorageType='" + sessionInfoStorageType + '\'' +
+                ", databasePlatform='" + databasePlatform + '\'' +
+                ", clearSessionOnStart=" + clearSessionOnStart +
+                ", defaultLangCode='" + defaultLangCode + '\'' +
+                '}';
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/service/BaseService.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/service/BaseService.java
new file mode 100644
index 0000000..08c4623
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/service/BaseService.java
@@ -0,0 +1,10 @@
+package com.vci.starter.web.service;
+
+/**
+ * 鍩虹鐨勬湇鍔�
+ * @author weidy
+ * @date 2019/12/10 6:17 PM
+ */
+public class BaseService<T> {
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/service/LanguageServiceI.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/service/LanguageServiceI.java
new file mode 100644
index 0000000..c19f961
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/service/LanguageServiceI.java
@@ -0,0 +1,27 @@
+package com.vci.starter.web.service;
+
+/**
+ * 澶氳瑷�鐨勬湇鍔℃帴鍙�
+ * @author weidy
+ * @date 2020/1/29
+ */
+public interface LanguageServiceI {
+
+    /**
+     * 鑾峰彇澶氳瑷�鐨勫墠缂�
+     * @return 涓哄綋鍓嶇被鎵�鍦ㄧ殑鍖呯殑鍚嶇О
+     */
+    default String getMsgPrefix(){
+        return getClass().getPackage().getName();
+    }
+
+    /**
+     * 鑾峰彇澶氳瑷�銆傞粯璁や负鍖呭悕.鍚庣紑鐨勬柟寮忥紝姣斿com.vci.xxx
+     * @param subfix 鍚庣紑
+     * @return 鍖呭悕.鍚庣紑鐨勬柟寮忥紝姣斿com.vci.xxx
+     */
+    default String getMsg(String subfix){
+        return getMsgPrefix() + "." + subfix;
+    }
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/service/VciSecretServiceI.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/service/VciSecretServiceI.java
new file mode 100644
index 0000000..ffb9cf8
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/service/VciSecretServiceI.java
@@ -0,0 +1,43 @@
+package com.vci.starter.web.service;
+
+import com.vci.starter.web.enumpck.UserSecretEnum;
+import com.vci.starter.web.pagemodel.SessionInfo;
+import com.vci.starter.web.util.VciBaseUtil;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * 瀵嗙骇鏈嶅姟
+ * @author weidy
+ * @date 2020/3/11
+ */
+public interface VciSecretServiceI {
+
+    /**
+     * 鏌ヨ鏁版嵁鏃剁殑瀵嗙骇杩囨护sql
+     * @return 榛樿灏忎簬绛変簬褰撳墠鐢ㄦ埛鐨勫瘑绾у��
+     */
+    default String getLessThanUserSecretSql(){
+        SessionInfo sessionInfo = VciBaseUtil.getCurrentUserSessionInfoNotException();
+        if(sessionInfo!=null) {
+            return sessionInfo.getUserSecret();
+        }
+        return "";
+    }
+
+    /**
+     * 鏍¢獙鐢ㄦ埛鐨勫瘑绾ф槸鍚︽湁鏉冮檺鏌ョ湅褰撳墠鐨勬暟鎹瘑绾�
+     * @param dataSecret 鏁版嵁瀵嗙骇鐨勫��
+     * @return 榛樿灏忎簬绛変簬褰撳墠鐢ㄦ埛鐨勫瘑绾у�煎嵆鍙�
+     */
+    default boolean checkUserSecret(int dataSecret){
+        SessionInfo sessionInfo = VciBaseUtil.getCurrentUserSessionInfoNotException();
+        if(sessionInfo!=null) {
+            if(StringUtils.isBlank(sessionInfo.getUserSecret())){
+                sessionInfo.setUserSecret(UserSecretEnum.NONE.getValue() +"");
+            }
+            return VciBaseUtil.getInt(sessionInfo.getUserSecret())>= dataSecret;
+        }
+        return false;
+    }
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/toolmodel/DateConverter.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/toolmodel/DateConverter.java
new file mode 100644
index 0000000..9186e87
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/toolmodel/DateConverter.java
@@ -0,0 +1,307 @@
+package com.vci.starter.web.toolmodel;
+
+import com.vci.starter.web.constant.RegExpConstant;
+import com.vci.starter.web.exception.VciBaseException;
+import com.vci.starter.web.util.VciDateUtil;
+import org.apache.commons.lang3.StringUtils;
+
+import java.beans.PropertyEditorSupport;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * 鏃堕棿澶勭悊锛屽墠鍙癹son浼犺緭杩囨潵鐨勫唴瀹圭殑鏃跺��
+ * @author weidy
+ */
+public class DateConverter extends PropertyEditorSupport {
+
+	/**
+	 *鏃堕棿鏍煎紡
+	 */
+	private DateFormat dateFormat;
+
+	 /**
+	 *鏃堕棿鍐呭鐨勯暱搴�
+	 */
+	private  int exactDateLength;
+
+	/**
+	 * 鍏蜂綋鐨勫��
+	 */
+	private Date value;
+
+	public DateFormat getDateFormat() {
+		return dateFormat;
+	}
+
+	public void setDateFormat(DateFormat dateFormat) {
+		this.dateFormat = dateFormat;
+	}
+
+	public int getExactDateLength() {
+		return exactDateLength;
+	}
+
+	public void setExactDateLength(int exactDateLength) {
+		this.exactDateLength = exactDateLength;
+	}
+
+	public Date getValue() {
+		return value;
+	}
+
+	public void setValue(Date value) {
+		this.value = value;
+	}
+
+	/**
+	 *灏嗗瓧绗︿覆杞崲涓烘棩鏈熸牸寮�
+	 * @param text 瀛楃涓�
+	 * @throws VciBaseException 杞崲鍑洪敊鐨勬椂鍊欐姏鍑哄紓甯�
+	 */
+	public void setAsText(String text) throws VciBaseException {
+		if (StringUtils.isBlank(text)) {
+			setValue(null);
+		}else {
+	    	text = text.trim();
+
+			//闃叉鏈変腑鏂囩殑鎯呭喌
+			text = text.replace("骞�","-").replace("鏈�","-").replace("鏃�","").replace("鏃�",":").replace("鍒�",":");
+			String pattern="\\d{2,4}([^\\d]?)\\d{1,2}\\1\\d{1,2}( \\d{1,2}([^\\d])\\d{1,2})?";
+			Pattern r = Pattern.compile(pattern);
+			Matcher m = r.matcher(text);
+			if(m.find()){
+				//璇存槑鏄鍚堣姹傜殑
+				String dateSplit = m.group(1);
+				//涓棿鐨勭┖鏍兼槸绗簩閮ㄥ垎
+				String timeSplit = m.group(3);
+				String formateStr = String.format("yyyy%sMM%sdd",dateSplit,dateSplit);
+				if(StringUtils.isNotBlank(timeSplit)){
+					//鏈夋椂闂�
+					String timeStr = text.substring(text.indexOf(" "));
+					String[] split = timeStr.split(timeSplit);
+					if(split.length == 2){
+						formateStr += String.format(" HH%smm",timeSplit);
+					}
+					if(split.length>2){
+						formateStr += String.format(" HH%smm%sss",timeSplit,timeSplit);
+					}
+					if(timeStr.contains(".")){
+						//姣
+						formateStr += ".SSS";
+					}
+				}
+				String yearMD = text.contains(" ")?text.substring(0, text.indexOf(" ")):text;
+				if(StringUtils.isNotBlank(dateSplit)){
+					//璇存槑鏈夋棩鏈熺殑鍒嗗壊绗�
+					String year = text.substring(0, text.indexOf(dateSplit));
+					if(StringUtils.isNotBlank(year) && year.length()==2){
+						formateStr = formateStr.replace("yyyy","yy");
+					}
+					String[] split = yearMD.split(dateSplit);
+					if(split.length == 2){
+						formateStr = formateStr.replace("dd","");
+					}
+				}else{
+					if(!text.matches(RegExpConstant.NUMBER)){
+						//璇存槑杩樻槸鏈夌鍙凤紝浣嗘槸涓嶇鍚堣姹傝�屽凡
+						if(text.length() == 5){
+							formateStr = formateStr.replace("yyyyMMdd","yy"+text.substring(2,3) + "MM");
+						}
+						if(text.length() == 7){
+							formateStr = formateStr.replace("yyyyMMdd","yyyy"+text.substring(4,5) + "MM");
+						}
+					}else {
+						//濡傛灉鍙湁鏃ユ湡
+						if (text.length() == 2 && text.matches(RegExpConstant.NUMBER)) {
+							formateStr = "yy";
+						} else if (text.length() == 4 && text.matches(RegExpConstant.NUMBER)) {
+							formateStr = "yyyy";
+						} else if (text.length() == 6 && text.matches(RegExpConstant.NUMBER)) {
+							formateStr = "yyyyMM";
+						} else {
+							if (StringUtils.isNotBlank(yearMD) && yearMD.length() < 6) {
+								formateStr = formateStr.replace("yyyy", "yy");
+							}
+						}
+					}
+				}
+				//鍙湁鏃堕棿锛屾垜浠槸娌″姙娉曡浆鎹㈢殑
+				SimpleDateFormat simpleDateFormat = new SimpleDateFormat(formateStr);
+				try {
+					setValue(simpleDateFormat.parse(text));
+				} catch (ParseException e) {
+					//鏄湅鐪嬬煭骞翠唤
+					formateStr= formateStr.replace("yyyy","yy");
+					simpleDateFormat = new SimpleDateFormat(formateStr);
+					try {
+						setValue(simpleDateFormat.parse(text));
+					} catch (ParseException ex) {
+						//濡傛灉鍙湁鏃ユ湡
+						if(text.length() == 2 && text.matches(RegExpConstant.NUMBER)){
+							formateStr = "yy";
+						}
+						throw new VciBaseException("涓嶈兘鏍煎紡鍖栨棩鏈�: {0}", new String[]{text}, e);
+					}
+				}
+			}else{
+				throw new VciBaseException("涓嶆槸鍚堟牸鐨勬椂闂存牸寮忓瓧绗︿覆,{0}", new String[]{text});
+			}
+//			if(text.contains("骞�") || text.contains("鏈�") || text.contains("鏃�")
+//			||text.contains("鏃�") || text.contains("鍒�") || text.contains("绉�") || text.contains("姣")
+//			||text.contains("鍛�") || text.contains("绀兼嫓") || text.contains("澶�")){
+//				//1. 鍙湁骞�
+//				if(text.indexOf("骞�") == text.length()-1){
+//					this.exactDateLength = text.length();
+//					if(text.length() ==3) {
+//						this.dateFormat = new SimpleDateFormat("yy骞�");
+//					}
+//				}
+//			}
+//	    	if(text.contains("/")) {
+//				if ( text.trim().length() == 19) {
+//					this.exactDateLength = 19;
+//					this.dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
+//				} else if (text.indexOf(".") > -1 && text.length() > 20) {
+//					this.exactDateLength = 23;
+//					text = fillNano(text);
+//					this.dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS");
+//				} else if (text.length() == 17) {
+//					this.exactDateLength = 17;
+//					this.dateFormat = new SimpleDateFormat("yy/MM/dd HH:mm:ss");
+//				} else if ( text.indexOf(".") > -1 && text.length() > 17) {
+//					this.exactDateLength = 21;
+//					text = fillNano(text);
+//					this.dateFormat = new SimpleDateFormat("yy/MM/dd HH:mm:ss.SSS");
+//				} else if (text.length() == 10) {
+//					this.exactDateLength = 10;
+//					this.dateFormat = new SimpleDateFormat("yyyy/MM/dd");
+//				} else if (text.length() >=8 && text.length() < 10 ) {
+//					//2018/1/1  鎴栬��18/01/01锛�18/1/1
+//					if(text.substring(0,text.indexOf("/")).length() == 4){
+//						this.dateFormat = new SimpleDateFormat("yyyy/MM/dd");
+//					}else{
+//						this.dateFormat = new SimpleDateFormat("yy/MM/dd");
+//					}
+//					this.exactDateLength = text.length();
+//				}else{
+//					this.dateFormat = new SimpleDateFormat("yy/MM/dd");
+//					this.exactDateLength = text.length();
+//				}
+//			}else if(text.contains("-")) {
+//	    		if (text.length() == 19) {
+//					this.exactDateLength = 19;
+//					this.dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+//				} else if ( text.indexOf(".") > -1 && text.length() > 20) {
+//					this.exactDateLength = 23;
+//					text = fillNano(text);
+//					this.dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+//				} else if (text.length() == 17) {
+//					this.exactDateLength = 17;
+//					this.dateFormat = new SimpleDateFormat("yy-MM-dd HH:mm:ss");
+//				} else if ( text.length() == 8) {
+//					this.exactDateLength = 8;
+//					this.dateFormat = new SimpleDateFormat("yy-MM-dd");
+//				} else if (text.length() == 10) {
+//					this.exactDateLength = 10;
+//					this.dateFormat = new SimpleDateFormat("yyyy-MM-dd");
+//				}else if (text.length() >=8 && text.length() < 10 ) {
+//	    			//2018-1-1  鎴栬��18-01-01锛�18/1/1
+//					if(text.substring(0,text.indexOf("-")).length() == 4){
+//						this.dateFormat = new SimpleDateFormat("yyyy-MM-dd");
+//					}else{
+//						this.dateFormat = new SimpleDateFormat("yy-MM-dd");
+//					}
+//					this.exactDateLength = text.length();
+//				}else{
+//					this.dateFormat = new SimpleDateFormat("yy-MM-dd");
+//					this.exactDateLength = text.length();
+//				}//鍏堝紕杩欎箞澶氾紝涓嶅鍐嶆坊鍔�
+//			}else if(text.matches(RegExpConstant.NUMBER)){
+//
+//			}else{
+//				this.exactDateLength = 19;
+//				this.dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+//			}
+//			//if ((text != null) && (this.exactDateLength >= 0)&& (text.length() != this.exactDateLength)) {
+//			//	throw new IllegalArgumentException("涓嶈兘鍒濆鍖栨椂闂达紝鍥犱负鍐呭涓嶅埌" + this.exactDateLength + "闀垮害");
+//		//	}
+//			try {
+//				setValue(VciDateUtil.str2Date(VciDateUtil.date2Str(this.dateFormat.parse(text),VciDateUtil.DateTimeMillFormat),VciDateUtil.DateTimeMillFormat));
+//				//鏃犺鐣岄潰鏄粈涔堟牸寮忥紝鎴戜滑閮借浆鍖栦负"yyyy-MM-dd HH:mm:ss.SSS"杩欐牱鍙互缁熶竴鍚庡彴鐨勫唴瀹�
+//			} catch (ParseException ex) {
+//				throw new VciBaseException("涓嶈兘鏍煎紡鍖栨棩鏈�: "+ ex.getMessage(), new Object[0],ex);
+//			} catch (Exception e) {
+//				throw new VciBaseException("涓嶈兘鏍煎紡鍖栨棩鏈�: "+ e.getMessage(), new Object[0], e);
+//			}
+		}
+	}
+
+	/**
+	 * 鎶涘純姣
+	 * @param text 瀛楃涓�
+	 * @return 娌℃湁姣鐨勬椂闂村��
+	 */
+	private String fillNano(String text){
+		String nano = text.substring(text.lastIndexOf(".") + 1);
+		if(nano.length() < 3){
+			for(int i = 0 ; i < (3-nano.length()) ; i ++){
+				nano += "0";
+			}
+		}
+		return text.substring(0,text.lastIndexOf(".")) + "." + nano;
+	}
+
+	public static void main(String[] args) {
+		List<String> list = new ArrayList<String>(){{
+			add("2020-11-12 12:12:03");
+			add("2020-1-2 2:2:3");
+			add("2020-11-12 12:12:03.232");
+			add("2020/11/12 12:12:03");
+			add("2020/1/2 2:2:3");
+			add("2020/11/12 12:12:03.232");
+			add("20/11/12 12:12:03");
+			add("20/1/2 2:2:3");
+			add("20/11/12 12:12:03.232");
+			add("2020");
+			add("2020-11");
+			add("202011");
+			add("12:02:12");
+			add("2:2:3");
+			add("20201112");
+			add("202012");
+			add("202012");
+			add("2020骞�11鏈�12鏃� 12鏃�12鍒�03绉�");
+			add("2020骞�1鏈�2鏃� 2:2:3");
+			add("2020骞�11鏈�12鏃� 12鏃�12鍒�03绉�232姣");
+		}};
+		list.stream().forEach(t->{
+			try {
+				DateConverter dateConverter = new DateConverter();
+				dateConverter.setAsText(t);
+				System.out.println("杞崲鍓�:" + t + "; 杞崲鍚�:" + VciDateUtil.date2Str(dateConverter.getValue(), VciDateUtil.DateTimeMillFormat));
+			}catch (Throwable e){
+				e.printStackTrace();
+			}
+		});
+
+	}
+
+	/**
+	 * 鑾峰彇鏃ユ湡杞崲涓哄瓧绗︿覆鐨勫��
+	 * @return 瀛楃涓�
+	 */
+	public String getAsText(String dateFormat) {
+		Date value = (Date) getValue();
+		if(StringUtils.isEmpty(dateFormat)){
+			dateFormat= VciDateUtil.DateTimeMillFormat;
+		}
+		return value != null ? new SimpleDateFormat(dateFormat).format(value) : "";
+	}
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/toolmodel/String2DateConverterForSpringMvc.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/toolmodel/String2DateConverterForSpringMvc.java
new file mode 100644
index 0000000..7997269
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/toolmodel/String2DateConverterForSpringMvc.java
@@ -0,0 +1,26 @@
+package com.vci.starter.web.toolmodel;
+
+import org.springframework.core.convert.converter.Converter;
+import org.springframework.lang.Nullable;
+import java.util.Date;
+
+/**
+ * 閽堝springmvc璁剧疆鐨勬棩鏈熺殑杞崲鍣�
+ * @author weidy
+ * @date 2019/12/3 4:17 PM
+ */
+public class String2DateConverterForSpringMvc implements Converter<String, Date> {
+
+    /**
+     * 杞崲瀛楃涓插埌鏃ユ湡绫诲瀷
+     * @param source 瀛楃涓�
+     * @return 鏃ユ湡瀵硅薄
+     */
+    @Nullable
+    @Override
+    public Date convert(String source) {
+        DateConverter dateConverter = new DateConverter();
+        dateConverter.setAsText(source);
+        return dateConverter.getValue();
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/toolmodel/StringEscapeEditor.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/toolmodel/StringEscapeEditor.java
new file mode 100644
index 0000000..87aa53b
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/toolmodel/StringEscapeEditor.java
@@ -0,0 +1,75 @@
+package com.vci.starter.web.toolmodel;
+
+import org.springframework.web.util.HtmlUtils;
+import org.springframework.web.util.JavaScriptUtils;
+
+import java.beans.PropertyEditorSupport;
+
+/**
+ * 涓巗pring mvc鐨凘InitBinder缁撳悎
+ * 鐢ㄤ簬闃叉XSS鏀诲嚮
+ * 灏咹tml涓寘鍚殑js绛夌浉鍏崇殑鍐呭杞崲
+ * @author weidy
+ * 
+ */
+public class StringEscapeEditor extends PropertyEditorSupport {
+
+	/**
+	 * 瑕佺紪鐮佺殑HTML鍐呭
+	 */
+	private boolean escapeHTML;// 缂栫爜HTML
+	/**
+	 * 瑕佺紪鐮佺殑js
+	 */
+	private boolean escapeJavaScript;// 缂栫爜javascript
+
+	/**
+	 * 鏋勯�犳柟娉�
+	 */
+	public StringEscapeEditor() {
+		super();
+	}
+
+	/**
+	 * 鏋勯�犳柟娉�
+	 * @param escapeHTML 瑕佺紪鐮佺殑html
+	 * @param escapeJavaScript 瑕佺紪鐮佺殑JS
+	 */
+	public StringEscapeEditor(boolean escapeHTML, boolean escapeJavaScript) {
+		super();
+		this.escapeHTML = escapeHTML;
+		this.escapeJavaScript = escapeJavaScript;
+	}
+
+	/**
+	 * 鎵ц杞崲
+	 * @return 缂栫爜鍚庣殑鍐呭
+	 */
+	@Override
+	public String getAsText() {
+		Object value = getValue();
+		return value != null ? value.toString() : "";
+	}
+
+	/**
+	 * 鎵ц涓撳
+	 * @param text 杞崲閽辩殑鍊�
+	 * @throws IllegalArgumentException 杞崲鐨勮繃绋嬪嚭鐜颁簡閿欒浼氭姏鍑哄紓甯�
+	 */
+	@Override
+	public void setAsText(String text) throws IllegalArgumentException {
+		if (text == null) {
+			setValue(null);
+		} else {
+			String value = text;
+			if (escapeHTML) {
+				value = HtmlUtils.htmlEscape(value);
+			}
+			if (escapeJavaScript) {
+				value = JavaScriptUtils.javaScriptEscape(value);
+			}
+			setValue(value);
+		}
+	}
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/ApplicationContextProvider.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/ApplicationContextProvider.java
new file mode 100644
index 0000000..800ff1d
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/ApplicationContextProvider.java
@@ -0,0 +1,107 @@
+package com.vci.starter.web.util;
+
+import com.vci.starter.web.annotation.controller.VciUnCheckRight;
+import com.vci.starter.web.annotation.log.VciUnLog;
+import com.vci.starter.web.autoconfigure.AppAutoConfigure;
+import com.vci.starter.web.pagemodel.BaseResult;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * spring鐨勪笂涓嬫枃宸ュ叿锛�
+ * 娉ㄦ剰springmvc涓殑controller涓嶅簲璇ュ湪杩欓噷鑾峰彇锛屽洜涓簊pringmvc鍙簲璇ヨ鍓嶇璋冪敤
+ * 娌℃湁浣跨敤springboot鐨刴ain鍑芥暟閲岃缃苟鑾峰彇鏄洜涓哄彲鑳戒細璁╁涓湇鍔″悎骞跺埌涓�璧峰惎鍔�
+ * @author weidy
+ * @date 2019/10/31 9:02 AM
+ */
+@RestController
+@RequestMapping("/application")
+public class ApplicationContextProvider implements ApplicationContextAware {
+
+    /**
+     * 鏈嶅姟鐨勯厤缃�
+     */
+    @Autowired
+    private AppAutoConfigure appAutoConfigure;
+
+    /**
+     * 搴旂敤鐨勪笂涓嬫枃
+     */
+    private static ApplicationContext applicationContext ;
+
+    /**
+     * 璁剧疆搴旂敤鐨勪笂涓嬫枃
+     * @param applicationContext 涓婁笅鏂�
+     * @throws BeansException 鍑虹幇閿欒鏃堕渶瑕佹姏鍑哄紓甯哥粰spring瀹瑰櫒
+     */
+    @Override
+    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+        ApplicationContextProvider.applicationContext = applicationContext;
+    }
+
+    /**
+     * 鑾峰彇搴旂敤鐨勪笂涓嬫枃
+     * @return 涓婁笅鏂�
+     */
+    public static ApplicationContext getApplicationContext() {
+        return applicationContext;
+    }
+
+    /**
+     * 鑾峰彇瀵硅薄
+     * @param name bean鐨勫悕绉�
+     * @return Object bean鐨勫璞�
+     * @throws BeansException 濡傛灉涓嶅瓨鍦ㄤ細鎶涘嚭寮傚父
+     */
+    public static Object getBean(String name) throws BeansException {
+        return applicationContext.getBean(name);
+    }
+
+    /**
+     * 鑾峰彇瀵硅薄
+     * @param c bean鐨勬帴鍙g被
+     * @param <T> bean鎵�灞炵被鐨勭被鍨�
+     * @return bean瀵硅薄
+     * @throws BeansException 濡傛灉涓嶅瓨鍦ㄤ細鎶涘嚭寮傚父
+     */
+    public static <T> T getBean(Class<T> c) throws BeansException{
+        return applicationContext.getBean(c);
+    }
+
+    /**
+     * 鍏虫満
+     * @return 鎵ц瀹屾垚
+     */
+    @PostMapping("/shutDownContext")
+    @VciUnLog
+    @VciUnCheckRight
+    public BaseResult shutDownContext(String privateKey){
+        if( appAutoConfigure.getPrivateTokenKey().equalsIgnoreCase(privateKey)) {
+            ConfigurableApplicationContext ctx = (ConfigurableApplicationContext) applicationContext;
+            ctx.close();
+            return BaseResult.success("鍏抽棴鏈嶅姟鎴愬姛");
+        }else{
+            return BaseResult.fail("鎮ㄦ病鏈夋潈闄愬叧闂湇鍔�");
+        }
+    }
+
+    /**
+     * 妫�鏌ユ槸鍚﹀畬鎴�
+     * @return 璋冪敤灏辫鏄庢垚鍔熶簡
+     */
+    @PostMapping("/checkOnline")
+    @VciUnLog
+    @VciUnCheckRight
+    public BaseResult checkOnline(){
+        return BaseResult.success("鍚姩瀹屾垚");
+    }
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/BeanUtil.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/BeanUtil.java
new file mode 100644
index 0000000..61a4a36
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/BeanUtil.java
@@ -0,0 +1,222 @@
+package com.vci.starter.web.util;
+
+import com.vci.starter.web.toolmodel.DateConverter;
+import org.springframework.cglib.beans.BeanCopier;
+import org.springframework.cglib.core.Converter;
+
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * 瀵硅薄鎷疯礉宸ュ叿绫�
+ * 浣跨敤鐨刢glib鐨刡eancopier锛屽洜涓轰娇鐢ㄤ簡杞崲鍣紝鎵�浠ユ�ц兘姣旀病鏈変娇鐢ㄨ浆鎹㈠櫒鐨勮浣庝竴浜�
+ * 浼氳嚜鍔ㄥ垽鏂槸鍚﹂渶瑕佽浆鎹㈠櫒锛屽綋鏈夊睘鎬х浉鍚岋紝绫诲瀷涓嶅悓锛屽拰鏈夊璞$被鍨嬶紝map锛宭ist绛夐泦鍚堢被鍨嬫椂鎵嶉渶瑕佽浆鎹㈠櫒
+ * @author weidy
+ * @date 2019/11/23 9:22 AM
+ */
+public class BeanUtil {
+
+
+    /**
+     * 瀛樻斁鎷疯礉瀵硅薄鐨勭紦瀛�
+     */
+    private static final ConcurrentMap<String,BeanCopier> beanCopierMap = new ConcurrentHashMap<>();
+
+    /**
+     * 鑾峰彇绫绘嫹璐濈殑瀵硅薄
+     * @param source 婧愬璞$被
+     * @param target 鐩爣瀵硅薄绫�
+     * @param useConverter 鏄惁浣跨敤杞崲鍣�
+     * @return 鎷疯礉瀵硅薄
+     */
+    public static BeanCopier getBeanCopier(Class<?> source, Class<?> target,boolean useConverter) {
+        String beanCopierKey = generateBeanKey(source, target);
+        if (beanCopierMap.containsKey(beanCopierKey)) {
+            return beanCopierMap.get(beanCopierKey);
+        } else {
+            BeanCopier beanCopier = BeanCopier.create(source, target, useConverter);
+            beanCopierMap.putIfAbsent(beanCopierKey, beanCopier);
+        }
+        return beanCopierMap.get(beanCopierKey);
+    }
+
+    /**
+     * 鐢熸垚涓や釜绫荤殑key,鐢ㄤ簬瀛樻斁鍒扮紦瀛樹箣涓�
+     * @param source 婧愬璞$被鍨�
+     * @param target 鐩爣瀵硅薄绫�
+     * @return 涓や釜绫荤殑鍚嶇О杩炴帴鍒颁竴璧峰悗鐨勫悕瀛�
+     */
+    public static String generateBeanKey(Class<?> source, Class<?> target) {
+        return source.getName() + "@" + target.getName();
+    }
+
+    /**
+     * 涓や釜瀵硅薄涔嬮棿杞崲
+     * @param source 婧愬璞�
+     * @param target 鐩爣瀵硅薄
+     * @param useConvert 鏄惁浣跨敤榛樿鐨勮浆鎹㈠櫒锛岃鍦ㄥ嚭鐜板睘鎬у悕绉扮浉鍚岃�岀被鍨嬩笉鍚岋紝鎴栬�呮湁瀵硅薄绫诲瀷锛岄泦鍚堝睘鎬ф椂鎵嶈浆鎹�
+     */
+    public static void convert(Object source,Object target,boolean useConvert){
+        if(source != null && target !=null){
+            BeanCopier beanCopier = getBeanCopier(source.getClass(),target.getClass(),useConvert);
+            beanCopier.copy(source,target,useConvert?new DeepCopyConverter(target):null);
+        }
+    }
+
+    /**
+     * 涓や釜瀵硅薄涔嬮棿杞崲
+     * @param source 婧愬璞�
+     * @param target 鐩爣瀵硅薄
+     * @return 鐩爣瀵硅薄
+     */
+    public static void convert(Object source,Object target){
+        convert(source,target,true);
+    }
+
+    /**
+     * 娣卞害鎷疯礉杞崲鍣�
+     */
+    public static class DeepCopyConverter implements Converter {
+
+        /**
+         * 鐩爣瀵硅薄
+         */
+        private Object target;
+
+        /**
+         * 鏋勯�犳柟娉�
+         * @param target 鐩爣瀵硅薄
+         */
+        public DeepCopyConverter(Object target) {
+            this.target = target;
+        }
+
+        /**
+         * 鎵ц鎷疯礉
+         * @param value 婧愬璞$殑灞炴�х殑鍊�
+         * @param targetClazz 鐩爣瀵硅薄鐨勫睘鎬х殑绫�
+         * @param methodName set鏂规硶鐨勫悕瀛�
+         * @return 杞崲鍚庣殑鍊�
+         */
+        @Override
+        public Object convert(Object value, Class targetClazz, Object methodName) {
+            if (value instanceof List) {
+                List values = (List) value;
+                List retList = new ArrayList<>(values.size());
+                copyForCollection(values,retList,methodName);
+                return retList;
+            } else if(value instanceof Set){
+                Set values = (Set) value;
+                Set retSet = new HashSet<>();
+                copyForCollection(values,retSet,methodName);
+            } else if(value instanceof Vector){
+                Vector values = (Vector)value;
+                Vector retVector = new Vector();
+                copyForCollection(values,retVector,methodName);
+            }else if (value instanceof Map) {
+                Map values = (Map)value;
+                Map retMap = new HashMap();
+                for (final Object key : values.keySet()) {
+                    Object mapValue = values.get(key);
+                    String tempFieldName = methodName.toString().replace("set",
+                            "");
+                    String fieldName = tempFieldName.substring(0, 1)
+                            .toLowerCase() + tempFieldName.substring(1);
+                    Class clazz = ClassUtil.getElementType(target.getClass(), fieldName);
+                    Object targetAttr = null;
+                    try{
+                        targetAttr = clazz.newInstance();
+                    }catch (Throwable e){
+                        //鏂扮殑瀵硅薄鐨勫睘鎬у垵濮嬪寲鍑洪敊
+                    }
+                    BeanUtil.convert(mapValue, targetAttr);
+                    retMap.put(key,targetAttr);
+                }
+            } else if (!ClassUtil.isPrimitive(targetClazz)) {
+                //杩欎釜鏄璞$被鍨�
+                Object targetAttr = null;
+                try{
+                    targetAttr = targetClazz.newInstance();
+                }catch (Throwable e){
+                    //鏂扮殑瀵硅薄灞炴�у垵濮嬪寲鍑洪敊
+                }
+                BeanUtil.convert(value, targetAttr);
+                return targetAttr;
+            }
+            if(value instanceof Boolean && targetClazz.equals(String.class)){
+                //浠巄oolean鎷疯礉鍒皊tring
+                return String.valueOf(value);
+            }
+            if(value instanceof String && (targetClazz.equals(Boolean.class)
+                    || targetClazz.equals(boolean.class))){
+                //浠嶴tring鎷疯礉鍒癰oolean
+                if("true".equalsIgnoreCase((String)value)){
+                    return true;
+                }else{
+                    return false;
+                }
+            }
+            if(value instanceof Date && targetClazz.equals(String.class)){
+                //鏃堕棿鏍煎紡
+                return VciDateUtil.date2Str((Date)value,VciDateUtil.DateTimeMillFormat);
+            }
+            if(value instanceof String && targetClazz.equals(Date.class)){
+                //杞崲
+                DateConverter dateConverter = new DateConverter();
+                dateConverter.setAsText((String)value);
+                return dateConverter.getValue();
+            }
+            return value;
+        }
+
+        /**
+         * 澶勭悊闆嗗悎灞炴��
+         * @param sourceCollection 婧愬璞′腑闆嗗悎灞炴�х殑鐨勫��
+         * @param targetCollection 鐩爣瀵硅薄鐨勯泦鍚堝睘鎬х殑鍊�
+         * @param methodName setter鏂规硶
+         */
+        private void copyForCollection(Collection<?> sourceCollection,Collection targetCollection,Object methodName){
+            for (final Object source : sourceCollection) {
+                if(source instanceof Collection){
+                    List<Object> targetValues = new ArrayList<>();
+                    copyForCollection((Collection<?>)source,targetValues,methodName);
+                    targetCollection.add(targetValues);
+                }else if(source instanceof Map){
+                    String tempFieldName = methodName.toString().replace("set",
+                            "");
+                    String fieldName = tempFieldName.substring(0, 1)
+                            .toLowerCase() + tempFieldName.substring(1);
+                    Class clazz = ClassUtil.getElementType(target.getClass(), fieldName);
+                    Object targetAttr = null;
+                    try {
+                        targetAttr = clazz.newInstance();
+                    } catch (Throwable e) {
+                        //鏂扮殑瀵硅薄鐨勫睘鎬у垵濮嬪寲鍑洪敊
+                    }
+                    Map map = (Map) source;
+                    for(Object key : map.keySet()){
+                        VciBaseUtil.setValueForField(key.toString(),targetAttr,VciBaseUtil.getStringValueFromObject(map.get(key)));
+                    }
+                    targetCollection.add(targetAttr);
+                }else  {
+                    String tempFieldName = methodName.toString().replace("set",
+                            "");
+                    String fieldName = tempFieldName.substring(0, 1)
+                            .toLowerCase() + tempFieldName.substring(1);
+                    Class clazz = ClassUtil.getElementType(target.getClass(), fieldName);
+                    Object targetAttr = null;
+                    try {
+                        targetAttr = clazz.newInstance();
+                    } catch (Throwable e) {
+                        //鏂扮殑瀵硅薄鐨勫睘鎬у垵濮嬪寲鍑洪敊
+                    }
+                    BeanUtil.convert(source, targetAttr);
+                    targetCollection.add(targetAttr);
+                }
+            }
+        }
+    }
+
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/BeanUtilForVCI.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/BeanUtilForVCI.java
new file mode 100644
index 0000000..0fc3a78
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/BeanUtilForVCI.java
@@ -0,0 +1,258 @@
+package com.vci.starter.web.util;
+
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.util.CollectionUtils;
+
+import java.lang.reflect.Field;
+import java.util.*;
+
+/**
+ * 涓氬姟绫诲瀷涓撶敤鐨勬嫹璐濆伐鍏凤紝杩欎釜鏄祬鎷疯礉锛�
+ * @author weidy
+ * @date 2022-1-18
+ */
+public class BeanUtilForVCI {
+
+    /**
+     * 鏃ュ織
+     */
+    private static Logger logger = LoggerFactory.getLogger(BeanUtilForVCI.class);
+
+    /**
+     * 鎷疯礉鏁版嵁
+     * 澶у皬鍐欏彲浠ュ拷鐣�
+     * 涓嬪垝绾� _ 琚拷鐣�
+     * null鍜岀┖瀛楃涓茬殑涔熶細琚鐩�
+     * @param source 鏉ユ簮灞炴��
+     * @param target 鐩爣灞炴��
+     */
+    public static void copyPropertiesIgnoreCase(Object source, Object target) {
+        copyPropertiesIgnoreCase(source,target,false);
+    }
+
+    /**
+     * 鎷疯礉灞炴��
+     * @param source 婧愬璞�
+     * @param target 鐩爣瀵硅薄
+     * @param fieldMap 灞炴�х殑鏄犲皠
+     */
+    public static void copyPropertiesIgnoreCase(Object source,Object target,Map<String/**鍘熷璞$殑灞炴�у悕瀛�**/,String/**鐩爣瀵硅薄鐨勫睘鎬у悕绉�**/> fieldMap){
+        copyPropertiesIgnoreCase(source,target,false,fieldMap);
+    }
+
+    /**
+     * 鎷疯礉鏁版嵁
+     * 澶у皬鍐欏彲浠ュ拷鐣�
+     * 涓嬪垝绾� _ 琚拷鐣�
+     * @param source 鏉ユ簮灞炴��
+     * @param target 鐩爣灞炴��
+     * @param ignoreNull 鏄惁蹇界暐鎺у埗
+     */
+    public static void copyPropertiesIgnoreCase(Object source,Object target,boolean ignoreNull){
+        copyPropertiesIgnoreCase(source, target, ignoreNull,null);
+    }
+
+    /**
+     * 鎷疯礉鏈綋鐨勫睘鎬у唴瀹�
+     * @param source 鏉ユ簮瀵硅薄
+     * @param target 鐩爣瀵硅薄
+     */
+    public static void copyDeclaredIgnoreCase(Object source,Object target){
+        copyDeclaredIgnoreCase(source,target,false);
+    }
+
+    /**
+     * 鎷疯礉鏈綋鐨勫睘鎬у唴瀹�
+     * @param source 鏉ユ簮瀵硅薄
+     * @param target 鐩爣瀵硅薄
+     * @param ignoreNull  蹇界暐绌哄�肩殑灞炴��
+     */
+    public static void copyDeclaredIgnoreCase(Object source,Object target,boolean ignoreNull){
+        copyDeclaredIgnoreCase(source,target,ignoreNull,null);
+    }
+
+    /**
+     * 鎷疯礉鏈綋鐨勫睘鎬у唴瀹�
+     * @param source 鏉ユ簮瀵硅薄
+     * @param target 鐩爣瀵硅薄
+     * @param ignoreNull 蹇界暐绌哄�肩殑灞炴��
+     * @param fieldMap 瀛楁鐨勬槧灏�
+     */
+    public static void copyDeclaredIgnoreCase(Object source,Object target,boolean ignoreNull,Map<String/**鍘熷璞$殑灞炴�у悕瀛�**/,String/**鐩爣瀵硅薄鐨勫睘鎬у悕绉�**/> fieldMap){
+        copyDeclaredIgnoreCase(source,target,ignoreNull,fieldMap,null);
+    }
+
+    /**
+     * 鎷疯礉鏈綋鐨勫睘鎬у唴瀹�
+     * @param source 鏉ユ簮瀵硅薄
+     * @param target 鐩爣瀵硅薄
+     * @param ignoreNull 蹇界暐绌哄�肩殑灞炴��
+     * @param fieldMap 瀛楁鐨勬槧灏�
+     * @param ignoreField 蹇界暐瀛楁
+     */
+    public static void copyDeclaredIgnoreCase(Object source,Object target,boolean ignoreNull,Map<String/**鍘熷璞$殑灞炴�у悕瀛�**/,String/**鐩爣瀵硅薄鐨勫睘鎬у悕绉�**/> fieldMap,Collection<String> ignoreField){
+        Map<String, Field> sourceMap = CacheFieldMap.getDeclaredFieldMap(source.getClass());
+        Map<String, Field> targetMap = CacheFieldMap.getDeclaredFieldMap(target.getClass());
+        copyPropertiesIgnoreCase(source,target,ignoreNull,fieldMap,ignoreField,sourceMap,targetMap);
+    }
+    /**
+     * 鎷疯礉鏁版嵁
+     * 澶у皬鍐欏彲浠ュ拷鐣�
+     * 涓嬪垝绾� _ 琚拷鐣�
+     * @param source 鏉ユ簮灞炴��
+     * @param target 鐩爣灞炴��
+     * @param ignoreNull 鏄惁蹇界暐鎺у埗
+     */
+    public static void copyPropertiesIgnoreCase(Object source, Object target, boolean ignoreNull, Map<String/**鍘熷璞$殑灞炴�у悕瀛�**/,String/**鐩爣瀵硅薄鐨勫睘鎬у悕绉�**/> fieldMap, Collection<String> ignoreField) {
+        Map<String, Field> sourceMap = CacheFieldMap.getFieldMap(source.getClass());
+        Map<String, Field> targetMap = CacheFieldMap.getFieldMap(target.getClass());
+        copyPropertiesIgnoreCase(source,target,ignoreNull,fieldMap,ignoreField,sourceMap,targetMap);
+    }
+
+    /**
+     * 鎷疯礉鏁版嵁
+     * 澶у皬鍐欏彲浠ュ拷鐣�
+     * 涓嬪垝绾� _ 琚拷鐣�
+     * @param source 鏉ユ簮灞炴��
+     * @param target 鐩爣灞炴��
+     * @param ignoreNull 鏄惁蹇界暐鎺у埗
+     */
+    public static void copyPropertiesIgnoreCase(Object source, Object target, boolean ignoreNull,
+                                                Map<String/**鍘熷璞$殑灞炴�у悕瀛�**/,String/**鐩爣瀵硅薄鐨勫睘鎬у悕绉�**/> fieldMap, Collection<String> ignoreField,
+                                                Map<String, Field> sourceMap,Map<String, Field> targetMap ) {
+        if(fieldMap == null){
+            fieldMap = new HashMap<>();
+        }
+        Map<String, String> finalFieldMap = fieldMap;
+        targetMap.values().forEach((it) -> {
+            boolean not = false;
+            if(ignoreField!=null &&  ignoreField.contains(it.getName())){
+                not = true;
+            }
+            if(!not) {
+                String itFieldName = it.getName().toLowerCase().replace("_", "");
+                itFieldName = finalFieldMap.getOrDefault(itFieldName, itFieldName);
+                Field field = sourceMap.getOrDefault(itFieldName, null);
+                if (field != null) {
+                    it.setAccessible(true);
+                    field.setAccessible(true);
+                    try {
+                        //蹇界暐null鍜岀┖瀛楃涓�
+                        //澶勭悊boolean鍜孲tring
+                        String sourceClassName = field.getClass().getName();
+                        String targetClassName = it.getClass().getName();
+                        if (((sourceClassName.equalsIgnoreCase(Boolean.class.getName())
+                                || sourceClassName.equalsIgnoreCase(boolean.class.getName())
+                        ) && targetClassName.equalsIgnoreCase(String.class.getName()))
+                                || ((targetClassName.equalsIgnoreCase(Boolean.class.getName())
+                                || targetClassName.equalsIgnoreCase(boolean.class.getName()))
+                                && sourceClassName.equalsIgnoreCase(String.class.getName()))) {
+                            if (targetClassName.equalsIgnoreCase(String.class.getName())) {
+                                it.set(target, String.valueOf((Boolean) field.get(source)));
+                            } else {
+                                it.set(target, Boolean.valueOf((String) field.get(source)));
+                            }
+                        } else {
+                            if (!ignoreNull) {
+                                it.set(target, field.get(source));
+                            } else {
+                                //闇�瑕佸垽鏂槸鍚︿负绌�
+                                Object sourceValue = field.get(source);
+                                if (sourceValue != null && StringUtils.isNotBlank(sourceValue.toString())) {
+                                    it.set(target, sourceValue);
+                                }
+                            }
+                        }
+                    } catch (IllegalAccessException e) {
+                        if (logger.isErrorEnabled()) {
+                            logger.error("鎷疯礉灞炴�у嚭閿�" + e);
+                        }
+                    }
+                }
+            }
+        });
+    }
+
+
+
+
+        /**
+         * 鎷疯礉鏁版嵁
+         * 澶у皬鍐欏彲浠ュ拷鐣�
+         * 涓嬪垝绾� _ 琚拷鐣�
+         * @param source 鏉ユ簮灞炴��
+         * @param target 鐩爣灞炴��
+         * @param ignoreNull 鏄惁蹇界暐鎺у埗
+         */
+    public static void copyPropertiesIgnoreCase(Object source,Object target,boolean ignoreNull,Map<String/**鍘熷璞$殑灞炴�у悕瀛�**/,String/**鐩爣瀵硅薄鐨勫睘鎬у悕绉�**/> fieldMap){
+        copyPropertiesIgnoreCase(source,target,ignoreNull,fieldMap,null);
+    }
+
+    /**
+     * 缂撳瓨瀵硅薄鐨勫睘鎬�
+     */
+    private static class CacheFieldMap {
+        /**
+         * 瀵硅薄灞炴�х殑缂撳瓨
+         */
+        private static Map<String/**绫荤殑鍚嶅瓧**/, Map<String/**灞炴�х殑鍚嶇О灏忓啓**/, Field/**灞炴�х殑瀵硅薄**/>> cacheMap = new HashMap<>();
+
+        /**
+         * 瀵硅薄鐨勮嚜宸辩被鐨勭幆澧冿紝涓嶅寘鎷埗绫�
+         */
+        private static Map<String/**绫荤殑鍚嶇О**/,Map<String/**灞炴�х殑鍚嶇О灏忓啓**/,Field/**灞炴�х殑瀵硅薄**/>> declaredCacheMap = new HashMap<>();
+
+        /**
+         * 鑾峰彇灞炴�х殑鏄犲皠
+         * @param clazz 绫�
+         * @return 灞炴�у悕绉板皬鍐欏拰灞炴�х殑鏄犲皠
+         */
+        private static Map<String/**灞炴�у悕绉�**/, Field> getFieldMap(Class clazz) {
+            Map<String, Field> result = cacheMap.get(clazz.getName());
+            if (result == null) {
+                synchronized (CacheFieldMap.class) {
+                    if (result == null) {
+                        Map<String, Field> fieldMap = new HashMap<>();
+                        List<Field> allFields = VciBaseUtil.getAllFieldForObj(clazz);
+                        if(!CollectionUtils.isEmpty(allFields)){
+                            allFields.stream().forEach(field -> {
+                                fieldMap.put(field.getName().toLowerCase().replace("_", ""), field);
+                            });
+                        }
+                        cacheMap.put(clazz.getName(), fieldMap);
+                        result = cacheMap.get(clazz.getName());
+                    }
+                }
+            }
+            return result;
+        }
+
+        /**
+         * 鑾峰彇灞炴�х殑鏄犲皠锛堜笉鍖呭惈鐖剁被锛�
+         * @param clazz 绫�
+         * @return 灞炴�у悕绉板皬鍐欏拰灞炴�х殑鏄犲皠
+         */
+        private static Map<String/**灞炴�у悕绉�**/,Field> getDeclaredFieldMap(Class clazz){
+            Map<String, Field> result = declaredCacheMap.get(clazz.getName());
+            if(result == null){
+                synchronized(CacheFieldMap.class){
+                    if (result == null) {
+                        Map<String, Field> fieldMap = new HashMap<>();
+                        Field[] allFields = clazz.getDeclaredFields();
+                        if(allFields!=null && allFields.length>0){
+                            Arrays.stream(allFields).forEach(field -> {
+                                fieldMap.put(field.getName().toLowerCase().replace("_", ""), field);
+                            });
+                        }
+                        declaredCacheMap.put(clazz.getName(), fieldMap);
+                        result = declaredCacheMap.get(clazz.getName());
+                    }
+                }
+            }
+            return result;
+        }
+    }
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/BusAnnotationUtil.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/BusAnnotationUtil.java
new file mode 100644
index 0000000..15d65e6
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/BusAnnotationUtil.java
@@ -0,0 +1,52 @@
+package com.vci.starter.web.util;
+
+import com.vci.starter.web.exception.VciBaseException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.util.CollectionUtils;
+
+import java.lang.reflect.Method;
+import java.util.Map;
+
+/**
+ * 涓氬姟鐨勬敞瑙e伐鍏风被
+ * @author weidy
+ * @date 2022-04-12
+ */
+public class BusAnnotationUtil {
+
+    /**
+     * 鏃ュ織
+     */
+    private static Logger logger = LoggerFactory.getLogger(BusAnnotationUtil.class);
+
+    /**
+     * 閫氳繃娉ㄨВ鍘昏皟鐢ㄥ搴旂殑鏂规硶
+     * @param classAnnotation 绫荤殑娉ㄨВ
+     * @param methodAnnotation 鏂规硶鐨勬敞瑙�
+     * @param args 鍙傛暟
+     */
+    public static void callForAnnotation(Class classAnnotation,Class methodAnnotation,Object ... args){
+        //鍦ㄧ櫥褰曚箣鍓嶏紝鐪嬬湅鏄惁鏈夋彃浠�
+        Map<String, Object> beanMap = ApplicationContextProvider.getApplicationContext().getBeansWithAnnotation(classAnnotation);
+        if (!CollectionUtils.isEmpty(beanMap)) {
+            beanMap.forEach((k, v) -> {
+                Method[] methods = v.getClass().getSuperclass().getDeclaredMethods();
+                if (methods != null && methods.length > 0) {
+                    for (Method method : methods) {
+                        if (method.isAnnotationPresent(methodAnnotation)) {
+                            try {
+                                method.invoke(v, args);
+                            } catch (Throwable e) {
+                                if (logger.isErrorEnabled()) {
+                                    logger.error("璋冪敤鎻掍欢鍑洪敊", e);
+                                }
+                                throw new VciBaseException("璋冪敤鎻掍欢鍑洪敊,{0},{1}", new String[]{v.getClass().getName(), method.getName()}, e);
+                            }
+                        }
+                    }
+                }
+            });
+        }
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/ClassUtil.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/ClassUtil.java
new file mode 100644
index 0000000..efea946
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/ClassUtil.java
@@ -0,0 +1,85 @@
+package com.vci.starter.web.util;
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 绫荤殑鎿嶄綔宸ュ叿
+ * @author weidy
+ * @date 2019/11/23 10:18 AM
+ */
+public class ClassUtil {
+    /**
+     * 鍩烘湰绫诲瀷鐨勬槧灏�
+     */
+    private static final Map<Class<?>, Class<?>> primitiveMap = new HashMap<>(9);
+
+    /**
+     * 鍒濆鍖栫殑鏃跺�欙紝灏嗗熀纭�绫诲瀷娣诲姞杩涘幓
+     */
+    static {
+        primitiveMap.put(String.class, String.class);
+        primitiveMap.put(Boolean.class, boolean.class);
+        primitiveMap.put(Byte.class, byte.class);
+        primitiveMap.put(Character.class, char.class);
+        primitiveMap.put(Double.class, double.class);
+        primitiveMap.put(Float.class, float.class);
+        primitiveMap.put(Integer.class, int.class);
+        primitiveMap.put(Long.class, long.class);
+        primitiveMap.put(Short.class, short.class);
+        primitiveMap.put(Date.class, Date.class);
+    }
+
+    /**
+     * 鍒ゆ柇鍩烘湰绫诲瀷
+     * @see     java.lang.String
+     * @see     java.lang.Boolean#TYPE
+     * @see     java.lang.Character#TYPE
+     * @see     java.lang.Byte#TYPE
+     * @see     java.lang.Short#TYPE
+     * @see     java.lang.Integer#TYPE
+     * @see     java.lang.Long#TYPE
+     * @see     java.lang.Float#TYPE
+     * @see     java.lang.Double#TYPE
+     * @see     java.lang.Boolean#TYPE
+     * @see     byte
+     * @see     short
+     * @see     int
+     * @see     long
+     * @see     float
+     * @see     double
+     * @param clazz 绫�
+     * @return boolean true琛ㄧず涓哄熀鏈被鍨�
+     */
+    public static boolean isPrimitive(Class<?> clazz) {
+        if (primitiveMap.containsKey(clazz)) {
+            return true;
+        }
+        return clazz.isPrimitive();
+    }
+
+    /**
+     * 鑾峰彇鏂规硶杩斿洖鍊肩被鍨�
+     * @param tartget 鐩爣瀵硅薄鐨勭被
+     * @param fieldName 灞炴�х殑鍚嶇О
+     * @return Class<?> 杩斿洖鍊肩被鍨�
+     */
+    public static Class<?> getElementType(Class<?> tartget, String fieldName) {
+        Class<?> elementTypeClass = null;
+        try {
+            Type type = VciBaseUtil.getFieldForObject(fieldName,tartget).getGenericType();
+            ParameterizedType t = (ParameterizedType) type;
+            String classStr = t.getActualTypeArguments()[0].toString().replace("class ", "");
+            if(classStr.contains("<")){
+                classStr = classStr.substring(classStr.lastIndexOf("<") + 1 ,classStr.indexOf(">"));
+            }
+            elementTypeClass = Thread.currentThread().getContextClassLoader().loadClass(classStr);
+        } catch (ClassNotFoundException | SecurityException e) {
+            throw new RuntimeException("get fieldName[" + fieldName + "] error", e);
+        }
+        return elementTypeClass;
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/ControllerUtil.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/ControllerUtil.java
new file mode 100644
index 0000000..876a80b
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/ControllerUtil.java
@@ -0,0 +1,326 @@
+package com.vci.starter.web.util;
+
+import com.vci.starter.web.pagemodel.PageHelper;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.MediaType;
+
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.*;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * 鍦╟ontroller灞備娇鐢ㄧ殑宸ュ叿
+ * @author weidy
+ * @date 2020/2/19
+ */
+public class ControllerUtil {
+
+    /**
+     * 鏃ュ織瀵硅薄
+     */
+    private static Logger logger = LoggerFactory.getLogger(ControllerUtil.class);
+
+    /**
+     * 灏嗘枃浠跺啓鍏ュ埌杩斿洖娴佷腑
+     * @param response 鍝嶅簲瀵硅薄
+     * @param fileName 鏂囦欢鍚嶇О
+     * @throws FileNotFoundException 鏂囦欢娌℃湁鎵惧埌
+     * @throws IOException 璇诲彇鏂囦欢鍑洪敊锛屾垨鑰呭啓鏁版嵁鍑洪敊
+     */
+    public static void writeFileToResponse(HttpServletResponse response,String fileName) throws FileNotFoundException,IOException{
+        writeFileToResponse(response,fileName,true);
+    }
+
+    /**
+     * 灏嗘枃浠跺啓鍏ュ埌杩斿洖娴佷腑
+     * @param response 鍝嶅簲瀵硅薄
+     * @param fileName 鏂囦欢鍚嶇О
+     * @param deleteFile 涓嬭浇瀹屾垚鍚庢槸鍚﹀垹闄ゆ枃浠讹紝true琛ㄧず鍒犻櫎锛屽彟澶栬繖涓枃浠剁殑涓婄骇鏂囦欢澶逛篃浼氳鍒犻櫎锛屽洜姝や复鏃舵枃浠跺す涓�鑸兘娣诲姞浜嗛殢鏈哄悕绉扮殑鏂囦欢澶�
+     * @throws FileNotFoundException 鏂囦欢娌℃湁鎵惧埌
+     * @throws IOException 璇诲彇鏂囦欢鍑洪敊锛屾垨鑰呭啓鏁版嵁鍑洪敊
+     */
+    public static void writeFileToResponse(HttpServletResponse response,String fileName,boolean deleteFile) throws FileNotFoundException,IOException{
+        writeFileToResponse(response,fileName,null,deleteFile);
+    }
+
+    /**
+     * 灏嗘枃浠跺啓鍏ュ埌杩斿洖娴佷腑
+     * @param response 鍝嶅簲瀵硅薄
+     * @param fileName 鏂囦欢鍚嶇О
+     * @param deleteFile 涓嬭浇瀹屾垚鍚庢槸鍚﹀垹闄ゆ枃浠讹紝true琛ㄧず鍒犻櫎锛屽彟澶栬繖涓枃浠剁殑涓婄骇鏂囦欢澶逛篃浼氳鍒犻櫎锛屽洜姝や复鏃舵枃浠跺す涓�鑸兘娣诲姞浜嗛殢鏈哄悕绉扮殑鏂囦欢澶�
+     * @param showName 鏄剧ず鏂囦欢鍚嶏紝鍗崇敤鎴风湅鍒扮殑鍚嶇О锛屽惁鍒欑洿鎺ヤ负鍘熸枃浠剁殑鍚嶇О
+     * @throws FileNotFoundException 鏂囦欢娌℃湁鎵惧埌
+     * @throws IOException 璇诲彇鏂囦欢鍑洪敊锛屾垨鑰呭啓鏁版嵁鍑洪敊
+     */
+    public static void writeFileToResponse(HttpServletResponse response,String fileName,String showName,boolean deleteFile) throws FileNotFoundException,IOException {
+        File file = new File(fileName);
+        if(!file.exists()){
+            throw new FileNotFoundException(fileName);
+        }
+        writeFileToResponse(response,file,showName,deleteFile);
+    }
+
+    /**
+     * 灏嗘枃浠跺啓鍏ュ埌杩斿洖娴佷腑
+     * @param response 鍝嶅簲瀵硅薄
+     * @param file 鏂囦欢瀵硅薄
+     * @throws FileNotFoundException 鏂囦欢娌℃湁鎵惧埌
+     * @throws IOException 璇诲彇鏂囦欢鍑洪敊锛屾垨鑰呭啓鏁版嵁鍑洪敊
+     */
+    public static void writeFileToResponse(HttpServletResponse response, File file) throws FileNotFoundException,IOException{
+        writeFileToResponse(response,file,true);
+    }
+
+    /**
+     * 灏嗘枃浠跺啓鍏ュ埌杩斿洖娴佷腑
+     * @param response 鍝嶅簲瀵硅薄
+     * @param file 鏂囦欢瀵硅薄
+     * @param deleteFile 涓嬭浇瀹屾垚鍚庢槸鍚﹀垹闄ゆ枃浠讹紝true琛ㄧず鍒犻櫎锛屽彟澶栬繖涓枃浠剁殑涓婄骇鏂囦欢澶逛篃浼氳鍒犻櫎锛屽洜姝や复鏃舵枃浠跺す涓�鑸兘娣诲姞浜嗛殢鏈哄悕绉扮殑鏂囦欢澶�
+     * @throws FileNotFoundException 鏂囦欢娌℃湁鎵惧埌
+     * @throws IOException 璇诲彇鏂囦欢鍑洪敊锛屾垨鑰呭啓鏁版嵁鍑洪敊
+     */
+    public static void writeFileToResponse(HttpServletResponse response,File file,boolean deleteFile) throws FileNotFoundException,IOException{
+        writeFileToResponse(response,file,null,deleteFile);
+    }
+
+    /**
+     * 灏嗘枃浠跺啓鍏ュ埌杩斿洖娴佷腑
+     * @param response 鍝嶅簲瀵硅薄
+     * @param file 鏂囦欢瀵硅薄
+     * @param deleteFile 涓嬭浇瀹屾垚鍚庢槸鍚﹀垹闄ゆ枃浠讹紝true琛ㄧず鍒犻櫎锛屽彟澶栬繖涓枃浠剁殑涓婄骇鏂囦欢澶逛篃浼氳鍒犻櫎锛屽洜姝や复鏃舵枃浠跺す涓�鑸兘娣诲姞浜嗛殢鏈哄悕绉扮殑鏂囦欢澶�
+     * @param showName 鏄剧ず鏂囦欢鍚嶏紝鍗崇敤鎴风湅鍒扮殑鍚嶇О锛屽惁鍒欑洿鎺ヤ负鍘熸枃浠剁殑鍚嶇О
+     * @throws FileNotFoundException 鏂囦欢娌℃湁鎵惧埌
+     * @throws IOException 璇诲彇鏂囦欢鍑洪敊锛屾垨鑰呭啓鏁版嵁鍑洪敊
+     */
+    public static void writeFileToResponse(HttpServletResponse response,File file,String showName,boolean deleteFile) throws FileNotFoundException,IOException {
+        writeFileToResponse(response,file,showName,deleteFile,null);
+    }
+    /**
+     * 灏嗘枃浠跺啓鍏ュ埌杩斿洖娴佷腑
+     * @param response 鍝嶅簲瀵硅薄
+     * @param file 鏂囦欢瀵硅薄
+     * @param deleteFile 涓嬭浇瀹屾垚鍚庢槸鍚﹀垹闄ゆ枃浠讹紝true琛ㄧず鍒犻櫎锛屽彟澶栬繖涓枃浠剁殑涓婄骇鏂囦欢澶逛篃浼氳鍒犻櫎锛屽洜姝や复鏃舵枃浠跺す涓�鑸兘娣诲姞浜嗛殢鏈哄悕绉扮殑鏂囦欢澶�
+     * @param showName 鏄剧ず鏂囦欢鍚嶏紝鍗崇敤鎴风湅鍒扮殑鍚嶇О锛屽惁鍒欑洿鎺ヤ负鍘熸枃浠剁殑鍚嶇О
+     * @throws FileNotFoundException 鏂囦欢娌℃湁鎵惧埌
+     * @throws IOException 璇诲彇鏂囦欢鍑洪敊锛屾垨鑰呭啓鏁版嵁鍑洪敊
+     */
+    public static void writeFileToResponse(HttpServletResponse response,File file,String showName,boolean deleteFile,String contentType) throws FileNotFoundException,IOException {
+        VciBaseUtil.alertNotNull(file, "鏂囦欢瀵硅薄");
+        if (!file.exists()) {
+            throw new FileNotFoundException(file.getName());
+        }
+        if (StringUtils.isBlank(showName)) {
+            showName = file.getName();
+        }
+        InputStream in = null;
+        try {
+            in = new FileInputStream(file);
+            writeFileToResponse(response, in, showName, contentType);
+        } catch (IOException e) {
+            //鏈夊彲鑳藉鎴风鐨勯摼鎺�
+            if (logger.isErrorEnabled()) {
+                logger.error("鍐欏叆鏂囦欢鍒板搷搴旀祦鍑洪敊", e);
+            }
+        } finally {
+            IOUtils.closeQuietly(in);
+            if (deleteFile) {
+                File parentFile = file.getParentFile();
+                file.delete();
+                parentFile.delete();
+            }
+        }
+    }
+
+
+    /**
+     * 灏嗚緭鍏ユ祦鍐欏叆鍒拌繑鍥炴祦涓�
+     * @param response  鍝嶅簲瀵硅薄
+     * @param ins 杈撳叆娴�
+     * @param showName 鍚嶇О
+     * @throws IOException 鎷疯礉鍑洪敊鐨勬椂鍊欎細鎶涘嚭寮傚父
+     */
+    public static void writeFileToResponse(HttpServletResponse response,InputStream ins,String showName) throws IOException{
+        writeFileToResponse(response,ins,showName,null);
+    }
+
+    /**
+     * 灏嗚緭鍏ユ祦鍐欏叆鍒拌繑鍥炴祦涓�
+     * @param response  鍝嶅簲瀵硅薄
+     * @param ins 杈撳叆娴�
+     * @param showName 鍚嶇О
+     * @throws IOException 鎷疯礉鍑洪敊鐨勬椂鍊欎細鎶涘嚭寮傚父
+     */
+    public static void writeFileToResponse(HttpServletResponse response,InputStream ins,String showName,String contentType ) throws IOException{
+        if(StringUtils.isBlank(contentType)) {
+            contentType = "application/force-download";
+        }
+        if(StringUtils.isBlank(showName)){
+            showName = "涓嬭浇鏂囦欢";
+        }
+        // 璁剧疆寮哄埗涓嬭浇涓嶆墦寮�
+        response.setContentType(contentType);
+        try{
+            String fileName = URLEncoder.encode(showName, "UTF8");
+            response.addHeader("Content-Disposition", "attachment; filename="+ fileName+ ";filename*=utf-8''" + fileName);
+        }catch(Exception e){
+            if(logger.isErrorEnabled()){
+                logger.error("璁剧疆鏂囦欢鐨勫悕绉板埌鍝嶅簲娴佺殑鏃跺�欏嚭閿�",e);
+            }
+        }
+        response.setCharacterEncoding("UTF-8");
+        Cookie cookie = new Cookie("fileDownload", "true");
+        cookie.setPath("/");
+        response.addCookie(cookie);
+        try{
+            IOUtils.copy(ins,response.getOutputStream());
+        } catch (IOException e) {
+            //鏈夊彲鑳藉鎴风鐨勯摼鎺�
+            if(logger.isErrorEnabled()){
+                logger.error("鍐欏叆鏂囦欢鍒板搷搴旀祦鍑洪敊",e);
+            }
+            throw e;
+        }finally {
+
+            IOUtils.closeQuietly(ins);
+        }
+    }
+
+    /**
+     * 灏嗚緭鍏ユ祦鍐欏叆鍒拌繑鍥炴祦涓�
+     * @param response  鍝嶅簲瀵硅薄
+     * @param data 鏁版嵁鐨勪俊鎭�
+     * @throws IOException 鎷疯礉鍑洪敊鐨勬椂鍊欎細鎶涘嚭寮傚父
+     */
+    public static void writeDataToResponse(HttpServletResponse response,byte[] data,String contentType) throws IOException {
+        if (StringUtils.isBlank(contentType)) {
+            contentType = "application/force-download";
+        }
+        response.setContentType(contentType);
+        response.setCharacterEncoding("UTF-8");
+        Cookie cookie = new Cookie("fileDownload", "true");
+        cookie.setPath("/");
+        response.addCookie(cookie);
+        try {
+            response.getOutputStream().write(data);
+        } catch (IOException e) {
+            //鏈夊彲鑳藉鎴风鐨勯摼鎺�
+            if (logger.isErrorEnabled()) {
+                logger.error("鍐欏叆鏂囦欢鍒板搷搴旀祦鍑洪敊", e);
+            }
+            throw e;
+        }
+    }
+    /**
+     * 灏嗙幆澧冨彉閲忎腑鐨勬煇涓枃浠跺啓鍒拌繑鍥炴祦涓�
+     * @param response 鍝嶅簲瀵硅薄
+     * @param classPathFileName 鍦ㄧ幆澧冨彉閲忛噷鐨勬枃浠跺悕绉�
+     * @throws FileNotFoundException 鏂囦欢娌℃湁鎵惧埌
+     * @throws IOException 璇诲彇鏂囦欢鍑洪敊锛屾垨鑰呭啓鏁版嵁鍑洪敊
+     */
+    public static void writeClasspathFileToResponse(HttpServletResponse response,String classPathFileName) throws FileNotFoundException,IOException{
+        writeClasspathFileToResponse(response,classPathFileName,null);
+    }
+
+    /**
+     * 灏嗙幆澧冨彉閲忎腑鐨勬煇涓枃浠跺啓鍒拌繑鍥炴祦涓�
+     * @param response 鍝嶅簲瀵硅薄
+     * @param classPathFileName 鍦ㄧ幆澧冨彉閲忛噷鐨勬枃浠跺悕绉�
+     * @param showName 鏄剧ず鍚嶇О
+     * @throws FileNotFoundException 鏂囦欢娌℃湁鎵惧埌
+     * @throws IOException 璇诲彇鏂囦欢鍑洪敊锛屾垨鑰呭啓鏁版嵁鍑洪敊
+     */
+    public static void writeClasspathFileToResponse(HttpServletResponse response,String classPathFileName,String showName) throws FileNotFoundException,IOException{
+        InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(classPathFileName);
+        if(StringUtils.isBlank(showName)){
+            showName = classPathFileName.contains("/")?classPathFileName.substring(classPathFileName.lastIndexOf("/") + 1):classPathFileName;
+        }
+        try {
+            writeFileToResponse(response, in, showName);
+        }catch (IOException e){
+            throw e;
+        }finally {
+            IOUtils.closeQuietly(in);
+        }
+    }
+
+    /**
+     * 鑾峰彇IP鍦板潃锛岄�氳繃request
+     * @param request http璇锋眰瀵硅薄
+     * @return ip鍦板潃
+     */
+    public static String getClientInfo(HttpServletRequest request){
+        String ip = request.getHeader("X-Forwarded-For");
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("Proxy-Client-IP");
+        }
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("WL-Proxy-Client-IP");
+        }
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("HTTP_CLIENT_IP");
+        }
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
+        }
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getRemoteAddr();
+        }
+        if (ip == null || ip.length() == 0 || ip.indexOf("0:0:0:0:0:0:0:1") >-1) {//0:0:0:0:0:0:0:1鏄湰鏈哄湪璁块棶
+            ip = "127.0.0.1";
+        }
+        return ip;
+    }
+
+    /**
+     * 涓嬭浇閿欒鏂囦欢鐨勬槧灏勫唴瀹�
+     */
+    public static final Map<String/**涓婚敭**/,String/**鏂囦欢璺緞**/> tempFileForDownloadMap = new ConcurrentHashMap<>();
+
+
+    /**
+     * 璁剧疆鏌ヨ鎬绘暟
+     * @param request 璇锋眰瀵硅薄
+     * @param isQueryTotal 鏄惁鏌ヨ鎬绘暟
+     */
+    public static void setQueryTotal(HttpServletRequest request, boolean isQueryTotal){
+        WebThreadLocalUtil.getNeedQueryTotalInThread().set(isQueryTotal?"true":"false");
+        //request.setAttribute(webProperties.getQueryTotalSessionName(), isQueryTotal);
+    }
+
+    /**
+     * 鏀剧疆閿欒鐨勬枃浠�
+     * @param errorFile 閿欒鐨勬枃浠�
+     * @return 鍞竴鏍囪瘑
+     */
+    public static String putErrorFile(String errorFile){
+        String uuid = VciBaseUtil.getPk();
+        tempFileForDownloadMap.put(uuid,errorFile);
+        return uuid;
+    }
+
+    /**
+     * 涓嬭浇閿欒鐨勬枃浠�(浠呴檺浜巈xcel)
+     * @param response 鍝嶅簲瀵硅薄
+     * @param uuid 鍞竴鐨勬爣璇�
+     * @throws IOException 鍐欏叆鏂囦欢鍑洪敊鐨勬椂鍊欐姏鍑哄紓甯�
+     */
+    public static void downloadErrorFile(HttpServletResponse response,String uuid) throws IOException{
+        String errorFile = tempFileForDownloadMap.getOrDefault(uuid, "");
+        try {
+            if (StringUtils.isNotBlank(errorFile)) {
+                ControllerUtil.writeFileToResponse(response, new File(errorFile), null, true, "application/msexcel");
+            }
+        }finally {
+            tempFileForDownloadMap.remove(uuid);
+        }
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/LangBaseUtil.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/LangBaseUtil.java
new file mode 100644
index 0000000..6610ebc
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/LangBaseUtil.java
@@ -0,0 +1,41 @@
+package com.vci.starter.web.util;
+
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * 澶氳鐩稿叧鐨勫伐鍏风被
+ * @author weidy
+ */
+public class LangBaseUtil {
+    /**
+     * 鑾峰彇寮傚父淇℃伅
+     * @param e 寮傚父瀵硅薄
+     * @return 寮傚父瀵硅薄涓婄殑鎵�鏈夊唴瀹�
+     */
+    public static String getErrorMsg(Throwable e){
+        if(e == null){
+            return "鏈煡閿欒";
+        }
+        if( e.getClass()!= null && e.getClass().getSuperclass()!= null &&
+                (e.getClass().getSuperclass().equals(RuntimeException.class)
+                        || e.getClass().getSuperclass().getName().endsWith(".VciBaseException")
+                        || e.getClass().getName().endsWith(".VciBaseException"))){
+            //璇存槑鏄垜浠嚜瀹氫箟鐨勫紓甯哥被
+            try {
+                Method errorMethod = e.getClass().getMethod("getErrorMsg");
+                if(errorMethod != null ){
+                    return (String)errorMethod.invoke(e);
+                }
+            } catch (NoSuchMethodException e1) {
+                return e.getMessage();
+            } catch (IllegalAccessException e1) {
+                return e.getMessage();
+            } catch (InvocationTargetException e1) {
+                return e.getMessage();
+            }
+        }
+        return e.getMessage();
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/LocalFileUtil.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/LocalFileUtil.java
new file mode 100644
index 0000000..32250ec
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/LocalFileUtil.java
@@ -0,0 +1,386 @@
+package com.vci.starter.web.util;
+
+import com.vci.starter.web.exception.VciBaseException;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.boot.system.ApplicationHome;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.util.ResourceUtils;
+
+import java.io.*;
+import java.nio.channels.FileChannel;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.UUID;
+
+/**
+ * 鏈湴鏂囦欢鎿嶄綔绫�
+ * @author weidy
+ */
+public class LocalFileUtil {
+
+	/**
+	 * 涓荤被
+	 */
+	public static Class mainClass = null;
+	/**
+	 * 鍒犻櫎鏂囦欢澶�
+	 * @param file 瑕佸垹闄ょ殑鏂囦欢鎴栬�呮枃浠跺す
+	 */
+	public static void deleteFile(File file) {
+		if(file == null || !file.exists()){
+			return;
+		}
+		if (file.isDirectory()) {
+			File[] files = file.listFiles();
+			for (int i = 0; i < files.length; i++) {
+				deleteFile(files[i]);
+			}
+		}
+		file.delete();
+	}
+
+	/**
+	 * 鎷疯礉鏂囦欢
+	 * @param source 婧愭枃浠�
+	 * @param target 鐩爣鏂囦欢
+	 * @throws VciBaseException 鎷疯礉鏂囦欢鍑洪敊鐨勬椂鍊欎細鎶涘嚭寮傚父
+	 */
+	public static void copyFile(File source, File target) throws VciBaseException {
+		FileInputStream is = null;
+		FileOutputStream os = null;
+		try{
+			is = new FileInputStream(source);
+			os = new FileOutputStream(target);
+			FileChannel sourceChannel = is.getChannel();
+			FileChannel targetChannel = os.getChannel();
+			int i=0;
+			int length=2097152;
+			while(true){
+				if(sourceChannel.position()==sourceChannel.size()){
+					sourceChannel.close();
+					targetChannel.close();
+					break;
+				}
+				if((sourceChannel.size()-sourceChannel.position())<20971520) {
+					length = (int) (sourceChannel.size() - sourceChannel.position());
+				}else {
+					length = 20971520;
+				}
+				sourceChannel.transferTo(sourceChannel.position(),length,targetChannel);
+				sourceChannel.position(sourceChannel.position()+length);
+				i++;
+			}
+		}catch(Throwable e){
+			throw new VciBaseException("鎷疯礉鏂囦欢鍑洪敊",new String[0],e);
+		}finally {
+			IOUtils.closeQuietly(is);
+			IOUtils.closeQuietly(os);
+		}
+	}
+
+	/**
+	 * 鑾峰彇榛樿鐨勪复鏃舵枃浠跺す
+	 * @return 涓存椂鏂囦欢澶癸紝榛樿涓哄綋鍓嶉」鐩殑杩愯璺緞涓嬬殑tempFolder涓嬬殑闅忔満鍊�
+	 */
+	public static String getDefaultTempFolder() throws VciBaseException{
+		String path = getProjectFolder();
+		path = path + File.separator + "tempFolder" + File.separator + UUID.randomUUID().toString();
+		File folder = new File(path);
+		if(!folder.exists()){
+			folder.mkdirs();
+		}
+		return path;
+	}
+
+	/**
+	 * 鑾峰彇椤圭洰鐨勮矾寰�
+	 * @return 椤圭洰鐨勮矾寰�
+	 * @throws VciBaseException 鑾峰彇璺緞鍑虹幇浜嗛敊璇細鎶涘嚭寮傚父
+	 */
+	public static String getProjectFolder() throws VciBaseException{
+		return getProjectFolder(LocalFileUtil.class);
+	}
+
+	/**
+	 * 鑾峰彇鏌愪釜class鎵�鍦ㄩ」鐩殑璺緞
+	 * @param classObj 鏌愪釜class
+	 * @return 椤圭洰鐨勮矾寰�
+	 * @throws VciBaseException 鑾峰彇璺緞鍑虹幇浜嗛敊璇細鎶涘嚭寮傚父
+	 */
+	public static String getProjectFolder(Class classObj) throws VciBaseException{
+		String path = "";
+		try {
+			ApplicationHome h = new ApplicationHome(classObj == null?(mainClass ==null?LocalFileUtil.class:mainClass):classObj);
+			File jarF = h.getSource();
+			if(jarF == null){
+				//閽堝娴嬭瘯鐨勬椂鍊�
+				jarF = h.getDir();
+			}
+			path =  jarF.getParentFile().toString();
+			if(path.contains("!")){
+				path = new File(path).getParentFile().getParent();
+			}
+		}catch (Throwable e){
+			e.printStackTrace();
+			throw new VciBaseException("鑾峰彇褰撳墠鏈嶅姟鎵�鍦ㄧ殑鏂囦欢澶瑰嚭鐜颁簡閿欒",new String[0],e);
+		}
+		if(path.startsWith("file:\\")){
+			path = path.substring(6);
+		}
+		if (System.getProperty("os.name").toLowerCase().startsWith("win") && path.startsWith("/")) {
+			path = path.substring(path.indexOf("/") + 1);
+		}
+		System.out.println("椤圭洰鐨勮矾寰勬槸:" + path);
+		return path;
+	}
+
+	/**
+	 * 鍒犻櫎涓存椂鏂囦欢
+	 * @param tempFile 涓存椂鏂囦欢
+	 * @param deleteRandomFolder 鏄惁鍒犻櫎闅忔満鐨勯偅涓枃浠跺す
+	 * @throws VciBaseException 鍒犻櫎鍑洪敊鐨勬椂鍊欐姏鍑哄紓甯�
+	 */
+	public static void deleteTempFile(File tempFile,boolean deleteRandomFolder) throws VciBaseException{
+		if(tempFile!=null){
+			tempFile.delete();
+			if(deleteRandomFolder){
+				tempFile.getParentFile().delete();
+			}
+		}
+	}
+
+
+	/**
+	 * 鍒ゆ柇鍙傛暟鏄惁涓虹┖
+	 * @param s 鍙傛暟锛岀涓�涓负鍙傛暟锛岀浜屼釜涓烘彁绀轰俊鎭�
+	 * @throws VciBaseException 涓虹┖鏃舵姏鍑鸿繖涓紓甯�
+	 */
+	public static void alertNotNull(Object... s) throws VciBaseException{
+		if(s!=null && s.length>0){
+			for(int i = 0 ; i < s.length ; i ++){
+				Object obj = s[i];
+				if(obj==null ||StringUtils.isBlank(obj.toString())){
+					String param = "";
+					try{
+						i++;
+						param = s[i].toString();
+					}catch(Exception e){
+
+					}
+					throw new VciBaseException("鍙傛暟[" + param + "]涓嶈兘涓虹┖");
+				}
+			}
+		}
+	}
+
+	/**
+	 * 鑾峰彇鏂囦欢鐨勫悗缂�鍚�
+	 * @param file 鏂囦欢瀵硅薄
+	 * @return 鍚庣紑鍚嶏紝涓嶅寘鍚�.锛涘鏋滄枃浠朵笉瀛樺湪鎴栬�呮病鏈夊悗缂�鍚嶈繑鍥�""
+	 */
+	public static String getFileExtension(File file){
+		if(file!=null){
+			return getFileExtensionByName(file.getName());
+		}
+		return "";
+	}
+
+	/**
+	 * 鑾峰彇鏂囦欢鐨勫悗缂�鍚�
+	 * @param name 鏂囦欢鍚嶇О
+	 * @return 鍚庣紑鍚嶏紝涓嶅寘鍚�.锛涙病鏈夊悗缂�鍚嶈繑鍥�""
+	 */
+	public static String getFileExtensionByName(String name){
+		if(StringUtils.isNotBlank(name)){
+			if(name.contains(".")){
+				return name.substring(name.lastIndexOf(".")+1);
+			}
+		}
+		return "";
+	}
+
+	/**
+	 * 鑾峰彇涓婁紶鏂囦欢鐨勫悕绉帮紝鍦↖E娴忚鍣ㄤ笂锛屼笂浼犱細鎶婂叏璺緞甯﹁繃鏉�
+	 * @param name 鏂囦欢鐨勫悕绉�
+	 * @return 鏇挎崲鍚庣殑鍊�
+	 */
+	public static String getFileNameForIE(String name){
+		if(StringUtils.isBlank(name)){
+			return name;
+		}
+		if(name.contains(File.separator)){
+			return name.substring(name.lastIndexOf(File.separator)+1);
+		}
+		if(name.contains("\\")){
+			return name.substring(name.lastIndexOf("\\") + 1);
+		}
+		return name;
+	}
+
+	/**
+	 * 浠庡伐绋嬩腑璇诲彇鏂囦欢鐨勫唴瀹�
+	 * @param fileName 鏂囦欢鐨勫悕绉�
+	 * @return 鏂囦欢鐨勫唴瀹�
+	 * @throws VciBaseException 璇诲彇鍑洪敊鐨勬椂鍊欎細鎶涘嚭寮傚父
+	 */
+	public static String readContentForFileInJar(String fileName) throws VciBaseException{
+		if(StringUtils.isBlank(fileName)){
+			throw new VciBaseException("鏂囦欢鍚嶄负绌�");
+		}
+		if(!fileName.startsWith("/")){
+			fileName = "/" + fileName;
+		}
+		InputStream in = null;
+		ByteArrayOutputStream os = null;
+		try{
+			in = LocalFileUtil.class.getResourceAsStream( fileName);
+			if(in ==null){
+				in=Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName);
+			}
+			os = new ByteArrayOutputStream();
+			IOUtils.copy(in,os);
+			return new String(os.toByteArray(),"UTF-8");
+		}catch (Throwable e){
+			throw new VciBaseException("璇诲彇鏂囦欢鐨勫唴瀹瑰嚭鐜颁簡閿欒",new String[0],e);
+		}finally {
+			IOUtils.closeQuietly(in);
+			IOUtils.closeQuietly(os);
+		}
+	}
+
+	/**
+	 * 璇诲彇鏂囦欢鐨勫唴瀹癸紝鏂囦欢涓嶈兘鏄痡ar閲岀殑
+	 * @param fileName 鏂囦欢鐨勫悕绉�
+	 * @return 鏂囦欢鐨勫唴瀹癸紝鏄疷TF-8鐨勫瓧绗﹂泦
+	 * @throws VciBaseException 鏂囦欢涓嶅瓨鍦紝鍜岃鍙栧嚭閿欑殑鏃跺�欎細鎶涘嚭寮傚父
+	 */
+	public static String readContentForFile(String fileName) throws VciBaseException{
+		File file = new File(fileName);
+		if(!file.exists()){
+			throw new VciBaseException("鏂囦欢鏈壘鍒帮紝{0}",new String[]{fileName});
+		}
+		InputStream in = null;
+		ByteArrayOutputStream os = null;
+		try{
+			in = new FileInputStream( file);
+			os = new ByteArrayOutputStream();
+			IOUtils.copy(in,os);
+			return new String(os.toByteArray(),"UTF-8");
+		}catch (Throwable e){
+			throw new VciBaseException("璇诲彇鏂囦欢鐨勫唴瀹瑰嚭鐜颁簡閿欒",new String[0],e);
+		}finally {
+			IOUtils.closeQuietly(in);
+			IOUtils.closeQuietly(os);
+		}
+	}
+
+	/**
+	 * 鍐欏叆瀛楃涓插埌鏂囦欢
+	 * @param content 瀛楃涓�
+	 * @param fileName 鏂囦欢鐨勫悕绉�
+	 * @throws VciBaseException 鍐欏叆鍑洪敊鐨勬椂鍊欎細鎶涘嚭寮傚父
+	 */
+	public static void writeContentToFile(String content,String fileName) throws VciBaseException{
+		File file = new File(fileName);
+		if(!file.exists()){
+			File parentFile = file.getParentFile();
+			if(!parentFile.exists()){
+				parentFile.mkdirs();
+			}
+			try {
+				file.createNewFile();
+			} catch (IOException e) {
+				throw new VciBaseException("鍐欏叆鏂囦欢鐨勫唴瀹规椂鍊欏嚭鐜颁簡鍒涘缓鏂囦欢澶辫触鐨勯棶棰�,{}",new String[]{fileName},e);
+			}
+		}
+		if(content == null){
+			content = "";
+		}
+		OutputStream os = null;
+		try{
+			os = new FileOutputStream(file);
+			os.write(content.getBytes(StandardCharsets.UTF_8));
+			os.flush();
+		}catch(Throwable e){
+			throw new VciBaseException("鍐欏叆鏂囦欢鐨勫唴瀹规椂鍊欏嚭鐜颁簡鍒涢敊璇�,{}",new String[]{fileName},e);
+		}finally {
+			IOUtils.closeQuietly(os);
+		}
+	}
+
+	/**
+	 * 浠庨」鐩噷鎴栬�卝ar鐨勬枃浠跺埌鐩爣鏂囦欢
+	 * @param fileInJar jar鎴栬�呴」鐩噷鐨勬枃浠跺悕绉�
+	 * @param target 鐩爣鏂囦欢
+	 * @throws VciBaseException 鎷疯礉鏂囦欢鍑虹幇閿欒鐨勬椂鍊欎細鎶涘嚭寮傚父
+	 */
+	public static void copyFileInJar(String fileInJar,String target) throws  VciBaseException{
+		VciBaseUtil.alertNotNull(fileInJar,"婧愭枃浠�",target,"鐩爣鏂囦欢");
+		File targetFile = new File(target);
+		File folder = targetFile.getParentFile();
+		if(!folder.exists()){
+			folder.mkdirs();
+		}
+		if(!targetFile.exists()){
+			try {
+				targetFile.createNewFile();
+			} catch (IOException e) {
+				throw new VciBaseException("鍒涘缓鐩爣鏂囦欢鐨勫嚭鐜颁簡閿欒",new String[0],e);
+			}
+		}
+		if(!fileInJar.startsWith("/")){
+			fileInJar = "/" + fileInJar;
+		}
+		InputStream in = null;
+		FileOutputStream os = null;
+		try{
+			in =  LocalFileUtil.class.getResourceAsStream( fileInJar);
+			if(in ==null){
+				in=Thread.currentThread().getContextClassLoader().getResourceAsStream(fileInJar);
+			}
+			os = new FileOutputStream(target);
+			IOUtils.copy(in,os);
+		}catch (Throwable e){
+			throw new VciBaseException("鎷疯礉鏂囦欢鐨勫唴瀹瑰嚭鐜颁簡閿欒.{0},{1}",new String[]{fileInJar,target},e);
+		}finally {
+			IOUtils.closeQuietly(in);
+			IOUtils.closeQuietly(os);
+		}
+	}
+
+	/**
+	 * 鏂囦欢杞崲涓鸿矾寰�
+	 * @param fileList 鏂囦欢鍒楄〃
+	 * @return 璺緞鍒楄〃
+	 * @throws VciBaseException 鍙傛暟涓虹┖鍜屾枃浠朵笉瀛樺湪浼氭姏鍑哄紓甯�
+	 */
+	public static List<String> fileToPatch(Collection<File> fileList) throws VciBaseException  {
+		VciBaseUtil.alertNotNull("鏂囦欢鍒楄〃",fileList);
+		List<String> filePath = new ArrayList<>();
+		for(File file : fileList){
+			if(!file.exists()){
+				throw new VciBaseException(file.getAbsolutePath() + "鏂囦欢娌℃湁鎵惧埌",new String[0]);
+			}
+			filePath.add(file.getAbsolutePath());
+		}
+		return filePath;
+	}
+
+	/**
+	 * 鑾峰彇鍥剧墖涓撶敤鐨勪复鏃惰矾寰�
+	 * @return 璺緞
+	 * @throws VciBaseException 鑾峰彇鍑洪敊浼氭姤閿�
+	 */
+	public static String getDefaultPicTempFolder() throws VciBaseException{
+		String path = LocalFileUtil.getProjectFolder();
+		path = path + File.separator + "tempFolder" + File.separator + "picFolder" + File.separator ;
+		File folder = new File(path);
+		if(!folder.exists()){
+			folder.mkdirs();
+		}
+		return path;
+	}
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/Lunar.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/Lunar.java
new file mode 100644
index 0000000..79aab0b
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/Lunar.java
@@ -0,0 +1,282 @@
+package com.vci.starter.web.util;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+
+/**
+ * 鍐滃巻杞崲
+ * @author weidy
+ * @date
+ */
+public class Lunar {
+	/**
+	 * 骞�
+	 */
+	private int year;
+	/**
+	 * 鏈堜唤
+	 */
+	private int month;
+	/**
+	 * 澶╂暟
+	 */
+	private int day;
+	/**
+	 *
+	 */
+	private boolean leap;
+	/**
+	 * 鏈堜唤
+	 */
+	final static String chineseNumber[] = { "涓�", "浜�", "涓�", "鍥�", "浜�", "鍏�", "涓�",
+			"鍏�", "涔�", "鍗�", "鍗佷竴", "鍗佷簩" };
+	/**
+	 * 鏃堕棿鏍煎紡
+	 */
+	static SimpleDateFormat chineseDateFormat = new SimpleDateFormat(
+			"yyyy骞碝M鏈坉d鏃�");
+	/**
+	 * 鍐滃巻鐨勪俊鎭�
+	 */
+	final static long[] lunarInfo = new long[] { 0x04bd8, 0x04ae0, 0x0a570,
+			0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2,
+			0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0,
+			0x0ada2, 0x095b0, 0x14977, 0x04970, 0x0a4b0, 0x0b4b5, 0x06a50,
+			0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, 0x06566,
+			0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0,
+			0x1c8d7, 0x0c950, 0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4,
+			0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, 0x06ca0, 0x0b550,
+			0x15355, 0x04da0, 0x0a5d0, 0x14573, 0x052d0, 0x0a9a8, 0x0e950,
+			0x06aa0, 0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260,
+			0x0f263, 0x0d950, 0x05b57, 0x056a0, 0x096d0, 0x04dd5, 0x04ad0,
+			0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b5a0, 0x195a6,
+			0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40,
+			0x0af46, 0x0ab60, 0x09570, 0x04af5, 0x04970, 0x064b0, 0x074a3,
+			0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, 0x092e0, 0x0c960,
+			0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0,
+			0x092d0, 0x0cab5, 0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9,
+			0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, 0x07954, 0x06aa0,
+			0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65,
+			0x0d530, 0x05aa0, 0x076a3, 0x096d0, 0x04bd7, 0x04ad0, 0x0a4d0,
+			0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, 0x0b5a0, 0x056d0, 0x055b2,
+			0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0 };
+
+	/**
+	 * 	====== 浼犲洖鍐滃巻 y骞寸殑鎬诲ぉ鏁�
+	 */
+	final private static int yearDays(int y) {
+		int i, sum = 348;
+		for (i = 0x8000; i > 0x8; i >>= 1) {
+			if ((lunarInfo[y - 1900] & i) != 0) {
+				sum += 1;
+			}
+		}
+		return (sum + leapDays(y));
+	}
+
+	/**
+	 * 	====== 浼犲洖鍐滃巻 y骞撮棸鏈堢殑澶╂暟
+	 */
+	final private static int leapDays(int y) {
+		if (leapMonth(y) != 0) {
+			if ((lunarInfo[y - 1900] & 0x10000) != 0) {
+				return 30;
+			}
+			else {
+				return 29;
+			}
+		} else {
+			return 0;
+		}
+	}
+
+	/**
+	 *  ====== 浼犲洖鍐滃巻 y骞撮棸鍝釜鏈� 1-12 , 娌¢棸浼犲洖 0
+	 *
+	 */
+	final private static int leapMonth(int y) {
+		return (int) (lunarInfo[y - 1900] & 0xf);
+	}
+
+	/**
+	 * ====== 浼犲洖鍐滃巻 y骞磎鏈堢殑鎬诲ぉ鏁�
+	 *
+	 * @param y
+	 * @param m
+	 * @return
+	 */
+	final private static int monthDays(int y, int m) {
+		if ((lunarInfo[y - 1900] & (0x10000 >> m)) == 0) {
+			return 29;
+		}
+		else {
+			return 30;
+		}
+	}
+
+	// ====== 浼犲洖鍐滃巻 y骞寸殑鐢熻倴
+	final public String animalsYear() {
+		final String[] Animals = new String[] { "榧�", "鐗�", "铏�", "鍏�", "榫�", "铔�",
+				"椹�", "缇�", "鐚�", "楦�", "鐙�", "鐚�" };
+		return Animals[(year - 4) % 12];
+	}
+
+	// ====== 浼犲叆 鏈堟棩鐨刼ffset 浼犲洖骞叉敮, 0=鐢插瓙
+	final private static String cyclicalm(int num) {
+		final String[] Gan = new String[] { "鐢�", "涔�", "涓�", "涓�", "鎴�", "宸�", "搴�",
+				"杈�", "澹�", "鐧�" };
+		final String[] Zhi = new String[] { "瀛�", "涓�", "瀵�", "鍗�", "杈�", "宸�", "鍗�",
+				"鏈�", "鐢�", "閰�", "鎴�", "浜�" };
+		return (Gan[num % 10] + Zhi[num % 12]);
+	}
+
+	// ====== 浼犲叆 offset 浼犲洖骞叉敮, 0=鐢插瓙
+	final public String cyclical() {
+		int num = year - 1900 + 36;
+		return (cyclicalm(num));
+	}
+
+	/**
+	 * 浼犲嚭y骞磎鏈坉鏃ュ搴旂殑鍐滃巻. yearCyl3:鍐滃巻骞翠笌1864鐨勭浉宸暟 ? monCyl4:浠�1900骞�1鏈�31鏃ヤ互鏉�,闂版湀鏁�
+	 * dayCyl5:涓�1900骞�1鏈�31鏃ョ浉宸殑澶╂暟,鍐嶅姞40 ?
+	 * 
+	 * @param cal
+	 * @return
+	 */
+	public Lunar(Calendar cal) {
+		@SuppressWarnings("unused")
+		int yearCyl, monCyl, dayCyl;
+		int leapMonth = 0;
+		Date baseDate = null;
+		try {
+			baseDate = chineseDateFormat.parse("1900骞�1鏈�31鏃�");
+		} catch (ParseException e) {
+			e.printStackTrace(); // To change body of catch statement use
+									// Options | File Templates.
+		}
+
+		// 姹傚嚭鍜�1900骞�1鏈�31鏃ョ浉宸殑澶╂暟
+		int offset = (int) ((cal.getTime().getTime() - baseDate.getTime()) / 86400000L);
+		dayCyl = offset + 40;
+		monCyl = 14;
+
+		// 鐢╫ffset鍑忓幓姣忓啘鍘嗗勾鐨勫ぉ鏁�
+		// 璁$畻褰撳ぉ鏄啘鍘嗙鍑犲ぉ
+		// i鏈�缁堢粨鏋滄槸鍐滃巻鐨勫勾浠�
+		// offset鏄綋骞寸殑绗嚑澶�
+		int iYear, daysOfYear = 0;
+		for (iYear = 1900; iYear < 2050 && offset > 0; iYear++) {
+			daysOfYear = yearDays(iYear);
+			offset -= daysOfYear;
+			monCyl += 12;
+		}
+		if (offset < 0) {
+			offset += daysOfYear;
+			iYear--;
+			monCyl -= 12;
+		}
+		// 鍐滃巻骞翠唤
+		year = iYear;
+
+		yearCyl = iYear - 1864;
+		leapMonth = leapMonth(iYear); // 闂板摢涓湀,1-12
+		leap = false;
+
+		// 鐢ㄥ綋骞寸殑澶╂暟offset,閫愪釜鍑忓幓姣忔湀锛堝啘鍘嗭級鐨勫ぉ鏁帮紝姹傚嚭褰撳ぉ鏄湰鏈堢殑绗嚑澶�
+		int iMonth, daysOfMonth = 0;
+		for (iMonth = 1; iMonth < 13 && offset > 0; iMonth++) {
+			// 闂版湀
+			if (leapMonth > 0 && iMonth == (leapMonth + 1) && !leap) {
+				--iMonth;
+				leap = true;
+				daysOfMonth = leapDays(year);
+			} else {
+				daysOfMonth = monthDays(year, iMonth);
+			}
+
+			offset -= daysOfMonth;
+			// 瑙i櫎闂版湀
+			if (leap && iMonth == (leapMonth + 1)) {
+				leap = false;
+			}
+			if (!leap) {
+				monCyl++;
+			}
+		}
+		// offset涓�0鏃讹紝骞朵笖鍒氭墠璁$畻鐨勬湀浠芥槸闂版湀锛岃鏍℃
+		if (offset == 0 && leapMonth > 0 && iMonth == leapMonth + 1) {
+			if (leap) {
+				leap = false;
+			} else {
+				leap = true;
+				--iMonth;
+				--monCyl;
+			}
+		}
+		// offset灏忎簬0鏃讹紝涔熻鏍℃
+		if (offset < 0) {
+			offset += daysOfMonth;
+			--iMonth;
+			--monCyl;
+		}
+		month = iMonth;
+		day = offset + 1;
+	}
+
+	public static String getChinaDayString(int day) {
+		String chineseTen[] = { "鍒�", "鍗�", "寤�", "鍗�" };
+		int n = day % 10 == 0 ? 9 : day % 10 - 1;
+		if (day > 30) {
+			return "";
+		}
+		if (day == 10) {
+			return "鍒濆崄";
+		}
+		else {
+			return chineseTen[day / 10] + chineseNumber[n];
+		}
+	}
+
+	@Override
+	public String toString() {
+		String m = chineseNumber[month - 1];
+		if (m != null && m.trim().equals("涓�")) {
+			m = "姝�";
+		}
+		if (m != null && m.trim().equals("鍗佷竴")) {
+			m = "鍐�";
+		}
+		if (m != null && m.trim().equals("鍗佷簩")) {
+			m = "鑵�";
+		}
+		return year + cyclical() + animalsYear() + "骞�" + (leap ? "闂�" : "") + m
+				+ "鏈�" + getChinaDayString(day);
+	}
+
+	public String getDate() {
+		String m = chineseNumber[month - 1];
+		if (m != null && m.trim().equals("涓�")) {
+			m = "姝�";
+		}
+		if (m != null && m.trim().equals("鍗佷竴")) {
+			m = "鍐�";
+		}
+		if (m != null && m.trim().equals("鍗佷簩")) {
+			m = "鑵�";
+		}
+		// cyclical() +
+		return animalsYear() + "骞�" + (leap ? "闂�" : "") + m + "鏈�"
+				+ getChinaDayString(day);
+	}
+
+	public static void main(String[] args) throws ParseException {
+		Calendar today = Calendar.getInstance();
+		today.setTime(chineseDateFormat.parse("2013骞�2鏈�1鏃�"));
+		Lunar lunar = new Lunar(today);
+		System.out.println(lunar.toString());
+		System.out.println("鍖椾含鏃堕棿锛�" + chineseDateFormat.format(today.getTime())
+				+ "銆�鍐滃巻" + lunar);
+	}
+}
\ No newline at end of file
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/Md5.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/Md5.java
new file mode 100644
index 0000000..206db1d
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/Md5.java
@@ -0,0 +1,120 @@
+package com.vci.starter.web.util;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.security.MessageDigest;
+
+
+/***
+ * MD5鍔犲瘑
+ * @author weidy
+ */
+public class Md5 {
+
+	/**
+	 * 鏃ュ織瀵硅薄
+	 */
+	private static Logger logger = LoggerFactory.getLogger(Md5.class);
+
+	public Md5() {}
+	
+	/**
+	 * @desc 灏嗗瓧绗︿覆杞崲涓虹殑MD5
+	 * @param v 鏉ユ簮瀛楃涓�
+	 * @return 杞崲鍚庣殑MD5瀛楃涓�
+	 * @throws Exception
+	 */
+	public static String md5(String v) {
+		if (v == null) {
+			return null;
+		}
+		try{
+			MessageDigest md = MessageDigest.getInstance("MD5");
+			return toHex(md.digest(v.getBytes()));
+		}catch(Exception e){
+			return null;
+		}
+	}
+
+	/**
+	 * @desc 涓ゆMD5鍔犲瘑
+	 * @param sourceString 鍔犲瘑鍓嶇殑瀛楃涓�
+	 * @return 涓ゆ鍔犲瘑鍚庣殑瀛楃涓�
+	 * @throws Exception
+	 */
+	public static String twoTimesMd5(String sourceString) throws Exception {
+		if(sourceString == null) {
+			return null;
+		}
+		return md5(md5(sourceString));
+	}
+	
+	/**
+	 * @desc 瀵规瘮浼犲叆鐨勫瓧绗︿覆鐢熸垚鐨凪D5浜巑d5String鏄惁鐩哥瓑
+	 * @param md5String 鐢ㄤ簬瀵规瘮鐨刴d5瀛楃涓�
+	 * @param sourceString 鍔犲瘑鍓嶇殑瀛楃涓�
+	 * @return 瀵规瘮md5鍚庣殑鍊硷紝true琛ㄧず鐩哥瓑
+	 */
+	public static boolean equalMd5(String md5String, String sourceString) {
+		if(md5String == null || sourceString == null) {
+			return false;
+		}else {
+			try {
+				if(md5String.equals(twoTimesMd5(sourceString))) {
+					return true;
+				}else {
+					return false;
+				}
+			} catch (Exception e) {
+				e.printStackTrace();
+				return false;
+			}
+		}
+	}
+	
+	/**
+	 * @desc md5涓�娆″悗杩涜瀵规瘮锛岃繖涓富瑕佹槸涓虹櫥褰曢獙璇佸瘑鐮佺敤鐨勶紝鍥犱负鍓嶅彴JS浼氬厛杩涜MD5鍔犲瘑涓�娆�
+	 * @param md5String 鐢ㄤ簬瀵规瘮鐨刴d5瀛楃涓�
+	 * @param sourceString 鍔犲瘑鍓嶇殑瀛楃涓�
+	 * @return true琛ㄧず鐩哥瓑
+	 */
+	public static boolean equalOneMd5(String md5String, String sourceString) {
+		if(md5String == null || sourceString == null) {
+			return false;
+		} else {
+			try {
+				String ms = md5(sourceString);
+				if(md5String.equals(ms)) {
+					return true;
+				}else {
+					return false;
+				}
+			}catch (Exception e) {
+				if(logger.isErrorEnabled()) {
+					logger.error("瀵规瘮md5鐨勬椂鍊欏嚭鐜颁簡閿欒", e);
+				}
+				return false;
+			}
+		}
+	}
+	
+	/**
+	 *  杞崲涓篽ex鐨勬柟寮�
+	 * @param buffer 瑕佽浆鎹㈢殑瀛楄妭鏁扮粍
+	 * @return 杞崲鍚庣殑瀛楃涓�
+	 */
+	private static String toHex(byte buffer[]) {
+		StringBuffer sb = new StringBuffer(32);
+		String s = null;
+		for (int i = 0; i < buffer.length; i++) {
+			s = Integer.toHexString((int) buffer[i] & 0xff);
+			if (s.length() < 2) {
+				sb.append('0');
+			}
+			sb.append(s);
+		}
+		return sb.toString();
+	}
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/MessageUtils.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/MessageUtils.java
new file mode 100644
index 0000000..f800198
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/MessageUtils.java
@@ -0,0 +1,54 @@
+package com.vci.starter.web.util;
+
+import org.springframework.context.MessageSource;
+import org.springframework.context.i18n.LocaleContextHolder;
+import org.springframework.stereotype.Component;
+
+/**
+ * 鍥介檯鍖栧伐鍏�
+ * @author weidy
+ * @date 2019/11/7 2:41 PM
+ */
+@Component
+public class MessageUtils {
+
+    /**
+     * 娉ㄥ叆鍥介檯鍖栬祫婧愰暅鍍�
+     */
+    private static MessageSource messageSource;
+
+    /**
+     * 鏋勯�犲嚱鏁�
+     * @param messageSource 鍥介檯鍖栬祫婧�
+     */
+    public MessageUtils(MessageSource messageSource) {
+        MessageUtils.messageSource = messageSource;
+    }
+
+    /**
+     * 鑾峰彇鍗曚釜鍥介檯鍖栫炕璇戝��
+     * @param msgKey 璧勬簮浠e彿
+     * @return 缈昏瘧鍚庣殑鍊�
+     */
+    public static String get(String msgKey) {
+        try {
+            return messageSource.getMessage(msgKey, null, LocaleContextHolder.getLocale());
+        } catch (Throwable e) {
+            return msgKey;
+        }
+    }
+
+    /**
+     * 鑾峰彇鍗曚釜鍥介檯鍖栫炕璇戝��
+     * @param msgKey 璧勬簮浠e彿
+     * @param objects 缈昏瘧鏃朵娇鐢ㄧ殑瀵硅薄
+     * @return 缈昏瘧鍚庣殑鍊�
+     */
+    public static String get(String msgKey,Object[] objects){
+        try {
+            return messageSource.getMessage(msgKey, objects, LocaleContextHolder.getLocale());
+        } catch (Throwable e) {
+            return msgKey;
+        }
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/VciBaseUtil.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/VciBaseUtil.java
new file mode 100644
index 0000000..913d390
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/VciBaseUtil.java
@@ -0,0 +1,1932 @@
+package com.vci.starter.web.util;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson.serializer.SerializerFeature;
+import com.vci.starter.web.annotation.Id;
+import com.vci.starter.web.annotation.VciBtmType;
+import com.vci.starter.web.annotation.VciLinkType;
+import com.vci.starter.web.enumpck.BooleanEnum;
+import com.vci.starter.web.enumpck.UserSecretEnum;
+import com.vci.starter.web.exception.VciBaseException;
+import com.vci.starter.web.pagemodel.SessionInfo;
+import com.vci.starter.web.toolmodel.DateConverter;
+import com.vci.starter.web.wrapper.VciQueryWrapperForDO;
+import freemarker.cache.StringTemplateLoader;
+import freemarker.template.Configuration;
+import freemarker.template.Template;
+import freemarker.template.TemplateException;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.ResourceUtils;
+
+import java.beans.IntrospectionException;
+import java.beans.PropertyDescriptor;
+import java.io.File;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.lang.annotation.Annotation;
+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.net.InetAddress;
+import java.net.NetworkInterface;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+/**
+ * 鍩虹鐨勫伐鍏风被
+ * @author weidy
+ */
+public class VciBaseUtil {
+
+    /**
+     * 鏃ュ織瀵硅薄
+     */
+    private static Logger log = LoggerFactory.getLogger(VciBaseUtil.class);
+
+    /**
+     * 鐢熸垚PK鍊硷紝uuid鍦ㄩ珮骞跺彂鐨勬椂鍊欎細閲嶅锛屼絾鏄潪浜掕仈缃戜骇鍝佷腑锛屽悓涓�涓暟鎹簱琛ㄤ腑鐨勪富閿嚭鐜伴噸澶嶇殑姒傜巼杈冨皬
+     * 濡傛灉鏄簰鑱旂綉浜у搧锛岄渶瑕佸皢杩欎釜淇敼涓簉edis涓幏鍙杣uid
+     * @return uuid鐨勫��
+     */
+    public static String getPk() {
+        return UUID.randomUUID().toString();
+    }
+
+    /**
+     * 瀛楃涓茶浆鏁板瓧
+     * @param string 瀛楃涓�
+     * @return 鏁板瓧
+     */
+    public static int getInt(String string) {
+        int i = 0;
+        if (string == null || "".equals(string.trim())) {
+            return 0;
+        }
+        if(string.contains(".")){
+            string = string.substring(0,string.indexOf("."));
+        }
+        try {
+            i = Integer.parseInt(string);
+        } catch (Exception e) {
+            return 0;
+        }
+        return i;
+    }
+
+    /**
+     * 鎶奲oolean鍨嬭浆鍖栦负鏁板瓧
+     * @param b 甯冨皵
+     * @return 鏁板瓧
+     */
+    public static int getIntForBoolean(boolean b){
+        if (b) {
+            return 1;
+        } else {
+            return 0;
+        }
+    }
+
+    /**
+     * 鍦╤ibernate涓皢缁撴灉杞寲涓烘暟瀛�
+     * @param obj 缁撴灉鐨勫璞�
+     * @return 鏁板瓧
+     */
+    public static int getIntFromHibernateResult(Object obj){
+        if(obj == null){
+            return 0;
+        }
+        if(obj instanceof BigDecimal){
+            return ((BigDecimal)obj).intValue();
+        }else if(obj instanceof BigInteger){
+            return ((BigInteger)obj).intValue();
+        }else if(obj instanceof Double){
+            return ((Double)obj).intValue();
+        }else if(obj instanceof Long){
+            return ((Long)obj).intValue();
+        }else if(obj instanceof Short){
+            return ((Short)obj).intValue();
+        }else if(obj instanceof Float){
+            return ((Float)obj).intValue();
+        }else if(obj instanceof String){
+            try{
+                return Integer.valueOf(obj.toString());
+            }catch(Exception e){
+                return 0;
+            }
+        }else{
+            return 0;
+        }
+    }
+
+    /**
+     * 瀛楃涓茶浆甯冨皵鍨�
+     * @param s 瀛楃涓�
+     * @return true瀛楃涓茶繑鍥瀊oolean鍨嬬殑true锛屽叾浣欒繑鍥瀎alse
+     */
+    public static  boolean getBoolean(String s){
+        if(BooleanEnum.TRUE.getValue().equals(s)){
+            return true;
+        }else{
+            return false;
+        }
+    }
+
+    /**
+     * 鏍规嵁瀛楃涓茶幏鍙栧搴旂殑浜岃繘鍒�
+     * @param s 瀛楃
+     * @return 浜岃繘鍒跺璞�
+     */
+    public static byte getByte(String s) {
+        byte b = 0;
+        if (s == null) {
+            return 0;
+        }
+        try {
+            b = Byte.parseByte(s);
+        } catch (Exception e) {
+            return 0;
+        }
+        return b;
+    }
+
+    /**
+     *  瀛楃杞瑂hort
+     * @param s 瀛楃涓�
+     * @return short鍊�
+     */
+    public static short getShort(String s) {
+        short i = 0;
+        if (s == null) {
+            return 0;
+        }
+        try {
+            i = Short.parseShort(s);
+        } catch (Exception e) {
+            return 0;
+        }
+        return i;
+    }
+
+    /**
+     * 瀛楃涓茶浆Long
+     * @param s 瀛楃涓�
+     * @return long
+     */
+    public static long getLong(String s) {
+        long l = 0;
+        if (s == null) {
+            return 0;
+        }
+        try {
+            l = Long.parseLong(s);
+        } catch (Exception e) {
+            return 0;
+        }
+        return l;
+    }
+
+    /**
+     * 瀛楃涓茶浆娴偣鍨�
+     * @param s 瀛楃涓�
+     * @return 娴偣鍨�
+     */
+    public static float getFloat(String s) {
+        float f = 0;
+        if (s == null) {
+            return 0;
+        }
+        try {
+            f = Float.parseFloat(s);
+        } catch (Exception e) {
+            return 0;
+        }
+        return f;
+    }
+
+    /**
+     * 瀛楃涓茶浆double鍨�
+     * @param s 瀛楃涓�
+     * @return double
+     */
+    public static double getDouble(String s) {
+        double d = 0;
+        if (isNull(s)) {
+            return 0;
+        }
+        try {
+            d = Double.parseDouble(s);
+        } catch (Exception e) {
+            return 0;
+        }
+        return d;
+    }
+
+
+
+    /**
+     * 鍘婚櫎鏈�鍓嶉潰鐨勯�楀彿锛屽幓闄ゅ悗闈㈢殑閫楀彿
+     * @param s 瀛楃涓�
+     * @return 鍘婚櫎鏈熬閫楀彿
+     */
+    public static String removeComma(String s){
+        if(s == null || s.trim().length() == 0) {
+            return s;
+        }
+        else{
+            if(s.startsWith(",")) {
+                s = s.substring(1, s.length());
+            }
+            if(s.endsWith(",")) {
+                s = s.substring(0, s.length() - 1);
+            }
+            return s;
+        }
+    }
+
+    /**
+     * 涓簊ql涓娇鐢╥n鏃讹紝鎻愪緵杞崲锛屾敞鎰廼n閲岀殑鍊间笉鑳借秴杩�1000
+     * @param s 瀛楃涓�
+     * @return 杩斿洖sql璇彞
+     */
+    public static String toInSql(String s){
+        s= removeComma(s);
+        if(s == null || s.trim().length() == 0) {
+            return "";
+        }
+        String[] temp = s.split(",");
+        return toInSql(temp);
+    }
+
+    /**
+     * 娉ㄦ剰s鐨勯暱搴︿笉鑳借秴杩囦竴鍗�
+     * @param s 瀛楃涓�
+     * @return insql
+     */
+    public static String toInSql(String[] s){
+        if(s != null && s.length >0){
+            StringBuilder sb = new StringBuilder();
+            if(s!=null&&s.length>0){
+                for(int i = 0 ; i < s.length ; i ++){
+                    if(s[i]!=null&&s[i].trim().length() >0 && !s[i].startsWith("'")) {
+                        sb.append("'")
+                                .append(s[i])
+                                .append("',");
+                    }
+                }
+            }
+            return removeComma(sb.toString());
+        }else{
+            return "";
+        }
+    }
+
+    /**
+     * 鏀寔in 閲屾暟鎹负1000浠ヤ笂鐨�
+     * @param field 瀛楁鍚嶇О
+     * @param s 鍘熷瓧绗︿覆
+     * @return 鍚玦n鐨凷QL
+     */
+    public static String toInSql(String field, String s){
+        if(StringUtils.isBlank(field) || StringUtils.isBlank(s)){
+            return "";
+        }
+        return toInSql(field,removeComma(s).split(","),"");
+    }
+
+    /**
+     * 鏀寔in閲屾暟鎹�1000浠ヤ笂
+     * @param field 瀛楁鍚嶇О
+     * @param s 鍘熷瓧绗︿覆
+     * @return 鍚玦n鐨凷QL
+     */
+    public static String toInSql(String field, String[] s){
+        return toInSql(field,s,"in");
+    }
+
+    /**
+     * 涓嶇瓑浜�
+     */
+    public static final String NOTIN="not in";
+    /**
+     * 鏀寔not in
+     * @param field 瀛楁
+     * @param s 瀛楃涓叉暟缁�
+     * @param operation 鎿嶄綔鏂瑰紡
+     * @return insql
+     */
+    public static String toInSql(String field, String[] s, String operation){
+        if(StringUtils.isBlank(field) || s == null || s.length == 0){
+            return "";
+        }else{
+            StringBuilder sb = new StringBuilder();
+            if(s!=null&&s.length>0){
+                String andOr = "or";
+                if(operation.trim().toLowerCase().equals(NOTIN)){
+                    andOr = "and";
+                }
+                for(int i = 0 ; i < s.length ; i ++){
+                    if(s[i]!=null&&s[i].trim().length() >0 && !s[i].startsWith("'")) {
+                        if (i == 0) {
+                            sb.append(field).append(" ").append(operation).append(" (");
+                        }
+                        if (i % 500 == 0 && i != 0) {
+                            sb.append(" ").append(andOr).append(" ").append(field).append(" ").append(operation).append(" (");
+                        }
+                        sb.append("'").append(s[i]).append("'");
+                        if (i % 500 != 499 && i != s.length - 1) {
+                            sb.append(",");
+                        }
+                        if (i % 500 == 499 || i == s.length - 1) {
+                            sb.append(") ");
+                        }
+                    }
+                }
+            }
+            return sb.toString();
+        }
+    }
+
+    /**
+     * 鏁扮粍杞负閫楀彿鍒嗛殧鐨勫瓧绗︿覆  浣跨敤array2String
+     * @param array 鏁扮粍
+     * @return 瀛楃涓�
+     */
+    @Deprecated
+    public static String arrayToString(String[] array){
+        if(array!= null && array.length>0){
+            StringBuilder sb = new StringBuilder();
+            for(int i = 0 ; i < array.length; i ++){
+                String record = array[i];
+                if(StringUtils.isNotBlank(record)) {
+                    sb.append(record)
+                            .append(",");
+
+                }
+            }
+            return removeComma(sb.toString());
+        }
+        return "";
+    }
+
+    /**
+     * 灏嗛泦鍚堣浆鎹负瀛楃涓�
+     * @param collection 闆嗗悎
+     * @return 瀛楃涓�
+     */
+    public static String collectionToString(Collection collection){
+        if(!CollectionUtils.isEmpty(collection)){
+            StringBuilder sb = new StringBuilder();
+            Iterator it = collection.iterator();
+            while(it.hasNext()){
+                Object record = it.next();
+                if(record !=null && (!(record instanceof String) ||  StringUtils.isNotBlank(((String) record)))){
+                    sb.append(record.toString()).append(",");
+                }
+            }
+            return removeComma(sb.toString());
+        }
+        return "";
+    }
+
+    /**
+     * 棣栧瓧姣嶅ぇ鍐�
+     * @param s 瀛楃涓�
+     * @return 鍚ぇ鍐欑殑瀛楃涓�
+     */
+    public static String toUpForFirst(String s){
+        if(s== null || s.trim().length()==0) {
+            return "";
+        }
+        String temp = s.substring(0, 1);
+        temp = temp.toUpperCase();
+        return temp + s.substring(1,s.length());
+    }
+
+    /**
+     * 棣栧瓧姣嶅皬鍐�
+     * @param s 瀛楃涓�
+     * @return 鍚ぇ鍐欑殑瀛楃涓�
+     */
+    public static String toLowForFirst(String s){
+        if(s== null || s.trim().length()==0) {
+            return "";
+        }
+        String temp = s.substring(0, 1);
+        temp = temp.toLowerCase();
+        return temp + s.substring(1,s.length());
+    }
+
+    /**
+     * 瀛楃涓蹭腑鏌愪釜瀛楃鍑虹幇鐨勬鏁�
+     * @param s 瀛楃涓�
+     * @param findC 瑕佹壘鐨勫瓧绗�
+     * @return 鎴彇鍚庣殑瀛楃涓�
+     */
+    public static int countOfString(String s, char findC) {
+        Map<String, Integer> charMap = new HashMap<String, Integer>();
+        char[] cs = s.toCharArray();
+        for (char c : cs) {
+            charMap.put(String.valueOf(c), (!charMap.containsKey(String.valueOf(c))? 1 : charMap.get(String.valueOf(c)) + 1));
+        }
+        return charMap.get(String.valueOf(findC));
+    }
+
+    /**
+     * 甯﹂�楀彿鐨勫瓧绗︿覆杞负list
+     * @param s 瀛楃涓�
+     * @return 瀛楃涓插垪琛�
+     */
+    public static List<String> str2List(String s){
+        if (isNull(s)) {
+            return null;
+        } else {
+            List<String> l = new ArrayList<String>();
+            Collections.addAll(l,removeComma(s).split(","));
+            return l;
+        }
+    }
+
+    /**
+     * 鍒楄〃杞负甯﹂�楀彿鍒嗛殧鐨勫瓧绗︿覆
+     * @param ls 瀛楃涓插垪琛�
+     * @return 閫楀彿鍒嗛殧鐨勫瓧绗︿覆
+     */
+    public static String list2String(List<String> ls){
+        if(ls == null || ls.size() == 0) {
+            return "";
+        }else{
+            return ls.stream().collect(Collectors.joining(","));
+        }
+    }
+
+    /**
+     * 鍒ゆ柇瀛楃涓叉槸涓嶆槸绌�,涓嶅垽鏂璽rim
+     * @param o 瀛楃涓�
+     * @return true琛ㄧず绌�
+     */
+    public static boolean isNull(String o){
+        return StringUtils.isEmpty(o);
+    }
+
+    /**
+     * 鍒ゆ柇涓嶆槸绌猴紝涓嶅垽鏂璽rim
+     * @param o 瀛楃涓�
+     * @return true琛ㄧず涓嶄负绌�
+     */
+    public static boolean isNotNull(String o){
+        return !isNull(o);
+    }
+
+    /**
+     * 鍒ゆ柇瀛楃涓叉槸涓嶆槸绌�,鍘婚櫎trim
+     * @param o 瀛楃涓�
+     * @return true琛ㄧず涓虹┖锛屾垨鑰卬ull,鎴�"",鎴�" "
+     */
+    public static boolean isNullOrNullString(String o){
+        return StringUtils.isBlank(o);
+    }
+
+
+    /**
+     * 瀛楃涓叉槸鍚﹀湪鏁扮粍涓�
+     * @param arr 鏁扮粍瀵硅薄
+     * @param s 瀛楃涓�
+     * @return 涓嶅尯鍒嗗ぇ灏忓啓
+     */
+    public static boolean inArray(String[] arr, String s) {
+        if(arr!=null && s != null){
+            for(String a : arr){
+                if(s.trim().equalsIgnoreCase(a)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * 鏄惁鍦ㄦ暟缁勪腑
+     * @param arr 鏁扮粍瀵硅薄
+     * @param o 瀵硅薄
+     * @return true琛ㄧず鍦ㄦ暟缁勪腑
+     */
+    public static boolean inArray(Object[] arr, Object o){
+        if(arr!=null && o != null){
+            for(Object a : arr){
+                if(a.equals(o)){
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+    /**
+     * double鍙栫簿搴�
+     * @param value 鍊�
+     * @param scale 淇濈暀灏忔暟
+     * @param roundingMode 灏炬暟澶勭悊鏂规硶
+     * @return 杞崲鍚庣殑鍊�
+     */
+    public static double round(double value, int scale,
+                               int roundingMode) {
+        BigDecimal bd = new BigDecimal(value);
+        bd = bd.setScale(scale, roundingMode);
+        double d = bd.doubleValue();
+        bd = null;
+        return d;
+    }
+
+    /**
+     * 鍙栫簿搴︼紝鍥涜垗浜斿叆娉�
+     * @param value 鍊�
+     * @param scale 姣斾緥
+     * @return 杞崲鍚庣殑鍊�
+     */
+    public static double round(double value,int scale){
+        return round(value,scale, BigDecimal.ROUND_HALF_UP);
+    }
+
+
+    /**
+     * 鍒ゆ柇閭欢鍦板潃鏄惁鍚堟硶
+     * @param string 瀛楃涓�
+     * @return true琛ㄧず涓洪偖浠跺湴鍧�
+     */
+    public static boolean isEmail(String string) {
+        if (StringUtils.isBlank(string)) {
+            return false;
+        }
+        String regEx1 = "^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
+        Pattern p;
+        Matcher m;
+        p = Pattern.compile(regEx1);
+        m = p.matcher(string);
+        if (m.matches()) {
+            return true;
+        }else {
+            return false;
+        }
+    }
+
+
+
+    /**
+     * 鍒ゆ柇鏄惁涓烘暟瀛�
+     * @param s 瀛楃涓�
+     * @return true琛ㄧず绗﹀悎
+     */
+    public static boolean isNumber(String s){
+        if(StringUtils.isNotBlank(s) && s.matches("\\d+\\.?\\d*")){
+            return true;
+        }else{
+            return false;
+        }
+    }
+
+    /**
+     * 鑾峰彇灞炴�у垪琛ㄤ腑寰楁煇涓睘鎬�
+     * @param fieldName 瀛楁鍚嶇О
+     * @param fieldsList 瀛楁鐨勫璞″垪琛�
+     * @return 绗﹀悎鏉′欢鐨勫睘鎬у璞�
+     */
+    public static Field getFieldForObject(String fieldName, List<Field> fieldsList){
+        if(StringUtils.isBlank(fieldName)){
+            return null ;
+        }
+        if(fieldsList != null && fieldsList.size() > 0){
+            for(Field field : fieldsList){
+                if(field.getName().toLowerCase().equals(fieldName.toLowerCase())){
+                    return field;
+                }
+            }
+        }
+        return null ;
+    }
+
+    /**
+     * 鑾峰彇瀛楁鐨剆etter
+     * @param c 绫诲璞�
+     * @param fieldName 瀛楁鍚嶇О
+     * @return 绗﹀悎鏉′欢鐨勫璞�
+     */
+    public static Method getSetmethod(Class c, String fieldName){
+        if(c!=null&&StringUtils.isNotBlank(fieldName)){
+            try {
+                PropertyDescriptor pd = new PropertyDescriptor(fieldName, c);
+                return pd.getWriteMethod();
+            } catch (SecurityException e) {
+                if(log.isErrorEnabled()){
+                    log.error("鑾峰彇getter鍑洪敊",e);
+                }
+            } catch (IntrospectionException e) {
+                if(log.isErrorEnabled()){
+                    log.error("鑾峰彇getter鍑洪敊",e);
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * 鑾峰彇瀛楁鐨刧etter
+     * @param c 绫诲璞�
+     * @param fieldName 灞炴�у悕绉�
+     * @return 绗﹀悎鏉′欢鐨勫璞�
+     */
+    public static Method getGetmethod(Class c, String fieldName){
+        if(c!=null&&StringUtils.isNotBlank(fieldName)){
+            try {
+                PropertyDescriptor pd = new PropertyDescriptor(fieldName, c);
+                return pd.getReadMethod();
+            } catch (SecurityException e) {
+                if(log.isErrorEnabled()){
+                    log.error("鑾峰彇getter鍑洪敊",e);
+                }
+            } catch (IntrospectionException e) {
+                if(log.isErrorEnabled()){
+                    log.error("鑾峰彇getter鍑洪敊",e);
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * 鑾峰彇Column娉ㄨВ涓婄殑name鐨勫��
+     * @param fieldAnnotaions 鎵�鏈夌殑娉ㄨВ瀵硅薄
+     * @return name鐨勫��
+     */
+    public static String getColumnAnnotaionNameValue(Annotation[] fieldAnnotaions){
+        return getAnnotationValue("com.vci.starter.web.annotation.Column,javax.persistence.Column","name",fieldAnnotaions);
+    }
+
+    /**
+     * 鑾峰彇娉ㄨВ涓殑鏌愪釜鏂规硶鐨勫��
+     * @param annotationName 娉ㄨВ鐨勫悕绉�
+     * @param methodName 鏂规硶鍚嶇О
+     * @param fieldAnnotaions 娉ㄨВ鐨勯泦鍚�
+     * @return 绗﹀悎鏉′欢鐨勫��
+     */
+    public static String getAnnotationValue(String annotationName,String methodName,Annotation[] fieldAnnotaions){
+        String[] annotaionNameArray = annotationName.split(",");
+        for(Annotation annotation : fieldAnnotaions){
+            String anname = annotation.annotationType().getName();
+            if(inArray(annotaionNameArray,anname)){
+                String name = null;
+                try {
+                    name = (String)annotation.getClass().getMethod(methodName).invoke(annotation);
+                } catch (IllegalAccessException e) {
+                    e.printStackTrace();
+                } catch (InvocationTargetException e) {
+                    e.printStackTrace();
+                } catch (NoSuchMethodException e) {
+                    e.printStackTrace();
+                }
+                return name;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * 浠庡璞′笂鑾峰彇cbo閲岀殑鍊�
+     * @param field 瀛楁瀵硅薄
+     * @param c 绫诲璞�
+     * @return cbo涓殑鍊�
+     */
+    public static String getCboAttrNameFromField(Field field, Class c){
+        String clientBoAttrName = field.getName().toLowerCase();
+        String name = null;
+        if(!VciQueryWrapperForDO.USER_TABLE_COMPATIBILITY &&( VciQueryWrapperForDO.BASIC_FIELD_MAP.containsKey(clientBoAttrName)
+                ||VciQueryWrapperForDO.REVISION_MANAGE_FIELD_MAP.containsKey(clientBoAttrName)
+                ||VciQueryWrapperForDO.LIFECYCLE_MANAGE_FIELD_MAP.containsKey(clientBoAttrName)
+                ||VciQueryWrapperForDO.LINK_TYPE_FIELD_MAP.containsKey(clientBoAttrName))){
+            //鏄柊骞冲彴锛屼笉鐢╟olumn娉ㄨВ涓婂幓鑾峰彇鍚嶅瓧
+        }else {
+            name = getColumnAnnotaionNameValue(field.getDeclaredAnnotations());
+            if (StringUtils.isBlank(name)) {
+                //鎵句竴涓婫et鏂规硶涓�..set鏂规硶涓婅偗瀹氭槸涓嶆敮鎸佺殑锛�
+                Method getMethod = getGetmethod(c, field.getName());
+                if (getMethod != null) {
+                    name = getColumnAnnotaionNameValue(getMethod.getDeclaredAnnotations());
+                }
+                if (StringUtils.isBlank(name)) {
+                    //鍙傜収鎴栬�呮槸鏋氫妇鐨�
+                    name = getAnnotationValue("com.vci.starter.web.annotation.Transient", "referColumn", field.getDeclaredAnnotations());
+                }
+            }
+        }
+        if(StringUtils.isNotBlank(name)){
+            clientBoAttrName = name;
+        }
+        return clientBoAttrName;
+    }
+
+    /**
+     * 鏄惁涓哄熀纭�绫诲瀷
+     * @param c 绫诲璞�
+     * @return true琛ㄧず鍩虹绫诲瀷
+     */
+    public  static boolean isBasicType(Class<?> c){
+        if(c == null){
+            return false;
+        }
+        if(c.isArray()){
+            return isBasicType(c.getComponentType());
+        }
+        return ClassUtil.isPrimitive(c);
+    }
+
+    /**
+     * 鑾峰彇绫讳腑鐨勫瓧娈垫槧灏�
+     * @param c 绫诲璞�
+     * @return key涓轰笟鍔$被鍨嬩腑鐨勫瓧娈靛悕绉帮紝value涓虹被涓殑灞炴�у悕绉�
+     */
+    public static Map<String/*涓氬姟绫诲瀷涓殑瀛楁*/,String/*瀵硅薄涓婄殑灞炴��*/> getFieldNameMap(Class c){
+        Map<String,String> fieldMap = new HashMap<String, String>();
+        List<Field> allField = getAllFieldForObj(c);
+        if(allField!=null&&allField.size()>0){
+            for(Field field : allField){
+                if(!field.getName().equals("serialVersionUID")){
+                    Class fieldTypeClass = field.getType();
+                    if(isBasicType(fieldTypeClass)){
+                        String referColumn =  getAnnotationValue("com.vci.starter.web.annotation.Transient","referColumn",field.getDeclaredAnnotations());
+                        if (StringUtils.isNotBlank(referColumn)){
+                            //璇存槑涓嶆槸鎸佷箙鍖栫殑灞炴�э紝浣嗘槸浠庡钩鍙颁腑鏌ヨ鍑烘潵鍚庡彲鑳藉緱闇�瑕佹樉绀�
+                            fieldMap.put(referColumn, field.getName());
+                        }else{
+
+                            String clientBoAttrName = getCboAttrNameFromField(field,c);
+                            fieldMap.put(clientBoAttrName, field.getName());
+                        }
+                    }else{
+                        //涓嶆槸鍩烘湰绫诲瀷鐨勶紝閭d竴瀹氫笉鏄鐨勫睘鎬�
+                    }
+                }
+            }
+        }
+        return fieldMap;
+    }
+
+    /**
+     * 浠庡璞′笂鑾峰彇灞炴�х殑鍊�
+     * @param fieldName 灞炴�у悕
+     * @param sourceObject 瀵硅薄
+     * @return 灞炴�х殑鍊�
+     */
+    public static Object getValueFromField(String fieldName, Object sourceObject){
+        if(StringUtils.isNotBlank(fieldName)){
+            try {
+                Method getMethod = getGetmethod(sourceObject.getClass(), fieldName);
+                if(getMethod !=null){
+                    return getMethod.invoke(sourceObject);
+                }else{
+                    //璇存槑娌℃湁璁剧疆getter锛屾瘮濡侭O鍜孡O瀵硅薄杩欑
+                    Field field = getFieldForObject(fieldName, sourceObject);
+                    if(field !=null){
+                        field.setAccessible(true);
+                        return field.get(sourceObject);
+                    }
+                }
+            } catch (SecurityException e) {
+                if(log.isErrorEnabled()){
+                    log.error("浠庡睘鎬т笂鑾峰彇鍊�",e);
+                }
+            } catch (IllegalAccessException e) {
+                if(log.isErrorEnabled()){
+                    log.error("浠庡睘鎬т笂鑾峰彇鍊�",e);
+                }
+            } catch (IllegalArgumentException e) {
+                if(log.isErrorEnabled()){
+                    log.error("浠庡睘鎬т笂鑾峰彇鍊�",e);
+                }
+            } catch (InvocationTargetException e) {
+                if(log.isErrorEnabled()){
+                    log.error("浠庡睘鎬т笂鑾峰彇鍊�",e);
+                }
+            }
+        }
+        return null;
+    }
+
+
+    /**
+     * 灏嗗睘鎬у�艰祴鍊煎埌瀵硅薄涓�
+     * @param fieldName 灞炴�у悕
+     * @param obj 瀵硅薄
+     * @param value 灞炴�у��
+     */
+    public static void setValueForField(String fieldName, Object obj, String value){
+        try{
+            Field field = getFieldForObject(fieldName,obj);
+            if(field!=null){
+                setValueForField(field,obj,value);
+            }
+        }catch (Exception e) {
+            if(log.isErrorEnabled()) {
+                log.error("璁剧疆灞炴�х殑鍊煎嚭閿欎簡閿欒",e);
+            }
+        }
+    }
+
+    /**
+     * 灏嗗睘鎬у�艰祴鍊煎埌瀵硅薄涓�
+     * @param field 灞炴�у璞�
+     * @param obj 瀵硅薄
+     * @param value 灞炴�у��
+     */
+    public static void setValueForField(Field field,Object obj, String value){
+        try {
+            if (field != null && StringUtils.isNotBlank(value)) {
+                field.setAccessible(true);
+                Method setMethod = getSetmethod(field.getDeclaringClass(), field.getName());
+                Class type = field.getType();
+                //浠庡钩鍙拌鍙栧埌鐨勫�间笉浼氫负null锛屼负绌烘椂涓�""锛涙墍浠ヤ笉澶勭悊绌哄��
+                Object valueObj = null;
+                if (type.equals(int.class) || type.equals(Integer.class)) {
+                    valueObj = VciBaseUtil.getInt(value);
+                } else if (type.equals(float.class) || type.equals(Float.class)) {
+                    valueObj = VciBaseUtil.getFloat(value);
+                } else if (type.equals(long.class) || type.equals(Long.class)) {
+                    valueObj = VciBaseUtil.getLong(value);
+
+                } else if (type.equals(Double.class) || type.equals(double.class)) {
+                     valueObj = VciBaseUtil.getDouble(value);
+                    //浠庡钩鍙颁腑鏌ヨ鍑烘潵灏变笉鐢ㄥ鐞嗙簿搴︿簡锛屽洜涓哄钩鍙颁細鑷澶勭悊
+                } else if (type.equals(Date.class)) {
+                    DateConverter dateConverter = new DateConverter();
+                    dateConverter.setAsText(value);
+                    valueObj = dateConverter.getValue();
+                } else if (type.equals(String.class)) {
+                    valueObj = value;
+                } else {
+                    valueObj = value;
+                    if (log.isErrorEnabled()) {
+                        log.error("涓嶆敮鎸佺殑绫诲瀷" + type.toString());
+                    }
+                }
+                if (setMethod != null) {
+                    setMethod.invoke(obj, valueObj);
+                } else {
+                    field.set(obj, valueObj);
+                }
+            }
+        }catch (Throwable e){
+            if(log.isErrorEnabled()) {
+                log.error("璁剧疆灞炴�х殑鍊煎嚭閿欎簡閿欒",e);
+            }
+        }
+    }
+
+    /**
+     * 璋冪敤灞炴�х殑setter璧嬪��
+     * @param field 灞炴�у璞�
+     * @param obj 瑕佽祴鍊肩殑瀵硅薄
+     * @param value 鍊�
+     */
+    public  static void setValueForMethod(Field field, Object obj , Object value){
+        try {
+            if (field != null) {
+                field.setAccessible(true);
+                Method setMethod = getSetmethod(field.getDeclaringClass(), field.getName());
+                setMethod.invoke(obj, value);
+            }
+        }catch (Exception e){
+            log.error("鍙嶅皠璋冪敤鏂规硶鍑虹幇浜嗛敊璇�,",e);
+        }
+    }
+
+    /**
+     * 鎶妎bject瀵硅薄杞寲涓哄瓧绗︿覆
+     * @param obj 瀵硅薄
+     * @return 瀛楃涓�
+     */
+    public static String getStringValueFromObject(Object obj){
+        if(obj == null){
+            return "";
+        }else{
+            if(obj instanceof Integer || obj instanceof Float || obj instanceof Long || obj instanceof Double){
+                if(obj instanceof  Double){
+                    Double aDouble = (Double) obj;
+                    if(aDouble!=null&& aDouble%1==0){
+                        return String.valueOf(aDouble.intValue());
+                    }
+                }
+                return String.valueOf(obj);
+            }else if(obj instanceof Date){
+                return VciDateUtil.date2Str((Date)obj, VciDateUtil.DateTimeMillFormat);
+            }else{
+                return obj.toString();
+            }
+        }
+    }
+
+    /**
+     * 鎻愮ず鍙傛暟涓虹┖
+     * @param s 鐩稿叧鐨勫弬鏁帮紝涓や袱缁勫悎锛岀涓�涓负鍙傛暟鐨勫璞★紝绗簩涓负鏄剧ず鐨勫悕绉�
+     * @throws VciBaseException 濡傛灉鍙傛暟涓虹┖鐨勬椂鍊欎細鎶涘嚭寮傚父
+     */
+    public static void alertNotNull(Object... s) throws VciBaseException {
+        if(s!=null && s.length>0){
+            for(int i = 0 ; i < s.length ; i ++){
+                Object obj = s[i];
+                String param = "";
+                try{
+                    i++;
+                    param = s[i].toString();
+                }catch(Exception e){
+
+                }
+                if(obj==null){
+                    throw new VciBaseException("鍙傛暟[{0}]涓嶈兘涓虹┖",new String[]{param});
+                }else {
+                    if(obj instanceof Collection){
+                        if(CollectionUtils.isEmpty((Collection)obj)){
+                            throw new VciBaseException("鍙傛暟[{0}]涓嶈兘涓虹┖",new String[]{param});
+                        }
+                    }else{
+                        if(StringUtils.isBlank(obj.toString())){
+                            throw new VciBaseException("鍙傛暟[{0}]涓嶈兘涓虹┖",new String[]{param});
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * 鎻愮ず闆嗗悎閲岀殑鍙傛暟涓虹┖,锛�2020-09琚簾寮冿紝璇风洿鎺ヤ娇鐢╝lertNotNull鏂规硶)
+     * @param param 鎻愮ず淇℃伅
+     * @param collections 闆嗗悎
+     * @throws VciBaseException 鍙傛暟涓虹┖鐨勬椂鍊欎細鎶涘嚭寮傚父
+     */
+    @Deprecated
+    public static void alertCollectionNotNull(String param, Collection collections) throws VciBaseException{
+        if(CollectionUtils.isEmpty(collections)){
+            throw new VciBaseException("鍙傛暟{0}涓嶈兘涓虹┖",new String[]{param});
+        }
+    }
+
+    /**
+     * oracle in 鏌ヨ涓嶈兘瓒呰繃1000锛岃浆鎹竴涓嬮泦鍚�
+     * 鐢变簬SQL璇彞1000涓彲鑳藉緢闀匡紝瓒呰繃oracle10g锛屾墍浠ョ壓鐗叉�ц兘鍒嗛厤涓�500涓暟缁�
+     * @param list 闇�瑕佽浆鎹㈢殑鍒楄〃鍐呭
+     * @return 鍒嗙粍鍚庣殑list
+     */
+    public static <T> List<List<T>> switchListForOracleIn(List<T> list) {
+        List<List<T>> listHasList = new ArrayList<List<T>>();
+        if(list == null){
+            return listHasList;
+        }
+        List<T> newList = new ArrayList<T>();
+        for(Object obj : list){
+            //涓轰簡璁﹍ist杩樺彲浠ユ坊鍔犲唴瀹癸紝鍥犱负浣跨敤sublist鍚庯紝list涓嶈兘鍐岮dd浜�
+            newList.add((T)obj);
+        }
+        int muti = 1;
+        if(newList.size() >500){
+            int balance = newList.size()%500;
+            muti = (newList.size() - balance)/500 + (balance == 0?0:1);
+        }
+        for(int i = 0 ; i < muti; i ++){
+            int start = i*500;
+            int end = start + 500;
+            if(i == muti-1 || end >newList.size() ){
+                end = newList.size();
+            }
+            List subList = newList.subList(start,end);
+            listHasList.add(subList);
+        }
+        return listHasList;
+    }
+
+    /**
+     * oracle in 鏌ヨ涓嶈兘瓒呰繃1000锛岃浆鎹竴涓嬮泦鍚�
+     * 鐢变簬SQL璇彞1000涓彲鑳藉緢闀匡紝瓒呰繃oracle10g锛屾墍浠ョ壓鐗叉�ц兘鍒嗛厤涓�500涓暟缁�
+     * @param list 闇�瑕佽浆鎹㈢殑鍒楄〃鍐呭
+     * @return 鍒嗙粍鍚庣殑list
+     */
+    public static <T> Collection<Collection<T>> switchCollectionForOracleIn(Collection<T> list) {
+       return switchCollectionForOracleIn(list,500);
+    }
+
+    /**
+     * 杞崲闆嗗悎鐨勫ぇ灏忥紝杩欎釜鐢ㄥ湪feign璋冪敤鐨勬椂鍊欙紝涓嶈鍦╯ql鏌ヨ鐨勬椂鍊欎娇鐢�
+     * @param collection 闇�瑕佽浆鎹㈢殑鍒楄〃鍐呭
+     * @param preSize 姣忎釜鍒嗙粍鐨勫ぇ灏�
+     * @return 鍒嗙粍鍚庣殑list
+     */
+    public static <T> Collection<Collection<T>> switchCollectionForOracleIn(Collection<T> collection,int preSize) {
+        Collection<Collection<T>> listHasList = new ArrayList<>();
+        if(collection == null){
+            return listHasList;
+        }
+        List<T> newList = new ArrayList<T>();
+        for(Object obj : collection){
+            //涓轰簡璁﹍ist杩樺彲浠ユ坊鍔犲唴瀹癸紝鍥犱负浣跨敤sublist鍚庯紝list涓嶈兘鍐岮dd浜�
+            newList.add((T)obj);
+        }
+        int muti = 1;
+        if(newList.size() >preSize){
+            int balance = newList.size()%preSize;
+            muti = (newList.size() - balance)/preSize + (balance == 0?0:1);
+        }
+        for(int i = 0 ; i < muti; i ++){
+            int start = i*preSize;
+            int end = start + preSize;
+            if(i == muti-1 || end >newList.size() ){
+                end = newList.size();
+            }
+            List subList = newList.subList(start,end);
+            listHasList.add(subList);
+        }
+        return listHasList;
+    }
+
+    /**
+     * oracle in 鏌ヨ涓嶈兘瓒呰繃1000锛岃浆鎹竴涓嬮泦鍚堛�傛敞鎰忚繖涓『搴忓彲鑳戒細鍙戠敓鍙樺寲
+     * 鐢变簬SQL璇彞1000涓彲鑳藉緢闀匡紝瓒呰繃oracle10g锛屾墍浠ョ壓鐗叉�ц兘鍒嗛厤涓�500涓暟缁�
+     * @param set set闆嗗悎
+     * @return 杞崲鍚庣殑set
+     * @throws VciBaseException
+     */
+    public static <T> Set<Set<T>> switchSetForOracleIn(Set<T> set){
+        Set<Set<T>> listHasList = new HashSet<Set<T>>();
+        if(set == null){
+            return listHasList;
+        }
+        int muti = 1;
+        if(set.size() >500){
+            int balance = set.size()%500;
+            muti = (set.size() - balance)/500 + (balance == 0?0:1);
+        }
+        List list = new ArrayList();
+        //涓轰簡淇濊瘉浠ュ墠鐨勫紩鐢ㄥ叧绯伙紝涓嶆槸鏈夎浆鏁扮粍鐨勬柟娉�
+        Iterator it = set.iterator();
+        while(it.hasNext()){
+            list.add(it.next());
+        }
+        for(int i = 0 ; i < muti; i ++){
+            int start = i*500;
+            int end = start + 500;
+            if(i == muti-1 || end >set.size() ){
+                end = set.size();
+            }
+            List subList = list.subList(start,end);
+            Set subSet = new HashSet();
+            for(Object obj : subList){
+                subSet.add(obj);
+            }
+            listHasList.add(subSet);
+        }
+        return listHasList;
+    }
+
+    /**
+     * oracle in 鏌ヨ涓嶈兘瓒呰繃1000锛岃浆鎹竴涓嬮泦鍚堬紝娉ㄦ剰杩欎釜椤哄簭鍙兘浼氬彂鐢熷彉鍖�
+     * 鐢变簬SQL璇彞1000涓彲鑳藉緢闀匡紝瓒呰繃oracle10g锛屾墍浠ョ壓鐗叉�ц兘鍒嗛厤涓�500涓暟缁�
+     * @param vector vector闆嗗悎
+     * @return 杞崲鍚庣殑杩唬鍣�
+     * @throws VciBaseException
+     */
+    public static <T> Vector<Vector<T>> switchVectorForOracleIn(Vector<T> vector) {
+        Vector<Vector<T>> listHasList = new Vector<Vector<T>>();
+        if(vector == null){
+            return listHasList;
+        }
+        int muti = 1;
+        if(vector.size() >500){
+            int balance = vector.size()%500;
+            muti = (vector.size() - balance)/500 + (balance == 0?0:1);
+        }
+        List list = new ArrayList();
+        //涓轰簡淇濊瘉浠ュ墠鐨勫紩鐢ㄥ叧绯伙紝涓嶆槸鏈夎浆鏁扮粍鐨勬柟娉�
+        Iterator it = vector.iterator();
+        while(it.hasNext()){
+            list.add(it.next());
+        }
+        for(int i = 0 ; i < muti; i ++){
+            int start = i*500;
+            int end = start + 500;
+            if(i == muti-1 || end >vector.size() ){
+                end = vector.size();
+            }
+            List subList = list.subList(start,end);
+            Vector subSet = new Vector();
+            for(Object obj : subList){
+                subSet.add(obj);
+            }
+            listHasList.add(subSet);
+        }
+        return listHasList;
+    }
+
+    /**
+     * 鑾峰彇褰撳墠鐢ㄦ埛鐨勭敤鎴峰悕
+     * @return 褰撳墠鐢ㄦ埛鐨勭敤鎴峰悕
+     */
+    public static String getCurrentUserId( ){
+        SessionInfo s = getCurrentUserSessionInfoNotException();
+        if(s !=null){
+            return s.getUserId();
+        }else{
+            return  "";
+        }
+    }
+
+    /**
+     * 鑾峰彇褰撳墠鐢ㄦ埛鐨勪富閿�
+     * @return 褰撳墠鐢ㄦ埛鐨勪富閿�
+     */
+    public static String getCurrentUserOid(){
+        SessionInfo s = getCurrentUserSessionInfoNotException();
+        if(s !=null){
+            return s.getUserOid();
+        }else{
+            return  "";
+        }
+    }
+
+    /**
+     * json瀛楃涓茶浆涓哄璞�
+     * @param jsonString json瀛楃涓�
+     * @param beanClass 瀵硅薄绫诲瀷
+     * @return java瀵硅薄
+     */
+    public static <T> T jsonString2JavaBean(String jsonString, Class<T> beanClass){
+        return (T) JSONObject.parseObject(jsonString,  beanClass);
+    }
+
+    /**
+     * 鍒ゆ柇瀛楃涓叉槸鍚︿负绌猴紝涓虹┖鍒欐坊鍔犻粯璁ゅ��
+     * @param str 瀛楃涓�
+     * @param defaultValue 榛樿鍊�
+     */
+    public static void ifNullSetDefautl(String str, String defaultValue) {
+        if(isNull(str)) {
+            str = defaultValue;
+        }
+    }
+
+    /**
+     * 浠巎son瀛楃涓蹭腑鑾峰彇绗竴涓璞�
+     * @param jsonString json瀛楃涓�
+     * @param beanClass 瀵硅薄绫诲瀷
+     * @return java瀵硅薄
+     * @throws Exception
+     */
+    public static <T> T getFristObjectFromJson(String jsonString, Class<T> beanClass){
+        if(!isNull(jsonString)) {
+            return JSONObject.parseArray(jsonString, beanClass).get(0);
+        }else {
+            return null;
+        }
+    }
+
+    /**
+     * 鑾峰彇褰撳墠绾跨▼涓殑鐢ㄦ埛瀵硅薄
+     * @return 浼氳瘽淇℃伅
+     * @throws VciBaseException 濡傛灉娌℃湁鐧诲綍浼氭姏鍑哄紓甯�
+     */
+    public static SessionInfo getCurrentUserSessionInfo() throws VciBaseException {
+        SessionInfo si= getCurrentUserSessionInfoNotException();
+        if(si==null){
+            throw new VciBaseException("noLogin",new String[]{"娌℃湁褰撳墠鐢ㄦ埛淇℃伅"});
+        }
+        return si;
+    }
+
+    /**
+     * 鑾峰彇褰撳墠绾跨▼涓殑鐢ㄦ埛瀵硅薄
+     * @return 浼氳瘽瀵硅薄
+     */
+    public static SessionInfo getCurrentUserSessionInfoNotException() {
+        return WebThreadLocalUtil.getCurrentUserSessionInfoInThread().get();
+    }
+
+    /**
+     * 璁剧疆褰撳墠绾跨▼涓殑鐢ㄦ埛瀵硅薄
+     * @param sessionInfo 鐢ㄦ埛瀵硅薄
+     */
+    public static void setCurrentUserSessionInfo(SessionInfo sessionInfo){
+        WebThreadLocalUtil.getCurrentUserSessionInfoInThread().set(sessionInfo);
+    }
+
+    /**
+     * 鏄惁鏌ヨ鎬绘暟
+     * @return true琛ㄧず鏌ヨ
+     */
+    public static boolean isQueryTotal(){
+        String needQueryTotal = WebThreadLocalUtil.getNeedQueryTotalInThread().get();
+        if("false".equalsIgnoreCase(needQueryTotal)){
+            return false;
+        }else{
+            return true;
+        }
+    }
+
+    /**
+     * 灏嗗璞¤浆鎹负瀛楃涓插嚭鏉�
+     * @return json瀛楃涓�
+     */
+    public static String getJSONStringWithDateFormat(Object obj){
+        return JSONObject.toJSONStringWithDateFormat(obj, VciDateUtil.DateTimeMillFormat, SerializerFeature.WriteDateUseDateFormat);
+    }
+
+    /**
+     * 瀵硅薄杞崲涓簃ap
+     * @param o 瀵硅薄
+     * @return map瀵硅薄
+     */
+    public static Map<String,Object> objectToMap(Object o) {
+        Map<String,Object> map = new HashMap<String,Object>();
+        if(o!=null) {
+            String jsonString = JSONObject.toJSONStringWithDateFormat(o, VciDateUtil.DateTimeMillFormat, SerializerFeature.WriteDateUseDateFormat);
+            if(org.apache.commons.lang3.StringUtils.isNotBlank(jsonString)) {
+                JSONObject jsonObject = JSONObject.parseObject(jsonString);
+                if(jsonObject!=null){
+                    for(String key : jsonObject.keySet()){
+                        map.put(key,jsonObject.get(key));
+                    }
+                }
+            }
+        }
+        return map;
+    }
+
+    /**
+     * 瀵硅薄杞崲涓簃ap锛屽�间负瀛楃涓�
+     * @param o 瀵硅薄
+     * @return map瀵硅薄
+     */
+    public static Map<String,String> objectToMapString(Object o){
+        Map<String,String> map = new HashMap<String,String>();
+        if(o!=null) {
+            String jsonString = JSONObject.toJSONStringWithDateFormat(o, VciDateUtil.DateTimeMillFormat, SerializerFeature.WriteDateUseDateFormat);
+            if(org.apache.commons.lang3.StringUtils.isNotBlank(jsonString)) {
+                JSONObject jsonObject = JSONObject.parseObject(jsonString);
+                if(jsonObject!=null){
+                    for(String key : jsonObject.keySet()){
+                        map.put(key,jsonObject.getString(key));
+                    }
+                }
+            }
+        }
+        return map;
+    }
+
+
+    /**
+     * 灞炴�у�兼槸鍚︿负绌�
+     * @param obj 瀵硅薄
+     * @param f 灞炴�у璞�
+     * @return true涓嶆槸绌�
+     */
+    public static boolean isNotNullForField(Object obj, Field f){
+        if(!"serialVersionUID".equalsIgnoreCase(f.getName()) &&!"DEFAULT_INITIAL_CAPACITY".equalsIgnoreCase(f.getName())&&null!=obj && !isNullOrNullString(obj.toString())) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * 鏁扮粍杞崲涓篠tring
+     * @param array 鏁扮粍瀵硅薄
+     * @return 閫楀彿閾炬帴鐨勫瓧绗︿覆
+     */
+    public static String array2String(String[] array) {
+        if(null == array || array.length == 0) {
+            return "";
+        } else{
+            String ss = "";
+            for(String s : array){
+                ss += s + ",";
+                //1.8鍙互
+            }
+            return removeComma(ss);
+        }
+    }
+
+    /**
+     * 瀵硅薄杞崲涓哄瓧绗︿覆
+     * @param obj 瀵硅薄
+     * @return 瀛楃涓�
+     */
+    public static String getString(Object obj){
+        if(obj == null) {
+            return "";
+        }
+        if(obj instanceof Date) {
+            return VciDateUtil.date2Str((Date) obj, VciDateUtil.DateTimeFormat);
+        }
+        return String.valueOf(obj);
+    }
+
+    /**
+     * 鎷疯礉鍊煎埌map
+     * @param source 鍘熷璞�
+     * @param target 鐩爣瀵硅薄
+     * @param copyField 瑕佹嫹璐濈殑灞炴�у��
+     */
+    public static void copyValueForMap(Map source, Map target, String[] copyField){
+        Map<String,String> copyFieldMap = new HashMap<String,String>();
+        for(String field : copyField) {
+            copyFieldMap.put(field, field);
+        }
+        copyValueForMap(source,target,copyFieldMap);
+    }
+    /**
+     * 涓簃ap鎷疯礉鍊�
+     * @param source 婧愬璞�
+     * @param target 鐩爣瀵硅薄
+     * @param copyField key涓虹洰鏍囧璞¢噷鐨勫瓧娈碉紝
+     */
+    public static void copyValueForMap(Map source, Map target, Map<String,String> copyField){
+        try{
+            Iterator<String> it = copyField.keySet().iterator();
+            while(it.hasNext()){
+                String field = it.next();
+                target.put(field, source.get(copyField.get(field)));
+            }
+        }catch(Exception e){
+
+        }
+    }
+
+    /**
+     * 浠庢槧灏勫璞′腑鑾峰彇double鐨勫��
+     * @param field 瀛楁鍚嶇О
+     * @param record 鏄犲皠瀵硅薄
+     * @return double绫诲瀷鐨勫�硷紝涓嶅瓨鍦ㄦ椂杩斿洖null
+     */
+    public static Double getDoubleFromMap(String field,
+                                          Map<String, Object> record) {
+        if(isNullOrNullString(field) || record == null || !record.containsKey(field)) {
+            return null;
+        }else{
+            Object v = record.get(field);
+            if(v instanceof BigDecimal){
+                return ((BigDecimal)v).doubleValue();
+            }else if(v instanceof Double){
+                return ((Double)v).doubleValue();
+            }
+            else{
+                return getDouble((String)v);
+            }
+        }
+    }
+
+    /**
+     * 浠庢槧灏勫璞′腑鑾峰彇鏌愪釜key鐨勫瓧绗︿覆绫诲瀷鍊�
+     * @param key 閿�
+     * @param data 鏄犲皠瀵硅薄
+     * @return string绫诲瀷鐨勫�硷紝涓嶅瓨鍦ㄦ椂杩斿洖""
+     */
+    public static String getDataByKey(String key, Map<String,Object> data){
+        String value = "";
+        if(data.containsKey(key)) {
+            value = (String) data.get(key);
+        }
+        if(value == null) {
+            value = "";
+        }
+        return value;
+    }
+
+    /**
+     * 鑾峰彇涓嶆槸绌哄�肩殑鏄犲皠锛屼笖key鏄皬鍐�
+     * @param map 鑾峰彇涓嶅寘鍚┖鍊肩殑鏄犲皠瀵硅薄
+     * @return 涓嶅寘鍚┖鍊肩殑鏄犲皠瀵硅薄
+     */
+    public static Map getNotNullMap(Map map){
+        if(map == null){
+            return new HashMap();
+        }
+        Iterator it = map.keySet().iterator();
+        Map unNullMap = new HashMap();
+        while(it.hasNext()){
+            Object key = it.next();
+            String newKey = key.toString().toLowerCase();
+            Object value = map.get(key);
+            if(value !=null){
+                if(value instanceof String && isNotNull(value.toString())){
+                    unNullMap.put(newKey, value);
+                }else if(!(value instanceof String)){
+                    unNullMap.put(newKey, value);
+                }
+            }
+        }
+        return unNullMap;
+    }
+
+    /**
+     * 鑾峰彇瀵硅薄涓殑鎵�鏈夊睘鎬э紝鍖呮嫭鍏剁户鎵跨殑灞炴��
+     * @param c 瀵硅薄鎵�灞炵殑绫�
+     * @return 鎵�鏈夌殑瀛楁
+     */
+    public static List<Field> getAllFieldForObj(Class c){
+        List<Field> allField = new ArrayList<Field>();
+        Set<String> fieldNameSet = new HashSet<>();
+        for(Class<?> classz = c; classz != Object.class ; classz = classz.getSuperclass() ){
+            Field[] thisClassField = classz.getDeclaredFields();
+            for(Field field : thisClassField){
+                if(!field.getName().equals("serialVersionUID")){
+                    String fieldLowerName = field.getName().toLowerCase();
+                    if(!fieldNameSet.contains(fieldLowerName)){
+                        fieldNameSet.add(fieldLowerName);
+                        allField.add(field);
+                    }
+                }
+            }
+        }
+        return allField;
+    }
+
+    /**
+     * 鑾峰彇瀵硅薄鐨勪富閿�
+     * @param c 瀵硅薄鎵�灞炵殑绫�
+     * @return 灞炴�у璞�
+     */
+    public static Field getPkFieldForObj(Class c){
+        List<Field> allField = getAllFieldForObj(c);
+        if(allField!=null&&allField.size()>0){
+            for(Field field : allField){
+                if(field.isAnnotationPresent(Id.class)){
+                    return  field;
+                }
+            }
+            //濡傛灉娌℃壘鍒帮紝閭e氨鎵緊id
+            for(Field field : allField){
+                if(field.getName().toLowerCase().equalsIgnoreCase("oid")){
+                    return  field;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * 鑾峰彇ts鐨勫瓧娈�
+     * @param c 瀵硅薄鎵�灞炵殑绫�
+     * @return 鏃堕棿鎴崇殑灞炴�у璞�
+     */
+    public static Field getTsField(Class c){
+        List<Field> allField = getAllFieldForObj(c);
+        if(allField!=null&&allField.size()>0){
+            for(Field field : allField){
+                if(field.getName().equals("ts")){
+                    return  field;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * 鏍规嵁鍚嶇О鑾峰彇瀛楁
+     * @param fieldName 灞炴�х殑鍚嶇О
+     * @param obj 鏁版嵁瀵硅薄
+     * @return 灞炴�у璞�
+     */
+    public static Field getFieldForObject(String fieldName, Object obj){
+        if(obj == null){
+            return null;
+        }
+        return getFieldForObject(fieldName,obj.getClass());
+    }
+
+    /**
+     * 鏍规嵁灞炴�у悕绉拌幏鍙栧睘鎬х殑瀵硅薄
+     * @param fieldName 灞炴�у悕绉�
+     * @param c 瀵硅薄鎵�灞炵被
+     * @return 灞炴�у璞�
+     */
+    public static Field getFieldForObject (String fieldName, Class c){
+        List<Field> allField = getAllFieldForObj(c);
+        if(allField!=null&&allField.size()>0){
+            for(Field field : allField){
+                if(field.getName().toLowerCase().equalsIgnoreCase(fieldName.toLowerCase())){
+                    return  field;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * 鑾峰彇瀛楁鐨剆etter
+     * @param c 瀵硅薄鎵�灞炵被
+     * @param field 灞炴�у璞�
+     * @return set鐨勬柟娉�
+     */
+    public static Method getSetmethod(Class c, Field field){
+        return getSetmethod(c,field.getName());
+    }
+
+    /**
+     * 鑾峰彇瀛楁鐨刧etter
+     * @param c 瀵硅薄鎵�灞炵被
+     * @param field 灞炴�у璞�
+     * @return get鏂规硶
+     */
+    public static Method getGetmethod(Class c, Field field){
+        return getGetmethod(c,field.getName());
+    }
+
+    /**
+     * 鏍规嵁鏂规硶鐨勫悕瀛楄幏鍙栨柟娉曠殑瀵硅薄
+     * @param classObj 鎵�灞炵殑绫�
+     * @param methodName 鏂规硶鐨勫悕绉�
+     * @return 鏂规硶鐨勫璞�
+     */
+    public static Method getMethodByName(Class<?> classObj,String methodName){
+        VciBaseUtil.alertNotNull(classObj,"鑾峰彇鏂规硶鐨勫璞℃墍灞炵殑绫�",methodName,"鏂规硶鐨勫悕瀛�");
+        Method[] methods = classObj.getMethods();
+        List<Method> sameMethods = Arrays.stream(methods).filter(method -> method.getName().equalsIgnoreCase(methodName)).collect(Collectors.toList());
+        if(!CollectionUtils.isEmpty(sameMethods)){
+            return sameMethods.get(0);
+        }else{
+            return null;
+        }
+    }
+
+    /**
+     * 灏唚hereSql閲岀殑鍐呭杞寲鍒版煡璇ap閲�
+     * @param whereSql 鏌ヨ璇彞sql
+     * @return map瀵硅薄锛宬ey鏄煡璇㈡潯浠讹紝value鏄潯浠跺��
+     */
+    public static Map<String,String> whereSql2Map(
+            String whereSql) {
+        Map<String,String> map = new HashMap<String, String>();
+        if(isNotNull(whereSql)){
+            String[] selects = whereSql.split("and");
+            if(selects!=null&&selects.length>0){
+                for(String s : selects){
+                    s = s.trim();
+                    map.put(s.substring(0,s.indexOf(" ")).trim(), s.substring(s.indexOf(" ") +1).trim());
+                }
+            }
+        }
+        return map;
+    }
+
+    /**
+     * 鑾峰彇闅忔満鐨勬枃浠跺悕绉�
+     * @param prefix 鍓嶇紑
+     * @return 鏂囦欢鍚嶇О
+     */
+    public synchronized static String getRoundFilename(String prefix) {
+        if(prefix == null) {
+            prefix = "";
+        }
+        return prefix + System.currentTimeMillis();
+    }
+
+    private static String localIp = null;
+
+    /**
+     * 鑾峰彇鏈満鍦板潃锛屼笉鏄鎴风鐢佃剳鐨刬p,鏄綋鍓嶆湇鍔℃墍鍦ㄧ殑ip
+     * @return 鏈満鍦板潃锛屽鏋滄病鏈夊垯鏈�127.0.0.1
+     */
+    public static String getLocalIp(){
+        if(localIp == null){
+            try {
+                InetAddress inetAddress = getLocalHostLANAddress();
+                if (inetAddress == null) {
+                    localIp = "127.0.0.1";
+                } else {
+                    localIp = inetAddress.getHostAddress();
+                }
+            }catch (Exception e){
+                localIp = "127.0.0.1";
+            }
+        }
+        return localIp;
+    }
+
+    /**
+     * 浠庣綉缁滄帴鍙d笂鑾峰彇ip鍦板潃
+     * @return IP鎺ュ彛瀵硅薄
+     * @throws Exception 鏌ヨ鍑洪敊鏃朵細鎶涘嚭寮傚父
+     */
+    private static InetAddress getLocalHostLANAddress() throws Exception {
+        try {
+            InetAddress candidateAddress = null;
+            // 閬嶅巻鎵�鏈夌殑缃戠粶鎺ュ彛
+            for (Enumeration ifaces = NetworkInterface.getNetworkInterfaces(); ifaces.hasMoreElements(); ) {
+                NetworkInterface iface = (NetworkInterface) ifaces.nextElement();
+                // 鍦ㄦ墍鏈夌殑鎺ュ彛涓嬪啀閬嶅巻IP
+                for (Enumeration inetAddrs = iface.getInetAddresses(); inetAddrs.hasMoreElements(); ) {
+                    InetAddress inetAddr = (InetAddress) inetAddrs.nextElement();
+                    if (!inetAddr.isLoopbackAddress()) {// 鎺掗櫎loopback绫诲瀷鍦板潃
+                        if (inetAddr.isSiteLocalAddress()) {
+                            // 濡傛灉鏄痵ite-local鍦板潃锛屽氨鏄畠浜�
+                            return inetAddr;
+                        } else if (candidateAddress == null) {
+                            // site-local绫诲瀷鐨勫湴鍧�鏈鍙戠幇锛屽厛璁板綍鍊欓�夊湴鍧�
+                            candidateAddress = inetAddr;
+                        }
+                    }
+                }
+            }
+            if (candidateAddress != null) {
+                return candidateAddress;
+            }
+            // 濡傛灉娌℃湁鍙戠幇 non-loopback鍦板潃.鍙兘鐢ㄦ渶娆¢�夌殑鏂规
+            InetAddress jdkSuppliedAddress = InetAddress.getLocalHost();
+            return jdkSuppliedAddress;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * 鑾峰彇褰撳墠鐢ㄦ埛鐨勫瘑绾�
+     * @return 濡傛灉鐢ㄦ埛娌℃湁鐧诲綍锛岃繑鍥為潪瀵�
+     */
+    public static Integer getCurrentUserSecret() {
+        SessionInfo currentUserSession = getCurrentUserSessionInfoNotException();
+        if(currentUserSession != null){
+            return getInt(currentUserSession.getUserSecret());
+        }else{
+            return UserSecretEnum.NONE.getValue();
+        }
+    }
+
+    /**
+     * 鑾峰彇椤圭洰杩愯鏃剁殑璺緞锛屽湪寮�鍙戠幆澧冮噷鐨勫湴鍧�鏄埌target鏂囦欢澶�
+     * @return 椤圭洰杩愯鐨勭幆澧冨湴鍧�锛屽紑鍙戠幆澧冧负target鎵�鍦ㄧ殑鍦板潃
+     */
+    public static String getProjectPath(){
+        String path = "";
+        try {
+            String jarFilePath = ResourceUtils.getURL("classpath:").getPath();
+            if(jarFilePath.contains("!")){
+                path = new File(jarFilePath).getParentFile().getParentFile().getParent();
+            }else {
+                path = new File(jarFilePath).getParent();
+            }
+        }catch (IOException e){
+            throw new VciBaseException("鑾峰彇褰撳墠鏈嶅姟鎵�鍦ㄧ殑鏂囦欢澶瑰嚭鐜颁簡閿欒");
+        }
+        if(path.startsWith("file:\\")){
+            path = path.substring(6);
+        }
+        return path;
+    }
+
+    /**
+     * 浠庢暟鎹璞′笂鑾峰彇涓氬姟绫诲瀷鐨勫悕绉�
+     * @param modelClass 鏁版嵁瀵硅薄鎵�灞炵殑绫�
+     * @return 濡傛灉瀛樺湪娉ㄨВ灏辫幏鍙栨敞瑙d笂鐨勫悕绉帮紝鍚﹀垯鑾峰彇绫荤殑鍚嶇О
+     */
+    public static String getBtmTypeNameFromDO(Class<?> modelClass){
+        if(modelClass.isAnnotationPresent(VciBtmType.class)){
+            VciBtmType btmType = modelClass.getDeclaredAnnotation(VciBtmType.class);
+            if(btmType != null){
+                return btmType.name();
+            }
+        }
+        String name = modelClass.getSimpleName();
+        if(name.endsWith("DO")){
+            name = name.substring(0,name.length()-2);
+        }
+        return name;
+    }
+
+    /**
+     * 浠庢暟鎹璞′笂鑾峰彇閾炬帴绫诲瀷鐨勫悕绉�
+     * @param modelClass 鏁版嵁瀵硅薄鎵�灞炵殑绫�
+     * @return 濡傛灉瀛樺湪娉ㄨВ灏辫幏鍙栨敞瑙d笂鐨勫悕绉帮紝鍚﹀垯鑾峰彇绫荤殑鍚嶇О
+     */
+    public static String getLinkTypeNameFromDO(Class<?> modelClass){
+        if(modelClass.isAnnotationPresent(VciLinkType.class)){
+            VciLinkType linkType = modelClass.getDeclaredAnnotation(VciLinkType.class);
+            if(linkType !=null){
+                return linkType.name();
+            }
+        }
+        String name = modelClass.getSimpleName();
+        if(name.endsWith("DO")){
+            name = name.substring(0,name.length()-2);
+        }
+        return name;
+    }
+
+
+    /**
+     * 鏍规嵁涓氬姟绫诲瀷鑾峰彇琛ㄦ牸鍚嶇О
+     * @param btmname 涓氬姟绫诲瀷锛屽苟涓斾笉鑳芥槸瑙嗗浘
+     * @return 鏁版嵁搴撹〃鏍煎悕绉�
+     */
+    public static String getTableName(String btmname) {
+        return (VciQueryWrapperForDO.USER_TABLE_COMPATIBILITY?"platformbtm_":"vcibt_") + btmname.trim().toLowerCase();
+    }
+
+    /**
+     * 鏍规嵁閾炬帴绫诲瀷鑾峰彇琛ㄦ牸鍚嶇О
+     * @param linkName 閾炬帴绫诲瀷
+     * @return 鏁版嵁搴撹〃鏍煎悕绉�
+     */
+    public static String getLinkTableName(String linkName){
+        return (VciQueryWrapperForDO.USER_TABLE_COMPATIBILITY?"platformlt_":"vcilt_")+ linkName.trim().toLowerCase();
+    }
+
+    /**
+     * 鏄惁涓嶆槸绯荤粺闅愯棌灞炴��
+     * @param fieldName 灞炴�х殑鍚嶇О
+     * @return true琛ㄧず涓嶆槸闅愯棌
+     */
+    public static boolean isNotHiddenField(String fieldName){
+        if("id".equalsIgnoreCase(fieldName) || "name".equalsIgnoreCase(fieldName) || "description".equalsIgnoreCase(fieldName)){
+            return true;
+        }
+        if(VciQueryWrapperForDO.BASIC_FIELD_MAP.containsKey(fieldName.toLowerCase())){
+            return false;
+        }
+        if(VciQueryWrapperForDO.REVISION_MANAGE_FIELD_MAP.containsKey(fieldName.toLowerCase())){
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * 鍒╃敤鍙嶅皠灏唌ap闆嗗悎灏佽鎴恇ean瀵硅薄
+     * @param map map闆嗗悎
+     * @param clazz map闆嗗悎鎵�鏄犲皠鐨刡ean瀵硅薄
+     * @return 鏄犲皠瀵硅薄
+     */
+    public static <T> T mapToBean(Map<String, String> map, Class<T> clazz) throws Exception {
+        if(!CollectionUtils.isEmpty(map)){
+            Map<String,String> dataMap = new ConcurrentHashMap<>();
+            List<Field> allFieldForObj = getAllFieldForObj(clazz);
+            allFieldForObj.parallelStream().forEach(field->{
+                String key = map.keySet().stream().filter(s -> s.equalsIgnoreCase(field.getName())).findFirst().orElseGet(() -> null);
+                if(StringUtils.isNotBlank(key)){
+                    dataMap.put(field.getName(),map.get(key));
+                }
+            });
+            return BeanUtil.toBeanIgnoreCase(dataMap, clazz, true);
+        }
+        return null;
+    }
+
+    /**
+     * 浣跨敤freemarker鏇挎崲鍊�
+     * @param freemarker 琛ㄨ揪寮�
+     * @param replaceMap 浣跨敤鏇挎崲鐨勬暟鎹簮
+     * @return 鏇挎崲鍚庣殑鍊�
+     */
+    public static String replaceByFreeMarker(String freemarker,Map<String,String> replaceMap){
+        if(StringUtils.isBlank(freemarker)){
+            return "";
+        }
+        freemarker = freemarker.replace("root.${","${").replace("sourceData.${","${");
+        //鍏堥厤缃�
+        Configuration configuration = new Configuration(Configuration.VERSION_2_3_23);
+        StringTemplateLoader templateLoader = new StringTemplateLoader();
+        configuration.setTemplateLoader(templateLoader);
+        configuration.setDefaultEncoding("UTF-8");
+        try {
+            Template template = new Template("temp",freemarker,configuration);
+            StringWriter stringWriter = new StringWriter();
+            template.process(replaceMap, stringWriter);
+            return stringWriter.toString();
+        } catch (IOException | TemplateException e) {
+            throw new VciBaseException(e.getLocalizedMessage(),new String[0],e);
+        }
+    }
+
+    /**
+     * url鐨勫唴瀹硅浆鎹负鍙傛暟
+     * @param url 璺緞
+     * @return 鍙傛暟鐨勬牸寮�
+     */
+    public static Map<String,String> getParamsByUrl(String url){
+        if(StringUtils.isBlank(url)){
+            return new HashMap<>();
+        }
+        String[] array = url.split("&");
+        Map<String,String> params = new HashMap<>();
+        for(String temp : array){
+            if(temp.contains("=")){
+                String[] keyValues = temp.split("=");
+                params.put(keyValues[0],keyValues[1]);
+            }else{
+                params.put(temp,"");
+            }
+        }
+        return params;
+    }
+
+    /**
+     * 瀛楃鏄惁涓轰腑鏂�
+     * Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS 锛� 4E00-9FBF锛欳JK 缁熶竴琛ㄦ剰绗﹀彿
+     Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS 锛欶900-FAFF锛欳JK 鍏煎璞″舰鏂囧瓧
+     Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A 锛�3400-4DBF锛欳JK 缁熶竴琛ㄦ剰绗﹀彿鎵╁睍 A
+     Character.UnicodeBlock.GENERAL_PUNCTUATION 锛�2000-206F锛氬父鐢ㄦ爣鐐�
+     Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION 锛�3000-303F锛欳JK 绗﹀彿鍜屾爣鐐�
+     Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS 锛欶F00-FFEF锛氬崐瑙掑強鍏ㄨ褰㈠紡
+     * @param c 瀛楃
+     * @return true 鏄腑鏂�
+     * */
+    public static boolean isChinese(char c){
+        Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
+        if(ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
+                ||ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
+                ||ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
+                ||ub == Character.UnicodeBlock.GENERAL_PUNCTUATION  // GENERAL_PUNCTUATION 鍒ゆ柇涓枃鐨勨�滃彿
+                ||ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION     // CJK_SYMBOLS_AND_PUNCTUATION 鍒ゆ柇涓枃鐨勩�傚彿
+                ||ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS    // HALFWIDTH_AND_FULLWIDTH_FORMS 鍒ゆ柇涓枃鐨勶紝鍙�
+        ) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * map涓嶅尯鍒嗗ぇ灏忓啓鍒ゆ柇
+     * @param map 鏁版嵁
+     * @param key key
+     * @return true琛ㄧず瀛樺湪
+     */
+    public static boolean containsKeyUnCaseForMap(Map map,String key){
+        if(!CollectionUtils.isEmpty(map)){
+            final boolean[] finded = {false};
+            map.forEach((k,value)->{
+                if(k instanceof String && k.toString().toLowerCase(Locale.ROOT).equalsIgnoreCase(key)){
+                    finded[0] = true;
+                    return;
+                }
+            });
+            return finded[0];
+        }
+        return false;
+    }
+
+    /**
+     * 鏄惁涓轰腑鏂�
+     * @param str 瀛楃涓�
+     * @return true琛ㄧず鏈変腑鏂�
+     */
+    public static boolean isChinese(String str){
+        char[] ch =  str.toCharArray();
+        for (char c : ch) {
+            if(isChinese(c)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * 鍏ㄨ杞崐瑙�
+     * @param input 杞崲鍓�
+     * @return 杞崲鍚�
+     */
+    public static String toDBC(String input){
+        if(StringUtils.isBlank(input)){
+            return input;
+        }
+        char[] c = input.toCharArray();
+        for (int i = 0; i < c.length; i++) {
+            if(c[i] == '\u3000'){
+                c[i] = ' ';
+            }else if(c[i] > '\uFF00' && c[i] < '\uFF5F'){
+                c[i] = (char) (c[i]-65248);
+            }
+        }
+        return new String(c);
+    }
+
+    /**
+     * 鍗婅杞叏瑙�
+     * @param input 杞崲鍓�
+     * @return 杞崲鍚�
+     */
+    public static String toSBC(String input){
+        if(StringUtils.isBlank(input)){
+            return input;
+        }
+        char[] c = input.toCharArray();
+        for (int i = 0; i < c.length; i++) {
+            if(c[i] == '\u3000'){
+                c[i] = ' ';
+            }else if(c[i] > '\uFF00' && c[i] < '\uFF5F'){
+                c[i] = (char) (c[i] + 65248);
+            }
+        }
+        return new String(c);
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/VciDateUtil.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/VciDateUtil.java
new file mode 100644
index 0000000..14acc5d
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/VciDateUtil.java
@@ -0,0 +1,1090 @@
+package com.vci.starter.web.util;
+
+import org.apache.commons.lang3.StringUtils;
+
+import java.sql.Timestamp;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+
+
+/**
+ * 鏃堕棿宸ュ叿绫�
+ * 鏆傛椂涓嶇敤JDK8鐨勬棩鏈熸牸寮�
+ * @author weidy
+ */
+public  class VciDateUtil {
+
+	/**
+	 * 榛樿鏃ユ湡鏍煎紡
+	 */
+	private static final String DEFAULT_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS";
+
+	/**
+	 * 鏃ユ湡鏃堕棿
+	 */
+	public static final String DateTimeFormat = "yyyy-MM-dd HH:mm:ss";
+
+	/**
+	 * 鏃ユ湡鏃堕棿-涓嶅惈绗﹀彿
+	 */
+	public static final String DateTimeFormatStr = "yyyyMMddHHmmss";
+
+	/**
+	 * 鏃ユ湡鏃堕棿鍚绉掞紝涓嶅惈绗﹀彿
+	 */
+	public static final String DateTimeMillFormatStr = "yyyyMMddHHmmssSSS";
+
+	/**
+	 * 鏃ユ湡鏃堕棿鍚绉�
+	 */
+	public static final String DateTimeMillFormat = "yyyy-MM-dd HH:mm:ss.SSS";
+
+	/**
+	 * 鏃ユ湡鏍煎紡
+	 */
+	public static final String DateFormat = "yyyy-MM-dd";
+
+	/**
+	 * 鏃堕棿鏍煎紡
+	 */
+	public static final String TimeFormat = "HH:mm:ss";
+
+	/**
+	 * 榛樿鏋勯�犲嚱鏁�
+	 */
+	private VciDateUtil() {
+	}
+
+	/**
+	 * 瀛楃涓茶浆鎹㈡垚鏃ユ湡 濡傛灉杞崲鏍煎紡涓虹┖锛屽垯鍒╃敤榛樿鏍煎紡杩涜杞崲鎿嶄綔
+	 * 
+	 * @param str
+	 *            瀛楃涓�
+	 * @param format
+	 *            鏃ユ湡鏍煎紡
+	 * @return 鏃ユ湡
+	 * @throws ParseException
+	 */
+	public static Date str2Date(String str, String format) throws Exception {
+		if (null == str || "".equals(str) || str.equals("null")) {
+			return null;
+		}
+		// 濡傛灉娌℃湁鎸囧畾瀛楃涓茶浆鎹㈢殑鏍煎紡锛屽垯鐢ㄩ粯璁ゆ牸寮忚繘琛岃浆鎹�
+		if (null == format || "".equals(format) || format.equals("null")) {
+			format = DEFAULT_FORMAT;
+		}
+		SimpleDateFormat sdf = new SimpleDateFormat(format);
+		Date date = null;
+		try {
+			date = sdf.parse(str);
+			return date;
+		} catch (ParseException e) {
+			throw new Exception(e);
+		}
+	}
+
+	/**
+	 * 鑾峰彇褰撳墠鍛ㄧ殑鍛ㄤ竴
+	 * @return 鍛ㄤ竴鐨勬棩鏈�
+	 */
+	public static Date getCurrentMonday(){
+		return getCurrentWeekDay(2);
+	}
+
+	/**
+	 * 鑾峰彇褰撳墠鍛ㄧ殑鏌愪竴澶�
+	 * @param dayOfWeek 浠庡懆鏃ュ紑濮嬩负1锛屽懆涓�涓�2锛屼竴娆℃帹绠�
+	 * @return 鏃ユ湡
+	 */
+	public static Date getCurrentWeekDay(int dayOfWeek){
+		if(dayOfWeek>7){
+			dayOfWeek = 7;
+		}
+		if(dayOfWeek<1){
+			dayOfWeek = 1;
+		}
+		Date date = new Date();
+		Calendar calendar = Calendar.getInstance();
+
+		calendar.setTime(date);
+		calendar.set(Calendar.DAY_OF_WEEK, dayOfWeek);
+		calendar.set(Calendar.HOUR_OF_DAY, 0);
+		calendar.set(Calendar.MINUTE, 0);
+		calendar.set(Calendar.SECOND, 0);
+		calendar.set(Calendar.MILLISECOND, 0);
+		return calendar.getTime();
+	}
+
+	/**
+	 * 鑾峰彇褰撳墠鍛ㄧ殑鍛ㄤ簲
+	 * @return 鏃ユ湡
+	 */
+	public static Date getCurrentFriday(){
+		return getCurrentWeekDay(6);
+	}
+
+	/**
+	 * 鏃ユ湡杞崲涓哄瓧绗︿覆
+	 * 
+	 * @param date
+	 *            鏃ユ湡
+	 * @param format
+	 *            鏃ユ湡鏍煎紡
+	 * @return 瀛楃涓�
+	 */
+	public static String date2Str(Date date, String format) {
+		if (null == date) {
+			return null;
+		}
+		if (format == null || format.trim().length() == 0) {
+			format = DEFAULT_FORMAT;
+		}
+		SimpleDateFormat sdf = new SimpleDateFormat(format);
+		return sdf.format(date);
+	}
+
+	/**
+	 * 鏃堕棿鎴宠浆鎹负瀛楃涓�
+	 * 
+	 * @param time 鏃堕棿鎴�
+	 * @return 瀛楃涓�
+	 */
+	public static String timestamp2Str(Timestamp time) {
+		Date date = null;
+		if (null == time) {
+			return null;
+		}
+		if (null != time) {
+			date = new Date(time.getTime());
+		}
+		return date2Str(date, DEFAULT_FORMAT);
+	}
+
+	/**
+	 * 瀛楃涓茶浆鎹㈡椂闂存埑
+	 * 
+	 * @param str 瀛楃涓�
+	 * @return 鏃堕棿鎴�
+	 * @throws Exception 瀛楃涓茬殑鏍煎紡鍑虹幇閿欒鐨勬椂鍊欐姏鍑哄紓甯�
+	 */
+	public static Timestamp str2Timestamp(String str) throws Exception {
+		if (str == null || str.trim().length() == 0) {
+			return null;
+		}
+		Date date = str2Date(str, DEFAULT_FORMAT);
+		return new Timestamp(date.getTime());
+	}
+
+
+
+	/**
+	 * 瀵规瘮涓や釜鏃ユ湡鐨勫ぇ灏�
+	 * 
+	 * @param date 鏃堕棿瀵硅薄1
+	 * @param date1 鏃堕棿瀵硅薄2
+	 * @return
+	 */
+	public static String compareDate(String date, String date1)
+			throws Exception {
+		if (date == null || date.trim().length() == 0 || date1 == null
+				|| date1.trim().length() == 0) {
+			throw new Exception("浼犲叆compareDate鐨勫弬鏁颁负绌�");
+		}
+		try {
+			long time = str2Date(date, DateFormat).getTime();
+			long time1 = str2Date(date1, DateFormat).getTime();
+			if (time == time1) {
+				return "=";
+			}
+			if (time < time1) {
+				return "<";
+			}
+			if (time > time1) {
+				return ">";
+			}
+			else {
+				return "";
+			}
+		} catch (Exception e) {
+			throw e;
+		}
+	}
+
+	/**
+	 * 鏃堕棿瀵规瘮
+	 * @param date 鏃ユ湡瀵硅薄1
+	 * @param date1 鏃ユ湡瀵硅薄2
+	 * @return 瀵规瘮鐨勭粨鏋�
+	 */
+	public static String compareDate(Date date, Date date1) {
+		if (date == null || date1 == null) {
+			return "";
+		}
+		long time = date.getTime();
+		long time1 = date1.getTime();
+		if (time == time1) {
+			return "=";
+		}
+		if (time < time1) {
+			return "<";
+		}
+		if (time > time1) {
+			return ">";
+		}
+		else {
+			return "";
+		}
+	}
+
+	/**
+	 * 鍦ㄦ椂闂存埑涓婂姞鍒嗛挓
+	 * 
+	 * @param date 鏃ユ湡瀛楃涓�
+	 * @param minute 鍒嗛挓
+	 * @return 娣诲姞鍚庢棩鏈熷��
+	 * @throws Exception 鏃ユ湡瀛楃涓茬殑鏍煎紡閿欒鏃朵細鎶涘嚭閿欒
+	 */
+	public static String dateTimeAddMinutes(String date, int minute)
+			throws Exception {
+		String ret = "";
+		if (date == null || date.equals("")) {
+			date = date2Str(getNow(), DEFAULT_FORMAT);
+		}
+		if (minute == 0) {
+			ret = date;
+		}
+		else {
+			Date d = VciDateUtil.str2Date(date, DateTimeFormat);
+			Calendar cal = Calendar.getInstance();
+			cal.setTime(d);
+			cal.add(Calendar.MINUTE,minute);
+			return date2Str(cal.getTime(), DateTimeFormat);
+		}
+		return ret;
+	}
+
+	/**
+	 * 鍦ㄦ椂闂翠笂鍔犲ぉ鏁�
+	 * 
+	 * @param date 鏃ユ湡瀛楃涓�
+	 * @param dayCount 澶╂暟锛屽彲浠ヤ负璐熸暟
+	 * @return 娣诲姞鍚庣殑鏃ユ湡鍊�
+	 * @throws Exception 鏃ユ湡瀛楃涓茬殑鏍煎紡閿欒
+	 */
+	public static Date getDateAddDay(String date, int dayCount)
+			throws Exception {
+		if (date == null || date.equals("") || date.equals("null")) {
+			return getNow();
+		}
+		else {
+			if (dayCount == 0) {
+				return str2Date(date, DateFormat);
+			}
+			else {
+				Date d = str2Date(date, DateFormat);
+				Calendar cal = Calendar.getInstance();
+				cal.setTime(d);
+				cal.add(Calendar.DAY_OF_MONTH,dayCount);
+				return cal.getTime();
+			}
+		}
+	}
+
+	/**
+	 * 鍦ㄦ椂闂翠笂鍔犲ぉ鏁�
+	 * 
+	 * @param date 鏃ユ湡瀵硅薄
+	 * @param dayCount 澶╂暟
+	 * @return 娣诲姞鍚庣殑鏃ユ湡瀵硅薄
+	 */
+	public static Date getDateAddDay(Date date, int dayCount) {
+		if (dayCount == 0) {
+			return date;
+		}
+		else {
+			Calendar cal = Calendar.getInstance();
+			cal.setTime(date);
+			cal.add(Calendar.DAY_OF_MONTH,dayCount);
+			return cal.getTime();
+		}
+	}
+
+	/**
+	 * 鏃ユ湡鐩稿噺
+	 * 
+	 * @param beginDateStr 寮�濮嬫棩鏈熷瓧绗︿覆
+	 * @param endDateStr 缁撴潫鏃ユ湡瀛楃涓�
+	 * @return 鐩稿噺鍚庢棩鏈熷��
+	 */
+	public static long getDaySub(String beginDateStr, String endDateStr) {
+		if (beginDateStr == null || beginDateStr.trim().equals("")
+				|| endDateStr == null || endDateStr.trim().equals("")) {
+			return 0;
+		}
+		long day = 0;
+		SimpleDateFormat format = new SimpleDateFormat(DateFormat);
+		Date beginDate;
+		Date endDate;
+		try {
+			beginDate = format.parse(beginDateStr);
+			endDate = format.parse(endDateStr);
+			day = (endDate.getTime() - beginDate.getTime())
+					/ (24 * 60 * 60 * 1000);
+		} catch (ParseException e) {
+			e.printStackTrace();
+		}
+		return day;
+	}
+
+	/**
+	 * 鑾峰彇鐩稿叧鏃ユ湡鐩稿噺
+	 * @param date 寮�濮嬫棩鏈�
+	 * @param date1 缁撴潫鏃ユ湡
+	 * @return 鐩稿噺鐨勫樊棰�
+	 */
+	public static long getDaySub(Date date, Date date1) {
+		return (date.getTime() - date1.getTime()) / (24 * 60 * 60 * 1000);
+	}
+
+
+	/**
+	 * 鍦ㄦ椂闂翠笂鍔犱笂鏌愪釜鏁般�備笉鑳戒娇鐢╣etTime鍚庣劧鍚庢坊鍔犳暟锛屼細閫犳垚long鐨勬孩鍑�
+	 * @param d 鍘熷鏃ユ湡瀵硅薄
+	 * @param addDayType 娣诲姞鐨勭被鍨嬶紝蹇呴』鏄疌alendar.YEAR,Calendar.MOUTH,Calendar.DAY_OF_YEAR锛孋alendar.DAY_OF_WEEK鍏朵腑涓�涓�
+	 * @param addCount 瑕佹坊鍔犵殑鏁帮紝鍙互鏄礋鏁�
+	 * @return 娣诲姞鑾峰彇鍑忓幓鐨勬棩鏈�
+	 */
+	public static Date addOrSubDate(Date d, int addDayType, int addCount ) {
+		Calendar cal = Calendar.getInstance();
+		cal.setTime(d);
+		cal.add(addDayType,addCount);
+		return cal.getTime();
+	}
+
+	/**
+	 * 鑾峰彇褰撴湡鏃堕棿
+	 * 
+	 * @return 褰撳墠鏃ユ湡
+	 */
+	public static Date getNow() {
+		return new Date();
+	}
+
+	/**
+	 * 鑾峰彇褰撳墠鏃堕棿鐨勫瓧绗︿覆鏍煎紡
+	 * 
+	 * @return 褰撳墠鏃ユ湡鐨勫瓧绗︿覆褰㈠紡
+	 */
+	public static String getNowString() {
+		return getNowString(DEFAULT_FORMAT);
+	}
+
+	/**
+	 * 鑾峰彇褰撳墠鏃堕棿鐨勫瓧绗︿覆鏍煎紡锛堝彲鑷畾涔夋椂闂存牸寮忥級
+	 * 
+	 * @param simpleDateFormat
+	 *            鏃堕棿鐨勬牸寮�
+	 * @return 鎸囧畾鏍煎紡鐨勫綋鍓嶆棩鏈熷瓧绗︿覆
+	 */
+	public static String getNowString(String simpleDateFormat) {
+		Date currentTime = new Date();
+		SimpleDateFormat formatter = new SimpleDateFormat(simpleDateFormat);
+		return formatter.format(currentTime);
+	}
+
+	/**
+	 * 鑾峰彇褰撳墠鏃堕棿锛堝彲鑷畾涔夋椂闂存牸寮忥級
+	 * 
+	 * @param simpleDateFormat
+	 *            鏃堕棿鏍煎紡
+	 * @return 鏍规嵁鎸囧畾鏍煎紡鐨勫綋鍓嶆棩鏈熷璞�
+	 * @throws Exception 鏃ユ湡鏍煎紡瀛楃涓茬殑鍐呭閿欒鏃舵姏鍑哄紓甯�
+	 */
+	public static Date getNow(String simpleDateFormat) throws Exception {
+		return str2Date(getNowString(simpleDateFormat), simpleDateFormat);
+	}
+
+	/**
+	 * 鑾峰彇鍓╀笅鐨勬椂闂�
+	 * 
+	 * @param oldtime 鍘熷鏃堕棿
+	 * @param newTime 缁撴潫鏃堕棿
+	 * @return 鏃堕棿浣欓锛岃礋鏁拌〃绀哄凡缁忚秴鏃朵簡
+	 */
+	public static String getCountdown(String oldtime, String newTime) {
+		if (oldtime == null || oldtime.trim().equals("") || newTime == null
+				|| newTime.equals("")) {
+			return "";
+		} else {
+			try {
+				Date date1 = new SimpleDateFormat(DateTimeFormat)
+						.parse(oldtime);
+				Date date2 = new SimpleDateFormat(DateTimeFormat)
+						.parse(newTime);
+				long l = date1.getTime() - date2.getTime() > 0 ? date1
+						.getTime() - date2.getTime() : date2.getTime()
+						- date1.getTime();
+				long d = 0;
+				long yushu = l;
+				long h = 0;
+				long m = 0;
+				if (l > (24 * 60 * 60 * 1000)) {
+					yushu = l % (24 * 60 * 60 * 1000);
+					d = (l - yushu) / (24 * 60 * 60 * 1000);
+				}
+				if (yushu > (60 * 60 * 1000)) {
+					h = (yushu - yushu % (60 * 60 * 1000)) / (60 * 60 * 1000);
+					yushu = yushu % (60 * 60 * 1000);
+				}
+				if (yushu > (60 * 1000)) {
+					m = (yushu - yushu % (60 * 1000)) / (60 * 1000);
+				}
+				if (date1.getTime() - date2.getTime() < 0) {
+					return "宸茬粡瓒呮湡" + d + "澶�" + h + "灏忔椂" + m + "鍒�";
+				}
+				else {
+					return "杩樺墿涓�" + d + "澶�" + h + "灏忔椂" + m + "鍒�";
+				}
+			} catch (Exception te) {
+				return "";
+			}
+		}
+	}
+
+	/**
+	 * 涓や釜鏃堕棿鐩稿噺
+	 * 
+	 * @param oldTime 鍘熸椂闂�
+	 * @param newTime 缁撴潫鏃堕棿
+	 * @return 鐩稿噺鍚庣殑姣鏁�
+	 */
+	public static long getDateDiffer(String oldTime, String newTime) {
+		if (oldTime == null || oldTime.trim().equals("") || newTime == null
+				|| newTime.equals("")) {
+			return 0;
+		} else {
+			try {
+				Date date1 = new SimpleDateFormat(DateTimeFormat)
+						.parse(oldTime);
+				Date date2 = new SimpleDateFormat(DateTimeFormat)
+						.parse(newTime);
+				return date1.getTime() - date2.getTime();
+			} catch (Exception e) {
+				return 0;
+			}
+		}
+	}
+
+	/**
+	 * 鑾峰彇鏌愬勾涓�鍏辨湁澶氬皯鍛�
+	 * 
+	 * @param year 骞翠唤
+	 * @return 鏌愬勾鐨勫懆鏁�
+	 */
+	public static int getWeeks(int year) {
+		if (year == 0) {
+			return year;
+		}
+		int week = 0;
+		int days = 365;
+		if (year % 400 == 0 || year % 4 == 0 && year % 100 != 0) {
+			days = 366;
+		}
+		week = days / 7;
+		return week;
+	}
+
+	/**
+	 * 浼犲叆鐨勬椂闂村湪杩欎竴骞存槸绗嚑鍛�
+	 * 
+	 * @param date 鏃ユ湡瀵硅薄
+	 * @return 鏃ユ湡鎵�鍦ㄧ殑鍛ㄦ暟
+	 */
+	public static int getWeekOnDate(Date date) {
+		GregorianCalendar g = new GregorianCalendar();
+		g.setTime(date);
+		if (isSunday(date)) {
+			return g.get(Calendar.WEEK_OF_YEAR) - 1;
+		}
+		return g.get(Calendar.WEEK_OF_YEAR);// 鑾峰緱鍛ㄦ暟
+	}
+
+	/**
+	 * 鑾峰彇鏌愬勾涓煇鍛ㄧ殑鏃ュ巻瀵硅薄
+	 * 
+	 * @param year 骞翠唤
+	 * @param week 鍛ㄦ暟
+	 * @return 鏃ュ巻瀵硅薄
+	 * @throws Exception 鍦ㄥ勾浠界殑瀛楃涓叉牸寮忛敊璇椂鎶涘嚭閿欒
+	 */
+	public static Calendar getCalendarFromWeek(String year, int week)
+			throws Exception {
+		Date newDate;
+		newDate = str2Date(year + "-01-01", DateFormat);
+		Calendar caleNew = Calendar.getInstance();
+		caleNew.setTime(newDate);
+		caleNew.add(Calendar.WEEK_OF_YEAR, week - 1);
+		return caleNew;
+	}
+
+	/**
+	 * 鑾峰彇鏌愬勾涓煇鍛ㄧ殑鏃ユ湡鏁扮粍
+	 * 
+	 * @param year 骞翠唤
+	 * @param week 鍛ㄦ暟
+	 * @return 鏌愪竴鍛ㄧ殑鏁翠釜鏃ユ湡
+	 */
+	public static String[] getDaysInWeek(int year, int week) {
+		String[] thisWeek = new String[7];
+		try {
+			GregorianCalendar gc = (GregorianCalendar) getCalendarFromWeek(
+					String.valueOf(year) + "-01-01", week);
+			for (int i = 0; i < 7; i++) {
+				Calendar myCale = Calendar.getInstance();
+				myCale.setTime(gc.getTime());
+				myCale.set(Calendar.DATE,
+						gc.get(Calendar.DATE) - gc.get(Calendar.DAY_OF_WEEK)
+								+ i + 2);
+				thisWeek[i] = date2Str(myCale.getTime(), DateFormat);
+			}
+		} catch (Exception e) {
+			System.out.println(e.getMessage());
+		}
+		return thisWeek;
+	}
+
+	/**
+	 * 鍒ゆ柇浠婂ぉ鏄笉鏄懆鏃�
+	 * 
+	 * @return true琛ㄧず涓哄懆鏃ワ紝false琛ㄧず涓轰笉鏄懆鏃�
+	 */
+	public static boolean isSunday() {
+		return isSunday(new Date());
+	}
+
+	/**
+	 * 鍒ゆ柇鏌愬ぉ鏄笉鏄懆鏃�
+	 * 
+	 * @param date 鏃ユ湡瀵硅薄
+	 * @return true琛ㄧず涓哄懆鏃ワ紝false琛ㄧず涓轰笉鏄懆鏃�
+	 */
+	public static boolean isSunday(Date date) {
+		Calendar calendar = Calendar.getInstance();
+		calendar.setTime(date);
+		int week = calendar.get(Calendar.DAY_OF_WEEK) - 1;
+		if (week == 0) {
+			return true;
+		}
+		else {
+			return false;
+		}
+	}
+
+	/**
+	 * 鍒ゆ柇鏌愬ぉ鏄惁鍛ㄦ湯
+	 * 
+	 * @param date 鏃ユ湡瀵硅薄
+	 * @return true琛ㄧず涓哄懆鏈紝false琛ㄧず涓轰笉鏄懆鏈�
+	 */
+	public static boolean isWeekend(Date date) {
+		Calendar calendar = Calendar.getInstance();
+		calendar.setTime(date);
+		int week = calendar.get(Calendar.DAY_OF_WEEK) - 1;
+		if (week == 0 || week == 1) {
+			return true;
+		}
+		else {
+			return false;
+		}
+	}
+
+	/**
+	 * 鍒ゆ柇鏌愬ぉ鏄惁涓哄懆5
+	 * 
+	 * @param date 鏃ユ湡瀵硅薄
+	 * @return true琛ㄧず涓哄懆浜旓紝false琛ㄧず涓轰笉鏄懆浜�
+	 */
+	public static boolean isFriday(Date date) {
+		Calendar calendar = Calendar.getInstance();
+		calendar.setTime(date);
+		int week = calendar.get(Calendar.DAY_OF_WEEK) - 1;
+		if (week == 5) {
+			return true;
+		}
+		else {
+			return false;
+		}
+	}
+
+	/**
+	 * 鍒ゆ柇鏌愬ぉ鏄惁涓烘湀鏈�
+	 * 
+	 * @param date 鏃ユ湡
+	 * @return true琛ㄧず涓烘湀鏈紝false琛ㄧず涓轰笉鏄湀鏈�
+	 */
+	public static boolean isMouthEnd(Date date) {
+		Calendar calendar = Calendar.getInstance();
+		calendar.setTime(date);
+		int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
+		int endMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
+		if (endMonth == dayOfMonth) {
+			return true;
+		} else {
+			return false;
+		}
+	}
+
+	/**
+	 * 鍒ゆ柇鏌愬ぉ鏄惁涓哄鏈�
+	 * 
+	 * @param date 鏃ユ湡瀵硅薄
+	 * @return true琛ㄧず涓哄鏈紝false琛ㄧず涓轰笉鏄鏈�
+	 */
+	public static boolean isSeasonEnd(Date date) {
+		Calendar calendar = Calendar.getInstance();
+		calendar.setTime(date);
+		int y = calendar.get(Calendar.MONTH) + 1;
+		int d = calendar.get(Calendar.DATE);
+		if (y == 3 && d == 31) {
+			return true;
+		}
+		if (y == 6 && d == 30) {
+			return true;
+		}
+		if (y == 9 && d == 30) {
+			return true;
+		}
+		if (y == 12 && d == 31) {
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * 鍒ゆ柇鏌愬ぉ鏄惁涓哄勾鏈�
+	 * 
+	 * @param date 鏃ユ湡瀵硅薄
+	 * @return true琛ㄧず涓哄勾鏈紝false琛ㄧず涓轰笉鏄勾鏈�
+	 */
+	public static boolean isYearEnd(Date date) {
+		Calendar calendar = Calendar.getInstance();
+		calendar.setTime(date);
+		int y = calendar.get(Calendar.MONTH) + 1;
+		int d = calendar.get(Calendar.DATE);
+		if (y == 12 && d == 31) {
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * 鑾峰彇鑰楁椂
+	 * 
+	 * @param newDate 鏂版棩鏈�
+	 * @param startDate 寮�濮嬫棩鏈�
+	 * @return 鑰楁椂鐨勬绉掓暟
+	 */
+	public static Long getProcessedTime(Date newDate, Date startDate) {
+		try {
+			Long p = (newDate.getTime() - startDate.getTime());
+			return p;
+		} catch (Exception e) {
+			return 0L;
+		}
+	}
+
+	/**
+	 * 鑾峰彇鑰楁椂
+	 * 
+	 * @param startDate 寮�濮嬫棩鏈�
+	 * @return 鍒板綋鍓嶆椂闂寸殑鑰楁椂鐨勫ソ鎻忚堪
+	 */
+	public static String getProcessedTime(Date startDate) {
+		return getProcessedTime(new Date(), startDate) + "ms";
+	}
+
+	/**
+	 * 鑾峰彇褰撳墠鐨勫勾浠�
+	 * @return 骞翠唤
+	 */
+	public static String getCurrentYear() {
+		Calendar c = Calendar.getInstance();
+		return String.valueOf(c.get(Calendar.YEAR) + 1900);
+	}
+
+	/**
+	 * 鑾峰彇褰撳勾鐨勫勾鍒�
+	 * @return 鏃ユ湡瀛楃涓�
+	 */
+	public static String getCurrentYearStart() {
+		return getCurrentYear() + "-01-01 00:00:00";
+	}
+
+	/**
+	 * 鑾峰彇褰撳勾鐨勫勾鏈�
+	 * @return 鏃ユ湡瀛楃涓�
+	 */
+	public static String getCurrentYearEnd() {
+		return getCurrentYear() + "-12-31 23:59:59";
+	}
+
+	/**
+	 * 鑾峰彇褰撳墠鎵�鍦ㄧ殑瀛e害
+	 * @return 瀛e害
+	 */
+	public static String getCurrentQuarter() {
+		String currentMouth = getCurrentMouth();
+		int currentMouthInt = getInt(currentMouth);
+		if (currentMouthInt > 0 && currentMouthInt <= 3) {
+			return "1";
+		}
+		else if (currentMouthInt > 3 && currentMouthInt <= 6) {
+			return "2";
+		}
+		else if (currentMouthInt > 6 && currentMouthInt <= 9) {
+			return "3";
+		}
+		else {
+			return "4";
+		}
+	}
+
+	/**
+	 * 瀛楃涓茶浆涓烘暟瀛�
+	 * @param s 瀛楃涓�
+	 * @return 鏁板瓧
+	 */
+	private static int getInt(String s){
+		try{
+			return Integer.valueOf(s);
+		}catch (Exception e){
+
+		}
+		return 0;
+	}
+
+	/**
+	 * 鑾峰彇褰撳墠瀛e害鐨勫紑濮嬫棩鏈�
+	 * @return 鏃ユ湡瀛楃涓�
+	 */
+	public static String getCurrentQuarterStart() {
+		String currentQuarter = getCurrentQuarter();
+		if ("1".equalsIgnoreCase(currentQuarter)) {
+			return getCurrentYearStart();
+		}
+		else if ("2".equalsIgnoreCase(currentQuarter)) {
+			return getCurrentYear() + "-04-01 00:00:00";
+		}
+		else if ("3".equalsIgnoreCase(currentQuarter)) {
+			return getCurrentYear() + "-07-01 00:00:00";
+		}
+		else {
+			return getCurrentYear() + "-10-01 00:00:00";
+		}
+	}
+
+	/**
+	 * 鑾峰彇褰撳墠瀛e害鐨勭粨鏉熸棩鏈�
+	 * @return 鏃ユ湡瀛楃涓�
+	 */
+	public static String getCurrentQuarterEnd() {
+		String currentQuarter = getCurrentQuarter();
+		if ("1".equalsIgnoreCase(currentQuarter)) {
+			return getCurrentYear() + "-03-31 23:59:59";
+		}
+		else if ("2".equalsIgnoreCase(currentQuarter)) {
+			return getCurrentYear() + "-06-30 23:59:59";
+		}
+		else if ("3".equalsIgnoreCase(currentQuarter)) {
+			return getCurrentYear() + "-09-30 23:59:59";
+		}
+		else {
+			return getCurrentYear() + "-12-31 23:59:59";
+		}
+	}
+
+	/**
+	 * 鑾峰彇褰撳墠鐨勬湀浠�
+	 * @return 鏃ユ湡瀛楃涓�
+	 */
+	public static String getCurrentMouth() {
+		Calendar cal = Calendar.getInstance();
+		cal.setTime(getNow());
+		int m = cal.get(Calendar.MONTH);
+		if (m < 10) {
+			return "0" + String.valueOf(m);
+		}
+		else {
+			return String.valueOf(m);
+		}
+	}
+
+	/**
+	 * 鑾峰彇褰撳墠鏈堜唤鐨勫紑濮嬫椂闂�
+	 * @return 鏃ユ湡鏍煎紡瀛楃涓�
+	 */
+	public static String getCurrentMouthStart() {
+		String currentMouth = getCurrentMouth();
+		return getCurrentYear() + "-" + currentMouth + "-01 00:00:00";
+	}
+
+	/**
+	 * 鑾峰彇褰撳墠鏈堜唤鐨勭粨鏉熸椂闂�
+	 * @return 鏃ユ湡鏍煎紡瀛楃涓�
+	 */
+	public static String getCurrentMouthEnd() {
+		String currentMouth = getCurrentMouth();
+		int currentMouthInt = getInt(currentMouth);
+		if (currentMouthInt == 1 || currentMouthInt == 3
+				|| currentMouthInt == 5 || currentMouthInt == 7
+				|| currentMouthInt == 8 || currentMouthInt == 10
+				|| currentMouthInt == 12) {
+			return getCurrentYear() + "-" + currentMouth + "-31 23:59:59";
+		}
+		else if (currentMouthInt == 2) {
+			if (isLeapYear(getInt(getCurrentYear()))) {
+				return getCurrentYear() + "-" + currentMouth + "-29 23:59:59";
+			}else {
+				return getCurrentYear() + "-" + currentMouth + "-28 23:59:59";
+			}
+		} else {
+			return getCurrentYear() + "-" + currentMouth + "-30 23:59:59";
+		}
+	}
+
+	/**
+	 * 鏄惁鏄棸骞�
+	 * 
+	 * @param year 骞翠唤
+	 * @return true涓洪棸骞达紝false涓嶆槸闂板勾
+	 */
+	public static boolean isLeapYear(int year) {
+		if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
+			return true;
+		}else {
+			return false;
+		}
+	}
+
+	/**
+	 * 鑾峰彇褰撳墠鏃ユ湡
+	 * @return 褰撳墠鏃ユ湡鐨勫瓧绗︿覆
+	 */
+	public static String getCurrentDay() {
+		Calendar cal = Calendar.getInstance();
+		cal.setTime(getNow());
+		int day = cal.get(Calendar.DAY_OF_MONTH);
+		if (day < 10) {
+			return "0" + String.valueOf(day);
+		}else {
+			return String.valueOf(day);
+		}
+	}
+
+	/**
+	 * 鑾峰彇褰撳ぉ鐨勫紑濮嬫椂闂�
+	 * @return  鏃ユ湡瀛楃涓�
+	 */
+	public static String getCurrentDayStart() {
+		return  LocalDateTime.of(LocalDateTime.now().toLocalDate(), LocalTime.MIN).format(DateTimeFormatter.ofPattern(DateTimeFormat));
+	}
+
+	/**
+	 * 鑾峰彇褰撳墠鐨勭粨鏉熸椂闂�
+	 * @return 鏃ユ湡瀛楃涓�
+	 */
+	public static String getCurrentDayEnd() {
+		return  LocalDateTime.of(LocalDateTime.now().toLocalDate(), LocalTime.MAX).format(DateTimeFormatter.ofPattern(DateTimeFormat));
+	}
+
+	/**
+	 * 鑾峰彇鏌愪釜鏃堕棿娈靛唴鐨勬墍鏈夋棩鏈�
+	 * @param dBegin 寮�濮嬫棩鏈�
+	 * @param dEnd 缁撴潫鏃ユ湡
+	 * @return 鏈熼棿鐨勬墍鏈夋棩鏈�
+	 */
+	public static List<Date> getDateInRange(Date dBegin, Date dEnd) {
+		List lDate = new ArrayList();
+		lDate.add(dBegin);
+		Calendar calBegin = Calendar.getInstance();
+		// 浣跨敤缁欏畾鐨� Date 璁剧疆姝� Calendar 鐨勬椂闂�
+		calBegin.setTime(dBegin);
+		Calendar calEnd = Calendar.getInstance();
+		// 浣跨敤缁欏畾鐨� Date 璁剧疆姝� Calendar 鐨勬椂闂�
+		calEnd.setTime(dEnd);
+		// 娴嬭瘯姝ゆ棩鏈熸槸鍚﹀湪鎸囧畾鏃ユ湡涔嬪悗
+		while (dEnd.after(calBegin.getTime())) {
+			// 鏍规嵁鏃ュ巻鐨勮鍒欙紝涓虹粰瀹氱殑鏃ュ巻瀛楁娣诲姞鎴栧噺鍘绘寚瀹氱殑鏃堕棿閲�
+			calBegin.add(Calendar.DAY_OF_MONTH, 1);
+			lDate.add(calBegin.getTime());
+		}
+		return lDate;
+	}
+
+	/**
+	 * 瀛楃涓茶浆鏃堕棿鏍煎紡锛屼富瑕佹槸鐩存帴鐢╤ibernate鏌ヨSQL璇彞鍑烘潵鐨勫唴瀹逛娇鐢�
+	 * @param value 鍊�
+	 * @return 绉婚櫎浜嗘绉掔殑鍚庝笁浣�
+	 */
+	public static Date getDateFromStringForVci(String value){
+		Date d = null;
+		if(StringUtils.isNotBlank(value)){
+			try{
+				if(value.indexOf("-") > -1 && value.indexOf(".")> -1 &&value.indexOf(" ") > -1 && value.substring(value.lastIndexOf(".") +1).length() >= 9){
+					//2013-4-19.14.5. 45. 734000000  杩欑鏍煎紡锛岃繖涓湪浣跨敤SQL璇彞鐩存帴鏌ヨ鍑烘椂闂村瓧娈电殑鏃跺�欏氨浼氭樉绀烘垚杩欐牱
+					String ymd = value.substring(0,value.indexOf("."));
+					value = value.substring(value.indexOf(".") + 1);
+					if(value.indexOf(".")> -1){
+						String hms = value.substring(0,value.lastIndexOf("."));
+						String nano = value.substring(value.lastIndexOf(".") + 1).trim();
+						if(nano.length()>3){
+							nano = nano.substring(0,3);
+						}
+						hms = hms.replace(".", ":").replace(" ", "");
+						Date tempDate = VciDateUtil.str2Date(ymd + " " + hms , "yyyy-M-d h:m:s");
+						if(tempDate!=null){
+							d = VciDateUtil.str2Date(VciDateUtil.date2Str(tempDate, VciDateUtil.DateTimeFormat) + "." + nano, VciDateUtil.DateTimeMillFormat);
+						}
+					}
+				} else if(VciBaseUtil.isNumber(value)){
+					d = new Date();
+					try{
+						d = VciDateUtil.str2Date(value, VciDateUtil.DateTimeMillFormatStr);
+					}catch(Exception e){
+						if(value.length() != 14){
+							d.setTime(VciBaseUtil.getLong(value));
+						}else {
+							try {
+								d = VciDateUtil.str2Date(value, VciDateUtil.DateTimeFormatStr);
+								Calendar cal = Calendar.getInstance();
+								cal.setTime(d);
+								if(cal.get(Calendar.YEAR) < 1900){
+									d.setTime(VciBaseUtil.getLong(value));
+								}
+							} catch (Exception e2) {
+								//璇存槑涓嶆槸鏃堕棿鏍煎紡
+								d.setTime(VciBaseUtil.getLong(value));
+							}
+						}
+					}
+				}else{
+					d = VciDateUtil.str2Date(value, VciDateUtil.DateTimeMillFormat);
+				}
+			}catch(Exception e){
+				try{
+					d = VciDateUtil.str2Date(value, VciDateUtil.DateTimeMillFormat);
+				}catch (Exception e1) {
+
+				}
+			}
+		}
+		return d;
+	}
+
+	/**
+	 * 璇诲彇鏂囨湰鍒版椂闂存牸寮�
+	 * @param text
+	 * @return
+	 */
+	public static Date readText2Date(String text){
+		if(VciBaseUtil.isNullOrNullString(text)) {
+			return null;
+		}
+		SimpleDateFormat dateFormat = null;
+		int exactDateLength = 0;
+		if(text.trim().indexOf("/")>-1 && text.trim().length() ==19){
+			exactDateLength = 19;
+			dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
+		}
+		else if(text.trim().indexOf("/")>-1 && text.trim().length() ==17){
+			exactDateLength = 17;
+			dateFormat = new SimpleDateFormat("yy/MM/dd HH:mm:ss");
+		}
+		else if(text.trim().indexOf("/")>-1 && text.trim().length() ==8){
+			exactDateLength = 8;
+			dateFormat = new SimpleDateFormat("yy/MM/dd");
+		}
+		else if(text.trim().indexOf("-")>-1 && text.trim().length() >=19){
+			if(text.trim().length() == 19){
+				exactDateLength = 19;
+				dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+			}else if(text.trim().length() == 23){
+				exactDateLength = 23;
+				dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+			}
+		}
+		else if (text.trim().indexOf("-")>-1 && text.trim().length() ==17){
+			exactDateLength = 17;
+			dateFormat = new SimpleDateFormat("yy-MM-dd HH:mm:ss");
+		}
+		else if(text.trim().indexOf("-")>-1 && text.trim().length() ==8){
+			exactDateLength = 8;
+			dateFormat = new SimpleDateFormat("yy-MM-dd");
+		}//鍏堝紕杩欎箞澶氾紝涓嶅鍐嶆坊鍔�
+		else{
+			exactDateLength = 19;
+			dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+		}
+		if ((text != null) && (exactDateLength >= 0)&& (text.length() != exactDateLength)) {
+			throw new IllegalArgumentException("涓嶈兘鍒濆鍖栨椂闂达紝鍥犱负鍐呭涓嶅埌" + exactDateLength + "闀垮害");
+		}
+		try {
+			return VciDateUtil.str2Date(VciDateUtil.date2Str(dateFormat.parse(text), VciDateUtil.DateTimeFormat), VciDateUtil.DateTimeMillFormat);//鏃犺鐣岄潰鏄粈涔堟牸寮忥紝鎴戜滑閮借浆鍖栦负"yyyy-MM-dd HH:mm:ss.SSS"杩欐牱鍙互缁熶竴鍚庡彴鐨勫唴瀹�
+		} catch (ParseException ex) {
+			throw new IllegalArgumentException("涓嶈兘鏍煎紡鍖栨棩鏈�: "+ ex.getMessage(), ex);
+		} catch (Exception e) {
+			throw new IllegalArgumentException("涓嶈兘鏍煎紡鍖栨棩鏈�: "+ e.getMessage(), e);
+		}
+	}
+
+	/**
+	 * 鑾峰彇鏌愬ぉ鐨勫啘鍘嗗舰寮�
+	 *
+	 * @param d
+	 * @return
+	 * @throws Exception
+	 */
+	public static String getChinaDate(String d) throws Exception {
+		Date s = str2Date(d, DateFormat);
+		SimpleDateFormat chineseDateFormat = new SimpleDateFormat("yyyy骞碝M鏈坉d鏃�");
+		Calendar today = Calendar.getInstance();
+		try {
+			today.setTime(chineseDateFormat.parse(date2Str(s,
+					"yyyy骞碝M鏈坉d鏃�")));
+		} catch (ParseException e) {
+			throw new Exception(e);
+		}
+		Lunar lunar = new Lunar(today);
+		return lunar.getDate();
+	}
+
+	/**
+	 * 鑾峰彇鏃堕棿鐨則ime鍊�
+	 * @param date date
+	 * @Return java.lang.Long
+	 */
+	public static Long getTime(Date date) {
+		if(date == null){
+			return null;
+		}
+		return date.getTime();
+	}
+
+	/**
+	 * 灏唗imestamp杞崲涓篋ate
+	 * @param timestamp timestamp
+	 * @Return java.util.Date
+	 */
+	public static Date long2Date(Long timestamp){
+		if(timestamp == null){
+			return null;
+		}
+		Calendar calendar = Calendar.getInstance();
+		calendar.setTimeInMillis(timestamp);
+		return calendar.getTime();
+	}
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/WebThreadLocalUtil.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/WebThreadLocalUtil.java
new file mode 100644
index 0000000..bf5b699
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/util/WebThreadLocalUtil.java
@@ -0,0 +1,44 @@
+package com.vci.starter.web.util;
+
+
+import com.vci.starter.web.pagemodel.SessionInfo;
+
+/**
+ * 绾跨▼涓瓨鍌ㄧ殑鍙橀噺淇℃伅
+ * @author weidy
+ */
+public class WebThreadLocalUtil {
+
+    /**
+     * 绾跨▼閲岀殑褰撳墠鐢ㄦ埛session淇℃伅
+     */
+    private static ThreadLocal<SessionInfo> currentUserSessionInfoInThread = new ThreadLocal<SessionInfo>();
+
+    /**
+     * 鏌ヨ鍒楄〃鐨勬椂鍊欐槸鍚︽煡璇㈡�绘暟
+     */
+    private static ThreadLocal<String> needQueryTotalInThread = new ThreadLocal<String>();
+
+
+    /**
+     * 鑾峰彇褰撳墠鐢ㄦ埛鐨剆ession瀵硅薄
+     * @return session瀵硅薄
+     */
+    public static ThreadLocal<SessionInfo> getCurrentUserSessionInfoInThread() {
+        return currentUserSessionInfoInThread;
+    }
+
+
+    public static void setCurrentUserSessionInfoInThread(ThreadLocal<SessionInfo> currentUserSessionInfoInThread) {
+        WebThreadLocalUtil.currentUserSessionInfoInThread = currentUserSessionInfoInThread;
+    }
+
+    public static ThreadLocal<String> getNeedQueryTotalInThread() {
+        return needQueryTotalInThread;
+    }
+
+    public static void setNeedQueryTotalInThread(ThreadLocal<String> needQueryTotalInThread) {
+        WebThreadLocalUtil.needQueryTotalInThread = needQueryTotalInThread;
+    }
+
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/wrapper/VciParentQueryOption.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/wrapper/VciParentQueryOption.java
new file mode 100644
index 0000000..1ceea6e
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/wrapper/VciParentQueryOption.java
@@ -0,0 +1,182 @@
+package com.vci.starter.web.wrapper;
+
+/**
+ * 涓婁笅绾у叧绯绘煡璇㈤厤缃」
+ * 1. 涓婄骇鏄綋鍓嶅璞″璞¢噷鐨勬煇涓睘鎬э紝姣斿閮ㄩ棬锛屼笂绾ч儴闂ㄦ槸閮ㄩ棬瀵硅薄涓殑涓�涓睘鎬э紝浣跨敤parentFieldName
+ * 2. 濡傛灉浣跨敤閾炬帴绫诲瀷瀛樺偍涓婁笅绾х殑鍏崇郴锛屾瘮濡傝璁$粨鏋凟BOM锛岃缃甽inkTypeFlag涓簍rue锛岃缃甽inkTypeName涓洪摼鎺ョ被鍨嬬殑鑻辨枃鍚嶇О锛涢粯璁や紶閫抐Oid浣滀负鏌ヨ鏉′欢
+ * 3. 濡傛灉鏄痶o绔殑涓婚敭鏉ユ煡璇rom绔殑淇℃伅锛屽湪绗�2鏉$殑鍩虹涓婏紝璁剧疆queryFromToFlag涓簍rue
+ * 4. 濡傛灉涓洪摼鎺ョ被鍨嬶紝鍙槸鏌ヨ鏌愪釜瀵硅薄鐨勬墍鏈夌殑鐗堟湰鍏宠仈鐨則o绔暟鎹紝鍒欏湪绗�2鏉$殑鍩虹涓婏紝涓嶄紶閫抐Oid锛屾敼涓轰紶閫抐NameOid;
+ * 5. 濡傛灉涓洪摼鎺ョ被鍨嬶紝鍙槸鏌ヨ鏌愪釜瀵硅薄鐨勬煇涓増鏈殑鎵�鏈夌増娆″叧鑱旂殑to绔暟鎹紝鍒欏湪绗�2鏉$殑鍩虹涓婏紝涓嶄紶閫抐Oid锛屾敼涓轰紶閫抐RevisionOid;
+ * 6. 濡傛灉涓洪摼鎺ョ被鍨嬶紝鍒欓摼鎺ョ被鍨嬬殑from绔湁澶氫釜涓氬姟绫诲瀷锛屼笖涓氬姟绫诲瀷鐨刼id鍙兘閲嶅鏃讹紝闇�瑕佷紶閫抐BtmName灞炴��
+ * @author weidy
+ * @date 2020-07-20
+ */
+public class VciParentQueryOption {
+
+    /**
+     * 涓婄骇灞炴�х殑鍚嶇О
+     */
+    private String parentFieldName;
+
+    /**
+     * 閾炬帴绫诲瀷瀛樺偍鍏崇郴
+     */
+    private boolean linkTypeFlag;
+
+    /**
+     * 閾炬帴绫诲瀷鍚嶇О
+     */
+    private String linkTypeName;
+
+    /**
+     * from绔富閿�
+     */
+    private String fOid;
+
+    /**
+     * from绔増鏈富閿�
+     */
+    private String fRevisionOid;
+
+    /**
+     * from绔璞′富閿�
+     */
+    private String fNameOid;
+
+    /**
+     * from绔笟鍔$被鍨�
+     */
+    private String fBtmName;
+
+    /**
+     * 鏄惁涓簍o绔煡璇�
+     */
+    private boolean queryFromToFlag = false;
+
+    /**
+     * 鏄惁鍖呭惈鑷韩
+     */
+    private boolean hasSelf = false;
+
+    /**
+     * 榛樿鏋勯�犲嚱鏁�
+     */
+    public VciParentQueryOption(){
+
+    }
+
+    /**
+     * 鑷弬鐓у舰寮忚缃笂绾у瓧娈�
+     * @param parentFieldName 涓婄骇瀛楁鐨勫睘鎬у悕绉�
+     */
+    public VciParentQueryOption(String parentFieldName){
+        this.parentFieldName = parentFieldName;
+    }
+
+    /**
+     * 閾炬帴绫诲瀷鏌ヨ
+     * @param linkTypeName 閾炬帴绫诲瀷鐨勫悕绉�
+     */
+    public void linkType(String linkTypeName){
+        this.linkTypeName = linkTypeName;
+        this.linkTypeFlag = true;
+    }
+
+    /**
+     * 閾炬帴绫诲瀷鏌ヨ
+     * @param linkTypeName 閾炬帴绫诲瀷鐨勫悕绉�
+     * @param queryFromToFlag 浠嶵o绔煡璇�
+     */
+    public void linkType(String linkTypeName,boolean queryFromToFlag){
+        this.linkTypeName = linkTypeName;
+        this.linkTypeFlag = true;
+        this.queryFromToFlag = queryFromToFlag;
+    }
+
+    public String getParentFieldName() {
+        return parentFieldName;
+    }
+
+    public void setParentFieldName(String parentFieldName) {
+        this.parentFieldName = parentFieldName;
+    }
+
+    public boolean isLinkTypeFlag() {
+        return linkTypeFlag;
+    }
+
+    public void setLinkTypeFlag(boolean linkTypeFlag) {
+        this.linkTypeFlag = linkTypeFlag;
+    }
+
+    public String getLinkTypeName() {
+        return linkTypeName;
+    }
+
+    public void setLinkTypeName(String linkTypeName) {
+        this.linkTypeName = linkTypeName;
+    }
+
+    public String getfOid() {
+        return fOid;
+    }
+
+    public void setfOid(String fOid) {
+        this.fOid = fOid;
+    }
+
+    public String getfRevisionOid() {
+        return fRevisionOid;
+    }
+
+    public void setfRevisionOid(String fRevisionOid) {
+        this.fRevisionOid = fRevisionOid;
+    }
+
+    public String getfNameOid() {
+        return fNameOid;
+    }
+
+    public void setfNameOid(String fNameOid) {
+        this.fNameOid = fNameOid;
+    }
+
+    public String getfBtmName() {
+        return fBtmName;
+    }
+
+    public void setfBtmName(String fBtmName) {
+        this.fBtmName = fBtmName;
+    }
+
+    public boolean isQueryFromToFlag() {
+        return queryFromToFlag;
+    }
+
+    public void setQueryFromToFlag(boolean queryFromToFlag) {
+        this.queryFromToFlag = queryFromToFlag;
+    }
+
+    public boolean isHasSelf() {
+        return hasSelf;
+    }
+
+    public void setHasSelf(boolean hasSelf) {
+        this.hasSelf = hasSelf;
+    }
+
+    @Override
+    public String toString() {
+        return "VciParentQueryOption{" +
+                "parentFieldName='" + parentFieldName + '\'' +
+                ", linkTypeFlag=" + linkTypeFlag +
+                ", linkTypeName='" + linkTypeName + '\'' +
+                ", fOid='" + fOid + '\'' +
+                ", fRevisionOid='" + fRevisionOid + '\'' +
+                ", fNameOid='" + fNameOid + '\'' +
+                ", fBtmName='" + fBtmName + '\'' +
+                ", queryFromToFlag=" + queryFromToFlag +
+                ", hasSelf=" + hasSelf +
+                '}';
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/wrapper/VciQueryWrapperForDO.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/wrapper/VciQueryWrapperForDO.java
new file mode 100644
index 0000000..2d2ce8e
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/wrapper/VciQueryWrapperForDO.java
@@ -0,0 +1,1613 @@
+package com.vci.starter.web.wrapper;
+
+import com.vci.starter.web.annotation.*;
+import com.vci.starter.web.constant.FrameWorkLcStatusConstant;
+import com.vci.starter.web.constant.QueryOptionConstant;
+import com.vci.starter.web.enumpck.DataBaseEnum;
+import com.vci.starter.web.enumpck.VciFieldTypeEnum;
+import com.vci.starter.web.exception.VciBaseException;
+import com.vci.starter.web.pagemodel.PageHelper;
+import com.vci.starter.web.pagemodel.TreeQueryObject;
+import com.vci.starter.web.service.VciSecretServiceI;
+import com.vci.starter.web.toolmodel.DateConverter;
+import com.vci.starter.web.util.VciBaseUtil;
+import com.vci.starter.web.util.VciDateUtil;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.util.CollectionUtils;
+
+import java.lang.reflect.Field;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * 鏌ヨ灏佽
+ * 鍦╩ybatis鐨剎ml鍐呭涓渶瑕佸啓鍏�
+ * ${qw.getSelectFieldSql} from XXX ${wq.getTableNick} ${qw.getLinkTableSql} <where>${qw.whereSql}</where> ${qw.getPageSql}
+ * 鐗瑰埆娉ㄦ剰锛宨n鏉′欢鍚庣殑鍐呭涓嶈兘瓒呰繃1000锛屽洜涓哄彈oracle鐨勯檺鍒�
+ * @author weidy
+ * @date 2019/10/15 16:31
+ */
+public class VciQueryWrapperForDO implements VciSecretServiceI{
+
+    /**
+     * 鏄惁鐢ㄦ埛瑙掕壊閮ㄩ棬绛夎〃鏍肩殑鍏煎鎬�
+     */
+    public static boolean USER_TABLE_COMPATIBILITY = false;
+
+    /**
+     * 鏁版嵁搴撶殑骞冲彴
+     */
+    public static String DATABASE_PLATFORM = DataBaseEnum.ORACLE.getValue();
+
+    /**
+     * 鍦ㄥ吋瀹硅�佹棫鐨勫钩鍙扮殑鏃跺�欙紝鏂板钩鍙扮殑涓氬姟绫诲瀷鍜屽湪鑰佸钩鍙扮殑鏁版嵁搴撹〃鐨勬槧灏勶紝key鏄柊鐨勫钩鍙扮殑涓氬姟瀵硅薄锛寁alue鑰佸钩鍙颁腑鐨勮〃鏍�,key蹇呴』鏄皬鍐�
+     */
+    public static Map<String,String> USER_TABLE_COMPATIBILITY_BTM_MAP = new HashMap<>();
+
+    /**
+     * 鍦ㄥ吋瀹硅�佹棫鐨勫钩鍙扮殑鏃跺�欙紝鏂板钩鍙扮殑涓氬姟绫诲瀷涓殑瀛楁涓庤�佸钩鍙扮殑鏁版嵁搴撹〃涓瓧娈电殑鏄犲皠锛岀浉鍚岀殑鏃跺�欎笉鐢ㄦ坊鍔狅紝key鏄柊鐨勫钩鍙扮殑涓氬姟瀵硅薄+鍒嗛殧绗�+瀛楁鍚嶇О锛寁alue鏄�佸钩鍙颁腑鐨勮〃鏍奸噷鐨勫瓧娈碉紝key鍏ㄦ槸灏忓啓
+     */
+    public static Map<String,String> USER_TABLE_COMPATIBILITY_FIELD_MAP = new HashMap<>();
+
+    /**
+     * 鍏煎鑰佹棫鐨勫钩鍙扮殑鍒嗛殧绗�
+     */
+    public static final String USER_TABLE_COMPATIBILITY_FIELD_SEP = "${vcicomplibitysep}";
+
+
+    /**
+     * 鏌ヨ鏉′欢
+     */
+    private Map<String,String> conditionMap ;
+
+    /**
+     * 鑷啓鐨凷QL,鍙互鏄爣璇嗙锛岀敤浜庣Щ闄ょ殑鏃跺�欙紝鍊兼槸鍏蜂綋鐨剆ql锛屼篃鍙互鐢∣R寮�澶磋〃绀烘垨鐨勬儏鍐�
+     */
+    private Map<String,String> customerSqlMap;
+
+    /**
+     * 涓婚敭鐨勫睘鎬�
+     */
+    private String oidFieldName = "oid";
+
+    /**
+     * 绌烘牸
+     */
+    private static final String SPACE = " ";
+
+    /**
+     * 鏌ヨ瀵嗙骇
+     */
+    public static final String QUERY_FIELD_SECRET = "${vciQuerySecret}";
+
+    /**
+     * 榛樿鏌ヨ瀵嗙骇
+     */
+    public static final Boolean DEFAULT_QUERY_SECRET = true;
+
+    /**
+     * 榛樿涓嶆煡璇㈡暟鎹潈闄�
+     */
+    public static final Boolean DEFAULT_QUERY_DATARIGHT = false;
+
+    /**
+     * 鏌ヨ鏁版嵁鏉冮檺
+     */
+    public static final String QUERY_FIELD_DATARIGHT = "${vciQueryDataRight}";
+
+    /**
+     * 鏌ヨ閰嶇疆
+     */
+    private VciQueryWrapperOption queryWrapperOption ;
+
+    /**
+     * 鏁版嵁瀵硅薄
+     */
+    private Class<?> doClass;
+
+    /**
+     * 鍒嗛〉瀵硅薄锛屽寘鍚垎椤靛拰鎺掑簭
+     */
+    private PageHelper pageHelper;
+
+    /**
+     * 鎵�鏈夌殑瀛楁鍚嶇О,key鏄璞″睘鎬т腑鐨勫瓧娈碉紝value鏄暟鎹簱閲岀殑瀛楁
+     */
+    private Map<String,String> allFieldNameMap;
+
+    /**
+     * xml鐨刦ield
+     */
+    private List<String> xmlTypeFieldList = new ArrayList<>();
+
+    /**
+     * 鏄惁鍞竴
+     */
+    private boolean  distinct = false;
+
+    /**
+     * 鐗堟湰绠$悊鐩稿叧鐨勫瓧娈靛拰鏄剧ず鍚嶇О鏄犲皠
+     */
+    public static final Map<String,String> REVISION_MANAGE_FIELD_MAP = new HashMap(){{
+        put("nameoid","瀵硅薄涓婚敭");
+        put("revisionoid","鐗堟湰涓婚敭");
+        put("lastr","鏄惁鏈�鏂扮増鏈�");
+        put("firstr","鏄惁鏈�鑰佺増鏈�");
+        put("lastv","鏄惁鏈�鏂扮増娆�");
+        put("firstv","鏄惁鏈�鑰佺増娆�");
+        put("revisionrule","鐗堟湰瑙勫垯");
+        put("revisionseq","鐗堟湰鎺掑簭鍙�");
+        put("revisionvalue","鐗堟湰鍊�");
+        put("versionrule","鐗堟瑙勫垯");
+        put("versionseq","鐗堟鎺掑簭鍙�");
+        put("versionvalue","鐗堟鍊�");
+        put("checkinby","绛惧叆浜�");
+        put("checkintime","绛惧叆鏃堕棿");
+        put("checkoutby","绛惧嚭浜�");
+        put("checkouttime","绛惧嚭鏃堕棿");
+        put("copyfromversion","鎷疯礉鐗堟湰鏉ユ簮");
+    }} ;
+
+    /**
+     * 鍩虹鐨勫睘鎬у瓧娈垫暟缁�
+     */
+    public static final Map<String,String> BASIC_FIELD_MAP = new HashMap(){{
+        put("oid","涓婚敭");
+        put("btmname","涓氬姟绫诲瀷鐨勫悕绉�");
+        put("id","缂栧彿");
+        put("name","鍚嶇О");
+        put("description","鎻忚堪");
+        put("creator","鍒涘缓浜�");
+        put("createtime","鍒涘缓鏃堕棿");
+        put("lastmodifier","鏈�鍚庢椂闂翠汉");
+        put("lastmodifytime","鏈�鍚庝慨鏀规椂闂�");
+        put("ts","鏃堕棿鎴�");
+        put("owner","鎷ユ湁鑰�");
+    }};
+
+    /**
+     * 鍏煎鐨勬椂鍊欙紝鍩虹妯″瀷鐨勫睘鎬ф槧灏�
+     */
+    public static final Map<String,String> BASE_MODEL_COMPATIBILITY_MAP = new HashMap(){{
+        put("lastr","islastr");
+        put("firstr","isfirstr");
+        put("lastv","islastv");
+        put("firstv","isfirstv");
+    }};
+
+    /**
+     * 涓婚敭灞炴��
+     */
+    public static final String OID_FIELD = "oid";
+
+    /**
+     * 缂栧彿鐨勫睘鎬�
+     */
+    public static final String ID_FIELD = "id";
+
+    /**
+     * 鐢熷懡鍛ㄦ湡鐨勫睘鎬�
+     */
+    public static final String LC_STATUS_FIELD = "lcstatus";
+
+    /**
+     * 鐢熷懡鍛ㄦ湡鐨勬樉绀烘枃鏈�
+     */
+    public static final String LC_STATUS_FIELD_TEXT = "lcStatus_text";
+
+    /**
+     * 鐢熷懡鍛ㄦ湡绠$悊鐩稿叧鐨勫瓧娈�
+     */
+    public static final Map<String,String>  LIFECYCLE_MANAGE_FIELD_MAP = new HashMap(){{
+        put(LC_STATUS_FIELD,"鐢熷懡鍛ㄦ湡鍊�");
+    }};
+
+    /**
+     * 瀵嗙骇绠$悊鐩稿叧鐨勫瓧娈�
+     */
+    public static final Map<String,String> SECRET_MANAGE_FIELD_MAP = new HashMap(){{
+        put("secretgrade","瀵嗙骇鍊�");
+    }};
+
+    /**
+     * 閾炬帴绫诲瀷鐨勫瓧娈祄ap
+     */
+    public static final Map<String,String> LINK_TYPE_FIELD_MAP = new HashMap(){{
+        put("oid","涓婚敭");
+        put("creator","鍒涘缓浜�");
+        put("createtime","鍒涘缓鏃堕棿");
+        put("lastmodifier","鏈�鍚庢椂闂翠汉");
+        put("lastmodifytime","鏈�鍚庝慨鏀规椂闂�");
+        put("f_oid","from绔富閿�");
+        put("f_revisionoid","from绔増鏈富閿�");
+        put("f_nameoid","from绔璞′富閿�");
+        put("f_btmname","from绔笟鍔$被鍨�");
+        put("t_oid","to绔富閿�");
+        put("t_revisionoid","to绔増鏈富閿�");
+        put("t_nameoid","to绔璞′富閿�");
+        put("t_btmname","to绔笟鍔$被鍨�");
+        put("ts","鏃堕棿鎴�");
+    }};
+
+    /**
+     * 鑾峰彇瀛楁鐨勭被鍨�
+     */
+    private Map<String,VciFieldTypeEnum> allFieldTypeMap;
+
+    /**
+     * 鍙傜収鐨勪俊鎭槧灏勶紝key鏄疍O瀵硅薄涓殑灞炴�у悕绉帮紝value鏄弬鐓х殑瀵硅薄淇℃伅
+     */
+    private List<VciReferFieldInfo> referFieldInfoList ;
+
+    /**
+     * 浣跨敤鍙傜収瀛楁鐨勬槧灏�
+     */
+    private Map<String,String> useReferMap;
+
+    /**
+     * 鏋氫妇瀛楁鐨勬槧灏勶紝key鏄暟鎹璞¢噷鐨勫睘鎬э紝value鏄灇涓捐〃杈惧紡
+     */
+    private Map<String,String> enumFieldMap;
+
+    /**
+     * 鍏宠仈琛ㄧ殑璇彞
+     */
+    private String linkTableSql;
+
+
+    /**
+     * 鏌ヨ瀛楁璇彞
+     */
+    private String selectFieldSql;
+
+    /**
+     * 鍒嗛〉鏃跺鍔犵殑鍓嶇紑
+     */
+    private String selectPrefixForPage = "";
+
+    /**
+     * 鏌ヨ璇彞锛屽寘鍚垎椤靛拰鎺掑簭
+     */
+    private String whereSql;
+
+    /**
+     * 鎺掑簭鐨勮鍙�
+     */
+    private String orderSql;
+
+    /**
+     * 鍒嗛〉鏃跺鍔犵殑鍚庣紑
+     */
+    private String whereSubfixForPage ="";
+
+    /**
+     * 鍊肩殑鏄犲皠瀵硅薄
+     */
+    private Map<String,String> valuesMap;
+
+    /**
+     * 琛ㄦ牸鐨勬樀绉�
+     */
+    private String tableNick;
+
+    /**
+     * 鎵╁睍鐨勬煡璇㈠垪
+     */
+    private Map<String,String> extendFieldMap = new HashMap<>();
+
+    /**
+     * 娣诲姞鏋勯�犲櫒鐨勫唴瀹�
+     * @param doClass 鏁版嵁瀵硅薄鐨勭被
+     */
+    public VciQueryWrapperForDO( Class<?> doClass) throws VciBaseException {
+        this(null,doClass,new PageHelper(-1),true);
+    }
+    /**
+     * 娣诲姞鏋勯�犲櫒鐨勫唴瀹�
+     * @param conditionMap 鏌ヨ鏉′欢
+     * @param doClass 鏁版嵁瀵硅薄鐨勭被
+     */
+    public VciQueryWrapperForDO(Map<String,String> conditionMap, Class<?> doClass) throws VciBaseException {
+        this(conditionMap,doClass,new PageHelper(-1),true);
+    }
+
+
+    /**
+     * 娣诲姞鏋勯�犲櫒鐨勫唴瀹�
+     * @param conditionMap 鏌ヨ鏉′欢
+     * @param doClass 鏁版嵁瀵硅薄鐨勭被
+     * @param pageHelper 鍒嗛〉瀵硅薄
+     */
+    public VciQueryWrapperForDO(Map<String,String> conditionMap, Class<?> doClass, PageHelper pageHelper) throws VciBaseException {
+        this(conditionMap,doClass,pageHelper,true);
+    }
+    /**
+     * 娣诲姞鏋勯�犲櫒鐨勫唴瀹�
+     * @param conditionMap 鏌ヨ鏉′欢
+     * @param doClass 鏁版嵁瀵硅薄鐨勭被
+     * @param pageHelper 鍒嗛〉瀵硅薄
+     * @param autoWrapper 鏄惁鑷姩灏佽
+     */
+    public VciQueryWrapperForDO(Map<String,String> conditionMap, Class<?> doClass, PageHelper pageHelper, boolean autoWrapper) throws VciBaseException {
+        this(conditionMap,doClass,pageHelper,autoWrapper,new VciQueryWrapperOption());
+    }
+
+    /**
+     * 娣诲姞鏋勯�犲櫒鐨勫唴瀹�
+     * @param conditionMap 鏌ヨ鏉′欢
+     * @param doClass 鏁版嵁瀵硅薄鐨勭被
+     * @param pageHelper 鍒嗛〉瀵硅薄
+     * @param autoWrapper 鏄惁鑷姩灏佽,鍗虫瀯閫犳柟娉曞氨浼氭嫾鎺QL锛�
+     * @param queryWrapperOption  鏌ヨ鐨勭被鍨�
+     */
+    public VciQueryWrapperForDO(Map<String,String> conditionMap, Class<?> doClass, PageHelper pageHelper, boolean autoWrapper, VciQueryWrapperOption queryWrapperOption) throws VciBaseException {
+        this.conditionMap = conditionMap;
+        this.doClass = doClass;
+        this.pageHelper = pageHelper;
+        this.queryWrapperOption = queryWrapperOption;
+        if(autoWrapper) {
+            wrapperSql();
+        }
+
+    }
+
+    /**
+     * 浣跨敤鏌ヨ鏉′欢
+     * @param obj 鏌ヨ瀵硅薄
+     */
+    public void initConditionByQueryObject(Object obj){
+        if(this.conditionMap == null){
+            this.conditionMap = new HashMap<>();
+        }
+        Map<String, String> queryValueObject = VciBaseUtil.objectToMapString(obj);
+        if(!CollectionUtils.isEmpty(queryValueObject)){
+           this.conditionMap.putAll(queryValueObject);
+        }
+        initWhereSql();
+    }
+
+    /**
+     * 娓呴櫎鍒嗛〉
+     */
+    public void clearPage(){
+        this.pageHelper = null;
+        this.selectPrefixForPage = "";
+        this.whereSubfixForPage = "";
+    }
+
+    /**
+     * 璁剧疆鏂扮殑鍒嗛〉淇℃伅
+     * @param limit 鍒嗛〉
+     * @param page 褰撳墠绗嚑椤�
+     */
+    public void setPageLimit(int limit,int page){
+        if(this.pageHelper == null){
+            this.pageHelper = new PageHelper(limit);
+            this.pageHelper.setPage(page);
+        }else{
+            this.pageHelper.setLimit(limit);
+            this.pageHelper.setPage(page);
+        }
+        initPageSql();
+    }
+
+    /**
+     * 璁剧疆鍒嗛〉瀵硅薄
+     * @param pageHelper 鏂扮殑鍒嗛〉瀵硅薄
+     */
+    public void setPageHelper(PageHelper pageHelper){
+        this.pageHelper = pageHelper;
+        initPageSql();
+    }
+
+    /**
+     * 杩藉姞in鎿嶄綔
+     * @param key 瀛楁
+     * @param value 鍊�
+     * @return 褰撳墠瀵硅薄
+     * @throws VciBaseException 娣诲姞涓嶇鍚堣姹傜殑鏃跺�欎細鎶涘嚭寮傚父
+     */
+    public VciQueryWrapperForDO in(String key, String value) throws VciBaseException {
+        addQueryMap(key,value, QueryOptionConstant.IN);
+        return this;
+    }
+
+    /**
+     * 杩藉姞not in鎿嶄綔
+     * @param key 瀛楁
+     * @param value 鍊�
+     * @return 褰撳墠瀵硅薄
+     * @throws VciBaseException 娣诲姞涓嶇鍚堣姹傜殑鏃跺�欎細鎶涘嚭寮傚父
+     */
+    public VciQueryWrapperForDO notIn(String key,String value) throws VciBaseException {
+        addQueryMap(key,value, QueryOptionConstant.NOTIN);
+        return this;
+    }
+
+    /**
+     * 杩藉姞绛変簬鎿嶄綔
+     * @param key 瀛楁
+     * @param value 鍊�
+     * @return 褰撳墠瀵硅薄
+     * @throws VciBaseException 娣诲姞涓嶇鍚堣姹傜殑鏃跺�欎細鎶涘嚭寮傚父
+     */
+    public VciQueryWrapperForDO eq(String key,String value) throws VciBaseException {
+        addQueryMap(key,value);
+        return this;
+    }
+    /**
+     * 杩藉姞涓嶇瓑浜庢搷浣�
+     * @param key 瀛楁
+     * @param value 鍊�
+     * @return 褰撳墠瀵硅薄
+     * @throws VciBaseException 娣诲姞涓嶇鍚堣姹傜殑鏃跺�欎細鎶涘嚭寮傚父
+     */
+    public VciQueryWrapperForDO neq(String key,String value) throws VciBaseException {
+        addQueryMap(key,value, QueryOptionConstant.NOTEQUAL);
+        return this;
+    }
+    /**
+     * 杩藉姞灏忎簬鎿嶄綔
+     * @param key 瀛楁
+     * @param value 鍊�
+     * @return 褰撳墠瀵硅薄
+     * @throws VciBaseException 娣诲姞涓嶇鍚堣姹傜殑鏃跺�欎細鎶涘嚭寮傚父
+     */
+    public VciQueryWrapperForDO less(String key,String value) throws VciBaseException {
+        addQueryMap(key,value, QueryOptionConstant.LESS);
+        return this;
+    }
+
+    /**
+     * 杩藉姞灏忎簬绛変簬鎿嶄綔
+     * @param key 瀛楁
+     * @param value 鍊�
+     * @return 褰撳墠瀵硅薄
+     * @throws VciBaseException 娣诲姞涓嶇鍚堣姹傜殑鏃跺�欎細鎶涘嚭寮傚父
+     */
+    public VciQueryWrapperForDO lessThan(String key,String value) throws VciBaseException {
+        addQueryMap(key,value, QueryOptionConstant.LESSTHAN);
+        return this;
+    }
+
+    /**
+     * 杩藉姞澶т簬鎿嶄綔
+     * @param key 瀛楁
+     * @param value 鍊�
+     * @return 褰撳墠瀵硅薄
+     * @throws VciBaseException 娣诲姞涓嶇鍚堣姹傜殑鏃跺�欎細鎶涘嚭寮傚父
+     */
+    public VciQueryWrapperForDO more(String key,String value) throws VciBaseException {
+        addQueryMap(key,value, QueryOptionConstant.MORE);
+        return this;
+    }
+
+    /**
+     * 杩藉姞澶т簬绛変簬鎿嶄綔
+     * @param key 瀛楁
+     * @param value 鍊�
+     * @return 褰撳墠瀵硅薄
+     * @throws VciBaseException 娣诲姞涓嶇鍚堣姹傜殑鏃跺�欎細鎶涘嚭寮傚父
+     */
+    public VciQueryWrapperForDO moreThan(String key,String value) throws VciBaseException {
+        addQueryMap(key,value, QueryOptionConstant.MORETHAN);
+        return this;
+    }
+
+    /**
+     * 杩藉姞涓虹┖鎿嶄綔
+     * @param key 瀛楁
+     * @return 褰撳墠瀵硅薄
+     * @throws VciBaseException 娣诲姞涓嶇鍚堣姹傜殑鏃跺�欎細鎶涘嚭寮傚父
+     */
+    public VciQueryWrapperForDO isNull(String key) throws VciBaseException {
+        addQueryMap(key,"_n", QueryOptionConstant.ISNULL);
+        return this;
+    }
+
+    /**
+     * 杩藉姞涓嶄负绌烘搷浣�
+     * @param key 瀛楁
+     * @return 褰撳墠瀵硅薄
+     * @throws VciBaseException 娣诲姞涓嶇鍚堣姹傜殑鏃跺�欎細鎶涘嚭寮傚父
+     */
+    public VciQueryWrapperForDO isNotNull(String key) throws VciBaseException {
+        addQueryMap(key,"_n", QueryOptionConstant.ISNOTNULL);
+        return this;
+    }
+
+    /**
+     * 杩藉姞瀵嗙骇
+     * @return 褰撳墠瀵硅薄
+     * @throws VciBaseException 娣诲姞涓嶇鍚堣姹傜殑鏃跺�欎細鎶涘嚭寮傚父
+     */
+    public VciQueryWrapperForDO secret() throws VciBaseException{
+        String secretSql = getLessThanUserSecretSql();
+        addQueryMap("secretGrade",secretSql,QueryOptionConstant.LESSTHAN );
+        return this;
+    }
+
+    /**
+     * 娣诲姞鏌ヨ鏉′欢
+     * @param key 瀛楁
+     * @param value 鍊�
+     */
+    public void addQueryMap(String key, String value) {
+        addQueryMap(key,value,null);
+    }
+
+    /**
+     * 娣诲姞鏌ヨ鏉′欢
+     * @param key 瀛楁
+     * @param value 鍊�
+     * @param operation 鎿嶄綔绫诲瀷
+     */
+    public void addQueryMap(String key, String value, String operation) {
+        VciBaseUtil.alertNotNull(key,"鏌ヨ鏉′欢鐨勫悕绉�");
+        if(StringUtils.isNotBlank(value)) {
+            if (this.conditionMap == null) {
+                this.conditionMap = new HashMap<>();
+            }
+            if (operation == null) {
+                operation = "";
+            }
+            this.conditionMap.put(key, operation + value);
+        }
+    }
+
+    /**
+     * 鍔犲叆鑷畾涔夌殑sql
+     * @param key key
+     * @param sql sql鐨勪俊鎭�
+     */
+    public void addCustomSql(String key,String sql){
+        VciBaseUtil.alertNotNull(key,"鑷畾涔塖QL鐨凨EY",sql,"鑷畾涔夌殑SQL璇彞");
+        if(StringUtils.isNotBlank(sql)){
+            if (this.customerSqlMap == null) {
+                this.customerSqlMap = new HashMap<>();
+            }
+            this.customerSqlMap.put(key,sql);
+        }
+    }
+
+    /**
+     * 娣诲姞鎵╁睍鐨勬煡璇㈠瓧娈�
+     * @param fieldName 瀛楁鐨勫悕绉�
+     */
+    public void addExtendField(String fieldName){
+        addExtendField(fieldName,fieldName);
+    }
+
+    /**
+     * 娣诲姞鎵╁睍鐨勬煡璇㈠瓧娈�
+     * @param fieldName 瀛楁鍚嶇О
+     * @param nickName 鏄电О
+     */
+    public void addExtendField(String fieldName,String nickName){
+        extendFieldMap.put(fieldName,nickName);
+    }
+
+
+    public Map<String, String> getConditionMap() {
+        return conditionMap;
+    }
+
+    public void setConditionMap(Map<String, String> conditionMap) {
+        this.conditionMap = conditionMap;
+    }
+
+    /**
+     * 绉婚櫎鏌ヨ鏉′欢,鍖呮嫭鑷畾涔夌殑SQL
+     * @param key 鏌ヨ鏉′欢
+     */
+    public void removeQueryMap(String key){
+        VciBaseUtil.alertNotNull(key,"鏌ヨ鏉′欢鐨勫悕绉�");
+        if (this.conditionMap == null) {
+            this.conditionMap = new HashMap<>();
+        }
+        if(this.conditionMap.containsKey(key)){
+            this.conditionMap.remove(key);
+        }
+        if(this.customerSqlMap == null){
+            this.customerSqlMap = new HashMap<>();
+        }
+        if(this.customerSqlMap.containsKey(key)){
+            this.customerSqlMap.remove(key);
+        }
+        initWhereSql();
+    }
+
+    /**
+     * 灏佽SQL璇彞
+     */
+    public void wrapperSql() throws VciBaseException {
+        VciBaseUtil.alertNotNull(this.doClass,"鏁版嵁瀵硅薄绫�");
+        //棣栧厛鏄鍏堟壘灞炴�у瓧娈�
+        initFieldNameMap();
+        //缁勫缓鏌ヨ瀛楁
+        initSelectSql();
+        //缁勫缓鏉′欢璇彞
+        initWhereSql();
+        //缁勫缓鍜屾帓搴忕殑SQL
+        initPageSql();
+    }
+
+    /**
+     * 鍒濆鍖栨帓搴忕殑SQL
+     */
+    private void initPageSql() {
+        if(this.pageHelper != null) {
+            this.pageHelper.setNick(this.getTableNick());
+            //鍥犱负鍙傜収鍏宠仈鐨勬椂鍊欙紝鏄妸瀛楁鏈�灏忓寲褰撴垚琛ㄦ牸鐨勬樀绉扮殑锛屾墍浠ョ洿鎺ュ垽鏂嵆鍙�
+            if (StringUtils.isNotBlank(this.pageHelper.getSort())) {
+                //鎺掑簭杩欎釜閮芥湁娌℃湁鍒嗛〉閮芥病鍏崇郴
+                this.pageHelper.getUnNickField().addAll(this.extendFieldMap.values().stream().map(s->s.toLowerCase(Locale.ROOT)).collect(Collectors.toList()));
+                this.orderSql = this.pageHelper.getOrdersql();
+            }
+            if (this.pageHelper.getLimit() > 0) {
+                DataBaseEnum db = DataBaseEnum.forValue(DATABASE_PLATFORM);
+                switch (db){
+                    case SQLITE:
+                        this.whereSubfixForPage = " limit " + this.pageHelper.getLimit() + " offset " + this.pageHelper.getLimit()*(this.pageHelper.getPage()-1);
+                        break;
+                    case MYSQL:
+                        //娌℃湁鐢ㄥ垎椤垫彃浠讹紝椤圭洰鐨勬暟閲忎笉浼氬お澶氾紝鎵�浠ョ洿鎺ql閲岀粍瑁�
+                        this.whereSubfixForPage = " limit " + this.pageHelper.getLimit()*(this.pageHelper.getPage()-1) + "," + this.pageHelper.getLimit() ;
+                        break;
+                    case SQL_SERVER:
+                        this.selectPrefixForPage =  "select top (" + this.pageHelper.getLimit() + ") * from (select A.*,ROW_NUMBER() OVER(" + (StringUtils.isNotBlank(this.orderSql)?this.orderSql:" order by oid") + " AS RowId from (";
+                        this.whereSubfixForPage = " ) as A ) as B where B.RowId > "
+                                + (this.pageHelper.getLimit()*(this.pageHelper.getPage()-1) + 1);
+                        break;
+                    default:
+                        List<String> compatibilityPageSqlList = new ArrayList<>();
+                        String[] temp = this.selectFieldSql.split(",");
+                        if(temp!=null && temp.length>0){
+                            for (int i = 0; i < temp.length; i++) {
+                                String record = temp[i];
+                                if(record.contains(" as ")){
+                                    compatibilityPageSqlList.add(record.split(" as ")[1]);
+                                }
+                            }
+                        }
+                        this.selectPrefixForPage =  (USER_TABLE_COMPATIBILITY?("select " + compatibilityPageSqlList.stream().collect(Collectors.joining(","))):" select *") +" from (select A.*,rownum RN from (";
+                        //page = 2, limit = 25,                鎵�浠ユ槸澶т簬绛変簬(2-1)*25 + 1    == 26.锛屽皬浜� 2*25+1  ==51,灏辨槸1,鍒�25 锛�26鍒�50,
+                        this.whereSubfixForPage = " ) A where rownum < " + (this.pageHelper.getLimit()*this.pageHelper.getPage() + 1) + ") where RN >= "
+                                + (this.pageHelper.getLimit()*(this.pageHelper.getPage()-1) + 1);
+                        break;
+                }
+            }
+        }
+    }
+
+    /**
+     * 鍒濆鍖栨潯浠惰鍙�
+     */
+    public void initWhereSql() {
+        List<String> andSql = new ArrayList<>();
+        List<String> orSql = new ArrayList<>();
+        if(!CollectionUtils.isEmpty(this.conditionMap)){
+            Map<String,String> orConditionMap = new HashMap<>();
+            Map<String,String> andCondtionMap = new HashMap<>();
+            //鍏堝垎绂籵r鐨勬煡璇㈡潯浠讹紝鍙﹀褰撴煡璇㈡潯浠舵槸绌虹殑鏃跺�欎篃涓嶆煡璇�
+            this.conditionMap.forEach((k,v) -> {
+                if(QUERY_FIELD_SECRET.equalsIgnoreCase(k)){
+                    if(!Boolean.valueOf(v)){
+                        this.queryWrapperOption.setThisObjectQuerySecret(false);
+                    }
+                }else if(QUERY_FIELD_DATARIGHT.equalsIgnoreCase(k)){
+                    //
+                }else {
+                    if (StringUtils.isNotBlank(v) && (k.contains(".") || k.endsWith("_begin") || k.endsWith("_end") || this.allFieldNameMap.containsKey(k.toLowerCase().trim()))) {
+                        if (v.startsWith(QueryOptionConstant.OR)) {
+                            orConditionMap.put(k, v);
+                        } else {
+                            andCondtionMap.put(k, v);
+                        }
+                    }
+                }
+            } );
+
+            andCondtionMap.forEach((k,v) -> {
+                andSql.add(getConditionSql(k.toLowerCase(),v));
+            });
+            orConditionMap.forEach((k,v) -> {
+                orSql.add(getConditionSql(k.toLowerCase(),v.substring(QueryOptionConstant.OR.length())));
+            });
+        }
+        List<String> appendWhereSqlList = new ArrayList<>();
+        if(!CollectionUtils.isEmpty(customerSqlMap)){
+            //璇存槑鏈夎嚜瀹氫箟鐨凷QL锛岃繖绉嶇洿鎺ユ坊鍔犲嵆鍙�
+            customerSqlMap.forEach((k,v)->{
+                if(v.startsWith(QueryOptionConstant.OR)){
+                    orSql.add(v.substring(QueryOptionConstant.OR.length()));
+                }else if(v.startsWith(QueryOptionConstant.NO_OR_AND)){
+                    appendWhereSqlList.add(v.substring(QueryOptionConstant.NO_OR_AND.length()));
+                }else{
+                    andSql.add(v);
+                }
+            });
+        }
+        //缁勫悎璧锋潵
+        StringBuilder andSb = new StringBuilder();
+        andSql.stream().forEach( s -> {
+            andSb.append(s).append(SPACE).append(QueryOptionConstant.AND).append(SPACE);
+        });
+
+        String andString = andSb.toString().trim();
+        String endWithSql = QueryOptionConstant.AND;
+        if(andString.endsWith(endWithSql) ){
+            andString = andString.substring(0,andString.length() - endWithSql.length());
+        }
+
+        String orString = orSql.stream().collect(Collectors.joining(" or "));
+        if(StringUtils.isNotBlank(orString)){
+            this.whereSql = SPACE + (StringUtils.isBlank(andString)?(orString):("(" + SPACE + andString + SPACE + ") and (" + SPACE + orString + SPACE + ")")) + SPACE;
+        }else{
+            this.whereSql = andString + SPACE;
+        }
+        if(this.queryWrapperOption.getThisObjectQuerySecret()){
+            //璇存槑瑕佹坊鍔犲瘑绾�
+            this.whereSql += " and ( " + this.getTableNick() + ".secretGrade <= " + VciBaseUtil.getCurrentUserSecret() + ") ";
+        }
+        if(this.queryWrapperOption.getThisObjectQueryRevision() && this.queryWrapperOption.getThisObjectQueryLastRevision()){
+            //璇存槑鏌ヨ鏈�鍚庣殑鐗堟湰
+            if(USER_TABLE_COMPATIBILITY){
+                this.whereSql += " and ( " + this.getTableNick() + "." + BASE_MODEL_COMPATIBILITY_MAP.getOrDefault("lastr","lastr") + " = '1' and " + this.getTableNick() + "." + BASE_MODEL_COMPATIBILITY_MAP.getOrDefault("lastv","lastv") + "= '1' ) ";
+            }else {
+                this.whereSql += " and ( " + this.getTableNick() + ".LastR = '1' and " + this.getTableNick() + ".LastV = '1' ) ";
+            }
+        }
+        if(this.queryWrapperOption.getThisObjectQueryRevision() && this.queryWrapperOption.getThisObjectQueryRelease()){
+            //璇存槑鏌ヨ鏌ヨ鏈�鍚庣殑鐗堟湰
+            this.whereSql += " and releaseobj.oid is not null ";
+        }
+        if(!CollectionUtils.isEmpty(appendWhereSqlList)){
+            if(StringUtils.isBlank(this.whereSql)){
+                this.whereSql = " 1 = 1 ";
+            }
+            appendWhereSqlList.stream().forEach(sql->{
+                this.whereSql += (sql + SPACE);
+            });
+        }
+    }
+
+    /**
+     * 鑾峰彇鏌ヨ閮ㄥ垎鐨剆ql,
+     * @param key 鏌ヨ鏉′欢
+     * @param value 鏌ヨ鐨勫��
+     * @return 涓嶅寘鍚玜nd鎴栬�卭r
+     */
+    private String getConditionSql(String key,String value){
+        boolean isReferField = false;
+        //鍥犱负鏁版嵁搴撶殑瀛楁鍜屽睘鎬х殑瀛楁涓嶇浉鍚�
+        boolean hasNick = false;
+        if(StringUtils.isNotBlank(getTableNick()) && key.startsWith(getTableNick() + ".")){
+            hasNick = true;
+        }else{
+            if(key.contains(".")){
+                isReferField = true;
+            }
+        }
+        String selectKey = key;
+        if(hasNick){
+           //鐩存帴浣跨敤浼犲叆杩涙潵鐨�
+        }else if(isReferField){
+            //鍙傜収鐨勬椂鍊欙紝浼犻�掔殑xxxx.yy鐨勫舰寮忥紝鍏朵腑xxx鏄綋鍓嶅璞¢噷鐨勫睘鎬э紝鑰寉y鏄弬鐓х殑涓氬姟绫诲瀷涓殑鏁版嵁搴撳睘鎬�
+            String[] referKeyInfos = key.split("\\.");
+            String referKeyLower = referKeyInfos[0].toLowerCase().trim();
+            if(this.allFieldNameMap.containsKey(referKeyLower)){
+                String thisObjectKey = this.allFieldNameMap.get(referKeyLower);
+                selectKey = thisObjectKey.toLowerCase() + "." + referKeyInfos[1];
+            }else{
+                //澧炲姞鑷畾涔夌殑鏉′欢
+                selectKey = key;
+            }
+        }else if(selectKey.endsWith("_begin") && this.allFieldNameMap.containsKey(selectKey.substring(0,selectKey.length()-6).toLowerCase().trim())){
+            String field = (selectKey.substring(0,selectKey.length()-6).toLowerCase().trim());
+            return getTableNick()+"." + field + SPACE + ">=" + SPACE + getStringValueInWhere(value,field) + SPACE;
+        }else if(selectKey.endsWith("_end") && this.allFieldNameMap.containsKey(selectKey.substring(0,selectKey.length()-4).toLowerCase().trim())){
+            String field = (selectKey.substring(0,selectKey.length()-4).toLowerCase().trim());
+            return getTableNick()+"." + field + SPACE + "<=" + SPACE + getStringValueInWhere(value,field) + SPACE;
+        }else{
+            if(!this.allFieldNameMap.containsKey(key.toLowerCase().trim())){
+                if(this.allFieldNameMap.containsValue(key.toLowerCase().trim())){
+                    //浼犻�掔殑灞炴�т笂鐨勫唴瀹�
+                    selectKey = this.allFieldNameMap.entrySet()
+                            .stream()
+                            .filter(entry -> key.equalsIgnoreCase(entry.getValue()))
+                            .map(Map.Entry::getKey).collect(Collectors.joining());
+                }
+            }
+            if(StringUtils.isNotBlank(getTableNick())){
+                selectKey = getTableNick()+"." + selectKey;
+            }
+        }
+        StringBuilder sql = new StringBuilder();
+        if (value.startsWith(QueryOptionConstant.IN)) {
+            sql.append(selectKey)
+                    .append(SPACE)
+                    .append("in")
+                    .append(SPACE)
+                    .append("(")
+                    .append(value.replace(QueryOptionConstant.IN, ""))
+                    .append(")");
+        } else if (value.startsWith(QueryOptionConstant.NOTIN)) {
+            sql.append(selectKey)
+                    .append(SPACE)
+                    .append("not in")
+                    .append(SPACE)
+                    .append("(")
+                    .append(value.replace(QueryOptionConstant.NOTIN, ""))
+                    .append(")");
+        }  else if (value.startsWith(QueryOptionConstant.ISNOTNULL)) {
+            sql.append(selectKey)
+                    .append(SPACE)
+                    .append(" is not null");
+        } else if (value.startsWith(QueryOptionConstant.NOTEQUAL)) {
+            value = value.replace(QueryOptionConstant.NOTEQUAL, "");
+            if(isReferField){
+                value = "'" + value + "'";
+            }else{
+                value = getStringValueInWhere(value,key);
+            }
+            sql.append(selectKey)
+                    .append(SPACE)
+                    .append(QueryOptionConstant.NOTEQUAL)
+                    .append(SPACE)
+                    .append(value);
+        }else if (value.startsWith(QueryOptionConstant.MORETHAN)) {
+            value = value.replace(QueryOptionConstant.MORETHAN, "");
+            if(isReferField){
+                value = "'" + value + "'";
+            }else{
+                value = getStringValueInWhere(value,key);
+            }
+            sql.append(selectKey)
+                    .append(SPACE)
+                    .append(QueryOptionConstant.MORETHAN)
+                    .append(SPACE)
+                    .append(value);
+        }  else if (value.startsWith(QueryOptionConstant.MORE)) {
+            value = value.replace(QueryOptionConstant.MORE, "");
+            if(isReferField){
+                value = "'" + value + "'";
+            }else{
+                value = getStringValueInWhere(value,key);
+            }
+            sql.append(selectKey)
+                    .append(SPACE)
+                    .append(QueryOptionConstant.MORE)
+                    .append(SPACE)
+                    .append(value);
+        } else if (value.startsWith(QueryOptionConstant.LESSTHAN)) {
+            value = value.replace(QueryOptionConstant.LESSTHAN, "");
+            if(isReferField){
+                value = "'" + value + "'";
+            }else{
+                value = getStringValueInWhere(value,key);
+            }
+            sql.append(selectKey)
+                    .append(SPACE)
+                    .append(QueryOptionConstant.LESSTHAN)
+                    .append(SPACE)
+                    .append(value);
+        }else if (value.startsWith(QueryOptionConstant.LESS)) {
+            value = value.replace(QueryOptionConstant.LESS, "");
+            if(isReferField){
+                value = "'" + value + "'";
+            }else{
+                value =  getStringValueInWhere(value,key);
+            }
+            sql.append(selectKey)
+                    .append(SPACE)
+                    .append(QueryOptionConstant.LESS)
+                    .append(SPACE)
+                    .append(value);
+        } else if (value.startsWith(QueryOptionConstant.ISNULL)) {
+            sql.append(selectKey)
+                    .append(SPACE)
+                    .append(" is null");
+        } else if(value.contains("*")){
+            //璇存槑鏄痩ike锛屾垨鑰卨efe like ,right like
+            sql.append(selectKey)
+                    .append(SPACE)
+                    .append("like")
+                    .append(SPACE)
+                    .append("'")
+                    .append(value.replace("*","%"))
+                    .append("'")
+                    .append(SPACE);
+        } else {
+            if(isReferField){
+                value = "'" + value + "'";
+            }else{
+                value = getStringValueInWhere(value,key);
+            }
+            sql.append(selectKey)
+                    .append(SPACE)
+                    .append(QueryOptionConstant.EQUAL)
+                    .append(SPACE)
+                    .append(value);
+        }
+        sql.append(SPACE);
+        return sql.toString();
+    }
+
+    /**
+     * 鑾峰彇鏌ヨ鏉′欢涓殑鍊肩殑锛屽鐞嗕笉鍚岀殑绫诲瀷
+     * @param value 鍊�
+     * @param field 瀛楁鍚嶇О
+     * @return 鏃ユ湡鎴栬�呮椂闂存牸寮忎細鍖呮嫭to_date锛屽瓧绗︿覆浼氬姞'
+     */
+    private String getStringValueInWhere(String value,String field){
+        VciFieldTypeEnum fieldTypeEnum = this.allFieldTypeMap.get(field.toLowerCase());
+        if("ts".equals(field.toLowerCase())){
+            return "to_timestamp('" + value +"', '" + DATETIME_FORMAT + ".ff')";
+        }
+        DateConverter dateConverter = new DateConverter();
+        if(VciFieldTypeEnum.VTDateTime.equals(fieldTypeEnum)){
+            //瀹為檯涓婏紝鏁版嵁搴撻兘鏄痶imestamp鐨勭被鍨�.
+            dateConverter.setAsText(value);
+            return "to_date('" + dateConverter.getAsText(VciDateUtil.DateTimeFormat) + "','"+ DATETIME_FORMAT +"')";
+        }else if(VciFieldTypeEnum.VTDate.equals(fieldTypeEnum)){
+            dateConverter.setAsText(value);
+            return "to_date('" + dateConverter.getAsText(VciDateUtil.DateFormat) + "','"+ DATE_FORMAT +"')";
+        }else if(VciFieldTypeEnum.VTDouble.equals(fieldTypeEnum)
+                || VciFieldTypeEnum.VTLong.equals(fieldTypeEnum)
+                || VciFieldTypeEnum.VTInteger.equals(fieldTypeEnum)){
+            return value;
+        }else{
+            return "'" + value + "'";
+        }
+    }
+
+    /**
+     * 榛樿鐨勬椂闂存牸寮�
+     */
+    private static final String DATETIME_FORMAT = "yyyy-mm-dd hh24:mi:ss";
+
+    /**
+     * 鏃ユ湡鏍煎紡
+     */
+    private static final String DATE_FORMAT = "yyyy-mm-dd";
+
+    /**
+     * 鍒濆鍖栨煡璇㈠瓧娈电殑璇彞锛岃繖閲屼笉澶勭悊鍒嗛〉鐨勫唴瀹�
+     */
+    private void initSelectSql() throws VciBaseException {
+        if(!CollectionUtils.isEmpty(this.allFieldNameMap)){
+            String tableName = getTableName();
+            if(StringUtils.isBlank(this.getTableNick())){
+                if(tableName.contains("_")){
+                    this.setTableNick(tableName.substring(tableName.indexOf("_")+1));
+                }else {
+                    this.setTableNick(tableName);
+                }
+                this.setTableNick(this.getTableNick() + "0");
+            }
+            StringBuilder sb = new StringBuilder();
+            sb.append("select").append(SPACE);
+            if(isDistinct()){
+                sb.append("DISTINCT").append(SPACE);
+            }
+            this.allFieldNameMap.forEach((k,v) -> {
+                sb.append(this.getTableNick()).append(".").append(k.toUpperCase()).append(xmlTypeFieldList.contains(k.toLowerCase(Locale.ROOT))?".getclobval()":"").append(USER_TABLE_COMPATIBILITY?(" as " + k):" ").append(",").append(SPACE);
+            });
+            if(!CollectionUtils.isEmpty(extendFieldMap)){
+                extendFieldMap.forEach((k,v)->{
+                    sb.append(SPACE).append(k).append(SPACE).append("as").append(SPACE).append(v).append(SPACE).append(",").append(SPACE);
+                });
+            }
+            StringBuilder joinSqlSb = new StringBuilder();
+            Set<String> joinedFieldSet = new HashSet<>();
+            if(!CollectionUtils.isEmpty(this.referFieldInfoList)){
+                //璇存槑鏈夊弬鐓э紝key
+                this.referFieldInfoList.stream().forEach(s ->{
+                    //绗竴娆$殑鏃跺�欙紝referBtmType杩樻槸琛ㄨ揪寮�
+                    String exp = s.getReferBtmTypeExp();
+                    if(StringUtils.isBlank(exp)){
+                        throw new VciBaseException("{0}涓睘鎬1}鐨勬敞瑙d腑referColumn涓虹┖",new Object[]{this.doClass.getName() , s.getShowReferFieldName()});
+                    }
+                    if(!exp.contains(".")){
+                        throw new VciBaseException("{0}涓睘鎬1}鐨勬敞瑙d腑referColumn鐨勬牸寮忎笉姝g‘锛屽繀椤讳负xxx.yy鏂瑰紡锛寈xx鏄綋鍓嶅璞′腑浣跨敤鍙傜収鐨勫睘鎬у悕绉帮紝yy鏄弬鐓х殑涓氬姟绫诲瀷涓殑瀛楁鍚嶇О",new Object[]{this.doClass.getName() , s.getShowReferFieldName()});
+                    }
+                    //姣斿 pkPerson鍜宲kPersonName. 鍙傜収person杩欎釜涓氬姟绫诲瀷鐨刵ame灞炴��,pkPerson瀵瑰簲鐨勬暟鎹簱瀛楁涓簆ersonoid
+                    //褰撳墠鏁版嵁瀵硅薄鐨勫睘鎬у瓧娈碉紝灏辩瓑浜巔kPerson
+                    String thisFieldName = exp.substring(0,exp.indexOf("."));
+                    //褰撳墠鏁版嵁瀵硅薄鐨勫睘鎬у瓧娈靛皬鍐�  pkperson
+                    String thisFieldNameLow = thisFieldName.toLowerCase().trim();
+                    //寮曠敤鐨勪笟鍔$被鍨嬩腑鐨勫睘鎬у瓧娈碉紝name
+                    String referBtmTypeFieldName = exp.substring(exp.indexOf(".") + 1);
+                    if(this.useReferMap.containsKey(thisFieldNameLow)){
+                        s.setReferBtmType(this.useReferMap.get(thisFieldNameLow));
+                        String primaryKey = OID_FIELD;
+                        if(USER_TABLE_COMPATIBILITY){
+                            //璇存槑闇�瑕佸吋瀹硅�佺殑骞冲彴
+                            //姣斿 pkuser.name as pkUser.name 瀵瑰簲鑰佸钩鍙扮殑灏辨槸pkuser.plname as pkUser.name
+                            //left join vcibt_user pkuser on xxx.pkuser = pkuser.oid 瀵瑰簲鑰佸钩鍙版槸 left join pluser pkuser on xxx.pkuser = pkuser.pluid
+                            String referBtmTypeLower = s.getReferBtmType().toLowerCase().trim();
+                            if(USER_TABLE_COMPATIBILITY_BTM_MAP.containsKey(referBtmTypeLower)){
+                                s.setReferTableName(USER_TABLE_COMPATIBILITY_BTM_MAP.get(referBtmTypeLower));
+                                String fieldKey = referBtmTypeLower + USER_TABLE_COMPATIBILITY_FIELD_SEP +  referBtmTypeFieldName.trim().toLowerCase();
+                                if(USER_TABLE_COMPATIBILITY_FIELD_MAP.containsKey(fieldKey)){
+                                    referBtmTypeFieldName = USER_TABLE_COMPATIBILITY_FIELD_MAP.get(fieldKey);
+                                }
+
+                                String primaryKeyCompa = referBtmTypeLower + USER_TABLE_COMPATIBILITY_FIELD_SEP +  primaryKey;
+                                if(USER_TABLE_COMPATIBILITY_FIELD_MAP.containsKey(primaryKeyCompa)){
+                                    primaryKey = USER_TABLE_COMPATIBILITY_FIELD_MAP.get(primaryKeyCompa);
+                                }
+                                if(OID_FIELD.equalsIgnoreCase(s.getReferBtmTypeField())){
+                                    s.setReferBtmTypeField(primaryKey);
+                                }
+                            }else{
+                                s.setReferTableName(VciBaseUtil.getTableName(s.getReferBtmType()));
+                            }
+                        }else {
+                            s.setReferTableName(VciBaseUtil.getTableName( s.getReferBtmType()));
+                        }
+                        s.setUseReferFieldName(thisFieldName);
+                        s.setUseReferDbFieldName(this.allFieldNameMap.get(thisFieldNameLow));
+                        // pkperson.name as pkPersonName
+                        sb.append(thisFieldNameLow)
+                                .append(".")
+                                .append(referBtmTypeFieldName)
+                                .append(SPACE)
+                                .append("as")
+                                .append(SPACE)
+                                .append(s.getShowReferFieldName())
+                                .append(",")
+                                .append(SPACE);
+                        if(!joinedFieldSet.contains(thisFieldNameLow)) {
+                            //left join vcibt_person pkperson on xxx.personoid = pkperson.oid
+                            joinSqlSb.append(" left join ")
+                                    .append(s.getReferTableName())
+                                    .append(SPACE)
+                                    .append(thisFieldNameLow)
+                                    .append(SPACE)
+                                    .append("on")
+                                    .append(SPACE)
+                                    .append(this.getTableNick())
+                                    .append(".")
+                                    .append(s.getUseReferDbFieldName())
+                                    .append(SPACE)
+                                    .append("=")
+                                    .append(SPACE)
+                                    .append(thisFieldNameLow)
+                                    .append(".")
+                                    .append(StringUtils.isBlank(s.getReferBtmTypeField())?primaryKey:s.getReferBtmTypeField())
+                                    .append(SPACE);
+                            joinedFieldSet.add(thisFieldNameLow);
+                        }
+                    }else{
+                        if(USER_TABLE_COMPATIBILITY){
+                            //濡傛灉鏄吋瀹规ā寮忕殑璇濓紝鍙互鐩存帴鏌ヨ
+                            sb.append(thisFieldNameLow)
+                                    .append(".")
+                                    .append(referBtmTypeFieldName)
+                                    .append(SPACE)
+                                    .append("as")
+                                    .append(SPACE)
+                                    .append(s.getShowReferFieldName())
+                                    .append(",")
+                                    .append(SPACE);
+                        }else {
+                            throw new VciBaseException("{0}涓睘鎬1}鐨勬敞瑙d腑referColumn鐨勫唴瀹逛笉姝g‘锛屼娇鐢ㄥ弬鐓х殑灞炴�2}涓嶅瓨鍦�", new Object[]{this.doClass.getName(), s.getShowReferFieldName(), thisFieldName});
+                        }
+                    }
+                });
+            }
+            if(this.queryWrapperOption.getThisObjectQueryRevision() && this.queryWrapperOption.getThisObjectQueryRelease()){
+                joinSqlSb.append( " left join ")
+                        .append("vcibt_releasedobj")
+                        .append(SPACE)
+                        .append("releaseobj")
+                        .append(SPACE)
+                        .append("on")
+                        .append(SPACE)
+                        .append(this.getTableNick())
+                        .append(".")
+                        .append("nameoid")
+                        .append(SPACE)
+                        .append("=")
+                        .append(SPACE)
+                        .append("releaseobj")
+                        .append(".")
+                        .append("nameoid")
+                        .append(SPACE);
+            }
+
+            this.selectFieldSql = sb.toString().trim();
+            if(this.selectFieldSql.endsWith(",")){
+                this.selectFieldSql = this.selectFieldSql.substring(0,this.selectFieldSql.length() -1) + SPACE;
+            }
+           this.linkTableSql = joinSqlSb.toString();
+        }
+    }
+
+    /**
+     * 鑾峰彇鏁版嵁搴撹〃鐨勫悕绉�
+     * @return 鏁版嵁搴撹〃鐨勫悕绉帮紝濡傛灉鏄鍥剧殑璇濓紝璇蜂笉瑕佷娇鐢ㄨ繖涓被鏉ユ煡璇�
+     */
+    public String getTableName(){
+        if(this.doClass.isAnnotationPresent(VciLinkType.class)){
+            VciLinkType linkType = this.doClass.getDeclaredAnnotation(VciLinkType.class);
+            String tableName = linkType.tableName();
+            if(StringUtils.isBlank(tableName)){
+                return VciBaseUtil.getLinkTableName(linkType.name());
+            }else{
+                return tableName;
+            }
+        }else if(this.doClass.isAnnotationPresent(VciBtmType.class)){
+            VciBtmType btmType = this.doClass.getDeclaredAnnotation(VciBtmType.class);
+            String tableName = btmType.tableName();
+            if(StringUtils.isBlank(tableName)){
+                return VciBaseUtil.getTableName(btmType.name());
+            }else{
+                return tableName;
+            }
+        }else{
+            String name = this.doClass.getSimpleName();
+            if(name.endsWith("DO")){
+                name = name.substring(0,name.length()-2);
+            }
+            return VciBaseUtil.getTableName(name);
+        }
+    }
+
+    /**
+     * 鍒濆鍖栧彉閲�
+     */
+    private void initMap(){
+        if(this.allFieldNameMap == null){
+            this.allFieldNameMap = new HashMap<>();
+        }else{
+            this.allFieldNameMap.clear();
+        }
+        if(this.allFieldTypeMap == null){
+            this.allFieldTypeMap = new HashMap<>();
+        }else{
+            this.allFieldTypeMap.clear();;
+        }
+        if(this.referFieldInfoList == null){
+            this.referFieldInfoList = new ArrayList<>();
+        }else{
+            this.referFieldInfoList.clear();
+        }
+        if(this.useReferMap == null){
+            this.useReferMap = new HashMap<>();
+        }else{
+            this.useReferMap.clear();
+        }
+        if(this.enumFieldMap == null){
+            this.enumFieldMap = new HashMap<>();
+        }else{
+            this.enumFieldMap.clear();
+        }
+    }
+
+    /**
+     * 鑾峰彇绫讳腑鐨勫瓧娈垫槧灏�
+     */
+    public void initFieldNameMap(){
+        initMap();
+        List<Field> allField = VciBaseUtil.getAllFieldForObj(this.doClass);
+        //鏄惁鏈夌増鏈鐞�
+        boolean hasRevisionManage = getRevisionManage();
+        if(hasRevisionManage){
+            this.queryWrapperOption.setThisObjectQueryRevision(true);
+        }
+        //鏄惁鏈夌敓鍛藉懆鏈熺鐞�
+        boolean hasLifeCycleManage = getLifeCycleManage();
+        if(hasLifeCycleManage){
+            this.queryWrapperOption.setThisObjectQueryLifeCycle(true);
+        }
+        //鏄惁鏈夊瘑绾х鐞�
+        boolean hasSecretManage = getSecretManage();
+        if(!hasSecretManage){
+            this.queryWrapperOption.setThisObjectQuerySecret(false);
+        }else{
+            //鏈夊瘑绾э紝杩樺緱鐪嬫槸鍚﹀紑鍚瘑绾�
+            if(this.queryWrapperOption.getThisObjectQuerySecret() == null){
+                this.queryWrapperOption.setThisObjectQuerySecret(DEFAULT_QUERY_SECRET);
+            }
+        }
+        //鏁版嵁鏉冮檺鎬庝箞寮�
+        //TODO 鏁版嵁鏉冮檺闇�瑕佸鐞� weidy
+        if(allField!=null&&allField.size()>0){
+            for(Field field : allField){
+                field.setAccessible(true);
+                if(field.isAnnotationPresent(Id.class)){
+                    this.oidFieldName = field.getName();
+                }
+                if(!field.getName().equals("serialVersionUID") ){
+                    Class fieldTypeClass = field.getType();
+                    if(VciBaseUtil.isBasicType(fieldTypeClass)){
+                        String fieldName = field.getName();
+                        if(!hasRevisionManage && REVISION_MANAGE_FIELD_MAP.containsKey(fieldName.toLowerCase()) && !USER_TABLE_COMPATIBILITY){
+                            //涓嶇鐞嗙増鏈�
+                        }else if(!hasLifeCycleManage && LIFECYCLE_MANAGE_FIELD_MAP.containsKey(fieldName.toLowerCase()) && !USER_TABLE_COMPATIBILITY){
+                            //涓嶇鐞嗙敓鍛藉懆鏈�
+                        }else if(!hasSecretManage && SECRET_MANAGE_FIELD_MAP.containsKey(fieldName.toLowerCase())){
+                            //涓嶇鐞嗗瘑绾�
+                        }else {
+                            String clientBoAttrName = VciBaseUtil.getCboAttrNameFromField(field, this.doClass);
+                            if(USER_TABLE_COMPATIBILITY){
+                                clientBoAttrName = BASE_MODEL_COMPATIBILITY_MAP.getOrDefault(clientBoAttrName,clientBoAttrName);
+                            }
+                            if (field.isAnnotationPresent(Transient.class)) {
+                                //璇存槑杩欎釜涓嶆槸鎸佷箙鍖栫殑
+                                Transient trans = field.getAnnotation(Transient.class);
+                                if (StringUtils.isNotBlank(trans.referColumn()) && trans.referColumn().contains(".")) {
+                                    //璇存槑鏄弬鐓х殑瀛楁.鑾峰彇鍙傜収鐨勫唴瀹�
+                                    VciReferFieldInfo vciReferFieldInfo = new VciReferFieldInfo();
+                                    vciReferFieldInfo.setShowReferFieldName(fieldName);
+                                    vciReferFieldInfo.setShowReferDbFieldName(clientBoAttrName);
+                                    vciReferFieldInfo.setReferBtmTypeExp(trans.referColumn());
+                                    vciReferFieldInfo.setReferBtmTypeField(trans.valueField());
+                                    this.referFieldInfoList.add(vciReferFieldInfo);
+                                }
+                                if(USER_TABLE_COMPATIBILITY && "lctid".equalsIgnoreCase(fieldName)){
+                                    this.allFieldTypeMap.put("lctid", VciFieldTypeEnum.VTString);
+                                }
+                            } else {
+                                allFieldNameMap.put(clientBoAttrName.toLowerCase().trim(), field.getName());
+                                if(field.isAnnotationPresent(XmlType.class)){
+                                    xmlTypeFieldList.add(clientBoAttrName.toLowerCase(Locale.ROOT).trim());
+                                }
+                                VciFieldTypeEnum fieldTypeEnum = null;
+                                if (field.isAnnotationPresent(VciFieldType.class)) {
+                                    VciFieldType vciFieldType = field.getAnnotation(VciFieldType.class);
+                                    fieldTypeEnum = VciFieldTypeEnum.forValue(vciFieldType.value().name());
+                                } else {
+                                    //鏍规嵁鏁版嵁鐨勭被鍨嬪垽鏂�
+                                    if (VciBaseUtil.inArray(new Object[]{Double.class, double.class}, fieldTypeClass)) {
+                                        fieldTypeEnum = VciFieldTypeEnum.VTDouble;
+                                    } else if (VciBaseUtil.inArray(new Object[]{Integer.class, int.class}, fieldTypeClass)) {
+                                        fieldTypeEnum = VciFieldTypeEnum.VTInteger;
+                                    } else if (VciBaseUtil.inArray(new Object[]{Long.class, long.class}, fieldTypeClass)) {
+                                        fieldTypeEnum = VciFieldTypeEnum.VTLong;
+                                    } else if (Date.class.equals(fieldTypeClass)) {
+                                        fieldTypeEnum = VciFieldTypeEnum.VTDateTime;
+                                    } else {
+                                        fieldTypeEnum = VciFieldTypeEnum.VTString;
+                                    }
+                                }
+                                this.allFieldTypeMap.put(clientBoAttrName.toLowerCase().trim(), fieldTypeEnum);
+
+                                if (field.isAnnotationPresent(VciUseEnum.class)) {
+                                    //璇存槑鏄灇涓惧�肩殑瀛楁
+                                    VciUseEnum useEnum = field.getAnnotation(VciUseEnum.class);
+                                    this.enumFieldMap.put(useEnum.showTextField(), useEnum.value());
+                                }
+                                if (field.isAnnotationPresent(VciUseRefer.class)) {
+                                    VciUseRefer useRefer = field.getAnnotation(VciUseRefer.class);
+                                    this.useReferMap.put(clientBoAttrName.toLowerCase().trim(), useRefer.value());
+                                }
+                            }
+                        }
+                    }else{
+                        //涓嶆槸鍩烘湰绫诲瀷鐨勶紝閭d竴瀹氫笉鏄鐨勫睘鎬�
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * 鏍规嵁鐖舵煡璇㈠瓙鑺傜偣
+     * @param treeQueryObject 鏍戝舰鏌ヨ鏉′欢鍜岄厤缃�
+     * @param parentQueryOption 鐖舵煡璇㈤厤缃紝鏄嚜韬睘鎬э紝杩樻槸閾炬帴绫诲瀷
+     */
+    public void parentQueryChild(TreeQueryObject treeQueryObject,VciParentQueryOption parentQueryOption) {
+        if (treeQueryObject == null){
+            treeQueryObject = new TreeQueryObject();
+        }
+        VciQueryWrapperOption queryWrapperOption = new VciQueryWrapperOption();
+        if(treeQueryObject.isQueryAllRev()){
+            queryWrapperOption.setThisObjectQueryLastRevision(false);
+            queryWrapperOption.setThisObjectQueryRelease(false);
+        }
+        this.conditionMap = treeQueryObject.getConditionMap();
+        this.pageHelper = new PageHelper(-1);
+        this.queryWrapperOption = queryWrapperOption;
+        if(parentQueryOption!=null&& !parentQueryOption.isLinkTypeFlag() &&
+                StringUtils.isNotBlank(parentQueryOption.getParentFieldName())){
+            //璇存槑鏄牴鎹笂绾х殑瀛楁鏉ユ煡璇�
+            if(StringUtils.isNotBlank(treeQueryObject.getParentOid()) ){
+                //璇存槑浼犻�掍簡涓婄骇鐨�
+                if(treeQueryObject.isQueryAllLevel()){
+                    this.addCustomSql("startwithparent" + parentQueryOption.getParentFieldName() ,
+                            QueryOptionConstant.NO_OR_AND + " start with " + this.getTableNick() + "." + parentQueryOption.getParentFieldName() + " = '" + treeQueryObject.getParentOid().trim()
+                                    + "' connect by prior " + this.getTableNick() + "." + this.getOidFieldName() + " = " +  this.getTableNick() + "." + parentQueryOption.getParentFieldName());
+                }else {
+                    //鏍规嵁涓婄骇鏌ヨ鐩村睘涓嬬骇
+                    this.eq(parentQueryOption.getParentFieldName(), treeQueryObject.getParentOid());
+                }
+            }else{
+                if(treeQueryObject.isQueryAllLevel()){
+                    //鍏ㄩ儴鐨勫眰绾ч兘瑕佹煡璇紝鎴戜滑浣跨敤start with鍏堟煡璇㈠嚭缁撴灉鍚庯紝鍐嶅尮閰嶆煡璇㈡潯浠�
+                    this.addCustomSql("startwithparent" + parentQueryOption.getParentFieldName() , QueryOptionConstant.NO_OR_AND + "start with " + this.getTableNick() + "." + parentQueryOption.getParentFieldName()
+                            + " is null connect by prior " + this.getTableNick() + "." + this.getOidFieldName() + " = " + this.getTableNick() + "." + parentQueryOption.getParentFieldName() );
+                }else{
+                    this.isNull(parentQueryOption.getParentFieldName());
+                }
+            }
+        }else if(parentQueryOption!=null&& parentQueryOption.isLinkTypeFlag() && StringUtils.isNotBlank(parentQueryOption.getLinkTypeName())){
+            if(treeQueryObject.isQueryAllLevel()){
+                this.in(this.getOidFieldName(),
+                        " select " + (parentQueryOption.isQueryFromToFlag()?" f_oid ":" t_oid ") +
+                                " from " + VciBaseUtil.getLinkTableName(parentQueryOption.getLinkTypeName()) + " start with " +
+                                (parentQueryOption.isQueryFromToFlag()?" t_oid ":" f_oid ") +
+                                (StringUtils.isNotBlank(treeQueryObject.getParentOid())?(" = '" + treeQueryObject.getParentOid().trim() + "'"):" is null ") + " connect by prior " +
+                                (parentQueryOption.isQueryFromToFlag()?" t_oid = f_oid ":"f_oid = t_oid "));
+            }else{
+                //鏌ヨ鐩村睘涓嬬骇
+                this.in(this.getOidFieldName()," select " + (parentQueryOption.isQueryFromToFlag()?" f_oid ":" t_oid ") +
+                        " from " + VciBaseUtil.getLinkTableName(parentQueryOption.getLinkTypeName()) + " where " +
+                        (parentQueryOption.isQueryFromToFlag()?" t_oid ":" f_oid ") +
+                        (StringUtils.isNotBlank(treeQueryObject.getParentOid())?(" = '" + treeQueryObject.getParentOid().trim() + "'"):" is null "));
+            }
+        }else{
+            //throw new VciBaseException("parentQueryOption鍙傛暟閿欒锛岃涔堟槸鎸囧畾涓婄骇鐨勫睘鎬э紝瑕佷箞鏄摼鎺ョ被鍨嬬殑鏂瑰紡");
+        }
+        wrapperSql();
+    }
+
+    /**
+     * 瀛愭煡璇㈢埗
+     * @param parentQueryOption 涓婄骇鐨勯厤缃紝鏄嚜韬睘鎬э紝杩樻槸閾炬帴绫诲瀷
+     */
+    public void childQueryParent(VciParentQueryOption parentQueryOption){
+        VciBaseUtil.alertNotNull(parentQueryOption,"涓婄骇鏌ヨ閰嶇疆");
+        String valueSql = (StringUtils.isNotBlank(parentQueryOption.getfOid()))?(" = '" + parentQueryOption.getfOid() + "'"):(" is null");
+        if(!parentQueryOption.isLinkTypeFlag() &&
+                StringUtils.isNotBlank(parentQueryOption.getParentFieldName())){
+            //璇存槑鏄嚜韬湁涓婄骇鐨勫睘鎬�
+            this.addCustomSql("startwithchild" +parentQueryOption.getParentFieldName(),
+                    QueryOptionConstant.NO_OR_AND  + "start with " + this.getTableNick() + "." +
+                                (parentQueryOption.isHasSelf()?("oid" + valueSql):("oid = (select " + parentQueryOption.getParentFieldName() + " from " + this.getTableName() + " where oid " + valueSql + ") ")) +
+                                 " connect by prior " + this.getTableNick() + "."+ parentQueryOption.getParentFieldName() + " = " + this.getTableNick() + ".oid ");
+        }else if(parentQueryOption.isLinkTypeFlag()){
+            this.in(this.getOidFieldName()," select " + (parentQueryOption.isQueryFromToFlag()?"t_oid ":"f_oid") +
+                    " from " + VciBaseUtil.getLinkTableName(parentQueryOption.getLinkTypeName()) + " start with " +
+                    (parentQueryOption.isQueryFromToFlag()?" f_oid ":" t_oid" ) + valueSql +
+                    " connect by prior " +
+                    (parentQueryOption.isQueryFromToFlag()?" f_oid = t_oid ":"t_oid = f_oid "));
+        }else{
+            throw new VciBaseException("parentQueryOption鍙傛暟閿欒锛岃涔堟槸鎸囧畾涓婄骇鐨勫睘鎬э紝瑕佷箞鏄摼鎺ョ被鍨嬬殑鏂瑰紡");
+        }
+    }
+
+
+    /**
+     * 鑾峰彇鏄惁绠$悊瀵嗙骇
+     * @return true琛ㄧず绠$悊
+     */
+    private boolean getSecretManage() {
+        if(this.doClass.isAnnotationPresent(VciBtmType.class)){
+            VciBtmType vciBtmType = this.doClass.getDeclaredAnnotation(VciBtmType.class);
+            return vciBtmType.secretAble();
+        }
+        return false;
+    }
+
+    /**
+     * 鑾峰彇鏄惁绠$悊鐢熷懡鍛ㄦ湡
+     * @return true琛ㄧず绠$悊
+     */
+    private boolean getLifeCycleManage() {
+        if(this.doClass.isAnnotationPresent(VciBtmType.class)){
+            VciBtmType vciBtmType = this.doClass.getDeclaredAnnotation(VciBtmType.class);
+            if(StringUtils.isNotBlank(vciBtmType.lifeCycle()) && !FrameWorkLcStatusConstant.EMTYPE_LIFE_CYCLE.equalsIgnoreCase(vciBtmType.lifeCycle()) ){
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * 鏄惁鍖呭惈鐗堟湰绠$悊
+     * @return true琛ㄧず绠$悊鐗堟湰
+     */
+    private boolean getRevisionManage() {
+        if(this.doClass.isAnnotationPresent(VciBtmType.class)){
+            VciBtmType vciBtmType = this.doClass.getDeclaredAnnotation(VciBtmType.class);
+            if(StringUtils.isNotBlank(vciBtmType.revisionRule()) || vciBtmType.revisionRuleInput()){
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * 杞崲涓篸b鐨勫瓧娈�
+     * @return 瀛楁鍜屾煡璇㈢殑鍊�
+     */
+    public Map<String,String> switchConditionMap(){
+        Map<String,String> queryMap = new HashMap<>();
+        if(!CollectionUtils.isEmpty(this.conditionMap)){
+            this.conditionMap.forEach((key,value)->{
+                queryMap.put(key,value);
+            });
+            //鎴戜滑杞崲涓�涓嬶紝鐩存帴set锛屽鏋滆繕鏈夐噸澶嶇殑灏卞彧鑳借嚜琛岃В鍐�
+            this.allFieldNameMap.forEach((dbField,field)->{
+                if(conditionMap.containsKey(field)){
+                    queryMap.put(dbField,this.conditionMap.get(field));
+                }
+            });
+        }
+        return queryMap;
+    }
+
+    /**
+     * 鑾峰彇鍏宠仈琛ㄦ牸鐨勫唴瀹�
+     * @return 鍏宠仈琛ㄦ牸鐨剆ql
+     */
+    public String getLinkTableSql() {
+        return linkTableSql;
+    }
+
+    public void setLinkTableSql(String linkTableSql) {
+        this.linkTableSql = linkTableSql;
+    }
+
+
+
+    /**
+     * 杩藉姞杩炴帴鐨勮〃
+     * @param linkTableSql 杩炴帴琛ㄧ殑sql
+     */
+    public void addLinkTableSql(String linkTableSql){
+        this.linkTableSql += (SPACE + linkTableSql + SPACE);
+    }
+
+    public String getSelectFieldSql() {
+        initWhereSql();
+        if(this.pageHelper!=null&& this.pageHelper.getLimit()>0){
+            return this.selectPrefixForPage + this.selectFieldSql;
+        }
+        return selectFieldSql;
+    }
+
+    public void setSelectFieldSql(String selectFieldSql) {
+        this.selectFieldSql = selectFieldSql;
+    }
+
+    /**
+     * 娣诲姞鑷畾涔夌殑鏌ヨ瀛楁
+     * @param sql 娣诲姞鐨凷ql
+     */
+    public void appendSelectField(String sql){
+        this.selectFieldSql += "," + sql;
+    }
+
+    /**
+     *  鎵╁睍鏌ヨ鐨勫墠缂�
+     * @param sql 娣诲姞鐨凷ql
+     */
+    public void appendSelectPagePrefix(String sql){
+        this.selectPrefixForPage += "," + sql;
+    }
+
+
+    public String getWhereSql() {
+        if(StringUtils.isBlank(this.whereSql)){
+            this.whereSql = " 1 = 1 ";
+        }
+        if(this.pageHelper!=null&& this.pageHelper.getLimit()>0){
+            return this.whereSql + (this.orderSql== null?"":this.orderSql) +  (this.whereSubfixForPage == null?"":this.whereSubfixForPage);
+        }
+        return (StringUtils.isNotBlank(whereSql)?whereSql:" 1= 1 ") + (this.orderSql == null?"":this.orderSql);
+    }
+
+    /**
+     * 闆嗗悎鐨勬煡璇㈠皝瑁呬负
+     * @param key 灞炴��
+     * @param list 鍊�
+     */
+    public void wrapperForCollection(String key,Collection<String> list){
+        if(!CollectionUtils.isEmpty(list)) {
+            removeQueryMap(key);
+            //涓嶇敤in鏌ヨ
+            StringBuffer sb = new StringBuffer();
+            sb.append("(");
+            list.stream().forEach(s -> {
+                sb.append(" ").append(getTableNick()).append(".").append(key).append(" = '").append(s).append("' or");
+            });
+            addCustomSql(key, sb.substring(0,sb.length()-2) +" )");
+        }
+    }
+
+
+
+    public void setWhereSql(String whereSql) {
+        this.whereSql = whereSql;
+    }
+
+    public Map<String, String> getValuesMap() {
+        return valuesMap;
+    }
+
+    public void setValuesMap(Map<String, String> valuesMap) {
+        this.valuesMap = valuesMap;
+    }
+
+    public String getTableNick() {
+        return tableNick;
+    }
+
+    public void setTableNick(String tableNick) {
+        this.tableNick = tableNick;
+    }
+
+    public String getOrderSql() {
+        return orderSql;
+    }
+
+    public void setOrderSql(String orderSql) {
+        this.orderSql = orderSql;
+    }
+
+    public String getOidFieldName() {
+        return oidFieldName;
+    }
+
+    public void setOidFieldName(String oidFieldName) {
+        this.oidFieldName = oidFieldName;
+    }
+
+    public VciQueryWrapperOption getQueryWrapperOption() {
+        return queryWrapperOption;
+    }
+
+    public void setQueryWrapperOption(VciQueryWrapperOption queryWrapperOption) {
+        this.queryWrapperOption = queryWrapperOption;
+    }
+
+    public boolean isDistinct() {
+        return distinct;
+    }
+
+    public void setDistinct(boolean distinct) {
+        this.distinct = distinct;
+    }
+
+    public Map<String, String> getCustomerSqlMap() {
+        return customerSqlMap;
+    }
+
+    public void setCustomerSqlMap(Map<String, String> customerSqlMap) {
+        this.customerSqlMap = customerSqlMap;
+    }
+
+
+
+    @Override
+    public String toString() {
+        return "VciQueryWrapperForDO{" +
+                "conditionMap=" + conditionMap +
+                ", customerSqlMap=" + customerSqlMap +
+                ", oidFieldName='" + oidFieldName + '\'' +
+                ", queryWrapperOption=" + queryWrapperOption +
+                ", doClass=" + doClass +
+                ", pageHelper=" + pageHelper +
+                ", allFieldNameMap=" + allFieldNameMap +
+                ", xmlTypeFieldList=" + xmlTypeFieldList +
+                ", distinct=" + distinct +
+                ", allFieldTypeMap=" + allFieldTypeMap +
+                ", referFieldInfoList=" + referFieldInfoList +
+                ", useReferMap=" + useReferMap +
+                ", enumFieldMap=" + enumFieldMap +
+                ", linkTableSql='" + linkTableSql + '\'' +
+                ", selectFieldSql='" + selectFieldSql + '\'' +
+                ", selectPrefixForPage='" + selectPrefixForPage + '\'' +
+                ", whereSql='" + whereSql + '\'' +
+                ", orderSql='" + orderSql + '\'' +
+                ", whereSubfixForPage='" + whereSubfixForPage + '\'' +
+                ", valuesMap=" + valuesMap +
+                ", tableNick='" + tableNick + '\'' +
+                '}';
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/wrapper/VciQueryWrapperOption.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/wrapper/VciQueryWrapperOption.java
new file mode 100644
index 0000000..2ab8c59
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/wrapper/VciQueryWrapperOption.java
@@ -0,0 +1,117 @@
+package com.vci.starter.web.wrapper;
+
+/**
+ * 鏌ヨ鐨勫弬鏁�
+ * @author weidy
+ * @date 2019/10/21 18:40
+ */
+public class VciQueryWrapperOption {
+
+    /**
+     * 鏋勯�犳柟娉曪紝榛樿鏌ヨ鏈�鍚庣殑鐗堟湰鍜屽彂甯冪殑鐗堟湰鏁版嵁
+     */
+    public VciQueryWrapperOption(){
+        this.thisObjectQueryLastRevision = true;
+        this.thisObjectQueryRelease = false;
+    }
+
+    /**
+     * 鏋勯�犳柟娉曪紝
+     * @param queryLastRevision 鏄惁鏌ヨ鏈�鍚庣殑鐗堟湰
+     * @param queryRelease 鏄惁鏌ヨ鍙戝竷鐨勭増鏈�
+     */
+    public VciQueryWrapperOption(Boolean queryLastRevision,Boolean queryRelease){
+        this.thisObjectQueryLastRevision = queryLastRevision;
+        this.thisObjectQueryRelease = queryRelease;
+    }
+
+    /**
+     *  鏋勯�犳柟娉�
+     * @param queryLastRevision 鏌ヨ鏈�鍚庣殑鐗堟湰
+     * @param queryRelease 鏌ヨ鍙戝竷鐨勭増鏈�
+     * @param querySecret 鏌ヨ瀵嗙骇
+     * @param queryDataRight 鏌ヨ鏁版嵁鏉冮檺
+     */
+    public VciQueryWrapperOption(Boolean queryLastRevision,Boolean queryRelease,Boolean querySecret,Boolean queryDataRight){
+        this.thisObjectQueryLastRevision = queryLastRevision;
+        this.thisObjectQueryRelease = queryRelease;
+    }
+
+    /**
+     * 褰撳墠瀵硅薄鏄惁鏌ヨ瀵嗙骇-鐢遍厤缃�
+     */
+    private Boolean thisObjectQuerySecret = false;
+
+    /**
+     * 褰撳墠瀵硅薄鏄惁鏌ヨ鏁版嵁鏉冮檺
+     */
+    private Boolean thisObjectQueryDataRight = false;
+
+    /**
+     * 褰撳墠瀵硅薄鏄惁鏌ヨ鐗堟湰
+     */
+    private Boolean thisObjectQueryRevision =false;
+
+    /**
+     * 褰撳墠瀵硅薄鏄惁鏌ヨ鐢熷懡鍛ㄦ湡
+     */
+    private Boolean thisObjectQueryLifeCycle =false;
+
+    /**
+     * 褰撳墠瀵硅薄鏄惁鏌ヨ鏈�鍚庣殑鐗堟湰
+     */
+    private Boolean thisObjectQueryLastRevision = true;
+
+    /**
+     * 褰撳墠瀵硅薄鏄惁鏌ヨ鍙戝竷鐨勭増鏈�
+     */
+    private Boolean thisObjectQueryRelease = false ;
+
+    public Boolean getThisObjectQuerySecret() {
+        return thisObjectQuerySecret;
+    }
+
+    public void setThisObjectQuerySecret(Boolean thisObjectQuerySecret) {
+        this.thisObjectQuerySecret = thisObjectQuerySecret;
+    }
+
+    public Boolean getThisObjectQueryDataRight() {
+        return thisObjectQueryDataRight;
+    }
+
+    public void setThisObjectQueryDataRight(Boolean thisObjectQueryDataRight) {
+        this.thisObjectQueryDataRight = thisObjectQueryDataRight;
+    }
+
+    public Boolean getThisObjectQueryRevision() {
+        return thisObjectQueryRevision;
+    }
+
+    public void setThisObjectQueryRevision(Boolean thisObjectQueryRevision) {
+        this.thisObjectQueryRevision = thisObjectQueryRevision;
+    }
+
+    public Boolean getThisObjectQueryLifeCycle() {
+        return thisObjectQueryLifeCycle;
+    }
+
+    public void setThisObjectQueryLifeCycle(Boolean thisObjectQueryLifeCycle) {
+        this.thisObjectQueryLifeCycle = thisObjectQueryLifeCycle;
+    }
+
+    public Boolean getThisObjectQueryLastRevision() {
+        return thisObjectQueryLastRevision;
+    }
+
+    public void setThisObjectQueryLastRevision(Boolean thisObjectQueryLastRevision) {
+        this.thisObjectQueryLastRevision = thisObjectQueryLastRevision;
+    }
+
+    public Boolean getThisObjectQueryRelease() {
+        return thisObjectQueryRelease;
+    }
+
+    public void setThisObjectQueryRelease(Boolean thisObjectQueryRelease) {
+        this.thisObjectQueryRelease = thisObjectQueryRelease;
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/wrapper/VciReferFieldInfo.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/wrapper/VciReferFieldInfo.java
new file mode 100644
index 0000000..6c7dbd6
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/wrapper/VciReferFieldInfo.java
@@ -0,0 +1,128 @@
+package com.vci.starter.web.wrapper;
+
+/**
+ * 鍙傜収鐨勪俊鎭皝瑁呭璞�
+ * @author weidy
+ * @date 2019/10/21 15:44
+ */
+public class VciReferFieldInfo {
+
+    /**
+     * 鏄剧ず鐢ㄧ殑瀛楁鍚嶇О锛堜笉鏄暟鎹簱琛ㄤ腑锛�
+     */
+    private String showReferFieldName;
+
+    /**
+     * 鏄剧ず鐢ㄧ殑鏁版嵁搴撳瓧娈靛悕绉帮紝鐢ㄤ簬resultMap涓娇鐢�
+     */
+    private String showReferDbFieldName;
+
+    /**
+     * 鍏蜂綋寮曠敤鐨勫睘鎬у悕绉�
+     */
+    private String useReferFieldName;
+
+    /**
+     * 鍏蜂綋寮曠敤鐨勫睘鎬х殑鏁版嵁搴撳瓧娈靛悕绉�
+     */
+    private String useReferDbFieldName;
+
+    /**
+     * 寮曠敤鐨勪笟鍔$被鍨嬭〃杈惧紡锛岋紝XXX.name 鎴栬�厁xx.id
+     */
+    private String referBtmTypeExp;
+
+    /**
+     * 寮曠敤鐨勪笟鍔$被鍨�
+     */
+    private String referBtmType;
+
+    /**
+     * 寮曠敤鐨勪笟鍔$被鍨嬬殑鏁版嵁搴撹〃
+     */
+    private String referTableName;
+
+    /**
+     * 寮曠敤鐨勪笟鍔$被鍨嬬殑灞炴��
+     */
+    private String referBtmTypeField;
+
+
+    public String getShowReferFieldName() {
+        return showReferFieldName;
+    }
+
+    public void setShowReferFieldName(String showReferFieldName) {
+        this.showReferFieldName = showReferFieldName;
+    }
+
+    public String getShowReferDbFieldName() {
+        return showReferDbFieldName;
+    }
+
+    public void setShowReferDbFieldName(String showReferDbFieldName) {
+        this.showReferDbFieldName = showReferDbFieldName;
+    }
+
+    public String getUseReferFieldName() {
+        return useReferFieldName;
+    }
+
+    public void setUseReferFieldName(String useReferFieldName) {
+        this.useReferFieldName = useReferFieldName;
+    }
+
+    public String getUseReferDbFieldName() {
+        return useReferDbFieldName;
+    }
+
+    public void setUseReferDbFieldName(String useReferDbFieldName) {
+        this.useReferDbFieldName = useReferDbFieldName;
+    }
+
+    public String getReferBtmType() {
+        return referBtmType;
+    }
+
+    public void setReferBtmType(String referBtmType) {
+        this.referBtmType = referBtmType;
+    }
+
+    public String getReferTableName() {
+        return referTableName;
+    }
+
+    public void setReferTableName(String referTableName) {
+        this.referTableName = referTableName;
+    }
+
+    public String getReferBtmTypeExp() {
+        return referBtmTypeExp;
+    }
+
+    public void setReferBtmTypeExp(String referBtmTypeExp) {
+        this.referBtmTypeExp = referBtmTypeExp;
+    }
+
+    public String getReferBtmTypeField() {
+        return referBtmTypeField;
+    }
+
+    public void setReferBtmTypeField(String referBtmTypeField) {
+        this.referBtmTypeField = referBtmTypeField;
+    }
+
+    @Override
+    public String toString() {
+        return "VciReferFieldInfo{" +
+                "showReferFieldName='" + showReferFieldName + '\'' +
+                ", showReferDbFieldName='" + showReferDbFieldName + '\'' +
+                ", useReferFieldName='" + useReferFieldName + '\'' +
+                ", useReferDbFieldName='" + useReferDbFieldName + '\'' +
+                ", referBtmTypeExp='" + referBtmTypeExp + '\'' +
+                ", referBtmType='" + referBtmType + '\'' +
+                ", referTableName='" + referTableName + '\'' +
+                ", referBtmTypeField='" + referBtmTypeField + '\'' +
+                '}';
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/yml/YamlPropertySourceFactory.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/yml/YamlPropertySourceFactory.java
new file mode 100644
index 0000000..e54fde8
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/web/yml/YamlPropertySourceFactory.java
@@ -0,0 +1,50 @@
+package com.vci.starter.web.yml;
+
+import org.springframework.boot.env.YamlPropertySourceLoader;
+import org.springframework.core.env.PropertySource;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.support.EncodedResource;
+import org.springframework.core.io.support.PropertySourceFactory;
+import org.springframework.util.CollectionUtils;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * 璇诲彇鑷畾涔夌殑yml鏂囦欢
+ * @author weidy
+ * @date 2020/3/13
+ */
+public class YamlPropertySourceFactory implements PropertySourceFactory {
+    /**
+     * 鍒涘缓yaml鐨勫伐鍘傝祫婧�
+     * @param name 鍚嶇О
+     * @param resource 璧勬簮闆嗗悎
+     * @return 瀛樺湪鐨勬椂鍊欒繑鍥瀙ropertySource
+     * @throws IOException 璇诲彇鏂囦欢閿欒浼氭姏鍑哄紓甯�
+     */
+    @Override
+    public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
+        //璋冪敤yaml
+        List<PropertySource<?>> sourceList = name != null ? new YamlPropertySourceLoader().load( name, resource.getResource()) : new YamlPropertySourceLoader().load(
+                getNameForResource(resource.getResource()), resource.getResource());
+        if(!CollectionUtils.isEmpty(sourceList)){
+            return sourceList.get(0);
+        }
+        return null;
+    }
+
+    /**
+     * 鑾峰彇璧勬簮鐨勫悕绉�
+     * @param resource 璧勬簮瀵硅薄
+     * @return 璧勬簮鍚嶇О
+     */
+    private static String getNameForResource(Resource resource) {
+        String name = resource.getDescription();
+        if (!org.springframework.util.StringUtils.hasText(name)) {
+            name = resource.getClass().getSimpleName() + "@" + System.identityHashCode(resource);
+        }
+        return name;
+
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/workflow/dto/WFWorkflowRuntimeDTO.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/workflow/dto/WFWorkflowRuntimeDTO.java
new file mode 100644
index 0000000..60296a2
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/workflow/dto/WFWorkflowRuntimeDTO.java
@@ -0,0 +1,94 @@
+package com.vci.starter.workflow.dto;
+
+import com.vci.starter.workflow.pagemodel.WFWorkflowTaskHisVO;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 娴佺▼鐨勬墽琛屼俊鎭�
+ * @author weidy
+ * @date 2021/4/9
+ */
+public class WFWorkflowRuntimeDTO implements java.io.Serializable{
+
+    /**
+     * 搴忓垪鍖�
+     */
+    private static final long serialVersionUID = -5305339505741718337L;
+    /**
+     * 涓氬姟绫诲瀷
+     */
+    private String btmType;
+
+    /**
+     * 鏁版嵁鐨勪富閿�
+     */
+    private List<String> oids;
+
+    /**
+     * 鍙橀噺鐨勫唴瀹�
+     */
+    private Map<String,Object> variableMap;
+
+    /**
+     * 鎵ц鍘嗗彶
+     */
+    private List<WFWorkflowTaskHisVO> taskHisVOList;
+
+    /**
+     * 褰撳墠姝e湪鎵ц鐨勪换鍔″悕绉�
+     */
+    private String currentTaskName;
+
+    public String getCurrentTaskName() {
+        return currentTaskName;
+    }
+
+    public void setCurrentTaskName(String currentTaskName) {
+        this.currentTaskName = currentTaskName;
+    }
+
+    public String getBtmType() {
+        return btmType;
+    }
+
+    public void setBtmType(String btmType) {
+        this.btmType = btmType;
+    }
+
+    public List<String> getOids() {
+        return oids;
+    }
+
+    public void setOids(List<String> oids) {
+        this.oids = oids;
+    }
+
+    public Map<String, Object> getVariableMap() {
+        return variableMap;
+    }
+
+    public void setVariableMap(Map<String, Object> variableMap) {
+        this.variableMap = variableMap;
+    }
+
+    public List<WFWorkflowTaskHisVO> getTaskHisVOList() {
+        return taskHisVOList;
+    }
+
+    public void setTaskHisVOList(List<WFWorkflowTaskHisVO> taskHisVOList) {
+        this.taskHisVOList = taskHisVOList;
+    }
+
+    @Override
+    public String toString() {
+        return "WFWorkflowRuntimeDTO{" +
+                "btmType='" + btmType + '\'' +
+                ", oids=" + oids +
+                ", variableMap=" + variableMap +
+                ", taskHisVOList=" + taskHisVOList +
+                ", currentTaskName='" + currentTaskName + '\'' +
+                '}';
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/workflow/pagemodel/WFWorkflowTaskHisVO.java b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/workflow/pagemodel/WFWorkflowTaskHisVO.java
new file mode 100644
index 0000000..d49217e
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/java/com/vci/starter/workflow/pagemodel/WFWorkflowTaskHisVO.java
@@ -0,0 +1,345 @@
+package com.vci.starter.workflow.pagemodel;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 娴佺▼浠诲姟鍘嗗彶鏄剧ず瀵硅薄
+ * @author weidy
+ * @date 2020-09-28
+ */
+public class WFWorkflowTaskHisVO implements java.io.Serializable{
+
+    /**
+     * 绂佹淇敼杩欎釜鍊�
+     */
+    private static final long serialVersionUID = 7539176109676429282L;
+    /**
+     * 鍘嗗彶璁板綍涓婚敭
+     */
+    private String oid;
+
+    /**
+     * 娲诲姩涓婚敭
+     */
+    private String activityId;
+
+    /**
+     * 浠诲姟鍚嶇О
+     */
+    private String activityName;
+
+    /**
+     * 浠诲姟绫诲瀷
+     */
+    private String activityType;
+
+    /**
+     * 娴佺▼瀹氫箟涓婚敭
+     */
+    private String processDefinitionId;
+
+    /**
+     * 娴佺▼瀹炰緥涓婚敭
+     */
+    private String processInstanceId;
+
+    /**
+     * 娴佺▼鐨勫悕绉�
+     */
+    private String processName;
+
+    /**
+     * 娴佺▼妯℃澘鍚嶇О
+     */
+    private String processDefinitionName;
+
+    /**
+     * 鎵ц涓婚敭
+     */
+    private String executionId;
+
+    /**
+     * 浠诲姟涓婚敭
+     */
+    private String taskId;
+
+    /**
+     * 璋冪敤娴佺▼涓婚敭
+     */
+    private String calledProcessInstanceId;
+
+    /**
+     * 鎵ц浜鸿处鍙�
+     */
+    private String assignee;
+
+    /**
+     * 鎵ц浜哄鍚�
+     */
+    private String assigneeName;
+
+    /**
+     * 寮�濮嬫椂闂�
+     */
+    private Date startTime;
+
+    /**
+     * 瀹屾垚鏃堕棿
+     */
+    private Date endTime;
+
+    /**
+     * 鑰楁椂
+     */
+    private Long durationInMillis;
+
+    /**
+     * 鍒犻櫎鍘熷洜
+     */
+    private String deleteReason;
+
+    /**
+     * 绉熸埛涓婚敭
+     */
+    private String tenantId;
+
+    /**
+     * 瀹℃壒鎰忚
+     */
+    private String description;
+
+    /**
+     * 鍙橀噺
+     */
+    private Map<String,Object> variablesMap;
+
+    /**
+     * 澶氭潯鏁版嵁鏃跺叧鑱旂殑涓氬姟鏁版嵁涓婚敭
+     */
+    private List<String> linkBusinessOids;
+
+    /**
+     * 鏄剧ず璺緞
+     */
+    private String displayUrl;
+
+    /**
+     * 鍙戣捣娴佺▼鐨勪笟鍔$被鍨�
+     */
+    private String btmType;
+
+    public String getProcessName() {
+        return processName;
+    }
+
+    public void setProcessName(String processName) {
+        this.processName = processName;
+    }
+
+    public String getProcessDefinitionName() {
+        return processDefinitionName;
+    }
+
+    public void setProcessDefinitionName(String processDefinitionName) {
+        this.processDefinitionName = processDefinitionName;
+    }
+
+    public String getBtmType() {
+        return btmType;
+    }
+
+    public void setBtmType(String btmType) {
+        this.btmType = btmType;
+    }
+
+    public String getOid() {
+        return oid;
+    }
+
+    public void setOid(String oid) {
+        this.oid = oid;
+    }
+
+    public List<String> getLinkBusinessOids() {
+        return linkBusinessOids;
+    }
+
+    public void setLinkBusinessOids(List<String> linkBusinessOids) {
+        this.linkBusinessOids = linkBusinessOids;
+    }
+
+    public String getDisplayUrl() {
+        return displayUrl;
+    }
+
+    public void setDisplayUrl(String displayUrl) {
+        this.displayUrl = displayUrl;
+    }
+
+    public String getActivityId() {
+        return activityId;
+    }
+
+    public void setActivityId(String activityId) {
+        this.activityId = activityId;
+    }
+
+    public String getActivityName() {
+        return activityName;
+    }
+
+    public void setActivityName(String activityName) {
+        this.activityName = activityName;
+    }
+
+    public String getActivityType() {
+        return activityType;
+    }
+
+    public void setActivityType(String activityType) {
+        this.activityType = activityType;
+    }
+
+    public String getProcessDefinitionId() {
+        return processDefinitionId;
+    }
+
+    public void setProcessDefinitionId(String processDefinitionId) {
+        this.processDefinitionId = processDefinitionId;
+    }
+
+    public String getProcessInstanceId() {
+        return processInstanceId;
+    }
+
+    public void setProcessInstanceId(String processInstanceId) {
+        this.processInstanceId = processInstanceId;
+    }
+
+    public String getExecutionId() {
+        return executionId;
+    }
+
+    public void setExecutionId(String executionId) {
+        this.executionId = executionId;
+    }
+
+    public String getTaskId() {
+        return taskId;
+    }
+
+    public void setTaskId(String taskId) {
+        this.taskId = taskId;
+    }
+
+    public String getCalledProcessInstanceId() {
+        return calledProcessInstanceId;
+    }
+
+    public void setCalledProcessInstanceId(String calledProcessInstanceId) {
+        this.calledProcessInstanceId = calledProcessInstanceId;
+    }
+
+    public String getAssignee() {
+        return assignee;
+    }
+
+    public void setAssignee(String assignee) {
+        this.assignee = assignee;
+    }
+
+    public String getAssigneeName() {
+        return assigneeName;
+    }
+
+    public void setAssigneeName(String assigneeName) {
+        this.assigneeName = assigneeName;
+    }
+
+    public Date getStartTime() {
+        return startTime;
+    }
+
+    public void setStartTime(Date startTime) {
+        this.startTime = startTime;
+    }
+
+    public Date getEndTime() {
+        return endTime;
+    }
+
+    public void setEndTime(Date endTime) {
+        this.endTime = endTime;
+    }
+
+    public Long getDurationInMillis() {
+        return durationInMillis;
+    }
+
+    public void setDurationInMillis(Long durationInMillis) {
+        this.durationInMillis = durationInMillis;
+    }
+
+    public String getDeleteReason() {
+        return deleteReason;
+    }
+
+    public void setDeleteReason(String deleteReason) {
+        this.deleteReason = deleteReason;
+    }
+
+    public String getTenantId() {
+        return tenantId;
+    }
+
+    public void setTenantId(String tenantId) {
+        this.tenantId = tenantId;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public Map<String, Object> getVariablesMap() {
+        return variablesMap;
+    }
+
+    public void setVariablesMap(Map<String, Object> variablesMap) {
+        this.variablesMap = variablesMap;
+    }
+
+    @Override
+    public String toString() {
+        return "WFWorkflowTaskHisVO{" +
+                "oid='" + oid + '\'' +
+                ", activityId='" + activityId + '\'' +
+                ", activityName='" + activityName + '\'' +
+                ", activityType='" + activityType + '\'' +
+                ", processDefinitionId='" + processDefinitionId + '\'' +
+                ", processInstanceId='" + processInstanceId + '\'' +
+                ", processName='" + processName + '\'' +
+                ", processDefinitionName='" + processDefinitionName + '\'' +
+                ", executionId='" + executionId + '\'' +
+                ", taskId='" + taskId + '\'' +
+                ", calledProcessInstanceId='" + calledProcessInstanceId + '\'' +
+                ", assignee='" + assignee + '\'' +
+                ", assigneeName='" + assigneeName + '\'' +
+                ", startTime=" + startTime +
+                ", endTime=" + endTime +
+                ", durationInMillis=" + durationInMillis +
+                ", deleteReason='" + deleteReason + '\'' +
+                ", tenantId='" + tenantId + '\'' +
+                ", description='" + description + '\'' +
+                ", variablesMap=" + variablesMap +
+                ", linkBusinessOids=" + linkBusinessOids +
+                ", displayUrl='" + displayUrl + '\'' +
+                ", btmType='" + btmType + '\'' +
+                '}';
+    }
+}
diff --git a/Source/plt-web/plt-web-parent/plt-web-base/src/main/resources/application-web.yml b/Source/plt-web/plt-web-parent/plt-web-base/src/main/resources/application-web.yml
new file mode 100644
index 0000000..a443a74
--- /dev/null
+++ b/Source/plt-web/plt-web-parent/plt-web-base/src/main/resources/application-web.yml
@@ -0,0 +1,24 @@
+spring:
+  application:
+    name: vci-${app.group:}-${app.name:}
+  http:
+    encoding.charset: UTF-8
+    encoding.enable: true
+    encoding.force: true
+  aop:
+    proxy-target-class: true
+  jackson:
+    generator:
+      WRITE_NUMBERS_AS_STRINGS: true
+
+server:
+  port: 8080
+  undertow:
+    io-threads: 2
+    worker-threads: 200
+  tomcat:
+    uri-encoding: UTF-8
+cors:
+  enabled: true
+vcispringmvc:
+  enabled: true
diff --git a/Source/plt-web/plt-web-parent/plt-web/pom.xml b/Source/plt-web/plt-web-parent/plt-web/pom.xml
index 49e6d2f..df1c4e0 100644
--- a/Source/plt-web/plt-web-parent/plt-web/pom.xml
+++ b/Source/plt-web/plt-web-parent/plt-web/pom.xml
@@ -14,15 +14,7 @@
     <dependencies>
         <dependency>
             <groupId>com.vci</groupId>
-            <artifactId>vci-starter-parent</artifactId>
-            <version>1.0-SNAPSHOT</version>
-            <type>pom</type>
-        </dependency>
-
-        <dependency>
-            <groupId>com.vci</groupId>
-            <artifactId>vci-starter-web</artifactId>
-            <version>1.0-SNAPSHOT</version>
+            <artifactId>plt-web-base</artifactId>
             <exclusions>
                 <exclusion>
                     <groupId>org.springframework.boot</groupId>
@@ -66,8 +58,7 @@
         </dependency>
         <dependency>
             <groupId>com.vci</groupId>
-            <artifactId>vci-starter-word</artifactId>
-            <version>1.0-SNAPSHOT</version>
+            <artifactId>plt-poi</artifactId>
             <exclusions>
                 <exclusion>
                     <groupId>org.springframework.boot</groupId>
@@ -75,22 +66,7 @@
                 </exclusion>
                 <exclusion>
                     <groupId>com.vci</groupId>
-                    <artifactId>vci-starter-web</artifactId>
-                </exclusion>
-            </exclusions>
-        </dependency>
-        <dependency>
-            <groupId>com.vci</groupId>
-            <artifactId>vci-starter-poi</artifactId>
-            <version>1.0-SNAPSHOT</version>
-            <exclusions>
-                <exclusion>
-                    <groupId>org.springframework.boot</groupId>
-                    <artifactId>spring-boot-starter-thymeleaf</artifactId>
-                </exclusion>
-                <exclusion>
-                    <groupId>com.vci</groupId>
-                    <artifactId>vci-starter-web</artifactId>
+                    <artifactId>plt-web-base</artifactId>
                 </exclusion>
             </exclusions>
         </dependency>
@@ -110,7 +86,7 @@
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-cache</artifactId>
-            <version>2.1.3.RELEASE</version>
+            <version>${spring.version}</version>
         </dependency>
 
         <!-- ehcache缂撳瓨 -->
@@ -140,16 +116,6 @@
             <artifactId>reflections</artifactId>
             <version>0.9.11</version>
         </dependency>
-        <dependency>
-            <groupId>org.projectlombok</groupId>
-            <artifactId>lombok</artifactId>
-            <version>${lombok.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>com.fasterxml.jackson.core</groupId>
-            <artifactId>jackson-core</artifactId>
-            <version>${jackson.version}</version>
-        </dependency>
 
         <!--redis start-->
         <dependency>
@@ -163,6 +129,11 @@
             <version>2.9.0</version>
         </dependency>
         <!--redis end-->
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-core</artifactId>
+            <version>2.13.3</version>
+        </dependency>
     </dependencies>
 
     <build>
diff --git a/Source/plt-web/plt-web-parent/pom.xml b/Source/plt-web/plt-web-parent/pom.xml
index 567eb4b..c609de5 100644
--- a/Source/plt-web/plt-web-parent/pom.xml
+++ b/Source/plt-web/plt-web-parent/pom.xml
@@ -12,16 +12,186 @@
     <modules>
         <module>plt-web</module>
         <module>plt-starter</module>
+        <module>plt-web-base</module>
+        <module>plt-poi</module>
     </modules>
 
     <properties>
-        <plt.version>1.0.RELEASE</plt.version>
-        <platform.version>2024.1-SNAPSHOT</platform.version>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
         <java.version>1.8</java.version>
+        
+        <plt.version>1.0.RELEASE</plt.version>
+        <platform.version>2024.1-SNAPSHOT</platform.version>
+        <spring.version>2.1.3.RELEASE</spring.version>
         <lombok.version>1.18.22</lombok.version>
-        <jackson.version>2.13.3</jackson.version>
+        <fastjson.version>1.2.83</fastjson.version>
+        <common3.version>3.8.1</common3.version>
+        <log.version>2.17.0</log.version>
+        <jackson-dataformat-yaml.version>2.9.8</jackson-dataformat-yaml.version>
     </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter</artifactId>
+            <version>${spring.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.springframework.boot</groupId>
+                    <artifactId>spring-boot-starter-logging</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-log4j2</artifactId>
+            <version>${spring.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.apache.logging.log4j</groupId>
+                    <artifactId>*</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-core</artifactId>
+            <version>${log.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.apache.logging.log4j</groupId>
+                    <artifactId>log4j-api</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-api</artifactId>
+            <version>${log.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-slf4j-impl</artifactId>
+            <version>${log.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.apache.logging.log4j</groupId>
+                    <artifactId>log4j-api</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.apache.logging.log4j</groupId>
+                    <artifactId>log4j-core</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-jul</artifactId>
+            <version>${log.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.apache.logging.log4j</groupId>
+                    <artifactId>log4j-api</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.apache.logging.log4j</groupId>
+                    <artifactId>log4j-core</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency> <!--涓嶈鏄笉鏄娇鐢╟orba锛岄兘寮曞叆web-->
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-configuration-processor</artifactId>
+            <version>${spring.version}</version>
+            <optional>true</optional>
+        </dependency>
+        <!--fastjson-->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>${fastjson.version}</version>
+        </dependency>
+        <dependency><!--瀛楃涓插垽鏂�-->
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+            <version>${common3.version}</version>
+        </dependency>
+        <dependency><!--鏂囦欢鎷疯礉鍜岃鍙�-->
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>2.5</version>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <version>${lombok.version}</version>
+        </dependency>
+    </dependencies>
+
+    <dependencyManagement>
+        <dependencies>
+            <!--plt-web-->
+            <dependency>
+                <groupId>com.vci</groupId>
+                <artifactId>plt-starter</artifactId>
+                <version>2024.1-SNAPSHOT</version>
+            </dependency>
+            <dependency>
+                <groupId>com.vci</groupId>
+                <artifactId>plt-web</artifactId>
+                <version>2024.1-SNAPSHOT</version>
+            </dependency>
+            <dependency>
+                <groupId>com.vci</groupId>
+                <artifactId>plt-web-base</artifactId>
+                <version>2024.1-SNAPSHOT</version>
+            </dependency>
+            <dependency>
+                <groupId>com.vci</groupId>
+                <artifactId>plt-poi</artifactId>
+                <version>2024.1-SNAPSHOT</version>
+            </dependency>
+
+            <!--spring鐩稿叧-->
+            <dependency>
+                <groupId>com.springframework.boot</groupId>
+                <artifactId>spring-boot-starter</artifactId>
+                <version>${spring.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-starter-test</artifactId>
+                <scope>test</scope>
+                <version>${spring.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-starter-web</artifactId>
+                <version>${spring.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-devtools</artifactId>
+                <version>${spring.version}</version>
+                <optional>true</optional>
+            </dependency>
+            <!--jackson璇嗗埆yml閰嶇疆-->
+            <dependency>
+                <groupId>com.fasterxml.jackson.dataformat</groupId>
+                <artifactId>jackson-dataformat-yaml</artifactId>
+                <version>${jackson-dataformat-yaml.version}</version>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
 
     <!-- Maven鍒嗗彂鏋勪欢鐨勪綅缃紝绉佹湇鍦板潃 -->
     <distributionManagement>
@@ -34,21 +204,7 @@
             <url>http://dev.yunkeruida.top:9000/repository/maven-snapshots/</url>
         </snapshotRepository>
     </distributionManagement>
-
-    <dependencyManagement>
-        <dependencies>
-            <dependency>
-                <groupId>com.vci</groupId>
-                <artifactId>plt-starter</artifactId>
-                <version>2024.1-SNAPSHOT</version>
-            </dependency>
-            <dependency>
-                <groupId>com.vci</groupId>
-                <artifactId>plt-web</artifactId>
-                <version>2024.1-SNAPSHOT</version>
-            </dependency>
-        </dependencies>
-    </dependencyManagement>
+    
     <build>
         <plugins>
             <plugin>

--
Gitblit v1.9.3