Compare commits

..

136 Commits

Author SHA1 Message Date
thinkgem
6bd4204fec 避免有时候 cookie path 为空的时候无法读取。 2021-02-24 17:11:35 +08:00
thinkgem
a9f8cd778e 优化用户选择根据用户类型查询用户 2021-02-24 11:18:56 +08:00
thinkgem
a57052ba38 用户类型的 未知 字典改为 无 2021-02-24 10:38:09 +08:00
thinkgem
63111832dc Merge branch 'v4.2_dev' into master
# Conflicts:
#	parent/pom.xml
2021-02-22 11:57:00 +08:00
thinkgem
5834b92129 点击右上角【Star】收藏本软件 ^_^ 2021-02-22 11:51:50 +08:00
thinkgem
37259267a2 当启用登录后生成新的sid时,验证码失效问题。 2021-02-20 11:35:00 +08:00
thinkgem
4396fdaea4 v4.2.3 2021-02-19 21:55:41 +08:00
thinkgem
ce1c531580 新增 mybatis.jdbcTransaction 参数,支持 MyBatis 指定 JDBC 事务管理,默认 Spring 管理事务 2021-02-12 23:22:59 +08:00
thinkgem
238102bf80 完善grid使用实例 2021-02-07 18:18:03 +08:00
thinkgem
6c01728455 spring boot 2.3.8 2021-02-04 20:43:44 +08:00
thinkgem
c39a8226e5 addTabPage 增加 data-title="false" 不显示对话框标题参数;
data-layer-shade-close="false" 点击遮罩层关闭参数
2021-02-03 16:13:05 +08:00
thinkgem
0e39f391cd upgrade shiro 1.7.1、druid 1.1.22 2021-02-01 21:05:40 +08:00
卓源软件
35b96a0f3d upgrade shiro 1.7.1 2021-02-01 20:29:26 +08:00
thinkgem
f2c23b72a0 新增zTree主题,图标美化 2021-01-30 00:37:39 +08:00
thinkgem
04bef9ac2c 新增zTree主题,图标美化 2021-01-28 01:04:29 +08:00
thinkgem
ae274cd8e6 sys_file_upload extend 2021-01-25 21:49:09 +08:00
thinkgem
596c64aa56 新增 使用手机或邮箱 找回密码开关 2021-01-25 15:35:31 +08:00
thinkgem
dcbac8dea9 国际化安全审计功能 2021-01-25 15:34:53 +08:00
thinkgem
dcf2b48d31 新增 page.maxPageSize 参数 2021-01-25 15:34:36 +08:00
thinkgem
0127572420 日期选择图标美化 2021-01-23 12:17:27 +08:00
thinkgem
d5b2e37fdb 添加菜单初始化完成后的js执行事件 2021-01-22 01:05:40 +08:00
thinkgem
aa9e0b82bc 从父类统一忽略,避免通过接口获取到用户类型详细数据,增加数据安全性 2021-01-20 23:05:51 +08:00
thinkgem
94ca59e025 修改数据日志,差异化工具显示增强,人性化,通用化 2021-01-19 22:17:21 +08:00
thinkgem
b1996130e6 优化有些数据库错误不打印日志,如字段数据过长,的信息将输出日志 2021-01-19 22:16:55 +08:00
thinkgem
9dbf48c30d 员工用户对象忽略refObj的json数据返回,因为与employee重复。 2021-01-18 00:41:25 +08:00
thinkgem
9cf813dcd6 如果会话超时,则提醒用户会话超时,请重新登录的对话框。 2021-01-18 00:40:33 +08:00
thinkgem
f1c2aa1281 当用户类型为管理员的时候启用员工的首页设置 2021-01-14 23:33:48 +08:00
thinkgem
afc61f4a32 生成模板优化 2021-01-14 23:33:17 +08:00
thinkgem
b05433f0b6 增加genIdAndValid注释提示 2021-01-10 11:46:26 +08:00
thinkgem
81657cd0df remove dialog from bat 2021-01-10 11:45:46 +08:00
thinkgem
26871a85f6 只将未知异常输出到日志文件 2021-01-05 21:24:01 +08:00
thinkgem
b4d93dda93 update 2021-01-05 21:22:52 +08:00
thinkgem
06d75964db 设置显示隐藏或排序Grid列的对话增加全选/取消全选复选框 2021-01-02 09:35:33 +08:00
thinkgem
8a1268d8a8 fileupload、listselect、treeselect支持通过js.template指定readonly属性,或者通过cssClass指定disabled设置只读。 2021-01-02 09:33:17 +08:00
thinkgem
759b416297 修正ios下单选和复选框不容易选择问题 2020-12-31 11:45:00 +08:00
thinkgem
129764925c 使用boot内置tomcat无需启用spring-boot-starter-tomcat,外置war部署时启用依赖。 2020-12-27 22:38:55 +08:00
thinkgem
eb340af57c 密码策略强制修改密码的情况下修改后不能跳转到首页的问题 2020-12-23 15:35:34 +08:00
thinkgem
1ddaa7b34d Tomcat的最大POST数据限制参数实例 2020-12-22 22:07:15 +08:00
thinkgem
c7a03196a8 Merge branch 'v4.2_dev' of https://gitee.com/thinkgem/jeesite4 into
v4.2_dev

# Conflicts:
#	modules/core/src/main/java/com/jeesite/modules/sys/utils/LogUtils.java
2020-12-22 10:14:21 +08:00
thinkgem
a96991f7ea 访问日志记录,增加表单提交前后的差异数据分析 2020-12-22 10:12:35 +08:00
thinkgem
5fd34ea584 访问日志记录,增加表单提交前后的差异数据分析 2020-12-22 00:16:30 +08:00
thinkgem
7e42620f44 找回密码和注册账号的密码填写增加密码等级提醒 2020-12-21 22:47:50 +08:00
thinkgem
7409024987 点击右上角【Star】收藏本软件 ^_^ 2020-12-19 18:20:31 +08:00
thinkgem
0e919bdd0a fileupload 增加 extend 扩展字段 2020-12-18 16:55:54 +08:00
thinkgem
09a567f4d9 优化界面细节和提示 2020-12-18 16:20:47 +08:00
thinkgem
e61f7f1ecb 代码生成模板主子表服务类增加子表数据查询方法;去掉复选框必须选择一项的验证; 2020-12-10 16:22:45 +08:00
thinkgem
dc9bfdc65e 美化表单、表格、整体样式 2020-12-10 16:16:52 +08:00
thinkgem
f7cf4dc521 shiro1.7新增了非法请求过滤器,因为不支持中文URL,所以关闭NonAscii验证。 2020-12-09 19:43:26 +08:00
thinkgem
46a4a3118f 新增不连接数据库的情况下启动服务的支持 2020-12-07 22:23:29 +08:00
thinkgem
51335cffeb IdGen.nextCode支持超长数值 2020-12-07 22:19:47 +08:00
thinkgem
6c08c9a28c 增加日志追踪标识,方便对每次请求执行的日志做出分析 2020-12-07 16:26:30 +08:00
thinkgem
a98b928c3f proxyBeanMethods = false 2020-12-07 16:24:25 +08:00
thinkgem
ba55da3e71 start 4.2.3 2020-12-07 11:40:18 +08:00
thinkgem
9f8dfd53b1 隐藏 map 文件提醒 2020-12-02 12:50:49 +08:00
thinkgem
4bf31c6418 update 2020-11-26 22:24:01 +08:00
thinkgem
ade275c057 laytpl 去掉无用的 console.log() 2020-11-24 23:52:45 +08:00
thinkgem
c57bc6e6c0 分页附加信息实例 2020-11-24 15:45:13 +08:00
thinkgem
22f4b1f121 update versions 2020-11-18 18:47:37 +08:00
thinkgem
a18ee3dbab 去掉冗余字段的查询,默认使用join返回的数据 2020-11-18 10:26:35 +08:00
thinkgem
699afecc3e DateUtils增加"yyyyMMdd","yyyyMM"格式解析 2020-11-12 12:14:33 +08:00
thinkgem
fd55449efb ObjectUtils增加logger输出 2020-11-12 12:13:57 +08:00
thinkgem
57c1cb3289 upgrade shiro 1.7.0 2020-11-03 17:30:50 +08:00
thinkgem
9d32a7f17d 删除无用的代码 2020-10-30 20:53:33 +08:00
thinkgem
eabaf8b0d6 topMenu 引用 子模板文件 路径改为绝对路径 2020-10-29 16:13:58 +08:00
thinkgem
53bf08eeca layer get method 支持 contentFormData 参数 2020-10-29 15:56:09 +08:00
thinkgem
b23e65fed9 Double-checked locking and volatile 2020-10-28 12:36:38 +08:00
thinkgem
f48a7b38d2 Merge branch 'master' of https://gitee.com/thinkgem/jeesite4 into master
# Conflicts:
#	parent/pom.xml
2020-10-27 22:17:38 +08:00
thinkgem
4e1c54435b Merge branch 'v4.2_dev' of https://gitee.com/thinkgem/jeesite4 into v4.2_dev 2020-10-27 21:12:42 +08:00
thinkgem
c54a21cfd6 兼容 spring cloud config 2020-10-27 21:12:05 +08:00
thinkgem
913a77d01f 兼容 spring cloud config 2020-10-26 14:17:15 +08:00
thinkgem
2747e0d5d3 update 2020-10-23 15:58:06 +08:00
thinkgem
fa2b3d92ca 更改cookie默认存储路径为contextpath 2020-10-14 22:55:29 +08:00
thinkgem
629b1b963f 个人信息保存即时显示最新信息的问题 2020-10-14 17:56:30 +08:00
thinkgem
5e346c6d72 找回密码和注册用户敏感信息加密处理 2020-09-29 16:07:47 +08:00
thinkgem
ac4c092a1c 泛型函数返回类型优化 2020-09-28 15:12:49 +08:00
thinkgem
4e6e22e4dc sql过滤优化增加|sleep|union|load_file函数的过滤 2020-09-28 15:11:27 +08:00
thinkgem
a95d663db3 新增 listselect 代码生成模板。 2020-09-25 22:37:39 +08:00
thinkgem
40169ac7a9 新增 Cloud 微服务模块的代码生成模板。 2020-09-25 16:22:33 +08:00
thinkgem
9e62a3b259 增加 shell 打包和部署脚本 2020-09-25 14:30:14 +08:00
thinkgem
63fa05b440 新增创建模块的代码生成功能,模块代码生成模板。 2020-09-24 10:12:32 +08:00
thinkgem
3dd8ec03b9 优化ueditor设置高度的时候出现不必要的滚动条。 2020-09-24 10:05:00 +08:00
thinkgem
32f81e1fee userSelect、empUserSelect的json验证优化 2020-09-24 10:04:27 +08:00
thinkgem
37675bac9d 点击右上角【Star】收藏本软件 ^_^ 2020-09-24 10:03:30 +08:00
thinkgem
f9842c3c86 upgrade spring boot 2.3.4、spring 5.2.9 2020-09-22 10:48:58 +08:00
卓源软件
b8cae70933 upgrade spring boot 2.2.10spring 5.2.9 2020-09-22 10:47:18 +08:00
thinkgem
0f0ff4af1a 新增 BPM 表单代码生成模板;Cloud 代码生成模块迁移到核心模块; 2020-09-21 14:29:25 +08:00
thinkgem
3539230d44 代码优化 2020-09-21 13:38:44 +08:00
thinkgem
af56d05847 登录界面 user.loginByValidCode 优化 2020-09-21 13:38:15 +08:00
thinkgem
75c1c74fea 优化模拟短信发送提示 2020-09-20 19:17:48 +08:00
thinkgem
202e9d8918 新增手机号短信验证码登录 user.loginByValidCode=true;调整
sysLogin、sysIndex、menuTree、forgetPwd、registerUser 的目录,方便覆写和理解;增加 自定义主题视图
的 readme.txt 帮助文件。
2020-09-20 18:42:25 +08:00
thinkgem
faeb49ee98 新增手机号短信验证码登录 user.loginByValidCode=true;调整
sysLogin、sysIndex、menuTree、forgetPwd、registerUser 的目录,方便覆写和理解;增加 自定义主题视图
的 readme.txt 帮助文件。
2020-09-20 18:28:48 +08:00
thinkgem
bbb37722d6 单点登录接口和无条件登录接口优化改进,并在调用登录时统一增加登录成功和失败事件,方便返回登录信息。 2020-09-20 17:38:54 +08:00
thinkgem
f3bb96d719 如果是在个性化用户类型的登录界面,登录的系统,则在退出时返回对应用户类型的登录界面。 2020-09-20 09:41:54 +08:00
thinkgem
055d791c44 不允许上传空文件友情提示 2020-09-18 16:55:11 +08:00
thinkgem
bf01c76167 升级工具依赖;去掉一些极少用的依赖,按需加入; 2020-09-17 15:12:34 +08:00
thinkgem
df98f266b9 初始化数据库脚本优化 2020-09-14 23:01:25 +08:00
thinkgem
9daef68787 升级到 spring boot 2.3.3;依赖模块 es 升级到 7.x 利用 RestHighLevelClient
实现检索;菜单优化,选择模块改为多选下拉框;其它优化
2020-09-11 18:51:00 +08:00
thinkgem
663a66b571 点击右上角【Star】收藏本软件 ^_^ 2020-09-09 21:00:27 +08:00
thinkgem
687dbe0f93 生成模板的树表没有状态字段的时候不判断状态 2020-09-09 20:56:59 +08:00
thinkgem
9063996fd0 主题优化,全屏桌面,性能及体验再此提升。 2020-09-09 19:16:37 +08:00
thinkgem
1fef63126d 文件管理增加租户支持 2020-09-08 17:13:20 +08:00
thinkgem
add7294529 细节优化 2020-09-06 23:44:09 +08:00
thinkgem
93652a25ae 点击右上角【Star】收藏本软件 ^_^ 2020-09-06 23:43:41 +08:00
thinkgem
0ed597e1f1 start 4.2.2 2020-09-06 23:43:09 +08:00
thinkgem
b799b92cf1 登录页图标显示优化 2020-09-01 11:27:37 +08:00
thinkgem
70f2b5fefc 点击右上角【Star】收藏本软件 ^_^ 2020-09-01 11:27:17 +08:00
thinkgem
07c50de54a 点击右上角【Star】收藏本软件 ^_^ 2020-08-25 15:12:22 +08:00
thinkgem
a11fd3a645 微不足道,按登录设备自定义会话超时时间的例子。 2020-08-25 15:08:06 +08:00
thinkgem
39ffa1c449 点击右上角【Star】收藏本软件 ^_^ 2020-08-24 21:43:52 +08:00
thinkgem
36f7640a83 优化isAjaxRequest增加个性化配置开关 2020-08-24 09:06:26 +08:00
thinkgem
4ac34013b3 当使用 __ajax=json 参数的时候 403 页面返回空字符的优化。 2020-08-23 23:59:49 +08:00
thinkgem
78c3f02f41 用户管理新增附属部门及岗位的查询 2020-08-20 14:21:19 +08:00
thinkgem
7750bfd49a 性能提升 2020-08-20 14:20:54 +08:00
thinkgem
f46b42d28e upgrade shiro 1.6.0 2020-08-18 19:25:30 +08:00
thinkgem
14f0cc5811 支持匿名访问swagger文档 2020-08-18 18:37:44 +08:00
thinkgem
3a9e0d5dc1 use jackson xml instead jaxb 2020-08-15 23:21:38 +08:00
thinkgem
f56b92ba5f remove jaxb dependency 2020-08-14 17:46:17 +08:00
thinkgem
98f57a2511 update 2020-08-14 12:02:16 +08:00
thinkgem
9e53433922 审核状态的用户显示启用按钮 2020-08-14 12:02:08 +08:00
thinkgem
1726e5af57 Merge branch 'master' of https://gitee.com/thinkgem/jeesite4 into master 2020-08-13 14:53:48 +08:00
thinkgem
1174723bc0 Merge branch 'v4.2_dev' into master 2020-08-13 14:51:54 +08:00
thinkgem
7654cdc6c8 v4.2.1 2020-08-13 14:48:58 +08:00
thinkgem
c03c75609a 导入的数据进行 xss 过滤 2020-08-12 11:17:21 +08:00
thinkgem
32ce44dac4 登录提交信息非法请求解析错误则忽略异常 2020-08-12 11:05:02 +08:00
thinkgem
c068718fa0 修正 ueditor 快速图片上传 session 丢失问题 2020-08-07 12:50:08 +08:00
thinkgem
44b25989d6 jdk11下默认不加载jaxb模块,因此加载实现。 2020-08-03 21:45:45 +08:00
thinkgem
b9808181d5 upgrade boot 2.2.9 2020-07-30 11:59:16 +08:00
thinkgem
769f89ea67 add plugin repos 2020-07-30 10:45:27 +08:00
卓源软件
8486aa1909 update plugin repos 2020-07-30 10:44:05 +08:00
thinkgem
a4ca4aeb18 Tab页签支持拖拽排序;Grid列支持拖拽排序;Grid列支持显示隐藏;表头下放搜索工具条演示; 2020-07-29 17:56:48 +08:00
thinkgem
38ee55bd38 快捷日期选择新增近1周,近n天参数。 2020-07-27 23:36:29 +08:00
thinkgem
d9c3b036f3 修正 laydate.js 的 done 事件,当下一个日期弹出前,可能上一个还未设置,导致选择不上的问题。 2020-07-27 19:14:39 +08:00
卓源软件
a6cbbbfd16 修正 laydate.js 的 done 事件,当下一个日期弹出前,可能上一个还未设置,导致选择不上的问题。 2020-07-27 19:14:12 +08:00
thinkgem
91452fdd93 4.2.1 2020-07-27 17:52:27 +08:00
thinkgem
34c47d1686 Merge remote-tracking branch 'remotes/origin/v4.2_dev' 2020-07-27 17:49:47 +08:00
thinkgem
8319ed58ed 点击右上角【Star】收藏本软件 ^_^ 2020-07-27 17:46:55 +08:00
230 changed files with 15176 additions and 1308 deletions

