Compare commits

...

123 Commits

Author SHA1 Message Date
thinkgem
8629d2a055 update comment 2018-12-28 22:27:49 +08:00
thinkgem
ab2cfb1130 update 2018-12-25 21:59:46 +08:00
thinkgem
a15eaf244a Merge branch 'v4.1_dev' 2018-12-22 21:23:08 +08:00
thinkgem
10c55689a9 Merge branch 'master' of https://gitee.com/thinkgem/jeesite4 2018-12-22 20:50:50 +08:00
thinkgem
67c6f9e772 v4.1.2 2018-12-22 19:19:18 +08:00
thinkgem
314cef3201 菜单归属系统代码优化及各种细节优化 2018-12-22 19:16:47 +08:00
thinkgem
e663ae3207 update 2018-12-22 19:07:19 +08:00
ThinkGem
564e470103 update 2018-12-22 15:46:53 +08:00
ThinkGem
92f665d00e !5 彩色日志
Merge pull request !5 from 清曦宛若扇/master
2018-12-22 15:42:43 +08:00
gaoxiyang
3a78e56815 彩色日志 2018-12-18 09:52:57 +08:00
thinkgem
2d7f66b1e0 修复苹果手机IOS下不能左右滚动问题,另外需按如下步骤操作手机:设置 -> Safari浏览器 -> 高级 -> Experimental
Features -> 关闭 Async Frame Scrolling 选项。
2018-12-17 22:48:52 +08:00
thinkgem
1724e3ead1 代码优化,减少一些js警告的提示。建议设置IDE忽略一些无关紧要的警告提示。 2018-12-16 16:54:09 +08:00
thinkgem
c7a9ccf615 代码生成模板分离出dataGrid生成代码;日期控件选填显示清空按钮;仅查询生成模板优化; 2018-12-16 13:53:05 +08:00
thinkgem
c21949d733 租户管理员支持绑定角色,让不同的租户可拥有不同的菜单。 2018-12-15 23:33:11 +08:00
thinkgem
2de5300ae5 update 2018-12-15 19:54:19 +08:00
thinkgem
466b323114 update 2018-12-13 22:31:02 +08:00
thinkgem
19752502f1 主题切换中新增“表单弹窗模式”、“取消页签模式”选项开关 2018-12-12 21:21:20 +08:00
thinkgem
2d02047e81 新增 shiro.isAllowMultiDeviceLogin
参数,是否允许多账号多设备登录,如果设置为false,其它地点登录的相同账号全部登录设备将被踢下线
2018-12-09 22:32:03 +08:00
thinkgem
a36244316c rename MainTest.java to Test.java 2018-12-02 15:43:14 +08:00
thinkgem
c0ae3ad32f 删除一些无用的代码 2018-11-30 22:08:10 +08:00
thinkgem
ac04d84c53 优化树表代码生成,展开节点清理请求参数数据时排除状态查询条件;查询树表优化,编辑后支持刷新列表中无父节点数据; 2018-11-30 21:50:20 +08:00
thinkgem
aef4837827 新增连接池最大空闲的时间,默认30分钟。 2018-11-30 20:49:45 +08:00
thinkgem
af17a4664c 新增WebOffice在线文件预览的支持。 2018-11-27 22:38:52 +08:00
thinkgem
19da4dc3b5 FileUtils.getContentType的准确性优化,有时候会对下载视频播放造成影响; 2018-11-27 22:14:22 +08:00
thinkgem
32ba7bb0a4 xss过滤去除&和#的转换,有时候会产生一点问题 2018-11-27 22:07:54 +08:00
thinkgem
b0f01baeb4 优化repos地址 2018-11-25 15:55:57 +08:00
thinkgem
0b63e8ad6b 新增仅查询功能(不含增删改)的代码生成模板 #IOZ3S 2018-11-24 21:41:03 +08:00
thinkgem
125018df1d start 4.1.2 2018-11-24 21:06:03 +08:00
thinkgem
e6fe7b5420 测试代码优化 2018-11-20 21:25:33 +08:00
thinkgem
da5c212536 update 2018-11-18 20:36:47 +08:00
thinkgem
43005b16b1 v4.1.1 2018-11-17 23:55:18 +08:00
thinkgem
68ffd4e8f3 v4.1.1 2018-11-17 23:32:55 +08:00
thinkgem
b22fc6d45e v4.1.1 2018-11-17 22:52:36 +08:00
thinkgem
01a7acffc3 v4.1.1 2018-11-17 22:09:39 +08:00
thinkgem
95a6b6c8c7 UI美化色调微调,表单控件小圆角增强平滑感 2018-11-17 21:57:06 +08:00
thinkgem
92f8cc8a92 ServiceSupport的类移动到support子包下。 2018-11-17 21:45:13 +08:00
thinkgem
89749e064e 将公司、部门、员工、用户、岗位、日志分离出接口方便用户扩展 2018-11-17 21:45:01 +08:00
thinkgem
711985fbe9 新增内部系统访问过滤器,可设置多个允许的内部系统IP地址串,多个用逗号隔开 2018-11-17 21:42:52 +08:00
thinkgem
95dbae82a8 add gitee issues template 2018-11-17 21:15:03 +08:00
thinkgem
65fae6152c update readme.md 2018-11-17 21:14:38 +08:00
thinkgem
2288c62c3a TimeUtils.formatDateAgo 精简优化 2018-11-10 23:35:25 +08:00
thinkgem
55d7526c73 新增 StringUtils.trim2 方法,去除左右空格,支持清理中文空格 2018-11-09 22:24:27 +08:00
thinkgem
7b3bba8b99 update .gitignore 2018-11-09 20:19:50 +08:00
thinkgem
8961624fd6 减少行政区划初始化数据,提升安装速度。 2018-11-09 20:19:27 +08:00
thinkgem
01f0dedbe8 update readme.md 2018-11-08 23:42:30 +08:00
thinkgem
48b08c81a1 手机号验证增加199号码段;修正部分功能xss漏洞; 2018-11-08 23:42:18 +08:00
thinkgem
a2f6c7cb0b 新增文件服务层的重写扩展支持 2018-10-31 21:14:10 +08:00
thinkgem
e41884ae17 新增代码生成gen.enabled开关;新增系统监控state.enabled开关;区域表单优化; 2018-10-30 22:41:38 +08:00
thinkgem
6dfe980f46 优化启动脚本。 2018-10-30 22:39:23 +08:00
thinkgem
b79c1ba182 UI美化色调微调,表单控件小圆角增强平滑感 2018-10-29 21:12:57 +08:00
thinkgem
3fbaa3e14f 记住我情况下解决偶尔出现不显示登录页面的问题。 2018-10-27 19:13:45 +08:00
thinkgem
f33a7db4ba 优化代码方便分布式配置中心获取数据 2018-10-25 22:53:13 +08:00
thinkgem
3d5f48bc43 MsgPushUtils增加一个方法,填写定时发送消息时不需要填写是否合并消息参数了 2018-10-22 22:12:05 +08:00
thinkgem
7f4e0625aa Merge branch 'master' of https://gitee.com/thinkgem/jeesite4 2018-10-21 15:26:41 +08:00
ThinkGem
e060ee8ac7 update readme.md 2018-10-21 14:26:09 +08:00
thinkgem
45bae9ef17 update readme.md 2018-10-21 14:14:26 +08:00
thinkgem
f110cde882 upgrade spring boot 2.0.5 to 2.0.6 2018-10-19 23:59:31 +08:00
thinkgem
cc3921c7bb start v4.1.1 2018-10-18 22:59:44 +08:00
thinkgem
64253cf91c update 2018-10-17 21:36:07 +08:00
thinkgem
200690a7c6 delete root .settings 2018-10-16 22:18:01 +08:00
thinkgem
1c07c0db80 update .settings 2018-10-16 22:13:54 +08:00
thinkgem
f77f925ba4 update .settings 2018-10-16 22:10:47 +08:00
thinkgem
c80c5ec769 common 新增 PropertyLoader 在 Boot 环境初始化属性用 2018-10-16 22:09:07 +08:00
thinkgem
7cbc0ba7b7 /sys/empUser/treeData 删掉 mgr_type 条件 2018-10-16 22:05:43 +08:00
thinkgem
ec29a3941f core resource rename resources 2018-10-16 22:04:51 +08:00
thinkgem
2b6c4c1adb 去掉devtools模块,合并到core模块。 2018-10-15 23:12:57 +08:00
thinkgem
4cf671dc7f update bin script 2018-10-14 21:33:04 +08:00
thinkgem
a872b9e02e v4.1.0 2018-10-14 19:55:19 +08:00
thinkgem
4ef6d1a981 修正二级缓存存储模式为hash的时候clear报错问题 2018-10-14 18:06:57 +08:00
thinkgem
6959238eec 支持菜单、用户、角色 Service 层自定义,详见 sys.service.impl 包。 2018-10-14 12:50:22 +08:00
thinkgem
a94de0c372 支持菜单、用户、角色 Service 层自定义,详见 sys.service.impl 包。 2018-10-14 12:50:22 +08:00
thinkgem
1d250a126a 其它各种优化,性能优化,增强autoconfigure,简化 Application.java;新增PwdUtils工具类 2018-10-13 22:30:02 +08:00
thinkgem
57f67c0a0e 日志配置优化,并重命名移动到 src/main/resources/config/logback-spring.xml 2018-10-13 21:44:35 +08:00
thinkgem
7dc85de589 演示组件中新增用户列表选择应用例子 2018-10-11 21:31:45 +08:00
thinkgem
ebf7b52656 角色数据权限范围,支持扩展自定义的数据权限,并相关权限功能优化改进;新增本部门数据、本公司数据、本部门和本公司数据的权限范围 2018-10-10 20:09:23 +08:00
thinkgem
021672b180 优化用户菜单缓存,提示主页面加载速度 2018-10-02 23:17:26 +08:00
thinkgem
0c84378419 代码优化 2018-09-29 22:08:40 +08:00
thinkgem
968e5fe357 新增超级管理员租户切换功能 2018-09-28 22:25:38 +08:00
thinkgem
bc66796ca7 修正岗位名称唯一验证不应该是LIKE 2018-09-28 22:17:31 +08:00
thinkgem
c16e81b410 修正树表名称有正则表达式特殊字符的时候更新报错 #IN6V8 2018-09-28 22:05:54 +08:00
thinkgem
8a64867ed3 form:treeselect增加callbackFuncName属性,可自定义回调方法的函数名 2018-09-28 22:02:25 +08:00
thinkgem
43a6f86115 代码生成器支持多数据源表生成 2018-09-26 22:37:22 +08:00
thinkgem
38f8c6cda3 新增 jeesite-module-swagger 模块 2018-09-26 22:36:25 +08:00
thinkgem
41db27ae0d 代码生成器支持栅格自定义 2018-09-26 20:19:43 +08:00
thinkgem
90ec91cc69 demo视图文件增加demo前缀 2018-09-26 20:19:10 +08:00
thinkgem
1ce27089e2 支持开发者自定义控制用户密码加密和验证策略。 2018-09-25 22:43:37 +08:00
thinkgem
8ebb5b07f6 form:checkbox组件,不选中时提交空字符串,而不是提交null 2018-09-25 22:42:16 +08:00
thinkgem
2717f036ec update 2018-09-24 18:12:10 +08:00
thinkgem
34125ee274 泛型化对象序列化和反序列化接口 2018-09-24 11:46:07 +08:00
thinkgem
7d6e99c8fb 缓存工具类新增timeToLiveInSeconds支持;优化分页接口 2018-09-23 23:40:56 +08:00
thinkgem
d9e18a70c7 升级到 Spring Boot 2.0.5 以及相关依赖库全面升级,采用J2Cache作为缓存。 2018-09-22 21:12:45 +08:00
thinkgem
c9ecd3cfc8 update README.md 2018-09-15 23:39:57 +08:00
thinkgem
fe030b75c6 删除失信企业湖南乐活科技lehuo520.cn乐云短信代码 2018-09-15 20:49:55 +08:00
thinkgem
8563888fd5 v4.0.7 2018-09-15 17:46:18 +08:00
thinkgem
39a5f6164d 添加 ueditor后台源码,方便扩展上传文件存储。 2018-09-09 22:17:49 +08:00
33112
8b3a20b68b * 官方论坛:<http://jeesite.net> 2018-09-07 15:44:30 +08:00
33112
f6f824054a 取消测试声明 2018-09-07 11:56:12 +08:00
33112
9e163b1034 测试演示课程 2018-09-07 11:52:08 +08:00
thinkgem
1f92830aec update readme.md 2018-09-04 22:21:16 +08:00
ThinkGem
85c50bbd40 更新 README.md 2018-09-04 20:56:43 +08:00
thinkgem
6c7decc4a3 修正多个endBracket的情况下不输出问题,#IMJU8 2018-09-03 22:57:04 +08:00
thinkgem
bfabf1a85e 增加文件上传组件开关file.enabled;增加文件上传扩展服务类FileUploadServiceExtend接口,支持将文件保存到第三方文件服务器(如飞牛、OSS等) 2018-09-02 19:07:50 +08:00
thinkgem
5706c8bfc9 NumberUtils新增formatNumber方法 2018-08-29 23:34:28 +08:00
thinkgem
27434ee26e 分页器优化,Service基类新增重载findPage(T entity) 2018-08-28 23:08:58 +08:00
thinkgem
7bcf1095ff 消息推送单元测试完善;消息推送的PC消息按钮修正;模板消息优化修正; 2018-08-28 22:12:09 +08:00
thinkgem
01abf24665 job.scheduler.instanceName 2018-08-27 22:02:19 +08:00
thinkgem
8f4724fab2 i18n语言设置开关优化 2018-08-27 22:01:26 +08:00
thinkgem
b908885634 job数据源优化,druid升级到1.1.10版本 2018-08-26 23:10:55 +08:00
thinkgem
91d0e233f9 ListUtils.listOrderBy支持默认升序排序 2018-08-25 19:12:24 +08:00
thinkgem
cfdc99f190 客户端接口API信息输出优化 2018-08-25 19:11:42 +08:00
thinkgem
c553d966d6 新增调度日志开关,可关闭或只保存错误级别的日志,详见:jeesite.yml 2018-08-25 16:55:14 +08:00
thinkgem
0267908ece 增加Spring环境切换提示,不可设置为test,因为它是单元测试环境专属的名称。 2018-08-25 16:53:20 +08:00
thinkgem
7fdcecb912 支持@JsonView注解,自定义过滤Json视图输出字段。这在移动端API节省流量,隐私信息,或特殊场景下非常有用。 2018-08-23 22:11:55 +08:00
thinkgem
e1b6cdc831 修正PC消息提醒获取按钮报错问题。 2018-08-23 22:04:12 +08:00
thinkgem
596b1245d9 访问日志去掉日期范围查询条件 2018-08-21 21:33:00 +08:00
thinkgem
145e0b6b07 微不足道的修改 2018-08-21 21:32:06 +08:00
thinkgem
437220e34a update version. 2018-08-19 20:25:27 +08:00
thinkgem
28e1cd6f1d 记住我的账号,使用在线列表踢出用户无效问题修正。 2018-08-19 17:32:58 +08:00
thinkgem
09286c8287 新增记住我密钥自定义设置选项shiro.rememberMe.secretKey 2018-08-19 17:31:13 +08:00
thinkgem
b195480441 增加微服务优化选项,可关闭一些不需要的功能开关,包括如下:1、可关闭根据模块状态去更新相连的菜单状态(menu.updateStatusByModuleStatus=false);
2、可关闭国际化管理(lang.enabled=false);3、可关闭任务调度功能(job.enabled=false);4、可关闭核心模块的Web功能(web.core.enabled=false);减少加载启动时间,控制在10秒内;
2018-08-19 11:05:29 +08:00
ThinkGem
ec73aa0ab0 更新 jeesite.yml 2018-08-18 20:15:58 +08:00
thinkgem
55bc4dd3ad Md5Utils增加获取文件MD5值,支持获取文件指定前部分的MD5。 2018-08-17 23:11:17 +08:00
thinkgem
7a82d8a31c 添加mybatis.scanTypeHandlersPackage参数,TypeHandlers的扫描基础包。 2018-08-17 20:36:17 +08:00
228 changed files with 8419 additions and 9646 deletions

View File

@@ -0,0 +1,13 @@
### 该问题是怎么引起的?
### 重现步骤
### 报错信息

7
.gitignore vendored
View File

