Compare commits

...

143 Commits

Author SHA1 Message Date
thinkgem
9678b6e8b7 Merge branch 'master' of https://gitee.com/thinkgem/jeesite4.git 2019-05-20 18:22:37 +08:00
thinkgem
dd9e400f6a 添加jta在oracle下设置授权的提示信息 2019-05-18 00:35:59 +08:00
thinkgem
2de70e79ae 注意:@MyBatisDao如果不设置dataSourceName,则为default默认数据源,如果需要使用DataSourceHolder.setDataSourceName设置数据源,请将设置该注解属性设置为dataSourceName=DataSourceHolder.EMPTY 2019-05-17 23:16:01 +08:00
thinkgem
5248cf9a68 关闭jta事务最大超时时间限制 2019-05-17 18:53:29 +08:00
thinkgem
51a83b70a3 修正国际化遗留问题 2019-05-17 18:52:53 +08:00
thinkgem
1b66126184 jquery.validate新增重置验证方法,将valid替换为resetValid用户体验会更好 2019-05-16 16:10:48 +08:00
thinkgem
a2d9c846bf 代码优化 2019-05-14 23:09:04 +08:00
thinkgem
5da0520832 新增用户和组织管理功能的,控制权限类型设置user.adminCtrlPermi,1拥有的权限 2管理的权限,无限级授权应用场景使用 2019-05-13 17:49:02 +08:00
thinkgem
aae461a0b4 新增全局默认事务超时时间参数
jdbc.transactionTimeout,原jdbc.jta.transactionTimeout参数可不用配置了。
2019-05-13 17:42:15 +08:00
thinkgem
eb218f7973 开放所有国际化语言包,方便用户自定义语言包。 2019-05-10 23:52:20 +08:00
thinkgem
2d80ce3bda 开放所有国际化语言包,方便用户自定义语言包。 2019-05-10 23:48:44 +08:00
thinkgem
42b36a5377 新增日语(日本语)语言包 2019-05-09 23:11:22 +08:00
thinkgem
720148bea7 增加favicon网页收藏图标,可自行替换修改。 2019-05-09 14:27:04 +08:00
thinkgem
ff462950bd 用户管理新增附属机构配置,支持一个用户配置多个部门,支持多部门数据权限过滤 2019-05-08 17:07:45 +08:00
thinkgem
00cc2fa797 暂时注释掉无用的jquery-migrate-1.4.1.min.js,如果你需要可以放开注释。 2019-05-08 16:58:59 +08:00
thinkgem
b0d66960a8 ReflectUtils.invokeGetter支持静态类及方法调用 2019-05-08 16:58:08 +08:00
thinkgem
e123d96465 js.formatNumber优化,传递0数值的时候返回0.00,传递null的时候返回默认值。 2019-05-07 22:25:47 +08:00
thinkgem
7b4ca62ce8 文件上传组件新增 cueWords 提示语属性,默认:或将照片(文件)拖到这里,最多可选 maxUploadNum 张(个) 2019-05-07 17:29:39 +08:00
thinkgem
df74e417e8 点击右上角【Star】收藏本软件 ^_^ 2019-05-06 13:38:04 +08:00
thinkgem
fe7637a110 点击右上角【Star】收藏本软件 ^_^ 2019-05-06 13:36:13 +08:00
thinkgem
b71d2502ef 国际化译文细节优化 2019-05-06 10:37:24 +08:00
thinkgem
2792531a7d 角色数据权限配置,支持返回数组的情况,在一个用户多个部门的场景下使用。 2019-05-05 22:08:20 +08:00
thinkgem
04781bed25 记住密码 文字改为 自动登录 2019-05-05 16:42:00 +08:00
thinkgem
b82217e624 新增 web.strictMode,提供更严格的数据安全验证 2019-05-05 15:43:52 +08:00
thinkgem
3c92f26684 优化ServletUtils.renderResult 2019-05-05 15:41:52 +08:00
thinkgem
c31259d5c8 错别字修正,请稍后->请稍候 2019-05-05 15:41:20 +08:00
thinkgem
36dd4c70bc 增加web严格模式 web.strictMode=false(更严格的数据安全验证,如isAll=true这种参数形式将被禁用) 2019-05-01 23:49:59 +08:00
thinkgem
ddc8510479 会话过期后顶部菜单点击后显示json的代码优化 2019-04-29 08:36:15 +08:00
thinkgem
ac4c9f932d 编辑表格子表的表头增加新增按钮实例 2019-04-28 15:31:13 +08:00
thinkgem
9aa599fb0b 新增Docker部署脚本实例 2019-04-27 21:41:18 +08:00
thinkgem
1b0099c831 update 2019-04-24 22:45:58 +08:00
ThinkGem
fca4902a38 优化 File.downFile 如果传递 source=preview 则不添加 attachment 内容描述 2019-04-23 21:07:21 +08:00
thinkgem
59e1792467 优化 File.downFile 如果传递 source=preview 则不添加 attachment 内容描述 2019-04-23 20:22:38 +08:00
thinkgem
73ac352219 修复jQuery原型污染漏洞 ThinkGem 2019-04-23 20:21:03 +08:00
thinkgem
722029e555 update 2019-04-23 09:51:31 +08:00
thinkgem
2ce0eb76be 完成文件管理数据库初始化脚本 2019-04-22 16:50:36 +08:00
thinkgem
2d9548aa90 ListUtils.getPageList改为公共方法 2019-04-21 17:47:12 +08:00
thinkgem
1d31c9fcef 降级maven-surefire插件,新版本可能会出现VM崩溃。 2019-04-21 17:43:23 +08:00
thinkgem
9c8ae36924 优化代码 2019-04-18 18:15:40 +08:00
thinkgem
88a9b11859 静态资源路径前缀,可做CDN加速优化 2019-04-17 17:48:27 +08:00
thinkgem
72b536a4d5 DateUtils getOfDayFirst getOfDayLast 24小时制修正 2019-04-17 16:08:14 +08:00
thinkgem
e9763efaa7 新增文件管理模块 2019-04-11 22:38:34 +08:00
thinkgem
532ca319ec update 2019-04-11 10:54:44 +08:00
thinkgem
9c0fc71587 优化init-data 2019-04-11 10:50:22 +08:00
thinkgem
16ba2c92a0 优化对 .json .xml 后缀的URI会话失效后传递支持。 2019-04-08 10:04:24 +08:00
thinkgem
0729db8ae8 start 4.1.5 2019-04-01 16:43:10 +08:00
thinkgem
e1be50a2e6 jta开启情况下支持初始化db 2019-03-29 16:01:08 +08:00
thinkgem
6f5b7ee120 @Table单元测试类优化 2019-03-27 11:37:31 +08:00
thinkgem
c010df1fb6 我的工作内部消息菜单图标修改 2019-03-22 10:23:30 +08:00
thinkgem
5b16c6c3d2 当adminPath修改过后,发送通知的地址不正确问题 2019-03-21 18:09:30 +08:00
thinkgem
3b0060c300 初始化数据库脚本小优化 2019-03-21 17:04:36 +08:00
thinkgem
9cf1b944db 修正站内信Oracle下ORA-00932错误 2019-03-21 16:57:36 +08:00
thinkgem
5ff356665f 修正主子表示例,删除的时候子表数据未删除问题 2019-03-21 16:40:08 +08:00
thinkgem
61e56671a9 Merge branch 'v4.1_dev'
# Conflicts:
#	modules/core/src/main/resources/i18n/core/common/i18n_en.properties
2019-03-20 22:30:03 +08:00
thinkgem
7ccd4f09a0 v4.1.4 2019-03-20 20:58:15 +08:00
thinkgem
b0676503ee update 2019-03-20 17:43:13 +08:00
thinkgem
49e503809e beetl升级到2.9.8 2019-03-20 13:38:03 +08:00
thinkgem
a22539808f 新增内部消息站内信功能。 2019-03-20 10:53:30 +08:00
thinkgem
b6c992787d 新增内部消息站内信功能。 2019-03-19 23:49:01 +08:00
thinkgem
fce1cf8082 将消息推送实现类移动到core项目下。 2019-03-18 23:22:09 +08:00
thinkgem
c50d07b949 EmpUserService添加获取用户最基本的信息API。 2019-03-18 22:52:12 +08:00
thinkgem
8827d04222 jqgrid新增“没有符合数据”示例 2019-03-18 22:45:56 +08:00
thinkgem
88d0615c4a 基础组件(输入框、单选按钮、复选框、下拉框)的边框颜色加重一点 2019-03-18 22:45:24 +08:00
thinkgem
5fd3547aa2 update 2019-03-18 15:49:05 +08:00
thinkgem
d5f42ee183 岗位排序修正 2019-03-13 18:35:47 +08:00
thinkgem
fb12bde120 用户管理点击左侧树节点时reset按钮调用不对问题 2019-03-12 22:32:30 +08:00
thinkgem
23b2aab97c 文字修正:保密->密保 2019-03-12 14:51:48 +08:00
thinkgem
57a00dfb97 文件上传控件增加fileMeta字段,用来存在文件信息,例如图片可存储宽高,用来做瀑布流式布局。 2019-03-11 10:23:01 +08:00
thinkgem
2dc8e6a675 支持fileupload分片上传,多线程上传(默认关闭) 2019-03-08 22:55:01 +08:00
thinkgem
0c9e3bf92f 解决用户为中午的时候报错到cookie乱码问题。#IS654 2019-03-07 23:27:04 +08:00
thinkgem
8aa9700ae5 mybatis返回值为Map时,当返回空值字段时,仍然需要返回这个Key 2019-03-07 21:17:45 +08:00
thinkgem
3aa20f63d0 取消Shiro内部密码验证,统一使用validatePassword密码验证方法,简化密码存储的个性化修改。 2019-03-05 23:27:46 +08:00
thinkgem
ee9f3fd580 job添加instanceName集群的实例名字段,与yml配置文件一致,在微服务模块中使用非常重要;优化job目标字符串中包含单引号的时候XSS问题;若你重写了jobForm.html你需要同步下次此文件;若你在yml中修改了instanceName名字,你需要更新下sys_job的instanceName字段为你修改的名字。 2019-03-05 22:10:09 +08:00
thinkgem
2e4ca4b2ad JTA事物超时默认设置3分钟示例 2019-02-28 23:16:22 +08:00
thinkgem
2ce628456f remove file_md5 unique index 2019-02-27 21:40:06 +08:00
thinkgem
85790225af 登录地址支持传递__url参数,指定登录后跳转的页面。 2019-02-27 21:37:49 +08:00
thinkgem
3a5c9fc5c9 update 2019-02-26 22:07:57 +08:00
thinkgem
ff063e81ee update 2019-02-26 22:03:25 +08:00
thinkgem
b7d29d4e98 update 2019-02-24 20:44:44 +08:00
thinkgem
2720470436 添加是否允许接收跨域的Cookie凭证数据配置参数。 2019-02-23 15:14:39 +08:00
thinkgem
c594f02dfd 删掉多余的idx_sys_msg_inner_r_rc索引 2019-02-23 15:13:35 +08:00
thinkgem
83dae7c0a1 代码生成器新增BigDecimal数据类型 2019-02-21 22:53:37 +08:00
thinkgem
bd19bd2445 update 2019-02-21 22:16:18 +08:00
thinkgem
97f460448b 初始化数据库时,默认情况下job是关闭状态,导致注入jobService失败,需要注入jobDao 2019-02-18 23:07:00 +08:00
thinkgem
a28ac15194 优化XSS正则表达式 2019-02-16 14:35:51 +08:00
thinkgem
1d5c90ca06 主框架页PC消息提醒增加提示音。 2019-02-13 20:14:33 +08:00
thinkgem
fa562d955d v4.1.3 2019-02-12 20:36:30 +08:00
thinkgem
b0c67108d4 update config 2019-02-10 22:38:05 +08:00
thinkgem
7d2615be5d 新增参数配置 sys.index.menuStyle=2 的时候,一级菜单显示在主框架页顶部。 2019-02-05 21:04:49 +08:00
thinkgem
2a5857645b 点击侧边栏头像隐藏header部分,扩大操作区域。 2019-02-04 20:59:32 +08:00
thinkgem
cd6c655ff5 sys_config的config_key字段设置为唯一约束属性 2019-02-04 17:22:31 +08:00
thinkgem
914242ad88 将sysDesktop中的echarts替换为本地资源文件 2019-02-04 17:05:13 +08:00
thinkgem
e2c546cc62 js.text()的语言配置文件移动到core项目下 2019-02-04 17:04:13 +08:00
thinkgem
006d34792f 新增 lang.defaultLocale 和 lang.defaultTimeZone
指定默认语言和默认时区参数(解决某些linux下的国际化的问题)
2019-02-03 21:58:09 +08:00
thinkgem
e1d47099b6 优化脚本 2019-02-03 21:56:32 +08:00
thinkgem
0cc00091ca 默认关闭lang和job较少运维(4.1.3+) 2019-01-30 20:38:26 +08:00
thinkgem
bd63181299 修正新增子级公司的时候选择的包含机构数据无法保存问题 2019-01-26 15:25:50 +08:00
thinkgem
727c2fcf3c 修正主子表情况下,子表点击删除按钮,但不点击确认删除,保存之后仍会删除
https://gitee.com/thinkgem/jeesite4/issues/IRDVT
2019-01-24 21:07:08 +08:00
thinkgem
038e89316a 修正账号登录安全选项锁定账号失效的问题 2019-01-23 20:55:23 +08:00
thinkgem
b57ae4930b open sso controller 2019-01-14 22:06:18 +08:00
thinkgem
846864622f update 2019-01-14 22:05:08 +08:00
thinkgem
ce5aa1c5c3 优化代码生成模板和默认设置,另修正当没有status字段时误导入了DataEntity的问题。 2019-01-10 22:33:46 +08:00
thinkgem
c9d513111f 取消页签模式下不显示字典数据的新增按钮问题 2019-01-10 20:09:37 +08:00
thinkgem
da9ff38b1b add bootstrap.yml load. 2019-01-10 20:07:07 +08:00
thinkgem
2af14b2244 fileupload组件新增extendParams扩展参数,附加数据,方便后台做出相应处理;新增ImageUtils工具类生成缩略图;Ueditor新增StorageManager.uploadFileSuccess方法,方便写上传文件后回调。 2019-01-07 21:37:11 +08:00
thinkgem
8d46bf2e9d update 2019-01-06 19:59:36 +08:00
thinkgem
3e7ed978a3 日志输出格式优化 2019-01-05 19:25:20 +08:00
thinkgem
9cb50983dd 新增可编辑的Grid列表选择组件应用示例。 2019-01-01 19:59:22 +08:00
thinkgem
307a860060 update 2018-12-31 23:19:28 +08:00
thinkgem
4147a940e1 移除极少使用的metadata-extractor图片Meta获取类库,若有需要可自行添加该类库。 2018-12-31 16:37:50 +08:00
thinkgem
d22fe96763 start v4.1.3 2018-12-30 16:56:40 +08:00
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
256 changed files with 12574 additions and 11706 deletions

View File