View File

@@ -8,6 +8,7 @@
### 报错信息
```
```

View File

@@ -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. 您若套用本平台的一些代码或功能参考,需要在您的软件介绍明显位置说明出处。

View File

@@ -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>
* 关注微信公众号,了解最新动态:
![JeeSite4微信公众号](https://images.gitee.com/uploads/images/2020/0727/091951_a3ab258c_6732.jpeg "JeeSite4微信公众号")
## 平台介绍
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
* 持久层Apache MyBatis 3.5、Hibernate Validator 6.0、Alibaba Druid 1.1
* 主框架Spring Boot 2.3、Spring Framework 5.2、Apache Shiro 1.7、J2Cache
* 持久层Apache MyBatis 3.5、Hibernate Validator 6.1、Alibaba Druid 1.2
* 视图层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>
* 微信公众号(关注动态):
![JeeSite4微信公众号](https://static.oschina.net/uploads/space/2018/0302/145133_OGZf_941661.jpg "JeeSite4微信公众号")
## 今后如何升级?
尽量不修改 web 项目以外的源码项目,如 jeesite-common、jeesite-modele-core如果修改了请 Pull Requests 上来,否则代码与官方不同步,会将对你的日后升级增加难度。
如果您修改了依赖模块代码,也没关系,这时你需要利用 Git 版本控制工具,与官方仓库代码进行同步,合并代码即可。
每个版本升级,我们都会附带详细更新日志:<http://jeesite.com/?t=273830>
每个版本升级,我们都会附带详细更新日志:<http://jeesite.com/docs/upgrade/>
在这里,你可以看到 JeeSite 新增哪些新功能和改进,在每个版本下都有对应升级方法。

View File

@@ -15,5 +15,4 @@ cd ..
call mvn clean deploy -Dmaven.test.skip=true -Pdeploy
cd bin
cmd /c msg %username% /time:0 /w "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>..."
pause

15
common/bin/deploy.sh Normal file
View 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

View File

@@ -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

View File

@@ -15,5 +15,4 @@ cd ..
call mvn clean install -Dmaven.test.skip=true -Ppackage
cd bin
cmd /c msg %username% /time:0 /w "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>..."
pause

15
common/bin/package.sh Normal file
View 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

View File

@@ -6,7 +6,7 @@
<parent>
<groupId>com.jeesite</groupId>
<artifactId>jeesite-parent</artifactId>
<version>4.2.0-SNAPSHOT</version>
<version>4.2.3-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>

View File

@@ -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){

View File

@@ -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))");
}
}

View File

@@ -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>();
}

View File

@@ -3,6 +3,7 @@
*/
package com.jeesite.common.idgen;
import java.math.BigDecimal;
import java.security.SecureRandom;
import java.util.UUID;
@@ -79,7 +80,7 @@ public class IdGen {
prefix = str.substring(0, lastNotNumIndex);
prevNum = str.substring(lastNotNumIndex, str.length());
}
String nextNum = String.valueOf(Long.valueOf(prevNum) + 1);
String nextNum = new BigDecimal(prevNum).add(BigDecimal.ONE).toString();
str = prefix + StringUtils.leftPad(nextNum, prevNum.length(), "0");
return str;
}

View File

@@ -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; // 曲线波纹

View File

@@ -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;
}

View File

@@ -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

View File

@@ -23,7 +23,7 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
"yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM/dd HH", "yyyy/MM",
"yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM.dd HH", "yyyy.MM",
"yyyy年MM月dd日", "yyyy年MM月dd日 HH时mm分ss秒", "yyyy年MM月dd日 HH时mm分", "yyyy年MM月dd日 HH时", "yyyy年MM月",
"yyyy"};
"yyyyMMdd", "yyyyMM", "yyyy"};
/**
* 得到日期字符串 转换格式yyyy-MM-dd

View File

@@ -13,6 +13,8 @@ import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.nustaq.serialization.FSTConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.core.NamedThreadLocal;
@@ -23,6 +25,8 @@ import org.springframework.core.NamedThreadLocal;
*/
public class ObjectUtils extends org.apache.commons.lang3.ObjectUtils {
private static Logger logger = LoggerFactory.getLogger(ObjectUtils.class);
/**
* 转换为 Double 类型
*/
@@ -170,7 +174,7 @@ public class ObjectUtils extends org.apache.commons.lang3.ObjectUtils {
}
long totalTime = System.currentTimeMillis() - beginTime;
if (totalTime > 3000){
System.out.println("Serialize time: " + TimeUtils.formatDateAgo(totalTime));
logger.warn(object.getClass() + " serialize time: " + TimeUtils.formatDateAgo(totalTime));
}
return bytes;
}
@@ -196,7 +200,7 @@ public class ObjectUtils extends org.apache.commons.lang3.ObjectUtils {
}
long totalTime = System.currentTimeMillis() - beginTime;
if (totalTime > 3000){
System.out.println("Unserialize time: " + TimeUtils.formatDateAgo(totalTime));
logger.warn(object.getClass() + " unserialize time: " + TimeUtils.formatDateAgo(totalTime));
}
return object;
}
@@ -221,7 +225,7 @@ public class ObjectUtils extends org.apache.commons.lang3.ObjectUtils {
byte[] bytes = fstConfiguration.get().asByteArray(object);
long totalTime = System.currentTimeMillis() - beginTime;
if (totalTime > 3000){
System.out.println("Fst serialize time: " + TimeUtils.formatDateAgo(totalTime));
logger.warn(object.getClass() + " fst serialize time: " + TimeUtils.formatDateAgo(totalTime));
}
return bytes;
}
@@ -239,7 +243,7 @@ public class ObjectUtils extends org.apache.commons.lang3.ObjectUtils {
Object object = fstConfiguration.get().asObject(bytes);
long totalTime = System.currentTimeMillis() - beginTime;
if (totalTime > 3000){
System.out.println("Fst unserialize time: " + TimeUtils.formatDateAgo(totalTime));
logger.warn(object.getClass() + " fst unserialize time: " + TimeUtils.formatDateAgo(totalTime));
}
return object;
}

View File

@@ -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 {
//

View File

@@ -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>的内容");
// }
}

View File

@@ -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:\"短信模拟发送成功!\"}";
}
}

View File

@@ -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];
}

View File

@@ -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);

View File