@@ -3,6 +3,8 @@
**/webapp/userfiles
**/WEB-INF/classes
**/logs/*.log*
*.epoch
*.lic
.classpath
.project
@@ -11,9 +13,6 @@
*.ipr
*.iml
*.iws
*.lic
.DS_Store
Thumbs.db
*.epoch
Thumbs.db

View File

@@ -1,2 +0,0 @@
eclipse.preferences.version=1
encoding/<project>=UTF-8

View File

@@ -1,4 +0,0 @@
activeProfiles=
eclipse.preferences.version=1
resolveWorkspaceProjects=true
version=1

View File

@@ -1,45 +1,37 @@
# 引言
## 引言
JeeSite 是一个 Java EE 企业级快速开发平台基于经典技术组合Spring Boot、Spring MVC、Apache Shiro、MyBatis、Beetl、Bootstrap、AdminLTE在线代码生成功能包括核心模块如组织机构、角色用户、菜单及按钮授权、数据权限、系统参数、内容管理、工作流等。采用松耦合设计界面无刷新一键换肤众多账号安全设置密码策略在线定时任务配置支持集群支持SAAS支持多数据源。
JeeSite 是一个 Java EE 企业级快速开发平台基于经典技术组合Spring Boot、Spring MVC、Apache Shiro、MyBatis、Beetl、Bootstrap、AdminLTE采用经典开发模式,让初学者能够更快的入门并投入到团队开发中去。在线代码生成功能包括核心模块如组织机构、角色用户、菜单及按钮授权、数据权限、系统参数、内容管理、工作流等。采用松耦合设计界面无刷新一键换肤众多账号安全设置密码策略在线定时任务配置支持集群支持SAAS支持多数据源;支持微服务
JeeSite 快速开发平台的主要目的是能够让初级的研发人员快速的开发出复杂的业务功能(经典架构会的人多),让开发者注重专注业务,其余有平台来封装技术细节,降低技术难度,从而节省人力成本,缩短项目周期,提高软件安全质量。
JeeSite 自开源以来已被广大爱好者用到了企业、政府、医疗、金融、互联网等各个领域中JeeSite 依架构简单精良、易于扩展、大众思维的设计模式,深入开发者的内心,并得到一致好评,于[2016](http://www.oschina.net/project/top_cn_2016?sort=1)和[2017](http://www.oschina.net/project/top_cn_2017?sort=1)连续两年获得开源中国《最受欢迎中国开源软件》奖杯,期间也帮助了不少刚毕业的大学生作为入门教材,快速的去实践。
JeeSite 自 2013 年发布以来已被广大爱好者用到了企业、政府、医疗、金融、互联网等各个领域中JeeSite 依架构简单精良、易于扩展、大众思维的设计模式,深入开发者的内心,并得到一致好评,于[2016](http://www.oschina.net/project/top_cn_2016?sort=1)和[2017](http://www.oschina.net/project/top_cn_2017?sort=1)连续两年获得开源中国《最受欢迎中国开源软件》奖杯,期间也帮助了不少刚毕业的大学生作为入门教材,快速的去实践。
4.0的升级,作者结合了多年总结和经验,以及各方面的应用案例,对架构完成了一次全部重构,也纳入很多新的思想。不管是从开发者模式、底层架构、逻辑处理还是到用户界面,用户交互体验上都有很大的进步,在不忘学习成本、提高开发效率的情况下,安全方面也做和很多工作,包括:身份认证、密码策略、安全审计、日志收集。
V4 的升级,作者结合了多年总结和经验,以及各方面的应用案例,对架构完成了一次全部重构,也纳入很多新的思想。不管是从开发者模式、底层架构、逻辑处理还是到用户界面,用户交互体验上都有很大的进步,在不忘学习成本、提高开发效率的情况下,安全方面也做和很多工作,包括:身份认证、密码策略、安全审计、日志收集。
**我们的优势:** 架构清晰、技术先进、入门简单、易于维护、易于扩展、安全稳定。
### 4.x 新特性:<http://jeesite4.mydoc.io/?t=281645>
### 4.0 新特性
* <http://jeesite4.mydoc.io/?t=281645>
* **我们的优势:** 整体架构清晰、稳定技术先进、入门简单、易于维护、易于扩展、安全稳定。
## 技术选型
* 主框架Spring Boot 1.5、Spring Framework 4.3、Apache Shiro 1.4
* 持久层Apache MyBatis 3.4、Hibernate Validation 5.3、Alibaba Druid 1.1
* 视图层Spring MVC 4.3、Beetl 2.7 替换JSP、Bootstrap 3.3、AdminLTE 2.4
* 主框架Spring Boot 2.0、Spring Framework 5.0、Apache Shiro 1.4、J2Cache
* 持久层Apache MyBatis 3.4、Hibernate Validation 6.0、Alibaba Druid 1.1
* 视图层Spring MVC 5.0、Beetl 2.7 替换JSP、Bootstrap 3.3、AdminLTE 2.4
* 前端组件jQuery 1.12、jqGrid 4.7、layer 3.0、zTree 3.5、jquery-validation
* 工具组件Apache Commons、Logback 1.1、Jackson 2.8、POI 3.14、Quartz 2.2
* 乐云短信网关SmsUtils.java <http://www.lehuo520.cn>
* 技术选型详情:<http://jeesite4.mydoc.io/?t=273599>
## 内置功能菜单
## 内置功能
* <http://jeesite4.mydoc.io/?t=270187>
## 开发手册
## 生态系统
* 持久层开发手册 (Dao)<http://jeesite4.mydoc.io/?t=267351>
* 业务层开发手册 (Service)<http://jeesite4.mydoc.io/?t=267352>
* 视图层开发手册 (WebView)<http://jeesite4.mydoc.io/?t=267353>
* 权限管理应用基础 (Shiro)<http://jeesite4.mydoc.io/?t=298473>
* 常用JS类库API (jeesite.js)<http://jeesite4.mydoc.io/?t=301473>
* 数据表格API (DataGrid.js)<http://jeesite4.mydoc.io/?t=301488>
* 修改 (默认) 视图,新增主题:<http://jeesite4.mydoc.io/?t=267355>
* 手机 API 接口调用、前后分离:<http://jeesite4.mydoc.io/?t=270527>
* 分布式微服务系统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>【敬请期待】
# 快速体验
## 快速体验
### 在线演示
@@ -51,28 +43,44 @@ JeeSite 自开源以来已被广大爱好者用到了企业、政府、医疗、
1. 环境准备:`JDK 1.8``Maven 3.3``MySQL 5.7`
2. 下载源码:<https://gitee.com/thinkgem/jeesite4/attach_files>
3. 打开文件:/web`/src/main/resources/config/jeesite.yml` 配置JDBC连接
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://jeesite4.mydoc.io/?t=284210>
7. 部署常见问题:<http://jeesite4.mydoc.io/?t=284210>
### 开发环境
1. 部署运行:<http://jeesite4.mydoc.io/?t=267354>
2. 常见问题:<http://jeesite4.mydoc.io/?t=284210>
# 今后如何升级?
## 开发手册
* 代码生成 / 快速入门 (Guide)<http://jeesite4.mydoc.io/?t=316743>
* 持久层 / 数据库操作 (MyBatis)<http://jeesite4.mydoc.io/?t=267351>
* 业务层 / 数据权限 (Service)<http://jeesite4.mydoc.io/?t=267352>
* 视图层 / 表单组件 (Beetl)<http://jeesite4.mydoc.io/?t=267353>
* 功能权限基础文档 (Shiro)<http://jeesite4.mydoc.io/?t=298473>
* 常用JS类库API (jeesite.js)<http://jeesite4.mydoc.io/?t=301473>
* 数据表格API (DataGrid.js)<http://jeesite4.mydoc.io/?t=301488>
* 修改 (默认) 视图,新增主题:<http://jeesite4.mydoc.io/?t=267355>
* 手机 API 接口调用、前后分离:<http://jeesite4.mydoc.io/?t=270527>
* 消息提醒中心使用手册:<http://jeesite4.mydoc.io/?t=323351>
* 常见问题:<http://jeesite4.mydoc.io/?t=284210>
## 今后如何升级?
尽量不修改web项目以外的源码项目如 jeesite-common、jeesite-modele-core如果修改了请 Pull Requests 上来,否则代码编码将与官方不同步,将对你的日后升级带来困难。
JeeSite的小版本4.0.x升级是非常便捷的你只需要将 pom.xml 文件中的 parent.version 版本修改到最新版本即可同版本下你可进行Maven快照强制更新即可将最新版的依赖jar更新到本地下面介绍一下在Eclipse里如何操作
JeeSite的小版本4.1.x升级是非常便捷的你只需要将 pom.xml 文件中的 parent.version 版本修改到最新版本即可同版本下你可进行Maven快照强制更新即可将最新版的依赖jar更新到本地下面介绍一下在Eclipse里如何操作
在web项目上右键选择菜单 -> Maven -> Update Project...或按Alt+F5 -> 点击 Select All 按钮 -> 选择 Force Update of Snapshots/Releases 复选框 -> 点击OK按钮即可。
如果您修改了其它依赖模块代码这时你需要与官方Git仓库代码进行同步。
如果进行相对大的版本4.x.x升级这里我们会附加一个声明帮助你进行迁移操作。
# 授权协议声明
## 授权协议声明
1. 已开源的代码,授权协议采用 AGPL v3 + Apache Licence v2 进行发行。
2. 您可以免费使用、修改和衍生代码,但不允许修改后和衍生的代码做为闭源软件发布。
@@ -89,16 +97,16 @@ JeeSite的小版本4.0.x升级是非常便捷的你只需要将 pom.xml
# 技术交流方式
* QQ 群号: `127515876(已满)` `209330483(已满)` `223507718(已满)` `709534275` `730390092`
* QQ 群号:`127515876``209330483``223507718``709534275``730390092``183903863(外包)`
* 问题反馈:<https://gitee.com/thinkgem/jeesite4/issues>  [【新手必读】](http://www.dianbo.org/9238/stone/tiwendezhihui.htm)
* 码云Gitee<https://gitee.com/thinkgem/jeesite4>
* GitHub<https://github.com/thinkgem/jeesite4>
* 作者博客:<https://my.oschina.net/thinkgem>
* 官方网站:<http://jeesite.com>
* 官方论坛:<http://jeesite.net>
* 微信公众号:
![https://static.oschina.net/uploads/space/2018/0302/145133_OGZf_941661.jpg](https://static.oschina.net/uploads/space/2018/0302/145133_OGZf_941661.jpg "JeeSite4微信公众号")
![JeeSite4微信公众号](https://static.oschina.net/uploads/space/2018/0302/145133_OGZf_941661.jpg "JeeSite4微信公众号")
# Git 全局设置技巧

View File

@@ -1,8 +1,8 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.source=1.7
org.eclipse.jdt.core.compiler.source=1.8

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<faceted-project>
<installed facet="jst.utility" version="1.0"/>
<installed facet="java" version="1.7"/>
</faceted-project>
<?xml version="1.0" encoding="UTF-8"?>
<faceted-project>
<installed facet="jst.utility" version="1.0"/>
<installed facet="java" version="1.8"/>
</faceted-project>

View File

@@ -6,7 +6,7 @@
<parent>
<groupId>com.jeesite</groupId>
<artifactId>jeesite-parent</artifactId>
<version>4.0.6-SNAPSHOT</version>
<version>4.1.2-SNAPSHOT</version>
<relativePath>../parent/pom.xml</relativePath>
</parent>
@@ -27,17 +27,16 @@
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
@@ -46,19 +45,33 @@
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>${commons-beanutils.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
<version>${commons-text.version}</version>
</dependency>
<!-- Apache Tools Ant Tar Zip -->
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
<version>${ant.version}</version>
</dependency>
<!-- Java serialization -->
<dependency>
<groupId>de.ruedigermoeller</groupId>
<artifactId>fst</artifactId>
<version>${ruedigermoeller-fst.version}</version>
<version>${fst.version}</version>
</dependency>
<!-- Json in java -->
<!-- Json in java -->
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>${json.version}</version>
</dependency>
<!-- Jackson json -->
@@ -93,11 +106,97 @@
<artifactId>snakeyaml</artifactId>
</dependency>
<!-- Bean To Bean copy -->
<!-- Apache HTTP -->
<dependency>
<groupId>net.sf.dozer</groupId>
<artifactId>dozer</artifactId>
<version>${dozer.version}</version>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<!-- Jsoup HTTP -->
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>${jsoup.version}</version>
</dependency>
<!-- Email -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-email</artifactId>
<version>${commons-email.version}</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>${activation.version}</version>
</dependency>
<!-- User Agent -->
<dependency>
<groupId>eu.bitwalker</groupId>
<artifactId>UserAgentUtils</artifactId>
<version>${UserAgentUtils.version}</version>
</dependency>
<!-- 图片Meta获取 -->
<dependency>
<groupId>com.drewnoakes</groupId>
<artifactId>metadata-extractor</artifactId>
<version>${metadata-extractor.version}</version>
</dependency>
<!-- 缩略图工具 -->
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>${thumbnailator.version}</version>
</dependency>
<!-- 支持CMYK图片 -->
<dependency>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio-jpeg</artifactId>
<version>${twelvemonkeys.version}</version>
</dependency>
<!-- 图片验证码生成 -->
<dependency>
<groupId>com.bladejava</groupId>
<artifactId>blade-patchca</artifactId>
<version>${blade-patchca.version}</version>
</dependency>
<!-- File MimeType ContentType -->
<dependency>
<groupId>net.sf.jmimemagic</groupId>
<artifactId>jmimemagic</artifactId>
<version>${jmimemagic.version}</version>
<exclusions>
<exclusion>
<groupId>xerces</groupId>
<artifactId>xercesImpl</artifactId>
</exclusion>
<exclusion>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-xc</artifactId>
</exclusion>
<exclusion>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-jaxrs</artifactId>
</exclusion>
<exclusion>
<artifactId>log4j</artifactId>
<groupId>log4j</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- 条形码、二维码生成 -->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>${zxing.version}</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>${zxing.version}</version>
</dependency>
<!-- POI Office Tools -->
@@ -128,109 +227,14 @@
<version>${poi.version}</version>
</dependency>
<!-- Email -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-email</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
<!-- 条形码、二维码生成 -->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.3.0</version>
</dependency>
<!-- User Agent -->
<dependency>
<groupId>eu.bitwalker</groupId>
<artifactId>UserAgentUtils</artifactId>
<version>1.20</version>
</dependency>
<!-- Apache HTTP -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<!-- Jsoup HTTP -->
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.9.1</version>
</dependency>
<!-- 图片Meta获取 -->
<dependency>
<groupId>com.drewnoakes</groupId>
<artifactId>metadata-extractor</artifactId>
<version>2.9.1</version>
</dependency>
<!-- 缩略图工具 -->
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.8</version>
</dependency>
<!-- 图片验证码生成 -->
<dependency>
<groupId>com.bladejava</groupId>
<artifactId>blade-patchca</artifactId>
<version>1.0.5</version>
</dependency>
<!-- Apache Tools Ant Tar Zip -->
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
<version>1.9.7</version>
</dependency>
<!-- File MimeType ContentType -->
<dependency>
<groupId>net.sf.jmimemagic</groupId>
<artifactId>jmimemagic</artifactId>
<version>0.1.3</version>
<exclusions>
<exclusion>
<groupId>xerces</groupId>
<artifactId>xercesImpl</artifactId>
</exclusion>
<exclusion>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-xc</artifactId>
</exclusion>
<exclusion>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-jaxrs</artifactId>
</exclusion>
<exclusion>
<artifactId>log4j</artifactId>
<groupId>log4j</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- pinyin4j -->
<dependency>
<groupId>com.belerweb</groupId>
<artifactId>pinyin4j</artifactId>
<version>2.5.0</version>
<version>${pinyin4j.version}</version>
</dependency>
<!-- LOGGING begin -->
<!-- Logging begin -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
@@ -255,23 +259,24 @@
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<!-- LOGGING end -->
<!-- Logging end -->
<!-- Spring Core Web-->
<!-- Spring begin -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<artifactId>spring-beans</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<optional>true</optional>
</dependency>
<!-- Bean validate -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<optional>true</optional>
</dependency>
<!-- Spring end -->
<!-- JUnit Test -->
<dependency>

View File

@@ -15,7 +15,7 @@ import java.util.regex.Pattern;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.text.StringEscapeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -216,7 +216,34 @@ public class EncodeUtils {
&& !(StringUtils.startsWith(value, "{") && StringUtils.endsWith(value, "}")) // JSON Object
&& !(StringUtils.startsWith(value, "[") && StringUtils.endsWith(value, "]")) // JSON Array
){
value = value.replaceAll("\"", "&quot;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
StringBuilder sb = new StringBuilder();
for (int i = 0; i < value.length(); i++) {
char c = value.charAt(i);
switch (c) {
case '>':
sb.append("");
break;
case '<':
sb.append("");
break;
case '\'':
sb.append("");
break;
case '\"':
sb.append("");
break;
// case '&':
// sb.append("");
// break;
// case '#':
// sb.append("");
// break;
default:
sb.append(c);
break;
}
}
value = sb.toString();
}
if (logger.isInfoEnabled() && !value.equals(oriValue)){
logger.info("xssFilter: {} <=<=<= {}", value, text);
@@ -250,33 +277,35 @@ public class EncodeUtils {
}
// public static void main(String[] args) {
// xssFilter("你好,<script>alert(document.cookie)</script>我还在。");
// xssFilter("你好,<strong>加粗文字</strong>我还在。");
// xssFilter("<!--HTML-->你好,\"><strong>加粗文字</strong>我还在。");
// xssFilter("<!--HTML-->你好,<iframe src=\"abcdef\"></iframe><strong>加粗文字</strong>我还在。");
// xssFilter("<!--HTML-->你好,<iframe src=\"abcdef\"/><strong>加粗文字</strong>我还在。");
// xssFilter("<!--HTML-->你好,<iframe src=\"abcdef\"><strong>加粗文字</strong>我还在。");
// xssFilter("<!--HTML-->你好,<script type=\"text/javascript\">alert(document.cookie)</script>我还在。");
// xssFilter("<!--HTML-->你好,<script\n type=\"text/javascript\">\nalert(document.cookie)\n</script>我还在。");
// xssFilter("<!--HTML-->你好,<script src='' onerror='alert(document.cookie)'></script>我还在。");
// xssFilter("<!--HTML-->你好,<script type=text/javascript>alert()我还在。");
// xssFilter("<!--HTML-->你好,<script>alert(document.cookie)</script>我还在。");
// xssFilter("<!--HTML-->你好,<script>window.location='url'我还在。");
// xssFilter("<!--HTML-->你好,</script></iframe>我还在。");
// xssFilter("<!--HTML-->你好eval(abc)我还在。");
// xssFilter("<!--HTML-->你好xpression(abc)我还在。");
// xssFilter("<!--HTML-->你好,<img src='abc.jpg' onerror='location='';alert(document.cookie);'></img>我还在。");
// xssFilter("<!--HTML-->你好,<img src='abc.jpg' onerror='alert(document.cookie);'/>我还在。");
// xssFilter("<!--HTML-->你好,<img src='abc.jpg' onerror='alert(document.cookie);'>我还在。");
// xssFilter("<!--HTML-->你好,<a onload='alert(\"abc\")'>hello</a>我还在。");
// xssFilter("<!--HTML-->你好,<a href=\"/abc\">hello</a>我还在。");
// xssFilter("<!--HTML-->你好,<a href='/abc'>hello</a>我还在。");
// xssFilter("<!--HTML-->你好,<a href='vbscript:alert(\"abc\");'>hello</a>我还在。");
// xssFilter("<!--HTML-->你好,<a href='javascript:alert(\"abc\");'>hello</a>我还在。");
// xssFilter("<!--HTML-->你好,?abc=def&hello=123&world={\"a\":1}我还在。");
// sqlFilter("你好select * from xxx where abc=def and 1=1我还在。");
// sqlFilter("你好insert into xxx values(1,2,3,4,5)我还在。");
// sqlFilter("你好,delete from xxx我还在。");
// int i = 0;
// xssFilter((++i)+"你好,<script>alert(document.cookie)</script>我还在。");
// xssFilter((++i)+"你好,<strong>加粗文字</strong>我还在。");
// xssFilter("<!--HTML-->"+(++i)+"你好,\"><strong>加粗文字</strong>我还在。");
// xssFilter("<!--HTML-->"+(++i)+"你好,<iframe src=\"abcdef\"></iframe><strong>加粗文字</strong>我还在。");
// xssFilter("<!--HTML-->"+(++i)+"你好,<iframe src=\"abcdef\"/><strong>加粗文字</strong>我还在。");
// xssFilter("<!--HTML-->"+(++i)+"你好,<iframe src=\"abcdef\"><strong>加粗文字</strong>我还在。");
// xssFilter("<!--HTML-->"+(++i)+"你好,<script type=\"text/javascript\">alert(document.cookie)</script>我还在。");
// xssFilter("<!--HTML-->"+(++i)+"你好,<script\n type=\"text/javascript\">\nalert(document.cookie)\n</script>我还在。");
// xssFilter("<!--HTML-->"+(++i)+"你好,<script src='' onerror='alert(document.cookie)'></script>我还在。");
// xssFilter("<!--HTML-->"+(++i)+"你好,<script type=text/javascript>alert()我还在。");
// xssFilter("<!--HTML-->"+(++i)+"你好,<script>alert(document.cookie)</script>我还在。");
// xssFilter("<!--HTML-->"+(++i)+"你好,<script>window.location='url'我还在。");
// xssFilter("<!--HTML-->"+(++i)+"你好,</script></iframe>我还在。");
// xssFilter("<!--HTML-->"+(++i)+"你好eval(abc)我还在。");
// xssFilter("<!--HTML-->"+(++i)+"你好xpression(abc)我还在。");
// xssFilter("<!--HTML-->"+(++i)+"你好,<img src='abc.jpg' onerror='location='';alert(document.cookie);'></img>我还在。");
// xssFilter("<!--HTML-->"+(++i)+"你好,<img src='abc.jpg' onerror='alert(document.cookie);'/>我还在。");
// xssFilter("<!--HTML-->"+(++i)+"你好,<img src='abc.jpg' onerror='alert(document.cookie);'>我还在。");
// xssFilter("<!--HTML-->"+(++i)+"你好,<a onload='alert(\"abc\")'>hello</a>我还在。");
// xssFilter("<!--HTML-->"+(++i)+"你好,<a href=\"/abc\">hello</a>我还在。");
// xssFilter("<!--HTML-->"+(++i)+"你好,<a href='/abc'>hello</a>我还在。");
// xssFilter("<!--HTML-->"+(++i)+"你好,<a href='vbscript:alert(\"abc\");'>hello</a>我还在。");
// 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我还在。");
// }
}

View File

@@ -3,12 +3,16 @@
*/
package com.jeesite.common.codec;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import com.jeesite.common.io.IOUtils;
/**
* MD5不可逆加密工具类
* @author ThinkGem
@@ -17,7 +21,6 @@ public class Md5Utils {
private static final String MD5 = "MD5";
private static final String DEFAULT_ENCODING = "UTF-8";
/**
* 对输入字符串进行md5散列.
@@ -63,5 +66,33 @@ public class Md5Utils {
public static byte[] md5(InputStream input) throws IOException {
return DigestUtils.digest(input, MD5);
}
/**
* 获取文件的MD5值
*/
public static String md5File(File file) {
return md5File(file, -1);
}
/**
* 获取文件的MD5值支持获取文件部分的MD5值
* uploader.md5File(file, 0, 10 * 1024 * 1024)
*/
public static String md5File(File file, int size) {
if (file != null && file.exists()){
try (InputStream in = FileUtils.openInputStream(file)){
byte[] bytes = null;
if (size != -1 && file.length() >= size){
bytes = IOUtils.toByteArray(in, size);
}else{
bytes = IOUtils.toByteArray(in);
}
return EncodeUtils.encodeHex(md5(bytes));
} catch (IOException e) {
return StringUtils.EMPTY;
}
}
return StringUtils.EMPTY;
}
}

View File

