Compare commits
75 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
57c1cb3289 | ||
|
|
9d32a7f17d | ||
|
|
eabaf8b0d6 | ||
|
|
53bf08eeca | ||
|
|
b23e65fed9 | ||
|
|
f48a7b38d2 | ||
|
|
4e1c54435b | ||
|
|
c54a21cfd6 | ||
|
|
913a77d01f | ||
|
|
2747e0d5d3 | ||
|
|
fa2b3d92ca | ||
|
|
629b1b963f | ||
|
|
5e346c6d72 | ||
|
|
ac4c092a1c | ||
|
|
4e6e22e4dc | ||
|
|
a95d663db3 | ||
|
|
40169ac7a9 | ||
|
|
9e62a3b259 | ||
|
|
63fa05b440 | ||
|
|
3dd8ec03b9 | ||
|
|
32f81e1fee | ||
|
|
37675bac9d | ||
|
|
f9842c3c86 | ||
|
|
b8cae70933 | ||
|
|
0f0ff4af1a | ||
|
|
3539230d44 | ||
|
|
af56d05847 | ||
|
|
75c1c74fea | ||
|
|
202e9d8918 | ||
|
|
faeb49ee98 | ||
|
|
bbb37722d6 | ||
|
|
f3bb96d719 | ||
|
|
055d791c44 | ||
|
|
bf01c76167 | ||
|
|
df98f266b9 | ||
|
|
9daef68787 | ||
|
|
663a66b571 | ||
|
|
687dbe0f93 | ||
|
|
9063996fd0 | ||
|
|
1fef63126d | ||
|
|
add7294529 | ||
|
|
93652a25ae | ||
|
|
0ed597e1f1 | ||
|
|
b799b92cf1 | ||
|
|
70f2b5fefc | ||
|
|
07c50de54a | ||
|
|
a11fd3a645 | ||
|
|
39ffa1c449 | ||
|
|
36f7640a83 | ||
|
|
4ac34013b3 | ||
|
|
78c3f02f41 | ||
|
|
7750bfd49a | ||
|
|
f46b42d28e | ||
|
|
14f0cc5811 | ||
|
|
3a9e0d5dc1 | ||
|
|
f56b92ba5f | ||
|
|
98f57a2511 | ||
|
|
9e53433922 | ||
|
|
1726e5af57 | ||
|
|
1174723bc0 | ||
|
|
7654cdc6c8 | ||
|
|
c03c75609a | ||
|
|
32ce44dac4 | ||
|
|
c068718fa0 | ||
|
|
44b25989d6 | ||
|
|
b9808181d5 | ||
|
|
769f89ea67 | ||
|
|
8486aa1909 | ||
|
|
a4ca4aeb18 | ||
|
|
38ee55bd38 | ||
|
|
d9c3b036f3 | ||
|
|
a6cbbbfd16 | ||
|
|
91452fdd93 | ||
|
|
34c47d1686 | ||
|
|
8319ed58ed |
1
LICENSE
1
LICENSE
@@ -878,3 +878,4 @@ For more information on this, and how to apply and follow the GNU AGPL, see
|
||||
5. 在延伸的代码中(修改和有源代码衍生的代码中)需要带有原来代码中的协议、版权声明和其他
|
||||
原作者规定需要包含的说明(请尊重原作者的著作权,不要删除或修改文件中的`@author`信息)。
|
||||
6. 您可以应用于商业软件,但必须遵循以上条款原则(请协助改进本作品 http://jeesite.com)。
|
||||
7. 您若套用本平台的一些代码或功能参考,需要在您的软件介绍明显位置说明出处。
|
||||
|
||||
81
README.md
81
README.md
@@ -1,33 +1,61 @@
|
||||
## 引言
|
||||
|
||||
JeeSite 是一个 Java EE 企业级快速开发平台,基于经典技术组合(Spring Boot、Spring MVC、Apache Shiro、MyBatis、Beetl、Bootstrap、AdminLTE)采用经典开发模式,让初学者能够更快的入门并投入到团队开发中去。在线代码生成功能,包括核心模块如:组织机构、角色用户、菜单及按钮授权、数据权限、系统参数、内容管理、工作流等。采用松耦合设计;界面无刷新,一键换肤;众多账号安全设置,密码策略;在线定时任务配置;支持集群,支持SAAS;支持多数据源;支持读写分离、分库分表;支持微服务。
|
||||
## 技术交流
|
||||
|
||||
* 交流 QQ 群(千人大群):`127515876`、`209330483`、`223507718`、`709534275`、`730390092`、`1373527`、`183903863(外包)`
|
||||
* 问题反馈:<https://gitee.com/thinkgem/jeesite4/issues> [【新手必读】](https://gitee.com/thinkgem/jeesite4/issues/I18ARR)
|
||||
* 码云Gitee:<https://gitee.com/thinkgem/jeesite4>
|
||||
* GitHub:<https://github.com/thinkgem/jeesite4>
|
||||
* 作者博客:<https://my.oschina.net/thinkgem>
|
||||
* **技术服务:**<http://s.jeesite.com>
|
||||
* 官方网站:<http://jeesite.com>
|
||||
* 官方论坛:<http://jeesite.net>
|
||||
* 关注微信公众号,了解最新动态:
|
||||
|
||||

|
||||
|
||||
## 平台介绍
|
||||
|
||||
JeeSite 快速开发平台,不仅仅是一个后台开发框架,它是一个企业级快速开发解决方案,基于经典技术组合(Spring Boot、Spring MVC、Apache Shiro、MyBatis、Beetl、Bootstrap、AdminLTE)采用经典开发模式,让初学者能够更快的入门并投入到团队开发中去。在线代码生成功能,包括模块如:组织机构、角色用户、菜单及按钮授权、数据权限、系统参数、内容管理、工作流等。采用松耦合设计,模块增减便捷;界面无刷新,一键换肤;众多账号安全设置,密码策略;文件在线预览;消息推送;多元化第三方登录;在线定时任务配置;支持集群,支持SAAS;支持多数据源;支持读写分离、分库分表;支持微服务应用。
|
||||
|
||||
JeeSite 快速开发平台的主要目的是能够让初级的研发人员快速的开发出复杂的业务功能(经典架构会的人多),让开发者注重专注业务,其余有平台来封装技术细节,降低技术难度,从而节省人力成本,缩短项目周期,提高软件安全质量。
|
||||
|
||||
JeeSite 1.x 自 2013 年发布以来已被广大爱好者用到了企业、政府、医疗、金融、互联网等各个领域中,JeeSite 依架构简单精良、易于扩展、大众思维的设计模式,深入开发者的内心,并荣获开源中国《最受欢迎中国开源软件》奖杯,期间也帮助了不少刚毕业的大学生,作为入门教材,快速的去实践。
|
||||
JeeSite 自 2013 年发布以来已被广大爱好者用到了企业、政府、医疗、金融、互联网等各个领域中,JeeSite 架构精良、易于扩展、大众思维的设计模式、工匠精神打磨每一个细节,深入开发者的内心,并荣获开源中国《最受欢迎中国开源软件》奖杯,期间也帮助了不少刚毕业的大学生,教师作为入门教材,快速的去实践。
|
||||
|
||||
JeeSite 4.x 的升级,作者结合了多年总结和经验,以及各方面的应用案例,对架构完成了一次全部重构,也纳入很多新的思想。不管是从开发者模式、底层架构、逻辑处理还是到用户界面,用户交互体验上都有很大的进步,在不忘学习成本、提高开发效率的情况下,安全方面也做和很多工作,包括:身份认证、密码策略、安全审计、日志收集。
|
||||
JeeSite4 的升级,作者结合了多年总结和经验,以及各方面的应用案例,对架构完成了一次全部重构,也纳入很多新的思想。不管是从开发者模式、底层架构、逻辑处理还是到用户界面,用户交互体验上都有很大的进步,在不忘学习成本、提高开发效率的情况下,安全方面也做和很多工作,包括:身份认证、密码策略、安全审计、日志收集等众多安全选项供你选择。努力为大中小微企业打造全方位企业级快速开发解决方案。
|
||||
|
||||
### 4.x 的新特性及优势:<http://jeesite.com/?t=281645>
|
||||
## 平台优势
|
||||
|
||||
JeeSite 整体架构清晰、稳定技术先进、源代码书写规范、经典技术会的人多、易于维护、易于扩展、安全稳定。
|
||||
|
||||
JeeSite 功能全,JeeSite 的知识点非常多,也非常少。因为她使用的都是一些通用的技术,通俗的设计风格,大多数基础知识点多数人都能掌握,所以每一个 JeeSite 的功能点都非常容易掌握。只要你学会使用这些功能和组件的应用,就可以顺利的完成系统开发了。
|
||||
|
||||
JeeSite 是一个低代码开发平台,具有较高的封装度、扩展性,封装不是限制你去做一些事情,而是在便捷的同时,也具有较好的扩展性,在不具备一些功能的情况下,JeeSite 提供了扩展接口,提供了原生调用方法。
|
||||
|
||||
大家都在用 Spring ,在学习 Spring 架构的优点,Spring 提供了较好的扩展性,可又有多少人去修改它的源代码呢,退一步说,大家去修改了 Spring 的源码,反而会对未来升级造成很大困扰,您说不是呢?这样的例子很多,所以不要纠结,JeeSite 也一样具备强大的扩展性。
|
||||
|
||||
发展至今 JeeSite 平台架构已经非常稳定,JeeSite 是一个专业的平台,是一个让你使用放心的平台。
|
||||
|
||||
### v4 架构特点、安全方面等等的优势:<http://jeesite.com/docs/feature/>
|
||||
|
||||
## 技术选型
|
||||
|
||||
* 主框架:Spring Boot 2.2、Spring Framework 5.2、Apache Shiro 1.5、J2Cache
|
||||
* 主框架:Spring Boot 2.2、Spring Framework 5.2、Apache Shiro 1.6、J2Cache
|
||||
* 持久层:Apache MyBatis 3.5、Hibernate Validator 6.0、Alibaba Druid 1.1
|
||||
* 视图层:Spring MVC 5.2、Beetl 3.1(替换JSP)、Bootstrap 3.3、AdminLTE 2.4
|
||||
* 前端组件:jQuery 3.4、jqGrid 4.7、layer 3.1、zTree 3.5、jquery validation
|
||||
* 工作流引擎:Flowable 6.5、符合 BPMN 规范、在线流程设计器、中国式工作流
|
||||
* 技术选型详情:<http://jeesite.com/?t=273599>
|
||||
* 技术选型详情:<http://jeesite.com/docs/technology/>
|
||||
|
||||
## 内置功能
|
||||
|
||||
* <http://jeesite.com/?t=270187>
|
||||
* <http://jeesite.com/docs/function/>
|
||||
|
||||
## 生态系统
|
||||
|
||||
* 分布式微服务系统(Spring Cloud):<https://gitee.com/thinkgem/jeesite4-cloud>
|
||||
* JFlow工作流引擎:<https://gitee.com/thinkgem/jeesite4-jflow> :<http://ccflow.org>
|
||||
* 内容管理模块(CMS):<https://gitee.com/thinkgem/jeesite4-cms>【敬请期待】
|
||||
* Flowable业务流程模块(BPM):<http://jeesite.com/docs/bpm/>
|
||||
* 内容管理模块(CMS):<https://gitee.com/thinkgem/jeesite4-cms>
|
||||
|
||||
## 快速体验
|
||||
|
||||
@@ -40,21 +68,21 @@ JeeSite 4.x 的升级,作者结合了多年总结和经验,以及各方面
|
||||
### 本地运行
|
||||
|
||||
1. 环境准备:`JDK 1.8 or 11`、`Maven 3.6+`、`MySQL 5.7 or 8.0`
|
||||
2. 下载源码:<https://gitee.com/thinkgem/jeesite4/attach_files>
|
||||
3. 打开文件:/web`/src/main/resources/config/application.yml` 配置JDBC连接
|
||||
4. 执行脚本:/web`/bin/init-data.bat` 初始化数据库
|
||||
5. 执行脚本:/web`/bin/run-tomcat.bat` 启动服务即可
|
||||
2. 执行命令:`git clone https://gitee.com/thinkgem/jeesite4.git` 下载源码
|
||||
3. 打开文件:`/web/src/main/resources/config/application.yml` 配置JDBC连接
|
||||
4. 执行脚本:`/web/bin/init-data.bat` 初始化数据库
|
||||
5. 执行脚本:`/web/bin/run-tomcat.bat` 启动服务即可
|
||||
6. 浏览器访问:<http://127.0.0.1:8980/js/> 账号 system 密码 admin
|
||||
7. 部署常见问题:<http://jeesite.com/?t=284210>
|
||||
7. 部署常见问题:<http://jeesite.com/docs/faq/>
|
||||
|
||||
### 开发环境
|
||||
|
||||
1. 部署运行:<http://jeesite.com/?t=267354>
|
||||
2. 常见问题:<http://jeesite.com/?t=284210>
|
||||
1. 部署运行文档:<http://jeesite.com/docs/install-deploy/>
|
||||
2. 部署常见问题:<http://jeesite.com/docs/faq/>
|
||||
|
||||
## 在线文档
|
||||
|
||||
* <http://docs.jeesite.com>
|
||||
* 在线文档学习地址:<http://docs.jeesite.com>
|
||||
|
||||
## 授权协议声明
|
||||
|
||||
@@ -65,8 +93,9 @@ JeeSite 4.x 的升级,作者结合了多年总结和经验,以及各方面
|
||||
5. 在延伸的代码中(修改和有源代码衍生的代码中)需要带有原来代码中的协议、版权声明和其他原作者规定
|
||||
需要包含的说明(请尊重原作者的著作权,不要删除或修改文件中的`@author`信息)。
|
||||
6. 您可以应用于商业软件,但必须遵循以上条款原则(请协助改进本作品)。
|
||||
7. 关系平台的发展战略考虑,底层部分代码暂未开源,但这不影响您的二次开发。
|
||||
7. 您若套用本平台的一些代码或功能参考,需要在您的软件介绍明显位置说明出处。
|
||||
8. 请知悉社区版,用户数不可超过100个,最大允许20个用户同时在线(不含匿名)。
|
||||
9. 无限制版下载:<https://gitee.com/thinkgem/jeesite4/tree/v4.0_dev/>
|
||||
|
||||
## 技术服务与支持
|
||||
|
||||
@@ -74,27 +103,13 @@ JeeSite 4.x 的升级,作者结合了多年总结和经验,以及各方面
|
||||
* **联系方式(官方商务)QQ:[1766571055](http://wpa.qq.com/msgrd?v=3&uin=1766571055&site=qq&menu=yes)**
|
||||
* 技术服务支持网页:<http://s.jeesite.com>
|
||||
|
||||
# 技术交流方式
|
||||
|
||||
* QQ 群号:`127515876`、`209330483`、`223507718`、`709534275`、`730390092`、`1373527`、`183903863(外包)`
|
||||
* 问题反馈:<https://gitee.com/thinkgem/jeesite4/issues> [【新手必读】](https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way/blob/master/README-zh_CN.md)
|
||||
* 码云Gitee:<https://gitee.com/thinkgem/jeesite4>
|
||||
* GitHub:<https://github.com/thinkgem/jeesite4>
|
||||
* 作者博客:<https://my.oschina.net/thinkgem>
|
||||
* **技术服务:**<http://s.jeesite.com>
|
||||
* 官方网站:<http://jeesite.com>
|
||||
* 官方论坛:<http://jeesite.net>
|
||||
* 微信公众号(关注动态):
|
||||
|
||||

|
||||
|
||||
## 今后如何升级?
|
||||
|
||||
尽量不修改 web 项目以外的源码项目,如 jeesite-common、jeesite-modele-core,如果修改了,请 Pull Requests 上来,否则代码与官方不同步,会将对你的日后升级增加难度。
|
||||
|
||||
如果您修改了依赖模块代码,也没关系,这时你需要利用 Git 版本控制工具,与官方仓库代码进行同步,合并代码即可。
|
||||
|
||||
每个版本升级,我们都会附带详细更新日志:<http://jeesite.com/?t=273830>。
|
||||
每个版本升级,我们都会附带详细更新日志:<http://jeesite.com/docs/upgrade/>。
|
||||
|
||||
在这里,你可以看到 JeeSite 新增哪些新功能和改进,在每个版本下都有对应升级方法。
|
||||
|
||||
|
||||
15
common/bin/deploy.sh
Normal file
15
common/bin/deploy.sh
Normal file
@@ -0,0 +1,15 @@
|
||||
#!/bin/sh
|
||||
# /**
|
||||
# * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
# *
|
||||
# * Author: ThinkGem@163.com
|
||||
# *
|
||||
# */
|
||||
echo ""
|
||||
echo "[信息] 部署工程版本到Nexus服务器。"
|
||||
echo ""
|
||||
|
||||
cd ..
|
||||
mvn clean deploy -Dmaven.test.skip=true -Pdeploy
|
||||
|
||||
cd bin
|
||||
@@ -1,18 +0,0 @@
|
||||
@echo off
|
||||
rem /**
|
||||
rem * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
rem *
|
||||
rem * Author: ThinkGem@163.com
|
||||
rem */
|
||||
echo.
|
||||
echo [<5B><>Ϣ] <20><><EFBFBD>빤<EFBFBD><EBB9A4>Javadoc<6F><63><EFBFBD><EFBFBD><EFBFBD><EFBFBD>jar<61><72><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>
|
||||
echo.
|
||||
|
||||
%~d0
|
||||
cd %~dp0
|
||||
|
||||
cd ..
|
||||
call mvn clean package -Pjavadoc
|
||||
|
||||
cd bin
|
||||
pause
|
||||
15
common/bin/package.sh
Normal file
15
common/bin/package.sh
Normal file
@@ -0,0 +1,15 @@
|
||||
#!/bin/sh
|
||||
# /**
|
||||
# * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
# *
|
||||
# * Author: ThinkGem@163.com
|
||||
# *
|
||||
# */
|
||||
echo ""
|
||||
echo "[信息] 打包Web工程,生成war/jar包文件。"
|
||||
echo ""
|
||||
|
||||
cd ..
|
||||
mvn clean install -Dmaven.test.skip=true -Ppackage
|
||||
|
||||
cd bin
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>com.jeesite</groupId>
|
||||
<artifactId>jeesite-parent</artifactId>
|
||||
<version>4.2.0-SNAPSHOT</version>
|
||||
<version>4.2.2-SNAPSHOT</version>
|
||||
<relativePath>../parent/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
@@ -53,12 +53,12 @@
|
||||
<version>${commons-text.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Apache Tools Ant Tar Zip -->
|
||||
<!-- Apache Zip Tools
|
||||
<dependency>
|
||||
<groupId>org.apache.ant</groupId>
|
||||
<artifactId>ant</artifactId>
|
||||
<version>${ant.version}</version>
|
||||
</dependency>
|
||||
</dependency> -->
|
||||
|
||||
<!-- Java serialization -->
|
||||
<dependency>
|
||||
@@ -88,12 +88,22 @@
|
||||
<version>${fastjson.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Java xml -->
|
||||
<!-- Java xml
|
||||
<dependency>
|
||||
<groupId>org.dom4j</groupId>
|
||||
<artifactId>dom4j</artifactId>
|
||||
<version>${dom4j.version}</version>
|
||||
</dependency> -->
|
||||
|
||||
<!-- jdk11 JAXB module
|
||||
<dependency>
|
||||
<groupId>jakarta.xml.bind</groupId>
|
||||
<artifactId>jakarta.xml.bind-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jaxb</groupId>
|
||||
<artifactId>jaxb-runtime</artifactId>
|
||||
</dependency> -->
|
||||
|
||||
<!-- XPath xml -->
|
||||
<dependency>
|
||||
@@ -113,12 +123,12 @@
|
||||
<artifactId>httpclient</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Jsoup HTTP -->
|
||||
<!-- Jsoup HTTP
|
||||
<dependency>
|
||||
<groupId>org.jsoup</groupId>
|
||||
<artifactId>jsoup</artifactId>
|
||||
<version>${jsoup.version}</version>
|
||||
</dependency>
|
||||
</dependency> -->
|
||||
|
||||
<!-- Email -->
|
||||
<dependency>
|
||||
@@ -126,11 +136,11 @@
|
||||
<artifactId>commons-email</artifactId>
|
||||
<version>${commons-email.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<!-- <dependency>
|
||||
<groupId>javax.activation</groupId>
|
||||
<artifactId>activation</artifactId>
|
||||
<version>${activation.version}</version>
|
||||
</dependency>
|
||||
</dependency> -->
|
||||
|
||||
<!-- User Agent -->
|
||||
<dependency>
|
||||
@@ -200,7 +210,7 @@
|
||||
<version>${zxing.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- POI Office Tools -->
|
||||
<!-- Office Tools -->
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi</artifactId>
|
||||
|
||||
@@ -43,7 +43,11 @@ public class DesUtils {
|
||||
return "";
|
||||
}
|
||||
if ("Base64".equals(secretKey)) {
|
||||
return EncodeUtils.decodeBase64String(data);
|
||||
try {
|
||||
return EncodeUtils.decodeBase64String(data);
|
||||
}catch (IllegalArgumentException e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
String[] ks = StringUtils.split(secretKey, ",");
|
||||
if (ks.length >= 3){
|
||||
|
||||
@@ -263,7 +263,7 @@ public class EncodeUtils {
|
||||
// 预编译SQL过滤正则表达式
|
||||
private static Pattern sqlPattern = Pattern.compile(
|
||||
"(?:')|(?:--)|(/\\*(?:.|[\\n\\r])*?\\*/)|((extractvalue|updatexml)([\\s]*?)\\()|"
|
||||
+ "(\\b(select|update|and|or|delete|insert|trancate|char|into|substr|ascii|declare|exec|count|master|into|drop|execute|case when)\\b)",
|
||||
+ "(\\b(select|update|and|or|delete|insert|trancate|char|into|substr|ascii|declare|exec|count|master|into|drop|execute|case when|sleep|union|load_file)\\b)",
|
||||
Pattern.CASE_INSENSITIVE);
|
||||
|
||||
/**
|
||||
@@ -286,8 +286,8 @@ public class EncodeUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
// public static void main(String[] args) {
|
||||
// int i = 0;
|
||||
public static void main(String[] args) {
|
||||
int i = 0;
|
||||
// xssFilter((++i)+"你好,<script>alert(document.cookie)</script>我还在。");
|
||||
// xssFilter((++i)+"你好,<strong>加粗文字</strong>我还在。");
|
||||
// xssFilter("<!--HTML-->"+(++i)+"你好,\"><strong>加粗文字</strong>我还在。");
|
||||
@@ -313,10 +313,11 @@ public class EncodeUtils {
|
||||
// xssFilter("<!--HTML-->"+(++i)+"你好,<a href='javascript:alert(\"abc\");'>hello</a>我还在。");
|
||||
// xssFilter("<!--HTML-->"+(++i)+"你好,?abc=def&hello=123&world={\"a\":1}我还在。");
|
||||
// xssFilter("<!--HTML-->"+(++i)+"你好,?abc=def&hello=123&world={'a':1}我还在。");
|
||||
// sqlFilter((++i)+"你好,select * from xxx where abc=def and 1=1我还在。");
|
||||
// sqlFilter((++i)+"你好,insert into xxx values(1,2,3,4,5)我还在。");
|
||||
// sqlFilter((++i)+"你好,delete from xxx我还在。");
|
||||
// sqlFilter((++i)+"a.audit_result asc,case when 1 like case when length(database())=6 then 1 else exp(11111111111111111) end then 1 else 1/0 end");
|
||||
// }
|
||||
sqlFilter((++i)+"你好,select * from xxx where abc=def and 1=1我还在。");
|
||||
sqlFilter((++i)+"你好,insert into xxx values(1,2,3,4,5)我还在。");
|
||||
sqlFilter((++i)+"你好,delete from xxx我还在。");
|
||||
sqlFilter((++i)+"你好,a.audit_result asc,case when 1 like case when length(database())=6 then 1 else exp(11111111111111111) end then 1 else 1/0 end");
|
||||
sqlFilter((++i)+"你好,if(1=2,1,SLEEP(10))");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -46,6 +46,27 @@ public class ListUtils extends org.apache.commons.collections.ListUtils {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否包含字符串
|
||||
* @param strs 验证字符串组
|
||||
* @param strs2 字符串组
|
||||
* @return 包含返回true
|
||||
*/
|
||||
public static boolean inString(List<String> strs, List<String> strs2){
|
||||
if (strs != null && strs2 != null){
|
||||
for (String s : strs){
|
||||
if (s != null) {
|
||||
for (String s2 : strs2){
|
||||
if (StringUtils.trim(s).equals(StringUtils.trim(s2))){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static <E> ArrayList<E> newArrayList() {
|
||||
return new ArrayList<E>();
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ import org.patchca.word.RandomWordFactory;
|
||||
public class CaptchaUtils {
|
||||
|
||||
private static Random random = new Random();
|
||||
private static ConfigurableCaptchaService ccs;
|
||||
private volatile static ConfigurableCaptchaService ccs;
|
||||
private static WobbleRippleFilterFactory wrff; // 摆波纹
|
||||
private static DoubleRippleFilterFactory doff; // 双波纹
|
||||
private static CurvesRippleFilterFactory crff; // 曲线波纹
|
||||
|
||||
@@ -13,6 +13,9 @@ import java.io.OutputStream;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
import javax.activation.MimetypesFileTypeMap;
|
||||
import javax.servlet.ServletOutputStream;
|
||||
@@ -21,9 +24,6 @@ import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.io.Charsets;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.tools.zip.ZipEntry;
|
||||
import org.apache.tools.zip.ZipFile;
|
||||
import org.apache.tools.zip.ZipOutputStream;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
@@ -462,14 +462,18 @@ public class FileUtils extends org.apache.commons.io.FileUtils {
|
||||
}
|
||||
}
|
||||
|
||||
// public static void main(String[] args) {
|
||||
// zipFiles("target\\classes", "*", "target\\classes.zip");
|
||||
// unZipFiles("target\\classes.zip", "target\\classes2");
|
||||
// }
|
||||
|
||||
/**
|
||||
* 压缩文件或目录
|
||||
* @param srcDirName 压缩的根目录
|
||||
* @param fileName 根目录下的待压缩的文件名或文件夹名,其中*或""表示跟目录下的全部文件
|
||||
* @param descFileName 目标zip文件
|
||||
*/
|
||||
public static void zipFiles(String srcDirName, String fileName,
|
||||
String descFileName) {
|
||||
public static void zipFiles(String srcDirName, String fileName, String descFileName) {
|
||||
// 判断目录是否存在
|
||||
if (srcDirName == null) {
|
||||
logger.debug("文件压缩失败,目录 " + srcDirName + " 不存在!");
|
||||
@@ -483,8 +487,7 @@ public class FileUtils extends org.apache.commons.io.FileUtils {
|
||||
String dirPath = fileDir.getAbsolutePath();
|
||||
File descFile = new File(descFileName);
|
||||
try {
|
||||
ZipOutputStream zouts = new ZipOutputStream(new FileOutputStream(
|
||||
descFile));
|
||||
ZipOutputStream zouts = new ZipOutputStream(new FileOutputStream(descFile));
|
||||
if ("*".equals(fileName) || "".equals(fileName)) {
|
||||
FileUtils.zipDirectoryToZipFile(dirPath, fileDir, zouts);
|
||||
} else {
|
||||
@@ -492,8 +495,7 @@ public class FileUtils extends org.apache.commons.io.FileUtils {
|
||||
if (file.isFile()) {
|
||||
FileUtils.zipFilesToZipFile(dirPath, file, zouts);
|
||||
} else {
|
||||
FileUtils
|
||||
.zipDirectoryToZipFile(dirPath, file, zouts);
|
||||
FileUtils.zipDirectoryToZipFile(dirPath, file, zouts);
|
||||
}
|
||||
}
|
||||
zouts.close();
|
||||
@@ -525,7 +527,7 @@ public class FileUtils extends org.apache.commons.io.FileUtils {
|
||||
int readByte = 0;
|
||||
// 获取ZIP文件里所有的entry
|
||||
@SuppressWarnings("rawtypes")
|
||||
Enumeration enums = zipFile.getEntries();
|
||||
Enumeration enums = zipFile.entries();
|
||||
// 遍历所有entry
|
||||
while (enums.hasMoreElements()) {
|
||||
entry = (ZipEntry) enums.nextElement();
|
||||
@@ -585,12 +587,10 @@ public class FileUtils extends org.apache.commons.io.FileUtils {
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
if (files[i].isFile()) {
|
||||
// 如果是文件,则调用文件压缩方法
|
||||
FileUtils
|
||||
.zipFilesToZipFile(dirPath, files[i], zouts);
|
||||
FileUtils.zipFilesToZipFile(dirPath, files[i], zouts);
|
||||
} else {
|
||||
// 如果是目录,则递归调用
|
||||
FileUtils.zipDirectoryToZipFile(dirPath, files[i],
|
||||
zouts);
|
||||
FileUtils.zipDirectoryToZipFile(dirPath, files[i], zouts);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -646,7 +646,6 @@ public class FileUtils extends org.apache.commons.io.FileUtils {
|
||||
filePath += "/";
|
||||
}
|
||||
int index = filePath.indexOf(dirPaths);
|
||||
|
||||
return filePath.substring(index + dirPaths.length());
|
||||
}
|
||||
|
||||
@@ -879,8 +878,9 @@ public class FileUtils extends org.apache.commons.io.FileUtils {
|
||||
if (f.exists()){
|
||||
break;
|
||||
}
|
||||
if (file.getParentFile() != null){
|
||||
file = file.getParentFile();
|
||||
File p = file.getParentFile();
|
||||
if (p != null){
|
||||
file = p;
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
@@ -917,8 +917,9 @@ public class FileUtils extends org.apache.commons.io.FileUtils {
|
||||
if (f.exists()){
|
||||
return f.getPath();
|
||||
}
|
||||
if (file.getParentFile() != null){
|
||||
file = file.getParentFile();
|
||||
File p = file.getParentFile();
|
||||
if (p != null){
|
||||
file = p;
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -4,25 +4,30 @@
|
||||
package com.jeesite.common.io;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.springframework.boot.env.OriginTrackedMapPropertySource;
|
||||
import org.springframework.boot.env.PropertiesPropertySourceLoader;
|
||||
import org.springframework.boot.env.YamlPropertySourceLoader;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
import org.springframework.core.io.Resource;
|
||||
|
||||
import com.alibaba.fastjson.parser.ParserConfig;
|
||||
import com.jeesite.common.lang.StringUtils;
|
||||
|
||||
/**
|
||||
* 配置文件加载(Boot)
|
||||
* @author ThinkGem
|
||||
* @version 2018-10-16
|
||||
* @version 2020-10-26
|
||||
*/
|
||||
public class PropertyLoader implements org.springframework.boot.env.PropertySourceLoader, Ordered{
|
||||
public class PropertyLoader extends PropertiesPropertySourceLoader implements org.springframework.boot.env.PropertySourceLoader, Ordered{
|
||||
|
||||
private static boolean isLoadPropertySource = false;
|
||||
private static boolean isLoadJeeSitePropertySource = false;
|
||||
private PropertiesPropertySourceLoader propertiesPropertySourceLoader = new PropertiesPropertySourceLoader();
|
||||
private YamlPropertySourceLoader yamlPropertySourceLoader = new YamlPropertySourceLoader();
|
||||
|
||||
@Override
|
||||
public String[] getFileExtensions() {
|
||||
@@ -31,13 +36,21 @@ public class PropertyLoader implements org.springframework.boot.env.PropertySour
|
||||
|
||||
@Override
|
||||
public List<PropertySource<?>> load(String name, Resource resource) throws IOException {
|
||||
if (!isLoadPropertySource){
|
||||
isLoadPropertySource = true;
|
||||
List<PropertySource<?>> propertySources = new ArrayList<>();
|
||||
if (!isLoadJeeSitePropertySource) {
|
||||
isLoadJeeSitePropertySource = true;
|
||||
ParserConfig.getGlobalInstance().setSafeMode(true); // 开启 FastJSON 安全模式
|
||||
Properties properties = PropertiesUtils.getInstance().getProperties();
|
||||
return Collections.singletonList(new OriginTrackedMapPropertySource("jeesite", properties));
|
||||
propertySources.add(new OriginTrackedMapPropertySource("jeesite", properties));
|
||||
} else {
|
||||
String ext = FileUtils.getFileExtension(resource.getFilename());
|
||||
if (StringUtils.inString(ext, propertiesPropertySourceLoader.getFileExtensions())) {
|
||||
propertySources.addAll(propertiesPropertySourceLoader.load(name, resource));
|
||||
}else if (StringUtils.inString(ext, yamlPropertySourceLoader.getFileExtensions())) {
|
||||
propertySources.addAll(yamlPropertySourceLoader.load(name, resource));
|
||||
}
|
||||
}
|
||||
return Collections.emptyList();
|
||||
return propertySources;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -4,21 +4,9 @@
|
||||
package com.jeesite.common.mapper;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.dom4j.Attribute;
|
||||
import org.dom4j.Document;
|
||||
import org.dom4j.DocumentException;
|
||||
import org.dom4j.DocumentHelper;
|
||||
import org.dom4j.Element;
|
||||
import org.dom4j.Namespace;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
|
||||
@@ -124,167 +112,167 @@ public class XmlMapper extends com.fasterxml.jackson.dataformat.xml.XmlMapper{
|
||||
return (T) XmlMapper.getInstance().fromXmlString(jsonString, clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* xml转map 不带属性
|
||||
* @param xmlStr
|
||||
* @param needRootKey 是否需要在返回的map里加根节点键
|
||||
* @throws DocumentException
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Map<String, Object> xmlToMap(String xmlStr, boolean needRootKey) {
|
||||
try {
|
||||
Document doc = DocumentHelper.parseText(xmlStr);
|
||||
Element root = doc.getRootElement();
|
||||
Map<String, Object> map = (Map<String, Object>) xmlToMap(root);
|
||||
if (root.elements().size() == 0 && root.attributes().size() == 0) {
|
||||
return map;
|
||||
}
|
||||
if (needRootKey) {
|
||||
//在返回的map里加根节点键(如果需要)
|
||||
Map<String, Object> rootMap = new HashMap<String, Object>();
|
||||
rootMap.put(root.getName(), map);
|
||||
return rootMap;
|
||||
}
|
||||
return map;
|
||||
} catch (DocumentException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* xml转map 带属性
|
||||
* @param xmlStr
|
||||
* @param needRootKey 是否需要在返回的map里加根节点键
|
||||
* @return
|
||||
* @throws DocumentException
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Map<String, Object> xmlToMapWithAttr(String xmlStr, boolean needRootKey) {
|
||||
try {
|
||||
Document doc = DocumentHelper.parseText(xmlStr);
|
||||
Element root = doc.getRootElement();
|
||||
Map<String, Object> map = (Map<String, Object>) xmlToMapWithAttr(root);
|
||||
if (root.elements().size() == 0 && root.attributes().size() == 0) {
|
||||
return map; //根节点只有一个文本内容
|
||||
}
|
||||
if (needRootKey) {
|
||||
//在返回的map里加根节点键(如果需要)
|
||||
Map<String, Object> rootMap = new HashMap<String, Object>();
|
||||
rootMap.put(root.getName(), map);
|
||||
return rootMap;
|
||||
}
|
||||
return map;
|
||||
} catch (DocumentException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* xml转map 不带属性
|
||||
* @param element
|
||||
* @return
|
||||
*/
|
||||
private static Object xmlToMap(Element element) {
|
||||
// System.out.println(element.getName());
|
||||
Map<String, Object> map = new LinkedHashMap<String, Object>();
|
||||
List<Element> elements = element.elements();
|
||||
if (elements.size() == 0) {
|
||||
map.put(element.getName(), element.getText());
|
||||
if (!element.isRootElement()) {
|
||||
return element.getText();
|
||||
}
|
||||
} else if (elements.size() == 1) {
|
||||
map.put(elements.get(0).getName(), xmlToMap(elements.get(0)));
|
||||
} else if (elements.size() > 1) {
|
||||
// 多个子节点的话就得考虑list的情况了,比如多个子节点有节点名称相同的
|
||||
// 构造一个map用来去重
|
||||
Map<String, Element> tempMap = new LinkedHashMap<String, Element>();
|
||||
for (Element ele : elements) {
|
||||
tempMap.put(ele.getName(), ele);
|
||||
}
|
||||
Set<String> keySet = tempMap.keySet();
|
||||
for (String string : keySet) {
|
||||
Namespace namespace = tempMap.get(string).getNamespace();
|
||||
List<Element> elements2 = element.elements(new org.dom4j.QName(string, namespace));
|
||||
// 如果同名的数目大于1则表示要构建list
|
||||
if (elements2.size() > 1) {
|
||||
List<Object> list = new ArrayList<Object>();
|
||||
for (Element ele : elements2) {
|
||||
list.add(xmlToMap(ele));
|
||||
}
|
||||
map.put(string, list);
|
||||
} else {
|
||||
// 同名的数量不大于1则直接递归去
|
||||
map.put(string, xmlToMap(elements2.get(0)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* xml转map 带属性
|
||||
* @param element
|
||||
* @return
|
||||
*/
|
||||
private static Object xmlToMapWithAttr(Element element) {
|
||||
// System.out.println(element.getName());
|
||||
Map<String, Object> map = new LinkedHashMap<String, Object>();
|
||||
List<Element> elements = element.elements();
|
||||
|
||||
List<Attribute> listAttr = element.attributes(); // 当前节点的所有属性的list
|
||||
boolean hasAttributes = false;
|
||||
for (Attribute attr : listAttr) {
|
||||
hasAttributes = true;
|
||||
map.put("@" + attr.getName(), attr.getValue());
|
||||
}
|
||||
|
||||
if (elements.size() == 0) {
|
||||
// map.put(element.getName(), element.getText());
|
||||
if (hasAttributes) {
|
||||
map.put("#text", element.getText());
|
||||
} else {
|
||||
map.put(element.getName(), element.getText());
|
||||
}
|
||||
|
||||
if (!element.isRootElement()) {
|
||||
// return element.getText();
|
||||
if (!hasAttributes) {
|
||||
return element.getText();
|
||||
}
|
||||
}
|
||||
} else if (elements.size() == 1) {
|
||||
map.put(elements.get(0).getName(), xmlToMapWithAttr(elements.get(0)));
|
||||
} else if (elements.size() > 1) {
|
||||
// 多个子节点的话就得考虑list的情况了,比如多个子节点有节点名称相同的
|
||||
// 构造一个map用来去重
|
||||
Map<String, Element> tempMap = new LinkedHashMap<String, Element>();
|
||||
for (Element ele : elements) {
|
||||
tempMap.put(ele.getName(), ele);
|
||||
}
|
||||
Set<String> keySet = tempMap.keySet();
|
||||
for (String string : keySet) {
|
||||
Namespace namespace = tempMap.get(string).getNamespace();
|
||||
List<Element> elements2 = element.elements(new org.dom4j.QName(string, namespace));
|
||||
// 如果同名的数目大于1则表示要构建list
|
||||
if (elements2.size() > 1) {
|
||||
List<Object> list = new ArrayList<Object>();
|
||||
for (Element ele : elements2) {
|
||||
list.add(xmlToMapWithAttr(ele));
|
||||
}
|
||||
map.put(string, list);
|
||||
} else {
|
||||
// 同名的数量不大于1则直接递归去
|
||||
map.put(string, xmlToMapWithAttr(elements2.get(0)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
// /**
|
||||
// * xml转map 不带属性
|
||||
// * @param xmlStr
|
||||
// * @param needRootKey 是否需要在返回的map里加根节点键
|
||||
// * @throws DocumentException
|
||||
// */
|
||||
// @SuppressWarnings("unchecked")
|
||||
// public static Map<String, Object> xmlToMap(String xmlStr, boolean needRootKey) {
|
||||
// try {
|
||||
// Document doc = DocumentHelper.parseText(xmlStr);
|
||||
// Element root = doc.getRootElement();
|
||||
// Map<String, Object> map = (Map<String, Object>) xmlToMap(root);
|
||||
// if (root.elements().size() == 0 && root.attributes().size() == 0) {
|
||||
// return map;
|
||||
// }
|
||||
// if (needRootKey) {
|
||||
// //在返回的map里加根节点键(如果需要)
|
||||
// Map<String, Object> rootMap = new HashMap<String, Object>();
|
||||
// rootMap.put(root.getName(), map);
|
||||
// return rootMap;
|
||||
// }
|
||||
// return map;
|
||||
// } catch (DocumentException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * xml转map 带属性
|
||||
// * @param xmlStr
|
||||
// * @param needRootKey 是否需要在返回的map里加根节点键
|
||||
// * @return
|
||||
// * @throws DocumentException
|
||||
// */
|
||||
// @SuppressWarnings("unchecked")
|
||||
// public static Map<String, Object> xmlToMapWithAttr(String xmlStr, boolean needRootKey) {
|
||||
// try {
|
||||
// Document doc = DocumentHelper.parseText(xmlStr);
|
||||
// Element root = doc.getRootElement();
|
||||
// Map<String, Object> map = (Map<String, Object>) xmlToMapWithAttr(root);
|
||||
// if (root.elements().size() == 0 && root.attributes().size() == 0) {
|
||||
// return map; //根节点只有一个文本内容
|
||||
// }
|
||||
// if (needRootKey) {
|
||||
// //在返回的map里加根节点键(如果需要)
|
||||
// Map<String, Object> rootMap = new HashMap<String, Object>();
|
||||
// rootMap.put(root.getName(), map);
|
||||
// return rootMap;
|
||||
// }
|
||||
// return map;
|
||||
// } catch (DocumentException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * xml转map 不带属性
|
||||
// * @param element
|
||||
// * @return
|
||||
// */
|
||||
// private static Object xmlToMap(Element element) {
|
||||
// // System.out.println(element.getName());
|
||||
// Map<String, Object> map = new LinkedHashMap<String, Object>();
|
||||
// List<Element> elements = element.elements();
|
||||
// if (elements.size() == 0) {
|
||||
// map.put(element.getName(), element.getText());
|
||||
// if (!element.isRootElement()) {
|
||||
// return element.getText();
|
||||
// }
|
||||
// } else if (elements.size() == 1) {
|
||||
// map.put(elements.get(0).getName(), xmlToMap(elements.get(0)));
|
||||
// } else if (elements.size() > 1) {
|
||||
// // 多个子节点的话就得考虑list的情况了,比如多个子节点有节点名称相同的
|
||||
// // 构造一个map用来去重
|
||||
// Map<String, Element> tempMap = new LinkedHashMap<String, Element>();
|
||||
// for (Element ele : elements) {
|
||||
// tempMap.put(ele.getName(), ele);
|
||||
// }
|
||||
// Set<String> keySet = tempMap.keySet();
|
||||
// for (String string : keySet) {
|
||||
// Namespace namespace = tempMap.get(string).getNamespace();
|
||||
// List<Element> elements2 = element.elements(new org.dom4j.QName(string, namespace));
|
||||
// // 如果同名的数目大于1则表示要构建list
|
||||
// if (elements2.size() > 1) {
|
||||
// List<Object> list = new ArrayList<Object>();
|
||||
// for (Element ele : elements2) {
|
||||
// list.add(xmlToMap(ele));
|
||||
// }
|
||||
// map.put(string, list);
|
||||
// } else {
|
||||
// // 同名的数量不大于1则直接递归去
|
||||
// map.put(string, xmlToMap(elements2.get(0)));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return map;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * xml转map 带属性
|
||||
// * @param element
|
||||
// * @return
|
||||
// */
|
||||
// private static Object xmlToMapWithAttr(Element element) {
|
||||
// // System.out.println(element.getName());
|
||||
// Map<String, Object> map = new LinkedHashMap<String, Object>();
|
||||
// List<Element> elements = element.elements();
|
||||
//
|
||||
// List<Attribute> listAttr = element.attributes(); // 当前节点的所有属性的list
|
||||
// boolean hasAttributes = false;
|
||||
// for (Attribute attr : listAttr) {
|
||||
// hasAttributes = true;
|
||||
// map.put("@" + attr.getName(), attr.getValue());
|
||||
// }
|
||||
//
|
||||
// if (elements.size() == 0) {
|
||||
// // map.put(element.getName(), element.getText());
|
||||
// if (hasAttributes) {
|
||||
// map.put("#text", element.getText());
|
||||
// } else {
|
||||
// map.put(element.getName(), element.getText());
|
||||
// }
|
||||
//
|
||||
// if (!element.isRootElement()) {
|
||||
// // return element.getText();
|
||||
// if (!hasAttributes) {
|
||||
// return element.getText();
|
||||
// }
|
||||
// }
|
||||
// } else if (elements.size() == 1) {
|
||||
// map.put(elements.get(0).getName(), xmlToMapWithAttr(elements.get(0)));
|
||||
// } else if (elements.size() > 1) {
|
||||
// // 多个子节点的话就得考虑list的情况了,比如多个子节点有节点名称相同的
|
||||
// // 构造一个map用来去重
|
||||
// Map<String, Element> tempMap = new LinkedHashMap<String, Element>();
|
||||
// for (Element ele : elements) {
|
||||
// tempMap.put(ele.getName(), ele);
|
||||
// }
|
||||
// Set<String> keySet = tempMap.keySet();
|
||||
// for (String string : keySet) {
|
||||
// Namespace namespace = tempMap.get(string).getNamespace();
|
||||
// List<Element> elements2 = element.elements(new org.dom4j.QName(string, namespace));
|
||||
// // 如果同名的数目大于1则表示要构建list
|
||||
// if (elements2.size() > 1) {
|
||||
// List<Object> list = new ArrayList<Object>();
|
||||
// for (Element ele : elements2) {
|
||||
// list.add(xmlToMapWithAttr(ele));
|
||||
// }
|
||||
// map.put(string, list);
|
||||
// } else {
|
||||
// // 同名的数量不大于1则直接递归去
|
||||
// map.put(string, xmlToMapWithAttr(elements2.get(0)));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return map;
|
||||
// }
|
||||
|
||||
// public static void main(String[] args) throws Exception {
|
||||
//
|
||||
|
||||
@@ -77,4 +77,9 @@ public class EmailUtils {
|
||||
return false;
|
||||
}
|
||||
|
||||
// public static void main(String[] args) {
|
||||
// EmailUtils.send("jeesite_demo@163.com", "jeesitedemo1234", "smtp.163.com",
|
||||
// "false", "465", "jeesite_demo@163.com", "测试邮件", "测试<b>邮件</b>的内容");
|
||||
// }
|
||||
|
||||
}
|
||||
@@ -21,23 +21,23 @@ public class SmsUtils {
|
||||
// String data = props.getProperty("msg.sms.data");
|
||||
// String prefix = props.getProperty("msg.sms.prefix", "");
|
||||
// String suffix = props.getProperty("msg.sms.suffix", "");
|
||||
// Connection conn = Jsoup.connect(url);
|
||||
// conn.postDataCharset("UTF-8");
|
||||
// conn.method(Method.POST);
|
||||
// Map<String, String> dataMap = MapUtils.newHashMap();
|
||||
// for (String param : StringUtils.split(data, "&")){
|
||||
// String[] ss = StringUtils.split(param, "=");
|
||||
// if (ss.length == 1){
|
||||
// conn.data(ss[0], "");
|
||||
// dataMap.put(ss[0], "");
|
||||
// }else if (ss.length == 2){
|
||||
// conn.data(ss[0], ss[1]);
|
||||
// dataMap.put(ss[0], ss[1]);
|
||||
// }
|
||||
// }
|
||||
// // 手机号码
|
||||
// conn.data("mobile", mobile);
|
||||
// dataMap.put("mobile", mobile);
|
||||
// // 短信内容
|
||||
// conn.data("content", prefix + content + suffix);
|
||||
logger.warn("模拟发送短信成功!请实现 "+SmsUtils.class+" 的 send 方法。内容:"+content);
|
||||
return "{result:0,message:\"模拟发送短信成功!\"}";
|
||||
// dataMap.put("content", prefix + content + suffix);
|
||||
// HttpClientUtils.post(url, dataMap, "UTF-8");
|
||||
logger.debug("短信内容:" + content + " 手机号码:" + mobile);
|
||||
logger.warn("短信模拟发送成功!实际并未发送到手机,请实现 " + SmsUtils.class + " 的 send 方法。");
|
||||
return "{result:0,message:\"短信模拟发送成功!\"}";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -296,7 +296,8 @@ public class ReflectUtils {
|
||||
* 改变private/protected的方法为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。
|
||||
*/
|
||||
public static void makeAccessible(Method method) {
|
||||
if ((!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers()))
|
||||
if ((!Modifier.isPublic(method.getModifiers())
|
||||
|| !Modifier.isPublic(method.getDeclaringClass().getModifiers()))
|
||||
&& !method.isAccessible()) {
|
||||
method.setAccessible(true);
|
||||
}
|
||||
@@ -306,8 +307,9 @@ public class ReflectUtils {
|
||||
* 改变private/protected的成员变量为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。
|
||||
*/
|
||||
public static void makeAccessible(Field field) {
|
||||
if ((!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers()) || Modifier
|
||||
.isFinal(field.getModifiers())) && !field.isAccessible()) {
|
||||
if ((!Modifier.isPublic(field.getModifiers())
|
||||
|| !Modifier.isPublic(field.getDeclaringClass().getModifiers())
|
||||
|| Modifier.isFinal(field.getModifiers())) && !field.isAccessible()) {
|
||||
field.setAccessible(true);
|
||||
}
|
||||
}
|
||||
@@ -333,16 +335,12 @@ public class ReflectUtils {
|
||||
* @return the index generic declaration, or Object.class if cannot be determined
|
||||
*/
|
||||
public static Class getClassGenricType(final Class clazz, final int index) {
|
||||
|
||||
Type genType = clazz.getGenericSuperclass();
|
||||
|
||||
if (!(genType instanceof ParameterizedType)) {
|
||||
logger.debug(clazz.getSimpleName() + "'s superclass not ParameterizedType");
|
||||
return Object.class;
|
||||
}
|
||||
|
||||
Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
|
||||
|
||||
if (index >= params.length || index < 0) {
|
||||
logger.debug("Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: "
|
||||
+ params.length);
|
||||
@@ -352,7 +350,6 @@ public class ReflectUtils {
|
||||
logger.debug(clazz.getSimpleName() + " not set the actual class on superclass generic parameter");
|
||||
return Object.class;
|
||||
}
|
||||
|
||||
return (Class) params[index];
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ import org.slf4j.LoggerFactory;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import com.jeesite.common.callback.MethodCallback;
|
||||
import com.jeesite.common.codec.EncodeUtils;
|
||||
import com.jeesite.common.collect.ListUtils;
|
||||
import com.jeesite.common.collect.MapUtils;
|
||||
import com.jeesite.common.lang.DateUtils;
|
||||
@@ -478,6 +479,10 @@ public class ExcelImport implements Closeable {
|
||||
// 参数:Exception ex, int rowNum, int columnNum
|
||||
exceptionCallback.execute(ex, i, column);
|
||||
}
|
||||
// 导入的数据进行 xss 过滤
|
||||
if (val != null && val instanceof String) {
|
||||
val = EncodeUtils.xssFilter(val.toString());
|
||||
}
|
||||
// set entity value
|
||||
if (StringUtils.isNotBlank(ef.attrName())){
|
||||
ReflectUtils.invokeSetter(e, ef.attrName(), val);
|
||||
|
||||
@@ -9,6 +9,7 @@ import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.jeesite.common.codec.EncodeUtils;
|
||||
import com.jeesite.common.lang.StringUtils;
|
||||
import com.jeesite.common.web.http.ServletUtils;
|
||||
|
||||
/**
|
||||
* Cookie工具类
|
||||
@@ -45,7 +46,8 @@ public class CookieUtils {
|
||||
* @param uri 路径
|
||||
*/
|
||||
public static void setCookie(HttpServletResponse response, String name, String value, int maxAge) {
|
||||
setCookie(response, name, value, "/", maxAge);
|
||||
HttpServletRequest request = ServletUtils.getRequest();
|
||||
setCookie(response, name, value, request != null ? request.getContextPath() : "", maxAge);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -94,7 +96,7 @@ public class CookieUtils {
|
||||
* @return 值
|
||||
*/
|
||||
public static String getCookie(HttpServletRequest request, HttpServletResponse response, String name, boolean isRemove) {
|
||||
return getCookie(request, response, name, "/", false);
|
||||
return getCookie(request, response, name, request != null ? request.getContextPath() : "", false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -42,7 +42,11 @@ public class ServletUtils {
|
||||
// 定义静态文件后缀;静态文件排除URI地址
|
||||
private static String[] staticFiles;
|
||||
private static String[] staticFileExcludeUri;
|
||||
|
||||
private static Boolean favorPathExtension;
|
||||
private static Boolean favorParameter;
|
||||
private static Boolean favorHeader;
|
||||
private static Boolean jsonp;
|
||||
|
||||
/**
|
||||
* 获取当前请求对象
|
||||
* web.xml: <listener><listener-class>
|
||||
@@ -97,45 +101,10 @@ public class ServletUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否是Ajax异步请求
|
||||
* @param request
|
||||
*/
|
||||
public static boolean isAjaxRequest(HttpServletRequest request){
|
||||
|
||||
String accept = request.getHeader("accept");
|
||||
if (StringUtils.contains(accept, MediaType.APPLICATION_JSON_VALUE)){
|
||||
return true;
|
||||
}
|
||||
|
||||
String xRequestedWith = request.getHeader("X-Requested-With");
|
||||
if (StringUtils.contains(xRequestedWith, "XMLHttpRequest")){
|
||||
return true;
|
||||
}
|
||||
|
||||
String ajaxHeader = request.getHeader("__ajax");
|
||||
if (StringUtils.inStringIgnoreCase(ajaxHeader, "json", "xml")){
|
||||
return true;
|
||||
}
|
||||
|
||||
String ajaxParameter = request.getParameter("__ajax");
|
||||
if (StringUtils.inStringIgnoreCase(ajaxParameter, "json", "xml")){
|
||||
return true;
|
||||
}
|
||||
|
||||
String uri = request.getRequestURI();
|
||||
if (StringUtils.endsWithIgnoreCase(uri, ".json")
|
||||
|| StringUtils.endsWithIgnoreCase(uri, ".xml")){
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断访问URI是否是静态文件请求
|
||||
* 判断访问URI是否是静态文件请求
|
||||
* @throws Exception
|
||||
*/
|
||||
public static boolean isStaticFile(String uri){
|
||||
*/
|
||||
public static boolean isStaticFile(String uri){
|
||||
if (staticFiles == null){
|
||||
PropertiesUtils pl = PropertiesUtils.getInstance();
|
||||
try{
|
||||
@@ -165,7 +134,64 @@ public class ServletUtils {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化一些个性化配置
|
||||
* @author ThinkGem
|
||||
*/
|
||||
private static void initWebViewConfig() {
|
||||
if (favorPathExtension == null || favorParameter == null || favorHeader == null || jsonp == null) {
|
||||
PropertiesUtils props = PropertiesUtils.getInstance();
|
||||
favorPathExtension = ObjectUtils.toBoolean(props.getProperty("web.view.favorPathExtension", "false"));
|
||||
favorParameter = ObjectUtils.toBoolean(props.getProperty("web.view.favorParameter", "true"));
|
||||
favorHeader = ObjectUtils.toBoolean(props.getProperty("web.view.favorHeader", "true"));
|
||||
jsonp = ObjectUtils.toBoolean(props.getProperty("web.jsonp.enabled", "false"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否是Ajax异步请求
|
||||
* @param request
|
||||
*/
|
||||
public static boolean isAjaxRequest(HttpServletRequest request){
|
||||
|
||||
String accept = request.getHeader("accept");
|
||||
if (StringUtils.contains(accept, MediaType.APPLICATION_JSON_VALUE)){
|
||||
return true;
|
||||
}
|
||||
|
||||
String xRequestedWith = request.getHeader("X-Requested-With");
|
||||
if (StringUtils.contains(xRequestedWith, "XMLHttpRequest")){
|
||||
return true;
|
||||
}
|
||||
|
||||
initWebViewConfig();
|
||||
|
||||
if (favorPathExtension) {
|
||||
String uri = request.getRequestURI();
|
||||
if (StringUtils.endsWithIgnoreCase(uri, ".json")
|
||||
|| StringUtils.endsWithIgnoreCase(uri, ".xml")){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (favorParameter) {
|
||||
String ajaxParameter = request.getParameter("__ajax");
|
||||
if (StringUtils.inStringIgnoreCase(ajaxParameter, "json", "xml")){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (favorHeader) {
|
||||
String ajaxHeader = request.getHeader("__ajax");
|
||||
if (StringUtils.inStringIgnoreCase(ajaxHeader, "json", "xml")){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回结果JSON字符串(支持JsonP,请求参数加:__callback=回调函数名)
|
||||
@@ -222,9 +248,9 @@ public class ServletUtils {
|
||||
HttpServletResponse response = getResponse();
|
||||
HttpServletRequest request = getRequest();
|
||||
if (request != null){
|
||||
String uri = request.getRequestURI();
|
||||
if (StringUtils.endsWithIgnoreCase(uri, ".xml") || StringUtils
|
||||
.equalsIgnoreCase(request.getParameter("__ajax"), "xml")){
|
||||
String uri = request.getRequestURI(); initWebViewConfig();
|
||||
if ((favorPathExtension && StringUtils.endsWithIgnoreCase(uri, ".xml"))
|
||||
|| (favorParameter && StringUtils.equalsIgnoreCase(request.getParameter("__ajax"), "xml"))){
|
||||
if (response != null){
|
||||
response.setContentType(MediaType.APPLICATION_XML_VALUE);
|
||||
}
|
||||
@@ -234,7 +260,7 @@ public class ServletUtils {
|
||||
return XmlMapper.toXml(resultMap);
|
||||
}
|
||||
}
|
||||
if (ObjectUtils.toBoolean(PropertiesUtils.getInstance().getProperty("web.jsonp.enabled"))) {
|
||||
if (jsonp) {
|
||||
String functionName = request.getParameter("__callback");
|
||||
if (StringUtils.isNotBlank(functionName)){
|
||||
object = new JSONPObject(functionName, resultMap);
|
||||
@@ -311,12 +337,12 @@ public class ServletUtils {
|
||||
*/
|
||||
public static String renderObject(HttpServletResponse response, Object object, Class<?> jsonView) {
|
||||
HttpServletRequest request = getRequest();
|
||||
String uri = request.getRequestURI();
|
||||
if (StringUtils.endsWithIgnoreCase(uri, ".xml") || StringUtils
|
||||
.equalsIgnoreCase(request.getParameter("__ajax"), "xml")){
|
||||
String uri = request.getRequestURI(); initWebViewConfig();
|
||||
if ((favorPathExtension && StringUtils.endsWithIgnoreCase(uri, ".xml"))
|
||||
|| (favorParameter && StringUtils.equalsIgnoreCase(request.getParameter("__ajax"), "xml"))){
|
||||
return renderString(response, XmlMapper.toXml(object));
|
||||
}
|
||||
if (ObjectUtils.toBoolean(PropertiesUtils.getInstance().getProperty("web.jsonp.enabled"))) {
|
||||
if (jsonp) {
|
||||
String functionName = request.getParameter("__callback");
|
||||
if (StringUtils.isNotBlank(functionName)){
|
||||
object = new JSONPObject(functionName, object);
|
||||
@@ -362,7 +388,9 @@ public class ServletUtils {
|
||||
type = MediaType.TEXT_PLAIN_VALUE;
|
||||
}
|
||||
}
|
||||
response.setContentType(type);
|
||||
if (type != null) {
|
||||
response.setContentType(type);
|
||||
}
|
||||
response.getWriter().print(string);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
|
||||
@@ -45,7 +45,7 @@ a, a:hover, a:active, a:focus, .form-unit, th[aria-selected=true] .ui-jqgrid-sor
|
||||
}
|
||||
}
|
||||
.main-header .logo {
|
||||
background-color: #1890ff;
|
||||
background-color: transparent;
|
||||
color: #ffffff;
|
||||
border-bottom: 0 solid transparent;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,12 @@ a, a:hover, a:active, a:focus, .form-unit, th[aria-selected=true] .ui-jqgrid-sor
|
||||
color:#1e5edb;
|
||||
}
|
||||
.main-header .navbar {
|
||||
background-color: #1951be;
|
||||
background: #1951be;
|
||||
background: -webkit-gradient(linear, left bottom, right top, color-stop(0, #1951be), color-stop(1, #2780ec));
|
||||
background: -ms-linear-gradient(left, #1951be, #2780ec);
|
||||
background: -moz-linear-gradient(left top, #1951be 0%, #2780ec 100%);
|
||||
background: -o-linear-gradient(#2780ec, #1951be);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(GradientType = 1,startColorstr='#2780ec', endColorstr='#1951be');
|
||||
}
|
||||
.main-header .navbar .nav > li > a {
|
||||
color: #ffffff;
|
||||
@@ -45,7 +50,7 @@ a, a:hover, a:active, a:focus, .form-unit, th[aria-selected=true] .ui-jqgrid-sor
|
||||
}
|
||||
}
|
||||
.main-header .logo {
|
||||
background-color: #1951be;
|
||||
background-color: transparent;
|
||||
color: #ffffff;
|
||||
border-bottom: 0 solid transparent;
|
||||
}
|
||||
|
||||
@@ -1647,8 +1647,8 @@
|
||||
} else {
|
||||
if(lay(btn).hasClass(DISABLED)) return that.hint('不在有效日期或时间范围内');
|
||||
}
|
||||
that.done();
|
||||
that.setValue(that.parse()).remove()
|
||||
that.done();
|
||||
}
|
||||
};
|
||||
active[type] && active[type]();
|
||||
|
||||
@@ -307,7 +307,7 @@ Class.pt.creat = function(){
|
||||
// + config.content[0] + '"></iframe>';
|
||||
// 2017-5-13 ThinkGem 支持post方式提交iframe
|
||||
config.content = '<iframe scrolling="'+ (config.content[1]||'auto') +'" allowtransparency="true" id="'
|
||||
+ doms[4] +''+ times +'" name="'+ doms[4] +''+ times
|
||||
+ doms[4] + times +'" name="'+ doms[4] +''+ times
|
||||
+ '" onload="this.className=\'\';" class="layui-layer-load" frameborder="0"></iframe><form id="'
|
||||
+ doms[4] + '-form' + times+'" action="' + config.content[0] + '" method="post" target="'
|
||||
+ doms[4] + '' + times +'"></form>';
|
||||
@@ -357,7 +357,12 @@ Class.pt.creat = function(){
|
||||
// 2017-5-13 ThinkGem 支持post方式提交iframe
|
||||
if (config.type == 2){
|
||||
if (config.method == 'GET' || config.method == 'get'){
|
||||
that.layero.find('iframe').attr('src', content[0]);
|
||||
var iframeSrc = content[0] || '', formData = config.contentFormData;
|
||||
for(var key in formData || {}){
|
||||
iframeSrc += iframeSrc.indexOf('?') == -1 ? '?' : '&';
|
||||
iframeSrc += key + '=' + formData[key];
|
||||
}
|
||||
that.layero.find('#' + doms[4] + times).attr('src', iframeSrc);
|
||||
}else{
|
||||
var form = that.layero.find('#' + doms[4] + '-form' + times), formData = config.contentFormData;
|
||||
for(var key in formData || {}){
|
||||
|
||||
15
modules/core/bin/deploy.sh
Normal file
15
modules/core/bin/deploy.sh
Normal file
@@ -0,0 +1,15 @@
|
||||
#!/bin/sh
|
||||
# /**
|
||||
# * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
# *
|
||||
# * Author: ThinkGem@163.com
|
||||
# *
|
||||
# */
|
||||
echo ""
|
||||
echo "[信息] 部署工程版本到Nexus服务器。"
|
||||
echo ""
|
||||
|
||||
cd ..
|
||||
mvn clean deploy -Dmaven.test.skip=true -Pdeploy
|
||||
|
||||
cd bin
|
||||
@@ -1,18 +0,0 @@
|
||||
@echo off
|
||||
rem /**
|
||||
rem * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
rem *
|
||||
rem * Author: ThinkGem@163.com
|
||||
rem */
|
||||
echo.
|
||||
echo [<5B><>Ϣ] <20><><EFBFBD>빤<EFBFBD><EBB9A4>Javadoc<6F><63><EFBFBD><EFBFBD><EFBFBD><EFBFBD>jar<61><72><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>
|
||||
echo.
|
||||
|
||||
%~d0
|
||||
cd %~dp0
|
||||
|
||||
cd ..
|
||||
call mvn clean package -Pjavadoc
|
||||
|
||||
cd bin
|
||||
pause
|
||||
15
modules/core/bin/package.sh
Normal file
15
modules/core/bin/package.sh
Normal file
@@ -0,0 +1,15 @@
|
||||
#!/bin/sh
|
||||
# /**
|
||||
# * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
# *
|
||||
# * Author: ThinkGem@163.com
|
||||
# *
|
||||
# */
|
||||
echo ""
|
||||
echo "[信息] 打包Web工程,生成war/jar包文件。"
|
||||
echo ""
|
||||
|
||||
cd ..
|
||||
mvn clean install -Dmaven.test.skip=true -Ppackage
|
||||
|
||||
cd bin
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>com.jeesite</groupId>
|
||||
<artifactId>jeesite-parent</artifactId>
|
||||
<version>4.2.0-SNAPSHOT</version>
|
||||
<version>4.2.2-SNAPSHOT</version>
|
||||
<relativePath>../../parent/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
@@ -3,44 +3,34 @@
|
||||
*/
|
||||
package com.jeesite.common.shiro.filter;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.shiro.authc.AuthenticationException;
|
||||
import org.apache.shiro.authc.AuthenticationToken;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
import org.apache.shiro.web.util.WebUtils;
|
||||
|
||||
import com.jeesite.common.lang.ExceptionUtils;
|
||||
import com.jeesite.common.lang.StringUtils;
|
||||
import com.jeesite.common.shiro.realm.CasAuthorizingRealm;
|
||||
import com.jeesite.common.shiro.realm.LoginInfo;
|
||||
|
||||
/**
|
||||
* CAS过滤器
|
||||
* @author ThinkGem
|
||||
* @version 2018-7-11
|
||||
* @version 2020-9-19
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class CasAuthenticationFilter extends org.apache.shiro.cas.CasFilter {
|
||||
|
||||
private CasAuthorizingRealm authorizingRealm; // 安全认证类
|
||||
|
||||
/**
|
||||
* 登录成功调用事件
|
||||
*/
|
||||
@Override
|
||||
protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request, ServletResponse response) throws Exception {
|
||||
|
||||
// 登录成功后初始化授权信息并处理登录后的操作
|
||||
authorizingRealm.onLoginSuccess((LoginInfo)subject.getPrincipal(), (HttpServletRequest)request);
|
||||
|
||||
// AJAX不支持Redirect改用Forward
|
||||
request.getRequestDispatcher(getSuccessUrl()).forward(request, response);
|
||||
return false;
|
||||
return FormAuthenticationFilter.onLoginSuccess((HttpServletRequest)request, (HttpServletResponse)response);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -59,15 +49,15 @@ public class CasAuthenticationFilter extends org.apache.shiro.cas.CasFilter {
|
||||
return false;
|
||||
} else {
|
||||
try {
|
||||
if (ae != null && StringUtils.startsWith(ae.getMessage(), "msg:")){
|
||||
String message = ExceptionUtils.getExceptionMessage(ae);
|
||||
if (StringUtils.isNotBlank(message)){
|
||||
request.setAttribute("exception", ae);
|
||||
request.setAttribute("message", message);
|
||||
request.getRequestDispatcher("/error/403").forward(request, response);
|
||||
}else{
|
||||
WebUtils.issueRedirect(request, response, getLoginUrl());
|
||||
}
|
||||
} catch (ServletException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
@@ -75,7 +65,7 @@ public class CasAuthenticationFilter extends org.apache.shiro.cas.CasFilter {
|
||||
}
|
||||
|
||||
public void setAuthorizingRealm(CasAuthorizingRealm authorizingRealm) {
|
||||
this.authorizingRealm = authorizingRealm;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -34,7 +34,6 @@ import com.jeesite.common.lang.StringUtils;
|
||||
import com.jeesite.common.network.IpUtils;
|
||||
import com.jeesite.common.shiro.authc.FormToken;
|
||||
import com.jeesite.common.shiro.realm.BaseAuthorizingRealm;
|
||||
import com.jeesite.common.shiro.realm.LoginInfo;
|
||||
import com.jeesite.common.web.CookieUtils;
|
||||
import com.jeesite.common.web.http.ServletUtils;
|
||||
import com.jeesite.modules.sys.entity.Log;
|
||||
@@ -45,20 +44,20 @@ import com.jeesite.modules.sys.utils.UserUtils;
|
||||
/**
|
||||
* 表单验证(包含验证码)过滤类
|
||||
* @author ThinkGem
|
||||
* @version 2020-4-13
|
||||
* @version 2020-9-19
|
||||
*/
|
||||
public class FormAuthenticationFilter extends org.apache.shiro.web.filter.authc.FormAuthenticationFilter {
|
||||
|
||||
public static final String CAPTCHA_PARAM = "validCode"; // 验证码
|
||||
public static final String MESSAGE_PARAM = "message"; // 登录返回消息
|
||||
public static final String REMEMBER_USERCODE_PARAM = "rememberUserCode"; // 记住用户名
|
||||
public static final String EXCEPTION_ATTRIBUTE_NAME = "exception"; // 异常类属性名
|
||||
public static final String CAPTCHA_PARAM = "validCode"; // 验证码
|
||||
public static final String MESSAGE_PARAM = "message"; // 登录返回消息
|
||||
public static final String REMEMBER_USERCODE_PARAM = "rememberUserCode"; // 记住用户名
|
||||
public static final String EXCEPTION_ATTRIBUTE_NAME = "exception"; // 异常类属性名
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(FormAuthenticationFilter.class);
|
||||
|
||||
private BaseAuthorizingRealm authorizingRealm; // 安全认证类
|
||||
private static FormAuthenticationFilter instance;
|
||||
|
||||
private Cookie rememberUserCodeCookie; // 记住用户名Cookie
|
||||
private BaseAuthorizingRealm authorizingRealm;
|
||||
private Cookie rememberUserCodeCookie; // 记住用户名Cookie
|
||||
|
||||
/**
|
||||
* 构造方法
|
||||
@@ -68,8 +67,16 @@ public class FormAuthenticationFilter extends org.apache.shiro.web.filter.authc.
|
||||
rememberUserCodeCookie = new SimpleCookie(REMEMBER_USERCODE_PARAM);
|
||||
rememberUserCodeCookie.setHttpOnly(true);
|
||||
rememberUserCodeCookie.setMaxAge(Cookie.ONE_YEAR);
|
||||
instance = this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建登录授权令牌
|
||||
*/
|
||||
public static FormToken newToken(HttpServletRequest request, HttpServletResponse response) {
|
||||
return (FormToken)instance.createToken(request, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建登录授权令牌
|
||||
*/
|
||||
@@ -94,13 +101,13 @@ public class FormAuthenticationFilter extends org.apache.shiro.web.filter.authc.
|
||||
}
|
||||
// 登录用户名解密(解决登录用户名明文传输安全问题)
|
||||
String secretKey = Global.getProperty("shiro.loginSubmit.secretKey");
|
||||
if (StringUtils.isNotBlank(secretKey)){
|
||||
if (StringUtils.isNotBlank(username) && StringUtils.isNotBlank(secretKey)){
|
||||
username = DesUtils.decode(username, secretKey);
|
||||
if (StringUtils.isBlank(username)){
|
||||
logger.info("登录账号为空或解码错误.");
|
||||
}
|
||||
}
|
||||
// 登录成功后,判断是否需要记住用户名
|
||||
// 登录时判断是否需要记住用户名
|
||||
if (WebUtils.isTrue(request, REMEMBER_USERCODE_PARAM)) {
|
||||
rememberUserCodeCookie.setValue(EncodeUtils.encodeUrl(EncodeUtils.xssFilter(username)));
|
||||
rememberUserCodeCookie.saveTo((HttpServletRequest)request, (HttpServletResponse)response);
|
||||
@@ -121,7 +128,7 @@ public class FormAuthenticationFilter extends org.apache.shiro.web.filter.authc.
|
||||
}
|
||||
// 登录密码解密(解决登录密码明文传输安全问题)
|
||||
String secretKey = Global.getProperty("shiro.loginSubmit.secretKey");
|
||||
if (StringUtils.isNotBlank(secretKey)){
|
||||
if (StringUtils.isNotBlank(password) && StringUtils.isNotBlank(secretKey)){
|
||||
password = DesUtils.decode(password, secretKey);
|
||||
if (StringUtils.isBlank(password)){
|
||||
logger.info("登录密码为空或解码错误.");
|
||||
@@ -160,7 +167,7 @@ public class FormAuthenticationFilter extends org.apache.shiro.web.filter.authc.
|
||||
}
|
||||
// 登录用户名解密(解决登录用户名明文传输安全问题)
|
||||
String secretKey = Global.getProperty("shiro.loginSubmit.secretKey");
|
||||
if (StringUtils.isNotBlank(secretKey)){
|
||||
if (StringUtils.isNotBlank(captcha) && StringUtils.isNotBlank(secretKey)){
|
||||
captcha = DesUtils.decode(captcha, secretKey);
|
||||
}
|
||||
return captcha;
|
||||
@@ -241,30 +248,51 @@ public class FormAuthenticationFilter extends org.apache.shiro.web.filter.authc.
|
||||
return super.executeLogin(request, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 登录成功调用事件(静态方便其他位置调用)
|
||||
*/
|
||||
public static boolean onLoginSuccess(HttpServletRequest request, HttpServletResponse response) {
|
||||
try {
|
||||
return instance.onLoginSuccess(null, null, request, response);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 登录成功调用事件
|
||||
*/
|
||||
@Override
|
||||
protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request, ServletResponse response) throws Exception {
|
||||
|
||||
// 登录成功后初始化授权信息并处理登录后的操作
|
||||
authorizingRealm.onLoginSuccess((LoginInfo)subject.getPrincipal(), (HttpServletRequest) request);
|
||||
|
||||
authorizingRealm.onLoginSuccess(UserUtils.getLoginInfo(), (HttpServletRequest)request);
|
||||
// AJAX不支持Redirect改用Forward
|
||||
request.getRequestDispatcher(getSuccessUrl()).forward(request, response);
|
||||
try {
|
||||
request.getRequestDispatcher(getSuccessUrl()).forward(request, response);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 登录失败调用事件(静态方便其他位置调用)
|
||||
*/
|
||||
public static boolean onLoginFailure(AuthenticationException e, HttpServletRequest request, HttpServletResponse response) {
|
||||
return instance.onLoginFailure(null, e, request, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 登录失败调用事件
|
||||
*/
|
||||
@Override
|
||||
protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e, ServletRequest request, ServletResponse response) {
|
||||
String message = StringUtils.EMPTY;
|
||||
if (e instanceof IncorrectCredentialsException || e instanceof UnknownAccountException) {
|
||||
message = Global.getText("sys.login.failure");
|
||||
} else if (e.getMessage() != null && StringUtils.startsWith(e.getMessage(), "msg:")) {
|
||||
if (e.getMessage() != null && StringUtils.startsWith(e.getMessage(), "msg:")) {
|
||||
message = StringUtils.replace(e.getMessage(), "msg:", "");
|
||||
} else if (e instanceof IncorrectCredentialsException || e instanceof UnknownAccountException) {
|
||||
message = Global.getText("sys.login.failure");
|
||||
} else {
|
||||
message = Global.getText("sys.login.error");
|
||||
logger.error(message, e); // 输出到日志文件
|
||||
@@ -272,20 +300,20 @@ public class FormAuthenticationFilter extends org.apache.shiro.web.filter.authc.
|
||||
request.setAttribute(EXCEPTION_ATTRIBUTE_NAME, e);
|
||||
request.setAttribute(MESSAGE_PARAM, message);
|
||||
|
||||
// 登录操作如果是Ajax操作,直接返回登录信息字符串。
|
||||
if (ServletUtils.isAjaxRequest(((HttpServletRequest) request))){
|
||||
Map<String, Object> data = getLoginFailureData(((HttpServletRequest) request), ((HttpServletResponse) response));
|
||||
ServletUtils.renderResult(((HttpServletResponse) response), Global.TRUE, message, data);
|
||||
return false;
|
||||
// AJAX不支持Redirect改用Forward
|
||||
try {
|
||||
String loginFailureUrl = Global.getProperty("adminPath")+"/loginFailure";
|
||||
request.getRequestDispatcher(loginFailureUrl).forward(request, response);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setAuthorizingRealm(BaseAuthorizingRealm authorizingRealm) {
|
||||
this.authorizingRealm = authorizingRealm;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取登录页面数据
|
||||
* @author ThinkGem
|
||||
*/
|
||||
public static Map<String, Object> getLoginData(HttpServletRequest request, HttpServletResponse response) {
|
||||
Map<String, Object> data = MapUtils.newHashMap();
|
||||
|
||||
@@ -294,7 +322,7 @@ public class FormAuthenticationFilter extends org.apache.shiro.web.filter.authc.
|
||||
for (Entry<String, Object> entry : paramMap.entrySet()){
|
||||
data.put(ServletUtils.EXT_PARAMS_PREFIX + entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
|
||||
// 如果已登录,再次访问主页,则退出原账号。
|
||||
if (!Global.TRUE.equals(Global.getConfig("shiro.isAllowRefreshIndex"))){
|
||||
CookieUtils.setCookie(response, "LOGINED", "false");
|
||||
@@ -316,6 +344,10 @@ public class FormAuthenticationFilter extends org.apache.shiro.web.filter.authc.
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取登录失败数据
|
||||
* @author ThinkGem
|
||||
*/
|
||||
public static Map<String, Object> getLoginFailureData(HttpServletRequest request, HttpServletResponse response) {
|
||||
Map<String, Object> data = MapUtils.newHashMap();
|
||||
|
||||
@@ -362,4 +394,9 @@ public class FormAuthenticationFilter extends org.apache.shiro.web.filter.authc.
|
||||
data.put("result", Global.FALSE);
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setAuthorizingRealm(BaseAuthorizingRealm authorizingRealm) {
|
||||
this.authorizingRealm = authorizingRealm;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -38,16 +38,17 @@ public class LogoutFilter extends org.apache.shiro.web.filter.authc.LogoutFilter
|
||||
try {
|
||||
Object principal = subject.getPrincipal();
|
||||
if (principal != null){
|
||||
// // 记录用户退出日志(@Deprecated v4.0.5支持setAuthorizingRealm,之后版本可删除此if子句)
|
||||
// if (authorizingRealm == null){
|
||||
// LogUtils.saveLog(UserUtils.getUser(), ServletUtils.getRequest(),
|
||||
// "系统退出", Log.TYPE_LOGIN_LOGOUT);
|
||||
// }
|
||||
// else{
|
||||
// 退出成功之前初始化授权信息并处理登录后的操作
|
||||
authorizingRealm.onLogoutSuccess((LoginInfo)subject.getPrincipal(),
|
||||
(HttpServletRequest)request);
|
||||
// }
|
||||
LoginInfo loginInfo = (LoginInfo)principal;
|
||||
|
||||
// 退出成功之前调用退出事件,方便记录日志等相关销毁工作
|
||||
authorizingRealm.onLogoutSuccess(loginInfo, (HttpServletRequest)request);
|
||||
|
||||
// 设定了用户类型的登录页面,则退出到对应用户类型的登录页面
|
||||
String userType = loginInfo.getParam("userType");
|
||||
if(StringUtils.isNotBlank(userType)){
|
||||
redirectUrl += StringUtils.contains(redirectUrl, "?") ? "&" : "?";
|
||||
redirectUrl += "param_userType=" + userType;
|
||||
}
|
||||
}
|
||||
// 退出登录
|
||||
subject.logout();
|
||||
|
||||
@@ -38,7 +38,7 @@ import com.jeesite.modules.sys.utils.UserUtils;
|
||||
/**
|
||||
* 系统安全认证实现类
|
||||
* @author ThinkGem
|
||||
* @version 2018-7-11
|
||||
* @version 2020-9-19
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class CasAuthorizingRealm extends BaseAuthorizingRealm {
|
||||
@@ -92,7 +92,7 @@ public class CasAuthorizingRealm extends BaseAuthorizingRealm {
|
||||
casToken.setUserId(casPrincipal.getName());
|
||||
|
||||
// 生成登录信息对象
|
||||
FormToken token = new FormToken();
|
||||
FormToken token = new FormToken(request);
|
||||
token.setUsername(casPrincipal.getName());
|
||||
Map<String, Object> params = MapUtils.newHashMap();
|
||||
params.putAll(casPrincipal.getAttributes());
|
||||
|
||||
@@ -11,9 +11,10 @@ import com.jeesite.modules.sys.entity.Employee;
|
||||
* 员工管理DAO接口
|
||||
* @author ThinkGem
|
||||
* @version 2017-03-25
|
||||
* 通过 UserUtils.loadRefObj() 加载引用类型对象时,需要给MyBatisDao指定引用entity类型。
|
||||
* 通过 user.getRefObj() 获取引用对象时,需要给 \@MyBatisDao 指定引用 entity 类型。
|
||||
* 但是,在 4.2.0+ 版本中,新增了 userTypeMap 指定 service,所以无需设置 entity 类型。
|
||||
*/
|
||||
@MyBatisDao(entity=Employee.class)
|
||||
@MyBatisDao(entity = Employee.class)
|
||||
public interface EmployeeDao extends CrudDao<Employee> {
|
||||
|
||||
}
|
||||
@@ -36,7 +36,7 @@ import com.jeesite.common.utils.excel.fieldtype.OfficeType;
|
||||
@Column(name="emp_no", attrName="empNo", label="员工工号"),
|
||||
@Column(name="emp_name", attrName="empName", label="员工姓名", queryType=QueryType.LIKE),
|
||||
@Column(name="emp_name_en", attrName="empNameEn", label="英文名", queryType=QueryType.LIKE),
|
||||
}),
|
||||
}),
|
||||
@JoinTable(type=Type.LEFT_JOIN, entity=Office.class, alias="o",
|
||||
on="o.office_code=e.office_code", attrName="employee.office",
|
||||
columns={
|
||||
@@ -52,7 +52,7 @@ import com.jeesite.common.utils.excel.fieldtype.OfficeType;
|
||||
@Column(name="address", label="联系地址"),
|
||||
@Column(name="zip_code", label="邮政编码"),
|
||||
@Column(name="email", label="邮箱"),
|
||||
}),
|
||||
}),
|
||||
@JoinTable(type=Type.LEFT_JOIN, entity=Company.class, alias="c",
|
||||
on="c.company_code=e.company_code", attrName="employee.company",
|
||||
columns={
|
||||
@@ -62,7 +62,7 @@ import com.jeesite.common.utils.excel.fieldtype.OfficeType;
|
||||
@Column(name="view_code", label="公司代码"),
|
||||
@Column(name="company_name", label="公司名称", isQuery=false),
|
||||
@Column(name="full_name", label="公司全称"),
|
||||
}),
|
||||
}),
|
||||
@JoinTable(type=Type.LEFT_JOIN, entity=Area.class, alias="ar",
|
||||
on="ar.area_code = c.area_code", attrName="employee.company.area",
|
||||
columns={
|
||||
@@ -70,6 +70,10 @@ import com.jeesite.common.utils.excel.fieldtype.OfficeType;
|
||||
@Column(name="area_name", label="区域名称", isQuery=false),
|
||||
@Column(name="area_type", label="区域类型"),
|
||||
}),
|
||||
// @JoinTable(type=Type.LEFT_JOIN, entity=User.class, attrName="this", alias="u",
|
||||
// on="u.user_code = a.create_by", columns={
|
||||
// @Column(name="user_name", attrName="createByName", label="用户名称", isQuery=false),
|
||||
// }),
|
||||
},
|
||||
// extFromKeys="dsfOfficeFrom, dsfCompanyFrom",
|
||||
// extWhereKeys="dsfOfficeWhere, dsfCompanyWhere",
|
||||
@@ -107,7 +111,7 @@ public class EmpUser extends User {
|
||||
@ExcelField(title="最后登录", attrName="lastLoginDate", align=Align.CENTER, words=20, sort=900, type=ExcelField.Type.EXPORT),
|
||||
})
|
||||
public Employee getEmployee(){
|
||||
Employee employee = (Employee)super.getRefObj();
|
||||
Employee employee = super.getRefObj();
|
||||
if (employee == null){
|
||||
employee = new Employee(getRefCode());
|
||||
super.setRefObj(employee);
|
||||
|
||||
@@ -54,7 +54,7 @@ public class EmpUtils {
|
||||
*/
|
||||
public static Employee get(User user){
|
||||
if (user != null && User.USER_TYPE_EMPLOYEE.equals(user.getUserType())){
|
||||
return (Employee)user.getRefObj();
|
||||
return user.getRefObj();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
/**
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
*/
|
||||
package com.jeesite.modules.sys.web.user;
|
||||
package com.jeesite.modules.sys.web;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.shiro.authc.AuthenticationException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.stereotype.Controller;
|
||||
@@ -17,12 +19,15 @@ import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import com.jeesite.common.codec.DesUtils;
|
||||
import com.jeesite.common.collect.MapUtils;
|
||||
import com.jeesite.common.config.Global;
|
||||
import com.jeesite.common.lang.StringUtils;
|
||||
import com.jeesite.common.msg.EmailUtils;
|
||||
import com.jeesite.common.msg.SmsUtils;
|
||||
import com.jeesite.common.service.ServiceException;
|
||||
import com.jeesite.common.shiro.authc.FormToken;
|
||||
import com.jeesite.common.shiro.filter.FormAuthenticationFilter;
|
||||
import com.jeesite.common.web.BaseController;
|
||||
import com.jeesite.modules.sys.entity.User;
|
||||
import com.jeesite.modules.sys.service.UserService;
|
||||
@@ -38,28 +43,77 @@ import io.swagger.annotations.ApiOperation;
|
||||
/**
|
||||
* 账号自助服务Controller
|
||||
* @author ThinkGem
|
||||
* @version 2017-12-7
|
||||
* @version 2020-9-20
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping(value = "/account")
|
||||
@ConditionalOnProperty(name="web.core.enabled", havingValue="true", matchIfMissing=true)
|
||||
@Api(tags = "Account / 账号自助服务、找回密码、账号注册")
|
||||
@Api(tags = "Account / 账号服务:验证码登录、找回密码、账号注册")
|
||||
public class AccountController extends BaseController{
|
||||
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
|
||||
/**
|
||||
* 获取登录短信或邮件验证码
|
||||
* @param validCode 图片验证码,防止重复机器人。
|
||||
* @param validType 验证方式:mobile、email
|
||||
* @author ThinkGem
|
||||
*/
|
||||
@PostMapping(value = "getLoginValidCode")
|
||||
@ResponseBody
|
||||
@ApiOperation(value = "获取登录的短信或邮件验证码")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "username", value = "登录账号", required = true, paramType="query", type="String"),
|
||||
@ApiImplicitParam(name = "validCode", value = "图片验证码,防止重复机器人", required = true),
|
||||
@ApiImplicitParam(name = "validType", value = "验证方式(mobile、email)", required = true),
|
||||
})
|
||||
public String getLoginValidCode(String username, String validCode, String validType, HttpServletRequest request) {
|
||||
return getValidCode("login", username, validCode, validType, request, "登录验证码");
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据短信或邮件验证码登录系统
|
||||
* @author ThinkGem
|
||||
*/
|
||||
@PostMapping(value = "loginByValidCode")
|
||||
@ResponseBody
|
||||
@ApiOperation(value = "根据短信或邮件验证码登录系统")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "username", value = "登录账号", required = true, paramType="query", type="String"),
|
||||
@ApiImplicitParam(name = "loginValidCode", value = "手机或邮箱接受的验证码", required = true),
|
||||
})
|
||||
public String loginByValidCode(String username, String loginValidCode, HttpServletRequest request, HttpServletResponse response) {
|
||||
if (!Global.getConfigToBoolean("user.loginByValidCode", "true")) {
|
||||
return renderResult(Global.FALSE, "验证码登录未开启,请设置:user.loginByValidCode=true");
|
||||
}
|
||||
FormToken formToken = FormAuthenticationFilter.newToken(request, response);
|
||||
String s = validValidCode("login", formToken.getUsername(), loginValidCode, request);
|
||||
if (s != null) {
|
||||
return s;
|
||||
}
|
||||
// 登录系统
|
||||
try {
|
||||
formToken.setInnerLogin(true); // 因为手机验证码已验证,所以无需再进行验证密码
|
||||
UserUtils.getSubject().login(formToken);
|
||||
FormAuthenticationFilter.onLoginSuccess(request, response);
|
||||
} catch (AuthenticationException e) {
|
||||
FormAuthenticationFilter.onLoginFailure(e, request, response);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 忘记密码页面
|
||||
*/
|
||||
@GetMapping(value = "forgetPwd")
|
||||
@ApiOperation(value = "忘记密码页面")
|
||||
public String forgetPwd(Model model) {
|
||||
return "modules/sys/account/forgetPwd";
|
||||
return "modules/sys/forgetPwd";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取找回密码短信、邮件验证码
|
||||
* 获取找回密码短信或邮件验证码
|
||||
* @param validCode 图片验证码,防止重复机器人。
|
||||
* @param validType 验证方式:mobile、email
|
||||
*/
|
||||
@@ -72,41 +126,7 @@ public class AccountController extends BaseController{
|
||||
@ApiImplicitParam(name = "validType", value = "验证方式(mobile、email)", required = true),
|
||||
})
|
||||
public String getFpValidCode(User user, String validCode, String validType, HttpServletRequest request) {
|
||||
// 校验图片验证码,防止重复机器人。
|
||||
if (!ValidCodeUtils.validate(request, validCode)){
|
||||
return renderResult(Global.FALSE, text("图片验证码不正确或已失效,请点击图片刷新!"));
|
||||
}
|
||||
if (!"mobile".equals(validType) && !"email".equals(validType)){
|
||||
return renderResult(Global.FALSE, text("非法操作。"));
|
||||
}
|
||||
User u = UserUtils.getByLoginCode(user.getLoginCode());
|
||||
if(u == null){
|
||||
return renderResult(Global.FALSE, text("登录账号不正确!"));
|
||||
}
|
||||
if("mobile".equals(validType) && StringUtils.isBlank(u.getMobile())){
|
||||
return renderResult(Global.FALSE, text("该账号未设置手机号码!"));
|
||||
}else if("email".equals(validType) && StringUtils.isBlank(u.getEmail())){
|
||||
return renderResult(Global.FALSE, text("该账号未设置邮件地址!"));
|
||||
}
|
||||
// 操作是否频繁验证, 如果离上次获取验证码小于20秒,则提示操作频繁。
|
||||
Date date = (Date)UserUtils.getCache("fpLastDate");
|
||||
if (date != null && (System.currentTimeMillis()-date.getTime())/(1000L) < 20L){
|
||||
return renderResult(Global.FALSE, text("您当前操作太频繁,请稍等一会再操作!"));
|
||||
}else{
|
||||
UserUtils.putCache("fpLastDate", new Date());
|
||||
}
|
||||
// 生成验证码,并缓存。
|
||||
String fpValidCode = StringUtils.getRandomNum(6);
|
||||
UserUtils.putCache("fpUserCode", u.getUserCode());
|
||||
UserUtils.putCache("fpLoginCode", u.getLoginCode());
|
||||
UserUtils.putCache("fpValidCode", fpValidCode);
|
||||
// 发送邮箱或短信验证码
|
||||
if("mobile".equals(validType)){
|
||||
return sendSmsValidCode(u, fpValidCode, text("找回密码"));
|
||||
}else if("email".equals(validType)){
|
||||
return sendEmailValidCode(u, fpValidCode, text("找回密码"));
|
||||
}
|
||||
return null;
|
||||
return getValidCode("fp", user.getLoginCode(), validCode, validType, request, "找回密码");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -121,39 +141,98 @@ public class AccountController extends BaseController{
|
||||
@ApiImplicitParam(name = "password", value = "新密码", required = true, paramType="query", type="String"),
|
||||
})
|
||||
public String savePwdByValidCode(User user, String fpValidCode, HttpServletRequest request) {
|
||||
String userCode = (String)UserUtils.getCache("fpUserCode");
|
||||
String loginCode = (String)UserUtils.getCache("fpLoginCode");
|
||||
String validCode = (String)UserUtils.getCache("fpValidCode");
|
||||
Date date = (Date)UserUtils.getCache("fpLastDate");
|
||||
String userCode = UserUtils.getCache("fp" + "UserCode");
|
||||
String s = validValidCode("fp", user.getLoginCode(), fpValidCode, request);
|
||||
if (s != null) {
|
||||
return s;
|
||||
}
|
||||
String secretKey = Global.getProperty("shiro.loginSubmit.secretKey");
|
||||
if (StringUtils.isNotBlank(secretKey)){
|
||||
user.setPassword(DesUtils.decode(user.getPassword(), secretKey));
|
||||
}
|
||||
// 更新为新密码
|
||||
try{
|
||||
userService.updatePassword(userCode, user.getPassword());
|
||||
}catch(ServiceException se){
|
||||
return renderResult(Global.FALSE, se.getMessage());
|
||||
}
|
||||
return renderResult(Global.TRUE, text("恭喜你,您的账号 {0} 密码找回成功!", user.getLoginCode()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取验证码
|
||||
* @author ThinkGem
|
||||
*/
|
||||
private String getValidCode(String type, String loginCode, String validCode, String validType, HttpServletRequest request, String msgTitle) {
|
||||
// 校验图片验证码,防止重复机器人。
|
||||
if (!ValidCodeUtils.validate(request, validCode)){
|
||||
return renderResult(Global.FALSE, text("图片验证码不正确或已失效,请点击图片刷新!"));
|
||||
}
|
||||
if (!"mobile".equals(validType) && !"email".equals(validType)){
|
||||
return renderResult(Global.FALSE, text("非法操作。"));
|
||||
}
|
||||
User u = UserUtils.getByLoginCode(loginCode);
|
||||
if(u == null){
|
||||
return renderResult(Global.FALSE, text("登录账号不正确!"));
|
||||
}
|
||||
if("mobile".equals(validType) && StringUtils.isBlank(u.getMobile())){
|
||||
return renderResult(Global.FALSE, text("该账号未设置手机号码!"));
|
||||
}else if("email".equals(validType) && StringUtils.isBlank(u.getEmail())){
|
||||
return renderResult(Global.FALSE, text("该账号未设置邮件地址!"));
|
||||
}
|
||||
// 操作是否频繁验证, 如果离上次获取验证码小于20秒,则提示操作频繁。
|
||||
Date date = (Date)UserUtils.getCache(type + "LastDate");
|
||||
if (date != null && (System.currentTimeMillis()-date.getTime())/(1000L) < 20L){
|
||||
return renderResult(Global.FALSE, text("您当前操作太频繁,请稍等一会再操作!"));
|
||||
}else{
|
||||
UserUtils.putCache(type + "LastDate", new Date());
|
||||
}
|
||||
// 生成验证码,并缓存。
|
||||
String loginValidCode = StringUtils.getRandomNum(6);
|
||||
UserUtils.putCache(type + "UserCode", u.getUserCode());
|
||||
UserUtils.putCache(type + "LoginCode", u.getLoginCode());
|
||||
UserUtils.putCache(type + "ValidCode", loginValidCode);
|
||||
// 发送邮箱或短信验证码
|
||||
if("mobile".equals(validType)){
|
||||
return sendSmsValidCode(u, loginValidCode, text(msgTitle));
|
||||
}else if("email".equals(validType)){
|
||||
return sendEmailValidCode(u, loginValidCode, text(msgTitle));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证验证码
|
||||
* @author ThinkGem
|
||||
*/
|
||||
private String validValidCode(String type, String loginCode, String loginValidCode, HttpServletRequest request) {
|
||||
String userCode = UserUtils.getCache(type + "UserCode");
|
||||
String loginCode2 = UserUtils.getCache(type + "LoginCode");
|
||||
String validCode = UserUtils.getCache(type + "ValidCode");
|
||||
Date date = (Date)UserUtils.getCache(type + "LastDate");
|
||||
|
||||
// 一同验证保存的用户名和验证码是否正确(如果只校验验证码,不验证用户名,则会有获取验证码后修改用户名的漏洞)
|
||||
if (!(userCode != null && loginCode != null && loginCode.equals(user.getLoginCode()))){
|
||||
if (!(userCode != null && loginCode != null && loginCode.equals(loginCode2))){
|
||||
return renderResult(Global.FALSE, text("请重新获取验证码!"));
|
||||
}
|
||||
|
||||
// 清理验证码,验证码只允许使用一次。
|
||||
UserUtils.removeCache("fpUserCode");
|
||||
UserUtils.removeCache("fpLoginCode");
|
||||
UserUtils.removeCache("fpValidCode");
|
||||
UserUtils.removeCache("fpLastDate");
|
||||
|
||||
// 验证码是否超时
|
||||
boolean isTimeout = true;
|
||||
String validTime = Global.getConfig("sys.account.validCodeTimeout", "10"); //验证码有效时间(单位分钟,0表示不限制,默认值10)
|
||||
if("0".equals(validTime) || (date != null && (System.currentTimeMillis()-date.getTime())/(1000L) < 60*Long.parseLong(validTime))){
|
||||
isTimeout = false;
|
||||
}
|
||||
if (!(validCode != null && validCode.equals(fpValidCode) && !isTimeout)){
|
||||
if (!(validCode != null && validCode.equals(loginValidCode) && !isTimeout)){
|
||||
return renderResult(Global.FALSE, text("验证码不正确或已失效,请重新获取验证码!"));
|
||||
}
|
||||
|
||||
// 更新为新密码。
|
||||
try{
|
||||
userService.updatePassword(userCode, user.getPassword());
|
||||
}catch(ServiceException se){
|
||||
return renderResult(Global.FALSE, se.getMessage());
|
||||
}
|
||||
return renderResult(Global.TRUE, text("恭喜你,您的账号 {0} 密码修改成功!", loginCode));
|
||||
// 验证成功后,清理缓存
|
||||
UserUtils.removeCache(type + "UserCode");
|
||||
UserUtils.removeCache(type + "LoginCode");
|
||||
UserUtils.removeCache(type + "ValidCode");
|
||||
UserUtils.removeCache(type + "LastDate");
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -217,17 +296,21 @@ public class AccountController extends BaseController{
|
||||
@ApiImplicitParam(name = "password", value = "新密码", required = true, paramType="query", type="String"),
|
||||
})
|
||||
public String savePwdByPwdQuestion(User user, HttpServletRequest request) {
|
||||
String userCode = (String)UserUtils.getCache("fpUserCode");
|
||||
String loginCode = (String)UserUtils.getCache("fpLoginCode");
|
||||
String userCode = UserUtils.getCache("fpUserCode");
|
||||
String loginCode = UserUtils.getCache("fpLoginCode");
|
||||
|
||||
// 一同验证保存的用户名和验证码是否正确(如果只校验验证码,不验证用户名,则会有获取验证码后修改用户名的漏洞)
|
||||
if (!(userCode != null && loginCode != null && loginCode.equals(user.getLoginCode()))){
|
||||
return renderResult(Global.FALSE, text("请重新获取保密问题!"));
|
||||
}
|
||||
|
||||
// 清理保密问题,每次获取只允许使用一次。
|
||||
UserUtils.removeCache("fpUserCode");
|
||||
UserUtils.removeCache("fpLoginCode");
|
||||
String secretKey = Global.getProperty("shiro.loginSubmit.secretKey");
|
||||
if (StringUtils.isNotBlank(secretKey)){
|
||||
user.setPwdQuestionAnswer(DesUtils.decode(user.getPwdQuestionAnswer(), secretKey));
|
||||
user.setPwdQuestionAnswer2(DesUtils.decode(user.getPwdQuestionAnswer2(), secretKey));
|
||||
user.setPwdQuestionAnswer3(DesUtils.decode(user.getPwdQuestionAnswer3(), secretKey));
|
||||
user.setPassword(DesUtils.decode(user.getPassword(), secretKey));
|
||||
}
|
||||
|
||||
// 验证三个密保问题是否正确。
|
||||
User u = UserUtils.getByLoginCode(user.getLoginCode());
|
||||
@@ -244,7 +327,12 @@ public class AccountController extends BaseController{
|
||||
}catch(ServiceException se){
|
||||
return renderResult(Global.FALSE, se.getMessage());
|
||||
}
|
||||
return renderResult(Global.TRUE, text("验证通过"));
|
||||
|
||||
// 更新密码后,清理缓存
|
||||
UserUtils.removeCache("fpUserCode");
|
||||
UserUtils.removeCache("fpLoginCode");
|
||||
|
||||
return renderResult(Global.TRUE, text("恭喜你,您的账号 {0} 密码找回成功!", user.getLoginCode()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -254,7 +342,7 @@ public class AccountController extends BaseController{
|
||||
@GetMapping(value = "registerUser")
|
||||
@ApiOperation(value = "用户注册页面")
|
||||
public String registerUser(User user, HttpServletRequest request) {
|
||||
return "modules/sys/account/registerUser";
|
||||
return "modules/sys/registerUser";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -352,14 +440,14 @@ public class AccountController extends BaseController{
|
||||
if (!"true".equals(Global.getConfig("sys.account.registerUser"))){
|
||||
return renderResult(Global.FALSE, text("当前系统没有开启注册功能!"));
|
||||
}
|
||||
String corpCode = (String)UserUtils.getCache("regCorpCode");
|
||||
String corpName = (String)UserUtils.getCache("regCorpName");
|
||||
String userType = (String)UserUtils.getCache("regUserType");
|
||||
String loginCode = (String)UserUtils.getCache("regLoginCode");
|
||||
String userName = (String)UserUtils.getCache("regUserName");
|
||||
String email = (String)UserUtils.getCache("regEmail");
|
||||
String mobile = (String)UserUtils.getCache("regMobile");
|
||||
String validCode = (String)UserUtils.getCache("regValidCode");
|
||||
String corpCode = UserUtils.getCache("regCorpCode");
|
||||
String corpName = UserUtils.getCache("regCorpName");
|
||||
String userType = UserUtils.getCache("regUserType");
|
||||
String loginCode = UserUtils.getCache("regLoginCode");
|
||||
String userName = UserUtils.getCache("regUserName");
|
||||
String email = UserUtils.getCache("regEmail");
|
||||
String mobile = UserUtils.getCache("regMobile");
|
||||
String validCode = UserUtils.getCache("regValidCode");
|
||||
Date date = (Date)UserUtils.getCache("regLastDate");
|
||||
|
||||
// 一同验证保存的用户名和验证码是否正确(如果只校验验证码,不验证用户名,则会有获取验证码后修改用户名的漏洞)
|
||||
@@ -391,6 +479,10 @@ public class AccountController extends BaseController{
|
||||
}
|
||||
u.setLoginCode(loginCode);
|
||||
u.setUserName(userName);
|
||||
String secretKey = Global.getProperty("shiro.loginSubmit.secretKey");
|
||||
if (StringUtils.isNotBlank(secretKey)){
|
||||
user.setPassword(DesUtils.decode(user.getPassword(), secretKey));
|
||||
}
|
||||
u.setPassword(user.getPassword());
|
||||
u.setEmail(email);
|
||||
u.setMobile(mobile);
|
||||
@@ -399,7 +491,7 @@ public class AccountController extends BaseController{
|
||||
u.setStatus(User.STATUS_AUDIT); // 待审核状态
|
||||
userService.save(u);
|
||||
|
||||
// 验证成功后清理验证码,验证码只允许使用一次。
|
||||
// 注册用户后,清理缓存
|
||||
UserUtils.removeCache("regCorpCode");
|
||||
UserUtils.removeCache("regCorpName");
|
||||
UserUtils.removeCache("regUserType");
|
||||
@@ -408,7 +500,7 @@ public class AccountController extends BaseController{
|
||||
UserUtils.removeCache("regValidCode");
|
||||
UserUtils.removeCache("regLastDate");
|
||||
|
||||
return renderResult(Global.TRUE, text("恭喜你,您的账号 "+u.getLoginCode()+" 注册成功!"));
|
||||
return renderResult(Global.TRUE, text("恭喜你,您的账号 {0} 注册成功!", u.getLoginCode()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -18,7 +18,6 @@ import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonView;
|
||||
@@ -37,16 +36,16 @@ import com.jeesite.modules.sys.utils.UserUtils;
|
||||
/**
|
||||
* 登录Controller
|
||||
* @author ThinkGem
|
||||
* @version 2020-4-13
|
||||
* @version 2020-9-19
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping(value = "${adminPath}")
|
||||
public class LoginController extends BaseController{
|
||||
|
||||
/**
|
||||
* 管理登录
|
||||
* 登录页面
|
||||
*/
|
||||
@RequestMapping(value = "login", method = RequestMethod.GET)
|
||||
@RequestMapping(value = "login")
|
||||
public String login(HttpServletRequest request, HttpServletResponse response, Model model) {
|
||||
// 地址中如果包含JSESSIONID,则跳转一次,去掉JSESSIONID信息。
|
||||
if (StringUtils.containsIgnoreCase(request.getRequestURI(), ";JSESSIONID=")){
|
||||
@@ -94,9 +93,9 @@ public class LoginController extends BaseController{
|
||||
}
|
||||
|
||||
/**
|
||||
* 登录失败,真正登录的POST请求由Filter完成
|
||||
* 登录失败,返回错误信息
|
||||
*/
|
||||
@RequestMapping(value = "login", method = RequestMethod.POST)
|
||||
@RequestMapping(value = "loginFailure")
|
||||
public String loginFailure(HttpServletRequest request, HttpServletResponse response, Model model) {
|
||||
LoginInfo loginInfo = UserUtils.getLoginInfo();
|
||||
|
||||
@@ -190,7 +189,7 @@ public class LoginController extends BaseController{
|
||||
// 设置共享SessionId的Cookie值(第三方系统使用)
|
||||
String cookieName = Global.getProperty("session.shareSessionIdCookieName");
|
||||
if (StringUtils.isNotBlank(cookieName)){
|
||||
CookieUtils.setCookie((HttpServletResponse)response, cookieName, (String)session.getId());
|
||||
CookieUtils.setCookie(response, cookieName, (String)session.getId(), "/");
|
||||
}
|
||||
// 如果登录设置了语言,则切换语言
|
||||
if (loginInfo.getParam("lang") != null){
|
||||
@@ -200,6 +199,9 @@ public class LoginController extends BaseController{
|
||||
|
||||
// 获取登录成功后跳转的页面
|
||||
String successUrl = request.getParameter("__url");
|
||||
if (StringUtils.isBlank(successUrl)){
|
||||
successUrl = (String)request.getAttribute("__url");
|
||||
}
|
||||
if (StringUtils.isBlank(successUrl)){
|
||||
successUrl = Global.getProperty("shiro.successUrl");
|
||||
}
|
||||
@@ -272,16 +274,16 @@ public class LoginController extends BaseController{
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取侧边栏菜单数据
|
||||
* 侧边栏菜单数据
|
||||
*/
|
||||
@RequiresPermissions("user")
|
||||
@RequestMapping(value = "index/menuTree")
|
||||
public String indexMenuTree(String parentCode) {
|
||||
return "modules/sys/sysIndex/menuTree";
|
||||
return "modules/sys/menuTree";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前用户权限字符串数据(移动端用)
|
||||
* 当前用户权限字符串数据(移动端用)
|
||||
*/
|
||||
@RequiresPermissions("user")
|
||||
@RequestMapping(value = "authInfo")
|
||||
@@ -291,7 +293,7 @@ public class LoginController extends BaseController{
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前用户菜单数据(移动端用)
|
||||
* 当前用户菜单数据(移动端用)
|
||||
*/
|
||||
@RequiresPermissions("user")
|
||||
@RequestMapping(value = "menuTree")
|
||||
@@ -334,7 +336,7 @@ public class LoginController extends BaseController{
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换主题
|
||||
* 切换主题风格
|
||||
*/
|
||||
@RequiresPermissions("user")
|
||||
@RequestMapping(value = "switchSkin/{skinName}")
|
||||
|
||||
@@ -18,6 +18,7 @@ import com.jeesite.common.codec.EncodeUtils;
|
||||
import com.jeesite.common.config.Global;
|
||||
import com.jeesite.common.lang.ObjectUtils;
|
||||
import com.jeesite.common.shiro.authc.FormToken;
|
||||
import com.jeesite.common.shiro.filter.FormAuthenticationFilter;
|
||||
import com.jeesite.common.web.BaseController;
|
||||
import com.jeesite.common.web.http.ServletUtils;
|
||||
import com.jeesite.modules.sys.entity.User;
|
||||
@@ -26,7 +27,7 @@ import com.jeesite.modules.sys.utils.UserUtils;
|
||||
/**
|
||||
* 单点登录Controller
|
||||
* @author ThinkGem
|
||||
* @version 2017-03-25
|
||||
* @version 2020-9-19
|
||||
*/
|
||||
@Controller
|
||||
public class SsoController extends BaseController{
|
||||
@@ -63,24 +64,20 @@ public class SsoController extends BaseController{
|
||||
// 通过令牌登录系统
|
||||
if (token != null){
|
||||
try {
|
||||
FormToken upToken = new FormToken();
|
||||
upToken.setUsername(username); // 登录用户名
|
||||
upToken.setSsoToken(token); // 单点登录令牌
|
||||
upToken.setParams(ServletUtils.getExtParams(request)); // 登录附加参数
|
||||
UserUtils.getSubject().login(upToken);
|
||||
if (ServletUtils.isAjaxRequest(request)){
|
||||
return ServletUtils.renderResult(response, Global.TRUE, text("账号登录成功"));
|
||||
}else{
|
||||
return REDIRECT + EncodeUtils.decodeUrl2(url);
|
||||
}
|
||||
// FormToken 构造方法的三个参数:登录名、单点登录的令牌秘钥、请求对象
|
||||
UserUtils.getSubject().login(new FormToken(username, token, request));
|
||||
request.setAttribute("__url", EncodeUtils.decodeUrl2(url));
|
||||
FormAuthenticationFilter.onLoginSuccess(request, response);
|
||||
} catch (AuthenticationException e) {
|
||||
if (!e.getMessage().startsWith("msg:")){
|
||||
throw new AuthenticationException("msg:登录失败,请联系管理员。", e);
|
||||
}
|
||||
throw e;
|
||||
FormAuthenticationFilter.onLoginFailure(e, request, response);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return "error/403";
|
||||
}
|
||||
|
||||
// public static void main(String[] args) {
|
||||
// System.out.println(UserUtils.getSsoToken("system"));
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
@@ -268,6 +268,7 @@ public class CorpAdminController extends BaseController {
|
||||
if (UserUtils.getUser().isSuperAdmin()){
|
||||
User where = new User();
|
||||
where.setCorpCode_(corpCode);
|
||||
where.setPage(new Page<>(1, 1, -1));
|
||||
List<User> list = userService.findCorpList(where);
|
||||
if (list.size() > 0){
|
||||
User user = list.get(0);
|
||||
|
||||
@@ -11,6 +11,7 @@ import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.shiro.authz.annotation.Logical;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
@@ -24,6 +25,7 @@ import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import com.alibaba.fastjson.JSONValidator;
|
||||
import com.jeesite.common.codec.EncodeUtils;
|
||||
import com.jeesite.common.collect.ListUtils;
|
||||
import com.jeesite.common.collect.MapUtils;
|
||||
@@ -31,7 +33,6 @@ import com.jeesite.common.config.Global;
|
||||
import com.jeesite.common.entity.Page;
|
||||
import com.jeesite.common.lang.DateUtils;
|
||||
import com.jeesite.common.lang.StringUtils;
|
||||
import com.jeesite.common.mapper.JsonMapper;
|
||||
import com.jeesite.common.shiro.realm.AuthorizingRealm;
|
||||
import com.jeesite.common.utils.excel.ExcelExport;
|
||||
import com.jeesite.common.utils.excel.annotation.ExcelField.Type;
|
||||
@@ -73,10 +74,7 @@ public class EmpUserController extends BaseController {
|
||||
|
||||
@ModelAttribute
|
||||
public EmpUser get(String userCode, boolean isNewRecord) {
|
||||
EmpUser empUser = new EmpUser();
|
||||
empUser.setUserCode(userCode);
|
||||
empUser.setIsNewRecord(isNewRecord);
|
||||
return empUserService.getAndValid(empUser);
|
||||
return empUserService.get(userCode, isNewRecord);
|
||||
}
|
||||
|
||||
@RequiresPermissions("sys:empUser:view")
|
||||
@@ -172,12 +170,11 @@ public class EmpUserController extends BaseController {
|
||||
if (!Global.TRUE.equals(checkEmpNo(old != null ? old.getEmployee().getEmpNo() : "", empUser.getEmployee().getEmpNo()))) {
|
||||
return renderResult(Global.FALSE, text("保存用户失败,员工工号''{0}''已存在", empUser.getEmployee().getEmpNo()));
|
||||
}
|
||||
if (StringUtils.inString(op, Global.OP_ADD, Global.OP_EDIT)
|
||||
&& UserUtils.getSubject().isPermitted("sys:empUser:edit")){
|
||||
Subject subject = UserUtils.getSubject();
|
||||
if (StringUtils.inString(op, Global.OP_ADD, Global.OP_EDIT) && subject.isPermitted("sys:empUser:edit")){
|
||||
empUserService.save(empUser);
|
||||
}
|
||||
if (StringUtils.inString(op, Global.OP_ADD, Global.OP_AUTH)
|
||||
&& UserUtils.getSubject().isPermitted("sys:empUser:authRole")){
|
||||
if (StringUtils.inString(op, Global.OP_ADD, Global.OP_AUTH) && subject.isPermitted("sys:empUser:authRole")){
|
||||
userService.saveAuth(empUser);
|
||||
}
|
||||
return renderResult(Global.TRUE, text("保存用户''{0}''成功", empUser.getUserName()));
|
||||
@@ -427,7 +424,7 @@ public class EmpUserController extends BaseController {
|
||||
@RequestMapping(value = "empUserSelect")
|
||||
public String empUserSelect(EmpUser empUser, String selectData, Model model) {
|
||||
String selectDataJson = EncodeUtils.decodeUrl(selectData);
|
||||
if (JsonMapper.fromJson(selectDataJson, Map.class) != null){
|
||||
if (selectDataJson != null && JSONValidator.from(selectDataJson).validate()){
|
||||
model.addAttribute("selectData", selectDataJson);
|
||||
}
|
||||
model.addAttribute("empUser", empUser);
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
*/
|
||||
package com.jeesite.modules.sys.web.user;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
@@ -17,12 +15,12 @@ import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import com.alibaba.fastjson.JSONValidator;
|
||||
import com.jeesite.common.codec.DesUtils;
|
||||
import com.jeesite.common.codec.EncodeUtils;
|
||||
import com.jeesite.common.config.Global;
|
||||
import com.jeesite.common.entity.Page;
|
||||
import com.jeesite.common.lang.StringUtils;
|
||||
import com.jeesite.common.mapper.JsonMapper;
|
||||
import com.jeesite.common.service.ServiceException;
|
||||
import com.jeesite.common.web.BaseController;
|
||||
import com.jeesite.modules.sys.entity.User;
|
||||
@@ -84,7 +82,7 @@ public class UserController extends BaseController {
|
||||
op = "base";
|
||||
}
|
||||
model.addAttribute("op", op);
|
||||
model.addAttribute("user", user.getCurrentUser());
|
||||
model.addAttribute("user", UserUtils.getUser());
|
||||
return "modules/sys/user/userInfo";
|
||||
}
|
||||
|
||||
@@ -202,7 +200,7 @@ public class UserController extends BaseController {
|
||||
@RequestMapping(value = "userSelect")
|
||||
public String userSelect(User user, String selectData, Model model) {
|
||||
String selectDataJson = EncodeUtils.decodeUrl(selectData);
|
||||
if (JsonMapper.fromJson(selectDataJson, Map.class) != null){
|
||||
if (selectDataJson != null && JSONValidator.from(selectDataJson).validate()){
|
||||
model.addAttribute("selectData", selectDataJson);
|
||||
}
|
||||
model.addAttribute("user", user);
|
||||
|
||||
@@ -131,6 +131,9 @@ user:
|
||||
|
||||
# 登录账号是否租户内唯一,否则全局唯一
|
||||
loginCodeCorpUnique: false
|
||||
|
||||
# 是否启用验证码登录(手机、邮箱)
|
||||
loginByValidCode: true
|
||||
|
||||
# 用户类型配置信息(employee员工,member会员,btype往来单位,persion个人,expert专家,...),JSON 格式说明如下:
|
||||
# {"用户类型":{"beanName":"Service或Dao的Bean名称","loginView":"登录页面视图","indexView":"主框架页面视图,支持 redirect: 前缀"}}
|
||||
@@ -335,10 +338,11 @@ shiro:
|
||||
|
||||
# 登录提交信息加密(如果不需要加密,设置为空即可)
|
||||
loginSubmit:
|
||||
# 登录提交信息安全Key,加密用户名、密码、验证码,后再提交(key设置为3个,用逗号分隔)加密方式:DES
|
||||
# v4.2.0+ 支持 Base64 加密方式,方便移动端及第三方系统处理认证,可直接设置 Key 为 Base64
|
||||
# 加密用户名、密码、验证码,后再提交(key设置为3个,用逗号分隔)加密方式:DES(4.1.9及之前版本默认设置)
|
||||
# v4.2.0+ 开始支持 Base64 加密方式,方便移动端及第三方系统处理认证,可直接设置 Key 为 Base64(4.2.0+默认设置)
|
||||
#secretKey: thinkgem,jeesite,com
|
||||
secretKey: Base64
|
||||
#secretKey: ~
|
||||
|
||||
# 记住我密钥设置,你可以通过 com.jeesite.test.RememberMeKeyGen 类快速生成一个秘钥。
|
||||
# 若不设置,则每次启动系统后自动生成一个新秘钥,这样会导致每次重启后,客户端记录的用户信息将失效。
|
||||
@@ -367,7 +371,7 @@ shiro:
|
||||
# accessControlAllowOrigin: http://demo.jeesite.com
|
||||
# accessControlAllowOrigin: '*'
|
||||
|
||||
# 允许跨域访问时 CORS,可以使用的方法和响应头
|
||||
# 允许跨域访问时 CORS,可以使用的方法和标头
|
||||
# accessControlAllowMethods: GET, POST, OPTIONS
|
||||
# accessControlAllowHeaders: Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With
|
||||
|
||||
@@ -396,6 +400,7 @@ shiro:
|
||||
# ${adminPath}/cms/article/* = anon
|
||||
# ${adminPath}/cms/link/* = anon
|
||||
# ${adminPath}/sys/corpAdmin/treeData = anon
|
||||
# ${adminPath}/${spring.application.name}/swagger/** = anon
|
||||
# ${adminPath}/** = user
|
||||
filterChainDefinitions: |
|
||||
${adminPath}/sys/corpAdmin/treeData = anon
|
||||
@@ -429,8 +434,11 @@ session:
|
||||
# 注意:如果超时超过30m,你还需要同步修改当前配置文件的属性:j2cache.caffeine.region.sessionCache 超时时间,大于这个值。
|
||||
sessionTimeout: 1800000
|
||||
|
||||
# PC设备会话超时参数设置,登录请求参数加 param_deviceType=pc 时有效
|
||||
#pcSessionTimeout: 1800000
|
||||
|
||||
# 手机APP设备会话超时参数设置,登录请求参数加 param_deviceType=mobileApp 时有效
|
||||
mobileAppSessionTimeout: 43200000
|
||||
#mobileAppSessionTimeout: 43200000
|
||||
|
||||
# 定时清理失效会话,清理用户直接关闭浏览器造成的孤立会话
|
||||
sessionTimeoutClean: 1200000
|
||||
@@ -503,10 +511,12 @@ web:
|
||||
# 使用智能参数接收器,同时支持 JSON 和 FormData 的参数接受
|
||||
smartMethodArgumentResolver: true
|
||||
|
||||
# 使用 .json、.xml 后缀匹配视图(不推荐使用,推荐使用 favorParameter)
|
||||
# 使用 .json、.xml 后缀匹配返回视图数据(Spring官方已不推荐使用)
|
||||
favorPathExtension: false
|
||||
# 使用 __ajax=json、__ajax=xml 参数名匹配视图
|
||||
# 使用 __ajax=json、__ajax=xml 后缀匹配返回视图数据
|
||||
favorParameter: true
|
||||
# 使用 __ajax=json、__ajax=xml 请求头匹配返回视图数据
|
||||
favorHeader: true
|
||||
|
||||
# MVC 拦截器
|
||||
interceptor:
|
||||
@@ -623,6 +633,10 @@ video:
|
||||
# 将mp4视频的元数据信息转到视频第一帧
|
||||
qtFaststartFile: d:/tools/video/qt-faststart/qt-faststart.exe
|
||||
|
||||
# 文件管理是否启用租户模式
|
||||
filemanager:
|
||||
useCorpModel: false
|
||||
|
||||
#======================================#
|
||||
#========== Message settings ==========#
|
||||
#======================================#
|
||||
|
||||
@@ -1,17 +1,5 @@
|
||||
-- tables_db2_v95.sql
|
||||
|
||||
DROP TABLE ${_prefix}job_FIRED_TRIGGERS;
|
||||
DROP TABLE ${_prefix}job_PAUSED_TRIGGER_GRPS;
|
||||
DROP TABLE ${_prefix}job_SCHEDULER_STATE;
|
||||
DROP TABLE ${_prefix}job_LOCKS;
|
||||
DROP TABLE ${_prefix}job_SIMPLE_TRIGGERS;
|
||||
DROP TABLE ${_prefix}job_SIMPROP_TRIGGERS;
|
||||
DROP TABLE ${_prefix}job_CRON_TRIGGERS;
|
||||
DROP TABLE ${_prefix}job_TRIGGERS;
|
||||
DROP TABLE ${_prefix}job_JOB_DETAILS;
|
||||
DROP TABLE ${_prefix}job_CALENDARS;
|
||||
DROP TABLE ${_prefix}job_BLOB_TRIGGERS;
|
||||
|
||||
create table ${_prefix}job_job_details(
|
||||
sched_name varchar(120) not null,
|
||||
job_name varchar(80) not null,
|
||||
|
||||
@@ -16,4 +16,5 @@
|
||||
4.1.7
|
||||
4.1.8
|
||||
4.1.9
|
||||
4.2.0
|
||||
4.2.0
|
||||
4.2.1
|
||||
@@ -20,6 +20,7 @@
|
||||
操作=Actions
|
||||
更多=More
|
||||
更多操作=More action
|
||||
设置=Setting
|
||||
|
||||
基本信息=Basic information
|
||||
详细信息=Detail information
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
操作=操作
|
||||
更多=さらに多
|
||||
更多操作=他の操作
|
||||
设置=設置
|
||||
|
||||
基本信息=基本情報
|
||||
详细信息=詳細情報
|
||||
|
||||
@@ -69,6 +69,10 @@
|
||||
|
||||
登录=Login
|
||||
欢迎回来=Welcome
|
||||
账号登录=Login
|
||||
手机登录=Mobile
|
||||
没有账号=No account
|
||||
点击注册=Register
|
||||
|
||||
请填写登录账号.=Please enter login account.
|
||||
登录账号=Login account
|
||||
@@ -77,6 +81,11 @@
|
||||
请填写登录密码.=Please enter login password.
|
||||
登录密码=Login password
|
||||
|
||||
登录租户=Login tenant
|
||||
请填写手机验证码.=Please enter mobile valid code
|
||||
手机验证码=Mobile valid code
|
||||
获取手机验证码=Get valid code
|
||||
|
||||
公共场所慎用,下次不需要再填写帐号=Use caution in public places.
|
||||
记住账号=Remember account
|
||||
公共场所慎用,下次不需要再填写帐号和密码=Use caution in public places.
|
||||
|
||||
@@ -70,6 +70,10 @@
|
||||
|
||||
登录=ログイン
|
||||
欢迎回来=おかえり
|
||||
账号登录=ログイン
|
||||
手机登录=電話登録
|
||||
没有账号=アカウントなし
|
||||
点击注册=きにゅう
|
||||
|
||||
请填写登录账号.=ログインIDを入力してください.
|
||||
登录账号=ログインアカウント
|
||||
@@ -78,6 +82,11 @@
|
||||
请填写登录密码.=パスワードを入力してください.
|
||||
登录密码=パスワード
|
||||
|
||||
登录租户=テナント登録
|
||||
请填写手机验证码.=携帯電話の検証コード
|
||||
手机验证码=電話の検証コード
|
||||
获取手机验证码=コードを取得
|
||||
|
||||
公共场所慎用,下次不需要再填写帐号=次回からログインIDの入力が不要にします.
|
||||
记住账号=ログインID記憶
|
||||
公共场所慎用,下次不需要再填写帐号和密码=次回からパスワードの入力が不要にします.
|
||||
@@ -90,6 +99,9 @@
|
||||
注册账号=アカウント作成
|
||||
忘记密码=パスワードを忘れた
|
||||
|
||||
注册账号=アカウントを登録する
|
||||
忘记密码=パスワードを忘れる
|
||||
|
||||
# =========== 主框架页 ===========
|
||||
|
||||
仪表盘=計器盤
|
||||
|
||||
@@ -18,7 +18,21 @@
|
||||
AND ur.role_code = #{roleCode}
|
||||
</if>
|
||||
<if test="employee.postCode != null and employee.postCode != ''">
|
||||
AND ep.post_code = #{employee.postCode}
|
||||
AND (
|
||||
ep.post_code = #{employee.postCode}
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM ${_prefix}sys_employee_office
|
||||
WHERE emp_code = e.emp_code
|
||||
AND post_code = #{employee.postCode}
|
||||
)
|
||||
)
|
||||
</if>
|
||||
<if test="employee.office.officeCode != null and employee.office.officeCode != ''">
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM ${_prefix}sys_employee_office
|
||||
WHERE emp_code = e.emp_code
|
||||
AND office_code = #{employee.office.officeCode}
|
||||
)
|
||||
</if>
|
||||
</where>
|
||||
ORDER BY ${sqlMap.order.toSql()}
|
||||
|
||||
111
modules/core/src/main/resources/static/modules/sys/forgetPwd.js
Normal file
111
modules/core/src/main/resources/static/modules/sys/forgetPwd.js
Normal file
@@ -0,0 +1,111 @@
|
||||
/*!
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
*
|
||||
* @author ThinkGem
|
||||
* @version 2019-1-6
|
||||
*/
|
||||
$(function(){
|
||||
|
||||
$('#fp_validType').change(function(){
|
||||
var val = $(this).val(), action = '';
|
||||
$('.fp-element').addClass('hide').removeClass('block');
|
||||
$('.fp-'+val).addClass('block').removeClass('hide');
|
||||
setTimeout(function(){
|
||||
$('#fp_loginCode').focus();
|
||||
}, 100);
|
||||
if (val == 'mobile' || val == 'email'){
|
||||
var txt = (val == 'mobile' ? '手机' : '邮箱')
|
||||
$('#fpValidCode').attr('placeholder', txt+'验证码')
|
||||
.attr('data-msg-required', '请填写'+txt+'验证码.');
|
||||
$('#sendFpValidCode').val('获取'+txt+'验证码');
|
||||
action = ctxPath + '/account/savePwdByValidCode';
|
||||
}else if(val == 'question'){
|
||||
action = ctxPath + '/account/savePwdByPwdQuestion';
|
||||
}
|
||||
$('#forgetForm').attr('action', action);
|
||||
}).change();
|
||||
|
||||
var waitTime = 60;
|
||||
function sendTime(o) {
|
||||
if (waitTime == 0) {
|
||||
o.removeAttribute("disabled");
|
||||
o.value = "获取验证码";
|
||||
waitTime = 60;
|
||||
} else {
|
||||
o.setAttribute("disabled", true);
|
||||
o.value = "重新发送(" + waitTime + ")";
|
||||
waitTime--;
|
||||
setTimeout(function() {
|
||||
sendTime(o)
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
$('#sendFpValidCode').click(function() {
|
||||
var $this = this;
|
||||
js.ajaxSubmit(ctxPath + '/account/getFpValidCode', {
|
||||
validType: $('#fp_validType').val(),
|
||||
loginCode : $('#fp_loginCode').val(),
|
||||
validCode : $('#fp_validCode').val()
|
||||
}, function(data){
|
||||
js.showMessage(data.message);
|
||||
if (data.result == 'true'){
|
||||
sendTime($this);
|
||||
$('#fpValidCode').focus();
|
||||
}else{
|
||||
$('#fp_validCodeImg').click();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#fp_getQuestion').click(function() {
|
||||
js.ajaxSubmit(ctxPath + '/account/getPwdQuestion', {
|
||||
loginCode : $('#fp_loginCode').val(),
|
||||
validCode : $('#fp_validCode').val()
|
||||
}, function(data){
|
||||
js.showMessage(data.message);
|
||||
if (data.result == 'true'){
|
||||
$('#fp_q1').text(data.pwdQuestion);
|
||||
$('#fp_q2').text(data.pwdQuestion2);
|
||||
$('#fp_q3').text(data.pwdQuestion3);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#forgetForm').validate({
|
||||
ignore: ":hidden",
|
||||
submitHandler: function(form) {
|
||||
var $form = $(form),
|
||||
action = $form.attr('action'),
|
||||
data = $form.serializeArray(),
|
||||
key = window.secretKey||$('#loginKey').data('key');
|
||||
if (key != ''){
|
||||
for (var i=0, l=data.length; i<l; i++){
|
||||
if (data[i].name == 'pwdQuestionAnswer'){
|
||||
data[i].value = DesUtils.encode($('#fp_pwdQuestionAnswer').val(), key);
|
||||
}else if (data[i].name == 'pwdQuestionAnswer2'){
|
||||
data[i].value = DesUtils.encode($('#fp_pwdQuestionAnswer2').val(), key);
|
||||
}else if (data[i].name == 'pwdQuestionAnswer3'){
|
||||
data[i].value = DesUtils.encode($('#fp_pwdQuestionAnswer3').val(), key);
|
||||
}else if (data[i].name == 'password'){
|
||||
data[i].value = DesUtils.encode($('#fp_password').val(), key);
|
||||
}
|
||||
}
|
||||
}
|
||||
js.ajaxSubmit(action, data, function(data, status, xhr){
|
||||
if (data.result == "true"){
|
||||
alert(data.message);
|
||||
location = ctx + '/login';
|
||||
}else{
|
||||
js.showMessage(data.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$('#btnReset').click(function(){
|
||||
location = ctx + '/login';
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
/*!
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
*
|
||||
* @author ThinkGem
|
||||
* @version 2019-1-6
|
||||
*/
|
||||
$(function(){
|
||||
|
||||
$('#reg_validType').change(function(){
|
||||
var val = $(this).val(), action = '';
|
||||
$('.reg-element').addClass('hide').removeClass('block');
|
||||
$('.reg-'+val).addClass('block').removeClass('hide');
|
||||
setTimeout(function(){
|
||||
$('#reg_loginCode').focus();
|
||||
}, 100);
|
||||
if (val == 'mobile' || val == 'email'){
|
||||
var txt = (val == 'mobile' ? '手机' : '邮箱')
|
||||
$('#regValidCode').attr('placeholder', txt+'验证码')
|
||||
.attr('data-msg-required', '请填写'+txt+'验证码.');
|
||||
$('#sendRegValidCode').val('获取'+txt+'验证码');
|
||||
action = ctxPath + '/account/saveRegByValidCode';
|
||||
}else if(val == 'question'){
|
||||
action = ctxPath + '/account/savePwdByPwdQuestion';
|
||||
}
|
||||
$('#registerForm').attr('action', action);
|
||||
}).change();
|
||||
|
||||
var waitTime = 60;
|
||||
function sendTime(o) {
|
||||
if (waitTime == 0) {
|
||||
o.removeAttribute("disabled");
|
||||
o.value = "获取验证码";
|
||||
waitTime = 60;
|
||||
} else {
|
||||
o.setAttribute("disabled", true);
|
||||
o.value = "重新发送(" + waitTime + ")";
|
||||
waitTime--;
|
||||
setTimeout(function() {
|
||||
sendTime(o)
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
$('#sendRegValidCode').click(function() {
|
||||
var $this = this;
|
||||
js.ajaxSubmit(ctxPath + '/account/getRegValidCode', {
|
||||
validType: $('#reg_validType').val(),
|
||||
corpCode_ : $('#reg_corpCode').val(),
|
||||
corpName_ : $('#reg_corpName').val(),
|
||||
loginCode : $('#reg_loginCode').val(),
|
||||
userName : $('#reg_userName').val(),
|
||||
email : $('#reg_email').val(),
|
||||
mobile : $('#reg_mobile').val(),
|
||||
userType: $('#reg_userType').val(),
|
||||
validCode : $('#reg_validCode').val()
|
||||
}, function(data){
|
||||
js.showMessage(data.message);
|
||||
if (data.result == 'true'){
|
||||
sendTime($this);
|
||||
$('#regValidCode').focus();
|
||||
}else{
|
||||
$('#reg_validCodeImg').click();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#registerForm').validate({
|
||||
ignore: ":hidden",
|
||||
submitHandler: function(form) {
|
||||
var $form = $(form),
|
||||
action = $form.attr('action'),
|
||||
data = $form.serializeArray(),
|
||||
key = window.secretKey||$('#loginKey').data('key');
|
||||
if (key != ''){
|
||||
for (var i=0, l=data.length; i<l; i++){
|
||||
if (data[i].name == 'password'){
|
||||
data[i].value = DesUtils.encode($('#reg_password').val(), key);
|
||||
}
|
||||
}
|
||||
}
|
||||
js.ajaxSubmit(action, data, function(data, status, xhr){
|
||||
if (data.result == "true"){
|
||||
alert(data.message);
|
||||
location = ctx + '/login';
|
||||
}else{
|
||||
js.showMessage(data.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$('#btnReset').click(function(){
|
||||
location = ctx + '/login';
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -7131,7 +7131,7 @@ var fillCharReg = new RegExp(domUtils.fillChar, 'g');
|
||||
this.iframe.parentNode.style.height = height + 'px';
|
||||
}
|
||||
!notSetHeight && (this.options.minFrameHeight = this.options.initialFrameHeight = height);
|
||||
this.body.style.height = height + 'px';
|
||||
//this.body.style.height = height + 'px'; // 设置高的时候会出现多余的垂直滚动条
|
||||
!notSetHeight && this.trigger('setHeight')
|
||||
},
|
||||
|
||||
@@ -24454,6 +24454,7 @@ UE.plugin.register('simpleupload', function (){
|
||||
var w = containerBtn.offsetWidth || 20,
|
||||
h = containerBtn.offsetHeight || 20,
|
||||
btnIframe = document.createElement('iframe'),
|
||||
btnIframe2 = document.createElement('iframe'), // ThinkGem
|
||||
btnStyle = 'display:block;width:' + w + 'px;height:' + h + 'px;overflow:hidden;border:0;margin:0;padding:0;position:absolute;top:0;left:0;filter:alpha(opacity=0);-moz-opacity:0;-khtml-opacity: 0;opacity: 0;cursor:pointer;';
|
||||
|
||||
domUtils.on(btnIframe, 'load', function(){
|
||||
@@ -24471,9 +24472,13 @@ UE.plugin.register('simpleupload', function (){
|
||||
'style="' + btnStyle + '">' +
|
||||
'<input id="edui_input_' + timestrap + '" type="file" accept="image/*" name="' + me.options.imageFieldName + '" ' +
|
||||
'style="' + btnStyle + '">' +
|
||||
'</form>' +
|
||||
'<iframe id="edui_iframe_' + timestrap + '" name="edui_iframe_' + timestrap + '" style="display:none;width:0;height:0;border:0;margin:0;padding:0;position:absolute;"></iframe>';
|
||||
'</form>';// +
|
||||
//'<iframe id="edui_iframe_' + timestrap + '" name="edui_iframe_' + timestrap + '" style="display:none;width:0;height:0;border:0;margin:0;padding:0;position:absolute;"></iframe>';
|
||||
|
||||
// 解决因 iframe 嵌套问题 session 丢失 ThinkGem
|
||||
btnIframe2.id = 'edui_iframe_' + timestrap;
|
||||
btnIframe2.name = 'edui_iframe_' + timestrap;
|
||||
|
||||
wrapper.className = 'edui-' + me.options.theme;
|
||||
wrapper.id = me.ui.id + '_iframeupload';
|
||||
btnIframeBody.style.cssText = btnStyle;
|
||||
@@ -24488,7 +24493,7 @@ UE.plugin.register('simpleupload', function (){
|
||||
|
||||
var form = btnIframeDoc.getElementById('edui_form_' + timestrap);
|
||||
var input = btnIframeDoc.getElementById('edui_input_' + timestrap);
|
||||
var iframe = btnIframeDoc.getElementById('edui_iframe_' + timestrap);
|
||||
var iframe = btnIframe2;//btnIframeDoc.getElementById('edui_iframe_' + timestrap);
|
||||
|
||||
domUtils.on(input, 'change', function(){
|
||||
if(!input.value) return;
|
||||
@@ -24573,6 +24578,10 @@ UE.plugin.register('simpleupload', function (){
|
||||
|
||||
btnIframe.style.cssText = btnStyle;
|
||||
containerBtn.appendChild(btnIframe);
|
||||
|
||||
// 解决因 iframe 嵌套问题 session 丢失 ThinkGem
|
||||
btnIframe2.style.cssText = 'display:none;width:0;height:0;border:0;margin:0;padding:0;position:absolute;';
|
||||
containerBtn.appendChild(btnIframe2);
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@@ -34,6 +34,7 @@ $.fn.webuploader.defaults.i18n = {
|
||||
'向右旋转': 'Rotate right',
|
||||
'向左旋转': 'Rotate left',
|
||||
|
||||
'不能上传空文件': 'Empty file error',
|
||||
'文件类型不对': 'File type error',
|
||||
'文件大小超出': 'File size exceeded',
|
||||
'文件传输中断': 'File transfer interrupt',
|
||||
|
||||
@@ -33,7 +33,8 @@ $.fn.webuploader.defaults.i18n = {
|
||||
'删除': '削除',
|
||||
'向右旋转': '右にまがる',
|
||||
'向左旋转': '左に回る',
|
||||
|
||||
|
||||
'不能上传空文件': '空のファイルはアップロードできません',
|
||||
'文件类型不对': '書類のタイプが違う',
|
||||
'文件大小超出': '書類のサイズがはみ出る',
|
||||
'文件传输中断': 'ファイル転送を中断する。',
|
||||
|
||||
@@ -14,19 +14,45 @@
|
||||
<template>category-ref:dao</template>
|
||||
</childTable>
|
||||
</category>
|
||||
<category value="crud_select" label="单表/主子表 (增删改查,含 listselect 选择页面)">
|
||||
<template>category-ref:crud</template>
|
||||
<template>crud/viewSelect.xml</template>
|
||||
<childTable>
|
||||
<template>category-ref:dao</template>
|
||||
</childTable>
|
||||
</category>
|
||||
<category value="crud_cloud" label="单表/主子表 (增删改查 Cloud,生成 Api/Client)">
|
||||
<template>crud/mapper.xml</template>
|
||||
<template>crud_cloud/entity.xml</template>
|
||||
<template>crud/dao.xml</template>
|
||||
<template>crud_cloud/api.xml</template>
|
||||
<template>crud_cloud/client.xml</template>
|
||||
<template>crud_cloud/service.xml</template>
|
||||
<template>crud/controller.xml</template>
|
||||
<template>crud/viewList.xml</template>
|
||||
<template>crud/viewForm.xml</template>
|
||||
<childTable>
|
||||
<template>crud/mapper.xml</template>
|
||||
<template>crud_cloud/entity.xml</template>
|
||||
<template>crud/dao.xml</template>
|
||||
</childTable>
|
||||
</category>
|
||||
<category value="treeGrid" label="树表/树结构表(增删改查)">
|
||||
<template>category-ref:crud</template>
|
||||
</category>
|
||||
<category value="service" label="业务层和持久层(不含控制器和视图)">
|
||||
<category value="treeGrid_cloud" label="树表/树结构表(增删改查 Cloud,生成 Api/Client)">
|
||||
<template>category-ref:crud</template>
|
||||
</category>
|
||||
<category value="service" label="业务层和持久层(dao/service,不含控制器和视图)">
|
||||
<template>category-ref:dao</template>
|
||||
<template>crud/service.xml</template>
|
||||
</category>
|
||||
<category value="dao" label="仅持久层(dao/mapper/entity)">
|
||||
<category value="dao" label="关系表/仅持久层(dao/mapper/entity)">
|
||||
<template>crud/mapper.xml</template>
|
||||
<template>crud/entity.xml</template>
|
||||
<template>crud/dao.xml</template>
|
||||
</category>
|
||||
<category value="query" label="仅查询功能(不含增删改)">
|
||||
<category value="query" label="仅查询功能(不含增删改,仅数据展现)">
|
||||
<template>crud/mapper.xml</template>
|
||||
<template>crud/entity.xml</template>
|
||||
<template>query/dao.xml</template>
|
||||
@@ -110,4 +136,42 @@
|
||||
<dict value="4/4/8" label="4/4/8 三列"/>
|
||||
<dict value="3/4/8" label="3/4/8 四列"/>
|
||||
</gridRowCol>
|
||||
<!-- 模块生成模板分类 -->
|
||||
<moduleTplCategory>
|
||||
<category value="module" label="生成模块代码">
|
||||
<template>module/bin/deploy.bat.xml</template>
|
||||
<template>module/bin/deploy.sh.xml</template>
|
||||
<template>module/bin/package.bat.xml</template>
|
||||
<template>module/bin/package.sh.xml</template>
|
||||
<template>module/db/erm.xml</template>
|
||||
<template>module/src/main/java/package.xml</template>
|
||||
<template>module/src/main/resources/config/jeesite.xml</template>
|
||||
<template>module/src/main/resources/db/versions.xml</template>
|
||||
<template>module/src/main/resources/static/static.xml</template>
|
||||
<template>module/pom.xml</template>
|
||||
</category>
|
||||
<category value="module_cloud" label="生成微服务模块代码(Cloud)">
|
||||
<template>module_cloud/client/bin/deploy.bat.xml</template>
|
||||
<template>module_cloud/client/bin/deploy.sh.xml</template>
|
||||
<template>module_cloud/client/bin/package.bat.xml</template>
|
||||
<template>module_cloud/client/bin/package.sh.xml</template>
|
||||
<template>module_cloud/client/src/main/java/package.xml</template>
|
||||
<template>module_cloud/client/pom.xml</template>
|
||||
<template>module_cloud/web/bin/docker-bulid.bat.xml</template>
|
||||
<template>module_cloud/web/bin/docker-bulid.sh.xml</template>
|
||||
<template>module_cloud/web/bin/package.bat.xml</template>
|
||||
<template>module_cloud/web/bin/package.sh.xml</template>
|
||||
<template>module_cloud/web/bin/run-tomcat.bat.xml</template>
|
||||
<template>module_cloud/web/bin/run-tomcat.sh.xml</template>
|
||||
<template>module_cloud/web/bin/run-web.bat.xml</template>
|
||||
<template>module_cloud/web/bin/run-web.sh.xml</template>
|
||||
<template>module_cloud/web/db/erm.xml</template>
|
||||
<template>module_cloud/web/src/main/java/package.xml</template>
|
||||
<template>module_cloud/web/src/main/java/startClass.xml</template>
|
||||
<template>module_cloud/web/src/main/resources/config/bootstrap.xml</template>
|
||||
<template>module_cloud/web/src/main/resources/config/logback-spring.xml</template>
|
||||
<template>module_cloud/web/src/main/resources/static/static.xml</template>
|
||||
<template>module_cloud/web/pom.xml</template>
|
||||
</category>
|
||||
</moduleTplCategory>
|
||||
</config>
|
||||
@@ -39,6 +39,10 @@ import com.jeesite.modules.sys.utils.UserUtils;
|
||||
<% }else{ %>
|
||||
import com.jeesite.common.entity.Page;
|
||||
<% } %>
|
||||
<% if (table.tplCategory == 'crud_select'){ %>
|
||||
import com.alibaba.fastjson.JSONValidator;
|
||||
import com.jeesite.common.codec.EncodeUtils;
|
||||
<% } %>
|
||||
import com.jeesite.common.web.BaseController;
|
||||
import ${packageName}.${moduleName}.entity${isNotEmpty(subModuleName)?'.'+subModuleName:''}.${ClassName};
|
||||
import ${packageName}.${moduleName}.service${isNotEmpty(subModuleName)?'.'+subModuleName:''}.${ClassName}Service;
|
||||
@@ -238,10 +242,12 @@ public class ${ClassName}Controller extends BaseController {
|
||||
List<${ClassName}> list = ${className}Service.findList(new ${ClassName}());
|
||||
for (int i=0; i<list.size(); i++){
|
||||
${ClassName} e = list.get(i);
|
||||
<% if (table.statusExists){ %>
|
||||
// 过滤非正常的数据
|
||||
if (!${ClassName}.STATUS_NORMAL.equals(e.getStatus())){
|
||||
continue;
|
||||
}
|
||||
<% } %>
|
||||
// 过滤被排除的编码(包括所有子级)
|
||||
if (StringUtils.isNotBlank(excludeCode)){
|
||||
if (e.getId().equals(excludeCode)){
|
||||
@@ -274,6 +280,22 @@ public class ${ClassName}Controller extends BaseController {
|
||||
return renderResult(Global.TRUE, "数据修复成功");
|
||||
}
|
||||
<% } %>
|
||||
<% if (table.tplCategory == 'crud_select'){ %>
|
||||
|
||||
/**
|
||||
* 列表选择对话框
|
||||
*/
|
||||
@RequiresPermissions("${permissionPrefix}:view")
|
||||
@RequestMapping(value = "${className}Select")
|
||||
public String empUserSelect(${ClassName} ${className}, String selectData, Model model) {
|
||||
String selectDataJson = EncodeUtils.decodeUrl(selectData);
|
||||
if (selectDataJson != null && JSONValidator.from(selectDataJson).validate()){
|
||||
model.addAttribute("selectData", selectDataJson);
|
||||
}
|
||||
model.addAttribute("${ClassName}", ${className});
|
||||
return "${lastPackageName}/${viewPrefix}Select";
|
||||
}
|
||||
<% } %>
|
||||
|
||||
}]]>
|
||||
</content>
|
||||
|
||||
@@ -21,6 +21,13 @@ import com.jeesite.common.entity.TreeEntity;
|
||||
import com.jeesite.common.mybatis.annotation.Column;
|
||||
import com.jeesite.common.mybatis.annotation.Table;
|
||||
import com.jeesite.common.mybatis.mapper.query.QueryType;
|
||||
<% if(toBoolean(table.optionMap['isBpmForm'])){ %>
|
||||
<% if(table.isTreeEntity){ %>
|
||||
import com.jeesite.modules.bpm.entity.BpmTreeEntity;
|
||||
<% }else{ %>
|
||||
import com.jeesite.modules.bpm.entity.BpmEntity;
|
||||
<% } %>
|
||||
<% } %>
|
||||
|
||||
/**
|
||||
* ${functionName}Entity
|
||||
@@ -136,9 +143,9 @@ import com.jeesite.common.mybatis.mapper.query.QueryType;
|
||||
}
|
||||
}
|
||||
if (isNotBlank(joinTables)){
|
||||
print('joinTable={\n');
|
||||
print('joinTable={');
|
||||
print(joinTables);
|
||||
print('\t}, ');
|
||||
print('}, ');
|
||||
}
|
||||
// ◆ 生成排序字段
|
||||
%>orderBy="<% if (isTree){
|
||||
@@ -156,7 +163,7 @@ import com.jeesite.common.mybatis.mapper.query.QueryType;
|
||||
}
|
||||
} %>"
|
||||
)
|
||||
public class ${ClassName} extends ${table.isTreeEntity?'Tree':'Data'}Entity<${ClassName}> {
|
||||
public class ${ClassName} extends ${toBoolean(table.optionMap['isBpmForm'])?(table.isTreeEntity?'BpmTree':'Bpm'):table.isTreeEntity?'Tree':'Data'}Entity<${ClassName}> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
<%
|
||||
|
||||
@@ -22,6 +22,13 @@ import com.jeesite.common.entity.Page;
|
||||
import com.jeesite.common.service.${table.isTreeEntity?'Tree':'Crud'}Service;
|
||||
import ${packageName}.${moduleName}.entity${isNotEmpty(subModuleName)?'.'+subModuleName:''}.${ClassName};
|
||||
import ${packageName}.${moduleName}.dao${isNotEmpty(subModuleName)?'.'+subModuleName:''}.${ClassName}Dao;
|
||||
<% if(toBoolean(table.optionMap['isBpmForm'])){ %>
|
||||
import java.util.Map;
|
||||
import com.jeesite.common.lang.StringUtils;
|
||||
import com.jeesite.common.collect.MapUtils;
|
||||
import com.jeesite.common.service.ServiceException;
|
||||
import com.jeesite.modules.bpm.utils.BpmUtils;
|
||||
<% } %>
|
||||
<% if(toBoolean(table.optionMap['isImageUpload']) || toBoolean(table.optionMap['isFileUpload'])){ %>
|
||||
import com.jeesite.modules.file.utils.FileUploadUtils;
|
||||
<% } %>
|
||||
@@ -97,7 +104,43 @@ public class ${ClassName}Service extends ${table.isTreeEntity?'Tree':'Crud'}Serv
|
||||
@Override
|
||||
@Transactional(readOnly=false)
|
||||
public void save(${ClassName} ${className}) {
|
||||
<% if(toBoolean(table.optionMap['isBpmForm'])){ %>
|
||||
// 如果未设置状态,则指定状态为审核状态,以提交审核流程
|
||||
if (StringUtils.isBlank(${className}.getStatus())){
|
||||
${className}.setStatus(${ClassName}.STATUS_AUDIT);
|
||||
}
|
||||
|
||||
// 如果状态为正常,则代表不正常操作,可能前端进行了数据参数修改
|
||||
if (${ClassName}.STATUS_NORMAL.equals(${className}.getStatus())){
|
||||
throw new ServiceException(text("非法操作,前端数据被劫持!"));
|
||||
}
|
||||
|
||||
// 如果状态为草稿或审核状态,才可以保存业务数据
|
||||
if (${ClassName}.STATUS_DRAFT.equals(${className}.getStatus())
|
||||
|| ${ClassName}.STATUS_AUDIT.equals(${className}.getStatus())){
|
||||
super.save(${className});
|
||||
}
|
||||
|
||||
// 如果为审核状态,则进行审批流操作
|
||||
if (${ClassName}.STATUS_AUDIT.equals(${className}.getStatus())){
|
||||
|
||||
// 指定流程变量,作为流程条件,决定流转方向
|
||||
Map<String, Object> variables = MapUtils.newHashMap();
|
||||
//variables.put("leaveDays", ${className}.getLeaveDays());
|
||||
|
||||
// 如果流程实例为空,任务编号也为空,则:启动流程
|
||||
if (StringUtils.isBlank(${className}.getBpm().getProcInsId())
|
||||
&& StringUtils.isBlank(${className}.getBpm().getTaskId())){
|
||||
BpmUtils.start(${className}, "${table.optionMap['bpmFormKey']}", variables, null);
|
||||
}
|
||||
// 如果有任务信息,则:提交任务
|
||||
else{
|
||||
BpmUtils.complete(${className}, variables, null);
|
||||
}
|
||||
}
|
||||
<% }else{ %>
|
||||
super.save(${className});
|
||||
<% } %>
|
||||
<% if(toBoolean(table.optionMap['isImageUpload'])){ %>
|
||||
// 保存上传图片
|
||||
FileUploadUtils.saveFileUpload(${className}.getId(), "${className}_image");
|
||||
|
||||
@@ -45,13 +45,38 @@
|
||||
<% } %>
|
||||
<% include('/templates/modules/gen/include/formControl.html'){} %>
|
||||
<% include('/templates/modules/gen/include/formChildTable.html'){} %>
|
||||
<% if(toBoolean(table.optionMap['isBpmForm'])){ %>
|
||||
\<% if(isNotBlank(${className}.bpm.taskId)){ %>
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<div class="form-group">
|
||||
<label class="control-label col-xs-2">${text('审批意见')}:</label>
|
||||
<div class="col-xs-10">
|
||||
<${'#'}bpm:comment bpmEntity="\${${className}}" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
\<% } %>
|
||||
<${'#'}bpm:nextTaskInfo bpmEntity="\${${className}}" />
|
||||
<% } %>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<div class="row">
|
||||
<div class="col-sm-offset-2 col-sm-10">
|
||||
<% if(toBoolean(table.optionMap['isBpmForm'])){ %>
|
||||
\<% if (hasPermi('${permissionPrefix}:edit')){ %>
|
||||
<${'#'}form:hidden path="status"/>
|
||||
\<% if (${className}.isNewRecord || ${className}.status == '9'){ %>
|
||||
<button type="submit" class="btn btn-sm btn-info" id="btnDraft"><i class="fa fa-save"></i> ${text('暂 存')}</button>
|
||||
\<% } %>
|
||||
<${'#'}bpm:button bpmEntity="\${${className}}" formKey="${table.optionMap['bpmFormKey']}" completeText="${text('提 交')}"/>
|
||||
\<% } %>
|
||||
<% }else{ %>
|
||||
\<% if (hasPermi('${permissionPrefix}:edit')){ %>
|
||||
<button type="submit" class="btn btn-sm btn-primary" id="btnSubmit"><i class="fa fa-check"></i> \${text('保 存')}</button>
|
||||
\<% } %>
|
||||
<% } %>
|
||||
<button type="button" class="btn btn-sm btn-default" id="btnCancel" onclick="js.closeCurrentTabPage()"><i class="fa fa-reply-all"></i> \${text('关 闭')}</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -62,6 +87,19 @@
|
||||
\<% } %>
|
||||
<% include('/templates/modules/gen/include/formChildTableScript.html'){} %>
|
||||
<script>
|
||||
<% if(toBoolean(table.optionMap['isBpmForm'])){ %>
|
||||
// 业务实现草稿按钮
|
||||
$('#btnDraft').click(function(){
|
||||
$('#status').val(Global.STATUS_DRAFT);
|
||||
});
|
||||
// 流程按钮操作事件
|
||||
BpmButton = window.BpmButton || {};
|
||||
BpmButton.init = function(task){ }
|
||||
BpmButton.complete = function($this, task){
|
||||
$('#status').val(Global.STATUS_AUDIT);
|
||||
};
|
||||
// 表单验证提交事件
|
||||
<% } %>
|
||||
$("#inputForm").validate({
|
||||
submitHandler: function(form){
|
||||
js.ajaxSubmitForm($(form), function(data){
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
\<% if(hasPermi('${permissionPrefix}:edit')){ %>
|
||||
<a href="\${ctx}/${urlPrefix}/form" class="btn btn-default btnTool" title="\${text('新增${functionNameSimple}')}"><i class="fa fa-plus"></i> \${text('新增')}</a>
|
||||
\<% } %>
|
||||
<a href="#" class="btn btn-default" id="btnSetting" title="\${text('设置')}"><i class="fa fa-navicon"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) 2013-Now http://jeesite.com All rights reserved. -->
|
||||
<template>
|
||||
<name>viewSelect</name>
|
||||
<filePath>src/main/resources/views/${lastPackageName}/${moduleName}/${subModuleName}</filePath>
|
||||
<fileName>${className}Select.html</fileName>
|
||||
<content><![CDATA[
|
||||
\<% layout('/layouts/default.html', {title: '${functionNameSimple}管理', libs: ['dataGrid']}){ %>
|
||||
<div class="main-content">
|
||||
<div class="box box-main">
|
||||
<div class="box-body">
|
||||
<% include('/templates/modules/gen/include/searchForm.html'){} %>
|
||||
<div class="row">
|
||||
<div class="col-xs-10 pr10">
|
||||
<table id="dataGrid"></table>
|
||||
<% if(!table.isTreeEntity){ %>
|
||||
<div id="dataGridPage"></div>
|
||||
<% } %>
|
||||
</div>
|
||||
<div class="col-xs-2 pl0">
|
||||
<div id="selectData" class="tags-input"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
\<% } %>
|
||||
<% include('/templates/modules/gen/include/dataGridSelectScript.html'){} %>]]>
|
||||
</content>
|
||||
</template>
|
||||
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) 2013-Now http://jeesite.com All rights reserved. -->
|
||||
<template>
|
||||
<name>controller</name>
|
||||
<filePath>${moduleName}-client/src/main/java/${packageName}/${moduleName}/api/${subModuleName}</filePath>
|
||||
<fileName>${ClassName}ServiceApi.java</fileName>
|
||||
<content><![CDATA[
|
||||
/**
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
*/
|
||||
package ${packageName}.${moduleName}.api${isNotEmpty(subModuleName)?'.'+subModuleName:''};
|
||||
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
import com.jeesite.common.service.rest.CrudServiceRest;
|
||||
import ${packageName}.${moduleName}.entity${isNotEmpty(subModuleName)?'.'+subModuleName:''}.${ClassName};
|
||||
|
||||
/**
|
||||
* ${functionName}API
|
||||
* @author ${functionAuthor}
|
||||
* @version ${functionVersion}
|
||||
*/
|
||||
@RequestMapping(value = "/inner/api/${urlPrefix}")
|
||||
public interface ${ClassName}ServiceApi extends ${table.isTreeEntity?'Tree':'Crud'}ServiceRest<${ClassName}> {
|
||||
|
||||
}]]>
|
||||
</content>
|
||||
</template>
|
||||
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) 2013-Now http://jeesite.com All rights reserved. -->
|
||||
<template>
|
||||
<name>client</name>
|
||||
<filePath>${moduleName}-client/src/main/java/${packageName}/${moduleName}/client/${subModuleName}</filePath>
|
||||
<fileName>${ClassName}ServiceClient.java</fileName>
|
||||
<content><![CDATA[
|
||||
/**
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
*/
|
||||
package ${packageName}.${moduleName}.client${isNotEmpty(subModuleName)?'.'+subModuleName:''};
|
||||
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
|
||||
import com.jeesite.modules.cloud.feign.condition.ConditionalOnNotCurrentApplication;
|
||||
import ${packageName}.${moduleName}.api${isNotEmpty(subModuleName)?'.'+subModuleName:''}.${ClassName}ServiceApi;
|
||||
|
||||
/**
|
||||
* ${functionName}API
|
||||
* @author ${functionAuthor}
|
||||
* @version ${functionVersion}
|
||||
*/
|
||||
@FeignClient(name="\${service.${moduleName}.name}", path="\${service.${moduleName}.path}")
|
||||
@ConditionalOnNotCurrentApplication(name="\${service.${moduleName}.name}")
|
||||
public interface ${ClassName}ServiceClient extends ${ClassName}ServiceApi {
|
||||
|
||||
}]]>
|
||||
</content>
|
||||
</template>
|
||||
@@ -0,0 +1,352 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) 2013-Now http://jeesite.com All rights reserved. -->
|
||||
<template>
|
||||
<name>entity</name>
|
||||
<filePath>${moduleName}-client/src/main/java/${packageName}/${moduleName}/entity/${subModuleName}</filePath>
|
||||
<fileName>${ClassName}.java</fileName>
|
||||
<content><![CDATA[
|
||||
/**
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
*/
|
||||
package ${packageName}.${moduleName}.entity${isNotBlank(subModuleName)?'.'+subModuleName:''};
|
||||
|
||||
<% for(i in table.importList){ %>
|
||||
import ${i};
|
||||
<% } %>
|
||||
|
||||
import com.jeesite.common.entity.DataEntity;
|
||||
<% if(table.isTreeEntity){ %>
|
||||
import com.jeesite.common.entity.TreeEntity;
|
||||
<% } %>
|
||||
import com.jeesite.common.mybatis.annotation.Column;
|
||||
import com.jeesite.common.mybatis.annotation.Table;
|
||||
import com.jeesite.common.mybatis.mapper.query.QueryType;
|
||||
<% if(toBoolean(table.optionMap['isBpmForm'])){ %>
|
||||
<% if(table.isTreeEntity){ %>
|
||||
import com.jeesite.modules.bpm.entity.BpmTreeEntity;
|
||||
<% }else{ %>
|
||||
import com.jeesite.modules.bpm.entity.BpmEntity;
|
||||
<% } %>
|
||||
<% } %>
|
||||
|
||||
/**
|
||||
* ${functionName}Entity
|
||||
* @author ${functionAuthor}
|
||||
* @version ${functionVersion}
|
||||
*/
|
||||
@Table(name="${table.genTableName}", alias="a", columns={
|
||||
<%
|
||||
var isBase = false, isData = false,
|
||||
isTree = false, isExtend = false;
|
||||
// ◆ 生成字段属性
|
||||
for(c in table.columnList){
|
||||
// ● 如果是BaseEntity类属性
|
||||
if(table.isBaseEntity && c.isBaseEntityColumn){
|
||||
if(!isBase){
|
||||
isBase = true;
|
||||
%>
|
||||
@Column(includeEntity=BaseEntity.class),
|
||||
<%
|
||||
}
|
||||
// ● 如果是DataEntity类属性
|
||||
}else if(table.isDataEntity && c.isDataEntityColumn){
|
||||
if(!isData){
|
||||
isData = true;
|
||||
%>
|
||||
@Column(includeEntity=DataEntity.class),
|
||||
<%
|
||||
}
|
||||
// ● 如果是TreeEntity类属性
|
||||
}else if(table.isTreeEntity && c.isTreeEntityColumn){
|
||||
if(!isTree){
|
||||
isTree = true;
|
||||
%>
|
||||
@Column(includeEntity=TreeEntity.class),
|
||||
<%
|
||||
}
|
||||
// ● 如果是Extend类属性
|
||||
}else if(table.isExtendEntity && c.isExtendColumn){
|
||||
if(!isExtend){
|
||||
isExtend = true;
|
||||
%>
|
||||
@Column(includeEntity=Extend.class, attrName="extend"),
|
||||
<%
|
||||
}
|
||||
// ● 其它情况下
|
||||
}else{
|
||||
// 容错,如果没有设置父表的主键属性,则设置
|
||||
if(!@StringUtils.contains(c.attrName, ".")){
|
||||
if (table.parentExists && table.parentTableFkName == c.columnName){
|
||||
for (pk in table.parent.pkList){
|
||||
c.fullAttrName = c.fullAttrName + '.' + pk.attrName;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
%>
|
||||
@Column(name="${c.columnName}", attrName="${c.attrName}", label="${c.columnLabel}"<%
|
||||
if (c.comments != c.columnLabel){
|
||||
print(', comment="'+c.comments+'"');
|
||||
}
|
||||
if (c.isPk == @Global.YES){
|
||||
print(', isPK=true');
|
||||
}else{
|
||||
if (c.isInsert != @Global.YES){
|
||||
print(', isInsert=false');
|
||||
}
|
||||
if (c.isUpdate != @Global.YES){
|
||||
print(', isUpdate=false');
|
||||
}
|
||||
if (c.isQuery == @Global.YES && @StringUtils.inString(c.queryType,
|
||||
'NE', 'GT', 'GTE', 'LT', 'LTE', 'LIKE', 'LEFT_LIKE', 'RIGHT_LIKE')){
|
||||
print(', queryType=QueryType.'+c.queryType);
|
||||
}
|
||||
if (c.isQuery != @Global.YES){
|
||||
print(', isQuery=false');
|
||||
}
|
||||
if (c.attrName == table.treeViewNameAttrName){
|
||||
print(', isTreeName=true');
|
||||
}
|
||||
}
|
||||
%>),
|
||||
<%
|
||||
}
|
||||
}
|
||||
%>
|
||||
}, <%
|
||||
// ◆ 生成关联表
|
||||
var joinTables = '';
|
||||
for(c in table.columnList){
|
||||
if (c.attrType == 'com.jeesite.modules.sys.entity.User'){
|
||||
var joinTable = {
|
||||
%>
|
||||
@JoinTable(type=Type.LEFT_JOIN, entity=User.class, attrName="${c.simpleAttrName}", alias="u${cLP.index}",
|
||||
on="u${cLP.index}.user_code = a.${c.columnName}", columns={
|
||||
@Column(name="user_code", label="用户编码", isPK=true),
|
||||
@Column(name="user_name", label="用户名称", isQuery=false),
|
||||
}),
|
||||
<%
|
||||
};
|
||||
joinTables = joinTables + joinTable;
|
||||
}
|
||||
else if (c.attrType == 'com.jeesite.modules.sys.entity.Office'){
|
||||
var joinTable = {
|
||||
%>
|
||||
@JoinTable(type=Type.LEFT_JOIN, entity=Office.class, attrName="${c.simpleAttrName}", alias="u${cLP.index}",
|
||||
on="u${cLP.index}.office_code = a.${c.columnName}", columns={
|
||||
@Column(name="office_code", label="机构编码", isPK=true),
|
||||
@Column(name="office_name", label="机构名称", isQuery=false),
|
||||
}),
|
||||
<%
|
||||
};
|
||||
joinTables = joinTables + joinTable;
|
||||
}
|
||||
}
|
||||
if (isNotBlank(joinTables)){
|
||||
print('joinTable={');
|
||||
print(joinTables);
|
||||
print('}, ');
|
||||
}
|
||||
// ◆ 生成排序字段
|
||||
%>orderBy="<% if (isTree){
|
||||
%>a.tree_sorts<%
|
||||
for(pk in table.pkList){
|
||||
%>, a.${pk.columnName}<%
|
||||
}
|
||||
}else if(table.parentExists && table.createDateExists){
|
||||
%>a.create_date ASC<%
|
||||
}else if(table.updateDateExists){
|
||||
%>a.update_date DESC<%
|
||||
}else{
|
||||
for(pk in table.pkList){
|
||||
%>${pkLP.index!=1?', ':''}a.${pk.columnName} ${table.parentExists?'ASC':'DESC'}<%
|
||||
}
|
||||
} %>"
|
||||
)
|
||||
public class ${ClassName} extends ${toBoolean(table.optionMap['isBpmForm'])?(table.isTreeEntity?'BpmTree':'Bpm'):table.isTreeEntity?'Tree':'Data'}Entity<${ClassName}> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
<%
|
||||
isExtend = false;
|
||||
// 生成字段属性
|
||||
for(c in table.columnList){
|
||||
// 如果是Extend类属性
|
||||
if(table.isExtendEntity && c.isExtendColumn){
|
||||
if(!isExtend){
|
||||
isExtend = true;
|
||||
%>
|
||||
private Extend extend; // 扩展字段
|
||||
<%
|
||||
}
|
||||
}
|
||||
// 如果不是基类属性
|
||||
else if(!@StringUtils.equalsIgnoreCase(c.columnName, 'id') && !c.isSuperColumn){
|
||||
// 父类对象
|
||||
if(table.parentExists && table.parentTableFkName == c.columnName){
|
||||
%>
|
||||
private ${@StringUtils.cap(table.parent.className)} ${c.simpleAttrName}; <% if (isNotBlank(c.comments)){ %>// ${c.comments} 父类<% } %>
|
||||
<%
|
||||
// 其它字段
|
||||
}else{
|
||||
%>
|
||||
private ${c.simpleAttrType} ${c.simpleAttrName}; <%if(isNotBlank(c.comments)){%>// ${c.comments}<%}%>
|
||||
<%
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 生成子表列表字段
|
||||
for(child in table.childList){
|
||||
%>
|
||||
private List<${@StringUtils.cap(child.className)}> ${@StringUtils.uncap(child.className)}List = ListUtils.newArrayList(); // 子表列表
|
||||
<%
|
||||
}
|
||||
|
||||
// 生成构造方法
|
||||
%>
|
||||
|
||||
public ${ClassName}() {
|
||||
this(<% for(pk in table.pkList){ %>${pkLP.index!=1?', ':''}null<% } %>);
|
||||
}
|
||||
|
||||
<%
|
||||
// 生成带主键参数的构造
|
||||
if (!table.parentExists){
|
||||
if (table.pkList.~size == 1){ %>
|
||||
public ${ClassName}(String id){
|
||||
super(id);
|
||||
}
|
||||
<% }else{ %>
|
||||
public ${ClassName}(<% for(pk in table.pkList){ %>${pkLP.index!=1?', ':''}${pk.simpleAttrType} ${pk.simpleAttrName}<% } %>){
|
||||
<% for(pk in table.pkList){ %>
|
||||
this.${pk.simpleAttrName} = ${pk.simpleAttrName};
|
||||
<% } %>
|
||||
}
|
||||
<%
|
||||
}
|
||||
}
|
||||
|
||||
// 生成父表参数的构造
|
||||
else{
|
||||
for(c in table.columnList){
|
||||
if(table.parentExists && table.parentTableFkName == c.columnName){
|
||||
%>
|
||||
|
||||
public ${ClassName}(${@StringUtils.cap(table.parent.className)} ${c.simpleAttrName}){
|
||||
this.${c.simpleAttrName} = ${c.simpleAttrName};
|
||||
}
|
||||
<%
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 如果是树实体,则输出相应方法
|
||||
if (table.isTreeEntity){
|
||||
%>
|
||||
|
||||
@Override
|
||||
public ${ClassName} getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParent(${ClassName} parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
<%
|
||||
}
|
||||
|
||||
// 生成属性的get和set方法
|
||||
isExtend = false;
|
||||
for(c in table.columnList){
|
||||
// 如果是Extend类属性
|
||||
if(c.isExtendColumn){
|
||||
if(!isExtend){
|
||||
isExtend = true;
|
||||
%>
|
||||
|
||||
public Extend getExtend() {
|
||||
return extend;
|
||||
}
|
||||
|
||||
public void setExtend(Extend extend) {
|
||||
this.extend = extend;
|
||||
}
|
||||
<%
|
||||
}
|
||||
// 如果不是基类属性
|
||||
}else if(!@StringUtils.equalsIgnoreCase(c.columnName, 'id') && !c.isSuperColumn){
|
||||
%>
|
||||
|
||||
<%
|
||||
for(a in c.simpleAnnotationList){
|
||||
%>
|
||||
@${a}
|
||||
<%
|
||||
}
|
||||
// 父类对象
|
||||
if(table.parentExists && table.parentTableFkName == c.columnName){
|
||||
%>
|
||||
public ${@StringUtils.cap(table.parent.className)} get${@StringUtils.cap(c.simpleAttrName)}() {
|
||||
return ${c.simpleAttrName};
|
||||
}
|
||||
|
||||
public void set${@StringUtils.cap(c.simpleAttrName)}(${@StringUtils.cap(table.parent.className)} ${c.simpleAttrName}) {
|
||||
this.${c.simpleAttrName} = ${c.simpleAttrName};
|
||||
}
|
||||
<%
|
||||
// 其它字段
|
||||
}else{
|
||||
%>
|
||||
public ${c.simpleAttrType} get${@StringUtils.cap(c.simpleAttrName)}() {
|
||||
return ${c.simpleAttrName};
|
||||
}
|
||||
|
||||
public void set${@StringUtils.cap(c.simpleAttrName)}(${c.simpleAttrType} ${c.simpleAttrName}) {
|
||||
this.${c.simpleAttrName} = ${c.simpleAttrName};
|
||||
}
|
||||
<%
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 生成条件字段get和set方法(范围类型)
|
||||
for(c in table.columnList){
|
||||
if(c.isQuery == "1" && c.queryType == "BETWEEN"){
|
||||
%>
|
||||
|
||||
public ${c.simpleAttrType} get${@StringUtils.cap(c.simpleAttrName)}_gte() {
|
||||
return sqlMap.getWhere().getValue("${c.columnName}", QueryType.GTE);
|
||||
}
|
||||
|
||||
public void set${@StringUtils.cap(c.simpleAttrName)}_gte(${c.simpleAttrType} ${c.simpleAttrName}) {
|
||||
sqlMap.getWhere().and("${c.columnName}", QueryType.GTE, ${c.simpleAttrName});
|
||||
}
|
||||
|
||||
public ${c.simpleAttrType} get${@StringUtils.cap(c.simpleAttrName)}_lte() {
|
||||
return sqlMap.getWhere().getValue("${c.columnName}", QueryType.LTE);
|
||||
}
|
||||
|
||||
public void set${@StringUtils.cap(c.simpleAttrName)}_lte(${c.simpleAttrType} ${c.simpleAttrName}) {
|
||||
sqlMap.getWhere().and("${c.columnName}", QueryType.LTE, ${c.simpleAttrName});
|
||||
}
|
||||
<%
|
||||
}
|
||||
}
|
||||
|
||||
// 生成子表列表get和set方法
|
||||
for(child in table.childList){
|
||||
%>
|
||||
|
||||
public List<${@StringUtils.cap(child.className)}> get${@StringUtils.cap(child.className)}List() {
|
||||
return ${@StringUtils.uncap(child.className)}List;
|
||||
}
|
||||
|
||||
public void set${@StringUtils.cap(child.className)}List(List<${@StringUtils.cap(child.className)}> ${@StringUtils.uncap(child.className)}List) {
|
||||
this.${@StringUtils.uncap(child.className)}List = ${@StringUtils.uncap(child.className)}List;
|
||||
}
|
||||
<% } %>
|
||||
|
||||
}]]>
|
||||
</content>
|
||||
</template>
|
||||
@@ -0,0 +1,216 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) 2013-Now http://jeesite.com All rights reserved. -->
|
||||
<template>
|
||||
<name>service</name>
|
||||
<filePath>src/main/java/${packageName}/${moduleName}/service/${subModuleName}</filePath>
|
||||
<fileName>${ClassName}Service.java</fileName>
|
||||
<content><![CDATA[
|
||||
/**
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
*/
|
||||
package ${packageName}.${moduleName}.service${isNotEmpty(subModuleName)?'.'+subModuleName:''};
|
||||
|
||||
import java.util.List;
|
||||
|
||||
<% if (table.childList.~size > 0){ %>
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
<% } %>
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.jeesite.common.entity.Page;
|
||||
import com.jeesite.common.service.${table.isTreeEntity?'Tree':'Crud'}Service;
|
||||
import ${packageName}.${moduleName}.entity${isNotEmpty(subModuleName)?'.'+subModuleName:''}.${ClassName};
|
||||
import ${packageName}.${moduleName}.dao${isNotEmpty(subModuleName)?'.'+subModuleName:''}.${ClassName}Dao;
|
||||
import ${packageName}.${moduleName}.api${isNotEmpty(subModuleName)?'.'+subModuleName:''}.${ClassName}ServiceApi;
|
||||
<% if(toBoolean(table.optionMap['isBpmForm'])){ %>
|
||||
import java.util.Map;
|
||||
import com.jeesite.common.lang.StringUtils;
|
||||
import com.jeesite.common.collect.MapUtils;
|
||||
import com.jeesite.common.service.ServiceException;
|
||||
import com.jeesite.modules.bpm.utils.client.BpmUtils;
|
||||
<% } %>
|
||||
<% if(toBoolean(table.optionMap['isImageUpload']) || toBoolean(table.optionMap['isFileUpload'])){ %>
|
||||
import com.jeesite.modules.file.utils.FileUploadUtils;
|
||||
<% } %>
|
||||
<% for (child in table.childList){ %>
|
||||
import ${packageName}.${moduleName}.entity${isNotEmpty(subModuleName)?'.'+subModuleName:''}.${@StringUtils.cap(child.className)};
|
||||
import ${packageName}.${moduleName}.dao${isNotEmpty(subModuleName)?'.'+subModuleName:''}.${@StringUtils.cap(child.className)}Dao;
|
||||
<% } %>
|
||||
|
||||
/**
|
||||
* ${functionName}Service
|
||||
* @author ${functionAuthor}
|
||||
* @version ${functionVersion}
|
||||
*/
|
||||
@Service
|
||||
@RestController
|
||||
@Transactional(readOnly=true)
|
||||
public class ${ClassName}Service extends ${table.isTreeEntity?'Tree':'Crud'}Service<${ClassName}Dao, ${ClassName}>
|
||||
implements ${ClassName}ServiceApi {
|
||||
<% for (child in table.childList){ %>
|
||||
|
||||
@Autowired
|
||||
private ${@StringUtils.cap(child.className)}Dao ${@StringUtils.uncap(child.className)}Dao;
|
||||
<% } %>
|
||||
|
||||
/**
|
||||
* 获取单条数据
|
||||
* @param ${className}
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public ${ClassName} get(${ClassName} ${className}) {
|
||||
<% if (table.childList.~size > 0){ %>
|
||||
${ClassName} entity = super.get(${className});
|
||||
if (entity != null){
|
||||
<% for (child in table.childList){ %>
|
||||
${@StringUtils.cap(child.className)} ${@StringUtils.uncap(child.className)} = new ${@StringUtils.cap(child.className)}(entity);
|
||||
${@StringUtils.uncap(child.className)}.setStatus(${@StringUtils.cap(child.className)}.STATUS_NORMAL);
|
||||
entity.set${@StringUtils.cap(child.className)}List(${@StringUtils.uncap(child.className)}Dao.findList(${@StringUtils.uncap(child.className)}));
|
||||
<% } %>
|
||||
}
|
||||
return entity;
|
||||
<% }else{ %>
|
||||
return super.get(${className});
|
||||
<% } %>
|
||||
}
|
||||
<% if(!table.isTreeEntity){ %>
|
||||
|
||||
/**
|
||||
* 查询分页数据
|
||||
* @param ${className} 查询条件
|
||||
* @param ${className}.page 分页对象
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Page<${ClassName}> findPage(${ClassName} ${className}) {
|
||||
return super.findPage(${className});
|
||||
}
|
||||
<% }else{ %>
|
||||
|
||||
/**
|
||||
* 查询列表数据
|
||||
* @param ${className}
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public List<${ClassName}> findList(${ClassName} ${className}) {
|
||||
return super.findList(${className});
|
||||
}
|
||||
<% } %>
|
||||
|
||||
/**
|
||||
* 保存数据(插入或更新)
|
||||
* @param ${className}
|
||||
*/
|
||||
@Override
|
||||
@Transactional(readOnly=false)
|
||||
public void save(${ClassName} ${className}) {
|
||||
<% if(toBoolean(table.optionMap['isBpmForm'])){ %>
|
||||
// 如果未设置状态,则指定状态为审核状态,以提交审核流程
|
||||
if (StringUtils.isBlank(${className}.getStatus())){
|
||||
${className}.setStatus(${ClassName}.STATUS_AUDIT);
|
||||
}
|
||||
|
||||
// 如果状态为正常,则代表不正常操作,可能前端进行了数据参数修改
|
||||
if (${ClassName}.STATUS_NORMAL.equals(${className}.getStatus())){
|
||||
throw new ServiceException(text("非法操作,前端数据被劫持!"));
|
||||
}
|
||||
|
||||
// 如果状态为草稿或审核状态,才可以保存业务数据
|
||||
if (${ClassName}.STATUS_DRAFT.equals(${className}.getStatus())
|
||||
|| ${ClassName}.STATUS_AUDIT.equals(${className}.getStatus())){
|
||||
super.save(${className});
|
||||
}
|
||||
|
||||
// 如果为审核状态,则进行审批流操作
|
||||
if (${ClassName}.STATUS_AUDIT.equals(${className}.getStatus())){
|
||||
|
||||
// 指定流程变量,作为流程条件,决定流转方向
|
||||
Map<String, Object> variables = MapUtils.newHashMap();
|
||||
//variables.put("leaveDays", ${className}.getLeaveDays());
|
||||
|
||||
// 如果流程实例为空,任务编号也为空,则:启动流程
|
||||
if (StringUtils.isBlank(${className}.getBpm().getProcInsId())
|
||||
&& StringUtils.isBlank(${className}.getBpm().getTaskId())){
|
||||
BpmUtils.start(${className}, "${table.optionMap['bpmFormKey']}", variables, null);
|
||||
}
|
||||
// 如果有任务信息,则:提交任务
|
||||
else{
|
||||
BpmUtils.complete(${className}, variables, null);
|
||||
}
|
||||
}
|
||||
<% }else{ %>
|
||||
super.save(${className});
|
||||
<% } %>
|
||||
<% if(toBoolean(table.optionMap['isImageUpload'])){ %>
|
||||
// 保存上传图片
|
||||
FileUploadUtils.saveFileUpload(${className}.getId(), "${className}_image");
|
||||
<% } %>
|
||||
<% if(toBoolean(table.optionMap['isFileUpload'])){ %>
|
||||
// 保存上传附件
|
||||
FileUploadUtils.saveFileUpload(${className}.getId(), "${className}_file");
|
||||
<% } %>
|
||||
<% for (child in table.childList) { %>
|
||||
// 保存 ${ClassName}子表
|
||||
for (${@StringUtils.cap(child.className)} ${@StringUtils.uncap(child.className)} : ${className}.get${@StringUtils.cap(child.className)}List()){
|
||||
if (!${@StringUtils.cap(child.className)}.STATUS_DELETE.equals(${@StringUtils.uncap(child.className)}.getStatus())){
|
||||
<%
|
||||
for(c in child.columnList){
|
||||
if (child.parentExists && child.parentTableFkName == c.columnName){
|
||||
%>
|
||||
${@StringUtils.uncap(child.className)}.set${@StringUtils.cap(c.simpleAttrName)}(${className});
|
||||
<%
|
||||
}
|
||||
}
|
||||
%>
|
||||
if (${@StringUtils.uncap(child.className)}.getIsNewRecord()){
|
||||
${@StringUtils.uncap(child.className)}Dao.insert(${@StringUtils.uncap(child.className)});
|
||||
}else{
|
||||
${@StringUtils.uncap(child.className)}Dao.update(${@StringUtils.uncap(child.className)});
|
||||
}
|
||||
}else{
|
||||
${@StringUtils.uncap(child.className)}Dao.delete(${@StringUtils.uncap(child.className)});
|
||||
}
|
||||
}
|
||||
<% } %>
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新状态
|
||||
* @param ${className}
|
||||
*/
|
||||
@Override
|
||||
@Transactional(readOnly=false)
|
||||
public void updateStatus(${ClassName} ${className}) {
|
||||
super.updateStatus(${className});
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除数据
|
||||
* @param ${className}
|
||||
*/
|
||||
@Override
|
||||
@Transactional(readOnly=false)
|
||||
public void delete(${ClassName} ${className}) {
|
||||
super.delete(${className});
|
||||
<% for (child in table.childList) { %>
|
||||
${@StringUtils.cap(child.className)} ${@StringUtils.uncap(child.className)} = new ${@StringUtils.cap(child.className)}();
|
||||
<%
|
||||
for(c in child.columnList){
|
||||
if (child.parentExists && child.parentTableFkName == c.columnName){
|
||||
%>
|
||||
${@StringUtils.uncap(child.className)}.set${@StringUtils.cap(c.simpleAttrName)}(${className});
|
||||
<%
|
||||
}
|
||||
}
|
||||
%>
|
||||
${@StringUtils.uncap(child.className)}Dao.deleteByEntity(${@StringUtils.uncap(child.className)});
|
||||
<% } %>
|
||||
}
|
||||
|
||||
}]]>
|
||||
</content>
|
||||
</template>
|
||||
@@ -91,6 +91,11 @@ $('#dataGrid').dataGrid({
|
||||
actions.push('<a href="\${ctx}/${urlPrefix}/form?parentCode='+row.id+'" class="btnList" title="\${text("新增下级${functionNameSimple}")}"><i class="fa fa-plus-square"></i></a> ');
|
||||
<% } %>
|
||||
\<% } %>
|
||||
<% if(toBoolean(table.optionMap['isBpmForm'])){ %>
|
||||
if (row.status != Global.STATUS_DRAFT){
|
||||
actions.push('<a href="\${ctx}/bpm/bpmRuntime/trace?formKey=${table.optionMap['bpmFormKey']}&bizKey='+row.id+'" class="btnList" title="\${text("流程追踪")}" data-layer="true"><i class="fa fa-file-picture-o"></i></a> ');
|
||||
}
|
||||
<% } %>
|
||||
<% } %>
|
||||
return actions.join('');
|
||||
}}
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
<script>
|
||||
var selectData = \${isNotBlank(selectData!) ? selectData! : "{\}"},
|
||||
selectNum = 0, dataGrid = $('#dataGrid').dataGrid({
|
||||
searchForm: $("#searchForm"),
|
||||
columnModel: [
|
||||
<%
|
||||
// 是否是第一列
|
||||
var firstColumn = true;
|
||||
var firstColumnName = "";
|
||||
// 生成树表的节点列
|
||||
if(table.isTreeEntity){
|
||||
for(c in table.columnList){
|
||||
if(c.attrName == table.treeViewNameAttrName){
|
||||
%>
|
||||
{header:'\${text("${c.columnLabel}")}', name:'${c.attrName}', index:'a.${c.columnName}', width:250, align:"left", frozen:true, formatter: function(val, obj, row, act){
|
||||
return '( '+row.${table.treeViewCodeAttrName}+' ) '+(val||row.id);
|
||||
}},
|
||||
<%
|
||||
firstColumn = false;
|
||||
firstColumnName = c.attrName;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
%>
|
||||
<%
|
||||
for(c in table.columnList){
|
||||
if(c.isList == "1"){
|
||||
// 如果是树结构的字段,则自动忽略
|
||||
if(table.isTreeEntity && @StringUtils.inString(c.columnName, 'parent_code',
|
||||
'parent_codes', 'tree_sorts', 'tree_leaf', 'tree_level', 'tree_names')
|
||||
&& c.attrName != table.treeViewCodeAttrName
|
||||
&& c.attrName != table.treeViewNameAttrName){
|
||||
}
|
||||
// 如果是首列,则输出带链接的列
|
||||
else if(firstColumn){
|
||||
firstColumn = false;
|
||||
firstColumnName = c.attrName;
|
||||
%>
|
||||
{header:'\${text("${c.columnLabel}")}', name:'${c.attrName}', index:'a.${c.columnName}', width:150, align:"left", frozen:true, formatter: function(val, obj, row, act){
|
||||
return (val||row.id);
|
||||
}},
|
||||
<% }else if(c.showType == 'select' || c.showType == 'select_multiple' || c.showType == 'checkbox' || c.showType == 'radio'){ %>
|
||||
{header:'\${text("${c.columnLabel}")}', name:'${c.attrName}', index:'a.${c.columnName}', width:150, align:"center", formatter: function(val, obj, row, act){
|
||||
return js.getDictLabel(\${@DictUtils.getDictListJson('${c.optionMap['dictType']}')}, val, '\${text("未知")}', true);
|
||||
}},
|
||||
<% }else if(c.showType == "userselect" || c.showType == "officeselect" || c.showType == "areaselect"){ %>
|
||||
{header:'\${text("${c.columnLabel}")}', name:'${c.attrName2}', index:'a.${c.columnName}', width:150, align:"center"},
|
||||
<% }else{
|
||||
if (@StringUtils.inString(c.attrType, 'java.util.Date', 'Integer', 'Long')){
|
||||
%>
|
||||
{header:'\${text("${c.columnLabel}")}', name:'${c.attrName}', index:'a.${c.columnName}', width:150, align:"center"},
|
||||
<%
|
||||
}else if (@StringUtils.inString(c.attrType, 'Float', 'Double')){
|
||||
%>
|
||||
{header:'\${text("${c.columnLabel}")}', name:'${c.attrName}', index:'a.${c.columnName}', width:150, align:"right", formatter: function(val, obj, row, act){
|
||||
return js.formatNumber(val, 2, false, ''); // 数值类型格式化 (原始数值, 小数位数, 是否千分位, 默认值,金额情况下设置0.00);
|
||||
}},
|
||||
<%
|
||||
}else {
|
||||
%>
|
||||
{header:'\${text("${c.columnLabel}")}', name:'${c.attrName}', index:'a.${c.columnName}', width:150, align:"left"},
|
||||
<%
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
%>
|
||||
{header:'行数据', name:'rowData', hidden:true, formatter: function(val, obj, row, act){
|
||||
return JSON.stringify(row);
|
||||
}}
|
||||
],
|
||||
<% if(table.isTreeEntity){ %>
|
||||
treeGrid: true, // 启用树结构表格
|
||||
defaultExpandLevel: 0, // 默认展开的层次
|
||||
expandNodeClearPostData: '<%
|
||||
for(c in table.columnList){
|
||||
if(c.isQuery == "1" && !c.isTreeEntityColumn && c.attrName != 'status'){
|
||||
print(c.attrName + ',');
|
||||
}
|
||||
} %>', // 展开节点清理请求参数数据(一般设置查询条件的字段属性,否则在查询后,不能展开子节点数据)
|
||||
<% } %>
|
||||
autoGridHeight: function(){
|
||||
var height = $(window).height() - $('#searchForm').height() - $('#dataGridPage').height() - 74;
|
||||
$('.tags-input').height($('.ui-jqgrid').height() - 10);
|
||||
return height;
|
||||
},
|
||||
showCheckbox: '\${parameter.checkbox}' == 'true',
|
||||
multiboxonly: false, // 单击复选框时再多选
|
||||
ajaxSuccess: function(data){
|
||||
$.each(selectData, function(key, value){
|
||||
dataGrid.dataGrid('setSelectRow', key);
|
||||
});
|
||||
initSelectTag();
|
||||
},
|
||||
onSelectRow: function(id, isSelect, event){
|
||||
if ('\${parameter.checkbox}' == 'true'){
|
||||
if(isSelect){
|
||||
selectData[id] = JSON.parse(dataGrid.dataGrid('getRowData', id).rowData);
|
||||
}else{
|
||||
delete selectData[id];
|
||||
}
|
||||
}else{
|
||||
selectData = {};
|
||||
selectData[id] = JSON.parse(dataGrid.dataGrid('getRowData', id).rowData);
|
||||
}
|
||||
initSelectTag();
|
||||
},
|
||||
onSelectAll: function(ids, isSelect){
|
||||
if ('\${parameter.checkbox}' == 'true'){
|
||||
for (var i=0; i<ids.length; i++){
|
||||
if(isSelect){
|
||||
selectData[ids[i]] = JSON.parse(dataGrid.dataGrid('getRowData', ids[i]).rowData);
|
||||
}else{
|
||||
delete selectData[ids[i]];
|
||||
}
|
||||
}
|
||||
}
|
||||
initSelectTag();
|
||||
},
|
||||
ondblClickRow: function(id, rownum, colnum, event){
|
||||
if ('\${parameter.checkbox}' != 'true'){
|
||||
js.layer.$('#' + window.name).closest('.layui-layer')
|
||||
.find(".layui-layer-btn0").trigger("click");
|
||||
}
|
||||
initSelectTag();
|
||||
}
|
||||
});
|
||||
function initSelectTag(){
|
||||
selectNum = 0;
|
||||
var html = [];
|
||||
$.each(selectData, function(key, value){
|
||||
selectNum ++;
|
||||
html.push('<span class="tag" id="'+key+'_tags-input"><span>'+(value.${firstColumnName}||value.id)+' </span>'
|
||||
+ '<a href="#" onclick="removeSelectTag(\''+key+'\');" title="\${text("取消选择")}">x</a></span>');
|
||||
});
|
||||
html.unshift('<div class="title">\${text("当前已选择 {0\} 项", "<span id=\"selectNum\">'+selectNum+'</span>")}:</div>');
|
||||
$('#selectData').empty().append(html.join(''));
|
||||
}
|
||||
function removeSelectTag(key){
|
||||
delete selectData[key];
|
||||
dataGrid.dataGrid('resetSelection', key);
|
||||
$('#selectNum').html(--selectNum);
|
||||
$('#'+key+'_tags-input').remove();
|
||||
}
|
||||
function getSelectData(){
|
||||
return selectData;
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) 2013-Now http://jeesite.com All rights reserved. -->
|
||||
<template>
|
||||
<name>deploy</name>
|
||||
<filePath>${module.moduleCode}/bin</filePath>
|
||||
<fileName>deploy.bat</fileName>
|
||||
<charset>GBK</charset>
|
||||
<content><![CDATA[@echo off
|
||||
rem /**
|
||||
rem * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
rem *
|
||||
rem * Author: ThinkGem@163.com
|
||||
rem */
|
||||
echo.
|
||||
echo [信息] 部署工程版本到Nexus服务器。
|
||||
echo.
|
||||
|
||||
%~d0
|
||||
cd %~dp0
|
||||
|
||||
cd ..
|
||||
call mvn clean deploy -Dmaven.test.skip=true -Pdeploy
|
||||
|
||||
cd bin
|
||||
cmd /c msg %username% /time:0 /w "部署完成..."
|
||||
pause]]>
|
||||
</content>
|
||||
</template>
|
||||
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) 2013-Now http://jeesite.com All rights reserved. -->
|
||||
<template>
|
||||
<name>deploy</name>
|
||||
<filePath>${module.moduleCode}/bin</filePath>
|
||||
<fileName>deploy.sh</fileName>
|
||||
<content><![CDATA[#!/bin/sh
|
||||
# /**
|
||||
# * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
# *
|
||||
# * Author: ThinkGem@163.com
|
||||
# *
|
||||
# */
|
||||
echo ""
|
||||
echo "[信息] 部署工程版本到Nexus服务器。"
|
||||
echo ""
|
||||
|
||||
cd ..
|
||||
mvn clean deploy -Dmaven.test.skip=true -Pdeploy
|
||||
|
||||
cd bin]]>
|
||||
</content>
|
||||
</template>
|
||||
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) 2013-Now http://jeesite.com All rights reserved. -->
|
||||
<template>
|
||||
<name>package</name>
|
||||
<filePath>${module.moduleCode}/bin</filePath>
|
||||
<fileName>package.bat</fileName>
|
||||
<charset>GBK</charset>
|
||||
<content><![CDATA[@echo off
|
||||
rem /**
|
||||
rem * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
rem *
|
||||
rem * Author: ThinkGem@163.com
|
||||
rem */
|
||||
echo.
|
||||
echo [信息] 打包安装工程,生成jar包文件。
|
||||
echo.
|
||||
|
||||
%~d0
|
||||
cd %~dp0
|
||||
|
||||
cd ..
|
||||
call mvn clean install -Dmaven.test.skip=true -Ppackage
|
||||
|
||||
cd bin
|
||||
cmd /c msg %username% /time:0 /w "打包完成..."
|
||||
pause]]>
|
||||
</content>
|
||||
</template>
|
||||
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) 2013-Now http://jeesite.com All rights reserved. -->
|
||||
<template>
|
||||
<name>package</name>
|
||||
<filePath>${module.moduleCode}/bin</filePath>
|
||||
<fileName>package.sh</fileName>
|
||||
<content><![CDATA[#!/bin/sh
|
||||
# /**
|
||||
# * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
# *
|
||||
# * Author: ThinkGem@163.com
|
||||
# *
|
||||
# */
|
||||
echo ""
|
||||
echo "[信息] 打包Web工程,生成war/jar包文件。"
|
||||
echo ""
|
||||
|
||||
cd ..
|
||||
mvn clean install -Dmaven.test.skip=true -Ppackage
|
||||
|
||||
cd bin]]>
|
||||
</content>
|
||||
</template>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) 2013-Now http://jeesite.com All rights reserved. -->
|
||||
<template>
|
||||
<name>pom</name>
|
||||
<filePath>${module.moduleCode}</filePath>
|
||||
<fileName>pom.xml</fileName>
|
||||
<charset></charset>
|
||||
<content><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>com.jeesite</groupId>
|
||||
<artifactId>jeesite-parent</artifactId>
|
||||
<version>${jeesiteVersion}-SNAPSHOT</version>
|
||||
<relativePath>../../parent/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>jeesite-module-${module.moduleCode}</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>JeeSite Module ${module.moduleName}</name>
|
||||
<url>http://jeesite.com</url>
|
||||
<inceptionYear>2013-Now</inceptionYear>
|
||||
|
||||
<properties>
|
||||
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.jeesite</groupId>
|
||||
<artifactId>jeesite-module-core</artifactId>
|
||||
<version>\${project.parent.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
|
||||
</plugins>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
|
||||
<developers>
|
||||
<developer>
|
||||
<id>thinkgem</id>
|
||||
<name>WangZhen</name>
|
||||
<email>thinkgem at 163.com</email>
|
||||
<roles><role>Project lead</role></roles>
|
||||
<timezone>+8</timezone>
|
||||
</developer>
|
||||
</developers>
|
||||
|
||||
<organization>
|
||||
<name>JeeSite</name>
|
||||
<url>http://jeesite.com</url>
|
||||
</organization>
|
||||
|
||||
</project>
|
||||
]]>
|
||||
</content>
|
||||
</template>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) 2013-Now http://jeesite.com All rights reserved. -->
|
||||
<template>
|
||||
<name>package</name>
|
||||
<filePath>${module.moduleCode}/src/main/java/com/jeesite/modules/${module.moduleCode}</filePath>
|
||||
<fileName></fileName>
|
||||
<content><![CDATA[
|
||||
|
||||
]]>
|
||||
</content>
|
||||
</template>
|
||||
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) 2013-Now http://jeesite.com All rights reserved. -->
|
||||
<template>
|
||||
<name>jeesite</name>
|
||||
<filePath>${module.moduleCode}/src/main/resources/config</filePath>
|
||||
<fileName>jeesite-${module.moduleCode}.yml</fileName>
|
||||
<content><![CDATA[
|
||||
# 温馨提示:不建议直接修改此文件,为了平台升级方便,建议将需要修改的参数值,复制到application.yml里进行覆盖该参数值。
|
||||
|
||||
#${module.moduleCode}:
|
||||
# enabled: true
|
||||
|
||||
]]>
|
||||
</content>
|
||||
</template>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) 2013-Now http://jeesite.com All rights reserved. -->
|
||||
<template>
|
||||
<name>versions</name>
|
||||
<filePath>${module.moduleCode}/src/main/resources/db/upgrade/${module.moduleCode}</filePath>
|
||||
<fileName>versions</fileName>
|
||||
<content><![CDATA[${module.currentVersion}]]>
|
||||
</content>
|
||||
</template>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) 2013-Now http://jeesite.com All rights reserved. -->
|
||||
<template>
|
||||
<name>static</name>
|
||||
<filePath>${module.moduleCode}/src/main/resources/static/modules/${module.moduleCode}</filePath>
|
||||
<fileName></fileName>
|
||||
<content><![CDATA[
|
||||
|
||||
]]>
|
||||
</content>
|
||||
</template>
|
||||
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) 2013-Now http://jeesite.com All rights reserved. -->
|
||||
<template>
|
||||
<name>deploy</name>
|
||||
<filePath>${module.moduleCode}/${module.moduleCode}-client/bin</filePath>
|
||||
<fileName>deploy.bat</fileName>
|
||||
<charset>GBK</charset>
|
||||
<content><![CDATA[@echo off
|
||||
rem /**
|
||||
rem * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
rem *
|
||||
rem * Author: ThinkGem@163.com
|
||||
rem */
|
||||
echo.
|
||||
echo [信息] 部署工程版本到Nexus服务器。
|
||||
echo.
|
||||
|
||||
%~d0
|
||||
cd %~dp0
|
||||
|
||||
cd ..
|
||||
call mvn clean deploy -Dmaven.test.skip=true -Pdeploy
|
||||
|
||||
cd bin
|
||||
cmd /c msg %username% /time:0 /w "部署完成..."
|
||||
pause]]>
|
||||
</content>
|
||||
</template>
|
||||
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) 2013-Now http://jeesite.com All rights reserved. -->
|
||||
<template>
|
||||
<name>deploy</name>
|
||||
<filePath>${module.moduleCode}/${module.moduleCode}-client/bin</filePath>
|
||||
<fileName>deploy.sh</fileName>
|
||||
<content><![CDATA[#!/bin/sh
|
||||
# /**
|
||||
# * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
# *
|
||||
# * Author: ThinkGem@163.com
|
||||
# *
|
||||
# */
|
||||
echo ""
|
||||
echo "[信息] 部署工程版本到Nexus服务器。"
|
||||
echo ""
|
||||
|
||||
cd ..
|
||||
mvn clean deploy -Dmaven.test.skip=true -Pdeploy
|
||||
|
||||
cd bin]]>
|
||||
</content>
|
||||
</template>
|
||||
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) 2013-Now http://jeesite.com All rights reserved. -->
|
||||
<template>
|
||||
<name>package</name>
|
||||
<filePath>${module.moduleCode}/${module.moduleCode}-client/bin</filePath>
|
||||
<fileName>package.bat</fileName>
|
||||
<charset>GBK</charset>
|
||||
<content><![CDATA[@echo off
|
||||
rem /**
|
||||
rem * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
rem *
|
||||
rem * Author: ThinkGem@163.com
|
||||
rem */
|
||||
echo.
|
||||
echo [信息] 打包安装工程,生成jar包文件。
|
||||
echo.
|
||||
|
||||
%~d0
|
||||
cd %~dp0
|
||||
|
||||
cd ..
|
||||
call mvn clean install -Dmaven.test.skip=true -Ppackage
|
||||
|
||||
cd bin
|
||||
cmd /c msg %username% /time:0 /w "打包完成..."
|
||||
pause]]>
|
||||
</content>
|
||||
</template>
|
||||
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) 2013-Now http://jeesite.com All rights reserved. -->
|
||||
<template>
|
||||
<name>package</name>
|
||||
<filePath>${module.moduleCode}/${module.moduleCode}-client/bin</filePath>
|
||||
<fileName>package.sh</fileName>
|
||||
<content><![CDATA[#!/bin/sh
|
||||
# /**
|
||||
# * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
# *
|
||||
# * Author: ThinkGem@163.com
|
||||
# *
|
||||
# */
|
||||
echo ""
|
||||
echo "[信息] 打包Web工程,生成war/jar包文件。"
|
||||
echo ""
|
||||
|
||||
cd ..
|
||||
mvn clean install -Dmaven.test.skip=true -Ppackage
|
||||
|
||||
cd bin]]>
|
||||
</content>
|
||||
</template>
|
||||
@@ -0,0 +1,66 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) 2013-Now http://jeesite.com All rights reserved. -->
|
||||
<template>
|
||||
<name>pom</name>
|
||||
<filePath>${module.moduleCode}/${module.moduleCode}-client</filePath>
|
||||
<fileName>pom.xml</fileName>
|
||||
<charset></charset>
|
||||
<content><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>com.jeesite</groupId>
|
||||
<artifactId>jeesite-cloud-parent</artifactId>
|
||||
<version>${jeesiteVersion}-SNAPSHOT</version>
|
||||
<relativePath>../../../parent/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>jeesite-cloud-module-${module.moduleCode}-client</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>JeeSite Cloud Module ${module.moduleName} Client</name>
|
||||
<url>http://jeesite.com</url>
|
||||
<inceptionYear>2013-Now</inceptionYear>
|
||||
|
||||
<properties>
|
||||
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- 云客户端 -->
|
||||
<dependency>
|
||||
<groupId>com.jeesite</groupId>
|
||||
<artifactId>jeesite-cloud-framework</artifactId>
|
||||
<version>\${project.parent.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<developers>
|
||||
<developer>
|
||||
<id>thinkgem</id>
|
||||
<name>WangZhen</name>
|
||||
<email>thinkgem at 163.com</email>
|
||||
<roles><role>Project lead</role></roles>
|
||||
<timezone>+8</timezone>
|
||||
</developer>
|
||||
</developers>
|
||||
|
||||
<organization>
|
||||
<name>JeeSite</name>
|
||||
<url>http://jeesite.com</url>
|
||||
</organization>
|
||||
|
||||
</project>
|
||||
]]>
|
||||
</content>
|
||||
</template>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) 2013-Now http://jeesite.com All rights reserved. -->
|
||||
<template>
|
||||
<name>package</name>
|
||||
<filePath>${module.moduleCode}/${module.moduleCode}-client/src/main/java/com/jeesite/modules/${module.moduleCode}</filePath>
|
||||
<fileName></fileName>
|
||||
<content><![CDATA[
|
||||
|
||||
]]>
|
||||
</content>
|
||||
</template>
|
||||
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) 2013-Now http://jeesite.com All rights reserved. -->
|
||||
<template>
|
||||
<name>docker-bulid</name>
|
||||
<filePath>${module.moduleCode}/${module.moduleCode}/bin</filePath>
|
||||
<fileName>docker-bulid.bat</fileName>
|
||||
<charset>GBK</charset>
|
||||
<content><![CDATA[@echo off
|
||||
rem /**
|
||||
rem * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
rem *
|
||||
rem * Author: ThinkGem@163.com
|
||||
rem */
|
||||
echo.
|
||||
echo [信息] 打包Web工程,导入到Docker服务。
|
||||
echo.
|
||||
|
||||
%~d0
|
||||
cd %~dp0
|
||||
|
||||
cd ..
|
||||
call mvn clean package docker:stop docker:remove docker:build docker:run -Dmaven.test.skip=true -U
|
||||
|
||||
cd bin
|
||||
pause]]>
|
||||
</content>
|
||||
</template>
|
||||
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) 2013-Now http://jeesite.com All rights reserved. -->
|
||||
<template>
|
||||
<name>docker-bulid</name>
|
||||
<filePath>${module.moduleCode}/${module.moduleCode}/bin</filePath>
|
||||
<fileName>docker-bulid.sh</fileName>
|
||||
<content><![CDATA[#!/bin/sh
|
||||
# /**
|
||||
# * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
# *
|
||||
# * Author: ThinkGem@163.com
|
||||
# *
|
||||
# */
|
||||
echo ""
|
||||
echo "[信息] 使用 Spring Boot Docker 编译 Web 工程。"
|
||||
echo ""
|
||||
|
||||
cd ..
|
||||
mvn clean package docker:stop docker:remove docker:build docker:run -Dmaven.test.skip=true -U
|
||||
|
||||
cd bin]]>
|
||||
</content>
|
||||
</template>
|
||||
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) 2013-Now http://jeesite.com All rights reserved. -->
|
||||
<template>
|
||||
<name>Dockerfile</name>
|
||||
<filePath>${module.moduleCode}/${module.moduleCode}/bin/docker</filePath>
|
||||
<fileName>Dockerfile</fileName>
|
||||
<content><![CDATA[FROM frolvlad/alpine-java:jdk8-slim
|
||||
MAINTAINER ThinkGem@163.com
|
||||
ENV TZ "Asia/Shanghai"
|
||||
ENV LANG C.UTF-8
|
||||
VOLUME /tmp
|
||||
|
||||
WORKDIR /app
|
||||
ADD ./maven/web.war ./app.war
|
||||
|
||||
RUN jar -xvf app.war
|
||||
#RUN chmod -R 755 ./*
|
||||
|
||||
WORKDIR /app/WEB-INF
|
||||
ADD ./app.yml ./classes/config/bootstrap-prod.yml
|
||||
#ADD jeesite.lic ./
|
||||
|
||||
#ENV JAVA_OPTS "-Xms256m -Xmx1024m"
|
||||
ENV JAVA_OPTS "$JAVA_OPTS -Dspring.profiles.active=prod"
|
||||
|
||||
ENTRYPOINT java $JAVA_OPTS -cp /app $JAVA_OPTS org.springframework.boot.loader.WarLauncher
|
||||
|
||||
EXPOSE 8983
|
||||
|
||||
#docker run -p 8983:8983 com.jeesite/jeesite-cloud-module-${module.moduleCode}:4.2
|
||||
]]>
|
||||
</content>
|
||||
</template>
|
||||
@@ -0,0 +1,61 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) 2013-Now http://jeesite.com All rights reserved. -->
|
||||
<template>
|
||||
<name>app</name>
|
||||
<filePath>${module.moduleCode}/${module.moduleCode}/bin/docker</filePath>
|
||||
<fileName>app</fileName>
|
||||
<content><![CDATA[
|
||||
#======================================#
|
||||
#========== Cloud settings ============#
|
||||
#======================================#
|
||||
|
||||
# 服务注册
|
||||
eureka:
|
||||
|
||||
# 实例设置
|
||||
instance:
|
||||
# 实例主机名称
|
||||
hostname: 10.0.2.15
|
||||
# 实例是否允许使用IP
|
||||
preferIpAddress: false
|
||||
|
||||
# 客户端设置
|
||||
client:
|
||||
# 注册中心地址(集群时指定另外一个注册中心地址)
|
||||
serviceUrl.defaultZone: http://10.0.2.15:8970/eureka/
|
||||
|
||||
#======================================#
|
||||
#========== Spring settings ===========#
|
||||
#======================================#
|
||||
|
||||
spring:
|
||||
|
||||
# 分布式配置中心
|
||||
cloud:
|
||||
config:
|
||||
discovery:
|
||||
enabled: true
|
||||
serviceId: jeesite-cloud-config
|
||||
|
||||
# Consul 服务发现
|
||||
consul:
|
||||
host: 10.0.2.15
|
||||
port: 8500
|
||||
discovery:
|
||||
hostname: 10.0.2.15
|
||||
preferIpAddress: false
|
||||
|
||||
# 服务注册和配置
|
||||
nacos:
|
||||
discovery:
|
||||
server-addr: 10.0.2.15:8848
|
||||
config:
|
||||
server-addr: 10.0.2.15:8848
|
||||
file-extension: yml
|
||||
group: jeesite-cloud-42
|
||||
ext-config:
|
||||
- data-id: application.yml
|
||||
group: jeesite-cloud-42
|
||||
]]>
|
||||
</content>
|
||||
</template>
|
||||
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) 2013-Now http://jeesite.com All rights reserved. -->
|
||||
<template>
|
||||
<name>package</name>
|
||||
<filePath>${module.moduleCode}/${module.moduleCode}/bin</filePath>
|
||||
<fileName>package.bat</fileName>
|
||||
<charset>GBK</charset>
|
||||
<content><![CDATA[@echo off
|
||||
rem /**
|
||||
rem * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
rem *
|
||||
rem * Author: ThinkGem@163.com
|
||||
rem */
|
||||
echo.
|
||||
echo [信息] 打包Web工程,生成war/jar包文件。
|
||||
echo.
|
||||
|
||||
%~d0
|
||||
cd %~dp0
|
||||
|
||||
cd ..
|
||||
call mvn clean package spring-boot:repackage -Dmaven.test.skip=true -U
|
||||
|
||||
cd bin
|
||||
cmd /c msg %username% /time:0 /w "打包完成..."
|
||||
pause]]>
|
||||
</content>
|
||||
</template>
|
||||
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) 2013-Now http://jeesite.com All rights reserved. -->
|
||||
<template>
|
||||
<name>package</name>
|
||||
<filePath>${module.moduleCode}/${module.moduleCode}/bin</filePath>
|
||||
<fileName>package.sh</fileName>
|
||||
<content><![CDATA[#!/bin/sh
|
||||
# /**
|
||||
# * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
# *
|
||||
# * Author: ThinkGem@163.com
|
||||
# *
|
||||
# */
|
||||
echo ""
|
||||
echo "[信息] 打包Web工程,生成war/jar包文件。"
|
||||
echo ""
|
||||
|
||||
cd ..
|
||||
mvn clean package spring-boot:repackage -Dmaven.test.skip=true -U
|
||||
|
||||
cd bin]]>
|
||||
</content>
|
||||
</template>
|
||||
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) 2013-Now http://jeesite.com All rights reserved. -->
|
||||
<template>
|
||||
<name>run-tomcat</name>
|
||||
<filePath>${module.moduleCode}/${module.moduleCode}/bin</filePath>
|
||||
<fileName>run-tomcat.bat</fileName>
|
||||
<charset>GBK</charset>
|
||||
<content><![CDATA[@echo off
|
||||
rem /**
|
||||
rem * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
rem *
|
||||
rem * Author: ThinkGem@163.com
|
||||
rem */
|
||||
echo.
|
||||
echo [信息] 使用 Spring Boot Tomcat 运行 Web 工程。
|
||||
echo.
|
||||
|
||||
%~d0
|
||||
cd %~dp0
|
||||
|
||||
cd ..
|
||||
title %cd%
|
||||
set "MAVEN_OPTS=%MAVEN_OPTS% -Xms512m -Xmx1024m"
|
||||
call mvn clean spring-boot:run -Dmaven.test.skip=true
|
||||
|
||||
pause]]>
|
||||
</content>
|
||||
</template>
|
||||
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) 2013-Now http://jeesite.com All rights reserved. -->
|
||||
<template>
|
||||
<name>run-tomcat</name>
|
||||
<filePath>${module.moduleCode}/${module.moduleCode}/bin</filePath>
|
||||
<fileName>run-tomcat.sh</fileName>
|
||||
<content><![CDATA[#!/bin/sh
|
||||
# /**
|
||||
# * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
# *
|
||||
# * Author: ThinkGem@163.com
|
||||
# *
|
||||
# */
|
||||
echo ""
|
||||
echo "[信息] 使用 Spring Boot Tomcat 运行 Web 工程。"
|
||||
echo ""
|
||||
|
||||
cd ..
|
||||
MAVEN_OPTS="$MAVEN_OPTS -Xms512m -Xmx1024m"
|
||||
mvn clean spring-boot:run -Dmaven.test.skip=true]]>
|
||||
</content>
|
||||
</template>
|
||||
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) 2013-Now http://jeesite.com All rights reserved. -->
|
||||
<template>
|
||||
<name>run-web</name>
|
||||
<filePath>${module.moduleCode}/${module.moduleCode}/bin</filePath>
|
||||
<fileName>run-web.bat</fileName>
|
||||
<charset>GBK</charset>
|
||||
<content><![CDATA[@echo off
|
||||
rem /**
|
||||
rem * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
rem *
|
||||
rem * Author: ThinkGem@163.com
|
||||
rem */
|
||||
echo.
|
||||
echo [信息] 打包Web工程,并运行Web工程。
|
||||
echo.
|
||||
|
||||
%~d0
|
||||
cd %~dp0
|
||||
|
||||
rem 打包Web工程(开始)
|
||||
cd ..
|
||||
call mvn clean package spring-boot:repackage -Dmaven.test.skip=true -U
|
||||
cd target
|
||||
rem 打包Web工程(结束)
|
||||
|
||||
|
||||
rem 根据情况修改 web.jar 为您的 jar 包名称
|
||||
mkdir web
|
||||
copy web.war web
|
||||
cd web
|
||||
jar -xvf web.war
|
||||
cd WEB-INF
|
||||
call startup.bat
|
||||
|
||||
pause]]>
|
||||
</content>
|
||||
</template>
|
||||
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) 2013-Now http://jeesite.com All rights reserved. -->
|
||||
<template>
|
||||
<name>run-web</name>
|
||||
<filePath>${module.moduleCode}/${module.moduleCode}/bin</filePath>
|
||||
<fileName>run-web.sh</fileName>
|
||||
<content><![CDATA[#!/bin/sh
|
||||
# /**
|
||||
# * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
# *
|
||||
# * Author: ThinkGem@163.com
|
||||
# *
|
||||
# */
|
||||
echo ""
|
||||
echo "[信息] 打包Web工程,并运行Web工程。"
|
||||
echo ""
|
||||
|
||||
# 打包Web工程(开始)
|
||||
cd ..
|
||||
mvn clean package spring-boot:repackage -Dmaven.test.skip=true -U
|
||||
cd target
|
||||
# 打包Web工程(结束)
|
||||
|
||||
|
||||
# 根据情况修改 web.jar 为您的 jar 包名称
|
||||
mkdir web
|
||||
cp web.war ./web
|
||||
cd web
|
||||
jar -xvf web.war
|
||||
cd WEB-INF
|
||||
exec ./startup.sh
|
||||
]]>
|
||||
</content>
|
||||
</template>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) 2013-Now http://jeesite.com All rights reserved. -->
|
||||
<template>
|
||||
<name>pom</name>
|
||||
<filePath>${module.moduleCode}</filePath>
|
||||
<fileName>pom.xml</fileName>
|
||||
<charset></charset>
|
||||
<content><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>com.jeesite</groupId>
|
||||
<artifactId>jeesite-parent</artifactId>
|
||||
<version>${jeesiteVersion}-SNAPSHOT</version>
|
||||
<relativePath>../../parent/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>jeesite-module-${module.moduleCode}</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>JeeSite Module ${module.moduleName}</name>
|
||||
<url>http://jeesite.com</url>
|
||||
<inceptionYear>2013-Now</inceptionYear>
|
||||
|
||||
<properties>
|
||||
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.jeesite</groupId>
|
||||
<artifactId>jeesite-module-core</artifactId>
|
||||
<version>\${project.parent.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
|
||||
</plugins>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
|
||||
<developers>
|
||||
<developer>
|
||||
<id>thinkgem</id>
|
||||
<name>WangZhen</name>
|
||||
<email>thinkgem at 163.com</email>
|
||||
<roles><role>Project lead</role></roles>
|
||||
<timezone>+8</timezone>
|
||||
</developer>
|
||||
</developers>
|
||||
|
||||
<organization>
|
||||
<name>JeeSite</name>
|
||||
<url>http://jeesite.com</url>
|
||||
</organization>
|
||||
|
||||
</project>
|
||||
]]>
|
||||
</content>
|
||||
</template>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) 2013-Now http://jeesite.com All rights reserved. -->
|
||||
<template>
|
||||
<name>package</name>
|
||||
<filePath>${module.moduleCode}/${module.moduleCode}/src/main/java/com/jeesite/modules/${module.moduleCode}</filePath>
|
||||
<fileName></fileName>
|
||||
<content><![CDATA[
|
||||
|
||||
]]>
|
||||
</content>
|
||||
</template>
|
||||
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) 2013-Now http://jeesite.com All rights reserved. -->
|
||||
<template>
|
||||
<name>start-class</name>
|
||||
<filePath>${module.moduleCode}/${module.moduleCode}/src/main/java/com/jeesite/modules</filePath>
|
||||
<fileName>${@StringUtils.cap(module.moduleCode)}Application.java</fileName>
|
||||
<content><![CDATA[/**
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
*/
|
||||
package com.jeesite.modules;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
|
||||
import org.springframework.cloud.client.SpringCloudApplication;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
|
||||
/**
|
||||
* Application
|
||||
* @author ThinkGem
|
||||
* @version ${@DateUtils.getDate()}
|
||||
*/
|
||||
@SpringCloudApplication
|
||||
@EnableFeignClients(basePackages={"com.jeesite.modules"})
|
||||
public class ${@StringUtils.cap(module.moduleCode)}Application extends SpringBootServletInitializer {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(${@StringUtils.cap(module.moduleCode)}Application.class, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
|
||||
this.setRegisterErrorPageFilter(false); // 错误页面有容器来处理,而不是SpringBoot
|
||||
return builder.sources(${@StringUtils.cap(module.moduleCode)}Application.class);
|
||||
}
|
||||
|
||||
}]]>
|
||||
</content>
|
||||
</template>
|
||||
@@ -0,0 +1,86 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) 2013-Now http://jeesite.com All rights reserved. -->
|
||||
<template>
|
||||
<name>bootstrap</name>
|
||||
<filePath>${module.moduleCode}/${module.moduleCode}/src/main/resources/config</filePath>
|
||||
<fileName>bootstrap.yml</fileName>
|
||||
<content><![CDATA[
|
||||
#======================================#
|
||||
#========== Server settings ===========#
|
||||
#======================================#
|
||||
|
||||
server:
|
||||
|
||||
port: 8989
|
||||
|
||||
#======================================#
|
||||
#========== Cloud settings ============#
|
||||
#======================================#
|
||||
|
||||
# 服务注册
|
||||
eureka:
|
||||
|
||||
# 实例设置
|
||||
instance:
|
||||
# 实例主机名称
|
||||
hostname: 127.0.0.1
|
||||
# 实例是否允许使用IP
|
||||
preferIpAddress: false
|
||||
|
||||
# 客户端设置
|
||||
client:
|
||||
# 注册中心地址(集群时指定另外一个注册中心地址)
|
||||
serviceUrl.defaultZone: http://127.0.0.1:8970/eureka/
|
||||
|
||||
#======================================#
|
||||
#========== Spring settings ===========#
|
||||
#======================================#
|
||||
|
||||
spring:
|
||||
|
||||
# 应用程序名称
|
||||
application:
|
||||
name: jeesite-cloud-module-${module.moduleCode}
|
||||
|
||||
# 当前环境名称(注意:不可设置为 test 它是单元测试专用的名称)
|
||||
profiles:
|
||||
active: default
|
||||
|
||||
# 分布式配置中心
|
||||
cloud:
|
||||
config:
|
||||
discovery:
|
||||
enabled: true
|
||||
serviceId: jeesite-cloud-config
|
||||
|
||||
# Consul 服务发现
|
||||
consul:
|
||||
host: 127.0.0.1
|
||||
port: 8500
|
||||
discovery:
|
||||
hostname: 127.0.0.1
|
||||
preferIpAddress: false
|
||||
|
||||
# 服务注册和配置
|
||||
nacos:
|
||||
discovery:
|
||||
server-addr: 127.0.0.1:8848
|
||||
config:
|
||||
server-addr: 127.0.0.1:8848
|
||||
file-extension: yml
|
||||
group: jeesite-cloud-42
|
||||
ext-config:
|
||||
- data-id: application.yml
|
||||
group: jeesite-cloud-42
|
||||
|
||||
# 打印横幅
|
||||
main:
|
||||
bannerMode: "off"
|
||||
allow-bean-definition-overriding: true
|
||||
|
||||
# 日志配置
|
||||
logging:
|
||||
config: classpath:config/logback-spring.xml
|
||||
]]>
|
||||
</content>
|
||||
</template>
|
||||
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) 2013-Now http://jeesite.com All rights reserved. -->
|
||||
<template>
|
||||
<name>logback-spring</name>
|
||||
<filePath>${module.moduleCode}/${module.moduleCode}/src/main/resources/config</filePath>
|
||||
<fileName>logback-spring.yml</fileName>
|
||||
<content><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration debug="false" scan="false">
|
||||
|
||||
<!-- Log file path -->
|
||||
<property name="log.path" value="\${logPath:-\${java.io.tmpdir:-.}}/logs" />
|
||||
|
||||
<!-- Framework level setting -->
|
||||
<include resource="config/logger-core.xml"/>
|
||||
|
||||
<!-- Project level setting -->
|
||||
<!-- <logger name="your.package" level="DEBUG" /> -->
|
||||
<logger name="org.springframework.context.annotation.AnnotationConfigApplicationContext" level="ERROR" />
|
||||
|
||||
<!-- Console log output -->
|
||||
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{MM-dd HH:mm:ss.SSS} %clr(%-5p) %clr([%-39logger{39}]){cyan} - %m%n%wEx</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- Log file debug output -->
|
||||
<appender name="debug" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>\${log.path}/debug.log</file>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>\${log.path}/debug.%d{yyyy-MM-dd}.%i.log.zip</fileNamePattern>
|
||||
<maxFileSize>50MB</maxFileSize>
|
||||
<maxHistory>30</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5p \${PID:- } [%15.15t] [%-39logger{39}] - %m%n%wEx</pattern>
|
||||
</encoder>
|
||||
<!--<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<level>ERROR</level>
|
||||
<onMatch>DENY</onMatch>
|
||||
<onMismatch>NEUTRAL</onMismatch>
|
||||
</filter>-->
|
||||
</appender>
|
||||
|
||||
<!-- Log file error output -->
|
||||
<appender name="error" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>\${log.path}/error.log</file>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<fileNamePattern>\${log.path}/error.%d{yyyy-MM-dd}.%i.log.zip</fileNamePattern>
|
||||
<maxFileSize>50MB</maxFileSize>
|
||||
<maxHistory>30</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5p \${PID:- } [%15.15t] [%-39logger{39}] - %m%n%wEx</pattern>
|
||||
</encoder>
|
||||
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||
<level>ERROR</level>
|
||||
</filter>
|
||||
</appender>
|
||||
|
||||
<!-- Level: FATAL 0 ERROR 3 WARN 4 INFO 6 DEBUG 7 -->
|
||||
<root level="WARN">
|
||||
<appender-ref ref="console" />
|
||||
<appender-ref ref="debug" />
|
||||
<appender-ref ref="error" />
|
||||
</root>
|
||||
|
||||
</configuration>]]>
|
||||
</content>
|
||||
</template>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (c) 2013-Now http://jeesite.com All rights reserved. -->
|
||||
<template>
|
||||
<name>static</name>
|
||||
<filePath>${module.moduleCode}/${module.moduleCode}/src/main/resources/static/modules/${module.moduleCode}</filePath>
|
||||
<fileName></fileName>
|
||||
<content><![CDATA[
|
||||
|
||||
]]>
|
||||
</content>
|
||||
</template>
|
||||
@@ -140,10 +140,12 @@ public class ${ClassName}Controller extends BaseController {
|
||||
List<${ClassName}> list = ${className}Service.findList(new ${ClassName}());
|
||||
for (int i=0; i<list.size(); i++){
|
||||
${ClassName} e = list.get(i);
|
||||
<% if (table.statusExists){ %>
|
||||
// 过滤非正常的数据
|
||||
if (!${ClassName}.STATUS_NORMAL.equals(e.getStatus())){
|
||||
continue;
|
||||
}
|
||||
<% } %>
|
||||
// 过滤被排除的编码(包括所有子级)
|
||||
if (StringUtils.isNotBlank(excludeCode)){
|
||||
if (e.getId().equals(excludeCode)){
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user