@@ -877,4 +877,4 @@ For more information on this, and how to apply and follow the GNU AGPL, see
理解您的用意。
5. 在延伸的代码中(修改和有源代码衍生的代码中)需要带有原来代码中的协议、版权声明和其他
原作者规定需要包含的说明(请尊重原作者的著作权,不要删除或修改文件中的`@author`信息)。
6. 您可以应用于商业软件,但必须遵循以上条款原则(请协助改进本作品)。
6. 您可以应用于商业软件,但必须遵循以上条款原则(请协助改进本作品 http://jeesite.com)。

View File

@@ -1,29 +1,27 @@
## 引言
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 1.x 自 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.x的升级作者结合了多年总结和经验以及各方面的应用案例对架构完成了一次全部重构也纳入很多新的思想。不管是从开发者模式、底层架构、逻辑处理还是到用户界面用户交互体验上都有很大的进步在不忘学习成本、提高开发效率的情况下安全方面也做和很多工作包括身份认证、密码策略、安全审计、日志收集。
JeeSite 4.x 的升级,作者结合了多年总结和经验,以及各方面的应用案例,对架构完成了一次全部重构,也纳入很多新的思想。不管是从开发者模式、底层架构、逻辑处理还是到用户界面,用户交互体验上都有很大的进步,在不忘学习成本、提高开发效率的情况下,安全方面也做和很多工作,包括:身份认证、密码策略、安全审计、日志收集。
### 4.x 新特性:<http://jeesite4.mydoc.io/?t=281645>
* **我们的优势:** 整体架构清晰、稳定技术先进、入门简单、易于维护、易于扩展、安全稳定。
### 4.x 新特性及优势<http://jeesite.com/?t=281645>
## 技术选型
* 主框架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
* 视图层Spring MVC 5.0、Beetl 2.9 替换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
* 技术选型详情:<http://jeesite4.mydoc.io/?t=273599>
* 技术选型详情:<http://jeesite.com/?t=273599>
## 内置功能
* <http://jeesite4.mydoc.io/?t=270187>
* <http://jeesite.com/?t=270187>
## 生态系统
@@ -47,38 +45,16 @@ JeeSite 自开源以来已被广大爱好者用到了企业、政府、医疗、
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://jeesite.com/?t=284210>
### 开发环境
1. 部署运行:<http://jeesite4.mydoc.io/?t=267354>
2. 常见问题:<http://jeesite4.mydoc.io/?t=284210>
1. 部署运行:<http://jeesite.com/?t=267354>
2. 常见问题:<http://jeesite.com/?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.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升级这里我们会附加一个声明帮助你进行迁移操作。
* <http://docs.jeesite.com>
## 授权协议声明
@@ -89,11 +65,13 @@ JeeSite的小版本4.1.x升级是非常便捷的你只需要将 pom.xml
5. 在延伸的代码中(修改和有源代码衍生的代码中)需要带有原来代码中的协议、版权声明和其他原作者规定需要包含的说明(请尊重原作者的著作权,不要删除或修改文件中的`@author`信息)。
6. 您可以应用于商业软件,但必须遵循以上条款原则(请协助改进本作品)。
7. 关系平台的发展战略考虑,底层部分代码暂未开源,但这不影响您的二次开发。
8. 请知悉社区版用户数不可超过100个最大允许10个用户同时在线不含匿名
8. 请知悉社区版用户数不可超过100个最大允许20个用户同时在线不含匿名
### 获得技术服务支持<http://jeesite4.mydoc.io/?t=267685>
## 技术服务支持
* 随着JeeSite发展我们也需要有相应的资金支持才能持续的开发和维护。支持我们,您可以得到一些回报,我们有了这些也会把开源事业做的更好,请给我们一些动力吧,谢谢您的支持
* 没有资金的支撑就很难得到发展,特别是一个好的产品,如果 JeeSite 帮助了您,请为我们点赞。支持我们,您可以得到一些回报,有了这些我们会把公益事业做的更好,回报社区和社会,请给我们一些动力吧,在此非常感谢已支持我们的朋友
* **联系方式官方商务QQ[1766571055](http://sighttp.qq.com/msgrd?v=1&uin=1766571055)**
* 技术服务支持网页:<http://s.jeesite.com>
# 技术交流方式
@@ -102,12 +80,25 @@ JeeSite的小版本4.1.x升级是非常便捷的你只需要将 pom.xml
* 码云Gitee<https://gitee.com/thinkgem/jeesite4>
* GitHub<https://github.com/thinkgem/jeesite4>
* 作者博客:<https://my.oschina.net/thinkgem>
* **技术服务:**<http://s.jeesite.com>
* 官方网站:<http://jeesite.com>
* 官方论坛:<http://jeesite.net>
* 微信公众号:
![JeeSite4微信公众号](https://static.oschina.net/uploads/space/2018/0302/145133_OGZf_941661.jpg "JeeSite4微信公众号")
## 今后如何升级?
尽量不修改web项目以外的源码项目如 jeesite-common、jeesite-modele-core如果修改了请 Pull Requests 上来,否则代码编码将与官方不同步,将对你的日后升级带来困难。
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升级这里我们会附加一个声明帮助你进行迁移操作更新日志<http://jeesite.com/?t=273830>
# Git 全局设置技巧
```

View File

@@ -6,7 +6,7 @@
<parent>
<groupId>com.jeesite</groupId>
<artifactId>jeesite-parent</artifactId>
<version>4.1.1-SNAPSHOT</version>
<version>4.1.5-SNAPSHOT</version>
<relativePath>../parent/pom.xml</relativePath>
</parent>
@@ -138,18 +138,24 @@
<version>${UserAgentUtils.version}</version>
</dependency>
<!-- 图片Meta获取 -->
<!-- 图片Meta获取
<dependency>
<groupId>com.drewnoakes</groupId>
<artifactId>metadata-extractor</artifactId>
<version>${metadata-extractor.version}</version>
</dependency>
</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>

View File

@@ -192,7 +192,7 @@ public class EncodeUtils {
Pattern.compile("(<\\s*(script|link|style|iframe)([\\s\\S]*?)(>|<\\/\\s*\\1\\s*>))|(</\\s*(script|link|style|iframe)\\s*>)", Pattern.CASE_INSENSITIVE),
Pattern.compile("\\s*(href|src)\\s*=\\s*(\"\\s*(javascript|vbscript):[^\"]+\"|'\\s*(javascript|vbscript):[^']+'|(javascript|vbscript):[^\\s]+)\\s*(?=>)", Pattern.CASE_INSENSITIVE),
Pattern.compile("\\s*on[a-z]+\\s*=\\s*(\"[^\"]+\"|'[^']+'|[^\\s]+)\\s*(?=>)", Pattern.CASE_INSENSITIVE),
Pattern.compile("(eval\\((.|\\n)*\\)|xpression\\((.|\\n)*\\))", Pattern.CASE_INSENSITIVE)
Pattern.compile("(eval\\((.*?)\\)|xpression\\((.*?)\\))", Pattern.CASE_INSENSITIVE)
);
/**
@@ -232,12 +232,12 @@ public class EncodeUtils {
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;
@@ -255,7 +255,7 @@ public class EncodeUtils {
// 预编译SQL过滤正则表达式
private static Pattern sqlPattern = Pattern.compile("(?:')|(?:--)|(/\\*(?:.|[\\n\\r])*?\\*/)|(\\b(select|update|and|or|delete|insert|trancate|char|into|substr|ascii|declare|exec|count|master|into|drop|execute)\\b)", Pattern.CASE_INSENSITIVE);
/**
* SQL过滤防止注入传入参数输入有select相关代码替换空。
* @author ThinkGem
@@ -263,7 +263,7 @@ public class EncodeUtils {
public static String sqlFilter(String text){
if (text != null){
String value = text;
Matcher matcher = sqlPattern.matcher(text);
Matcher matcher = sqlPattern.matcher(value);
if (matcher.find()) {
value = matcher.replaceAll(StringUtils.EMPTY);
}

View File

@@ -356,7 +356,7 @@ public class ListUtils extends org.apache.commons.collections.ListUtils {
* @param totalPage 总页码数
* @author ThinkGem
*/
private static <T> List<T> getPageList(List<T> list, int pageNo, int pageSize, int totalPage) {
public static <T> List<T> getPageList(List<T> list, int pageNo, int pageSize, int totalPage) {
int fromIndex = 0; // 从哪里开始截取
int toIndex = 0; // 截取几个
if (list == null || list.size() == 0){

View File

@@ -1,66 +1,66 @@
/**
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
*/
package com.jeesite.common.image;
import java.io.File;
import com.drew.imaging.jpeg.JpegMetadataReader;
import com.drew.lang.Rational;
import com.drew.metadata.Metadata;
import com.drew.metadata.exif.GpsDirectory;
/**
* 图片地理信息获取
* @author ThinkGem
*/
public class ImageGeo {
public double lat = 0.0;
public double lon = 0.0;
public double alt = 0.0;
public boolean error = false;
public ImageGeo(String filename) {
try {
error = false;
File jpegFile = new File(filename);
Metadata metadata = JpegMetadataReader.readMetadata(jpegFile);
GpsDirectory gpsdir = (GpsDirectory) metadata.getDirectoriesOfType(GpsDirectory.class);
Rational latpart[] = gpsdir.getRationalArray(GpsDirectory.TAG_LATITUDE);
Rational lonpart[] = gpsdir.getRationalArray(GpsDirectory.TAG_LONGITUDE);
String northing = gpsdir.getString(GpsDirectory.TAG_LATITUDE_REF);
String easting = gpsdir.getString(GpsDirectory.TAG_LONGITUDE_REF);
try {
alt = gpsdir.getDouble(GpsDirectory.TAG_ALTITUDE);
} catch (Exception ex) {}
double latsign = 1.0d;
if (northing.equalsIgnoreCase("S")) {
latsign = -1.0d;
}
double lonsign = 1.0d;
if (easting.equalsIgnoreCase("W")) {
lonsign = -1.0d;
}
lat = (Math.abs(latpart[0].doubleValue()) + latpart[1].doubleValue() / 60.0d + latpart[2].doubleValue() / 3600.0d) * latsign;
lon = (Math.abs(lonpart[0].doubleValue()) + lonpart[1].doubleValue() / 60.0d + lonpart[2].doubleValue() / 3600.0d) * lonsign;
if (Double.isNaN(lat) || Double.isNaN(lon)) {
error = true;
}
} catch (Exception ex) {
error = true;
}
System.out.println(filename + ": (" + lat + ", " + lon + ")");
}
// public static void main(String[] args) {
// ImageGeo imageGeo = new ImageGeo(ImageGeo.class.getResource("IMAG0068.jpg").getFile());
// System.out.println(imageGeo.lon + "," + imageGeo.lat);
///**
// * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
// */
//package com.jeesite.common.image;
//
//import java.io.File;
//
//import com.drew.imaging.jpeg.JpegMetadataReader;
//import com.drew.lang.Rational;
//import com.drew.metadata.Metadata;
//import com.drew.metadata.exif.GpsDirectory;
//
///**
// * 图片地理信息获取
// * @author ThinkGem
// */
//public class ImageGeo {
//
// public double lat = 0.0;
// public double lon = 0.0;
// public double alt = 0.0;
// public boolean error = false;
//
// public ImageGeo(String filename) {
// try {
// error = false;
// File jpegFile = new File(filename);
// Metadata metadata = JpegMetadataReader.readMetadata(jpegFile);
//
// GpsDirectory gpsdir = (GpsDirectory) metadata.getDirectoriesOfType(GpsDirectory.class);
// Rational latpart[] = gpsdir.getRationalArray(GpsDirectory.TAG_LATITUDE);
// Rational lonpart[] = gpsdir.getRationalArray(GpsDirectory.TAG_LONGITUDE);
// String northing = gpsdir.getString(GpsDirectory.TAG_LATITUDE_REF);
// String easting = gpsdir.getString(GpsDirectory.TAG_LONGITUDE_REF);
//
// try {
// alt = gpsdir.getDouble(GpsDirectory.TAG_ALTITUDE);
// } catch (Exception ex) {}
//
// double latsign = 1.0d;
// if (northing.equalsIgnoreCase("S")) {
// latsign = -1.0d;
// }
// double lonsign = 1.0d;
// if (easting.equalsIgnoreCase("W")) {
// lonsign = -1.0d;
// }
//
// lat = (Math.abs(latpart[0].doubleValue()) + latpart[1].doubleValue() / 60.0d + latpart[2].doubleValue() / 3600.0d) * latsign;
// lon = (Math.abs(lonpart[0].doubleValue()) + lonpart[1].doubleValue() / 60.0d + lonpart[2].doubleValue() / 3600.0d) * lonsign;
//
// if (Double.isNaN(lat) || Double.isNaN(lon)) {
// error = true;
// }
// } catch (Exception ex) {
// error = true;
// }
// System.out.println(filename + ": (" + lat + ", " + lon + ")");
// }
}
//
//// public static void main(String[] args) {
//// ImageGeo imageGeo = new ImageGeo(ImageGeo.class.getResource("IMAG0068.jpg").getFile());
//// System.out.println(imageGeo.lon + "," + imageGeo.lat);
//// }
//
//}

View File

@@ -0,0 +1,70 @@
/**
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
*/
package com.jeesite.common.image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.jeesite.common.io.FileUtils;
import com.jeesite.common.lang.StringUtils;
import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.Thumbnails.Builder;
/**
* 图片处理工具类
* @author ThinkGem
* @version 2018年12月31日
*/
public class ImageUtils {
private static Logger logger = LoggerFactory.getLogger(ImageUtils.class);
/**
* 缩略图生成,处理一些较大的图片,防止占用太多的网络资源
*/
public static void thumbnails(File imageFile, int maxWidth, int maxHeight, String outputFormat){
if (imageFile == null || !imageFile.exists() || (maxWidth <= 0 && maxHeight <= 0)){
return;
}
// 只处理可以压缩的图片如gif图片压缩后会出现黑色背景的情况
String extension = FileUtils.getFileExtension(imageFile.getName());
if (!StringUtils.inString(extension, "png", "jpg", "jpeg", "bmp", "ico")){
return;
}
try{
BufferedImage bufferedImage = ImageIO.read(imageFile);
Builder<BufferedImage> bilder = Thumbnails.of(bufferedImage);
if (bufferedImage != null){
if (maxWidth > 0){
if (bufferedImage.getWidth() <= maxWidth){
bilder.width(bufferedImage.getWidth());
}else{
bilder.width(maxWidth);
}
}
if (maxHeight > 0){
if (bufferedImage.getHeight() <= maxHeight){
bilder.height(bufferedImage.getHeight());
}else{
bilder.height(maxHeight);
}
}
if (StringUtils.isNotBlank(outputFormat)){
bilder.outputFormat(outputFormat);
}
bilder.toFile(imageFile);
}
}catch(IOException e){
logger.error("图片压缩失败:" + imageFile.getAbsoluteFile(), e);
}
}
}

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;
/**
* 复制单个文件,如果目标文件存在,则不覆盖
@@ -654,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);
}
/**
@@ -752,7 +756,8 @@ public class FileUtils extends org.apache.commons.io.FileUtils {
}
try {
response.addHeader("Content-Disposition", "attachment; filename=\"" +
boolean isPreview = "preview".equalsIgnoreCase(request.getParameter("source"));
response.addHeader("Content-Disposition", (!isPreview ? "attachment; " : "") + "filename=\"" +
EncodeUtils.encodeUrl(StringUtils.isBlank(fileName) ? file.getName() : fileName) + "\"");
response.setContentType(FileUtils.getContentType(file.getName())); // set the MIME type.
response.addHeader("Content-Length", String.valueOf(contentLength));

View File

@@ -16,7 +16,6 @@ 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;
import com.jeesite.common.collect.SetUtils;
@@ -34,6 +33,7 @@ public class PropertiesUtils {
// 默认加载的文件可通过继承覆盖若有相同Key优先加载后面的
public static final String[] DEFAULT_CONFIG_FILE = new String[]{
"classpath:config/bootstrap.yml", "classpath:bootstrap.yml",
"classpath:config/application.yml", "classpath:application.yml"};
private static Logger logger = PropertiesUtils.initLogger();
@@ -214,7 +214,7 @@ public class PropertiesUtils {
String logPath = null;
try {
// 获取当前classes目录
logPath = new DefaultResourceLoader().getResource("/").getFile().getPath();
logPath = ResourceUtils.getResource("/").getFile().getPath();
} catch (Exception e) {
// 取不到,取当前工作路径
logPath = System.getProperty("user.dir");
@@ -224,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

@@ -244,7 +244,7 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
}
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.HOUR, 0);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
@@ -262,7 +262,7 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
}
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.HOUR, 23);
calendar.set(Calendar.HOUR_OF_DAY, 23);
calendar.set(Calendar.MINUTE, 59);
calendar.set(Calendar.SECOND, 59);
calendar.set(Calendar.MILLISECOND, 999);

View File

@@ -26,6 +26,7 @@ import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.util.JSONPObject;
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule;
import com.jeesite.common.collect.ListUtils;
import com.jeesite.common.io.PropertiesUtils;
/**
* 简单封装Jackson实现JSON String<->Java Object的Mapper.
@@ -55,8 +56,9 @@ public class JsonMapper extends ObjectMapper {
this.configure(Feature.ALLOW_SINGLE_QUOTES, true);
// 允许不带引号的字段名称
this.configure(Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
// 设置时区
this.setTimeZone(TimeZone.getTimeZone("GMT+8:00"));
// 设置默认时区
this.setTimeZone(TimeZone.getTimeZone(PropertiesUtils.getInstance()
.getProperty("lang.defaultTimeZone", "GMT+08:00")));
// 设置输入时忽略在JSON字符串中存在但Java对象实际没有的属性
this.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
// 遇到空值处理为空串

View File

@@ -24,6 +24,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import com.fasterxml.jackson.databind.JavaType;
import com.jeesite.common.io.PropertiesUtils;
/**
* XML <-> Map、Object
@@ -49,8 +50,9 @@ 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"));
// 设置默认时区
this.setTimeZone(TimeZone.getTimeZone(PropertiesUtils.getInstance()
.getProperty("lang.defaultTimeZone", "GMT+08:00")));
}
/**

View File

@@ -1,28 +1,21 @@
package com.jeesite.common.media;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.jeesite.common.collect.ListUtils;
import com.jeesite.common.image.ImageUtils;
import com.jeesite.common.io.FileUtils;
import com.jeesite.common.io.PropertiesUtils;
import com.jeesite.common.lang.ObjectUtils;
import com.jeesite.common.lang.StringUtils;
import com.jeesite.common.lang.TimeUtils;
import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.Thumbnails.Builder;
/**
* 视频工具类
* @author ThinkGem
@@ -114,34 +107,11 @@ public class VideoUtils {
try {
File imgfile = new File(imgFile);
if (imgfile.exists()){
// 过滤掉gif图片因为gif图片转换后会出现黑色背景的情况gif基本也没有比较大的图片
if (!StringUtils.inString(FileUtils.getFileExtension(imgFile), "gif")){
Integer w = 800;
Integer h = 600;
if (StringUtils.isNotBlank(width)){
w = ObjectUtils.toInteger(width);
}
if (StringUtils.isNotBlank(height)){
h = ObjectUtils.toInteger(height);
}
Builder<File> file = Thumbnails.of(imgFile);
BufferedImage bufferedImage = ImageIO.read(imgfile);
if (bufferedImage.getWidth() <= w){
file.width(bufferedImage.getWidth());
}else{
file.width(w);
}
if (bufferedImage.getHeight() <= h){
file.height(bufferedImage.getHeight());
}else{
file.height(h);
}
file.toFile(imgFile);
}
ImageUtils.thumbnails(imgfile, 800, 600, null);
}else{
statusTemp = false;
}
} catch (IOException e) {
} catch (Exception e) {
statusTemp = false;
log.error("视频剪切图片失败", e);
}

View File

@@ -40,8 +40,9 @@ public class ReflectUtils {
private static Logger logger = LoggerFactory.getLogger(ReflectUtils.class);
/**
* 调用Getter方法.
* 支持多级,如:对象名.对象名.方法
* 调用Getter方法
* 支持多级,如:对象名.对象名.方法
* 支持静态类及方法调用
*/
@SuppressWarnings("unchecked")
public static <E> E invokeGetter(Object obj, String propertyName) {
@@ -54,8 +55,9 @@ public class ReflectUtils {
}
/**
* 调用Setter方法, 仅匹配方法名
* 支持多级,如:对象名.对象名.方法
* 调用Setter方法仅匹配方法名
* 支持多级,如:对象名.对象名.方法
* 支持静态类及方法调用
*/
public static <E> void invokeSetter(Object obj, String propertyName, E value) {
Object object = obj;
@@ -72,7 +74,7 @@ public class ReflectUtils {
}
/**
* 直接读取对象属性值, 无视private/protected修饰符, 不经过getter函数.
* 直接读取对象属性值无视private/protected修饰符不经过getter函数
*/
@SuppressWarnings("unchecked")
public static <E> E getFieldValue(final Object obj, final String fieldName) {
@@ -92,7 +94,7 @@ public class ReflectUtils {
}
/**
* 直接设置对象属性值, 无视private/protected修饰符, 不经过setter函数.
* 直接设置对象属性值无视private/protected修饰符不经过setter函数
*/
public static <E> void setFieldValue(final Object obj, final String fieldName, final E value) {
Field field = getAccessibleField(obj, fieldName);
@@ -109,9 +111,10 @@ public class ReflectUtils {
}
/**
* 直接调用对象方法, 无视private/protected修饰符.
* 用于一次性调用的情况否则应使用getAccessibleMethod()函数获得Method后反复调用.
* 直接调用对象方法无视private/protected修饰符
* 用于一次性调用的情况否则应使用getAccessibleMethod()函数获得Method后反复调用
* 同时匹配方法名+参数类型,
* 支持静态类及方法调用
*/
@SuppressWarnings("unchecked")
public static <E> E invokeMethod(final Object obj, final String methodName, final Class<?>[] parameterTypes,
@@ -122,11 +125,11 @@ public class ReflectUtils {
Method method = getAccessibleMethod(obj, methodName, parameterTypes);
if (method == null) {
//throw new IllegalArgumentException("在 [" + obj.getClass() + "] 中,没有找到 [" + methodName + "] 方法 ");
logger.debug("在 [" + obj.getClass() + "] 中,没有找到 [" + methodName + "] 方法 ");
logger.debug("在 [" + (obj.getClass() == Class.class ? obj : obj.getClass()) + "] 中,没有找到 [" + methodName + "] 方法 ");
return null;
}
try {
return (E)method.invoke(obj, args);
return (E)method.invoke(obj.getClass() == Class.class ? null : obj, args);
} catch (Exception e) {
String msg = "method: "+method+", obj: "+obj+", args: "+args+"";
throw convertReflectionExceptionToUnchecked(msg, e);
@@ -134,9 +137,10 @@ public class ReflectUtils {
}
/**
* 直接调用对象方法, 无视private/protected修饰符
* 用于一次性调用的情况否则应使用getAccessibleMethodByName()函数获得Method后反复调用.
* 只匹配函数名,如果有多个同名函数调用第一个
* 直接调用对象方法无视private/protected修饰符
* 用于一次性调用的情况否则应使用getAccessibleMethodByName()函数获得Method后反复调用
* 只匹配函数名,如果有多个同名函数调用第一个
* 支持静态类及方法调用
*/
@SuppressWarnings("unchecked")
public static <E> E invokeMethodByName(final Object obj, final String methodName, final Object[] args) {
@@ -144,7 +148,7 @@ public class ReflectUtils {
if (method == null) {
// 如果为空不报错,直接返回空。
// throw new IllegalArgumentException("在 [" + obj.getClass() + "] 中,没有找到 [" + methodName + "] 方法 ");
logger.debug("在 [" + obj.getClass() + "] 中,没有找到 [" + methodName + "] 方法 ");
logger.debug("在 [" + (obj.getClass() == Class.class ? obj : obj.getClass()) + "] 中,没有找到 [" + methodName + "] 方法 ");
return null;
}
try {
@@ -175,7 +179,7 @@ public class ReflectUtils {
}
}
}
return (E)method.invoke(obj, args);
return (E)method.invoke(obj.getClass() == Class.class ? null : obj, args);
} catch (Exception e) {
String msg = "method: "+method+", obj: "+obj+", args: "+args+"";
throw convertReflectionExceptionToUnchecked(msg, e);
@@ -183,8 +187,8 @@ public class ReflectUtils {
}
/**
* 循环向上转型, 获取对象的DeclaredField, 并强制设置为可访问.
* 如向上转型到Object仍无法找到, 返回null.
* 循环向上转型获取对象的DeclaredField并强制设置为可访问
* 如向上转型到Object仍无法找到返回null
*/
public static Field getAccessibleField(final Object obj, final String fieldName) {
// 为空不报错。直接返回 null
@@ -207,10 +211,10 @@ public class ReflectUtils {
}
/**
* 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问.
* 如向上转型到Object仍无法找到, 返回null.
* 循环向上转型获取对象的DeclaredMethod,并强制设置为可访问
* 如向上转型到Object仍无法找到返回null
* 匹配函数名+参数类型。
* 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args)
* 用于方法需要被多次调用的情况先使用本函数先取得Method然后调用Method.invoke(Object obj, Object... args)
*/
public static Method getAccessibleMethod(final Object obj, final String methodName,
final Class<?>... parameterTypes) {
@@ -219,8 +223,12 @@ public class ReflectUtils {
if (obj == null){
return null;
}
Class<?> clazz = obj.getClass();
if (clazz == Class.class){
clazz = (Class) obj;
}
Validate.notBlank(methodName, "methodName can't be blank");
for (Class<?> searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass()) {
for (Class<?> searchType = clazz; searchType != Object.class; searchType = searchType.getSuperclass()) {
try {
Method method = searchType.getDeclaredMethod(methodName, parameterTypes);
makeAccessible(method);
@@ -234,10 +242,10 @@ public class ReflectUtils {
}
/**
* 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问.
* 如向上转型到Object仍无法找到, 返回null.
* 循环向上转型获取对象的DeclaredMethod并强制设置为可访问
* 如向上转型到Object仍无法找到返回null
* 只匹配函数名。
* 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args)
* 用于方法需要被多次调用的情况先使用本函数先取得Method然后调用Method.invoke(Object obj, Object... args)
*/
public static Method getAccessibleMethodByName(final Object obj, final String methodName, int argsNum) {
// 为空不报错。直接返回 null
@@ -245,8 +253,12 @@ public class ReflectUtils {
if (obj == null){
return null;
}
Class<?> clazz = obj.getClass();
if (clazz == Class.class){
clazz = (Class) obj;
}
Validate.notBlank(methodName, "methodName can't be blank");
for (Class<?> searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass()) {
for (Class<?> searchType = clazz; searchType != Object.class; searchType = searchType.getSuperclass()) {
Method[] methods = searchType.getDeclaredMethods();
for (Method method : methods) {
if (method.getName().equals(methodName) && method.getParameterTypes().length == argsNum) {
@@ -279,10 +291,9 @@ public class ReflectUtils {
}
/**
* 通过反射, 获得Class定义中声明的泛型参数的类型, 注意泛型必须定义在父类处
* 如无法找到, 返回Object.class.
* eg.
* public UserDao extends HibernateDao<User>
* 通过反射获得Class定义中声明的泛型参数的类型注意泛型必须定义在父类处
* 如无法找到返回Object.class
* 如 public UserDao extends CrudDao<User>
* @param clazz The class to introspect
* @return the first generic declaration, or Object.class if cannot be determined
*/
@@ -292,9 +303,9 @@ public class ReflectUtils {
}
/**
* 通过反射, 获得Class定义中声明的父类的泛型参数的类型.
* 如无法找到, 返回Object.class.
* 如public UserDao extends HibernateDao<User,Long>
* 通过反射获得Class定义中声明的父类的泛型参数的类型
* 如无法找到返回Object.class
* 如 public UserDao extends CrudDao<User, Long>
* @param clazz clazz The class to introspect
* @param index the Index of the generic ddeclaration,start from 0.
* @return the index generic declaration, or Object.class if cannot be determined
@@ -323,6 +334,9 @@ public class ReflectUtils {
return (Class) params[index];
}
/**
* 获取类的Class如果为内部类则返回上级类Class
*/
public static Class<?> getUserClass(Object instance) {
if (instance == null){
throw new RuntimeException("Instance must not be null");
@@ -339,7 +353,7 @@ public class ReflectUtils {
}
/**
* 将反射时的checked exception转换为unchecked exception.
* 将反射时的checked exception转换为unchecked exception
*/
public static RuntimeException convertReflectionExceptionToUnchecked(String msg, Exception e) {
if (e instanceof IllegalAccessException || e instanceof IllegalArgumentException

View File

@@ -39,6 +39,9 @@ public final class Base64Uploader {
storageState.putInfo("url", ctx + PathFormat.format(savePath));
storageState.putInfo("type", suffix);
storageState.putInfo("original", "");
// UEditor上传文件成功后调用事件
StorageManager.uploadFileSuccess(physicalPath, storageState);
}
return storageState;

View File

@@ -1,6 +1,5 @@
package com.jeesite.common.ueditor.upload;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
@@ -9,7 +8,6 @@ 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;
@@ -20,8 +18,8 @@ import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import com.jeesite.common.image.ImageUtils;
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;
@@ -30,9 +28,6 @@ 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,
@@ -114,21 +109,8 @@ public class BinaryUploader {
// 如果开启了压缩图片
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")){
Builder<File> file = Thumbnails.of(physicalPath);
BufferedImage bufferedImage = ImageIO.read(new File(physicalPath));
if (bufferedImage != null){
if (bufferedImage.getWidth() <= width){
file.width(bufferedImage.getWidth());
}else{
file.width(width);
}
file.toFile(physicalPath);
}
}
Integer maxWidth = (Integer)conf.get("imageCompressBorder");
ImageUtils.thumbnails(new File(physicalPath), maxWidth, -1, null);
}
}
@@ -153,12 +135,19 @@ public class BinaryUploader {
storageState.putInfo("url", ctx + PathFormat.format(savePath) + "." + v.getOutputFileExtension());
storageState.putInfo("type", "." + v.getOutputFileExtension());
storageState.putInfo("original", originFileName +"."+ v.getInputFileExtension());
// Ueditor编辑器上传文件完成后调用事件
StorageManager.uploadFileSuccess(physicalPath, storageState);
return storageState;
}
}
storageState.putInfo("url", ctx + PathFormat.format(savePath));
storageState.putInfo("type", suffix);
storageState.putInfo("original", originFileName + suffix);
// UEditor上传文件成功后调用事件
StorageManager.uploadFileSuccess(physicalPath, storageState);
}
return storageState;

View File

@@ -210,4 +210,14 @@ public class StorageManager {
return new BaseState(true);
}
/**
* UEditor上传文件成功后调用事件
* @param physicalPath 上传文件实际路径
* @param storageState.url 返回到客户端的文件访问地址
*/
public static void uploadFileSuccess(String physicalPath, State storageState){
}
}

View File

@@ -110,7 +110,8 @@ public class ServletUtils {
}
String uri = request.getRequestURI();
if (StringUtils.inStringIgnoreCase(uri, ".json", ".xml")){
if (StringUtils.endsWithIgnoreCase(uri, ".json")
|| StringUtils.endsWithIgnoreCase(uri, ".xml")){
return true;
}
@@ -189,19 +190,22 @@ public class ServletUtils {
}
}
HttpServletRequest request = getRequest();
String uri = request.getRequestURI();
if (StringUtils.endsWithIgnoreCase(uri, ".xml") || StringUtils
.equalsIgnoreCase(request.getParameter("__ajax"), "xml")){
return XmlMapper.toXml(resultMap);
}else{
String functionName = request.getParameter("__callback");
if (StringUtils.isNotBlank(functionName)){
return JsonMapper.toJsonp(functionName, resultMap);
if (request != null){
String uri = request.getRequestURI();
if (StringUtils.endsWithIgnoreCase(uri, ".xml") || StringUtils
.equalsIgnoreCase(request.getParameter("__ajax"), "xml")){
return XmlMapper.toXml(resultMap);
}else{
return JsonMapper.toJson(resultMap);
String functionName = request.getParameter("__callback");
if (StringUtils.isNotBlank(functionName)){
return JsonMapper.toJsonp(functionName, resultMap);
}else{
return JsonMapper.toJson(resultMap);
}
}
}else{
return JsonMapper.toJson(resultMap);
}
}
/**

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

@@ -94,7 +94,7 @@ body {
background: #fff;
padding: 15px;
color: #444;
border-top: 1px solid #d2d6de;
border-top: 1px solid #caced6;
}
/* Fixed layout */
.fixed .main-header,
@@ -350,7 +350,7 @@ a:focus {
top: 0;
right: 0;
float: none;
background: #d2d6de;
background: #caced6;
padding-left: 10px;
}
.content-header > .breadcrumb li:before {
@@ -859,10 +859,10 @@ a:focus {
.control-sidebar-light,
.control-sidebar-light + .control-sidebar-bg {
background: #f9fafc;
border-left: 1px solid #d2d6de;
border-left: 1px solid #caced6;
}
.control-sidebar-light .nav-tabs.control-sidebar-tabs {
border-bottom: #d2d6de;
border-bottom: #caced6;
}
.control-sidebar-light .nav-tabs.control-sidebar-tabs > li > a {
background: #e8ecf4;
@@ -871,8 +871,8 @@ a:focus {
.control-sidebar-light .nav-tabs.control-sidebar-tabs > li > a,
.control-sidebar-light .nav-tabs.control-sidebar-tabs > li > a:hover,
.control-sidebar-light .nav-tabs.control-sidebar-tabs > li > a:focus {
border-left-color: #d2d6de;
border-bottom-color: #d2d6de;
border-left-color: #caced6;
border-bottom-color: #caced6;
}
.control-sidebar-light .nav-tabs.control-sidebar-tabs > li > a:hover,
.control-sidebar-light .nav-tabs.control-sidebar-tabs > li > a:focus,
@@ -1235,7 +1235,7 @@ a:focus {
.form-control {
/*border-radius: 0;*/
box-shadow: none;
border-color: #d2d6de;
border-color: #caced6;
}
.form-control:focus {
border-color: #3c8dbc;
@@ -1288,7 +1288,7 @@ a:focus {
/* Input group */
.input-group .input-group-addon {
/*border-radius: 0;*/
border-color: #d2d6de;
border-color: #caced6;
background-color: #fff;
}
/* button groups */
@@ -1530,7 +1530,7 @@ a:focus {
position: relative;
border-radius: 3px;
background: #ffffff;
border-top: 3px solid #d2d6de;
border-top: 3px solid #caced6;
margin-bottom: 20px;
width: 100%;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
@@ -1551,7 +1551,7 @@ a:focus {
border-top-color: #00a65a;
}
.box.box-default {
border-top-color: #d2d6de;
border-top-color: #caced6;
}
.box.collapsed-box .box-body,
.box.collapsed-box .box-footer {
@@ -1585,12 +1585,12 @@ a:focus {
background: rgba(0, 0, 0, 0.1);
}
.box.box-solid.box-default {
border: 1px solid #d2d6de;
border: 1px solid #caced6;
}
.box.box-solid.box-default > .box-header {
color: #444444;
background: #d2d6de;
background-color: #d2d6de;
background: #caced6;
background-color: #caced6;
}
.box.box-solid.box-default > .box-header a,
.box.box-solid.box-default > .box-header .btn {
@@ -1913,7 +1913,7 @@ a:focus {
font-weight: 500;
}
.todo-list > li.done .label {
background: #d2d6de !important;
background: #caced6 !important;
}
.todo-list .danger {
border-left-color: #dd4b39;
@@ -2150,7 +2150,7 @@ a:focus {
line-height: 30px;
position: absolute;
color: #666;
background: #d2d6de;
background: #caced6;
border-radius: 50%;
text-align: center;
left: 18px;
@@ -2573,7 +2573,7 @@ a:focus {
border-top-color: #00a65a;
}
.nav-tabs-custom.tab-default > .nav-tabs > li.active {
border-top-color: #d2d6de;
border-top-color: #caced6;
}
/* PAGINATION */
.pagination > li > a {
@@ -2691,7 +2691,7 @@ table.text-center th {
* ----------------
*/
.label-default {
background-color: #d2d6de;
background-color: #caced6;
color: #444;
}
/*
@@ -2746,8 +2746,8 @@ table.text-center th {
border-radius: 5px;
position: relative;
padding: 5px 10px;
background: #d2d6de;
border: 1px solid #d2d6de;
background: #caced6;
border: 1px solid #caced6;
margin: 5px 0 0 50px;
color: #444444;
}
@@ -2757,7 +2757,7 @@ table.text-center th {
right: 100%;
top: 15px;
border: solid transparent;
border-right-color: #d2d6de;
border-right-color: #caced6;
content: ' ';
height: 0;
width: 0;
@@ -2780,7 +2780,7 @@ table.text-center th {
right: auto;
left: 100%;
border-right-color: transparent;
border-left-color: #d2d6de;
border-left-color: #caced6;
}
.direct-chat-img {
border-radius: 50%;
@@ -3169,7 +3169,7 @@ table.text-center th {
*/
/* ADD THIS CLASS TO THE <BODY> TAG */
.lockscreen {
background: #d2d6de;
background: #caced6;
}
.lockscreen-logo {
font-size: 35px;
@@ -3246,7 +3246,7 @@ table.text-center th {
}
.login-page,
.register-page {
background: #d2d6de;
background: #caced6;
}
.login-box,
.register-box {
@@ -3344,14 +3344,14 @@ table.text-center th {
margin: 0 auto;
width: 100px;
padding: 3px;
border: 3px solid #d2d6de;
border: 3px solid #caced6;
}
.profile-username {
font-size: 21px;
margin-top: 5px;
}
.post {
border-bottom: 1px solid #d2d6de;
border-bottom: 1px solid #caced6;
margin-bottom: 15px;
padding-bottom: 15px;
color: #666;
@@ -4231,7 +4231,7 @@ table.text-center th {
}
.select2-container--default .select2-selection--single,
.select2-selection .select2-selection--single {
border: 1px solid #d2d6de;
border: 1px solid #caced6;
/*border-radius: 0;*/
padding: 6px 12px;
height: 34px;
@@ -4240,7 +4240,7 @@ table.text-center th {
border-color: #3c8dbc;
}
.select2-dropdown {
border: 1px solid #d2d6de;
border: 1px solid #caced6;
/*border-radius: 0;*/
}
.select2-container--default .select2-results__option--highlighted[aria-selected] {
@@ -4271,7 +4271,7 @@ table.text-center th {
}
.select2-dropdown .select2-search__field,
.select2-search--inline .select2-search__field {
border: 1px solid #d2d6de;
border: 1px solid #caced6;
}
.select2-dropdown .select2-search__field:focus,
.select2-search--inline .select2-search__field:focus {
@@ -4292,14 +4292,14 @@ table.text-center th {
color: #444;
}
.select2-container--default .select2-selection--multiple {
border: 1px solid #d2d6de;
border: 1px solid #caced6;
/*border-radius: 0;*/
}
.select2-container--default .select2-selection--multiple:focus {
border-color: #3c8dbc;
}
.select2-container--default.select2-container--focus .select2-selection--multiple {
border-color: #d2d6de;
border-color: #caced6;
}
.select2-container--default .select2-selection--multiple .select2-selection__choice {
background-color: #3c8dbc;
@@ -4441,7 +4441,7 @@ table.text-center th {
}
.bg-gray {
color: #000;
background-color: #d2d6de !important;
background-color: #caced6 !important;
}
.bg-gray-light {
background-color: #f7f7f7;
@@ -4595,7 +4595,7 @@ table.text-center th {
color: #00a65a !important;
}
.text-gray {
color: #d2d6de !important;
color: #caced6 !important;
}
.text-navy {
color: #001f3f !important;
@@ -4868,11 +4868,11 @@ table.text-center th {
margin-left: 110px;
}
.img-bordered {
border: 3px solid #d2d6de;
border: 3px solid #caced6;
padding: 3px;
}
.img-bordered-sm {
border: 2px solid #d2d6de;
border: 2px solid #caced6;
padding: 2px;
}
.attachment-block {

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,108 @@
(function() {
this.Base64 = new Base64();
function Base64() {
// private property
_keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
// public method for encoding
this.encode = function (input) {
var output = "";
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
input = _utf8_encode(input);
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output +
_keyStr.charAt(enc1) + _keyStr.charAt(enc2) +
_keyStr.charAt(enc3) + _keyStr.charAt(enc4);
}
return output;
}
// public method for decoding
this.decode = function (input) {
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
while (i < input.length) {
enc1 = _keyStr.indexOf(input.charAt(i++));
enc2 = _keyStr.indexOf(input.charAt(i++));
enc3 = _keyStr.indexOf(input.charAt(i++));
enc4 = _keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
}
output = _utf8_decode(output);
return output;
}
// private method for UTF-8 encoding
_utf8_encode = function (string) {
string = string.replace(/\r\n/g,"\n");
var utftext = "";
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
} else if((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
} else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
}
// private method for UTF-8 decoding
_utf8_decode = function (utftext) {
var string = "";
var i = 0;
var c = c1 = c2 = 0;
while ( i < utftext.length ) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
} else if((c > 191) && (c < 224)) {
c2 = utftext.charCodeAt(i+1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
} else {
c2 = utftext.charCodeAt(i+1);
c3 = utftext.charCodeAt(i+2);
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
}
}
return string;
}
}
})();

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 2.2 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

@@ -1,4 +1,4 @@
/* Electron */ if(typeof module==='object'){window.module=module;module=undefined;}
if(typeof module==='object'){window.module=module;module=undefined;}/* Electron Support */
/*!
* jQuery JavaScript Library v1.12.4
* http://jquery.com/
@@ -211,7 +211,8 @@ jQuery.extend = jQuery.fn.extend = function() {
copy = options[ name ];
// Prevent never-ending loop
if ( target === copy ) {
// if ( target === copy ) {
if (name === "__proto__" || target === copy) { // 修复jQuery原型污染漏洞 ThinkGem
continue;
}

File diff suppressed because one or more lines are too long

View File

@@ -1,41 +1,12 @@
/**
@Namelayer v3.0.3 Web弹层组件
@Author贤心
@Sitehttp://layer.layui.com
@LicenseMIT
*/
;!function(window, undefined){
"use strict";
var i18n = {
btnOk: '确定',
btnCancel: '取消',
title: '信息',
promptTipA: '最多输入',
promptTipB: '个字符',
noPicture: '没有图片',
photoError: '当前图片地址异常<br>是否继续查看下一张?',
photoNextPage: '下一张',
photoClose: '不看了'
};
if (window.lang == 'en'){
i18n = {
btnOk: 'Ok',
btnCancel: 'Cancle',
title: 'Information',
promptTipA: 'Enter ',
promptTipB: 'character at most.',
noPicture: 'No picture',
photoError: 'Current image address error.<br>Next slide?',
photoNextPage: 'The next',
photoClose: 'Close'
};
}
var isLayui = window.layui && layui.define, $, win, ready = {
getPath: function(){
var js = document.scripts, script = js[js.length - 1], jsPath = script.src;
@@ -44,7 +15,7 @@ var isLayui = window.layui && layui.define, $, win, ready = {
}(),
config: {}, end: {}, minIndex: 0, minLeft: [],
btn: [i18n.btnOk, i18n.btnCancel],
//btn: [layer.i18n.btnOk, layer.i18n.btnCancel], // ThinkGem
//五种原始层模式
type: ['dialog', 'page', 'iframe', 'loading', 'tips']
@@ -53,6 +24,17 @@ var isLayui = window.layui && layui.define, $, win, ready = {
//默认内置方法。
var layer = {
v: '3.0.3',
i18n: { // ThinkGem 国际化支持
btnOk: '确定',
btnCancel: '取消',
title: '信息',
promptTipA: '最多输入',
promptTipB: '个字符',
noPicture: '没有图片',
photoError: '当前图片地址异常<br>是否继续查看下一张?',
photoNextPage: '下一张',
photoClose: '不看了'
},
ie: function(){ //ie版本
var agent = navigator.userAgent.toLowerCase();
return (!!window.ActiveXObject || "ActiveXObject" in window) ? (
@@ -133,7 +115,8 @@ var layer = {
}
return layer.open($.extend({
content: content,
btn: ready.btn,
//btn: ready.btn,
btn: [layer.i18n.btnOk, layer.i18n.btnCancel],
yes: yes,
btn2: cancel
}, type ? {} : options));
@@ -210,7 +193,7 @@ Class.pt.config = {
shade: 0.3,
fixed: true,
move: doms[1],
title: i18n.title,
title: layer.i18n.title,
offset: 'auto',
area: 'auto',
closeBtn: 1,
@@ -232,7 +215,7 @@ Class.pt.vessel = function(conType, callback){
var zIndex = config.zIndex + times, titype = typeof config.title === 'object';
var ismax = config.maxmin && (config.type === 1 || config.type === 2);
var titleHTML = (config.title ? '<div class="layui-layer-title" style="'+ (titype ? config.title[1] : '') +'">'
+ (titype ? config.title[0] : config.title)
+ (titype ? config.title[0] : layer.i18n.title)
+ '</div>' : '');
config.zIndex = zIndex;
@@ -248,7 +231,8 @@ Class.pt.vessel = function(conType, callback){
+ (config.type == 1 && conType ? '' : (config.content||''))
+ '</div>'
+ '<span class="layui-layer-setwin">'+ function(){
var closebtn = ismax ? '<a class="layui-layer-min" href="javascript:;"><cite></cite></a><a class="layui-layer-ico layui-layer-max" href="javascript:;"></a>' : '';
var closebtn = ismax && config.title ? '<a class="layui-layer-min" href="javascript:;"><cite></cite></a>' : ''; // ThinkGem 必须有标题的清空下才能最小化
closebtn += ismax ? '<a class="layui-layer-ico layui-layer-max" href="javascript:;"></a>' : '';
config.closeBtn && (closebtn += '<a class="layui-layer-ico '+ doms[7] +' '+ doms[7] + (config.title ? config.closeBtn : (config.type == 4 ? '1' : '2')) +'" href="javascript:;"></a>');
return closebtn;
}() + '</span>'
@@ -292,7 +276,8 @@ Class.pt.creat = function(){
switch(config.type){
case 0:
config.btn = ('btn' in config) ? config.btn : ready.btn[0];
//config.btn = ('btn' in config) ? config.btn : ready.btn[0]; ThinkGem
config.btn = ('btn' in config) ? config.btn : layer.i18n.btnOk;// ThinkGem
layer.closeAll('dialog');
break;
case 2:
@@ -1020,7 +1005,7 @@ layer.prompt = function(options, yes){
return layer.open($.extend({
type: 1
,btn: [i18n.btnOk,i18n.btnCancel]
,btn: [layer.i18n.btnOk,layer.i18n.btnCancel]
,content: content
,skin: 'layui-layer-prompt' + skin('prompt')
,maxWidth: win.width()
@@ -1035,7 +1020,7 @@ layer.prompt = function(options, yes){
if(value === ''){
prompt.focus();
} else if(value.length > (options.maxlength||500)) {
layer.tips(i18n.promptTipA + (options.maxlength || 500) + i18n.promptTipB, prompt, {tips: 1});
layer.tips(layer.i18n.promptTipA + (options.maxlength || 500) + layer.i18n.promptTipB, prompt, {tips: 1});
} else {
yes && yes(value, index, prompt);
}
@@ -1287,9 +1272,9 @@ layer.photos = function(options, loop, key){
}, options));
}, function(){
layer.close(dict.loadi);
layer.msg(i18n.photoError, {
layer.msg(layer.i18n.photoError, {
time: 30000,
btn: [i18n.photoNextPage, i18n.photoClose],
btn: [layer.i18n.photoNextPage, layer.i18n.photoClose],
yes: function(){
data.length > 1 && dict.imgnext(true,true);
}

View File

@@ -0,0 +1,24 @@
(function() {
if (jQuery && jQuery.fn && jQuery.fn.select2 && jQuery.fn.select2.amd)
var e = jQuery.fn.select2.amd;
return e.define("select2/i18n/zh_CN", [], function() {
return { errorLoading : function() {
return "結果に載せることはできない。"
}, inputTooLong : function(e) {
var t = e.input.length - e.maximum, n = "" + t + "文字を削除してください";
return n
}, inputTooShort : function(e) {
var t = e.minimum - e.input.length, n = "少なくとも" + t + "文字を入力してください";
return n
}, loadingMore : function() {
return "より多くの……"
}, maximumSelected : function(e) {
var t = "選択するしかない" + e.maximum + "項目別";
return t
}, noResults : function() {
return "一致する項目を見つけることができなかった"
}, searching : function() {
return "検索しています……"
} }
}), { define : e.define, require : e.require }
})();

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} %-5p [%-39logger{39}] - %m%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

@@ -2,5 +2,4 @@ eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding//src/main/resources=UTF-8
encoding//src/test/java=UTF-8
encoding//src/test/resources=UTF-8
encoding/<project>=UTF-8

File diff suppressed because it is too large Load Diff

View File

@@ -4,6 +4,7 @@
DROP TABLE js_gen_table_column;
DROP TABLE js_gen_table;
DROP TABLE js_sys_company_office;
DROP TABLE js_sys_employee_office;
DROP TABLE js_sys_employee_post;
DROP TABLE js_sys_user_data_scope;
DROP TABLE js_sys_user_role;
@@ -43,7 +44,7 @@ CREATE TABLE js_gen_table
(
table_name varchar(64) NOT NULL,
class_name varchar(100) NOT NULL,
comments varchar(500) NOT NULL,
comments vargraphic(500) NOT NULL,
parent_table_name varchar(64),
parent_table_fk_name varchar(64),
data_source_name varchar(64),
@@ -51,16 +52,16 @@ CREATE TABLE js_gen_table
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),
function_name vargraphic(200),
function_name_simple vargraphic(50),
function_author vargraphic(50),
gen_base_dir vargraphic(1000),
options vargraphic(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),
remarks vargraphic(500),
PRIMARY KEY (table_name)
);
@@ -73,8 +74,8 @@ CREATE TABLE js_gen_table_column
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,
column_label vargraphic(50),
comments vargraphic(500) NOT NULL,
attr_name varchar(200) NOT NULL,
attr_type varchar(200) NOT NULL,
is_pk char(1),
@@ -86,7 +87,7 @@ CREATE TABLE js_gen_table_column
query_type varchar(200),
is_edit char(1),
show_type varchar(200),
options varchar(1000),
options vargraphic(1000),
PRIMARY KEY (id)
);
@@ -102,14 +103,14 @@ CREATE TABLE js_sys_area
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_name vargraphic(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),
remarks vargraphic(500),
PRIMARY KEY (area_code)
);
@@ -126,25 +127,25 @@ CREATE TABLE js_sys_company
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,
company_name vargraphic(200) NOT NULL,
full_name vargraphic(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),
remarks vargraphic(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),
corp_name vargraphic(100) DEFAULT 'JeeSite' NOT NULL,
extend_s1 vargraphic(500),
extend_s2 vargraphic(500),
extend_s3 vargraphic(500),
extend_s4 vargraphic(500),
extend_s5 vargraphic(500),
extend_s6 vargraphic(500),
extend_s7 vargraphic(500),
extend_s8 vargraphic(500),
extend_i1 decimal(19),
extend_i2 decimal(19),
extend_i3 decimal(19),
@@ -174,15 +175,15 @@ CREATE TABLE js_sys_company_office
CREATE TABLE js_sys_config
(
id varchar(64) NOT NULL,
config_name varchar(100) NOT NULL,
config_name vargraphic(100) NOT NULL,
config_key varchar(100) NOT NULL,
config_value varchar(1000),
config_value vargraphic(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),
remarks vargraphic(500),
PRIMARY KEY (id)
);
@@ -198,29 +199,29 @@ CREATE TABLE js_sys_dict_data
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_label vargraphic(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),
description vargraphic(500),
css_style vargraphic(500),
css_class vargraphic(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),
remarks vargraphic(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),
corp_name vargraphic(100) DEFAULT 'JeeSite' NOT NULL,
extend_s1 vargraphic(500),
extend_s2 vargraphic(500),
extend_s3 vargraphic(500),
extend_s4 vargraphic(500),
extend_s5 vargraphic(500),
extend_s6 vargraphic(500),
extend_s7 vargraphic(500),
extend_s8 vargraphic(500),
extend_i1 decimal(19),
extend_i2 decimal(19),
extend_i3 decimal(19),
@@ -241,7 +242,7 @@ CREATE TABLE js_sys_dict_data
CREATE TABLE js_sys_dict_type
(
id varchar(64) NOT NULL,
dict_name varchar(100) NOT NULL,
dict_name vargraphic(100) NOT NULL,
dict_type varchar(100) NOT NULL,
is_sys char(1) NOT NULL,
status char(1) DEFAULT '0' NOT NULL,
@@ -249,7 +250,7 @@ CREATE TABLE js_sys_dict_type
create_date timestamp NOT NULL,
update_by varchar(64) NOT NULL,
update_date timestamp NOT NULL,
remarks varchar(500),
remarks vargraphic(500),
PRIMARY KEY (id)
);
@@ -258,24 +259,35 @@ CREATE TABLE js_sys_dict_type
CREATE TABLE js_sys_employee
(
emp_code varchar(64) NOT NULL,
emp_name varchar(100) NOT NULL,
emp_name vargraphic(100) NOT NULL,
emp_name_en varchar(100),
office_code varchar(64) NOT NULL,
office_name varchar(100) NOT NULL,
office_name vargraphic(100) NOT NULL,
company_code varchar(64),
company_name varchar(200),
company_name vargraphic(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),
remarks vargraphic(500),
corp_code varchar(64) DEFAULT '0' NOT NULL,
corp_name varchar(100) DEFAULT 'JeeSite' NOT NULL,
corp_name vargraphic(100) DEFAULT 'JeeSite' NOT NULL,
PRIMARY KEY (emp_code)
);
-- 员工附属机构关系表
CREATE TABLE js_sys_employee_office
(
id varchar(64) NOT NULL UNIQUE,
emp_code varchar(64) NOT NULL,
office_code varchar(64) NOT NULL,
post_code varchar(64),
PRIMARY KEY (emp_code, office_code)
);
-- 员工与岗位关联表
CREATE TABLE js_sys_employee_post
(
@@ -289,11 +301,12 @@ CREATE TABLE js_sys_employee_post
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_md5 varchar(64) NOT NULL,
file_path vargraphic(1000) NOT NULL,
file_content_type varchar(200) NOT NULL,
file_extension varchar(100) NOT NULL,
file_size decimal(31) NOT NULL,
file_meta varchar(255),
PRIMARY KEY (file_id)
);
@@ -303,7 +316,7 @@ CREATE TABLE js_sys_file_upload
(
id varchar(64) NOT NULL,
file_id varchar(64) NOT NULL,
file_name varchar(500) NOT NULL,
file_name vargraphic(500) NOT NULL,
file_type varchar(20) NOT NULL,
biz_key varchar(64),
biz_type varchar(64),
@@ -312,7 +325,7 @@ CREATE TABLE js_sys_file_upload
create_date timestamp NOT NULL,
update_by varchar(64) NOT NULL,
update_date timestamp NOT NULL,
remarks varchar(500),
remarks vargraphic(500),
PRIMARY KEY (id)
);
@@ -322,17 +335,18 @@ 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,
description vargraphic(100) NOT NULL,
invoke_target vargraphic(1000) NOT NULL,
cron_expression varchar(255) NOT NULL,
misfire_instruction decimal(1) NOT NULL,
concurrent char(1) NOT NULL,
instance_name varchar(64) DEFAULT 'JeeSiteScheduler' 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),
remarks vargraphic(500),
PRIMARY KEY (job_name, job_group)
);
@@ -358,14 +372,14 @@ 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_code vargraphic(500) NOT NULL,
lang_text vargraphic(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),
remarks vargraphic(500),
PRIMARY KEY (id)
);
@@ -375,11 +389,11 @@ CREATE TABLE js_sys_log
(
id varchar(64) NOT NULL,
log_type varchar(50) NOT NULL,
log_title varchar(500) NOT NULL,
log_title vargraphic(500) NOT NULL,
create_by varchar(64) NOT NULL,
create_by_name varchar(100) NOT NULL,
create_by_name vargraphic(100) NOT NULL,
create_date timestamp NOT NULL,
request_uri varchar(500),
request_uri vargraphic(500),
request_method varchar(10),
request_params clob,
diff_modify_data clob,
@@ -389,12 +403,12 @@ CREATE TABLE js_sys_log
server_addr varchar(255) NOT NULL,
is_exception char(1),
exception_info clob,
user_agent varchar(500),
user_agent vargraphic(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,
corp_name vargraphic(100) DEFAULT 'JeeSite' NOT NULL,
PRIMARY KEY (id)
);
@@ -426,15 +440,15 @@ CREATE TABLE js_sys_menu
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),
remarks vargraphic(500),
extend_s1 vargraphic(500),
extend_s2 vargraphic(500),
extend_s3 vargraphic(500),
extend_s4 vargraphic(500),
extend_s5 vargraphic(500),
extend_s6 vargraphic(500),
extend_s7 vargraphic(500),
extend_s8 vargraphic(500),
extend_i1 decimal(19),
extend_i2 decimal(19),
extend_i3 decimal(19),
@@ -456,7 +470,7 @@ CREATE TABLE js_sys_module
(
module_code varchar(64) NOT NULL,
module_name varchar(100) NOT NULL,
description varchar(500),
description vargraphic(500),
main_class_name varchar(500),
current_version varchar(50),
upgrade_info varchar(300),
@@ -465,7 +479,7 @@ CREATE TABLE js_sys_module
create_date timestamp NOT NULL,
update_by varchar(64) NOT NULL,
update_date timestamp NOT NULL,
remarks varchar(500),
remarks vargraphic(500),
PRIMARY KEY (module_code)
);
@@ -479,19 +493,19 @@ CREATE TABLE js_sys_msg_inner
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,
receive_codes clob,
receive_names clob,
send_user_code varchar(64),
send_user_name varchar(100),
send_date timestamp,
is_attac char(1),
notify_types varchar(100) NOT NULL,
notify_types varchar(100),
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),
remarks vargraphic(500),
PRIMARY KEY (id)
);
@@ -501,7 +515,7 @@ 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_code varchar(64) NOT NULL,
receive_user_name varchar(100) NOT NULL,
read_status char(1) NOT NULL,
read_date timestamp,
@@ -574,7 +588,7 @@ 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_name vargraphic(100) NOT NULL,
tpl_type varchar(16) NOT NULL,
tpl_content clob NOT NULL,
status char(1) DEFAULT '0' NOT NULL,
@@ -582,7 +596,7 @@ CREATE TABLE js_sys_msg_template
create_date timestamp NOT NULL,
update_by varchar(64) NOT NULL,
update_date timestamp NOT NULL,
remarks varchar(500),
remarks vargraphic(500),
PRIMARY KEY (id)
);
@@ -599,7 +613,7 @@ CREATE TABLE js_sys_office
tree_level decimal(4) NOT NULL,
tree_names varchar(1000) NOT NULL,
view_code varchar(100) NOT NULL,
office_name varchar(100) NOT NULL,
office_name vargraphic(100) NOT NULL,
full_name varchar(200) NOT NULL,
office_type char(1) NOT NULL,
leader varchar(100),
@@ -612,17 +626,17 @@ CREATE TABLE js_sys_office
create_date timestamp NOT NULL,
update_by varchar(64) NOT NULL,
update_date timestamp NOT NULL,
remarks varchar(500),
remarks vargraphic(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),
corp_name vargraphic(100) DEFAULT 'JeeSite' NOT NULL,
extend_s1 vargraphic(500),
extend_s2 vargraphic(500),
extend_s3 vargraphic(500),
extend_s4 vargraphic(500),
extend_s5 vargraphic(500),
extend_s6 vargraphic(500),
extend_s7 vargraphic(500),
extend_s8 vargraphic(500),
extend_i1 decimal(19),
extend_i2 decimal(19),
extend_i3 decimal(19),
@@ -651,9 +665,9 @@ CREATE TABLE js_sys_post
create_date timestamp NOT NULL,
update_by varchar(64) NOT NULL,
update_date timestamp NOT NULL,
remarks varchar(500),
remarks vargraphic(500),
corp_code varchar(64) DEFAULT '0' NOT NULL,
corp_name varchar(100) DEFAULT 'JeeSite' NOT NULL,
corp_name vargraphic(100) DEFAULT 'JeeSite' NOT NULL,
PRIMARY KEY (post_code)
);
@@ -673,9 +687,9 @@ CREATE TABLE js_sys_role
create_date timestamp NOT NULL,
update_by varchar(64) NOT NULL,
update_date timestamp NOT NULL,
remarks varchar(500),
remarks vargraphic(500),
corp_code varchar(64) DEFAULT '0' NOT NULL,
corp_name varchar(100) DEFAULT 'JeeSite' NOT NULL,
corp_name vargraphic(100) DEFAULT 'JeeSite' NOT NULL,
PRIMARY KEY (role_code)
);
@@ -712,7 +726,7 @@ CREATE TABLE js_sys_user
phone varchar(100),
sex char(1),
avatar varchar(1000),
sign varchar(200),
sign vargraphic(200),
wx_openid varchar(100),
mobile_imei varchar(100),
user_type varchar(16) NOT NULL,
@@ -739,17 +753,17 @@ CREATE TABLE js_sys_user
create_date timestamp NOT NULL,
update_by varchar(64) NOT NULL,
update_date timestamp NOT NULL,
remarks varchar(500),
remarks vargraphic(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),
corp_name vargraphic(100) DEFAULT 'JeeSite' NOT NULL,
extend_s1 vargraphic(500),
extend_s2 vargraphic(500),
extend_s3 vargraphic(500),
extend_s4 vargraphic(500),
extend_s5 vargraphic(500),
extend_s6 vargraphic(500),
extend_s7 vargraphic(500),
extend_s8 vargraphic(500),
extend_i1 decimal(19),
extend_i2 decimal(19),
extend_i3 decimal(19),
@@ -803,7 +817,7 @@ 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 UNIQUE 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);
@@ -860,7 +874,6 @@ 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);

View File

@@ -4,6 +4,7 @@
IF OBJECT_ID('[js_gen_table_column]') IS NOT NULL DROP TABLE [js_gen_table_column];
IF OBJECT_ID('[js_gen_table]') IS NOT NULL DROP TABLE [js_gen_table];
IF OBJECT_ID('[js_sys_company_office]') IS NOT NULL DROP TABLE [js_sys_company_office];
IF OBJECT_ID('[js_sys_employee_office]') IS NOT NULL DROP TABLE [js_sys_employee_office];
IF OBJECT_ID('[js_sys_employee_post]') IS NOT NULL DROP TABLE [js_sys_employee_post];
IF OBJECT_ID('[js_sys_user_data_scope]') IS NOT NULL DROP TABLE [js_sys_user_data_scope];
IF OBJECT_ID('[js_sys_user_role]') IS NOT NULL DROP TABLE [js_sys_user_role];
@@ -276,6 +277,17 @@ CREATE TABLE [js_sys_employee]
);
-- 员工附属机构关系表
CREATE TABLE [js_sys_employee_office]
(
[id] varchar(64) NOT NULL UNIQUE,
[emp_code] varchar(64) NOT NULL,
[office_code] varchar(64) NOT NULL,
[post_code] varchar(64),
PRIMARY KEY ([emp_code], [office_code])
);
-- 员工与岗位关联表
CREATE TABLE [js_sys_employee_post]
(
@@ -289,11 +301,12 @@ CREATE TABLE [js_sys_employee_post]
CREATE TABLE [js_sys_file_entity]
(
[file_id] varchar(64) NOT NULL,
[file_md5] varchar(64) NOT NULL UNIQUE,
[file_md5] varchar(64) NOT NULL,
[file_path] nvarchar(1000) NOT NULL,
[file_content_type] varchar(200) NOT NULL,
[file_extension] varchar(100) NOT NULL,
[file_size] decimal(31) NOT NULL,
[file_meta] varchar(255),
PRIMARY KEY ([file_id])
);
@@ -327,6 +340,7 @@ CREATE TABLE [js_sys_job]
[cron_expression] varchar(255) NOT NULL,
[misfire_instruction] decimal(1) NOT NULL,
[concurrent] char(1) NOT NULL,
[instance_name] varchar(64) DEFAULT 'JeeSiteScheduler' NOT NULL,
[status] char(1) NOT NULL,
[create_by] varchar(64) NOT NULL,
[create_date] datetime NOT NULL,
@@ -479,13 +493,13 @@ CREATE TABLE [js_sys_msg_inner]
[content_type] char(1),
[msg_content] text NOT NULL,
[receive_type] char(1) NOT NULL,
[receive_codes] text NOT NULL,
[receive_names] text NOT NULL,
[send_user_code] varchar(64) NOT NULL,
[send_user_name] varchar(100) NOT NULL,
[send_date] datetime NOT NULL,
[receive_codes] text,
[receive_names] text,
[send_user_code] varchar(64),
[send_user_name] varchar(100),
[send_date] datetime,
[is_attac] char(1),
[notify_types] varchar(100) NOT NULL,
[notify_types] varchar(100),
[status] char(1) NOT NULL,
[create_by] varchar(64) NOT NULL,
[create_date] datetime NOT NULL,
@@ -501,7 +515,7 @@ 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_code] varchar(64) NOT NULL,
[receive_user_name] varchar(100) NOT NULL,
[read_status] char(1) NOT NULL,
[read_date] datetime,
@@ -803,7 +817,7 @@ 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 UNIQUE 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]);
@@ -860,7 +874,6 @@ 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]);

View File

@@ -5,6 +5,7 @@ SET SESSION FOREIGN_KEY_CHECKS=0;
DROP TABLE IF EXISTS js_gen_table_column;
DROP TABLE IF EXISTS js_gen_table;
DROP TABLE IF EXISTS js_sys_company_office;
DROP TABLE IF EXISTS js_sys_employee_office;
DROP TABLE IF EXISTS js_sys_employee_post;
DROP TABLE IF EXISTS js_sys_user_data_scope;
DROP TABLE IF EXISTS js_sys_user_role;
@@ -277,6 +278,18 @@ CREATE TABLE js_sys_employee
) COMMENT = '员工表';
-- 员工附属机构关系表
CREATE TABLE js_sys_employee_office
(
id varchar(64) NOT NULL COMMENT '编号',
emp_code varchar(64) NOT NULL COMMENT '员工编码',
office_code varchar(64) NOT NULL COMMENT '机构编码',
post_code varchar(64) COMMENT '岗位编码',
PRIMARY KEY (emp_code, office_code),
UNIQUE (id)
) COMMENT = '员工附属机构关系表';
-- 员工与岗位关联表
CREATE TABLE js_sys_employee_post
(
@@ -295,8 +308,8 @@ CREATE TABLE js_sys_file_entity
file_content_type varchar(200) NOT NULL COMMENT '文件内容类型',
file_extension varchar(100) NOT NULL COMMENT '文件后缀扩展名',
file_size decimal(31) NOT NULL COMMENT '文件大小(单位B)',
PRIMARY KEY (file_id),
UNIQUE (file_md5)
file_meta varchar(255) COMMENT '文件信息(JSON格式)',
PRIMARY KEY (file_id)
) COMMENT = '文件实体表';
@@ -329,6 +342,7 @@ CREATE TABLE js_sys_job
cron_expression varchar(255) NOT NULL COMMENT 'Cron执行表达式',
misfire_instruction decimal(1) NOT NULL COMMENT '计划执行错误策略',
concurrent char(1) NOT NULL COMMENT '是否并发执行',
instance_name varchar(64) DEFAULT 'JeeSiteScheduler' NOT NULL COMMENT '集群的实例名字',
status char(1) NOT NULL COMMENT '状态0正常 1删除 2暂停',
create_by varchar(64) NOT NULL COMMENT '创建者',
create_date datetime NOT NULL COMMENT '创建时间',
@@ -480,14 +494,14 @@ CREATE TABLE js_sys_msg_inner
content_level char(1) NOT NULL COMMENT '内容级别1普通 2一般 3紧急',
content_type char(1) COMMENT '内容类型1公告 2新闻 3会议 4其它',
msg_content text NOT NULL COMMENT '消息内容',
receive_type char(1) NOT NULL COMMENT '接受者类型1用户 2部门 3角色 4岗位',
receive_codes text NOT NULL COMMENT '接受者字符串',
receive_names text NOT NULL COMMENT '接受者名称字符串',
send_user_code varchar(64) NOT NULL COMMENT '发送者用户编码',
send_user_name varchar(100) NOT NULL COMMENT '发送者用户姓名',
send_date datetime NOT NULL COMMENT '发送时间',
receive_type char(1) NOT NULL COMMENT '接受者类型(0全部 1用户 2部门 3角色 4岗位',
receive_codes text COMMENT '接受者字符串',
receive_names text COMMENT '接受者名称字符串',
send_user_code varchar(64) COMMENT '发送者用户编码',
send_user_name varchar(100) COMMENT '发送者用户姓名',
send_date datetime COMMENT '发送时间',
is_attac char(1) COMMENT '是否有附件',
notify_types varchar(100) NOT NULL COMMENT '通知类型PC APP 短信 邮件 微信)多选',
notify_types varchar(100) COMMENT '通知类型PC APP 短信 邮件 微信)多选',
status char(1) NOT NULL COMMENT '状态0正常 1删除 4审核 5驳回 9草稿',
create_by varchar(64) NOT NULL COMMENT '创建者',
create_date datetime NOT NULL COMMENT '创建时间',
@@ -503,9 +517,9 @@ CREATE TABLE js_sys_msg_inner_record
(
id varchar(64) NOT NULL COMMENT '编号',
msg_inner_id varchar(64) NOT NULL COMMENT '所属消息',
receive_user_code varchar(64) COMMENT '接受者用户编码',
receive_user_code varchar(64) NOT NULL 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)
@@ -535,7 +549,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 = '消息推送表';
@@ -564,7 +578,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 = '消息已推送表';
@@ -805,7 +819,7 @@ CREATE INDEX idx_sys_company_status ON js_sys_company (status ASC);
CREATE INDEX idx_sys_company_vc ON js_sys_company (view_code ASC);
CREATE INDEX idx_sys_company_pcs ON js_sys_company (parent_codes ASC);
CREATE INDEX idx_sys_company_tss ON js_sys_company (tree_sorts ASC);
CREATE INDEX idx_sys_config_key ON js_sys_config (config_key ASC);
CREATE UNIQUE INDEX idx_sys_config_key ON js_sys_config (config_key ASC);
CREATE INDEX idx_sys_dict_data_cc ON js_sys_dict_data (corp_code ASC);
CREATE INDEX idx_sys_dict_data_dt ON js_sys_dict_data (dict_type ASC);
CREATE INDEX idx_sys_dict_data_pc ON js_sys_dict_data (parent_code ASC);
@@ -862,7 +876,6 @@ CREATE INDEX idx_sys_msg_inner_cl ON js_sys_msg_inner (content_level ASC);
CREATE INDEX idx_sys_msg_inner_sc ON js_sys_msg_inner (send_user_code ASC);
CREATE INDEX idx_sys_msg_inner_sd ON js_sys_msg_inner (send_date ASC);
CREATE INDEX idx_sys_msg_inner_r_mi ON js_sys_msg_inner_record (msg_inner_id ASC);
CREATE INDEX idx_sys_msg_inner_r_rc ON js_sys_msg_inner_record (receive_user_code ASC);
CREATE INDEX idx_sys_msg_inner_r_ruc ON js_sys_msg_inner_record (receive_user_code ASC);
CREATE INDEX idx_sys_msg_inner_r_status ON js_sys_msg_inner_record (read_status ASC);
CREATE INDEX idx_sys_msg_inner_r_star ON js_sys_msg_inner_record (is_star ASC);

View File

@@ -4,6 +4,7 @@
DROP TABLE js_gen_table_column CASCADE CONSTRAINTS;
DROP TABLE js_gen_table CASCADE CONSTRAINTS;
DROP TABLE js_sys_company_office CASCADE CONSTRAINTS;
DROP TABLE js_sys_employee_office CASCADE CONSTRAINTS;
DROP TABLE js_sys_employee_post CASCADE CONSTRAINTS;
DROP TABLE js_sys_user_data_scope CASCADE CONSTRAINTS;
DROP TABLE js_sys_user_role CASCADE CONSTRAINTS;
@@ -276,6 +277,17 @@ CREATE TABLE js_sys_employee
);
-- 员工附属机构关系表
CREATE TABLE js_sys_employee_office
(
id varchar2(64) NOT NULL UNIQUE,
emp_code varchar2(64) NOT NULL,
office_code varchar2(64) NOT NULL,
post_code varchar2(64),
PRIMARY KEY (emp_code, office_code)
);
-- 员工与岗位关联表
CREATE TABLE js_sys_employee_post
(
@@ -289,11 +301,12 @@ CREATE TABLE js_sys_employee_post
CREATE TABLE js_sys_file_entity
(
file_id varchar2(64) NOT NULL,
file_md5 varchar2(64) NOT NULL UNIQUE,
file_md5 varchar2(64) NOT NULL,
file_path nvarchar2(1000) NOT NULL,
file_content_type varchar2(200) NOT NULL,
file_extension varchar2(100) NOT NULL,
file_size number(31) NOT NULL,
file_meta varchar2(255),
PRIMARY KEY (file_id)
);
@@ -327,6 +340,7 @@ CREATE TABLE js_sys_job
cron_expression varchar2(255) NOT NULL,
misfire_instruction number(1) NOT NULL,
concurrent char(1) NOT NULL,
instance_name varchar2(64) DEFAULT 'JeeSiteScheduler' NOT NULL,
status char(1) NOT NULL,
create_by varchar2(64) NOT NULL,
create_date timestamp NOT NULL,
@@ -479,13 +493,13 @@ CREATE TABLE js_sys_msg_inner
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 varchar2(64) NOT NULL,
send_user_name varchar2(100) NOT NULL,
send_date timestamp NOT NULL,
receive_codes clob,
receive_names clob,
send_user_code varchar2(64),
send_user_name varchar2(100),
send_date timestamp,
is_attac char(1),
notify_types varchar2(100) NOT NULL,
notify_types varchar2(100),
status char(1) NOT NULL,
create_by varchar2(64) NOT NULL,
create_date timestamp NOT NULL,
@@ -501,7 +515,7 @@ CREATE TABLE js_sys_msg_inner_record
(
id varchar2(64) NOT NULL,
msg_inner_id varchar2(64) NOT NULL,
receive_user_code varchar2(64),
receive_user_code varchar2(64) NOT NULL,
receive_user_name varchar2(100) NOT NULL,
read_status char(1) NOT NULL,
read_date timestamp,
@@ -803,7 +817,7 @@ 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 UNIQUE 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);
@@ -860,7 +874,6 @@ 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);
@@ -1103,6 +1116,11 @@ COMMENT ON COLUMN js_sys_employee.update_date IS '更新时间';
COMMENT ON COLUMN js_sys_employee.remarks IS '备注信息';
COMMENT ON COLUMN js_sys_employee.corp_code IS '租户代码';
COMMENT ON COLUMN js_sys_employee.corp_name IS '租户名称';
COMMENT ON TABLE js_sys_employee_office IS '员工附属机构关系表';
COMMENT ON COLUMN js_sys_employee_office.id IS '编号';
COMMENT ON COLUMN js_sys_employee_office.emp_code IS '员工编码';
COMMENT ON COLUMN js_sys_employee_office.office_code IS '机构编码';
COMMENT ON COLUMN js_sys_employee_office.post_code IS '岗位编码';
COMMENT ON TABLE js_sys_employee_post IS '员工与岗位关联表';
COMMENT ON COLUMN js_sys_employee_post.emp_code IS '员工编码';
COMMENT ON COLUMN js_sys_employee_post.post_code IS '岗位编码';
@@ -1113,6 +1131,7 @@ COMMENT ON COLUMN js_sys_file_entity.file_path IS '文件相对路径';
COMMENT ON COLUMN js_sys_file_entity.file_content_type IS '文件内容类型';
COMMENT ON COLUMN js_sys_file_entity.file_extension IS '文件后缀扩展名';
COMMENT ON COLUMN js_sys_file_entity.file_size IS '文件大小(单位B)';
COMMENT ON COLUMN js_sys_file_entity.file_meta IS '文件信息(JSON格式)';
COMMENT ON TABLE js_sys_file_upload IS '文件上传表';
COMMENT ON COLUMN js_sys_file_upload.id IS '编号';
COMMENT ON COLUMN js_sys_file_upload.file_id IS '文件编号';
@@ -1134,6 +1153,7 @@ COMMENT ON COLUMN js_sys_job.invoke_target IS '调用目标字符串';
COMMENT ON COLUMN js_sys_job.cron_expression IS 'Cron执行表达式';
COMMENT ON COLUMN js_sys_job.misfire_instruction IS '计划执行错误策略';
COMMENT ON COLUMN js_sys_job.concurrent IS '是否并发执行';
COMMENT ON COLUMN js_sys_job.instance_name IS '集群的实例名字';
COMMENT ON COLUMN js_sys_job.status IS '状态0正常 1删除 2暂停';
COMMENT ON COLUMN js_sys_job.create_by IS '创建者';
COMMENT ON COLUMN js_sys_job.create_date IS '创建时间';
@@ -1249,7 +1269,7 @@ COMMENT ON COLUMN js_sys_msg_inner.msg_title IS '消息标题';
COMMENT ON COLUMN js_sys_msg_inner.content_level IS '内容级别1普通 2一般 3紧急';
COMMENT ON COLUMN js_sys_msg_inner.content_type IS '内容类型1公告 2新闻 3会议 4其它';
COMMENT ON COLUMN js_sys_msg_inner.msg_content IS '消息内容';
COMMENT ON COLUMN js_sys_msg_inner.receive_type IS '接受者类型1用户 2部门 3角色 4岗位';
COMMENT ON COLUMN js_sys_msg_inner.receive_type IS '接受者类型(0全部 1用户 2部门 3角色 4岗位';
COMMENT ON COLUMN js_sys_msg_inner.receive_codes IS '接受者字符串';
COMMENT ON COLUMN js_sys_msg_inner.receive_names IS '接受者名称字符串';
COMMENT ON COLUMN js_sys_msg_inner.send_user_code IS '发送者用户编码';
@@ -1268,7 +1288,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 '消息推送表';
@@ -1292,7 +1312,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 '编号';
@@ -1315,7 +1335,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

@@ -4,6 +4,7 @@
DROP TABLE IF EXISTS js_gen_table_column;
DROP TABLE IF EXISTS js_gen_table;
DROP TABLE IF EXISTS js_sys_company_office;
DROP TABLE IF EXISTS js_sys_employee_office;
DROP TABLE IF EXISTS js_sys_employee_post;
DROP TABLE IF EXISTS js_sys_user_data_scope;
DROP TABLE IF EXISTS js_sys_user_role;
@@ -276,6 +277,17 @@ CREATE TABLE js_sys_employee
) WITHOUT OIDS;
-- 员工附属机构关系表
CREATE TABLE js_sys_employee_office
(
id varchar(64) NOT NULL UNIQUE,
emp_code varchar(64) NOT NULL,
office_code varchar(64) NOT NULL,
post_code varchar(64),
PRIMARY KEY (emp_code, office_code)
) WITHOUT OIDS;
-- 员工与岗位关联表
CREATE TABLE js_sys_employee_post
(
@@ -289,11 +301,12 @@ CREATE TABLE js_sys_employee_post
CREATE TABLE js_sys_file_entity
(
file_id varchar(64) NOT NULL,
file_md5 varchar(64) NOT NULL UNIQUE,
file_md5 varchar(64) NOT NULL,
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,
file_meta varchar(255),
PRIMARY KEY (file_id)
) WITHOUT OIDS;
@@ -327,6 +340,7 @@ CREATE TABLE js_sys_job
cron_expression varchar(255) NOT NULL,
misfire_instruction decimal(1) NOT NULL,
concurrent char(1) NOT NULL,
instance_name varchar(64) DEFAULT 'JeeSiteScheduler' NOT NULL,
status char(1) NOT NULL,
create_by varchar(64) NOT NULL,
create_date timestamp NOT NULL,
@@ -479,13 +493,13 @@ CREATE TABLE js_sys_msg_inner
content_type char(1),
msg_content text NOT NULL,
receive_type char(1) NOT NULL,
receive_codes text NOT NULL,
receive_names text NOT NULL,
send_user_code varchar(64) NOT NULL,
send_user_name varchar(100) NOT NULL,
send_date timestamp NOT NULL,
receive_codes text,
receive_names text,
send_user_code varchar(64),
send_user_name varchar(100),
send_date timestamp,
is_attac char(1),
notify_types varchar(100) NOT NULL,
notify_types varchar(100),
status char(1) NOT NULL,
create_by varchar(64) NOT NULL,
create_date timestamp NOT NULL,
@@ -501,7 +515,7 @@ 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_code varchar(64) NOT NULL,
receive_user_name varchar(100) NOT NULL,
read_status char(1) NOT NULL,
read_date timestamp,
@@ -803,7 +817,7 @@ 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 UNIQUE 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);
@@ -860,7 +874,6 @@ 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);
@@ -1103,6 +1116,11 @@ COMMENT ON COLUMN js_sys_employee.update_date IS '更新时间';
COMMENT ON COLUMN js_sys_employee.remarks IS '备注信息';
COMMENT ON COLUMN js_sys_employee.corp_code IS '租户代码';
COMMENT ON COLUMN js_sys_employee.corp_name IS '租户名称';
COMMENT ON TABLE js_sys_employee_office IS '员工附属机构关系表';
COMMENT ON COLUMN js_sys_employee_office.id IS '编号';
COMMENT ON COLUMN js_sys_employee_office.emp_code IS '员工编码';
COMMENT ON COLUMN js_sys_employee_office.office_code IS '机构编码';
COMMENT ON COLUMN js_sys_employee_office.post_code IS '岗位编码';
COMMENT ON TABLE js_sys_employee_post IS '员工与岗位关联表';
COMMENT ON COLUMN js_sys_employee_post.emp_code IS '员工编码';
COMMENT ON COLUMN js_sys_employee_post.post_code IS '岗位编码';
@@ -1113,6 +1131,7 @@ COMMENT ON COLUMN js_sys_file_entity.file_path IS '文件相对路径';
COMMENT ON COLUMN js_sys_file_entity.file_content_type IS '文件内容类型';
COMMENT ON COLUMN js_sys_file_entity.file_extension IS '文件后缀扩展名';
COMMENT ON COLUMN js_sys_file_entity.file_size IS '文件大小(单位B)';
COMMENT ON COLUMN js_sys_file_entity.file_meta IS '文件信息(JSON格式)';
COMMENT ON TABLE js_sys_file_upload IS '文件上传表';
COMMENT ON COLUMN js_sys_file_upload.id IS '编号';
COMMENT ON COLUMN js_sys_file_upload.file_id IS '文件编号';
@@ -1134,6 +1153,7 @@ COMMENT ON COLUMN js_sys_job.invoke_target IS '调用目标字符串';
COMMENT ON COLUMN js_sys_job.cron_expression IS 'Cron执行表达式';
COMMENT ON COLUMN js_sys_job.misfire_instruction IS '计划执行错误策略';
COMMENT ON COLUMN js_sys_job.concurrent IS '是否并发执行';
COMMENT ON COLUMN js_sys_job.instance_name IS '集群的实例名字';
COMMENT ON COLUMN js_sys_job.status IS '状态0正常 1删除 2暂停';
COMMENT ON COLUMN js_sys_job.create_by IS '创建者';
COMMENT ON COLUMN js_sys_job.create_date IS '创建时间';
@@ -1249,7 +1269,7 @@ COMMENT ON COLUMN js_sys_msg_inner.msg_title IS '消息标题';
COMMENT ON COLUMN js_sys_msg_inner.content_level IS '内容级别1普通 2一般 3紧急';
COMMENT ON COLUMN js_sys_msg_inner.content_type IS '内容类型1公告 2新闻 3会议 4其它';
COMMENT ON COLUMN js_sys_msg_inner.msg_content IS '消息内容';
COMMENT ON COLUMN js_sys_msg_inner.receive_type IS '接受者类型1用户 2部门 3角色 4岗位';
COMMENT ON COLUMN js_sys_msg_inner.receive_type IS '接受者类型(0全部 1用户 2部门 3角色 4岗位';
COMMENT ON COLUMN js_sys_msg_inner.receive_codes IS '接受者字符串';
COMMENT ON COLUMN js_sys_msg_inner.receive_names IS '接受者名称字符串';
COMMENT ON COLUMN js_sys_msg_inner.send_user_code IS '发送者用户编码';
@@ -1268,7 +1288,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 '消息推送表';
@@ -1292,7 +1312,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 '编号';
@@ -1315,7 +1335,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.1.1-SNAPSHOT</version>
<version>4.1.5-SNAPSHOT</version>
<relativePath>../../parent/pom.xml</relativePath>
</parent>
@@ -85,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

@@ -38,12 +38,8 @@ public class CasAuthenticationFilter extends org.apache.shiro.cas.CasFilter {
// 登录成功后初始化授权信息并处理登录后的操作
authorizingRealm.onLoginSuccess((LoginInfo)subject.getPrincipal(), (HttpServletRequest)request);
String url = request.getParameter("__url");
if (StringUtils.isNotBlank(url)) {
WebUtils.issueRedirect(request, response, url, null, true);
} else {
WebUtils.issueRedirect(request, response, getSuccessUrl(), null, true);
}
// AJAX不支持Redirect改用Forward
request.getRequestDispatcher(getSuccessUrl()).forward(request, response);
return false;
}
@@ -55,12 +51,8 @@ public class CasAuthenticationFilter extends org.apache.shiro.cas.CasFilter {
Subject subject = getSubject(request, response);
if (subject.isAuthenticated() || subject.isRemembered()) {
try {
String url = request.getParameter("__url");
if (StringUtils.isNotBlank(url)) {
WebUtils.issueRedirect(request, response, url, null, true);
} else {
WebUtils.issueRedirect(request, response, getSuccessUrl(), null, true);
}
// AJAX不支持Redirect改用Forward
request.getRequestDispatcher(getSuccessUrl()).forward(request, response);
} catch (Exception e) {
e.printStackTrace();
}

View File

@@ -70,7 +70,7 @@ public class FormAuthenticationFilter extends org.apache.shiro.web.filter.authc.
protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {
String username = getUsername(request, response); // 用户名
String password = getPassword(request); // 登录密码
boolean rememberMe = isRememberMe(request); // 记住我(记住密码
boolean rememberMe = isRememberMe(request); // 记住我(自动登录
String host = getHost(request); // 登录主机
String captcha = getCaptcha(request); // 登录验证码
Map<String, Object> paramMap = ServletUtils.getExtParams(request); // 登录附加参数
@@ -95,7 +95,7 @@ public class FormAuthenticationFilter extends org.apache.shiro.web.filter.authc.
}
// 登录成功后,判断是否需要记住用户名
if (WebUtils.isTrue(request, DEFAULT_REMEMBER_USERCODE_PARAM)) {
rememberUserCodeCookie.setValue(EncodeUtils.xssFilter(username));
rememberUserCodeCookie.setValue(EncodeUtils.encodeUrl(EncodeUtils.xssFilter(username)));
rememberUserCodeCookie.saveTo((HttpServletRequest)request, (HttpServletResponse)response);
} else {
rememberUserCodeCookie.removeFrom((HttpServletRequest)request, (HttpServletResponse)response);
@@ -235,19 +235,8 @@ public class FormAuthenticationFilter extends org.apache.shiro.web.filter.authc.
// 登录成功后初始化授权信息并处理登录后的操作
authorizingRealm.onLoginSuccess((LoginInfo)subject.getPrincipal(), (HttpServletRequest) request);
// 登录操作如果是Ajax操作直接返回登录信息字符串。
if (ServletUtils.isAjaxRequest((HttpServletRequest) request)) {
request.getRequestDispatcher(getSuccessUrl()).forward(request, response); // AJAX不支持Redirect改用Forward
}
// 登录成功直接返回到首页
else {
String url = request.getParameter("__url");
if (StringUtils.isNotBlank(url)) {
WebUtils.issueRedirect(request, response, url, null, true);
} else {
WebUtils.issueRedirect(request, response, getSuccessUrl(), null, true);
}
}
// AJAX不支持Redirect改用Forward
request.getRequestDispatcher(getSuccessUrl()).forward(request, response);
return false;
}

View File

@@ -73,6 +73,14 @@ public class PermissionsAuthorizationFilter extends org.apache.shiro.web.filter.
}
if (ServletUtils.isAjaxRequest(req)) {
try {
String uri = req.getRequestURI();
if (StringUtils.endsWithIgnoreCase(uri, ".json")
&& !StringUtils.endsWithIgnoreCase(loginUrl, ".json")){
loginUrl += ".json";
}else if (StringUtils.endsWithIgnoreCase(uri, ".xml")
&& !StringUtils.endsWithIgnoreCase(loginUrl, ".xml")){
loginUrl += ".xml";
}
request.getRequestDispatcher(loginUrl).forward(
new GetHttpServletRequestWrapper(request), response);
} catch (ServletException e) {

View File

@@ -5,10 +5,11 @@ package com.jeesite.common.shiro.realm;
import javax.servlet.http.HttpServletRequest;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authc.AuthenticationToken;
import com.jeesite.common.codec.EncodeUtils;
import com.jeesite.common.codec.Sha1Utils;
import com.jeesite.common.shiro.authc.FormToken;
import com.jeesite.common.utils.SpringUtils;
import com.jeesite.modules.sys.entity.Log;
import com.jeesite.modules.sys.entity.User;
@@ -31,10 +32,26 @@ public class AuthorizingRealm extends BaseAuthorizingRealm {
public AuthorizingRealm() {
super();
// 设定密码校验的Hash算法与迭代次数
HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(HASH_ALGORITHM);
matcher.setHashIterations(HASH_INTERATIONS);
this.setCredentialsMatcher(matcher);
// // 设定密码校验的Hash算法与迭代次数V4.1.4及以上版本不需要了统一使用validatePassword验证密码
// HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(HASH_ALGORITHM);
// matcher.setHashIterations(HASH_INTERATIONS);
// this.setCredentialsMatcher(matcher);
}
/**
* 获取登录令牌
*/
@Override
protected FormToken getFormToken(AuthenticationToken authcToken) {
return super.getFormToken(authcToken);
}
/**
* 获取用户信息
*/
@Override
protected User getUserInfo(FormToken token) {
return super.getUserInfo(token);
}
/**

View File

@@ -0,0 +1,18 @@
/**
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
*/
package com.jeesite.modules.msg.dao;
import com.jeesite.common.dao.CrudDao;
import com.jeesite.common.mybatis.annotation.MyBatisDao;
import com.jeesite.modules.msg.entity.MsgInner;
/**
* 内部消息DAO接口
* @author ThinkGem
* @version 2019-03-12
*/
@MyBatisDao
public interface MsgInnerDao extends CrudDao<MsgInner> {
}

View File

@@ -0,0 +1,23 @@
/**
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
*/
package com.jeesite.modules.msg.dao;
import com.jeesite.common.dao.CrudDao;
import com.jeesite.common.mybatis.annotation.MyBatisDao;
import com.jeesite.modules.msg.entity.MsgInnerRecord;
/**
* 内部消息发送记录表DAO接口
* @author ThinkGem
* @version 2019-03-12
*/
@MyBatisDao
public interface MsgInnerRecordDao extends CrudDao<MsgInnerRecord> {
/**
* 根据消息编号和接受者用户名更新读取状态
*/
public long updateReadStatus(MsgInnerRecord msgInnerRecord);
}

View File

@@ -0,0 +1,214 @@
/**
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
*/
package com.jeesite.modules.msg.entity;
import java.util.Date;
import javax.validation.constraints.NotBlank;
import org.hibernate.validator.constraints.Length;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.jeesite.common.entity.DataEntity;
import com.jeesite.common.lang.DateUtils;
import com.jeesite.common.mybatis.annotation.Column;
import com.jeesite.common.mybatis.annotation.Table;
import com.jeesite.common.mybatis.mapper.query.QueryType;
/**
* 内部消息Entity
* @author ThinkGem
* @version 2019-03-12
*/
@Table(name="${_prefix}sys_msg_inner", alias="a", columns={
@Column(name="id", attrName="id", label="编号", isPK=true),
@Column(name="msg_title", attrName="msgTitle", label="消息标题", queryType=QueryType.LIKE),
@Column(name="content_level", attrName="contentLevel", label="内容等级", comment="内容等级1普通 2一般 3紧急"),
@Column(name="content_type", attrName="contentType", label="内容类型", comment="内容类型1公告 2新闻 3会议 4其它"),
@Column(name="msg_content", attrName="msgContent", label="消息内容"),
@Column(name="receive_type", attrName="receiveType", label="接受者类型", comment="接受者类型1用户 2部门 3角色 4岗位"),
@Column(name="receive_codes", attrName="receiveCodes", label="接受者字符串"),
@Column(name="receive_names", attrName="receiveNames", label="接受者名称字符串", queryType=QueryType.LIKE),
@Column(name="send_user_code", attrName="sendUserCode", label="发送者用户编码"),
@Column(name="send_user_name", attrName="sendUserName", label="发送者用户姓名", queryType=QueryType.LIKE),
@Column(name="send_date", attrName="sendDate", label="发送时间"),
@Column(name="is_attac", attrName="isAttac", label="是否有附件"),
@Column(name="notify_types", attrName="notifyTypes", label="通知类型", comment="通知类型PC APP 短信 邮件 微信)多选"),
@Column(includeEntity=DataEntity.class, comment="状态0正常 1删除 4审核 5驳回 9草稿"),
}, orderBy="a.update_date DESC"
)
public class MsgInner extends DataEntity<MsgInner> {
// 接受者类型0所有 1用户 2部门 3角色 4岗位
public static final String RECEIVE_TYPE_ALL = "0";
public static final String RECEIVE_TYPE_USER = "1";
public static final String RECEIVE_TYPE_OFFICE = "2";
public static final String RECEIVE_TYPE_ROLE = "3";
public static final String RECEIVE_TYPE_POST = "4";
// 内容级别1普通 2一般 3紧急
public static final String CONTENT_LEVEL_1 = "1";
public static final String CONTENT_LEVEL_2 = "2";
public static final String CONTENT_LEVEL_3 = "3";
private static final long serialVersionUID = 1L;
private String msgTitle; // 消息标题
private String contentLevel; // 内容等级1普通 2一般 3紧急
private String contentType; // 内容类型1公告 2新闻 3会议 4其它
private String msgContent; // 消息内容
private String receiveType; // 接受者类型1用户 2部门 3角色 4岗位
private String receiveCodes; // 接受者字符串
private String receiveNames; // 接受者名称字符串
private String sendUserCode; // 发送者用户编码
private String sendUserName; // 发送者用户姓名
private Date sendDate; // 发送时间
private String isAttac; // 是否有附件
private String notifyTypes; // 通知类型PC APP 短信 邮件 微信)多选
private MsgInnerRecord record; // 消息记录状态
public MsgInner() {
this(null);
}
public MsgInner(String id){
super(id);
}
@NotBlank(message="消息标题不能为空")
@Length(min=0, max=200, message="消息标题长度不能超过 200 个字符")
public String getMsgTitle() {
return msgTitle;
}
public void setMsgTitle(String msgTitle) {
this.msgTitle = msgTitle;
}
@NotBlank(message="内容级别不能为空")
@Length(min=0, max=1, message="内容级别长度不能超过 1 个字符")
public String getContentLevel() {
return contentLevel;
}
public void setContentLevel(String contentLevel) {
this.contentLevel = contentLevel;
}
@Length(min=0, max=1, message="内容类型长度不能超过 1 个字符")
public String getContentType() {
return contentType;
}
public void setContentType(String contentType) {
this.contentType = contentType;
}
@NotBlank(message="消息内容不能为空")
public String getMsgContent() {
return msgContent;
}
public void setMsgContent(String msgContent) {
this.msgContent = msgContent;
}
@NotBlank(message="接受者类型不能为空")
@Length(min=0, max=1, message="接受者类型长度不能超过 1 个字符")
public String getReceiveType() {
return receiveType;
}
public void setReceiveType(String receiveType) {
this.receiveType = receiveType;
}
public String getReceiveCodes() {
return receiveCodes;
}
public void setReceiveCodes(String receiveCodes) {
this.receiveCodes = receiveCodes;
}
public String getReceiveNames() {
return receiveNames;
}
public void setReceiveNames(String receiveNames) {
this.receiveNames = receiveNames;
}
@Length(min=0, max=64, message="发送者用户编码长度不能超过 64 个字符")
public String getSendUserCode() {
return sendUserCode;
}
public void setSendUserCode(String sendUserCode) {
this.sendUserCode = sendUserCode;
}
@Length(min=0, max=100, message="发送者用户姓名长度不能超过 100 个字符")
public String getSendUserName() {
return sendUserName;
}
public void setSendUserName(String sendUserName) {
this.sendUserName = sendUserName;
}
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
public Date getSendDate() {
return sendDate;
}
public void setSendDate(Date sendDate) {
this.sendDate = sendDate;
}
public Date getSendDate_gte() {
return sqlMap.getWhere().getValue("send_date", QueryType.GTE);
}
public void setSendDate_gte(Date sendDate) {
sendDate = DateUtils.getOfDayFirst(sendDate);
sqlMap.getWhere().and("send_date", QueryType.GTE, sendDate);
}
public Date getSendDate_lte() {
return sqlMap.getWhere().getValue("send_date", QueryType.LTE);
}
public void setSendDate_lte(Date sendDate) {
sendDate = DateUtils.getOfDayLast(sendDate);
sqlMap.getWhere().and("send_date", QueryType.LTE, sendDate);
}
@Length(min=0, max=1, message="是否有附件长度不能超过 1 个字符")
public String getIsAttac() {
return isAttac;
}
public void setIsAttac(String isAttac) {
this.isAttac = isAttac;
}
@Length(min=0, max=100, message="通知类型长度不能超过 100 个字符")
public String getNotifyTypes() {
return notifyTypes;
}
public void setNotifyTypes(String notifyTypes) {
this.notifyTypes = notifyTypes;
}
public MsgInnerRecord getRecord() {
return record;
}
public void setRecord(MsgInnerRecord record) {
this.record = record;
}
}

View File

@@ -0,0 +1,112 @@
/**
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
*/
package com.jeesite.modules.msg.entity;
import java.util.Date;
import javax.validation.constraints.NotBlank;
import org.hibernate.validator.constraints.Length;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.jeesite.common.entity.DataEntity;
import com.jeesite.common.mybatis.annotation.Column;
import com.jeesite.common.mybatis.annotation.Table;
import com.jeesite.common.mybatis.mapper.query.QueryType;
/**
* 内部消息发送记录表Entity
* @author ThinkGem
* @version 2019-03-12
*/
@Table(name="${_prefix}sys_msg_inner_record", alias="a", columns={
@Column(name="id", attrName="id", label="编号", isPK=true),
@Column(name="msg_inner_id", attrName="msgInnerId", label="所属消息"),
@Column(name="receive_user_code", attrName="receiveUserCode", label="接受者用户编码"),
@Column(name="receive_user_name", attrName="receiveUserName", label="接受者用户姓名", queryType=QueryType.LIKE),
@Column(name="read_status", attrName="readStatus", label="读取状态", comment="读取状态0未送达 1已读 2未读"),
@Column(name="read_date", attrName="readDate", label="阅读时间"),
@Column(name="is_star", attrName="isStar", label="是否标星"),
}, orderBy="a.read_date ASC, a.id ASC"
)
public class MsgInnerRecord extends DataEntity<MsgInnerRecord> {
// 读取状态0未送达 1已读 2未读
public static final String READ_STATUS_READ = "1";
public static final String READ_STATUS_UNREAD = "2";
private static final long serialVersionUID = 1L;
private String msgInnerId; // 所属消息
private String receiveUserCode; // 接受者用户编码
private String receiveUserName; // 接受者用户姓名
private String readStatus; // 读取状态0未送达 1已读 2未读
private Date readDate; // 阅读时间
private String isStar; // 是否标星
public MsgInnerRecord() {
this(null);
}
public MsgInnerRecord(String id){
super(id);
}
@NotBlank(message="所属消息不能为空")
@Length(min=0, max=64, message="所属消息长度不能超过 64 个字符")
public String getMsgInnerId() {
return msgInnerId;
}
public void setMsgInnerId(String msgInnerId) {
this.msgInnerId = msgInnerId;
}
@Length(min=0, max=64, message="接受者用户编码长度不能超过 64 个字符")
public String getReceiveUserCode() {
return receiveUserCode;
}
public void setReceiveUserCode(String receiveUserCode) {
this.receiveUserCode = receiveUserCode;
}
@NotBlank(message="接受者用户姓名不能为空")
@Length(min=0, max=100, message="接受者用户姓名长度不能超过 100 个字符")
public String getReceiveUserName() {
return receiveUserName;
}
public void setReceiveUserName(String receiveUserName) {
this.receiveUserName = receiveUserName;
}
@NotBlank(message="读取状态不能为空")
@Length(min=0, max=1, message="读取状态长度不能超过 1 个字符")
public String getReadStatus() {
return readStatus;
}
public void setReadStatus(String readStatus) {
this.readStatus = readStatus;
}
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
public Date getReadDate() {
return readDate;
}
public void setReadDate(Date readDate) {
this.readDate = readDate;
}
@Length(min=0, max=1, message="是否标星长度不能超过 1 个字符")
public String getIsStar() {
return isStar;
}
public void setIsStar(String isStar) {
this.isStar = isStar;
}
}

View File

@@ -0,0 +1,78 @@
/**
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
*/
package com.jeesite.modules.msg.send;
import org.apache.commons.mail.HtmlEmail;
import org.springframework.stereotype.Service;
import com.jeesite.common.config.Global;
import com.jeesite.common.lang.ExceptionUtils;
import com.jeesite.common.lang.StringUtils;
import com.jeesite.common.service.BaseService;
import com.jeesite.modules.msg.entity.MsgPush;
import com.jeesite.modules.msg.entity.content.EmailMsgContent;
import com.jeesite.modules.msg.send.MsgSendService;
/**
* 电子邮件发送服务实现
* @author ThinkGem
* @version 2018年5月13日
*/
@Service
public class EmailSendService extends BaseService implements MsgSendService{
@Override
public void sendMessage(MsgPush msgPush) {
try{
String fromAddress = Global.getProperty("msg.email.fromAddress");
String fromPassword = Global.getProperty("msg.email.fromPassword");
String fromHostName = Global.getProperty("msg.email.fromHostName");
Integer smtpPort = Global.getPropertyToInteger("msg.email.smtpPort", "25");
String sslOnConnect = Global.getProperty("msg.email.sslOnConnect", "false");
String sslSmtpPort = Global.getProperty("msg.email.sslSmtpPort", "465");
HtmlEmail htmlEmail = new HtmlEmail();
htmlEmail.setCharset("utf-8");
htmlEmail.setFrom(fromAddress);
htmlEmail.setAuthentication(fromAddress, fromPassword);
htmlEmail.setHostName(fromHostName);
htmlEmail.setSmtpPort(smtpPort);
if ("true".equals(sslOnConnect)) {
htmlEmail.setSSLOnConnect(true);
htmlEmail.setSslSmtpPort(sslSmtpPort);
}
htmlEmail.addTo(msgPush.getReceiveCode(), msgPush.getReceiveUserName());
// 内容
EmailMsgContent content = msgPush.parseMsgContent(EmailMsgContent.class);
htmlEmail.setSubject(content.getTitle());
htmlEmail.setMsg(content.getContent());
// 抄送
if (StringUtils.isNotBlank(content.getCc())) {
for (String email : content.getCc().split(";")) {
htmlEmail.addCc(email);
}
}
// 密送
if (StringUtils.isNotBlank(content.getBcc())) {
for (String email : content.getBcc().split(";")) {
htmlEmail.addBcc(email);
}
}
// 发送邮件
String result = htmlEmail.send();
// 发送成功
msgPush.setPushStatus(MsgPush.PUSH_STATUS_SUCCESS);
msgPush.addPushReturnContent(result);
} catch (Exception ex) {
logger.error("发送邮件失败! ", ex);
msgPush.setPushStatus(MsgPush.PUSH_STATUS_FAIL);
msgPush.addPushReturnContent(ExceptionUtils.getStackTraceAsString(ex));
}
}
}

View File

@@ -0,0 +1,79 @@
/**
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
*/
package com.jeesite.modules.msg.send;
import java.util.Date;
import java.util.Map;
import org.springframework.stereotype.Service;
import com.jeesite.common.lang.ExceptionUtils;
import com.jeesite.common.lang.ObjectUtils;
import com.jeesite.common.mapper.JsonMapper;
import com.jeesite.common.msg.SmsUtils;
import com.jeesite.common.service.BaseService;
import com.jeesite.modules.msg.entity.MsgPush;
import com.jeesite.modules.msg.entity.content.SmsMsgContent;
import com.jeesite.modules.msg.send.MsgSendService;
/**
* 短信发送服务实现
* @author ThinkGem
* @version 2018年5月13日
*/
@Service
public class SmsSendService extends BaseService implements MsgSendService{
@Override
public void sendMessage(MsgPush msgPush) {
try{
// String url = Global.getProperty("msg.sms.url");
// String data = Global.getProperty("msg.sms.data");
// String prefix = Global.getProperty("msg.sms.prefix", "");
// String suffix = Global.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", msgPush.getReceiveCode());
// // 短信内容
// SmsMsgContent content = msgPush.parseMsgContent(SmsMsgContent.class);
// conn.data("content", prefix + content.getContent() + suffix);
// // 发送短信
// String result = conn.execute().body();
// String result = "{result:0,message:\"ok\"}"; // 模拟发送结果
// Map<String, Object> map = JsonMapper.fromJson(result, Map.class);
// 发送短信
SmsMsgContent content = msgPush.parseMsgContent(SmsMsgContent.class);
String result = SmsUtils.send(content.getContent(), msgPush.getReceiveCode());
Map<String, Object> map = JsonMapper.fromJson(result, Map.class);
// 发送成功
if (ObjectUtils.toInteger(map.get("result")) == 0){
msgPush.setPushStatus(MsgPush.PUSH_STATUS_SUCCESS);
msgPush.addPushReturnContent(result);
}
// 发送失败
else{
throw new RuntimeException(result);
}
} catch (Exception ex) {
logger.error("发送短信失败! ", ex);
msgPush.setPushDate(new Date());
msgPush.setPushStatus(MsgPush.PUSH_STATUS_FAIL);
msgPush.addPushReturnContent(ExceptionUtils.getStackTraceAsString(ex));
}
}
}

View File

@@ -0,0 +1,243 @@
/**
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
*/
package com.jeesite.modules.msg.service;
import java.util.Date;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.jeesite.common.callback.MethodCallback;
import com.jeesite.common.collect.ListUtils;
import com.jeesite.common.config.Global;
import com.jeesite.common.entity.Page;
import com.jeesite.common.lang.StringUtils;
import com.jeesite.common.service.CrudService;
import com.jeesite.common.web.http.ServletUtils;
import com.jeesite.modules.file.utils.FileUploadUtils;
import com.jeesite.modules.msg.dao.MsgInnerDao;
import com.jeesite.modules.msg.dao.MsgInnerRecordDao;
import com.jeesite.modules.msg.entity.MsgInner;
import com.jeesite.modules.msg.entity.MsgInnerRecord;
import com.jeesite.modules.msg.entity.MsgPush;
import com.jeesite.modules.msg.entity.content.AppMsgContent;
import com.jeesite.modules.msg.entity.content.BaseMsgContent;
import com.jeesite.modules.msg.entity.content.EmailMsgContent;
import com.jeesite.modules.msg.entity.content.PcMsgContent;
import com.jeesite.modules.msg.entity.content.SmsMsgContent;
import com.jeesite.modules.msg.utils.MsgPushUtils;
import com.jeesite.modules.sys.entity.EmpUser;
import com.jeesite.modules.sys.entity.User;
import com.jeesite.modules.sys.service.EmpUserService;
/**
* 内部消息Service
* @author ThinkGem
* @version 2019-03-12
*/
@Service
@Transactional(readOnly=true)
public class MsgInnerService extends CrudService<MsgInnerDao, MsgInner> {
@Autowired
private EmpUserService empUserService;
@Autowired
private MsgInnerRecordDao msgInnerRecordDao;
/**
* 获取单条数据
* @param msgInner
* @return
*/
@Override
public MsgInner get(MsgInner msgInner) {
return super.get(msgInner);
}
/**
* 查询分页数据
* @param msgInner 查询条件
* @param msgInner.page 分页对象
* @return
*/
@Override
public Page<MsgInner> findPage(MsgInner msgInner) {
return super.findPage(msgInner);
}
/**
* 查询消息记录数据
*/
public List<MsgInnerRecord> findRecordList(MsgInnerRecord msgInnerRecord){
return msgInnerRecordDao.findList(msgInnerRecord);
}
/**
* 保存数据(插入或更新)
* @param msgInner
*/
@Override
@Transactional(readOnly=false)
public void save(MsgInner msgInner) {
if (msgInner.getIsNewRecord()){
User user = msgInner.getCurrentUser();
msgInner.setSendUserCode(user.getUserCode());
msgInner.setSendUserName(user.getUserName());
// 没有设置状态,则默认新增后是草稿状态
if (StringUtils.isBlank(msgInner.getStatus())){
msgInner.setStatus(MsgInner.STATUS_DRAFT);
}
}
msgInner.setSendDate(new Date());
msgInner.setIsAttac(StringUtils.isNotBlank(ServletUtils.getParameter("msgInner_file"))?Global.YES:Global.NO);
super.save(msgInner);
// 保存上传附件
FileUploadUtils.saveFileUpload(msgInner.getId(), "msgInner_file");
// 发送内部消息
if (MsgInner.STATUS_NORMAL.equals(msgInner.getStatus())){
this.updateStatus(msgInner); // 更新状态
List<EmpUser> empUserList = null;
if (MsgInner.RECEIVE_TYPE_ALL.equals(msgInner.getReceiveType())){
EmpUser empUser = new EmpUser();
empUser.setCodes(new String[]{});
empUserList = empUserService.findUserList(empUser);
}else{
String[] codes = StringUtils.split(msgInner.getReceiveCodes(), ",");
String[] names = StringUtils.split(msgInner.getReceiveNames(), ",");
if (codes != null && names != null && codes.length > 0 && codes.length == names.length){
EmpUser empUser = new EmpUser();
empUser.setCodes(codes);
switch(msgInner.getReceiveType()){
case MsgInner.RECEIVE_TYPE_USER:
empUserList = ListUtils.newArrayList();
for (int i=0; i<codes.length; i++){
EmpUser e = new EmpUser();
e.setUserCode(codes[i]);
e.setUserName(names[i]);
empUserList.add(e);
}
break;
case MsgInner.RECEIVE_TYPE_OFFICE:
empUserList = empUserService.findUserListByOfficeCodes(empUser);
break;
case MsgInner.RECEIVE_TYPE_ROLE:
empUserList = empUserService.findUserListByRoleCodes(empUser);
break;
case MsgInner.RECEIVE_TYPE_POST:
empUserList = empUserService.findUserListByPostCodes(empUser);
break;
}
}
}
this.saveMsgInnerRecord(msgInner, empUserList);
}
}
/**
* 保存消息推送记录
*/
private void saveMsgInnerRecord(MsgInner msgInner, List<EmpUser> empUserList){
if (empUserList == null || empUserList.size() <= 0){
return;
}
String[] notifyTypes = StringUtils.split(msgInner.getNotifyTypes(), ",");
List<MsgInnerRecord> recordList = ListUtils.newArrayList();
empUserList.forEach(user -> {
MsgInnerRecord r = new MsgInnerRecord();
r.setMsgInnerId(msgInner.getId());
r.setReceiveUserCode(user.getUserCode());
r.setReceiveUserName(user.getUserName());
r.setReadStatus(MsgInnerRecord.READ_STATUS_UNREAD);
recordList.add(r);
// 发送消息通知(消息推送)
if (notifyTypes != null){
for (String type : notifyTypes){
BaseMsgContent msgContent = null;
if (MsgPush.TYPE_PC.equals(type)){
msgContent = new PcMsgContent();
msgContent.setContent("你有一条内部消息,点击“详情”进行查阅。");
((PcMsgContent)msgContent).addButton(new String[]{"详情",
Global.getAdminPath()+"/msg/msgInner/view?id="+msgInner.getId()});
}else if (MsgPush.TYPE_APP.equals(type)){
msgContent = new AppMsgContent();
}else if (MsgPush.TYPE_SMS.equals(type)){
msgContent = new SmsMsgContent();
}else if (MsgPush.TYPE_EMAIL.equals(type)){
msgContent = new EmailMsgContent();
}
if (msgContent != null){
msgContent.setTitle(msgInner.getMsgTitle());
if (msgContent.getContent() == null){
msgContent.setContent("你有一条内部消息请查阅:"
+ StringUtils.abbr(msgInner.getMsgTitle(), 30));
}
msgContent.setMsgPush(new MsgPush());
msgContent.getMsgPush().setIsRealtimePush(false); // 关闭实时推送,改为手动推送
MsgPushUtils.push(msgContent, msgInner.getId(),
MsgInner.class.getSimpleName(), user.getUserCode());
}
}
}
});
ListUtils.pageList(recordList, 100, new MethodCallback() {
@Override
@SuppressWarnings("unchecked")
public Object execute(Object... objs) {
msgInnerRecordDao.insertBatch((List<MsgInnerRecord>)objs[0]);
return null;
}
});
// 手动触发消息推送任务
if (Global.TRUE.equals(Global.getProperty("msg.realtime.enabled"))){
new Thread(){
public void run() {
try{
MsgPushUtils.getMsgPushTask().execute();
}catch(Exception ex){
logger.error("实时消息发送失败,推送服务配置不正确。", ex);
}
}
}.start();
}
}
/**
* 根据消息编号和接受者用户名读取内部消息
*/
@Transactional(readOnly=false)
public void readMsgInnerRecord(MsgInner msgInner){
MsgInnerRecord msgInnerRecord = new MsgInnerRecord();
msgInnerRecord.setMsgInnerId(msgInner.getId());
msgInnerRecord.setReceiveUserCode(msgInner.getCurrentUser().getUserCode());
msgInnerRecord.setReadStatus(MsgInnerRecord.READ_STATUS_READ);
msgInnerRecord.setReadDate(new Date());
msgInnerRecordDao.updateReadStatus(msgInnerRecord);
// 将关联的内部消息通知更新为已读(消息推送)
MsgPushUtils.readMsgByBiz(msgInner.getId(), MsgInner.class.getSimpleName(),
msgInnerRecord.getReceiveUserCode());
}
/**
* 更新状态
* @param msgInner
*/
@Override
@Transactional(readOnly=false)
public void updateStatus(MsgInner msgInner) {
super.updateStatus(msgInner);
}
/**
* 删除数据
* @param msgInner
*/
@Override
@Transactional(readOnly=false)
public void delete(MsgInner msgInner) {
super.delete(msgInner);
}
}

View File

@@ -0,0 +1,140 @@
/**
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
*/
package com.jeesite.modules.msg.web;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.jeesite.common.config.Global;
import com.jeesite.common.entity.Page;
import com.jeesite.common.lang.StringUtils;
import com.jeesite.common.web.BaseController;
import com.jeesite.modules.msg.entity.MsgInner;
import com.jeesite.modules.msg.entity.MsgInnerRecord;
import com.jeesite.modules.msg.entity.MsgPush;
import com.jeesite.modules.msg.service.MsgInnerService;
/**
* 内部消息Controller
* @author ThinkGem
* @version 2019-03-12
*/
@Controller
@RequestMapping(value = "${adminPath}/msg/msgInner")
public class MsgInnerController extends BaseController {
@Autowired
private MsgInnerService msgInnerService;
/**
* 获取数据
*/
@ModelAttribute
public MsgInner get(String id, boolean isNewRecord) {
return msgInnerService.get(id, isNewRecord);
}
/**
* 查询列表
*/
@RequiresPermissions("msg:msgInner:view")
@RequestMapping(value = {"list", ""})
public String list(MsgInner msgInner, Model model) {
model.addAttribute("msgInner", msgInner);
return "modules/msg/msgInnerList";
}
/**
* 查询列表数据
*/
@RequiresPermissions("msg:msgInner:view")
@RequestMapping(value = "listData")
@ResponseBody
public Page<MsgInner> listData(MsgInner msgInner, HttpServletRequest request, HttpServletResponse response) {
msgInner.setPage(new Page<>(request, response));
msgInner.setRecord(new MsgInnerRecord());
msgInner.getRecord().setReceiveUserCode(msgInner.getCurrentUser().getUserCode());
Page<MsgInner> page = msgInnerService.findPage(msgInner);
return page;
}
/**
* 查看编辑表单
*/
@RequiresPermissions("msg:msgInner:view")
@RequestMapping(value = "form")
public String form(MsgInner msgInner, Model model) {
if (StringUtils.isBlank(msgInner.getNotifyTypes())){
msgInner.setNotifyTypes(MsgPush.TYPE_PC);
}
if (StringUtils.isBlank(msgInner.getContentLevel())){
msgInner.setContentLevel(MsgInner.CONTENT_LEVEL_1);
}
if (StringUtils.isBlank(msgInner.getReceiveType())){
msgInner.setReceiveType(MsgInner.RECEIVE_TYPE_USER);
}
model.addAttribute("msgInner", msgInner);
return "modules/msg/msgInnerForm";
}
/**
* 查看编辑表单
*/
@RequiresPermissions("msg:msgInner:view")
@RequestMapping(value = "view")
public String view(MsgInner msgInner, Model model) {
model.addAttribute("msgInner", msgInner);
// 根据消息编号和接受者用户名读取内部消息
msgInnerService.readMsgInnerRecord(msgInner);
// 查询已读和未读用户列表数据
MsgInnerRecord msgInnerRecord = new MsgInnerRecord();
msgInnerRecord.setMsgInnerId(msgInner.getId());
msgInnerRecord.setReadStatus(MsgInnerRecord.READ_STATUS_READ);
model.addAttribute("readList", msgInnerService.findRecordList(msgInnerRecord));
msgInnerRecord.setReadStatus(MsgInnerRecord.READ_STATUS_UNREAD);
model.addAttribute("unReadList", msgInnerService.findRecordList(msgInnerRecord));
return "modules/msg/msgInnerView";
}
/**
* 保存消息
*/
@RequiresPermissions("msg:msgInner:edit")
@PostMapping(value = "save")
@ResponseBody
public String save(@Validated MsgInner msgInner, HttpServletRequest request) {
MsgInner old = super.getWebDataBinderSource(request);
if (old != null && MsgInner.STATUS_NORMAL.equals(old.getStatus())){
return renderResult(Global.FALSE, "数据已发布,不允许修改!");
}
msgInnerService.save(msgInner);
return renderResult(Global.TRUE, text("保存消息成功!"));
}
/**
* 删除消息
*/
@RequiresPermissions("msg:msgInner:edit")
@RequestMapping(value = "delete")
@ResponseBody
public String delete(MsgInner msgInner, HttpServletRequest request) {
MsgInner old = super.getWebDataBinderSource(request);
if (old != null && MsgInner.STATUS_NORMAL.equals(old.getStatus())){
return renderResult(Global.FALSE, "数据已发布,不允许删除!");
}
msgInnerService.delete(msgInner);
return renderResult(Global.TRUE, text("删除消息成功!"));
}
}

View File

@@ -4,7 +4,6 @@
package com.jeesite.modules.sys.dao;
import com.jeesite.common.dao.TreeDao;
import com.jeesite.common.datasource.DataSourceHolder;
import com.jeesite.common.mybatis.annotation.MyBatisDao;
import com.jeesite.modules.sys.entity.Area;
@@ -13,7 +12,7 @@ import com.jeesite.modules.sys.entity.Area;
* @author ThinkGem
* @version 2017-03-22
*/
@MyBatisDao(dataSourceName=DataSourceHolder.DEFAULT)
@MyBatisDao
public interface AreaDao extends TreeDao<Area> {
}

View File

@@ -4,7 +4,6 @@
package com.jeesite.modules.sys.dao;
import com.jeesite.common.dao.TreeDao;
import com.jeesite.common.datasource.DataSourceHolder;
import com.jeesite.common.mybatis.annotation.MyBatisDao;
import com.jeesite.modules.sys.entity.Company;
@@ -13,7 +12,7 @@ import com.jeesite.modules.sys.entity.Company;
* @author ThinkGem
* @version 2017-03-12
*/
@MyBatisDao(dataSourceName=DataSourceHolder.DEFAULT)
@MyBatisDao
public interface CompanyDao extends TreeDao<Company> {
}

View File

@@ -4,7 +4,6 @@
package com.jeesite.modules.sys.dao;
import com.jeesite.common.dao.CrudDao;
import com.jeesite.common.datasource.DataSourceHolder;
import com.jeesite.common.mybatis.annotation.MyBatisDao;
import com.jeesite.modules.sys.entity.CompanyOffice;
@@ -13,7 +12,7 @@ import com.jeesite.modules.sys.entity.CompanyOffice;
* @author ThinkGem
* @version 2017-03-23
*/
@MyBatisDao(dataSourceName=DataSourceHolder.DEFAULT)
@MyBatisDao
public interface CompanyOfficeDao extends CrudDao<CompanyOffice> {
}

View File

@@ -3,8 +3,9 @@
*/
package com.jeesite.modules.sys.dao;
import java.util.List;
import com.jeesite.common.dao.CrudDao;
import com.jeesite.common.datasource.DataSourceHolder;
import com.jeesite.common.mybatis.annotation.MyBatisDao;
import com.jeesite.modules.sys.entity.EmpUser;
@@ -13,7 +14,27 @@ import com.jeesite.modules.sys.entity.EmpUser;
* @author ThinkGem
* @version 2017-03-25
*/
@MyBatisDao(dataSourceName=DataSourceHolder.DEFAULT)
@MyBatisDao
public interface EmpUserDao extends CrudDao<EmpUser> {
/**
* 查询全部用户,仅返回基本信息
*/
public List<EmpUser> findUserList(EmpUser empUser);
/**
* 根据部门编码查询用户,仅返回基本信息
*/
public List<EmpUser> findUserListByOfficeCodes(EmpUser empUser);
/**
* 根据角色编码查询用户,仅返回基本信息
*/
public List<EmpUser> findUserListByRoleCodes(EmpUser empUser);
/**
* 根据岗位编码查询用户,仅返回基本信息
*/
public List<EmpUser> findUserListByPostCodes(EmpUser empUser);
}

View File

@@ -4,7 +4,6 @@
package com.jeesite.modules.sys.dao;
import com.jeesite.common.dao.CrudDao;
import com.jeesite.common.datasource.DataSourceHolder;
import com.jeesite.common.mybatis.annotation.MyBatisDao;
import com.jeesite.modules.sys.entity.Employee;
@@ -14,7 +13,7 @@ import com.jeesite.modules.sys.entity.Employee;
* @version 2017-03-25
* 通过 UserUtils.loadRefObj() 加载引用类型对象时需要给MyBatisDao指定引用entity类型。
*/
@MyBatisDao(entity=Employee.class, dataSourceName=DataSourceHolder.DEFAULT)
@MyBatisDao(entity=Employee.class)
public interface EmployeeDao extends CrudDao<Employee> {
}

View File

@@ -0,0 +1,18 @@
/**
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
*/
package com.jeesite.modules.sys.dao;
import com.jeesite.common.dao.CrudDao;
import com.jeesite.common.mybatis.annotation.MyBatisDao;
import com.jeesite.modules.sys.entity.EmployeeOffice;
/**
* 员工附属机构关系表DAO接口
* @author ThinkGem
* @version 2019-04-29
*/
@MyBatisDao
public interface EmployeeOfficeDao extends CrudDao<EmployeeOffice> {
}

View File

@@ -4,7 +4,6 @@
package com.jeesite.modules.sys.dao;
import com.jeesite.common.dao.CrudDao;
import com.jeesite.common.datasource.DataSourceHolder;
import com.jeesite.common.mybatis.annotation.MyBatisDao;
import com.jeesite.modules.sys.entity.EmployeePost;
@@ -13,7 +12,7 @@ import com.jeesite.modules.sys.entity.EmployeePost;
* @author ThinkGem
* @version 2017-03-25
*/
@MyBatisDao(dataSourceName=DataSourceHolder.DEFAULT)
@MyBatisDao
public interface EmployeePostDao extends CrudDao<EmployeePost> {
}

View File

@@ -4,7 +4,6 @@
package com.jeesite.modules.sys.dao;
import com.jeesite.common.dao.CrudDao;
import com.jeesite.common.datasource.DataSourceHolder;
import com.jeesite.common.mybatis.annotation.MyBatisDao;
import com.jeesite.modules.sys.entity.Log;
@@ -13,7 +12,7 @@ import com.jeesite.modules.sys.entity.Log;
* @author ThinkGem
* @version 2017-03-19
*/
@MyBatisDao(dataSourceName=DataSourceHolder.DEFAULT)
@MyBatisDao
public interface LogDao extends CrudDao<Log> {
}

View File

@@ -4,7 +4,6 @@
package com.jeesite.modules.sys.dao;
import com.jeesite.common.dao.TreeDao;
import com.jeesite.common.datasource.DataSourceHolder;
import com.jeesite.common.mybatis.annotation.MyBatisDao;
import com.jeesite.modules.sys.entity.Office;
@@ -13,7 +12,7 @@ import com.jeesite.modules.sys.entity.Office;
* @author ThinkGem
* @version 2017-03-23
*/
@MyBatisDao(dataSourceName=DataSourceHolder.DEFAULT)
@MyBatisDao
public interface OfficeDao extends TreeDao<Office> {
}

View File

@@ -4,7 +4,6 @@
package com.jeesite.modules.sys.dao;
import com.jeesite.common.dao.CrudDao;
import com.jeesite.common.datasource.DataSourceHolder;
import com.jeesite.common.mybatis.annotation.MyBatisDao;
import com.jeesite.modules.sys.entity.Post;
@@ -13,7 +12,7 @@ import com.jeesite.modules.sys.entity.Post;
* @author ThinkGem
* @version 2017-03-25
*/
@MyBatisDao(dataSourceName=DataSourceHolder.DEFAULT)
@MyBatisDao
public interface PostDao extends CrudDao<Post> {
}

View File

@@ -14,8 +14,8 @@ import com.jeesite.common.tests.BaseInitDataTests;
import com.jeesite.modules.gen.entity.GenTable;
import com.jeesite.modules.gen.entity.GenTableColumn;
import com.jeesite.modules.gen.service.GenTableService;
import com.jeesite.modules.job.dao.JobDao;
import com.jeesite.modules.job.entity.JobEntity;
import com.jeesite.modules.job.service.JobService;
import com.jeesite.modules.msg.task.impl.MsgLocalMergePushTask;
import com.jeesite.modules.msg.task.impl.MsgLocalPushTask;
import com.jeesite.modules.sys.dao.RoleMenuDao;
@@ -61,8 +61,7 @@ public class InitCoreData extends BaseInitDataTests {
@Override
public void begin() {
super.begin();
excelFile = InitCoreData.class.getName().replaceAll("\\.", "/")+".xlsx";
super.begin(InitCoreData.class);
}
/**
@@ -374,7 +373,7 @@ public class InitCoreData extends BaseInitDataTests {
}
@Autowired
private JobService jobService;
private JobDao jobDao; // 默认情况下job是关闭状态需要注入jobDao
/**
* 初始化消息推送服务
*/
@@ -386,7 +385,7 @@ public class InitCoreData extends BaseInitDataTests {
job.setConcurrent(Global.NO);
job.setMisfireInstruction(CronTrigger.MISFIRE_INSTRUCTION_DO_NOTHING);
job.setStatus(JobEntity.STATUS_PAUSED);
jobService.insert(job);
jobDao.insert(job);
job = new JobEntity(MsgLocalMergePushTask.class.getSimpleName(), "SYSTEM");
job.setDescription("消息推送服务 (延迟推送)");
job.setInvokeTarget("msgLocalMergePushTask.execute()");
@@ -394,7 +393,7 @@ public class InitCoreData extends BaseInitDataTests {
job.setConcurrent(Global.NO);
job.setMisfireInstruction(CronTrigger.MISFIRE_INSTRUCTION_DO_NOTHING);
job.setStatus(JobEntity.STATUS_PAUSED);
jobService.insert(job);
jobDao.insert(job);
}
@Autowired

View File

@@ -68,7 +68,9 @@ import com.jeesite.common.utils.excel.fieldtype.OfficeType;
public class EmpUser extends User {
private static final long serialVersionUID = 1L;
private String[] codes; // 查询用
public EmpUser() {
this(null);
}
@@ -94,7 +96,7 @@ public class EmpUser extends User {
public Employee getEmployee(){
Employee employee = (Employee)super.getRefObj();
if (employee == null){
employee = new Employee();
employee = new Employee(getRefCode());
super.setRefObj(employee);
}
return employee;
@@ -103,5 +105,13 @@ public class EmpUser extends User {
public void setEmployee(Employee employee){
super.setRefObj(employee);
}
public String[] getCodes() {
return codes;
}
public void setCodes(String[] codes) {
this.codes = codes;
}
}

View File

@@ -61,6 +61,7 @@ public class Employee extends DataEntity<Employee> {
private String postCode; // 根据职位查询
private List<EmployeePost> employeePostList = ListUtils.newArrayList(); // 关联岗位信息
private List<EmployeeOffice> employeeOfficeList = ListUtils.newArrayList(); // 关联附属机构信息
public Employee() {
this(null);
@@ -150,5 +151,13 @@ public class Employee extends DataEntity<Employee> {
}
}
}
public List<EmployeeOffice> getEmployeeOfficeList() {
return employeeOfficeList;
}
public void setEmployeeOfficeList(List<EmployeeOffice> employeeOfficeList) {
this.employeeOfficeList = employeeOfficeList;
}
}

View File

@@ -0,0 +1,111 @@
/**
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
*/
package com.jeesite.modules.sys.entity;
import org.hibernate.validator.constraints.Length;
import com.jeesite.common.entity.DataEntity;
import com.jeesite.common.mybatis.annotation.Column;
import com.jeesite.common.mybatis.annotation.JoinTable;
import com.jeesite.common.mybatis.annotation.Table;
import com.jeesite.common.mybatis.annotation.JoinTable.Type;
import com.jeesite.common.mybatis.mapper.query.QueryType;
/**
* 附属机构Entity
* @author ThinkGem
* @version 2019-04-29
*/
@Table(name="${_prefix}sys_employee_office", alias="a", columns={
@Column(name="id", attrName="id", label="编码", isPK=true),
@Column(name="emp_code", attrName="empCode", label="员工编码"),
@Column(name="office_code", attrName="officeCode", label="机构编码"),
@Column(name="post_code", attrName="postCode", label="岗位编码"),
}, joinTable={
@JoinTable(type=Type.LEFT_JOIN, entity=Office.class, alias="o",
on="o.office_code=a.office_code", attrName="this",
columns={
@Column(name="office_code", label="机构编码", isPK=true),
@Column(name="parent_codes",label="所有父级编码", queryType=QueryType.LIKE),
@Column(name="office_name", label="机构名称", isQuery=false),
}),
@JoinTable(type=Type.LEFT_JOIN, entity=Post.class, alias="p",
on="p.post_code=a.post_code", attrName="this",
columns={
@Column(name="post_code", label="岗位编码", isPK=true),
@Column(name="post_name", label="岗位名称", isQuery=false),
}),
}, orderBy="a.id ASC"
)
public class EmployeeOffice extends DataEntity<EmployeeOffice> {
private static final long serialVersionUID = 1L;
private String empCode; // 员工编码
private String officeCode; // 机构编码
private String postCode; // 岗位编码
private String parentCodes; // 机构所有上级编码(数据权限用)
private String officeName; // 机构名称(联合查询项)
private String postName; // 岗位名称(联合查询项)
public EmployeeOffice() {
this(null, null);
}
public EmployeeOffice(String empCode, String officeCode){
super(null);
this.empCode = empCode;
this.officeCode = officeCode;
}
public String getEmpCode() {
return empCode;
}
public void setEmpCode(String empCode) {
this.empCode = empCode;
}
public String getOfficeCode() {
return officeCode;
}
public void setOfficeCode(String officeCode) {
this.officeCode = officeCode;
}
@Length(min=0, max=64, message="岗位编码长度不能超过 64 个字符")
public String getPostCode() {
return postCode;
}
public void setPostCode(String postCode) {
this.postCode = postCode;
}
public String getParentCodes() {
return parentCodes;
}
public void setParentCodes(String parentCodes) {
this.parentCodes = parentCodes;
}
public String getOfficeName() {
return officeName;
}
public void setOfficeName(String officeName) {
this.officeName = officeName;
}
public String getPostName() {
return postName;
}
public void setPostName(String postName) {
this.postName = postName;
}
}

View File

@@ -19,7 +19,7 @@ import com.jeesite.common.mybatis.mapper.query.QueryType;
@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"
}, orderBy="a.post_sort ASC"
)
public class Post extends DataEntity<Post> {

View File

@@ -3,6 +3,8 @@
*/
package com.jeesite.modules.sys.service;
import java.util.List;
import org.springframework.web.multipart.MultipartFile;
import com.jeesite.common.entity.Page;
@@ -35,6 +37,26 @@ public interface EmpUserService extends CrudServiceApi<EmpUser> {
*/
@Override
public Page<EmpUser> findPage(EmpUser empUser);
/**
* 查询全部用户,仅返回基本信息
*/
public List<EmpUser> findUserList(EmpUser empUser);
/**
* 根据部门编码查询用户,仅返回基本信息
*/
public List<EmpUser> findUserListByOfficeCodes(EmpUser empUser);
/**
* 根据角色编码查询用户,仅返回基本信息
*/
public List<EmpUser> findUserListByRoleCodes(EmpUser empUser);
/**
* 根据岗位编码查询用户,仅返回基本信息
*/
public List<EmpUser> findUserListByPostCodes(EmpUser empUser);
/**
* 保存用户员工

View File

@@ -8,6 +8,7 @@ import java.util.List;
import com.jeesite.common.entity.Page;
import com.jeesite.common.service.api.CrudServiceApi;
import com.jeesite.modules.sys.entity.Employee;
import com.jeesite.modules.sys.entity.EmployeeOffice;
import com.jeesite.modules.sys.entity.EmployeePost;
/**
@@ -45,5 +46,10 @@ public interface EmployeeService extends CrudServiceApi<Employee> {
* 查询当前员工关联的岗位信息
*/
public List<EmployeePost> findEmployeePostList(Employee employee);
/**
* 查询当前员工关联的附属机构信息
*/
public List<EmployeeOffice> findEmployeeOfficeList(Employee employee);
}

View File

@@ -1,61 +0,0 @@
///**
// * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
// */
//package com.jeesite.modules.sys.service.impl;
//
//import java.util.List;
//
//import org.springframework.stereotype.Service;
//
//import com.jeesite.modules.file.entity.FileEntity;
//import com.jeesite.modules.file.service.FileEntityServiceSupport;
//
///**
// * 文件实体实现类
// * @author ThinkGem
// * @version 2018年10月13日
// */
//@Service
//public class FileEntityServiceImpl extends FileEntityServiceSupport {
//
// public FileEntityServiceImpl() {
// this.entityClass = FileEntity.class;
// }
//
// @Override
// public FileEntity get(FileEntity fileEntity) {
// System.out.println("============= fileEntity get ");
// return super.get(fileEntity);
// }
//
// @Override
// public FileEntity getByMd5(FileEntity fileEntity) {
// System.out.println("============= fileEntity getByMd5 ");
// return super.get(fileEntity);
// }
//
// @Override
// public List<FileEntity> findList(FileEntity fileEntity) {
// System.out.println("============= fileEntity findList ");
// return super.findList(fileEntity);
// }
//
// @Override
// public void save(FileEntity fileEntity) {
// System.out.println("============= fileEntity save ");
// super.save(fileEntity);
// }
//
// @Override
// public void updateStatus(FileEntity fileEntity) {
// System.out.println("============= fileEntity updateStatus ");
// super.updateStatus(fileEntity);
// }
//
// @Override
// public void delete(FileEntity fileEntity) {
// System.out.println("============= fileEntity delete ");
// super.delete(fileEntity);
// }
//
//}

View File

@@ -1,53 +0,0 @@
///**
// * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
// */
//package com.jeesite.modules.sys.service.impl;
//
//import javax.servlet.http.HttpServletRequest;
//import javax.servlet.http.HttpServletResponse;
//
//import org.springframework.stereotype.Service;
//
//import com.jeesite.modules.file.entity.FileEntity;
//import com.jeesite.modules.file.entity.FileUpload;
//import com.jeesite.modules.file.service.FileUploadServiceExtendSupport;
//
///**
// * 文件上传扩展实现类
// * @author ThinkGem
// * @version 2018年10月13日
// */
//@Service
//public class FileUploadServiceExtendImpl extends FileUploadServiceExtendSupport {
//
// @Override
// public boolean fileExists(FileEntity fileEntity) {
// System.out.println("============= fileupload fileExists ");
// return super.fileExists(fileEntity);
// }
//
// @Override
// public void uploadFile(FileEntity fileEntity) {
// System.out.println("============= fileupload uploadFile ");
// super.uploadFile(fileEntity);
// }
//
// @Override
// public void saveUploadFile(FileUpload fileUpload) {
// System.out.println("============= fileupload saveUploadFile ");
// super.saveUploadFile(fileUpload);
// }
//
// @Override
// public String getFileUrl(FileUpload fileUpload) {
// System.out.println("============= fileupload getFileUrl ");
// return super.getFileUrl(fileUpload);
// }
//
// @Override
// public String downFile(FileUpload fileUpload, HttpServletRequest request, HttpServletResponse response) {
// System.out.println("============= fileupload downFile ");
// return super.downFile(fileUpload, request, response);
// }
//
//}

View File

@@ -1,55 +0,0 @@
///**
// * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
// */
//package com.jeesite.modules.sys.service.impl;
//
//import java.util.List;
//
//import org.springframework.stereotype.Service;
//
//import com.jeesite.modules.file.entity.FileUpload;
//import com.jeesite.modules.file.service.FileUploadServiceSupport;
//
///**
// * 文件上传实现类
// * @author ThinkGem
// * @version 2018年10月13日
// */
//@Service
//public class FileUploadServiceImpl extends FileUploadServiceSupport {
//
// public FileUploadServiceImpl() {
// this.entityClass = FileUpload.class;
// }
//
// @Override
// public FileUpload get(FileUpload fileUpload) {
// System.out.println("============= fileUpload get ");
// return super.get(fileUpload);
// }
//
// @Override
// public List<FileUpload> findList(FileUpload fileUpload) {
// System.out.println("============= fileUpload findList ");
// return super.findList(fileUpload);
// }
//
// @Override
// public void save(FileUpload fileUpload) {
// System.out.println("============= fileUpload save ");
// super.save(fileUpload);
// }
//
// @Override
// public void updateStatus(FileUpload fileUpload) {
// System.out.println("============= fileUpload updateStatus ");
// super.updateStatus(fileUpload);
// }
//
// @Override
// public void delete(FileUpload fileUpload) {
// System.out.println("============= fileUpload delete ");
// super.delete(fileUpload);
// }
//
//}

View File

@@ -1,49 +0,0 @@
///**
// * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
// */
//package com.jeesite.modules.sys.service.impl;
//
//import java.util.List;
//
//import org.springframework.stereotype.Service;
//
//import com.jeesite.modules.sys.entity.Menu;
//import com.jeesite.modules.sys.service.MenuServiceSupport;
//
///**
// * 菜单服务扩展实现类
// * @author ThinkGem
// * @version 2018年10月13日
// */
//@Service
//public class MenuServiceImpl extends MenuServiceSupport {
//
// public MenuServiceImpl() {
// this.entityClass = Menu.class;
// }
//
// @Override
// public Menu get(Menu menu) {
// System.out.println("============= menu get ");
// return super.get(menu);
// }
//
// @Override
// public List<Menu> findList(Menu menu) {
// System.out.println("============= menu findList ");
// return super.findList(menu);
// }
//
// @Override
// public List<Menu> findByRoleCode(Menu menu) {
// System.out.println("============= menu findByRoleCode ");
// return super.findByRoleCode(menu);
// }
//
// @Override
// public List<Menu> findByUserCode(Menu menu) {
// System.out.println("============= menu findByUserCode ");
// return super.findByUserCode(menu);
// }
//
//}

View File

@@ -1,43 +0,0 @@
///**
// * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
// */
//package com.jeesite.modules.sys.service.impl;
//
//import java.util.List;
//
//import org.springframework.stereotype.Service;
//
//import com.jeesite.modules.sys.entity.Role;
//import com.jeesite.modules.sys.service.RoleServiceSupport;
//
///**
// * 角色服务扩展实现类
// * @author ThinkGem
// * @version 2018年10月13日
// */
//@Service
//public class RoleServiceImpl extends RoleServiceSupport {
//
// public RoleServiceImpl() {
// this.entityClass = Role.class;
// }
//
// @Override
// public Role get(Role role) {
// System.out.println("============= role get ");
// return super.get(role);
// }
//
// @Override
// public List<Role> findList(Role role) {
// System.out.println("============= role findList ");
// return super.findList(role);
// }
//
// @Override
// public List<Role> findListByUserCode(Role role) {
// System.out.println("============= role findListByUserCode ");
// return super.findListByUserCode(role);
// }
//
//}

View File

@@ -1,49 +0,0 @@
///**
// * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
// */
//package com.jeesite.modules.sys.service.impl;
//
//import java.util.List;
//
//import org.springframework.stereotype.Service;
//
//import com.jeesite.modules.sys.entity.User;
//import com.jeesite.modules.sys.service.UserServiceSupport;
//
///**
// * 用户服务扩展实现类
// * @author ThinkGem
// * @version 2018年10月13日
// */
//@Service
//public class UserServiceImpl extends UserServiceSupport {
//
// public UserServiceImpl() {
// this.entityClass = User.class;
// }
//
// @Override
// public User get(User user) {
// System.out.println("============= user get ");
// return super.get(user);
// }
//
// @Override
// public User getByLoginCode(User user) {
// System.out.println("============= user getByLoginCode ");
// return super.getByLoginCode(user);
// }
//
// @Override
// public User getByUserTypeAndRefCode(User user) {
// System.out.println("============= user getByUserTypeAndRefCode ");
// return super.getByUserTypeAndRefCode(user);
// }
//
// @Override
// public List<User> findList(User user) {
// System.out.println("============= user findList ");
// return super.findList(user);
// }
//
//}

View File

@@ -7,7 +7,6 @@ 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;
@@ -25,7 +24,6 @@ import com.jeesite.modules.sys.utils.EmpUtils;
* @author ThinkGem
* @version 2016-4-23
*/
@Service
@Transactional(readOnly=true)
public class CompanyServiceSupport extends TreeService<CompanyDao, Company>
implements CompanyService{
@@ -79,8 +77,12 @@ public class CompanyServiceSupport extends TreeService<CompanyDao, Company>
CompanyOffice where = new CompanyOffice();
where.setCompanyCode(company.getCompanyCode());
companyOfficeDao.deleteByEntity(where);
if (ListUtils.isNotEmpty(company.getCompanyOfficeList())){
companyOfficeDao.insertBatch(company.getCompanyOfficeList());
List<CompanyOffice> list = company.getCompanyOfficeList();
if (ListUtils.isNotEmpty(list)){
list.forEach(e -> {
e.setCompanyCode(company.getCompanyCode());
});
companyOfficeDao.insertBatch(list);
}
// 清理公司相关缓存
clearCompanyCache();

View File

@@ -8,7 +8,6 @@ import java.util.List;
import javax.validation.ConstraintViolationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
@@ -20,8 +19,10 @@ import com.jeesite.common.service.ServiceException;
import com.jeesite.common.utils.excel.ExcelImport;
import com.jeesite.common.validator.ValidatorUtils;
import com.jeesite.modules.sys.dao.EmpUserDao;
import com.jeesite.modules.sys.dao.EmployeeOfficeDao;
import com.jeesite.modules.sys.entity.EmpUser;
import com.jeesite.modules.sys.entity.Employee;
import com.jeesite.modules.sys.entity.EmployeeOffice;
import com.jeesite.modules.sys.entity.User;
import com.jeesite.modules.sys.service.EmpUserService;
import com.jeesite.modules.sys.service.EmployeeService;
@@ -34,16 +35,16 @@ import com.jeesite.modules.sys.utils.UserUtils;
* @author ThinkGem
* @version 2017-03-25
*/
@Service
@Transactional(readOnly=true)
public class EmpUserServiceSupport extends CrudService<EmpUserDao, EmpUser>
implements EmpUserService{
@Autowired
private UserService userService;
@Autowired
private EmployeeService employeeService;
@Autowired
private EmployeeOfficeDao employeeOfficeDao;
/**
* 获取单条数据
@@ -76,6 +77,34 @@ public class EmpUserServiceSupport extends CrudService<EmpUserDao, EmpUser>
return super.findPage(empUser);
}
/**
* 查询全部用户,仅返回基本信息
*/
public List<EmpUser> findUserList(EmpUser empUser){
return dao.findUserList(empUser);
}
/**
* 根据部门编码查询用户,仅返回基本信息
*/
public List<EmpUser> findUserListByOfficeCodes(EmpUser empUser){
return dao.findUserListByOfficeCodes(empUser);
}
/**
* 根据角色编码查询用户,仅返回基本信息
*/
public List<EmpUser> findUserListByRoleCodes(EmpUser empUser){
return dao.findUserListByRoleCodes(empUser);
}
/**
* 根据岗位编码查询用户,仅返回基本信息
*/
public List<EmpUser> findUserListByPostCodes(EmpUser empUser){
return dao.findUserListByPostCodes(empUser);
}
/**
* 保存用户员工
*/
@@ -105,6 +134,17 @@ public class EmpUserServiceSupport extends CrudService<EmpUserDao, EmpUser>
// 3、保存员工
employee.setIsNewRecord(user.getIsNewRecord());
employeeService.save(employee);
// 4、保存附属机构
EmployeeOffice employeeOfficeWhere = new EmployeeOffice();
employeeOfficeWhere.setEmpCode(employee.getEmpCode());
employeeOfficeDao.deleteByEntity(employeeOfficeWhere);
if (employee.getEmployeeOfficeList().size() > 0){
employee.getEmployeeOfficeList().forEach(employeeOffice -> {
employeeOffice.setId(IdGen.nextId());
employeeOffice.setEmpCode(employee.getEmpCode());
});
employeeOfficeDao.insertBatch(employee.getEmployeeOfficeList());
}
}
/**

View File

@@ -6,15 +6,16 @@ package com.jeesite.modules.sys.service.support;
import java.util.List;
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.entity.Page;
import com.jeesite.common.service.CrudService;
import com.jeesite.modules.sys.dao.EmployeeDao;
import com.jeesite.modules.sys.dao.EmployeeOfficeDao;
import com.jeesite.modules.sys.dao.EmployeePostDao;
import com.jeesite.modules.sys.entity.Employee;
import com.jeesite.modules.sys.entity.EmployeeOffice;
import com.jeesite.modules.sys.entity.EmployeePost;
import com.jeesite.modules.sys.service.EmployeeService;
@@ -23,13 +24,14 @@ import com.jeesite.modules.sys.service.EmployeeService;
* @author ThinkGem
* @version 2017-03-25
*/
@Service
@Transactional(readOnly=true)
public class EmployeeServiceSupport extends CrudService<EmployeeDao, Employee>
implements EmployeeService{
@Autowired
private EmployeePostDao employeePostDao;
@Autowired
private EmployeeOfficeDao employeeOfficeDao;
/**
* 获取单条数据
@@ -88,4 +90,13 @@ public class EmployeeServiceSupport extends CrudService<EmployeeDao, Employee>
employeePost.setEmpCode(employee.getEmpCode());
return employeePostDao.findList(employeePost);
}
/**
* 查询当前员工关联的附属机构信息
*/
public List<EmployeeOffice> findEmployeeOfficeList(Employee employee){
EmployeeOffice employeeOffice = new EmployeeOffice();
employeeOffice.setEmpCode(employee.getEmpCode());
return employeeOfficeDao.findList(employeeOffice);
}
}

View File

@@ -3,7 +3,6 @@
*/
package com.jeesite.modules.sys.service.support;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@@ -18,7 +17,6 @@ import com.jeesite.modules.sys.service.LogService;
* @author ThinkGem
* @version 2014-05-16
*/
@Service
@Transactional(readOnly=true)
public class LogServiceSupport extends CrudService<LogDao, Log>
implements LogService{

View File

@@ -6,7 +6,6 @@ package com.jeesite.modules.sys.service.support;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.jeesite.common.service.TreeService;
@@ -21,7 +20,6 @@ import com.jeesite.modules.sys.utils.EmpUtils;
* @author ThinkGem
* @version 2016-4-23
*/
@Service
@Transactional(readOnly=true)
public class OfficeServiceSupport extends TreeService<OfficeDao, Office>
implements OfficeService{

View File

@@ -3,7 +3,6 @@
*/
package com.jeesite.modules.sys.service.support;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.jeesite.common.entity.Page;
@@ -17,7 +16,6 @@ import com.jeesite.modules.sys.service.PostService;
* @author ThinkGem
* @version 2017-03-25
*/
@Service
@Transactional(readOnly=true)
public class PostServiceSupport extends CrudService<PostDao, Post>
implements PostService{

View File

@@ -5,13 +5,16 @@ package com.jeesite.modules.sys.utils;
import java.util.List;
import com.jeesite.common.collect.ListUtils;
import com.jeesite.common.lang.StringUtils;
import com.jeesite.common.utils.SpringUtils;
import com.jeesite.modules.sys.entity.Company;
import com.jeesite.modules.sys.entity.Employee;
import com.jeesite.modules.sys.entity.EmployeeOffice;
import com.jeesite.modules.sys.entity.Office;
import com.jeesite.modules.sys.entity.User;
import com.jeesite.modules.sys.service.CompanyService;
import com.jeesite.modules.sys.service.EmployeeService;
import com.jeesite.modules.sys.service.OfficeService;
/**
@@ -28,6 +31,7 @@ public class EmpUtils {
// 部门和公司缓存常量
public static final String CACHE_OFFICE_ALL_LIST = "officeAllList";
public static final String CACHE_COMPANY_ALL_LIST = "companyAllList";
public static final String CACHE_COMPANY_OFFICE_LIST = "employeeOfficeList";
/**
* 静态内部类,延迟加载,懒汉式,线程安全的单例模式
@@ -35,6 +39,7 @@ public class EmpUtils {
private static final class Static {
private static OfficeService officeService = SpringUtils.getBean(OfficeService.class);
private static CompanyService companyService = SpringUtils.getBean(CompanyService.class);
private static EmployeeService employeeService = SpringUtils.getBean(EmployeeService.class);
}
/**
@@ -45,7 +50,7 @@ public class EmpUtils {
User user = UserUtils.getUser();
Employee employee = null;
if (User.USER_TYPE_EMPLOYEE.equals(user.getUserType())){
employee = (Employee)UserUtils.getUser().getRefObj();
employee = (Employee)user.getRefObj();
}
if (employee == null){
employee = new Employee();
@@ -54,10 +59,43 @@ public class EmpUtils {
}
/**
* 获取当前部门对象
* 获取当前附属部门对象列表
*/
public static Office getOffice(){
return getEmployee().getOffice();
public static List<EmployeeOffice> getEmployeeOfficeList(){
List<EmployeeOffice> list = UserUtils.getCache(CACHE_COMPANY_OFFICE_LIST);
if (list == null){
list = Static.employeeService.findEmployeeOfficeList(getEmployee());
UserUtils.putCache(CACHE_COMPANY_OFFICE_LIST, list);
}
return list;
}
/**
* 获取所有部门编码,包括附属部门(数据权限用)
* @return
* @author ThinkGem
*/
public static String[] getOfficeCodes(){
List<String> list = ListUtils.newArrayList();
list.add(getOffice().getOfficeCode());
getEmployeeOfficeList().forEach(e -> {
list.add(e.getOfficeCode());
});
return list.toArray(new String[list.size()]);
}
/**
* 获取所有部门编码,包括附属部门(数据权限用)
* @return
* @author ThinkGem
*/
public static String[] getOfficeParentCodess(){
List<String> list = ListUtils.newArrayList();
list.add(getOffice().getParentCodes());
getEmployeeOfficeList().forEach(e -> {
list.add(e.getParentCodes());
});
return list.toArray(new String[list.size()]);
}
/**
@@ -74,6 +112,13 @@ public class EmpUtils {
}
return null;
}
/**
* 获取当前员工附属部门
*/
public static Office getOffice(){
return getEmployee().getOffice();
}
//
// /**
// * 获取当前用户有权限访问的机构

View File

@@ -63,7 +63,7 @@ public class AreaController extends BaseController {
* 查询区域数据
* @param area
*/
@RequiresPermissions("user")
@RequiresPermissions("sys:area:view")
@RequestMapping(value = "listData")
@ResponseBody
public List<Area> listData(Area area) {

View File

@@ -70,7 +70,7 @@ public class CompanyController extends BaseController {
* 查询公司数据
* @param company
*/
@RequiresPermissions("user")
@RequiresPermissions("sys:company:view")
@RequestMapping(value = "listData")
@ResponseBody
public List<Company> listData(Company company, String ctrlPermi) {
@@ -209,7 +209,7 @@ public class CompanyController extends BaseController {
List<Map<String, Object>> mapList = ListUtils.newArrayList();
Company where = new Company();
where.setStatus(Company.STATUS_NORMAL);
if (!(isAll != null && isAll)){
if (!(isAll != null && isAll) || Global.isStrictMode()){
companyService.addDataScopeFilter(where, ctrlPermi);
}
List<Company> list = companyService.findList(where);

View File

@@ -24,6 +24,8 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.fasterxml.jackson.annotation.JsonView;
import com.jeesite.common.codec.DesUtils;
import com.jeesite.common.config.Global;
import com.jeesite.common.lang.StringUtils;
import com.jeesite.common.shiro.filter.FormAuthenticationFilter;
@@ -135,6 +137,11 @@ public class LoginController extends BaseController{
String exception = (String)request.getAttribute(FormAuthenticationFilter.DEFAULT_ERROR_KEY_ATTRIBUTE_NAME);
String message = (String)request.getAttribute(FormAuthenticationFilter.DEFAULT_MESSAGE_PARAM);
String secretKey = Global.getProperty("shiro.loginSubmit.secretKey");
if (StringUtils.isNotBlank(secretKey)){
username = DesUtils.decode(username, secretKey);
}
model.addAttribute(FormAuthenticationFilter.DEFAULT_USERNAME_PARAM, username);
model.addAttribute(FormAuthenticationFilter.DEFAULT_REMEMBER_ME_PARAM, rememberMe);
model.addAttribute(FormAuthenticationFilter.DEFAULT_REMEMBER_USERCODE_PARAM, rememberUserCode);
@@ -246,10 +253,10 @@ public class LoginController extends BaseController{
}
}
// 获取登录成功页面
String successUrl = Global.getProperty("shiro.successUrl");
if (!StringUtils.contains(successUrl, "://")){
successUrl = request.getContextPath() + successUrl;
// 获取登录成功后跳转的页面
String successUrl = request.getParameter("__url");
if (StringUtils.isBlank(successUrl)){
successUrl = Global.getProperty("shiro.successUrl");
}
// 登录操作如果是Ajax操作直接返回登录信息字符串。
@@ -262,6 +269,9 @@ public class LoginController extends BaseController{
model.addAttribute("message", text("sys.login.getInfo"));
}
model.addAttribute("sessionid", (String)session.getId());
if (!StringUtils.contains(successUrl, "://")){
successUrl = request.getContextPath() + successUrl;
}
model.addAttribute("__url", successUrl); // 告诉浏览器登录后跳转的页面
return ServletUtils.renderObject(response, model);
}
@@ -295,6 +305,11 @@ public class LoginController extends BaseController{
return null;
}
// 非无类型用户,自动根据用户类型设置默认菜单的归属系统(个性化示例)
//if (!User.USER_TYPE_NONE.equals(user.getUserType())){
// session.setAttribute("sysCode", user.getUserType());
//}
// 返回指定用户类型的首页视图
String view = UserUtils.getUserTypeValue(user.getUserType(), "indexView");
if(StringUtils.isNotBlank(view)){
@@ -305,6 +320,15 @@ public class LoginController extends BaseController{
return "modules/sys/sysIndex";
}
/**
* 获取侧边栏菜单数据
*/
@RequiresPermissions("user")
@RequestMapping(value = "index/menuTree")
public String indexMenuTree(String parentCode) {
return "modules/sys/sysIndex/menuTree";
}
/**
* 获取当前用户权限字符串数据(移动端用)
*/
@@ -321,6 +345,7 @@ public class LoginController extends BaseController{
@RequiresPermissions("user")
@RequestMapping(value = "menuTree")
@ResponseBody
@JsonView(Menu.SimpleView.class)
public List<Menu> menuTree(String parentCode) {
if (StringUtils.isNotBlank(parentCode)){
return UserUtils.getMenuListByParentCode(parentCode);
@@ -334,14 +359,11 @@ public class LoginController extends BaseController{
@RequiresPermissions("user")
@RequestMapping(value = "switch/{sysCode}")
public String switchSys(@PathVariable String sysCode) {
LoginInfo principal = UserUtils.getLoginInfo();
User user = UserUtils.get(principal.getId());
User user = UserUtils.getUser();
if (user.isSuperAdmin() && StringUtils.isNotBlank(sysCode)){
if (!StringUtils.equals(principal.getParam("sysCode"), sysCode)){
principal.setParam("sysCode", sysCode);
UserUtils.removeCacheByKeyPrefix(UserUtils.CACHE_MENU_LIST);
UserUtils.removeCache(UserUtils.CACHE_AUTH_INFO);
}
Session session = UserUtils.getSession();
session.setAttribute("sysCode", sysCode);
UserUtils.removeCache(UserUtils.CACHE_AUTH_INFO+"_"+session.getId());
}
return REDIRECT + adminPath + "/index";
}

View File

@@ -67,7 +67,7 @@ public class OfficeController extends BaseController {
* 查询机构数据
* @param office
*/
@RequiresPermissions("user")
@RequiresPermissions("sys:company:view")
@RequestMapping(value = "listData")
@ResponseBody
public List<Office> listData(Office office, String ctrlPermi) {
@@ -222,7 +222,7 @@ public class OfficeController extends BaseController {
Office where = new Office();
where.setStatus(Office.STATUS_NORMAL);
where.setCompanyCode(companyCode);
if (!(isAll != null && isAll)){
if (!(isAll != null && isAll) || Global.isStrictMode()){
officeService.addDataScopeFilter(where, ctrlPermi);
}
List<Office> list = officeService.findList(where);

View File

@@ -148,15 +148,17 @@ public class OnlineController extends BaseController{
public String tickOut(String sessionId) {
Session session = sessionDAO.readSession(sessionId);
if (session != null){
@SuppressWarnings("unchecked")
Map<String, String> onlineTickOutMap = (Map<String, String>)CacheUtils.get("onlineTickOutMap");
Map<String, String> onlineTickOutMap = CacheUtils.get("onlineTickOutMap");
if (onlineTickOutMap == null){
onlineTickOutMap = MapUtils.newConcurrentMap();
}
PrincipalCollection pc = (PrincipalCollection)session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
LoginInfo principal = (pc != null ? (LoginInfo)pc.getPrimaryPrincipal() : null);
if (principal != null){
onlineTickOutMap.put(principal.getId()+"_"+principal.getParam("deviceType", "PC"), StringUtils.EMPTY);
Object pc = session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
if (pc != null && pc instanceof PrincipalCollection){
LoginInfo loginInfo = (LoginInfo)((PrincipalCollection)pc).getPrimaryPrincipal();
if (loginInfo != null){
String key = loginInfo.getId()+"_"+loginInfo.getParam("deviceType", "PC");
onlineTickOutMap.put(key, StringUtils.EMPTY);
}
}
CacheUtils.put("onlineTickOutMap", onlineTickOutMap);
sessionDAO.delete(session);

View File

@@ -3,6 +3,9 @@
*/
package com.jeesite.modules.sys.web;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -17,8 +20,11 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.jeesite.common.collect.ListUtils;
import com.jeesite.common.collect.MapUtils;
import com.jeesite.common.config.Global;
import com.jeesite.common.entity.Page;
import com.jeesite.common.lang.StringUtils;
import com.jeesite.common.web.BaseController;
import com.jeesite.modules.sys.entity.Post;
import com.jeesite.modules.sys.service.PostService;
@@ -122,5 +128,28 @@ public class PostController extends BaseController {
}
return Global.FALSE;
}
/**
* 获取岗位树结构数据
* @param isShowCode 是否显示编码true or 1显示在左侧2显示在右侧false or null不显示
* @return
*/
@RequiresPermissions("user")
@RequestMapping(value = "treeData")
@ResponseBody
public List<Map<String, Object>> treeData(String userType, String isShowCode, String ctrlPermi) {
List<Map<String, Object>> mapList = ListUtils.newArrayList();
Post where = new Post();
where.setStatus(Post.STATUS_NORMAL);
List<Post> list = postService.findList(where);
list.forEach(e -> {
Map<String, Object> map = MapUtils.newHashMap();
map.put("id", e.getId());
map.put("pId", "0");
map.put("name", StringUtils.getTreeNodeName(isShowCode, e.getPostCode(), e.getPostName()));
mapList.add(map);
});
return mapList;
}
}

View File

@@ -0,0 +1,76 @@
/**
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
*/
package com.jeesite.modules.sys.web;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.jeesite.common.codec.EncodeUtils;
import com.jeesite.common.lang.ObjectUtils;
import com.jeesite.common.shiro.authc.FormToken;
import com.jeesite.common.web.BaseController;
import com.jeesite.common.web.http.ServletUtils;
import com.jeesite.modules.sys.entity.User;
import com.jeesite.modules.sys.utils.UserUtils;
/**
* 单点登录Controller
* @author ThinkGem
* @version 2017-03-25
*/
@Controller
public class SsoController extends BaseController{
/**
* 单点登录(如已经登录,则直接跳转)
* @param username 登录用户名loginCode
* @param token 单点登录令牌令牌组成sso密钥+用户名+日期进行md5加密举例
* // 注意如果 shiro.sso.encryptKey 为 true则 secretKey 会自动加密。
* String secretKey = Global.getConfig("shiro.sso.secretKey");
* String token = Md5Utils.md5(secretKey + username + DateUtils.getDate("yyyyMMdd"));
* @param params 登录附加参数JSON格式或 param_ 前缀的请求参数。
* @param url 登录成功后跳转的url地址。
* @param relogin 是否强制重新登录需要强制重新登录传递true
* @see 调用示例:
* http://localhost/project/sso/{username}/{token}?url=/sys/user/list?p1=v1%26p2=v2&relogin=true
* 如果url中携带参数请使用转义字符如“&”号,使用“%26”转义。
*/
@RequestMapping(value = "sso/{username}/{token}")
public String sso(@PathVariable String username, @PathVariable String token,
@RequestParam(defaultValue="${adminPath}") String url, String relogin,
HttpServletRequest request, Model model){
User user = UserUtils.getUser();
// 如果已经登录,并且是同一个人,并且不强制重新登录,则直接跳转到目标页
if(StringUtils.isNotBlank(user.getUserCode())
&& StringUtils.equals(user.getLoginCode(), username)
&& !ObjectUtils.toBoolean(relogin)){
return REDIRECT + EncodeUtils.decodeUrl2(url);
}
// 通过令牌登录系统
if (token != null){
try {
FormToken upToken = new FormToken();
upToken.setUsername(username); // 登录用户名
upToken.setSsoToken(token); // 单点登录令牌
upToken.setParams(ServletUtils.getExtParams(request)); // 登录附加参数
UserUtils.getSubject().login(upToken);
return REDIRECT + EncodeUtils.decodeUrl2(url);
} catch (AuthenticationException e) {
if (!e.getMessage().startsWith("msg:")){
throw new AuthenticationException("msg:登录失败,请联系管理员。", e);
}
throw e;
}
}
return "error/403";
}
}

View File

@@ -30,7 +30,9 @@ import com.jeesite.common.lang.StringUtils;
import com.jeesite.common.mybatis.mapper.query.QueryType;
import com.jeesite.common.web.BaseController;
import com.jeesite.modules.sys.entity.EmpUser;
import com.jeesite.modules.sys.entity.Role;
import com.jeesite.modules.sys.entity.User;
import com.jeesite.modules.sys.service.RoleService;
import com.jeesite.modules.sys.service.UserService;
import com.jeesite.modules.sys.utils.UserUtils;
@@ -46,6 +48,8 @@ public class CorpAdminController extends BaseController {
@Autowired
private UserService userService;
@Autowired
private RoleService roleService;
@ModelAttribute
public User get(String userCode, boolean isNewRecord) {
@@ -84,6 +88,10 @@ public class CorpAdminController extends BaseController {
user.setCorpName_(StringUtils.EMPTY); // 租户名称
}
}
// 获取当前用户所拥有的角色
Role role = new Role();
role.setUserCode(user.getUserCode());
model.addAttribute("roleList", roleService.findListByUserCode(role));
// 操作类型addCorp: 添加租户; addAdmin: 添加管理员; edit: 编辑
model.addAttribute("op", op);
model.addAttribute("user", user);
@@ -135,6 +143,7 @@ public class CorpAdminController extends BaseController {
}
}
userService.save(user);
userService.saveAuth(user);
// 如果修改的是当前用户,则清除当前用户缓存
if (user.getUserCode().equals(UserUtils.getUser().getUserCode())) {
UserUtils.clearCache();
@@ -260,8 +269,8 @@ public class CorpAdminController extends BaseController {
where.setCorpCode_(corpCode);
List<User> list = userService.findCorpList(where);
if (list.size() > 0){
Session session = UserUtils.getSession();
User user = list.get(0);
Session session = UserUtils.getSession();
session.setAttribute("corpCode", user.getCorpCode_());
session.setAttribute("corpName", user.getCorpName_());
return renderResult(Global.TRUE, "租户切换成功!");

View File

@@ -95,7 +95,7 @@ public class EmpUserController extends BaseController {
public Page<EmpUser> listData(EmpUser empUser, Boolean isAll, String ctrlPermi, HttpServletRequest request, HttpServletResponse response) {
empUser.getEmployee().getOffice().setIsQueryChildren(true);
empUser.getEmployee().getCompany().setIsQueryChildren(true);
if (!(isAll != null && isAll)){
if (!(isAll != null && isAll) || Global.isStrictMode()){
empUserService.addDataScopeFilter(empUser, ctrlPermi);
}
empUser.setPage(new Page<>(request, response));
@@ -123,9 +123,11 @@ public class EmpUserController extends BaseController {
Post post = new Post();
model.addAttribute("postList", postService.findList(post));
// 获取当前用户所拥有的岗位
if (StringUtils.isNotBlank(employee.getEmpCode())){
// 获取当前用户所拥有的岗位
employee.setEmployeePostList(employeeService.findEmployeePostList(employee));
// 获取当前员工关联的附属机构信息
employee.setEmployeeOfficeList(employeeService.findEmployeeOfficeList(employee));
}
// 获取当前编辑用户的角色和权限
@@ -175,7 +177,7 @@ public class EmpUserController extends BaseController {
public void exportData(EmpUser empUser, Boolean isAll, String ctrlPermi, HttpServletResponse response) {
empUser.getEmployee().getOffice().setIsQueryChildren(true);
empUser.getEmployee().getCompany().setIsQueryChildren(true);
if (!(isAll != null && isAll)){
if (!(isAll != null && isAll) || Global.isStrictMode()){
empUserService.addDataScopeFilter(empUser, ctrlPermi);
}
List<EmpUser> list = empUserService.findList(empUser);
@@ -367,7 +369,7 @@ public class EmpUserController extends BaseController {
empUser.setRoleCode(roleCode);
empUser.setStatus(User.STATUS_NORMAL);
empUser.setUserType(User.USER_TYPE_EMPLOYEE);
if (!(isAll != null && isAll)) {
if (!(isAll != null && isAll) || Global.isStrictMode()) {
empUserService.addDataScopeFilter(empUser, ctrlPermi);
}
List<EmpUser> list = empUserService.findList(empUser);

View File

@@ -50,7 +50,7 @@ public class SecAdminController extends BaseController {
return "modules/sys/user/secAdminList";
}
@RequiresPermissions("user")
@RequiresPermissions("sys:secAdmin:view")
@RequestMapping(value = "listData")
@ResponseBody
public Page<User> listData(User user, HttpServletRequest request, HttpServletResponse response) {

View File

@@ -25,26 +25,36 @@ jdbc:
# 最大连接数
maxActive: 20
# 获取连接等待超时时间单位毫秒4.0.6+
# 获取连接等待超时时间,单位毫秒(1分钟4.0.6+
maxWait: 60000
# 从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个4.0.6+
# 从池中取出连接前进行检验如果检验失败则从池中去除连接并尝试取出另一个4.0.6+
testOnBorrow: false
testOnReturn: false
# 间隔多久才进行一次检测检测需要关闭的空闲连接单位毫秒4.0.6+
# 间隔多久才进行一次检测,检测需要关闭的空闲连接,单位毫秒(1分钟4.0.6+
timeBetweenEvictionRunsMillis: 60000
# 一个连接在池中最小生存的时间单位毫秒4.0.6+
minEvictableIdleTimeMillis: 300000
# 一个连接在池中最小空闲的时间,单位毫秒(20分钟4.0.6+
minEvictableIdleTimeMillis: 1200000
# 一个连接在池中最大空闲的时间单位毫秒30分钟4.1.2+
maxEvictableIdleTimeMillis: 1800000
# 配置是否自动回收超时连接超时时间,单位秒 4.0.6+
# 是否自动回收泄露的连接超时时间,单位秒35分钟4.0.6+
removeAbandoned: true
removeAbandonedTimeout: 1800
removeAbandonedTimeout: 2100
# JTA 分布式事务v4.0.4+
jta:
enabled: false
# 注意:如果报 oracle.jdbc.xa.OracleXAResource.recover 错误,则需要授权如下:
# 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;
# 事务超时时间单位秒30分钟v4.1.5+
transactionTimeout: 1800
# 表名前缀
tablePrefix: js_
@@ -98,11 +108,11 @@ user:
# 系统管理员角色编号(客户方管理员使用的角色)
corpAdminRoleCode: corpAdmin
# 用户类型配置信息employee员工member会员btype往来单位persion个人expert专家...
# JSON格式说明{"用户类型":{"dao":"Dao的Bean名称","loginView":"登录视图","indexView":"主框架面视图"}}
# 用户类型配置信息employee员工member会员btype往来单位persion个人expert专家...JSON 格式说明如下:
# {"用户类型":{"dao":"Dao的Bean名称","loginView":"登录页面视图","indexView":"主框架面视图,支持 redirect: 前缀"}}
userTypeMap: >
{
"employee":{"dao":"employeeDao","loginView":"","indexView":""},
"employee":{"dao":"employeeDao","loginView":"","indexView":"modules/sys/sysIndex"},
"member":{"dao":"memberDao","loginView":"","indexView":"modules/sys/sysIndexMember"},
"btype":{"dao":"btypeInfoDao","loginView":"","indexView":"modules/sys/sysIndexBtype"},
"persion":{"dao":"persionDao","loginView":"","indexView":"modules/sys/sysIndexPersion"},
@@ -143,6 +153,9 @@ user:
remarks: ""
}]
# 管理功能的控制权限类型1拥有的权限 2管理的权限v4.1.5+
adminCtrlPermi: 2
# 多租户模式SAAS模式专业版
useCorpModel: false
@@ -156,14 +169,18 @@ user:
# 角色管理
role:
# 扩展数据权限定义3本部门4本公司5本部门和本公司
# 如果 ctrlTypeClass 为 NONE则代表是不控制该类型权限
extendDataScopes: >
{
3: {
Office: {
#控制类型的类名 : "用来获取控制表名和主键,如果为 NONE则代表是不控制该类型权限",
ctrlTypeClass: "com.jeesite.modules.sys.entity.Office",
ctrlDataAttrName: "currentUser.refObj.office.officeCode",
ctrlDataParentCodesAttrName: "currentUser.refObj.office.parentCodes"
#控制数据的类名: "指定一个静态类名,方便 ctrlDataAttrName 得到权限数据,如:当前部门编码、公司编码",
ctrlDataClass: "com.jeesite.modules.sys.utils.EmpUtils",
#控制数据的类名下的属性名 : "可看做类下的 get 方法EmpUtils.getOffices(),支持返回字符串或字符串数组类型",
ctrlDataAttrName: "officeCodes",
#控制数据的所有上级编码 : "用于控制数据为树表的情况,为数组时,必须与 ctrlDataAttrName 返回的长度相同,不是树表设置为空",
ctrlDataParentCodesAttrName: "officeParentCodess"
},
Company: {
ctrlTypeClass: "NONE"
@@ -175,20 +192,23 @@ role:
},
Company: {
ctrlTypeClass: "com.jeesite.modules.sys.entity.Company",
ctrlDataAttrName: "currentUser.refObj.company.companyCode",
ctrlDataParentCodesAttrName: "currentUser.refObj.company.parentCodes"
ctrlDataClass: "com.jeesite.modules.sys.utils.EmpUtils",
ctrlDataAttrName: "company.companyCode",
ctrlDataParentCodesAttrName: "company.parentCodes"
}
},
5: {
Office: {
ctrlTypeClass: "com.jeesite.modules.sys.entity.Office",
ctrlDataAttrName: "currentUser.refObj.office.officeCode",
ctrlDataParentCodesAttrName: "currentUser.refObj.office.parentCodes"
ctrlDataClass: "com.jeesite.modules.sys.utils.EmpUtils",
ctrlDataAttrName: "officeCodes",
ctrlDataParentCodesAttrName: "officeParentCodess"
},
Company: {
ctrlTypeClass: "com.jeesite.modules.sys.entity.Company",
ctrlDataAttrName: "currentUser.refObj.company.companyCode",
ctrlDataParentCodesAttrName: "currentUser.refObj.company.parentCodes"
ctrlDataClass: "com.jeesite.modules.sys.utils.EmpUtils",
ctrlDataAttrName: "company.companyCode",
ctrlDataParentCodesAttrName: "company.parentCodes"
}
}
}
@@ -200,11 +220,16 @@ menu:
# 国际化管理(专业版)
lang:
enabled: true
enabled: false
# 默认语言4.1.3+
defaultLocale: zh_CN
# 默认时区4.1.3+
defaultTimeZone: GMT+08:00
# 任务调度(个人版)
job:
enabled: true
enabled: false
# 是否自动启动任务调度(可关闭)
autoStartup: true
@@ -274,7 +299,7 @@ shiro:
logoutUrl: ${shiro.loginUrl}
successUrl: ${adminPath}/index
# # Jasig CAS 相关配置(个人版)
# # Apereo CAS 相关配置(个人版)
# casServerUrl: http://127.0.0.1:8981/cas
# casClientUrl: http://127.0.0.1:8980/js
# loginUrl: ${shiro.casServerUrl}?service=${shiro.casClientUrl}${adminPath}/login-cas
@@ -310,6 +335,9 @@ shiro:
# 是否允许账号多地登录如果设置为false同一个设备类型的其它地点登录的相同账号被踢下线
isAllowMultiAddrLogin: true
# 是否允许多账号多设备登录如果设置为false其它地点登录的相同账号全部登录设备将被踢下线
isAllowMultiDeviceLogin: true
# 是否允许刷新主框架页如果设置为false刷新主页将导致重新登录。如安全性比较高的如银行个人首页不允许刷新。
isAllowRefreshIndex: true
@@ -319,6 +347,9 @@ shiro:
# 是否允许跨域访问,如果允许,设置允许的域名,全部域名设置*号,如果不允许,此设置应该为空
# accessControlAllowOrigin: http://demo.jeesite.com
# accessControlAllowOrigin: '*'
# 是否允许接收跨域的Cookie凭证数据
# accessControlAllowCredentials: true
# 是否在登录后生成新的Session默认false
isGenerateNewSessionAfterLogin: false
@@ -399,7 +430,7 @@ mybatis:
# Web 相关
web:
# MVC 视图相关
view:
@@ -420,6 +451,7 @@ web:
${adminPath}/index,
${adminPath}/login,
${adminPath}/desktop,
${adminPath}/index/menuTree,
${adminPath}/sys/online/count,
${adminPath}/state/server/rtInfo,
${adminPath}/**/treeData,
@@ -439,12 +471,18 @@ web:
# 静态文件后缀排除的url路径指定哪些uri路径不进行静态文件过滤。
staticFileExcludeUri: /druid/
# 静态资源路径前缀可做CDN加速优化
staticPrefix: /static
# 严格模式(更严格的数据安全验证)
strictMode: false
# 自定义正则表达式验证(主键、登录名)
validator:
id: '[a-zA-Z0-9_\-/#\u4e00-\u9fa5]{0,64}'
user.loginCode: '[a-zA-Z0-9_\u4e00-\u9fa5]{4,20}'
# 核心模块的Web功能仅作为微服务时设为false
core:
enabled: true
@@ -474,17 +512,40 @@ file:
# 上传单个文件最大字节500M在这之上还有 > Tomcat限制 > Nginx限制此设置会覆盖 spring.http.multipart.maxFileSize 设置
maxFileSize: 500*1024*1024
#设置允许上传的文件后缀
# 设置允许上传的文件后缀
imageAllowSuffixes: .gif,.bmp,.jpeg,.jpg,.ico,.png,.tif,.tiff,
mediaAllowSuffixes: .flv,.swf,.mkv,webm,.mid,.mov,.mp3,.mp4,.m4v,.mpc,.mpeg,.mpg,.swf,.wav,.wma,.wmv,.avi,.rm,.rmi,.rmvb,.aiff,.asf,.ogg,.ogv,
fileAllowSuffixes: .doc,.docx,.rtf,.xls,.xlsx,.csv,.ppt,.pptx,.pdf,.vsd,.txt,.md,.xml,.rar,.zip,7z,.tar,.tgz,.jar,.gz,.gzip,.bz2,.cab,.iso,.ipa,.apk,
#允许上传的文件内容类型图片、word、excel、ppt防止修改后缀恶意上传文件默认不启用验证
# 允许上传的文件内容类型图片、word、excel、ppt防止修改后缀恶意上传文件默认不启用验证
# allowContentTypes: image/jpeg,image/gif,image/bmp,image/png,image/x-png,
# application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,
# application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,
# application/vnd.ms-powerpoint,application/vnd.openxmlformats-officedocument.presentationml.presentation
# 是否开启分片上传
chunked: false
# 分片大小单位字节10M
chunkSize: 10485760
# 最大上传线程数
threads: 1
# 是否用文件流方式下载(支持断点续传)
isFileStreamDown: true
# 视频转码
video:
# 视频格式转换 ffmpeg.exe 所放的路径
ffmpegFile: d:/tools/video/ffmpeg-4.9/bin/ffmpeg.exe
# ffmpegFile: d:/tools/video/libav-10.6-win64/bin/avconv.exe
# 视频格式转换 mencoder.exe 所放的路径
mencoderFile: d:/tools/video/mencoder-4.9/mencoder.exe
# 将mp4视频的元数据信息转到视频第一帧
qtFaststartFile: d:/tools/video/qt-faststart/qt-faststart.exe
#======================================#
#========== Message settings ==========#
#======================================#
@@ -539,18 +600,3 @@ msg:
oauth:
redirectUri: http://demo.jeesite.com/js
#======================================#
#========== Video settings ============#
#======================================#
video:
# 视频格式转换 ffmpeg.exe 所放的路径
ffmpegFile: d:/tools/video/ffmpeg-4.9/bin/ffmpeg.exe
# ffmpegFile: d:/tools/video/libav-10.6-win64/bin/avconv.exe
# 视频格式转换 mencoder.exe 所放的路径
mencoderFile: d:/tools/video/mencoder-4.9/mencoder.exe
# 将mp4视频的元数据信息转到视频第一帧
qtFaststartFile: d:/tools/video/qt-faststart/qt-faststart.exe

View File

@@ -11,7 +11,11 @@
<!-- <logger name="org.springframework.jdbc" level="DEBUG" /> -->
<logger name="org.mybatis.spring.transaction" level="DEBUG" />
<logger name="com.atomikos.icatch.config.UserTransactionServiceImp" level="ERROR" />
<logger name="com.atomikos.icatch.provider.imp.AssemblerImp" level="ERROR" />
<logger name="com.atomikos.jdbc.AbstractDataSourceBean" level="ERROR" />
<logger name="com.atomikos.jdbc.AtomikosConnectionProxy" level="ERROR" />
<logger name="com.atomikos.recovery.xa.XaResourceRecoveryManager" level="ERROR" />
<!-- <logger name="org.springframework.transaction.support.TransactionSynchronizationManager" level="TRACE" /> -->
<logger name="springfox.documentation.spring.web.readers.parameter.ParameterDataTypeReader" level="ERROR" />
<!-- <logger name="io.swagger" level="DEBUG" /> -->
@@ -20,6 +24,7 @@
<logger name="com.jeesite" level="DEBUG" />
<logger name="com.jeesite.common.i18n" level="INFO" />
<logger name="com.jeesite.common.shiro" level="INFO" />
<logger name="com.jeesite.common.cache" level="INFO" />
<logger name="com.jeesite.common.j2cache" level="INFO" />
<logger name="com.jeesite.common.mybatis" level="INFO" />
<logger name="com.jeesite.common.mybatis.mapper" level="DEBUG" />

View File

@@ -2,5 +2,3 @@
UPDATE ${_prefix}sys_menu SET permission='sys:stste:cache' WHERE permission='sys:stste:ehcache';
UPDATE ${_prefix}sys_menu SET menu_href='/state/cache/index' WHERE menu_href='/state/ehcache';
UPDATE ${_prefix}sys_menu SET menu_href='/state/server/index' WHERE menu_href='/state/server';
commit;

View File

@@ -0,0 +1,8 @@
-- 将config表的key设置为唯一索引
DROP INDEX [idx_sys_config_key] ON [${_prefix}sys_config];
CREATE UNIQUE INDEX [idx_sys_config_key] ON [${_prefix}sys_config] ([config_key]);
-- 新增主导航菜单显示风格配置
INSERT INTO ${_prefix}sys_config(id, config_name, config_key, config_value, is_sys, create_by, create_date, update_by, update_date, remarks)
VALUES ('1092344803460943872', '主框架页-主导航菜单显示风格', 'sys.index.menuStyle', '1', '0', 'system', getdate(), 'system', getdate(), '1菜单全部在左侧2根菜单显示在顶部');

View File

@@ -0,0 +1,27 @@
-- 删除sys_file_entity表的file_md5唯一索引
-- ALTER TABLE [${_prefix}sys_file_entity] DROP CONSTRAINT [UQ__${_prefix}sys_f__3BD63C9E32E0915F];
-- 增加文件信息字段(可存储图片大小)
ALTER TABLE [${_prefix}sys_file_entity] ADD [file_meta] varchar(64) NULL;
-- 集群的实例名字
ALTER TABLE [${_prefix}sys_job] ADD [instance_name] varchar(64) DEFAULT 'JeeSiteScheduler' NOT NULL;
-- 内部消息菜单
INSERT INTO ${_prefix}sys_menu(menu_code, parent_code, parent_codes, tree_sort, tree_sorts, tree_leaf, tree_level, tree_names, menu_name, menu_type, menu_href, menu_target, menu_icon, menu_color, permission, weight, is_show, sys_code, module_codes, status, create_by, create_date, update_by, update_date, remarks, extend_s1, extend_s2, extend_s3, extend_s4, extend_s5, extend_s6, extend_s7, extend_s8, extend_i1, extend_i2, extend_i3, extend_i4, extend_f1, extend_f2, extend_f3, extend_f4, extend_d1, extend_d2, extend_d3, extend_d4)
VALUES ('1105443204287991808', '0', '0,', 9030, '0000009030,', '1', 0, '站内消息', '站内消息', '1', '/msg/msgInner/list', '', 'icon-speech', '', 'msg:msgInner', 40, '1', 'default', 'core', '0', 'system', getdate(), 'system', getdate(), '', '', '', '', '', '', '', '', '', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
-- 内部消息新增字典数据
INSERT INTO ${_prefix}sys_dict_type(id, dict_name, dict_type, is_sys, status, create_by, create_date, update_by, update_date, remarks)
VALUES ('1105440848414543872', '消息状态', 'msg_inner_msg_status', '0', '0', 'system', getdate(), 'system', getdate(), '');
INSERT INTO ${_prefix}sys_dict_data(dict_code, parent_code, parent_codes, tree_sort, tree_sorts, tree_leaf, tree_level, tree_names, dict_label, dict_value, dict_type, is_sys, description, css_style, css_class, status, create_by, create_date, update_by, update_date, remarks, corp_code, corp_name, extend_s1, extend_s2, extend_s3, extend_s4, extend_s5, extend_s6, extend_s7, extend_s8, extend_i1, extend_i2, extend_i3, extend_i4, extend_f1, extend_f2, extend_f3, extend_f4, extend_d1, extend_d2, extend_d3, extend_d4)
VALUES ('1106135527342673920', '0', '0,', 20, '0000000020,', '1', 0, '全部', '全部', '0', 'msg_inner_receiver_type', '1', '', '', '', '0', 'system', getdate(), 'system', getdate(), '', '0', 'JeeSite', '', '', '', '', '', '', '', '', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
-- 取消内部消息部分字段必填选项
ALTER TABLE [${_prefix}sys_msg_inner] ALTER COLUMN [receive_codes] text NULL;
ALTER TABLE [${_prefix}sys_msg_inner] ALTER COLUMN [receive_names] text NULL;
ALTER TABLE [${_prefix}sys_msg_inner] ALTER COLUMN [send_user_code] varchar(64) NULL;
ALTER TABLE [${_prefix}sys_msg_inner] ALTER COLUMN [send_user_name] varchar(100) NULL;
ALTER TABLE [${_prefix}sys_msg_inner] ALTER COLUMN [send_date] datetime NULL;
ALTER TABLE [${_prefix}sys_msg_inner] ALTER COLUMN [notify_types] varchar(100) NULL;

View File

@@ -0,0 +1,18 @@
-- 新增文件管理模块
INSERT INTO ${_prefix}sys_module(module_code, module_name, description, main_class_name, current_version, upgrade_info, status, create_by, create_date, update_by, update_date, remarks)
VALUES ('filemanager', '文件管理', '公共文件柜、个人文件柜、文件分享', 'com.jeesite.modules.filemanager.web.FilemanagerController', '4.1.4', NULL, '0', 'system', getdate(), 'system', getdate(), NULL);
-- 员工附属机构关系表
CREATE TABLE [${_prefix}sys_employee_office]
(
[id] varchar(64) NOT NULL UNIQUE,
[emp_code] varchar(64) NOT NULL,
[office_code] varchar(64) NOT NULL,
[post_code] varchar(64),
PRIMARY KEY ([emp_code], [office_code])
);
-- 新增日语(日本语)语言包
INSERT INTO ${_prefix}sys_dict_data(dict_code, parent_code, parent_codes, tree_sort, tree_sorts, tree_leaf, tree_level, tree_names, dict_label, dict_value, dict_type, is_sys, description, css_style, css_class, status, create_by, create_date, update_by, update_date, remarks, corp_code, corp_name, extend_s1, extend_s2, extend_s3, extend_s4, extend_s5, extend_s6, extend_s7, extend_s8, extend_i1, extend_i2, extend_i3, extend_i4, extend_f1, extend_f2, extend_f3, extend_f4, extend_d1, extend_d2, extend_d3, extend_d4)
VALUES ('1126375062364020736', '0', '0,', 60, '0000000060,', '1', 0, '日本語', '日本語', 'ja_JP', 'sys_lang_type', '1', '', '', '', '0', 'system', getdate(), 'system', getdate(), '', '0', 'JeeSite', '', '', '', '', '', '', '', '', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);

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