syh 6 лет назад
Родитель
Сommit
4f6b6b7a95
100 измененных файлов с 30082 добавлено и 27 удалено
  1. 9 0
      .idea/adsp-boot.iml
  2. 36 0
      .idea/inspectionProfiles/Project_Default.xml
  3. 6 0
      .idea/misc.xml
  4. 8 0
      .idea/modules.xml
  5. 6 0
      .idea/vcs.xml
  6. 21 0
      LICENSE
  7. 245 27
      README.md
  8. 2501 0
      db/jeecg-boot-mysql-20190705.sql
  9. 2471 0
      db/jeecg-boot-mysql.sql
  10. 3852 0
      db/jeecg-boot-oracle_11g.sql
  11. 10239 0
      db/jeecg-boot-sqlserver_2008.sql
  12. 61 0
      db/增量升级SQL——mysql/jeecgboot2.0.1到2.0.2增量升级SQL
  13. 1 0
      jeecg-boot-base-common/.gitignore
  14. 234 0
      jeecg-boot-base-common/jeecg-boot-base-common.iml
  15. 32 0
      jeecg-boot-base-common/pom.xml
  16. 111 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/api/vo/Result.java
  17. 36 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/aspect/annotation/AutoLog.java
  18. 42 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/aspect/annotation/Dict.java
  19. 29 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/aspect/annotation/PermissionData.java
  20. 26 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/constant/CacheConstant.java
  21. 129 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/constant/CommonConstant.java
  22. 14 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/constant/CommonSendStatus.java
  23. 100 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/constant/DataBaseConstant.java
  24. 19 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/exception/JeecgBootException.java
  25. 69 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/exception/JeecgBootExceptionHandler.java
  26. 78 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/system/api/ISysBaseAPI.java
  27. 105 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/system/base/controller/JeecgController.java
  28. 54 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/system/base/entity/JeecgEntity.java
  29. 12 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/system/base/service/JeecgService.java
  30. 19 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/system/base/service/impl/JeecgServiceImpl.java
  31. 220 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/system/controller/CommonController.java
  32. 55 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/system/query/QueryCondition.java
  33. 592 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/system/query/QueryGenerator.java
  34. 71 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/system/query/QueryRuleEnum.java
  35. 90 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/system/util/JeecgDataAutorUtils.java
  36. 204 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/system/util/JwtUtil.java
  37. 40 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/system/vo/DictModel.java
  38. 83 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/system/vo/LoginUser.java
  39. 67 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/system/vo/SysUserCacheInfo.java
  40. 10 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/util/BrowserType.java
  41. 194 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/util/BrowserUtils.java
  42. 622 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/util/DateUtils.java
  43. 105 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/util/DySmsHelper.java
  44. 58 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/util/IPUtils.java
  45. 43 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/util/MD5Util.java
  46. 92 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/util/MyClassLoader.java
  47. 179 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/util/PasswordUtil.java
  48. 574 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/util/RedisUtil.java
  49. 84 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/util/SpringContextUtils.java
  50. 80 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/util/SqlInjectionUtil.java
  51. 95 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/util/UUIDGenerator.java
  52. 173 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/util/YouBianCodeUtil.java
  53. 124 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/util/encryption/AesEncryptUtil.java
  54. 12 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/util/encryption/EncryptedString.java
  55. 157 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/util/jsonschema/CommonProperty.java
  56. 87 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/util/jsonschema/JsonSchemaDescrip.java
  57. 70 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/util/jsonschema/JsonschemaUtil.java
  58. 82 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/util/jsonschema/validate/DictProperty.java
  59. 156 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/util/jsonschema/validate/NumberProperty.java
  60. 76 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/util/jsonschema/validate/PopupProperty.java
  61. 120 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/util/jsonschema/validate/StringProperty.java
  62. 92 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/util/jsonschema/validate/TreeSelectProperty.java
  63. 592 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/util/oConvertUtils.java
  64. 60 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/util/superSearch/ObjectParseUtil.java
  65. 60 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/util/superSearch/QueryRuleEnum.java
  66. 11 0
      jeecg-boot-base-common/src/main/java/org/jeecg/common/util/superSearch/QueryRuleVo.java
  67. 78 0
      jeecg-boot-base-common/src/main/java/org/jeecg/modules/system/entity/SysPermissionDataRule.java
  68. 11 0
      jeecg-boot-base-common/src/main/main.iml
  69. 1 0
      jeecg-boot-module-system/.gitignore
  70. 24 0
      jeecg-boot-module-system/docs/规范/编码必看规范
  71. BIN
      jeecg-boot-module-system/docs/规范/阿里巴巴Java开发手册(详尽版).pdf
  72. 18 0
      jeecg-boot-module-system/docs/项目说明
  73. 246 0
      jeecg-boot-module-system/jeecg-boot-module-system.iml
  74. 81 0
      jeecg-boot-module-system/pom.xml
  75. 41 0
      jeecg-boot-module-system/src/main/java/org/jeecg/JeecgApplication.java
  76. 18 0
      jeecg-boot-module-system/src/main/java/org/jeecg/JeecgOneGUI.java
  77. 69 0
      jeecg-boot-module-system/src/main/java/org/jeecg/JeecgOneToMainUtil.java
  78. 28 0
      jeecg-boot-module-system/src/main/java/org/jeecg/config/AutoPoiConfig.java
  79. 36 0
      jeecg-boot-module-system/src/main/java/org/jeecg/config/MybatisPlusConfig.java
  80. 106 0
      jeecg-boot-module-system/src/main/java/org/jeecg/config/RedisConfig.java
  81. 151 0
      jeecg-boot-module-system/src/main/java/org/jeecg/config/ShiroConfig.java
  82. 101 0
      jeecg-boot-module-system/src/main/java/org/jeecg/config/Swagger2Config.java
  83. 62 0
      jeecg-boot-module-system/src/main/java/org/jeecg/config/WebMvcConfiguration.java
  84. 164 0
      jeecg-boot-module-system/src/main/java/org/jeecg/config/mybatis/MybatisInterceptor.java
  85. 113 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/AdCoverController.java
  86. 251 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/AdvertiserController.java
  87. 128 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/AuthController.java
  88. 244 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/CTopOauthTokenController.java
  89. 244 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/CTopToutiaoAdvertisePlanController.java
  90. 244 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/CTopToutiaoAdvertiserController.java
  91. 244 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/CTopToutiaoCampaignController.java
  92. 49 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/CallbackController.java
  93. 244 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/CtopToutiaoAdvertiserBudgetController.java
  94. 244 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/CtopToutiaoBudgetTemplateController.java
  95. 75 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/GraphqlController.java
  96. 253 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/KuaishouAdvertiserController.java
  97. 251 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/KuaishouAppAccountController.java
  98. 63 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/SyncDataController.java
  99. 205 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/TouTiaoAdvertiserController.java
  100. 0 0
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/ToutiaoCreativeController.java

+ 9 - 0
.idea/adsp-boot.iml

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

+ 36 - 0
.idea/inspectionProfiles/Project_Default.xml

@@ -0,0 +1,36 @@
+<component name="InspectionProjectProfileManager">
+  <profile version="1.0">
+    <option name="myName" value="Project Default" />
+    <inspection_tool class="JavaDoc" enabled="true" level="WARNING" enabled_by_default="true">
+      <option name="TOP_LEVEL_CLASS_OPTIONS">
+        <value>
+          <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
+          <option name="REQUIRED_TAGS" value="" />
+        </value>
+      </option>
+      <option name="INNER_CLASS_OPTIONS">
+        <value>
+          <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
+          <option name="REQUIRED_TAGS" value="" />
+        </value>
+      </option>
+      <option name="METHOD_OPTIONS">
+        <value>
+          <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
+          <option name="REQUIRED_TAGS" value="@return@param@throws or @exception" />
+        </value>
+      </option>
+      <option name="FIELD_OPTIONS">
+        <value>
+          <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
+          <option name="REQUIRED_TAGS" value="" />
+        </value>
+      </option>
+      <option name="IGNORE_DEPRECATED" value="false" />
+      <option name="IGNORE_JAVADOC_PERIOD" value="true" />
+      <option name="IGNORE_DUPLICATED_THROWS" value="false" />
+      <option name="IGNORE_POINT_TO_ITSELF" value="false" />
+      <option name="myAdditionalJavadocTags" value="date" />
+    </inspection_tool>
+  </profile>
+</component>

+ 6 - 0
.idea/misc.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="JavaScriptSettings">
+    <option name="languageLevel" value="ES6" />
+  </component>
+</project>

+ 8 - 0
.idea/modules.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/.idea/adsp-boot.iml" filepath="$PROJECT_DIR$/.idea/adsp-boot.iml" />
+    </modules>
+  </component>
+</project>

+ 6 - 0
.idea/vcs.xml

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

+ 21 - 0
LICENSE

@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2019 jeecg-boot
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

+ 245 - 27
README.md

@@ -1,39 +1,257 @@
-# 广告平台后端
+Jeecg-Boot 快速开发平台
+===============
 
-#### 介绍
-{**以下是码云平台说明,您可以替换此简介**
-码云是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN)。专为开发者提供稳定、高效、安全的云端软件开发协作平台
-无论是个人、团队、或是企业,都能够用码云实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)}
+当前最新版本: 2.0.2(发布日期:20190708)
 
-#### 软件架构
-软件架构说明
 
+## 后端技术架构
+- 基础框架:Spring Boot 2.1.3.RELEASE
 
-#### 安装教程
+- 持久层框架:Mybatis-plus_3.1.2
 
-1. xxxx
-2. xxxx
-3. xxxx
+- 安全框架:Apache Shiro 1.4.0,Jwt_3.7.0
 
-#### 使用说明
+- 数据库连接池:阿里巴巴Druid 1.1.10
 
-1. xxxx
-2. xxxx
-3. xxxx
+- 缓存框架:redis
 
-#### 参与贡献
+- 日志打印:logback
 
-1. Fork 本仓库
-2. 新建 Feat_xxx 分支
-3. 提交代码
-4. 新建 Pull Request
+- 其他:fastjson,poi,Swagger-ui,quartz, lombok(简化代码)等。
 
 
-#### 码云特技
 
-1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md
-2. 码云官方博客 [blog.gitee.com](https://blog.gitee.com)
-3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解码云上的优秀开源项目
-4. [GVP](https://gitee.com/gvp) 全称是码云最有价值开源项目,是码云综合评定出的优秀开源项目
-5. 码云官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
-6. 码云封面人物是一档用来展示码云会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
+## 开发环境
+
+- 语言:Java 8
+
+- IDE(JAVA): Eclipse安装lombok插件 或者 IDEA
+
+- 依赖管理:Maven
+
+- 数据库:MySQL5.0  &  Oracle 11g
+
+- 缓存:Redis
+
+ 
+## 开发文档
+
+- 查询过滤器用法
+
+```
+QueryWrapper<?> queryWrapper = QueryGenerator.initQueryWrapper(?, req.getParameterMap());
+```
+
+代码示例:
+
+```
+
+	@GetMapping(value = "/list")
+	public Result<IPage<JeecgDemo>> list(JeecgDemo jeecgDemo, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, 
+	                                     @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
+			HttpServletRequest req) {
+		Result<IPage<JeecgDemo>> result = new Result<IPage<JeecgDemo>>();
+		
+		//调用QueryGenerator的initQueryWrapper
+		QueryWrapper<JeecgDemo> queryWrapper = QueryGenerator.initQueryWrapper(jeecgDemo, req.getParameterMap());
+		
+		Page<JeecgDemo> page = new Page<JeecgDemo>(pageNo, pageSize);
+		IPage<JeecgDemo> pageList = jeecgDemoService.page(page, queryWrapper);
+		result.setSuccess(true);
+		result.setResult(pageList);
+		return result;
+	}
+
+```
+
+
+
+- 查询规则 (本规则不适用于高级查询,高级查询有自己对应的查询类型可以选择 )
+
+| 查询模式           | 用法    | 说明                         |
+|---------- |-------------------------------------------------------|------------------|
+| 模糊查询     | 支持左右模糊和全模糊  需要在查询输入框内前或后带\*或是前后全部带\* |    |
+| 取非查询     | 在查询输入框前面输入! 则查询该字段不等于输入值的数据(数值类型不支持此种查询,可以将数值字段定义为字符串类型的) |    |
+| \>  \>= < <=     | 同取非查询 在输入框前面输入对应特殊字符即表示走对应规则查询 |    |
+| in查询     | 若传入的数据带,(逗号) 则表示该查询为in查询 |    |
+| 多选字段模糊查询     | 上述4 有一个特例,若某一查询字段前后都带逗号 则会将其视为走这种查询方式 ,该查询方式是将查询条件以逗号分割再遍历数组 将每个元素作like查询 用or拼接,例如 现在name传入值 ,a,b,c, 那么结果sql就是 name like '%a%' or name like '%b%' or name like '%c%' |    |
+
+
+- Autopoi使用文档(EXCEL工具类 -  EasyPOI衍变升级重构版本)
+ 
+  [在线文档](https://github.com/zhangdaiscott/autopoi)
+  
+
+
+
+- **代码生成器**
+
+** 功能说明**:   一键生成的代码(包括:controller、service、dao、mapper、entity、vue)
+ 
+ **模板位置**: src/main/resources/jeecg/code-template  
+
+**使用方法**: 
+ 
+ 【**一对一模板**】  
+  
+**1.**先找到**jeecg-boot/src/resources/jeecg**下的  
+**jeecg_config.properties**和**jeecg_database.properties**两个文件。  
+**jeecg_config.properties:** 用来配置文件生成的路径,  
+    
+**jeecg_database.properties:** 用来配置数据库相关配置.  
+         
+         
+**2.**配置好这些配置之后,我们需要找到**jeecg-boot/src/main/java/org/jeecg/JeecgOneGUI.java**类,也就是启动一对一代码生成器的入口;
+  
+    
+**3.**右键运行该类,紧接着会弹出一个窗口,如下图:  
+        ![](https://static.oschina.net/uploads/img/201904/14222638_Svth.png)  
+          
+          
+**4.**然后根据窗口左侧的提示,在右侧填写对应的信息即可.
+     
+ 【**一对多模板**】  
+   
+   
+**1.**先找到**jeecg-boot/src/resources/jeecg**下的
+    
+**jeecg_config.properties**和**jeecg_database.properties**两个文件。  
+  
+**jeecg_config.properties:** 是配置文件生成路径的,  
+  
+  
+**jeecg_database.properties:** 是配置数据库相关配置的文件。  
+       
+       
+**2.**接着我们需要找到**jeecg-boot/src/main/java/org/jeecg/JeecgOneToMainUtil.java**这个类。
+     该类是生成一对多模板的启动入口。  
+       
+       
+**3.**该类中需要三个步骤来配置一对多表的信息。  
+  
+    
+  (1) 第一步: 配置主表信息,代码如下:
+  
+```
+		//第一步:设置主表配置
+		MainTableVo mainTable = new MainTableVo();
+		mainTable.setTableName("jeecg_order_main");//表名
+		mainTable.setEntityName("TestOrderMain");	 //实体名
+		mainTable.setEntityPackage("test2");	 //包名
+		mainTable.setFtlDescription("订单");	 //描述
+		
+```
+  (2) 第二步: 配置子表信息,**有多个则配置多个**, 代码如下: 
+     
+  ①比如: 配置子表 1:
+  
+  ```
+		//第二步:设置子表集合配置
+		List<SubTableVo> subTables = new ArrayList<SubTableVo>();
+		//[1].子表一
+		SubTableVo po = new SubTableVo();
+		po.setTableName("jeecg_order_customer");//表名
+		po.setEntityName("TestOrderCustom");	    //实体名
+		po.setEntityPackage("test2");	        //包名
+		po.setFtlDescription("客户明细");       //描述
+		//子表外键参数配置
+		/*说明: 
+		 * a) 子表引用主表主键ID作为外键,外键字段必须以_ID结尾;
+		 * b) 主表和子表的外键字段名字,必须相同(除主键ID外);
+		 * c) 多个外键字段,采用逗号分隔;
+		*/
+		po.setForeignKeys(new String[]{"order_id"});
+		subTables.add(po);
+  ```
+  ②比如: 配置子表 2:  
+  
+```
+		//[2].子表二
+		SubTableVo po2 = new SubTableVo();
+		po2.setTableName("jeecg_order_ticket");		//表名
+		po2.setEntityName("TestOrderTicket");			//实体名
+		po2.setEntityPackage("test2"); 				//包名
+		po2.setFtlDescription("产品明细");			//描述
+		//子表外键参数配置
+		/*说明: 
+		 * a) 子表引用主表主键ID作为外键,外键字段必须以_ID结尾;
+		 * b) 主表和子表的外键字段名字,必须相同(除主键ID外);
+		 * c) 多个外键字段,采用逗号分隔;
+		*/
+		po2.setForeignKeys(new String[]{"order_id"});
+		subTables.add(po2);  
+  ```
+  ③将整合了子表VO的subTables添加到主表对象当中去: 
+
+```
+  mainTable.setSubTables(subTables);
+  ```
+  ④需要注意如下代码,该代码的作用是,为子表设置主外键关联,当添加数据时,  
+主表的主键将会添加到子表的"order_id"中:  
+  
+```
+  		po2.setForeignKeys(new String[]{"order_id"});
+  ```
+    
+  (3) 第三步: 启动(run)程序,生成代码, 代码如下:
+  
+  ```
+  		//第三步:一对多(父子表)数据模型,代码生成
+		new CodeGenerateOneToMany(mainTable,subTables).generateCodeFile();
+  ```
+ 
+[在线文档](https://github.com/zhangdaiscott/autopoi)  
+  
+
+- **编码排重使用示例**   
+
+重复校验效果:
+![输入图片说明](https://static.oschina.net/uploads/img/201904/19191836_eGkQ.png "在这里输入图片标题")
+
+1.引入排重接口,代码如下:  
+ 
+```
+import { duplicateCheck } from '@/api/api'
+  ```
+2.找到编码必填校验规则的前端代码,代码如下:  
+  
+```
+<a-input placeholder="请输入编码" v-decorator="['code', validatorRules.code ]"/>
+
+code: {
+            rules: [
+              { required: true, message: '请输入编码!' },
+              {validator: this.validateCode}
+            ]
+          },
+  ```
+3.找到rules里validator对应的方法在哪里,然后使用第一步中引入的排重校验接口.  
+  以用户online表单编码为示例,其中四个必传的参数有:  
+    
+```
+  {tableName:表名,fieldName:字段名,fieldVal:字段值,dataId:表的主键},
+  ```
+ 具体使用代码如下:  
+ 
+```
+    validateCode(rule, value, callback){
+        let pattern = /^[a-z|A-Z][a-z|A-Z|\d|_|-]{0,}$/;
+        if(!pattern.test(value)){
+          callback('编码必须以字母开头,可包含数字、下划线、横杠');
+        } else {
+          var params = {
+            tableName: "onl_cgreport_head",
+            fieldName: "code",
+            fieldVal: value,
+            dataId: this.model.id
+          };
+          duplicateCheck(params).then((res)=>{
+            if(res.success){
+             callback();
+            }else{
+              callback(res.message);
+            }
+          })
+        }
+      },
+```

Разница между файлами не показана из-за своего большого размера
+ 2501 - 0
db/jeecg-boot-mysql-20190705.sql


Разница между файлами не показана из-за своего большого размера
+ 2471 - 0
db/jeecg-boot-mysql.sql


Разница между файлами не показана из-за своего большого размера
+ 3852 - 0
db/jeecg-boot-oracle_11g.sql


Разница между файлами не показана из-за своего большого размера
+ 10239 - 0
db/jeecg-boot-sqlserver_2008.sql


Разница между файлами не показана из-за своего большого размера
+ 61 - 0
db/增量升级SQL——mysql/jeecgboot2.0.1到2.0.2增量升级SQL


+ 1 - 0
jeecg-boot-base-common/.gitignore

@@ -0,0 +1 @@
+/target/

+ 234 - 0
jeecg-boot-base-common/jeecg-boot-base-common.iml

@@ -0,0 +1,234 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
+  <component name="FacetManager">
+    <facet type="Spring" name="Spring">
+      <configuration />
+    </facet>
+    <facet type="web" name="Web">
+      <configuration>
+        <webroots />
+      </configuration>
+    </facet>
+  </component>
+  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
+    <output url="file://$MODULE_DIR$/target/classes" />
+    <output-test url="file://$MODULE_DIR$/target/test-classes" />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
+      <excludeFolder url="file://$MODULE_DIR$/target" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-web:2.1.3.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.1.3.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.1.3.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.1.3.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.2.3" level="project" />
+    <orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.2.3" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-to-slf4j:2.11.2" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.11.2" level="project" />
+    <orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.25" level="project" />
+    <orderEntry type="library" name="Maven: javax.annotation:javax.annotation-api:1.3.2" level="project" />
+    <orderEntry type="library" scope="RUNTIME" name="Maven: org.yaml:snakeyaml:1.23" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-json:2.1.3.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.9.8" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml.jackson.module:jackson-module-parameter-names:2.9.8" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-tomcat:2.1.3.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-core:9.0.16" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-el:9.0.16" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-websocket:9.0.16" level="project" />
+    <orderEntry type="library" name="Maven: org.hibernate.validator:hibernate-validator:6.0.14.Final" level="project" />
+    <orderEntry type="library" name="Maven: javax.validation:validation-api:2.0.1.Final" level="project" />
+    <orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.3.2.Final" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-web:5.1.5.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-beans:5.1.5.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-webmvc:5.1.5.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-context:5.1.5.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-expression:5.1.5.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-mail:2.1.3.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-context-support:5.1.5.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: com.sun.mail:javax.mail:1.6.2" level="project" />
+    <orderEntry type="library" name="Maven: javax.activation:activation:1.1" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-starter-test:2.1.3.RELEASE" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-test:2.1.3.RELEASE" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-test-autoconfigure:2.1.3.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: com.jayway.jsonpath:json-path:2.4.0" level="project" />
+    <orderEntry type="library" name="Maven: net.minidev:json-smart:2.3" level="project" />
+    <orderEntry type="library" name="Maven: net.minidev:accessors-smart:1.2" level="project" />
+    <orderEntry type="library" name="Maven: org.ow2.asm:asm:5.0.4" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
+    <orderEntry type="library" name="Maven: org.assertj:assertj-core:3.11.1" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.mockito:mockito-core:2.23.4" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: net.bytebuddy:byte-buddy-agent:1.9.10" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.objenesis:objenesis:2.6" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-library:1.3" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.skyscreamer:jsonassert:1.5.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: com.vaadin.external.google:android-json:0.0.20131108.vaadin1" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-core:5.1.5.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.1.5.RELEASE" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.springframework:spring-test:5.1.5.RELEASE" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.xmlunit:xmlunit-core:2.6.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-aop:2.1.3.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-aop:5.1.5.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.aspectj:aspectjweaver:1.9.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-actuator:2.1.3.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-actuator-autoconfigure:2.1.3.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-actuator:2.1.3.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: io.micrometer:micrometer-core:1.1.3" level="project" />
+    <orderEntry type="library" name="Maven: org.hdrhistogram:HdrHistogram:2.1.9" level="project" />
+    <orderEntry type="library" name="Maven: org.latencyutils:LatencyUtils:2.0.3" level="project" />
+    <orderEntry type="library" name="Maven: commons-io:commons-io:2.6" level="project" />
+    <orderEntry type="library" name="Maven: commons-lang:commons-lang:2.6" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-freemarker:2.1.3.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.freemarker:freemarker:2.3.28" level="project" />
+    <orderEntry type="library" name="Maven: org.projectlombok:lombok:1.18.6" level="project" />
+    <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-boot-starter:3.0.6" level="project" />
+    <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus:3.0.6" level="project" />
+    <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-extension:3.0.6" level="project" />
+    <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-core:3.0.6" level="project" />
+    <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-annotation:3.0.6" level="project" />
+    <orderEntry type="library" name="Maven: com.github.jsqlparser:jsqlparser:1.2" level="project" />
+    <orderEntry type="library" name="Maven: org.mybatis:mybatis-spring:1.3.2" level="project" />
+    <orderEntry type="library" name="Maven: org.mybatis:mybatis:3.4.6" level="project" />
+    <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-generator:3.0.6" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.1.3.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:2.1.3.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: com.zaxxer:HikariCP:3.2.0" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-jdbc:5.1.5.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-configuration-processor:2.1.3.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba:druid-spring-boot-starter:1.1.10" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba:druid:1.1.10" level="project" />
+    <orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.25" level="project" />
+    <orderEntry type="library" name="Maven: com.baomidou:dynamic-datasource-spring-boot-starter:2.5.4" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba:fastjson:1.2.56" level="project" />
+    <orderEntry type="library" scope="RUNTIME" name="Maven: mysql:mysql-connector-java:5.1.47" level="project" />
+    <orderEntry type="library" scope="RUNTIME" name="Maven: net.sourceforge.jtds:jtds:1.3.1" level="project" />
+    <orderEntry type="library" scope="RUNTIME" name="Maven: com.microsoft.sqlserver:mssql-jdbc:7.2.1.jre8" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-quartz:2.1.3.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-tx:5.1.5.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.quartz-scheduler:quartz:2.3.0" level="project" />
+    <orderEntry type="library" name="Maven: com.mchange:mchange-commons-java:0.2.11" level="project" />
+    <orderEntry type="library" name="Maven: com.auth0:java-jwt:3.7.0" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.9.8" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.9.0" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.shiro:shiro-spring-boot-starter:1.4.0" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.shiro:shiro-spring:1.4.0" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.shiro:shiro-core:1.4.0" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.shiro:shiro-lang:1.4.0" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.shiro:shiro-cache:1.4.0" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.shiro:shiro-crypto-hash:1.4.0" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.shiro:shiro-crypto-core:1.4.0" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.shiro:shiro-crypto-cipher:1.4.0" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.shiro:shiro-config-core:1.4.0" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.shiro:shiro-config-ogdl:1.4.0" level="project" />
+    <orderEntry type="library" name="Maven: commons-beanutils:commons-beanutils:1.9.3" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.shiro:shiro-event:1.4.0" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.shiro:shiro-web:1.4.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-swagger2:2.9.2" level="project" />
+    <orderEntry type="library" name="Maven: io.swagger:swagger-annotations:1.5.20" level="project" />
+    <orderEntry type="library" name="Maven: io.swagger:swagger-models:1.5.20" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-spi:2.9.2" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-core:2.9.2" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-schema:2.9.2" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-swagger-common:2.9.2" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-spring-web:2.9.2" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml:classmate:1.4.0" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-core:1.2.0.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-metadata:1.2.0.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.mapstruct:mapstruct:1.2.0.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-swagger-ui:2.9.2" level="project" />
+    <orderEntry type="library" name="Maven: com.github.xiaoymin:swagger-bootstrap-ui:1.9.3" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-bean-validators:2.9.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-data-redis:2.1.3.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.data:spring-data-redis:2.1.5.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.data:spring-data-keyvalue:2.1.5.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.data:spring-data-commons:2.1.5.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-oxm:5.1.5.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: io.lettuce:lettuce-core:5.1.4.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-common:4.1.33.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-handler:4.1.33.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-buffer:4.1.33.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-codec:4.1.33.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-transport:4.1.33.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-resolver:4.1.33.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.projectreactor:reactor-core:3.2.6.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.commons:commons-pool2:2.6.1" level="project" />
+    <orderEntry type="library" name="Maven: org.jeecgframework.boot:codegenerate:1.0.5" level="project" />
+    <orderEntry type="library" name="Maven: org.jeecgframework:autopoi-web:1.0.3" level="project" />
+    <orderEntry type="library" name="Maven: org.jeecgframework:autopoi:1.0.3" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.poi:poi:3.9" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml:3.9" level="project" />
+    <orderEntry type="library" name="Maven: dom4j:dom4j:1.6.1" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml-schemas:3.9" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.xmlbeans:xmlbeans:2.3.0" level="project" />
+    <orderEntry type="library" name="Maven: stax:stax-api:1.0.1" level="project" />
+    <orderEntry type="library" name="Maven: xerces:xercesImpl:2.9.1" level="project" />
+    <orderEntry type="library" name="Maven: xml-apis:xml-apis:1.4.01" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.poi:poi-scratchpad:3.9" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpclient:4.5.9" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpcore:4.4" level="project" />
+    <orderEntry type="library" name="Maven: com.squareup.retrofit2:retrofit:2.6.0" level="project" />
+    <orderEntry type="library" name="Maven: com.squareup.okhttp3:okhttp:3.12.0" level="project" />
+    <orderEntry type="library" name="Maven: com.graphql-java:graphql-java:13.0" level="project" />
+    <orderEntry type="library" name="Maven: org.antlr:antlr4-runtime:4.7.2" level="project" />
+    <orderEntry type="library" name="Maven: com.graphql-java:java-dataloader:2.1.1" level="project" />
+    <orderEntry type="library" name="Maven: org.reactivestreams:reactive-streams:1.0.2" level="project" />
+    <orderEntry type="library" name="Maven: org.mountcloud:graphql-client:1.2" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.9.8" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.9.8" level="project" />
+    <orderEntry type="library" name="Maven: com.google.code.gson:gson:2.8.5" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.pdfbox:fontbox:2.0.15" level="project" />
+    <orderEntry type="library" name="Maven: commons-logging:commons-logging:1.2" level="project" />
+    <orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-java:3.14.0" level="project" />
+    <orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-api:3.14.0" level="project" />
+    <orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-chrome-driver:3.14.0" level="project" />
+    <orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-edge-driver:3.14.0" level="project" />
+    <orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-firefox-driver:3.14.0" level="project" />
+    <orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-ie-driver:3.14.0" level="project" />
+    <orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-opera-driver:3.14.0" level="project" />
+    <orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-remote-driver:3.14.0" level="project" />
+    <orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-safari-driver:3.14.0" level="project" />
+    <orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-support:3.14.0" level="project" />
+    <orderEntry type="library" name="Maven: net.bytebuddy:byte-buddy:1.9.10" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.commons:commons-exec:1.3" level="project" />
+    <orderEntry type="library" name="Maven: com.squareup.okio:okio:1.14.1" level="project" />
+    <orderEntry type="library" name="Maven: org.json:json:20180813" level="project" />
+    <orderEntry type="library" name="Maven: com.google.guava:guava:25.0-jre" level="project" />
+    <orderEntry type="library" name="Maven: com.google.code.findbugs:jsr305:1.3.9" level="project" />
+    <orderEntry type="library" name="Maven: org.checkerframework:checker-compat-qual:2.0.0" level="project" />
+    <orderEntry type="library" name="Maven: com.google.errorprone:error_prone_annotations:2.1.3" level="project" />
+    <orderEntry type="library" name="Maven: com.google.j2objc:j2objc-annotations:1.1" level="project" />
+    <orderEntry type="library" name="Maven: org.codehaus.mojo:animal-sniffer-annotations:1.14" level="project" />
+    <orderEntry type="library" name="Maven: us.codecraft:webmagic-core:0.7.3" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.8.1" level="project" />
+    <orderEntry type="library" name="Maven: us.codecraft:xsoup:0.3.1" level="project" />
+    <orderEntry type="library" name="Maven: org.slf4j:slf4j-log4j12:1.7.25" level="project" />
+    <orderEntry type="library" name="Maven: log4j:log4j:1.2.17" level="project" />
+    <orderEntry type="library" name="Maven: commons-collections:commons-collections:3.2.2" level="project" />
+    <orderEntry type="library" name="Maven: org.jsoup:jsoup:1.10.3" level="project" />
+    <orderEntry type="library" name="Maven: us.codecraft:webmagic-extension:0.7.3" level="project" />
+    <orderEntry type="library" name="Maven: redis.clients:jedis:2.9.1" level="project" />
+    <orderEntry type="library" name="Maven: net.sourceforge.htmlunit:htmlunit:2.35.0" level="project" />
+    <orderEntry type="library" name="Maven: xalan:xalan:2.7.2" level="project" />
+    <orderEntry type="library" name="Maven: xalan:serializer:2.7.2" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.commons:commons-text:1.6" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpmime:4.5.7" level="project" />
+    <orderEntry type="library" name="Maven: net.sourceforge.htmlunit:htmlunit-core-js:2.35.0" level="project" />
+    <orderEntry type="library" name="Maven: net.sourceforge.htmlunit:neko-htmlunit:2.35.0" level="project" />
+    <orderEntry type="library" name="Maven: net.sourceforge.htmlunit:htmlunit-cssparser:1.4.0" level="project" />
+    <orderEntry type="library" name="Maven: commons-net:commons-net:3.6" level="project" />
+    <orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-client:9.4.14.v20181114" level="project" />
+    <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-client:9.4.14.v20181114" level="project" />
+    <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-http:9.4.14.v20181114" level="project" />
+    <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-xml:9.4.14.v20181114" level="project" />
+    <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-util:9.4.14.v20181114" level="project" />
+    <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-io:9.4.14.v20181114" level="project" />
+    <orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-common:9.4.14.v20181114" level="project" />
+    <orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-api:9.4.14.v20181114" level="project" />
+    <orderEntry type="library" name="Maven: commons-codec:commons-codec:1.11" level="project" />
+    <orderEntry type="library" name="Maven: cn.hutool:hutool-all:4.5.11" level="project" />
+    <orderEntry type="library" name="Maven: com.aliyun:aliyun-java-sdk-dysmsapi:1.0.0" level="project" />
+    <orderEntry type="library" name="Maven: com.aliyun:aliyun-java-sdk-core:3.2.3" level="project" />
+  </component>
+</module>

+ 32 - 0
jeecg-boot-base-common/pom.xml

@@ -0,0 +1,32 @@
+<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>
+    <artifactId>jeecg-boot-base-common</artifactId>
+    <version>2.0.2</version>
+    <parent>
+        <groupId>org.jeecgframework.boot</groupId>
+        <artifactId>jeecg-boot-parent</artifactId>
+        <version>2.0.2</version>
+    </parent>
+
+    <repositories>
+        <repository>
+            <id>aliyun</id>
+            <name>aliyun Repository</name>
+            <url>http://maven.aliyun.com/nexus/content/groups/public</url>
+            <snapshots>
+                <enabled>false</enabled>
+            </snapshots>
+        </repository>
+        <repository>
+            <id>jeecg</id>
+            <name>jeecg Repository</name>
+            <url>http://maven.jeecg.org/nexus/content/repositories/jeecg</url>
+            <snapshots>
+                <enabled>false</enabled>
+            </snapshots>
+        </repository>
+    </repositories>
+
+</project>

+ 111 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/api/vo/Result.java

@@ -0,0 +1,111 @@
+package org.jeecg.common.api.vo;
+
+import java.io.Serializable;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.jeecg.common.constant.CommonConstant;
+
+import lombok.Data;
+
+/**
+ *   接口返回数据格式
+ * @author scott
+ * @email jeecgos@163.com
+ * @date  2019年1月19日
+ */
+@Data
+@ApiModel(value="接口返回对象", description="接口返回对象")
+public class Result<T> implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * 成功标志
+	 */
+	@ApiModelProperty(value = "成功标志")
+	private boolean success = true;
+
+	/**
+	 * 返回处理消息
+	 */
+	@ApiModelProperty(value = "返回处理消息")
+	private String message = "操作成功!";
+
+	/**
+	 * 返回代码
+	 */
+	@ApiModelProperty(value = "返回代码")
+	private Integer code = 0;
+	
+	/**
+	 * 返回数据对象 data
+	 */
+	@ApiModelProperty(value = "返回数据对象")
+	private T result;
+
+	/**
+	 * 时间戳
+	 */
+	@ApiModelProperty(value = "时间戳")
+	private long timestamp = System.currentTimeMillis();
+	public Result() {
+		
+	}
+	
+	public Result<T> error500(String message) {
+		this.message = message;
+		this.code = CommonConstant.SC_INTERNAL_SERVER_ERROR_500;
+		this.success = false;
+		return this;
+	}
+	
+	public Result<T> success(String message) {
+		this.message = message;
+		this.code = CommonConstant.SC_OK_200;
+		this.success = true;
+		return this;
+	}
+	
+	public static Result<Object> ok() {
+		Result<Object> r = new Result<Object>();
+		r.setSuccess(true);
+		r.setCode(CommonConstant.SC_OK_200);
+		r.setMessage("成功");
+		return r;
+	}
+	
+	public static Result<Object> ok(String msg) {
+		Result<Object> r = new Result<Object>();
+		r.setSuccess(true);
+		r.setCode(CommonConstant.SC_OK_200);
+		r.setMessage(msg);
+		return r;
+	}
+	
+	public static Result<Object> ok(Object data) {
+		Result<Object> r = new Result<Object>();
+		r.setSuccess(true);
+		r.setCode(CommonConstant.SC_OK_200);
+		r.setResult(data);
+		return r;
+	}
+	
+	public static Result<Object> error(String msg) {
+		return error(CommonConstant.SC_INTERNAL_SERVER_ERROR_500, msg);
+	}
+	
+	public static Result<Object> error(int code, String msg) {
+		Result<Object> r = new Result<Object>();
+		r.setCode(code);
+		r.setMessage(msg);
+		r.setSuccess(false);
+		return r;
+	}
+	
+	/**
+	 * 无权限访问返回结果
+	 */
+	public static Result<Object> noauth(String msg) {
+		return error(CommonConstant.SC_JEECG_NO_AUTHZ, msg);
+	}
+}

+ 36 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/aspect/annotation/AutoLog.java

@@ -0,0 +1,36 @@
+package org.jeecg.common.aspect.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.jeecg.common.constant.CommonConstant;
+
+/**
+ * 系统日志注解
+ * 
+ * @Author scott
+ * @email jeecgos@163.com
+ * @Date 2019年1月14日
+ */
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface AutoLog {
+
+	/**
+	 * 日志内容
+	 * 
+	 * @return
+	 */
+	String value() default "";
+
+	/**
+	 * 日志类型
+	 * 
+	 * @return 0:操作日志;1:登录日志;2:定时任务;
+	 */
+	int logType() default CommonConstant.LOG_TYPE_2;
+}

+ 42 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/aspect/annotation/Dict.java

@@ -0,0 +1,42 @@
+package org.jeecg.common.aspect.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ *  类描述:  字典注解
+ * 作    者: dangzhenghui
+ * 日    期: 2019年03月17日-下午9:37:16
+ */
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Dict {
+    /**
+     * 方法描述:  数据code
+     * 作    者: dangzhenghui
+     * 日    期: 2019年03月17日-下午9:37:16
+     *
+     * @return 返回类型: String
+     */
+    String dicCode();
+
+    /**
+     * 方法描述:  数据Text
+     * 作    者: dangzhenghui
+     * 日    期: 2019年03月17日-下午9:37:16
+     *
+     * @return 返回类型: String
+     */
+    String dicText() default "";
+
+    /**
+     * 方法描述: 数据字典表
+     * 作    者: dangzhenghui
+     * 日    期: 2019年03月17日-下午9:37:16
+     *
+     * @return 返回类型: String
+     */
+    String dictTable() default "";
+}

+ 29 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/aspect/annotation/PermissionData.java

@@ -0,0 +1,29 @@
+package org.jeecg.common.aspect.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+  *  数据权限注解
+ * @Author taoyan
+ * @Date 2019年4月11日
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE,ElementType.METHOD})
+@Documented
+public @interface PermissionData {
+	/**
+	 * 暂时没用
+	 * @return
+	 */
+	String value() default "";
+	
+	
+	/**
+	 * 配置菜单的组件路径,用于数据权限
+	 */
+	String pageComponent() default "";
+}

+ 26 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/constant/CacheConstant.java

@@ -0,0 +1,26 @@
+package org.jeecg.common.constant;
+
+/**
+ * @author: huangxutao
+ * @date: 2019-06-14
+ * @description: 缓存常量
+ */
+public interface CacheConstant {
+
+	/**
+	 * 字典信息缓存
+	 */
+    public static final String DICT_CACHE = "dictCache";
+
+	/**
+	 * 权限信息缓存
+	 */
+    public static final String PERMISSION_CACHE = "permission";
+
+	/**
+	 * 登录用户规则缓存
+	 */
+    public static final String LOGIN_USER_RULES_CACHE = "loginUser_cacheRules";
+
+
+}

+ 129 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/constant/CommonConstant.java

@@ -0,0 +1,129 @@
+package org.jeecg.common.constant;
+
+public interface CommonConstant {
+
+	/**
+	 * 正常状态
+	 */
+
+	public static final Integer STATUS_NORMAL = 0;
+
+
+	/**
+	 * 禁用状态
+	 */
+
+	public static final Integer STATUS_DISABLE = -1;
+
+
+	/**
+	 * 删除标志
+	 */
+	public static final Integer DEL_FLAG_1 = 1;
+
+	/**
+	 * 未删除
+	 */
+
+	public static final Integer DEL_FLAG_0 = 0;
+
+	/**
+	 * 系统日志类型: 登录
+	 */
+	public static final int LOG_TYPE_1 = 1;
+
+	/**
+	 * 系统日志类型: 操作
+	 */
+	public static final int LOG_TYPE_2 = 2;
+	
+	
+	/** {@code 500 Server Error} (HTTP/1.0 - RFC 1945) */
+    public static final Integer SC_INTERNAL_SERVER_ERROR_500 = 500;
+    /** {@code 200 OK} (HTTP/1.0 - RFC 1945) */
+    public static final Integer SC_OK_200 = 200;
+    
+    /**访问权限认证未通过 510*/
+    public static final Integer SC_JEECG_NO_AUTHZ=510;
+
+    /** 登录用户拥有角色缓存KEY前缀 */
+    public static String LOGIN_USER_CACHERULES_ROLE = "loginUser_cacheRules::Roles_";
+    /** 登录用户拥有权限缓存KEY前缀 */
+    public static String LOGIN_USER_CACHERULES_PERMISSION  = "loginUser_cacheRules::Permissions_";
+    /** 登录用户令牌缓存KEY前缀 */
+
+    public static final int  TOKEN_EXPIRE_TIME  = 3600; //3600秒即是一小时
+    
+    public static final String PREFIX_USER_TOKEN  = "PREFIX_USER_TOKEN_";
+    
+    /**
+     *  0:一级菜单
+     */
+    public static final Integer MENU_TYPE_0  = 0;
+   /**
+    *  1:子菜单 
+    */
+    public static final Integer MENU_TYPE_1  = 1;
+    /**
+     *  2:按钮权限
+     */
+    public static final Integer MENU_TYPE_2  = 2;
+    
+    /**通告对象类型(USER:指定用户,ALL:全体用户)*/
+    public static final String MSG_TYPE_UESR  = "USER";
+    public static final String MSG_TYPE_ALL  = "ALL";
+    
+    /**发布状态(0未发布,1已发布,2已撤销)*/
+    public static final String NO_SEND  = "0";
+    public static final String HAS_SEND  = "1";
+    public static final String HAS_CANCLE  = "2";
+    
+    /**阅读状态(0未读,1已读)*/
+    public static final String HAS_READ_FLAG  = "1";
+    public static final String NO_READ_FLAG  = "0";
+    
+    /**优先级(L低,M中,H高)*/
+    public static final String PRIORITY_L  = "L";
+    public static final String PRIORITY_M  = "M";
+    public static final String PRIORITY_H  = "H";
+    
+    /**
+     * 短信模板方式  0 .登录模板、1.注册模板、2.忘记密码模板
+     */
+    public static final String SMS_TPL_TYPE_0  = "0";
+    public static final String SMS_TPL_TYPE_1  = "1";
+    public static final String SMS_TPL_TYPE_2  = "2";
+    
+    /**
+     * 状态(0无效1有效)
+     */
+    public static final String STATUS_0 = "0";
+    public static final String STATUS_1 = "1";
+    
+    /**
+     * 同步工作流引擎1同步0不同步
+     */
+    public static final String ACT_SYNC_0 = "0";
+    public static final String ACT_SYNC_1 = "1";
+    
+    /**
+     * 消息类型1:通知公告2:系统消息
+     */
+    public static final String MSG_CATEGORY_1 = "1";
+    public static final String MSG_CATEGORY_2 = "2";
+    
+    /**
+     * 是否配置菜单的数据权限 1是0否
+     */
+    public static final Integer RULE_FLAG_0 = 0;
+    public static final Integer RULE_FLAG_1 = 1;
+
+    /**
+     * 是否用户已被冻结 1(解冻)正常 2冻结
+     */
+    public static final Integer USER_UNFREEZE = 1;
+    public static final Integer USER_FREEZE = 2;
+    
+    /**字典翻译文本后缀*/
+    public static final String DICT_TEXT_SUFFIX = "_dictText";
+}

+ 14 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/constant/CommonSendStatus.java

@@ -0,0 +1,14 @@
+package org.jeecg.common.constant;
+
+/**
+ * 	系统通告 - 发布状态
+ * @Author LeeShaoQing
+ *
+ */
+public interface CommonSendStatus {
+	public static final String UNPUBLISHED_STATUS_0 = "0";	//未发布
+	
+	public static final String PUBLISHED_STATUS_1 = "1";		//已发布
+	
+	public static final String REVOKE_STATUS_2 = "2";			//撤销
+}

+ 100 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/constant/DataBaseConstant.java

@@ -0,0 +1,100 @@
+package org.jeecg.common.constant;
+/**
+ * 数据库上下文常量
+ */
+public interface DataBaseConstant {
+	
+	//*********系统上下文变量****************************************
+	/**
+	 * 数据-所属机构编码
+	 */
+	public static final String SYS_ORG_CODE = "sysOrgCode";
+	/**
+	 * 数据-所属机构编码
+	 */
+	public static final String SYS_MULTI_ORG_CODE = "sysMultiOrgCode";
+	
+	/**
+	 * 数据-所属机构编码
+	 */
+	public static final String SYS_ORG_CODE_TABLE = "sys_org_code";
+	/**
+	 * 数据-系统用户编码(对应登录用户账号)
+	 */
+	public static final String SYS_USER_CODE = "sysUserCode";
+	/**
+	 * 数据-系统用户编码(对应登录用户账号)
+	 */
+	public static final String SYS_USER_CODE_TABLE = "sys_user_code";
+	
+	/**
+	 * 登录用户真实姓名
+	 */
+	public static final String SYS_USER_NAME = "sysUserName";
+	/**
+	 * 登录用户真实姓名
+	 */
+	public static final String SYS_USER_NAME_TABLE = "sys_user_name";
+	/**
+	 * 系统日期"yyyy-MM-dd"
+	 */
+	public static final String SYS_DATE = "sysDate";
+	/**
+	 * 系统日期"yyyy-MM-dd"
+	 */
+	public static final String SYS_DATE_TABLE = "sys_date";
+	/**
+	 * 系统时间"yyyy-MM-dd HH:mm"
+	 */
+	public static final String SYS_TIME = "sysTime";
+	/**
+	 * 系统时间"yyyy-MM-dd HH:mm"
+	 */
+	public static final String SYS_TIME_TABLE = "sys_time";
+	//*********系统上下文变量****************************************
+	
+	
+	//*********系统建表标准字段****************************************
+	/**
+	 * 创建者登录名称
+	 */
+	public static final String CREATE_BY_TABLE = "create_by";
+	/**
+	 * 创建者登录名称
+	 */
+	public static final String CREATE_BY = "createBy";
+	/**
+	 * 创建日期时间
+	 */
+	public static final String CREATE_TIME_TABLE = "create_time";
+	/**
+	 * 创建日期时间
+	 */
+	public static final String CREATE_TIME = "createTime";
+	/**
+	 * 更新用户登录名称
+	 */
+	public static final String UPDATE_BY_TABLE = "update_by";
+	/**
+	 * 更新用户登录名称
+	 */
+	public static final String UPDATE_BY = "updateBy";
+	/**
+	 * 更新日期时间
+	 */
+	public static final String UPDATE_TIME = "updateTime";
+	/**
+	 * 更新日期时间
+	 */
+	public static final String UPDATE_TIME_TABLE = "update_time";
+	
+	/**
+	 * 业务流程状态
+	 */
+	public static final String BPM_STATUS = "bpmStatus";
+	/**
+	 * 业务流程状态
+	 */
+	public static final String BPM_STATUS_TABLE = "bpm_status";
+	//*********系统建表标准字段****************************************
+}

+ 19 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/exception/JeecgBootException.java

@@ -0,0 +1,19 @@
+package org.jeecg.common.exception;
+
+public class JeecgBootException extends RuntimeException {
+	private static final long serialVersionUID = 1L;
+
+	public JeecgBootException(String message){
+		super(message);
+	}
+	
+	public JeecgBootException(Throwable cause)
+	{
+		super(cause);
+	}
+	
+	public JeecgBootException(String message,Throwable cause)
+	{
+		super(message,cause);
+	}
+}

+ 69 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/exception/JeecgBootExceptionHandler.java

@@ -0,0 +1,69 @@
+package org.jeecg.common.exception;
+
+import org.apache.shiro.authz.AuthorizationException;
+import org.apache.shiro.authz.UnauthorizedException;
+import org.jeecg.common.api.vo.Result;
+import org.springframework.dao.DuplicateKeyException;
+import org.springframework.web.HttpRequestMethodNotSupportedException;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+import org.springframework.web.servlet.NoHandlerFoundException;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 异常处理器
+ * 
+ * @Author scott
+ * @Date 2019
+ */
+@RestControllerAdvice
+@Slf4j
+public class JeecgBootExceptionHandler {
+
+	/**
+	 * 处理自定义异常
+	 */
+	@ExceptionHandler(JeecgBootException.class)
+	public Result<?> handleRRException(JeecgBootException e){
+		log.error(e.getMessage(), e);
+		return Result.error(e.getMessage());
+	}
+
+	@ExceptionHandler(NoHandlerFoundException.class)
+	public Result<?> handlerNoFoundException(Exception e) {
+		log.error(e.getMessage(), e);
+		return Result.error(404, "路径不存在,请检查路径是否正确");
+	}
+
+	@ExceptionHandler(DuplicateKeyException.class)
+	public Result<?> handleDuplicateKeyException(DuplicateKeyException e){
+		log.error(e.getMessage(), e);
+		return Result.error("数据库中已存在该记录");
+	}
+
+	@ExceptionHandler({UnauthorizedException.class, AuthorizationException.class})
+	public Result<?> handleAuthorizationException(AuthorizationException e){
+		log.error(e.getMessage(), e);
+		return Result.noauth("没有权限,请联系管理员授权");
+
+	}
+
+	@ExceptionHandler(Exception.class)
+	public Result<?> handleException(Exception e){
+		log.error(e.getMessage(), e);
+		return Result.error(e.getMessage());
+	}
+	
+	/**
+	 * @Author 政辉
+	 * @param e
+	 * @return
+	 */
+	@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
+	public Result<?> HttpRequestMethodNotSupportedException(Exception e){
+		log.error(e.getMessage(), e);
+		return Result.error("没有权限,请联系管理员授权");
+	}
+
+}

+ 78 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/system/api/ISysBaseAPI.java

@@ -0,0 +1,78 @@
+package org.jeecg.common.system.api;
+
+import java.sql.SQLException;
+import java.util.List;
+
+import org.jeecg.common.system.vo.DictModel;
+import org.jeecg.common.system.vo.LoginUser;
+
+/**
+ * @Description: 底层共通业务API,提供其他独立模块调用
+ * @Author: scott
+ * @Date:2019-4-20 
+ * @Version:V1.0
+ */
+public interface ISysBaseAPI {
+
+	/**
+	 * 日志添加
+	 * @param LogContent 内容
+	 * @param logType 日志类型(0:操作日志;1:登录日志;2:定时任务)
+	 * @param operatetype 操作类型(1:添加;2:修改;3:删除;)
+	 */
+	void addLog(String LogContent, Integer logType, Integer operatetype);
+	
+	/**
+	  * 根据用户账号查询登录用户信息
+	 * @param username
+	 * @return
+	 */
+	public LoginUser getUserByName(String username);
+	
+	/**
+	 * 通过用户账号查询角色集合
+	 * @param username
+	 * @return
+	 */
+	public List<String> getRolesByUsername(String username);
+
+	/**
+	 * 获取当前数据库类型
+	 * @return
+	 * @throws Exception 
+	 */
+	public String getDatabaseType() throws SQLException;
+	
+	/**
+	  * 获取数据字典
+	 * @param code
+	 * @return
+	 */
+	public List<DictModel> queryDictItemsByCode(String code);
+
+	/** 查询所有的父级字典,按照create_time排序 */
+	public List<DictModel> queryAllDict();
+	/**
+	  * 获取表数据字典
+	 * @param table
+	 * @param text
+	 * @param code
+	 * @return
+	 */
+    List<DictModel> queryTableDictItemsByCode(String table, String text, String code);
+    
+    /**
+   	 * 查询所有部门 作为字典信息 id -->value,departName -->text
+   	 * @return
+   	 */
+   	public List<DictModel> queryAllDepartBackDictModel();
+   	
+	/**
+	 * 发送系统消息
+	 * @param fromUser 发送人(用户登录账户)
+	 * @param toUser  发送给(用户登录账户)
+	 * @param title  消息主题
+	 * @param msgContent  消息内容
+	 */
+	public void sendSysAnnouncement(String fromUser,String toUser,String title, String msgContent);
+}

+ 105 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/system/base/controller/JeecgController.java

@@ -0,0 +1,105 @@
+package org.jeecg.common.system.base.controller;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.shiro.SecurityUtils;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.system.base.entity.JeecgEntity;
+import org.jeecg.common.system.base.service.JeecgService;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.common.system.vo.LoginUser;
+import org.jeecgframework.poi.excel.ExcelImportUtil;
+import org.jeecgframework.poi.excel.def.NormalExcelConstants;
+import org.jeecgframework.poi.excel.entity.ExportParams;
+import org.jeecgframework.poi.excel.entity.ImportParams;
+import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
+import org.springframework.web.servlet.ModelAndView;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * @Description: Controller基类
+ * @Author: dangzhenghui@163.com
+ * @Date: 2019-4-21 8:13
+ * @Version: 1.0
+ */
+@Slf4j
+public class JeecgController<T extends JeecgEntity, S extends JeecgService<T>> {
+	@Autowired
+	S service;
+
+	/**
+	 * 导出excel
+	 *
+	 * @param request
+	 * @param response
+	 */
+	protected ModelAndView exportXls(HttpServletRequest request,T object,Class<T> clazz,String title) {
+		//--------------------------------------------------------------------------------
+		//获取当前用户
+		LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal();
+		//--------------------------------------------------------------------------------
+		// Step.1 组装查询条件
+		QueryWrapper<T> queryWrapper = QueryGenerator.initQueryWrapper(object, request.getParameterMap());
+
+		// Step.2 AutoPoi 导出Excel
+		ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
+		List<T> pageList = service.list(queryWrapper);
+		// 导出文件名称
+		mv.addObject(NormalExcelConstants.FILE_NAME, title); //此处设置的filename无效 ,前端会重更新设置一下
+		mv.addObject(NormalExcelConstants.CLASS, clazz);
+		mv.addObject(NormalExcelConstants.PARAMS, new ExportParams(title + "报表", "导出人:"+sysUser.getRealname(), title + "表"));
+		mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
+		return mv;
+	}
+
+	/**
+	 * 通过excel导入数据
+	 *
+	 * @param request
+	 * @param response
+	 * @return
+	 */
+	protected Result<?> importExcel(HttpServletRequest request, HttpServletResponse response, Class<T> clazz) {
+		MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
+		Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
+		for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
+			MultipartFile file = entity.getValue();// 获取上传文件对象
+			ImportParams params = new ImportParams();
+			params.setTitleRows(2);
+			params.setHeadRows(1);
+			params.setNeedSave(true);
+			try {
+				List<T> list = ExcelImportUtil.importExcel(file.getInputStream(), clazz, params);
+				//update-begin-author:taoyan date:20190528 for:批量插入数据
+				long start = System.currentTimeMillis();
+				service.saveBatch(list);
+				//400条 saveBatch消耗时间1592毫秒  循环插入消耗时间1947毫秒
+				//1200条  saveBatch消耗时间3687毫秒 循环插入消耗时间5212毫秒
+				log.info("消耗时间"+(System.currentTimeMillis()-start)+"毫秒");
+				//update-end-author:taoyan date:20190528 for:批量插入数据
+				return Result.ok("文件导入成功!数据行数:" + list.size());
+			} catch (Exception e) {
+				log.error(e.getMessage(), e);
+				return Result.error("文件导入失败:" + e.getMessage());
+			} finally {
+				try {
+					file.getInputStream().close();
+				} catch (IOException e) {
+					e.printStackTrace();
+				}
+			}
+		}
+		return Result.error("文件导入失败!");
+	}
+}

+ 54 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/system/base/entity/JeecgEntity.java

@@ -0,0 +1,54 @@
+package org.jeecg.common.system.base.entity;
+
+import java.io.Serializable;
+
+import org.jeecgframework.poi.excel.annotation.Excel;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+/**
+ * @Description: Entity基类
+ * @Author: dangzhenghui@163.com
+ * @Date: 2019-4-28
+ * @Version: 1.1
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+
+public class JeecgEntity implements Serializable {
+	private static final long serialVersionUID = 1L;
+
+	/** ID */
+	@TableId(type = IdType.ID_WORKER_STR)
+	@ApiModelProperty(value = "ID")
+	private java.lang.String id;
+	/** 创建人 */
+	@ApiModelProperty(value = "创建人")
+	@Excel(name = "创建人", width = 15)
+	private java.lang.String createBy;
+	/** 创建时间 */
+	@ApiModelProperty(value = "创建时间")
+	@Excel(name = "创建时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
+	@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+	@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	private java.util.Date createTime;
+	/** 更新人 */
+	@ApiModelProperty(value = "更新人")
+	@Excel(name = "更新人", width = 15)
+	private java.lang.String updateBy;
+	/** 更新时间 */
+	@ApiModelProperty(value = "更新时间")
+	@Excel(name = "更新时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
+	@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+	@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+	private java.util.Date updateTime;
+}

+ 12 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/system/base/service/JeecgService.java

@@ -0,0 +1,12 @@
+package org.jeecg.common.system.base.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * @Description: Service基类
+ * @Author: dangzhenghui@163.com
+ * @Date: 2019-4-21 8:13
+ * @Version: 1.0
+ */
+public interface JeecgService<T> extends IService<T> {
+}

+ 19 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/system/base/service/impl/JeecgServiceImpl.java

@@ -0,0 +1,19 @@
+package org.jeecg.common.system.base.service.impl;
+
+import org.jeecg.common.system.base.entity.JeecgEntity;
+import org.jeecg.common.system.base.service.JeecgService;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * @Description: ServiceImpl基类
+ * @Author: dangzhenghui@163.com
+ * @Date: 2019-4-21 8:13
+ * @Version: 1.0
+ */
+@Slf4j
+public class JeecgServiceImpl<M extends BaseMapper<T>, T extends JeecgEntity> extends ServiceImpl<M, T> implements JeecgService<T> {
+
+}

+ 220 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/system/controller/CommonController.java

@@ -0,0 +1,220 @@
+package org.jeecg.common.system.controller;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.jeecg.common.api.vo.Result;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.util.AntPathMatcher;
+import org.springframework.util.FileCopyUtils;
+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;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
+import org.springframework.web.servlet.HandlerMapping;
+import org.springframework.web.servlet.ModelAndView;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * <p>
+ * 用户表 前端控制器
+ * </p>
+ *
+ * @Author scott
+ * @since 2018-12-20
+ */
+@Slf4j
+@RestController
+@RequestMapping("/sys/common")
+public class CommonController {
+
+	@Value(value = "${jeecg.path.upload}")
+	private String uploadpath;
+
+	/**
+	 * @Author 政辉
+	 * @return
+	 */
+	@GetMapping("/403")
+	public Result<?> noauth()  {
+		return Result.error("没有权限,请联系管理员授权");
+	}
+	
+	@PostMapping(value = "/upload")
+	public Result<?> upload(HttpServletRequest request, HttpServletResponse response) {
+		Result<?> result = new Result<>();
+		try {
+			String ctxPath = uploadpath;
+			String fileName = null;
+			String bizPath = "files";
+			String nowday = new SimpleDateFormat("yyyyMMdd").format(new Date());
+			File file = new File(ctxPath + File.separator + bizPath + File.separator + nowday);
+			if (!file.exists()) {
+				file.mkdirs();// 创建文件根目录
+			}
+			MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
+			MultipartFile mf = multipartRequest.getFile("file");// 获取上传文件对象
+			String orgName = mf.getOriginalFilename();// 获取文件名
+			fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.indexOf("."));
+			String savePath = file.getPath() + File.separator + fileName;
+			File savefile = new File(savePath);
+			FileCopyUtils.copy(mf.getBytes(), savefile);
+			String dbpath = bizPath + File.separator + nowday + File.separator + fileName;
+			if (dbpath.contains("\\")) {
+				dbpath = dbpath.replace("\\", "/");
+			}
+			result.setMessage(dbpath);
+			result.setSuccess(true);
+		} catch (IOException e) {
+			result.setSuccess(false);
+			result.setMessage(e.getMessage());
+			log.error(e.getMessage(), e);
+		}
+		return result;
+	}
+
+	/**
+	 * 预览图片
+	 * 请求地址:http://localhost:8080/common/view/{user/20190119/e1fe9925bc315c60addea1b98eb1cb1349547719_1547866868179.jpg}
+	 * 
+	 * @param request
+	 * @param response
+	 */
+	@GetMapping(value = "/view/**")
+	public void view(HttpServletRequest request, HttpServletResponse response) {
+		// ISO-8859-1 ==> UTF-8 进行编码转换
+		String imgPath = extractPathFromPattern(request);
+		// 其余处理略
+		InputStream inputStream = null;
+		OutputStream outputStream = null;
+		try {
+			imgPath = imgPath.replace("..", "");
+			if (imgPath.endsWith(",")) {
+				imgPath = imgPath.substring(0, imgPath.length() - 1);
+			}
+			response.setContentType("image/jpeg;charset=utf-8");
+			String localPath = uploadpath;
+			String imgurl = localPath + File.separator + imgPath;
+			inputStream = new BufferedInputStream(new FileInputStream(imgurl));
+			outputStream = response.getOutputStream();
+			byte[] buf = new byte[1024];
+			int len;
+			while ((len = inputStream.read(buf)) > 0) {
+				outputStream.write(buf, 0, len);
+			}
+			response.flushBuffer();
+		} catch (IOException e) {
+			log.error("预览图片失败" + e.getMessage());
+			// e.printStackTrace();
+		} finally {
+			if (inputStream != null) {
+				try {
+					inputStream.close();
+				} catch (IOException e) {
+					log.error(e.getMessage(), e);
+				}
+			}
+			if (outputStream != null) {
+				try {
+					outputStream.close();
+				} catch (IOException e) {
+					log.error(e.getMessage(), e);
+				}
+			}
+		}
+
+	}
+	
+	/**
+	 * 下载文件
+	 * 请求地址:http://localhost:8080/common/download/{user/20190119/e1fe9925bc315c60addea1b98eb1cb1349547719_1547866868179.jpg}
+	 * 
+	 * @param request
+	 * @param response
+	 * @throws Exception 
+	 */
+	@GetMapping(value = "/download/**")
+	public void download(HttpServletRequest request, HttpServletResponse response) throws Exception {
+		// ISO-8859-1 ==> UTF-8 进行编码转换
+		String filePath = extractPathFromPattern(request);
+		// 其余处理略
+		InputStream inputStream = null;
+		OutputStream outputStream = null;
+		try {
+			filePath = filePath.replace("..", "");
+			if (filePath.endsWith(",")) {
+				filePath = filePath.substring(0, filePath.length() - 1);
+			}
+			String localPath = uploadpath;
+			String downloadFilePath = localPath + File.separator + filePath;
+			File file = new File(downloadFilePath);
+	         if (file.exists()) {
+	        	 response.setContentType("application/force-download");// 设置强制下载不打开            
+	 			response.addHeader("Content-Disposition", "attachment;fileName=" + new String(file.getName().getBytes("UTF-8"),"iso-8859-1"));
+	 			inputStream = new BufferedInputStream(new FileInputStream(file));
+	 			outputStream = response.getOutputStream();
+	 			byte[] buf = new byte[1024];
+	 			int len;
+	 			while ((len = inputStream.read(buf)) > 0) {
+	 				outputStream.write(buf, 0, len);
+	 			}
+	 			response.flushBuffer();
+	         }
+			
+		} catch (Exception e) {
+			log.info("文件下载失败" + e.getMessage());
+			// e.printStackTrace();
+		} finally {
+			if (inputStream != null) {
+				try {
+					inputStream.close();
+				} catch (IOException e) {
+					e.printStackTrace();
+				}
+			}
+			if (outputStream != null) {
+				try {
+					outputStream.close();
+				} catch (IOException e) {
+					e.printStackTrace();
+				}
+			}
+		}
+
+	}
+	/**
+	 * @功能:pdf预览Iframe
+	 * @param modelAndView
+	 * @return
+	 */
+	@RequestMapping("/pdf/pdfPreviewIframe")
+	public ModelAndView pdfPreviewIframe(ModelAndView modelAndView) {
+		modelAndView.setViewName("pdfPreviewIframe");
+		return modelAndView;
+	}
+
+	/**
+	  *  把指定URL后的字符串全部截断当成参数 
+	  *  这么做是为了防止URL中包含中文或者特殊字符(/等)时,匹配不了的问题
+	 * @param request
+	 * @return
+	 */
+	private static String extractPathFromPattern(final HttpServletRequest request) {
+		String path = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
+		String bestMatchPattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
+		return new AntPathMatcher().extractPathWithinPattern(bestMatchPattern, path);
+	}
+	
+}

+ 55 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/system/query/QueryCondition.java

@@ -0,0 +1,55 @@
+package org.jeecg.common.system.query;
+
+import java.io.Serializable;
+
+public class QueryCondition implements Serializable {
+
+	private static final long serialVersionUID = 4740166316629191651L;
+	
+	private String field;
+	private String type;
+	private String rule;
+	private String val;
+	
+	public String getField() {
+		return field;
+	}
+
+	public void setField(String field) {
+		this.field = field;
+	}
+
+	public String getType() {
+		return type;
+	}
+
+	public void setType(String type) {
+		this.type = type;
+	}
+
+	public String getRule() {
+		return rule;
+	}
+
+	public void setRule(String rule) {
+		this.rule = rule;
+	}
+
+	public String getVal() {
+		return val;
+	}
+
+	public void setVal(String val) {
+		this.val = val;
+	}
+
+	@Override
+	public String toString(){
+		StringBuffer sb =new StringBuffer();
+		if(field == null || "".equals(field)){
+			return "";
+		}
+		sb.append(this.field).append(" ").append(this.rule).append(" ").append(this.type).append(" ").append(this.val);
+		return sb.toString();
+	}
+}

+ 592 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/system/query/QueryGenerator.java

@@ -0,0 +1,592 @@
+package org.jeecg.common.system.query;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.beanutils.PropertyUtils;
+import org.jeecg.common.constant.CommonConstant;
+import org.jeecg.common.system.util.JeecgDataAutorUtils;
+import org.jeecg.common.system.util.JwtUtil;
+import org.jeecg.common.util.SqlInjectionUtil;
+import org.jeecg.common.util.oConvertUtils;
+import org.jeecg.modules.system.entity.SysPermissionDataRule;
+import org.springframework.util.NumberUtils;
+
+import java.beans.PropertyDescriptor;
+import java.io.UnsupportedEncodingException;
+import java.math.BigDecimal;
+import java.net.URLDecoder;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+@Slf4j
+public class QueryGenerator {
+	
+	public static final String SQL_RULES_COLUMN = "SQL_RULES_COLUMN";
+	
+	private static final String BEGIN = "_begin";
+	private static final String END = "_end";
+	private static final String STAR = "*";
+	private static final String COMMA = ",";
+	private static final String NOT_EQUAL = "!";
+	/**高级查询前端传来的参数名*/
+	private static final String SUPER_QUERY_PARAMS = "superQueryParams";
+	
+	/**排序列*/
+	private static final String ORDER_COLUMN = "column";
+	/**排序方式*/
+	private static final String ORDER_TYPE = "order";
+	private static final String ORDER_TYPE_ASC = "ASC";
+	
+	/**时间格式化 */
+	private static final ThreadLocal<SimpleDateFormat> local = new ThreadLocal<SimpleDateFormat>();
+	private static SimpleDateFormat getTime(){
+		SimpleDateFormat time = local.get();
+		if(time == null){
+			time = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
+			local.set(time);
+		}
+		return time;
+	}
+	
+	/**
+	 * 获取查询条件构造器QueryWrapper实例 通用查询条件已被封装完成
+	 * @param searchObj 查询实体
+	 * @param parameterMap request.getParameterMap()
+	 * @return QueryWrapper实例
+	 */
+	public static <T> QueryWrapper<T> initQueryWrapper(T searchObj,Map<String, String[]> parameterMap){
+		long start = System.currentTimeMillis();
+		QueryWrapper<T> queryWrapper = new QueryWrapper<T>();
+		installMplus(queryWrapper, searchObj, parameterMap);
+		log.debug("---查询条件构造器初始化完成,耗时:"+(System.currentTimeMillis()-start)+"毫秒----");
+		return queryWrapper;
+	}
+	
+	/**
+	 * 组装Mybatis Plus 查询条件
+	 * <p>使用此方法 需要有如下几点注意:   
+	 * <br>1.使用QueryWrapper 而非LambdaQueryWrapper;
+	 * <br>2.实例化QueryWrapper时不可将实体传入参数   
+	 * <br>错误示例:如QueryWrapper<JeecgDemo> queryWrapper = new QueryWrapper<JeecgDemo>(jeecgDemo);
+	 * <br>正确示例:QueryWrapper<JeecgDemo> queryWrapper = new QueryWrapper<JeecgDemo>();
+	 * <br>3.也可以不使用这个方法直接调用 {@link #initQueryWrapper}直接获取实例
+	 */
+	public static void installMplus(QueryWrapper<?> queryWrapper,Object searchObj,Map<String, String[]> parameterMap) {
+		
+		/*
+		 * 注意:权限查询由前端配置数据规则 当一个人有多个所属部门时候 可以在规则配置包含条件 orgCode 包含 #{sys_org_code}
+		但是不支持在自定义SQL中写orgCode in #{sys_org_code} 
+		当一个人只有一个部门 就直接配置等于条件: orgCode 等于 #{sys_org_code} 或者配置自定义SQL: orgCode = '#{sys_org_code}'
+		*/
+		
+		//区间条件组装 模糊查询 高级查询组装 简单排序 权限查询
+		PropertyDescriptor origDescriptors[] = PropertyUtils.getPropertyDescriptors(searchObj);
+		Map<String,SysPermissionDataRule> ruleMap = getRuleMap();
+		
+		//权限规则自定义SQL表达式
+		for (String c : ruleMap.keySet()) {
+			if(oConvertUtils.isNotEmpty(c) && c.startsWith(SQL_RULES_COLUMN)){
+				queryWrapper.and(i ->i.apply(getSqlRuleValue(ruleMap.get(c).getRuleValue())));
+			}
+		}
+		
+		String name, type;
+		for (int i = 0; i < origDescriptors.length; i++) {
+			//aliasName = origDescriptors[i].getName();  mybatis  不存在实体属性 不用处理别名的情况
+			name = origDescriptors[i].getName();
+			type = origDescriptors[i].getPropertyType().toString();
+			try {
+				if (judgedIsUselessField(name)|| !PropertyUtils.isReadable(searchObj, name)) {
+					continue;
+				}
+				
+				//数据权限查询
+				if(ruleMap.containsKey(name)) {
+					addRuleToQueryWrapper(ruleMap.get(name), name, origDescriptors[i].getPropertyType(), queryWrapper);
+				}
+				
+				// 添加 判断是否有区间值
+				String endValue = null,beginValue = null;
+				if (parameterMap != null && parameterMap.containsKey(name + BEGIN)) {
+					beginValue = parameterMap.get(name + BEGIN)[0].trim();
+					addQueryByRule(queryWrapper, name, type, beginValue, QueryRuleEnum.GE);
+					
+				}
+				if (parameterMap != null && parameterMap.containsKey(name + END)) {
+					endValue = parameterMap.get(name + END)[0].trim();
+					addQueryByRule(queryWrapper, name, type, endValue, QueryRuleEnum.LE);
+				}
+				
+				//判断单值  参数带不同标识字符串 走不同的查询
+				//TODO 这种前后带逗号的支持分割后模糊查询需要否 使多选字段的查询生效
+				Object value = PropertyUtils.getSimpleProperty(searchObj, name);
+				if (null != value && value.toString().startsWith(COMMA) && value.toString().endsWith(COMMA)) {
+					String multiLikeval = value.toString().replace(",,", COMMA);
+					String[] vals = multiLikeval.substring(1, multiLikeval.length()).split(COMMA);
+					final String field = oConvertUtils.camelToUnderline(name);
+					if(vals.length>1) {
+						queryWrapper.and(j -> {
+							j = j.like(field,vals[0]);
+							for (int k=1;k<vals.length;k++) {
+								j = j.or().like(field,vals[k]);
+							}
+							return j;
+						});
+					}else {
+						queryWrapper.and(j -> j.like(field,vals[0]));
+					}
+				}else {
+					//根据参数值带什么关键字符串判断走什么类型的查询
+					QueryRuleEnum rule = convert2Rule(value);
+					value = replaceValue(rule,value);
+					addEasyQuery(queryWrapper, name, rule, value);
+				}
+				
+			} catch (Exception e) {
+				log.error(e.getMessage(), e);
+			}
+		}
+		// 排序逻辑 处理 
+		doMultiFieldsOrder(queryWrapper, parameterMap);
+				
+		//高级查询
+		doSuperQuery(queryWrapper, parameterMap);
+		
+	}
+	
+	//多字段排序 TODO 需要修改前端
+	public static void doMultiFieldsOrder(QueryWrapper<?> queryWrapper,Map<String, String[]> parameterMap) {
+		String column=null,order=null;
+		if(parameterMap!=null&& parameterMap.containsKey(ORDER_COLUMN)) {
+			column = parameterMap.get(ORDER_COLUMN)[0];
+		}
+		if(parameterMap!=null&& parameterMap.containsKey(ORDER_TYPE)) {
+			order = parameterMap.get(ORDER_TYPE)[0];
+		}
+		log.debug("排序规则>>列:"+column+",排序方式:"+order);
+		if (oConvertUtils.isNotEmpty(column) && oConvertUtils.isNotEmpty(order)) {
+			//字典字段,去掉字典翻译文本后缀
+			if(column.endsWith(CommonConstant.DICT_TEXT_SUFFIX)) {
+				column = column.substring(0, column.lastIndexOf(CommonConstant.DICT_TEXT_SUFFIX));
+			}
+			//SQL注入check
+			SqlInjectionUtil.filterContent(column); 
+
+			if (order.toUpperCase().indexOf(ORDER_TYPE_ASC)>=0) {
+				queryWrapper.orderByAsc(oConvertUtils.camelToUnderline(column));
+			} else {
+				queryWrapper.orderByDesc(oConvertUtils.camelToUnderline(column));
+			}
+		}
+	}
+	
+	/**
+	 * 高级查询
+	 * @param queryWrapper
+	 * @param parameterMap
+	 */
+	public static void doSuperQuery(QueryWrapper<?> queryWrapper,Map<String, String[]> parameterMap) {
+		if(parameterMap!=null&& parameterMap.containsKey(SUPER_QUERY_PARAMS)){
+			String superQueryParams = parameterMap.get(SUPER_QUERY_PARAMS)[0];
+			// 解码
+			try {
+				superQueryParams = URLDecoder.decode(superQueryParams, "UTF-8");
+			} catch (UnsupportedEncodingException e) {
+				log.error("--高级查询参数转码失败!", e);
+			}
+			List<QueryCondition> conditions = JSON.parseArray(superQueryParams, QueryCondition.class);
+			log.info("---高级查询参数-->"+conditions.toString());
+			
+			for (QueryCondition rule : conditions) {
+				if(oConvertUtils.isNotEmpty(rule.getField()) && oConvertUtils.isNotEmpty(rule.getRule()) && oConvertUtils.isNotEmpty(rule.getVal())){
+					addEasyQuery(queryWrapper, rule.getField(), QueryRuleEnum.getByValue(rule.getRule()), rule.getVal());
+				}
+			}
+		}
+	}
+	/**
+	 * 根据所传的值 转化成对应的比较方式
+	 * 支持><= like in !
+	 * @param value
+	 * @return
+	 */
+	public static QueryRuleEnum convert2Rule(Object value) {
+		// 避免空数据
+		if (value == null) {
+			return null;
+		}
+		String val = (value + "").toString().trim();
+		if (val.length() == 0) {
+			return null;
+		}
+		QueryRuleEnum rule =null;
+		// step 2 .>= =<
+		if (rule == null && val.length() >= 2) {
+			rule = QueryRuleEnum.getByValue(val.substring(0, 2));
+		}
+		// step 1 .> <
+		if (rule == null && val.length() >= 1) {
+			rule = QueryRuleEnum.getByValue(val.substring(0, 1));
+		}
+		
+		// step 3 like
+		if (rule == null && val.contains(STAR)) {
+			if (val.startsWith(STAR) && val.endsWith(STAR)) {
+				rule = QueryRuleEnum.LIKE;
+			} else if (val.startsWith(STAR)) {
+				rule = QueryRuleEnum.LEFT_LIKE;
+			} else if(val.endsWith(STAR)){
+				rule = QueryRuleEnum.RIGHT_LIKE;
+			}
+		}
+		// step 4 in
+		if (rule == null && val.contains(COMMA)) {
+			//TODO in 查询这里应该有个bug  如果一字段本身就是多选 此时用in查询 未必能查询出来
+			rule = QueryRuleEnum.IN;
+		}
+		// step 5 != 
+		if(rule == null && val.startsWith(NOT_EQUAL)){
+			rule = QueryRuleEnum.NE;
+		}
+		return rule != null ? rule : QueryRuleEnum.EQ;
+	}
+	
+	/**
+	 * 替换掉关键字字符
+	 * 
+	 * @param rule
+	 * @param value
+	 * @return
+	 */
+	public static Object replaceValue(QueryRuleEnum rule, Object value) {
+		if (rule == null) {
+			return null;
+		}
+		if (! (value instanceof String)){
+			return value;
+		}
+		String val = (value + "").toString().trim();
+		if (rule == QueryRuleEnum.LIKE) {
+			value = val.substring(1, val.length() - 1);
+		} else if (rule == QueryRuleEnum.LEFT_LIKE || rule == QueryRuleEnum.NE) {
+			value = val.substring(1);
+		} else if (rule == QueryRuleEnum.RIGHT_LIKE) {
+			value = val.substring(0, val.length() - 1);
+		} else if (rule == QueryRuleEnum.IN) {
+			value = val.split(",");
+		} else {
+			value = val.replace(rule.getValue(),"");
+		}
+		return value;
+	}
+	
+	private static void addQueryByRule(QueryWrapper<?> queryWrapper,String name,String type,String value,QueryRuleEnum rule) throws ParseException {
+		if(!"".equals(value)) {
+			Object temp;
+			switch (type) {
+			case "class java.lang.Integer":
+				temp =  Integer.parseInt(value);
+				break;
+			case "class java.math.BigDecimal":
+				temp =  new BigDecimal(value);
+				break;
+			case "class java.lang.Short":
+				temp =  Short.parseShort(value);
+				break;
+			case "class java.lang.Long":
+				temp =  Long.parseLong(value);
+				break;
+			case "class java.lang.Float":
+				temp =   Float.parseFloat(value);
+				break;
+			case "class java.lang.Double":
+				temp =  Double.parseDouble(value);
+				break;
+			case "class java.util.Date":
+				temp = getDateQueryByRule(value, rule);
+				break;
+			default:
+				temp = value;
+				break;
+			}
+			addEasyQuery(queryWrapper, name, rule, temp);
+		}
+	}
+	
+	/**
+	 * 获取日期类型的值
+	 * @param value
+	 * @param rule
+	 * @return
+	 * @throws ParseException
+	 */
+	private static Date getDateQueryByRule(String value,QueryRuleEnum rule) throws ParseException {
+		Date date = null;
+		if(value.length()==10) {
+			if(rule==QueryRuleEnum.GE) {
+				//比较大于
+				date = getTime().parse(value + " 00:00:00");
+			}else if(rule==QueryRuleEnum.LE) {
+				//比较小于
+				date = getTime().parse(value + " 23:59:59");
+			}
+			//TODO 日期类型比较特殊 可能oracle下不一定好使
+		}
+		if(date==null) {
+			date = getTime().parse(value);
+		}
+		return date;
+	}
+	
+	/**
+	  * 根据规则走不同的查询
+	 * @param queryWrapper QueryWrapper
+	 * @param name         字段名字
+	 * @param rule         查询规则
+	 * @param value        查询条件值
+	 */
+	private static void addEasyQuery(QueryWrapper<?> queryWrapper, String name, QueryRuleEnum rule, Object value) {
+		if (value == null || rule == null) {
+			return;
+		}
+		name = oConvertUtils.camelToUnderline(name);
+		log.info("--查询规则-->"+name+" "+rule.getValue()+" "+value);
+		switch (rule) {
+		case GT:
+			queryWrapper.gt(name, value);
+			break;
+		case GE:
+			queryWrapper.ge(name, value);
+			break;
+		case LT:
+			queryWrapper.lt(name, value);
+			break;
+		case LE:
+			queryWrapper.le(name, value);
+			break;
+		case EQ:
+			queryWrapper.eq(name, value);
+			break;
+		case NE:
+			queryWrapper.ne(name, value);
+			break;
+		case IN:
+			if(value instanceof String) {
+				queryWrapper.in(name, (Object[])value.toString().split(","));
+			}else if(value instanceof String[]) {
+				queryWrapper.in(name, (Object[]) value);
+			}else {
+				queryWrapper.in(name, value);
+			}
+			break;
+		case LIKE:
+			queryWrapper.like(name, value);
+			break;
+		case LEFT_LIKE:
+			queryWrapper.likeLeft(name, value);
+			break;
+		case RIGHT_LIKE:
+			queryWrapper.likeRight(name, value);
+			break;
+		default:
+			log.info("--查询规则未匹配到---");
+			break;
+		}
+	}
+	/**
+	 * 
+	 * @param name
+	 * @return
+	 */
+	private static boolean judgedIsUselessField(String name) {
+		return "class".equals(name) || "ids".equals(name)
+				|| "page".equals(name) || "rows".equals(name)
+				|| "sort".equals(name) || "order".equals(name);
+	}
+
+	
+
+	/**
+	 * 
+	 * @return
+	 */
+	public static Map<String, SysPermissionDataRule> getRuleMap() {
+		Map<String, SysPermissionDataRule> ruleMap = new HashMap<String, SysPermissionDataRule>();
+		List<SysPermissionDataRule> list =JeecgDataAutorUtils.loadDataSearchConditon();
+		if(list != null&&list.size()>0){
+			if(list.get(0)==null){
+				return ruleMap;
+			}
+			for (SysPermissionDataRule rule : list) {
+				String column = rule.getRuleColumn();
+				if(QueryRuleEnum.SQL_RULES.getValue().equals(rule.getRuleConditions())) {
+					column = SQL_RULES_COLUMN+rule.getId();
+				}
+				ruleMap.put(column, rule);
+			}
+		}
+		return ruleMap;
+	}
+	
+	private static void addRuleToQueryWrapper(SysPermissionDataRule dataRule,String name, Class propertyType, QueryWrapper<?> queryWrapper) {
+		QueryRuleEnum rule = QueryRuleEnum.getByValue(dataRule.getRuleConditions());
+		if(rule.equals(QueryRuleEnum.IN) && ! propertyType.equals(String.class)) {
+			String[] values = dataRule.getRuleValue().split(",");
+			Object[] objs = new Object[values.length];
+			for (int i = 0; i < values.length; i++) {
+				objs[i] = NumberUtils.parseNumber(values[i], propertyType);
+			}
+			addEasyQuery(queryWrapper, name, rule, objs);
+		}else {
+			if (propertyType.equals(String.class)) {
+				addEasyQuery(queryWrapper, name, rule, converRuleValue(dataRule.getRuleValue()));
+			} else {
+				addEasyQuery(queryWrapper, name, rule, NumberUtils.parseNumber(dataRule.getRuleValue(), propertyType));
+			}
+		}
+	}
+	
+	public static String converRuleValue(String ruleValue) {
+		String value = JwtUtil.getSessionData(ruleValue);
+		if(oConvertUtils.isEmpty(value)) {
+			value = JwtUtil.getUserSystemData(ruleValue,null);
+		}
+		return value!= null ? value : ruleValue;
+	}
+	
+	public static String getSqlRuleValue(String sqlRule){
+		try {
+			Set<String> varParams = getSqlRuleParams(sqlRule);
+			for(String var:varParams){
+				String tempValue = converRuleValue(var);
+				sqlRule = sqlRule.replace("#{"+var+"}",tempValue);
+			}
+		} catch (Exception e) {
+			log.error(e.getMessage(), e);
+		}
+		return sqlRule;
+	}
+	
+	/**
+	 * 获取sql中的#{key} 这个key组成的set
+	 */
+	public static Set<String> getSqlRuleParams(String sql) {
+		if(oConvertUtils.isEmpty(sql)){
+			return null;
+		}
+		Set<String> varParams = new HashSet<String>();
+		String regex = "\\#\\{\\w+\\}";
+		
+		Pattern p = Pattern.compile(regex);
+		Matcher m = p.matcher(sql);
+		while(m.find()){
+			String var = m.group();
+			varParams.add(var.substring(var.indexOf("{")+1,var.indexOf("}")));
+		}
+		return varParams;
+	}
+	
+	/**
+	 * 获取查询条件 
+	 * @param field
+	 * @param alias
+	 * @param value
+	 * @param isString
+	 * @return
+	 */
+	public static String getSingleQueryConditionSql(String field,String alias,Object value,boolean isString) {
+		if (value == null) {
+			return "";
+		}
+		field =  alias+oConvertUtils.camelToUnderline(field);
+		QueryRuleEnum rule = QueryGenerator.convert2Rule(value);
+		String res = "";
+		switch (rule) {
+		case GT:
+			res =field+rule.getValue()+getFieldConditionValue(value, isString);
+			break;
+		case GE:
+			res = field+rule.getValue()+getFieldConditionValue(value, isString);
+			break;
+		case LT:
+			res = field+rule.getValue()+getFieldConditionValue(value, isString);
+			break;
+		case LE:
+			res = field+rule.getValue()+getFieldConditionValue(value, isString);
+			break;
+		case EQ:
+			res = field+rule.getValue()+getFieldConditionValue(value, isString);
+			break;
+		case NE:
+			res = field+" <> "+getFieldConditionValue(value, isString);
+			break;
+		case IN:
+			res = field + " in "+getInConditionValue(value, isString);
+			break;
+		case LIKE:
+			res = field + " like "+getLikeConditionValue(value);
+			break;
+		case LEFT_LIKE:
+			res = field + " like "+getLikeConditionValue(value);
+			break;
+		case RIGHT_LIKE:
+			res = field + " like "+getLikeConditionValue(value);
+			break;
+		default:
+			res = field+" = "+getFieldConditionValue(value, isString);
+			break;
+		}
+		return res;
+	}
+	private static String getFieldConditionValue(Object value,boolean isString) {
+		String str = value.toString().trim();
+		if(str.startsWith("!")) {
+			str = str.substring(1);
+		}else if(str.startsWith(">=")) {
+			str = str.substring(2);
+		}else if(str.startsWith("<=")) {
+			str = str.substring(2);
+		}else if(str.startsWith(">")) {
+			str = str.substring(1);
+		}else if(str.startsWith("<")) {
+			str = str.substring(1);
+		}
+		if(isString) {
+			return " '"+str+"' ";
+		}else {
+			return value.toString();
+		}
+	}
+	
+	private static String getInConditionValue(Object value,boolean isString) {
+		if(isString) {
+			String temp[] = value.toString().split(",");
+			String res="";
+			for (String string : temp) {
+				res+=",'"+string+"'";
+			}
+			return "("+res.substring(1)+")";
+		}else {
+			return "("+value.toString()+")";
+		}
+	}
+	
+	private static String getLikeConditionValue(Object value) {
+		String str = value.toString().trim();
+		if(str.startsWith("*") && str.endsWith("*")) {
+			return "'%"+str.substring(1,str.length()-1)+"%'";
+		}else if(str.startsWith("*")) {
+			return "'%"+str.substring(1)+"'";
+		}else if(str.endsWith("*")) {
+			return "'"+str.substring(0,str.length()-1)+"%'";
+		}else {
+			return str;
+		}
+	}
+	
+	
+}

+ 71 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/system/query/QueryRuleEnum.java

@@ -0,0 +1,71 @@
+package org.jeecg.common.system.query;
+
+import org.jeecg.common.util.oConvertUtils;
+
+/**
+ * Query 规则 常量
+ * @Author Scott
+ * @Date 2019年02月14日
+ */
+public enum QueryRuleEnum {
+
+    GT(">","gt","大于"),
+    GE(">=","ge","大于等于"),
+    LT("<","lt","小于"),
+    LE("<=","le","小于等于"),
+    EQ("=","eq","等于"),
+    NE("!=","ne","不等于"),
+    IN("IN","in","包含"),
+    LIKE("LIKE","like","全模糊"),
+    LEFT_LIKE("LEFT_LIKE","left_like","左模糊"),
+    RIGHT_LIKE("RIGHT_LIKE","right_like","右模糊"),
+    SQL_RULES("USE_SQL_RULES","ext","自定义SQL片段");
+
+    private String value;
+    
+    private String condition; 
+
+    private String msg;
+
+    QueryRuleEnum(String value, String condition, String msg){
+        this.value = value;
+        this.condition = condition;
+        this.msg = msg;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    public void setMsg(String msg) {
+        this.msg = msg;
+    }
+
+    public String getCondition() {
+		return condition;
+	}
+
+	public void setCondition(String condition) {
+		this.condition = condition;
+	}
+
+	public static QueryRuleEnum getByValue(String value){
+    	if(oConvertUtils.isEmpty(value)) {
+    		return null;
+    	}
+        for(QueryRuleEnum val :values()){
+            if (val.getValue().equals(value) || val.getCondition().equals(value)){
+                return val;
+            }
+        }
+        return  null;
+    }
+}

+ 90 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/system/util/JeecgDataAutorUtils.java

@@ -0,0 +1,90 @@
+package org.jeecg.common.system.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.jeecg.common.system.vo.SysUserCacheInfo;
+import org.jeecg.common.util.SpringContextUtils;
+import org.jeecg.modules.system.entity.SysPermissionDataRule;
+import org.springframework.util.StringUtils;
+
+/**
+ * @ClassName: JeecgDataAutorUtils
+ * @Description: 数据权限查询规则容器工具类
+ * @Author: 张代浩
+ * @Date: 2012-12-15 下午11:27:39
+ * 
+ */
+public class JeecgDataAutorUtils {
+	
+	public static final String MENU_DATA_AUTHOR_RULES = "MENU_DATA_AUTHOR_RULES";
+	
+	public static final String MENU_DATA_AUTHOR_RULE_SQL = "MENU_DATA_AUTHOR_RULE_SQL";
+	
+	public static final String SYS_USER_INFO = "SYS_USER_INFO";
+
+	/**
+	 * 往链接请求里面,传入数据查询条件
+	 * 
+	 * @param request
+	 * @param MENU_DATA_AUTHOR_RULES
+	 */
+	public static synchronized void installDataSearchConditon(HttpServletRequest request, List<SysPermissionDataRule> dataRules) {
+		@SuppressWarnings("unchecked")
+		List<SysPermissionDataRule> list = (List<SysPermissionDataRule>)loadDataSearchConditon();// 1.先从request获取MENU_DATA_AUTHOR_RULES,如果存则获取到LIST
+		if (list==null) {
+			// 2.如果不存在,则new一个list
+			list = new ArrayList<SysPermissionDataRule>();
+		}
+		for (SysPermissionDataRule tsDataRule : dataRules) {
+			list.add(tsDataRule);
+		}
+		request.setAttribute(MENU_DATA_AUTHOR_RULES, list); // 3.往list里面增量存指
+	}
+
+	/**
+	 * 获取请求对应的数据权限规则
+	 * 
+	 * @param request
+	 * @return
+	 */
+	@SuppressWarnings("unchecked")
+	public static synchronized List<SysPermissionDataRule> loadDataSearchConditon() {
+		return (List<SysPermissionDataRule>) SpringContextUtils.getHttpServletRequest().getAttribute(MENU_DATA_AUTHOR_RULES);
+				
+	}
+
+	/**
+	 * 获取请求对应的数据权限SQL
+	 * 
+	 * @param request
+	 * @return
+	 */
+	public static synchronized String loadDataSearchConditonSQLString() {
+		return (String) SpringContextUtils.getHttpServletRequest().getAttribute(MENU_DATA_AUTHOR_RULE_SQL);
+	}
+
+	/**
+	 * 往链接请求里面,传入数据查询条件
+	 * 
+	 * @param request
+	 * @param MENU_DATA_AUTHOR_RULE_SQL
+	 */
+	public static synchronized void installDataSearchConditon(HttpServletRequest request, String sql) {
+		String ruleSql = (String)loadDataSearchConditonSQLString();
+		if (!StringUtils.hasText(ruleSql)) {
+			request.setAttribute(MENU_DATA_AUTHOR_RULE_SQL,sql);
+		}
+	}
+	
+	public static synchronized void installUserInfo(HttpServletRequest request, SysUserCacheInfo userinfo) {
+		request.setAttribute(SYS_USER_INFO, userinfo);
+	}
+	
+	public static synchronized SysUserCacheInfo loadUserInfo() {
+		return (SysUserCacheInfo) SpringContextUtils.getHttpServletRequest().getAttribute(SYS_USER_INFO);
+				
+	}
+}

+ 204 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/system/util/JwtUtil.java

@@ -0,0 +1,204 @@
+package org.jeecg.common.system.util;
+
+import com.auth0.jwt.JWT;
+import com.auth0.jwt.JWTVerifier;
+import com.auth0.jwt.algorithms.Algorithm;
+import com.auth0.jwt.exceptions.JWTDecodeException;
+import com.auth0.jwt.interfaces.DecodedJWT;
+import com.google.common.base.Joiner;
+
+import java.util.Date;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+
+
+import org.jeecg.common.constant.DataBaseConstant;
+import org.jeecg.common.exception.JeecgBootException;
+
+import org.apache.shiro.SecurityUtils;
+import org.jeecg.common.constant.DataBaseConstant;
+import org.jeecg.common.exception.JeecgBootException;
+import org.jeecg.common.system.vo.LoginUser;
+import org.jeecg.common.system.vo.SysUserCacheInfo;
+import org.jeecg.common.util.SpringContextUtils;
+import org.jeecg.common.util.oConvertUtils;
+
+/**
+ * @Author Scott
+ * @Date 2018-07-12 14:23
+ * @Desc JWT工具类
+ **/
+public class JwtUtil {
+
+	// 过期时间30分钟
+	public static final long EXPIRE_TIME = 30 * 60 * 1000;
+
+	/**
+	 * 校验token是否正确
+	 *
+	 * @param token  密钥
+	 * @param secret 用户的密码
+	 * @return 是否正确
+	 */
+	public static boolean verify(String token, String username, String secret) {
+		try {
+			// 根据密码生成JWT效验器
+			Algorithm algorithm = Algorithm.HMAC256(secret);
+			JWTVerifier verifier = JWT.require(algorithm).withClaim("username", username).build();
+			// 效验TOKEN
+			DecodedJWT jwt = verifier.verify(token);
+			return true;
+		} catch (Exception exception) {
+			return false;
+		}
+	}
+
+	/**
+	 * 获得token中的信息无需secret解密也能获得
+	 *
+	 * @return token中包含的用户名
+	 */
+	public static String getUsername(String token) {
+		try {
+			DecodedJWT jwt = JWT.decode(token);
+			return jwt.getClaim("username").asString();
+		} catch (JWTDecodeException e) {
+			return null;
+		}
+	}
+
+	/**
+	 * 生成签名,5min后过期
+	 *
+	 * @param username 用户名
+	 * @param secret   用户的密码
+	 * @return 加密的token
+	 */
+	public static String sign(String username, String secret) {
+		Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
+		Algorithm algorithm = Algorithm.HMAC256(secret);
+		// 附带username信息
+		return JWT.create().withClaim("username", username).withExpiresAt(date).sign(algorithm);
+
+	}
+
+	/**
+	 * 根据request中的token获取用户账号
+	 * 
+	 * @param request
+	 * @return
+	 * @throws JeecgBootException
+	 */
+	public static String getUserNameByToken(HttpServletRequest request) throws JeecgBootException {
+		String accessToken = request.getHeader("X-Access-Token");
+		String username = getUsername(accessToken);
+		if (oConvertUtils.isEmpty(username)) {
+			throw new JeecgBootException("未获取到用户");
+		}
+		return username;
+	}
+	
+	/**
+	  *  从session中获取变量
+	 * @param key
+	 * @return
+	 */
+	public static String getSessionData(String key) {
+		//${myVar}%
+		//得到${} 后面的值
+		String moshi = "";
+		if(key.indexOf("}")!=-1){
+			 moshi = key.substring(key.indexOf("}")+1);
+		}
+		String returnValue = null;
+		if (key.contains("#{")) {
+			key = key.substring(2,key.indexOf("}"));
+		}
+		if (oConvertUtils.isNotEmpty(key)) {
+			HttpSession session = SpringContextUtils.getHttpServletRequest().getSession();
+			returnValue = (String) session.getAttribute(key);
+		}
+		//结果加上${} 后面的值
+		if(returnValue!=null){returnValue = returnValue + moshi;}
+		return returnValue;
+	}
+	
+	/**
+	  * 从当前用户中获取变量
+	 * @param key
+	 * @param user
+	 * @return
+	 */
+
+	//TODO 急待改造 sckjkdsjsfjdk
+
+	public static String getUserSystemData(String key,SysUserCacheInfo user) {
+		if(user==null) {
+			user = JeecgDataAutorUtils.loadUserInfo();
+		}
+		//#{sys_user_code}%
+
+		// 获取登录用户信息
+		LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
+
+		String moshi = "";
+		if(key.indexOf("}")!=-1){
+			 moshi = key.substring(key.indexOf("}")+1);
+		}
+		String returnValue = null;
+		//针对特殊标示处理#{sysOrgCode},判断替换
+		if (key.contains("#{")) {
+			key = key.substring(2,key.indexOf("}"));
+		} else {
+			key = key;
+		}
+		//替换为系统登录用户帐号
+		if (key.equals(DataBaseConstant.SYS_USER_CODE)|| key.equals(DataBaseConstant.SYS_USER_CODE_TABLE)) {
+			if(user==null) {
+				returnValue = sysUser.getUsername();
+			}else {
+				returnValue = user.getSysUserCode();
+			}
+		}
+		//替换为系统登录用户真实名字
+		if (key.equals(DataBaseConstant.SYS_USER_NAME)|| key.equals(DataBaseConstant.SYS_USER_NAME_TABLE)) {
+			if(user==null) {
+				returnValue = sysUser.getRealname();
+			}else {
+				returnValue = user.getSysUserName();
+			}
+		}
+		
+		//替换为系统用户登录所使用的机构编码
+		if (key.equals(DataBaseConstant.SYS_ORG_CODE)|| key.equals(DataBaseConstant.SYS_ORG_CODE_TABLE)) {
+			if(user==null) {
+				returnValue = sysUser.getOrgCode();
+			}else {
+				returnValue = user.getSysOrgCode();
+			}
+
+		}
+		//替换为系统用户所拥有的所有机构编码
+		if (key.equals(DataBaseConstant.SYS_MULTI_ORG_CODE)|| key.equals(DataBaseConstant.SYS_MULTI_ORG_CODE)) {
+			if(user.isOneDepart()) {
+				returnValue = user.getSysMultiOrgCode().get(0);
+			}else {
+				returnValue = Joiner.on(",").join(user.getSysMultiOrgCode());
+			}
+		}
+		//替换为当前系统时间(年月日)
+		if (key.equals(DataBaseConstant.SYS_DATE)|| key.equals(DataBaseConstant.SYS_DATE_TABLE)) {
+			returnValue = user.getSysDate();
+		}
+		//替换为当前系统时间(年月日时分秒)
+		if (key.equals(DataBaseConstant.SYS_TIME)|| key.equals(DataBaseConstant.SYS_TIME_TABLE)) {
+			returnValue = user.getSysTime();
+		}
+		//流程状态默认值(默认未发起)
+		if (key.equals(DataBaseConstant.BPM_STATUS_TABLE)|| key.equals(DataBaseConstant.BPM_STATUS_TABLE)) {
+			returnValue = "1";
+		}
+		if(returnValue!=null){returnValue = returnValue + moshi;}
+		return returnValue;
+	}
+}

+ 40 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/system/vo/DictModel.java

@@ -0,0 +1,40 @@
+package org.jeecg.common.system.vo;
+
+import java.io.Serializable;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class DictModel implements Serializable{
+	private static final long serialVersionUID = 1L;
+
+
+	public DictModel() {
+	}
+	
+	public DictModel(String value, String text) {
+		this.value = value;
+		this.text = text;
+	}
+	
+	/**
+	 * 字典value
+	 */
+	private String value;
+	/**
+	 * 字典文本
+	 */
+	private String text;
+
+	/**
+	 * 特殊用途: JgEditableTable
+	 * @return
+	 */
+	public String getTitle() {
+		return this.text;
+	}
+}

+ 83 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/system/vo/LoginUser.java

@@ -0,0 +1,83 @@
+package org.jeecg.common.system.vo;
+
+import java.util.Date;
+
+import org.springframework.format.annotation.DateTimeFormat;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+/**
+ * <p>
+ * 在线用户信息
+ * </p>
+ *
+ * @Author scott
+ * @since 2018-12-20
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class LoginUser {
+
+	/**
+	 * 登录人id
+	 */
+	private String id;
+
+	/**
+	 * 登录人账号
+	 */
+	private String username;
+
+	/**
+	 * 登录人名字
+	 */
+	private String realname;
+
+     /**
+      * 当前登录部门code
+      */
+    private String orgCode;
+	/**
+	 * 头像
+	 */
+	private String avatar;
+
+	/**
+	 * 生日
+	 */
+	@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
+	@DateTimeFormat(pattern = "yyyy-MM-dd")
+	private Date birthday;
+
+	/**
+	 * 性别(1:男 2:女)
+	 */
+	private Integer sex;
+
+	/**
+	 * 电子邮件
+	 */
+	private String email;
+
+	/**
+	 * 电话
+	 */
+	private String phone;
+
+	/**
+	 * 状态(1:正常 2:冻结 )
+	 */
+	private Integer status;
+	
+	private String delFlag;
+	/**
+     * 同步工作流引擎1同步0不同步
+     */
+    private String activitiSync;
+
+}

+ 67 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/system/vo/SysUserCacheInfo.java

@@ -0,0 +1,67 @@
+package org.jeecg.common.system.vo;
+
+import java.util.List;
+
+import org.jeecg.common.util.DateUtils;
+
+public class SysUserCacheInfo {
+	
+	private String sysUserCode;
+	
+	private String sysUserName;
+	
+	private String sysOrgCode;
+	
+	private List<String> sysMultiOrgCode;
+	
+	private boolean oneDepart;
+	
+	public boolean isOneDepart() {
+		return oneDepart;
+	}
+
+	public void setOneDepart(boolean oneDepart) {
+		this.oneDepart = oneDepart;
+	}
+
+	public String getSysDate() {
+		return DateUtils.formatDate();
+	}
+
+	public String getSysTime() {
+		return DateUtils.now();
+	}
+
+	public String getSysUserCode() {
+		return sysUserCode;
+	}
+
+	public void setSysUserCode(String sysUserCode) {
+		this.sysUserCode = sysUserCode;
+	}
+
+	public String getSysUserName() {
+		return sysUserName;
+	}
+
+	public void setSysUserName(String sysUserName) {
+		this.sysUserName = sysUserName;
+	}
+
+	public String getSysOrgCode() {
+		return sysOrgCode;
+	}
+
+	public void setSysOrgCode(String sysOrgCode) {
+		this.sysOrgCode = sysOrgCode;
+	}
+
+	public List<String> getSysMultiOrgCode() {
+		return sysMultiOrgCode;
+	}
+
+	public void setSysMultiOrgCode(List<String> sysMultiOrgCode) {
+		this.sysMultiOrgCode = sysMultiOrgCode;
+	}
+
+}

+ 10 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/util/BrowserType.java

@@ -0,0 +1,10 @@
+package org.jeecg.common.util;
+
+/**
+ * 
+ * @Author  张代浩
+ *
+ */
+public enum BrowserType {
+	IE11,IE10,IE9,IE8,IE7,IE6,Firefox,Safari,Chrome,Opera,Camino,Gecko
+}

+ 194 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/util/BrowserUtils.java

@@ -0,0 +1,194 @@
+package org.jeecg.common.util;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * 
+ * @Author 张代浩
+ * 
+ */
+public class BrowserUtils {
+	
+	// 判断是否是IE
+	public static boolean isIE(HttpServletRequest request) {
+		return (request.getHeader("USER-AGENT").toLowerCase().indexOf("msie") > 0 || request
+				.getHeader("USER-AGENT").toLowerCase().indexOf("rv:11.0") > 0) ? true
+				: false;
+	}
+
+	/**
+	 * 获取IE版本
+	 * 
+	 * @param request
+	 * @return
+	 */
+	public static Double getIEversion(HttpServletRequest request) {
+		Double version = 0.0;
+		if (getBrowserType(request, IE11)) {
+			version = 11.0;
+		} else if (getBrowserType(request, IE10)) {
+			version = 10.0;
+		} else if (getBrowserType(request, IE9)) {
+			version = 9.0;
+		} else if (getBrowserType(request, IE8)) {
+			version = 8.0;
+		} else if (getBrowserType(request, IE7)) {
+			version = 7.0;
+		} else if (getBrowserType(request, IE6)) {
+			version = 6.0;
+		}
+		return version;
+	}
+
+	/**
+	 * 获取浏览器类型
+	 * 
+	 * @param request
+	 * @return
+	 */
+	public static BrowserType getBrowserType(HttpServletRequest request) {
+		BrowserType browserType = null;
+		if (getBrowserType(request, IE11)) {
+			browserType = BrowserType.IE11;
+		}
+		if (getBrowserType(request, IE10)) {
+			browserType = BrowserType.IE10;
+		}
+		if (getBrowserType(request, IE9)) {
+			browserType = BrowserType.IE9;
+		}
+		if (getBrowserType(request, IE8)) {
+			browserType = BrowserType.IE8;
+		}
+		if (getBrowserType(request, IE7)) {
+			browserType = BrowserType.IE7;
+		}
+		if (getBrowserType(request, IE6)) {
+			browserType = BrowserType.IE6;
+		}
+		if (getBrowserType(request, FIREFOX)) {
+			browserType = BrowserType.Firefox;
+		}
+		if (getBrowserType(request, SAFARI)) {
+			browserType = BrowserType.Safari;
+		}
+		if (getBrowserType(request, CHROME)) {
+			browserType = BrowserType.Chrome;
+		}
+		if (getBrowserType(request, OPERA)) {
+			browserType = BrowserType.Opera;
+		}
+		if (getBrowserType(request, "Camino")) {
+			browserType = BrowserType.Camino;
+		}
+		return browserType;
+	}
+
+	private static boolean getBrowserType(HttpServletRequest request,
+			String brosertype) {
+		return request.getHeader("USER-AGENT").toLowerCase()
+				.indexOf(brosertype) > 0 ? true : false;
+	}
+
+	private final static String IE11 = "rv:11.0";
+	private final static String IE10 = "MSIE 10.0";
+	private final static String IE9 = "MSIE 9.0";
+	private final static String IE8 = "MSIE 8.0";
+	private final static String IE7 = "MSIE 7.0";
+	private final static String IE6 = "MSIE 6.0";
+	private final static String MAXTHON = "Maxthon";
+	private final static String QQ = "QQBrowser";
+	private final static String GREEN = "GreenBrowser";
+	private final static String SE360 = "360SE";
+	private final static String FIREFOX = "Firefox";
+	private final static String OPERA = "Opera";
+	private final static String CHROME = "Chrome";
+	private final static String SAFARI = "Safari";
+	private final static String OTHER = "其它";
+
+	public static String checkBrowse(HttpServletRequest request) {
+		String userAgent = request.getHeader("USER-AGENT");
+		if (regex(OPERA, userAgent)) {
+			return OPERA;
+		}
+		if (regex(CHROME, userAgent)) {
+			return CHROME;
+		}
+		if (regex(FIREFOX, userAgent)) {
+			return FIREFOX;
+		}
+		if (regex(SAFARI, userAgent)) {
+			return SAFARI;
+		}
+		if (regex(SE360, userAgent)) {
+			return SE360;
+		}
+		if (regex(GREEN, userAgent)) {
+			return GREEN;
+		}
+		if (regex(QQ, userAgent)) {
+			return QQ;
+		}
+		if (regex(MAXTHON, userAgent)) {
+			return MAXTHON;
+		}
+		if (regex(IE11, userAgent)) {
+			return IE11;
+		}
+		if (regex(IE10, userAgent)) {
+			return IE10;
+		}
+		if (regex(IE9, userAgent)) {
+			return IE9;
+		}
+		if (regex(IE8, userAgent)) {
+			return IE8;
+		}
+		if (regex(IE7, userAgent)) {
+			return IE7;
+		}
+		if (regex(IE6, userAgent)) {
+			return IE6;
+		}
+		return OTHER;
+	}
+
+	public static boolean regex(String regex, String str) {
+		Pattern p = Pattern.compile(regex, Pattern.MULTILINE);
+		Matcher m = p.matcher(str);
+		return m.find();
+	}
+
+	
+	private static Map<String, String> langMap = new HashMap<String, String>();
+	private final static String ZH = "zh";
+	private final static String ZH_CN = "zh-cn";
+	
+	private final static String EN = "en";
+	private final static String EN_US = "en";
+	
+	
+	static 
+	{
+		langMap.put(ZH, ZH_CN);
+		langMap.put(EN, EN_US);
+	}
+	
+	public static String getBrowserLanguage(HttpServletRequest request) {
+		
+		String browserLang = request.getLocale().getLanguage();
+		String browserLangCode = (String)langMap.get(browserLang);
+		
+		if(browserLangCode == null)
+		{
+			browserLangCode = EN_US;
+		}
+		return browserLangCode;
+	}
+
+}

+ 622 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/util/DateUtils.java

@@ -0,0 +1,622 @@
+package org.jeecg.common.util;
+
+import java.beans.PropertyEditorSupport;
+import java.sql.Timestamp;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+
+import org.springframework.util.StringUtils;
+
+/**
+ * 
+ * 类描述:时间操作定义类
+ * 
+ * @Author: 张代浩
+ * @Date:2012-12-8 12:15:03
+ * @Version 1.0
+ */
+public class DateUtils extends PropertyEditorSupport {
+	// 各种时间格式
+	public static final SimpleDateFormat date_sdf = new SimpleDateFormat("yyyy-MM-dd");
+	// 各种时间格式
+	public static final SimpleDateFormat yyyyMMdd = new SimpleDateFormat("yyyyMMdd");
+	// 各种时间格式
+	public static final SimpleDateFormat date_sdf_wz = new SimpleDateFormat("yyyy年MM月dd日");
+	public static final SimpleDateFormat time_sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
+	public static final SimpleDateFormat yyyymmddhhmmss = new SimpleDateFormat("yyyyMMddHHmmss");
+	public static final SimpleDateFormat short_time_sdf = new SimpleDateFormat("HH:mm");
+	public static final SimpleDateFormat datetimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+	// 以毫秒表示的时间
+	private static final long DAY_IN_MILLIS = 24 * 3600 * 1000;
+	private static final long HOUR_IN_MILLIS = 3600 * 1000;
+	private static final long MINUTE_IN_MILLIS = 60 * 1000;
+	private static final long SECOND_IN_MILLIS = 1000;
+
+	// 指定模式的时间格式
+	private static SimpleDateFormat getSDFormat(String pattern) {
+		return new SimpleDateFormat(pattern);
+	}
+
+	/**
+	 * 当前日历,这里用中国时间表示
+	 * 
+	 * @return 以当地时区表示的系统当前日历
+	 */
+	public static Calendar getCalendar() {
+		return Calendar.getInstance();
+	}
+
+	/**
+	 * 指定毫秒数表示的日历
+	 * 
+	 * @param millis 毫秒数
+	 * @return 指定毫秒数表示的日历
+	 */
+	public static Calendar getCalendar(long millis) {
+		Calendar cal = Calendar.getInstance();
+		// --------------------cal.setTimeInMillis(millis);
+		cal.setTime(new Date(millis));
+		return cal;
+	}
+
+	// ////////////////////////////////////////////////////////////////////////////
+	// getDate
+	// 各种方式获取的Date
+	// ////////////////////////////////////////////////////////////////////////////
+
+	/**
+	 * 当前日期
+	 * 
+	 * @return 系统当前时间
+	 */
+	public static Date getDate() {
+		return new Date();
+	}
+
+	/**
+	 * 指定毫秒数表示的日期
+	 * 
+	 * @param millis 毫秒数
+	 * @return 指定毫秒数表示的日期
+	 */
+	public static Date getDate(long millis) {
+		return new Date(millis);
+	}
+
+	/**
+	 * 时间戳转换为字符串
+	 * 
+	 * @param time
+	 * @return
+	 */
+	public static String timestamptoStr(Timestamp time) {
+		Date date = null;
+		if (null != time) {
+			date = new Date(time.getTime());
+		}
+		return date2Str(date_sdf);
+	}
+
+	/**
+	 * 字符串转换时间戳
+	 * 
+	 * @param str
+	 * @return
+	 */
+	public static Timestamp str2Timestamp(String str) {
+		Date date = str2Date(str, date_sdf);
+		return new Timestamp(date.getTime());
+	}
+
+	/**
+	 * 字符串转换成日期
+	 * 
+	 * @param str
+	 * @param sdf
+	 * @return
+	 */
+	public static Date str2Date(String str, SimpleDateFormat sdf) {
+		if (null == str || "".equals(str)) {
+			return null;
+		}
+		Date date = null;
+		try {
+			date = sdf.parse(str);
+			return date;
+		} catch (ParseException e) {
+			e.printStackTrace();
+		}
+		return null;
+	}
+
+	/**
+	 * 日期转换为字符串
+	 * 
+	 * @param date   日期
+	 * @param format 日期格式
+	 * @return 字符串
+	 */
+	public static String date2Str(SimpleDateFormat date_sdf) {
+		Date date = getDate();
+		if (null == date) {
+			return null;
+		}
+		return date_sdf.format(date);
+	}
+
+	/**
+	 * 格式化时间
+	 * 
+	 * @param date
+	 * @param format
+	 * @return
+	 */
+	public static String dateformat(String date, String format) {
+		SimpleDateFormat sformat = new SimpleDateFormat(format);
+		Date _date = null;
+		try {
+			_date = sformat.parse(date);
+		} catch (ParseException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		return sformat.format(_date);
+	}
+
+	/**
+	 * 日期转换为字符串
+	 * 
+	 * @param date   日期
+	 * @param format 日期格式
+	 * @return 字符串
+	 */
+	public static String date2Str(Date date, SimpleDateFormat date_sdf) {
+		if (null == date) {
+			return null;
+		}
+		return date_sdf.format(date);
+	}
+
+	/**
+	 * 日期转换为字符串
+	 * 
+	 * @param date   日期
+	 * @param format 日期格式
+	 * @return 字符串
+	 */
+	public static String getDate(String format) {
+		Date date = new Date();
+		if (null == date) {
+			return null;
+		}
+		SimpleDateFormat sdf = new SimpleDateFormat(format);
+		return sdf.format(date);
+	}
+
+	/**
+	 * 指定毫秒数的时间戳
+	 * 
+	 * @param millis 毫秒数
+	 * @return 指定毫秒数的时间戳
+	 */
+	public static Timestamp getTimestamp(long millis) {
+		return new Timestamp(millis);
+	}
+
+	/**
+	 * 以字符形式表示的时间戳
+	 * 
+	 * @param time 毫秒数
+	 * @return 以字符形式表示的时间戳
+	 */
+	public static Timestamp getTimestamp(String time) {
+		return new Timestamp(Long.parseLong(time));
+	}
+
+	/**
+	 * 系统当前的时间戳
+	 * 
+	 * @return 系统当前的时间戳
+	 */
+	public static Timestamp getTimestamp() {
+		return new Timestamp(System.currentTimeMillis());
+	}
+
+	/**
+	 * 当前时间,格式 yyyy-MM-dd HH:mm:ss
+	 * 
+	 * @return 当前时间的标准形式字符串
+	 */
+	public static String now() {
+		return datetimeFormat.format(getCalendar().getTime());
+	}
+	
+	/**
+	 * 指定日期的时间戳
+	 * 
+	 * @param date 指定日期
+	 * @return 指定日期的时间戳
+	 */
+	public static Timestamp getTimestamp(Date date) {
+		return new Timestamp(date.getTime());
+	}
+
+	/**
+	 * 指定日历的时间戳
+	 * 
+	 * @param cal 指定日历
+	 * @return 指定日历的时间戳
+	 */
+	public static Timestamp getCalendarTimestamp(Calendar cal) {
+		// ---------------------return new Timestamp(cal.getTimeInMillis());
+		return new Timestamp(cal.getTime().getTime());
+	}
+
+	public static Timestamp gettimestamp() {
+		Date dt = new Date();
+		DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+		String nowTime = df.format(dt);
+		java.sql.Timestamp buydate = java.sql.Timestamp.valueOf(nowTime);
+		return buydate;
+	}
+
+	// ////////////////////////////////////////////////////////////////////////////
+	// getMillis
+	// 各种方式获取的Millis
+	// ////////////////////////////////////////////////////////////////////////////
+
+	/**
+	 * 系统时间的毫秒数
+	 * 
+	 * @return 系统时间的毫秒数
+	 */
+	public static long getMillis() {
+		return System.currentTimeMillis();
+	}
+
+	/**
+	 * 指定日历的毫秒数
+	 * 
+	 * @param cal 指定日历
+	 * @return 指定日历的毫秒数
+	 */
+	public static long getMillis(Calendar cal) {
+		// --------------------return cal.getTimeInMillis();
+		return cal.getTime().getTime();
+	}
+
+	/**
+	 * 指定日期的毫秒数
+	 * 
+	 * @param date 指定日期
+	 * @return 指定日期的毫秒数
+	 */
+	public static long getMillis(Date date) {
+		return date.getTime();
+	}
+
+	/**
+	 * 指定时间戳的毫秒数
+	 * 
+	 * @param ts 指定时间戳
+	 * @return 指定时间戳的毫秒数
+	 */
+	public static long getMillis(Timestamp ts) {
+		return ts.getTime();
+	}
+
+	// ////////////////////////////////////////////////////////////////////////////
+	// formatDate
+	// 将日期按照一定的格式转化为字符串
+	// ////////////////////////////////////////////////////////////////////////////
+
+	/**
+	 * 默认方式表示的系统当前日期,具体格式:年-月-日
+	 * 
+	 * @return 默认日期按“年-月-日“格式显示
+	 */
+	public static String formatDate() {
+		return date_sdf.format(getCalendar().getTime());
+	}
+
+	/**
+	 * 默认方式表示的系统当前日期,具体格式:yyyy-MM-dd HH:mm:ss
+	 * 
+	 * @return 默认日期按“yyyy-MM-dd HH:mm:ss“格式显示
+	 */
+	public static String formatDateTime() {
+		return datetimeFormat.format(getCalendar().getTime());
+	}
+
+	/**
+	 * 获取时间字符串
+	 */
+	public static String getDataString(SimpleDateFormat formatstr) {
+		return formatstr.format(getCalendar().getTime());
+	}
+
+	/**
+	 * 指定日期的默认显示,具体格式:年-月-日
+	 * 
+	 * @param cal 指定的日期
+	 * @return 指定日期按“年-月-日“格式显示
+	 */
+	public static String formatDate(Calendar cal) {
+		return date_sdf.format(cal.getTime());
+	}
+
+	/**
+	 * 指定日期的默认显示,具体格式:年-月-日
+	 * 
+	 * @param date 指定的日期
+	 * @return 指定日期按“年-月-日“格式显示
+	 */
+	public static String formatDate(Date date) {
+		return date_sdf.format(date);
+	}
+
+	/**
+	 * 指定毫秒数表示日期的默认显示,具体格式:年-月-日
+	 * 
+	 * @param millis 指定的毫秒数
+	 * @return 指定毫秒数表示日期按“年-月-日“格式显示
+	 */
+	public static String formatDate(long millis) {
+		return date_sdf.format(new Date(millis));
+	}
+
+	/**
+	 * 默认日期按指定格式显示
+	 * 
+	 * @param pattern 指定的格式
+	 * @return 默认日期按指定格式显示
+	 */
+	public static String formatDate(String pattern) {
+		return getSDFormat(pattern).format(getCalendar().getTime());
+	}
+
+	/**
+	 * 指定日期按指定格式显示
+	 * 
+	 * @param cal     指定的日期
+	 * @param pattern 指定的格式
+	 * @return 指定日期按指定格式显示
+	 */
+	public static String formatDate(Calendar cal, String pattern) {
+		return getSDFormat(pattern).format(cal.getTime());
+	}
+
+	/**
+	 * 指定日期按指定格式显示
+	 * 
+	 * @param date    指定的日期
+	 * @param pattern 指定的格式
+	 * @return 指定日期按指定格式显示
+	 */
+	public static String formatDate(Date date, String pattern) {
+		return getSDFormat(pattern).format(date);
+	}
+
+	// ////////////////////////////////////////////////////////////////////////////
+	// formatTime
+	// 将日期按照一定的格式转化为字符串
+	// ////////////////////////////////////////////////////////////////////////////
+
+	/**
+	 * 默认方式表示的系统当前日期,具体格式:年-月-日 时:分
+	 * 
+	 * @return 默认日期按“年-月-日 时:分“格式显示
+	 */
+	public static String formatTime() {
+		return time_sdf.format(getCalendar().getTime());
+	}
+
+	/**
+	 * 指定毫秒数表示日期的默认显示,具体格式:年-月-日 时:分
+	 * 
+	 * @param millis 指定的毫秒数
+	 * @return 指定毫秒数表示日期按“年-月-日 时:分“格式显示
+	 */
+	public static String formatTime(long millis) {
+		return time_sdf.format(new Date(millis));
+	}
+
+	/**
+	 * 指定日期的默认显示,具体格式:年-月-日 时:分
+	 * 
+	 * @param cal 指定的日期
+	 * @return 指定日期按“年-月-日 时:分“格式显示
+	 */
+	public static String formatTime(Calendar cal) {
+		return time_sdf.format(cal.getTime());
+	}
+
+	/**
+	 * 指定日期的默认显示,具体格式:年-月-日 时:分
+	 * 
+	 * @param date 指定的日期
+	 * @return 指定日期按“年-月-日 时:分“格式显示
+	 */
+	public static String formatTime(Date date) {
+		return time_sdf.format(date);
+	}
+
+	// ////////////////////////////////////////////////////////////////////////////
+	// formatShortTime
+	// 将日期按照一定的格式转化为字符串
+	// ////////////////////////////////////////////////////////////////////////////
+
+	/**
+	 * 默认方式表示的系统当前日期,具体格式:时:分
+	 * 
+	 * @return 默认日期按“时:分“格式显示
+	 */
+	public static String formatShortTime() {
+		return short_time_sdf.format(getCalendar().getTime());
+	}
+
+	/**
+	 * 指定毫秒数表示日期的默认显示,具体格式:时:分
+	 * 
+	 * @param millis 指定的毫秒数
+	 * @return 指定毫秒数表示日期按“时:分“格式显示
+	 */
+	public static String formatShortTime(long millis) {
+		return short_time_sdf.format(new Date(millis));
+	}
+
+	/**
+	 * 指定日期的默认显示,具体格式:时:分
+	 * 
+	 * @param cal 指定的日期
+	 * @return 指定日期按“时:分“格式显示
+	 */
+	public static String formatShortTime(Calendar cal) {
+		return short_time_sdf.format(cal.getTime());
+	}
+
+	/**
+	 * 指定日期的默认显示,具体格式:时:分
+	 * 
+	 * @param date 指定的日期
+	 * @return 指定日期按“时:分“格式显示
+	 */
+	public static String formatShortTime(Date date) {
+		return short_time_sdf.format(date);
+	}
+
+	// ////////////////////////////////////////////////////////////////////////////
+	// parseDate
+	// parseCalendar
+	// parseTimestamp
+	// 将字符串按照一定的格式转化为日期或时间
+	// ////////////////////////////////////////////////////////////////////////////
+
+	/**
+	 * 根据指定的格式将字符串转换成Date 如输入:2003-11-19 11:20:20将按照这个转成时间
+	 * 
+	 * @param src     将要转换的原始字符窜
+	 * @param pattern 转换的匹配格式
+	 * @return 如果转换成功则返回转换后的日期
+	 * @throws ParseException
+	 * @throws AIDateFormatException
+	 */
+	public static Date parseDate(String src, String pattern) throws ParseException {
+		return getSDFormat(pattern).parse(src);
+
+	}
+
+	/**
+	 * 根据指定的格式将字符串转换成Date 如输入:2003-11-19 11:20:20将按照这个转成时间
+	 * 
+	 * @param src     将要转换的原始字符窜
+	 * @param pattern 转换的匹配格式
+	 * @return 如果转换成功则返回转换后的日期
+	 * @throws ParseException
+	 * @throws AIDateFormatException
+	 */
+	public static Calendar parseCalendar(String src, String pattern) throws ParseException {
+
+		Date date = parseDate(src, pattern);
+		Calendar cal = Calendar.getInstance();
+		cal.setTime(date);
+		return cal;
+	}
+
+	public static String formatAddDate(String src, String pattern, int amount) throws ParseException {
+		Calendar cal;
+		cal = parseCalendar(src, pattern);
+		cal.add(Calendar.DATE, amount);
+		return formatDate(cal);
+	}
+
+	/**
+	 * 根据指定的格式将字符串转换成Date 如输入:2003-11-19 11:20:20将按照这个转成时间
+	 * 
+	 * @param src     将要转换的原始字符窜
+	 * @param pattern 转换的匹配格式
+	 * @return 如果转换成功则返回转换后的时间戳
+	 * @throws ParseException
+	 * @throws AIDateFormatException
+	 */
+	public static Timestamp parseTimestamp(String src, String pattern) throws ParseException {
+		Date date = parseDate(src, pattern);
+		return new Timestamp(date.getTime());
+	}
+
+	// ////////////////////////////////////////////////////////////////////////////
+	// dateDiff
+	// 计算两个日期之间的差值
+	// ////////////////////////////////////////////////////////////////////////////
+
+	/**
+	 * 计算两个时间之间的差值,根据标志的不同而不同
+	 * 
+	 * @param flag   计算标志,表示按照年/月/日/时/分/秒等计算
+	 * @param calSrc 减数
+	 * @param calDes 被减数
+	 * @return 两个日期之间的差值
+	 */
+	public static int dateDiff(char flag, Calendar calSrc, Calendar calDes) {
+
+		long millisDiff = getMillis(calSrc) - getMillis(calDes);
+
+		if (flag == 'y') {
+			return (calSrc.get(calSrc.YEAR) - calDes.get(calDes.YEAR));
+		}
+
+		if (flag == 'd') {
+			return (int) (millisDiff / DAY_IN_MILLIS);
+		}
+
+		if (flag == 'h') {
+			return (int) (millisDiff / HOUR_IN_MILLIS);
+		}
+
+		if (flag == 'm') {
+			return (int) (millisDiff / MINUTE_IN_MILLIS);
+		}
+
+		if (flag == 's') {
+			return (int) (millisDiff / SECOND_IN_MILLIS);
+		}
+
+		return 0;
+	}
+
+	/**
+	 * String类型 转换为Date, 如果参数长度为10 转换格式”yyyy-MM-dd“ 如果参数长度为19 转换格式”yyyy-MM-dd
+	 * HH:mm:ss“ * @param text String类型的时间值
+	 */
+	@Override
+	public void setAsText(String text) throws IllegalArgumentException {
+		if (StringUtils.hasText(text)) {
+			try {
+				if (text.indexOf(":") == -1 && text.length() == 10) {
+					setValue(this.date_sdf.parse(text));
+				} else if (text.indexOf(":") > 0 && text.length() == 19) {
+					setValue(this.datetimeFormat.parse(text));
+				} else {
+					throw new IllegalArgumentException("Could not parse date, date format is error ");
+				}
+			} catch (ParseException ex) {
+				IllegalArgumentException iae = new IllegalArgumentException("Could not parse date: " + ex.getMessage());
+				iae.initCause(ex);
+				throw iae;
+			}
+		} else {
+			setValue(null);
+		}
+	}
+
+	public static int getYear() {
+		GregorianCalendar calendar = new GregorianCalendar();
+		calendar.setTime(getDate());
+		return calendar.get(Calendar.YEAR);
+	}
+
+}

+ 105 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/util/DySmsHelper.java

@@ -0,0 +1,105 @@
+package org.jeecg.common.util;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import com.aliyuncs.DefaultAcsClient;
+import com.aliyuncs.IAcsClient;
+import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
+import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
+import com.aliyuncs.exceptions.ClientException;
+import com.aliyuncs.profile.DefaultProfile;
+import com.aliyuncs.profile.IClientProfile;
+
+/**
+ * Created on 17/6/7.
+ * 短信API产品的DEMO程序,工程中包含了一个SmsDemo类,直接通过
+ * 执行main函数即可体验短信产品API功能(只需要将AK替换成开通了云通信-短信产品功能的AK即可)
+ * 工程依赖了2个jar包(存放在工程的libs目录下)
+ * 1:aliyun-java-sdk-core.jar
+ * 2:aliyun-java-sdk-dysmsapi.jar
+ *
+ * 备注:Demo工程编码采用UTF-8
+ * 国际短信发送请勿参照此DEMO
+ */
+public class DySmsHelper {
+
+	private final static Logger logger=LoggerFactory.getLogger(DySmsHelper.class);
+
+    //产品名称:云通信短信API产品,开发者无需替换
+    static final String product = "Dysmsapi";
+    //产品域名,开发者无需替换
+    static final String domain = "dysmsapi.aliyuncs.com";
+
+    // TODO 此处需要替换成开发者自己的AK(在阿里云访问控制台寻找)
+    static final String accessKeyId = "?";
+    static final String accessKeySecret = "?";
+
+    /**
+         * 登陆时采用的短信发送模板编码
+     */
+    public static final String LOGIN_TEMPLATE_CODE="SMS_167040816";
+
+    /**
+     * 忘记密码时采用的短信发送模板编码
+     */
+    public static final String FORGET_PASSWORD_TEMPLATE_CODE="SMS_167040816";
+
+
+    /**
+     * 注册时采用的短信发送模板编码
+     */
+    public static final String REGISTER_TEMPLATE_CODE="SMS_144146309";
+
+    /**
+         * 必填:短信签名-可在短信控制台中找到
+     */
+    public static final String signName="JEECG";
+
+
+    public static boolean sendSms(String phone,String code,String templateCode) throws ClientException {
+    	//可自助调整超时时间
+        System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
+        System.setProperty("sun.net.client.defaultReadTimeout", "10000");
+
+        //初始化acsClient,暂不支持region化
+        IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
+        DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
+        IAcsClient acsClient = new DefaultAcsClient(profile);
+
+        //组装请求对象-具体描述见控制台-文档部分内容
+        SendSmsRequest request = new SendSmsRequest();
+        //必填:待发送手机号
+        request.setPhoneNumbers(phone);
+        //必填:短信签名-可在短信控制台中找到
+        request.setSignName(signName);
+        //必填:短信模板-可在短信控制台中找到
+        request.setTemplateCode("SMS_167040816");
+        //可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
+        request.setTemplateParam("{\"code\":\""+code+"\"}");
+
+        //选填-上行短信扩展码(无特殊需求用户请忽略此字段)
+        //request.setSmsUpExtendCode("90997");
+
+        //可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
+        //request.setOutId("yourOutId");
+
+        boolean result = false;
+
+        //hint 此处可能会抛出异常,注意catch
+        SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
+        logger.info("短信接口返回的数据----------------");
+        logger.info("{Code:" + sendSmsResponse.getCode()+",Message:" + sendSmsResponse.getMessage()+",RequestId:"+ sendSmsResponse.getRequestId()+",BizId:"+sendSmsResponse.getBizId()+"}");
+        if ("OK".equals(sendSmsResponse.getCode())) {
+            result = true;
+        }
+        return result;
+
+    }
+
+
+    public static void main(String[] args) throws ClientException, InterruptedException {
+
+    	sendSms("13800138000", "123456", FORGET_PASSWORD_TEMPLATE_CODE);
+
+    }
+}

+ 58 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/util/IPUtils.java

@@ -0,0 +1,58 @@
+package org.jeecg.common.util;
+
+
+import com.alibaba.druid.util.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.http.HttpServletRequest;
+/**
+ * IP地址
+ * 
+ * @Author scott
+ * @email jeecgos@163.com
+ * @Date 2019年01月14日
+ */
+public class IPUtils {
+	private static Logger logger = LoggerFactory.getLogger(IPUtils.class);
+
+	/**
+	 * 获取IP地址
+	 * 
+	 * 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址
+	 * 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址
+	 */
+	public static String getIpAddr(HttpServletRequest request) {
+    	String ip = null;
+        try {
+            ip = request.getHeader("x-forwarded-for");
+            if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
+                ip = request.getHeader("Proxy-Client-IP");
+            }
+            if (StringUtils.isEmpty(ip) || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+                ip = request.getHeader("WL-Proxy-Client-IP");
+            }
+            if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
+                ip = request.getHeader("HTTP_CLIENT_IP");
+            }
+            if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
+                ip = request.getHeader("HTTP_X_FORWARDED_FOR");
+            }
+            if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
+                ip = request.getRemoteAddr();
+            }
+        } catch (Exception e) {
+        	logger.error("IPUtils ERROR ", e);
+        }
+        
+//        //使用代理,则获取第一个IP地址
+//        if(StringUtils.isEmpty(ip) && ip.length() > 15) {
+//			if(ip.indexOf(",") > 0) {
+//				ip = ip.substring(0, ip.indexOf(","));
+//			}
+//		}
+        
+        return ip;
+    }
+	
+}

+ 43 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/util/MD5Util.java

@@ -0,0 +1,43 @@
+package org.jeecg.common.util;
+
+import java.security.MessageDigest;
+
+public class MD5Util {
+
+	public static String byteArrayToHexString(byte b[]) {
+		StringBuffer resultSb = new StringBuffer();
+		for (int i = 0; i < b.length; i++){
+			resultSb.append(byteToHexString(b[i]));
+		}
+		return resultSb.toString();
+	}
+
+	private static String byteToHexString(byte b) {
+		int n = b;
+		if (n < 0) {
+			n += 256;
+		}
+		int d1 = n / 16;
+		int d2 = n % 16;
+		return hexDigits[d1] + hexDigits[d2];
+	}
+
+	public static String MD5Encode(String origin, String charsetname) {
+		String resultString = null;
+		try {
+			resultString = new String(origin);
+			MessageDigest md = MessageDigest.getInstance("MD5");
+			if (charsetname == null || "".equals(charsetname)) {
+				resultString = byteArrayToHexString(md.digest(resultString.getBytes()));
+			} else {
+				resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname)));
+			}
+		} catch (Exception exception) {
+		}
+		return resultString;
+	}
+
+	private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5",
+			"6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
+
+}

+ 92 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/util/MyClassLoader.java

@@ -0,0 +1,92 @@
+package org.jeecg.common.util;
+
+/**
+ * @Author  张代浩
+ */
+public class MyClassLoader extends ClassLoader {
+	public static Class getClassByScn(String className) {
+		Class myclass = null;
+		try {
+			myclass = Class.forName(className);
+		} catch (ClassNotFoundException e) {
+			e.printStackTrace();
+			throw new RuntimeException(className+" not found!");
+		}
+		return myclass;
+	}
+
+	// 获得类的全名,包括包名
+	public static String getPackPath(Object object) {
+		// 检查用户传入的参数是否为空
+		if (object == null) {
+			throw new java.lang.IllegalArgumentException("参数不能为空!");
+		}
+		// 获得类的全名,包括包名
+		String clsName = object.getClass().getName();
+		return clsName;
+	}
+
+	public static String getAppPath(Class cls) {
+		// 检查用户传入的参数是否为空
+		if (cls == null) {
+			throw new java.lang.IllegalArgumentException("参数不能为空!");
+		}
+		ClassLoader loader = cls.getClassLoader();
+		// 获得类的全名,包括包名
+		String clsName = cls.getName() + ".class";
+		// 获得传入参数所在的包
+		Package pack = cls.getPackage();
+		String path = "";
+		// 如果不是匿名包,将包名转化为路径
+		if (pack != null) {
+			String packName = pack.getName();
+			// 此处简单判定是否是Java基础类库,防止用户传入JDK内置的类库
+			if (packName.startsWith("java.") || packName.startsWith("javax.")) {
+				throw new java.lang.IllegalArgumentException("不要传送系统类!");
+			}
+			// 在类的名称中,去掉包名的部分,获得类的文件名
+			clsName = clsName.substring(packName.length() + 1);
+			// 判定包名是否是简单包名,如果是,则直接将包名转换为路径,
+			if (packName.indexOf(".") < 0) {
+				path = packName + "/";
+			} else {// 否则按照包名的组成部分,将包名转换为路径
+				int start = 0, end = 0;
+				end = packName.indexOf(".");
+				while (end != -1) {
+					path = path + packName.substring(start, end) + "/";
+					start = end + 1;
+					end = packName.indexOf(".", start);
+				}
+				path = path + packName.substring(start) + "/";
+			}
+		}
+		// 调用ClassLoader的getResource方法,传入包含路径信息的类文件名
+		java.net.URL url = loader.getResource(path + clsName);
+		// 从URL对象中获取路径信息
+		String realPath = url.getPath();
+		// 去掉路径信息中的协议名"file:"
+		int pos = realPath.indexOf("file:");
+		if (pos > -1) {
+			realPath = realPath.substring(pos + 5);
+		}
+		// 去掉路径信息最后包含类文件信息的部分,得到类所在的路径
+		pos = realPath.indexOf(path + clsName);
+		realPath = realPath.substring(0, pos - 1);
+		// 如果类文件被打包到JAR等文件中时,去掉对应的JAR等打包文件名
+		if (realPath.endsWith("!")) {
+			realPath = realPath.substring(0, realPath.lastIndexOf("/"));
+		}
+		/*------------------------------------------------------------  
+		 ClassLoader的getResource方法使用了utf-8对路径信息进行了编码,当路径  
+		  中存在中文和空格时,他会对这些字符进行转换,这样,得到的往往不是我们想要  
+		  的真实路径,在此,调用了URLDecoder的decode方法进行解码,以便得到原始的  
+		  中文及空格路径  
+		-------------------------------------------------------------*/
+		try {
+			realPath = java.net.URLDecoder.decode(realPath, "utf-8");
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+		return realPath;
+	}// getAppPath定义结束
+}

+ 179 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/util/PasswordUtil.java

@@ -0,0 +1,179 @@
+package org.jeecg.common.util;
+
+import java.security.Key;
+import java.security.SecureRandom;
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
+import javax.crypto.spec.PBEParameterSpec;
+public class PasswordUtil {
+
+	/**
+	 * JAVA6支持以下任意一种算法 PBEWITHMD5ANDDES PBEWITHMD5ANDTRIPLEDES
+	 * PBEWITHSHAANDDESEDE PBEWITHSHA1ANDRC2_40 PBKDF2WITHHMACSHA1
+	 * */
+
+	/**
+	 * 定义使用的算法为:PBEWITHMD5andDES算法
+	 */
+	public static final String ALGORITHM = "PBEWithMD5AndDES";//加密算法
+	public static final String Salt = "63293188";//密钥
+
+	/**
+	 * 定义迭代次数为1000次
+	 */
+	private static final int ITERATIONCOUNT = 1000;
+
+	/**
+	 * 获取加密算法中使用的盐值,解密中使用的盐值必须与加密中使用的相同才能完成操作. 盐长度必须为8字节
+	 * 
+	 * @return byte[] 盐值
+	 * */
+	public static byte[] getSalt() throws Exception {
+		// 实例化安全随机数
+		SecureRandom random = new SecureRandom();
+		// 产出盐
+		return random.generateSeed(8);
+	}
+
+	public static byte[] getStaticSalt() {
+		// 产出盐
+		return Salt.getBytes();
+	}
+
+	/**
+	 * 根据PBE密码生成一把密钥
+	 * 
+	 * @param password
+	 *            生成密钥时所使用的密码
+	 * @return Key PBE算法密钥
+	 * */
+	private static Key getPBEKey(String password) {
+		// 实例化使用的算法
+		SecretKeyFactory keyFactory;
+		SecretKey secretKey = null;
+		try {
+			keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
+			// 设置PBE密钥参数
+			PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
+			// 生成密钥
+			secretKey = keyFactory.generateSecret(keySpec);
+		} catch (Exception e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+
+		return secretKey;
+	}
+
+	/**
+	 * 加密明文字符串
+	 * 
+	 * @param plaintext
+	 *            待加密的明文字符串
+	 * @param password
+	 *            生成密钥时所使用的密码
+	 * @param salt
+	 *            盐值
+	 * @return 加密后的密文字符串
+	 * @throws Exception
+	 */
+	public static String encrypt(String plaintext, String password, String salt) {
+
+		Key key = getPBEKey(password);
+		byte[] encipheredData = null;
+		PBEParameterSpec parameterSpec = new PBEParameterSpec(salt.getBytes(), ITERATIONCOUNT);
+		try {
+			Cipher cipher = Cipher.getInstance(ALGORITHM);
+
+			cipher.init(Cipher.ENCRYPT_MODE, key, parameterSpec);
+
+			encipheredData = cipher.doFinal(plaintext.getBytes());
+		} catch (Exception e) {
+		}
+		return bytesToHexString(encipheredData);
+	}
+
+	/**
+	 * 解密密文字符串
+	 * 
+	 * @param ciphertext
+	 *            待解密的密文字符串
+	 * @param password
+	 *            生成密钥时所使用的密码(如需解密,该参数需要与加密时使用的一致)
+	 * @param salt
+	 *            盐值(如需解密,该参数需要与加密时使用的一致)
+	 * @return 解密后的明文字符串
+	 * @throws Exception
+	 */
+	public static String decrypt(String ciphertext, String password, String salt) {
+
+		Key key = getPBEKey(password);
+		byte[] passDec = null;
+		PBEParameterSpec parameterSpec = new PBEParameterSpec(salt.getBytes(), ITERATIONCOUNT);
+		try {
+			Cipher cipher = Cipher.getInstance(ALGORITHM);
+
+			cipher.init(Cipher.DECRYPT_MODE, key, parameterSpec);
+
+			passDec = cipher.doFinal(hexStringToBytes(ciphertext));
+		}
+
+		catch (Exception e) {
+			// TODO: handle exception
+		}
+		return new String(passDec);
+	}
+
+	/**
+	 * 将字节数组转换为十六进制字符串
+	 * 
+	 * @param src
+	 *            字节数组
+	 * @return
+	 */
+	public static String bytesToHexString(byte[] src) {
+		StringBuilder stringBuilder = new StringBuilder("");
+		if (src == null || src.length <= 0) {
+			return null;
+		}
+		for (int i = 0; i < src.length; i++) {
+			int v = src[i] & 0xFF;
+			String hv = Integer.toHexString(v);
+			if (hv.length() < 2) {
+				stringBuilder.append(0);
+			}
+			stringBuilder.append(hv);
+		}
+		return stringBuilder.toString();
+	}
+
+	/**
+	 * 将十六进制字符串转换为字节数组
+	 * 
+	 * @param hexString
+	 *            十六进制字符串
+	 * @return
+	 */
+	public static byte[] hexStringToBytes(String hexString) {
+		if (hexString == null || hexString.equals("")) {
+			return null;
+		}
+		hexString = hexString.toUpperCase();
+		int length = hexString.length() / 2;
+		char[] hexChars = hexString.toCharArray();
+		byte[] d = new byte[length];
+		for (int i = 0; i < length; i++) {
+			int pos = i * 2;
+			d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
+		}
+		return d;
+	}
+
+	private static byte charToByte(char c) {
+		return (byte) "0123456789ABCDEF".indexOf(c);
+	}
+
+
+}

+ 574 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/util/RedisUtil.java

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

+ 84 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/util/SpringContextUtils.java

@@ -0,0 +1,84 @@
+package org.jeecg.common.util;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+@Component
+public class SpringContextUtils implements ApplicationContextAware {
+
+	/**
+	 * 上下文对象实例
+	 */
+	private static ApplicationContext applicationContext;
+
+	@Override
+	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+		this.applicationContext = applicationContext;
+	}
+
+	/**
+	 * 获取applicationContext
+	 *
+	 * @return
+	 */
+	public static ApplicationContext getApplicationContext() {
+		return applicationContext;
+	}
+
+	/**
+	  * 获取HttpServletRequest
+	 */
+	public static HttpServletRequest getHttpServletRequest() {
+		return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+	}
+
+	public static String getDomain(){
+		HttpServletRequest request = getHttpServletRequest();
+		StringBuffer url = request.getRequestURL();
+		return url.delete(url.length() - request.getRequestURI().length(), url.length()).toString();
+	}
+
+	public static String getOrigin(){
+		HttpServletRequest request = getHttpServletRequest();
+		return request.getHeader("Origin");
+	}
+	
+	/**
+	 * 通过name获取 Bean.
+	 *
+	 * @param name
+	 * @return
+	 */
+	public static Object getBean(String name) {
+		return getApplicationContext().getBean(name);
+	}
+
+	/**
+	 * 通过class获取Bean.
+	 *
+	 * @param clazz
+	 * @param       <T>
+	 * @return
+	 */
+	public static <T> T getBean(Class<T> clazz) {
+		return getApplicationContext().getBean(clazz);
+	}
+
+	/**
+	 * 通过name,以及Clazz返回指定的Bean
+	 *
+	 * @param name
+	 * @param clazz
+	 * @param       <T>
+	 * @return
+	 */
+	public static <T> T getBean(String name, Class<T> clazz) {
+		return getApplicationContext().getBean(name, clazz);
+	}
+}

+ 80 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/util/SqlInjectionUtil.java

@@ -0,0 +1,80 @@
+package org.jeecg.common.util;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * sql注入处理工具类
+ * 
+ * @author zhoujf
+ */
+@Slf4j
+public class SqlInjectionUtil {
+	final static String xssStr = "'|and |exec |insert |select |delete |update |drop |count |chr |mid |master |truncate |char |declare |;|or |+|,";
+
+	/**
+	 * sql注入过滤处理,遇到注入关键字抛异常
+	 * 
+	 * @param value
+	 * @return
+	 */
+	public static void filterContent(String value) {
+		if (value == null || "".equals(value)) {
+			return;
+		}
+		value = value.toLowerCase();// 统一转为小写
+		String[] xssArr = xssStr.split("\\|");
+		for (int i = 0; i < xssArr.length; i++) {
+			if (value.indexOf(xssArr[i]) > -1) {
+				log.error("请注意,值可能存在SQL注入风险!---> {}", value);
+				throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
+			}
+		}
+		return;
+	}
+
+	/**
+	 * sql注入过滤处理,遇到注入关键字抛异常
+	 * 
+	 * @param value
+	 * @return
+	 */
+	public static void filterContent(String[] values) {
+		String[] xssArr = xssStr.split("\\|");
+		for (String value : values) {
+			if (value == null || "".equals(value)) {
+				return;
+			}
+			value = value.toLowerCase();// 统一转为小写
+			for (int i = 0; i < xssArr.length; i++) {
+				if (value.indexOf(xssArr[i]) > -1) {
+					log.error("请注意,值可能存在SQL注入风险!---> {}", value);
+					throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
+				}
+			}
+		}
+		return;
+	}
+
+	/**
+	 * @特殊方法(不通用) 仅用于字典条件SQL参数,注入过滤
+	 * @param value
+	 * @return
+	 */
+	@Deprecated
+	public static void specialFilterContent(String value) {
+		String specialXssStr = "exec |insert |select |delete |update |drop |count |chr |mid |master |truncate |char |declare |;|+|,";
+		String[] xssArr = specialXssStr.split("\\|");
+		if (value == null || "".equals(value)) {
+			return;
+		}
+		value = value.toLowerCase();// 统一转为小写
+		for (int i = 0; i < xssArr.length; i++) {
+			if (value.indexOf(xssArr[i]) > -1) {
+				log.error("请注意,值可能存在SQL注入风险!---> {}", value);
+				throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value);
+			}
+		}
+		return;
+	}
+
+}

+ 95 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/util/UUIDGenerator.java

@@ -0,0 +1,95 @@
+package org.jeecg.common.util;
+
+
+import java.net.InetAddress;
+
+/**
+ * 
+ * @Author  张代浩
+ *
+ */
+public class UUIDGenerator {
+
+	
+	/**
+	 * 产生一个32位的UUID
+	 * 
+	 * @return
+	 */
+
+	public static String generate() {
+		return new StringBuilder(32).append(format(getIP())).append(
+				format(getJVM())).append(format(getHiTime())).append(
+				format(getLoTime())).append(format(getCount())).toString();
+		
+	}
+
+	private static final int IP;
+	static {
+		int ipadd;
+		try {
+			ipadd = toInt(InetAddress.getLocalHost().getAddress());
+		} catch (Exception e) {
+			ipadd = 0;
+		}
+		IP = ipadd;
+	}
+
+	private static short counter = (short) 0;
+
+	private static final int JVM = (int) (System.currentTimeMillis() >>> 8);
+
+	private final static String format(int intval) {
+		String formatted = Integer.toHexString(intval);
+		StringBuilder buf = new StringBuilder("00000000");
+		buf.replace(8 - formatted.length(), 8, formatted);
+		return buf.toString();
+	}
+
+	private final static String format(short shortval) {
+		String formatted = Integer.toHexString(shortval);
+		StringBuilder buf = new StringBuilder("0000");
+		buf.replace(4 - formatted.length(), 4, formatted);
+		return buf.toString();
+	}
+
+	private final static int getJVM() {
+		return JVM;
+	}
+
+	private final static short getCount() {
+		synchronized (UUIDGenerator.class) {
+			if (counter < 0) {
+				counter = 0;
+			}
+			return counter++;
+		}
+	}
+
+	/**
+	 * Unique in a local network
+	 */
+	private final static int getIP() {
+		return IP;
+	}
+
+	/**
+	 * Unique down to millisecond
+	 */
+	private final static short getHiTime() {
+		return (short) (System.currentTimeMillis() >>> 32);
+	}
+
+	private final static int getLoTime() {
+		return (int) System.currentTimeMillis();
+	}
+
+	private final static int toInt(byte[] bytes) {
+		int result = 0;
+		for (int i = 0; i < 4; i++) {
+			result = (result << 8) - Byte.MIN_VALUE + (int) bytes[i];
+		}
+		return result;
+	}
+
+}

+ 173 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/util/YouBianCodeUtil.java

@@ -0,0 +1,173 @@
+package org.jeecg.common.util;
+
+import io.netty.util.internal.StringUtil;
+
+/**
+ * 流水号生成规则(按默认规则递增,数字从1-99开始递增,数字到99,递增字母;位数不够增加位数)
+ * A001
+ * A001A002
+ * @Author zhangdaihao
+ *
+ */
+public class YouBianCodeUtil {
+
+	// 数字位数(默认生成3位的数字)
+
+	private static final int numLength = 2;//代表数字位数
+
+	public static final int zhanweiLength = 1+numLength;
+
+	/**
+	 * 根据前一个code,获取同级下一个code
+	 * 例如:当前最大code为D01A04,下一个code为:D01A05
+	 * 
+	 * @param code
+	 * @return
+	 */
+	public static synchronized String getNextYouBianCode(String code) {
+		String newcode = "";
+		if (code == null || code =="") {
+			String zimu = "A";
+			String num = getStrNum(1);
+			newcode = zimu + num;
+		} else {
+			String before_code = code.substring(0, code.length() - 1- numLength);
+			String after_code = code.substring(code.length() - 1 - numLength,code.length());
+			char after_code_zimu = after_code.substring(0, 1).charAt(0);
+			Integer after_code_num = Integer.parseInt(after_code.substring(1));
+//			org.jeecgframework.core.util.LogUtil.info(after_code);
+//			org.jeecgframework.core.util.LogUtil.info(after_code_zimu);
+//			org.jeecgframework.core.util.LogUtil.info(after_code_num);
+
+			String nextNum = "";
+			char nextZimu = 'A';
+			// 先判断数字等于999*,则计数从1重新开始,递增
+			if (after_code_num == getMaxNumByLength(numLength)) {
+				nextNum = getNextStrNum(0);
+			} else {
+				nextNum = getNextStrNum(after_code_num);
+			}
+			// 先判断数字等于999*,则字母从A重新开始,递增
+			if(after_code_num == getMaxNumByLength(numLength)) {
+				nextZimu = getNextZiMu(after_code_zimu);
+			}else{
+				nextZimu = after_code_zimu;
+			}
+
+			// 例如Z99,下一个code就是Z99A01
+			if ('Z' == after_code_zimu && getMaxNumByLength(numLength) == after_code_num) {
+				newcode = code + (nextZimu + nextNum);
+			} else {
+				newcode = before_code + (nextZimu + nextNum);
+			}
+		}
+		return newcode;
+
+	}
+
+	/**
+	 * 根据父亲code,获取下级的下一个code
+	 * 
+	 * 例如:父亲CODE:A01
+	 *       当前CODE:A01B03
+	 *       获取的code:A01B04
+	 *       
+	 * @param parentCode   上级code
+	 * @param localCode    同级code
+	 * @return
+	 */
+	public static synchronized String getSubYouBianCode(String parentCode,String localCode) {
+		if(localCode!=null && localCode!=""){
+
+//			return parentCode + getNextYouBianCode(localCode);
+			return getNextYouBianCode(localCode);
+
+		}else{
+			parentCode = parentCode + "A"+ getNextStrNum(0);
+		}
+		return parentCode;
+	}
+
+	
+
+	/**
+	 * 将数字前面位数补零
+	 * 
+	 * @param num
+	 * @return
+	 */
+	private static String getNextStrNum(int num) {
+		return getStrNum(getNextNum(num));
+	}
+
+	/**
+	 * 将数字前面位数补零
+	 * 
+	 * @param num
+	 * @return
+	 */
+	private static String getStrNum(int num) {
+		String s = String.format("%0" + numLength + "d", num);
+		return s;
+	}
+
+	/**
+	 * 递增获取下个数字
+	 * 
+	 * @param num
+	 * @return
+	 */
+	private static int getNextNum(int num) {
+		num++;
+		return num;
+	}
+
+	/**
+	 * 递增获取下个字母
+	 * 
+	 * @param num
+	 * @return
+	 */
+	private static char getNextZiMu(char zimu) {
+		if (zimu == 'Z') {
+			return 'A';
+		}
+		zimu++;
+		return zimu;
+	}
+	
+	/**
+	 * 根据数字位数获取最大值
+	 * @param length
+	 * @return
+	 */
+	private static int getMaxNumByLength(int length){
+		if(length==0){
+			return 0;
+		}
+		String max_num = "";
+		for (int i=0;i<length;i++){
+			max_num = max_num + "9";
+		}
+		return Integer.parseInt(max_num);
+	}
+	public static String[] cutYouBianCode(String code){
+		if(code==null || StringUtil.isNullOrEmpty(code)){
+			return null;
+		}else{
+			//获取标准长度为numLength+1,截取的数量为code.length/numLength+1
+			int c = code.length()/(numLength+1);
+			String[] cutcode = new String[c];
+			for(int i =0 ; i <c;i++){
+				cutcode[i] = code.substring(0,(i+1)*(numLength+1));
+			}
+			return cutcode;
+		}
+		
+	}
+	public static void main(String[] args) {
+		// org.jeecgframework.core.util.LogUtil.info(getNextZiMu('C'));
+		// org.jeecgframework.core.util.LogUtil.info(getNextNum(8));
+	    // org.jeecgframework.core.util.LogUtil.info(cutYouBianCode("C99A01B01")[2]);
+	}
+}

+ 124 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/util/encryption/AesEncryptUtil.java

@@ -0,0 +1,124 @@
+package org.jeecg.common.util.encryption;
+
+import org.apache.shiro.codec.Base64;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+
+/**
+ * AES 加密
+ */
+public class AesEncryptUtil {
+
+    //使用AES-128-CBC加密模式,key需要为16位,key和iv可以相同!
+    private static String KEY = EncryptedString.key;
+
+    private static String IV = EncryptedString.iv;
+
+    /**
+     * 加密方法
+     * @param data  要加密的数据
+     * @param key 加密key
+     * @param iv 加密iv
+     * @return 加密的结果
+     * @throws Exception
+     */
+    public static String encrypt(String data, String key, String iv) throws Exception {
+        try {
+
+            Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");//"算法/模式/补码方式"NoPadding PkcsPadding
+            int blockSize = cipher.getBlockSize();
+
+            byte[] dataBytes = data.getBytes();
+            int plaintextLength = dataBytes.length;
+            if (plaintextLength % blockSize != 0) {
+                plaintextLength = plaintextLength + (blockSize - (plaintextLength % blockSize));
+            }
+
+            byte[] plaintext = new byte[plaintextLength];
+            System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length);
+
+            SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
+            IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
+
+            cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
+            byte[] encrypted = cipher.doFinal(plaintext);
+
+            return new Base64().encodeToString(encrypted);
+
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    /**
+     * 解密方法
+     * @param data 要解密的数据
+     * @param key  解密key
+     * @param iv 解密iv
+     * @return 解密的结果
+     * @throws Exception
+     */
+    public static String desEncrypt(String data, String key, String iv) throws Exception {
+        try {
+            byte[] encrypted1 = new Base64().decode(data);
+
+            Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
+            SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
+            IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
+
+            cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
+
+            byte[] original = cipher.doFinal(encrypted1);
+            String originalString = new String(original);
+            return originalString;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    /**
+     * 使用默认的key和iv加密
+     * @param data
+     * @return
+     * @throws Exception
+     */
+    public static String encrypt(String data) throws Exception {
+        return encrypt(data, KEY, IV);
+    }
+
+    /**
+     * 使用默认的key和iv解密
+     * @param data
+     * @return
+     * @throws Exception
+     */
+    public static String desEncrypt(String data) throws Exception {
+        return desEncrypt(data, KEY, IV);
+    }
+
+
+
+    /**
+     * 测试
+     */
+    public static void main(String args[]) throws Exception {
+
+        String test1 = "sa";
+        String test =new String(test1.getBytes(),"UTF-8");
+        String data = null;
+        String key =  KEY;
+        String iv = IV;
+        // /g2wzfqvMOeazgtsUVbq1kmJawROa6mcRAzwG1/GeJ4=
+        data = encrypt(test, key, iv);
+        System.out.println("数据:"+test);
+        System.out.println("加密:"+data);
+        String jiemi =desEncrypt(data, key, iv).trim();
+        System.out.println("解密:"+jiemi);
+
+
+    }
+}

+ 12 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/util/encryption/EncryptedString.java

@@ -0,0 +1,12 @@
+package org.jeecg.common.util.encryption;
+
+
+import lombok.Data;
+
+@Data
+public class  EncryptedString {
+
+    public static  String key = "1234567890adbcde";//长度为16个字符
+
+    public static  String iv  = "1234567890hjlkew";//长度为16个字符
+}

+ 157 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/util/jsonschema/CommonProperty.java

@@ -0,0 +1,157 @@
+package org.jeecg.common.util.jsonschema;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+
+import org.jeecg.common.system.vo.DictModel;
+
+import com.alibaba.fastjson.JSONObject;
+
+/**
+ * 验证通用属性
+ */
+public abstract class CommonProperty implements Serializable{
+
+	private static final long serialVersionUID = -426159949502493187L;
+
+
+	protected String key;
+	
+	
+	/**
+	 * <p>此关键字的值必须是字符串或数组。如果它是一个数组,那么数组的元素必须是字符串,并且必须是唯一的。
+	 * <p>字符串值必须是六种基本类型之一(“null”,“boolean”,“object”,“array”,“number”或“string”),或“integer”,它匹配任何数字,零分数部分。
+	 * <p>当且仅当实例位于为此关键字列出的任何集合中时,实例才会验证。
+     *
+	 */
+	protected String type;
+	
+	/**
+	 * 对应JsonSchema的enum
+	 * <p>该关键字的值必须是一个数组。这个数组应该至少有一个元素。数组中的元素应该是唯一的。如果实例的值等于此关键字的数组值中的某个元素,则实例将对此关键字成功验证。
+	 * 数组中的元素可以是任何值,包括null
+	 * 
+	 *  {
+	 *   "type": "string",
+	 *   "enum": ["1", "2", "3"] 需要的话可以通过这个include转一下
+	 *	}
+	 */
+	protected List<DictModel> include;
+	
+	/**
+	 * 对应JsonSchema的const
+	 * <p>此关键字的值可以是任何类型,包括null。
+	 *	如果实例的值等于关键字的值,则实例将针对此关键字成功验证。
+	 */
+	protected Object constant;
+	
+	//三个自定义 属性
+	protected String view;// 展示类型
+	protected String title;//数据库字段备注
+	protected Integer order;//字段显示排序
+	
+	protected boolean disabled;//是否禁用
+	
+	public boolean isDisabled() {
+		return disabled;
+	}
+
+	public void setDisabled(boolean disabled) {
+		this.disabled = disabled;
+	}
+
+	public String getView() {
+		return view;
+	}
+
+	public void setView(String view) {
+		this.view = view;
+	}
+
+	public String getKey() {
+		return key;
+	}
+
+	public void setKey(String key) {
+		this.key = key;
+	}
+
+	public String getType() {
+		return type;
+	}
+
+	public void setType(String type) {
+		this.type = type;
+	}
+
+	public List<DictModel> getInclude() {
+		return include;
+	}
+
+	public void setInclude(List<DictModel> include) {
+		this.include = include;
+	}
+
+	public Object getConstant() {
+		return constant;
+	}
+
+	public void setConstant(Object constant) {
+		this.constant = constant;
+	}
+	
+	public String getTitle() {
+		return title;
+	}
+
+	public void setTitle(String title) {
+		this.title = title;
+	}
+
+	public Integer getOrder() {
+		return order;
+	}
+
+	public void setOrder(Integer order) {
+		this.order = order;
+	}
+
+	/**
+	 * 返回一个map有两个key
+	 * <P>key ---> Property JSON的key
+	 * <P>prop --> JSON object
+	 * @return
+	 */
+	public abstract Map<String,Object> getPropertyJson();
+	
+    public JSONObject getCommonJson() {
+		JSONObject json = new JSONObject();
+		json.put("type", type);
+		if(include!=null && include.size()>0) {
+			json.put("enum", include);
+		}
+		if(constant!=null) {
+			json.put("const", constant);
+		}
+		if(title!=null) {
+			json.put("title", title);
+		}
+		if(order!=null) {
+			json.put("order", order);
+		}
+		if(view==null) {
+			json.put("view", "input");
+		}else {
+			json.put("view", view);
+		}
+		if(disabled) {
+			String str = "{\"widgetattrs\":{\"disabled\":true}}";
+			JSONObject ui = JSONObject.parseObject(str);
+			json.put("ui", ui);
+		}
+		return json;
+	}
+	
+
+}

+ 87 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/util/jsonschema/JsonSchemaDescrip.java

@@ -0,0 +1,87 @@
+package org.jeecg.common.util.jsonschema;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * JsonSchema 模式类
+ * < http://json-schema.org/draft-07/schema# >
+ */
+public class JsonSchemaDescrip implements Serializable{
+	
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 7682073117441544718L;
+	
+	
+	private String $schema = "http://json-schema.org/draft-07/schema#";
+	
+	/**
+	 * 用它给我们的模式提供了标题。
+	 */
+	private String title;
+	
+	/**
+	 * 关于模式的描述。
+	 */
+	private String description;
+	
+	/**
+	 *type 关键字在我们的 JSON 数据上定义了第一个约束:必须是一个 JSON 对象。 可以直接设置成object
+	 */
+	private String type;
+	
+	private List<String> required;
+	
+	
+	public List<String> getRequired() {
+		return required;
+	}
+
+	public void setRequired(List<String> required) {
+		this.required = required;
+	}
+
+	public String get$schema() {
+		return $schema;
+	}
+
+	public void set$schema(String $schema) {
+		this.$schema = $schema;
+	}
+
+	public String getTitle() {
+		return title;
+	}
+
+	public void setTitle(String title) {
+		this.title = title;
+	}
+
+	public String getDescription() {
+		return description;
+	}
+
+	public void setDescription(String description) {
+		this.description = description;
+	}
+
+	public String getType() {
+		return type;
+	}
+
+	public void setType(String type) {
+		this.type = type;
+	}
+	
+	public JsonSchemaDescrip() {}
+	
+	public JsonSchemaDescrip(List<String> required) {
+		this.description="我是一个jsonschema description";
+		this.title="我是一个jsonschema title";
+		this.type="object";
+		this.required = required;
+	}
+
+}

+ 70 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/util/jsonschema/JsonschemaUtil.java

@@ -0,0 +1,70 @@
+package org.jeecg.common.util.jsonschema;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class JsonschemaUtil {
+	
+	/**
+	 * 生成JsonSchema
+	 * 
+	 * @param descrip
+	 * @param propertyList
+	 * @return
+	 */
+	public static JSONObject getJsonSchema(JsonSchemaDescrip descrip, List<CommonProperty> propertyList) {
+		JSONObject obj = new JSONObject();
+		obj.put("$schema", descrip.get$schema());
+		obj.put("type", descrip.getType());
+		obj.put("title", descrip.getTitle());
+
+		List<String> requiredArr = descrip.getRequired();
+		obj.put("required", requiredArr);
+
+		JSONObject properties = new JSONObject();
+		for (CommonProperty commonProperty : propertyList) {
+			Map<String, Object> map = commonProperty.getPropertyJson();
+			properties.put(map.get("key").toString(), map.get("prop"));
+		}
+		obj.put("properties", properties);
+		//鬼知道这里为什么报错 org.jeecg.modules.system.model.DictModel cannot be cast to org.jeecg.modules.system.model.DictModel
+		//log.info("---JSONSchema--->"+obj.toJSONString());
+		return obj;
+	}
+	
+	/**
+	 * 生成JsonSchema 用于子对象
+	 * @param title 子对象描述
+	 * @param requiredArr 子对象必填属性名集合
+	 * @param propertyList 子对象属性集合
+	 * @return
+	 */
+	public static JSONObject getSubJsonSchema(String title,List<String> requiredArr,List<CommonProperty> propertyList) {
+		JSONObject obj = new JSONObject();
+		obj.put("type", "object");
+		obj.put("view", "tab");
+		obj.put("title", title);
+
+		if(requiredArr==null) {
+			requiredArr = new ArrayList<String>();
+		}
+		obj.put("required", requiredArr);
+
+		JSONObject properties = new JSONObject();
+		for (CommonProperty commonProperty : propertyList) {
+			Map<String, Object> map = commonProperty.getPropertyJson();
+			properties.put(map.get("key").toString(), map.get("prop"));
+		}
+		obj.put("properties", properties);
+		//log.info("---JSONSchema--->"+obj.toString());
+		return obj;
+	}
+
+}

+ 82 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/util/jsonschema/validate/DictProperty.java

@@ -0,0 +1,82 @@
+package org.jeecg.common.util.jsonschema.validate;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.jeecg.common.util.jsonschema.CommonProperty;
+
+import com.alibaba.fastjson.JSONObject;
+
+/**
+ * 字典属性
+ * @author 86729
+ *
+ */
+public class DictProperty extends CommonProperty {
+	
+	private static final long serialVersionUID = 3786503639885610767L;
+	
+	//字典三属性
+	private String dictCode;
+	private String dictTable;
+	private String dictText;
+	
+	public String getDictCode() {
+		return dictCode;
+	}
+
+	public void setDictCode(String dictCode) {
+		this.dictCode = dictCode;
+	}
+
+	public String getDictTable() {
+		return dictTable;
+	}
+
+	public void setDictTable(String dictTable) {
+		this.dictTable = dictTable;
+	}
+
+	public String getDictText() {
+		return dictText;
+	}
+
+	public void setDictText(String dictText) {
+		this.dictText = dictText;
+	}
+
+	public DictProperty() {}
+	
+	/**
+	 *  构造器
+	 */
+	public DictProperty(String key,String title,String dictTable,String dictCode,String dictText) {
+		this.type = "string";
+		this.view = "sel_search";
+		this.key = key;
+		this.title = title;
+		this.dictCode = dictCode;
+		this.dictTable= dictTable;
+		this.dictText= dictText;
+	}
+	
+	@Override
+	public Map<String, Object> getPropertyJson() {
+		Map<String,Object> map = new HashMap<>();
+		map.put("key",getKey());
+		JSONObject prop = getCommonJson();
+		if(dictCode!=null) {
+			prop.put("dictCode",dictCode);
+		}
+		if(dictTable!=null) {
+			prop.put("dictTable",dictTable);
+		}
+		if(dictText!=null) {
+			prop.put("dictText",dictText);
+		}
+		map.put("prop",prop);
+		return map;
+	}
+
+	//TODO 重构问题:数据字典 只是字符串类的还是有存储的数值类型?只有字符串请跳过这个 只改前端
+}

+ 156 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/util/jsonschema/validate/NumberProperty.java

@@ -0,0 +1,156 @@
+package org.jeecg.common.util.jsonschema.validate;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.jeecg.common.system.vo.DictModel;
+import org.jeecg.common.util.jsonschema.CommonProperty;
+
+import com.alibaba.fastjson.JSONObject;
+
+public class NumberProperty extends CommonProperty {
+
+	private static final long serialVersionUID = -558615331436437200L;
+	
+	/**
+	 * 倍数
+	 * 验证实例是否为此数值的倍数
+	 * “multipleOf”的值必须是一个数字,严格大于0。
+	 */
+	private Integer multipleOf;
+	
+	/**
+	 * 小于等于
+	 * “maximum”的值必须是一个数字,表示数字实例的包含上限。
+	 *	如果实例是数字,则仅当实例小于或等于“最大”时,此关键字才会生效。
+	 */
+	private Integer maxinum;
+	
+	/**
+	 * 小于
+	 * “exclusiveMaximum”的值必须是数字,表示数字实例的独占上限。
+     * 如果实例是数字,则实例仅在其值严格小于(不等于)“exclusiveMaximum”时才有效。
+	 */
+	private Integer exclusiveMaximum;
+	
+	/**
+	 * 大于等于
+	 */
+	private Integer minimum;
+	
+	/**
+	 * 大于等于
+	 */
+	private Integer exclusiveMinimum;
+
+	
+	private String pattern;
+
+	public Integer getMultipleOf() {
+		return multipleOf;
+	}
+
+	public void setMultipleOf(Integer multipleOf) {
+		this.multipleOf = multipleOf;
+	}
+
+	public Integer getMaxinum() {
+		return maxinum;
+	}
+
+	public void setMaxinum(Integer maxinum) {
+		this.maxinum = maxinum;
+	}
+
+	public Integer getExclusiveMaximum() {
+		return exclusiveMaximum;
+	}
+
+	public void setExclusiveMaximum(Integer exclusiveMaximum) {
+		this.exclusiveMaximum = exclusiveMaximum;
+	}
+
+	public Integer getMinimum() {
+		return minimum;
+	}
+
+	public void setMinimum(Integer minimum) {
+		this.minimum = minimum;
+	}
+
+	public Integer getExclusiveMinimum() {
+		return exclusiveMinimum;
+	}
+
+	public void setExclusiveMinimum(Integer exclusiveMinimum) {
+		this.exclusiveMinimum = exclusiveMinimum;
+	}
+
+	
+	public String getPattern() {
+		return pattern;
+	}
+
+	public void setPattern(String pattern) {
+		this.pattern = pattern;
+	}
+
+	public NumberProperty() {}
+	
+	/**
+	  *  构造器
+	 * @param key 字段名
+	 * @param title 字段备注 
+	 * @param type number和integer
+	 */
+	public NumberProperty(String key,String title,String type) {
+		this.key = key;
+		this.type = type;
+		this.title = title;
+		this.view = "number";
+	}
+	
+	/**
+	  * 列表类型的走这个构造器  字典里存储的都是字符串 没法走这个构造器
+	 * @param key
+	 * @param type
+	 * @param view list-checkbox-radio
+	 * @param include
+	 */
+	public NumberProperty(String key,String title,String view,List<DictModel> include) {
+		this.type = "integer";
+		this.key = key;
+		this.view = view;
+		this.title = title;
+		this.include = include;
+	}
+	
+	@Override
+	public Map<String,Object> getPropertyJson() {
+		Map<String,Object> map = new HashMap<>();
+		map.put("key",getKey());
+		JSONObject prop = getCommonJson();
+		if(multipleOf!=null) {
+			prop.put("multipleOf",multipleOf);
+		}
+		if(maxinum!=null) {
+			prop.put("maxinum",maxinum);
+		}
+		if(exclusiveMaximum!=null) {
+			prop.put("exclusiveMaximum",exclusiveMaximum);
+		}
+		if(minimum!=null) {
+			prop.put("minimum",minimum);
+		}
+		if(exclusiveMinimum!=null) {
+			prop.put("exclusiveMinimum",exclusiveMinimum);
+		}
+		if(pattern!=null) {
+			prop.put("pattern",pattern);
+		}
+
+		map.put("prop",prop);
+		return map;
+	}
+}

+ 76 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/util/jsonschema/validate/PopupProperty.java

@@ -0,0 +1,76 @@
+package org.jeecg.common.util.jsonschema.validate;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.jeecg.common.util.jsonschema.CommonProperty;
+
+import com.alibaba.fastjson.JSONObject;
+
+public class PopupProperty extends CommonProperty {
+	
+	private static final long serialVersionUID = -3200493311633999539L;
+	
+	private String code;
+	
+	private String destFields;
+	
+	private String orgFields;
+	
+	public String getCode() {
+		return code;
+	}
+
+	public void setCode(String code) {
+		this.code = code;
+	}
+
+	public String getDestFields() {
+		return destFields;
+	}
+
+	public void setDestFields(String destFields) {
+		this.destFields = destFields;
+	}
+
+	public String getOrgFields() {
+		return orgFields;
+	}
+
+	public void setOrgFields(String orgFields) {
+		this.orgFields = orgFields;
+	}
+
+	public PopupProperty() {}
+	
+	public PopupProperty(String key,String title,String code,String destFields,String orgFields) {
+		this.view = "popup";
+		this.type = "string";
+		this.key = key;
+		this.title = title;
+		this.code = code;
+		this.destFields=destFields;
+		this.orgFields=orgFields;
+	}
+	
+
+	@Override
+	public Map<String, Object> getPropertyJson() {
+		Map<String,Object> map = new HashMap<>();
+		map.put("key",getKey());
+		JSONObject prop = getCommonJson();
+		if(code!=null) {
+			prop.put("code",code);
+		}
+		if(destFields!=null) {
+			prop.put("destFields",destFields);
+		}
+		if(orgFields!=null) {
+			prop.put("orgFields",orgFields);
+		}
+		map.put("prop",prop);
+		return map;
+	}
+
+}

+ 120 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/util/jsonschema/validate/StringProperty.java

@@ -0,0 +1,120 @@
+package org.jeecg.common.util.jsonschema.validate;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.jeecg.common.system.vo.DictModel;
+import org.jeecg.common.util.jsonschema.CommonProperty;
+
+import com.alibaba.fastjson.JSONObject;
+
+public class StringProperty extends CommonProperty {
+	
+	private static final long serialVersionUID = -3200493311633999539L;
+	
+	private Integer maxLength;
+	
+	private Integer minLength;
+	
+	/**
+	 * 根据ECMA 262正则表达式方言,该字符串应该是有效的正则表达式。
+	 */
+	private String pattern;
+	
+
+	/**
+	 * 错误提示信息
+	 */
+	private String errorInfo;
+
+	public Integer getMaxLength() {
+		return maxLength;
+	}
+
+
+	public void setMaxLength(Integer maxLength) {
+		this.maxLength = maxLength;
+	}
+
+	public Integer getMinLength() {
+		return minLength;
+	}
+
+	public void setMinLength(Integer minLength) {
+		this.minLength = minLength;
+	}
+
+	public String getPattern() {
+		return pattern;
+	}
+
+	public void setPattern(String pattern) {
+		this.pattern = pattern;
+	}
+
+	
+	public String getErrorInfo() {
+		return errorInfo;
+	}
+
+
+	public void setErrorInfo(String errorInfo) {
+		this.errorInfo = errorInfo;
+	}
+
+	public StringProperty() {}
+	
+	/**
+	 *  一般字符串类型走这个构造器
+	 * @param key 字段名
+	 * @param title 字段备注
+	 * @param view 展示控件
+	 * @param maxLength 数据库字段最大长度
+	 */
+	public StringProperty(String key,String title,String view,Integer maxLength) {
+		this.maxLength = maxLength;
+		this.key = key;
+		this.view = view;
+		this.title = title;
+		this.type = "string";
+	}
+	
+	/**
+         *  列表类型的走这个构造器  
+	 * @param key 字段名
+	 * @param title 字段备注 
+	 * @param view 展示控件 list-checkbox-radio
+	 * @param maxLength 数据库字段最大长度
+	 * @param include 数据字典
+	 */
+	public StringProperty(String key,String title,String view,Integer maxLength,List<DictModel> include) {
+		this.maxLength = maxLength;
+		this.key = key;
+		this.view = view;
+		this.title = title;
+		this.type = "string";
+		this.include = include;
+	}
+	@Override
+	public Map<String, Object> getPropertyJson() {
+		Map<String,Object> map = new HashMap<>();
+		map.put("key",getKey());
+		JSONObject prop = getCommonJson();
+		if(maxLength!=null) {
+			prop.put("maxLength",maxLength);
+		}
+		if(minLength!=null) {
+			prop.put("minLength",minLength);
+		}
+		if(pattern!=null) {
+			prop.put("pattern",pattern);
+		}
+		if(errorInfo!=null) {
+			prop.put("errorInfo",errorInfo);
+		}
+		map.put("prop",prop);
+		return map;
+	}
+
+}

+ 92 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/util/jsonschema/validate/TreeSelectProperty.java

@@ -0,0 +1,92 @@
+package org.jeecg.common.util.jsonschema.validate;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.jeecg.common.util.jsonschema.CommonProperty;
+
+import com.alibaba.fastjson.JSONObject;
+
+/**
+ * 字典属性
+ * @author 86729
+ *
+ */
+public class TreeSelectProperty extends CommonProperty {
+	
+	private static final long serialVersionUID = 3786503639885610767L;
+	
+	private String dict;//表名,文本,id
+	private String pidField;//父级字段 默认pid
+	private String pidValue;//父级节点的值 暂时没用到 默认为0
+	private String hasChildField;
+	
+	public String getDict() {
+		return dict;
+	}
+
+	public void setDict(String dict) {
+		this.dict = dict;
+	}
+
+	public String getPidField() {
+		return pidField;
+	}
+
+	public void setPidField(String pidField) {
+		this.pidField = pidField;
+	}
+
+	public String getPidValue() {
+		return pidValue;
+	}
+
+	public void setPidValue(String pidValue) {
+		this.pidValue = pidValue;
+	}
+	
+	public String getHasChildField() {
+		return hasChildField;
+	}
+
+	public void setHasChildField(String hasChildField) {
+		this.hasChildField = hasChildField;
+	}
+
+	public TreeSelectProperty() {}
+	
+	/**
+	 *  构造器
+	 */
+	public TreeSelectProperty(String key,String title,String dict,String pidField,String pidValue) {
+		this.type = "string";
+		this.view = "sel_tree";
+		this.key = key;
+		this.title = title;
+		this.dict = dict;
+		this.pidField= pidField;
+		this.pidValue= pidValue;
+	}
+	
+	@Override
+	public Map<String, Object> getPropertyJson() {
+		Map<String,Object> map = new HashMap<>();
+		map.put("key",getKey());
+		JSONObject prop = getCommonJson();
+		if(dict!=null) {
+			prop.put("dict",dict);
+		}
+		if(pidField!=null) {
+			prop.put("pidField",pidField);
+		}
+		if(pidValue!=null) {
+			prop.put("pidValue",pidValue);
+		}
+		if(hasChildField!=null) {
+			prop.put("hasChildField",hasChildField);
+		}
+		map.put("prop",prop);
+		return map;
+	}
+
+}

+ 592 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/util/oConvertUtils.java

@@ -0,0 +1,592 @@
+package org.jeecg.common.util;
+
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.Field;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+import java.sql.Date;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * 
+ * @Author  张代浩
+ *
+ */
+public class oConvertUtils {
+	public static boolean isEmpty(Object object) {
+		if (object == null) {
+			return (true);
+		}
+		if ("".equals(object)) {
+			return (true);
+		}
+		if ("null".equals(object)) {
+			return (true);
+		}
+		return (false);
+	}
+	
+	public static boolean isNotEmpty(Object object) {
+		if (object != null && !object.equals("") && !object.equals("null")) {
+			return (true);
+		}
+		return (false);
+	}
+
+	public static String decode(String strIn, String sourceCode, String targetCode) {
+		String temp = code2code(strIn, sourceCode, targetCode);
+		return temp;
+	}
+
+	public static String StrToUTF(String strIn, String sourceCode, String targetCode) {
+		strIn = "";
+		try {
+			strIn = new String(strIn.getBytes("ISO-8859-1"), "GBK");
+		} catch (UnsupportedEncodingException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		return strIn;
+
+	}
+
+	private static String code2code(String strIn, String sourceCode, String targetCode) {
+		String strOut = null;
+		if (strIn == null || (strIn.trim()).equals("")) {
+			return strIn;
+		}
+		try {
+			byte[] b = strIn.getBytes(sourceCode);
+			for (int i = 0; i < b.length; i++) {
+				System.out.print(b[i] + "  ");
+			}
+			strOut = new String(b, targetCode);
+		} catch (Exception e) {
+			e.printStackTrace();
+			return null;
+		}
+		return strOut;
+	}
+
+	public static int getInt(String s, int defval) {
+		if (s == null || s == "") {
+			return (defval);
+		}
+		try {
+			return (Integer.parseInt(s));
+		} catch (NumberFormatException e) {
+			return (defval);
+		}
+	}
+
+	public static int getInt(String s) {
+		if (s == null || s == "") {
+			return 0;
+		}
+		try {
+			return (Integer.parseInt(s));
+		} catch (NumberFormatException e) {
+			return 0;
+		}
+	}
+
+	public static int getInt(String s, Integer df) {
+		if (s == null || s == "") {
+			return df;
+		}
+		try {
+			return (Integer.parseInt(s));
+		} catch (NumberFormatException e) {
+			return 0;
+		}
+	}
+
+	public static Integer[] getInts(String[] s) {
+		Integer[] integer = new Integer[s.length];
+		if (s == null) {
+			return null;
+		}
+		for (int i = 0; i < s.length; i++) {
+			integer[i] = Integer.parseInt(s[i]);
+		}
+		return integer;
+
+	}
+
+	public static double getDouble(String s, double defval) {
+		if (s == null || s == "") {
+			return (defval);
+		}
+		try {
+			return (Double.parseDouble(s));
+		} catch (NumberFormatException e) {
+			return (defval);
+		}
+	}
+
+	public static double getDou(Double s, double defval) {
+		if (s == null) {
+			return (defval);
+		}
+		return s;
+	}
+
+	/*public static Short getShort(String s) {
+		if (StringUtil.isNotEmpty(s)) {
+			return (Short.parseShort(s));
+		} else {
+			return null;
+		}
+	}*/
+
+	public static int getInt(Object object, int defval) {
+		if (isEmpty(object)) {
+			return (defval);
+		}
+		try {
+			return (Integer.parseInt(object.toString()));
+		} catch (NumberFormatException e) {
+			return (defval);
+		}
+	}
+	
+	public static Integer getInt(Object object) {
+		if (isEmpty(object)) {
+			return null;
+		}
+		try {
+			return (Integer.parseInt(object.toString()));
+		} catch (NumberFormatException e) {
+			return null;
+		}
+	}
+
+	public static int getInt(BigDecimal s, int defval) {
+		if (s == null) {
+			return (defval);
+		}
+		return s.intValue();
+	}
+
+	public static Integer[] getIntegerArry(String[] object) {
+		int len = object.length;
+		Integer[] result = new Integer[len];
+		try {
+			for (int i = 0; i < len; i++) {
+				result[i] = new Integer(object[i].trim());
+			}
+			return result;
+		} catch (NumberFormatException e) {
+			return null;
+		}
+	}
+
+	public static String getString(String s) {
+		return (getString(s, ""));
+	}
+
+	/**
+	 * 转义成Unicode编码
+	 * @param s
+	 * @return
+	 */
+	/*public static String escapeJava(Object s) {
+		return StringEscapeUtils.escapeJava(getString(s));
+	}*/
+	
+	public static String getString(Object object) {
+		if (isEmpty(object)) {
+			return "";
+		}
+		return (object.toString().trim());
+	}
+
+	public static String getString(int i) {
+		return (String.valueOf(i));
+	}
+
+	public static String getString(float i) {
+		return (String.valueOf(i));
+	}
+
+	public static String getString(String s, String defval) {
+		if (isEmpty(s)) {
+			return (defval);
+		}
+		return (s.trim());
+	}
+
+	public static String getString(Object s, String defval) {
+		if (isEmpty(s)) {
+			return (defval);
+		}
+		return (s.toString().trim());
+	}
+
+	public static long stringToLong(String str) {
+		Long test = new Long(0);
+		try {
+			test = Long.valueOf(str);
+		} catch (Exception e) {
+		}
+		return test.longValue();
+	}
+
+	/**
+	 * 获取本机IP
+	 */
+	public static String getIp() {
+		String ip = null;
+		try {
+			InetAddress address = InetAddress.getLocalHost();
+			ip = address.getHostAddress();
+
+		} catch (UnknownHostException e) {
+			e.printStackTrace();
+		}
+		return ip;
+	}
+
+	/**
+	 * 判断一个类是否为基本数据类型。
+	 * 
+	 * @param clazz
+	 *            要判断的类。
+	 * @return true 表示为基本数据类型。
+	 */
+	private static boolean isBaseDataType(Class clazz) throws Exception {
+		return (clazz.equals(String.class) || clazz.equals(Integer.class) || clazz.equals(Byte.class) || clazz.equals(Long.class) || clazz.equals(Double.class) || clazz.equals(Float.class) || clazz.equals(Character.class) || clazz.equals(Short.class) || clazz.equals(BigDecimal.class) || clazz.equals(BigInteger.class) || clazz.equals(Boolean.class) || clazz.equals(Date.class) || clazz.isPrimitive());
+	}
+
+	/**
+	 * @param request
+	 *            IP
+	 * @return IP Address
+	 */
+	public static String getIpAddrByRequest(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.getRemoteAddr();
+		}
+		return ip;
+	}
+
+	/**
+	 * @return 本机IP
+	 * @throws SocketException
+	 */
+	public static String getRealIp() throws SocketException {
+		String localip = null;// 本地IP,如果没有配置外网IP则返回它
+		String netip = null;// 外网IP
+
+		Enumeration<NetworkInterface> netInterfaces = NetworkInterface.getNetworkInterfaces();
+		InetAddress ip = null;
+		boolean finded = false;// 是否找到外网IP
+		while (netInterfaces.hasMoreElements() && !finded) {
+			NetworkInterface ni = netInterfaces.nextElement();
+			Enumeration<InetAddress> address = ni.getInetAddresses();
+			while (address.hasMoreElements()) {
+				ip = address.nextElement();
+				if (!ip.isSiteLocalAddress() && !ip.isLoopbackAddress() && ip.getHostAddress().indexOf(":") == -1) {// 外网IP
+					netip = ip.getHostAddress();
+					finded = true;
+					break;
+				} else if (ip.isSiteLocalAddress() && !ip.isLoopbackAddress() && ip.getHostAddress().indexOf(":") == -1) {// 内网IP
+					localip = ip.getHostAddress();
+				}
+			}
+		}
+
+		if (netip != null && !"".equals(netip)) {
+			return netip;
+		} else {
+			return localip;
+		}
+	}
+
+	/**
+	 * java去除字符串中的空格、回车、换行符、制表符
+	 * 
+	 * @param str
+	 * @return
+	 */
+	public static String replaceBlank(String str) {
+		String dest = "";
+		if (str != null) {
+			Pattern p = Pattern.compile("\\s*|\t|\r|\n");
+			Matcher m = p.matcher(str);
+			dest = m.replaceAll("");
+		}
+		return dest;
+
+	}
+
+	/**
+	 * 判断元素是否在数组内
+	 * 
+	 * @param substring
+	 * @param source
+	 * @return
+	 */
+	public static boolean isIn(String substring, String[] source) {
+		if (source == null || source.length == 0) {
+			return false;
+		}
+		for (int i = 0; i < source.length; i++) {
+			String aSource = source[i];
+			if (aSource.equals(substring)) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * 获取Map对象
+	 */
+	public static Map<Object, Object> getHashMap() {
+		return new HashMap<Object, Object>();
+	}
+
+	/**
+	 * SET转换MAP
+	 * 
+	 * @param setobj
+	 * @return
+	 */
+	public static Map<Object, Object> SetToMap(Set<Object> setobj) {
+		Map<Object, Object> map = getHashMap();
+		for (Iterator iterator = setobj.iterator(); iterator.hasNext();) {
+			Map.Entry<Object, Object> entry = (Map.Entry<Object, Object>) iterator.next();
+			map.put(entry.getKey().toString(), entry.getValue() == null ? "" : entry.getValue().toString().trim());
+		}
+		return map;
+
+	}
+
+	public static boolean isInnerIP(String ipAddress) {
+		boolean isInnerIp = false;
+		long ipNum = getIpNum(ipAddress);
+		/**
+		 * 私有IP:A类 10.0.0.0-10.255.255.255 B类 172.16.0.0-172.31.255.255 C类 192.168.0.0-192.168.255.255 当然,还有127这个网段是环回地址
+		 **/
+		long aBegin = getIpNum("10.0.0.0");
+		long aEnd = getIpNum("10.255.255.255");
+		long bBegin = getIpNum("172.16.0.0");
+		long bEnd = getIpNum("172.31.255.255");
+		long cBegin = getIpNum("192.168.0.0");
+		long cEnd = getIpNum("192.168.255.255");
+		isInnerIp = isInner(ipNum, aBegin, aEnd) || isInner(ipNum, bBegin, bEnd) || isInner(ipNum, cBegin, cEnd) || ipAddress.equals("127.0.0.1");
+		return isInnerIp;
+	}
+
+	private static long getIpNum(String ipAddress) {
+		String[] ip = ipAddress.split("\\.");
+		long a = Integer.parseInt(ip[0]);
+		long b = Integer.parseInt(ip[1]);
+		long c = Integer.parseInt(ip[2]);
+		long d = Integer.parseInt(ip[3]);
+
+		long ipNum = a * 256 * 256 * 256 + b * 256 * 256 + c * 256 + d;
+		return ipNum;
+	}
+
+	private static boolean isInner(long userIp, long begin, long end) {
+		return (userIp >= begin) && (userIp <= end);
+	}
+	
+	/**
+	 * 将下划线大写方式命名的字符串转换为驼峰式。
+	 * 如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。</br>
+	 * 例如:hello_world->helloWorld
+	 * 
+	 * @param name
+	 *            转换前的下划线大写方式命名的字符串
+	 * @return 转换后的驼峰式命名的字符串
+	 */
+	public static String camelName(String name) {
+		StringBuilder result = new StringBuilder();
+		// 快速检查
+		if (name == null || name.isEmpty()) {
+			// 没必要转换
+			return "";
+		} else if (!name.contains("_")) {
+			// 不含下划线,仅将首字母小写
+			//update-begin--Author:zhoujf  Date:20180503 for:TASK #2500 【代码生成器】代码生成器开发一通用模板生成功能
+			//update-begin--Author:zhoujf  Date:20180503 for:TASK #2500 【代码生成器】代码生成器开发一通用模板生成功能
+			return name.substring(0, 1).toLowerCase() + name.substring(1).toLowerCase();
+			//update-end--Author:zhoujf  Date:20180503 for:TASK #2500 【代码生成器】代码生成器开发一通用模板生成功能
+		}
+		// 用下划线将原始字符串分割
+		String camels[] = name.split("_");
+		for (String camel : camels) {
+			// 跳过原始字符串中开头、结尾的下换线或双重下划线
+			if (camel.isEmpty()) {
+				continue;
+			}
+			// 处理真正的驼峰片段
+			if (result.length() == 0) {
+				// 第一个驼峰片段,全部字母都小写
+				result.append(camel.toLowerCase());
+			} else {
+				// 其他的驼峰片段,首字母大写
+				result.append(camel.substring(0, 1).toUpperCase());
+				result.append(camel.substring(1).toLowerCase());
+			}
+		}
+		return result.toString();
+	}
+	
+	/**
+	 * 将下划线大写方式命名的字符串转换为驼峰式。
+	 * 如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。</br>
+	 * 例如:hello_world,test_id->helloWorld,testId
+	 * 
+	 * @param name
+	 *            转换前的下划线大写方式命名的字符串
+	 * @return 转换后的驼峰式命名的字符串
+	 */
+	public static String camelNames(String names) {
+		if(names==null||names.equals("")){
+			return null;
+		}
+		StringBuffer sf = new StringBuffer();
+		String[] fs = names.split(",");
+		for (String field : fs) {
+			field = camelName(field);
+			sf.append(field + ",");
+		}
+		String result = sf.toString();
+		return result.substring(0, result.length() - 1);
+	}
+	
+	//update-begin--Author:zhoujf  Date:20180503 for:TASK #2500 【代码生成器】代码生成器开发一通用模板生成功能
+	/**
+	 * 将下划线大写方式命名的字符串转换为驼峰式。(首字母写)
+	 * 如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。</br>
+	 * 例如:hello_world->HelloWorld
+	 * 
+	 * @param name
+	 *            转换前的下划线大写方式命名的字符串
+	 * @return 转换后的驼峰式命名的字符串
+	 */
+	public static String camelNameCapFirst(String name) {
+		StringBuilder result = new StringBuilder();
+		// 快速检查
+		if (name == null || name.isEmpty()) {
+			// 没必要转换
+			return "";
+		} else if (!name.contains("_")) {
+			// 不含下划线,仅将首字母小写
+			return name.substring(0, 1).toUpperCase() + name.substring(1).toLowerCase();
+		}
+		// 用下划线将原始字符串分割
+		String camels[] = name.split("_");
+		for (String camel : camels) {
+			// 跳过原始字符串中开头、结尾的下换线或双重下划线
+			if (camel.isEmpty()) {
+				continue;
+			}
+			// 其他的驼峰片段,首字母大写
+			result.append(camel.substring(0, 1).toUpperCase());
+			result.append(camel.substring(1).toLowerCase());
+		}
+		return result.toString();
+	}
+	//update-end--Author:zhoujf  Date:20180503 for:TASK #2500 【代码生成器】代码生成器开发一通用模板生成功能
+	
+	/**
+	 * 将驼峰命名转化成下划线
+	 * @param para
+	 * @return
+	 */
+	public static String camelToUnderline(String para){
+        if(para.length()<3){
+        	return para.toLowerCase(); 
+        }
+        StringBuilder sb=new StringBuilder(para);
+        int temp=0;//定位
+        //从第三个字符开始 避免命名不规范 
+        for(int i=2;i<para.length();i++){
+            if(Character.isUpperCase(para.charAt(i))){
+                sb.insert(i+temp, "_");
+                temp+=1;
+            }
+        }
+        return sb.toString().toLowerCase(); 
+	}
+
+	/**
+	 * 随机数
+	 * @param place 定义随机数的位数
+	 */
+	public static String randomGen(int place) {
+		String base = "qwertyuioplkjhgfdsazxcvbnmQAZWSXEDCRFVTGBYHNUJMIKLOP0123456789";
+		StringBuffer sb = new StringBuffer();
+		Random rd = new Random();
+		for(int i=0;i<place;i++) {
+			sb.append(base.charAt(rd.nextInt(base.length())));
+		}
+		return sb.toString();
+	}
+	
+	/**
+	 * 获取类的所有属性,包括父类
+	 * 
+	 * @param object
+	 * @return
+	 */
+	public static Field[] getAllFields(Object object) {
+		Class<?> clazz = object.getClass();
+		List<Field> fieldList = new ArrayList<>();
+		while (clazz != null) {
+			fieldList.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields())));
+			clazz = clazz.getSuperclass();
+		}
+		Field[] fields = new Field[fieldList.size()];
+		fieldList.toArray(fields);
+		return fields;
+	}
+
+	
+	/**
+	  * 将map的key全部转成小写
+	 * @param list
+	 * @return
+	 */
+	public static List<Map<String, Object>> toLowerCasePageList(List<Map<String, Object>> list){
+		List<Map<String, Object>> select = new ArrayList<>();
+		for (Map<String, Object> row : list) {
+			 Map<String, Object> resultMap = new HashMap<>();
+			 Set<String> keySet = row.keySet(); 
+			 for (String key : keySet) { 
+				 String newKey = key.toLowerCase(); 
+				 resultMap.put(newKey, row.get(key)); 
+			 }
+			 select.add(resultMap);
+		}
+		return select;
+	}
+}

+ 60 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/util/superSearch/ObjectParseUtil.java

@@ -0,0 +1,60 @@
+package org.jeecg.common.util.superSearch;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+
+/**
+ *   判断类型,追加查询规则
+ * 
+ * @Author Scott
+ * @Date 2019年02月14日
+ */
+public class ObjectParseUtil {
+
+	/**
+	 * 
+	 * @param queryWrapper QueryWrapper
+	 * @param name         字段名字
+	 * @param rule         查询规则
+	 * @param value        查询条件值
+	 */
+	public static void addCriteria(QueryWrapper<?> queryWrapper, String name, QueryRuleEnum rule, Object value) {
+		if (value == null || rule == null) {
+			return;
+		}
+		switch (rule) {
+		case GT:
+			queryWrapper.gt(name, value);
+			break;
+		case GE:
+			queryWrapper.ge(name, value);
+			break;
+		case LT:
+			queryWrapper.lt(name, value);
+			break;
+		case LE:
+			queryWrapper.le(name, value);
+			break;
+		case EQ:
+			queryWrapper.eq(name, value);
+			break;
+		case NE:
+			queryWrapper.ne(name, value);
+			break;
+		case IN:
+			queryWrapper.in(name, (Object[]) value);
+			break;
+		case LIKE:
+			queryWrapper.like(name, value);
+			break;
+		case LEFT_LIKE:
+			queryWrapper.likeLeft(name, value);
+			break;
+		case RIGHT_LIKE:
+			queryWrapper.likeRight(name, value);
+			break;
+		default:
+			break;
+		}
+	}
+
+}

+ 60 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/util/superSearch/QueryRuleEnum.java

@@ -0,0 +1,60 @@
+package org.jeecg.common.util.superSearch;
+
+import org.jeecg.common.util.oConvertUtils;
+
+/**
+ * Query 规则 常量
+ * @Author Scott
+ * @Date 2019年02月14日
+ */
+public enum QueryRuleEnum {
+
+    GT(">","大于"),
+    GE(">=","大于等于"),
+    LT("<","小于"),
+    LE("<=","小于等于"),
+    EQ("=","等于"),
+    NE("!=","不等于"),
+    IN("IN","包含"),
+    LIKE("LIKE","全模糊"),
+    LEFT_LIKE("LEFT_LIKE","左模糊"),
+    RIGHT_LIKE("RIGHT_LIKE","右模糊"),
+    SQL_RULES("EXTEND_SQL","自定义SQL片段");
+
+    private String value;
+
+    private String msg;
+
+    QueryRuleEnum(String value, String msg){
+        this.value = value;
+        this.msg = msg;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    public void setMsg(String msg) {
+        this.msg = msg;
+    }
+
+    public static QueryRuleEnum getByValue(String value){
+    	if(oConvertUtils.isEmpty(value)) {
+    		return null;
+    	}
+        for(QueryRuleEnum val :values()){
+            if (val.getValue().equals(value)){
+                return val;
+            }
+        }
+        return  null;
+    }
+}

+ 11 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/common/util/superSearch/QueryRuleVo.java

@@ -0,0 +1,11 @@
+package org.jeecg.common.util.superSearch;
+
+import lombok.Data;
+
+@Data
+public class QueryRuleVo {
+
+	private String field;
+	private String rule;
+	private String val;
+}	

+ 78 - 0
jeecg-boot-base-common/src/main/java/org/jeecg/modules/system/entity/SysPermissionDataRule.java

@@ -0,0 +1,78 @@
+package org.jeecg.modules.system.entity;
+
+import java.io.Serializable;
+import java.util.Date;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+/**
+ * <p>
+ * 菜单权限规则表
+ * </p>
+ *
+ * @Author huangzhilin
+ * @since 2019-03-29
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class SysPermissionDataRule implements Serializable {
+	
+	private static final long serialVersionUID = 1L;
+	
+	/**
+	 * id
+	 */
+	@TableId(type = IdType.UUID)
+	private String id;
+	
+	/**
+	 * 对应的菜单id
+	 */
+	private String permissionId;
+	
+	/**
+	 * 规则名称
+	 */
+	private String ruleName;
+	
+	/**
+	 * 字段
+	 */
+	private String ruleColumn;
+	
+	/**
+	 * 条件
+	 */
+	private String ruleConditions;
+	
+	/**
+	 * 规则值
+	 */
+	private String ruleValue;
+	
+	/**
+	 * 创建时间
+	 */
+	private Date createTime;
+	
+	/**
+	 * 创建人
+	 */
+	private String createBy;
+	
+	/**
+	 * 修改时间
+	 */
+	private Date updateTime;
+	
+	/**
+	 * 修改人
+	 */
+	private String updateBy;
+}

+ 11 - 0
jeecg-boot-base-common/src/main/main.iml

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

+ 1 - 0
jeecg-boot-module-system/.gitignore

@@ -0,0 +1 @@
+/target/

+ 24 - 0
jeecg-boot-module-system/docs/规范/编码必看规范

@@ -0,0 +1,24 @@
+【第一部分】代码注释规范
+
+[1].代码修改注释
+	//update-begin--Author:zhangdaihao  Date:20140212 for:[bugfree号]树机构调整--------------------
+	//update-end--Author:zhangdaihao  Date:20140212 for:[bugfree号]树机构调整----------------------
+[2].代码存在缺陷或者留有功能点的代码,采用以下方式进行标示
+    //TODO author:zhangdaihao  for:插入未完成   date:20130711
+
+[3].SVN提交注释
+	[author:用户名     date:20130203   for:(bugfree号码)增加查询条件,组织机构]
+
+
+【第二部分】修改文件记录
+	代码修改日志    :/jeecg-boot/docs/代码修改日志
+	数据库修改日志:/jeecg-boot/docs/DB修改日志.sql
+	
+【第三部分】建表规范
+	1.主键必须是ID,字符串类型,32位长度,唯一索引;
+	2.建表标准字段,必须有:创建人、创建时间、修改人、修改时间等标准字段;
+	3.表字段注释,每个字段必须设置注释说明;
+	4.表字段注释,状态类型的字段必须说明取值规则(比如性别sex取值规则)
+                 比如:'性别  0/男,1/女'
+    5.索引,查询频率高的字段加索引(单字段索引 、组合索引);
+    6.类型字段,尽量用字符串varchar类型1-2长度,少用int类型,避免不必要的问题。

BIN
jeecg-boot-module-system/docs/规范/阿里巴巴Java开发手册(详尽版).pdf


+ 18 - 0
jeecg-boot-module-system/docs/项目说明

@@ -0,0 +1,18 @@
+
+一、技术文档
+	http://jeecg-boot.mydoc.io
+	
+二、部署文档
+    修改redis、数据库配置文件
+    修改上传文件目录
+    修改登录页面提示账号密码
+    修改前端API的图片访问域名
+    
+    
+    
+重要方法:
+
+  动态加载路由的类: SysPermissionController.queryByUser
+ 路由name命名规则: 通过菜单URL生成路由name(去掉URL前缀斜杠,替换内容中的斜杠‘/’为-)
+	 			     举例:              URL = /isystem/role
+	      		         RouteName = isystem-role

+ 246 - 0
jeecg-boot-module-system/jeecg-boot-module-system.iml

@@ -0,0 +1,246 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
+  <component name="FacetManager">
+    <facet type="Spring" name="Spring">
+      <configuration />
+    </facet>
+    <facet type="web" name="Web">
+      <configuration>
+        <webroots />
+        <sourceRoots>
+          <root url="file://$MODULE_DIR$/src/main/java" />
+          <root url="file://$MODULE_DIR$/src/main/resources" />
+        </sourceRoots>
+      </configuration>
+    </facet>
+  </component>
+  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
+    <output url="file://$MODULE_DIR$/target/classes" />
+    <output-test url="file://$MODULE_DIR$/target/test-classes" />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
+      <excludeFolder url="file://$MODULE_DIR$/target" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="module" module-name="jeecg-boot-base-common" />
+    <orderEntry type="module" module-name="module-media" />
+    <orderEntry type="module" module-name="module-common" />
+    <orderEntry type="module" module-name="module-kuaishou" />
+    <orderEntry type="module" module-name="module-crawler" />
+    <orderEntry type="module" module-name="module-toutiao" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-web:2.1.3.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.1.3.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.1.3.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.1.3.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.2.3" level="project" />
+    <orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.2.3" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-to-slf4j:2.11.2" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.11.2" level="project" />
+    <orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.25" level="project" />
+    <orderEntry type="library" name="Maven: javax.annotation:javax.annotation-api:1.3.2" level="project" />
+    <orderEntry type="library" scope="RUNTIME" name="Maven: org.yaml:snakeyaml:1.23" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-json:2.1.3.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.9.8" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml.jackson.module:jackson-module-parameter-names:2.9.8" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-tomcat:2.1.3.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-core:9.0.16" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-el:9.0.16" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-websocket:9.0.16" level="project" />
+    <orderEntry type="library" name="Maven: org.hibernate.validator:hibernate-validator:6.0.14.Final" level="project" />
+    <orderEntry type="library" name="Maven: javax.validation:validation-api:2.0.1.Final" level="project" />
+    <orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.3.2.Final" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-web:5.1.5.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-beans:5.1.5.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-webmvc:5.1.5.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-context:5.1.5.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-expression:5.1.5.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-mail:2.1.3.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-context-support:5.1.5.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: com.sun.mail:javax.mail:1.6.2" level="project" />
+    <orderEntry type="library" name="Maven: javax.activation:activation:1.1" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-starter-test:2.1.3.RELEASE" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-test:2.1.3.RELEASE" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-test-autoconfigure:2.1.3.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: com.jayway.jsonpath:json-path:2.4.0" level="project" />
+    <orderEntry type="library" name="Maven: net.minidev:json-smart:2.3" level="project" />
+    <orderEntry type="library" name="Maven: net.minidev:accessors-smart:1.2" level="project" />
+    <orderEntry type="library" name="Maven: org.ow2.asm:asm:5.0.4" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
+    <orderEntry type="library" name="Maven: org.assertj:assertj-core:3.11.1" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.mockito:mockito-core:2.23.4" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: net.bytebuddy:byte-buddy-agent:1.9.10" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.objenesis:objenesis:2.6" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-library:1.3" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.skyscreamer:jsonassert:1.5.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: com.vaadin.external.google:android-json:0.0.20131108.vaadin1" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-core:5.1.5.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.1.5.RELEASE" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.springframework:spring-test:5.1.5.RELEASE" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.xmlunit:xmlunit-core:2.6.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-aop:2.1.3.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-aop:5.1.5.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.aspectj:aspectjweaver:1.9.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-actuator:2.1.3.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-actuator-autoconfigure:2.1.3.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-actuator:2.1.3.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: io.micrometer:micrometer-core:1.1.3" level="project" />
+    <orderEntry type="library" name="Maven: org.hdrhistogram:HdrHistogram:2.1.9" level="project" />
+    <orderEntry type="library" name="Maven: org.latencyutils:LatencyUtils:2.0.3" level="project" />
+    <orderEntry type="library" name="Maven: commons-io:commons-io:2.6" level="project" />
+    <orderEntry type="library" name="Maven: commons-lang:commons-lang:2.6" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-freemarker:2.1.3.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.freemarker:freemarker:2.3.28" level="project" />
+    <orderEntry type="library" name="Maven: org.projectlombok:lombok:1.18.6" level="project" />
+    <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-boot-starter:3.0.6" level="project" />
+    <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus:3.0.6" level="project" />
+    <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-extension:3.0.6" level="project" />
+    <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-core:3.0.6" level="project" />
+    <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-annotation:3.0.6" level="project" />
+    <orderEntry type="library" name="Maven: com.github.jsqlparser:jsqlparser:1.2" level="project" />
+    <orderEntry type="library" name="Maven: org.mybatis:mybatis-spring:1.3.2" level="project" />
+    <orderEntry type="library" name="Maven: org.mybatis:mybatis:3.4.6" level="project" />
+    <orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-generator:3.0.6" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.1.3.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:2.1.3.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: com.zaxxer:HikariCP:3.2.0" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-jdbc:5.1.5.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-configuration-processor:2.1.3.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba:druid-spring-boot-starter:1.1.10" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba:druid:1.1.10" level="project" />
+    <orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.25" level="project" />
+    <orderEntry type="library" name="Maven: com.baomidou:dynamic-datasource-spring-boot-starter:2.5.4" level="project" />
+    <orderEntry type="library" name="Maven: com.alibaba:fastjson:1.2.56" level="project" />
+    <orderEntry type="library" scope="RUNTIME" name="Maven: mysql:mysql-connector-java:5.1.47" level="project" />
+    <orderEntry type="library" scope="RUNTIME" name="Maven: net.sourceforge.jtds:jtds:1.3.1" level="project" />
+    <orderEntry type="library" scope="RUNTIME" name="Maven: com.microsoft.sqlserver:mssql-jdbc:7.2.1.jre8" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-quartz:2.1.3.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-tx:5.1.5.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.quartz-scheduler:quartz:2.3.0" level="project" />
+    <orderEntry type="library" name="Maven: com.mchange:mchange-commons-java:0.2.11" level="project" />
+    <orderEntry type="library" name="Maven: com.auth0:java-jwt:3.7.0" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.9.8" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.9.0" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.shiro:shiro-spring-boot-starter:1.4.0" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.shiro:shiro-spring:1.4.0" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.shiro:shiro-core:1.4.0" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.shiro:shiro-lang:1.4.0" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.shiro:shiro-cache:1.4.0" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.shiro:shiro-crypto-hash:1.4.0" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.shiro:shiro-crypto-core:1.4.0" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.shiro:shiro-crypto-cipher:1.4.0" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.shiro:shiro-config-core:1.4.0" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.shiro:shiro-config-ogdl:1.4.0" level="project" />
+    <orderEntry type="library" name="Maven: commons-beanutils:commons-beanutils:1.9.3" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.shiro:shiro-event:1.4.0" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.shiro:shiro-web:1.4.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-swagger2:2.9.2" level="project" />
+    <orderEntry type="library" name="Maven: io.swagger:swagger-annotations:1.5.20" level="project" />
+    <orderEntry type="library" name="Maven: io.swagger:swagger-models:1.5.20" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-spi:2.9.2" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-core:2.9.2" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-schema:2.9.2" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-swagger-common:2.9.2" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-spring-web:2.9.2" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml:classmate:1.4.0" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-core:1.2.0.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-metadata:1.2.0.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.mapstruct:mapstruct:1.2.0.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-swagger-ui:2.9.2" level="project" />
+    <orderEntry type="library" name="Maven: com.github.xiaoymin:swagger-bootstrap-ui:1.9.3" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-bean-validators:2.9.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-data-redis:2.1.3.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.data:spring-data-redis:2.1.5.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.data:spring-data-keyvalue:2.1.5.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.data:spring-data-commons:2.1.5.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-oxm:5.1.5.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: io.lettuce:lettuce-core:5.1.4.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-common:4.1.33.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-handler:4.1.33.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-buffer:4.1.33.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-codec:4.1.33.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-transport:4.1.33.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.netty:netty-resolver:4.1.33.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.projectreactor:reactor-core:3.2.6.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.commons:commons-pool2:2.6.1" level="project" />
+    <orderEntry type="library" name="Maven: org.jeecgframework.boot:codegenerate:1.0.5" level="project" />
+    <orderEntry type="library" name="Maven: org.jeecgframework:autopoi-web:1.0.3" level="project" />
+    <orderEntry type="library" name="Maven: org.jeecgframework:autopoi:1.0.3" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.poi:poi:3.9" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml:3.9" level="project" />
+    <orderEntry type="library" name="Maven: dom4j:dom4j:1.6.1" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.poi:poi-ooxml-schemas:3.9" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.xmlbeans:xmlbeans:2.3.0" level="project" />
+    <orderEntry type="library" name="Maven: stax:stax-api:1.0.1" level="project" />
+    <orderEntry type="library" name="Maven: xerces:xercesImpl:2.9.1" level="project" />
+    <orderEntry type="library" name="Maven: xml-apis:xml-apis:1.4.01" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.poi:poi-scratchpad:3.9" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpclient:4.5.9" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpcore:4.4" level="project" />
+    <orderEntry type="library" name="Maven: com.squareup.retrofit2:retrofit:2.6.0" level="project" />
+    <orderEntry type="library" name="Maven: com.squareup.okhttp3:okhttp:3.12.0" level="project" />
+    <orderEntry type="library" name="Maven: com.graphql-java:graphql-java:13.0" level="project" />
+    <orderEntry type="library" name="Maven: org.antlr:antlr4-runtime:4.7.2" level="project" />
+    <orderEntry type="library" name="Maven: com.graphql-java:java-dataloader:2.1.1" level="project" />
+    <orderEntry type="library" name="Maven: org.reactivestreams:reactive-streams:1.0.2" level="project" />
+    <orderEntry type="library" name="Maven: org.mountcloud:graphql-client:1.2" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.9.8" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.9.8" level="project" />
+    <orderEntry type="library" name="Maven: com.google.code.gson:gson:2.8.5" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.pdfbox:fontbox:2.0.15" level="project" />
+    <orderEntry type="library" name="Maven: commons-logging:commons-logging:1.2" level="project" />
+    <orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-java:3.14.0" level="project" />
+    <orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-api:3.14.0" level="project" />
+    <orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-chrome-driver:3.14.0" level="project" />
+    <orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-edge-driver:3.14.0" level="project" />
+    <orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-firefox-driver:3.14.0" level="project" />
+    <orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-ie-driver:3.14.0" level="project" />
+    <orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-opera-driver:3.14.0" level="project" />
+    <orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-remote-driver:3.14.0" level="project" />
+    <orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-safari-driver:3.14.0" level="project" />
+    <orderEntry type="library" name="Maven: org.seleniumhq.selenium:selenium-support:3.14.0" level="project" />
+    <orderEntry type="library" name="Maven: net.bytebuddy:byte-buddy:1.9.10" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.commons:commons-exec:1.3" level="project" />
+    <orderEntry type="library" name="Maven: com.squareup.okio:okio:1.14.1" level="project" />
+    <orderEntry type="library" name="Maven: org.json:json:20180813" level="project" />
+    <orderEntry type="library" name="Maven: com.google.guava:guava:25.0-jre" level="project" />
+    <orderEntry type="library" name="Maven: com.google.code.findbugs:jsr305:1.3.9" level="project" />
+    <orderEntry type="library" name="Maven: org.checkerframework:checker-compat-qual:2.0.0" level="project" />
+    <orderEntry type="library" name="Maven: com.google.errorprone:error_prone_annotations:2.1.3" level="project" />
+    <orderEntry type="library" name="Maven: com.google.j2objc:j2objc-annotations:1.1" level="project" />
+    <orderEntry type="library" name="Maven: org.codehaus.mojo:animal-sniffer-annotations:1.14" level="project" />
+    <orderEntry type="library" name="Maven: us.codecraft:webmagic-core:0.7.3" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.8.1" level="project" />
+    <orderEntry type="library" name="Maven: us.codecraft:xsoup:0.3.1" level="project" />
+    <orderEntry type="library" name="Maven: org.slf4j:slf4j-log4j12:1.7.25" level="project" />
+    <orderEntry type="library" name="Maven: log4j:log4j:1.2.17" level="project" />
+    <orderEntry type="library" name="Maven: commons-collections:commons-collections:3.2.2" level="project" />
+    <orderEntry type="library" name="Maven: org.jsoup:jsoup:1.10.3" level="project" />
+    <orderEntry type="library" name="Maven: us.codecraft:webmagic-extension:0.7.3" level="project" />
+    <orderEntry type="library" name="Maven: redis.clients:jedis:2.9.1" level="project" />
+    <orderEntry type="library" name="Maven: net.sourceforge.htmlunit:htmlunit:2.35.0" level="project" />
+    <orderEntry type="library" name="Maven: xalan:xalan:2.7.2" level="project" />
+    <orderEntry type="library" name="Maven: xalan:serializer:2.7.2" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.commons:commons-text:1.6" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpmime:4.5.7" level="project" />
+    <orderEntry type="library" name="Maven: net.sourceforge.htmlunit:htmlunit-core-js:2.35.0" level="project" />
+    <orderEntry type="library" name="Maven: net.sourceforge.htmlunit:neko-htmlunit:2.35.0" level="project" />
+    <orderEntry type="library" name="Maven: net.sourceforge.htmlunit:htmlunit-cssparser:1.4.0" level="project" />
+    <orderEntry type="library" name="Maven: commons-net:commons-net:3.6" level="project" />
+    <orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-client:9.4.14.v20181114" level="project" />
+    <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-client:9.4.14.v20181114" level="project" />
+    <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-http:9.4.14.v20181114" level="project" />
+    <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-xml:9.4.14.v20181114" level="project" />
+    <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-util:9.4.14.v20181114" level="project" />
+    <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-io:9.4.14.v20181114" level="project" />
+    <orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-common:9.4.14.v20181114" level="project" />
+    <orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-api:9.4.14.v20181114" level="project" />
+    <orderEntry type="library" name="Maven: commons-codec:commons-codec:1.11" level="project" />
+    <orderEntry type="library" name="Maven: cn.hutool:hutool-all:4.5.11" level="project" />
+    <orderEntry type="library" name="Maven: com.aliyun:aliyun-java-sdk-dysmsapi:1.0.0" level="project" />
+    <orderEntry type="library" name="Maven: com.aliyun:aliyun-java-sdk-core:3.2.3" level="project" />
+  </component>
+</module>

+ 81 - 0
jeecg-boot-module-system/pom.xml

@@ -0,0 +1,81 @@
+<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>
+    <artifactId>jeecg-boot-module-system</artifactId>
+    <version>2.0.2</version>
+
+    <parent>
+        <groupId>org.jeecgframework.boot</groupId>
+        <artifactId>jeecg-boot-parent</artifactId>
+        <version>2.0.2</version>
+    </parent>
+
+    <repositories>
+        <repository>
+            <id>aliyun</id>
+            <name>aliyun Repository</name>
+            <url>http://maven.aliyun.com/nexus/content/groups/public</url>
+            <snapshots>
+                <enabled>false</enabled>
+            </snapshots>
+        </repository>
+        <repository>
+            <id>jeecg</id>
+            <name>jeecg Repository</name>
+            <url>http://maven.jeecg.org/nexus/content/repositories/jeecg</url>
+            <snapshots>
+                <enabled>false</enabled>
+            </snapshots>
+        </repository>
+    </repositories>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.jeecgframework.boot</groupId>
+            <artifactId>jeecg-boot-base-common</artifactId>
+            <version>2.0.2</version>
+        </dependency>
+
+        <dependency>
+            <groupId>cn.com.ctop</groupId>
+            <artifactId>module-media</artifactId>
+            <version>2.0.2</version>
+        </dependency>
+        <dependency>
+            <groupId>cn.com.ctop</groupId>
+            <artifactId>module-kuaishou</artifactId>
+            <version>2.0.2</version>
+        </dependency>
+        <dependency>
+            <groupId>cn.com.ctop</groupId>
+            <artifactId>module-toutiao</artifactId>
+            <version>2.0.2</version>
+            <scope>compile</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+        <resources>
+            <!-- 解决MyBatis配置文件引入问题 -->
+            <resource>
+                <directory>src/main/java</directory>
+                <includes>
+                    <include>**/*.properties</include>
+                    <include>**/*.xml</include>
+                </includes>
+                <!-- 是否替换资源中的属性-->
+                <filtering>false</filtering>
+            </resource>
+            <resource>
+                <directory>src/main/resources</directory>
+            </resource>
+        </resources>
+    </build>
+</project>

+ 41 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/JeecgApplication.java

@@ -0,0 +1,41 @@
+package org.jeecg;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.core.env.Environment;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+@Slf4j
+@EnableSwagger2
+@SpringBootApplication
+@ComponentScan(basePackages={"cn.com.ctop","org.jeecg"})
+@EnableAutoConfiguration
+@ComponentScan
+
+public class JeecgApplication {
+
+  public static void main(String[] args) throws UnknownHostException {
+    //System.setProperty("spring.devtools.restart.enabled", "true");
+
+    ConfigurableApplicationContext application = SpringApplication.run(JeecgApplication.class, args);
+    Environment env = application.getEnvironment();
+    String ip = InetAddress.getLocalHost().getHostAddress();
+    String port = env.getProperty("server.port");
+    String path = env.getProperty("server.servlet.context-path");
+    log.info("\n----------------------------------------------------------\n\t" +
+        "Application Jeecg-Boot is running! Access URLs:\n\t" +
+        "Local: \t\thttp://localhost:" + port + path + "/\n\t" +
+        "External: \thttp://" + ip + ":" + port + path + "/\n\t" +
+        "swagger-ui: \thttp://" + ip + ":" + port + path + "/swagger-ui.html\n\t" +
+        "Doc: \t\thttp://" + ip + ":" + port + path + "/doc.html\n" +
+        "----------------------------------------------------------");
+
+  }
+}

+ 18 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/JeecgOneGUI.java

@@ -0,0 +1,18 @@
+package org.jeecg;
+
+import org.jeecgframework.codegenerate.window.CodeWindow;
+
+/**
+ * @Title: 单表代码生成器入口
+ * @Author 张代浩
+ * @site www.jeecg.org
+ * @Version:V1.0.1
+ */
+public class JeecgOneGUI {
+
+	/** 详细使用手册: http://jeecg-boot.mydoc.io/?t=338140 */
+    public static void main(String[] args) {
+    	new CodeWindow().pack();
+	}
+
+}

+ 69 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/JeecgOneToMainUtil.java

@@ -0,0 +1,69 @@
+package org.jeecg;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jeecgframework.codegenerate.generate.impl.CodeGenerateOneToMany;
+import org.jeecgframework.codegenerate.generate.pojo.onetomany.MainTableVo;
+import org.jeecgframework.codegenerate.generate.pojo.onetomany.SubTableVo;
+
+/**
+ * 代码生成器入口【一对多】
+ * @Author 张代浩
+ * @site www.jeecg.org
+ * 
+ */
+public class JeecgOneToMainUtil {
+
+	/**
+	 * 一对多(父子表)数据模型,生成方法
+	 * @param args
+	 */
+	public static void main(String[] args) {
+		//第一步:设置主表配置
+		MainTableVo mainTable = new MainTableVo();
+		mainTable.setTableName("jeecg_order_main");//表名
+		mainTable.setEntityName("TestOrderMain");	 //实体名
+		mainTable.setEntityPackage("test2");	 //包名
+		mainTable.setFtlDescription("订单");	 //描述
+		
+		//第二步:设置子表集合配置
+		List<SubTableVo> subTables = new ArrayList<SubTableVo>();
+		//[1].子表一
+		SubTableVo po = new SubTableVo();
+		po.setTableName("jeecg_order_customer");//表名
+		po.setEntityName("TestOrderCustom");	    //实体名
+		po.setEntityPackage("test2");	        //包名
+		po.setFtlDescription("客户明细");       //描述
+		//子表外键参数配置
+		/*说明: 
+		 * a) 子表引用主表主键ID作为外键,外键字段必须以_ID结尾;
+		 * b) 主表和子表的外键字段名字,必须相同(除主键ID外);
+		 * c) 多个外键字段,采用逗号分隔;
+		*/
+		po.setForeignKeys(new String[]{"order_id"});
+		subTables.add(po);
+		//[2].子表二
+		SubTableVo po2 = new SubTableVo();
+		po2.setTableName("jeecg_order_ticket");		//表名
+		po2.setEntityName("TestOrderTicket");			//实体名
+		po2.setEntityPackage("test2"); 				//包名
+		po2.setFtlDescription("产品明细");			//描述
+		//子表外键参数配置
+		/*说明: 
+		 * a) 子表引用主表主键ID作为外键,外键字段必须以_ID结尾;
+		 * b) 主表和子表的外键字段名字,必须相同(除主键ID外);
+		 * c) 多个外键字段,采用逗号分隔;
+		*/
+		po2.setForeignKeys(new String[]{"order_id"});
+		subTables.add(po2);
+		mainTable.setSubTables(subTables);
+		
+		//第三步:一对多(父子表)数据模型,代码生成
+		try {
+			new CodeGenerateOneToMany(mainTable,subTables).generateCodeFile();
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+}

+ 28 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/config/AutoPoiConfig.java

@@ -0,0 +1,28 @@
+package org.jeecg.config;
+
+import org.jeecgframework.core.util.ApplicationContextUtil;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @Author: Scott
+ * @Date: 2018/2/7
+ * @description: autopoi 配置类
+ */
+
+@Configuration
+public class AutoPoiConfig {
+	
+	/**
+	 * excel注解字典参数支持(导入导出字典值,自动翻译)
+	 * 举例: @Excel(name = "性别", width = 15, dicCode = "sex")
+	 * 1、导出的时候会根据字典配置,把值1,2翻译成:男、女;
+	 * 2、导入的时候,会把男、女翻译成1,2存进数据库;
+	 * @return
+	 */
+	@Bean
+	public ApplicationContextUtil applicationContextUtil() {
+		return new org.jeecgframework.core.util.ApplicationContextUtil();
+	}
+
+}

+ 36 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/config/MybatisPlusConfig.java

@@ -0,0 +1,36 @@
+package org.jeecg.config;
+
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor;
+
+/**
+ * 单数据源配置(jeecg.datasource.open = false时生效)
+ * @Author zhoujf
+ *
+ */
+@Configuration
+@MapperScan(value={"org.jeecg.modules.**.mapper*","cn.com.ctop.kuaishou.modules.**.mapper*","cn.com.ctop.crawler.modules.**.mapper*"})
+
+public class MybatisPlusConfig {
+
+    /**
+         *  分页插件
+     */
+    @Bean
+    public PaginationInterceptor paginationInterceptor() {
+        return new PaginationInterceptor();
+    }
+    
+//    /**
+//     * mybatis-plus SQL执行效率插件【生产环境可以关闭】
+//     */
+//    @Bean
+//    public PerformanceInterceptor performanceInterceptor() {
+//        return new PerformanceInterceptor();
+//    }
+    
+   
+}

+ 106 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/config/RedisConfig.java

@@ -0,0 +1,106 @@
+package org.jeecg.config;
+
+import java.lang.reflect.Method;
+import java.time.Duration;
+import java.util.Arrays;
+
+
+import javax.annotation.Resource;
+
+import org.springframework.cache.CacheManager;
+import org.springframework.cache.annotation.CachingConfigurerSupport;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.cache.interceptor.KeyGenerator;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.cache.RedisCacheConfiguration;
+import org.springframework.data.redis.cache.RedisCacheManager;
+import org.springframework.data.redis.cache.RedisCacheWriter;
+import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
+import org.springframework.data.redis.serializer.RedisSerializer;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
+import com.fasterxml.jackson.annotation.PropertyAccessor;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.ObjectMapper.DefaultTyping;
+
+@Configuration
+@EnableCaching // 开启缓存支持
+public class RedisConfig extends CachingConfigurerSupport {
+
+	@Resource
+	private LettuceConnectionFactory lettuceConnectionFactory;
+
+	/**
+	 * @description 自定义的缓存key的生成策略 若想使用这个key
+	 *              只需要讲注解上keyGenerator的值设置为keyGenerator即可</br>
+	 * @return 自定义策略生成的key
+	 */
+	@Override
+	@Bean
+	public KeyGenerator keyGenerator() {
+		return new KeyGenerator() {
+			@Override
+			public Object generate(Object target, Method method, Object... params) {
+
+				StringBuilder sb = new StringBuilder();
+				sb.append(target.getClass().getName());
+				sb.append(method.getDeclaringClass().getName());
+				Arrays.stream(params).map(Object::toString).forEach(sb::append);
+				return sb.toString();
+			}
+		};
+	}
+
+	/**
+	 * RedisTemplate配置
+	 */
+	@Bean
+	public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
+		// 设置序列化
+		Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
+		ObjectMapper om = new ObjectMapper();
+		om.setVisibility(PropertyAccessor.ALL, Visibility.ANY);
+		om.enableDefaultTyping(DefaultTyping.NON_FINAL);
+		jackson2JsonRedisSerializer.setObjectMapper(om);
+		// 配置redisTemplate
+		RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
+		redisTemplate.setConnectionFactory(lettuceConnectionFactory);
+		RedisSerializer<?> stringSerializer = new StringRedisSerializer();
+		redisTemplate.setKeySerializer(stringSerializer);// key序列化
+		redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);// value序列化
+		redisTemplate.setHashKeySerializer(stringSerializer);// Hash key序列化
+		redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);// Hash value序列化
+		redisTemplate.afterPropertiesSet();
+		return redisTemplate;
+	}
+
+	/**
+	 * 缓存配置管理器
+	 */
+	@Bean
+	public CacheManager cacheManager(LettuceConnectionFactory factory) {
+		// 以锁写入的方式创建RedisCacheWriter对象
+		RedisCacheWriter writer = RedisCacheWriter.lockingRedisCacheWriter(factory);
+		/**
+		 * 设置CacheManager的Value序列化方式为JdkSerializationRedisSerializer,
+		 * 但其实RedisCacheConfiguration默认就是使用 StringRedisSerializer序列化key,
+		 * JdkSerializationRedisSerializer序列化value, 所以以下注释代码就是默认实现,没必要写,直接注释掉
+		 */
+		// RedisSerializationContext.SerializationPair pair =
+		// RedisSerializationContext.SerializationPair.fromSerializer(new
+		// JdkSerializationRedisSerializer(this.getClass().getClassLoader()));
+		// RedisCacheConfiguration config =
+		// RedisCacheConfiguration.defaultCacheConfig().serializeValuesWith(pair);
+		// 创建默认缓存配置对象
+
+		// 创建默认缓存配置对象
+		RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(3)); //设置缓存默认有效期3小时;
+
+		RedisCacheManager cacheManager = new RedisCacheManager(writer, config);
+		return cacheManager;
+	}
+
+}

+ 151 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/config/ShiroConfig.java

@@ -0,0 +1,151 @@
+package org.jeecg.config;
+
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import javax.servlet.Filter;
+
+import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
+import org.apache.shiro.mgt.DefaultSubjectDAO;
+import org.apache.shiro.mgt.SecurityManager;
+import org.apache.shiro.spring.LifecycleBeanPostProcessor;
+import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
+import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
+import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
+import org.jeecg.modules.shiro.authc.ShiroRealm;
+import org.jeecg.modules.shiro.authc.aop.JwtFilter;
+import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.DependsOn;
+
+/**
+ * @author: Scott
+ * @date: 2018/2/7
+ * @description: shiro 配置类
+ */
+
+@Configuration
+public class ShiroConfig {
+	
+	/**
+	 * Filter Chain定义说明 
+	 * 
+	 * 1、一个URL可以配置多个Filter,使用逗号分隔
+	 * 2、当设置多个过滤器时,全部验证通过,才视为通过
+	 * 3、部分过滤器可指定参数,如perms,roles
+	 */
+	@Bean("shiroFilter")
+	public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
+		ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
+		shiroFilterFactoryBean.setSecurityManager(securityManager);
+		// 拦截器
+		Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
+		// 配置不会被拦截的链接 顺序判断
+		filterChainDefinitionMap.put("/sys/login", "anon"); //登录接口排除
+
+		filterChainDefinitionMap.put("/sys/getEncryptedString", "anon"); //获取加密串
+		filterChainDefinitionMap.put("/sys/sms", "anon");//短信验证码
+		filterChainDefinitionMap.put("/sys/phoneLogin", "anon");//手机登录		
+		filterChainDefinitionMap.put("/sys/user/checkOnlyUser", "anon");//校验用户是否存在
+		filterChainDefinitionMap.put("/sys/user/register", "anon");//用户注册
+		filterChainDefinitionMap.put("/sys/user/querySysUser", "anon");//根据手机号获取用户信息
+		filterChainDefinitionMap.put("/sys/user/phoneVerification", "anon");//用户忘记密码验证手机号
+		filterChainDefinitionMap.put("/sys/user/passwordChange", "anon");//用户更改密码
+		filterChainDefinitionMap.put("/auth/2step-code", "anon");//登录验证码
+		filterChainDefinitionMap.put("/sys/common/view/**", "anon");//图片预览不限制token
+		filterChainDefinitionMap.put("/sys/common/download/**", "anon");//文件下载不限制token
+		filterChainDefinitionMap.put("/sys/common/pdf/**", "anon");//pdf预览
+		filterChainDefinitionMap.put("/generic/**", "anon");//pdf预览需要文件
+		filterChainDefinitionMap.put("/", "anon");
+		filterChainDefinitionMap.put("/doc.html", "anon");
+		filterChainDefinitionMap.put("/**/*.js", "anon");
+		filterChainDefinitionMap.put("/**/*.css", "anon");
+		filterChainDefinitionMap.put("/**/*.html", "anon");
+		filterChainDefinitionMap.put("/**/*.svg", "anon");
+		filterChainDefinitionMap.put("/**/*.jpg", "anon");
+		filterChainDefinitionMap.put("/**/*.png", "anon");
+		filterChainDefinitionMap.put("/**/*.ico", "anon");
+		filterChainDefinitionMap.put("/druid/**", "anon");
+		filterChainDefinitionMap.put("/swagger-ui.html", "anon");
+		filterChainDefinitionMap.put("/swagger**/**", "anon");
+		filterChainDefinitionMap.put("/webjars/**", "anon");
+		filterChainDefinitionMap.put("/v2/**", "anon");
+		
+		//性能监控
+		filterChainDefinitionMap.put("/actuator/metrics/**", "anon");
+		filterChainDefinitionMap.put("/actuator/httptrace/**", "anon");
+		filterChainDefinitionMap.put("/actuator/redis/**", "anon");
+		filterChainDefinitionMap.put("/test/jeecgDemo/demo3", "anon"); //模板测试
+		filterChainDefinitionMap.put("/test/jeecgDemo/redisDemo/**", "anon"); //redis测试
+
+		//oauth接口
+		filterChainDefinitionMap.put("/auth/kuaishou", "anon");
+		filterChainDefinitionMap.put("/auth/bytedance", "anon");
+		filterChainDefinitionMap.put("/auth/begin", "anon");
+		filterChainDefinitionMap.put("/ctop/syncdata/**", "anon");
+		//头条接口
+		filterChainDefinitionMap.put("/toutiao/**", "anon");
+
+		//爬虫接口
+		filterChainDefinitionMap.put("/graphql/video", "anon");
+
+		// 添加自己的过滤器并且取名为jwt
+		Map<String, Filter> filterMap = new HashMap<String, Filter>(1);
+		filterMap.put("jwt", new JwtFilter());
+		shiroFilterFactoryBean.setFilters(filterMap);
+		// <!-- 过滤链定义,从上向下顺序执行,一般将/**放在最为下边
+		filterChainDefinitionMap.put("/**", "jwt");
+
+		// 未授权界面返回JSON
+		shiroFilterFactoryBean.setUnauthorizedUrl("/sys/common/403");
+		shiroFilterFactoryBean.setLoginUrl("/sys/common/403");
+		shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
+		return shiroFilterFactoryBean;
+	}
+
+	@Bean("securityManager")
+	public DefaultWebSecurityManager securityManager(ShiroRealm myRealm) {
+		DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
+		securityManager.setRealm(myRealm);
+
+		/*
+		 * 关闭shiro自带的session,详情见文档
+		 * http://shiro.apache.org/session-management.html#SessionManagement-
+		 * StatelessApplications%28Sessionless%29
+		 */
+		DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
+		DefaultSessionStorageEvaluator defaultSessionStorageEvaluator = new DefaultSessionStorageEvaluator();
+		defaultSessionStorageEvaluator.setSessionStorageEnabled(false);
+		subjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator);
+		securityManager.setSubjectDAO(subjectDAO);
+
+		return securityManager;
+	}
+
+	/**
+	 * 下面的代码是添加注解支持
+	 * @return
+	 */
+	@Bean
+	@DependsOn("lifecycleBeanPostProcessor")
+	public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
+		DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
+		defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
+		return defaultAdvisorAutoProxyCreator;
+	}
+
+	@Bean
+	public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
+		return new LifecycleBeanPostProcessor();
+	}
+
+	@Bean
+	public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
+		AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
+		advisor.setSecurityManager(securityManager);
+		return advisor;
+	}
+
+}

+ 101 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/config/Swagger2Config.java

@@ -0,0 +1,101 @@
+package org.jeecg.config;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jeecg.modules.shiro.vo.DefContants;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+import com.github.xiaoymin.swaggerbootstrapui.annotations.EnableSwaggerBootstrapUI;
+
+import io.swagger.annotations.ApiOperation;
+import springfox.documentation.service.Parameter;
+import lombok.extern.slf4j.Slf4j;
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.ParameterBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.schema.ModelRef;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+/**
+ * @Author scott
+ */
+@Slf4j
+@Configuration
+@EnableSwagger2
+@EnableSwaggerBootstrapUI
+public class Swagger2Config implements WebMvcConfigurer {
+
+	/**
+	 *
+	 * 显示swagger-ui.html文档展示页,还必须注入swagger资源:
+	 * 
+	 * @param registry
+	 */
+	@Override
+	public void addResourceHandlers(ResourceHandlerRegistry registry) {
+		registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
+		registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/");
+		registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
+	}
+
+	/**
+	 * swagger2的配置文件,这里可以配置swagger2的一些基本的内容,比如扫描的包等等
+	 *
+	 * @return Docket
+	 */
+	@Bean
+	public Docket createRestApi() {
+		return new Docket(DocumentationType.SWAGGER_2)
+				.apiInfo(apiInfo())
+				.select()
+				//此包路径下的类,才生成接口文档
+				.apis(RequestHandlerSelectors.basePackage("org.jeecg.modules"))
+				//加了ApiOperation注解的类,才生成接口文档
+	            .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
+				.paths(PathSelectors.any())
+				.build()
+				.globalOperationParameters(setHeaderToken());
+	}
+
+	/**
+	 * JWT token
+	 * @return
+	 */
+	private List<Parameter> setHeaderToken() {
+        ParameterBuilder tokenPar = new ParameterBuilder();
+        List<Parameter> pars = new ArrayList<>();
+        tokenPar.name(DefContants.X_ACCESS_TOKEN).description("token").modelRef(new ModelRef("string")).parameterType("header").required(false).build();
+        pars.add(tokenPar.build());
+        return pars;
+    }
+
+	/**
+	 * api文档的详细信息函数,注意这里的注解引用的是哪个
+	 *
+	 * @return
+	 */
+	private ApiInfo apiInfo() {
+		return new ApiInfoBuilder()
+				// //大标题
+				.title("Jeecg-Boot 后台服务API接口文档")
+				// 版本号
+				.version("1.0")
+//				.termsOfServiceUrl("NO terms of service")
+				// 描述
+				.description("restful 风格接口")
+				// 作者
+//				.contact(new Contact("scott", "http://jeecg.org", "jeecgos@163.com"))
+//                .license("The Apache License, Version 2.0")
+//                .licenseUrl("http://www.apache.org/licenses/LICENSE-2.0.html")
+				.build();
+	}
+
+}

+ 62 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/config/WebMvcConfiguration.java

@@ -0,0 +1,62 @@
+package org.jeecg.config;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.cors.CorsConfiguration;
+import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
+import org.springframework.web.filter.CorsFilter;
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
+import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+/**
+ * Spring Boot 2.0 解决跨域问题
+ * 
+ * @Author qinfeng
+ *
+ */
+@Configuration
+public class WebMvcConfiguration implements WebMvcConfigurer {
+
+	@Value("${jeecg.path.upload}")
+	private String upLoadPath;
+	@Value("${jeecg.path.webapp}")
+	private String webAppPath;
+	@Value("${spring.resource.static-locations}")
+	private String staticLocations;
+
+	@Bean
+	public CorsFilter corsFilter() {
+		final UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
+		final CorsConfiguration corsConfiguration = new CorsConfiguration();
+		/* 是否允许请求带有验证信息 */
+		corsConfiguration.setAllowCredentials(true);
+		/* 允许访问的客户端域名 */
+		corsConfiguration.addAllowedOrigin("*");
+		/* 允许服务端访问的客户端请求头 */
+		corsConfiguration.addAllowedHeader("*");
+		/* 允许访问的方法名,GET POST等 */
+		corsConfiguration.addAllowedMethod("*");
+		urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
+		return new CorsFilter(urlBasedCorsConfigurationSource);
+	}
+
+	/**
+	 * 静态资源的配置 - 使得可以从磁盘中读取 Html、图片、视频、音频等
+	 */
+	@Override
+	public void addResourceHandlers(ResourceHandlerRegistry registry) {
+		registry.addResourceHandler("/**")
+		.addResourceLocations("file:" + upLoadPath + "//", "file:" + webAppPath + "//")
+		.addResourceLocations(staticLocations.split(","));
+	}
+
+	/**
+	 * 访问根路径默认跳转 index.html页面 (简化部署方案: 可以把前端打包直接放到项目的 webapp,上面的配置)
+	 */
+	@Override
+	public void addViewControllers(ViewControllerRegistry registry) {
+		registry.addViewController("/").setViewName("index.html");
+	}
+}

+ 164 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/config/mybatis/MybatisInterceptor.java

@@ -0,0 +1,164 @@
+package org.jeecg.config.mybatis;
+
+import java.lang.reflect.Field;
+import java.util.Date;
+import java.util.Properties;
+
+import org.apache.ibatis.binding.MapperMethod.ParamMap;
+import org.apache.ibatis.executor.Executor;
+import org.apache.ibatis.mapping.MappedStatement;
+import org.apache.ibatis.mapping.SqlCommandType;
+import org.apache.ibatis.plugin.Interceptor;
+import org.apache.ibatis.plugin.Intercepts;
+import org.apache.ibatis.plugin.Invocation;
+import org.apache.ibatis.plugin.Plugin;
+import org.apache.ibatis.plugin.Signature;
+import org.apache.shiro.SecurityUtils;
+import org.jeecg.common.system.vo.LoginUser;
+import org.jeecg.common.util.oConvertUtils;
+import org.jeecg.modules.system.entity.SysUser;
+import org.springframework.stereotype.Component;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * mybatis拦截器,自动注入创建人、创建时间、修改人、修改时间
+ * @Author scott
+ * @Date  2019-01-19
+ *
+ */
+@Slf4j
+@Component
+@Intercepts({ @Signature(type = Executor.class, method = "update", args = { MappedStatement.class, Object.class }) })
+public class MybatisInterceptor implements Interceptor {
+
+	@Override
+	public Object intercept(Invocation invocation) throws Throwable {
+		MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
+		String sqlId = mappedStatement.getId();
+		log.debug("------sqlId------" + sqlId);
+		SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType();
+		Object parameter = invocation.getArgs()[1];
+		log.debug("------sqlCommandType------" + sqlCommandType);
+
+		if (parameter == null) {
+			return invocation.proceed();
+		}
+		if (SqlCommandType.INSERT == sqlCommandType) {
+			Field[] fields = oConvertUtils.getAllFields(parameter);
+			for (Field field : fields) {
+				log.debug("------field.name------" + field.getName());
+				try {
+					// 获取登录用户信息
+					LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
+					if ("createBy".equals(field.getName())) {
+						field.setAccessible(true);
+						Object local_createBy = field.get(parameter);
+						field.setAccessible(false);
+						if (local_createBy == null || local_createBy.equals("")) {
+							String createBy = "jeecg";
+							if (sysUser != null) {
+								// 登录账号
+								createBy = sysUser.getUsername();
+							}
+							if (oConvertUtils.isNotEmpty(createBy)) {
+								field.setAccessible(true);
+								field.set(parameter, createBy);
+								field.setAccessible(false);
+							}
+						}
+					}
+					// 注入创建时间
+					if ("createTime".equals(field.getName())) {
+						field.setAccessible(true);
+						Object local_createDate = field.get(parameter);
+						field.setAccessible(false);
+						if (local_createDate == null || local_createDate.equals("")) {
+							field.setAccessible(true);
+							field.set(parameter, new Date());
+							field.setAccessible(false);
+						}
+					}
+					//注入部门编码
+					if ("sysOrgCode".equals(field.getName())) {
+						field.setAccessible(true);
+						Object local_sysOrgCode = field.get(parameter);
+						field.setAccessible(false);
+						if (local_sysOrgCode == null || local_sysOrgCode.equals("")) {
+							String sysOrgCode = "";
+							// 获取登录用户信息
+							if (sysUser != null) {
+								// 登录账号
+								sysOrgCode = sysUser.getOrgCode();
+							}
+							if (oConvertUtils.isNotEmpty(sysOrgCode)) {
+								field.setAccessible(true);
+								field.set(parameter, sysOrgCode);
+								field.setAccessible(false);
+							}
+						}
+					}
+				} catch (Exception e) {
+				}
+			}
+		}
+		if (SqlCommandType.UPDATE == sqlCommandType) {
+			Field[] fields = null;
+			if (parameter instanceof ParamMap) {
+				ParamMap<?> p = (ParamMap<?>) parameter;
+				parameter = p.get("param1");
+				fields = oConvertUtils.getAllFields(parameter);
+			} else {
+				fields = oConvertUtils.getAllFields(parameter);
+			}
+
+			for (Field field : fields) {
+				log.debug("------field.name------" + field.getName());
+				try {
+					if ("updateBy".equals(field.getName())) {
+						field.setAccessible(true);
+						Object local_updateBy = field.get(parameter);
+						field.setAccessible(false);
+						if (local_updateBy == null || local_updateBy.equals("")) {
+							String updateBy = "jeecg";
+							// 获取登录用户信息
+							LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
+							if (sysUser != null) {
+								// 登录账号
+								updateBy = sysUser.getUsername();
+							}
+							if (oConvertUtils.isNotEmpty(updateBy)) {
+								field.setAccessible(true);
+								field.set(parameter, updateBy);
+								field.setAccessible(false);
+							}
+						}
+					}
+					if ("updateTime".equals(field.getName())) {
+						field.setAccessible(true);
+						Object local_updateDate = field.get(parameter);
+						field.setAccessible(false);
+						if (local_updateDate == null || local_updateDate.equals("")) {
+							field.setAccessible(true);
+							field.set(parameter, new Date());
+							field.setAccessible(false);
+						}
+					}
+				} catch (Exception e) {
+				}
+			}
+		}
+		return invocation.proceed();
+	}
+
+	@Override
+	public Object plugin(Object target) {
+		return Plugin.wrap(target, this);
+	}
+
+	@Override
+	public void setProperties(Properties properties) {
+		// TODO Auto-generated method stub
+	}
+
+}

+ 113 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/AdCoverController.java

@@ -0,0 +1,113 @@
+package org.jeecg.modules.ctop.controller;
+
+import cn.com.ctop.crawler.modules.account.entity.KuaishouAdAccount;
+import cn.com.ctop.crawler.modules.account.service.IKuaishouAdAccountService;
+import cn.com.ctop.kuaishou.modules.app.entity.AppAd;
+import cn.com.ctop.kuaishou.modules.app.entity.AppVideo;
+import cn.com.ctop.kuaishou.modules.app.service.IAppAdService;
+import cn.com.ctop.kuaishou.modules.app.service.IAppVideoService;
+import cn.com.ctop.kuaishou.modules.app.service.IKuaishouAppService;
+import cn.com.ctop.kuaishou.modules.graphql.entity.KuaishouVideo;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.google.gson.Gson;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.modules.system.entity.SysCategory;
+import org.jeecg.modules.system.service.ISysCategoryService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@RestController
+@RequestMapping("/ctop/adcover")
+public class AdCoverController {
+    @Autowired
+    private IAppAdService appAdService;
+    @Autowired
+    private IAppVideoService appVideoService;
+    @Autowired
+    private IKuaishouAdAccountService kuaishouAdAccountService;
+    @Autowired
+    private ISysCategoryService sysCategoryService;
+    @ResponseBody
+    @RequestMapping(value="/feeds", method = RequestMethod.GET)
+    public Result<List<AppAd>> getVideoList(HttpServletRequest req){
+        Result<List<AppAd>> result = new Result<List<AppAd>>();
+        AppAd ad = new AppAd();
+        Map<String,String[]> paramMap = req.getParameterMap();
+        String industry = paramMap.get("industry")!=null?sysCategoryService.getById(paramMap.get("industry")[0]).getName():null;
+        String company = paramMap.get("company")!=null?paramMap.get("company")[0]:null;
+        String product = paramMap.get("product")!=null?paramMap.get("product")[0]:null;
+        String start = paramMap.get("start")!=null?paramMap.get("start")[0]:null;
+        String end = paramMap.get("end")!=null?paramMap.get("end")[0]:null;
+        String orderByColumn = paramMap.get("orderByColumn")!=null?paramMap.get("orderByColumn")[0]:null;
+        String orderByType = paramMap.get("orderByType")!=null?paramMap.get("orderByType")[0]:null;
+        Integer pageSize = paramMap.get("pageSize")!=null?Integer.parseInt(paramMap.get("pageSize")[0]):null;
+        Integer pageNo = paramMap.get("pageNo")!=null?Integer.parseInt(paramMap.get("pageNo")[0]):null;
+//        Integer pageSize = paramMap.get("pageSize")!=null?paramMap.get("orderByType")[0]:null;
+        int pageStart = (pageNo-1)*pageSize;
+        Page<AppAd> page = new Page<AppAd>(pageNo, pageSize);
+        List<AppAd> list = appAdService.queryAdFeeds(industry,company,product,start,end,orderByColumn,orderByType,pageStart,pageSize);
+        result.setResult(list);
+        result.setSuccess(true);
+        return result;
+    }
+
+//    @RequestMapping(value = "/list", method = RequestMethod.GET)
+//    //@RequiresPermissions("sys:user:list")
+//    public Result<IPage<SysUser>> queryPageList(SysUser user, @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
+//                                                @RequestParam(name="pageSize", defaultValue="10") Integer pageSize, HttpServletRequest req) {
+//        Result<IPage<SysUser>> result = new Result<IPage<SysUser>>();
+//        QueryWrapper<SysUser> queryWrapper = QueryGenerator.initQueryWrapper(user, req.getParameterMap());
+//        Page<SysUser> page = new Page<SysUser>(pageNo, pageSize);
+//        IPage<SysUser> pageList = sysUserService.page(page, queryWrapper);
+//        result.setSuccess(true);
+//        result.setResult(pageList);
+//        return result;
+//    }
+    @ResponseBody
+    @RequestMapping(value="/detail", method = RequestMethod.GET)
+    public Result<Map<String,Object>> getDetail(@RequestParam(name="photoId") Long photoId, @RequestParam(name="userId") Long userId){
+        Result<Map<String,Object>> result = new Result<Map<String,Object>>();
+        AppAd ad = new AppAd();
+        ad.setPhotoId(photoId);
+        QueryWrapper<AppAd> queryWrapper = QueryGenerator.initQueryWrapper(ad,null);
+        List<AppAd> list = appAdService.list(queryWrapper);
+        AppVideo video = appVideoService.getById(photoId);
+        KuaishouAdAccount kuaishouAdAccount = kuaishouAdAccountService.getById(userId);
+        if(kuaishouAdAccount == null){
+            kuaishouAdAccount = new KuaishouAdAccount();
+        }
+        if(video == null){
+            video = new AppVideo();
+        }
+        kuaishouAdAccount.setUrl("https://live.kuaishou.com/profile/"+video.getShareInfo().substring(video.getShareInfo().indexOf("=")+1,video.getShareInfo().indexOf("&")));
+        video.setShareInfo("https://live.kuaishou.com/u/"+video.getShareInfo().replace("userId=","").replace("photoId=","").replace("&","/"));
+        Map<String,Object> map = new HashMap<String,Object>();
+        map.put("adlist",list);
+        map.put("user",kuaishouAdAccount);
+        map.put("video",video);
+        result.setResult(map);
+        result.setSuccess(true);
+        return result;
+    }
+
+    @ResponseBody
+    @RequestMapping(value="/adlist", method = RequestMethod.GET)
+    public Result<List<AppAd>> getAdList(@RequestParam(name="photoId") String photoId, @RequestParam(name="userId") Long userId){
+        Result<List<AppAd>> result = new Result<List<AppAd>>();
+        AppAd ad = new AppAd();
+        ad.setPhotoId(Long.valueOf(photoId));
+        QueryWrapper<AppAd> queryWrapper = QueryGenerator.initQueryWrapper(ad,null);
+        List<AppAd> list = appAdService.list(queryWrapper);
+        result.setResult(list);
+        result.setSuccess(true);
+        return result;
+    }
+}

+ 251 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/AdvertiserController.java

@@ -0,0 +1,251 @@
+package org.jeecg.modules.ctop.controller;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.common.aspect.annotation.AutoLog;
+import org.jeecg.common.util.oConvertUtils;
+import org.jeecg.modules.ctop.entity.Advertiser;
+import org.jeecg.modules.ctop.service.IAdvertiserService;
+import java.util.Date;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.extern.slf4j.Slf4j;
+
+import org.jeecgframework.poi.excel.ExcelImportUtil;
+import org.jeecgframework.poi.excel.def.NormalExcelConstants;
+import org.jeecgframework.poi.excel.entity.ExportParams;
+import org.jeecgframework.poi.excel.entity.ImportParams;
+import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
+import org.springframework.web.servlet.ModelAndView;
+import com.alibaba.fastjson.JSON;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+ /**
+ * @Description: 广告主信息表
+ * @Author: jeecg-boot
+ * @Date:   2019-06-11
+ * @Version: V1.0
+ */
+@Slf4j
+@Api(tags="广告主信息表")
+@RestController
+@RequestMapping("/ctop/advertiser")
+public class AdvertiserController {
+	@Autowired
+	private IAdvertiserService advertiserService;
+	
+	/**
+	  * 分页列表查询
+	 * @param advertiser
+	 * @param pageNo
+	 * @param pageSize
+	 * @param req
+	 * @return
+	 */
+	@AutoLog(value = "广告主信息表-分页列表查询")
+	@ApiOperation(value="广告主信息表-分页列表查询", notes="广告主信息表-分页列表查询")
+	@GetMapping(value = "/list")
+	public Result<IPage<Advertiser>> queryPageList(Advertiser advertiser,
+									  @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
+									  @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
+									  HttpServletRequest req) {
+		Result<IPage<Advertiser>> result = new Result<IPage<Advertiser>>();
+		QueryWrapper<Advertiser> queryWrapper = QueryGenerator.initQueryWrapper(advertiser, req.getParameterMap());
+		Page<Advertiser> page = new Page<Advertiser>(pageNo, pageSize);
+		IPage<Advertiser> pageList = advertiserService.page(page, queryWrapper);
+		result.setSuccess(true);
+		result.setResult(pageList);
+		return result;
+	}
+	
+	/**
+	  *   添加
+	 * @param advertiser
+	 * @return
+	 */
+	@AutoLog(value = "广告主信息表-添加")
+	@ApiOperation(value="广告主信息表-添加", notes="广告主信息表-添加")
+	@PostMapping(value = "/add")
+	public Result<Advertiser> add(@RequestBody Advertiser advertiser) {
+		Result<Advertiser> result = new Result<Advertiser>();
+		try {
+			advertiserService.save(advertiser);
+			result.success("添加成功!");
+		} catch (Exception e) {
+			log.error(e.getMessage(),e);
+			result.error500("操作失败");
+		}
+		return result;
+	}
+	
+	/**
+	  *  编辑
+	 * @param advertiser
+	 * @return
+	 */
+	@AutoLog(value = "广告主信息表-编辑")
+	@ApiOperation(value="广告主信息表-编辑", notes="广告主信息表-编辑")
+	@PutMapping(value = "/edit")
+	public Result<Advertiser> edit(@RequestBody Advertiser advertiser) {
+		Result<Advertiser> result = new Result<Advertiser>();
+		Advertiser advertiserEntity = advertiserService.getById(advertiser.getId());
+		if(advertiserEntity==null) {
+			result.error500("未找到对应实体");
+		}else {
+			boolean ok = advertiserService.updateById(advertiser);
+			//TODO 返回false说明什么?
+			if(ok) {
+				result.success("修改成功!");
+			}
+		}
+		
+		return result;
+	}
+	
+	/**
+	  *   通过id删除
+	 * @param id
+	 * @return
+	 */
+	@AutoLog(value = "广告主信息表-通过id删除")
+	@ApiOperation(value="广告主信息表-通过id删除", notes="广告主信息表-通过id删除")
+	@DeleteMapping(value = "/delete")
+	public Result<Advertiser> delete(@RequestParam(name="id",required=true) String id) {
+		Result<Advertiser> result = new Result<Advertiser>();
+		Advertiser advertiser = advertiserService.getById(id);
+		if(advertiser==null) {
+			result.error500("未找到对应实体");
+		}else {
+			boolean ok = advertiserService.removeById(id);
+			if(ok) {
+				result.success("删除成功!");
+			}
+		}
+		
+		return result;
+	}
+	
+	/**
+	  *  批量删除
+	 * @param ids
+	 * @return
+	 */
+	@AutoLog(value = "广告主信息表-批量删除")
+	@ApiOperation(value="广告主信息表-批量删除", notes="广告主信息表-批量删除")
+	@DeleteMapping(value = "/deleteBatch")
+	public Result<Advertiser> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
+		Result<Advertiser> result = new Result<Advertiser>();
+		if(ids==null || "".equals(ids.trim())) {
+			result.error500("参数不识别!");
+		}else {
+			this.advertiserService.removeByIds(Arrays.asList(ids.split(",")));
+			result.success("删除成功!");
+		}
+		return result;
+	}
+	
+	/**
+	  * 通过id查询
+	 * @param id
+	 * @return
+	 */
+	@AutoLog(value = "广告主信息表-通过id查询")
+	@ApiOperation(value="广告主信息表-通过id查询", notes="广告主信息表-通过id查询")
+	@GetMapping(value = "/queryById")
+	public Result<Advertiser> queryById(@RequestParam(name="id",required=true) String id) {
+		Result<Advertiser> result = new Result<Advertiser>();
+		Advertiser advertiser = advertiserService.getById(id);
+		if(advertiser==null) {
+			result.error500("未找到对应实体");
+		}else {
+			result.setResult(advertiser);
+			result.setSuccess(true);
+		}
+		return result;
+	}
+
+  /**
+      * 导出excel
+   *
+   * @param request
+   * @param response
+   */
+  @RequestMapping(value = "/exportXls")
+  public ModelAndView exportXls(HttpServletRequest request, HttpServletResponse response) {
+      // Step.1 组装查询条件
+      QueryWrapper<Advertiser> queryWrapper = null;
+      try {
+          String paramsStr = request.getParameter("paramsStr");
+          if (oConvertUtils.isNotEmpty(paramsStr)) {
+              String deString = URLDecoder.decode(paramsStr, "UTF-8");
+              Advertiser advertiser = JSON.parseObject(deString, Advertiser.class);
+              queryWrapper = QueryGenerator.initQueryWrapper(advertiser, request.getParameterMap());
+          }
+      } catch (UnsupportedEncodingException e) {
+          e.printStackTrace();
+      }
+
+      //Step.2 AutoPoi 导出Excel
+      ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
+      List<Advertiser> pageList = advertiserService.list(queryWrapper);
+      //导出文件名称
+      mv.addObject(NormalExcelConstants.FILE_NAME, "广告主信息表列表");
+      mv.addObject(NormalExcelConstants.CLASS, Advertiser.class);
+      mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("广告主信息表列表数据", "导出人:Jeecg", "导出信息"));
+      mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
+      return mv;
+  }
+
+  /**
+      * 通过excel导入数据
+   *
+   * @param request
+   * @param response
+   * @return
+   */
+  @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
+  public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
+      MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
+      Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
+      for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
+          MultipartFile file = entity.getValue();// 获取上传文件对象
+          ImportParams params = new ImportParams();
+          params.setTitleRows(2);
+          params.setHeadRows(1);
+          params.setNeedSave(true);
+          try {
+              List<Advertiser> listAdvertisers = ExcelImportUtil.importExcel(file.getInputStream(), Advertiser.class, params);
+              for (Advertiser advertiserExcel : listAdvertisers) {
+                  advertiserService.save(advertiserExcel);
+              }
+              return Result.ok("文件导入成功!数据行数:" + listAdvertisers.size());
+          } catch (Exception e) {
+              log.error(e.getMessage(),e);
+              return Result.error("文件导入失败:"+e.getMessage());
+          } finally {
+              try {
+                  file.getInputStream().close();
+              } catch (IOException e) {
+                  e.printStackTrace();
+              }
+          }
+      }
+      return Result.ok("文件导入失败!");
+  }
+
+}

+ 128 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/AuthController.java

@@ -0,0 +1,128 @@
+package org.jeecg.modules.ctop.controller;
+
+import cn.com.ctop.common.utils.HttpUtils;
+import cn.com.ctop.common.utils.PropertiesUtils;
+import cn.com.ctop.kuaishou.modules.material.service.IKuaishouInterfaceService;
+import cn.com.ctop.toutiao.common.BytedanceInterfaceConstant;
+import com.alibaba.fastjson.JSONObject;
+import com.google.gson.Gson;
+import constant.KuaishouInterfaceConstant;
+import org.apache.commons.lang.StringUtils;
+import org.jeecg.modules.ctop.entity.CTopOauthToken;
+import org.jeecg.modules.ctop.mapper.CTopOauthTokenMapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+@Controller
+@RequestMapping("/auth")
+public class AuthController {
+    private static final Logger logger = LoggerFactory.getLogger(AuthController.class);
+    @Autowired
+    private IKuaishouInterfaceService kuaishouInterfaceService;
+    @RequestMapping("/begin")
+    public String authBegin(HttpServletRequest request,
+                            HttpServletResponse response,
+                            @RequestParam("auth_type")String authType){
+        try{
+            String codeUrl = "";
+            switch (authType)
+            {
+                case "bytedance":
+                    codeUrl = this.getByteDanceCodeUrl(UUID.randomUUID().toString());
+                    System.out.println(codeUrl);
+                    return "redirect:"+codeUrl;
+                case "kuaishou":
+                    codeUrl = this.getKuaishouCodeUrl(UUID.randomUUID().toString());
+                    System.out.println(codeUrl);
+                    return "redirect:"+codeUrl;
+                default:
+                    System.out.println("");
+
+            }
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+
+        return "auth_error";
+    }
+    @RequestMapping("/bytedance")
+    @ResponseBody
+    public String bytedance(HttpServletRequest request,
+                            HttpServletResponse response,
+                            @RequestParam("auth_code")String authCode,
+                            @RequestParam("state")String state,@RequestParam("accountId")String accountId) {
+        System.out.println(request.getQueryString());
+        if(StringUtils.isNotBlank(authCode)){
+            System.out.println(this.getByteDanceAccessToken(authCode,accountId));
+            return "auth_success";
+        }
+        return "auth_fail";
+    }
+
+
+    public String getByteDanceAccessToken(String authCode,String accountId){
+        Map<String, Object> param = new HashMap<String, Object>();
+        param.put("app_id",PropertiesUtils.getValue("bytedance_config","bytedance_appid"));
+        param.put("secret",PropertiesUtils.getValue("bytedance_config","bytedance_secret"));
+        param.put("grant_type","auth_code");
+        param.put("auth_code",authCode);
+
+        Gson gson = new Gson();
+        String result = "";
+        try{
+            System.out.println(PropertiesUtils.getValue("bytedance_config","bytedance_api_url")+ BytedanceInterfaceConstant.AUTH_TOKEN);
+            result = HttpUtils.httpPostRequest(PropertiesUtils.getValue("bytedance_config","bytedance_api_url")+BytedanceInterfaceConstant.AUTH_TOKEN,param,new HashMap<>());
+            System.out.println(result);
+            JSONObject resultObject = JSONObject.parseObject(result);
+            Integer code = resultObject.getInteger("code");
+            String message = resultObject.getString("message");
+            if(null == code||code!=0){
+                logger.info("获取token失败,accountId:{},message:{}",accountId,message);
+            }
+            JSONObject data = resultObject.getJSONObject("data");
+            CTopOauthToken token = new CTopOauthToken(accountId,data);
+            cTopOauthTokenMapper.insert(token);
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+        return result;
+    }
+
+    @Autowired
+    private CTopOauthTokenMapper cTopOauthTokenMapper;
+
+    public String getKuaishouCodeUrl(String state) throws UnsupportedEncodingException {
+        StringBuffer sb = new StringBuffer();
+        sb.append(PropertiesUtils.getValue("kuaishou_config","kuaishou_auth_url"))
+                .append(KuaishouInterfaceConstant.AUTH_PATH)
+                .append("?app_id="+PropertiesUtils.getValue("kuaishou_config","kuaishou_appid"))
+                .append("&state="+state)
+                .append("&scope=%5B%22report_service%22%2C%22ad_query%22%5D")
+                .append("&redirect_uri="+ URLEncoder.encode(PropertiesUtils.getValue("kuaishou_config","kuaishou_callback_url"),"UTF-8"));
+        return sb.toString();
+    }
+
+
+    public String getByteDanceCodeUrl(String state) throws UnsupportedEncodingException {
+        StringBuffer sb = new StringBuffer();
+        sb.append(PropertiesUtils.getValue("bytedance_config","bytedance_auth_url"))
+                .append(BytedanceInterfaceConstant.AUTH_PATH)
+                .append("?app_id="+PropertiesUtils.getValue("bytedance_config","bytedance_appid"))
+                .append("&state="+state)
+                .append("&redirect_uri="+ URLEncoder.encode(PropertiesUtils.getValue("bytedance_config","bytedance_callback_url"),"UTF-8"));
+        return sb.toString();
+    }
+}

+ 244 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/CTopOauthTokenController.java

@@ -0,0 +1,244 @@
+package org.jeecg.modules.ctop.controller;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.common.aspect.annotation.AutoLog;
+import org.jeecg.common.util.oConvertUtils;
+import org.jeecg.modules.ctop.entity.CTopOauthToken;
+import org.jeecg.modules.ctop.service.ICTopOauthTokenService;
+import java.util.Date;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.extern.slf4j.Slf4j;
+
+import org.jeecgframework.poi.excel.ExcelImportUtil;
+import org.jeecgframework.poi.excel.def.NormalExcelConstants;
+import org.jeecgframework.poi.excel.entity.ExportParams;
+import org.jeecgframework.poi.excel.entity.ImportParams;
+import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
+import org.springframework.web.servlet.ModelAndView;
+import com.alibaba.fastjson.JSON;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+ /**
+ * @Description: oauth授权码
+ * @Author: jeecg-boot
+ * @Date:   2019-07-09
+ * @Version: V1.0
+ */
+@Slf4j
+@Api(tags="oauth授权码")
+@RestController
+@RequestMapping("/ctop/cTopOauthToken")
+public class CTopOauthTokenController {
+	@Autowired
+	private ICTopOauthTokenService cTopOauthTokenService;
+	
+	/**
+	  * 分页列表查询
+	 * @param cTopOauthToken
+	 * @param pageNo
+	 * @param pageSize
+	 * @param req
+	 * @return
+	 */
+	@AutoLog(value = "oauth授权码-分页列表查询")
+	@ApiOperation(value="oauth授权码-分页列表查询", notes="oauth授权码-分页列表查询")
+	@GetMapping(value = "/list")
+	public Result<IPage<CTopOauthToken>> queryPageList(CTopOauthToken cTopOauthToken,
+									  @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
+									  @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
+									  HttpServletRequest req) {
+		Result<IPage<CTopOauthToken>> result = new Result<IPage<CTopOauthToken>>();
+		QueryWrapper<CTopOauthToken> queryWrapper = QueryGenerator.initQueryWrapper(cTopOauthToken, req.getParameterMap());
+		Page<CTopOauthToken> page = new Page<CTopOauthToken>(pageNo, pageSize);
+		IPage<CTopOauthToken> pageList = cTopOauthTokenService.page(page, queryWrapper);
+		result.setSuccess(true);
+		result.setResult(pageList);
+		return result;
+	}
+	
+	/**
+	  *   添加
+	 * @param cTopOauthToken
+	 * @return
+	 */
+	@AutoLog(value = "oauth授权码-添加")
+	@ApiOperation(value="oauth授权码-添加", notes="oauth授权码-添加")
+	@PostMapping(value = "/add")
+	public Result<CTopOauthToken> add(@RequestBody CTopOauthToken cTopOauthToken) {
+		Result<CTopOauthToken> result = new Result<CTopOauthToken>();
+		try {
+			cTopOauthTokenService.save(cTopOauthToken);
+			result.success("添加成功!");
+		} catch (Exception e) {
+			log.error(e.getMessage(),e);
+			result.error500("操作失败");
+		}
+		return result;
+	}
+	
+	/**
+	  *  编辑
+	 * @param cTopOauthToken
+	 * @return
+	 */
+	@AutoLog(value = "oauth授权码-编辑")
+	@ApiOperation(value="oauth授权码-编辑", notes="oauth授权码-编辑")
+	@PutMapping(value = "/edit")
+	public Result<CTopOauthToken> edit(@RequestBody CTopOauthToken cTopOauthToken) {
+		Result<CTopOauthToken> result = new Result<CTopOauthToken>();
+		CTopOauthToken cTopOauthTokenEntity = cTopOauthTokenService.getById(cTopOauthToken.getId());
+		if(cTopOauthTokenEntity==null) {
+			result.error500("未找到对应实体");
+		}else {
+			boolean ok = cTopOauthTokenService.updateById(cTopOauthToken);
+			//TODO 返回false说明什么?
+			if(ok) {
+				result.success("修改成功!");
+			}
+		}
+		
+		return result;
+	}
+	
+	/**
+	  *   通过id删除
+	 * @param id
+	 * @return
+	 */
+	@AutoLog(value = "oauth授权码-通过id删除")
+	@ApiOperation(value="oauth授权码-通过id删除", notes="oauth授权码-通过id删除")
+	@DeleteMapping(value = "/delete")
+	public Result<?> delete(@RequestParam(name="id",required=true) String id) {
+		try {
+			cTopOauthTokenService.removeById(id);
+		} catch (Exception e) {
+			log.error("删除失败",e.getMessage());
+			return Result.error("删除失败!");
+		}
+		return Result.ok("删除成功!");
+	}
+	
+	/**
+	  *  批量删除
+	 * @param ids
+	 * @return
+	 */
+	@AutoLog(value = "oauth授权码-批量删除")
+	@ApiOperation(value="oauth授权码-批量删除", notes="oauth授权码-批量删除")
+	@DeleteMapping(value = "/deleteBatch")
+	public Result<CTopOauthToken> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
+		Result<CTopOauthToken> result = new Result<CTopOauthToken>();
+		if(ids==null || "".equals(ids.trim())) {
+			result.error500("参数不识别!");
+		}else {
+			this.cTopOauthTokenService.removeByIds(Arrays.asList(ids.split(",")));
+			result.success("删除成功!");
+		}
+		return result;
+	}
+	
+	/**
+	  * 通过id查询
+	 * @param id
+	 * @return
+	 */
+	@AutoLog(value = "oauth授权码-通过id查询")
+	@ApiOperation(value="oauth授权码-通过id查询", notes="oauth授权码-通过id查询")
+	@GetMapping(value = "/queryById")
+	public Result<CTopOauthToken> queryById(@RequestParam(name="id",required=true) String id) {
+		Result<CTopOauthToken> result = new Result<CTopOauthToken>();
+		CTopOauthToken cTopOauthToken = cTopOauthTokenService.getById(id);
+		if(cTopOauthToken==null) {
+			result.error500("未找到对应实体");
+		}else {
+			result.setResult(cTopOauthToken);
+			result.setSuccess(true);
+		}
+		return result;
+	}
+
+  /**
+      * 导出excel
+   *
+   * @param request
+   * @param response
+   */
+  @RequestMapping(value = "/exportXls")
+  public ModelAndView exportXls(HttpServletRequest request, HttpServletResponse response) {
+      // Step.1 组装查询条件
+      QueryWrapper<CTopOauthToken> queryWrapper = null;
+      try {
+          String paramsStr = request.getParameter("paramsStr");
+          if (oConvertUtils.isNotEmpty(paramsStr)) {
+              String deString = URLDecoder.decode(paramsStr, "UTF-8");
+              CTopOauthToken cTopOauthToken = JSON.parseObject(deString, CTopOauthToken.class);
+              queryWrapper = QueryGenerator.initQueryWrapper(cTopOauthToken, request.getParameterMap());
+          }
+      } catch (UnsupportedEncodingException e) {
+          e.printStackTrace();
+      }
+
+      //Step.2 AutoPoi 导出Excel
+      ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
+      List<CTopOauthToken> pageList = cTopOauthTokenService.list(queryWrapper);
+      //导出文件名称
+      mv.addObject(NormalExcelConstants.FILE_NAME, "oauth授权码列表");
+      mv.addObject(NormalExcelConstants.CLASS, CTopOauthToken.class);
+      mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("oauth授权码列表数据", "导出人:Jeecg", "导出信息"));
+      mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
+      return mv;
+  }
+
+  /**
+      * 通过excel导入数据
+   *
+   * @param request
+   * @param response
+   * @return
+   */
+  @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
+  public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
+      MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
+      Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
+      for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
+          MultipartFile file = entity.getValue();// 获取上传文件对象
+          ImportParams params = new ImportParams();
+          params.setTitleRows(2);
+          params.setHeadRows(1);
+          params.setNeedSave(true);
+          try {
+              List<CTopOauthToken> listCTopOauthTokens = ExcelImportUtil.importExcel(file.getInputStream(), CTopOauthToken.class, params);
+              cTopOauthTokenService.saveBatch(listCTopOauthTokens);
+              return Result.ok("文件导入成功!数据行数:" + listCTopOauthTokens.size());
+          } catch (Exception e) {
+              log.error(e.getMessage(),e);
+              return Result.error("文件导入失败:"+e.getMessage());
+          } finally {
+              try {
+                  file.getInputStream().close();
+              } catch (IOException e) {
+                  e.printStackTrace();
+              }
+          }
+      }
+      return Result.ok("文件导入失败!");
+  }
+
+}

+ 244 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/CTopToutiaoAdvertisePlanController.java

@@ -0,0 +1,244 @@
+package org.jeecg.modules.ctop.controller;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.common.aspect.annotation.AutoLog;
+import org.jeecg.common.util.oConvertUtils;
+import org.jeecg.modules.ctop.entity.CTopToutiaoAdvertisePlan;
+import org.jeecg.modules.ctop.service.ICTopToutiaoAdvertisePlanService;
+import java.util.Date;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.extern.slf4j.Slf4j;
+
+import org.jeecgframework.poi.excel.ExcelImportUtil;
+import org.jeecgframework.poi.excel.def.NormalExcelConstants;
+import org.jeecgframework.poi.excel.entity.ExportParams;
+import org.jeecgframework.poi.excel.entity.ImportParams;
+import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
+import org.springframework.web.servlet.ModelAndView;
+import com.alibaba.fastjson.JSON;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+ /**
+ * @Description: 头条广告主广告计划信息
+ * @Author: jeecg-boot
+ * @Date:   2019-07-10
+ * @Version: V1.0
+ */
+@Slf4j
+@Api(tags="头条广告主广告计划信息")
+@RestController
+@RequestMapping("/ctop/cTopToutiaoAdvertisePlan")
+public class CTopToutiaoAdvertisePlanController {
+	@Autowired
+	private ICTopToutiaoAdvertisePlanService cTopToutiaoAdvertisePlanService;
+	
+	/**
+	  * 分页列表查询
+	 * @param cTopToutiaoAdvertisePlan
+	 * @param pageNo
+	 * @param pageSize
+	 * @param req
+	 * @return
+	 */
+	@AutoLog(value = "头条广告主广告计划信息-分页列表查询")
+	@ApiOperation(value="头条广告主广告计划信息-分页列表查询", notes="头条广告主广告计划信息-分页列表查询")
+	@GetMapping(value = "/list")
+	public Result<IPage<CTopToutiaoAdvertisePlan>> queryPageList(CTopToutiaoAdvertisePlan cTopToutiaoAdvertisePlan,
+									  @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
+									  @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
+									  HttpServletRequest req) {
+		Result<IPage<CTopToutiaoAdvertisePlan>> result = new Result<IPage<CTopToutiaoAdvertisePlan>>();
+		QueryWrapper<CTopToutiaoAdvertisePlan> queryWrapper = QueryGenerator.initQueryWrapper(cTopToutiaoAdvertisePlan, req.getParameterMap());
+		Page<CTopToutiaoAdvertisePlan> page = new Page<CTopToutiaoAdvertisePlan>(pageNo, pageSize);
+		IPage<CTopToutiaoAdvertisePlan> pageList = cTopToutiaoAdvertisePlanService.page(page, queryWrapper);
+		result.setSuccess(true);
+		result.setResult(pageList);
+		return result;
+	}
+	
+	/**
+	  *   添加
+	 * @param cTopToutiaoAdvertisePlan
+	 * @return
+	 */
+	@AutoLog(value = "头条广告主广告计划信息-添加")
+	@ApiOperation(value="头条广告主广告计划信息-添加", notes="头条广告主广告计划信息-添加")
+	@PostMapping(value = "/add")
+	public Result<CTopToutiaoAdvertisePlan> add(@RequestBody CTopToutiaoAdvertisePlan cTopToutiaoAdvertisePlan) {
+		Result<CTopToutiaoAdvertisePlan> result = new Result<CTopToutiaoAdvertisePlan>();
+		try {
+			cTopToutiaoAdvertisePlanService.save(cTopToutiaoAdvertisePlan);
+			result.success("添加成功!");
+		} catch (Exception e) {
+			log.error(e.getMessage(),e);
+			result.error500("操作失败");
+		}
+		return result;
+	}
+	
+	/**
+	  *  编辑
+	 * @param cTopToutiaoAdvertisePlan
+	 * @return
+	 */
+	@AutoLog(value = "头条广告主广告计划信息-编辑")
+	@ApiOperation(value="头条广告主广告计划信息-编辑", notes="头条广告主广告计划信息-编辑")
+	@PutMapping(value = "/edit")
+	public Result<CTopToutiaoAdvertisePlan> edit(@RequestBody CTopToutiaoAdvertisePlan cTopToutiaoAdvertisePlan) {
+		Result<CTopToutiaoAdvertisePlan> result = new Result<CTopToutiaoAdvertisePlan>();
+		CTopToutiaoAdvertisePlan cTopToutiaoAdvertisePlanEntity = cTopToutiaoAdvertisePlanService.getById(cTopToutiaoAdvertisePlan.getId());
+		if(cTopToutiaoAdvertisePlanEntity==null) {
+			result.error500("未找到对应实体");
+		}else {
+			boolean ok = cTopToutiaoAdvertisePlanService.updateById(cTopToutiaoAdvertisePlan);
+			//TODO 返回false说明什么?
+			if(ok) {
+				result.success("修改成功!");
+			}
+		}
+		
+		return result;
+	}
+	
+	/**
+	  *   通过id删除
+	 * @param id
+	 * @return
+	 */
+	@AutoLog(value = "头条广告主广告计划信息-通过id删除")
+	@ApiOperation(value="头条广告主广告计划信息-通过id删除", notes="头条广告主广告计划信息-通过id删除")
+	@DeleteMapping(value = "/delete")
+	public Result<?> delete(@RequestParam(name="id",required=true) String id) {
+		try {
+			cTopToutiaoAdvertisePlanService.removeById(id);
+		} catch (Exception e) {
+			log.error("删除失败",e.getMessage());
+			return Result.error("删除失败!");
+		}
+		return Result.ok("删除成功!");
+	}
+	
+	/**
+	  *  批量删除
+	 * @param ids
+	 * @return
+	 */
+	@AutoLog(value = "头条广告主广告计划信息-批量删除")
+	@ApiOperation(value="头条广告主广告计划信息-批量删除", notes="头条广告主广告计划信息-批量删除")
+	@DeleteMapping(value = "/deleteBatch")
+	public Result<CTopToutiaoAdvertisePlan> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
+		Result<CTopToutiaoAdvertisePlan> result = new Result<CTopToutiaoAdvertisePlan>();
+		if(ids==null || "".equals(ids.trim())) {
+			result.error500("参数不识别!");
+		}else {
+			this.cTopToutiaoAdvertisePlanService.removeByIds(Arrays.asList(ids.split(",")));
+			result.success("删除成功!");
+		}
+		return result;
+	}
+	
+	/**
+	  * 通过id查询
+	 * @param id
+	 * @return
+	 */
+	@AutoLog(value = "头条广告主广告计划信息-通过id查询")
+	@ApiOperation(value="头条广告主广告计划信息-通过id查询", notes="头条广告主广告计划信息-通过id查询")
+	@GetMapping(value = "/queryById")
+	public Result<CTopToutiaoAdvertisePlan> queryById(@RequestParam(name="id",required=true) String id) {
+		Result<CTopToutiaoAdvertisePlan> result = new Result<CTopToutiaoAdvertisePlan>();
+		CTopToutiaoAdvertisePlan cTopToutiaoAdvertisePlan = cTopToutiaoAdvertisePlanService.getById(id);
+		if(cTopToutiaoAdvertisePlan==null) {
+			result.error500("未找到对应实体");
+		}else {
+			result.setResult(cTopToutiaoAdvertisePlan);
+			result.setSuccess(true);
+		}
+		return result;
+	}
+
+  /**
+      * 导出excel
+   *
+   * @param request
+   * @param response
+   */
+  @RequestMapping(value = "/exportXls")
+  public ModelAndView exportXls(HttpServletRequest request, HttpServletResponse response) {
+      // Step.1 组装查询条件
+      QueryWrapper<CTopToutiaoAdvertisePlan> queryWrapper = null;
+      try {
+          String paramsStr = request.getParameter("paramsStr");
+          if (oConvertUtils.isNotEmpty(paramsStr)) {
+              String deString = URLDecoder.decode(paramsStr, "UTF-8");
+              CTopToutiaoAdvertisePlan cTopToutiaoAdvertisePlan = JSON.parseObject(deString, CTopToutiaoAdvertisePlan.class);
+              queryWrapper = QueryGenerator.initQueryWrapper(cTopToutiaoAdvertisePlan, request.getParameterMap());
+          }
+      } catch (UnsupportedEncodingException e) {
+          e.printStackTrace();
+      }
+
+      //Step.2 AutoPoi 导出Excel
+      ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
+      List<CTopToutiaoAdvertisePlan> pageList = cTopToutiaoAdvertisePlanService.list(queryWrapper);
+      //导出文件名称
+      mv.addObject(NormalExcelConstants.FILE_NAME, "头条广告主广告计划信息列表");
+      mv.addObject(NormalExcelConstants.CLASS, CTopToutiaoAdvertisePlan.class);
+      mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("头条广告主广告计划信息列表数据", "导出人:Jeecg", "导出信息"));
+      mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
+      return mv;
+  }
+
+  /**
+      * 通过excel导入数据
+   *
+   * @param request
+   * @param response
+   * @return
+   */
+  @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
+  public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
+      MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
+      Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
+      for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
+          MultipartFile file = entity.getValue();// 获取上传文件对象
+          ImportParams params = new ImportParams();
+          params.setTitleRows(2);
+          params.setHeadRows(1);
+          params.setNeedSave(true);
+          try {
+              List<CTopToutiaoAdvertisePlan> listCTopToutiaoAdvertisePlans = ExcelImportUtil.importExcel(file.getInputStream(), CTopToutiaoAdvertisePlan.class, params);
+              cTopToutiaoAdvertisePlanService.saveBatch(listCTopToutiaoAdvertisePlans);
+              return Result.ok("文件导入成功!数据行数:" + listCTopToutiaoAdvertisePlans.size());
+          } catch (Exception e) {
+              log.error(e.getMessage(),e);
+              return Result.error("文件导入失败:"+e.getMessage());
+          } finally {
+              try {
+                  file.getInputStream().close();
+              } catch (IOException e) {
+                  e.printStackTrace();
+              }
+          }
+      }
+      return Result.ok("文件导入失败!");
+  }
+
+}

+ 244 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/CTopToutiaoAdvertiserController.java

@@ -0,0 +1,244 @@
+package org.jeecg.modules.ctop.controller;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.common.aspect.annotation.AutoLog;
+import org.jeecg.common.util.oConvertUtils;
+import org.jeecg.modules.ctop.entity.CTopToutiaoAdvertiser;
+import org.jeecg.modules.ctop.service.ICTopToutiaoAdvertiserService;
+import java.util.Date;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.extern.slf4j.Slf4j;
+
+import org.jeecgframework.poi.excel.ExcelImportUtil;
+import org.jeecgframework.poi.excel.def.NormalExcelConstants;
+import org.jeecgframework.poi.excel.entity.ExportParams;
+import org.jeecgframework.poi.excel.entity.ImportParams;
+import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
+import org.springframework.web.servlet.ModelAndView;
+import com.alibaba.fastjson.JSON;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+ /**
+ * @Description: 头条广告主信息
+ * @Author: jeecg-boot
+ * @Date:   2019-07-10
+ * @Version: V1.0
+ */
+@Slf4j
+@Api(tags="头条广告主信息")
+@RestController
+@RequestMapping("/ctop/cTopToutiaoAdvertiser")
+public class CTopToutiaoAdvertiserController {
+	@Autowired
+	private ICTopToutiaoAdvertiserService cTopToutiaoAdvertiserService;
+	
+	/**
+	  * 分页列表查询
+	 * @param cTopToutiaoAdvertiser
+	 * @param pageNo
+	 * @param pageSize
+	 * @param req
+	 * @return
+	 */
+	@AutoLog(value = "头条广告主信息-分页列表查询")
+	@ApiOperation(value="头条广告主信息-分页列表查询", notes="头条广告主信息-分页列表查询")
+	@GetMapping(value = "/list")
+	public Result<IPage<CTopToutiaoAdvertiser>> queryPageList(CTopToutiaoAdvertiser cTopToutiaoAdvertiser,
+									  @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
+									  @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
+									  HttpServletRequest req) {
+		Result<IPage<CTopToutiaoAdvertiser>> result = new Result<IPage<CTopToutiaoAdvertiser>>();
+		QueryWrapper<CTopToutiaoAdvertiser> queryWrapper = QueryGenerator.initQueryWrapper(cTopToutiaoAdvertiser, req.getParameterMap());
+		Page<CTopToutiaoAdvertiser> page = new Page<CTopToutiaoAdvertiser>(pageNo, pageSize);
+		IPage<CTopToutiaoAdvertiser> pageList = cTopToutiaoAdvertiserService.page(page, queryWrapper);
+		result.setSuccess(true);
+		result.setResult(pageList);
+		return result;
+	}
+	
+	/**
+	  *   添加
+	 * @param cTopToutiaoAdvertiser
+	 * @return
+	 */
+	@AutoLog(value = "头条广告主信息-添加")
+	@ApiOperation(value="头条广告主信息-添加", notes="头条广告主信息-添加")
+	@PostMapping(value = "/add")
+	public Result<CTopToutiaoAdvertiser> add(@RequestBody CTopToutiaoAdvertiser cTopToutiaoAdvertiser) {
+		Result<CTopToutiaoAdvertiser> result = new Result<CTopToutiaoAdvertiser>();
+		try {
+			cTopToutiaoAdvertiserService.save(cTopToutiaoAdvertiser);
+			result.success("添加成功!");
+		} catch (Exception e) {
+			log.error(e.getMessage(),e);
+			result.error500("操作失败");
+		}
+		return result;
+	}
+	
+	/**
+	  *  编辑
+	 * @param cTopToutiaoAdvertiser
+	 * @return
+	 */
+	@AutoLog(value = "头条广告主信息-编辑")
+	@ApiOperation(value="头条广告主信息-编辑", notes="头条广告主信息-编辑")
+	@PutMapping(value = "/edit")
+	public Result<CTopToutiaoAdvertiser> edit(@RequestBody CTopToutiaoAdvertiser cTopToutiaoAdvertiser) {
+		Result<CTopToutiaoAdvertiser> result = new Result<CTopToutiaoAdvertiser>();
+		CTopToutiaoAdvertiser cTopToutiaoAdvertiserEntity = cTopToutiaoAdvertiserService.getById(cTopToutiaoAdvertiser.getId());
+		if(cTopToutiaoAdvertiserEntity==null) {
+			result.error500("未找到对应实体");
+		}else {
+			boolean ok = cTopToutiaoAdvertiserService.updateById(cTopToutiaoAdvertiser);
+			//TODO 返回false说明什么?
+			if(ok) {
+				result.success("修改成功!");
+			}
+		}
+		
+		return result;
+	}
+	
+	/**
+	  *   通过id删除
+	 * @param id
+	 * @return
+	 */
+	@AutoLog(value = "头条广告主信息-通过id删除")
+	@ApiOperation(value="头条广告主信息-通过id删除", notes="头条广告主信息-通过id删除")
+	@DeleteMapping(value = "/delete")
+	public Result<?> delete(@RequestParam(name="id",required=true) String id) {
+		try {
+			cTopToutiaoAdvertiserService.removeById(id);
+		} catch (Exception e) {
+			log.error("删除失败",e.getMessage());
+			return Result.error("删除失败!");
+		}
+		return Result.ok("删除成功!");
+	}
+	
+	/**
+	  *  批量删除
+	 * @param ids
+	 * @return
+	 */
+	@AutoLog(value = "头条广告主信息-批量删除")
+	@ApiOperation(value="头条广告主信息-批量删除", notes="头条广告主信息-批量删除")
+	@DeleteMapping(value = "/deleteBatch")
+	public Result<CTopToutiaoAdvertiser> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
+		Result<CTopToutiaoAdvertiser> result = new Result<CTopToutiaoAdvertiser>();
+		if(ids==null || "".equals(ids.trim())) {
+			result.error500("参数不识别!");
+		}else {
+			this.cTopToutiaoAdvertiserService.removeByIds(Arrays.asList(ids.split(",")));
+			result.success("删除成功!");
+		}
+		return result;
+	}
+	
+	/**
+	  * 通过id查询
+	 * @param id
+	 * @return
+	 */
+	@AutoLog(value = "头条广告主信息-通过id查询")
+	@ApiOperation(value="头条广告主信息-通过id查询", notes="头条广告主信息-通过id查询")
+	@GetMapping(value = "/queryById")
+	public Result<CTopToutiaoAdvertiser> queryById(@RequestParam(name="id",required=true) String id) {
+		Result<CTopToutiaoAdvertiser> result = new Result<CTopToutiaoAdvertiser>();
+		CTopToutiaoAdvertiser cTopToutiaoAdvertiser = cTopToutiaoAdvertiserService.getById(id);
+		if(cTopToutiaoAdvertiser==null) {
+			result.error500("未找到对应实体");
+		}else {
+			result.setResult(cTopToutiaoAdvertiser);
+			result.setSuccess(true);
+		}
+		return result;
+	}
+
+  /**
+      * 导出excel
+   *
+   * @param request
+   * @param response
+   */
+  @RequestMapping(value = "/exportXls")
+  public ModelAndView exportXls(HttpServletRequest request, HttpServletResponse response) {
+      // Step.1 组装查询条件
+      QueryWrapper<CTopToutiaoAdvertiser> queryWrapper = null;
+      try {
+          String paramsStr = request.getParameter("paramsStr");
+          if (oConvertUtils.isNotEmpty(paramsStr)) {
+              String deString = URLDecoder.decode(paramsStr, "UTF-8");
+              CTopToutiaoAdvertiser cTopToutiaoAdvertiser = JSON.parseObject(deString, CTopToutiaoAdvertiser.class);
+              queryWrapper = QueryGenerator.initQueryWrapper(cTopToutiaoAdvertiser, request.getParameterMap());
+          }
+      } catch (UnsupportedEncodingException e) {
+          e.printStackTrace();
+      }
+
+      //Step.2 AutoPoi 导出Excel
+      ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
+      List<CTopToutiaoAdvertiser> pageList = cTopToutiaoAdvertiserService.list(queryWrapper);
+      //导出文件名称
+      mv.addObject(NormalExcelConstants.FILE_NAME, "头条广告主信息列表");
+      mv.addObject(NormalExcelConstants.CLASS, CTopToutiaoAdvertiser.class);
+      mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("头条广告主信息列表数据", "导出人:Jeecg", "导出信息"));
+      mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
+      return mv;
+  }
+
+  /**
+      * 通过excel导入数据
+   *
+   * @param request
+   * @param response
+   * @return
+   */
+  @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
+  public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
+      MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
+      Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
+      for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
+          MultipartFile file = entity.getValue();// 获取上传文件对象
+          ImportParams params = new ImportParams();
+          params.setTitleRows(2);
+          params.setHeadRows(1);
+          params.setNeedSave(true);
+          try {
+              List<CTopToutiaoAdvertiser> listCTopToutiaoAdvertisers = ExcelImportUtil.importExcel(file.getInputStream(), CTopToutiaoAdvertiser.class, params);
+              cTopToutiaoAdvertiserService.saveBatch(listCTopToutiaoAdvertisers);
+              return Result.ok("文件导入成功!数据行数:" + listCTopToutiaoAdvertisers.size());
+          } catch (Exception e) {
+              log.error(e.getMessage(),e);
+              return Result.error("文件导入失败:"+e.getMessage());
+          } finally {
+              try {
+                  file.getInputStream().close();
+              } catch (IOException e) {
+                  e.printStackTrace();
+              }
+          }
+      }
+      return Result.ok("文件导入失败!");
+  }
+
+}

+ 244 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/CTopToutiaoCampaignController.java

@@ -0,0 +1,244 @@
+package org.jeecg.modules.ctop.controller;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.common.aspect.annotation.AutoLog;
+import org.jeecg.common.util.oConvertUtils;
+import org.jeecg.modules.ctop.entity.CTopToutiaoCampaign;
+import org.jeecg.modules.ctop.service.ICTopToutiaoCampaignService;
+import java.util.Date;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.extern.slf4j.Slf4j;
+
+import org.jeecgframework.poi.excel.ExcelImportUtil;
+import org.jeecgframework.poi.excel.def.NormalExcelConstants;
+import org.jeecgframework.poi.excel.entity.ExportParams;
+import org.jeecgframework.poi.excel.entity.ImportParams;
+import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
+import org.springframework.web.servlet.ModelAndView;
+import com.alibaba.fastjson.JSON;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+ /**
+ * @Description: 头条广告主广告组信息
+ * @Author: jeecg-boot
+ * @Date:   2019-07-10
+ * @Version: V1.0
+ */
+@Slf4j
+@Api(tags="头条广告主广告组信息")
+@RestController
+@RequestMapping("/ctop/cTopToutiaoCampaign")
+public class CTopToutiaoCampaignController {
+	@Autowired
+	private ICTopToutiaoCampaignService cTopToutiaoCampaignService;
+	
+	/**
+	  * 分页列表查询
+	 * @param cTopToutiaoCampaign
+	 * @param pageNo
+	 * @param pageSize
+	 * @param req
+	 * @return
+	 */
+	@AutoLog(value = "头条广告主广告组信息-分页列表查询")
+	@ApiOperation(value="头条广告主广告组信息-分页列表查询", notes="头条广告主广告组信息-分页列表查询")
+	@GetMapping(value = "/list")
+	public Result<IPage<CTopToutiaoCampaign>> queryPageList(CTopToutiaoCampaign cTopToutiaoCampaign,
+									  @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
+									  @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
+									  HttpServletRequest req) {
+		Result<IPage<CTopToutiaoCampaign>> result = new Result<IPage<CTopToutiaoCampaign>>();
+		QueryWrapper<CTopToutiaoCampaign> queryWrapper = QueryGenerator.initQueryWrapper(cTopToutiaoCampaign, req.getParameterMap());
+		Page<CTopToutiaoCampaign> page = new Page<CTopToutiaoCampaign>(pageNo, pageSize);
+		IPage<CTopToutiaoCampaign> pageList = cTopToutiaoCampaignService.page(page, queryWrapper);
+		result.setSuccess(true);
+		result.setResult(pageList);
+		return result;
+	}
+	
+	/**
+	  *   添加
+	 * @param cTopToutiaoCampaign
+	 * @return
+	 */
+	@AutoLog(value = "头条广告主广告组信息-添加")
+	@ApiOperation(value="头条广告主广告组信息-添加", notes="头条广告主广告组信息-添加")
+	@PostMapping(value = "/add")
+	public Result<CTopToutiaoCampaign> add(@RequestBody CTopToutiaoCampaign cTopToutiaoCampaign) {
+		Result<CTopToutiaoCampaign> result = new Result<CTopToutiaoCampaign>();
+		try {
+			cTopToutiaoCampaignService.save(cTopToutiaoCampaign);
+			result.success("添加成功!");
+		} catch (Exception e) {
+			log.error(e.getMessage(),e);
+			result.error500("操作失败");
+		}
+		return result;
+	}
+	
+	/**
+	  *  编辑
+	 * @param cTopToutiaoCampaign
+	 * @return
+	 */
+	@AutoLog(value = "头条广告主广告组信息-编辑")
+	@ApiOperation(value="头条广告主广告组信息-编辑", notes="头条广告主广告组信息-编辑")
+	@PutMapping(value = "/edit")
+	public Result<CTopToutiaoCampaign> edit(@RequestBody CTopToutiaoCampaign cTopToutiaoCampaign) {
+		Result<CTopToutiaoCampaign> result = new Result<CTopToutiaoCampaign>();
+		CTopToutiaoCampaign cTopToutiaoCampaignEntity = cTopToutiaoCampaignService.getById(cTopToutiaoCampaign.getId());
+		if(cTopToutiaoCampaignEntity==null) {
+			result.error500("未找到对应实体");
+		}else {
+			boolean ok = cTopToutiaoCampaignService.updateById(cTopToutiaoCampaign);
+			//TODO 返回false说明什么?
+			if(ok) {
+				result.success("修改成功!");
+			}
+		}
+		
+		return result;
+	}
+	
+	/**
+	  *   通过id删除
+	 * @param id
+	 * @return
+	 */
+	@AutoLog(value = "头条广告主广告组信息-通过id删除")
+	@ApiOperation(value="头条广告主广告组信息-通过id删除", notes="头条广告主广告组信息-通过id删除")
+	@DeleteMapping(value = "/delete")
+	public Result<?> delete(@RequestParam(name="id",required=true) String id) {
+		try {
+			cTopToutiaoCampaignService.removeById(id);
+		} catch (Exception e) {
+			log.error("删除失败",e.getMessage());
+			return Result.error("删除失败!");
+		}
+		return Result.ok("删除成功!");
+	}
+	
+	/**
+	  *  批量删除
+	 * @param ids
+	 * @return
+	 */
+	@AutoLog(value = "头条广告主广告组信息-批量删除")
+	@ApiOperation(value="头条广告主广告组信息-批量删除", notes="头条广告主广告组信息-批量删除")
+	@DeleteMapping(value = "/deleteBatch")
+	public Result<CTopToutiaoCampaign> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
+		Result<CTopToutiaoCampaign> result = new Result<CTopToutiaoCampaign>();
+		if(ids==null || "".equals(ids.trim())) {
+			result.error500("参数不识别!");
+		}else {
+			this.cTopToutiaoCampaignService.removeByIds(Arrays.asList(ids.split(",")));
+			result.success("删除成功!");
+		}
+		return result;
+	}
+	
+	/**
+	  * 通过id查询
+	 * @param id
+	 * @return
+	 */
+	@AutoLog(value = "头条广告主广告组信息-通过id查询")
+	@ApiOperation(value="头条广告主广告组信息-通过id查询", notes="头条广告主广告组信息-通过id查询")
+	@GetMapping(value = "/queryById")
+	public Result<CTopToutiaoCampaign> queryById(@RequestParam(name="id",required=true) String id) {
+		Result<CTopToutiaoCampaign> result = new Result<CTopToutiaoCampaign>();
+		CTopToutiaoCampaign cTopToutiaoCampaign = cTopToutiaoCampaignService.getById(id);
+		if(cTopToutiaoCampaign==null) {
+			result.error500("未找到对应实体");
+		}else {
+			result.setResult(cTopToutiaoCampaign);
+			result.setSuccess(true);
+		}
+		return result;
+	}
+
+  /**
+      * 导出excel
+   *
+   * @param request
+   * @param response
+   */
+  @RequestMapping(value = "/exportXls")
+  public ModelAndView exportXls(HttpServletRequest request, HttpServletResponse response) {
+      // Step.1 组装查询条件
+      QueryWrapper<CTopToutiaoCampaign> queryWrapper = null;
+      try {
+          String paramsStr = request.getParameter("paramsStr");
+          if (oConvertUtils.isNotEmpty(paramsStr)) {
+              String deString = URLDecoder.decode(paramsStr, "UTF-8");
+              CTopToutiaoCampaign cTopToutiaoCampaign = JSON.parseObject(deString, CTopToutiaoCampaign.class);
+              queryWrapper = QueryGenerator.initQueryWrapper(cTopToutiaoCampaign, request.getParameterMap());
+          }
+      } catch (UnsupportedEncodingException e) {
+          e.printStackTrace();
+      }
+
+      //Step.2 AutoPoi 导出Excel
+      ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
+      List<CTopToutiaoCampaign> pageList = cTopToutiaoCampaignService.list(queryWrapper);
+      //导出文件名称
+      mv.addObject(NormalExcelConstants.FILE_NAME, "头条广告主广告组信息列表");
+      mv.addObject(NormalExcelConstants.CLASS, CTopToutiaoCampaign.class);
+      mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("头条广告主广告组信息列表数据", "导出人:Jeecg", "导出信息"));
+      mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
+      return mv;
+  }
+
+  /**
+      * 通过excel导入数据
+   *
+   * @param request
+   * @param response
+   * @return
+   */
+  @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
+  public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
+      MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
+      Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
+      for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
+          MultipartFile file = entity.getValue();// 获取上传文件对象
+          ImportParams params = new ImportParams();
+          params.setTitleRows(2);
+          params.setHeadRows(1);
+          params.setNeedSave(true);
+          try {
+              List<CTopToutiaoCampaign> listCTopToutiaoCampaigns = ExcelImportUtil.importExcel(file.getInputStream(), CTopToutiaoCampaign.class, params);
+              cTopToutiaoCampaignService.saveBatch(listCTopToutiaoCampaigns);
+              return Result.ok("文件导入成功!数据行数:" + listCTopToutiaoCampaigns.size());
+          } catch (Exception e) {
+              log.error(e.getMessage(),e);
+              return Result.error("文件导入失败:"+e.getMessage());
+          } finally {
+              try {
+                  file.getInputStream().close();
+              } catch (IOException e) {
+                  e.printStackTrace();
+              }
+          }
+      }
+      return Result.ok("文件导入失败!");
+  }
+
+}

+ 49 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/CallbackController.java

@@ -0,0 +1,49 @@
+package org.jeecg.modules.ctop.controller;
+
+import cn.com.ctop.kuaishou.modules.material.entity.KuaishouAccessToken;
+import cn.com.ctop.kuaishou.modules.material.entity.KuaishouResultToken;
+import cn.com.ctop.kuaishou.modules.material.service.IKuaishouAccessTokenService;
+import cn.com.ctop.kuaishou.modules.material.service.IKuaishouInterfaceService;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.Date;
+
+@Controller
+@RequestMapping("/")
+public class CallbackController {
+    @Autowired
+    private IKuaishouInterfaceService kuaishouInterfaceService;
+    @Autowired
+    private IKuaishouAccessTokenService kuaishouAccessTokenService;
+    @RequestMapping("/kuaishou")
+    @ResponseBody
+    public String kuaishou(HttpServletRequest request,
+                           HttpServletResponse response,
+                           @RequestParam("auth_code")String authCode,
+                           @RequestParam("state")String state) {
+        System.out.println(request.getQueryString());
+        if(StringUtils.isNotBlank(authCode)){
+            KuaishouResultToken accessToken = kuaishouInterfaceService.getAccessToken(authCode);
+            KuaishouAccessToken token = accessToken.getData();
+            if(token != null){
+                long now = System.currentTimeMillis();
+                long accessTokenExpireIn = token.getAccessTokenExpiresIn() * 1000L;
+                long refreshTokenExpireIn = token.getRefreshTokenExpiresIn() * 1000L;
+                Date accessTokenExpireInDate = new Date(now+accessTokenExpireIn);
+                Date refreshTokenExpireInDate = new Date(now+refreshTokenExpireIn);
+                token.setAccessTokenExpiresInDate(accessTokenExpireInDate);
+                token.setRefreshTokenExpiresInDate(refreshTokenExpireInDate);
+                kuaishouAccessTokenService.saveOrUpdate(token);
+            }
+            return "auth_success";
+        }
+        return "auth_fail";
+    }
+}

+ 244 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/CtopToutiaoAdvertiserBudgetController.java

@@ -0,0 +1,244 @@
+package org.jeecg.modules.ctop.controller;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.common.aspect.annotation.AutoLog;
+import org.jeecg.common.util.oConvertUtils;
+import org.jeecg.modules.ctop.entity.CtopToutiaoAdvertiserBudget;
+import org.jeecg.modules.ctop.service.ICtopToutiaoAdvertiserBudgetService;
+import java.util.Date;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.extern.slf4j.Slf4j;
+
+import org.jeecgframework.poi.excel.ExcelImportUtil;
+import org.jeecgframework.poi.excel.def.NormalExcelConstants;
+import org.jeecgframework.poi.excel.entity.ExportParams;
+import org.jeecgframework.poi.excel.entity.ImportParams;
+import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
+import org.springframework.web.servlet.ModelAndView;
+import com.alibaba.fastjson.JSON;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+ /**
+ * @Description: 头条广告主账户预算信息
+ * @Author: jeecg-boot
+ * @Date:   2019-07-10
+ * @Version: V1.0
+ */
+@Slf4j
+@Api(tags="头条广告主账户预算信息")
+@RestController
+@RequestMapping("/ctop/ctopToutiaoAdvertiserBudget")
+public class CtopToutiaoAdvertiserBudgetController {
+	@Autowired
+	private ICtopToutiaoAdvertiserBudgetService ctopToutiaoAdvertiserBudgetService;
+	
+	/**
+	  * 分页列表查询
+	 * @param ctopToutiaoAdvertiserBudget
+	 * @param pageNo
+	 * @param pageSize
+	 * @param req
+	 * @return
+	 */
+	@AutoLog(value = "头条广告主账户预算信息-分页列表查询")
+	@ApiOperation(value="头条广告主账户预算信息-分页列表查询", notes="头条广告主账户预算信息-分页列表查询")
+	@GetMapping(value = "/list")
+	public Result<IPage<CtopToutiaoAdvertiserBudget>> queryPageList(CtopToutiaoAdvertiserBudget ctopToutiaoAdvertiserBudget,
+									  @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
+									  @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
+									  HttpServletRequest req) {
+		Result<IPage<CtopToutiaoAdvertiserBudget>> result = new Result<IPage<CtopToutiaoAdvertiserBudget>>();
+		QueryWrapper<CtopToutiaoAdvertiserBudget> queryWrapper = QueryGenerator.initQueryWrapper(ctopToutiaoAdvertiserBudget, req.getParameterMap());
+		Page<CtopToutiaoAdvertiserBudget> page = new Page<CtopToutiaoAdvertiserBudget>(pageNo, pageSize);
+		IPage<CtopToutiaoAdvertiserBudget> pageList = ctopToutiaoAdvertiserBudgetService.page(page, queryWrapper);
+		result.setSuccess(true);
+		result.setResult(pageList);
+		return result;
+	}
+	
+	/**
+	  *   添加
+	 * @param ctopToutiaoAdvertiserBudget
+	 * @return
+	 */
+	@AutoLog(value = "头条广告主账户预算信息-添加")
+	@ApiOperation(value="头条广告主账户预算信息-添加", notes="头条广告主账户预算信息-添加")
+	@PostMapping(value = "/add")
+	public Result<CtopToutiaoAdvertiserBudget> add(@RequestBody CtopToutiaoAdvertiserBudget ctopToutiaoAdvertiserBudget) {
+		Result<CtopToutiaoAdvertiserBudget> result = new Result<CtopToutiaoAdvertiserBudget>();
+		try {
+			ctopToutiaoAdvertiserBudgetService.save(ctopToutiaoAdvertiserBudget);
+			result.success("添加成功!");
+		} catch (Exception e) {
+			log.error(e.getMessage(),e);
+			result.error500("操作失败");
+		}
+		return result;
+	}
+	
+	/**
+	  *  编辑
+	 * @param ctopToutiaoAdvertiserBudget
+	 * @return
+	 */
+	@AutoLog(value = "头条广告主账户预算信息-编辑")
+	@ApiOperation(value="头条广告主账户预算信息-编辑", notes="头条广告主账户预算信息-编辑")
+	@PutMapping(value = "/edit")
+	public Result<CtopToutiaoAdvertiserBudget> edit(@RequestBody CtopToutiaoAdvertiserBudget ctopToutiaoAdvertiserBudget) {
+		Result<CtopToutiaoAdvertiserBudget> result = new Result<CtopToutiaoAdvertiserBudget>();
+		CtopToutiaoAdvertiserBudget ctopToutiaoAdvertiserBudgetEntity = ctopToutiaoAdvertiserBudgetService.getById(ctopToutiaoAdvertiserBudget.getId());
+		if(ctopToutiaoAdvertiserBudgetEntity==null) {
+			result.error500("未找到对应实体");
+		}else {
+			boolean ok = ctopToutiaoAdvertiserBudgetService.updateById(ctopToutiaoAdvertiserBudget);
+			//TODO 返回false说明什么?
+			if(ok) {
+				result.success("修改成功!");
+			}
+		}
+		
+		return result;
+	}
+	
+	/**
+	  *   通过id删除
+	 * @param id
+	 * @return
+	 */
+	@AutoLog(value = "头条广告主账户预算信息-通过id删除")
+	@ApiOperation(value="头条广告主账户预算信息-通过id删除", notes="头条广告主账户预算信息-通过id删除")
+	@DeleteMapping(value = "/delete")
+	public Result<?> delete(@RequestParam(name="id",required=true) String id) {
+		try {
+			ctopToutiaoAdvertiserBudgetService.removeById(id);
+		} catch (Exception e) {
+			log.error("删除失败",e.getMessage());
+			return Result.error("删除失败!");
+		}
+		return Result.ok("删除成功!");
+	}
+	
+	/**
+	  *  批量删除
+	 * @param ids
+	 * @return
+	 */
+	@AutoLog(value = "头条广告主账户预算信息-批量删除")
+	@ApiOperation(value="头条广告主账户预算信息-批量删除", notes="头条广告主账户预算信息-批量删除")
+	@DeleteMapping(value = "/deleteBatch")
+	public Result<CtopToutiaoAdvertiserBudget> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
+		Result<CtopToutiaoAdvertiserBudget> result = new Result<CtopToutiaoAdvertiserBudget>();
+		if(ids==null || "".equals(ids.trim())) {
+			result.error500("参数不识别!");
+		}else {
+			this.ctopToutiaoAdvertiserBudgetService.removeByIds(Arrays.asList(ids.split(",")));
+			result.success("删除成功!");
+		}
+		return result;
+	}
+	
+	/**
+	  * 通过id查询
+	 * @param id
+	 * @return
+	 */
+	@AutoLog(value = "头条广告主账户预算信息-通过id查询")
+	@ApiOperation(value="头条广告主账户预算信息-通过id查询", notes="头条广告主账户预算信息-通过id查询")
+	@GetMapping(value = "/queryById")
+	public Result<CtopToutiaoAdvertiserBudget> queryById(@RequestParam(name="id",required=true) String id) {
+		Result<CtopToutiaoAdvertiserBudget> result = new Result<CtopToutiaoAdvertiserBudget>();
+		CtopToutiaoAdvertiserBudget ctopToutiaoAdvertiserBudget = ctopToutiaoAdvertiserBudgetService.getById(id);
+		if(ctopToutiaoAdvertiserBudget==null) {
+			result.error500("未找到对应实体");
+		}else {
+			result.setResult(ctopToutiaoAdvertiserBudget);
+			result.setSuccess(true);
+		}
+		return result;
+	}
+
+  /**
+      * 导出excel
+   *
+   * @param request
+   * @param response
+   */
+  @RequestMapping(value = "/exportXls")
+  public ModelAndView exportXls(HttpServletRequest request, HttpServletResponse response) {
+      // Step.1 组装查询条件
+      QueryWrapper<CtopToutiaoAdvertiserBudget> queryWrapper = null;
+      try {
+          String paramsStr = request.getParameter("paramsStr");
+          if (oConvertUtils.isNotEmpty(paramsStr)) {
+              String deString = URLDecoder.decode(paramsStr, "UTF-8");
+              CtopToutiaoAdvertiserBudget ctopToutiaoAdvertiserBudget = JSON.parseObject(deString, CtopToutiaoAdvertiserBudget.class);
+              queryWrapper = QueryGenerator.initQueryWrapper(ctopToutiaoAdvertiserBudget, request.getParameterMap());
+          }
+      } catch (UnsupportedEncodingException e) {
+          e.printStackTrace();
+      }
+
+      //Step.2 AutoPoi 导出Excel
+      ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
+      List<CtopToutiaoAdvertiserBudget> pageList = ctopToutiaoAdvertiserBudgetService.list(queryWrapper);
+      //导出文件名称
+      mv.addObject(NormalExcelConstants.FILE_NAME, "头条广告主账户预算信息列表");
+      mv.addObject(NormalExcelConstants.CLASS, CtopToutiaoAdvertiserBudget.class);
+      mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("头条广告主账户预算信息列表数据", "导出人:Jeecg", "导出信息"));
+      mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
+      return mv;
+  }
+
+  /**
+      * 通过excel导入数据
+   *
+   * @param request
+   * @param response
+   * @return
+   */
+  @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
+  public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
+      MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
+      Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
+      for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
+          MultipartFile file = entity.getValue();// 获取上传文件对象
+          ImportParams params = new ImportParams();
+          params.setTitleRows(2);
+          params.setHeadRows(1);
+          params.setNeedSave(true);
+          try {
+              List<CtopToutiaoAdvertiserBudget> listCtopToutiaoAdvertiserBudgets = ExcelImportUtil.importExcel(file.getInputStream(), CtopToutiaoAdvertiserBudget.class, params);
+              ctopToutiaoAdvertiserBudgetService.saveBatch(listCtopToutiaoAdvertiserBudgets);
+              return Result.ok("文件导入成功!数据行数:" + listCtopToutiaoAdvertiserBudgets.size());
+          } catch (Exception e) {
+              log.error(e.getMessage(),e);
+              return Result.error("文件导入失败:"+e.getMessage());
+          } finally {
+              try {
+                  file.getInputStream().close();
+              } catch (IOException e) {
+                  e.printStackTrace();
+              }
+          }
+      }
+      return Result.ok("文件导入失败!");
+  }
+
+}

+ 244 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/CtopToutiaoBudgetTemplateController.java

@@ -0,0 +1,244 @@
+package org.jeecg.modules.ctop.controller;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.common.aspect.annotation.AutoLog;
+import org.jeecg.common.util.oConvertUtils;
+import org.jeecg.modules.ctop.entity.CtopToutiaoBudgetTemplate;
+import org.jeecg.modules.ctop.service.ICtopToutiaoBudgetTemplateService;
+import java.util.Date;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.extern.slf4j.Slf4j;
+
+import org.jeecgframework.poi.excel.ExcelImportUtil;
+import org.jeecgframework.poi.excel.def.NormalExcelConstants;
+import org.jeecgframework.poi.excel.entity.ExportParams;
+import org.jeecgframework.poi.excel.entity.ImportParams;
+import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
+import org.springframework.web.servlet.ModelAndView;
+import com.alibaba.fastjson.JSON;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+ /**
+ * @Description: 预算与出价模块模板
+ * @Author: jeecg-boot
+ * @Date:   2019-07-17
+ * @Version: V1.0
+ */
+@Slf4j
+@Api(tags="预算与出价模块模板")
+@RestController
+@RequestMapping("/ctop/ctopToutiaoBudgetTemplate")
+public class CtopToutiaoBudgetTemplateController {
+	@Autowired
+	private ICtopToutiaoBudgetTemplateService ctopToutiaoBudgetTemplateService;
+	
+	/**
+	  * 分页列表查询
+	 * @param ctopToutiaoBudgetTemplate
+	 * @param pageNo
+	 * @param pageSize
+	 * @param req
+	 * @return
+	 */
+	@AutoLog(value = "预算与出价模块模板-分页列表查询")
+	@ApiOperation(value="预算与出价模块模板-分页列表查询", notes="预算与出价模块模板-分页列表查询")
+	@GetMapping(value = "/list")
+	public Result<IPage<CtopToutiaoBudgetTemplate>> queryPageList(CtopToutiaoBudgetTemplate ctopToutiaoBudgetTemplate,
+									  @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
+									  @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
+									  HttpServletRequest req) {
+		Result<IPage<CtopToutiaoBudgetTemplate>> result = new Result<IPage<CtopToutiaoBudgetTemplate>>();
+		QueryWrapper<CtopToutiaoBudgetTemplate> queryWrapper = QueryGenerator.initQueryWrapper(ctopToutiaoBudgetTemplate, req.getParameterMap());
+		Page<CtopToutiaoBudgetTemplate> page = new Page<CtopToutiaoBudgetTemplate>(pageNo, pageSize);
+		IPage<CtopToutiaoBudgetTemplate> pageList = ctopToutiaoBudgetTemplateService.page(page, queryWrapper);
+		result.setSuccess(true);
+		result.setResult(pageList);
+		return result;
+	}
+	
+	/**
+	  *   添加
+	 * @param ctopToutiaoBudgetTemplate
+	 * @return
+	 */
+	@AutoLog(value = "预算与出价模块模板-添加")
+	@ApiOperation(value="预算与出价模块模板-添加", notes="预算与出价模块模板-添加")
+	@PostMapping(value = "/add")
+	public Result<CtopToutiaoBudgetTemplate> add(@RequestBody CtopToutiaoBudgetTemplate ctopToutiaoBudgetTemplate) {
+		Result<CtopToutiaoBudgetTemplate> result = new Result<CtopToutiaoBudgetTemplate>();
+		try {
+			ctopToutiaoBudgetTemplateService.save(ctopToutiaoBudgetTemplate);
+			result.success("添加成功!");
+		} catch (Exception e) {
+			log.error(e.getMessage(),e);
+			result.error500("操作失败");
+		}
+		return result;
+	}
+	
+	/**
+	  *  编辑
+	 * @param ctopToutiaoBudgetTemplate
+	 * @return
+	 */
+	@AutoLog(value = "预算与出价模块模板-编辑")
+	@ApiOperation(value="预算与出价模块模板-编辑", notes="预算与出价模块模板-编辑")
+	@PutMapping(value = "/edit")
+	public Result<CtopToutiaoBudgetTemplate> edit(@RequestBody CtopToutiaoBudgetTemplate ctopToutiaoBudgetTemplate) {
+		Result<CtopToutiaoBudgetTemplate> result = new Result<CtopToutiaoBudgetTemplate>();
+		CtopToutiaoBudgetTemplate ctopToutiaoBudgetTemplateEntity = ctopToutiaoBudgetTemplateService.getById(ctopToutiaoBudgetTemplate.getId());
+		if(ctopToutiaoBudgetTemplateEntity==null) {
+			result.error500("未找到对应实体");
+		}else {
+			boolean ok = ctopToutiaoBudgetTemplateService.updateById(ctopToutiaoBudgetTemplate);
+			//TODO 返回false说明什么?
+			if(ok) {
+				result.success("修改成功!");
+			}
+		}
+		
+		return result;
+	}
+	
+	/**
+	  *   通过id删除
+	 * @param id
+	 * @return
+	 */
+	@AutoLog(value = "预算与出价模块模板-通过id删除")
+	@ApiOperation(value="预算与出价模块模板-通过id删除", notes="预算与出价模块模板-通过id删除")
+	@DeleteMapping(value = "/delete")
+	public Result<?> delete(@RequestParam(name="id",required=true) String id) {
+		try {
+			ctopToutiaoBudgetTemplateService.removeById(id);
+		} catch (Exception e) {
+			log.error("删除失败",e.getMessage());
+			return Result.error("删除失败!");
+		}
+		return Result.ok("删除成功!");
+	}
+	
+	/**
+	  *  批量删除
+	 * @param ids
+	 * @return
+	 */
+	@AutoLog(value = "预算与出价模块模板-批量删除")
+	@ApiOperation(value="预算与出价模块模板-批量删除", notes="预算与出价模块模板-批量删除")
+	@DeleteMapping(value = "/deleteBatch")
+	public Result<CtopToutiaoBudgetTemplate> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
+		Result<CtopToutiaoBudgetTemplate> result = new Result<CtopToutiaoBudgetTemplate>();
+		if(ids==null || "".equals(ids.trim())) {
+			result.error500("参数不识别!");
+		}else {
+			this.ctopToutiaoBudgetTemplateService.removeByIds(Arrays.asList(ids.split(",")));
+			result.success("删除成功!");
+		}
+		return result;
+	}
+	
+	/**
+	  * 通过id查询
+	 * @param id
+	 * @return
+	 */
+	@AutoLog(value = "预算与出价模块模板-通过id查询")
+	@ApiOperation(value="预算与出价模块模板-通过id查询", notes="预算与出价模块模板-通过id查询")
+	@GetMapping(value = "/queryById")
+	public Result<CtopToutiaoBudgetTemplate> queryById(@RequestParam(name="id",required=true) String id) {
+		Result<CtopToutiaoBudgetTemplate> result = new Result<CtopToutiaoBudgetTemplate>();
+		CtopToutiaoBudgetTemplate ctopToutiaoBudgetTemplate = ctopToutiaoBudgetTemplateService.getById(id);
+		if(ctopToutiaoBudgetTemplate==null) {
+			result.error500("未找到对应实体");
+		}else {
+			result.setResult(ctopToutiaoBudgetTemplate);
+			result.setSuccess(true);
+		}
+		return result;
+	}
+
+  /**
+      * 导出excel
+   *
+   * @param request
+   * @param response
+   */
+  @RequestMapping(value = "/exportXls")
+  public ModelAndView exportXls(HttpServletRequest request, HttpServletResponse response) {
+      // Step.1 组装查询条件
+      QueryWrapper<CtopToutiaoBudgetTemplate> queryWrapper = null;
+      try {
+          String paramsStr = request.getParameter("paramsStr");
+          if (oConvertUtils.isNotEmpty(paramsStr)) {
+              String deString = URLDecoder.decode(paramsStr, "UTF-8");
+              CtopToutiaoBudgetTemplate ctopToutiaoBudgetTemplate = JSON.parseObject(deString, CtopToutiaoBudgetTemplate.class);
+              queryWrapper = QueryGenerator.initQueryWrapper(ctopToutiaoBudgetTemplate, request.getParameterMap());
+          }
+      } catch (UnsupportedEncodingException e) {
+          e.printStackTrace();
+      }
+
+      //Step.2 AutoPoi 导出Excel
+      ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
+      List<CtopToutiaoBudgetTemplate> pageList = ctopToutiaoBudgetTemplateService.list(queryWrapper);
+      //导出文件名称
+      mv.addObject(NormalExcelConstants.FILE_NAME, "预算与出价模块模板列表");
+      mv.addObject(NormalExcelConstants.CLASS, CtopToutiaoBudgetTemplate.class);
+      mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("预算与出价模块模板列表数据", "导出人:Jeecg", "导出信息"));
+      mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
+      return mv;
+  }
+
+  /**
+      * 通过excel导入数据
+   *
+   * @param request
+   * @param response
+   * @return
+   */
+  @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
+  public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
+      MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
+      Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
+      for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
+          MultipartFile file = entity.getValue();// 获取上传文件对象
+          ImportParams params = new ImportParams();
+          params.setTitleRows(2);
+          params.setHeadRows(1);
+          params.setNeedSave(true);
+          try {
+              List<CtopToutiaoBudgetTemplate> listCtopToutiaoBudgetTemplates = ExcelImportUtil.importExcel(file.getInputStream(), CtopToutiaoBudgetTemplate.class, params);
+              ctopToutiaoBudgetTemplateService.saveBatch(listCtopToutiaoBudgetTemplates);
+              return Result.ok("文件导入成功!数据行数:" + listCtopToutiaoBudgetTemplates.size());
+          } catch (Exception e) {
+              log.error(e.getMessage(),e);
+              return Result.error("文件导入失败:"+e.getMessage());
+          } finally {
+              try {
+                  file.getInputStream().close();
+              } catch (IOException e) {
+                  e.printStackTrace();
+              }
+          }
+      }
+      return Result.ok("文件导入失败!");
+  }
+
+}

+ 75 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/GraphqlController.java

@@ -0,0 +1,75 @@
+package org.jeecg.modules.ctop.controller;
+
+import cn.com.ctop.kuaishou.modules.graphql.entity.KuaishouVideo;
+import cn.com.ctop.kuaishou.modules.graphql.service.IKuaishouVideoService;
+import cn.com.ctop.kuaishou.modules.graphql.service.IKuaishouWebInterfaceService;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.google.gson.JsonObject;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.modules.system.entity.SysRole;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Controller
+@RequestMapping("/graphql")
+public class GraphqlController {
+    @Autowired
+    private IKuaishouWebInterfaceService kuaishouWebInterfaceService;
+    @Autowired
+    private IKuaishouVideoService kuaishouVideoService;
+    @RequestMapping("/video")
+    public void getVideoList(@RequestParam("uid") String uid){
+        kuaishouWebInterfaceService.getVideoList(uid);
+    }
+    @ResponseBody
+    @RequestMapping(value="/addkuaishouuser", method = RequestMethod.POST)
+    public Result<Map<String,Object>> addKuaishouUser(@RequestBody JSONObject jsonObject){
+        String url = jsonObject.getString("url");
+        System.out.println(jsonObject.toString());
+        String uid = kuaishouWebInterfaceService.checkKuaishouUser(url);
+        Map<String,Object> resultMap = new HashMap<String, Object>();
+        if(uid == null){
+            resultMap.put("hasUser",false);
+        }else {
+            resultMap.put("hasUser",true);
+            Thread thread = new Thread(){
+                @Override
+                public void run() {
+                    kuaishouWebInterfaceService.getVideoList(uid);
+                }
+            };
+            thread.start();
+        }
+        Result<Map<String,Object>> result = new Result<Map<String,Object>>();
+        result.setSuccess(true);
+        result.setResult(resultMap);
+        return result;
+    }
+    @ResponseBody
+    @RequestMapping(value="/publicfeeds", method = RequestMethod.GET)
+    public Result<IPage<KuaishouVideo>> getVideoList(@RequestParam("num") Integer num){
+        if(num==null){
+            num=99999999;
+        }
+        Result<IPage<KuaishouVideo>> result = new Result<IPage<KuaishouVideo>>();
+        KuaishouVideo video = new KuaishouVideo();
+        QueryWrapper<KuaishouVideo> queryWrapper = QueryGenerator.initQueryWrapper(video,null);
+        queryWrapper.orderByDesc("num");
+        queryWrapper.le("num",num);
+        System.out.println("num="+num);
+        Page<KuaishouVideo> page = new Page<KuaishouVideo>(1, 20);
+        IPage<KuaishouVideo> pageList = kuaishouVideoService.page(page,queryWrapper);
+        result.setResult(pageList);
+        result.setSuccess(true);
+        return result;
+    }
+}

+ 253 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/KuaishouAdvertiserController.java

@@ -0,0 +1,253 @@
+package org.jeecg.modules.ctop.controller;
+
+import cn.com.ctop.crawler.modules.account.entity.KuaishouAdAccount;
+import cn.com.ctop.crawler.modules.account.service.IKuaishouAdAccountService;
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.aspect.annotation.AutoLog;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.common.util.oConvertUtils;
+import org.jeecgframework.poi.excel.ExcelImportUtil;
+import org.jeecgframework.poi.excel.def.NormalExcelConstants;
+import org.jeecgframework.poi.excel.entity.ExportParams;
+import org.jeecgframework.poi.excel.entity.ImportParams;
+import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
+import org.springframework.web.servlet.ModelAndView;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+@Slf4j
+@Api(tags="快手广告主信息表")
+@RestController
+@RequestMapping("/ctop/kuaishou/advertiser")
+public class KuaishouAdvertiserController {
+    @Autowired
+    private IKuaishouAdAccountService kuaishouAdAccountService;
+    /**
+     * 分页列表查询
+     * @param kuaishouAdAccount
+     * @param pageNo
+     * @param pageSize
+     * @param req
+     * @return
+     */
+    @AutoLog(value = "快手广告主信息表-分页列表查询")
+    @ApiOperation(value="快手广告主信息表-分页列表查询", notes="快手广告主信息表-分页列表查询")
+    @GetMapping(value = "/list")
+    public Result<IPage<KuaishouAdAccount>> queryPageList(KuaishouAdAccount kuaishouAdAccount,
+                                                          @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
+                                                          @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
+                                                          HttpServletRequest req) {
+        Result<IPage<KuaishouAdAccount>> result = new Result<IPage<KuaishouAdAccount>>();
+        QueryWrapper<KuaishouAdAccount> queryWrapper = QueryGenerator.initQueryWrapper(kuaishouAdAccount, req.getParameterMap());
+        Page<KuaishouAdAccount> page = new Page<KuaishouAdAccount>(pageNo, pageSize);
+        IPage<KuaishouAdAccount> pageList = kuaishouAdAccountService.page(page, queryWrapper);
+        result.setSuccess(true);
+        result.setResult(pageList);
+        return result;
+    }
+
+    /**
+     *   添加
+     * @param kuaishouAdAccount
+     * @return
+     */
+    @AutoLog(value = "快手广告主信息表-添加")
+    @ApiOperation(value="快手广告主信息表-添加", notes="快手广告主信息表-添加")
+    @PostMapping(value = "/add")
+    public Result<KuaishouAdAccount> add(@RequestBody KuaishouAdAccount kuaishouAdAccount) {
+        Result<KuaishouAdAccount> result = new Result<KuaishouAdAccount>();
+        try {
+            kuaishouAdAccountService.save(kuaishouAdAccount);
+            result.success("添加成功!");
+        } catch (Exception e) {
+            log.error(e.getMessage(),e);
+            result.error500("操作失败");
+        }
+        return result;
+    }
+
+    /**
+     *  编辑
+     * @param kuaishouAdAccount
+     * @return
+     */
+    @AutoLog(value = "快手广告主信息表-编辑")
+    @ApiOperation(value="快手广告主信息表-编辑", notes="快手广告主信息表-编辑")
+    @PutMapping(value = "/edit")
+    public Result<KuaishouAdAccount> edit(@RequestBody KuaishouAdAccount kuaishouAdAccount) {
+        Result<KuaishouAdAccount> result = new Result<KuaishouAdAccount>();
+        KuaishouAdAccount kuaishouAdAccountEntity = kuaishouAdAccountService.getById(kuaishouAdAccount.getKsid());
+        if(kuaishouAdAccountEntity==null) {
+            result.error500("未找到对应实体");
+        }else {
+            boolean ok = kuaishouAdAccountService.updateById(kuaishouAdAccount);
+            //TODO 返回false说明什么?
+            if(ok) {
+                result.success("修改成功!");
+            }
+        }
+
+        return result;
+    }
+
+    /**
+     *   通过id删除
+     * @param id
+     * @return
+     */
+    @AutoLog(value = "快手广告主信息表-通过id删除")
+    @ApiOperation(value="快手广告主信息表-通过id删除", notes="快手广告主信息表-通过id删除")
+    @DeleteMapping(value = "/delete")
+    public Result<?> delete(@RequestParam(name="id",required=true) String id) {
+        try {
+            kuaishouAdAccountService.removeById(id);
+        } catch (Exception e) {
+            log.error("删除失败",e.getMessage());
+            return Result.error("删除失败!");
+        }
+        return Result.ok("删除成功!");
+    }
+
+    /**
+     *  批量删除
+     * @param ids
+     * @return
+     */
+    @AutoLog(value = "快手广告主信息表-批量删除")
+    @ApiOperation(value="快手广告主信息表-批量删除", notes="快手广告主信息表-批量删除")
+    @DeleteMapping(value = "/deleteBatch")
+    public Result<KuaishouAdAccount> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
+        Result<KuaishouAdAccount> result = new Result<KuaishouAdAccount>();
+        if(ids==null || "".equals(ids.trim())) {
+            result.error500("参数不识别!");
+        }else {
+            this.kuaishouAdAccountService.removeByIds(Arrays.asList(ids.split(",")));
+            result.success("删除成功!");
+        }
+        return result;
+    }
+
+    /**
+     * 通过id查询
+     * @param id
+     * @return
+     */
+    @AutoLog(value = "快手广告主信息表-通过id查询")
+    @ApiOperation(value="快手广告主信息表-通过id查询", notes="快手广告主信息表-通过id查询")
+    @GetMapping(value = "/queryById")
+    public Result<KuaishouAdAccount> queryById(@RequestParam(name="id",required=true) String id) {
+        Result<KuaishouAdAccount> result = new Result<KuaishouAdAccount>();
+        KuaishouAdAccount kuaishouAdAccount = kuaishouAdAccountService.getById(id);
+        if(kuaishouAdAccount==null) {
+            result.error500("未找到对应实体");
+        }else {
+            result.setResult(kuaishouAdAccount);
+            result.setSuccess(true);
+        }
+        return result;
+    }
+
+    /**
+     * 导出excel
+     *
+     * @param request
+     * @param response
+     */
+    @RequestMapping(value = "/exportXls")
+    public ModelAndView exportXls(HttpServletRequest request, HttpServletResponse response) {
+        // Step.1 组装查询条件
+        QueryWrapper<KuaishouAdAccount> queryWrapper = null;
+        try {
+            String paramsStr = request.getParameter("paramsStr");
+            if (oConvertUtils.isNotEmpty(paramsStr)) {
+                String deString = URLDecoder.decode(paramsStr, "UTF-8");
+                KuaishouAdAccount kuaishouAdAccount = JSON.parseObject(deString, KuaishouAdAccount.class);
+                queryWrapper = QueryGenerator.initQueryWrapper(kuaishouAdAccount, request.getParameterMap());
+            }
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+
+        //Step.2 AutoPoi 导出Excel
+        ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
+        List<KuaishouAdAccount> pageList = kuaishouAdAccountService.list(queryWrapper);
+        //导出文件名称
+        mv.addObject(NormalExcelConstants.FILE_NAME, "快手广告主信息表列表");
+        mv.addObject(NormalExcelConstants.CLASS, KuaishouAdAccount.class);
+        mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("快手广告主信息表列表数据", "导出人:Jeecg", "导出信息"));
+        mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
+        return mv;
+    }
+
+    /**
+     * 通过excel导入数据
+     *
+     * @param request
+     * @param response
+     * @return
+     */
+    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
+    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
+        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
+        Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
+        for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
+            MultipartFile file = entity.getValue();// 获取上传文件对象
+            ImportParams params = new ImportParams();
+            params.setTitleRows(2);
+            params.setHeadRows(1);
+            params.setNeedSave(true);
+            try {
+                List<KuaishouAdAccount> listKuaishouAdAccounts = ExcelImportUtil.importExcel(file.getInputStream(), KuaishouAdAccount.class, params);
+                kuaishouAdAccountService.saveBatch(listKuaishouAdAccounts);
+                return Result.ok("文件导入成功!数据行数:" + listKuaishouAdAccounts.size());
+            } catch (Exception e) {
+                log.error(e.getMessage(),e);
+                return Result.error("文件导入失败:"+e.getMessage());
+            } finally {
+                try {
+                    file.getInputStream().close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return Result.ok("文件导入失败!");
+    }
+    @ResponseBody
+    @RequestMapping(value="/companysugest", method = RequestMethod.GET)
+    public Result<List<String>> getCompanySugest(@RequestParam("company") String company){
+        Result<List<String>> result = new Result<List<String>>();
+        List<String> list = kuaishouAdAccountService.companySugest(company);
+        result.setResult(list);
+        result.setSuccess(true);
+        return result;
+    }
+
+    @ResponseBody
+    @RequestMapping(value="/productsugest", method = RequestMethod.GET)
+    public Result<List<String>> getProductSugest(@RequestParam("product") String product){
+        Result<List<String>> result = new Result<List<String>>();
+        List<String> list = kuaishouAdAccountService.productSugest(product);
+        result.setResult(list);
+        result.setSuccess(true);
+        return result;
+    }
+}

+ 251 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/KuaishouAppAccountController.java

@@ -0,0 +1,251 @@
+package org.jeecg.modules.ctop.controller;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.common.aspect.annotation.AutoLog;
+import org.jeecg.common.util.oConvertUtils;
+import cn.com.ctop.crawler.modules.account.entity.KuaishouAppAccount;
+import cn.com.ctop.crawler.modules.account.service.IKuaishouAppAccountService;
+import java.util.Date;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.extern.slf4j.Slf4j;
+
+import org.jeecgframework.poi.excel.ExcelImportUtil;
+import org.jeecgframework.poi.excel.def.NormalExcelConstants;
+import org.jeecgframework.poi.excel.entity.ExportParams;
+import org.jeecgframework.poi.excel.entity.ImportParams;
+import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
+import org.springframework.web.servlet.ModelAndView;
+import com.alibaba.fastjson.JSON;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+ /**
+ * @Description: 快手APP账号表
+ * @Author: jeecg-boot
+ * @Date:   2019-06-28
+ * @Version: V1.0
+ */
+@Slf4j
+@Api(tags="快手APP账号表")
+@RestController
+@RequestMapping("/ctop/kuaishouAppAccount")
+public class KuaishouAppAccountController {
+	@Autowired
+	private IKuaishouAppAccountService kuaishouAppAccountService;
+	
+	/**
+	  * 分页列表查询
+	 * @param kuaishouAppAccount
+	 * @param pageNo
+	 * @param pageSize
+	 * @param req
+	 * @return
+	 */
+	@AutoLog(value = "快手APP账号表-分页列表查询")
+	@ApiOperation(value="快手APP账号表-分页列表查询", notes="快手APP账号表-分页列表查询")
+	@GetMapping(value = "/list")
+	public Result<IPage<KuaishouAppAccount>> queryPageList(KuaishouAppAccount kuaishouAppAccount,
+									  @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
+									  @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
+									  HttpServletRequest req) {
+		Result<IPage<KuaishouAppAccount>> result = new Result<IPage<KuaishouAppAccount>>();
+		QueryWrapper<KuaishouAppAccount> queryWrapper = QueryGenerator.initQueryWrapper(kuaishouAppAccount, req.getParameterMap());
+		Page<KuaishouAppAccount> page = new Page<KuaishouAppAccount>(pageNo, pageSize);
+		IPage<KuaishouAppAccount> pageList = kuaishouAppAccountService.page(page, queryWrapper);
+		result.setSuccess(true);
+		result.setResult(pageList);
+		return result;
+	}
+	
+	/**
+	  *   添加
+	 * @param kuaishouAppAccount
+	 * @return
+	 */
+	@AutoLog(value = "快手APP账号表-添加")
+	@ApiOperation(value="快手APP账号表-添加", notes="快手APP账号表-添加")
+	@PostMapping(value = "/add")
+	public Result<KuaishouAppAccount> add(@RequestBody KuaishouAppAccount kuaishouAppAccount) {
+		Result<KuaishouAppAccount> result = new Result<KuaishouAppAccount>();
+		try {
+			kuaishouAppAccountService.save(kuaishouAppAccount);
+			result.success("添加成功!");
+		} catch (Exception e) {
+			log.error(e.getMessage(),e);
+			result.error500("操作失败");
+		}
+		return result;
+	}
+	
+	/**
+	  *  编辑
+	 * @param kuaishouAppAccount
+	 * @return
+	 */
+	@AutoLog(value = "快手APP账号表-编辑")
+	@ApiOperation(value="快手APP账号表-编辑", notes="快手APP账号表-编辑")
+	@PutMapping(value = "/edit")
+	public Result<KuaishouAppAccount> edit(@RequestBody KuaishouAppAccount kuaishouAppAccount) {
+		Result<KuaishouAppAccount> result = new Result<KuaishouAppAccount>();
+		KuaishouAppAccount kuaishouAppAccountEntity = kuaishouAppAccountService.getById(kuaishouAppAccount.getId());
+		if(kuaishouAppAccountEntity==null) {
+			result.error500("未找到对应实体");
+		}else {
+			boolean ok = kuaishouAppAccountService.updateById(kuaishouAppAccount);
+			//TODO 返回false说明什么?
+			if(ok) {
+				result.success("修改成功!");
+			}
+		}
+		
+		return result;
+	}
+	
+	/**
+	  *   通过id删除
+	 * @param id
+	 * @return
+	 */
+	@AutoLog(value = "快手APP账号表-通过id删除")
+	@ApiOperation(value="快手APP账号表-通过id删除", notes="快手APP账号表-通过id删除")
+	@DeleteMapping(value = "/delete")
+	public Result<KuaishouAppAccount> delete(@RequestParam(name="id",required=true) String id) {
+		Result<KuaishouAppAccount> result = new Result<KuaishouAppAccount>();
+		KuaishouAppAccount kuaishouAppAccount = kuaishouAppAccountService.getById(id);
+		if(kuaishouAppAccount==null) {
+			result.error500("未找到对应实体");
+		}else {
+			boolean ok = kuaishouAppAccountService.removeById(id);
+			if(ok) {
+				result.success("删除成功!");
+			}
+		}
+		
+		return result;
+	}
+	
+	/**
+	  *  批量删除
+	 * @param ids
+	 * @return
+	 */
+	@AutoLog(value = "快手APP账号表-批量删除")
+	@ApiOperation(value="快手APP账号表-批量删除", notes="快手APP账号表-批量删除")
+	@DeleteMapping(value = "/deleteBatch")
+	public Result<KuaishouAppAccount> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
+		Result<KuaishouAppAccount> result = new Result<KuaishouAppAccount>();
+		if(ids==null || "".equals(ids.trim())) {
+			result.error500("参数不识别!");
+		}else {
+			this.kuaishouAppAccountService.removeByIds(Arrays.asList(ids.split(",")));
+			result.success("删除成功!");
+		}
+		return result;
+	}
+	
+	/**
+	  * 通过id查询
+	 * @param id
+	 * @return
+	 */
+	@AutoLog(value = "快手APP账号表-通过id查询")
+	@ApiOperation(value="快手APP账号表-通过id查询", notes="快手APP账号表-通过id查询")
+	@GetMapping(value = "/queryById")
+	public Result<KuaishouAppAccount> queryById(@RequestParam(name="id",required=true) String id) {
+		Result<KuaishouAppAccount> result = new Result<KuaishouAppAccount>();
+		KuaishouAppAccount kuaishouAppAccount = kuaishouAppAccountService.getById(id);
+		if(kuaishouAppAccount==null) {
+			result.error500("未找到对应实体");
+		}else {
+			result.setResult(kuaishouAppAccount);
+			result.setSuccess(true);
+		}
+		return result;
+	}
+
+  /**
+      * 导出excel
+   *
+   * @param request
+   * @param response
+   */
+  @RequestMapping(value = "/exportXls")
+  public ModelAndView exportXls(HttpServletRequest request, HttpServletResponse response) {
+      // Step.1 组装查询条件
+      QueryWrapper<KuaishouAppAccount> queryWrapper = null;
+      try {
+          String paramsStr = request.getParameter("paramsStr");
+          if (oConvertUtils.isNotEmpty(paramsStr)) {
+              String deString = URLDecoder.decode(paramsStr, "UTF-8");
+              KuaishouAppAccount kuaishouAppAccount = JSON.parseObject(deString, KuaishouAppAccount.class);
+              queryWrapper = QueryGenerator.initQueryWrapper(kuaishouAppAccount, request.getParameterMap());
+          }
+      } catch (UnsupportedEncodingException e) {
+          e.printStackTrace();
+      }
+
+      //Step.2 AutoPoi 导出Excel
+      ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
+      List<KuaishouAppAccount> pageList = kuaishouAppAccountService.list(queryWrapper);
+      //导出文件名称
+      mv.addObject(NormalExcelConstants.FILE_NAME, "快手APP账号表列表");
+      mv.addObject(NormalExcelConstants.CLASS, KuaishouAppAccount.class);
+      mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("快手APP账号表列表数据", "导出人:Jeecg", "导出信息"));
+      mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
+      return mv;
+  }
+
+  /**
+      * 通过excel导入数据
+   *
+   * @param request
+   * @param response
+   * @return
+   */
+  @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
+  public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
+      MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
+      Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
+      for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
+          MultipartFile file = entity.getValue();// 获取上传文件对象
+          ImportParams params = new ImportParams();
+          params.setTitleRows(2);
+          params.setHeadRows(1);
+          params.setNeedSave(true);
+          try {
+              List<KuaishouAppAccount> listKuaishouAppAccounts = ExcelImportUtil.importExcel(file.getInputStream(), KuaishouAppAccount.class, params);
+              for (KuaishouAppAccount kuaishouAppAccountExcel : listKuaishouAppAccounts) {
+                  kuaishouAppAccountService.save(kuaishouAppAccountExcel);
+              }
+              return Result.ok("文件导入成功!数据行数:" + listKuaishouAppAccounts.size());
+          } catch (Exception e) {
+              log.error(e.getMessage(),e);
+              return Result.error("文件导入失败:"+e.getMessage());
+          } finally {
+              try {
+                  file.getInputStream().close();
+              } catch (IOException e) {
+                  e.printStackTrace();
+              }
+          }
+      }
+      return Result.ok("文件导入失败!");
+  }
+
+}

+ 63 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/SyncDataController.java

@@ -0,0 +1,63 @@
+package org.jeecg.modules.ctop.controller;
+
+import cn.com.ctop.crawler.modules.account.entity.KuaishouAppAccount;
+import cn.com.ctop.crawler.modules.account.service.IKuaishouAppAccountService;
+import cn.com.ctop.crawler.modules.core.util.KuaishouUtil;
+import cn.com.ctop.crawler.modules.log.entity.CrawlerLog;
+import cn.com.ctop.kuaishou.modules.app.service.IKuaishouAppService;
+import cn.com.ctop.kuaishou.modules.material.service.IKuaishouService;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import io.swagger.annotations.Api;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Date;
+import java.util.List;
+
+@Slf4j
+@RestController
+@RequestMapping("/ctop/syncdata")
+public class SyncDataController {
+    @Autowired
+    private IKuaishouService kuaishouService;
+    @Autowired
+    private IKuaishouAppService kuaishouAppService;
+    @Autowired
+    private IKuaishouAppAccountService kuaishouAppAccountService;
+    @RequestMapping("/test")
+    public void test(){
+        try {
+            System.out.println(1);
+            kuaishouService.getMaterial("97ec4cbc9a26ec24a8ba952b24856e6e",2289L);
+//            kuaishouService.getReportByDay("97ec4cbc9a26ec24a8ba952b24856e6e",2289L,"2019-06-01","2019-06-14");
+//            kuaishouService.getReportByHour("97ec4cbc9a26ec24a8ba952b24856e6e",2289L,"2019-06-11","2019-06-17");
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    @RequestMapping("/test2")
+    public void test2(){
+        try {
+            Integer page = 1;
+            while (page < 1000){
+                QueryWrapper<KuaishouAppAccount> queryWrapper = QueryGenerator.initQueryWrapper(new KuaishouAppAccount(),null);
+                queryWrapper.eq("path","/rest/n/feed/hot");
+                List<KuaishouAppAccount> list = kuaishouAppAccountService.list(queryWrapper);
+                if (list != null) {
+                    for (KuaishouAppAccount kuaishouAppAccount : list) {
+                        kuaishouAppService.adFetch(kuaishouAppAccount, page);
+                    }
+                }
+                Thread.sleep(6000);
+                page++;
+            }
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+
+    }
+}

+ 205 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/TouTiaoAdvertiserController.java

@@ -0,0 +1,205 @@
+package org.jeecg.modules.ctop.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.modules.ctop.service.ITouTiaoAdvertiserService;
+import org.jeecg.modules.system.entity.SysDictItem;
+import org.jeecg.modules.system.service.ISysDictItemService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 头条广告主相关 2019年7月10日14:13:04 @author 宋英豪
+ */
+@Controller
+@RequestMapping("toutiao")
+public class TouTiaoAdvertiserController {
+    @Autowired
+    private ITouTiaoAdvertiserService touTiaoAdvertiserService;
+
+    /**
+     * 1:获取广告主信息 @param accountId 本平台广告主id
+     */
+    @RequestMapping("/advertiser/info")
+    @ResponseBody
+    public Map<String, Object> advertiserInfo(String accountId) {
+        return touTiaoAdvertiserService.getAdvertiserInfo(accountId);
+    }
+
+    /**
+     * 2:获取广告主广告计划信息 @param accountId 本平台广告主id
+     */
+    @RequestMapping("/advertiser/plan/get")
+    @ResponseBody
+    public Map<String, Object> advertiserPlan(String accountId, String ids) {
+        return touTiaoAdvertiserService.getAdvertiserPlan(accountId, ids);
+    }
+
+    /**
+     * 3:修改广告计划信息状态 @param accountId 本平台广告主id
+     */
+    @RequestMapping("/advertiser/plan/update/status")
+    @ResponseBody
+    public Map<String, Object> advertiserPlanUpdateStatus(String accountId, String adIds, String optStatus) {
+        return touTiaoAdvertiserService.advertiserPlanUpdateStatus(accountId, adIds, optStatus);
+    }
+
+    /**
+     * 3:修改广告计划信息状态 @param accountId 本平台广告主id
+     */
+    @RequestMapping("/advertiser/plan/update/bid")
+    @ResponseBody
+    public Map<String, Object> advertiserPlanUpdateBid(String accountId, String adIds, String bids) {
+        return touTiaoAdvertiserService.advertiserPlanUpdateBid(accountId, adIds, bids);
+    }
+
+    /**
+     * 3:修改广告计划信息状态 @param accountId 本平台广告主id
+     */
+    @RequestMapping("/advertiser/plan/update/budget")
+    @ResponseBody
+    public Map<String, Object> advertiserPlanUpdateBudget(String accountId, String adIds, String budgets) {
+        return touTiaoAdvertiserService.advertiserPlanUpdateBudget(accountId, adIds, budgets);
+    }
+
+    /**
+     * 4:获取广告主广告预算信息 @param accountId 本平台广告主id
+     */
+    @RequestMapping("/advertiser/budget/get/")
+    @ResponseBody
+    public Map<String, Object> advertiserBudget(String accountId) {
+        return touTiaoAdvertiserService.getAdvertiserBudget(accountId);
+    }
+
+    /**
+     * 3:获取广告主广告组信息 @param accountId 本平台广告主id
+     */
+    @RequestMapping("/advertiser/campaign/get")
+    @ResponseBody
+    public Map<String, Object> advertiserCampaign(String accountId, String ids) {
+        return touTiaoAdvertiserService.getAdvertiserCampaign(accountId, ids);
+    }
+
+    /**
+     * 5:获取广告主广告创意信息 @param accountId 本平台广告主id
+     */
+    @RequestMapping("/advertiser/creative/get")
+    @ResponseBody
+    public Map<String, Object> getAdvertiserCreative(String accountId, String ids) {
+        return touTiaoAdvertiserService.getAdvertiserCreative(accountId, ids);
+    }
+
+    /**
+     * 5:修改广告创意信息状态 @param accountId 本平台广告主id
+     */
+    @RequestMapping("/advertiser/update/status/")
+    @ResponseBody
+    public Map<String, Object> advertiserCreativeUpdateStatus(String accountId, String creativeIds, String optStatus) {
+        return touTiaoAdvertiserService.advertiserCreativeUpdateStatus(accountId, creativeIds, optStatus);
+    }
+
+    /**
+     * 6:获取广告主广告创意素材信息 @param accountId 本平台广告主id @param creativeIds 广告创意id
+     */
+    @RequestMapping("/advertiser/creative/material/read")
+    @ResponseBody
+    public Map<String, Object> advertiserCreativeMaterial(String accountId, String creativeIds) {
+        return touTiaoAdvertiserService.getAdvertiserCreativeMaterial(accountId, creativeIds);
+    }
+
+    /**
+     * 7:创建广告组信息 @param accountId 本平台广告主id
+     */
+    @RequestMapping("/advertiser/campaign/create")
+    @ResponseBody
+    public Map<String, Object> advertiserCampaignCreate(String accountId, String campaignName, String budgetMode, Integer budget, String landingType) {
+        return touTiaoAdvertiserService.advertiserCampaignCreate(accountId, campaignName, budgetMode, budget, landingType);
+    }
+
+    /**
+     * 7:广告组更新状态信息 @param accountId 本平台广告主id
+     */
+    @RequestMapping("/advertiser/campaign/update/status")
+    @ResponseBody
+    public Map<String, Object> advertiserCampaignUpdateStatus(String accountId, String campaignIds, String optStatus) {
+        return touTiaoAdvertiserService.advertiserCampaignUpdateStatus(accountId, campaignIds, optStatus);
+    }
+
+    /**
+     * 8:广告组更新信息 @param accountId 本平台广告主id
+     */
+    @RequestMapping("/advertiser/campaign/update")
+    @ResponseBody
+    public Map<String, Object> advertiserCampaignUpdate(String accountId, Long campaignId, String budgetMode, Integer budget, String campaignName) {
+        return touTiaoAdvertiserService.advertiserCampaignUpdate(accountId, campaignId, budgetMode, budget, campaignName);
+    }
+
+    /**
+     * @功能:查询字典数据
+     * @param sysDictItem
+     * @param pageNo
+     * @param pageSize
+     * @param req
+     * @return
+     */
+    @RequestMapping(value = "dictItem/list", method = RequestMethod.GET)
+    @ResponseBody
+    public Result<IPage<SysDictItem>> queryPageList(SysDictItem sysDictItem, @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
+                                                    @RequestParam(name="pageSize", defaultValue="10") Integer pageSize, HttpServletRequest req) {
+        Result<IPage<SysDictItem>> result = new Result<IPage<SysDictItem>>();
+        QueryWrapper<SysDictItem> queryWrapper = QueryGenerator.initQueryWrapper(sysDictItem, req.getParameterMap());
+        queryWrapper.orderByAsc("sort_order");
+        Page<SysDictItem> page = new Page<SysDictItem>(pageNo, pageSize);
+        IPage<SysDictItem> pageList = sysDictItemService.page(page, queryWrapper);
+        result.setSuccess(true);
+        result.setResult(pageList);
+        return result;
+    }
+
+    /**
+     *
+     * @param setBidType
+     * @param setFlowControlMode
+     * @param setBudgetPrice
+     * @param setBudgetMode
+     * @param setFlowDate
+     * @param setDateFlowRange
+     * @param setDateQuantum
+     * @param setPriceType
+     * @param setConvertPrice
+     * @param setFilterType
+     * @param setDateQuantumRange
+     * @param req
+     * @return
+     */
+    @RequestMapping(value = "budgetModel/insert", method = RequestMethod.GET)
+    @ResponseBody
+    public Map<String,Object> budgetModelInsert(@RequestParam(name="setBidType", defaultValue="1")String setBidType,
+                                                @RequestParam(name="setFlowControlMode", defaultValue="1") String setFlowControlMode,
+                                                @RequestParam(name="setBudgetPrice", defaultValue="1") String setBudgetPrice,
+                                                @RequestParam(name="setBudgetMode", defaultValue="1") String setBudgetMode,
+                                                @RequestParam(name="setFlowDate", defaultValue="1") String setFlowDate,
+                                                @RequestParam(name="setDateFlowRange", defaultValue="1") String setDateFlowRange,
+                                                @RequestParam(name="setDateQuantum", defaultValue="1") String setDateQuantum,
+                                                @RequestParam(name="setPriceType", defaultValue="1") String setPriceType,
+                                                @RequestParam(name="setConvertPrice", defaultValue="1") String setConvertPrice,
+                                                @RequestParam(name="setFilterType", defaultValue="1") String setFilterType,
+                                                @RequestParam(name="setDateQuantumRange", defaultValue="1") String setDateQuantumRange,HttpServletRequest req) {
+        Map<String,Object> result = new HashMap<>();
+        return result;
+    }
+
+    @Autowired
+    private ISysDictItemService sysDictItemService;
+}

+ 0 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/controller/ToutiaoCreativeController.java


Некоторые файлы не были показаны из-за большого количества измененных файлов