@@ -383,7 +383,8 @@ public class ListUtils extends org.apache.commons.collections.ListUtils {
public static <T> List<T> listOrderBy(List<T> list, String orderBy){
if (list != null && StringUtils.isNotBlank(orderBy)){
final String[] ss = orderBy.trim().split(" ");
if (ss != null && ss.length == 2){
if (ss != null){
final String t = ss.length==2 ? ss[1] : "asc";
Collections.sort(list, new Comparator<T>() {
@Override
public int compare(T o1, T o2) {
@@ -395,12 +396,13 @@ public class ListUtils extends org.apache.commons.collections.ListUtils {
s1 = ObjectUtils.toString(ReflectUtils.invokeGetter(o1, ss[0]));
s2 = ObjectUtils.toString(ReflectUtils.invokeGetter(o2, ss[0]));
}
if ("asc".equals(ss[1])){
if ("asc".equalsIgnoreCase(t)){
return s1.compareTo(s2);
}else{
return s2.compareTo(s1);
}
}});
}
});
}
}
return list;

View File

@@ -44,6 +44,7 @@ import net.sf.jmimemagic.MagicMatch;
public class FileUtils extends org.apache.commons.io.FileUtils {
private static Logger logger = LoggerFactory.getLogger(FileUtils.class);
private static MimetypesFileTypeMap mimetypesFileTypeMap;
/**
* 复制单个文件,如果目标文件存在,则不覆盖
@@ -242,14 +243,10 @@ public class FileUtils extends org.apache.commons.io.FileUtils {
* @author ThinkGem 2016-7-4
*/
public static String readFileToString(String classResourcePath){
InputStream in = null;
try {
in = new ClassPathResource(classResourcePath).getInputStream();
try (InputStream in = new ClassPathResource(classResourcePath).getInputStream()){
return IOUtils.toString(in, Charsets.toCharset("UTF-8"));
} catch (IOException e) {
logger.warn("Error file convert: {}", e.getMessage());
}finally{
IOUtils.closeQuietly(in);
}
return null;
}
@@ -658,7 +655,10 @@ public class FileUtils extends org.apache.commons.io.FileUtils {
* @return 返回文件类型
*/
public static String getContentType(String fileName) {
return new MimetypesFileTypeMap().getContentType(fileName);
if (mimetypesFileTypeMap == null){
mimetypesFileTypeMap = new MimetypesFileTypeMap();
}
return mimetypesFileTypeMap.getContentType(fileName);
}
/**
@@ -758,7 +758,7 @@ public class FileUtils extends org.apache.commons.io.FileUtils {
try {
response.addHeader("Content-Disposition", "attachment; filename=\"" +
EncodeUtils.encodeUrl(StringUtils.isBlank(fileName) ? file.getName() : fileName) + "\"");
response.setContentType(getContentType(file.getName())); // set the MIME type.
response.setContentType(FileUtils.getContentType(file.getName())); // set the MIME type.
response.addHeader("Content-Length", String.valueOf(contentLength));
os = response.getOutputStream();
out = new BufferedOutputStream(os);
@@ -808,20 +808,20 @@ public class FileUtils extends org.apache.commons.io.FileUtils {
logger.debug("提醒向客户端传输时出现IO异常但此异常是允许的有可能客户端取消了下载导致此异常不用关心");
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
logger.debug(e.getMessage(), e);
} finally {
if (out != null) {
try {
out.close();
} catch (IOException e) {
logger.error(e.getMessage(), e);
// logger.error(e.getMessage(), e);
}
}
if (raf != null) {
try {
raf.close();
} catch (IOException e) {
logger.error(e.getMessage(), e);
// logger.error(e.getMessage(), e);
}
}
}
@@ -944,9 +944,9 @@ public class FileUtils extends org.apache.commons.io.FileUtils {
projectPath = file.toString();
}
} catch (FileNotFoundException e) {
;
// 忽略异常
} catch (IOException e) {
e.printStackTrace();
// 忽略异常
}
// 取不到,取当前工作路径
if (StringUtils.isBlank(projectPath)){
@@ -982,9 +982,9 @@ public class FileUtils extends org.apache.commons.io.FileUtils {
webappPath = file.toString();
}
} catch (FileNotFoundException e) {
;
// 忽略异常
} catch (IOException e) {
e.printStackTrace();
// 忽略异常
}
// 取不到,取当前工作路径
if (StringUtils.isBlank(webappPath)){

View File

@@ -3,10 +3,13 @@
*/
package com.jeesite.common.io;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* 数据流工具类
@@ -80,4 +83,24 @@ public class IOUtils extends org.apache.commons.io.IOUtils {
return fileOutputStream;
}
/**
* Closes a <code>Closeable</code> unconditionally.
*/
public static void closeQuietly(final InputStream input) {
closeQuietly((Closeable) input);
}
/**
* Closes a <code>Closeable</code> unconditionally.
*/
public static void closeQuietly(final Closeable closeable) {
try {
if (closeable != null) {
closeable.close();
}
} catch (final IOException ioe) {
// ignore
}
}
}

View File

@@ -12,10 +12,10 @@ import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.core.env.Environment;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
@@ -37,8 +37,9 @@ public class PropertiesUtils {
"classpath:config/application.yml", "classpath:application.yml"};
private static Logger logger = PropertiesUtils.initLogger();
private final Set<String> configSet = SetUtils.newLinkedHashSet();
private final Properties properties = new Properties();
private static Environment environment;
/**
* 当前类的实例持有者(静态内部类,延迟加载,懒汉式,线程安全的单例模式)
@@ -55,7 +56,7 @@ public class PropertiesUtils {
for(Resource resource : resources){
configSet.add("classpath:config/"+resource.getFilename());
}
configSet.add("classpath:config/jeesite.yml");
//configSet.add("classpath:config/jeesite.yml");
// 获取全局设置默认的配置文件(以下是支持环境配置的属性文件)
Set<String> set = SetUtils.newLinkedHashSet();
for (String configFile : DEFAULT_CONFIG_FILE){
@@ -83,7 +84,7 @@ public class PropertiesUtils {
}
for (String location : configFiles){
configSet.add(location);
if (StringUtils.isNotBlank(profiles) && !StringUtils.equals(profiles, "default")){
if (StringUtils.isNotBlank(profiles)){
if (location.endsWith(".properties")){
configSet.add(StringUtils.substringBeforeLast(location, ".properties")
+ "-" + profiles + ".properties");
@@ -108,14 +109,11 @@ public class PropertiesUtils {
Resource resource = ResourceUtils.getResource(location);
if (resource.exists()){
if (location.endsWith(".properties")){
InputStreamReader is = null;
try {
is = new InputStreamReader(resource.getInputStream(), "UTF-8");
try (InputStreamReader is = new InputStreamReader(resource.getInputStream(), "UTF-8")){
properties.load(is);
configSet.add(location);
} catch (IOException ex) {
logger.error("Load " + location + " failure. ", ex);
} finally {
IOUtils.closeQuietly(is);
}
}
else if (location.endsWith(".yml")){
@@ -125,18 +123,24 @@ public class PropertiesUtils {
properties.put(ObjectUtils.toString(entry.getKey()),
ObjectUtils.toString(entry.getValue()));
}
configSet.add(location);
}
}
} catch (Exception e) {
logger.error("Load " + location + " failure. ", e);
}
// 存储当前加载的配置文件路径和名称
properties.setProperty("configFiles", StringUtils.join(configFiles, ","));
}
}
/**
* 获取当前加载的属性
* 获取当前加载的属性文件
*/
public Set<String> getConfigSet() {
return configSet;
}
/**
* 获取当前加载的属性数据
*/
public Properties getProperties() {
return properties;
@@ -163,14 +167,19 @@ public class PropertiesUtils {
* 获取属性值取不到从System.getProperty()获取都取不到返回null
*/
public String getProperty(String key) {
if (environment != null){
String value = environment.getProperty(key);
if (value != null){
return value;
}
}
String value = properties.getProperty(key);
if (value != null){
// 支持嵌套取值的问题 key=${xx}/yy
Matcher m = p1.matcher(value);
while(m.find()) {
String g = m.group();
String keyChild = g.replaceAll("\\$\\{", "").replaceAll("\\}", "");
value = StringUtils.replace(value, g, getProperty(keyChild));
String childKey = g.replaceAll("\\$\\{|\\}", "");
value = StringUtils.replace(value, g, getProperty(childKey));
}
return value;
}else{
@@ -190,6 +199,14 @@ public class PropertiesUtils {
return value != null ? value : defaultValue;
}
/**
* 设置环境属性
* @param environment
*/
public static void setEnvironment(Environment environment) {
PropertiesUtils.environment = environment;
}
/**
* 初始化日志路径
*/
@@ -207,7 +224,9 @@ public class PropertiesUtils {
if (new File(classesLogPath).exists()){
logPath = classesLogPath;
}
System.setProperty("logPath", FileUtils.path(logPath));
if (StringUtils.isBlank(System.getProperty("logPath"))){
System.setProperty("logPath", FileUtils.path(logPath));
}
return LoggerFactory.getLogger(PropertiesUtils.class);
}

View File

@@ -0,0 +1,39 @@
/**
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
*/
package com.jeesite.common.io;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import org.springframework.boot.env.OriginTrackedMapPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.Resource;
/**
* 配置文件加载Boot
* @author ThinkGem
* @version 2018-10-16
*/
public class PropertyLoader implements org.springframework.boot.env.PropertySourceLoader{
private static boolean isLoadPropertySource = false;
@Override
public String[] getFileExtensions() {
return new String[] { "properties", "yml" };
}
@Override
public List<PropertySource<?>> load(String name, Resource resource) throws IOException {
if (!isLoadPropertySource){
isLoadPropertySource = true;
Properties properties = PropertiesUtils.getInstance().getProperties();
return Collections.singletonList(new OriginTrackedMapPropertySource("jeesite", properties));
}
return Collections.emptyList();
}
}

View File

@@ -67,14 +67,10 @@ public class ResourceUtils extends org.springframework.util.ResourceUtils {
* @author ThinkGem
*/
public static String getResourceFileContent(String location){
InputStream is = null;
try{
is = ResourceUtils.getResourceFileStream(location);
try(InputStream is = ResourceUtils.getResourceFileStream(location)){
return IOUtils.toString(is, "UTF-8");
}catch (IOException e) {
throw ExceptionUtils.unchecked(e);
}finally{
IOUtils.closeQuietly(is);
}
}

View File

@@ -4,6 +4,7 @@
package com.jeesite.common.lang;
import java.math.BigDecimal;
import java.text.DecimalFormat;
/**
* BigDecimal工具类
@@ -92,4 +93,19 @@ public class NumberUtils extends org.apache.commons.lang3.math.NumberUtils {
return bg.setScale(0, BigDecimal.ROUND_HALF_UP).toString();
}
/**
* 格式化数值类型
* @param data
* @param pattern
*/
public static String formatNumber(Object data, String pattern) {
DecimalFormat df = null;
if (pattern == null) {
df = new DecimalFormat();
} else {
df = new DecimalFormat(pattern);
}
return df.format(data);
}
}

View File

@@ -16,8 +16,6 @@ import org.nustaq.serialization.FSTConfiguration;
import org.springframework.beans.BeanUtils;
import org.springframework.core.NamedThreadLocal;
import com.jeesite.common.io.IOUtils;
/**
* 对象操作工具类, 继承org.apache.commons.lang3.ObjectUtils类
* @author ThinkGem
@@ -118,9 +116,13 @@ public class ObjectUtils extends org.apache.commons.lang3.ObjectUtils {
if (source == null){
return null;
}
Object target = BeanUtils.instantiate(source.getClass());
BeanUtils.copyProperties(source, target, ignoreProperties);
return target;
try {
Object target = source.getClass().newInstance();
BeanUtils.copyProperties(source, target, ignoreProperties);
return target;
} catch (InstantiationException | IllegalAccessException e) {
throw ExceptionUtils.unchecked(e);
}
}
/**
@@ -162,18 +164,12 @@ public class ObjectUtils extends org.apache.commons.lang3.ObjectUtils {
}
long beginTime = System.currentTimeMillis();
byte[] bytes = null;
ObjectOutputStream oos = null;
ByteArrayOutputStream baos = null;
try {
baos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(baos);
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);) {
oos.writeObject(object);
bytes = baos.toByteArray();
} catch (Exception e) {
e.printStackTrace();
} finally {
IOUtils.closeQuietly(oos);
IOUtils.closeQuietly(baos);
}
long totalTime = System.currentTimeMillis() - beginTime;
if (totalTime > 3000){
@@ -193,19 +189,13 @@ public class ObjectUtils extends org.apache.commons.lang3.ObjectUtils {
}
long beginTime = System.currentTimeMillis();
Object object = null;
ByteArrayInputStream bais = null;
ObjectInputStream ois = null;
try {
if (bytes.length > 0) {
bais = new ByteArrayInputStream(bytes);
ois = new ObjectInputStream(bais);
if (bytes.length > 0) {
try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bais);) {
object = ois.readObject();
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
IOUtils.closeQuietly(ois);
IOUtils.closeQuietly(bais);
}
long totalTime = System.currentTimeMillis() - beginTime;
if (totalTime > 3000){

View File

@@ -9,8 +9,6 @@ import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang3.StringEscapeUtils;
import com.jeesite.common.codec.EncodeUtils;
import com.jeesite.common.collect.ListUtils;
@@ -87,6 +85,14 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils {
}
return false;
}
/**
* 去除左右空格(包含中文空格)
* @param str
*/
public static String trim2(final String str) {
return str == null ? null : str.replaceAll("^[\\s| | ]*|[\\s| | ]*$", "");
}
/**
* 替换掉HTML标签方法
@@ -140,7 +146,7 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils {
try {
StringBuilder sb = new StringBuilder();
int currentLength = 0;
for (char c : stripHtml(StringEscapeUtils.unescapeHtml4(str)).toCharArray()) {
for (char c : stripHtml(EncodeUtils.decodeHtml(str)).toCharArray()) {
currentLength += String.valueOf(c).getBytes("GBK").length;
if (currentLength <= length - 3) {
sb.append(c);

View File

@@ -3,11 +3,8 @@
*/
package com.jeesite.common.lang;
import java.util.Arrays;
import java.util.Date;
import org.apache.commons.lang3.time.DateFormatUtils;
/**
* 时间计算工具类
* @author ThinkGem
@@ -16,45 +13,46 @@ import org.apache.commons.lang3.time.DateFormatUtils;
public class TimeUtils {
/**
* 将时间转换为字符串(xx天xx时xx分xx秒大于360天显示日期时间
* 将毫秒数转换为:xx天xx时xx分xx秒
*/
public static String formatDateAgo(long dateTime) {
public static String formatDateAgo(long millisecond) {
long ms = millisecond;
int ss = 1000;
int mi = ss * 60;
int hh = mi * 60;
int dd = hh * 24;
long day = ms / dd;
long hour = (ms - day * dd) / hh;
long minute = (ms - day * dd - hour * hh) / mi;
long second = (ms - day * dd - hour * hh - minute * mi) / ss;
StringBuilder sb = new StringBuilder();
if (dateTime < 1000){
sb.append(dateTime).append("毫秒");
}else{
TimeUtils t = new TimeUtils(dateTime);
int day = t.get(TimeUtils.DAY);
int hour = t.get(TimeUtils.HOUR);
int minute = t.get(TimeUtils.MINUTE);
int second = t.get(TimeUtils.SECOND);
if (day > 365){
return DateUtils.formatDate(new Date(dateTime), "yyyy年MM月dd日 HH时mm分ss秒");
}
if (day > 0){
if (ms < 1000) {
sb.append(ms).append("毫秒");
} else {
if (day > 0) {
sb.append(day).append("");
}
if (hour > 0){
if (hour > 0) {
sb.append(hour).append("");
}
if (minute > 0){
if (minute > 0) {
sb.append(minute).append("");
}
if (second > 0){
if (second > 0) {
sb.append(second).append("");
}
}
return sb.toString();
}
/**
/**
* 将过去的时间转为为刚刚xx秒xx分钟xx小时前、xx天前大于3天的显示日期
*/
public static String formatTimeAgo(String dateTime) {
return formatTimeAgo(DateUtils.parseDate(dateTime));
}
/**
/**
* 将过去的时间转为为刚刚xx秒xx分钟xx小时前、xx天前大于3天的显示日期
*/
public static String formatTimeAgo(Date dateTime) {
@@ -66,8 +64,8 @@ public class TimeUtils {
interval = "刚刚";
}
// 如果时间间隔大于24小时则显示多少天前
else if (time / 3600000 < 24*4 && time / 3600000 >= 24) {
int d = (int) (time / (3600000*24));// 得出的时间间隔的单位是天
else if (time / 3600000 < 24 * 4 && time / 3600000 >= 24) {
int d = (int) (time / (3600000 * 24));// 得出的时间间隔的单位是天
interval = d + "天前";
}
// 如果时间间隔小于24小时则显示多少小时前
@@ -76,310 +74,20 @@ public class TimeUtils {
interval = h + "小时前";
}
// 如果时间间隔小于60分钟则显示多少分钟前
else if (time / 60000 < 60 && time / 60000 >=1) {
else if (time / 60000 < 60 && time / 60000 >= 1) {
int m = (int) ((time % 3600000) / 60000);// 得出的时间间隔的单位是分钟
interval = m + "分钟前";
}
// 如果时间间隔小于60秒则显示多少秒前
else if (time / 1000 < 60 && time / 1000 >=10) {
else if (time / 1000 < 60 && time / 1000 >= 10) {
int se = (int) ((time % 60000) / 1000);
interval = se + "秒前";
}
// 大于3天的则显示正常的时间但是不显示秒
else {
interval = DateUtils.formatDate(dateTime,"yyyy-MM-dd");
interval = DateUtils.formatDate(dateTime, "yyyy-MM-dd");
}
return interval;
}
/**
* 时间字段常量,表示“秒”
*/
public final static int SECOND = 0;
/**
* 时间字段常量,表示“分”
*/
public final static int MINUTE = 1;
/**
* 时间字段常量,表示“时”
*/
public final static int HOUR = 2;
/**
* 时间字段常量,表示“天”
*/
public final static int DAY = 3;
/**
* 各常量允许的最大值
*/
private final int[] maxFields = { 59, 59, 23, Integer.MAX_VALUE - 1 };
/**
* 各常量允许的最小值
*/
private final int[] minFields = { 0, 0, 0, Integer.MIN_VALUE };
/**
* 默认的字符串格式时间分隔符
*/
private String timeSeparator = ":";
/**
* 时间数据容器
*/
private int[] fields = new int[4];
/**
* 无参构造,将各字段置为 0
*/
public TimeUtils() {
this(0, 0, 0, 0);
}
/**
* 使用时、分构造一个时间
* @param hour 小时
* @param minute 分钟
*/
public TimeUtils(int hour, int minute) {
this(0, hour, minute, 0);
}
/**
* 使用时、分、秒构造一个时间
* @param hour 小时
* @param minute 分钟
* @param second 秒
*/
public TimeUtils(int hour, int minute, int second) {
this(0, hour, minute, second);
}
/**
* 使用一个字符串构造时间<br>
* Time time = new Time("14:22:23");
* @param time 字符串格式的时间,默认采用“:”作为分隔符
*/
public TimeUtils(String time) {
this(time, null);
// System.out.println(time);
}
/**
* 使用时间毫秒构建时间
* @param time
*/
public TimeUtils(long time){
this(new Date(time));
}
/**
* 使用日期对象构造时间
* @param date
*/
public TimeUtils(Date date){
this(DateFormatUtils.formatUTC(date, "HH:mm:ss"));
}
/**
* 使用天、时、分、秒构造时间,进行全字符的构造
* @param day 天
* @param hour 时
* @param minute 分
* @param second 秒
*/
public TimeUtils(int day, int hour, int minute, int second) {
initialize(day, hour, minute, second);
}
/**
* 使用一个字符串构造时间,指定分隔符<br>
* Time time = new Time("14-22-23", "-");
* @param time 字符串格式的时间
*/
public TimeUtils(String time, String timeSeparator) {
if(timeSeparator != null) {
setTimeSeparator(timeSeparator);
}
parseTime(time);
}
/**
* 设置时间字段的值
* @param field 时间字段常量
* @param value 时间字段的值
*/
public void set(int field, int value) {
if(value < minFields[field]) {
throw new IllegalArgumentException(value + ", time value must be positive.");
}
fields[field] = value % (maxFields[field] + 1);
// 进行进位计算
int carry = value / (maxFields[field] + 1);
if(carry > 0) {
int upFieldValue = get(field + 1);
set(field + 1, upFieldValue + carry);
}
}
/**
* 获得时间字段的值
* @param field 时间字段常量
* @return 该时间字段的值
*/
public int get(int field) {
if(field < 0 || field > fields.length - 1) {
throw new IllegalArgumentException(field + ", field value is error.");
}
return fields[field];
}
/**
* 将时间进行“加”运算,即加上一个时间
* @param time 需要加的时间
* @return 运算后的时间
*/
public TimeUtils addTime(TimeUtils time) {
TimeUtils result = new TimeUtils();
int up = 0; // 进位标志
for (int i = 0; i < fields.length; i++) {
int sum = fields[i] + time.fields[i] + up;
up = sum / (maxFields[i] + 1);
result.fields[i] = sum % (maxFields[i] + 1);
}
return result;
}
/**
* 将时间进行“减”运算,即减去一个时间
* @param time 需要减的时间
* @return 运算后的时间
*/
public TimeUtils subtractTime(TimeUtils time) {
TimeUtils result = new TimeUtils();
int down = 0; // 退位标志
for (int i = 0, k = fields.length - 1; i < k; i++) {
int difference = fields[i] + down;
if (difference >= time.fields[i]) {
difference -= time.fields[i];
down = 0;
} else {
difference += maxFields[i] + 1 - time.fields[i];
down = -1;
}
result.fields[i] = difference;
}
result.fields[DAY] = fields[DAY] - time.fields[DAY] + down;
return result;
}
/**
* 获得时间字段的分隔符
* @return
*/
public String getTimeSeparator() {
return timeSeparator;
}
/**
* 设置时间字段的分隔符(用于字符串格式的时间)
* @param timeSeparator 分隔符字符串
*/
public void setTimeSeparator(String timeSeparator) {
this.timeSeparator = timeSeparator;
}
private void initialize(int day, int hour, int minute, int second) {
set(DAY, day);
set(HOUR, hour);
set(MINUTE, minute);
set(SECOND, second);
}
private void parseTime(String time) {
if(time == null) {
initialize(0, 0, 0, 0);
return;
}
String t = time;
int field = DAY;
set(field--, 0);
int p = -1;
while((p = t.indexOf(timeSeparator)) > -1) {
parseTimeField(time, t.substring(0, p), field--);
t = t.substring(p + timeSeparator.length());
}
parseTimeField(time, t, field--);
}
private void parseTimeField(String time, String t, int field) {
if(field < SECOND || t.length() < 1) {
parseTimeException(time);
}
char[] chs = t.toCharArray();
int n = 0;
for(int i = 0; i < chs.length; i++) {
if(chs[i] <= ' ') {
continue;
}
if(chs[i] >= '0' && chs[i] <= '9') {
n = n * 10 + chs[i] - '0';
continue;
}
parseTimeException(time);
}
set(field, n);
}
private void parseTimeException(String time) {
throw new IllegalArgumentException(time + ", time format error, HH"
+ this.timeSeparator + "mm" + this.timeSeparator + "ss");
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder(16);
sb.append(fields[DAY]).append(',').append(' ');
buildString(sb, HOUR).append(timeSeparator);
buildString(sb, MINUTE).append(timeSeparator);
buildString(sb, SECOND);
return sb.toString();
}
private StringBuilder buildString(StringBuilder sb, int field) {
if(fields[field] < 10) {
sb.append('0');
}
return sb.append(fields[field]);
}
@Override
public int hashCode() {
final int PRIME = 31;
int result = 1;
result = PRIME * result + Arrays.hashCode(fields);
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final TimeUtils other = (TimeUtils) obj;
if (!Arrays.equals(fields, other.fields)) {
return false;
}
return true;
}
}

View File

@@ -1,37 +0,0 @@
/**
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
*/
package com.jeesite.common.mail;
/**
* 发送电子邮件
*/
@Deprecated
public class EmailUtils {
/**
* 发送邮件
* @param toAddress 接收地址
* @param subject 标题
* @param content 内容
* @return
*/
@Deprecated
public static boolean sendEmail(String toAddress, String subject, String content) {
return com.jeesite.common.msg.EmailUtils.send(toAddress, subject, content);
}
/**
* 发送邮件
* @param toAddress 接收地址
* @param subject 标题
* @param content 内容
* @return
*/
@Deprecated
public static boolean sendEmail(String fromAddress, String fromPassword, String fromHostName,
String sslOnConnect, String sslSmtpPort, String toAddress, String subject, String content) {
return com.jeesite.common.msg.EmailUtils.send(fromAddress, fromPassword, fromHostName, sslOnConnect, sslSmtpPort, toAddress, subject, content);
}
}

View File

@@ -1,59 +0,0 @@
/**
* Copyright (c) 2005-2012 springside.org.cn
*
* Licensed under the Apache License, Version 2.0 (the "License");
*/
package com.jeesite.common.mapper;
import java.util.Collection;
import java.util.List;
import org.dozer.DozerBeanMapper;
import com.jeesite.common.collect.ListUtils;
/**
* 简单封装Dozer, 实现深度转换Bean<->Bean的Mapper.实现:
*
* 1. 持有Mapper的单例.
* 2. 返回值类型转换.
* 3. 批量转换Collection中的所有对象.
* 4. 区分创建新的B对象与将对象A值复制到已存在的B对象两种函数.
*
* @author calvin
* @version 2013-01-15
*/
public class BeanMapper {
/**
* 持有Dozer单例, 避免重复创建DozerMapper消耗资源.
*/
private static DozerBeanMapper dozer = new DozerBeanMapper();
/**
* 基于Dozer转换对象的类型.
*/
public static <T> T map(Object source, Class<T> destinationClass) {
return dozer.map(source, destinationClass);
}
/**
* 基于Dozer转换Collection中对象的类型.
*/
@SuppressWarnings("rawtypes")
public static <T> List<T> mapList(Collection sourceList, Class<T> destinationClass) {
List<T> destinationList = ListUtils.newArrayList();
for (Object sourceObject : sourceList) {
T destinationObject = dozer.map(sourceObject, destinationClass);
destinationList.add(destinationObject);
}
return destinationList;
}
/**
* 基于Dozer将对象A的值拷贝到对象B中.
*/
public static void copy(Object source, Object destinationObject) {
dozer.map(source, destinationObject);
}
}

View File

@@ -11,6 +11,7 @@ import java.util.TimeZone;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonGenerator;
@@ -46,6 +47,8 @@ public class JsonMapper extends ObjectMapper {
}
public JsonMapper() {
// Spring ObjectMapper 初始化配置,支持 @JsonView
new Jackson2ObjectMapperBuilder().configure(this);
// 为Null时不序列化
this.setSerializationInclusion(Include.NON_NULL);
// 允许单引号
@@ -61,7 +64,7 @@ public class JsonMapper extends ObjectMapper {
@Override
public void serialize(Object value, JsonGenerator jgen,
SerializerProvider provider) throws IOException, JsonProcessingException {
jgen.writeString("");
jgen.writeString(StringUtils.EMPTY);
}
});
// // 统一默认Date类型转换格式。如果设置Bean中的@JsonFormat将失效

View File

@@ -21,6 +21,7 @@ import org.dom4j.Element;
import org.dom4j.Namespace;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import com.fasterxml.jackson.databind.JavaType;
@@ -46,6 +47,8 @@ public class XmlMapper extends com.fasterxml.jackson.dataformat.xml.XmlMapper{
* 构造方法
*/
public XmlMapper() {
// Spring ObjectMapper 初始化配置,支持 @JsonView
new Jackson2ObjectMapperBuilder().configure(this);
// 设置时区
this.setTimeZone(TimeZone.getTimeZone("GMT+8:00"));
}

View File

@@ -24,12 +24,12 @@ public class EmailUtils {
* @return
*/
public static boolean send(String toAddress, String subject, String content) {
PropertiesUtils loader = PropertiesUtils.getInstance();
String fromAddress = loader.getProperty("msg.email.fromAddress");
String fromPassword = loader.getProperty("msg.email.fromPassword");
String fromHostName = loader.getProperty("msg.email.fromHostName");
String sslOnConnect = loader.getProperty("msg.email.sslOnConnect", "false");
String sslSmtpPort = loader.getProperty("msg.email.sslSmtpPort");
PropertiesUtils props = PropertiesUtils.getInstance();
String fromAddress = props.getProperty("msg.email.fromAddress");
String fromPassword = props.getProperty("msg.email.fromPassword");
String fromHostName = props.getProperty("msg.email.fromHostName");
String sslOnConnect = props.getProperty("msg.email.sslOnConnect", "false");
String sslSmtpPort = props.getProperty("msg.email.sslSmtpPort");
return send(fromAddress, fromPassword, fromHostName, sslOnConnect, sslSmtpPort, toAddress, subject, content);
}

View File

@@ -1,141 +1,43 @@
package com.jeesite.common.msg;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Date;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.jeesite.common.io.PropertiesUtils;
import com.jeesite.common.lang.DateUtils;
/**
* 发送短信(乐云短信
* 发送短信(请实现send方法
*/
public class SmsUtils {
private final static Logger logger = LoggerFactory.getLogger(SmsUtils.class);
private final static PropertiesUtils props = PropertiesUtils.getInstance();
private final static String url = props.getProperty("msg.sms.url", "http://lehuo520.cn/a/sms/api");
private final static String data = props.getProperty("msg.sms.data", "username=jeesite&password=jeesite.com");
private final static String prefix = props.getProperty("msg.sms.prefix", "【JeeSite】");
private final static String suffix = props.getProperty("msg.sms.suffix", "");
// public static void main(String[] args) {
// String phone = "18500000000"; // 收短信人手机号码;例如:18500000000 支持多号码号码之间用英文逗号隔开最多100个
// String content = "您好您的验证码是123456请勿透露给其他人感谢您的使用。"; // 输入需要发送内容;例如:你好这是一条测试短信
// String smsid = ""; // 短信id查询短信状态报告时需要可为空
// System.out.println(send(content, phone)); // 发短信
// System.out.println(status(smsid, phone)); // 取状态
// System.out.println(reply()); //取上行 回复短信
// }
/**
* 发送短信
* @param content 接受内容
* @param phone 接受手机号码
* @return {"result":"0","describing""提交成功","sms":[{"phone":"18073110001,18073110002","smsid":"83bd18f1d48b4cc9b9fe7810c768ac43","status":"3"}]}
* 模拟发送短信
* @param content 短信内容
* @param mobile 接受手机号码
*/
public static String send(String content, String phone) {
return send(content, phone, null);
public static String send(String content, String mobile) {
// PropertiesUtils props = PropertiesUtils.getInstance();
// String url = props.getProperty("msg.sms.url");
// 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);
// for (String param : StringUtils.split(data, "&")){
// String[] ss = StringUtils.split(param, "=");
// if (ss.length == 1){
// conn.data(ss[0], "");
// }else if (ss.length == 2){
// conn.data(ss[0], ss[1]);
// }
// }
// // 手机号码
// conn.data("mobile", mobile);
// // 短信内容
// conn.data("content", prefix + content + suffix);
logger.warn("模拟发送短信成功!请实现 "+SmsUtils.class+" 的 send 方法。");
return "{result:0,message:\"模拟发送短信成功!\"}";
}
/**
* 发送短信
* @param content 接受内容
* @param phone 接受手机号码
* @param sendtime 发送时间为空立即发送
* @return {"result":"0","describing""提交成功","sms":[{"phone":"18073110001,18073110002","smsid":"83bd18f1d48b4cc9b9fe7810c768ac43","status":"3"}]}
*/
public static String send(String content, String phone, Date sendTime) {
String res = "";
try {
String param = data + "&phone=" + phone + "&content=" + URLEncoder
.encode(prefix + content + suffix, "UTF-8")
+ "&sendTime=" + (sendTime != null ? DateUtils
.formatDate(sendTime, "yyyyMMddHHmm") : "");
res = connectURL(url + "/send", param);
} catch (Exception ex) {
logger.error(ex.getMessage(), ex);
}
return res;
}
/**
* 获取状态
* @param smsid,phone可为空,为空取最近两天未获取状态报告,沦询间隔时间不能低于5分钟
* @return 请求错误返回页面示例: {"result":"-1","describing""帐号不存在,请检查用户名或者密码是否正确","sms":[]} 请求成功返回页面示例:
* {"result":"0","describing""提交成功","sms":[{"phone":"18073110001","smsid":"83bd18f1d48b4cc9b9fe7810c768ac43","status":"7"},{"phone":"18073110001","smsid":"83bd18f1d48b4cc9b9fe7810c768ac43","status":"8"}]}
*/
public static String status(String smsid, String phone) {
String res = "";
try {
String param = data + "&smsid=" + smsid;
res = connectURL(url + "/status", param);
} catch (Exception ex) {
logger.error(ex.getMessage(), ex);
}
return res;
}
/**
* 获取回复
* @param smsid:下发短信对应短信IDtaskId同一批任务ID
* @return {"result":"0","sms":[{"phone":"18073110001","neirong":"已收到","taskId":"83bd18f1d48b4cc9b9fe7810c768ac43"},"smsId":"83bd18f1d48b48j9b9fe7810c768ac43"}]}
*/
public static String reply() {
String res = "";
try {
String param = data;
res = connectURL(url + "/query", param);
} catch (Exception ex) {
logger.error(ex.getMessage(), ex);
}
return res;
}
/**
* 进行http提交
* @param
* @return
* @throws IOException
* @throws Exception
*/
private static String connectURL(String url, String param) throws IOException {
String res = "";
HttpURLConnection urlConn = null;
URL url1 = new URL(url);
urlConn = (HttpURLConnection) url1.openConnection();
urlConn.setRequestMethod("POST");
urlConn.setDoOutput(true);
OutputStream out = null;
BufferedReader rd = null;
try{
out = urlConn.getOutputStream();
out.write(param.getBytes("UTF-8"));
out.flush();
rd = new BufferedReader(new InputStreamReader(urlConn.getInputStream(), "UTF-8"));
StringBuffer sb = new StringBuffer();
int ch;
while ((ch = rd.read()) > -1) {
sb.append((char) ch);
}
res = sb.toString().trim();
}finally {
if (out!=null){
out.close();
}
if (rd!=null){
rd.close();
}
}
return res;
}
}

View File

@@ -43,20 +43,21 @@ public class ReflectUtils {
* 调用Getter方法.
* 支持多级,如:对象名.对象名.方法
*/
public static Object invokeGetter(Object obj, String propertyName) {
@SuppressWarnings("unchecked")
public static <E> E invokeGetter(Object obj, String propertyName) {
Object object = obj;
for (String name : StringUtils.split(propertyName, ".")){
String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(name);
object = invokeMethod(object, getterMethodName, new Class[] {}, new Object[] {});
}
return object;
return (E)object;
}
/**
* 调用Setter方法, 仅匹配方法名。
* 支持多级,如:对象名.对象名.方法
*/
public static void invokeSetter(Object obj, String propertyName, Object value) {
public static <E> void invokeSetter(Object obj, String propertyName, E value) {
Object object = obj;
String[] names = StringUtils.split(propertyName, ".");
for (int i=0; i<names.length; i++){
@@ -73,16 +74,17 @@ public class ReflectUtils {
/**
* 直接读取对象属性值, 无视private/protected修饰符, 不经过getter函数.
*/
public static Object getFieldValue(final Object obj, final String fieldName) {
@SuppressWarnings("unchecked")
public static <E> E getFieldValue(final Object obj, final String fieldName) {
Field field = getAccessibleField(obj, fieldName);
if (field == null) {
//throw new IllegalArgumentException("在 [" + obj.getClass() + "] 中,没有找到 [" + fieldName + "] 字段 ");
logger.warn("在 [" + obj.getClass() + "] 中,没有找到 [" + fieldName + "] 字段 ");
logger.debug("在 [" + obj.getClass() + "] 中,没有找到 [" + fieldName + "] 字段 ");
return null;
}
Object result = null;
E result = null;
try {
result = field.get(obj);
result = (E)field.get(obj);
} catch (IllegalAccessException e) {
logger.error("不可能抛出的异常{}", e.getMessage());
}
@@ -92,11 +94,11 @@ public class ReflectUtils {
/**
* 直接设置对象属性值, 无视private/protected修饰符, 不经过setter函数.
*/
public static void setFieldValue(final Object obj, final String fieldName, final Object value) {
public static <E> void setFieldValue(final Object obj, final String fieldName, final E value) {
Field field = getAccessibleField(obj, fieldName);
if (field == null) {
//throw new IllegalArgumentException("在 [" + obj.getClass() + "] 中,没有找到 [" + fieldName + "] 字段 ");
logger.warn("在 [" + obj.getClass() + "] 中,没有找到 [" + fieldName + "] 字段 ");
logger.debug("在 [" + obj.getClass() + "] 中,没有找到 [" + fieldName + "] 字段 ");
return;
}
try {
@@ -111,7 +113,8 @@ public class ReflectUtils {
* 用于一次性调用的情况否则应使用getAccessibleMethod()函数获得Method后反复调用.
* 同时匹配方法名+参数类型,
*/
public static Object invokeMethod(final Object obj, final String methodName, final Class<?>[] parameterTypes,
@SuppressWarnings("unchecked")
public static <E> E invokeMethod(final Object obj, final String methodName, final Class<?>[] parameterTypes,
final Object[] args) {
if (obj == null || methodName == null){
return null;
@@ -119,11 +122,11 @@ public class ReflectUtils {
Method method = getAccessibleMethod(obj, methodName, parameterTypes);
if (method == null) {
//throw new IllegalArgumentException("在 [" + obj.getClass() + "] 中,没有找到 [" + methodName + "] 方法 ");
logger.warn("在 [" + obj.getClass() + "] 中,没有找到 [" + methodName + "] 方法 ");
logger.debug("在 [" + obj.getClass() + "] 中,没有找到 [" + methodName + "] 方法 ");
return null;
}
try {
return method.invoke(obj, args);
return (E)method.invoke(obj, args);
} catch (Exception e) {
String msg = "method: "+method+", obj: "+obj+", args: "+args+"";
throw convertReflectionExceptionToUnchecked(msg, e);
@@ -135,12 +138,13 @@ public class ReflectUtils {
* 用于一次性调用的情况否则应使用getAccessibleMethodByName()函数获得Method后反复调用.
* 只匹配函数名,如果有多个同名函数调用第一个。
*/
public static Object invokeMethodByName(final Object obj, final String methodName, final Object[] args) {
@SuppressWarnings("unchecked")
public static <E> E invokeMethodByName(final Object obj, final String methodName, final Object[] args) {
Method method = getAccessibleMethodByName(obj, methodName, args.length);
if (method == null) {
// 如果为空不报错,直接返回空。
// throw new IllegalArgumentException("在 [" + obj.getClass() + "] 中,没有找到 [" + methodName + "] 方法 ");
logger.warn("在 [" + obj.getClass() + "] 中,没有找到 [" + methodName + "] 方法 ");
logger.debug("在 [" + obj.getClass() + "] 中,没有找到 [" + methodName + "] 方法 ");
return null;
}
try {
@@ -171,7 +175,7 @@ public class ReflectUtils {
}
}
}
return method.invoke(obj, args);
return (E)method.invoke(obj, args);
} catch (Exception e) {
String msg = "method: "+method+", obj: "+obj+", args: "+args+"";
throw convertReflectionExceptionToUnchecked(msg, e);
@@ -300,19 +304,19 @@ public class ReflectUtils {
Type genType = clazz.getGenericSuperclass();
if (!(genType instanceof ParameterizedType)) {
logger.warn(clazz.getSimpleName() + "'s superclass not ParameterizedType");
logger.debug(clazz.getSimpleName() + "'s superclass not ParameterizedType");
return Object.class;
}
Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
if (index >= params.length || index < 0) {
logger.warn("Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: "
logger.debug("Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: "
+ params.length);
return Object.class;
}
if (!(params[index] instanceof Class)) {
logger.warn(clazz.getSimpleName() + " not set the actual class on superclass generic parameter");
logger.debug(clazz.getSimpleName() + " not set the actual class on superclass generic parameter");
return Object.class;
}

View File

@@ -0,0 +1,24 @@
package com.jeesite.common.ueditor;
public class Encoder {
public static String toUnicode ( String input ) {
StringBuilder builder = new StringBuilder();
char[] chars = input.toCharArray();
for ( char ch : chars ) {
if ( ch < 256 ) {
builder.append( ch );
} else {
builder.append( "\\u" + Integer.toHexString( ch& 0xffff ) );
}
}
return builder.toString();
}
}

View File

@@ -0,0 +1,170 @@
package com.jeesite.common.ueditor;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import com.jeesite.common.web.http.ServletUtils;
public class PathFormat {
private static final String TIME = "time";
private static final String FULL_YEAR = "yyyy";
private static final String YEAR = "yy";
private static final String MONTH = "mm";
private static final String DAY = "dd";
private static final String HOUR = "hh";
private static final String MINUTE = "ii";
private static final String SECOND = "ss";
private static final String RAND = "rand";
private static final String USERID = "userid"; // ThinkGem 添加自定义变量获取当前用户ID
private static Date currentDate = null;
private static Pattern pattern = Pattern.compile( "\\{([^\\}]+)\\}", Pattern.CASE_INSENSITIVE );
public static String parse ( String input ) {
Matcher matcher = pattern.matcher(input);
PathFormat.currentDate = new Date();
StringBuffer sb = new StringBuffer();
while ( matcher.find() ) {
matcher.appendReplacement(sb, PathFormat.getString( matcher.group( 1 ) ) );
}
matcher.appendTail(sb);
return sb.toString();
}
/**
* 格式化路径, 把windows路径替换成标准路径
* @param input 待格式化的路径
* @return 格式化后的路径
*/
public static String format ( String input ) {
return input.replace( "\\", "/" );
}
public static String parse ( String input, String filename ) {
Matcher matcher = pattern.matcher(input);
String matchStr = null;
PathFormat.currentDate = new Date();
StringBuffer sb = new StringBuffer();
while ( matcher.find() ) {
matchStr = matcher.group( 1 );
if ( matchStr.indexOf( "filename" ) != -1 ) {
filename = filename.replace( "$", "\\$" ).replaceAll( "[\\/:*?\"<>|]", "" );
matcher.appendReplacement(sb, filename );
} else {
matcher.appendReplacement(sb, PathFormat.getString( matchStr ) );
}
}
matcher.appendTail(sb);
return sb.toString();
}
private static String getString ( String pattern ) {
pattern = pattern.toLowerCase();
// time 处理
if ( pattern.indexOf( PathFormat.TIME ) != -1 ) {
return PathFormat.getTimestamp();
} else if ( pattern.indexOf( PathFormat.FULL_YEAR ) != -1 ) {
return PathFormat.getFullYear();
} else if ( pattern.indexOf( PathFormat.YEAR ) != -1 ) {
return PathFormat.getYear();
} else if ( pattern.indexOf( PathFormat.MONTH ) != -1 ) {
return PathFormat.getMonth();
} else if ( pattern.indexOf( PathFormat.DAY ) != -1 ) {
return PathFormat.getDay();
} else if ( pattern.indexOf( PathFormat.HOUR ) != -1 ) {
return PathFormat.getHour();
} else if ( pattern.indexOf( PathFormat.MINUTE ) != -1 ) {
return PathFormat.getMinute();
} else if ( pattern.indexOf( PathFormat.SECOND ) != -1 ) {
return PathFormat.getSecond();
} else if ( pattern.indexOf( PathFormat.RAND ) != -1 ) {
return PathFormat.getRandom( pattern );
} else if ( pattern.indexOf( PathFormat.USERID ) != -1 ) {
return PathFormat.getUserid( pattern );
}
return pattern;
}
private static String getTimestamp () {
return System.currentTimeMillis() + "";
}
private static String getFullYear () {
return new SimpleDateFormat( "yyyy" ).format( PathFormat.currentDate );
}
private static String getYear () {
return new SimpleDateFormat( "yy" ).format( PathFormat.currentDate );
}
private static String getMonth () {
return new SimpleDateFormat( "MM" ).format( PathFormat.currentDate );
}
private static String getDay () {
return new SimpleDateFormat( "dd" ).format( PathFormat.currentDate );
}
private static String getHour () {
return new SimpleDateFormat( "HH" ).format( PathFormat.currentDate );
}
private static String getMinute () {
return new SimpleDateFormat( "mm" ).format( PathFormat.currentDate );
}
private static String getSecond () {
return new SimpleDateFormat( "ss" ).format( PathFormat.currentDate );
}
private static String getRandom ( String pattern ) {
int length = 0;
pattern = pattern.split( ":" )[ 1 ].trim();
length = Integer.parseInt( pattern );
return ( Math.random() + "" ).replace( ".", "" ).substring( 0, length );
}
private static String getUserid(String pattern) {
String userId = null;
HttpServletRequest request = ServletUtils.getRequest();
if (request != null){
userId = (String)request.getSession().getAttribute("userCode");
}
return StringUtils.isNotBlank(userId) ? userId : "0";
}
}

View File

@@ -0,0 +1,42 @@
package com.jeesite.common.ueditor.define;
import java.util.Map;
import java.util.HashMap;
/**
* 定义请求action类型
* @author hancong03@baidu.com
*/
@SuppressWarnings("serial")
public final class ActionMap {
// 获取配置请求
public static final int CONFIG = 0;
public static final int UPLOAD_IMAGE = 1;
public static final int UPLOAD_SCRAWL = 2;
public static final int UPLOAD_VIDEO = 3;
public static final int UPLOAD_FILE = 4;
public static final int CATCH_IMAGE = 5;
public static final int LIST_FILE = 6;
public static final int LIST_IMAGE = 7;
public static final Map<String, Integer> mapping;
static {
mapping = new HashMap<String, Integer>(){{
put( "config", ActionMap.CONFIG );
put( "uploadimage", ActionMap.UPLOAD_IMAGE );
put( "uploadscrawl", ActionMap.UPLOAD_SCRAWL );
put( "uploadvideo", ActionMap.UPLOAD_VIDEO );
put( "uploadfile", ActionMap.UPLOAD_FILE );
put( "catchimage", ActionMap.CATCH_IMAGE );
put( "listfile", ActionMap.LIST_FILE );
put( "listimage", ActionMap.LIST_IMAGE );
}};
}
public static int getType ( String key ) {
return ActionMap.mapping.get( key );
}
}

View File

@@ -0,0 +1,5 @@
package com.jeesite.common.ueditor.define;
public enum ActionState {
UNKNOW_ERROR
}

View File

@@ -0,0 +1,78 @@
package com.jeesite.common.ueditor.define;
import java.util.HashMap;
import java.util.Map;
public final class AppInfo {
public static final int SUCCESS = 0;
public static final int MAX_SIZE = 1;
public static final int PERMISSION_DENIED = 2;
public static final int FAILED_CREATE_FILE = 3;
public static final int IO_ERROR = 4;
public static final int NOT_MULTIPART_CONTENT = 5;
public static final int PARSE_REQUEST_ERROR = 6;
public static final int NOTFOUND_UPLOAD_DATA = 7;
public static final int NOT_ALLOW_FILE_TYPE = 8;
public static final int INVALID_ACTION = 101;
public static final int CONFIG_ERROR = 102;
public static final int PREVENT_HOST = 201;
public static final int CONNECTION_ERROR = 202;
public static final int REMOTE_FAIL = 203;
public static final int NOT_DIRECTORY = 301;
public static final int NOT_EXIST = 302;
public static final int ILLEGAL = 401;
@SuppressWarnings("serial")
public static Map<Integer, String> info = new HashMap<Integer, String>(){{
put( AppInfo.SUCCESS, "SUCCESS" );
// 无效的Action
put( AppInfo.INVALID_ACTION, "\u65E0\u6548\u7684Action" );
// 配置文件初始化失败
put( AppInfo.CONFIG_ERROR, "\u914D\u7F6E\u6587\u4EF6\u521D\u59CB\u5316\u5931\u8D25" );
// 抓取远程图片失败
put( AppInfo.REMOTE_FAIL, "\u6293\u53D6\u8FDC\u7A0B\u56FE\u7247\u5931\u8D25" );
// 被阻止的远程主机
put( AppInfo.PREVENT_HOST, "\u88AB\u963B\u6B62\u7684\u8FDC\u7A0B\u4E3B\u673A" );
// 远程连接出错
put( AppInfo.CONNECTION_ERROR, "\u8FDC\u7A0B\u8FDE\u63A5\u51FA\u9519" );
// "文件大小超出限制"
put( AppInfo.MAX_SIZE, "\u6587\u4ef6\u5927\u5c0f\u8d85\u51fa\u9650\u5236" );
// 权限不足, 多指写权限
put( AppInfo.PERMISSION_DENIED, "\u6743\u9650\u4E0D\u8DB3" );
// 创建文件失败
put( AppInfo.FAILED_CREATE_FILE, "\u521B\u5EFA\u6587\u4EF6\u5931\u8D25" );
// IO错误
put( AppInfo.IO_ERROR, "IO\u9519\u8BEF" );
// 上传表单不是multipart/form-data类型
put( AppInfo.NOT_MULTIPART_CONTENT, "\u4E0A\u4F20\u8868\u5355\u4E0D\u662Fmultipart/form-data\u7C7B\u578B" );
// 解析上传表单错误
put( AppInfo.PARSE_REQUEST_ERROR, "\u89E3\u6790\u4E0A\u4F20\u8868\u5355\u9519\u8BEF" );
// 未找到上传数据
put( AppInfo.NOTFOUND_UPLOAD_DATA, "\u672A\u627E\u5230\u4E0A\u4F20\u6570\u636E" );
// 不允许的文件类型
put( AppInfo.NOT_ALLOW_FILE_TYPE, "\u4E0D\u5141\u8BB8\u7684\u6587\u4EF6\u7C7B\u578B" );
// 指定路径不是目录
put( AppInfo.NOT_DIRECTORY, "\u6307\u5B9A\u8DEF\u5F84\u4E0D\u662F\u76EE\u5F55" );
// 指定路径并不存在
put( AppInfo.NOT_EXIST, "\u6307\u5B9A\u8DEF\u5F84\u5E76\u4E0D\u5B58\u5728" );
// callback参数名不合法
put( AppInfo.ILLEGAL, "Callback\u53C2\u6570\u540D\u4E0D\u5408\u6CD5" );
}};
public static String getStateInfo ( int key ) {
return AppInfo.info.get( key );
}
}

View File

@@ -0,0 +1,92 @@
package com.jeesite.common.ueditor.define;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import com.jeesite.common.ueditor.Encoder;
public class BaseState implements State {
private boolean state = false;
private String info = null;
private Map<String, String> infoMap = new HashMap<String, String>();
public BaseState () {
this.state = true;
}
public BaseState ( boolean state ) {
this.setState( state );
}
public BaseState ( boolean state, String info ) {
this.setState( state );
this.info = info;
}
public BaseState ( boolean state, int infoCode ) {
this.setState( state );
this.info = AppInfo.getStateInfo( infoCode );
}
@Override
public boolean isSuccess () {
return this.state;
}
public void setState ( boolean state ) {
this.state = state;
}
public void setInfo ( String info ) {
this.info = info;
}
public void setInfo ( int infoCode ) {
this.info = AppInfo.getStateInfo( infoCode );
}
@Override
public String toJSONString() {
return this.toString();
}
@Override
public String toString () {
String key = null;
String stateVal = this.isSuccess() ? AppInfo.getStateInfo( AppInfo.SUCCESS ) : this.info;
StringBuilder builder = new StringBuilder();
builder.append( "{\"state\": \"" + stateVal + "\"" );
Iterator<String> iterator = this.infoMap.keySet().iterator();
while ( iterator.hasNext() ) {
key = iterator.next();
builder.append( ",\"" + key + "\": \"" + this.infoMap.get(key) + "\"" );
}
builder.append( "}" );
return Encoder.toUnicode( builder.toString() );
}
@Override
public void putInfo(String name, String val) {
this.infoMap.put(name, val);
}
@Override
public void putInfo(String name, long val) {
this.putInfo(name, val+"");
}
}

View File

@@ -0,0 +1,32 @@
package com.jeesite.common.ueditor.define;
import java.util.HashMap;
import java.util.Map;
public class FileType {
public static final String JPG = "JPG";
@SuppressWarnings("serial")
private static final Map<String, String> types = new HashMap<String, String>(){{
put( FileType.JPG, ".jpg" );
}};
public static String getSuffix ( String key ) {
return FileType.types.get( key );
}
/**
* 根据给定的文件名,获取其后缀信息
* @param filename
* @return
*/
public static String getSuffixByFilename ( String filename ) {
return filename.substring( filename.lastIndexOf( "." ) ).toLowerCase();
}
}

View File

@@ -0,0 +1,21 @@
package com.jeesite.common.ueditor.define;
import java.util.HashMap;
import java.util.Map;
public class MIMEType {
@SuppressWarnings("serial")
public static final Map<String, String> types = new HashMap<String, String>(){{
put( "image/gif", ".gif" );
put( "image/jpeg", ".jpg" );
put( "image/jpg", ".jpg" );
put( "image/png", ".png" );
put( "image/bmp", ".bmp" );
}};
public static String getSuffix ( String mime ) {
return MIMEType.types.get( mime );
}
}

View File

@@ -0,0 +1,111 @@
package com.jeesite.common.ueditor.define;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import com.jeesite.common.ueditor.Encoder;
/**
* 多状态集合状态
* 其包含了多个状态的集合, 其本身自己也是一个状态
* @author hancong03@baidu.com
*/
public class MultiState implements State {
private boolean state = false;
private String info = null;
private Map<String, Long> intMap = new HashMap<String, Long>();
private Map<String, String> infoMap = new HashMap<String, String>();
private List<String> stateList = new ArrayList<String>();
public MultiState ( boolean state ) {
this.state = state;
}
public MultiState ( boolean state, String info ) {
this.state = state;
this.info = info;
}
public MultiState ( boolean state, int infoKey ) {
this.state = state;
this.info = AppInfo.getStateInfo( infoKey );
}
@Override
public boolean isSuccess() {
return this.state;
}
public void addState ( State state ) {
stateList.add( state.toJSONString() );
}
/**
* 该方法调用无效果
*/
@Override
public void putInfo(String name, String val) {
this.infoMap.put(name, val);
}
@Override
public String toJSONString() {
String stateVal = this.isSuccess() ? AppInfo.getStateInfo( AppInfo.SUCCESS ) : this.info;
StringBuilder builder = new StringBuilder();
builder.append( "{\"state\": \"" + stateVal + "\"" );
// 数字转换
Iterator<String> iterator = this.intMap.keySet().iterator();
while ( iterator.hasNext() ) {
stateVal = iterator.next();
builder.append( ",\""+ stateVal +"\": " + this.intMap.get( stateVal ) );
}
iterator = this.infoMap.keySet().iterator();
while ( iterator.hasNext() ) {
stateVal = iterator.next();
builder.append( ",\""+ stateVal +"\": \"" + this.infoMap.get( stateVal ) + "\"" );
}
builder.append( ", list: [" );
iterator = this.stateList.iterator();
while ( iterator.hasNext() ) {
builder.append( iterator.next() + "," );
}
if ( this.stateList.size() > 0 ) {
builder.deleteCharAt( builder.length() - 1 );
}
builder.append( " ]}" );
return Encoder.toUnicode( builder.toString() );
}
@Override
public void putInfo(String name, long val) {
this.intMap.put( name, val );
}
}

View File

@@ -0,0 +1,17 @@
package com.jeesite.common.ueditor.define;
/**
* 处理状态接口
* @author hancong03@baidu.com
*/
public interface State {
public boolean isSuccess ();
public void putInfo( String name, String val );
public void putInfo ( String name, long val );
public String toJSONString ();
}

View File

@@ -0,0 +1,124 @@
package com.jeesite.common.ueditor.hunter;
import java.io.File;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.io.FileUtils;
import com.jeesite.common.ueditor.PathFormat;
import com.jeesite.common.ueditor.define.AppInfo;
import com.jeesite.common.ueditor.define.BaseState;
import com.jeesite.common.ueditor.define.MultiState;
import com.jeesite.common.ueditor.define.State;
public class FileManager {
public static final String USERFILES_BASE_URL = "/userfiles/";
private String dir = null;
private String rootPath = null;
private String[] allowFiles = null;
private int count = 0;
public FileManager ( Map<String, Object> conf ) {
this.rootPath = (String)conf.get( "rootPath" );
this.dir = this.rootPath + (String)conf.get( "dir" );
this.allowFiles = this.getAllowFiles( conf.get("allowFiles") );
this.count = (Integer)conf.get( "count" );
}
public State listFile (HttpServletRequest request, int index ) {
// File dir = new File( this.dir );
File dir = new File( PathFormat.parse(this.dir) ); // ThinkGem 路径中有变量时变量不转化问题
State state = null;
if ( !dir.exists() ) {
return new BaseState( false, AppInfo.NOT_EXIST );
}
if ( !dir.isDirectory() ) {
return new BaseState( false, AppInfo.NOT_DIRECTORY );
}
Collection<File> list = FileUtils.listFiles( dir, this.allowFiles, true );
if ( index < 0 || index > list.size() ) {
state = new MultiState( true );
} else {
Object[] fileList = Arrays.copyOfRange( list.toArray(), index, index + this.count );
state = this.getState(request, fileList );
}
state.putInfo( "start", index );
state.putInfo( "total", list.size() );
return state;
}
private State getState (HttpServletRequest request, Object[] files ) {
MultiState state = new MultiState( true );
BaseState fileState = null;
File file = null;
for ( Object obj : files ) {
if ( obj == null ) {
break;
}
file = (File)obj;
fileState = new BaseState( true );
//fileState.putInfo( "url", PathFormat.format( this.getPath( file ) ) );
// ThinkGem 将绝对路径转换为虚拟路径
String url = PathFormat.format( this.getPath( file ) );
int index = url.indexOf(USERFILES_BASE_URL);
if(index > 0) {
url = url.substring(index + USERFILES_BASE_URL.length());
}
fileState.putInfo( "url", request.getContextPath() + USERFILES_BASE_URL + url );
state.addState( fileState );
}
return state;
}
private String getPath ( File file ) {
String path = file.getAbsolutePath();
return path.replace( this.rootPath, "/" );
}
private String[] getAllowFiles ( Object fileExt ) {
String[] exts = null;
String ext = null;
if ( fileExt == null ) {
return new String[ 0 ];
}
exts = (String[])fileExt;
for ( int i = 0, len = exts.length; i < len; i++ ) {
ext = exts[ i ];
exts[ i ] = ext.replace( ".", "" );
}
return exts;
}
}

View File

@@ -0,0 +1,145 @@
package com.jeesite.common.ueditor.hunter;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import com.jeesite.common.ueditor.PathFormat;
import com.jeesite.common.ueditor.define.AppInfo;
import com.jeesite.common.ueditor.define.BaseState;
import com.jeesite.common.ueditor.define.MIMEType;
import com.jeesite.common.ueditor.define.MultiState;
import com.jeesite.common.ueditor.define.State;
import com.jeesite.common.ueditor.upload.StorageManager;
/**
* 图片抓取器
* @author hancong03@baidu.com
*/
public class ImageHunter {
private HttpServletRequest request = null;
private String filename = null;
private String savePath = null;
private String rootPath = null;
private List<String> allowTypes = null;
private long maxSize = -1;
private List<String> filters = null;
public ImageHunter (HttpServletRequest request, Map<String, Object> conf ) {
this.request = request;
this.filename = (String)conf.get( "filename" );
this.savePath = (String)conf.get( "savePath" );
this.rootPath = (String)conf.get( "rootPath" );
this.maxSize = (Long)conf.get( "maxSize" );
this.allowTypes = Arrays.asList( (String[])conf.get( "allowFiles" ) );
this.filters = Arrays.asList( (String[])conf.get( "filter" ) );
}
public State capture ( String[] list ) {
MultiState state = new MultiState( true );
for ( String source : list ) {
state.addState( captureRemoteData( source ) );
}
return state;
}
public State captureRemoteData ( String urlStr ) {
HttpURLConnection connection = null;
URL url = null;
String suffix = null;
try {
url = new URL( urlStr );
if ( !validHost( url.getHost() ) ) {
return new BaseState( false, AppInfo.PREVENT_HOST );
}
connection = (HttpURLConnection) url.openConnection();
connection.setInstanceFollowRedirects( true );
connection.setUseCaches( true );
if ( !validContentState( connection.getResponseCode() ) ) {
return new BaseState( false, AppInfo.CONNECTION_ERROR );
}
suffix = MIMEType.getSuffix( connection.getContentType() );
if ( !validFileType( suffix ) ) {
return new BaseState( false, AppInfo.NOT_ALLOW_FILE_TYPE );
}
if ( !validFileSize( connection.getContentLength() ) ) {
return new BaseState( false, AppInfo.MAX_SIZE );
}
String savePath = this.getPath( this.savePath, this.filename, suffix );
String physicalPath = this.rootPath + savePath;
State state = StorageManager.saveFileByInputStream( connection.getInputStream(), physicalPath );
if ( state.isSuccess() ) {
state.putInfo( "url", request.getContextPath() + PathFormat.format( savePath ) );
state.putInfo( "source", urlStr );
}
return state;
} catch ( Exception e ) {
return new BaseState( false, AppInfo.REMOTE_FAIL );
}
}
private String getPath ( String savePath, String filename, String suffix ) {
return PathFormat.parse( savePath + suffix, filename );
}
private boolean validHost ( String hostname ) {
try {
InetAddress ip = InetAddress.getByName(hostname);
if (ip.isSiteLocalAddress()) {
return false;
}
} catch (UnknownHostException e) {
return false;
}
return !filters.contains( hostname );
}
private boolean validContentState ( int code ) {
return HttpURLConnection.HTTP_OK == code;
}
private boolean validFileType ( String type ) {
return this.allowTypes.contains( type );
}
private boolean validFileSize ( int size ) {
return size < this.maxSize;
}
}

View File

@@ -0,0 +1,55 @@
package com.jeesite.common.ueditor.upload;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.codec.binary.Base64;
import com.jeesite.common.ueditor.PathFormat;
import com.jeesite.common.ueditor.define.AppInfo;
import com.jeesite.common.ueditor.define.BaseState;
import com.jeesite.common.ueditor.define.FileType;
import com.jeesite.common.ueditor.define.State;
public final class Base64Uploader {
public static State save(HttpServletRequest request, String content, Map<String, Object> conf) {
byte[] data = decode(content);
long maxSize = ((Long) conf.get("maxSize")).longValue();
if (!validSize(data, maxSize)) {
return new BaseState(false, AppInfo.MAX_SIZE);
}
String suffix = FileType.getSuffix("JPG");
String savePath = PathFormat.parse((String) conf.get("savePath"),
(String) conf.get("filename"));
savePath = savePath + suffix;
String physicalPath = (String) conf.get("rootPath") + savePath;
State storageState = StorageManager.saveBinaryFile(data, physicalPath);
if (storageState.isSuccess()) {
String ctx = request.getContextPath(); // ThinkGem 修正上传图片后返回无contextpath问题
storageState.putInfo("url", ctx + PathFormat.format(savePath));
storageState.putInfo("type", suffix);
storageState.putInfo("original", "");
}
return storageState;
}
private static byte[] decode(String content) {
return Base64.decodeBase64(content);
}
private static boolean validSize(byte[] data, long length) {
return data.length <= length;
}
}

View File

@@ -0,0 +1,178 @@
package com.jeesite.common.ueditor.upload;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import com.jeesite.common.io.FileUtils;
import com.jeesite.common.lang.StringUtils;
import com.jeesite.common.media.VideoUtils;
import com.jeesite.common.ueditor.PathFormat;
import com.jeesite.common.ueditor.define.ActionMap;
import com.jeesite.common.ueditor.define.AppInfo;
import com.jeesite.common.ueditor.define.BaseState;
import com.jeesite.common.ueditor.define.FileType;
import com.jeesite.common.ueditor.define.State;
import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.Thumbnails.Builder;
public class BinaryUploader {
public static final State save(HttpServletRequest request,
Map<String, Object> conf) {
FileItemStream fileStream = null; // 原始上传
MultipartFile fileStream2 = null; // Spring MVC 上传
boolean isAjaxUpload = request.getHeader( "X_Requested_With" ) != null;
if (!ServletFileUpload.isMultipartContent(request)) {
return new BaseState(false, AppInfo.NOT_MULTIPART_CONTENT);
}
ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory());
if ( isAjaxUpload ) {
upload.setHeaderEncoding( "UTF-8" );
}
try {
FileItemIterator iterator = upload.getItemIterator(request);
while (iterator.hasNext()) {
fileStream = iterator.next();
if (!fileStream.isFormField()) {
break;
}
fileStream = null;
}
if (fileStream == null) {
// 原始上传无文件则检查是否是Spring MVC上传 ThinkGem
MultipartFile file = null;
if (request instanceof MultipartHttpServletRequest){
MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
Iterator<String> it = multiRequest.getFileNames();
while (it.hasNext()) {
file = multiRequest.getFile(it.next());
break;
}
}
if (file != null && !file.isEmpty() && file.getOriginalFilename() != null) {
fileStream2 = file;
}
}
if (fileStream == null && fileStream2 == null) {
return new BaseState(false, AppInfo.NOTFOUND_UPLOAD_DATA);
}
String savePath = (String) conf.get("savePath");
String originFileName = fileStream != null ? fileStream.getName() : fileStream2.getOriginalFilename();
String suffix = FileType.getSuffixByFilename(originFileName);
originFileName = originFileName.substring(0,
originFileName.length() - suffix.length());
savePath = savePath + suffix;
long maxSize = ((Long) conf.get("maxSize")).longValue();
if (!validType(suffix, (String[]) conf.get("allowFiles"))) {
return new BaseState(false, AppInfo.NOT_ALLOW_FILE_TYPE);
}
savePath = PathFormat.parse(savePath, originFileName);
String physicalPath = FileUtils.path((String) conf.get("rootPath") + savePath);
InputStream is = fileStream != null ? fileStream.openStream() : fileStream2.getInputStream();
State storageState = StorageManager.saveFileByInputStream(is, physicalPath, maxSize);
is.close();
if (storageState.isSuccess()) {
int actionCode = ((Integer) conf.get("actionCode")).intValue();
String ctx = request.getContextPath(); // ThinkGem 修正上传图片后返回无contextpath问题
// 上传图片后,进行图片压缩
if (actionCode == ActionMap.UPLOAD_IMAGE){
// 如果开启了压缩图片
if ((Boolean)conf.get("imageCompressEnable")){
Integer width = (Integer)conf.get("imageCompressBorder");
// 过滤掉gif图片因为gif图片转换后会出现黑色背景的情况gif基本也没有比较大的图片
if (StringUtils.inString(FileUtils.getFileExtension(physicalPath),
"png","jpg","jpeg","bmp","ico")){
BufferedImage bufferedImage = ImageIO.read(new File(physicalPath));
Builder<BufferedImage> file = Thumbnails.of(bufferedImage);
if (bufferedImage != null){
if (bufferedImage.getWidth() <= width){
file.width(bufferedImage.getWidth());
}else{
file.width(width);
}
file.toFile(physicalPath);
}
}
}
}
// 上传成功后 转换格式 按照新的视频格式 返回前台 ThinkGem
else if(actionCode == ActionMap.UPLOAD_VIDEO){
final VideoUtils v = new VideoUtils(physicalPath);
// 先截图
if (v.cutPic()){
// 开启进程,在转换视频文件
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(5000);
v.convert();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
storageState.putInfo("url", ctx + PathFormat.format(savePath) + "." + v.getOutputFileExtension());
storageState.putInfo("type", "." + v.getOutputFileExtension());
storageState.putInfo("original", originFileName +"."+ v.getInputFileExtension());
return storageState;
}
}
storageState.putInfo("url", ctx + PathFormat.format(savePath));
storageState.putInfo("type", suffix);
storageState.putInfo("original", originFileName + suffix);
}
return storageState;
} catch (FileUploadException e) {
return new BaseState(false, AppInfo.PARSE_REQUEST_ERROR);
} catch (IOException e) {
return new BaseState(false, AppInfo.IO_ERROR);
}
}
private static boolean validType(String type, String[] allowTypes) {
List<String> list = Arrays.asList(allowTypes);
return list.contains(type);
}
}

View File

@@ -0,0 +1,213 @@
package com.jeesite.common.ueditor.upload;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import com.jeesite.common.idgen.IdGenerate;
import com.jeesite.common.io.FileUtils;
import com.jeesite.common.io.PropertiesUtils;
import com.jeesite.common.lang.StringUtils;
import com.jeesite.common.ueditor.define.AppInfo;
import com.jeesite.common.ueditor.define.BaseState;
import com.jeesite.common.ueditor.define.State;
public class StorageManager {
public static final int BUFFER_SIZE = 8192;
public StorageManager() {
}
public static State saveBinaryFile(byte[] data, String path) {
File file = new File(path);
State state = valid(file);
if (!state.isSuccess()) {
return state;
}
BufferedOutputStream bos = null;
try {
bos = new BufferedOutputStream(new FileOutputStream(file));
bos.write(data);
} catch (IOException ioe) {
return new BaseState(false, AppInfo.IO_ERROR);
}finally {
if (bos != null){
try {
bos.flush();
bos.close();
} catch (IOException e) {
;
}
}
}
// 验证允许的上传的文件类型(如果没有设置则不验证,默认不设置)
String allowContentTypes = PropertiesUtils.getInstance()
.getProperty("file.allowContentTypes");
if(StringUtils.isNotBlank(allowContentTypes)){
String rct = FileUtils.getRealContentType(file);
if (!StringUtils.inString(rct, allowContentTypes.split(","))){
file.delete();
return new BaseState(false, AppInfo.NOT_ALLOW_FILE_TYPE);
}
}
state = new BaseState(true, file.getAbsolutePath());
state.putInfo( "size", data.length );
state.putInfo( "title", file.getName() );
return state;
}
public static State saveFileByInputStream(InputStream is, String path, long maxSize) {
State state = null;
File tmpFile = getTmpFile();
byte[] dataBuf = new byte[ 2048 ];
BufferedInputStream bis = new BufferedInputStream(is, StorageManager.BUFFER_SIZE);
BufferedOutputStream bos = null;
try {
try{
bos = new BufferedOutputStream(
new FileOutputStream(tmpFile), StorageManager.BUFFER_SIZE);
int count = 0;
while ((count = bis.read(dataBuf)) != -1) {
bos.write(dataBuf, 0, count);
}
}finally {
if (bos != null){
bos.flush();
bos.close();
}
}
if (tmpFile.length() > maxSize) {
tmpFile.delete();
return new BaseState(false, AppInfo.MAX_SIZE);
}
// 验证允许的上传的文件类型(如果没有设置则不验证,默认不设置)
String allowContentTypes = PropertiesUtils.getInstance()
.getProperty("file.allowContentTypes");
if(StringUtils.isNotBlank(allowContentTypes)){
String rct = FileUtils.getRealContentType(tmpFile);
if (!StringUtils.inString(rct, allowContentTypes.split(","))){
tmpFile.delete();
return new BaseState(false, AppInfo.NOT_ALLOW_FILE_TYPE);
}
}
state = saveTmpFile(tmpFile, path);
if (!state.isSuccess()) {
tmpFile.delete();
}
return state;
} catch (IOException e) {
;
}finally {
if (bis != null){
try {
bis.close();
} catch (IOException e) {
;
}
}
}
return new BaseState(false, AppInfo.IO_ERROR);
}
public static State saveFileByInputStream(InputStream is, String path) {
State state = null;
File tmpFile = getTmpFile();
byte[] dataBuf = new byte[ 2048 ];
BufferedInputStream bis = new BufferedInputStream(is, StorageManager.BUFFER_SIZE);
try {
BufferedOutputStream bos = null;
try{
bos = new BufferedOutputStream(new FileOutputStream(tmpFile),
StorageManager.BUFFER_SIZE);
int count = 0;
while ((count = bis.read(dataBuf)) != -1) {
bos.write(dataBuf, 0, count);
}
}finally {
if (bos != null){
bos.flush();
bos.close();
}
}
state = saveTmpFile(tmpFile, path);
if (!state.isSuccess()) {
tmpFile.delete();
}
return state;
} catch (IOException e) {
;
}finally {
if (bis != null){
try {
bis.close();
} catch (IOException e) {
;
}
}
}
return new BaseState(false, AppInfo.IO_ERROR);
}
private static File getTmpFile() {
// File tmpDir = FileUtils.getTempDirectory();
File tmpDir = new File(System.getProperty("java.io.tmpdir"));
// String tmpFileName = (Math.random() * 10000 + "").replace(".", "");
// return new File(tmpDir, tmpFileName);
return new File(tmpDir, IdGenerate.randomBase62(10));
}
private static State saveTmpFile(File tmpFile, String path) {
State state = null;
File targetFile = new File(path);
if (targetFile.canWrite()) {
return new BaseState(false, AppInfo.PERMISSION_DENIED);
}
try {
FileUtils.moveFile(tmpFile, targetFile);
} catch (IOException e) {
return new BaseState(false, AppInfo.IO_ERROR);
}
state = new BaseState(true);
state.putInfo( "size", targetFile.length() );
state.putInfo( "title", targetFile.getName() );
return state;
}
private static State valid(File file) {
File parentPath = file.getParentFile();
if ((!parentPath.exists()) && (!parentPath.mkdirs())) {
return new BaseState(false, AppInfo.FAILED_CREATE_FILE);
}
if (!parentPath.canWrite()) {
return new BaseState(false, AppInfo.PERMISSION_DENIED);
}
return new BaseState(true);
}
}

View File

@@ -0,0 +1,32 @@
package com.jeesite.common.ueditor.upload;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import com.jeesite.common.ueditor.define.State;
public class Uploader {
private HttpServletRequest request = null;
private Map<String, Object> conf = null;
public Uploader(HttpServletRequest request, Map<String, Object> conf) {
this.request = request;
this.conf = conf;
}
public final State doExec() {
String filedName = (String) this.conf.get("fieldName");
State state = null;
if ("true".equals(this.conf.get("isBase64"))) {
state = Base64Uploader.save(this.request, this.request.getParameter(filedName),
this.conf);
} else {
state = BinaryUploader.save(this.request, this.conf);
}
return state;
}
}

View File

@@ -585,18 +585,18 @@ public class ExcelExport implements Closeable{
return this;
}
/**
* 清理临时文件
* @deprecated see close()
*/
public ExcelExport dispose(){
try {
this.close();
} catch (Exception e) {
e.printStackTrace();
}
return this;
}
// /**
// * 清理临时文件
// * @deprecated see close()
// */
// public ExcelExport dispose(){
// try {
// this.close();
// } catch (Exception e) {
// e.printStackTrace();
// }
// return this;
// }
@Override
public void close() {

View File

@@ -78,6 +78,21 @@ public class ServletUtils {
return response;
}
/**
* 支持AJAX的页面跳转
*/
public static void redirectUrl(HttpServletRequest request, HttpServletResponse response, String url){
try {
if (ServletUtils.isAjaxRequest(request)){
request.getRequestDispatcher(url).forward(request, response); // AJAX不支持Redirect改用Forward
}else{
response.sendRedirect(request.getContextPath() + url);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 是否是Ajax异步请求
* @param request
@@ -173,9 +188,10 @@ public class ServletUtils {
resultMap.put("data", data);
}
}
HttpServletRequest request = ServletUtils.getRequest();
HttpServletRequest request = getRequest();
String uri = request.getRequestURI();
if (StringUtils.endsWithIgnoreCase(uri, ".xml")){
if (StringUtils.endsWithIgnoreCase(uri, ".xml") || StringUtils
.equalsIgnoreCase(request.getParameter("__ajax"), "xml")){
return XmlMapper.toXml(resultMap);
}else{
String functionName = request.getParameter("__callback");
@@ -202,7 +218,7 @@ public class ServletUtils {
/**
* 直接将结果JSON字符串渲染到客户端支持JsonP请求参数加__callback=回调函数名)
* @param response 渲染对象:{result:'true',message:'',data:{}}
* @param result Global.TRUE or Globle.False
* @param result 结果标识:Global.TRUE or Globle.False
* @param message 执行消息
* @param data 消息数据
* @return null
@@ -212,16 +228,18 @@ public class ServletUtils {
}
/**
* 将对象转换为JSON字符串渲染到客户端支持JsonP请求参数加__callback=回调函数名)
* 将对象转换为JSON、XML、JSONP字符串渲染到客户端JsonP请求参数加__callback=回调函数名)
* @param request 请求对象用来得到输出格式的指令JSON、XML、JSONP
* @param response 渲染对象
* @param object 待转换JSON并渲染的对象
* @return null
*/
public static String renderObject(HttpServletResponse response, Object object) {
HttpServletRequest request = ServletUtils.getRequest();
HttpServletRequest request = getRequest();
String uri = request.getRequestURI();
if (StringUtils.endsWithIgnoreCase(uri, ".xml")){
return XmlMapper.toXml(object);
if (StringUtils.endsWithIgnoreCase(uri, ".xml") || StringUtils
.equalsIgnoreCase(request.getParameter("__ajax"), "xml")){
return renderString(response, XmlMapper.toXml(object));
}else{
String functionName = request.getParameter("__callback");
if (StringUtils.isNotBlank(functionName)){
@@ -250,8 +268,18 @@ public class ServletUtils {
*/
public static String renderString(HttpServletResponse response, String string, String type) {
try {
// response.reset(); // 注释掉否则以前设置的Header会被清理掉如ajax登录设置记住我Cookie
response.setContentType(type == null ? "application/json" : type);
// response.reset(); // 注释掉否则以前设置的Header会被清理掉如ajax登录设置记住我Cookie信息
if (type == null){
if ((StringUtils.startsWith(string, "{") && StringUtils.endsWith(string, "}"))
|| (StringUtils.startsWith(string, "[") && StringUtils.endsWith(string, "]"))){
type = "application/json";
}else if (StringUtils.startsWith(string, "<") && StringUtils.endsWith(string, ">")){
type = "application/xml";
}else{
type = "text/html";
}
}
response.setContentType(type);
response.setCharacterEncoding("utf-8");
response.getWriter().print(string);
} catch (IOException e) {

View File

@@ -0,0 +1,87 @@
text/html html htm shtml
text/css css
text/xml xml
image/gif gif
image/jpeg jpeg jpg
application/javascript js
application/atom+xml atom
application/rss+xml rss
text/mathml mml
text/plain txt
text/vnd.sun.j2me.app-descriptor jad
text/vnd.wap.wml wml
text/x-component htc
image/png png
image/tiff tif tiff
image/vnd.wap.wbmp wbmp
image/x-icon ico
image/x-jng jng
image/x-ms-bmp bmp
image/svg+xml svg svgz
image/webp webp
application/font-woff woff
application/java-archive jar war ear
application/json json
application/mac-binhex40 hqx
application/msword doc
application/pdf pdf
application/postscript ps eps ai
application/rtf rtf
application/vnd.apple.mpegurl m3u8
application/vnd.ms-excel xls
application/vnd.ms-fontobject eot
application/vnd.ms-powerpoint ppt
application/vnd.wap.wmlc wmlc
application/vnd.google-earth.kml+xml kml
application/vnd.google-earth.kmz kmz
application/x-7z-compressed 7z
application/x-cocoa cco
application/x-java-archive-diff jardiff
application/x-java-jnlp-file jnlp
application/x-makeself run
application/x-perl pl pm
application/x-pilot prc pdb
application/x-rar-compressed rar
application/x-redhat-package-manager rpm
application/x-sea sea
application/x-shockwave-flash swf
application/x-stuffit sit
application/x-tcl tcl tk
application/x-x509-ca-cert der pem crt
application/x-xpinstall xpi
application/xhtml+xml xhtml
application/xspf+xml xspf
application/zip zip
application/octet-stream bin exe dll
application/octet-stream deb
application/octet-stream dmg
application/octet-stream iso img
application/octet-stream msi msp msm
application/vnd.openxmlformats-officedocument.wordprocessingml.document docx
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx
application/vnd.openxmlformats-officedocument.presentationml.presentation pptx
audio/midi mid midi kar
audio/mpeg mp3
audio/ogg ogg
audio/x-m4a m4a
audio/x-realaudio ra
video/3gpp 3gpp 3gp
video/mp2t ts
video/mp4 mp4
video/mpeg mpeg mpg
video/quicktime mov
video/webm webm
video/x-flv flv
video/x-m4v m4v
video/x-mng mng
video/x-ms-asf asx asf
video/x-ms-wmv wmv
video/x-msvideo avi

View File

@@ -1,4 +1,4 @@
/*!
/*
* AdminLTE v2.4.0
* Author: Almsaeed Studio
* Website: Almsaeed Studio <https://adminlte.io>
@@ -198,7 +198,7 @@ a:focus {
margin-left: 230px;
border: none;
min-height: 50px;
border-radius: 0;
/*border-radius: 0;*/
}
.layout-top-nav .main-header .navbar {
margin-left: 0;
@@ -727,7 +727,7 @@ a:focus {
border-left-width: 0;
}
.nav-tabs.control-sidebar-tabs > li > a {
border-radius: 0;
/*border-radius: 0;*/
}
.nav-tabs.control-sidebar-tabs > li > a,
.nav-tabs.control-sidebar-tabs > li > a:hover {
@@ -1233,7 +1233,7 @@ a:focus {
* ---------------
*/
.form-control {
border-radius: 0;
/*border-radius: 0;*/
box-shadow: none;
border-color: #d2d6de;
}
@@ -1287,14 +1287,14 @@ a:focus {
}
/* Input group */
.input-group .input-group-addon {
border-radius: 0;
/*border-radius: 0;*/
border-color: #d2d6de;
background-color: #fff;
}
/* button groups */
.btn-group-vertical .btn.btn-flat:first-of-type,
.btn-group-vertical .btn.btn-flat:last-of-type {
border-radius: 0;
/*border-radius: 0;*/
}
.icheck > label {
padding-left: 0;
@@ -2026,7 +2026,7 @@ a:focus {
}
.info-box .progress,
.info-box .progress .progress-bar {
border-radius: 0;
/*border-radius: 0;*/
}
.info-box .progress .progress-bar {
background: #fff;
@@ -2177,7 +2177,7 @@ a:focus {
* -----------------
*/
.btn {
border-radius: 3px;
border-radius: 4px;
-webkit-box-shadow: none;
box-shadow: none;
border: 1px solid transparent;
@@ -2186,7 +2186,7 @@ a:focus {
text-transform: uppercase;
}
.btn.btn-flat {
border-radius: 0;
/*border-radius: 0;*/
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
@@ -2421,7 +2421,7 @@ a:focus {
}
/* NAV PILLS */
.nav-pills > li > a {
border-radius: 0;
/*border-radius: 0;*/
border-top: 3px solid transparent;
color: #444;
}
@@ -2440,7 +2440,7 @@ a:focus {
}
/* NAV STACKED */
.nav-stacked > li > a {
border-radius: 0;
/*border-radius: 0;*/
border-top: 0;
border-left: 3px solid transparent;
color: #444;
@@ -2482,7 +2482,7 @@ a:focus {
}
.nav-tabs-custom > .nav-tabs > li > a {
color: #444;
border-radius: 0;
/*border-radius: 0;*/
}
.nav-tabs-custom > .nav-tabs > li > a.text-muted {
color: #999;
@@ -2630,7 +2630,7 @@ a:focus {
.product-list-in-box > .item {
-webkit-box-shadow: none;
box-shadow: none;
border-radius: 0;
/*border-radius: 0;*/
border-bottom: 1px solid #f4f4f4;
}
.product-list-in-box > .item:last-of-type {
@@ -2967,7 +2967,7 @@ table.text-center th {
background: rgba(0, 0, 0, 0.3);
}
.modal-content {
border-radius: 0;
/*border-radius: 0;*/
-webkit-box-shadow: 0 2px 3px rgba(0, 0, 0, 0.125);
box-shadow: 0 2px 3px rgba(0, 0, 0, 0.125);
border: 0;
@@ -4232,7 +4232,7 @@ table.text-center th {
.select2-container--default .select2-selection--single,
.select2-selection .select2-selection--single {
border: 1px solid #d2d6de;
border-radius: 0;
/*border-radius: 0;*/
padding: 6px 12px;
height: 34px;
}
@@ -4241,7 +4241,7 @@ table.text-center th {
}
.select2-dropdown {
border: 1px solid #d2d6de;
border-radius: 0;
/*border-radius: 0;*/
}
.select2-container--default .select2-results__option--highlighted[aria-selected] {
background-color: #3c8dbc;
@@ -4293,7 +4293,7 @@ table.text-center th {
}
.select2-container--default .select2-selection--multiple {
border: 1px solid #d2d6de;
border-radius: 0;
/*border-radius: 0;*/
}
.select2-container--default .select2-selection--multiple:focus {
border-color: #3c8dbc;
@@ -4662,7 +4662,7 @@ table.text-center th {
.list-group-unbordered > .list-group-item {
border-left: 0;
border-right: 0;
border-radius: 0;
/*border-radius: 0;*/
padding-left: 0;
padding-right: 0;
}

File diff suppressed because one or more lines are too long

View File

@@ -43,7 +43,7 @@
}
}
.main-header .logo {
background-color: #367fa9;
/* background-color: #367fa9; */
color: #ffffff;
border-bottom: 0 solid transparent;
}

View File

@@ -43,7 +43,7 @@
}
}
.main-header .logo {
background-color: #008d4c;
/* background-color: #008d4c; */
color: #ffffff;
border-bottom: 0 solid transparent;
}

View File

@@ -43,7 +43,7 @@
}
}
.main-header .logo {
background-color: #555299;
/* background-color: #555299; */
color: #ffffff;
border-bottom: 0 solid transparent;
}

View File

@@ -43,7 +43,7 @@
}
}
.main-header .logo {
background-color: #d73925;
/* background-color: #d73925; */
color: #ffffff;
border-bottom: 0 solid transparent;
}

View File

@@ -43,7 +43,7 @@
}
}
.main-header .logo {
background-color: #e08e0b;
/* background-color: #e08e0b; */
color: #ffffff;
border-bottom: 0 solid transparent;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -1,249 +0,0 @@
/*
* Default Layout Theme
*
* Created for jquery.layout
*
* Copyright (c) 2010
* Fabrizio Balliano (http://www.fabrizioballiano.net)
* Kevin Dalman (http://allpro.net)
*
* Dual licensed under the GPL (http://www.gnu.org/licenses/gpl.html)
* and MIT (http://www.opensource.org/licenses/mit-license.php) licenses.
*
* Last Updated: 2010-02-10
* NOTE: For best code readability, view this with a fixed-space font and tabs equal to 4-chars
*/
.ui-draggable-handle{-ms-touch-action:none;touch-action:none}
/*
* DEFAULT FONT
* Just to make demo-pages look better - not actually relevant to Layout!
*/
/* body { */
/* font-family: Geneva, Arial, Helvetica, sans-serif; */
/* font-size: 100%; */
/* *font-size: 80%; */
/* } */
/*
* PANES & CONTENT-DIVs
*/
.ui-layout-pane { /* all 'panes' */
/* background: #FFF; */
/* border: 1px solid #eee; */
/* padding: 10px; */
overflow: auto;
/* DO NOT add scrolling (or padding) to 'panes' that have a content-div,
otherwise you may get double-scrollbars - on the pane AND on the content-div
- use ui-layout-wrapper class if pane has a content-div
- use ui-layout-container if pane has an inner-layout
*/
}
/* (scrolling) content-div inside pane allows for fixed header(s) and/or footer(s) */
.ui-layout-content {
padding: 10px;
position: relative; /* contain floated or positioned elements */
overflow: auto; /* add scrolling to content-div */
width: 100%;
border: 0;
}
/*
* UTILITY CLASSES
* Must come AFTER pane-class above so will override
* These classes are NOT auto-generated and are NOT used by Layout
*/
.layout-child-container,
.layout-content-container {
padding: 0;
overflow: hidden;
}
.layout-child-container {
border: 0; /* remove border because inner-layout-panes probably have borders */
}
.layout-scroll {
overflow: auto;
}
.layout-hide {
display: none;
}
/*
* RESIZER-BARS
*/
.ui-layout-resizer { /* all 'resizer-bars' */
background: #fafafa;
border: 1px solid #eee;
border-width: 0;
}
.ui-layout-resizer-drag { /* REAL resizer while resize in progress */
}
.ui-layout-resizer-hover { /* affects both open and closed states */
}
/* NOTE: It looks best when 'hover' and 'dragging' are set to the same color,
otherwise color shifts while dragging when bar can't keep up with mouse */
.ui-layout-resizer-open-hover , /* hover-color to 'resize' */
.ui-layout-resizer-dragging { /* resizer beging 'dragging' */
background: #fafafa;
}
.ui-layout-resizer-dragging { /* CLONED resizer being dragged */
border: 1px solid #eee;
}
.ui-layout-resizer-north-dragging,
.ui-layout-resizer-south-dragging {
border-width: 1px 0;
}
.ui-layout-resizer-west-dragging,
.ui-layout-resizer-east-dragging {
border-width: 0 1px;
}
/* NOTE: Add a 'dragging-limit' color to provide visual feedback when resizer hits min/max size limits */
.ui-layout-resizer-dragging-limit { /* CLONED resizer at min or max size-limit */
background: #E1A4A4; /* red */
}
.ui-layout-resizer-closed-hover { /* hover-color to 'slide open' */
background: #EBD5AA;
}
.ui-layout-resizer-sliding { /* resizer when pane is 'slid open' */
/* opacity: .10; show only a slight shadow */
/* filter: alpha(opacity=10); */
}
.ui-layout-resizer-sliding-hover { /* sliding resizer - hover */
/* opacity: 1.00; on-hover, show the resizer-bar normally */
/* filter: alpha(opacity=100); */
}
/* sliding resizer - add 'outside-border' to resizer on-hover
* this sample illustrates how to target specific panes and states */
.ui-layout-resizer-north-sliding-hover { border-bottom-width: 1px; }
.ui-layout-resizer-south-sliding-hover { border-top-width: 1px; }
.ui-layout-resizer-west-sliding-hover { border-right-width: 1px; }
.ui-layout-resizer-east-sliding-hover { border-left-width: 1px; }
/*
* TOGGLER-BUTTONS
*/
.ui-layout-toggler {
border: 1px solid #eee; /* match pane-border */
background-color: #eee;
}
.ui-layout-resizer-hover .ui-layout-toggler {
opacity: 1.00;
filter: alpha(opacity=100);
}
.ui-layout-toggler-hover , /* need when NOT resizable */
.ui-layout-resizer-hover .ui-layout-toggler-hover { /* need specificity when IS resizable */
background-color: #FC6;
opacity: 1.00;
filter: alpha(opacity=100);
}
.ui-layout-toggler-north ,
.ui-layout-toggler-south {
border-width: 0 1px; /* left/right borders */
}
.ui-layout-toggler-west ,
.ui-layout-toggler-east {
border-width: 1px 0; /* top/bottom borders */
}
/* hide the toggler-button when the pane is 'slid open' */
.ui-layout-resizer-sliding .ui-layout-toggler {
display: none;
}
/*
* style the text we put INSIDE the togglers
*/
.ui-layout-toggler .ui-content {
color: #666;
font-size: 12px;
font-weight: bold;
line-height: 8px;
width: 100%;
padding-bottom: 0.35ex; /* to 'vertically center' text inside text-span */
}
.ui-layout-toggler .ui-content .fa{
line-height: 8px;
}
.ui-layout-toggler-north-closed .fa:before,
.ui-layout-toggler-south-open .fa:before {
content: "\f0d7";/* 下 */
}
.ui-layout-toggler-south-closed .fa:before,
.ui-layout-toggler-north-open .fa:before {
content: "\f0d8";/* 上 */
}
.ui-layout-toggler-west-closed .fa:before,
.ui-layout-toggler-east-open .fa:before {
content: "\f0da";/* 右 */
}
.ui-layout-toggler-east-closed .fa:before,
.ui-layout-toggler-west-open .fa:before {
content: "\f0d9";/* 左 */
}
/*
* PANE-MASKS
* these styles are hard-coded on mask elems, but are also
* included here as !important to ensure will overrides any generic styles
*/
.ui-layout-mask {
border: none !important;
padding: 0 !important;
margin: 0 !important;
overflow: hidden !important;
position: absolute !important;
opacity: 0 !important;
filter: Alpha(Opacity="0") !important;
}
.ui-layout-mask-inside-pane { /* masks always inside pane EXCEPT when pane is an iframe */
top: 0 !important;
left: 0 !important;
width: 100% !important;
height: 100% !important;
}
div.ui-layout-mask {} /* standard mask for iframes */
iframe.ui-layout-mask {} /* extra mask for objects/applets */
/*
* Default printing styles
*/
@media print {
/*
* Unless you want to print the layout as it appears onscreen,
* these html/body styles are needed to allow the content to 'flow'
*/
html {
height: auto !important;
overflow: visible !important;
}
body.ui-layout-container {
position: static !important;
top: auto !important;
bottom: auto !important;
left: auto !important;
right: auto !important;
/* only IE6 has container width & height set by Layout */
_width: auto !important;
_height: auto !important;
}
.ui-layout-resizer, .ui-layout-toggler {
display: none !important;
}
/*
* Default pane print styles disables positioning, borders and backgrounds.
* You can modify these styles however it suit your needs.
*/
.ui-layout-pane {
border: none !important;
background: transparent !important;
position: relative !important;
top: auto !important;
bottom: auto !important;
left: auto !important;
right: auto !important;
width: auto !important;
height: auto !important;
overflow: visible !important;
}
}

View File

@@ -98,7 +98,7 @@ ul.ztree.zTreeDragUL {margin:0; padding:0; position:absolute; width:auto; height
/* 树搜索相关 */
.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 #bbb;padding:0 4px;}
.treeSearchInput input {width:140px;vertical-align:middle;line-height:24px;height:26px;border:1px solid #bbb;padding:0 4px;border-radius:4px;}
.treeSearchInput button {border:1px solid #bbb;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;}

View File

@@ -1,4 +1,4 @@
.Wdate,.Wdate-date,.Wdate-datetime{background:#fff url(datePicker.gif) no-repeat right;}
.Wdate,.Wdate-date,.Wdate-datetime{background:#fff url(datePicker.png) no-repeat right;}
.Wdate-date{width:105px!important}.Wdate-datetime{width:147px!important}
.WdateFmtErr{font-weight:bold;color:red;}
.Wdate::-ms-clear{display:none;}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 682 B

View File

@@ -26,12 +26,6 @@ public class CodeStatistic {
System.out.println("Path: " + path);
ArrayList<File> al = getFile(new File(path));
for (File f : al) {
if (!(f.getPath().contains("4.0\\jeesite\\")
|| f.getPath().contains("\\devtools\\")
|| f.getPath().contains("\\framework\\"))
|| f.getPath().contains("\\target\\")){
continue;
}
if (f.getName().matches(".*\\.java$")
|| f.getName().matches(".*\\.html$")
|| f.getName().matches(".*\\.js$")){

View File

@@ -1,33 +0,0 @@
/**
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
*/
package com.jeesite.test;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
/**
* Excel读写测试
* @author ThinkGem
* @version 2016年8月11日
*/
public class ExcelPoiTest {
public static void main(String[] args) throws Exception {
File file = new File("e:\\2016年调查表1.xls");
HSSFWorkbook wb = new HSSFWorkbook(new FileInputStream(file));
HSSFSheet sheet = wb.getSheetAt(2);
sheet.getRow(5).getCell(3).setCellValue("山东有限公司");
sheet.getRow(5).getCell(7).setCellValue("3799991911");
sheet.getRow(8).getCell(3).setCellValue("174");
sheet.getRow(8).getCell(7).setCellValue("私营股份有限公司");
wb.write(new FileOutputStream("e:\\2016年调查表2.xls"));
wb.close();
System.out.println("success");
}
}

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false" scan="false">
<!-- Console log output -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} %-5level [%logger{50}] - %msg%n</pattern>
</encoder>
</appender>
<!-- Level: FATAL 0 ERROR 3 WARN 4 INFO 6 DEBUG 7 -->
<root level="WARN">
<appender-ref ref="console" />
</root>
</configuration>

View File

@@ -1,8 +1,8 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.source=1.7
org.eclipse.jdt.core.compiler.source=1.8

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<faceted-project>
<fixed facet="jst.utility"/>
<fixed facet="java"/>
<installed facet="jst.utility" version="1.0"/>
<installed facet="java" version="1.7"/>
</faceted-project>
<?xml version="1.0" encoding="UTF-8"?>
<faceted-project>
<fixed facet="jst.utility"/>
<fixed facet="java"/>
<installed facet="jst.utility" version="1.0"/>
<installed facet="java" version="1.8"/>
</faceted-project>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,919 @@
/* Drop Tables */
DROP TABLE js_gen_table_column;
DROP TABLE js_gen_table;
DROP TABLE js_sys_company_office;
DROP TABLE js_sys_employee_post;
DROP TABLE js_sys_user_data_scope;
DROP TABLE js_sys_user_role;
DROP TABLE js_sys_user;
DROP TABLE js_sys_employee;
DROP TABLE js_sys_company;
DROP TABLE js_sys_area;
DROP TABLE js_sys_config;
DROP TABLE js_sys_dict_data;
DROP TABLE js_sys_dict_type;
DROP TABLE js_sys_file_upload;
DROP TABLE js_sys_file_entity;
DROP TABLE js_sys_job_log;
DROP TABLE js_sys_job;
DROP TABLE js_sys_lang;
DROP TABLE js_sys_log;
DROP TABLE js_sys_role_menu;
DROP TABLE js_sys_menu;
DROP TABLE js_sys_module;
DROP TABLE js_sys_msg_inner_record;
DROP TABLE js_sys_msg_inner;
DROP TABLE js_sys_msg_push;
DROP TABLE js_sys_msg_pushed;
DROP TABLE js_sys_msg_template;
DROP TABLE js_sys_office;
DROP TABLE js_sys_post;
DROP TABLE js_sys_role_data_scope;
DROP TABLE js_sys_role;
/* Create Tables */
-- 代码生成表
CREATE TABLE js_gen_table
(
table_name varchar(64) NOT NULL,
class_name varchar(100) NOT NULL,
comments varchar(500) NOT NULL,
parent_table_name varchar(64),
parent_table_fk_name varchar(64),
data_source_name varchar(64),
tpl_category varchar(200),
package_name varchar(500),
module_name varchar(30),
sub_module_name varchar(30),
function_name varchar(200),
function_name_simple varchar(50),
function_author varchar(50),
gen_base_dir varchar(1000),
options varchar(1000),
create_by varchar(64) NOT NULL,
create_date timestamp NOT NULL,
update_by varchar(64) NOT NULL,
update_date timestamp NOT NULL,
remarks varchar(500),
PRIMARY KEY (table_name)
);
-- 代码生成表列
CREATE TABLE js_gen_table_column
(
id varchar(64) NOT NULL,
table_name varchar(64) NOT NULL,
column_name varchar(64) NOT NULL,
column_sort decimal(10),
column_type varchar(100) NOT NULL,
column_label varchar(50),
comments varchar(500) NOT NULL,
attr_name varchar(200) NOT NULL,
attr_type varchar(200) NOT NULL,
is_pk char(1),
is_null char(1),
is_insert char(1),
is_update char(1),
is_list char(1),
is_query char(1),
query_type varchar(200),
is_edit char(1),
show_type varchar(200),
options varchar(1000),
PRIMARY KEY (id)
);
-- 行政区划
CREATE TABLE js_sys_area
(
area_code varchar(100) NOT NULL,
parent_code varchar(64) NOT NULL,
parent_codes varchar(1000) NOT NULL,
tree_sort decimal(10) NOT NULL,
tree_sorts varchar(1000) NOT NULL,
tree_leaf char(1) NOT NULL,
tree_level decimal(4) NOT NULL,
tree_names varchar(1000) NOT NULL,
area_name varchar(100) NOT NULL,
area_type char(1),
status char(1) DEFAULT '0' NOT NULL,
create_by varchar(64) NOT NULL,
create_date timestamp NOT NULL,
update_by varchar(64) NOT NULL,
update_date timestamp NOT NULL,
remarks varchar(500),
PRIMARY KEY (area_code)
);
-- 公司表
CREATE TABLE js_sys_company
(
company_code varchar(64) NOT NULL,
parent_code varchar(64) NOT NULL,
parent_codes varchar(1000) NOT NULL,
tree_sort decimal(10) NOT NULL,
tree_sorts varchar(1000) NOT NULL,
tree_leaf char(1) NOT NULL,
tree_level decimal(4) NOT NULL,
tree_names varchar(1000) NOT NULL,
view_code varchar(100) NOT NULL,
company_name varchar(200) NOT NULL,
full_name varchar(200) NOT NULL,
area_code varchar(100),
status char(1) DEFAULT '0' NOT NULL,
create_by varchar(64) NOT NULL,
create_date timestamp NOT NULL,
update_by varchar(64) NOT NULL,
update_date timestamp NOT NULL,
remarks varchar(500),
corp_code varchar(64) DEFAULT '0' NOT NULL,
corp_name varchar(100) DEFAULT 'JeeSite' NOT NULL,
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 (company_code)
);
-- 公司部门关联表
CREATE TABLE js_sys_company_office
(
company_code varchar(64) NOT NULL,
office_code varchar(64) NOT NULL,
PRIMARY KEY (company_code, office_code)
);
-- 参数配置表
CREATE TABLE js_sys_config
(
id varchar(64) NOT NULL,
config_name varchar(100) NOT NULL,
config_key varchar(100) NOT NULL,
config_value varchar(1000),
is_sys char(1) NOT NULL,
create_by varchar(64) NOT NULL,
create_date timestamp NOT NULL,
update_by varchar(64) NOT NULL,
update_date timestamp NOT NULL,
remarks varchar(500),
PRIMARY KEY (id)
);
-- 字典数据表
CREATE TABLE js_sys_dict_data
(
dict_code varchar(64) NOT NULL,
parent_code varchar(64) NOT NULL,
parent_codes varchar(1000) NOT NULL,
tree_sort decimal(10) NOT NULL,
tree_sorts varchar(1000) NOT NULL,
tree_leaf char(1) NOT NULL,
tree_level decimal(4) NOT NULL,
tree_names varchar(1000) NOT NULL,
dict_label varchar(100) NOT NULL,
dict_value varchar(100) NOT NULL,
dict_type varchar(100) NOT NULL,
is_sys char(1) NOT NULL,
description varchar(500),
css_style varchar(500),
css_class varchar(500),
status char(1) DEFAULT '0' NOT NULL,
create_by varchar(64) NOT NULL,
create_date timestamp NOT NULL,
update_by varchar(64) NOT NULL,
update_date timestamp NOT NULL,
remarks varchar(500),
corp_code varchar(64) DEFAULT '0' NOT NULL,
corp_name varchar(100) DEFAULT 'JeeSite' NOT NULL,
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 (dict_code)
);
-- 字典类型表
CREATE TABLE js_sys_dict_type
(
id varchar(64) NOT NULL,
dict_name varchar(100) NOT NULL,
dict_type varchar(100) NOT NULL,
is_sys char(1) NOT NULL,
status char(1) DEFAULT '0' NOT NULL,
create_by varchar(64) NOT NULL,
create_date timestamp NOT NULL,
update_by varchar(64) NOT NULL,
update_date timestamp NOT NULL,
remarks varchar(500),
PRIMARY KEY (id)
);
-- 员工表
CREATE TABLE js_sys_employee
(
emp_code varchar(64) NOT NULL,
emp_name varchar(100) NOT NULL,
emp_name_en varchar(100),
office_code varchar(64) NOT NULL,
office_name varchar(100) NOT NULL,
company_code varchar(64),
company_name varchar(200),
status char(1) NOT NULL,
create_by varchar(64) NOT NULL,
create_date timestamp NOT NULL,
update_by varchar(64) NOT NULL,
update_date timestamp NOT NULL,
remarks varchar(500),
corp_code varchar(64) DEFAULT '0' NOT NULL,
corp_name varchar(100) DEFAULT 'JeeSite' NOT NULL,
PRIMARY KEY (emp_code)
);
-- 员工与岗位关联表
CREATE TABLE js_sys_employee_post
(
emp_code varchar(64) NOT NULL,
post_code varchar(64) NOT NULL,
PRIMARY KEY (emp_code, post_code)
);
-- 文件实体表
CREATE TABLE js_sys_file_entity
(
file_id varchar(64) NOT NULL,
file_md5 varchar(64) NOT NULL UNIQUE,
file_path varchar(1000) NOT NULL,
file_content_type varchar(200) NOT NULL,
file_extension varchar(100) NOT NULL,
file_size decimal(31) NOT NULL,
PRIMARY KEY (file_id)
);
-- 文件上传表
CREATE TABLE js_sys_file_upload
(
id varchar(64) NOT NULL,
file_id varchar(64) NOT NULL,
file_name varchar(500) NOT NULL,
file_type varchar(20) NOT NULL,
biz_key varchar(64),
biz_type varchar(64),
status char(1) DEFAULT '0' NOT NULL,
create_by varchar(64) NOT NULL,
create_date timestamp NOT NULL,
update_by varchar(64) NOT NULL,
update_date timestamp NOT NULL,
remarks varchar(500),
PRIMARY KEY (id)
);
-- 作业调度表
CREATE TABLE js_sys_job
(
job_name varchar(64) NOT NULL,
job_group varchar(64) NOT NULL,
description varchar(100) NOT NULL,
invoke_target varchar(1000) NOT NULL,
cron_expression varchar(255) NOT NULL,
misfire_instruction decimal(1) NOT NULL,
concurrent char(1) NOT NULL,
status char(1) NOT NULL,
create_by varchar(64) NOT NULL,
create_date timestamp NOT NULL,
update_by varchar(64) NOT NULL,
update_date timestamp NOT NULL,
remarks varchar(500),
PRIMARY KEY (job_name, job_group)
);
-- 作业调度日志表
CREATE TABLE js_sys_job_log
(
id varchar(64) NOT NULL,
job_name varchar(64) NOT NULL,
job_group varchar(64) NOT NULL,
job_type varchar(50),
job_event varchar(200),
job_message varchar(500),
is_exception char(1),
exception_info clob,
create_date timestamp,
PRIMARY KEY (id)
);
-- 国际化语言
CREATE TABLE js_sys_lang
(
id varchar(64) NOT NULL,
module_code varchar(64) NOT NULL,
lang_code varchar(500) NOT NULL,
lang_text varchar(500) NOT NULL,
lang_type varchar(50) NOT NULL,
create_by varchar(64) NOT NULL,
create_date timestamp NOT NULL,
update_by varchar(64) NOT NULL,
update_date timestamp NOT NULL,
remarks varchar(500),
PRIMARY KEY (id)
);
-- 操作日志表
CREATE TABLE js_sys_log
(
id varchar(64) NOT NULL,
log_type varchar(50) NOT NULL,
log_title varchar(500) NOT NULL,
create_by varchar(64) NOT NULL,
create_by_name varchar(100) NOT NULL,
create_date timestamp NOT NULL,
request_uri varchar(500),
request_method varchar(10),
request_params clob,
diff_modify_data clob,
biz_key varchar(64),
biz_type varchar(64),
remote_addr varchar(255) NOT NULL,
server_addr varchar(255) NOT NULL,
is_exception char(1),
exception_info clob,
user_agent varchar(500),
device_name varchar(100),
browser_name varchar(100),
execute_time decimal(19),
corp_code varchar(64) DEFAULT '0' NOT NULL,
corp_name varchar(100) DEFAULT 'JeeSite' NOT NULL,
PRIMARY KEY (id)
);
-- 菜单表
CREATE TABLE js_sys_menu
(
menu_code varchar(64) NOT NULL,
parent_code varchar(64) NOT NULL,
parent_codes varchar(1000) NOT NULL,
tree_sort decimal(10) NOT NULL,
tree_sorts varchar(1000) NOT NULL,
tree_leaf char(1) NOT NULL,
tree_level decimal(4) NOT NULL,
tree_names varchar(1000) NOT NULL,
menu_name varchar(100) NOT NULL,
menu_type char(1) NOT NULL,
menu_href varchar(1000),
menu_target varchar(20),
menu_icon varchar(100),
menu_color varchar(50),
permission varchar(1000),
weight decimal(4),
is_show char(1) NOT NULL,
sys_code varchar(64) NOT NULL,
module_codes varchar(500) NOT NULL,
status char(1) DEFAULT '0' NOT NULL,
create_by varchar(64) NOT NULL,
create_date timestamp NOT NULL,
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 (menu_code)
);
-- 模块表
CREATE TABLE js_sys_module
(
module_code varchar(64) NOT NULL,
module_name varchar(100) NOT NULL,
description varchar(500),
main_class_name varchar(500),
current_version varchar(50),
upgrade_info varchar(300),
status char(1) DEFAULT '0' NOT NULL,
create_by varchar(64) NOT NULL,
create_date timestamp NOT NULL,
update_by varchar(64) NOT NULL,
update_date timestamp NOT NULL,
remarks varchar(500),
PRIMARY KEY (module_code)
);
-- 内部消息
CREATE TABLE js_sys_msg_inner
(
id varchar(64) NOT NULL,
msg_title varchar(200) NOT NULL,
content_level char(1) NOT NULL,
content_type char(1),
msg_content clob NOT NULL,
receive_type char(1) NOT NULL,
receive_codes clob NOT NULL,
receive_names clob NOT NULL,
send_user_code varchar(64) NOT NULL,
send_user_name varchar(100) NOT NULL,
send_date timestamp NOT NULL,
is_attac char(1),
notify_types varchar(100) NOT NULL,
status char(1) NOT NULL,
create_by varchar(64) NOT NULL,
create_date timestamp NOT NULL,
update_by varchar(64) NOT NULL,
update_date timestamp NOT NULL,
remarks varchar(500),
PRIMARY KEY (id)
);
-- 内部消息发送记录表
CREATE TABLE js_sys_msg_inner_record
(
id varchar(64) NOT NULL,
msg_inner_id varchar(64) NOT NULL,
receive_user_code varchar(64),
receive_user_name varchar(100) NOT NULL,
read_status char(1) NOT NULL,
read_date timestamp,
is_star char(1),
PRIMARY KEY (id)
);
-- 消息推送表
CREATE TABLE js_sys_msg_push
(
id varchar(64) NOT NULL,
msg_type varchar(16) NOT NULL,
msg_title varchar(200) NOT NULL,
msg_content clob NOT NULL,
biz_key varchar(64),
biz_type varchar(64),
receive_code varchar(64) NOT NULL,
receive_user_code varchar(64) NOT NULL,
receive_user_name varchar(100) NOT NULL,
send_user_code varchar(64) NOT NULL,
send_user_name varchar(100) NOT NULL,
send_date timestamp NOT NULL,
is_merge_push char(1),
plan_push_date timestamp,
push_number int,
push_return_code varchar(200),
push_return_msg_id varchar(200),
push_return_content clob,
push_status char(1),
push_date timestamp,
read_status char(1),
read_date timestamp,
PRIMARY KEY (id)
);
-- 消息已推送表
CREATE TABLE js_sys_msg_pushed
(
id varchar(64) NOT NULL,
msg_type varchar(16) NOT NULL,
msg_title varchar(200) NOT NULL,
msg_content clob NOT NULL,
biz_key varchar(64),
biz_type varchar(64),
receive_code varchar(64) NOT NULL,
receive_user_code varchar(64) NOT NULL,
receive_user_name varchar(100) NOT NULL,
send_user_code varchar(64) NOT NULL,
send_user_name varchar(100) NOT NULL,
send_date timestamp NOT NULL,
is_merge_push char(1),
plan_push_date timestamp,
push_number int,
push_return_content clob,
push_return_code varchar(200),
push_return_msg_id varchar(200),
push_status char(1),
push_date timestamp,
read_status char(1),
read_date timestamp,
PRIMARY KEY (id)
);
-- 消息模板
CREATE TABLE js_sys_msg_template
(
id varchar(64) NOT NULL,
module_code varchar(64),
tpl_key varchar(100) NOT NULL,
tpl_name varchar(100) NOT NULL,
tpl_type varchar(16) NOT NULL,
tpl_content clob NOT NULL,
status char(1) DEFAULT '0' NOT NULL,
create_by varchar(64) NOT NULL,
create_date timestamp NOT NULL,
update_by varchar(64) NOT NULL,
update_date timestamp NOT NULL,
remarks varchar(500),
PRIMARY KEY (id)
);
-- 组织机构表
CREATE TABLE js_sys_office
(
office_code varchar(64) NOT NULL,
parent_code varchar(64) NOT NULL,
parent_codes varchar(1000) NOT NULL,
tree_sort decimal(10) NOT NULL,
tree_sorts varchar(1000) NOT NULL,
tree_leaf char(1) NOT NULL,
tree_level decimal(4) NOT NULL,
tree_names varchar(1000) NOT NULL,
view_code varchar(100) NOT NULL,
office_name varchar(100) NOT NULL,
full_name varchar(200) NOT NULL,
office_type char(1) NOT NULL,
leader varchar(100),
phone varchar(100),
address varchar(255),
zip_code varchar(100),
email varchar(300),
status char(1) DEFAULT '0' NOT NULL,
create_by varchar(64) NOT NULL,
create_date timestamp NOT NULL,
update_by varchar(64) NOT NULL,
update_date timestamp NOT NULL,
remarks varchar(500),
corp_code varchar(64) DEFAULT '0' NOT NULL,
corp_name varchar(100) DEFAULT 'JeeSite' NOT NULL,
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 (office_code)
);
-- 员工岗位表
CREATE TABLE js_sys_post
(
post_code varchar(64) NOT NULL,
post_name varchar(100) NOT NULL,
post_type varchar(100),
post_sort decimal(10),
status char(1) DEFAULT '0' NOT NULL,
create_by varchar(64) NOT NULL,
create_date timestamp NOT NULL,
update_by varchar(64) NOT NULL,
update_date timestamp NOT NULL,
remarks varchar(500),
corp_code varchar(64) DEFAULT '0' NOT NULL,
corp_name varchar(100) DEFAULT 'JeeSite' NOT NULL,
PRIMARY KEY (post_code)
);
-- 角色表
CREATE TABLE js_sys_role
(
role_code varchar(64) NOT NULL,
role_name varchar(100) NOT NULL,
role_type varchar(100),
role_sort decimal(10),
is_sys char(1),
user_type varchar(16),
data_scope char(1),
status char(1) DEFAULT '0' NOT NULL,
create_by varchar(64) NOT NULL,
create_date timestamp NOT NULL,
update_by varchar(64) NOT NULL,
update_date timestamp NOT NULL,
remarks varchar(500),
corp_code varchar(64) DEFAULT '0' NOT NULL,
corp_name varchar(100) DEFAULT 'JeeSite' NOT NULL,
PRIMARY KEY (role_code)
);
-- 角色数据权限表
CREATE TABLE js_sys_role_data_scope
(
role_code varchar(64) NOT NULL,
ctrl_type varchar(20) NOT NULL,
ctrl_data varchar(64) NOT NULL,
ctrl_permi varchar(64) NOT NULL,
PRIMARY KEY (role_code, ctrl_type, ctrl_data, ctrl_permi)
);
-- 角色与菜单关联表
CREATE TABLE js_sys_role_menu
(
role_code varchar(64) NOT NULL,
menu_code varchar(64) NOT NULL,
PRIMARY KEY (role_code, menu_code)
);
-- 用户表
CREATE TABLE js_sys_user
(
user_code varchar(100) NOT NULL,
login_code varchar(100) NOT NULL,
user_name varchar(100) NOT NULL,
password varchar(100) NOT NULL,
email varchar(300),
mobile varchar(100),
phone varchar(100),
sex char(1),
avatar varchar(1000),
sign varchar(200),
wx_openid varchar(100),
mobile_imei varchar(100),
user_type varchar(16) NOT NULL,
ref_code varchar(64),
ref_name varchar(100),
mgr_type char(1) NOT NULL,
pwd_security_level decimal(1),
pwd_update_date timestamp,
pwd_update_record varchar(1000),
pwd_question varchar(200),
pwd_question_answer varchar(200),
pwd_question_2 varchar(200),
pwd_question_answer_2 varchar(200),
pwd_question_3 varchar(200),
pwd_question_answer_3 varchar(200),
pwd_quest_update_date timestamp,
last_login_ip varchar(100),
last_login_date timestamp,
freeze_date timestamp,
freeze_cause varchar(200),
user_weight decimal(8) DEFAULT 0,
status char NOT NULL,
create_by varchar(64) NOT NULL,
create_date timestamp NOT NULL,
update_by varchar(64) NOT NULL,
update_date timestamp NOT NULL,
remarks varchar(500),
corp_code varchar(64) DEFAULT '0' NOT NULL,
corp_name varchar(100) DEFAULT 'JeeSite' NOT NULL,
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 (user_code)
);
-- 用户数据权限表
CREATE TABLE js_sys_user_data_scope
(
user_code varchar(100) NOT NULL,
ctrl_type varchar(20) NOT NULL,
ctrl_data varchar(64) NOT NULL,
ctrl_permi varchar(64) NOT NULL,
PRIMARY KEY (user_code, ctrl_type, ctrl_data, ctrl_permi)
);
-- 用户与角色关联表
CREATE TABLE js_sys_user_role
(
user_code varchar(100) NOT NULL,
role_code varchar(64) NOT NULL,
PRIMARY KEY (user_code, role_code)
);
/* Create Indexes */
CREATE INDEX idx_gen_table_ptn ON js_gen_table (parent_table_name);
CREATE INDEX idx_gen_table_column_tn ON js_gen_table_column (table_name);
CREATE INDEX idx_sys_area_pc ON js_sys_area (parent_code);
CREATE INDEX idx_sys_area_ts ON js_sys_area (tree_sort);
CREATE INDEX idx_sys_area_status ON js_sys_area (status);
CREATE INDEX idx_sys_area_pcs ON js_sys_area (parent_codes);
CREATE INDEX idx_sys_area_tss ON js_sys_area (tree_sorts);
CREATE INDEX idx_sys_company_cc ON js_sys_company (corp_code);
CREATE INDEX idx_sys_company_pc ON js_sys_company (parent_code);
CREATE INDEX idx_sys_company_ts ON js_sys_company (tree_sort);
CREATE INDEX idx_sys_company_status ON js_sys_company (status);
CREATE INDEX idx_sys_company_vc ON js_sys_company (view_code);
CREATE INDEX idx_sys_company_pcs ON js_sys_company (parent_codes);
CREATE INDEX idx_sys_company_tss ON js_sys_company (tree_sorts);
CREATE INDEX idx_sys_config_key ON js_sys_config (config_key);
CREATE INDEX idx_sys_dict_data_cc ON js_sys_dict_data (corp_code);
CREATE INDEX idx_sys_dict_data_dt ON js_sys_dict_data (dict_type);
CREATE INDEX idx_sys_dict_data_pc ON js_sys_dict_data (parent_code);
CREATE INDEX idx_sys_dict_data_status ON js_sys_dict_data (status);
CREATE INDEX idx_sys_dict_data_pcs ON js_sys_dict_data (parent_codes);
CREATE INDEX idx_sys_dict_data_ts ON js_sys_dict_data (tree_sort);
CREATE INDEX idx_sys_dict_data_tss ON js_sys_dict_data (tree_sorts);
CREATE INDEX idx_sys_dict_data_dv ON js_sys_dict_data (dict_value);
CREATE INDEX idx_sys_dict_type_is ON js_sys_dict_type (is_sys);
CREATE INDEX idx_sys_dict_type_status ON js_sys_dict_type (status);
CREATE INDEX idx_sys_employee_cco ON js_sys_employee (company_code);
CREATE INDEX idx_sys_employee_cc ON js_sys_employee (corp_code);
CREATE INDEX idx_sys_employee_ud ON js_sys_employee (update_date);
CREATE INDEX idx_sys_employee_oc ON js_sys_employee (office_code);
CREATE INDEX idx_sys_employee_status ON js_sys_employee (status);
CREATE INDEX idx_sys_file_entity_md5 ON js_sys_file_entity (file_md5);
CREATE INDEX idx_sys_file_entity_size ON js_sys_file_entity (file_size);
CREATE INDEX idx_sys_file_biz_ft ON js_sys_file_upload (file_type);
CREATE INDEX idx_sys_file_biz_fi ON js_sys_file_upload (file_id);
CREATE INDEX idx_sys_file_biz_status ON js_sys_file_upload (status);
CREATE INDEX idx_sys_file_biz_cb ON js_sys_file_upload (create_by);
CREATE INDEX idx_sys_file_biz_ud ON js_sys_file_upload (update_date);
CREATE INDEX idx_sys_file_biz_bt ON js_sys_file_upload (biz_type);
CREATE INDEX idx_sys_file_biz_bk ON js_sys_file_upload (biz_key);
CREATE INDEX idx_sys_job_status ON js_sys_job (status);
CREATE INDEX idx_sys_job_log_jn ON js_sys_job_log (job_name);
CREATE INDEX idx_sys_job_log_jg ON js_sys_job_log (job_group);
CREATE INDEX idx_sys_job_log_t ON js_sys_job_log (job_type);
CREATE INDEX idx_sys_job_log_e ON js_sys_job_log (job_event);
CREATE INDEX idx_sys_job_log_ie ON js_sys_job_log (is_exception);
CREATE INDEX idx_sys_lang_code ON js_sys_lang (lang_code);
CREATE INDEX idx_sys_lang_type ON js_sys_lang (lang_type);
CREATE INDEX idx_sys_log_cb ON js_sys_log (create_by);
CREATE INDEX idx_sys_log_cc ON js_sys_log (corp_code);
CREATE INDEX idx_sys_log_lt ON js_sys_log (log_type);
CREATE INDEX idx_sys_log_bk ON js_sys_log (biz_key);
CREATE INDEX idx_sys_log_bt ON js_sys_log (biz_type);
CREATE INDEX idx_sys_log_ie ON js_sys_log (is_exception);
CREATE INDEX idx_sys_log_cd ON js_sys_log (create_date);
CREATE INDEX idx_sys_menu_pc ON js_sys_menu (parent_code);
CREATE INDEX idx_sys_menu_ts ON js_sys_menu (tree_sort);
CREATE INDEX idx_sys_menu_status ON js_sys_menu (status);
CREATE INDEX idx_sys_menu_mt ON js_sys_menu (menu_type);
CREATE INDEX idx_sys_menu_pss ON js_sys_menu (parent_codes);
CREATE INDEX idx_sys_menu_tss ON js_sys_menu (tree_sorts);
CREATE INDEX idx_sys_menu_sc ON js_sys_menu (sys_code);
CREATE INDEX idx_sys_menu_is ON js_sys_menu (is_show);
CREATE INDEX idx_sys_menu_mcs ON js_sys_menu (module_codes);
CREATE INDEX idx_sys_menu_wt ON js_sys_menu (weight);
CREATE INDEX idx_sys_module_status ON js_sys_module (status);
CREATE INDEX idx_sys_msg_inner_cb ON js_sys_msg_inner (create_by);
CREATE INDEX idx_sys_msg_inner_status ON js_sys_msg_inner (status);
CREATE INDEX idx_sys_msg_inner_cl ON js_sys_msg_inner (content_level);
CREATE INDEX idx_sys_msg_inner_sc ON js_sys_msg_inner (send_user_code);
CREATE INDEX idx_sys_msg_inner_sd ON js_sys_msg_inner (send_date);
CREATE INDEX idx_sys_msg_inner_r_mi ON js_sys_msg_inner_record (msg_inner_id);
CREATE INDEX idx_sys_msg_inner_r_rc ON js_sys_msg_inner_record (receive_user_code);
CREATE INDEX idx_sys_msg_inner_r_ruc ON js_sys_msg_inner_record (receive_user_code);
CREATE INDEX idx_sys_msg_inner_r_status ON js_sys_msg_inner_record (read_status);
CREATE INDEX idx_sys_msg_inner_r_star ON js_sys_msg_inner_record (is_star);
CREATE INDEX idx_sys_msg_push_type ON js_sys_msg_push (msg_type);
CREATE INDEX idx_sys_msg_push_rc ON js_sys_msg_push (receive_code);
CREATE INDEX idx_sys_msg_push_uc ON js_sys_msg_push (receive_user_code);
CREATE INDEX idx_sys_msg_push_suc ON js_sys_msg_push (send_user_code);
CREATE INDEX idx_sys_msg_push_pd ON js_sys_msg_push (plan_push_date);
CREATE INDEX idx_sys_msg_push_ps ON js_sys_msg_push (push_status);
CREATE INDEX idx_sys_msg_push_rs ON js_sys_msg_push (read_status);
CREATE INDEX idx_sys_msg_push_bk ON js_sys_msg_push (biz_key);
CREATE INDEX idx_sys_msg_push_bt ON js_sys_msg_push (biz_type);
CREATE INDEX idx_sys_msg_push_imp ON js_sys_msg_push (is_merge_push);
CREATE INDEX idx_sys_msg_pushed_type ON js_sys_msg_pushed (msg_type);
CREATE INDEX idx_sys_msg_pushed_rc ON js_sys_msg_pushed (receive_code);
CREATE INDEX idx_sys_msg_pushed_uc ON js_sys_msg_pushed (receive_user_code);
CREATE INDEX idx_sys_msg_pushed_suc ON js_sys_msg_pushed (send_user_code);
CREATE INDEX idx_sys_msg_pushed_pd ON js_sys_msg_pushed (plan_push_date);
CREATE INDEX idx_sys_msg_pushed_ps ON js_sys_msg_pushed (push_status);
CREATE INDEX idx_sys_msg_pushed_rs ON js_sys_msg_pushed (read_status);
CREATE INDEX idx_sys_msg_pushed_bk ON js_sys_msg_pushed (biz_key);
CREATE INDEX idx_sys_msg_pushed_bt ON js_sys_msg_pushed (biz_type);
CREATE INDEX idx_sys_msg_pushed_imp ON js_sys_msg_pushed (is_merge_push);
CREATE INDEX idx_sys_msg_tpl_key ON js_sys_msg_template (tpl_key);
CREATE INDEX idx_sys_msg_tpl_type ON js_sys_msg_template (tpl_type);
CREATE INDEX idx_sys_msg_tpl_status ON js_sys_msg_template (status);
CREATE INDEX idx_sys_office_cc ON js_sys_office (corp_code);
CREATE INDEX idx_sys_office_pc ON js_sys_office (parent_code);
CREATE INDEX idx_sys_office_pcs ON js_sys_office (parent_codes);
CREATE INDEX idx_sys_office_status ON js_sys_office (status);
CREATE INDEX idx_sys_office_ot ON js_sys_office (office_type);
CREATE INDEX idx_sys_office_vc ON js_sys_office (view_code);
CREATE INDEX idx_sys_office_ts ON js_sys_office (tree_sort);
CREATE INDEX idx_sys_office_tss ON js_sys_office (tree_sorts);
CREATE INDEX idx_sys_post_cc ON js_sys_post (corp_code);
CREATE INDEX idx_sys_post_status ON js_sys_post (status);
CREATE INDEX idx_sys_post_ps ON js_sys_post (post_sort);
CREATE INDEX idx_sys_role_cc ON js_sys_role (corp_code);
CREATE INDEX idx_sys_role_is ON js_sys_role (is_sys);
CREATE INDEX idx_sys_role_status ON js_sys_role (status);
CREATE INDEX idx_sys_role_rs ON js_sys_role (role_sort);
CREATE INDEX idx_sys_user_lc ON js_sys_user (login_code);
CREATE INDEX idx_sys_user_email ON js_sys_user (email);
CREATE INDEX idx_sys_user_mobile ON js_sys_user (mobile);
CREATE INDEX idx_sys_user_wo ON js_sys_user (wx_openid);
CREATE INDEX idx_sys_user_imei ON js_sys_user (mobile_imei);
CREATE INDEX idx_sys_user_rt ON js_sys_user (user_type);
CREATE INDEX idx_sys_user_rc ON js_sys_user (ref_code);
CREATE INDEX idx_sys_user_mt ON js_sys_user (mgr_type);
CREATE INDEX idx_sys_user_us ON js_sys_user (user_weight);
CREATE INDEX idx_sys_user_ud ON js_sys_user (update_date);
CREATE INDEX idx_sys_user_status ON js_sys_user (status);
CREATE INDEX idx_sys_user_cc ON js_sys_user (corp_code);

View File

@@ -46,6 +46,7 @@ CREATE TABLE [js_gen_table]
[comments] nvarchar(500) NOT NULL,
[parent_table_name] varchar(64),
[parent_table_fk_name] varchar(64),
[data_source_name] varchar(64),
[tpl_category] varchar(200),
[package_name] varchar(500),
[module_name] varchar(30),
@@ -292,7 +293,7 @@ CREATE TABLE [js_sys_file_entity]
[file_path] nvarchar(1000) NOT NULL,
[file_content_type] varchar(200) NOT NULL,
[file_extension] varchar(100) NOT NULL,
[file_size] decimal(38) NOT NULL,
[file_size] decimal(31) NOT NULL,
PRIMARY KEY ([file_id])
);

View File

@@ -47,6 +47,7 @@ CREATE TABLE js_gen_table
comments varchar(500) NOT NULL COMMENT '表说明',
parent_table_name varchar(64) COMMENT '关联父表的表名',
parent_table_fk_name varchar(64) COMMENT '本表关联父表的外键名',
data_source_name varchar(64) COMMENT '数据源名称',
tpl_category varchar(200) COMMENT '使用的模板',
package_name varchar(500) COMMENT '生成包路径',
module_name varchar(30) COMMENT '生成模块名',
@@ -293,7 +294,7 @@ CREATE TABLE js_sys_file_entity
file_path varchar(1000) NOT NULL COMMENT '文件相对路径',
file_content_type varchar(200) NOT NULL COMMENT '文件内容类型',
file_extension varchar(100) NOT NULL COMMENT '文件后缀扩展名',
file_size decimal(38) NOT NULL COMMENT '文件大小(单位B)',
file_size decimal(31) NOT NULL COMMENT '文件大小(单位B)',
PRIMARY KEY (file_id),
UNIQUE (file_md5)
) COMMENT = '文件实体表';
@@ -504,7 +505,7 @@ CREATE TABLE js_sys_msg_inner_record
msg_inner_id varchar(64) NOT NULL COMMENT '所属消息',
receive_user_code varchar(64) COMMENT '接受者用户编码',
receive_user_name varchar(100) NOT NULL COMMENT '接受者用户姓名',
read_status char(1) NOT NULL COMMENT '读取状态0未送达 1读 2读)',
read_status char(1) NOT NULL COMMENT '读取状态0未送达 1读 2读)',
read_date datetime COMMENT '阅读时间',
is_star char(1) COMMENT '是否标星',
PRIMARY KEY (id)
@@ -534,7 +535,7 @@ CREATE TABLE js_sys_msg_push
push_return_content text COMMENT '推送返回的内容信息',
push_status char(1) COMMENT '推送状态0未推送 1成功 2失败',
push_date datetime COMMENT '推送时间',
read_status char(1) COMMENT '读取状态0未送达 1读 2读)',
read_status char(1) COMMENT '读取状态0未送达 1读 2读)',
read_date datetime COMMENT '读取时间',
PRIMARY KEY (id)
) COMMENT = '消息推送表';
@@ -563,7 +564,7 @@ CREATE TABLE js_sys_msg_pushed
push_return_msg_id varchar(200) COMMENT '推送返回消息编号',
push_status char(1) COMMENT '推送状态0未推送 1成功 2失败',
push_date datetime COMMENT '推送时间',
read_status char(1) COMMENT '读取状态0未送达 1读 2读)',
read_status char(1) COMMENT '读取状态0未送达 1读 2读)',
read_date datetime COMMENT '读取时间',
PRIMARY KEY (id)
) COMMENT = '消息已推送表';

View File

@@ -1,13 +0,0 @@
-- 打开 my.ini 给 [mysqld] 增加如下配置:
-- sql_mode=ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
set global read_only=0;
create user 'jeesite'@'%' identified by 'jeesite';
create database jeesite DEFAULT CHARSET utf8 COLLATE utf8_general_ci;
grant all privileges on jeesite.* to 'jeesite'@'%' identified by 'jeesite';
flush privileges;

View File

@@ -46,6 +46,7 @@ CREATE TABLE js_gen_table
comments nvarchar2(500) NOT NULL,
parent_table_name varchar2(64),
parent_table_fk_name varchar2(64),
data_source_name varchar2(64),
tpl_category varchar2(200),
package_name varchar2(500),
module_name varchar2(30),
@@ -292,7 +293,7 @@ CREATE TABLE js_sys_file_entity
file_path nvarchar2(1000) NOT NULL,
file_content_type varchar2(200) NOT NULL,
file_extension varchar2(100) NOT NULL,
file_size number(38) NOT NULL,
file_size number(31) NOT NULL,
PRIMARY KEY (file_id)
);
@@ -924,6 +925,7 @@ COMMENT ON COLUMN js_gen_table.class_name IS '实体类名称';
COMMENT ON COLUMN js_gen_table.comments IS '表说明';
COMMENT ON COLUMN js_gen_table.parent_table_name IS '关联父表的表名';
COMMENT ON COLUMN js_gen_table.parent_table_fk_name IS '本表关联父表的外键名';
COMMENT ON COLUMN js_gen_table.data_source_name IS '数据源名称';
COMMENT ON COLUMN js_gen_table.tpl_category IS '使用的模板';
COMMENT ON COLUMN js_gen_table.package_name IS '生成包路径';
COMMENT ON COLUMN js_gen_table.module_name IS '生成模块名';
@@ -1266,7 +1268,7 @@ COMMENT ON COLUMN js_sys_msg_inner_record.id IS '编号';
COMMENT ON COLUMN js_sys_msg_inner_record.msg_inner_id IS '所属消息';
COMMENT ON COLUMN js_sys_msg_inner_record.receive_user_code IS '接受者用户编码';
COMMENT ON COLUMN js_sys_msg_inner_record.receive_user_name IS '接受者用户姓名';
COMMENT ON COLUMN js_sys_msg_inner_record.read_status IS '读取状态0未送达 1读 2读)';
COMMENT ON COLUMN js_sys_msg_inner_record.read_status IS '读取状态0未送达 1读 2读)';
COMMENT ON COLUMN js_sys_msg_inner_record.read_date IS '阅读时间';
COMMENT ON COLUMN js_sys_msg_inner_record.is_star IS '是否标星';
COMMENT ON TABLE js_sys_msg_push IS '消息推送表';
@@ -1290,7 +1292,7 @@ COMMENT ON COLUMN js_sys_msg_push.push_return_msg_id IS '推送返回消息编
COMMENT ON COLUMN js_sys_msg_push.push_return_content IS '推送返回的内容信息';
COMMENT ON COLUMN js_sys_msg_push.push_status IS '推送状态0未推送 1成功 2失败';
COMMENT ON COLUMN js_sys_msg_push.push_date IS '推送时间';
COMMENT ON COLUMN js_sys_msg_push.read_status IS '读取状态0未送达 1读 2读)';
COMMENT ON COLUMN js_sys_msg_push.read_status IS '读取状态0未送达 1读 2读)';
COMMENT ON COLUMN js_sys_msg_push.read_date IS '读取时间';
COMMENT ON TABLE js_sys_msg_pushed IS '消息已推送表';
COMMENT ON COLUMN js_sys_msg_pushed.id IS '编号';
@@ -1313,7 +1315,7 @@ COMMENT ON COLUMN js_sys_msg_pushed.push_return_code IS '推送返回结果码';
COMMENT ON COLUMN js_sys_msg_pushed.push_return_msg_id IS '推送返回消息编号';
COMMENT ON COLUMN js_sys_msg_pushed.push_status IS '推送状态0未推送 1成功 2失败';
COMMENT ON COLUMN js_sys_msg_pushed.push_date IS '推送时间';
COMMENT ON COLUMN js_sys_msg_pushed.read_status IS '读取状态0未送达 1读 2读)';
COMMENT ON COLUMN js_sys_msg_pushed.read_status IS '读取状态0未送达 1读 2读)';
COMMENT ON COLUMN js_sys_msg_pushed.read_date IS '读取时间';
COMMENT ON TABLE js_sys_msg_template IS '消息模板';
COMMENT ON COLUMN js_sys_msg_template.id IS '编号';

View File

@@ -1,15 +0,0 @@
create user jeesite
identified by jeesite
quota unlimited on users;
grant connect,resource,create session,select any table,
create any view,create any table,create any index,
drop any table,drop any view,drop any index
to jeesite;
-- 多数据源分布式事务下需要对目标用户进行如下授权否则会提示错误ResourceException: Error in recovery
grant select on sys.dba_pending_transactions to jeesite;
grant select on sys.pending_trans$ to jeesite;
grant select on sys.dba_2pc_pending to jeesite;
grant execute on sys.dbms_system to jeesite;

View File

@@ -46,6 +46,7 @@ CREATE TABLE js_gen_table
comments varchar(500) NOT NULL,
parent_table_name varchar(64),
parent_table_fk_name varchar(64),
data_source_name varchar(64),
tpl_category varchar(200),
package_name varchar(500),
module_name varchar(30),
@@ -292,7 +293,7 @@ CREATE TABLE js_sys_file_entity
file_path varchar(1000) NOT NULL,
file_content_type varchar(200) NOT NULL,
file_extension varchar(100) NOT NULL,
file_size decimal(38) NOT NULL,
file_size decimal(31) NOT NULL,
PRIMARY KEY (file_id)
) WITHOUT OIDS;
@@ -924,6 +925,7 @@ COMMENT ON COLUMN js_gen_table.class_name IS '实体类名称';
COMMENT ON COLUMN js_gen_table.comments IS '表说明';
COMMENT ON COLUMN js_gen_table.parent_table_name IS '关联父表的表名';
COMMENT ON COLUMN js_gen_table.parent_table_fk_name IS '本表关联父表的外键名';
COMMENT ON COLUMN js_gen_table.data_source_name IS '数据源名称';
COMMENT ON COLUMN js_gen_table.tpl_category IS '使用的模板';
COMMENT ON COLUMN js_gen_table.package_name IS '生成包路径';
COMMENT ON COLUMN js_gen_table.module_name IS '生成模块名';
@@ -1266,7 +1268,7 @@ COMMENT ON COLUMN js_sys_msg_inner_record.id IS '编号';
COMMENT ON COLUMN js_sys_msg_inner_record.msg_inner_id IS '所属消息';
COMMENT ON COLUMN js_sys_msg_inner_record.receive_user_code IS '接受者用户编码';
COMMENT ON COLUMN js_sys_msg_inner_record.receive_user_name IS '接受者用户姓名';
COMMENT ON COLUMN js_sys_msg_inner_record.read_status IS '读取状态0未送达 1读 2读)';
COMMENT ON COLUMN js_sys_msg_inner_record.read_status IS '读取状态0未送达 1读 2读)';
COMMENT ON COLUMN js_sys_msg_inner_record.read_date IS '阅读时间';
COMMENT ON COLUMN js_sys_msg_inner_record.is_star IS '是否标星';
COMMENT ON TABLE js_sys_msg_push IS '消息推送表';
@@ -1290,7 +1292,7 @@ COMMENT ON COLUMN js_sys_msg_push.push_return_msg_id IS '推送返回消息编
COMMENT ON COLUMN js_sys_msg_push.push_return_content IS '推送返回的内容信息';
COMMENT ON COLUMN js_sys_msg_push.push_status IS '推送状态0未推送 1成功 2失败';
COMMENT ON COLUMN js_sys_msg_push.push_date IS '推送时间';
COMMENT ON COLUMN js_sys_msg_push.read_status IS '读取状态0未送达 1读 2读)';
COMMENT ON COLUMN js_sys_msg_push.read_status IS '读取状态0未送达 1读 2读)';
COMMENT ON COLUMN js_sys_msg_push.read_date IS '读取时间';
COMMENT ON TABLE js_sys_msg_pushed IS '消息已推送表';
COMMENT ON COLUMN js_sys_msg_pushed.id IS '编号';
@@ -1313,7 +1315,7 @@ COMMENT ON COLUMN js_sys_msg_pushed.push_return_code IS '推送返回结果码';
COMMENT ON COLUMN js_sys_msg_pushed.push_return_msg_id IS '推送返回消息编号';
COMMENT ON COLUMN js_sys_msg_pushed.push_status IS '推送状态0未推送 1成功 2失败';
COMMENT ON COLUMN js_sys_msg_pushed.push_date IS '推送时间';
COMMENT ON COLUMN js_sys_msg_pushed.read_status IS '读取状态0未送达 1读 2读)';
COMMENT ON COLUMN js_sys_msg_pushed.read_status IS '读取状态0未送达 1读 2读)';
COMMENT ON COLUMN js_sys_msg_pushed.read_date IS '读取时间';
COMMENT ON TABLE js_sys_msg_template IS '消息模板';
COMMENT ON COLUMN js_sys_msg_template.id IS '编号';

View File

@@ -6,7 +6,7 @@
<parent>
<groupId>com.jeesite</groupId>
<artifactId>jeesite-parent</artifactId>
<version>4.0.6-SNAPSHOT</version>
<version>4.1.2-SNAPSHOT</version>
<relativePath>../../parent/pom.xml</relativePath>
</parent>
@@ -23,12 +23,38 @@
<dependencies>
<!-- JDBC device begin -->
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.3</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>net.sourceforge.jtds</groupId>
<artifactId>jtds</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<!-- JDBC device end -->
<!-- Common -->
<dependency>
<groupId>com.jeesite</groupId>
<artifactId>jeesite-common</artifactId>
<version>${project.parent.version}</version>
</dependency>
<!-- Framework -->
<dependency>
<groupId>com.jeesite</groupId>
<artifactId>jeesite-framework</artifactId>
@@ -59,41 +85,25 @@
</organization>
<repositories>
<repository>
<id>aliyun-repos</id>
<name>Aliyun Repository</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
<url>https://maven.aliyun.com/repository/public</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>false</enabled></snapshots>
</repository>
<repository>
<id>sonatype-repos</id>
<name>Sonatype Repository</name>
<url>https://oss.sonatype.org/content/groups/public</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>false</enabled></snapshots>
</repository>
<repository>
<repository>
<id>sonatype-repos-s</id>
<name>Sonatype Repository</name>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
<releases><enabled>false</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>aliyun-repos</id>
<name>Aliyun Repository</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>false</enabled></snapshots>
<url>https://maven.aliyun.com/repository/public</url>
</pluginRepository>
</pluginRepositories>
</project>

View File

@@ -0,0 +1,75 @@
/**
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
*/
package com.jeesite.autoconfigure.sys;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.jeesite.modules.sys.service.AreaService;
import com.jeesite.modules.sys.service.CompanyService;
import com.jeesite.modules.sys.service.EmpUserService;
import com.jeesite.modules.sys.service.EmployeeService;
import com.jeesite.modules.sys.service.LogService;
import com.jeesite.modules.sys.service.OfficeService;
import com.jeesite.modules.sys.service.PostService;
import com.jeesite.modules.sys.service.support.AreaServiceSupport;
import com.jeesite.modules.sys.service.support.CompanyServiceSupport;
import com.jeesite.modules.sys.service.support.EmpUserServiceSupport;
import com.jeesite.modules.sys.service.support.EmployeeServiceSupport;
import com.jeesite.modules.sys.service.support.LogServiceSupport;
import com.jeesite.modules.sys.service.support.OfficeServiceSupport;
import com.jeesite.modules.sys.service.support.PostServiceSupport;
/**
* 系统核心实现类
* @author ThinkGem
* @version 2018-10-13
*/
@Configuration
public class SysAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public AreaService areaService(){
return new AreaServiceSupport();
}
@Bean
@ConditionalOnMissingBean
public CompanyService companyService(){
return new CompanyServiceSupport();
}
@Bean
@ConditionalOnMissingBean
public EmployeeService employeeService(){
return new EmployeeServiceSupport();
}
@Bean
@ConditionalOnMissingBean
public EmpUserService empUserService(){
return new EmpUserServiceSupport();
}
@Bean
@ConditionalOnMissingBean
public LogService logService(){
return new LogServiceSupport();
}
@Bean
@ConditionalOnMissingBean
public OfficeService officeService(){
return new OfficeServiceSupport();
}
@Bean
@ConditionalOnMissingBean
public PostService postService(){
return new PostServiceSupport();
}
}

View File

@@ -0,0 +1,47 @@
/**
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
*/
package com.jeesite.common.shiro.filter;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import org.apache.shiro.web.filter.AccessControlFilter;
import com.jeesite.common.config.Global;
import com.jeesite.common.lang.StringUtils;
/**
* 内部系统访问过滤器
* @author ThinkGem
* @version 2018-11-10
*/
public class InnerFilter extends AccessControlFilter {
@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
boolean result = false;
String[] prefixes = (String[])mappedValue;
if (prefixes == null){
prefixes = StringUtils.split(Global.getProperty(
"shiro.innerFilterAllowRemoteAddrs", "127.0.0.1"), ",");
}
if (prefixes != null && request instanceof HttpServletRequest){
String ip = ((HttpServletRequest)request).getRemoteAddr();
for (String prefix : prefixes){
result = StringUtils.startsWithIgnoreCase(ip, StringUtils.trim(prefix));
if (result){
break;
}
}
}
return result;
}
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
return PermissionsAuthorizationFilter.redirectTo403Page(request, response);
}
}

View File

@@ -18,9 +18,6 @@ import com.jeesite.common.config.Global;
import com.jeesite.common.shiro.realm.BaseAuthorizingRealm;
import com.jeesite.common.shiro.realm.LoginInfo;
import com.jeesite.common.web.http.ServletUtils;
import com.jeesite.modules.sys.entity.Log;
import com.jeesite.modules.sys.utils.LogUtils;
import com.jeesite.modules.sys.utils.UserUtils;
/**
* 登出过滤器
@@ -41,16 +38,16 @@ 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{
// // 记录用户退出日志(@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);
}
// }
}
// 退出登录
subject.logout();

View File

@@ -5,6 +5,10 @@ package com.jeesite.common.shiro.realm;
import javax.servlet.http.HttpServletRequest;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import com.jeesite.common.codec.EncodeUtils;
import com.jeesite.common.codec.Sha1Utils;
import com.jeesite.common.utils.SpringUtils;
import com.jeesite.modules.sys.entity.Log;
import com.jeesite.modules.sys.entity.User;
@@ -18,11 +22,48 @@ import com.jeesite.modules.sys.utils.UserUtils;
* @version 2018-7-11
*/
public class AuthorizingRealm extends BaseAuthorizingRealm {
public static final String HASH_ALGORITHM = "SHA-1";
public static final int HASH_INTERATIONS = 1024;
public static final int SALT_SIZE = 8;
private UserService userService;
public AuthorizingRealm() {
super();
// 设定密码校验的Hash算法与迭代次数
HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(HASH_ALGORITHM);
matcher.setHashIterations(HASH_INTERATIONS);
this.setCredentialsMatcher(matcher);
}
/**
* 生成密文密码生成随机的16位salt并经过1024次 sha-1 hash
* @param plainPassword 明文密码
* @return 16位salt密钥 + 40位hash密码
*/
public String encryptPassword(String plainPassword) {
String plain = EncodeUtils.decodeHtml(plainPassword);
byte[] salt = Sha1Utils.genSalt(SALT_SIZE);
byte[] hashPassword = Sha1Utils.sha1(plain.getBytes(), salt, HASH_INTERATIONS);
return EncodeUtils.encodeHex(salt) + EncodeUtils.encodeHex(hashPassword);
}
/**
* 验证密码正确性
* @param plainPassword 明文密码
* @param password 密文密码
* @return 验证成功返回true
*/
public boolean validatePassword(String plainPassword, String password) {
try{
String plain = EncodeUtils.decodeHtml(plainPassword);
byte[] salt = EncodeUtils.decodeHex(password.substring(0, 16));
byte[] hashPassword = Sha1Utils.sha1(plain.getBytes(), salt, HASH_INTERATIONS);
return password.equals(EncodeUtils.encodeHex(salt) + EncodeUtils.encodeHex(hashPassword));
}catch(Exception e){
return false;
}
}
@Override

View File

@@ -19,8 +19,8 @@ import org.jasig.cas.client.validation.TicketValidationException;
import org.jasig.cas.client.validation.TicketValidator;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import com.beust.jcommander.internal.Maps;
import com.jeesite.common.codec.EncodeUtils;
import com.jeesite.common.collect.MapUtils;
import com.jeesite.common.lang.ObjectUtils;
import com.jeesite.common.shiro.authc.FormToken;
import com.jeesite.common.shiro.cas.CasCreateUser;
@@ -46,7 +46,6 @@ public class CasAuthorizingRealm extends BaseAuthorizingRealm {
private UserService userService;
private EmpUserService empUserService;
///////////// CAS /////////////
private CasOutHandler casOutHandler;
private String casServerUrl; // CAS 服务器地址
private String casServerCallbackUrl; // CAS 服务器回调地址
@@ -56,10 +55,7 @@ public class CasAuthorizingRealm extends BaseAuthorizingRealm {
super();
this.setAuthenticationTokenClass(CasToken.class);
}
/*
* 获取登录令牌
*/
@Override
protected FormToken getFormToken(AuthenticationToken authcToken) {
@@ -98,16 +94,13 @@ public class CasAuthorizingRealm extends BaseAuthorizingRealm {
// 生成登录信息对象
FormToken token = new FormToken();
token.setUsername(casPrincipal.getName());
Map<String, Object> params = Maps.newHashMap();
Map<String, Object> params = MapUtils.newHashMap();
params.putAll(casPrincipal.getAttributes());
params.put("ticket", ticket);
token.setParams(params);
return token;
}
/*
* 获取用户信息
*/
@Override
protected User getUserInfo(FormToken token) {
@@ -117,7 +110,7 @@ public class CasAuthorizingRealm extends BaseAuthorizingRealm {
// 如果允许客户端创建账号,则创建账号
if (ObjectUtils.toBoolean(attrs.get("isAllowClientCreateUser"))){
// 获取CAS传递过来的用户属性信息
user = new User(EncodeUtils.decodeUrl(ObjectUtils.toString(attrs.get("userCode"))));
user.setLoginCode(EncodeUtils.decodeUrl(ObjectUtils.toString(attrs.get("loginCode"))));
@@ -178,9 +171,6 @@ public class CasAuthorizingRealm extends BaseAuthorizingRealm {
return user;
}
/*
* 认证密码匹配调用方法
*/
@Override
protected void assertCredentialsMatch(AuthenticationToken authcToken,
AuthenticationInfo info) throws AuthenticationException {

View File

@@ -27,6 +27,7 @@ import com.jeesite.common.shiro.cas.CasOutHandler;
import com.jeesite.common.shiro.config.FilterChainDefinitionMap;
import com.jeesite.common.shiro.filter.CasAuthenticationFilter;
import com.jeesite.common.shiro.filter.FormAuthenticationFilter;
import com.jeesite.common.shiro.filter.InnerFilter;
import com.jeesite.common.shiro.filter.LogoutFilter;
import com.jeesite.common.shiro.filter.PermissionsAuthorizationFilter;
import com.jeesite.common.shiro.filter.RolesAuthorizationFilter;
@@ -54,12 +55,19 @@ public class ShiroConfig {
@Bean
@Order(3000)
@ConditionalOnMissingBean(name="shiroFilterProxy")
public FilterRegistrationBean shiroFilterProxy(ShiroFilterFactoryBean shiroFilter) throws Exception {
FilterRegistrationBean bean = new FilterRegistrationBean();
public FilterRegistrationBean<Filter> shiroFilterProxy(ShiroFilterFactoryBean shiroFilter) throws Exception {
FilterRegistrationBean<Filter> bean = new FilterRegistrationBean<>();
bean.setFilter((Filter) shiroFilter.getInstance());
bean.addUrlPatterns("/*");
return bean;
}
/**
* 内部系统访问过滤器
*/
private InnerFilter shiroInnerFilter() {
return new InnerFilter();
}
/**
* CAS登录过滤器
@@ -120,6 +128,7 @@ public class ShiroConfig {
bean.setLoginUrl(Global.getProperty("shiro.loginUrl"));
bean.setSuccessUrl(Global.getProperty("adminPath")+"/index");
Map<String, Filter> filters = bean.getFilters();
filters.put("inner", shiroInnerFilter());
filters.put("cas", shiroCasFilter(casAuthorizingRealm));
filters.put("authc", shiroAuthcFilter(authorizingRealm));
filters.put("logout", shiroLogoutFilter(authorizingRealm));

View File

@@ -18,15 +18,15 @@ import com.alibaba.druid.support.http.WebStatFilter;
* @version 2017年11月30日
*/
@Configuration
@ConditionalOnProperty(name="druid.stat.enabled", havingValue="true", matchIfMissing=true)
@ConditionalOnProperty(name="state.enabled", havingValue="true", matchIfMissing=true)
public class DruidStatConfig {
/**
* 注册DruidFilter拦截
*/
@Bean
public FilterRegistrationBean duridFilter() {
FilterRegistrationBean bean = new FilterRegistrationBean();
public FilterRegistrationBean<WebStatFilter> duridFilter() {
FilterRegistrationBean<WebStatFilter> bean = new FilterRegistrationBean<>();
bean.setFilter(new WebStatFilter());
bean.addInitParameter("exclusions", "*.css,*.js,*.png,"
+ "*.jpg,*.gif,*.jpeg,*.bmp,*.ico,*.swf,*.psd,*.htc,*.htm,*.html,"
@@ -40,8 +40,8 @@ public class DruidStatConfig {
* 注册DruidServlet
*/
@Bean
public ServletRegistrationBean druidServlet() {
ServletRegistrationBean bean = new ServletRegistrationBean();
public ServletRegistrationBean<StatViewServlet> druidServlet() {
ServletRegistrationBean<StatViewServlet> bean = new ServletRegistrationBean<>();
bean.setServlet(new StatViewServlet());
bean.addUrlMappings("/druid/*");
return bean;

View File

@@ -3,42 +3,45 @@
*/
package com.jeesite.modules.config.web;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import com.jeesite.common.config.Global;
import com.jeesite.common.web.PageCachingFilter;
/**
* Filter 配置
* 页面缓存,如果需要,则加入如下依赖并取消下面注释
1、pom.xml:
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-web</artifactId>
<version>2.0.4</version>
</dependency>
2、application.yml:
# 页面缓存配置
ehcache:
pageCaching:
enabled: false
urlPatterns: "*.html"
* @author ThinkGem
* @version 2017年11月30日
*/
@Configuration
//@Configuration
public class PageCacheConfig {
/**
* PageCache Filter, cache .html suffix.
*/
@Bean
@Order(2000)
@ConditionalOnProperty(name = "ehcache.pageCaching.enabled", havingValue = "true")
@ConditionalOnMissingBean(name="pageCachingFilter")
public FilterRegistrationBean pageCachingFilter(EhCacheManagerFactoryBean ehCacheManager) {
FilterRegistrationBean bean = new FilterRegistrationBean();
PageCachingFilter pageCachingFilter = new PageCachingFilter();
pageCachingFilter.setCacheManager(ehCacheManager.getObject());
bean.setFilter(pageCachingFilter);
bean.addInitParameter("cacheName", "pageCachingFilter");
bean.addUrlPatterns(StringUtils.split(Global.getProperty(
"ehcache.pageCaching.urlPatterns"), ","));
return bean;
}
// /**
// * PageCache Filter, cache .html suffix.
// */
// @Bean
// @Order(2000)
// @ConditionalOnProperty(name = "ehcache.pageCaching.enabled", havingValue = "true")
// @ConditionalOnMissingBean(name="pageCachingFilter")
// public FilterRegistrationBean<PageCachingFilter> pageCachingFilter(EhCacheManagerFactoryBean ehCacheManager) {
// FilterRegistrationBean<PageCachingFilter> bean = new FilterRegistrationBean<>();
// SimplePageCachingFilter pageCachingFilter = new SimplePageCachingFilter();
// pageCachingFilter.setCacheManager(ehCacheManager.getObject());
// bean.setFilter(pageCachingFilter);
// bean.addInitParameter("cacheName", "pageCachingFilter");
// bean.addUrlPatterns(StringUtils.split(Global.getProperty(
// "ehcache.pageCaching.urlPatterns"), ","));
// return bean;
// }
}

View File

@@ -8,7 +8,7 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import com.jeesite.common.config.Global;
import com.jeesite.common.lang.StringUtils;
@@ -22,7 +22,7 @@ import com.jeesite.modules.sys.interceptor.LogInterceptor;
@Configuration
@EnableWebMvc
@ConditionalOnProperty(name="web.interceptor.log.enabled", havingValue="true", matchIfMissing=true)
public class LogInterceptorConfig extends WebMvcConfigurerAdapter {
public class LogInterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {

View File

@@ -8,7 +8,7 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import com.jeesite.common.config.Global;
import com.jeesite.common.lang.StringUtils;
@@ -22,7 +22,7 @@ import com.jeesite.modules.sys.interceptor.MobileInterceptor;
@Configuration
@EnableWebMvc
@ConditionalOnProperty(name="web.interceptor.mobile.enabled", havingValue="true", matchIfMissing=false)
public class MobileViewInterceptorConfig extends WebMvcConfigurerAdapter {
public class MobileViewInterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {

View File

@@ -86,7 +86,7 @@ public class InitCoreData extends BaseInitDataTests {
/**
* 区域、行政区划表
*/
public void initArea() throws Exception{
public void initArea(String... prefixes) throws Exception{
clearTable(Area.class);
initExcelData(Area.class, new MethodCallback() {
@Override
@@ -95,7 +95,10 @@ public class InitCoreData extends BaseInitDataTests {
if("save".equals(action)){
Area entity = (Area)params[1];
entity.setIsNewRecord(true);
areaService.save(entity);
if (prefixes == null || prefixes.length == 0
|| StringUtils.startsWithAny(entity.getAreaCode(), prefixes)){
areaService.save(entity);
}
return null;
}
return null;

View File

@@ -4,7 +4,7 @@
package com.jeesite.modules.sys.entity;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.NotBlank;
import com.jeesite.common.entity.DataEntity;
import com.jeesite.common.entity.TreeEntity;

View File

@@ -9,7 +9,7 @@ import javax.validation.constraints.Pattern;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.NotBlank;
import com.jeesite.common.collect.ListUtils;
import com.jeesite.common.entity.BaseEntity;

View File

@@ -61,7 +61,9 @@ import com.jeesite.common.utils.excel.fieldtype.OfficeType;
@Column(name="area_name", label="区域名称", isQuery=false),
@Column(name="area_type", label="区域类型"),
}),
}, extWhereKeys="dsfOffice, dsfCompany", orderBy="a.user_weight DESC, a.update_date DESC"
},
extWhereKeys="dsfOffice, dsfCompany",
orderBy="a.user_weight DESC, a.update_date DESC"
)
public class EmpUser extends User {

View File

@@ -7,7 +7,7 @@ import java.util.Map;
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.NotBlank;
import com.jeesite.common.collect.MapUtils;
import com.jeesite.common.entity.BaseEntity;

View File

@@ -6,7 +6,7 @@ package com.jeesite.modules.sys.entity;
import javax.validation.constraints.Pattern;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.NotBlank;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.jeesite.common.entity.BaseEntity;
@@ -47,7 +47,7 @@ public class Office extends TreeEntity<Office> {
private String viewCode; // 机构代码(作为显示用,多租户内唯一)
private String officeName; // 机构名称
private String fullName; // 机构全称
private String officeType; // 机构类型1公司2部门3小组
private String officeType; // 机构类型1省级公司2市级公司3部门
private String leader; // 负责人
private String phone; // 电话
private String address; // 联系地址

View File

@@ -4,7 +4,7 @@
package com.jeesite.modules.sys.entity;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.NotBlank;
import com.jeesite.common.entity.BaseEntity;
import com.jeesite.common.entity.DataEntity;
@@ -16,7 +16,7 @@ import com.jeesite.common.mybatis.mapper.query.QueryType;
@Column(includeEntity=BaseEntity.class),
@Column(includeEntity=DataEntity.class),
@Column(name="post_code", attrName="postCode", label="岗位编码", isPK=true),
@Column(name="post_name", attrName="postName", label="岗位名称", queryType=QueryType.LIKE),
@Column(name="post_name", attrName="postName", label="岗位名称"),
@Column(name="post_type", attrName="postType", label="岗位分类", comment="岗位分类(高管、中层、基层)"),
@Column(name="post_sort", attrName="postSort", label="岗位排序", comment="岗位排序(升序)"),
}, orderBy="a.update_date DESC"
@@ -57,6 +57,14 @@ public class Post extends DataEntity<Post> {
this.postName = postName;
}
public String getPostName_like() {
return getSqlMap().getWhere().getValue("post_name", QueryType.LIKE);
}
public void setPostName_like(String roleName) {
getSqlMap().getWhere().and("post_name", QueryType.LIKE, roleName);
}
@Length(min=0, max=100, message="岗位分类长度不能超过 100 个字符")
public String getPostType() {
return postType;

View File

@@ -5,57 +5,38 @@ package com.jeesite.modules.sys.service;
import java.util.List;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.jeesite.common.service.TreeService;
import com.jeesite.modules.sys.dao.AreaDao;
import com.jeesite.common.service.api.TreeServiceApi;
import com.jeesite.modules.sys.entity.Area;
import com.jeesite.modules.sys.utils.AreaUtils;
/**
* 行政区划Service
* @author ThinkGem
* @version 2014-8-19
*/
@Service
@Transactional(readOnly=true)
public class AreaService extends TreeService<AreaDao, Area> {
public interface AreaService extends TreeServiceApi<Area> {
/**
* 获取区划
*/
@Override
public Area get(Area area) {
return super.get(area);
}
public Area get(Area area);
/**
* 查询区划
*/
@Override
public List<Area> findList(Area area) {
return super.findList(area);
}
public List<Area> findList(Area area);
/**
* 保存区划
*/
@Override
@Transactional(readOnly=false)
public void save(Area area) {
super.save(area);
AreaUtils.clearCache();
}
public void save(Area area);
/**
* 删除区划
*/
@Override
@Transactional(readOnly=false)
public void delete(Area area) {
super.delete(area);
AreaUtils.clearCache();
}
public void delete(Area area);
}

View File

@@ -5,112 +5,50 @@ package com.jeesite.modules.sys.service;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.jeesite.common.collect.ListUtils;
import com.jeesite.common.service.TreeService;
import com.jeesite.modules.sys.dao.CompanyDao;
import com.jeesite.modules.sys.dao.CompanyOfficeDao;
import com.jeesite.common.service.api.TreeServiceApi;
import com.jeesite.modules.sys.entity.Company;
import com.jeesite.modules.sys.entity.CompanyOffice;
import com.jeesite.modules.sys.utils.EmpUtils;
/**
* 公司管理Service
* @author thinkgem
* @author ThinkGem
* @version 2016-4-23
*/
@Service
@Transactional(readOnly=true)
public class CompanyService extends TreeService<CompanyDao, Company> {
public interface CompanyService extends TreeServiceApi<Company> {
@Autowired
private CompanyOfficeDao companyOfficeDao;
@Autowired
private DataScopeService dataScopeService;
/**
* 获取单条数据
*/
@Override
public Company get(Company company) {
return super.get(company);
}
public Company get(Company company);
/**
* 添加数据权限过滤条件
*/
@Override
public void addDataScopeFilter(Company company, String ctrlPermi) {
company.getSqlMap().getDataScope().addFilter("dsf", "Company", "a.company_code", ctrlPermi);
}
public void addDataScopeFilter(Company company, String ctrlPermi);
/**
* 查询公司列表
*/
@Override
public List<Company> findList(Company company) {
return super.findList(company);
}
public List<Company> findList(Company company);
/**
* 保存公司
*/
@Override
@Transactional(readOnly=false)
public void save(Company company) {
if (company.getIsNewRecord()){
genIdAndValid(company, company.getViewCode());
// 当前新数据授权,如果用户有上级数据权限,则当前数据也有相应的数据权限
dataScopeService.insertIfParentExists(company, "Company");
}
super.save(company);
// 重新绑定组织和公司之间的关系
if (StringUtils.isBlank(company.getCompanyCode())){
return;
}
CompanyOffice where = new CompanyOffice();
where.setCompanyCode(company.getCompanyCode());
companyOfficeDao.deleteByEntity(where);
if (ListUtils.isNotEmpty(company.getCompanyOfficeList())){
companyOfficeDao.insertBatch(company.getCompanyOfficeList());
}
// 清理公司相关缓存
clearCompanyCache();
}
public void save(Company company);
/**
* 删除公司
*/
@Override
@Transactional(readOnly=false)
public void delete(Company company) {
super.delete(company);
// 清理公司相关缓存
clearCompanyCache();
}
public void delete(Company company);
/**
* 停用当前节点
*/
@Override
@Transactional(readOnly=false)
public void updateStatus(Company company) {
dao.updateStatus(company);
// 清理公司相关缓存
clearCompanyCache();
}
/**
* 清理公司相关缓存
*/
private void clearCompanyCache(){
// EmpUtils.removeCache(EmpUtils.CACHE_COMPANY_LIST);
EmpUtils.removeCache(EmpUtils.CACHE_COMPANY_ALL_LIST);
}
public void updateStatus(Company company);
}

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