@@ -94,7 +94,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);
}
/**

View File

@@ -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();

View File

@@ -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;
}
@@ -203,7 +203,9 @@ a, a:hover, a:active, a:focus, .form-unit, th[aria-selected=true] .ui-jqgrid-sor
.box-main>.box-header .box-title .fa {color:#1890ff;}
.nav-tabs-custom>.nav-tabs>li.active {border-top-color:#3aa0ff;}
.form-control:focus,.select2-container--default.select2-container--focus .select2-selection--multiple,
.select2-container--default .select2-search--dropdown .select2-search__field {border-color:#66afe9!important;}
.select2-container--default .select2-search--dropdown .select2-search__field,
.select2-container--default.select2-container--focus .select2-selection--single,
.select2-container--default.select2-container--focus .select2-selection--multiple {border-color:#40a9ff!important;box-shadow:0 0 0 2px rgba(24,144,255,.2);}
.table thead tr, .ui-jqgrid-htable thead tr, .ui-jqgrid-hdiv, .ui-jqgrid-hbox {background-color:#f6f6f6;}
.ui-jqgrid .ui-jqgrid-htable th.ui-th-column-header, .ui-jqgrid .ui-jqgrid-htable th.ui-th-column,
.ui-jqgrid .ui-jqgrid-labels th, .ui-jqgrid .ui-widget-content, .ui-jqgrid tr.ui-row-ltr td,

View File

@@ -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;
}
@@ -203,7 +208,9 @@ a, a:hover, a:active, a:focus, .form-unit, th[aria-selected=true] .ui-jqgrid-sor
.box-main>.box-header .box-title .fa {color:#1e5edb;}
.nav-tabs-custom>.nav-tabs>li.active {border-top-color:#1e5edb;}
.form-control:focus,.select2-container--default.select2-container--focus .select2-selection--multiple,
.select2-container--default .select2-search--dropdown .select2-search__field {border-color:#6980c3!important;}
.select2-container--default .select2-search--dropdown .select2-search__field,
.select2-container--default.select2-container--focus .select2-selection--single,
.select2-container--default.select2-container--focus .select2-selection--multiple {border-color:#40a9ff!important;box-shadow:0 0 0 2px rgba(24,144,255,.2);}
.table thead tr, .ui-jqgrid-htable thead tr, .ui-jqgrid-hdiv, .ui-jqgrid-hbox {background-color:#f6f6f6;}
.ui-jqgrid .ui-jqgrid-htable th.ui-th-column-header, .ui-jqgrid .ui-jqgrid-htable th.ui-th-column,
.ui-jqgrid .ui-jqgrid-labels th, .ui-jqgrid .ui-widget-content, .ui-jqgrid tr.ui-row-ltr td,

View File

@@ -90,7 +90,6 @@ Tpl.pt.render = function(data, callback){
var that = this, tpl;
if(!data) return tool.error('no data');
tpl = that.cache ? that.cache(data, tool.escape) : that.parse(that.tpl, data);
console.log()
if(!callback) return tpl;
callback(tpl);
};

View File

@@ -198,7 +198,7 @@
if (!node[_disabled]) {
// Click
if (type == _click) {
if (type == _click || type == 'touchend') {
if ($(event.target).is('a')) {
return;
}

View File

@@ -6,5 +6,5 @@ a.slice(1)}function L(a,b,d,c){if(!c){if(b)a[p]("ifToggled");a[p]("ifChanged")[p
c.add(a):c.add(a.find(d))})};if(/^(check|uncheck|toggle|indeterminate|determinate|disable|enable|update|destroy)$/i.test(a))return a=a.toLowerCase(),e(this),c.each(function(){var c=h(this);"destroy"==a?M(c,"ifDestroyed"):F(c,!0,a);h.isFunction(b)&&b()});if("object"!=typeof a&&a)return this;var f=h.extend({checkedClass:l,disabledClass:s,indeterminateClass:m,checkboxClass:'icheckbox_minimal-grey',radioClass:'iradio_minimal-grey',labelHover:!0,aria:!1},a),k=f.handle,B=f.hoverClass||"hover",x=f.focusClass||"focus",w=f.activeClass||"active",y=!!f.labelHover,C=f.labelHoverClass||
"hover",r=(""+f.increaseArea).replace("%","")|0;if("checkbox"==k||k==u)d='input[type="'+k+'"]';-50>r&&(r=-50);e(this);return c.each(function(){var a=h(this);M(a);var c=this,b=c.id,e=-r+"%",d=100+2*r+"%",d={position:"absolute",top:e,left:e,display:"block",width:d,height:d,margin:0,padding:0,background:"#fff",border:0,opacity:0},e=J?{position:"absolute",visibility:"hidden"}:r?d:{position:"absolute",opacity:0},k="checkbox"==c[n]?f.checkboxClass||"icheckbox":f.radioClass||"i"+u,m=h(G+'[for="'+b+'"]').add(a.closest(G)),
A=!!f.aria,E=q+"-"+Math.random().toString(36).replace("0.",""),g='<div class="'+k+'" '+(A?'role="'+c[n]+'" ':"");m.length&&A&&m.each(function(){g+='aria-labelledby="';this.id?g+=this.id:(this.id=E,g+=E);g+='"'});g=a.wrap(g+"/>")[p]("ifCreated").parent().append(f.insert);d=h('<ins class="'+I+'"/>').css(d).appendTo(g);a.data(q,{o:f,s:a.attr("style")}).css(e);f.inheritClass&&g[v](c.className||"");f.inheritID&&b&&g.attr("id",q+"-"+b);"static"==g.css("position")&&g.css("position","relative");F(a,!0,H);
if(m.length)m.on("click.i mouseover.i mouseout.i touchbegin.i touchend.i",function(b){var d=b[n],e=h(this);if(!c[s]){if("click"==d){if(h(b.target).is("a"))return;F(a,!1,!0)}else y&&(/ut|nd/.test(d)?(g[z](B),e[z](C)):(g[v](B),e[v](C)));if(J)b.stopPropagation();else return!1}});a.on("click.i focus.i blur.i keyup.i keydown.i keypress.i",function(b){var d=b[n];b=b.keyCode;if("click"==d)return!1;if("keydown"==d&&32==b)return c[n]==u&&c[l]||(c[l]?t(a,l):D(a,l)),!1;if("keyup"==d&&c[n]==u)!c[l]&&D(a,l);else if(/us|ur/.test(d))g["blur"==
if(m.length)m.on("click.i mouseover.i mouseout.i touchbegin.i touchend.i",function(b){var d=b[n],e=h(this);if(!c[s]){if("click"==d||"touchend"==d){if(h(b.target).is("a"))return;F(a,!1,!0)}else y&&(/ut|nd/.test(d)?(g[z](B),e[z](C)):(g[v](B),e[v](C)));if(J)b.stopPropagation();else return!1}});a.on("click.i focus.i blur.i keyup.i keydown.i keypress.i",function(b){var d=b[n];b=b.keyCode;if("click"==d)return!1;if("keydown"==d&&32==b)return c[n]==u&&c[l]||(c[l]?t(a,l):D(a,l)),!1;if("keyup"==d&&c[n]==u)!c[l]&&D(a,l);else if(/us|ur/.test(d))g["blur"==
d?z:v](x)});d.on("click mousedown mouseup mouseover mouseout touchbegin.i touchend.i",function(b){var d=b[n],e=/wn|up/.test(d)?w:B;if(!c[s]){if("click"==d)F(a,!1,!0);else{if(/wn|er|in/.test(d))g[v](e);else g[z](e+" "+w);if(m.length&&y&&e==B)m[/ut|nd/.test(d)?z:v](C)}if(J)b.stopPropagation();else return!1}})})}})(window.jQuery||window.Zepto);

Binary file not shown.

After

Width:  |  Height:  |  Size: 381 B

View File

@@ -0,0 +1,113 @@
/*-------------------------------------
zTree Style 3.4 author: Hunter.z、ThinkGem
-------------------------------------*/
.ztree * {padding:0;margin:0;font-size:13px;}
.ztree {margin:0;padding:5px;color:#333}
.ztree li{padding:0;margin:0;list-style:none;line-height:21px;text-align:left;white-space:nowrap;outline:0}
.ztree li ul{ margin:0;padding:0 0 0 18px}
.ztree li a {padding-right:3px;margin:0;cursor:pointer;height:23px;color:#333;background-color: transparent;text-decoration:none;display: inline-block;vertical-align: middle;}
.ztree li a:hover {text-decoration:underline}
.ztree li a.curSelectedNode {padding-top:0px;background-color:#e5e5e5;color:black;height:23px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}
.ztree li a.curSelectedNode_Edit {padding-top:0px;background-color:#e5e5e5;color:black;height:23px;border:1px #666 solid;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}
.ztree li a.tmpTargetNode_inner {padding-top:0px;background-color:#aaa;color:white;height:21px;border:1px #666 solid;
opacity:0.8;filter:alpha(opacity=80)}
.ztree li a.tmpTargetNode_prev {}
.ztree li a.tmpTargetNode_next {}
.ztree li a input.rename {height:14px;width:80px;padding:0;margin:0;
font-size:12px;border:1px #7EC4CC solid;*border:0px}
.ztree li span {line-height:23px;margin-right:2px}
.ztree li span.button {line-height:0;margin:0;width:21px;height:21px;display: inline-block;vertical-align:middle;
border:0 none;cursor: pointer;outline:none;}
.ztree li span.button.ico_loading{margin-right:2px;background:url(./img/loading.gif) no-repeat scroll 0 0 transparent;vertical-align:top;*vertical-align:middle}
ul.tmpTargetzTree {background-color:#FFE6B0;opacity:0.8;filter:alpha(opacity=80)}
span.tmpzTreeMove_arrow {width:16px;height:21px;display: inline-block;padding:0;margin:2px 0 0 1px;border:0 none;position:absolute;
background-color:transparent;background-repeat:no-repeat;background-attachment: scroll;}
ul.ztree.zTreeDragUL {margin:0;padding:0;position:absolute;width:auto;height:auto;overflow:hidden;background-color:#cfcfcf;border:1px #00B83F dotted;opacity:0.8;filter:alpha(opacity=80)}
.zTreeMask {z-index:10000;background-color:#cfcfcf;opacity:0.0;filter:alpha(opacity=0);position:absolute}
/* 树搜索相关 */
.treeSearchInput {padding:13px 0 0 20px;}
.treeSearchInput label {padding:5px 0 3px 0;font-size:13px;font-weight:normal;vertical-align:middle;}
.treeSearchInput input {width:140px;vertical-align:middle;line-height:24px;height:26px;border:1px solid #aaa;padding:0 4px;border-radius:4px;}
.treeSearchInput button {border:1px solid #aaa;vertical-align:middle;height:26px;height:26px\9;font-size:13px;background:#efefef;padding:0 8px;}
.treeShowHideButton {position:absolute;right:8px;top:-3px;font-size:12px;color:#333;z-index:3;}
.treeShowHideButton label {cursor:pointer;}
.treeExpandCollapse {float:right;margin:6px 5px;padding:5px;font-size:12px;color:#333;position:relative;z-index:2;background:#fff;}
.treeExpandCollapse a {text-decoration:none;color:#333}
.treeselect.ztree {padding:10px 20px;}
/* 字体图标风格 */
.ztree * {box-sizing:content-box;}
.ztree li li {padding-left:9px;}
.ztree li ul.line {content:"";border-left:1px dotted #aaa;top:0px;left:0px;margin-top:-2px;padding-top:2px;}
.ztree li ul {position:relative;background:none;margin-left:9px;padding-left:0;}
.ztree li ul.line {background:none;}
.ztree li .noline_open + a + ul:before {border-left:none;}
.ztree li .noline_open + a + ul li:before {border-top:none;}
.ztree li a {height:26px;padding-left:3px;}
.ztree li span {height:26px;margin-left:4px;}
.ztree li span.node_name {margin-right:6px;}
.ztree li span.button.switch,
.ztree li span.button.chk,
.ztree li a span.button,
.ztree li span.button[class$="Page"] {position:relative;width:18px;height:22px;background:none;background-position:center center !important;padding:2px 0;
display:inline-block;font:normal normal normal 15px/1 FontAwesome;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;}
.ztree li span.button[class$="Page"] {width:15px;}
.ztree li a span.button[style="width:0px;height:0px;"]:before,
.ztree li a span.button[style^="background"]:before {content:"";}
.ztree li span.button.roots_docu, .ztree li span.button.center_docu, .ztree li span.button.bottom_docu {position:relative;height:24px;padding:0;}
.ztree li span.button.roots_docu:before {content:"";display:block;width:18px;height:11px;border-left:1px dotted #aaa;position:absolute;top:10px;left:9px;}
.ztree li span.button.roots_docu:after {content:"";display:block;width:9px;height:0;border-top:1px dotted #aaa;position:absolute;top:10px;left:9px;}
.ztree li span.button.center_docu:before {content:"";display:block;width:0;height:25px;border-left:1px dotted #aaa;position:absolute;top:-3px;left:9px;}
.ztree li span.button.center_docu:after {content:"";display:block;width:9px;height:0;border-top:1px dotted #aaa;position:absolute;top:10px;left:9px;}
.ztree li span.button.bottom_docu:before {content:"";display:block;width:0;height:12px;border-left:1px dotted #aaa;position:absolute;top:-3px;left:9px;}
.ztree li span.button.bottom_docu:after {content:"";display:block;width:9px;height:0;border-top:1px dotted #aaa;position:absolute;top:10px;left:9px;}
.ztree li span.button:before {display:block;line-height:20px;text-align:left;padding-left:4px;color:#666;}
.ztree li span.button.root_open:before,
.ztree li span.button.roots_open:before,
.ztree li span.button.center_open:before,
.ztree li span.button.bottom_open:before,
.ztree li span.button.noline_open:before {content:"\f147";}
.ztree li span.button.root_close:before,
.ztree li span.button.roots_close:before,
.ztree li span.button.center_close:before,
.ztree li span.button.bottom_close:before,
.ztree li span.button.noline_close:before {content:"\f196";}
.ztree li span.button.chk.checkbox_true_full:before,
.ztree li span.button.chk.checkbox_true_disable:before,
.ztree li span.button.chk.checkbox_true_full_focus:before {content:"\f046";}
.ztree li span.button.chk.checkbox_false_full:before,
.ztree li span.button.chk.checkbox_false_disable:before,
.ztree li span.button.chk.checkbox_false_full_focus:before {content:"\f096";}
.ztree li span.button.chk.checkbox_true_part:before,
.ztree li span.button.chk.checkbox_true_part_focus:before,
.ztree li span.button.chk.checkbox_false_part:before,
.ztree li span.button.chk.checkbox_false_part_focus:before {content:"\f14a";}
.ztree li span.button.chk.radio_true_full:before,
.ztree li span.button.chk.radio_true_disable:before,
.ztree li span.button.chk.radio_true_full_focus:before {content:"\f05d";}
.ztree li span.button.chk.radio_false_full:before,
.ztree li span.button.chk.radio_false_disable:before,
.ztree li span.button.chk.radio_false_full_focus:before {content:"\f10c";}
.ztree li span.button.chk.radio_true_part:before,
.ztree li span.button.chk.radio_true_part_focus:before,
.ztree li span.button.chk.radio_false_part:before,
.ztree li span.button.chk.radio_false_part_focus:before {content:"\f192";}
.ztree li span.button.ico_open:before {content:"\f115";}
.ztree li span.button.ico_close:before {content:"\f114";}
.ztree li span.button.ico_docu:before {content:"\f016";}
.ztree li span.button.add:before {content:"\f196";}
.ztree li span.button.edit:before {content:"\f044";}
.ztree li span.button.remove:before {content:"\f014";}
.ztree li span.button.firstPage:before {content:"\f100";}
.ztree li span.button.prevPage:before {content:"\f104";}
.ztree li span.button.nextPage:before {content:"\f105";}
.ztree li span.button.lastPage:before {content:"\f101";}
.ztree li span.button.chk[class$="focus"]:before {font-weight:bold;}
.ztree li span.button.chk[class$="disable"]:before {color:#aaa;}
.ztree li a.curSelectedNode, .ztree li a.tmpTargetNode_inner {height:26px;}

View File

@@ -8,23 +8,23 @@ website: http://code.google.com/p/jquerytree/
-------------------------------------*/
.ztree * {padding:0; margin:0; font-size:12px; font-family: Verdana, Arial, Helvetica, AppleGothic, sans-serif}
.ztree * {padding:0; margin:0; font-size:13px;}
.ztree {margin:0; padding:5px; color:#333}
.ztree li{padding:0; margin:0; list-style:none; line-height:21px; text-align:left; white-space:nowrap; outline:0}
.ztree li ul{ margin:0; padding:0 0 0 18px}
.ztree li ul.line{ background:url(./img/line_conn.png) 0 0 repeat-y;}
.ztree li a {padding-right:3px; margin:0; cursor:pointer; height:21px; color:#333; background-color: transparent; text-decoration:none; display: inline-block}
.ztree li a {padding-right:3px; margin:0; cursor:pointer; height:23px; color:#333; background-color: transparent; text-decoration:none; display: inline-block; vertical-align: middle;}
.ztree li a:hover {text-decoration:underline}
.ztree li a.curSelectedNode {padding-top:0px; background-color:#e5e5e5; color:black; height:22px; -webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}
.ztree li a.curSelectedNode_Edit {padding-top:0px; background-color:#e5e5e5; color:black; height:22px; border:1px #666 solid; -webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}
.ztree li a.curSelectedNode {padding-top:0px; background-color:#e5e5e5; color:black; height:23px; -webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}
.ztree li a.curSelectedNode_Edit {padding-top:0px; background-color:#e5e5e5; color:black; height:23px; border:1px #666 solid; -webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}
.ztree li a.tmpTargetNode_inner {padding-top:0px; background-color:#aaa; color:white; height:21px; border:1px #666 solid;
opacity:0.8; filter:alpha(opacity=80)}
.ztree li a.tmpTargetNode_prev {}
.ztree li a.tmpTargetNode_next {}
.ztree li a input.rename {height:14px; width:80px; padding:0; margin:0;
font-size:12px; border:1px #7EC4CC solid; *border:0px}
.ztree li span {line-height:21px; margin-right:2px}
.ztree li span {line-height:23px; margin-right:2px}
.ztree li span.button {line-height:0; margin:0; width:21px; height:21px; display: inline-block; vertical-align:middle;
border:0 none; cursor: pointer;outline:none;
background-color:transparent; background-repeat:no-repeat; background-attachment: scroll;
@@ -59,8 +59,8 @@ website: http://code.google.com/p/jquerytree/
.ztree li span.button.roots_close{background-position: -126px 0;}
.ztree li span.button.center_open{background-position: -105px -21px;}
.ztree li span.button.center_close{background-position: -126px -21px;}
.ztree li span.button.bottom_open{background-position: -105px -42px;}
.ztree li span.button.bottom_close{background-position: -126px -42px;}
.ztree li span.button.bottom_open{background-position: -105px -43px;}
.ztree li span.button.bottom_close{background-position: -126px -43px;}
.ztree li span.button.noline_open{background-position: -126px -84px;}
.ztree li span.button.noline_close{background-position: -105px -84px;}
.ztree li span.button.root_docu{ background:none;}

File diff suppressed because one or more lines are too long

View File

@@ -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]();

View File

@@ -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 || {}){

View File

@@ -15,5 +15,4 @@ cd ..
call mvn clean deploy -Dmaven.test.skip=true -Pdeploy
cd bin
cmd /c msg %username% /time:0 /w "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>..."
pause

View 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

View File

@@ -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

View File

@@ -15,5 +15,4 @@ cd ..
call mvn clean install -Dmaven.test.skip=true -Ppackage
cd bin
cmd /c msg %username% /time:0 /w "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>..."
pause

View 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

View File

@@ -11,8 +11,8 @@
</page_setting>
<category_index>0</category_index>
<zoom>1.0</zoom>
<x>317</x>
<y>2406</y>
<x>1625</x>
<y>0</y>
<default_color>
<r>128</r>
<g>128</g>
@@ -4548,229 +4548,6 @@
<schema></schema>
</table_properties>
</table>
<table>
<id>fe9991829b27dafb45a95e13b6e9dd724b3bf424</id>
<height>308</height>
<width>335</width>
<font_name>Segoe UI</font_name>
<font_size>9</font_size>
<x>3897</x>
<y>792</y>
<color>
<r>128</r>
<g>128</g>
<b>192</b>
</color>
<connections>
</connections>
<physical_name>js_sys_lang</physical_name>
<logical_name>国际化语言</logical_name>
<description></description>
<constraint></constraint>
<primary_key_name></primary_key_name>
<option></option>
<columns>
<normal_column>
<word_id>869fc70cf3a4e92e8056b40814df8e03f9f9efde</word_id>
<id>58d907ff9cf0c81b565cad158f3bec8b3758d59e</id>
<description></description>
<unique_key_name></unique_key_name>
<logical_name></logical_name>
<physical_name></physical_name>
<type>varchar(n)</type>
<constraint></constraint>
<default_value></default_value>
<auto_increment>false</auto_increment>
<foreign_key>false</foreign_key>
<not_null>true</not_null>
<primary_key>true</primary_key>
<unique_key>false</unique_key>
<character_set></character_set>
<collation></collation>
<sequence>
<name></name>
<schema></schema>
<increment></increment>
<min_value></min_value>
<max_value></max_value>
<start></start>
<cache></cache>
<nocache>false</nocache>
<cycle>false</cycle>
<order>false</order>
<description></description>
<data_type></data_type>
<decimal_size>0</decimal_size>
</sequence>
</normal_column>
<normal_column>
<word_id>c2c68b3979b0c52109cb085c491bebb415a189b4</word_id>
<id>669456aef17849070945f58eba9269628ad31cc2</id>
<description></description>
<unique_key_name></unique_key_name>
<logical_name></logical_name>
<physical_name></physical_name>
<type>varchar(n)</type>
<constraint></constraint>
<default_value></default_value>
<auto_increment>false</auto_increment>
<foreign_key>false</foreign_key>
<not_null>true</not_null>
<primary_key>false</primary_key>
<unique_key>false</unique_key>
<character_set></character_set>
<collation></collation>
<sequence>
<name></name>
<schema></schema>
<increment></increment>
<min_value></min_value>
<max_value></max_value>
<start></start>
<cache></cache>
<nocache>false</nocache>
<cycle>false</cycle>
<order>false</order>
<description></description>
<data_type></data_type>
<decimal_size>0</decimal_size>
</sequence>
</normal_column>
<normal_column>
<word_id>2392b56eaf51ec9f6e32fe6553460d25b3da9729</word_id>
<id>1832e034e60a8176274736a921861da8f4a17b1f</id>
<description></description>
<unique_key_name></unique_key_name>
<logical_name></logical_name>
<physical_name></physical_name>
<type>nvarchar(n)</type>
<constraint></constraint>
<default_value></default_value>
<auto_increment>false</auto_increment>
<foreign_key>false</foreign_key>
<not_null>true</not_null>
<primary_key>false</primary_key>
<unique_key>false</unique_key>
<character_set></character_set>
<collation></collation>
<sequence>
<name></name>
<schema></schema>
<increment></increment>
<min_value></min_value>
<max_value></max_value>
<start></start>
<cache></cache>
<nocache>false</nocache>
<cycle>false</cycle>
<order>false</order>
<description></description>
<data_type></data_type>
<decimal_size>0</decimal_size>
</sequence>
</normal_column>
<normal_column>
<word_id>26c952fa648f51d2350f628195fc098f918d8149</word_id>
<id>923b79d81325f08f9ef6d6cc4302024dd0717bad</id>
<description></description>
<unique_key_name></unique_key_name>
<logical_name></logical_name>
<physical_name></physical_name>
<type>nvarchar(n)</type>
<constraint></constraint>
<default_value></default_value>
<auto_increment>false</auto_increment>
<foreign_key>false</foreign_key>
<not_null>true</not_null>
<primary_key>false</primary_key>
<unique_key>false</unique_key>
<character_set></character_set>
<collation></collation>
<sequence>
<name></name>
<schema></schema>
<increment></increment>
<min_value></min_value>
<max_value></max_value>
<start></start>
<cache></cache>
<nocache>false</nocache>
<cycle>false</cycle>
<order>false</order>
<description></description>
<data_type></data_type>
<decimal_size>0</decimal_size>
</sequence>
</normal_column>
<normal_column>
<word_id>26bbe2ffbcc2678b0691f0721632c3dcdabfb4ff</word_id>
<id>b3438798385ef62434d0cdef3d6d9fa7a63e313c</id>
<description></description>
<unique_key_name></unique_key_name>
<logical_name></logical_name>
<physical_name></physical_name>
<type>varchar(n)</type>
<constraint></constraint>
<default_value></default_value>
<auto_increment>false</auto_increment>
<foreign_key>false</foreign_key>
<not_null>true</not_null>
<primary_key>false</primary_key>
<unique_key>false</unique_key>
<character_set></character_set>
<collation></collation>
<sequence>
<name></name>
<schema></schema>
<increment></increment>
<min_value></min_value>
<max_value></max_value>
<start></start>
<cache></cache>
<nocache>false</nocache>
<cycle>false</cycle>
<order>false</order>
<description></description>
<data_type></data_type>
<decimal_size>0</decimal_size>
</sequence>
</normal_column>
<column_group>85024a2953cf3e3c9c1cce49b2351853ab0d125b</column_group>
</columns>
<indexes>
<inidex>
<full_text>false</full_text>
<non_unique>true</non_unique>
<name>idx_sys_lang_code</name>
<type></type>
<description></description>
<columns>
<column>
<id>1832e034e60a8176274736a921861da8f4a17b1f</id>
<desc>false</desc>
</column>
</columns>
</inidex>
<inidex>
<full_text>false</full_text>
<non_unique>true</non_unique>
<name>idx_sys_lang_type</name>
<type></type>
<description></description>
<columns>
<column>
<id>b3438798385ef62434d0cdef3d6d9fa7a63e313c</id>
<desc>false</desc>
</column>
</columns>
</inidex>
</indexes>
<complex_unique_key_list>
</complex_unique_key_list>
<table_properties>
<schema></schema>
</table_properties>
</table>
<table>
<id>dfd92f583371dc219fe0aeb5c64f4d7fc5b2db58</id>
<height>620</height>
@@ -8200,8 +7977,8 @@
</color>
<connections>
<relation>
<id>8a39f8544732bdd0c9731340ee2fe7e265b9b3cb</id>
<source>a1303ae2ba44af053708a3742aee02836c407c3d</source>
<id>34abbb77c48708f95ddab5edd1235da98a90ea5f</id>
<source>bbe68e376638ab208682d127d252c38bb6c953a5</source>
<target>3c87a1572923924d481891ca9d1a09451008cef5</target>
<source_xp>-1</source_xp>
<source_yp>-1</source_yp>
@@ -8288,7 +8065,7 @@
<normal_column>
<id>1882f53a36409270c8622486740876fcb2af9842</id>
<referenced_column>e84c40cdf5ffdb2ba4d59630d98abb5972d74795</referenced_column>
<relation>8a39f8544732bdd0c9731340ee2fe7e265b9b3cb</relation>
<relation>34abbb77c48708f95ddab5edd1235da98a90ea5f</relation>
<description></description>
<unique_key_name></unique_key_name>
<logical_name></logical_name>
@@ -13794,12 +13571,12 @@
</table_properties>
</table>
<table>
<id>a1303ae2ba44af053708a3742aee02836c407c3d</id>
<height>1218</height>
<id>bbe68e376638ab208682d127d252c38bb6c953a5</id>
<height>1244</height>
<width>617</width>
<font_name>Segoe UI</font_name>
<font_size>9</font_size>
<x>2280</x>
<x>2292</x>
<y>36</y>
<color>
<r>128</r>
@@ -14387,13 +14164,13 @@
</table_properties>
</table>
<table>
<id>0e046d64a970231cfcc17e4e5c4bc281c289072f</id>
<height>360</height>
<id>8a139a0643de7dcb7489ba3a6eb8072830e2442c</id>
<height>906</height>
<width>470</width>
<font_name>Segoe UI</font_name>
<font_size>9</font_size>
<x>108</x>
<y>2412</y>
<y>2340</y>
<color>
<r>128</r>
<g>128</g>
@@ -14401,9 +14178,9 @@
</color>
<connections>
<relation>
<id>9d81b7570b3ebdcbbaeb87693137d863d319e742</id>
<source>ea4a1c367ad1a436305eb4c93d3d1f87ac140ba1</source>
<target>0e046d64a970231cfcc17e4e5c4bc281c289072f</target>
<id>b0046026a86b96d1e93facef0237f3f72c3a6460</id>
<source>d6c60af63d4b54ff24149a17b7dbef6ba492e484</source>
<target>8a139a0643de7dcb7489ba3a6eb8072830e2442c</target>
<source_xp>-1</source_xp>
<source_yp>-1</source_yp>
<target_xp>-1</target_xp>
@@ -14466,7 +14243,7 @@
<normal_column>
<id>fc44d466dd6009e48b5222d1d71e38d025194ff0</id>
<referenced_column>54b86f255d95078898534902087fb704b4265b60</referenced_column>
<relation>9d81b7570b3ebdcbbaeb87693137d863d319e742</relation>
<relation>b0046026a86b96d1e93facef0237f3f72c3a6460</relation>
<description></description>
<unique_key_name></unique_key_name>
<logical_name></logical_name>
@@ -14663,6 +14440,7 @@
</sequence>
</normal_column>
<column_group>35ae805d1da92afdb99b2fe8c536d1649356fccd</column_group>
<column_group>118dab95fc1f792cd468b9f66af2d4fabd98c39b</column_group>
</columns>
<indexes>
<inidex>
@@ -16474,13 +16252,13 @@
</table_properties>
</table>
<table>
<id>ea4a1c367ad1a436305eb4c93d3d1f87ac140ba1</id>
<height>230</height>
<id>d6c60af63d4b54ff24149a17b7dbef6ba492e484</id>
<height>256</height>
<width>397</width>
<font_name>Segoe UI</font_name>
<font_size>9</font_size>
<x>852</x>
<y>2451</y>
<x>732</x>
<y>2520</y>
<color>
<r>128</r>
<g>128</g>
@@ -16794,6 +16572,229 @@
<schema></schema>
</table_properties>
</table>
<table>
<id>fe9991829b27dafb45a95e13b6e9dd724b3bf424</id>
<height>308</height>
<width>335</width>
<font_name>Segoe UI</font_name>
<font_size>9</font_size>
<x>3897</x>
<y>792</y>
<color>
<r>128</r>
<g>128</g>
<b>192</b>
</color>
<connections>
</connections>
<physical_name>js_sys_lang</physical_name>
<logical_name>国际化语言</logical_name>
<description></description>
<constraint></constraint>
<primary_key_name></primary_key_name>
<option></option>
<columns>
<normal_column>
<word_id>869fc70cf3a4e92e8056b40814df8e03f9f9efde</word_id>
<id>58d907ff9cf0c81b565cad158f3bec8b3758d59e</id>
<description></description>
<unique_key_name></unique_key_name>
<logical_name></logical_name>
<physical_name></physical_name>
<type>varchar(n)</type>
<constraint></constraint>
<default_value></default_value>
<auto_increment>false</auto_increment>
<foreign_key>false</foreign_key>
<not_null>true</not_null>
<primary_key>true</primary_key>
<unique_key>false</unique_key>
<character_set></character_set>
<collation></collation>
<sequence>
<name></name>
<schema></schema>
<increment></increment>
<min_value></min_value>
<max_value></max_value>
<start></start>
<cache></cache>
<nocache>false</nocache>
<cycle>false</cycle>
<order>false</order>
<description></description>
<data_type></data_type>
<decimal_size>0</decimal_size>
</sequence>
</normal_column>
<normal_column>
<word_id>c2c68b3979b0c52109cb085c491bebb415a189b4</word_id>
<id>669456aef17849070945f58eba9269628ad31cc2</id>
<description></description>
<unique_key_name></unique_key_name>
<logical_name></logical_name>
<physical_name></physical_name>
<type>varchar(n)</type>
<constraint></constraint>
<default_value></default_value>
<auto_increment>false</auto_increment>
<foreign_key>false</foreign_key>
<not_null>true</not_null>
<primary_key>false</primary_key>
<unique_key>false</unique_key>
<character_set></character_set>
<collation></collation>
<sequence>
<name></name>
<schema></schema>
<increment></increment>
<min_value></min_value>
<max_value></max_value>
<start></start>
<cache></cache>
<nocache>false</nocache>
<cycle>false</cycle>
<order>false</order>
<description></description>
<data_type></data_type>
<decimal_size>0</decimal_size>
</sequence>
</normal_column>
<normal_column>
<word_id>2392b56eaf51ec9f6e32fe6553460d25b3da9729</word_id>
<id>1832e034e60a8176274736a921861da8f4a17b1f</id>
<description></description>
<unique_key_name></unique_key_name>
<logical_name></logical_name>
<physical_name></physical_name>
<type>nvarchar(n)</type>
<constraint></constraint>
<default_value></default_value>
<auto_increment>false</auto_increment>
<foreign_key>false</foreign_key>
<not_null>true</not_null>
<primary_key>false</primary_key>
<unique_key>false</unique_key>
<character_set></character_set>
<collation></collation>
<sequence>
<name></name>
<schema></schema>
<increment></increment>
<min_value></min_value>
<max_value></max_value>
<start></start>
<cache></cache>
<nocache>false</nocache>
<cycle>false</cycle>
<order>false</order>
<description></description>
<data_type></data_type>
<decimal_size>0</decimal_size>
</sequence>
</normal_column>
<normal_column>
<word_id>26c952fa648f51d2350f628195fc098f918d8149</word_id>
<id>923b79d81325f08f9ef6d6cc4302024dd0717bad</id>
<description></description>
<unique_key_name></unique_key_name>
<logical_name></logical_name>
<physical_name></physical_name>
<type>nvarchar(n)</type>
<constraint></constraint>
<default_value></default_value>
<auto_increment>false</auto_increment>
<foreign_key>false</foreign_key>
<not_null>true</not_null>
<primary_key>false</primary_key>
<unique_key>false</unique_key>
<character_set></character_set>
<collation></collation>
<sequence>
<name></name>
<schema></schema>
<increment></increment>
<min_value></min_value>
<max_value></max_value>
<start></start>
<cache></cache>
<nocache>false</nocache>
<cycle>false</cycle>
<order>false</order>
<description></description>
<data_type></data_type>
<decimal_size>0</decimal_size>
</sequence>
</normal_column>
<normal_column>
<word_id>26bbe2ffbcc2678b0691f0721632c3dcdabfb4ff</word_id>
<id>b3438798385ef62434d0cdef3d6d9fa7a63e313c</id>
<description></description>
<unique_key_name></unique_key_name>
<logical_name></logical_name>
<physical_name></physical_name>
<type>varchar(n)</type>
<constraint></constraint>
<default_value></default_value>
<auto_increment>false</auto_increment>
<foreign_key>false</foreign_key>
<not_null>true</not_null>
<primary_key>false</primary_key>
<unique_key>false</unique_key>
<character_set></character_set>
<collation></collation>
<sequence>
<name></name>
<schema></schema>
<increment></increment>
<min_value></min_value>
<max_value></max_value>
<start></start>
<cache></cache>
<nocache>false</nocache>
<cycle>false</cycle>
<order>false</order>
<description></description>
<data_type></data_type>
<decimal_size>0</decimal_size>
</sequence>
</normal_column>
<column_group>85024a2953cf3e3c9c1cce49b2351853ab0d125b</column_group>
</columns>
<indexes>
<inidex>
<full_text>false</full_text>
<non_unique>true</non_unique>
<name>idx_sys_lang_code</name>
<type></type>
<description></description>
<columns>
<column>
<id>1832e034e60a8176274736a921861da8f4a17b1f</id>
<desc>false</desc>
</column>
</columns>
</inidex>
<inidex>
<full_text>false</full_text>
<non_unique>true</non_unique>
<name>idx_sys_lang_type</name>
<type></type>
<description></description>
<columns>
<column>
<id>b3438798385ef62434d0cdef3d6d9fa7a63e313c</id>
<desc>false</desc>
</column>
</columns>
</inidex>
</indexes>
<complex_unique_key_list>
</complex_unique_key_list>
<table_properties>
<schema></schema>
</table_properties>
</table>
</contents>
<column_groups>
<column_group>

View File

@@ -292,6 +292,26 @@ CREATE TABLE js_sys_file_upload
update_by varchar(64) NOT NULL,
update_date timestamp NOT NULL,
remarks vargraphic(500),
extend_s1 vargraphic(500),
extend_s2 vargraphic(500),
extend_s3 vargraphic(500),
extend_s4 vargraphic(500),
extend_s5 vargraphic(500),
extend_s6 vargraphic(500),
extend_s7 vargraphic(500),
extend_s8 vargraphic(500),
extend_i1 decimal(19),
extend_i2 decimal(19),
extend_i3 decimal(19),
extend_i4 decimal(19),
extend_f1 decimal(19,4),
extend_f2 decimal(19,4),
extend_f3 decimal(19,4),
extend_f4 decimal(19,4),
extend_d1 timestamp,
extend_d2 timestamp,
extend_d3 timestamp,
extend_d4 timestamp,
PRIMARY KEY (id)
);

View File

@@ -292,6 +292,26 @@ CREATE TABLE js_sys_file_upload
update_by varchar(64) NOT NULL,
update_date datetime NOT NULL,
remarks varchar(500),
extend_s1 varchar(500),
extend_s2 varchar(500),
extend_s3 varchar(500),
extend_s4 varchar(500),
extend_s5 varchar(500),
extend_s6 varchar(500),
extend_s7 varchar(500),
extend_s8 varchar(500),
extend_i1 decimal(19),
extend_i2 decimal(19),
extend_i3 decimal(19),
extend_i4 decimal(19),
extend_f1 decimal(19,4),
extend_f2 decimal(19,4),
extend_f3 decimal(19,4),
extend_f4 decimal(19,4),
extend_d1 datetime,
extend_d2 datetime,
extend_d3 datetime,
extend_d4 datetime,
PRIMARY KEY (id)
);

View File

@@ -292,6 +292,26 @@ CREATE TABLE [js_sys_file_upload]
[update_by] varchar(64) NOT NULL,
[update_date] datetime NOT NULL,
[remarks] nvarchar(500),
[extend_s1] nvarchar(500),
[extend_s2] nvarchar(500),
[extend_s3] nvarchar(500),
[extend_s4] nvarchar(500),
[extend_s5] nvarchar(500),
[extend_s6] nvarchar(500),
[extend_s7] nvarchar(500),
[extend_s8] nvarchar(500),
[extend_i1] decimal(19),
[extend_i2] decimal(19),
[extend_i3] decimal(19),
[extend_i4] decimal(19),
[extend_f1] decimal(19,4),
[extend_f2] decimal(19,4),
[extend_f3] decimal(19,4),
[extend_f4] decimal(19,4),
[extend_d1] datetime,
[extend_d2] datetime,
[extend_d3] datetime,
[extend_d4] datetime,
PRIMARY KEY ([id])
);

View File

@@ -293,6 +293,26 @@ CREATE TABLE js_sys_file_upload
update_by varchar(64) NOT NULL COMMENT '更新者',
update_date datetime NOT NULL COMMENT '更新时间',
remarks varchar(500) COMMENT '备注信息',
extend_s1 varchar(500) COMMENT '扩展 String 1',
extend_s2 varchar(500) COMMENT '扩展 String 2',
extend_s3 varchar(500) COMMENT '扩展 String 3',
extend_s4 varchar(500) COMMENT '扩展 String 4',
extend_s5 varchar(500) COMMENT '扩展 String 5',
extend_s6 varchar(500) COMMENT '扩展 String 6',
extend_s7 varchar(500) COMMENT '扩展 String 7',
extend_s8 varchar(500) COMMENT '扩展 String 8',
extend_i1 decimal(19) COMMENT '扩展 Integer 1',
extend_i2 decimal(19) COMMENT '扩展 Integer 2',
extend_i3 decimal(19) COMMENT '扩展 Integer 3',
extend_i4 decimal(19) COMMENT '扩展 Integer 4',
extend_f1 decimal(19,4) COMMENT '扩展 Float 1',
extend_f2 decimal(19,4) COMMENT '扩展 Float 2',
extend_f3 decimal(19,4) COMMENT '扩展 Float 3',
extend_f4 decimal(19,4) COMMENT '扩展 Float 4',
extend_d1 datetime COMMENT '扩展 Date 1',
extend_d2 datetime COMMENT '扩展 Date 2',
extend_d3 datetime COMMENT '扩展 Date 3',
extend_d4 datetime COMMENT '扩展 Date 4',
PRIMARY KEY (id)
) COMMENT = '文件上传表';

View File

@@ -292,6 +292,26 @@ CREATE TABLE js_sys_file_upload
update_by varchar2(64) NOT NULL,
update_date timestamp NOT NULL,
remarks nvarchar2(500),
extend_s1 nvarchar2(500),
extend_s2 nvarchar2(500),
extend_s3 nvarchar2(500),
extend_s4 nvarchar2(500),
extend_s5 nvarchar2(500),
extend_s6 nvarchar2(500),
extend_s7 nvarchar2(500),
extend_s8 nvarchar2(500),
extend_i1 number(19),
extend_i2 number(19),
extend_i3 number(19),
extend_i4 number(19),
extend_f1 number(19,4),
extend_f2 number(19,4),
extend_f3 number(19,4),
extend_f4 number(19,4),
extend_d1 timestamp,
extend_d2 timestamp,
extend_d3 timestamp,
extend_d4 timestamp,
PRIMARY KEY (id)
);
@@ -1136,6 +1156,26 @@ COMMENT ON COLUMN js_sys_file_upload.create_date IS '创建时间';
COMMENT ON COLUMN js_sys_file_upload.update_by IS '更新者';
COMMENT ON COLUMN js_sys_file_upload.update_date IS '更新时间';
COMMENT ON COLUMN js_sys_file_upload.remarks IS '备注信息';
COMMENT ON COLUMN js_sys_file_upload.extend_s1 IS '扩展 String 1';
COMMENT ON COLUMN js_sys_file_upload.extend_s2 IS '扩展 String 2';
COMMENT ON COLUMN js_sys_file_upload.extend_s3 IS '扩展 String 3';
COMMENT ON COLUMN js_sys_file_upload.extend_s4 IS '扩展 String 4';
COMMENT ON COLUMN js_sys_file_upload.extend_s5 IS '扩展 String 5';
COMMENT ON COLUMN js_sys_file_upload.extend_s6 IS '扩展 String 6';
COMMENT ON COLUMN js_sys_file_upload.extend_s7 IS '扩展 String 7';
COMMENT ON COLUMN js_sys_file_upload.extend_s8 IS '扩展 String 8';
COMMENT ON COLUMN js_sys_file_upload.extend_i1 IS '扩展 Integer 1';
COMMENT ON COLUMN js_sys_file_upload.extend_i2 IS '扩展 Integer 2';
COMMENT ON COLUMN js_sys_file_upload.extend_i3 IS '扩展 Integer 3';
COMMENT ON COLUMN js_sys_file_upload.extend_i4 IS '扩展 Integer 4';
COMMENT ON COLUMN js_sys_file_upload.extend_f1 IS '扩展 Float 1';
COMMENT ON COLUMN js_sys_file_upload.extend_f2 IS '扩展 Float 2';
COMMENT ON COLUMN js_sys_file_upload.extend_f3 IS '扩展 Float 3';
COMMENT ON COLUMN js_sys_file_upload.extend_f4 IS '扩展 Float 4';
COMMENT ON COLUMN js_sys_file_upload.extend_d1 IS '扩展 Date 1';
COMMENT ON COLUMN js_sys_file_upload.extend_d2 IS '扩展 Date 2';
COMMENT ON COLUMN js_sys_file_upload.extend_d3 IS '扩展 Date 3';
COMMENT ON COLUMN js_sys_file_upload.extend_d4 IS '扩展 Date 4';
COMMENT ON TABLE js_sys_job IS '作业调度表';
COMMENT ON COLUMN js_sys_job.job_name IS '任务名称';
COMMENT ON COLUMN js_sys_job.job_group IS '任务组名';

View File

@@ -292,6 +292,26 @@ CREATE TABLE js_sys_file_upload
update_by varchar(64) NOT NULL,
update_date timestamp NOT NULL,
remarks varchar(500),
extend_s1 varchar(500),
extend_s2 varchar(500),
extend_s3 varchar(500),
extend_s4 varchar(500),
extend_s5 varchar(500),
extend_s6 varchar(500),
extend_s7 varchar(500),
extend_s8 varchar(500),
extend_i1 decimal(19),
extend_i2 decimal(19),
extend_i3 decimal(19),
extend_i4 decimal(19),
extend_f1 decimal(19,4),
extend_f2 decimal(19,4),
extend_f3 decimal(19,4),
extend_f4 decimal(19,4),
extend_d1 timestamp,
extend_d2 timestamp,
extend_d3 timestamp,
extend_d4 timestamp,
PRIMARY KEY (id)
) WITHOUT OIDS;
@@ -1136,6 +1156,26 @@ COMMENT ON COLUMN js_sys_file_upload.create_date IS '创建时间';
COMMENT ON COLUMN js_sys_file_upload.update_by IS '更新者';
COMMENT ON COLUMN js_sys_file_upload.update_date IS '更新时间';
COMMENT ON COLUMN js_sys_file_upload.remarks IS '备注信息';
COMMENT ON COLUMN js_sys_file_upload.extend_s1 IS '扩展 String 1';
COMMENT ON COLUMN js_sys_file_upload.extend_s2 IS '扩展 String 2';
COMMENT ON COLUMN js_sys_file_upload.extend_s3 IS '扩展 String 3';
COMMENT ON COLUMN js_sys_file_upload.extend_s4 IS '扩展 String 4';
COMMENT ON COLUMN js_sys_file_upload.extend_s5 IS '扩展 String 5';
COMMENT ON COLUMN js_sys_file_upload.extend_s6 IS '扩展 String 6';
COMMENT ON COLUMN js_sys_file_upload.extend_s7 IS '扩展 String 7';
COMMENT ON COLUMN js_sys_file_upload.extend_s8 IS '扩展 String 8';
COMMENT ON COLUMN js_sys_file_upload.extend_i1 IS '扩展 Integer 1';
COMMENT ON COLUMN js_sys_file_upload.extend_i2 IS '扩展 Integer 2';
COMMENT ON COLUMN js_sys_file_upload.extend_i3 IS '扩展 Integer 3';
COMMENT ON COLUMN js_sys_file_upload.extend_i4 IS '扩展 Integer 4';
COMMENT ON COLUMN js_sys_file_upload.extend_f1 IS '扩展 Float 1';
COMMENT ON COLUMN js_sys_file_upload.extend_f2 IS '扩展 Float 2';
COMMENT ON COLUMN js_sys_file_upload.extend_f3 IS '扩展 Float 3';
COMMENT ON COLUMN js_sys_file_upload.extend_f4 IS '扩展 Float 4';
COMMENT ON COLUMN js_sys_file_upload.extend_d1 IS '扩展 Date 1';
COMMENT ON COLUMN js_sys_file_upload.extend_d2 IS '扩展 Date 2';
COMMENT ON COLUMN js_sys_file_upload.extend_d3 IS '扩展 Date 3';
COMMENT ON COLUMN js_sys_file_upload.extend_d4 IS '扩展 Date 4';
COMMENT ON TABLE js_sys_job IS '作业调度表';
COMMENT ON COLUMN js_sys_job.job_name IS '任务名称';
COMMENT ON COLUMN js_sys_job.job_group IS '任务组名';

View File

@@ -6,7 +6,7 @@
<parent>
<groupId>com.jeesite</groupId>
<artifactId>jeesite-parent</artifactId>
<version>4.2.0-SNAPSHOT</version>
<version>4.2.3-SNAPSHOT</version>
<relativePath>../../parent/pom.xml</relativePath>
</parent>

View File

@@ -3,10 +3,12 @@
*/
package com.jeesite.autoconfigure.sys;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.jeesite.common.mybatis.MyBatisFactoryBean;
import com.jeesite.modules.sys.service.AreaService;
import com.jeesite.modules.sys.service.CompanyService;
import com.jeesite.modules.sys.service.EmpUserService;
@@ -27,7 +29,8 @@ import com.jeesite.modules.sys.service.support.PostServiceSupport;
* @author ThinkGem
* @version 2018-10-13
*/
@Configuration
@Configuration(proxyBeanMethods = false)
@ConditionalOnBean(MyBatisFactoryBean.class)
public class SysAutoConfiguration {
@Bean

View File

@@ -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;
}
}

View File

@@ -34,31 +34,31 @@ 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;
import com.jeesite.modules.sys.entity.User;
import com.jeesite.modules.sys.utils.LogUtils;
import com.jeesite.modules.sys.utils.UserUtils;
import com.jeesite.modules.sys.utils.ValidCodeUtils;
/**
* 表单验证(包含验证码)过滤类
* @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 +68,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 +102,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 +129,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 +168,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;
@@ -236,35 +244,70 @@ public class FormAuthenticationFilter extends org.apache.shiro.web.filter.authc.
protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
// 是否在登录后生成新的Session默认false
if (Global.getPropertyToBoolean("shiro.isGenerateNewSessionAfterLogin", "false")){
String[] keys = new String[] {ValidCodeUtils.VALID_CODE};
Map<String, Object> map = MapUtils.newHashMap();
final Session sessionOld = UserUtils.getSession();
for (String key : keys) {
Object value = sessionOld.getAttribute(key);
if (value != null) {
map.put(key, value);
}
}
UserUtils.getSubject().logout();
// 恢复生成新的Session之前的Session数据
final Session sessionNew = UserUtils.getSession();
map.forEach((key, value) -> {
sessionNew.setAttribute(key, value);
});
}
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 +315,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 +337,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 +359,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 +409,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;
}
}

View File

@@ -26,7 +26,7 @@ import com.jeesite.common.web.http.ServletUtils;
*/
public class LogoutFilter extends org.apache.shiro.web.filter.authc.LogoutFilter {
private static final Logger log = LoggerFactory.getLogger(LogoutFilter.class);
private static final Logger logger = LoggerFactory.getLogger(LogoutFilter.class);
private BaseAuthorizingRealm authorizingRealm; // 安全认证类
@Override
@@ -38,21 +38,22 @@ 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();
} catch (SessionException ise) {
log.debug("Encountered session exception during logout. This can generally safely be ignored.", ise);
logger.debug("Encountered session exception during logout. This can generally safely be ignored.", ise);
}
// 如果是Ajax请求返回Json字符串。
@@ -64,7 +65,7 @@ public class LogoutFilter extends org.apache.shiro.web.filter.authc.LogoutFilter
issueRedirect(request, response, redirectUrl);
}catch(Exception e){
log.debug("Encountered session exception during logout. This can generally safely be ignored.", e);
logger.debug("Encountered session exception during logout. This can generally safely be ignored.", e);
}
return false;
}

View File

@@ -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());

View File

@@ -13,6 +13,7 @@ import org.apache.shiro.cas.CasSubjectFactory;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.web.filter.InvalidRequestFilter;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
@@ -45,7 +46,7 @@ import com.jeesite.common.shiro.web.WebSecurityManager;
* @version 2018-7-11
*/
@SuppressWarnings("deprecation")
@Configuration
@Configuration(proxyBeanMethods = false)
public class ShiroConfig {
/**
@@ -115,6 +116,15 @@ public class ShiroConfig {
private UserFilter shiroUserFilter() {
return new UserFilter();
}
/**
* 非法请求过滤器
*/
private InvalidRequestFilter invalidRequestFilter() {
InvalidRequestFilter bean = new InvalidRequestFilter();
bean.setBlockNonAscii(false);
return bean;
}
/**
* Shiro认证过滤器
@@ -134,6 +144,7 @@ public class ShiroConfig {
filters.put("perms", shiroPermsFilter());
filters.put("roles", shiroRolesFilter());
filters.put("user", shiroUserFilter());
filters.put("invalidRequest", invalidRequestFilter());
FilterChainDefinitionMap chains = new FilterChainDefinitionMap();
chains.setFilterChainDefinitions(Global.getProperty("shiro.filterChainDefinitions"));
chains.setDefaultFilterChainDefinitions(Global.getProperty("shiro.defaultFilterChainDefinitions"));

View File

@@ -17,7 +17,7 @@ import com.alibaba.druid.support.http.WebStatFilter;
* @author ThinkGem
* @version 2017年11月30日
*/
@Configuration
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(name="state.enabled", havingValue="true", matchIfMissing=true)
public class DruidStatConfig {

View File

@@ -25,7 +25,7 @@ import org.springframework.core.Ordered;
* @author ThinkGem
* @version 2020年1月21日
*/
@Configuration
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(name="server.schemeHttps", havingValue="true", matchIfMissing=false)
public class SchemeHttpsConfig {

View File

@@ -19,9 +19,9 @@ import com.jeesite.modules.sys.interceptor.LogInterceptor;
* @author ThinkGem
* @version 2018年1月10日
*/
@Configuration
@EnableWebMvc
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(name="web.interceptor.log.enabled", havingValue="true", matchIfMissing=true)
@EnableWebMvc
public class LogInterceptorConfig implements WebMvcConfigurer {
@Override

View File

@@ -19,9 +19,9 @@ import com.jeesite.modules.sys.interceptor.MobileInterceptor;
* @author ThinkGem
* @version 2018年1月10日
*/
@Configuration
@EnableWebMvc
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(name="web.interceptor.mobile.enabled", havingValue="true", matchIfMissing=false)
@EnableWebMvc
public class MobileViewInterceptorConfig implements WebMvcConfigurer {
@Override

View File

@@ -21,7 +21,7 @@ import com.jeesite.common.mybatis.mapper.query.QueryType;
* @author ThinkGem
* @version 2019-03-12
*/
@Table(name="${_prefix}sys_msg_inner", alias="a", columns={
@Table(name="${_prefix}sys_msg_inner", alias="a", label="内部消息", columns={
@Column(name="id", attrName="id", label="编号", isPK=true),
@Column(name="msg_title", attrName="msgTitle", label="消息标题", queryType=QueryType.LIKE),
@Column(name="content_level", attrName="contentLevel", label="内容等级", comment="内容等级1普通 2一般 3紧急"),

View File

@@ -20,7 +20,7 @@ import com.jeesite.common.mybatis.mapper.query.QueryType;
* @author ThinkGem
* @version 2019-03-12
*/
@Table(name="${_prefix}sys_msg_inner_record", alias="a", columns={
@Table(name="${_prefix}sys_msg_inner_record", alias="a", label="消息发送记录", columns={
@Column(name="id", attrName="id", label="编号", isPK=true),
@Column(name="msg_inner_id", attrName="msgInnerId", label="所属消息"),
@Column(name="receive_user_code", attrName="receiveUserCode", label="接受者用户编码"),

View File

@@ -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> {
}

View File

@@ -17,7 +17,7 @@ import com.jeesite.common.mybatis.mapper.query.QueryType;
* @author ThinkGem
* @version 2017-03-22
*/
@Table(name="${_prefix}sys_area", alias="a", columns={
@Table(name="${_prefix}sys_area", alias="a", label="区域信息", columns={
@Column(includeEntity=DataEntity.class),
@Column(includeEntity=TreeEntity.class),
@Column(name="area_code", attrName="areaCode", label="区域代码", isPK=true),

View File

@@ -28,7 +28,7 @@ import com.jeesite.common.mybatis.mapper.query.QueryType;
* @author ThinkGem
* @version 2017-03-23
*/
@Table(name="${_prefix}sys_company", alias="a", columns={
@Table(name="${_prefix}sys_company", alias="a", label="公司信息", columns={
@Column(includeEntity=BaseEntity.class),
@Column(includeEntity=DataEntity.class),
@Column(includeEntity=TreeEntity.class),

View File

@@ -24,7 +24,7 @@ import com.jeesite.common.utils.excel.fieldtype.OfficeType;
* @author ThinkGem
* @version 2017-03-25
*/
@Table(name="${_prefix}sys_user", alias="a", columns={
@Table(name="${_prefix}sys_user", alias="a", label="员工信息", columns={
@Column(includeEntity=User.class),
}, joinTable={
@JoinTable(type=Type.JOIN, entity=Employee.class, alias="e",
@@ -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);
@@ -118,7 +122,7 @@ public class EmpUser extends User {
public void setEmployee(Employee employee){
super.setRefObj(employee);
}
public String[] getCodes() {
return codes;
}

View File

@@ -24,7 +24,7 @@ import com.jeesite.common.mybatis.mapper.query.QueryType;
* @author ThinkGem
* @version 2017-03-25
*/
@Table(name="${_prefix}sys_employee", alias="a", columns={
@Table(name="${_prefix}sys_employee", alias="a", label="员工信息", columns={
@Column(includeEntity=BaseEntity.class),
@Column(includeEntity=DataEntity.class),
@Column(name="emp_code", attrName="empCode", label="员工编码", isPK=true),

View File

@@ -25,7 +25,7 @@ import com.jeesite.common.mybatis.mapper.query.QueryType;
* @author ThinkGem
* @version 2017-03-19
*/
@Table(name="${_prefix}sys_log", alias="a", columns={
@Table(name="${_prefix}sys_log", alias="a", label="操作日志", columns={
@Column(includeEntity=BaseEntity.class),
@Column(name="id", attrName="id", label="编码", isPK=true),
@Column(name="log_type", attrName="logType", label="日志类型"),
@@ -36,6 +36,7 @@ import com.jeesite.common.mybatis.mapper.query.QueryType;
@Column(name="request_uri", attrName="requestUri", label="请求URI", queryType=QueryType.LIKE),
@Column(name="request_method", attrName="requestMethod", label="操作方式"),
@Column(name="request_params", attrName="requestParams", label="操作提交的数据", queryType=QueryType.LIKE),
@Column(name="diff_modify_data",attrName="diffModifyData", label="差异修改数据", queryType=QueryType.LIKE),
@Column(name="biz_key", attrName="bizKey", label="业务主键"),
@Column(name="biz_type", attrName="bizType", label="业务类型"),
@Column(name="remote_addr", attrName="remoteAddr", label="操作IP地址"),
@@ -63,6 +64,7 @@ public class Log extends DataEntity<Log> {
private String requestUri; // 请求URI
private String requestMethod; // 操作方式
private String requestParams; // 操作提交的数据
private String diffModifyData; // 差异修改数据
private String bizKey; // 业务主键
private String bizType; // 业务类型
private String remoteAddr; // 操作IP地址
@@ -130,6 +132,14 @@ public class Log extends DataEntity<Log> {
this.requestParams = requestParams;
}
public String getDiffModifyData() {
return diffModifyData;
}
public void setDiffModifyData(String diffModifyData) {
this.diffModifyData = diffModifyData;
}
@Length(min=0, max=64, message="业务主键长度不能超过 64 个字符")
public String getBizKey() {
return bizKey;
@@ -220,6 +230,9 @@ public class Log extends DataEntity<Log> {
}
public String getExecuteTimeFormat(){
if (executeTime == null) {
executeTime = 0L;
}
return TimeUtils.formatDateAgo(executeTime);
}

View File

@@ -23,7 +23,7 @@ import com.jeesite.modules.sys.utils.EmpUtils;
* @author ThinkGem
* @version 2017-03-23
*/
@Table(name="${_prefix}sys_office", alias="a", columns={
@Table(name="${_prefix}sys_office", alias="a", label="组织机构", columns={
@Column(includeEntity=BaseEntity.class),
@Column(includeEntity=DataEntity.class),
@Column(includeEntity=TreeEntity.class),

View File

@@ -12,7 +12,7 @@ import com.jeesite.common.mybatis.annotation.Column;
import com.jeesite.common.mybatis.annotation.Table;
import com.jeesite.common.mybatis.mapper.query.QueryType;
@Table(name="${_prefix}sys_post", alias="a", columns={
@Table(name="${_prefix}sys_post", alias="a", label="岗位信息", columns={
@Column(includeEntity=BaseEntity.class),
@Column(includeEntity=DataEntity.class),
@Column(name="post_code", attrName="postCode", label="岗位编码", isPK=true),

View File

@@ -8,12 +8,15 @@ import java.text.SimpleDateFormat;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.MDC;
import org.springframework.core.NamedThreadLocal;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import com.jeesite.common.idgen.IdGen;
import com.jeesite.common.lang.ByteUtils;
import com.jeesite.common.lang.DateUtils;
import com.jeesite.common.lang.StringUtils;
import com.jeesite.common.lang.TimeUtils;
import com.jeesite.common.network.IpUtils;
import com.jeesite.common.service.BaseService;
@@ -27,12 +30,16 @@ import com.jeesite.modules.sys.utils.UserUtils;
*/
public class LogInterceptor extends BaseService implements HandlerInterceptor {
private static final String TRACE_ID = "TRACE_ID";
private static final ThreadLocal<Long> startTimeThreadLocal =
new NamedThreadLocal<Long>("LogInterceptor StartTime");
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
if (StringUtils.isBlank(MDC.get(TRACE_ID))) {
MDC.put(TRACE_ID, IdGen.nextId());
}
long beginTime = System.currentTimeMillis();// 1、开始时间
startTimeThreadLocal.set(beginTime); // 线程绑定变量(该数据只有当前请求的线程可见)
if (logger.isDebugEnabled()){
@@ -77,7 +84,7 @@ public class LogInterceptor extends BaseService implements HandlerInterceptor {
DateUtils.formatDate(endTime, "hh:mm:ss.SSS"), TimeUtils.formatDateAgo(executeTime), request.getRequestURI(),
ByteUtils.formatByteSize(runtime.totalMemory()), ByteUtils.formatByteSize(runtime.totalMemory()-runtime.freeMemory()));
}
MDC.remove(TRACE_ID);
}
}

View File

@@ -66,6 +66,7 @@ public class CompanyServiceSupport extends TreeService<CompanyDao, Company>
@Transactional(readOnly=false)
public void save(Company company) {
if (company.getIsNewRecord()){
// 生成主键,并验证改主键是否存在,如存在则抛出验证信息
genIdAndValid(company, company.getViewCode());
// 当前新数据授权,如果用户有上级数据权限,则当前数据也有相应的数据权限
dataScopeService.insertIfParentExists(company, "Company");

View File

@@ -59,6 +59,7 @@ public class OfficeServiceSupport extends TreeService<OfficeDao, Office>
@Transactional(readOnly=false)
public void save(Office office) {
if (office.getIsNewRecord()){
// 生成主键,并验证改主键是否存在,如存在则抛出验证信息
genIdAndValid(office, office.getViewCode());
// 当前新数据授权,如果用户有上级数据权限,则当前数据也有相应的数据权限
dataScopeService.insertIfParentExists(office, "Office");

View File

@@ -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;
}

View File

@@ -11,12 +11,12 @@ import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletRequest;
import io.netty.util.concurrent.DefaultThreadFactory;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.method.HandlerMethod;
@@ -29,6 +29,7 @@ import com.jeesite.common.mybatis.annotation.Column;
import com.jeesite.common.mybatis.annotation.Table;
import com.jeesite.common.mybatis.mapper.MapperHelper;
import com.jeesite.common.network.IpUtils;
import com.jeesite.common.utils.DiffDataUtils;
import com.jeesite.common.utils.SpringUtils;
import com.jeesite.common.web.http.UserAgentUtils;
import com.jeesite.modules.sys.entity.Log;
@@ -37,6 +38,7 @@ import com.jeesite.modules.sys.service.LogService;
import com.jeesite.modules.sys.service.MenuService;
import eu.bitwalker.useragentutils.UserAgent;
import io.netty.util.concurrent.DefaultThreadFactory;
/**
* 日志工具类
@@ -60,7 +62,7 @@ public class LogUtils {
// 参数名获取工具(尝试获取标注为@ModelAttribute注解的方法第一个参数名一般为主键名
private static ParameterNameDiscoverer pnd = new DefaultParameterNameDiscoverer();
/**
* 保存日志
*/
@@ -112,9 +114,14 @@ public class LogUtils {
if (throwable == null){
throwable = ExceptionUtils.getThrowable(request);
}
// 获取原数据和修改后的目标数据对象
Object sourceData = request.getAttribute(WebDataBinder.class.getName()+".SOURCE");
Object targetData = request.getAttribute(WebDataBinder.class.getName()+".TARGET");
// 异步保存日志
logThreadPool.submit(new SaveLogThread(log, handler, request.getContextPath(), throwable));
logThreadPool.submit(new SaveLogThread(log, handler, request.getContextPath(),
throwable, sourceData, targetData));
}
/**
* 保存日志线程
@@ -125,12 +132,17 @@ public class LogUtils {
private Object handler;
private String contextPath;
private Throwable throwable;
private Object sourceData;
private Object targetData;
public SaveLogThread(Log log, Object handler, String contextPath, Throwable throwable){
public SaveLogThread(Log log, Object handler, String contextPath,
Throwable throwable, Object sourceData, Object targetData){
this.log = log;
this.handler = handler;
this.contextPath = contextPath;
this.throwable = throwable;
this.sourceData = sourceData;
this.targetData = targetData;
}
@Override
@@ -217,11 +229,15 @@ public class LogUtils {
if (StringUtils.isBlank(log.getRequestUri()) && StringUtils.isBlank(log.getExceptionInfo())){
return;
}
// 如果是修改类型的日志,则获取修改前后的差异数据
if (Log.TYPE_UPDATE.equals(log.getLogType()) && sourceData != null && targetData != null) {
log.setDiffModifyData(DiffDataUtils.getDiffData(sourceData, targetData));
}
// 保存日志信息
log.setIsNewRecord(true);
Static.logService.insertLog(log);
}
}
}

View File

@@ -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 验证方式mobileemail
* @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 验证方式mobileemail
*/
@@ -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()));
}
/**

View File

@@ -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");
}
@@ -262,7 +264,11 @@ public class LoginController extends BaseController{
//UserUtils.removeCache(UserUtils.CACHE_AUTH_INFO+"_"+session.getId());
// 返回指定用户类型的首页视图
String view = UserUtils.getUserTypeValue(user.getUserType(), "indexView");
String userType = user.getUserType();
if (User.USER_TYPE_NONE.equals(userType)){
userType = User.USER_TYPE_EMPLOYEE;
}
String view = UserUtils.getUserTypeValue(userType, "indexView");
if(StringUtils.isNotBlank(view)){
return view;
}
@@ -272,16 +278,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 +297,7 @@ public class LoginController extends BaseController{
}
/**
* 获取当前用户菜单数据(移动端用)
* 当前用户菜单数据(移动端用)
*/
@RequiresPermissions("user")
@RequestMapping(value = "menuTree")
@@ -334,7 +340,7 @@ public class LoginController extends BaseController{
}
/**
* 切换主题
* 切换主题风格
*/
@RequiresPermissions("user")
@RequestMapping(value = "switchSkin/{skinName}")

View File

@@ -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"));
// }
}

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -20,9 +20,9 @@ jdbc:
# 初始化连接数
init: 1
# 最小连接数
# 最小活动连接数
minIdle: 3
# 最大连接数
# 最大激活连接数
maxActive: 20
# 获取连接等待超时时间单位毫秒1分钟4.0.6+
@@ -108,8 +108,11 @@ frontPath: /f
# 分页相关
page:
# 分页默认大小
# 默认每页显示的数据条数
pageSize: 20
# 每页最大条数,防止分页过大导致系统缓慢或内存溢出
maxPageSize: 999
# 用户相关
user:
@@ -131,6 +134,9 @@ user:
# 登录账号是否租户内唯一,否则全局唯一
loginCodeCorpUnique: false
# 是否启用验证码登录(手机、邮箱)
loginByValidCode: true
# 用户类型配置信息employee员工member会员btype往来单位persion个人expert专家...JSON 格式说明如下:
# {"用户类型":{"beanName":"Service或Dao的Bean名称","loginView":"登录页面视图","indexView":"主框架页面视图,支持 redirect: 前缀"}}
@@ -335,10 +341,11 @@ shiro:
# 登录提交信息加密(如果不需要加密,设置为空即可)
loginSubmit:
# 登录提交信息安全Key加密用户名、密码、验证码后再提交key设置为3个用逗号分隔加密方式DES
# v4.2.0+ 支持 Base64 加密方式,方便移动端及第三方系统处理认证,可直接设置 Key 为 Base64
# 加密用户名、密码、验证码后再提交key设置为3个用逗号分隔加密方式DES4.1.9及之前版本默认设置)
# v4.2.0+ 开始支持 Base64 加密方式,方便移动端及第三方系统处理认证,可直接设置 Key 为 Base644.2.0+默认设置)
#secretKey: thinkgem,jeesite,com
secretKey: Base64
#secretKey: ~
# 记住我密钥设置,你可以通过 com.jeesite.test.RememberMeKeyGen 类快速生成一个秘钥。
# 若不设置,则每次启动系统后自动生成一个新秘钥,这样会导致每次重启后,客户端记录的用户信息将失效。
@@ -367,7 +374,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 +403,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 +437,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
@@ -481,6 +492,9 @@ mybatis:
# TypeHandlers 扫描基础包,如果多个,用“,”分隔
scanTypeHandlersPackage: ~
# 是否开启 JDBC 管理事务,默认 Spring 管理事务 v4.2.3
jdbcTransaction: false
# Mapper文件刷新线程
mapper:
refresh:
@@ -503,10 +517,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 +639,10 @@ video:
# 将mp4视频的元数据信息转到视频第一帧
qtFaststartFile: d:/tools/video/qt-faststart/qt-faststart.exe
# 文件管理是否启用租户模式
filemanager:
useCorpModel: false
#======================================#
#========== Message settings ==========#
#======================================#

View File

@@ -15,6 +15,7 @@
<logger name="com.atomikos.jdbc.AbstractDataSourceBean" level="ERROR" />
<logger name="com.atomikos.jdbc.AtomikosConnectionProxy" level="ERROR" />
<logger name="com.atomikos.recovery.xa.XaResourceRecoveryManager" level="ERROR" />
<logger name="org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator" level="DEBUG" />
<!-- <logger name="org.springframework.transaction.support.TransactionSynchronizationManager" level="TRACE" /> -->
<logger name="springfox.documentation.spring.web.readers.parameter.ParameterDataTypeReader" level="ERROR" />

View File

@@ -292,6 +292,26 @@ CREATE TABLE ${_prefix}sys_file_upload
update_by varchar(64) NOT NULL,
update_date timestamp NOT NULL,
remarks vargraphic(500),
extend_s1 vargraphic(500),
extend_s2 vargraphic(500),
extend_s3 vargraphic(500),
extend_s4 vargraphic(500),
extend_s5 vargraphic(500),
extend_s6 vargraphic(500),
extend_s7 vargraphic(500),
extend_s8 vargraphic(500),
extend_i1 decimal(19),
extend_i2 decimal(19),
extend_i3 decimal(19),
extend_i4 decimal(19),
extend_f1 decimal(19,4),
extend_f2 decimal(19,4),
extend_f3 decimal(19,4),
extend_f4 decimal(19,4),
extend_d1 timestamp,
extend_d2 timestamp,
extend_d3 timestamp,
extend_d4 timestamp,
PRIMARY KEY (id)
);

View File

@@ -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,

View File

@@ -292,6 +292,26 @@ CREATE TABLE ${_prefix}sys_file_upload
update_by varchar(64) NOT NULL,
update_date datetime NOT NULL,
remarks varchar(500),
extend_s1 varchar(500),
extend_s2 varchar(500),
extend_s3 varchar(500),
extend_s4 varchar(500),
extend_s5 varchar(500),
extend_s6 varchar(500),
extend_s7 varchar(500),
extend_s8 varchar(500),
extend_i1 decimal(19),
extend_i2 decimal(19),
extend_i3 decimal(19),
extend_i4 decimal(19),
extend_f1 decimal(19,4),
extend_f2 decimal(19,4),
extend_f3 decimal(19,4),
extend_f4 decimal(19,4),
extend_d1 datetime,
extend_d2 datetime,
extend_d3 datetime,
extend_d4 datetime,
PRIMARY KEY (id)
);

View File

@@ -292,6 +292,26 @@ CREATE TABLE [${_prefix}sys_file_upload]
[update_by] varchar(64) NOT NULL,
[update_date] datetime NOT NULL,
[remarks] nvarchar(500),
[extend_s1] nvarchar(500),
[extend_s2] nvarchar(500),
[extend_s3] nvarchar(500),
[extend_s4] nvarchar(500),
[extend_s5] nvarchar(500),
[extend_s6] nvarchar(500),
[extend_s7] nvarchar(500),
[extend_s8] nvarchar(500),
[extend_i1] decimal(19),
[extend_i2] decimal(19),
[extend_i3] decimal(19),
[extend_i4] decimal(19),
[extend_f1] decimal(19,4),
[extend_f2] decimal(19,4),
[extend_f3] decimal(19,4),
[extend_f4] decimal(19,4),
[extend_d1] datetime,
[extend_d2] datetime,
[extend_d3] datetime,
[extend_d4] datetime,
PRIMARY KEY ([id])
);

View File

@@ -293,6 +293,26 @@ CREATE TABLE ${_prefix}sys_file_upload
update_by varchar(64) NOT NULL COMMENT '更新者',
update_date datetime NOT NULL COMMENT '更新时间',
remarks varchar(500) COMMENT '备注信息',
extend_s1 varchar(500) COMMENT '扩展 String 1',
extend_s2 varchar(500) COMMENT '扩展 String 2',
extend_s3 varchar(500) COMMENT '扩展 String 3',
extend_s4 varchar(500) COMMENT '扩展 String 4',
extend_s5 varchar(500) COMMENT '扩展 String 5',
extend_s6 varchar(500) COMMENT '扩展 String 6',
extend_s7 varchar(500) COMMENT '扩展 String 7',
extend_s8 varchar(500) COMMENT '扩展 String 8',
extend_i1 decimal(19) COMMENT '扩展 Integer 1',
extend_i2 decimal(19) COMMENT '扩展 Integer 2',
extend_i3 decimal(19) COMMENT '扩展 Integer 3',
extend_i4 decimal(19) COMMENT '扩展 Integer 4',
extend_f1 decimal(19,4) COMMENT '扩展 Float 1',
extend_f2 decimal(19,4) COMMENT '扩展 Float 2',
extend_f3 decimal(19,4) COMMENT '扩展 Float 3',
extend_f4 decimal(19,4) COMMENT '扩展 Float 4',
extend_d1 datetime COMMENT '扩展 Date 1',
extend_d2 datetime COMMENT '扩展 Date 2',
extend_d3 datetime COMMENT '扩展 Date 3',
extend_d4 datetime COMMENT '扩展 Date 4',
PRIMARY KEY (id)
) COMMENT = '文件上传表';

View File

@@ -292,6 +292,26 @@ CREATE TABLE ${_prefix}sys_file_upload
update_by varchar2(64) NOT NULL,
update_date timestamp NOT NULL,
remarks nvarchar2(500),
extend_s1 nvarchar2(500),
extend_s2 nvarchar2(500),
extend_s3 nvarchar2(500),
extend_s4 nvarchar2(500),
extend_s5 nvarchar2(500),
extend_s6 nvarchar2(500),
extend_s7 nvarchar2(500),
extend_s8 nvarchar2(500),
extend_i1 number(19),
extend_i2 number(19),
extend_i3 number(19),
extend_i4 number(19),
extend_f1 number(19,4),
extend_f2 number(19,4),
extend_f3 number(19,4),
extend_f4 number(19,4),
extend_d1 timestamp,
extend_d2 timestamp,
extend_d3 timestamp,
extend_d4 timestamp,
PRIMARY KEY (id)
);
@@ -1136,6 +1156,26 @@ COMMENT ON COLUMN ${_prefix}sys_file_upload.create_date IS '创建时间';
COMMENT ON COLUMN ${_prefix}sys_file_upload.update_by IS '更新者';
COMMENT ON COLUMN ${_prefix}sys_file_upload.update_date IS '更新时间';
COMMENT ON COLUMN ${_prefix}sys_file_upload.remarks IS '备注信息';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_s1 IS '扩展 String 1';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_s2 IS '扩展 String 2';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_s3 IS '扩展 String 3';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_s4 IS '扩展 String 4';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_s5 IS '扩展 String 5';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_s6 IS '扩展 String 6';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_s7 IS '扩展 String 7';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_s8 IS '扩展 String 8';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_i1 IS '扩展 Integer 1';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_i2 IS '扩展 Integer 2';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_i3 IS '扩展 Integer 3';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_i4 IS '扩展 Integer 4';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_f1 IS '扩展 Float 1';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_f2 IS '扩展 Float 2';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_f3 IS '扩展 Float 3';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_f4 IS '扩展 Float 4';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_d1 IS '扩展 Date 1';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_d2 IS '扩展 Date 2';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_d3 IS '扩展 Date 3';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_d4 IS '扩展 Date 4';
COMMENT ON TABLE ${_prefix}sys_job IS '作业调度表';
COMMENT ON COLUMN ${_prefix}sys_job.job_name IS '任务名称';
COMMENT ON COLUMN ${_prefix}sys_job.job_group IS '任务组名';

View File

@@ -292,6 +292,26 @@ CREATE TABLE ${_prefix}sys_file_upload
update_by varchar(64) NOT NULL,
update_date timestamp NOT NULL,
remarks varchar(500),
extend_s1 varchar(500),
extend_s2 varchar(500),
extend_s3 varchar(500),
extend_s4 varchar(500),
extend_s5 varchar(500),
extend_s6 varchar(500),
extend_s7 varchar(500),
extend_s8 varchar(500),
extend_i1 decimal(19),
extend_i2 decimal(19),
extend_i3 decimal(19),
extend_i4 decimal(19),
extend_f1 decimal(19,4),
extend_f2 decimal(19,4),
extend_f3 decimal(19,4),
extend_f4 decimal(19,4),
extend_d1 timestamp,
extend_d2 timestamp,
extend_d3 timestamp,
extend_d4 timestamp,
PRIMARY KEY (id)
) WITHOUT OIDS;
@@ -1136,6 +1156,26 @@ COMMENT ON COLUMN ${_prefix}sys_file_upload.create_date IS '创建时间';
COMMENT ON COLUMN ${_prefix}sys_file_upload.update_by IS '更新者';
COMMENT ON COLUMN ${_prefix}sys_file_upload.update_date IS '更新时间';
COMMENT ON COLUMN ${_prefix}sys_file_upload.remarks IS '备注信息';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_s1 IS '扩展 String 1';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_s2 IS '扩展 String 2';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_s3 IS '扩展 String 3';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_s4 IS '扩展 String 4';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_s5 IS '扩展 String 5';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_s6 IS '扩展 String 6';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_s7 IS '扩展 String 7';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_s8 IS '扩展 String 8';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_i1 IS '扩展 Integer 1';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_i2 IS '扩展 Integer 2';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_i3 IS '扩展 Integer 3';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_i4 IS '扩展 Integer 4';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_f1 IS '扩展 Float 1';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_f2 IS '扩展 Float 2';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_f3 IS '扩展 Float 3';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_f4 IS '扩展 Float 4';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_d1 IS '扩展 Date 1';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_d2 IS '扩展 Date 2';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_d3 IS '扩展 Date 3';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_d4 IS '扩展 Date 4';
COMMENT ON TABLE ${_prefix}sys_job IS '作业调度表';
COMMENT ON COLUMN ${_prefix}sys_job.job_name IS '任务名称';
COMMENT ON COLUMN ${_prefix}sys_job.job_group IS '任务组名';

View File

@@ -0,0 +1,23 @@
-- 文件上传表增加 20 个扩展字段
ALTER TABLE ${_prefix}sys_file_upload
ADD extend_s1 nvarchar(500),
extend_s2 nvarchar(500),
extend_s3 nvarchar(500),
extend_s4 nvarchar(500),
extend_s5 nvarchar(500),
extend_s6 nvarchar(500),
extend_s7 nvarchar(500),
extend_s8 nvarchar(500),
extend_i1 decimal(19),
extend_i2 decimal(19),
extend_i3 decimal(19),
extend_i4 decimal(19),
extend_f1 decimal(19,4),
extend_f2 decimal(19,4),
extend_f3 decimal(19,4),
extend_f4 decimal(19,4),
extend_d1 datetime,
extend_d2 datetime,
extend_d3 datetime,
extend_d4 datetime;

View File

@@ -0,0 +1,23 @@
-- 文件上传表增加 20 个扩展字段
ALTER TABLE `${_prefix}sys_file_upload`
ADD COLUMN extend_s1 varchar(500) COMMENT '扩展 String 1',
ADD COLUMN extend_s2 varchar(500) COMMENT '扩展 String 2',
ADD COLUMN extend_s3 varchar(500) COMMENT '扩展 String 3',
ADD COLUMN extend_s4 varchar(500) COMMENT '扩展 String 4',
ADD COLUMN extend_s5 varchar(500) COMMENT '扩展 String 5',
ADD COLUMN extend_s6 varchar(500) COMMENT '扩展 String 6',
ADD COLUMN extend_s7 varchar(500) COMMENT '扩展 String 7',
ADD COLUMN extend_s8 varchar(500) COMMENT '扩展 String 8',
ADD COLUMN extend_i1 decimal(19) COMMENT '扩展 Integer 1',
ADD COLUMN extend_i2 decimal(19) COMMENT '扩展 Integer 2',
ADD COLUMN extend_i3 decimal(19) COMMENT '扩展 Integer 3',
ADD COLUMN extend_i4 decimal(19) COMMENT '扩展 Integer 4',
ADD COLUMN extend_f1 decimal(19,4) COMMENT '扩展 Float 1',
ADD COLUMN extend_f2 decimal(19,4) COMMENT '扩展 Float 2',
ADD COLUMN extend_f3 decimal(19,4) COMMENT '扩展 Float 3',
ADD COLUMN extend_f4 decimal(19,4) COMMENT '扩展 Float 4',
ADD COLUMN extend_d1 datetime COMMENT '扩展 Date 1',
ADD COLUMN extend_d2 datetime COMMENT '扩展 Date 2',
ADD COLUMN extend_d3 datetime COMMENT '扩展 Date 3',
ADD COLUMN extend_d4 datetime COMMENT '扩展 Date 4';

View File

@@ -0,0 +1,43 @@
-- 文件上传表增加 20 个扩展字段
ALTER TABLE ${_prefix}sys_file_upload
ADD (extend_s1 nvarchar2(500),
extend_s2 nvarchar2(500),
extend_s3 nvarchar2(500),
extend_s4 nvarchar2(500),
extend_s5 nvarchar2(500),
extend_s6 nvarchar2(500),
extend_s7 nvarchar2(500),
extend_s8 nvarchar2(500),
extend_i1 number(19),
extend_i2 number(19),
extend_i3 number(19),
extend_i4 number(19),
extend_f1 number(19,4),
extend_f2 number(19,4),
extend_f3 number(19,4),
extend_f4 number(19,4),
extend_d1 timestamp,
extend_d2 timestamp,
extend_d3 timestamp,
extend_d4 timestamp);
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_s1 IS '扩展 String 1';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_s2 IS '扩展 String 2';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_s3 IS '扩展 String 3';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_s4 IS '扩展 String 4';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_s5 IS '扩展 String 5';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_s6 IS '扩展 String 6';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_s7 IS '扩展 String 7';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_s8 IS '扩展 String 8';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_i1 IS '扩展 Integer 1';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_i2 IS '扩展 Integer 2';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_i3 IS '扩展 Integer 3';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_i4 IS '扩展 Integer 4';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_f1 IS '扩展 Float 1';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_f2 IS '扩展 Float 2';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_f3 IS '扩展 Float 3';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_f4 IS '扩展 Float 4';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_d1 IS '扩展 Date 1';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_d2 IS '扩展 Date 2';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_d3 IS '扩展 Date 3';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_d4 IS '扩展 Date 4';

View File

@@ -0,0 +1,43 @@
-- 文件上传表增加 20 个扩展字段
ALTER TABLE ${_prefix}sys_file_upload
ADD COLUMN extend_s1 varchar(500),
ADD COLUMN extend_s2 varchar(500),
ADD COLUMN extend_s3 varchar(500),
ADD COLUMN extend_s4 varchar(500),
ADD COLUMN extend_s5 varchar(500),
ADD COLUMN extend_s6 varchar(500),
ADD COLUMN extend_s7 varchar(500),
ADD COLUMN extend_s8 varchar(500),
ADD COLUMN extend_i1 decimal(19),
ADD COLUMN extend_i2 decimal(19),
ADD COLUMN extend_i3 decimal(19),
ADD COLUMN extend_i4 decimal(19),
ADD COLUMN extend_f1 decimal(19,4),
ADD COLUMN extend_f2 decimal(19,4),
ADD COLUMN extend_f3 decimal(19,4),
ADD COLUMN extend_f4 decimal(19,4),
ADD COLUMN extend_d1 timestamp,
ADD COLUMN extend_d2 timestamp,
ADD COLUMN extend_d3 timestamp,
ADD COLUMN extend_d4 timestamp;
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_s1 IS '扩展 String 1';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_s2 IS '扩展 String 2';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_s3 IS '扩展 String 3';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_s4 IS '扩展 String 4';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_s5 IS '扩展 String 5';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_s6 IS '扩展 String 6';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_s7 IS '扩展 String 7';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_s8 IS '扩展 String 8';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_i1 IS '扩展 Integer 1';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_i2 IS '扩展 Integer 2';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_i3 IS '扩展 Integer 3';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_i4 IS '扩展 Integer 4';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_f1 IS '扩展 Float 1';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_f2 IS '扩展 Float 2';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_f3 IS '扩展 Float 3';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_f4 IS '扩展 Float 4';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_d1 IS '扩展 Date 1';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_d2 IS '扩展 Date 2';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_d3 IS '扩展 Date 3';
COMMENT ON COLUMN ${_prefix}sys_file_upload.extend_d4 IS '扩展 Date 4';

View File

@@ -16,4 +16,7 @@
4.1.7
4.1.8
4.1.9
4.2.0
4.2.0
4.2.1
4.2.2
4.2.3

View File

@@ -20,6 +20,7 @@
操作=Actions
更多=More
更多操作=More action
设置=Setting
基本信息=Basic information
详细信息=Detail information

View File

@@ -20,6 +20,7 @@
操作=操作
更多=さらに多
更多操作=他の操作
设置=設置
基本信息=基本情報
详细信息=詳細情報

View File

@@ -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.
@@ -376,6 +385,29 @@
租户切换失败,没有这个租户!=Tenant switch failed, no tenant!
租户切换失败,只有超级管理员才可以操作!=Tenant switch failed, only super administrator can operate!
# =========== 安全审计 ===========
安全审计=Security Audit
账号密码审计=Account password audit
菜单权限审计=Menu permission audit
用户权限审计=User privileges audit
全部问题=All Problems
未修改初始密码=The initial password was not changed
密码等级是弱或者很弱的=The password level is weak or very weak
使用简单密码=Use simple password
定期未修改密码=Periodically unchanged password
定期未修改密码的账号\ {0}\ 天内不被审查=Periodic accounts with unchanged passwords {0} will not be reviewed within days
长期未登录=Long time not logged in
长期未登录的账号\ {0}\ 天内不被审查=Long time unlogged account \ {0}\ not censored within days
未设置密保=No is set secret guard
审计结果=Audit Result
修改密码时间=Change password time
最后登录时间=Last login time
请设置\ sys.user.passwordModifyCycle\ 参数,指定密码修改周期天数=Please set 'sys.user.passwordModifyCycle' parameter, specify the number of days password change cycle
# =========== 菜单管理 ===========
新增菜单=New menu

View File

@@ -70,6 +70,10 @@
登录=ログイン
欢迎回来=おかえり
账号登录=ログイン
手机登录=電話登録
没有账号=アカウントなし
点击注册=きにゅう
请填写登录账号.=ログインIDを入力してください.
登录账号=ログインアカウント
@@ -78,6 +82,11 @@
请填写登录密码.=パスワードを入力してください.
登录密码=パスワード
登录租户=テナント登録
请填写手机验证码.=携帯電話の検証コード
手机验证码=電話の検証コード
获取手机验证码=コードを取得
公共场所慎用,下次不需要再填写帐号=次回からログインIDの入力が不要にします.
记住账号=ログインID記憶
公共场所慎用,下次不需要再填写帐号和密码=次回からパスワードの入力が不要にします.
@@ -90,6 +99,9 @@
注册账号=アカウント作成
忘记密码=パスワードを忘れた
注册账号=アカウントを登録する
忘记密码=パスワードを忘れる
# =========== 主框架页 ===========
仪表盘=計器盤
@@ -377,6 +389,29 @@
租户切换失败,没有这个租户!=テナント换の失敗が、このテナント!
租户切换失败,只有超级管理员才可以操作!=テナント换に失敗し、スーパーの管理のみを操作できる!
# =========== 安全审计 ===========
安全审计=安全監査
账号密码审计=パスワード監査
菜单权限审计=メニュー権限監査
用户权限审计=ユーザ権限監査
全部问题=すべての問題
未修改初始密码=初期パスワードは未修正
密码等级是弱或者很弱的=暗号レベルは弱いか弱い
使用简单密码=簡単なパスワードを使う
定期未修改密码=定期的にパスワードを修正しない
定期未修改密码的账号\ {0}\ 天内不被审查=定期的にパスワードを変更しないアカウント {0} は日中審査されません
长期未登录=長期未登録
长期未登录的账号\ {0}\ 天内不被审查=長期未ログインのアカウント {0} は日中審査されません
未设置密保=未設置密保
审计结果=監査結果
修改密码时间=パスワードを修正する時間
最后登录时间=最終登録時間
请设置\ sys.user.passwordModifyCycle\ 参数,指定密码修改周期天数=設置 sys.user.passwordModifyCycle パラメータ、パスワードを指定改正周期日数
# =========== 菜单管理 ===========
新增菜单=メニューの追加

View File

@@ -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()}

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1611372977925" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1701" width="27" height="22" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style type="text/css"></style></defs><path d="M797.909333 219.818667h-91.306666v-21.333334a27.392 27.392 0 0 0-54.784 0v21.333334H371.754667v-21.333334a27.392 27.392 0 1 0-54.784 0v21.333334H225.621333c-30.293333 0-54.784 24.490667-54.784 54.784v523.605333c0 30.293333 24.490667 54.784 54.826667 54.784H797.866667c30.293333 0 54.826667-24.618667 54.826666-54.784V274.602667c0-30.293333-24.490667-54.784-54.826666-54.784zM317.013333 270.805333v19.029334a27.392 27.392 0 0 0 54.784 0v-19.029334h280.064v19.029334a27.392 27.392 0 0 0 54.784 0v-19.029334h95.146667v95.146667H221.866667v-95.146667h95.104z m487.04 533.205334H219.989333V414.592h584.021334v389.418667zM341.333333 512.042667h48.64a24.362667 24.362667 0 0 1 0 48.725333H341.333333a24.32 24.32 0 1 1 0-48.682667V512z m146.090667 0h48.682667a24.362667 24.362667 0 0 1 0 48.725333h-48.64a24.32 24.32 0 0 1 0-48.682667L487.424 512z m146.090667 0h48.768a24.362667 24.362667 0 0 1 0 48.725333h-48.768a24.32 24.32 0 1 1 0-48.682667V512zM341.333333 659.626667h48.768a24.362667 24.362667 0 0 1 0 48.682666H341.333333a24.32 24.32 0 0 1 0-48.682666z m146.176 0h48.682667a24.362667 24.362667 0 0 1 0 48.682666h-48.725333a24.32 24.32 0 0 1 0-48.682666z" fill="#999999" p-id="1702"></path></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

Some files were not shown because too many files have changed in this diff Show More