Compare commits

...

157 Commits

Author SHA1 Message Date
thinkgem
ef4d06ff2e update README.md 2024-04-01 12:03:00 +08:00
thinkgem
24d51e416e web-fast 默认使用 vue 前端展示 2024-04-01 12:02:36 +08:00
thinkgem
ed836c2f6a update PageNotFound log level 2024-04-01 11:57:44 +08:00
thinkgem
529d2b8192 代码优化 2024-04-01 11:52:46 +08:00
thinkgem
9c0885b4c9 增加msgview初始菜单地址 2024-04-01 11:52:20 +08:00
thinkgem
7ccbb05b7b 代码优化 2024-04-01 11:51:19 +08:00
thinkgem
53af15f85d 5.7.0 2024-03-28 14:15:33 +08:00
thinkgem
21b15f16e3 更新建表语句 2024-03-28 14:14:34 +08:00
thinkgem
8176853791 vue icon add prefix i- 2024-03-27 11:12:14 +08:00
thinkgem
a56e29d8f7 update import 2024-03-27 11:11:36 +08:00
thinkgem
081505f79c update import 2024-03-26 19:27:48 +08:00
thinkgem
a6adfbc726 新增IP地址黑白名单过滤器及参数配置 2024-03-25 13:57:03 +08:00
thinkgem
e883de354f 更新注释提示 2024-03-25 13:52:46 +08:00
thinkgem
f4909921ac update fonts 2024-03-22 21:45:17 +08:00
thinkgem
0eb09a0dbb 增加根据用户编码查询岗位列表接口 2024-03-22 14:43:02 +08:00
thinkgem
a58a2dcda2 侧边栏增加是否展开第一个菜单开关 2024-03-22 14:42:26 +08:00
thinkgem
1318ce840c format code 2024-03-22 14:40:54 +08:00
thinkgem
0a771a7008 EmployeePostDao 增加根据用户编码查询岗位 sqlMap().loadJoinTableAlias("p,u") 的时候有效 2024-03-22 14:40:15 +08:00
thinkgem
2ea481a417 模块管理增加生成模块的基础路径和模板存储字段,生成模块代码时给于确认提示;微服务下isLoader为true; 2024-03-22 09:16:33 +08:00
thinkgem
07d3eef8ab 修正代码生成模板logback-spring-elk和prod.xml文件名 2024-03-22 09:15:51 +08:00
thinkgem
f3c4a0dbe9 add getPageList(List<T> list, int pageNo, int pageSize) 2024-03-21 15:46:14 +08:00
thinkgem
8f14549fee 分离端调用login和index接口时,同时返回cookie。特殊情况下的iframe的页面会话同步 2024-03-20 14:05:38 +08:00
thinkgem
bccecc8b39 update productVersion 2024-03-20 09:39:05 +08:00
thinkgem
4a8bad7d35 返回响应头增加x-token,通过记住我登录系统时使用。 2024-03-13 13:34:17 +08:00
thinkgem
8ef29563f5 演示模式不允许清理会话和缓存 2024-03-13 13:29:02 +08:00
thinkgem
87b8dc6ec4 返回响应头增加x-token,通过记住我登录系统时使用。 2024-03-13 13:18:36 +08:00
thinkgem
b1f29a9d57 代码生成器config.xml的attrType字典增加attrName,用于选择控件编码和名称获取 2024-03-13 11:35:16 +08:00
thinkgem
33eb95f120 登录超时后不再统计在线人数 2024-03-12 13:20:44 +08:00
thinkgem
4bfe7b2316 缩短Logback日志TRACE_ID的长度 2024-03-12 12:24:24 +08:00
thinkgem
b0350b36d7 完善内部消息保存后的提示消息 2024-03-12 12:23:39 +08:00
thinkgem
9f16332c09 代码生成模板添加公司选择组件v2 2024-03-11 21:24:20 +08:00
thinkgem
419ed4f01b 新增 AesTypeHandler 处理字段数据加密解密或脱敏;新增 JsonTypeHandler 处理字段数据进行 JSON 字符串与 Java 对象 自动互转 2024-03-11 17:02:40 +08:00
thinkgem
69cd032b7e 代码优化 2024-03-11 17:01:20 +08:00
thinkgem
c0aeef4881 代码生成模板添加公司选择组件 2024-03-10 10:44:00 +08:00
thinkgem
e7c6e7e85b add vueFormRoute.xml 2024-03-10 10:42:17 +08:00
thinkgem
7f06df2bed 根据当前用户有的子系统,切换到默认系统下 2024-03-08 13:29:42 +08:00
thinkgem
250788a398 update nacos config 2024-03-04 11:50:43 +08:00
thinkgem
196cf4f10c 更新Docker多CPU平台架构 2024-02-28 10:35:36 +08:00
thinkgem
3b587c661b fix h2db job sql 2024-02-28 10:07:14 +08:00
thinkgem
7eb9484d7e TimeUtils millisecond to ms 2024-02-27 11:30:41 +08:00
thinkgem
c610af7c6b 分页栏居右、布局调整、样式美化 2024-02-23 14:16:28 +08:00
thinkgem
0c7cefb184 next version 2024-02-23 14:05:06 +08:00
thinkgem
19d2399eb2 5.6.1 2024-02-18 16:01:14 +08:00
thinkgem
37b0a120c9 1、修改默认值,oracle 下默认不启用 maxPoolPreparedStatementPerConnectionSize 可根据需要开启;2、将 com.oracle.ojdbc 驱动替换为 com.oracle.database.jdbc 驱动;3、默认将 jtds 驱动替换为 sqlserver 驱动; 2024-02-02 14:03:11 +08:00
thinkgem
5fb6ab0ca6 ueditor黑暗模式下的文字 2024-01-31 12:04:34 +08:00
thinkgem
2ba8b953d3 更新路由表单组件 2024-01-30 16:53:39 +08:00
thinkgem
738fd5c552 form:fileupload组件默认加dataMap属性 2024-01-30 11:40:29 +08:00
thinkgem
745f6e88c0 新增 js.ajaxSubmitForm支持application/json提交表单;新增 js.ajaxSubmitJson 方法 2024-01-30 11:38:39 +08:00
thinkgem
3db837d6d6 代码优化 2024-01-26 14:43:03 +08:00
thinkgem
14054a964f ts type check 2024-01-23 17:53:07 +08:00
thinkgem
14581655d2 code format 2024-01-17 16:17:09 +08:00
thinkgem
f162584d1e 代码优化,方便自定义内嵌的Web服务 2024-01-15 13:44:39 +08:00
thinkgem
e57e8127b5 报表增加请求参数的例子 2024-01-10 13:08:17 +08:00
thinkgem
b7d4efa6a6 update 2024-01-10 13:04:34 +08:00
thinkgem
91a4db4eb8 增加vue无框架页面的组件类型 2024-01-09 16:42:53 +08:00
thinkgem
7ed84e48cf 存储Key增加了默认,个性化时再指定 2024-01-08 15:25:41 +08:00
thinkgem
f068bd9c90 update version 2024-01-08 10:39:18 +08:00
thinkgem
4ae907a023 update 2024-01-05 20:49:46 +08:00
thinkgem
652a242c2b 5.6.0 2024-01-04 12:06:16 +08:00
thinkgem
d242408de2 5.6.0 2024-01-03 16:58:35 +08:00
thinkgem
b8f51011ed 配置类 ShiroConfig 改为 ShiroAutoConfiguration 方便覆写 2024-01-03 08:53:55 +08:00
thinkgem
84913ab783 分号修正 2024-01-03 08:24:38 +08:00
thinkgem
b7bb765193 update 2024 2024-01-02 10:24:19 +08:00
thinkgem
d1b06c45c8 add ConditionalOnMissingBean 2024-01-02 10:23:37 +08:00
thinkgem
19fe2023a6 update 2024-01-02 10:22:57 +08:00
thinkgem
590046d90c select2 i18n fix 2023-12-29 10:56:03 +08:00
thinkgem
00c162ece1 代码优化提示 2023-12-28 09:33:20 +08:00
thinkgem
d5deb38769 优化在线用户列表数值类型的排序 2023-12-27 10:47:44 +08:00
thinkgem
b71165f73c 代码生成模板:新增Vue路由表单、新增Vue弹窗表单、新增仅后端模板 2023-12-24 21:36:09 +08:00
thinkgem
4260accf88 不设置adminPath的时候需要增加oauth2的地址认证排除 2023-12-23 23:01:37 +08:00
thinkgem
353131ab2c 用户管理增加解冻用户功能提示 2023-12-23 23:00:30 +08:00
thinkgem
acb6baa226 细节优化 2023-12-23 22:59:38 +08:00
thinkgem
5b7f7b0860 spring boot 2.7.18、jackson 2.16.0、fastjson 2.0.43、mybatis 3.5.14、shiro 1.13.0 2023-12-13 21:37:09 +08:00
thinkgem
c57238e279 spring.data.elasticsearch.enabled to spring.elasticsearch.enabled 2023-12-13 21:06:42 +08:00
thinkgem
24ea4aaed0 增加一些vue下用的路由 2023-12-12 09:42:56 +08:00
thinkgem
0af1ae18c8 update 2023-12-12 09:41:38 +08:00
thinkgem
e054df919f BpmButton.vue将提交审批信息移动到提交对话框中 2023-12-07 17:20:30 +08:00
thinkgem
a9ca557672 update 2023-12-05 16:30:31 +08:00
thinkgem
5bc76dd23d update 2023-12-05 16:12:42 +08:00
thinkgem
f337faeecc 代码优化 2023-12-03 15:55:22 +08:00
thinkgem
a6d84c59c9 vue兼容优化 2023-12-01 10:40:54 +08:00
thinkgem
b8279ffe64 优化修改密码后的操作 2023-11-28 16:15:16 +08:00
thinkgem
af44331820 优化vue生成模板 2023-11-28 15:46:05 +08:00
thinkgem
00ead34076 BasicTable子表加TextArea组件 2023-11-27 12:23:54 +08:00
thinkgem
9b07e167f7 树表的局部刷新改进,删除、停用、启用、修改父节点的情况下完美体验 2023-11-27 10:11:56 +08:00
thinkgem
0fb15e31d6 next 2023-11-27 09:06:15 +08:00
thinkgem
3e769325f8 Layer弹窗后首先关闭获取焦点,防止回车弹出多个 2023-11-22 11:14:08 +08:00
thinkgem
d555d508c3 5.5.2 2023-11-21 21:47:55 +08:00
thinkgem
11511c14bd 更新h2的库名 2023-11-20 16:01:08 +08:00
thinkgem
2238ca062f 添加自动切换到脚本所在目录 2023-11-20 15:43:41 +08:00
thinkgem
3563f18335 更新docker运行脚本帮助 2023-11-20 15:16:26 +08:00
thinkgem
983ad2faff add db docs xlsx png 2023-11-17 11:17:35 +08:00
thinkgem
f569da908d 增加quartz表ER图和注释 2023-11-16 11:57:02 +08:00
thinkgem
2e0718ba41 增加vue的ListSelect选择框代码生成模板 2023-11-09 11:31:31 +08:00
thinkgem
846bf82375 Byte格式化默认显示两位小数 2023-11-08 11:46:51 +08:00
thinkgem
8cc6f25dd1 添加jdbc.connectTimeou和jdbc.socketTimeout连接池参数 2023-10-30 08:44:44 +08:00
thinkgem
5ff9ca9815 update version 2023-10-26 11:38:15 +08:00
thinkgem
31e6b01b4e 新增一个日志清理接口,可根据需要创建job调用 2023-10-26 11:27:50 +08:00
thinkgem
bc8a6d2db7 新增富文本和头像的对象存储调用 2023-10-23 10:57:27 +08:00
thinkgem
9a13b33dd8 查询和重置增加图标、搜索框布局优化 2023-10-23 10:55:34 +08:00
thinkgem
4bdba535bb 5.5.1 2023-10-16 21:43:00 +08:00
thinkgem
09bf40feee update README.md 2023-10-16 20:06:08 +08:00
thinkgem
5d74d2783f update README.md 2023-10-16 07:00:46 +08:00
thinkgem
807b47dbc4 docker update 2023-10-12 14:50:32 +08:00
thinkgem
456cdaf883 Merge remote-tracking branch 'origin/v5.temp' into v5.temp 2023-10-07 17:14:35 +08:00
thinkgem
d1b588b7d5 spring boot 2.7.16 2023-10-07 15:05:45 +08:00
thinkgem
22a4b0fcf7 update README.md 2023-10-07 10:57:23 +08:00
thinkgem
84407b5785 修改erm默认字体大小,适应多操作系统 2023-10-01 16:52:45 +08:00
thinkgem
f5771c56a4 修改erm默认字体大小,适应多操作系统 2023-09-28 16:54:29 +08:00
thinkgem
a3dee0f70a 优化JsonMapper,增加XSS过滤通用方法 2023-09-27 13:19:22 +08:00
thinkgem
797abcdf87 update README.md 2023-09-19 14:27:28 +08:00
thinkgem
0559c79687 update 2023-09-18 10:59:26 +08:00
thinkgem
f514b86bbc linux下如果有前缀就不增加了 2023-09-18 10:59:10 +08:00
thinkgem
49992195df update script 2023-09-12 10:26:09 +08:00
thinkgem
631225a108 new version 2023-09-11 13:49:25 +08:00
thinkgem
5922951c16 add startup info 2023-08-30 15:32:57 +08:00
thinkgem
5dc1b29a34 snakeyaml 1.33 2023-08-22 17:10:16 +08:00
thinkgem
97252f7d82 5.5.0 2023-08-21 17:09:42 +08:00
thinkgem
efa8d7788a maven ssl 2023-08-21 13:10:53 +08:00
thinkgem
40c5759f59 update area data 2023-08-21 11:07:02 +08:00
thinkgem
13df22605b update 2023-08-21 10:37:54 +08:00
thinkgem
a2644570be update 5.5 2023-08-17 14:26:18 +08:00
thinkgem
da12b2d092 角色增加包含系统参数,切换系统时只需展示当前用户包含的子系统 2023-08-16 16:30:07 +08:00
thinkgem
f5080cd8f5 new version 2023-08-16 10:43:18 +08:00
thinkgem
729801bab5 隐藏表单右上角按钮 2023-08-14 12:40:18 +08:00
thinkgem
0de77acca2 spring boot 2.7.14 2023-08-14 12:37:47 +08:00
thinkgem
7128998483 update README.md 2023-08-09 19:49:08 +08:00
thinkgem
1becabaea3 升级jquery migrate版本,解决ie9下的一些问题修复 2023-08-09 19:38:20 +08:00
thinkgem
23b726e335 downloadByUrl支持post带参数下载文件 2023-08-09 16:45:48 +08:00
thinkgem
6909116d9a 下载文件增加clearParams参数,清理掉不需要添加的请求参数,如:pageNo 2023-08-09 16:42:03 +08:00
thinkgem
12132ab592 html和js语法编写不同的占位符,减少IDE标红提示 2023-08-03 17:22:41 +08:00
thinkgem
920a1a8916 remove web.xml 2023-08-03 11:16:17 +08:00
thinkgem
eaa6646a74 增加缩略图生成设置,前端组件可使用 imageThumbName 使用缩略图 2023-08-02 10:42:02 +08:00
thinkgem
696b7addb9 ImageUtils 生成缩略图,增加目标文件参数,可以不是原文件 2023-08-02 10:39:26 +08:00
thinkgem
43fbbda930 修改弹窗表头高度小一点 2023-08-01 11:28:09 +08:00
thinkgem
727454d2a7 用户列表选择样式优化 2023-08-01 11:27:05 +08:00
thinkgem
33d0693bb1 online 代码优化 2023-08-01 11:24:29 +08:00
thinkgem
1eaff67ffd update 2023-07-31 10:01:41 +08:00
thinkgem
f54126bc07 update build time 2023-07-30 20:13:39 +08:00
thinkgem
fce22831ab update build time 2023-07-30 20:09:04 +08:00
thinkgem
ae17e2c2a4 shiro 1.12.0 2023-07-27 21:43:00 +08:00
thinkgem
db9ff3647a update 2023-07-26 14:57:31 +08:00
thinkgem
e5f5c4cd11 5.4.1 2023-07-24 18:13:47 +08:00
thinkgem
1098757b6a update script 2023-07-21 23:47:28 +08:00
thinkgem
084bfaac92 update version 2023-07-19 19:31:07 +08:00
thinkgem
e7ec4c52e8 国际化完善 2023-07-18 11:55:35 +08:00
thinkgem
02f0e1b300 基础圆角调整 antdv4.0 2023-07-17 12:54:48 +08:00
thinkgem
e7e15fd15e 多语言译文优化 2023-07-17 11:34:38 +08:00
thinkgem
a2d873fee5 将语言名称传递给vue,登录时检测 2023-07-17 10:54:47 +08:00
thinkgem
48a93201e6 update readme 2023-07-11 10:49:47 +08:00
thinkgem
e3e222d7bb update 2023-07-11 10:16:12 +08:00
thinkgem
050aa6e4bf update 2023-07-05 16:23:26 +08:00
thinkgem
a0bfba3abb 权限授权树,如果没有数据的时候可以隐藏 2023-07-05 16:22:55 +08:00
thinkgem
96838f50ad update 2023-07-05 16:21:51 +08:00
thinkgem
0a3c0e4bc8 update 2023-06-28 19:16:44 +08:00
thinkgem
0d24b71fe3 增加参数 web.xssFilterExcludeUri 2023-06-28 19:05:55 +08:00
thinkgem
e658f9e6f6 update 2023-06-28 17:11:18 +08:00
302 changed files with 35103 additions and 28590 deletions

View File

@@ -214,7 +214,7 @@
5. 任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。
6. 如果你对本软件有改进,希望可以贡献给我们,共同进步。
7. 本项目已申请软件著作权,请尊重开源,感谢阅读。
8. 本版本无用户数限制,无在线人数限制。
8. 无用户数限制,无在线人数限制,放心使用
版权所有:济南卓源软件有限公司

View File

@@ -4,7 +4,7 @@
</p>
<h3 align="center" style="margin:30px 0 30px;font-weight:bold;font-size:30px;">快速开发平台 - Spring Boot</h3>
<p align="center">
<a href="https://jeesite.com/docs/upgrade/" target="__blank"><img alt="JeeSite-V5.3" src="https://img.shields.io/badge/JeeSite-V5.3-success.svg"></a>
<a href="https://jeesite.com/docs/upgrade/" target="__blank"><img alt="JeeSite-V5.7" src="https://img.shields.io/badge/JeeSite-V5.7-success.svg"></a>
<a href="https://spring.io/projects/spring-boot#learn" target="__blank"><img alt="SpringBoot-2.7" src="https://img.shields.io/badge/SpringBoot-2.7-blue.svg"></a>
<a href="https://gitee.com/thinkgem/jeesite4/stargazers" target="__blank"><img alt="star" src="https://gitee.com/thinkgem/jeesite4/badge/star.svg?theme=dark"></a>
<a href="https://gitee.com/thinkgem/jeesite4/members" target="__blank"><img alt="fork" src="https://gitee.com/thinkgem/jeesite4/badge/fork.svg?theme=dark"></a>
@@ -28,21 +28,27 @@
## 平台介绍
JeeSite 快速开发平台,不仅仅是一个后台开发框架,它是一个企业级快速开发解决方案,后端基于经典组合 Spring Boot、Shiro、MyBatis前端采用 Beetl、Bootstrap、AdminLTE 经典开发模式,或者分离版 Vue3、Vite、Ant Design Vue、TypeScript、Vben Admin 最先进技术栈。提供在线代码生成功能可自动创建业务模块工程和微服务模块工程自动生成前端代码和后端代码包括功能模块如组织机构、角色用户、菜单及按钮授权、数据权限、系统参数、内容管理、工作流等。采用松耦合设计微内核和插件架构模块增减便捷界面无刷新一键换肤众多账号安全设置密码策略文件在线预览消息推送多元化第三方登录在线定时任务配置支持集群支持SAAS支持多数据源支持读写分离、分库分表支持微服务应用。
JeeSite 快速开发平台,不仅仅是一个后台开发框架,它是一个企业级快速开发解决方案,后端基于经典组合 Spring Boot、Shiro、MyBatis前端采用 Beetl、Bootstrap、AdminLTE 经典开发模式,或者分离版 Vue3、Vite、Ant Design Vue、TypeScript、Vben Admin 最先进技术栈。
JeeSite 快速开发平台的主要目的是能够让初级的研发人员快速的开发出复杂的业务功能,中高级人员有时间做一些更有用的事情。让开发者注重专注业务,其余有平台来封装技术细节,降低技术难度,从而节省人力成本,缩短项目周期,提高软件安全质量
提供在线代码生成功能,可自动创建业务模块工程和微服务模块工程,自动生成前端代码和后端代码;包括功能模块如:组织机构、角色用户、菜单及按钮授权、数据权限、系统参数、内容管理、工作流等
JeeSite 自 2013 年发布以来已被广大爱好者用到了企业、政府、医疗、金融、互联网等各个领域中JeeSite 架构精良、易于扩展、大众思维的设计模式、工匠精神打磨每一个细节,深入开发者的内心,并荣获开源中国《最受欢迎中国开源软件》奖杯,期间也帮助了不少刚毕业的大学生,教师作为入门教材,快速的去实践
采用松耦合设计微内核和插件架构模块增减便捷界面细节到位一键换肤众多账号安全设置密码策略文件在线预览消息推送多元化第三方登录在线定时任务配置支持集群支持SAAS支持多数据源支持读写分离、分库分表支持微服务应用
JeeSite4 的升级,作者结合了多年总结和经验,以及各方面的应用案例,对架构完成了一次全部重构,也纳入很多新的思想。不管是从开发者模式、底层架构、逻辑处理还是到用户界面,用户交互体验上都有很大的进步,在不忘学习成本、提高开发效率的情况下,安全方面也做和很多工作,包括:身份认证、密码策略、安全审计、日志收集等众多安全选项供你选择。努力为大中小微企业打造全方位企业级快速开发解决方案
主要目的是能够让初级的研发人员快速的开发出复杂的业务功能,中高级人员有时间做一些更有用的事情。让开发者注重专注业务,其余有平台来封装技术细节,降低技术难度,从而节省人力成本,缩短项目周期,提高软件安全质量
JeeSite 自 2013 年发布以来已被广大爱好者用到了企业、政府、医疗、金融、互联网等各个领域中,拥有:精良架构、易于扩展、大众思维的设计模式,工匠精神,用心打磨每一个细节,深入开发者的内心,并荣获开源中国《最受欢迎中国开源软件》多次奖项,期间也帮助了不少刚毕业的大学生,教师作为入门教材,快速的去实践。
2019 年换代升级,作者结合了多年总结和经验,以及各方面的应用案例,对架构完成了一次全部重构,也纳入很多新的思想。不管是从开发者模式、底层架构、逻辑处理还是到用户界面,用户交互体验上都有很大的进步,在不忘学习成本、提高开发效率的情况下,安全方面也做和很多工作,包括:身份认证、密码策略、安全审计、日志收集等众多安全选项供您选择。努力为大中小微企业打造全方位企业级快速开发解决方案。
2021 年终发布 Vue3 的前后分离版本,使得 JeeSite 拥有同一个后台服务 Web 来支撑分离版和全栈版两套前端技术栈。
## 平台优势
JeeSite 整体架构清晰、稳定技术先进、源代码书写规范、经典技术会的人多、易于维护、易于扩展、安全稳定。
JeeSite 非常易于二次开发,可控性高,整体架构清晰、技术稳定而先进、源代码书写规范、经典技术会的人多、易于维护、易于扩展、安全稳定。
JeeSite 功能全,知识点非常多,也非常少。因为她使用的都是一些通用的技术,通俗的设计风格,大多数基础知识点多数人都能掌握,所以每一个 JeeSite 的功能点都非常容易掌握。只要学会使用这些功能和组件的应用,就可以顺利的完成系统开发了。
JeeSite 功能全,知识点非常多,也非常少。因为她使用的都是一些通用的技术,通俗的设计风格,大多数基础知识点多数人都能掌握,所以每一个 JeeSite 的功能点都非常容易掌握。只要学会使用这些功能和组件的应用,就可以顺利的完成系统开发了。
JeeSite 是一个低代码开发平台,具有较高的封装度、扩展性,封装不是限制去做一些事情而是在便捷的同时也具有较好的扩展性在不具备一些功能的情况下JeeSite 提供了扩展接口,提供了原生调用方法。
JeeSite 是一个低代码开发平台,具有较高的封装度、扩展性,封装不是限制去做一些事情而是在便捷的同时也具有较好的扩展性在不具备一些功能的情况下JeeSite 提供了扩展接口,提供了原生调用方法。
大家都在用 Spring也在学习 Spring 的优点Spring 提供了较好的扩展性,可又有多少人去修改它的源代码呢,退一步说,大家去修改了 Spring 的源码反而会对未来升级造成很大困扰您说不是呢这样的例子很多所以不要纠结我们非常注重这一点JeeSite 也一样具备强大的扩展性。
@@ -51,21 +57,23 @@ JeeSite 是一个低代码开发平台,具有较高的封装度、扩展性,
* 至今 JeeSite 平台架构已经非常稳定。
* JeeSite 精益求精,用心打磨每一个细节。
* JeeSite 是一个专业的平台,是一个让你使用放心的平台。
* 社区版基于 Apache License 2.0 开源协议,永久免费使用。
### 架构特点及安全方面的优势:<https://jeesite.com/docs/feature/>
## 技术选型
* 主框架Spring Boot 2.7、Spring Framework 5.3、Apache Shiro 1.11、J2Cache
* 主框架Spring Boot 2.7、Spring Framework 5.3、Apache Shiro 1.12、J2Cache
* 持久层Apache MyBatis 3.5、Hibernate Validator 6.2、Alibaba Druid 1.2
* 视图层Spring MVC 5.3、Beetl 3.10替换JSP、Bootstrap 3.3、AdminLTE 2.4
* 前端组件jQuery 3.5、jqGrid 4.7、layer 3.5、zTree 3.5、jQuery Validation
* 分离前端版Node.js、TypeScript、Vue3、Vite、Ant Design Vue3、Vue Vben Admin
* 前端组件jQuery 3.7、jqGrid 4.7、layer 3.5、zTree 3.5、jQuery Validation
* 分离前端版Node.js、TypeScript、Vue3、Vite、Ant Design Vue、Vue Vben Admin
* 工作流引擎Flowable 6.6、符合 BPMN 规范、在线流程设计器、中国式流程、退回、撤回、自由流
* Bootstrap 版 支持 IE9 及以上版本及其他所有现代浏览器,如:谷歌、火狐、国产浏览器 等
* Vue3 版 支持现代浏览器,如:谷歌 Chrome 86+、火狐、国产浏览器 等
* 技术选型(详细):<http://jeesite.com/docs/technology/>
* JeeSite Vue<https://gitee.com/thinkgem/jeesite-vue>
* JeeSite Vue 版本<https://gitee.com/thinkgem/jeesite-vue>
* Spring Boot 3.x 版本:<https://gitee.com/thinkgem/jeesite4/tree/v5.springboot3>
## 更多介绍
@@ -77,50 +85,56 @@ JeeSite 是一个低代码开发平台,具有较高的封装度、扩展性,
## 生态系统
* 分布式微服务Spring Cloud<https://gitee.com/thinkgem/jeesite4-cloud>
* 分布式微服务Spring Cloud<https://gitee.com/thinkgem/jeesite-cloud>
* Flowable业务流程引擎BPM<http://jeesite.com/docs/bpm/>
* JFlow工作流引擎<https://gitee.com/thinkgem/jeesite4-jflow> <http://ccflow.org>
* 内容管理模块CMS<https://gitee.com/thinkgem/jeesite4/tree/v5.3/modules/cms>
* 手机端移动端:<https://gitee.com/thinkgem/jeesite4-uniapp>
* JFlow工作流引擎<https://gitee.com/thinkgem/jeesite-jflow>
* 多站点内容管理模块CMS<https://jeesite.com/docs/cms/>
* 手机端移动端:<https://gitee.com/thinkgem/jeesite-uniapp>
* PC客户端程序<https://gitee.com/thinkgem/jeesite-client>
* Vue3分离版本<https://gitee.com/thinkgem/jeesite-vue>
* JeeSite统一认证<https://jeesite.com/docs/oauth2-server>
* MybatisPlus: <https://gitee.com/thinkgem/jeesite-mybatisplus>
* Magic接口快速开发<https://gitee.com/thinkgem/jeesite-magic-api>
* 内外网中间件:<https://my.oschina.net/thinkgem/blog/4624519>
## 快速体验
### 在线演示
1. 地址:<http://demo.jeesite.com/>
1. 全栈版地址:<http://vue.jeesite.com/js>
2. Vue3分离版地址<http://vue.jeesite.com>
### 本地运行
1. 环境准备:`JDK 1.8 or 11、17``Maven 3.6+`、使用 `MySQL 5.7 or 8.0` 数据库、[其它数据库](https://jeesite.com/docs/technology/#_8、已支持数据库)
2. 下载源码:<https://gitee.com/thinkgem/jeesite4/repository/archive/v5.3.zip> 并解压
2. 下载源码:<https://gitee.com/thinkgem/jeesite4/repository/archive/v5.7.zip> 并解压
3. 打开文件:`/web/src/main/resources/config/application.yml` 配置JDBC连接
4. 执行脚本:`/web/bin/init-data.bat` 初始化数据库
5. 执行脚本:`/web/bin/run-tomcat.bat` 启动服务即可
6. 浏览器访问:<http://127.0.0.1:8980/js/> 账号 system 密码 admin
6. 浏览器访问:<http://127.0.0.1:8980/js> 账号 system 密码 admin
7. 部署常见问题:<https://jeesite.com/docs/faq/>
8. 分离端安装:<https://jeesite.com/docs/vue-install-deploy/>
### 快速运行
1. 环境准备:`JDK 1.8 or 11、17``Maven 3.6+`、无需准备数据库(使用内嵌 H2 DB
2. 下载源码:<https://gitee.com/thinkgem/jeesite4/repository/archive/v5.3.zip> 并解压
1. 环境准备:`JDK 1.8 or 11、17``Maven 3.6+`、无需准备数据库(使用内嵌 H2 DB、Vue资源包
2. 下载源码:<https://gitee.com/thinkgem/jeesite4/repository/archive/v5.7.zip> 并解压
3. 执行脚本:`/web-fast/bin/run-tomcat.bat` 启动服务即可(自动初始化库)
4. 浏览器访问<http://127.0.0.1:8980/js/> 账号 system 密码 admin
5. 部署常见问题<https://jeesite.com/docs/faq/>
8. 分离端安装:<https://jeesite.com/docs/vue-install-deploy/>
4. 全栈版本地址<http://127.0.0.1:8980/a/login>
5. Vue分离版本地址<http://127.0.0.1:8980/vue/login>
6. 默认超级管理员账号system 密码 admin
7. 部署常见问题:<https://jeesite.com/docs/faq/>
### 容器运行
- 拉取 Docker 镜像:
```
- 拉取 Docker 镜像演示使用JeeSite版本较久
```sh
docker pull thinkgem/jeesite-web
```
- 启动脚本:
```
docker run -d -p 8980:8980 --name jeesite-web -v /data:/data \
thinkgem/jeesite-web && docker logs -f jeesite-web
```sh
docker run --name jeesite-web -p 8980:8980 -d --restart unless-stopped \
-v ~/:/data thinkgem/jeesite-web && docker logs -f jeesite-web
```
- 浏览器访问:<http://127.0.0.1:8980/js/> 账号 system 密码 admin
- 分离端安装:<https://jeesite.com/docs/vue-install-deploy/>
@@ -195,7 +209,7 @@ thinkgem/jeesite-web && docker logs -f jeesite-web
5. 任何基于本软件而产生的一切法律纠纷和责任,均于我司无关。
6. 如果你对本软件有改进,希望可以贡献给我们,共同进步。
7. 本项目已申请软件著作权,请尊重开源,感谢阅读。
8. 本版本无用户数限制,无在线人数限制。
8. 无用户数限制,无在线人数限制,放心使用
## 技术服务与支持

View File

@@ -6,12 +6,15 @@ rem *
rem * Author: ThinkGem@163.com
rem */
echo.
echo [<5B><>Ϣ] <20><><EFBFBD>𹤳̰汾<EFBFBD><EFBFBD>Nexus<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
echo [<5B><>Ϣ] <20><><EFBFBD>𹤳̵<EFBFBD>Maven<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
echo.
%~d0
cd %~dp0
call mvn -v
echo.
cd ..
call mvn clean deploy -Dmaven.test.skip=true -Pdeploy

View File

@@ -4,10 +4,12 @@
# * No deletion without permission, or be held responsible to law.
# *
# * Author: ThinkGem@163.com
# *
# */
echo ""
echo "[信息] 部署工程版本到Nexus服务器。"
echo "[信息] 部署工程到Maven服务器。"
echo ""
mvn -v
echo ""
cd ..

View File

@@ -12,6 +12,9 @@ echo.
%~d0
cd %~dp0
call mvn -v
echo.
cd ..
call mvn clean install -Dmaven.test.skip=true -Ppackage

View File

@@ -4,10 +4,12 @@
# * No deletion without permission, or be held responsible to law.
# *
# * Author: ThinkGem@163.com
# *
# */
echo ""
echo "[信息] 打包Web工程,生成war/jar包文件。"
echo "[信息] 打包安装工程生成jar包文件。"
echo ""
mvn -v
echo ""
cd ..

View File

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

View File

@@ -35,9 +35,9 @@ import java.util.regex.Pattern;
* @version 2022-2-17
*/
public class EncodeUtils {
public static final String UTF_8 = "UTF-8";
private static final Logger logger = LoggerFactory.getLogger(EncodeUtils.class);
private static final char[] BASE62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".toCharArray();
@@ -65,7 +65,7 @@ public class EncodeUtils {
public static String encodeBase64(byte[] input) {
return new String(Base64.encodeBase64(input));
}
/**
* Base64编码.
*/
@@ -97,7 +97,7 @@ public class EncodeUtils {
throw ExceptionUtils.unchecked(e);
}
}
/**
* Base64解码.
*/
@@ -152,14 +152,14 @@ public class EncodeUtils {
}
/**
* URL 编码, Encode默认为UTF-8.
* URL 编码, Encode默认为UTF-8.
*/
public static String encodeUrl(String part) {
return encodeUrl(part, EncodeUtils.UTF_8);
}
/**
* URL 编码, Encode默认为UTF-8.
* URL 编码, Encode默认为UTF-8.
*/
public static String encodeUrl(String part, String encoding) {
if (part == null){
@@ -173,14 +173,14 @@ public class EncodeUtils {
}
/**
* URL 解码, Encode默认为UTF-8.
* URL 解码, Encode默认为UTF-8.
*/
public static String decodeUrl(String part) {
return decodeUrl(part, EncodeUtils.UTF_8);
}
/**
* URL 解码, Encode默认为UTF-8.
* URL 解码, Encode默认为UTF-8.
*/
public static String decodeUrl(String part, String encoding) {
if (part == null){
@@ -192,9 +192,9 @@ public class EncodeUtils {
throw ExceptionUtils.unchecked(e);
}
}
/**
* URL 解码(两次), Encode默认为UTF-8.
* URL 解码(两次), Encode默认为UTF-8.
*/
public static String decodeUrl2(String part) {
return decodeUrl(decodeUrl(part));
@@ -207,7 +207,7 @@ public class EncodeUtils {
Pattern.compile("\\s*on[a-z]+\\s*=\\s*(\"[^\"]+\"|'[^']+'|[^\\s]+)\\s*(?=>)", Pattern.CASE_INSENSITIVE),
Pattern.compile("(eval\\((.*?)\\)|xpression\\((.*?)\\))", Pattern.CASE_INSENSITIVE),
Pattern.compile("^(javascript:|vbscript:)", Pattern.CASE_INSENSITIVE)
);
);
/**
* XSS 非法字符过滤,内容以<!--HTML-->开头的用以下规则(保留标签)
@@ -216,12 +216,16 @@ public class EncodeUtils {
public static String xssFilter(String text) {
return xssFilter(text, null);
}
/**
* XSS 非法字符过滤,内容以<!--HTML-->开头的用以下规则(保留标签)
* @author ThinkGem
*/
public static String xssFilter(String text, HttpServletRequest request) {
request = (request != null ? request : ServletUtils.getRequest());
if (request != null && StringUtils.containsAny(request.getRequestURI(), ServletUtils.XSS_FILE_EXCLUDE_URI)) {
return text;
}
String oriValue = StringUtils.trim(text);
if (text != null){
String value = oriValue;
@@ -232,39 +236,37 @@ public class EncodeUtils {
}
}
// 如果开始不是HTMLXMLJOSN格式则再进行HTML的 "、<、> 转码。
if (!StringUtils.startsWithIgnoreCase(value, "<!--HTML-->") // HTML
&& !StringUtils.startsWithIgnoreCase(value, "<?xml ") // XML
&& !StringUtils.contains(value, "id=\"FormHtml\"") // JFlow
if (!StringUtils.startsWithIgnoreCase(value, "<!--HTML-->") // HTML
&& !StringUtils.startsWithIgnoreCase(value, "<?xml ") // XML
&& !StringUtils.contains(value, "id=\"FormHtml\"") // JFlow
&& !(StringUtils.startsWith(value, "{") && StringUtils.endsWith(value, "}")) // JSON Object
&& !(StringUtils.startsWith(value, "[") && StringUtils.endsWith(value, "]")) // JSON Array
&& !(StringUtils.containsAny((request != null ? request : ServletUtils.getRequest())
.getRequestURI(), "/ureport/", "/visual/")) // UReport、Visual
){
){
StringBuilder sb = new StringBuilder();
for (int i = 0; i < value.length(); i++) {
char c = value.charAt(i);
switch (c) {
case '>':
sb.append("");
break;
case '<':
sb.append("");
break;
case '\'':
sb.append("");
break;
case '\"':
sb.append("");
break;
// case '&':
// sb.append("");
// break;
// case '#':
// sb.append("");
// break;
default:
sb.append(c);
break;
case '>':
sb.append("");
break;
case '<':
sb.append("");
break;
case '\'':
sb.append("");
break;
case '\"':
sb.append("");
break;
// case '&':
// sb.append("");
// break;
// case '#':
// sb.append("");
// break;
default:
sb.append(c);
break;
}
}
value = sb.toString();
@@ -277,12 +279,12 @@ public class EncodeUtils {
}
return null;
}
// 预编译SQL过滤正则表达式
private static Pattern sqlPattern = Pattern.compile(
"(?:')|(?:--)|(/\\*(?:.|[\\n\\r])*?\\*/)|((extractvalue|updatexml|if|mid|database|rand|user)([\\s]*?)\\()|"
+ "(\\b(select|update|and|or|delete|insert|trancate|char|into|substr|ascii|declare|exec|count|master|into|"
+ "drop|execute|case when|sleep|union|load_file)\\b)",
+ "(\\b(select|update|and|or|delete|insert|trancate|char|into|substr|ascii|declare|exec|count|master|into|"
+ "drop|execute|case when|sleep|union|load_file)\\b)",
Pattern.CASE_INSENSITIVE);
private static Pattern orderByPattern = Pattern.compile("[a-z0-9_\\.\\, ]*", Pattern.CASE_INSENSITIVE);
@@ -293,6 +295,7 @@ public class EncodeUtils {
public static String sqlFilter(String text){
return sqlFilter(text, "common");
}
/**
* SQL过滤防止注入传入参数输入有select相关代码替换空。
* @author ThinkGem
@@ -319,7 +322,7 @@ public class EncodeUtils {
}
return null;
}
// public static void main(String[] args) {
// xssFilter("1 你好 <script>alert(document.cookie)</script>我还在。");
// xssFilter("2 你好 <strong>加粗文字</strong>我还在。");
@@ -353,5 +356,5 @@ public class EncodeUtils {
// sqlFilter("5 if(1=2,1,SLEEP(10)), if(mid(database(),{},1)=\\\"{}\\\",a.id,a.login_name)", "orderBy");
// sqlFilter("6 a.audit_result asc, b.audit_result2 desc, b.AuditResult3 desc", "orderBy");
// }
}

View File

@@ -391,6 +391,18 @@ public class ListUtils {
pageNo++;
}
}
/**
* 列表分页方法
* @param list 源数据
* @param pageNo 当前页码
* @param pageSize 每页显示条数
* @author ThinkGem
*/
public static <T> List<T> getPageList(List<T> list, int pageNo, int pageSize) {
int totalPage = (list.size() + pageSize - 1) / pageSize;
return getPageList(list, pageNo, pageSize, totalPage);
}
/**
* 列表分页方法

View File

@@ -24,11 +24,18 @@ import java.io.IOException;
public class ImageUtils {
private static final Logger logger = LoggerFactory.getLogger(ImageUtils.class);
/**
* 缩略图生成,处理一些较大的图片,防止占用太多的网络资源
*/
public static void thumbnails(File imageFile, int maxWidth, int maxHeight, String outputFormat){
thumbnails(imageFile, maxWidth, maxHeight, outputFormat, imageFile);
}
/**
* 缩略图生成,处理一些较大的图片,防止占用太多的网络资源
*/
public static void thumbnails(File imageFile, int maxWidth, int maxHeight, String outputFormat, File targetFile){
if (imageFile == null || !imageFile.exists() || (maxWidth <= 0 && maxHeight <= 0)){
return;
}
@@ -58,7 +65,7 @@ public class ImageUtils {
if (StringUtils.isNotBlank(outputFormat)){
bilder.outputFormat(outputFormat);
}
bilder.toFile(imageFile);
bilder.toFile(targetFile);
}
}catch(IOException e){
logger.error("图片压缩失败:" + imageFile.getAbsoluteFile(), e);

View File

@@ -779,12 +779,12 @@ public class FileUtils extends org.apache.commons.io.FileUtils {
String p = StringUtils.replace(path, WIN_SEPARATOR, SEPARATOR);
p = StringUtils.join(StringUtils.split(p, SEPARATOR), SEPARATOR);
if (!StringUtils.startsWithAny(p, SEPARATOR) && StringUtils.startsWithAny(path, WIN_SEPARATOR, SEPARATOR)){
p += SEPARATOR;
p = SEPARATOR + p;
}
if (!StringUtils.endsWithAny(p, SEPARATOR) && StringUtils.endsWithAny(path, WIN_SEPARATOR, SEPARATOR)){
p = p + SEPARATOR;
}
if (path != null && path.startsWith(SEPARATOR)){
if (path != null && path.startsWith(SEPARATOR) && !p.startsWith(SEPARATOR)){
p = SEPARATOR + p; // linux下路径
}
return p;

View File

@@ -40,9 +40,10 @@ public class PropertyLoader implements org.springframework.boot.env.PropertySour
if (!isLoadJeeSitePropertySource) {
isLoadJeeSitePropertySource = true;
try {
ParserConfig.getGlobalInstance().setSafeMode(true); // 开启 FastJSON 安全模式
} catch (Exception ignored) {
// 兼容 fastjson2 的调用,不返回异常
// 默认开启 FastJSON 1.x 的,安全模式
ParserConfig.getGlobalInstance().setSafeMode(true);
} catch (Throwable ignored) {
// 兼容 FastJSON 2.x 的调用,忽略异常
}
Properties properties = PropertiesUtils.getInstance().getProperties();
propertySources.add(new OriginTrackedMapPropertySource("jeesite", properties));

View File

@@ -66,9 +66,9 @@ public class ByteUtils {
private static String format(double size, String type) {
int precision = 0;
if(size * 1000 % 10 > 0) {
/*if(size * 1000 % 10 > 0) {
precision = 3;
} else if(size * 100 % 10 > 0) {
} else */if(size * 100 % 10 > 0) {
precision = 2;
} else if(size * 10 % 10 > 0) {
precision = 1;

View File

@@ -5,11 +5,11 @@
*/
package com.jeesite.common.lang;
import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;
import java.io.PrintWriter;
import java.io.StringWriter;
import javax.servlet.http.HttpServletRequest;
/**
* 关于异常的工具类.
* @author calvin
@@ -26,8 +26,8 @@ public class ExceptionUtils {
Throwable ex = null;
if (request.getAttribute("exception") != null) {
ex = (Throwable) request.getAttribute("exception");
} else if (request.getAttribute("javax.servlet.error.exception") != null) {
ex = (Throwable) request.getAttribute("javax.servlet.error.exception");
} else if (request.getAttribute(RequestDispatcher.ERROR_EXCEPTION) != null) {
ex = (Throwable) request.getAttribute(RequestDispatcher.ERROR_EXCEPTION);
}
return ex;
}

View File

@@ -14,7 +14,7 @@ import java.util.Date;
public class TimeUtils {
public static final String[] CN = new String[] {"毫秒", "", "", "", ""};
public static final String[] EN = new String[] {" millisecond ", " second ", " minute ", " hour ", " day "};
public static final String[] EN = new String[] {"ms", " second ", " minute ", " hour ", " day "};
public static final String[] AGO_CN = new String[] {"刚刚", "秒前", "分钟前", "小时前", "天前"};
public static final String[] AGO_EN = new String[] {"just now", " seconds ago", " minutes ago", " hours ago", " days ago"};

View File

@@ -7,13 +7,16 @@ package com.jeesite.common.mapper;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonParser.Feature;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.introspect.Annotated;
import com.fasterxml.jackson.databind.introspect.AnnotatedMethod;
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.util.JSONPObject;
import com.jeesite.common.codec.EncodeUtils;
import com.jeesite.common.collect.ListUtils;
import com.jeesite.common.io.PropertiesUtils;
import com.jeesite.common.lang.DateUtils;
@@ -31,16 +34,15 @@ import java.util.Map;
import java.util.TimeZone;
/**
* 简单封装Jackson实现JSON String<->Java Object的Mapper.
* 封装不同的输出风格, 使用不同的builder函数创建实例.
* 封装 Jackson实现 JSON StringJava Object 互转
* @author ThinkGem
* @version 2016-3-2
* @version 2023-09-26
*/
public class JsonMapper extends ObjectMapper {
private static final long serialVersionUID = 1L;
private static Logger logger = LoggerFactory.getLogger(JsonMapper.class);
private static final Logger logger = LoggerFactory.getLogger(JsonMapper.class);
/**
* 当前类的实例持有者(静态内部类,延迟加载,懒汉式,线程安全的单例模式)
@@ -48,7 +50,7 @@ public class JsonMapper extends ObjectMapper {
private static final class JsonMapperHolder {
private static final JsonMapper INSTANCE = new JsonMapper();
}
public JsonMapper() {
// Spring ObjectMapper 初始化配置,支持 @JsonView
new Jackson2ObjectMapperBuilder().configure(this);
@@ -59,9 +61,30 @@ public class JsonMapper extends ObjectMapper {
// 允许不带引号的字段名称
this.configure(Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
// 设置默认时区
this.setDefaultTimeZone();
// 设置默认日期格式
this.setDefaultDateFormat();
// 遇到空值处理为空串
this.enabledNullValueToEmpty();
// 设置输入时忽略在JSON字符串中存在但Java对象实际没有的属性
this.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
}
/**
* 开启日期类型默认格式化
* @author ThinkGem
*/
public JsonMapper setDefaultTimeZone(){
this.setTimeZone(TimeZone.getTimeZone(PropertiesUtils.getInstance()
.getProperty("lang.defaultTimeZone", "GMT+08:00")));
// 设置默认日期格式
return this;
}
/**
* 开启日期类型默认格式化
* @author ThinkGem
*/
public JsonMapper setDefaultDateFormat(){
this.setDateFormat(new SimpleDateFormat(PropertiesUtils.getInstance()
.getProperty("web.json.defaultDateFormat", "yyyy-MM-dd HH:mm:ss")));
this.setAnnotationIntrospector(new JacksonAnnotationIntrospector() {
@@ -74,8 +97,7 @@ public class JsonMapper extends ObjectMapper {
if (jf != null) {
return new JsonSerializer<Date>(){
@Override
public void serialize(Date value, JsonGenerator jgen,
SerializerProvider provider) throws IOException, JsonProcessingException {
public void serialize(Date value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
if (value != null){
jgen.writeString(DateUtils.formatDate(value, jf.pattern()));
}
@@ -86,27 +108,39 @@ public class JsonMapper extends ObjectMapper {
return super.findSerializer(a);
}
});
// 设置输入时忽略在JSON字符串中存在但Java对象实际没有的属性
this.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
// 遇到空值处理为空串
return this;
}
/**
* 开启将空值转换为空字符串
* @author ThinkGem
*/
public JsonMapper enabledNullValueToEmpty(){
this.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>(){
@Override
public void serialize(Object value, JsonGenerator jgen,
SerializerProvider provider) throws IOException, JsonProcessingException {
public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
jgen.writeString(StringUtils.EMPTY);
}
});
// // 进行HTML解码先注释掉否则会造成XSS攻击比如菜单名称里输入<script>alert(123)</script>转josn后就会还原这个编码 ,并在浏览器中运行)。
// this.registerModule(new SimpleModule().addSerializer(String.class, new JsonSerializer<String>(){
// @Override
// public void serialize(String value, JsonGenerator jgen,
// SerializerProvider provider) throws IOException,
// JsonProcessingException {
// if (value != null){
// jgen.writeString(StringEscapeUtils.unescapeHtml4(value));
// }
// }
// }));
return this;
}
/**
* 开启 XSS 过滤器
* @author ThinkGem
*/
public JsonMapper enabledXssFilter(){
this.registerModule(new SimpleModule().addDeserializer(String.class, new JsonDeserializer<String>() {
@Override
public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
String text = p.getText();
if (text != null) {
return EncodeUtils.xssFilter(text);
}
return null;
}
}));
return this;
}
/**

View File

@@ -93,7 +93,7 @@ public class IpUtils {
}
public static byte[] textToNumericFormatV4(String paramString) {
if (paramString.length() == 0) {
if (paramString.isEmpty()) {
return null;
}
byte[] arrayOfByte = new byte[4];

View File

@@ -1,5 +1,7 @@
package com.jeesite.common.utils;
import org.apache.commons.lang3.StringUtils;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
@@ -7,8 +9,6 @@ import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
/**
* 身份证工具类
*
@@ -152,7 +152,7 @@ public class IdcardUtils extends StringUtils {
int iSum17 = getPowerSum(iCard);
// 获取校验位
String sVal = getCheckCode18(iSum17);
if (sVal.length() > 0) {
if (!sVal.isEmpty()) {
idCard18 += sVal;
} else {
return null;
@@ -205,7 +205,7 @@ public class IdcardUtils extends StringUtils {
int iSum17 = getPowerSum(iCard);
// 获取校验位
String val = getCheckCode18(iSum17);
if (val.length() > 0) {
if (!val.isEmpty()) {
if (val.equalsIgnoreCase(code18)) {
bTrue = true;
}

View File

@@ -38,6 +38,9 @@ public class ServletUtils {
private static final String[] STATIC_FILE = StringUtils.splitComma(PROPS.getProperty("web.staticFile"));
private static final String[] STATIC_FILE_EXCLUDE_URI = StringUtils.splitComma(PROPS.getProperty("web.staticFileExcludeUri"));
// XSS 过滤器要排除的URI地址
public static final String[] XSS_FILE_EXCLUDE_URI = StringUtils.splitComma(PROPS.getProperty("web.xssFilterExcludeUri"));
// AJAX 请求参数和请求头名
public static final String AJAX_PARAM_NAME = PROPS.getProperty("web.ajaxParamName", "__ajax");
public static final String AJAX_HEADER_NAME = PROPS.getProperty("web.ajaxHeaderName", "x-ajax");
@@ -125,12 +128,8 @@ public class ServletUtils {
e.printStackTrace();
}
}
if (STATIC_FILE_EXCLUDE_URI != null){
for (String s : STATIC_FILE_EXCLUDE_URI){
if (StringUtils.contains(uri, s)){
return false;
}
}
if (StringUtils.containsAny(uri, STATIC_FILE_EXCLUDE_URI)) {
return false;
}
if (StringUtils.endsWithAny(uri, STATIC_FILE)){
return true;

View File

@@ -187,6 +187,8 @@ a, a:hover, a:active, a:focus, .form-unit, th[aria-selected=true] .ui-jqgrid-sor
.open>.dropdown-toggle.btn-primary:hover, .layui-layer-btn .layui-layer-btn0,
.select2-container--default .select2-selection--multiple .select2-selection__choice,
.select2-container--default .select2-results__option--highlighted[aria-selected],
.pagination>.active>a, .pagination>.active>a:focus, .pagination>.active>a:hover,
.pagination>.active>span, .pagination>.active>span:focus, .pagination>.active>span:hover,
.wup_container .placeholder .webuploader-pick {background-color:#1890ff!important;border-color:#1890ff;}
.form-unit, th[aria-selected=true] .ui-jqgrid-sortable {color:#1890ff;}
.form-unit {border-bottom:1px solid #eee;}

View File

@@ -169,7 +169,7 @@ a, a:hover, a:active, a:focus, .form-unit, th[aria-selected=true] .ui-jqgrid-sor
/* 页签添加内边距 */
.content-wrapper, .tabpanel_content, .tabpanel_content .html_content, body {background-color:#f0f2f5;}
.box-main, .nav-main, .ui-layout-pane, iframe {border-radius:5px;}
.tabpanel_content .html_content {padding:14px 14px 13px 15px;}
.tabpanel_content .html_content {padding:13px 14px 13px 15px;}
.tabpanel_tab_content {border-bottom:0;}
.ui-layout-resizer {background:none;}
.content {padding:0!important}
@@ -209,6 +209,8 @@ a, a:hover, a:active, a:focus, .form-unit, th[aria-selected=true] .ui-jqgrid-sor
.open>.dropdown-toggle.btn-primary:hover, .layui-layer-btn .layui-layer-btn0,
.select2-container--default .select2-selection--multiple .select2-selection__choice,
.select2-container--default .select2-results__option--highlighted[aria-selected],
.pagination>.active>a, .pagination>.active>a:focus, .pagination>.active>a:hover,
.pagination>.active>span, .pagination>.active>span:focus, .pagination>.active>span:hover,
.wup_container .placeholder .webuploader-pick {background-color:#1890ff!important;border-color:#1890ff!important;}
.form-unit, th[aria-selected=true] .ui-jqgrid-sortable {color:#1890ff;}
.form-unit {border-bottom:1px solid #eee;}

View File

@@ -187,6 +187,8 @@ a, a:hover, a:active, a:focus, .form-unit, th[aria-selected=true] .ui-jqgrid-sor
.open>.dropdown-toggle.btn-primary:hover, .layui-layer-btn .layui-layer-btn0,
.select2-container--default .select2-selection--multiple .select2-selection__choice,
.select2-container--default .select2-results__option--highlighted[aria-selected],
.pagination>.active>a, .pagination>.active>a:focus, .pagination>.active>a:hover,
.pagination>.active>span, .pagination>.active>span:focus, .pagination>.active>span:hover,
.wup_container .placeholder .webuploader-pick {background-color:#1e5edb!important;border-color:#1e5edb!important;}
.form-unit, th[aria-selected=true] .ui-jqgrid-sortable {color:#1e5edb;}
.form-unit {border-bottom:1px solid #eee;}

View File

@@ -169,7 +169,7 @@ a, a:hover, a:active, a:focus, .form-unit, th[aria-selected=true] .ui-jqgrid-sor
/* 页签添加内边距 */
.content-wrapper, .tabpanel_content, .tabpanel_content .html_content, body {background-color:#f0f2f5;}
.box-main, .nav-main, .ui-layout-pane, iframe {border-radius:5px;}
.tabpanel_content .html_content {padding:14px 14px 13px 15px;}
.tabpanel_content .html_content {padding:13px 14px 13px 15px;}
.tabpanel_tab_content {border-bottom:0;}
.ui-layout-resizer {background:none;}
.content {padding:0!important}
@@ -209,6 +209,8 @@ a, a:hover, a:active, a:focus, .form-unit, th[aria-selected=true] .ui-jqgrid-sor
.open>.dropdown-toggle.btn-primary:hover, .layui-layer-btn .layui-layer-btn0,
.select2-container--default .select2-selection--multiple .select2-selection__choice,
.select2-container--default .select2-results__option--highlighted[aria-selected],
.pagination>.active>a, .pagination>.active>a:focus, .pagination>.active>a:hover,
.pagination>.active>span, .pagination>.active>span:focus, .pagination>.active>span:hover,
.wup_container .placeholder .webuploader-pick {background-color:#1e5edb!important;border-color:#1e5edb!important;}
.form-unit, th[aria-selected=true] .ui-jqgrid-sortable {color:#1e5edb;}
.form-unit {border-bottom:1px solid #eee;}

View File

@@ -167,7 +167,7 @@ a, a:hover, a:active, a:focus, .form-unit, th[aria-selected=true] .ui-jqgrid-sor
/* 页签添加内边距 */
.content-wrapper, .tabpanel_content, .tabpanel_content .html_content, body {background-color:#000;}
.box-main, .nav-main, .ui-layout-pane, iframe {border-radius:5px;}
.tabpanel_content .html_content {padding:14px 14px 13px 15px;}
.tabpanel_content .html_content {padding:13px 14px 13px 15px;}
.tabpanel_tab_content {border-bottom:0;}
.ui-layout-resizer {background:none;}
.content {padding:0!important}
@@ -222,7 +222,9 @@ a, a:hover, a:active, a:focus, .form-unit, th[aria-selected=true] .ui-jqgrid-sor
.open>.dropdown-toggle.btn-primary:hover, .layui-layer-btn .layui-layer-btn0,
.select2-container--default .select2-selection--multiple .select2-selection__choice,
.select2-container--default .select2-results__option--highlighted[aria-selected],
.wup_container .placeholder .webuploader-pick {background-color:#1e5edb!important;border-color:#1e5edb!important;}
.pagination>.active>a, .pagination>.active>a:focus, .pagination>.active>a:hover,
.pagination>.active>span, .pagination>.active>span:focus, .pagination>.active>span:hover,
.wup_container .placeholder .webuploader-pick {background-color:#3aa0ff!important;border-color:#3aa0ff!important;}
.form-unit, th[aria-selected=true] .ui-jqgrid-sortable {color:#2975bc;}
.form-unit {border-bottom:1px solid #4e4e4e;}

View File

@@ -156,4 +156,6 @@ th[aria-selected=true] .ui-jqgrid-sortable {color:#00a65a;}
.open>.dropdown-toggle.btn-primary:hover, .layui-layer-btn .layui-layer-btn0,
.select2-container--default .select2-selection--multiple .select2-selection__choice,
.select2-container--default .select2-results__option--highlighted[aria-selected],
.pagination>.active>a, .pagination>.active>a:focus, .pagination>.active>a:hover,
.pagination>.active>span, .pagination>.active>span:focus, .pagination>.active>span:hover,
.wup_container .placeholder .webuploader-pick {background-color:#00a65a!important;border-color:#00a65a;}

View File

@@ -141,4 +141,6 @@ th[aria-selected=true] .ui-jqgrid-sortable {color:#00a65a;}
.open>.dropdown-toggle.btn-primary:hover, .layui-layer-btn .layui-layer-btn0,
.select2-container--default .select2-selection--multiple .select2-selection__choice,
.select2-container--default .select2-results__option--highlighted[aria-selected],
.pagination>.active>a, .pagination>.active>a:focus, .pagination>.active>a:hover,
.pagination>.active>span, .pagination>.active>span:focus, .pagination>.active>span:hover,
.wup_container .placeholder .webuploader-pick {background-color:#00a65a!important;border-color:#00a65a;}

View File

@@ -156,4 +156,6 @@ th[aria-selected=true] .ui-jqgrid-sortable {color:#605ca8;}
.open>.dropdown-toggle.btn-primary:hover, .layui-layer-btn .layui-layer-btn0,
.select2-container--default .select2-selection--multiple .select2-selection__choice,
.select2-container--default .select2-results__option--highlighted[aria-selected],
.pagination>.active>a, .pagination>.active>a:focus, .pagination>.active>a:hover,
.pagination>.active>span, .pagination>.active>span:focus, .pagination>.active>span:hover,
.wup_container .placeholder .webuploader-pick {background-color:#605ca8!important;border-color:#605ca8;}

View File

@@ -141,4 +141,6 @@ th[aria-selected=true] .ui-jqgrid-sortable {color:#605ca8;}
.open>.dropdown-toggle.btn-primary:hover, .layui-layer-btn .layui-layer-btn0,
.select2-container--default .select2-selection--multiple .select2-selection__choice,
.select2-container--default .select2-results__option--highlighted[aria-selected],
.pagination>.active>a, .pagination>.active>a:focus, .pagination>.active>a:hover,
.pagination>.active>span, .pagination>.active>span:focus, .pagination>.active>span:hover,
.wup_container .placeholder .webuploader-pick {background-color:#605ca8!important;border-color:#605ca8;}

View File

@@ -156,4 +156,6 @@ th[aria-selected=true] .ui-jqgrid-sortable {color:#dd4b39;}
.open>.dropdown-toggle.btn-primary:hover, .layui-layer-btn .layui-layer-btn0,
.select2-container--default .select2-selection--multiple .select2-selection__choice,
.select2-container--default .select2-results__option--highlighted[aria-selected],
.pagination>.active>a, .pagination>.active>a:focus, .pagination>.active>a:hover,
.pagination>.active>span, .pagination>.active>span:focus, .pagination>.active>span:hover,
.wup_container .placeholder .webuploader-pick {background-color:#dd4b39!important;border-color:#dd4b39;}

View File

@@ -141,4 +141,6 @@ th[aria-selected=true] .ui-jqgrid-sortable {color:#dd4b39;}
.open>.dropdown-toggle.btn-primary:hover, .layui-layer-btn .layui-layer-btn0,
.select2-container--default .select2-selection--multiple .select2-selection__choice,
.select2-container--default .select2-results__option--highlighted[aria-selected],
.pagination>.active>a, .pagination>.active>a:focus, .pagination>.active>a:hover,
.pagination>.active>span, .pagination>.active>span:focus, .pagination>.active>span:hover,
.wup_container .placeholder .webuploader-pick {background-color:#dd4b39!important;border-color:#dd4b39;}

View File

@@ -156,4 +156,6 @@ th[aria-selected=true] .ui-jqgrid-sortable {color:#f39c12;}
.open>.dropdown-toggle.btn-primary:hover, .layui-layer-btn .layui-layer-btn0,
.select2-container--default .select2-selection--multiple .select2-selection__choice,
.select2-container--default .select2-results__option--highlighted[aria-selected],
.pagination>.active>a, .pagination>.active>a:focus, .pagination>.active>a:hover,
.pagination>.active>span, .pagination>.active>span:focus, .pagination>.active>span:hover,
.wup_container .placeholder .webuploader-pick {background-color:#f39c12!important;border-color:#f39c12;}

View File

@@ -141,4 +141,6 @@ th[aria-selected=true] .ui-jqgrid-sortable {color:#f39c12;}
.open>.dropdown-toggle.btn-primary:hover, .layui-layer-btn .layui-layer-btn0,
.select2-container--default .select2-selection--multiple .select2-selection__choice,
.select2-container--default .select2-results__option--highlighted[aria-selected],
.pagination>.active>a, .pagination>.active>a:focus, .pagination>.active>a:hover,
.pagination>.active>span, .pagination>.active>span:focus, .pagination>.active>span:hover,
.wup_container .placeholder .webuploader-pick {background-color:#f39c12!important;border-color:#f39c12;}

View File

@@ -1,5 +1,5 @@
/*!
* jQuery Migrate - v3.4.0 - 2022-03-24T16:30Z
* jQuery Migrate - v3.4.1 - 2023-02-23T15:31Z
* Copyright OpenJS Foundation and other contributors
*/
( function( factory ) {
@@ -24,7 +24,7 @@
} )( function( jQuery, window ) {
"use strict";
jQuery.migrateVersion = "3.4.0";
jQuery.migrateVersion = "3.4.1";
// Returns 0 if v1 == v2, -1 if v1 < v2, 1 if v1 > v2
function compareVersions( v1, v2 ) {
@@ -82,7 +82,7 @@ jQuery.migrateIsPatchEnabled = function( patchCode ) {
return !disabledPatches[ patchCode ];
};
/*( function() {
( function() {
// Support: IE9 only
// IE9 only creates console object when dev tools are first opened
@@ -91,9 +91,10 @@ jQuery.migrateIsPatchEnabled = function( patchCode ) {
return;
}
// Need jQuery 3.0.0+ and no older Migrate loaded
if ( !jQuery || !jQueryVersionSince( "3.0.0" ) ) {
window.console.log( "JQMIGRATE: jQuery 3.0.0+ REQUIRED" );
// Need jQuery 3.x-4.x and no older Migrate loaded
if ( !jQuery || !jQueryVersionSince( "3.0.0" ) ||
jQueryVersionSince( "5.0.0" ) ) {
window.console.log( "JQMIGRATE: jQuery 3.x-4.x REQUIRED" );
}
if ( jQuery.migrateWarnings ) {
window.console.log( "JQMIGRATE: Migrate plugin loaded multiple times" );
@@ -104,7 +105,7 @@ jQuery.migrateIsPatchEnabled = function( patchCode ) {
( jQuery.migrateMute ? "" : " with logging active" ) +
", version " + jQuery.migrateVersion );
} )();*/
} )();
var warnedAbout = {};
@@ -206,9 +207,9 @@ var findProp,
rattrHashTest = /\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/,
rattrHashGlob = /\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/g,
// Support: Android <=4.0 only
// Make sure we trim BOM and NBSP
rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;
// Require that the "whitespace run" starts from a non-whitespace
// to avoid O(N^2) behavior when the engine would try matching "\s+$" at each space position.
rtrim = /^[\s\uFEFF\xA0]+|([^\s\uFEFF\xA0])[\s\uFEFF\xA0]+$/g;
migratePatchFunc( jQuery.fn, "init", function( arg1 ) {
var args = Array.prototype.slice.call( arguments );
@@ -300,7 +301,7 @@ if ( jQueryVersionSince( "3.1.1" ) ) {
migratePatchAndWarnFunc( jQuery, "trim", function( text ) {
return text == null ?
"" :
( text + "" ).replace( rtrim, "" );
( text + "" ).replace( rtrim, "$1" );
}, "trim",
"jQuery.trim is deprecated; use String.prototype.trim" );
}
@@ -419,10 +420,24 @@ var oldRemoveAttr = jQuery.fn.removeAttr,
rmatchNonSpace = /\S+/g;
migratePatchFunc( jQuery.fn, "removeAttr", function( name ) {
var self = this;
var self = this,
patchNeeded = false;
jQuery.each( name.match( rmatchNonSpace ), function( _i, attr ) {
if ( jQuery.expr.match.bool.test( attr ) ) {
// Only warn if at least a single node had the property set to
// something else than `false`. Otherwise, this Migrate patch
// doesn't influence the behavior and there's no need to set or warn.
self.each( function() {
if ( jQuery( this ).prop( attr ) !== false ) {
patchNeeded = true;
return false;
}
} );
}
if ( patchNeeded ) {
migrateWarn( "removeAttr-bool",
"jQuery.fn.removeAttr no longer sets boolean properties: " + attr );
self.prop( attr, false );
@@ -470,7 +485,7 @@ function camelCase( string ) {
} );
}
var origFnCss,
var origFnCss, internalCssNumber,
internalSwapCall = false,
ralphaStart = /^[a-z]/,
@@ -552,8 +567,11 @@ if ( jQueryVersionSince( "3.4.0" ) && typeof Proxy !== "undefined" ) {
// https://github.com/jquery/jquery/blob/3.6.0/src/css.js#L212-L233
// This way, number values for the CSS properties below won't start triggering
// Migrate warnings when jQuery gets updated to >=4.0.0 (gh-438).
if ( jQueryVersionSince( "4.0.0" ) && typeof Proxy !== "undefined" ) {
jQuery.cssNumber = new Proxy( {
if ( jQueryVersionSince( "4.0.0" ) ) {
// We need to keep this as a local variable as we need it internally
// in a `jQuery.fn.css` patch and this usage shouldn't warn.
internalCssNumber = {
animationIterationCount: true,
columnCount: true,
fillOpacity: true,
@@ -574,16 +592,31 @@ if ( jQueryVersionSince( "4.0.0" ) && typeof Proxy !== "undefined" ) {
widows: true,
zIndex: true,
zoom: true
}, {
get: function() {
migrateWarn( "css-number", "jQuery.cssNumber is deprecated" );
return Reflect.get.apply( this, arguments );
},
set: function() {
migrateWarn( "css-number", "jQuery.cssNumber is deprecated" );
return Reflect.set.apply( this, arguments );
}
} );
};
if ( typeof Proxy !== "undefined" ) {
jQuery.cssNumber = new Proxy( internalCssNumber, {
get: function() {
migrateWarn( "css-number", "jQuery.cssNumber is deprecated" );
return Reflect.get.apply( this, arguments );
},
set: function() {
migrateWarn( "css-number", "jQuery.cssNumber is deprecated" );
return Reflect.set.apply( this, arguments );
}
} );
} else {
// Support: IE 9-11+
// IE doesn't support proxies, but we still want to restore the legacy
// jQuery.cssNumber there.
jQuery.cssNumber = internalCssNumber;
}
} else {
// Make `internalCssNumber` defined for jQuery <4 as well as it's needed
// in the `jQuery.fn.css` patch below.
internalCssNumber = jQuery.cssNumber;
}
function isAutoPx( prop ) {
@@ -610,7 +643,10 @@ migratePatchFunc( jQuery.fn, "css", function( name, value ) {
if ( typeof value === "number" ) {
camelName = camelCase( name );
if ( !isAutoPx( camelName ) && !jQuery.cssNumber[ camelName ] ) {
// Use `internalCssNumber` to avoid triggering our warnings in this
// internal check.
if ( !isAutoPx( camelName ) && !internalCssNumber[ camelName ] ) {
migrateWarn( "css-number",
"Number-typed values are deprecated for jQuery.fn.css( \"" +
name + "\", value )" );
@@ -979,4 +1015,4 @@ jQuery.Deferred.exceptionHook = oldDeferred.exceptionHook;
}
return jQuery;
} );
} );

File diff suppressed because one or more lines are too long

View File

@@ -72,7 +72,7 @@ html #layuicss-laydate{display: none; position: absolute; width: 1989px;}
.layui-laydate-content{position: relative; padding: 5px; -moz-user-select: none; -webkit-user-select: none; -ms-user-select: none;}
.layui-laydate-content table{border-collapse: collapse; border-spacing: 0;}
.layui-laydate-content th,
.layui-laydate-content td{width: 36px; height: 30px; padding: 5px; text-align: center;}
.layui-laydate-content td{width: 36px; height: 30px; padding: 5px; text-align: center; border-radius: 4px;}
.layui-laydate-content th{font-weight: 400;}
.layui-laydate-content td{position: relative; cursor: pointer;}
.laydate-day-mark{position: absolute; left: 0; top: 0; width: 100%; line-height: 30px; font-size: 12px; overflow: hidden;}
@@ -111,7 +111,7 @@ html #layuicss-laydate{display: none; position: absolute; width: 1989px;}
/* 默认简约主题 */
.layui-laydate, .layui-laydate-hint{border: 1px solid #d2d2d2; box-shadow: 0 2px 4px rgba(0,0,0,.12); background-color: #fff; color: #666;}
.layui-laydate, .layui-laydate-hint{border: 1px solid #d2d2d2; box-shadow: 0 2px 4px rgba(0,0,0,.12); background-color: #fff; color: #666; border-radius: 4px;}
.layui-laydate-header{border-bottom: 1px solid #e2e2e2;}
.layui-laydate-header i:hover,
.layui-laydate-header span:hover{color: #08c;}

View File

@@ -710,6 +710,7 @@ Class.pt.callback = function(){
var that = this, layero = that.layero, config = that.config;
that.openLayer();
if(config.success){
layero.find('.layui-layer-close').focus(); // 弹窗后首先关闭获取焦点,防止回车弹出多个
if(config.type == 2){
layero.find('iframe').on('load', function(){
config.success(layero, that.index);

View File

@@ -3,7 +3,7 @@ html #layuicss-layer{display:none;position:absolute;width:1989px;}
.layui-layer-shade, .layui-layer{position:fixed;_position:absolute;pointer-events:auto;}
.layui-layer-shade{top:0;left:0;width:100%;height:100%;_height:expression(document.body.offsetHeight+"px");}
.layui-layer{-webkit-overflow-scrolling:touch;}
.layui-layer{top:150px;left:0;margin:0;padding:0;background-color:#fff;-webkit-background-clip:content;border-radius:3px;box-shadow:1px 1px 50px rgba(0,0,0,.3);}
.layui-layer{top:150px;left:0;margin:0;padding:0;background-color:#fff;-webkit-background-clip:content;border-radius:8px;box-shadow:1px 1px 50px rgba(0,0,0,.3);}
.layui-layer-close{position:absolute;}
.layui-layer-content{position:relative;overflow:hidden;}
.layui-layer-border{border:1px solid #B2B2B2;border:1px solid rgba(0,0,0,.1);box-shadow:1px 1px 5px rgba(0,0,0,.2);}
@@ -35,7 +35,7 @@ html #layuicss-layer{display:none;position:absolute;width:1989px;}
@keyframes layer-fadeIn{0%{opacity:0}100%{opacity:1}}.layer-anim-05{-webkit-animation-name:layer-fadeIn;animation-name:layer-fadeIn}
@-webkit-keyframes layer-shake{0%,100%{-webkit-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);transform:translateX(10px)}}@keyframes layer-shake{0%,100%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);-ms-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);-ms-transform:translateX(10px);transform:translateX(10px)}}.layer-anim-06{-webkit-animation-name:layer-shake;animation-name:layer-shake}@-webkit-keyframes fadeIn{0%{opacity:0}100%{opacity:1}}
.layui-layer-title{padding:0 80px 0 20px;height:50px;line-height:50px;border-bottom:1px solid #F0F0F0;font-size:14px;color:#333;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;border-radius:2px 2px 0 0;}
.layui-layer-title{padding:0 80px 0 20px;height:50px;line-height:50px;border-bottom:1px solid #F0F0F0;font-size:14px;color:#333;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;border-radius:8px 8px 0 0;}
.layui-layer-setwin{position:absolute;right:20px;*right:0;top:20px;font-size:0;line-height:initial;}
.layui-layer-setwin a{position:relative;width:16px;height:16px;margin-left:19px;font-size:12px;_overflow:hidden;}
.layui-layer-setwin .layui-layer-min{display:none!important}
@@ -51,7 +51,7 @@ html #layuicss-layer{display:none;position:absolute;width:1989px;}
.layui-layer-setwin .layui-layer-close2:hover{ background-position:-180px -31px;}
.layui-layer-btn{text-align:right;padding:0 15px 12px;pointer-events:auto;user-select:none;-webkit-user-select:none;}
.layui-layer-btn a{height:28px;line-height:28px;margin:5px 5px 0;padding:0 15px;border:1px solid #dedede;background-color:#fff;color:#333;border-radius:3px;font-weight:400;cursor:pointer;text-decoration:none;}
.layui-layer-btn a{height:28px;line-height:28px;margin:5px 5px 0;padding:0 15px;border:1px solid #dedede;background-color:#fff;color:#333;border-radius:8px;font-weight:400;cursor:pointer;text-decoration:none;}
.layui-layer-btn a:hover{opacity:0.9;text-decoration:none;}
.layui-layer-btn a:active{opacity:0.8;}
.layui-layer-btn .layui-layer-btn0{border-color:#1E9FFF;background-color:#1E9FFF;color:#fff;}
@@ -75,14 +75,14 @@ html #layuicss-layer{display:none;position:absolute;width:1989px;}
.layui-layer-page .layui-layer-content{position:relative;overflow:auto;}
.layui-layer-page .layui-layer-btn,.layui-layer-iframe .layui-layer-btn{padding-top:10px;}
.layui-layer-nobg{background:none;}
.layui-layer-iframe iframe{display:block;width:100%;border-radius:3px;}
.layui-layer-iframe iframe{display:block;width:100%;border-radius:8px;}
.layui-layer-loading{border-radius:100%;background:none; box-shadow:none; border:none;}
.layui-layer-loading .layui-layer-content{width:60px;height:24px;background:url(loading-0.gif) no-repeat;}
.layui-layer-loading .layui-layer-loading1{width:37px;height:37px;background:url(loading-1.gif) no-repeat;}
.layui-layer-loading .layui-layer-loading2, .layui-layer-ico16{width:32px;height:32px;background:url(loading-2.gif) no-repeat;}
.layui-layer-tips{background:none;box-shadow:none;border:none;}
.layui-layer-tips .layui-layer-content{position:relative;overflow:visible;line-height:22px;min-width:12px;padding:8px 15px;font-size:12px;_float:left;border-radius:3px;box-shadow:1px 1px 3px rgba(0,0,0,.2);background-color:#000;color:#fff;}
.layui-layer-tips .layui-layer-content{position:relative;overflow:visible;line-height:22px;min-width:12px;padding:8px 15px;font-size:12px;_float:left;border-radius:8px;box-shadow:1px 1px 3px rgba(0,0,0,.2);background-color:#000;color:#fff;}
.layui-layer-tips .layui-layer-close{right:-2px;top:-1px;}
.layui-layer-tips i.layui-layer-TipsG{ position:absolute; width:0;height:0;border-width:8px;border-color:transparent;border-style:dashed;*overflow:hidden;}
.layui-layer-tips i.layui-layer-TipsT, .layui-layer-tips i.layui-layer-TipsB{left:5px;border-right-style:solid;border-right-color:#000;}
@@ -143,12 +143,12 @@ html #layuicss-layer{display:none;position:absolute;width:1989px;}
}
.layer-anim-close{-webkit-animation-name:layer-bounceOut;animation-name:layer-bounceOut;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:.2s;animation-duration:.2s;}
.layui-layer-title {font-size:16px;background:#fff;height:57px;line-height:57px;}
.layui-layer-title {font-size:16px;background:#fff;height:52px;line-height:52px;}
.layui-layer-page .layui-layer-content {overflow-x:hidden;}
.layui-layer-page .layui-layer-content .form-file{padding-top:4px;}
.layui-layer-page .layui-layer-btn, .layui-layer-iframe .layui-layer-btn {padding-top:3px;padding-bottom:10px;}
.layui-layer-btn .layui-layer-btn0{border-color:#1e5edb;background-color:#1e5edb;}
.layui-layer-btn a {height:auto;padding:1px 14px;font-size:14px;background-color:#f4f4f4;}
.layui-layer-btn a {height:auto;padding:1px 12px;margin-right:4px;font-size:14px;background-color:#f4f4f4;}
.layui-layer.toast-top-full-width {min-width:60%;}
.skin-dark .layui-layer {background:#1a1a1a;color:#ddd;}

View File

@@ -4469,7 +4469,7 @@ S2.define('select2/dropdown/closeOnSelect',[
});
// ThinkGem 默认为中文
S2.define('select2/i18n/en',[],function () {
S2.define('select2/i18n/zh_CN',[],function () {
// English
return {
errorLoading: function () {
@@ -4549,7 +4549,7 @@ S2.define('select2/defaults',[
'./dropdown/selectOnClose',
'./dropdown/closeOnSelect',
'./i18n/en'
'./i18n/zh_CN'
], function ($, require,
ResultsList,
@@ -4763,7 +4763,7 @@ S2.define('select2/defaults',[
if ($.isArray(options.language)) {
var languages = new Translation();
options.language.push('en');
options.language.push('zh_CN');
var languageNames = options.language;
@@ -4800,7 +4800,7 @@ S2.define('select2/defaults',[
options.translations = languages;
} else {
var baseTranslation = Translation.loadPath(
this.defaults.amdLanguageBase + 'en'
this.defaults.amdLanguageBase + 'zh_CN'
);
var customTranslation = new Translation(options.language);
@@ -4952,6 +4952,8 @@ S2.define('select2/options',[
this.options.language = $e.prop('lang').toLowerCase();
} else if ($e.closest('[lang]').prop('lang')) {
this.options.language = $e.closest('[lang]').prop('lang');
} else if (window.lang) {
this.options.language = window.lang;
}
}

View File

@@ -6,12 +6,15 @@ rem *
rem * Author: ThinkGem@163.com
rem */
echo.
echo [<5B><>Ϣ] <20><><EFBFBD>𹤳̰汾<EFBFBD><EFBFBD>Nexus<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
echo [<5B><>Ϣ] <20><><EFBFBD>𹤳̵<EFBFBD>Maven<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
echo.
%~d0
cd %~dp0
call mvn -v
echo.
cd ..
call mvn clean deploy -Dmaven.test.skip=true -Pdeploy

View File

@@ -4,10 +4,12 @@
# * No deletion without permission, or be held responsible to law.
# *
# * Author: ThinkGem@163.com
# *
# */
echo ""
echo "[信息] 部署工程版本到Nexus服务器。"
echo "[信息] 部署工程到Maven服务器。"
echo ""
mvn -v
echo ""
cd ..

View File

@@ -12,6 +12,9 @@ echo.
%~d0
cd %~dp0
call mvn -v
echo.
cd ..
call mvn clean install -Dmaven.test.skip=true -Ppackage

View File

@@ -4,10 +4,12 @@
# * No deletion without permission, or be held responsible to law.
# *
# * Author: ThinkGem@163.com
# *
# */
echo ""
echo "[信息] 打包Web工程,生成war/jar包文件。"
echo "[信息] 打包安装工程生成jar包文件。"
echo ""
mvn -v
echo ""
cd ..

File diff suppressed because it is too large Load Diff

BIN
modules/app/db/app.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

View File

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

View File

@@ -10,7 +10,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import com.jeesite.common.callback.MethodCallback;
import com.jeesite.common.config.Global;
import com.jeesite.common.tests.BaseInitDataTests;
import com.jeesite.modules.app.entity.AppComment;

View File

@@ -9,4 +9,11 @@
5.3.0
5.3.1
5.3.2
5.4.0
5.4.0
5.4.1
5.5.0
5.5.1
5.5.2
5.6.0
5.6.1
5.7.0

View File

@@ -5,46 +5,46 @@
<div class="box-title">
<i class="fa icon-note"></i> ${text(appComment.isNewRecord ? '新增意见' : '编辑意见')}
</div>
<div class="box-tools pull-right">
<div class="box-tools pull-right hide">
<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button>
</div>
</div>
<#form:form id="inputForm" model="${appComment}" action="${ctx}/app/appComment/save" method="post" class="form-horizontal nofocus">
<div class="box-body">
<div class="form-unit">${text('基本信息')}</div>
<#form:hidden path="id"/>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label class="control-label col-sm-2" title="">
<span class="required ">*</span> ${text('问题分类')}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:select path="category" dictType="app_comment_category" class="form-control required" />
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label class="control-label col-sm-2" title="">
<span class="required ">*</span> ${text('问题和意见')}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:textarea path="content" rows="4" minlength="10" maxlength="500" class="form-control required"/>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label class="control-label col-sm-2" title="">
<span class="required hide">*</span> ${text('联系方式')}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:input path="contact" maxlength="200" class="form-control"/>
</div>
</div>
</div>
<#form:hidden path="id"/>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label class="control-label col-sm-2" title="">
<span class="required ">*</span> ${text('问题分类')}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:select path="category" dictType="app_comment_category" class="form-control required" />
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label class="control-label col-sm-2" title="">
<span class="required ">*</span> ${text('问题和意见')}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:textarea path="content" rows="4" minlength="10" maxlength="500" class="form-control required"/>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label class="control-label col-sm-2" title="">
<span class="required hide">*</span> ${text('联系方式')}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:input path="contact" maxlength="200" class="form-control"/>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
@@ -89,7 +89,7 @@
</div>
</div>
</div>
<div class="form-unit">${text('回复信息')}</div>
<div class="form-unit">${text('回复信息')}</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
@@ -119,7 +119,7 @@
${appComment.replyUserName}
</div>
</div>
</div>
</div>
</div>
<div class="form-unit">${text('其它信息')}</div>
<div class="row">
@@ -143,7 +143,7 @@
</div>
</div>
</div>
</div>
</div>
</div>
<div class="box-footer">
<div class="row">

View File

@@ -18,20 +18,20 @@
data-page-no="${parameter.pageNo}" data-page-size="${parameter.pageSize}" data-order-by="${parameter.orderBy}">
<div class="form-group">
<label class="control-label">${text('问题分类')}</label>
<div class="control-inline width-120">
<div class="control-inline width-90">
<#form:select path="category" dictType="app_comment_category" blankOption="true" class="form-control"/>
</div>
</div>
<div class="form-group">
<label class="control-label">${text('问题和意见')}</label>
<div class="control-inline">
<#form:input path="content" maxlength="500" class="form-control width-120"/>
<#form:input path="content" maxlength="500" class="form-control width-90"/>
</div>
</div>
<div class="form-group">
<label class="control-label">${text('联系方式')}</label>
<div class="control-inline">
<#form:input path="contact" maxlength="200" class="form-control width-120"/>
<#form:input path="contact" maxlength="200" class="form-control width-90"/>
</div>
</div>
<div class="form-group">
@@ -49,8 +49,8 @@
</div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary btn-sm">${text('查询')}</button>
<button type="reset" class="btn btn-default btn-sm isQuick">${text('重置')}</button>
<button type="submit" class="btn btn-primary btn-sm"><i class="glyphicon glyphicon-search"></i> ${text('查询')}</button>
<button type="reset" class="btn btn-default btn-sm isQuick"><i class="glyphicon glyphicon-repeat"></i> ${text('重置')}</button>
</div>
</#form:form>
<table id="dataGrid"></table>
@@ -60,19 +60,19 @@
</div>
<% } %>
<script>
// 初始化DataGrid对象
//# // 初始化DataGrid对象
$('#dataGrid').dataGrid({
searchForm: $("#searchForm"),
searchForm: $('#searchForm'),
columnModel: [
{header:'${text("问题和意见")}', name:'content', index:'a.content', width:250, align:"left", frozen:true, formatter: function(val, obj, row, act){
return '<a href="${ctx}/app/appComment/form?id='+row.id+'" class="btnList" data-title="${text("编辑意见")}">'+(val||row.id)+'</a>';
}},
{header:'${text("问题分类")}', name:'category', index:'a.category', width:100, align:"center", formatter: function(val, obj, row, act){
return js.getDictLabel(${@DictUtils.getDictListJson('app_comment_category')}, val, '${text("未知")}', true);
return js.getDictLabel("#{@DictUtils.getDictListJson('app_comment_category')}", val, '${text("未知")}', true);
}},
{header:'${text("联系方式")}', name:'contact', index:'a.contact', width:150, align:"center"},
{header:'${text("状态")}', name:'status', index:'a.status', width:100, align:"center", formatter: function(val, obj, row, act){
return js.getDictLabel(${@DictUtils.getDictListJson('app_comment_status')}, val, '${text("未知")}', true);
return js.getDictLabel("#{@DictUtils.getDictListJson('app_comment_status')}", val, '${text("未知")}', true);
}},
{header:'${text("提问时间")}', name:'createDate', index:'a.create_date', width:150, align:"center"},
{header:'${text("提问人员")}', name:'createByName', index:'a.create_by_name', width:150, align:"center"},
@@ -81,7 +81,7 @@ $('#dataGrid').dataGrid({
{header:'${text("回复人员")}', name:'replyUserName', index:'a.reply_user_name', width:150, align:"center"},
{header:'${text("操作")}', name:'actions', width:120, formatter: function(val, obj, row, act){
var actions = [];
//<% if(hasPermi('app:appComment:edit')){ %>
//# if(hasPermi('app:appComment:edit')){
actions.push('<a href="${ctx}/app/appComment/form?id='+row.id+'" class="btnList" title="${text("编辑意见")}"><i class="fa fa-pencil"></i></a>&nbsp;');
if (row.status == Global.STATUS_NORMAL){
actions.push('<a href="${ctx}/app/appComment/disable?id='+row.id+'" class="btnList" title="${text("停用意见")}" data-confirm="${text("确认要停用该意见吗?")}"><i class="glyphicon glyphicon-ban-circle"></i></a>&nbsp;');
@@ -89,11 +89,11 @@ $('#dataGrid').dataGrid({
actions.push('<a href="${ctx}/app/appComment/enable?id='+row.id+'" class="btnList" title="${text("启用意见")}" data-confirm="${text("确认要启用该意见吗?")}"><i class="glyphicon glyphicon-ok-circle"></i></a>&nbsp;');
}
actions.push('<a href="${ctx}/app/appComment/delete?id='+row.id+'" class="btnList" title="${text("删除意见")}" data-confirm="${text("确认要删除该意见吗?")}"><i class="fa fa-trash-o"></i></a>&nbsp;');
//<% } %>
//# }
return actions.join('');
}}
],
// 加载成功后执行事件
//# // 加载成功后执行事件
ajaxSuccess: function(data){
}

View File

@@ -5,7 +5,7 @@
<div class="box-title">
<i class="fa icon-note"></i> ${text(appUpgrade.isNewRecord ? '新增版本' : '编辑版本')}
</div>
<div class="box-tools pull-right">
<div class="box-tools pull-right hide">
<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button>
</div>
</div>
@@ -13,15 +13,15 @@
<div class="box-body">
<div class="form-unit">${text('基本信息')}</div>
<#form:hidden path="id"/>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required hide">*</span> ${text('升级标题')}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:input path="upTitle" maxlength="200" class="form-control"/>
</div>
</div>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required hide">*</span> ${text('升级标题')}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:input path="upTitle" maxlength="200" class="form-control"/>
</div>
</div>
</div>
</div>
<div class="row">
@@ -35,41 +35,41 @@
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label class="control-label col-sm-2" title="">
<span class="required hide">*</span> ${text('版本号码')}<i class="fa icon-question hide"></i></label>
<div class="col-sm-4">
<#form:input path="upVersion" class="form-control digits"/>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label class="control-label col-sm-2" title="">
<span class="required hide">*</span> ${text('版本号码')}<i class="fa icon-question hide"></i></label>
<div class="col-sm-4">
<#form:input path="upVersion" class="form-control digits"/>
</div>
<div class="col-sm-4 control-text" style="color:#888">
内部版本号,请填写数字
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required hide">*</span> ${text('升级类型')}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:select path="upType" dictType="app_upgrade_type" blankOption="true" class="form-control" />
</div>
</div>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required hide">*</span> ${text('升级类型')}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:select path="upType" dictType="app_upgrade_type" blankOption="true" class="form-control" />
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required hide">*</span> ${text('发布时间')}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:input path="upDate" readonly="true" maxlength="20" class="form-control laydate"
dataFormat="date" data-type="date" data-format="yyyy-MM-dd"/>
</div>
</div>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required hide">*</span> ${text('发布时间')}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:input path="upDate" readonly="true" maxlength="20" class="form-control laydate"
dataFormat="date" data-type="date" data-format="yyyy-MM-dd"/>
</div>
</div>
</div>
</div>
<div class="row">
@@ -83,39 +83,39 @@
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label class="control-label col-sm-2" title="">
<span class="required hide">*</span> ${text('APK下载地址')}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:input path="apkUrl" maxlength="500" class="form-control"/>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label class="control-label col-sm-2" title="">
<span class="required hide">*</span> ${text('APK下载地址')}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:input path="apkUrl" maxlength="500" class="form-control"/>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label class="control-label col-sm-2" title="">
<span class="required hide">*</span> ${text('资源下载地址')}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:input path="resUrl" maxlength="500" class="form-control"/>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label class="control-label col-sm-2" title="">
<span class="required hide">*</span> ${text('备注信息')}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:textarea path="remarks" rows="4" maxlength="500" class="form-control"/>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label class="control-label col-sm-2" title="">
<span class="required hide">*</span> ${text('资源下载地址')}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:input path="resUrl" maxlength="500" class="form-control"/>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label class="control-label col-sm-2" title="">
<span class="required hide">*</span> ${text('备注信息')}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:textarea path="remarks" rows="4" maxlength="500" class="form-control"/>
</div>
</div>
</div>
</div>
</div>
<div class="box-footer">
<div class="row">

View File

@@ -18,19 +18,19 @@
data-page-no="${parameter.pageNo}" data-page-size="${parameter.pageSize}" data-order-by="${parameter.orderBy}">
<div class="form-group">
<label class="control-label">${text('应用代号')}</label>
<div class="control-inline width-120">
<div class="control-inline width-90">
<#form:select path="appCode" dictType="app_code" blankOption="true" class="form-control"/>
</div>
</div>
<div class="form-group">
<label class="control-label">${text('升级标题')}</label>
<div class="control-inline">
<#form:input path="upTitle" maxlength="200" class="form-control width-120"/>
<#form:input path="upTitle" maxlength="200" class="form-control width-90"/>
</div>
</div>
<div class="form-group">
<label class="control-label">${text('升级类型')}</label>
<div class="control-inline width-120">
<div class="control-inline width-90">
<#form:select path="upType" dictType="app_upgrade_type" blankOption="true" class="form-control"/>
</div>
</div>
@@ -48,8 +48,8 @@
</div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary btn-sm">${text('查询')}</button>
<button type="reset" class="btn btn-default btn-sm isQuick">${text('重置')}</button>
<button type="submit" class="btn btn-primary btn-sm"><i class="glyphicon glyphicon-search"></i> ${text('查询')}</button>
<button type="reset" class="btn btn-default btn-sm isQuick"><i class="glyphicon glyphicon-repeat"></i> ${text('重置')}</button>
</div>
</#form:form>
<table id="dataGrid"></table>
@@ -59,29 +59,29 @@
</div>
<% } %>
<script>
// 初始化DataGrid对象
//# // 初始化DataGrid对象
$('#dataGrid').dataGrid({
searchForm: $("#searchForm"),
searchForm: $('#searchForm'),
columnModel: [
{header:'${text("升级标题")}', name:'upTitle', index:'a.up_title', width:350, align:"left", frozen:true, formatter: function(val, obj, row, act){
return '<a href="${ctx}/app/appUpgrade/form?id='+row.id+'" class="btnList" data-title="${text("编辑版本")}">'+(val||row.id)+'</a>';
}},
{header:'${text("应用代号")}', name:'appCode', index:'a.app_code', width:150, align:"center", formatter: function(val, obj, row, act){
return js.getDictLabel(${@DictUtils.getDictListJson('app_code')}, val, val, true);
return js.getDictLabel("#{@DictUtils.getDictListJson('app_code')}", val, val, true);
}},
{header:'${text("版本号码")}', name:'upVersion', index:'a.up_version', width:100, align:"center"},
{header:'${text("升级类型")}', name:'upType', index:'a.up_type', width:150, align:"center", formatter: function(val, obj, row, act){
return js.getDictLabel(${@DictUtils.getDictListJson('app_upgrade_type')}, val, '${text("未知")}', true);
return js.getDictLabel("#{@DictUtils.getDictListJson('app_upgrade_type')}", val, '${text("未知")}', true);
}},
{header:'${text("发布时间")}', name:'upDate', index:'a.up_date', width:150, align:"center"},
{header:'${text("升级内容")}', name:'upContent', index:'a.up_content', width:250, align:"left"},
{header:'${text("状态")}', name:'status', index:'a.status', width:100, align:"center", formatter: function(val, obj, row, act){
return js.getDictLabel(${@DictUtils.getDictListJson('sys_search_status')}, val, '${text("未知")}', true);
return js.getDictLabel("#{@DictUtils.getDictListJson('sys_search_status')}", val, '${text("未知")}', true);
}},
{header:'${text("更新时间")}', name:'updateDate', index:'a.update_date', width:150, align:"center"},
{header:'${text("操作")}', name:'actions', width:120, formatter: function(val, obj, row, act){
var actions = [];
//<% if(hasPermi('app:appUpgrade:edit')){ %>
//# if(hasPermi('app:appUpgrade:edit')){
actions.push('<a href="${ctx}/app/appUpgrade/form?id='+row.id+'" class="btnList" title="${text("编辑版本")}"><i class="fa fa-pencil"></i></a>&nbsp;');
if (row.status == Global.STATUS_NORMAL){
actions.push('<a href="${ctx}/app/appUpgrade/disable?id='+row.id+'" class="btnList" title="${text("停用版本")}" data-confirm="${text("确认要停用该版本吗?")}"><i class="glyphicon glyphicon-ban-circle"></i></a>&nbsp;');
@@ -89,11 +89,11 @@ $('#dataGrid').dataGrid({
actions.push('<a href="${ctx}/app/appUpgrade/enable?id='+row.id+'" class="btnList" title="${text("启用版本")}" data-confirm="${text("确认要启用该版本吗?")}"><i class="glyphicon glyphicon-ok-circle"></i></a>&nbsp;');
}
actions.push('<a href="${ctx}/app/appUpgrade/delete?id='+row.id+'" class="btnList" title="${text("删除版本")}" data-confirm="${text("确认要删除该版本吗?")}"><i class="fa fa-trash-o"></i></a>&nbsp;');
//<% } %>
//# }
return actions.join('');
}}
],
// 加载成功后执行事件
//# // 加载成功后执行事件
ajaxSuccess: function(data){
}

View File

@@ -6,12 +6,15 @@ rem *
rem * Author: ThinkGem@163.com
rem */
echo.
echo [<5B><>Ϣ] <20><><EFBFBD>𹤳̰汾<EFBFBD><EFBFBD>Nexus<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
echo [<5B><>Ϣ] <20><><EFBFBD>𹤳̵<EFBFBD>Maven<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
echo.
%~d0
cd %~dp0
call mvn -v
echo.
cd ..
call mvn clean deploy -Dmaven.test.skip=true -Pdeploy

View File

@@ -4,10 +4,12 @@
# * No deletion without permission, or be held responsible to law.
# *
# * Author: ThinkGem@163.com
# *
# */
echo ""
echo "[信息] 部署工程版本到Nexus服务器。"
echo "[信息] 部署工程到Maven服务器。"
echo ""
mvn -v
echo ""
cd ..

View File

@@ -12,6 +12,9 @@ echo.
%~d0
cd %~dp0
call mvn -v
echo.
cd ..
call mvn clean install -Dmaven.test.skip=true -Ppackage

View File

@@ -4,10 +4,12 @@
# * No deletion without permission, or be held responsible to law.
# *
# * Author: ThinkGem@163.com
# *
# */
echo ""
echo "[信息] 打包Web工程,生成war/jar包文件。"
echo "[信息] 打包安装工程生成jar包文件。"
echo ""
mvn -v
echo ""
cd ..

File diff suppressed because it is too large Load Diff

BIN
modules/cms/db/cms.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

View File

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

View File

@@ -4,18 +4,16 @@
*/
package com.jeesite.modules.cms.service;
import java.io.IOException;
import java.util.List;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.beust.jcommander.internal.Lists;
import com.jeesite.common.collect.ListUtils;
import com.jeesite.modules.cms.entity.FileTemplete;
import com.jeesite.modules.cms.entity.Site;
import com.jeesite.modules.cms.utils.CmsUtils;
import com.jeesite.modules.cms.utils.FileTempleteUtils;
import com.jeesite.modules.sys.entity.DictData;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.util.List;
/**
* 模版文件Service
@@ -36,7 +34,7 @@ public class FileTempleteService {
* @param prefix
*/
public List<DictData> getTempleteContentDict(String prefix) throws IOException {
List<DictData> listSite = Lists.newArrayList();
List<DictData> listSite = ListUtils.newArrayList();
String solutionPath = CmsUtils.getSite(Site.getCurrentSiteCode()).getSolutionPath();
List<FileTemplete> tplList = FileTempleteUtils.getFileTempleteListByPath(solutionPath);
for (FileTemplete tpl : tplList) {

View File

@@ -18,18 +18,7 @@ j2cache:
cmsPageCache: 100000, 7d
#spring:
# data:
# elasticsearch:
# # 开启 ES 功能
# enabled: true
#
# # 设置 ES 服务地址
# client:
# reactive:
# endpoints: 127.0.0.1:9200
#
# # 连接超时的时间
# properties:
# transport:
# tcp:
# connect_timeout: 120s
# elasticsearch:
# enabled: true
# uris: http://Win11:9200
# connection-timeout: 120s

View File

@@ -17,4 +17,11 @@
5.3.0
5.3.1
5.3.2
5.4.0
5.4.0
5.4.1
5.5.0
5.5.1
5.5.2
5.6.0
5.6.1
5.7.0

View File

@@ -2,8 +2,8 @@
// Bootswatch
// -----------------------------------------------------
$web-font-path: "https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,700" !default;
@import url($web-font-path);
//$web-font-path: "https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,700" !default;
//@import url($web-font-path);
// Navbar =====================================================================

View File

@@ -1,4 +1,4 @@
@import url("https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,700");
/*@import url("https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,700");*/
/*!
* bootswatch v3.4.1
* Homepage: http://bootswatch.com

View File

@@ -1,4 +1,5 @@
@import url("https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,700");/*!
/*@import url("https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,700");*/
/*!
* bootswatch v3.4.1
* Homepage: http://bootswatch.com
* Copyright 2012-2019 Thomas Park

View File

@@ -2,12 +2,12 @@
// Bootswatch
// -----------------------------------------------------
@web-font-path: "https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,700";
.web-font(@path) {
@import (css) url("@{path}");
}
.web-font(@web-font-path);
//@web-font-path: "https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,700";
//
//.web-font(@path) {
// @import (css) url("@{path}");
//}
//.web-font(@web-font-path);
// Navbar =====================================================================

View File

@@ -6,7 +6,7 @@
<div class="box-title">
<i class="fa icon-note"></i> ${text(article.isNewRecord ? '新增文章' : '编辑文章')}${@CmsUtils.getCurrentSite().getSiteName()}
</div>
<div class="box-tools pull-right">
<div class="box-tools pull-right hide">
<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button>
</div>
</div>
@@ -21,7 +21,7 @@
<label class="control-label col-sm-4" title="">
<span class="required ">*</span> ${text('所属栏目')}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:treeselect id="category" title="${text('所属栏目')}"
<#form:treeselect id="category" title="${text('所属栏目')}"
path="category.categoryCode" labelPath="category.categoryName"
url="${ctx}/cms/category/treeData?excludeCode=${article.category.categoryCode}"
class="required" allowClear="false" canSelectRoot="true" canSelectParent="false" />
@@ -70,145 +70,145 @@
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="${text('数值越大排序越靠前,可设置权重过期时间')}。">
${text('权重/排序')} <i class="fa icon-question"></i></label>
<div class="col-sm-8">
<div class="form-inline m0">
<#form:input path="weight" class="form-control width-90 digits" maxlength="10"/> &nbsp;
<#form:checkbox id="weightTop" label="${text('置顶')}" value="${article.weight==9999 ?'1' : ''}"
class="form-control" style="vertical-align:middle;"/>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="${text('数值越大排序越靠前,可设置权重过期时间')}。">
${text('权重/排序')} <i class="fa icon-question"></i></label>
<div class="col-sm-8">
<div class="form-inline m0">
<#form:input path="weight" class="form-control width-90 digits" maxlength="10"/> &nbsp;
<#form:checkbox id="weightTop" label="${text('置顶')}" value="${article.weight==9999 ?'1' : ''}"
class="form-control" style="vertical-align:middle;"/>
</div>
</div>
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="${text('时间到期后权重自动恢复为0如果为空则权重永不过期')}。">
${text('权重过期时间')} <i class="fa icon-question"></i></label>
<div class="col-sm-8">
<#form:input path="weightDate" readonly="true" maxlength="20" class="form-control laydate"
dataFormat="datetime" data-type="datetime" data-format="yyyy-MM-dd HH:mm"/>
</div>
</div>
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="${text('时间到期后权重自动恢复为0如果为空则权重永不过期')}。">
${text('权重过期时间')} <i class="fa icon-question"></i></label>
<div class="col-sm-8">
<#form:input path="weightDate" readonly="true" maxlength="20" class="form-control laydate"
dataFormat="datetime" data-type="datetime" data-format="yyyy-MM-dd HH:mm"/>
</div>
</div>
</div>
</div>
<div class="form-unit">${text('详细信息')}</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label class="control-label col-sm-1">${text('摘要')}</label>
<div class="col-sm-11">
<#form:textarea path="description" maxlength="500" class="form-control"/>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label class="control-label col-sm-1">${text('正文')}</label>
<div class="col-sm-11">
<#form:ueditor id="content" path="articleData.content" maxlength="10000" height="500" class="required" outline="${parameter.outline}"/>
</div>
</div>
</div>
</div>
<div class="form-unit">${text('其他信息')}</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label class="control-label col-sm-2" title="">
<span class="required hide">*</span> ${text('内容图片')}<i class="fa icon-question hide"></i></label>
<div class="col-sm-10">
<#form:fileupload id="uploadImage" bizKey="${article.id}"
bizType="article_image" returnPath="true"
filePathInputId="image" uploadType="image" readonly="false"
maxUploadNum="4" isMini="false" />
<#form:input path="image" maxlength="1000" readonly="true" class="form-control" />
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required hide">*</span> ${text('关键字')}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:input path="keywords" maxlength="500" class="form-control"/>
</div>
</div>
</div>
<!--<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4">${text('推荐位')}</label>
<div class="col-sm-8">
<div class="checkbox-list">
<#form:checkbox path="posidList" dictType="cms_post" class="form-control" />
<div class="form-unit">${text('详细信息')}</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label class="control-label col-sm-1">${text('摘要')}</label>
<div class="col-sm-11">
<#form:textarea path="description" maxlength="500" class="form-control"/>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="${text('文章的发布状态')}">${text('状态')}<i class="fa icon-question"></i></label>
<div class="col-sm-8">
<#form:select path="state" dictType="sys_status" blankOption="true" class="form-control" />
</div>
</div>
</div>-->
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="${text('可修改发布时间,不填则使用当前时间')}">
${text('发布时间')} <i class="fa icon-question"></i></label>
<div class="col-sm-8">
<#form:input path="createDate" readonly="true" maxlength="20" class="form-control laydate"
dataFormat="datetime" data-type="datetime" data-format="yyyy-MM-dd HH:mm"/>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label class="control-label col-sm-1">${text('正文')}</label>
<div class="col-sm-11">
<#form:ueditor id="content" path="articleData.content" maxlength="10000" height="500" class="required" outline="${parameter.outline}"/>
</div>
</div>
</div>
</div>
</div>
<div class="form-unit">${text('高级信息')}</div>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required hide">*</span> ${text('自定义内容视图')}<i class="fa icon-question" title="自定义内容视图名称必须以'${article_DEFAULT_TEMPLATE}'开始"></i></label>
<div class="col-sm-8">
<#form:select path="customContentView" items="${contentViewList}" itemLabel="id" itemValue="id" blankOption="true" class="form-control " />
<div class="form-unit">${text('其他信息')}</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label class="control-label col-sm-2" title="">
<span class="required hide">*</span> ${text('内容图片')}<i class="fa icon-question hide"></i></label>
<div class="col-sm-10">
<#form:fileupload id="uploadImage" bizKey="${article.id}"
bizType="article_image" returnPath="true"
filePathInputId="image" uploadType="image" readonly="false"
maxUploadNum="4" isMini="false" />
<#form:input path="image" maxlength="1000" readonly="true" class="form-control" />
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label class="control-label col-sm-2" title="">
<span class="required hide">*</span> ${text('视图参数配置')}<i class="fa icon-question" title="视图参数例如: {count:2, title_show:'yes'} 则在视图文件中的获取方法是:\${viewConfig_count}、\${viewConfig_titleShow}"></i></label>
<div class="col-sm-10">
<#form:input path="viewConfig" maxlength="1000" placeholder="视图参数例如: {count:2, title_show:'yes'} 则在视图文件中的获取方法是:${'${'}viewConfig_count}、${'${'}viewConfig_titleShow}" class="form-control"/>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required hide">*</span> ${text('关键字')}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:input path="keywords" maxlength="500" class="form-control"/>
</div>
</div>
</div>
<!--<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4">${text('推荐位')}</label>
<div class="col-sm-8">
<div class="checkbox-list">
<#form:checkbox path="posidList" dictType="cms_post" class="form-control" />
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label class="control-label col-sm-2" title="">
<span class="required hide">*</span> ${text('备注信息')}<i class="fa icon-question hide"></i></label>
<div class="col-sm-10">
<#form:textarea path="remarks" rows="4" maxlength="500" class="form-control"/>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="${text('文章的发布状态')}">${text('状态')}<i class="fa icon-question"></i></label>
<div class="col-sm-8">
<#form:select path="state" dictType="sys_status" blankOption="true" class="form-control" />
</div>
</div>
</div>-->
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="${text('可修改发布时间,不填则使用当前时间')}">
${text('发布时间')} <i class="fa icon-question"></i></label>
<div class="col-sm-8">
<#form:input path="createDate" readonly="true" maxlength="20" class="form-control laydate"
dataFormat="datetime" data-type="datetime" data-format="yyyy-MM-dd HH:mm"/>
</div>
</div>
</div>
</div>
<div class="form-unit">${text('页面配置')}</div>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required hide">*</span> ${text('自定义内容视图')}<i class="fa icon-question" title="自定义内容视图名称必须以'${article_DEFAULT_TEMPLATE}'开始"></i></label>
<div class="col-sm-8">
<#form:select path="customContentView" items="${contentViewList}" itemLabel="id" itemValue="id" blankOption="true" class="form-control " />
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label class="control-label col-sm-2" title="">
<span class="required hide">*</span> ${text('视图参数配置')}<i class="fa icon-question" title="视图参数例如: {count:2, title_show:'yes'} 则在视图文件中的获取方法是:\${viewConfig_count}、\${viewConfig_titleShow}"></i></label>
<div class="col-sm-10">
<#form:input path="viewConfig" maxlength="1000" placeholder="视图参数例如: {count:2, title_show:'yes'} 则在视图文件中的获取方法是:${'${'}viewConfig_count}、${'${'}viewConfig_titleShow}" class="form-control"/>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label class="control-label col-sm-2" title="">
<span class="required hide">*</span> ${text('备注信息')}<i class="fa icon-question hide"></i></label>
<div class="col-sm-10">
<#form:textarea path="remarks" rows="4" maxlength="500" class="form-control"/>
</div>
</div>
</div>
</div>
<#form:extend collapsed="true" pathPrefix="articleData"/>
</div>
<#form:extend collapsed="true" pathPrefix="articleData"/>
<div class="box-footer">
<div class="row">
<div class="col-sm-offset-2 col-sm-10">
@@ -226,7 +226,7 @@
<script src="${ctxStatic}/colorpicker/bootstrap-colorpicker.js"></script>
<script type="text/javascript">
// 颜色控件初始化
$("#inputForm .input-color").colorpicker();
$('#inputForm .input-color').colorpicker();
// 权重、排序
$('#weightTop input').on('ifChecked ifUnchecked', function(){
if ($(this).is(':checked')){
@@ -235,7 +235,7 @@ $('#weightTop input').on('ifChecked ifUnchecked', function(){
$('#weight').val('0');
}
});
$("#inputForm").validate({
$('#inputForm').validate({
submitHandler: function(form){
$('#wordCount').val(contentUE.getContentTxt().length);
js.ajaxSubmitForm($(form), function(data){

View File

@@ -28,12 +28,12 @@
<#form:input path="title" maxlength="255" class="form-control width-120"/>
</div>
</div>
<div class="form-group">
<!--<div class="form-group">
<label class="control-label">${text('关键字')}</label>
<div class="control-inline">
<#form:input path="keywords" maxlength="500" class="form-control width-120"/>
</div>
</div>
</div>-->
<div class="form-group">
<label class="control-label">${text('状态')}</label>
<div class="control-inline width-90">
@@ -41,8 +41,8 @@
</div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary btn-sm">${text('查询')}</button>
<button type="reset" class="btn btn-default btn-sm isQuick">${text('重置')}</button>
<button type="submit" class="btn btn-primary btn-sm"><i class="glyphicon glyphicon-search"></i> ${text('查询')}</button>
<button type="reset" class="btn btn-default btn-sm isQuick"><i class="glyphicon glyphicon-repeat"></i> ${text('重置')}</button>
</div>
</#form:form>
<table id="dataGrid"></table>
@@ -52,7 +52,7 @@
</div>
<% } %>
<script>
// 初始化DataGrid对象
//# // 初始化DataGrid对象
$('#dataGrid').dataGrid({
searchForm: $("#searchForm"),
columnModel: [
@@ -64,13 +64,13 @@ $('#dataGrid').dataGrid({
{header:'${text("点击数")}', name:'hits', index:'a.hits', width:100, align:"center"},
{header:'${text("字数")}', name:'wordCount', index:'a.word_count', width:100, align:"center"},
{header:'${text("状态")}', name:'status', index:'a.status', width:100, align:"center", formatter: function(val, obj, row, act){
return js.getDictLabel(${@DictUtils.getDictListJson('sys_search_status')}, val, '${text("未知")}', true);
return js.getDictLabel("#{@DictUtils.getDictListJson('sys_search_status')}", val, '${text("未知")}', true);
}},
{header:'${text("创建时间")}', name:'createDate', index:'a.create_date', width:150, align:"center"},
// {header:'${text("备注信息")}', name:'remarks', index:'a.remarks', width:150, align:"left"},
{header:'${text("操作")}', name:'actions', width:150, formatter: function(val, obj, row, act){
var actions = [];
//<% if(hasPermi('cms:article:edit')){ %>
//# if(hasPermi('cms:article:edit')){
actions.push('<a href="${ctx}/cms/article/form?id='+row.id+'" class="btnList" title="${text("编辑文章")}"><i class="fa fa-pencil"></i></a>&nbsp;');
if (row.status == Global.STATUS_NORMAL){
actions.push('<a href="${ctx}/cms/article/disable?id='+row.id+'" class="btnList" title="${text("停用文章")}" data-confirm="${text("确认要停用该文章吗?")}"><i class="glyphicon glyphicon-ban-circle"></i></a>&nbsp;');
@@ -82,11 +82,11 @@ $('#dataGrid').dataGrid({
if (row.status == Global.STATUS_NORMAL){
actions.push('<a href="${ctxFront}/view-'+row.category.categoryCode+'-'+row.id+'" target="_blank" title="${text("预览文章")}"><i class="fa fa-globe"></i></a>&nbsp;');
}
//<% } %>
//# }
return actions.join('');
}}
],
// 加载成功后执行事件
//# // 加载成功后执行事件
ajaxSuccess: function(data){
}

View File

@@ -5,12 +5,13 @@
<div class="box-title">
<i class="fa icon-organization"></i> ${text(category.isNewRecord ? '新增栏目' : '编辑栏目')}
</div>
<div class="box-tools pull-right">
<div class="box-tools pull-right hide">
<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button>
</div>
</div>
<#form:form id="inputForm" model="${category}" action="${ctx}/cms/category/save" method="post" class="form-horizontal">
<div class="box-body">
<div class="form-unit">${text('基本信息')}</div>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
@@ -131,112 +132,112 @@
</div>
</div>
</div>
<div class="form-unit">${text('栏目配置')}</div>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="是否在导航中显示该栏目">
<span class="required hide">*</span> ${text('是否在导航中显示')}<i class="fa icon-question"></i></label>
<div class="col-sm-8">
<#form:radio path="inMenu" dictType="sys_show_hide" class="form-control" />
</div>
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required hide">*</span> ${text('是否允许评论')}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:radio path="isCanComment" dictType="sys_yes_no" class="form-control" />
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="是否在分类页中显示该栏目的文章列表">
<span class="required hide">*</span> ${text('是否在分类页中显示')}<i class="fa icon-question" ></i></label>
<div class="col-sm-8">
<#form:radio path="inList" dictType="sys_show_hide" class="form-control" />
</div>
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title=""> <span class="required hide">*</span>
${text('是否需要审核')}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:radio path="isNeedAudit" dictType="sys_yes_no" class="form-control" />
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="默认展现方式,首栏目内容列表,栏目第一条内容">
<span class="required hide">*</span> ${text('内容展现模式')}<i class="fa icon-question" ></i></label>
<div class="col-sm-8">
<#form:radio path="showModes" dictType="cms_show_modes" class="form-control" />
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="自定义内容视图名称必须以'${category_DEFAULT_TEMPLATE}'开始">
${text('自定义列表视图')}<i class="fa icon-question "></i></label>
<div class="col-sm-8">
<#form:select path="customListView" items="${listViewList}" itemLabel="id" itemValue="id" blankOption="true" class="form-control " />
</div>
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="自定义内容视图名称必须以'${article_DEFAULT_TEMPLATE}'开始"> <span class="required hide">*</span>
${text('自定义内容视图')}<i class="fa icon-question "></i></label>
<div class="col-sm-8">
<#form:select path="customContentView" items="${contentViewList}" itemLabel="id" itemValue="id" blankOption="true" class="form-control " />
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label class="control-label col-sm-2" title="视图参数例如: {count:2, title_show:'yes'} 则在视图文件中的获取方法是:\${viewConfig_count}、\${viewConfig_titleShow}">
${text('视图参数配置')}<i class="fa icon-question"></i></label>
<div class="col-sm-10">
<#form:input path="viewConfig" maxlength="1000" class="form-control"
placeholder="视图参数例如: {count:2, title_show:'yes'} 则在视图文件中的获取方法是:${'${'}viewConfig_count}、${'${'}viewConfig_titleShow}" />
<br />
<ul class="text-muted well well-lg no-shadow m0 pt10 pb10">
<li>例如视图参数设置为:{count:2,titleShow:'yes'} 则在视图文件中的获取方法是:\${viewConfig_count}、\${viewConfig_titleShow}。</li>
<li>设置栏目的管理地址若设置【adminUrl:false】表示无管理地址在内容发布栏目列表中不显示该栏目</li>
<li>设置【adminUrl:'/cms/guestbook'】表示有管理地址,在内容发布栏目列表中点击该栏目链接到该地址。</li>
<!-- <li>管理地址参数若设置【adminUrlParam:'fileDownload=true'】则代表链接模型为文件下载的栏目,新增链接的时候出现文件上传对话框。</li>
<li>管理地址参数若设置【adminUrlParam:'outlineView=true'】则代表文章模型开启大纲视图编辑,在线编辑器左侧显示大纲视图。</li> -->
</ul>
</div>
</div>
</div>
</div>
<div class="form-unit">${text('其他信息')}</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label class="control-label col-sm-2" title="">
<span class="required hide">*</span> ${text('备注信息')}<i class="fa icon-question hide"></i></label>
<div class="col-sm-10">
<#form:textarea path="remarks" rows="4" maxlength="500" class="form-control" />
</div>
</div>
</div>
</div>
<#form:extend collapsed="true" />
</div>
<div class="form-unit">${text('栏目配置')}</div>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="是否在导航中显示该栏目">
<span class="required hide">*</span> ${text('是否在导航中显示')}<i class="fa icon-question"></i></label>
<div class="col-sm-8">
<#form:radio path="inMenu" dictType="sys_show_hide" class="form-control" />
</div>
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required hide">*</span> ${text('是否允许评论')}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:radio path="isCanComment" dictType="sys_yes_no" class="form-control" />
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="是否在分类页中显示该栏目的文章列表">
<span class="required hide">*</span> ${text('是否在分类页中显示')}<i class="fa icon-question" ></i></label>
<div class="col-sm-8">
<#form:radio path="inList" dictType="sys_show_hide" class="form-control" />
</div>
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title=""> <span class="required hide">*</span>
${text('是否需要审核')}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:radio path="isNeedAudit" dictType="sys_yes_no" class="form-control" />
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="默认展现方式,首栏目内容列表,栏目第一条内容">
<span class="required hide">*</span> ${text('内容展现模式')}<i class="fa icon-question" ></i></label>
<div class="col-sm-8">
<#form:radio path="showModes" dictType="cms_show_modes" class="form-control" />
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="自定义内容视图名称必须以'${category_DEFAULT_TEMPLATE}'开始">
${text('自定义列表视图')}<i class="fa icon-question "></i></label>
<div class="col-sm-8">
<#form:select path="customListView" items="${listViewList}" itemLabel="id" itemValue="id" blankOption="true" class="form-control " />
</div>
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="自定义内容视图名称必须以'${article_DEFAULT_TEMPLATE}'开始"> <span class="required hide">*</span>
${text('自定义内容视图')}<i class="fa icon-question "></i></label>
<div class="col-sm-8">
<#form:select path="customContentView" items="${contentViewList}" itemLabel="id" itemValue="id" blankOption="true" class="form-control " />
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label class="control-label col-sm-2" title="视图参数例如: {count:2, title_show:'yes'} 则在视图文件中的获取方法是:\${viewConfig_count}、\${viewConfig_titleShow}">
${text('视图参数配置')}<i class="fa icon-question"></i></label>
<div class="col-sm-10">
<#form:input path="viewConfig" maxlength="1000" class="form-control"
placeholder="视图参数例如: {count:2, title_show:'yes'} 则在视图文件中的获取方法是:${'${'}viewConfig_count}、${'${'}viewConfig_titleShow}" />
<br />
<ul class="text-muted well well-lg no-shadow m0 pt10 pb10">
<li>例如视图参数设置为:{count:2,titleShow:'yes'} 则在视图文件中的获取方法是:\${viewConfig_count}、\${viewConfig_titleShow}。</li>
<li>设置栏目的管理地址若设置【adminUrl:false】表示无管理地址在内容发布栏目列表中不显示该栏目</li>
<li>设置【adminUrl:'/cms/guestbook'】表示有管理地址,在内容发布栏目列表中点击该栏目链接到该地址。</li>
<!-- <li>管理地址参数若设置【adminUrlParam:'fileDownload=true'】则代表链接模型为文件下载的栏目,新增链接的时候出现文件上传对话框。</li>
<li>管理地址参数若设置【adminUrlParam:'outlineView=true'】则代表文章模型开启大纲视图编辑,在线编辑器左侧显示大纲视图。</li> -->
</ul>
</div>
</div>
</div>
</div>
<div class="form-unit">${text('其他信息')}</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label class="control-label col-sm-2" title="">
<span class="required hide">*</span> ${text('备注信息')}<i class="fa icon-question hide"></i></label>
<div class="col-sm-10">
<#form:textarea path="remarks" rows="4" maxlength="500" class="form-control" />
</div>
</div>
</div>
</div>
<#form:extend collapsed="true" />
<div class="box-footer">
<div class="row">
<div class="col-sm-offset-2 col-sm-10">
@@ -252,7 +253,7 @@
</div>
<% } %>
<script>
$("#inputForm").validate({
$('#inputForm').validate({
submitHandler : function(form) {
js.ajaxSubmitForm($(form), function(data) {
js.showMessage(data.message);

View File

@@ -57,8 +57,8 @@
</div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary btn-sm">${text('查询')}</button>
<button type="reset" class="btn btn-default btn-sm isQuick">${text('重置')}</button>
<button type="submit" class="btn btn-primary btn-sm"><i class="glyphicon glyphicon-search"></i> ${text('查询')}</button>
<button type="reset" class="btn btn-default btn-sm isQuick"><i class="glyphicon glyphicon-repeat"></i> ${text('重置')}</button>
</div>
</#form:form>
<table id="dataGrid"></table>
@@ -67,7 +67,7 @@
</div>
<% } %>
<script>
// 初始化DataGrid对象
//# // 初始化DataGrid对象
$('#dataGrid').dataGrid({
searchForm: $("#searchForm"),
columnModel: [
@@ -77,17 +77,17 @@ $('#dataGrid').dataGrid({
{header:'${text("模型")}', name:'moduleType', index:'a.module_type', width:100, align:"center"},
{header:'${text("排序")}', name:'treeSort', index:'a.tree_sort', width:50, align:"center"},
{header:'${text("导航栏目")}', name:'inMenu', index:'a.in_menu', width:80, fixed:true, align:"center", formatter: function(val, obj, row, act){
return js.getDictLabel(${@DictUtils.getDictListJson('sys_show_hide')}, val, '未知', true);
return js.getDictLabel("#{@DictUtils.getDictListJson('sys_show_hide')}", val, '未知', true);
}},
{header:'${text("栏目列表")}', name:'inList', index:'a.in_list', width:80, fixed:true, align:"center", formatter: function(val, obj, row, act){
return js.getDictLabel(${@DictUtils.getDictListJson('sys_show_hide')}, val, '未知', true);
return js.getDictLabel("#{@DictUtils.getDictListJson('sys_show_hide')}", val, '未知', true);
}},
{header:'${text("展现方式")}', name:'showModes', index:'a.show_modes', width:150, fixed:true, align:"center", formatter: function(val, obj, row, act){
return js.getDictLabel(${@DictUtils.getDictListJson('cms_show_modes')}, val, '未知', true);
return js.getDictLabel("#{@DictUtils.getDictListJson('cms_show_modes')}", val, '未知', true);
}},
{header:'${text("操作")}', name:'actions', width:150, formatter: function(val, obj, row, act){
var actions = [];
//<% if(hasPermi('cms:category:edit')){ %>
//# if(hasPermi('cms:category:edit')){
actions.push('<a href="${ctx}/cms/category/form?categoryCode='+row.categoryCode+'" class="btnList" title="${text("编辑栏目表")}"><i class="fa fa-pencil"></i></a>&nbsp;');
if (row.status == Global.STATUS_NORMAL){
actions.push('<a href="${ctx}/cms/category/disable?categoryCode='+row.categoryCode+'" class="btnList" title="${text("停用栏目表")}" data-confirm="${text("确认要停用该栏目表吗?")}"><i class="glyphicon glyphicon-ban-circle"></i></a>&nbsp;');
@@ -97,19 +97,20 @@ $('#dataGrid').dataGrid({
}
actions.push('<a href="${ctx}/cms/category/delete?categoryCode='+row.categoryCode+'" class="btnList" title="${text("删除栏目表")}" data-confirm="${text("确认要删除该栏目表及所有子栏目表吗?")}" data-deltreenode="'+row.id+'"><i class="fa fa-trash-o"></i></a>&nbsp;');
actions.push('<a href="${ctx}/cms/category/form?parentCode='+row.id+'&site.siteCode=${category.site.siteCode}" class="btnList" title="${text("新增下级栏目表")}"><i class="fa fa-plus-square"></i></a>&nbsp;');
//<% if(hasPermi('cms:category:rebuildIndex')){ %>
//# if(hasPermi('cms:category:rebuildIndex')){
actions.push('<a href="${ctx}/cms/category/rebuildIndex?categoryCode='+row.categoryCode+'" class="btnList" title="${text("重建该栏目索引")}" data-confirm="${text("确认重建该栏目下文章索引吗")}"><i class="fa fa-crosshairs"></i></a>&nbsp;');
//<% } %>
//# }
if (row.status == Global.STATUS_NORMAL){
actions.push('<a href="${ctxFront}/list-'+row.categoryCode+'" target="_blank" title="${text("访问栏目")}"><i class="fa fa-globe"></i></a>&nbsp;');
}
//<% } %>
//# }
return actions.join('');
}}
],
treeGrid: true, // 启用树结构表格
defaultExpandLevel: 0, // 默认展开的层次
expandNodeClearPostData: 'categoryName,siteCode,moduleType,image,href,target,keywords,description,inMenu,inList,showModes,isNeedAudit,isCanComment,customListView,customContentView,viewConfig,status,remarks,', // 展开节点清理请求参数数据(一般设置查询条件的字段属性,否则在查询后,不能展开子节点数据) // 加载成功后执行事件
expandNodeClearPostData: 'categoryName,siteCode,moduleType,image,href,target,keywords,description,inMenu,inList,showModes,isNeedAudit,isCanComment,customListView,customContentView,viewConfig,status,remarks,', // 展开节点清理请求参数数据(一般设置查询条件的字段属性,否则在查询后,不能展开子节点数据)
//# // 加载成功后执行事件
ajaxSuccess: function(data){
}

View File

@@ -34,13 +34,13 @@
</div>
<% } %>
<script>
// 初始化布局
//# // 初始化布局
$('body').layout({
west__size : 180
});
// 主页框架
//# // 主页框架
var win = $("#mainFrame")[0].contentWindow;
// 树结构初始化加载
//# // 树结构初始化加载
var setting = {
view : {selectedMulti : false},
data : {key : {title : "title"}, simpleData : {enable : true}},
@@ -85,7 +85,7 @@ var setting = {
}, null, null, js.text('loading.message'));
};
loadTree();
// 工具栏按钮绑定
//# // 工具栏按钮绑定
$('#btnExpand').click(function() {
tree.expandAll(true);
$(this).hide();

View File

@@ -1,17 +1,17 @@
<% layout('/layouts/default.html', {title: '文章评论表管理', libs: ['validate','fileupload']}){ %>
<div class="main-content">
<div class="box box-main">
<div class="box-header with-border">
<div class="box-title">
<i class="fa fa-list-alt"></i> ${text(comment.isNewRecord ? '新增文章评论表' : '编辑文章评论表')}
</div>
<div class="box-tools pull-right">
<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button>
</div>
</div>
<#form:form id="inputForm" model="${comment}" action="${ctx}/cms/comment/save" method="post" class="form-horizontal">
<div class="box-body">
<div class="form-unit">${text('基本信息')}</div>
<% layout('/layouts/default.html', {title: '文章评论表管理', libs: ['validate','fileupload']}){ %>
<div class="main-content">
<div class="box box-main">
<div class="box-header with-border">
<div class="box-title">
<i class="fa fa-list-alt"></i> ${text(comment.isNewRecord ? '新增文章评论表' : '编辑文章评论表')}
</div>
<div class="box-tools pull-right hide">
<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button>
</div>
</div>
<#form:form id="inputForm" model="${comment}" action="${ctx}/cms/comment/save" method="post" class="form-horizontal">
<div class="box-body">
<div class="form-unit">${text('基本信息')}</div>
<#form:hidden path="id"/>
<div class="row">
<div class="col-xs-6">
@@ -157,32 +157,32 @@
</div>
</div>
</div>
</div>
<div class="box-footer">
<div class="row">
<div class="col-sm-offset-2 col-sm-10">
<% if (hasPermi('cms:comment:edit')){ %>
<button type="submit" class="btn btn-sm btn-primary" id="btnSubmit"><i class="fa fa-check"></i> ${text('保 存')}</button>&nbsp;
<% } %>
<button type="button" class="btn btn-sm btn-default" id="btnCancel" onclick="js.closeCurrentTabPage()"><i class="fa fa-reply-all"></i> ${text('关 闭')}</button>
</div>
</div>
</div>
</#form:form>
</div>
</div>
<% } %>
<script>
$("#inputForm").validate({
submitHandler: function(form){
js.ajaxSubmitForm($(form), function(data){
js.showMessage(data.message);
if(data.result == Global.TRUE){
js.closeCurrentTabPage(function(contentWindow){
contentWindow.page();
});
}
}, "json");
}
});
</div>
<div class="box-footer">
<div class="row">
<div class="col-sm-offset-2 col-sm-10">
<% if (hasPermi('cms:comment:edit')){ %>
<button type="submit" class="btn btn-sm btn-primary" id="btnSubmit"><i class="fa fa-check"></i> ${text('保 存')}</button>&nbsp;
<% } %>
<button type="button" class="btn btn-sm btn-default" id="btnCancel" onclick="js.closeCurrentTabPage()"><i class="fa fa-reply-all"></i> ${text('关 闭')}</button>
</div>
</div>
</div>
</#form:form>
</div>
</div>
<% } %>
<script>
$("#inputForm").validate({
submitHandler: function(form){
js.ajaxSubmitForm($(form), function(data){
js.showMessage(data.message);
if(data.result == Global.TRUE){
js.closeCurrentTabPage(function(contentWindow){
contentWindow.page();
});
}
}, "json");
}
});
</script>

View File

@@ -94,8 +94,8 @@
</div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary btn-sm">${text('查询')}</button>
<button type="reset" class="btn btn-default btn-sm isQuick">${text('重置')}</button>
<button type="submit" class="btn btn-primary btn-sm"><i class="glyphicon glyphicon-search"></i> ${text('查询')}</button>
<button type="reset" class="btn btn-default btn-sm isQuick"><i class="glyphicon glyphicon-repeat"></i> ${text('重置')}</button>
</div>
</#form:form>
<table id="dataGrid"></table>
@@ -105,7 +105,7 @@
</div>
<% } %>
<script>
// 初始化DataGrid对象
//# // 初始化DataGrid对象
$('#dataGrid').dataGrid({
searchForm: $("#searchForm"),
columnModel: [
@@ -125,11 +125,11 @@ $('#dataGrid').dataGrid({
{header:'${text('支持数')}', name:'hitsPlus', index:'a.hits_plus', width:150, align:"center"},
{header:'${text('反对数')}', name:'hitsMinus', index:'a.hits_minus', width:150, align:"center"},
{header:'${text('状态')}', name:'status', index:'a.status', width:150, align:"center", formatter: function(val, obj, row, act){
return js.getDictLabel(${@DictUtils.getDictListJson('sys_search_status')}, val, '${text('未知')}', true);
return js.getDictLabel("#{@DictUtils.getDictListJson('sys_search_status')}", val, '${text('未知')}', true);
}},
{header:'${text('操作')}', name:'actions', width:120, formatter: function(val, obj, row, act){
var actions = [];
//<% if(hasPermi('cms:comment:edit')){ %>
//# if(hasPermi('cms:comment:edit')){
actions.push('<a href="${ctx}/cms/comment/form?id='+row.id+'" class="btnList" title="${text('编辑文章评论表')}"><i class="fa fa-pencil"></i></a>&nbsp;');
if (row.status == Global.STATUS_NORMAL){
actions.push('<a href="${ctx}/cms/comment/disable?id='+row.id+'" class="btnList" title="${text('停用文章评论表')}" data-confirm="${text('确认要停用该文章评论表吗')}"><i class="glyphicon glyphicon-ban-circle"></i></a>&nbsp;');
@@ -138,11 +138,11 @@ $('#dataGrid').dataGrid({
actions.push('<a href="${ctx}/cms/comment/enable?id='+row.id+'" class="btnList" title="${text('启用文章评论表')}" data-confirm="${text('确认要启用该文章评论表吗')}"><i class="glyphicon glyphicon-ok-circle"></i></a>&nbsp;');
}
actions.push('<a href="${ctx}/cms/comment/delete?id='+row.id+'" class="btnList" title="${text('删除文章评论表')}" data-confirm="${text('确认要删除该文章评论表吗')}"><i class="fa fa-trash-o"></i></a>&nbsp;');
//<% } %>
//# }
return actions.join('');
}}
],
// 加载成功后执行事件
//# // 加载成功后执行事件
ajaxSuccess: function(data){
}

View File

@@ -1,17 +1,17 @@
<% layout('/layouts/default.html', {title: '内容举报表管理', libs: ['validate','fileupload']}){ %>
<div class="main-content">
<div class="box box-main">
<div class="box-header with-border">
<div class="box-title">
<i class="fa fa-list-alt"></i> ${text(report.isNewRecord ? '新增内容举报表' : '编辑内容举报表')}
</div>
<div class="box-tools pull-right">
<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button>
</div>
</div>
<#form:form id="inputForm" model="${report}" action="${ctx}/cms/report/save" method="post" class="form-horizontal">
<div class="box-body">
<div class="form-unit">${text('基本信息')}</div>
<% layout('/layouts/default.html', {title: '内容举报表管理', libs: ['validate','fileupload']}){ %>
<div class="main-content">
<div class="box box-main">
<div class="box-header with-border">
<div class="box-title">
<i class="fa fa-list-alt"></i> ${text(report.isNewRecord ? '新增内容举报表' : '编辑内容举报表')}
</div>
<div class="box-tools pull-right hide">
<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button>
</div>
</div>
<#form:form id="inputForm" model="${report}" action="${ctx}/cms/report/save" method="post" class="form-horizontal">
<div class="box-body">
<div class="form-unit">${text('基本信息')}</div>
<#form:hidden path="id"/>
<div class="row">
<div class="row">
@@ -91,32 +91,32 @@
</div>
</div>
</div>
</div>
<div class="box-footer">
<div class="row">
<div class="col-sm-offset-2 col-sm-10">
<% if (hasPermi('cms:report:edit')){ %>
<button type="submit" class="btn btn-sm btn-primary" id="btnSubmit"><i class="fa fa-check"></i> ${text('保 存')}</button>&nbsp;
<% } %>
<button type="button" class="btn btn-sm btn-default" id="btnCancel" onclick="js.closeCurrentTabPage()"><i class="fa fa-reply-all"></i> ${text('关 闭')}</button>
</div>
</div>
</div>
</#form:form>
</div>
</div>
<% } %>
<script>
$("#inputForm").validate({
submitHandler: function(form){
js.ajaxSubmitForm($(form), function(data){
js.showMessage(data.message);
if(data.result == Global.TRUE){
js.closeCurrentTabPage(function(contentWindow){
contentWindow.page();
});
}
}, "json");
}
});
</div>
<div class="box-footer">
<div class="row">
<div class="col-sm-offset-2 col-sm-10">
<% if (hasPermi('cms:report:edit')){ %>
<button type="submit" class="btn btn-sm btn-primary" id="btnSubmit"><i class="fa fa-check"></i> ${text('保 存')}</button>&nbsp;
<% } %>
<button type="button" class="btn btn-sm btn-default" id="btnCancel" onclick="js.closeCurrentTabPage()"><i class="fa fa-reply-all"></i> ${text('关 闭')}</button>
</div>
</div>
</div>
</#form:form>
</div>
</div>
<% } %>
<script>
$("#inputForm").validate({
submitHandler: function(form){
js.ajaxSubmitForm($(form), function(data){
js.showMessage(data.message);
if(data.result == Global.TRUE){
js.closeCurrentTabPage(function(contentWindow){
contentWindow.page();
});
}
}, "json");
}
});
</script>

View File

@@ -46,8 +46,8 @@
</div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary btn-sm">${text('查询')}</button>
<button type="reset" class="btn btn-default btn-sm isQuick">${text('重置')}</button>
<button type="submit" class="btn btn-primary btn-sm"><i class="glyphicon glyphicon-search"></i> ${text('查询')}</button>
<button type="reset" class="btn btn-default btn-sm isQuick"><i class="glyphicon glyphicon-repeat"></i> ${text('重置')}</button>
</div>
</#form:form>
<table id="dataGrid"></table>
@@ -57,7 +57,7 @@
</div>
<% } %>
<script>
// 初始化DataGrid对象
//# // 初始化DataGrid对象
$('#dataGrid').dataGrid({
searchForm: $("#searchForm"),
columnModel: [
@@ -70,7 +70,7 @@ $('#dataGrid').dataGrid({
{header:'${text('举报原因')}', name:'reportCause', index:'a.report_cause', width:150, align:"left"},
{header:'${text('操作')}', name:'actions', width:120, formatter: function(val, obj, row, act){
var actions = [];
//<% if(hasPermi('cms:report:edit')){ %>
//# if(hasPermi('cms:report:edit')){
actions.push('<a href="${ctx}/cms/report/form?id='+row.id+'" class="btnList" title="${text('编辑内容举报表')}"><i class="fa fa-pencil"></i></a>&nbsp;');
if (row.status == Global.STATUS_NORMAL){
actions.push('<a href="${ctx}/cms/report/disable?id='+row.id+'" class="btnList" title="${text('停用内容举报表')}" data-confirm="${text('确认要停用该内容举报表吗')}"><i class="glyphicon glyphicon-ban-circle"></i></a>&nbsp;');
@@ -79,11 +79,11 @@ $('#dataGrid').dataGrid({
actions.push('<a href="${ctx}/cms/report/enable?id='+row.id+'" class="btnList" title="${text('启用内容举报表')}" data-confirm="${text('确认要启用该内容举报表吗')}"><i class="glyphicon glyphicon-ok-circle"></i></a>&nbsp;');
}
actions.push('<a href="${ctx}/cms/report/delete?id='+row.id+'" class="btnList" title="${text('删除内容举报表')}" data-confirm="${text('确认要删除该内容举报表吗')}"><i class="fa fa-trash-o"></i></a>&nbsp;');
//<% } %>
//# }
return actions.join('');
}}
],
// 加载成功后执行事件
//# // 加载成功后执行事件
ajaxSuccess: function(data){
}

View File

@@ -1,27 +1,26 @@
<% layout('/layouts/default.html', {title: '站点管理', libs: ['validate','fileupload','ueditor','dataGrid']}){ %>
<div class="main-content">
<div class="box box-main">
<div class="box-header with-border">
<div class="box-title">
<i class="fa fa-list-alt"></i> ${text(site.isNewRecord ? '新增站点' : '编辑站点')}
</div>
<div class="box-tools pull-right">
<div class="box-tools pull-right hide">
<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button>
</div>
</div>
<#form:form id="inputForm" model="${site}" action="${ctx}/cms/site/save" method="post" class="form-horizontal">
<div class="box-body">
<div class="form-unit">${text('基本信息')}</div>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required ">*</span> ${text('站点名称')}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:input path="siteName" maxlength="100" placeholder="默认站点" class="form-control required"/>
</div>
</div>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required ">*</span> ${text('站点名称')}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:input path="siteName" maxlength="100" placeholder="默认站点" class="form-control required"/>
</div>
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
@@ -53,7 +52,7 @@
<#form:input path="siteSort" maxlength="500" class="form-control required digits"/>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
@@ -71,82 +70,80 @@
<div class="form-group">
<label class="control-label col-sm-2">${text('站点logo')}</label>
<div class="col-sm-10">
<#form:fileupload id="uploadLogo" bizKey="${site.id}" bizType="site_logo" returnPath="true"
filePathInputId="logo"
uploadType="image" readonly="false" maxUploadNum="1" isMini="false"/>
<#form:input path="logo" class="form-control"/>
<#form:fileupload id="uploadLogo" bizKey="${site.id}" bizType="site_logo" returnPath="true"
filePathInputId="logo" uploadType="image" readonly="false" maxUploadNum="1" isMini="false"/>
<#form:input path="logo" class="form-control"/>
</div>
</div>
</div>
</div>
<div class="form-unit">${text('详细信息')}</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label class="control-label col-sm-2" title="">
<span class="required hide">*</span> ${text('描述')}<i class="fa icon-question hide"></i></label>
<div class="col-sm-10">
<#form:textarea path="description" maxlength="500" rows="3" placeholder="填写描述,有助于搜索引擎优化" class="form-control"/>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label class="control-label col-sm-2" title="">
<span class="required hide">*</span> ${text('关键字')}<i class="fa icon-question hide"></i></label>
<div class="col-sm-10">
<#form:input path="keywords" maxlength="500" placeholder="填写关键词,通过,或|分割,有助于搜索引擎优化" class="form-control"/>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required hide">*</span> ${text('主题风格')}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:select path="theme" dictType="cms_theme" class="form-control" />
</div>
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required hide">*</span> ${text('首页视图')}<i class="fa icon-question " title='自定义首页视图名称必须以"index"开始'></i></label>
<div class="col-sm-8">
<#form:select path="customIndexView" items="${indexViewList}" itemLabel="id" itemValue="id" class="form-control " />
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label class="control-label col-sm-2" title="">
<span class="required ">*</span> ${text('版权信息')}<i class="fa icon-question hide"></i></label>
<div class="col-sm-10">
<#form:ueditor name="copyright" path="copyright" maxlength="10000" height="200" class="required"
simpleToolbars="false" readonly="false" outline="false"/>
<div class="form-unit">${text('详细信息')}</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label class="control-label col-sm-2" title="">
<span class="required hide">*</span> ${text('描述')}<i class="fa icon-question hide"></i></label>
<div class="col-sm-10">
<#form:textarea path="description" maxlength="500" rows="3" placeholder="填写描述,有助于搜索引擎优化" class="form-control"/>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label class="control-label col-sm-2" title="">
<span class="required hide">*</span> ${text('关键字')}<i class="fa icon-question hide"></i></label>
<div class="col-sm-10">
<#form:input path="keywords" maxlength="500" placeholder="填写关键词,通过,或|分割,有助于搜索引擎优化" class="form-control"/>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required hide">*</span> ${text('主题风格')}<i class="fa icon-question hide"></i></label>
<div class="col-sm-8">
<#form:select path="theme" dictType="cms_theme" class="form-control" />
</div>
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
<label class="control-label col-sm-4" title="">
<span class="required hide">*</span> ${text('首页视图')}<i class="fa icon-question " title='自定义首页视图名称必须以"index"开始'></i></label>
<div class="col-sm-8">
<#form:select path="customIndexView" items="${indexViewList}" itemLabel="id" itemValue="id" class="form-control " />
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label class="control-label col-sm-2" title="">
<span class="required ">*</span> ${text('版权信息')}<i class="fa icon-question hide"></i></label>
<div class="col-sm-10">
<#form:ueditor name="copyright" path="copyright" maxlength="10000" height="200" class="required"
simpleToolbars="false" readonly="false" outline="false"/>
</div>
</div>
</div>
</div>
<div class="form-unit">${text('其他信息')}</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label class="control-label col-sm-2" title="">
<span class="required hide">*</span> ${text('备注信息')}<i class="fa icon-question hide"></i></label>
<div class="col-sm-10">
<#form:textarea path="remarks" rows="4" maxlength="500" class="form-control"/>
</div>
</div>
</div>
</div>
<div class="form-unit">${text('其他信息')}</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label class="control-label col-sm-2" title="">
<span class="required hide">*</span> ${text('备注信息')}<i class="fa icon-question hide"></i></label>
<div class="col-sm-10">
<#form:textarea path="remarks" rows="4" maxlength="500" class="form-control"/>
</div>
</div>
</div>
</div>
</div>
<div class="box-footer">
<div class="row">
@@ -163,7 +160,7 @@
</div>
<% } %>
<script>
$("#inputForm").validate({
$('#inputForm').validate({
submitHandler: function(form){
js.ajaxSubmitForm($(form), function(data){
js.showMessage(data.message);

View File

@@ -40,8 +40,8 @@
</div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary btn-sm">${text('查询')}</button>
<button type="reset" class="btn btn-default btn-sm isQuick">${text('重置')}</button>
<button type="submit" class="btn btn-primary btn-sm"><i class="glyphicon glyphicon-search"></i> ${text('查询')}</button>
<button type="reset" class="btn btn-default btn-sm isQuick"><i class="glyphicon glyphicon-repeat"></i> ${text('重置')}</button>
</div>
</#form:form>
<table id="dataGrid"></table>
@@ -51,7 +51,7 @@
</div>
<% } %>
<script>
// 初始化DataGrid对象
//# // 初始化DataGrid对象
$('#dataGrid').dataGrid({
searchForm: $("#searchForm"),
columnModel: [
@@ -64,12 +64,12 @@ $('#dataGrid').dataGrid({
{header:'${text("描述")}', name:'description', index:'a.description', width:150, align:"left"},
{header:'${text("主题")}', name:'theme', index:'a.theme', width:150, align:"center"},
{header:'${text("状态")}', name:'status', index:'a.status', width:90, align:"center", formatter: function(val, obj, row, act){
return js.getDictLabel(${@DictUtils.getDictListJson('sys_search_status')}, val, '${text("未知")}', true);
return js.getDictLabel("#{@DictUtils.getDictListJson('sys_search_status')}", val, '${text("未知")}', true);
}},
{header:'${text("创建时间")}', name:'createDate', index:'a.create_date', width:150, align:"center"},
{header:'${text("操作")}', name:'actions', width:150, formatter: function(val, obj, row, act){
var actions = [];
//<% if(hasPermi('cms:site:edit')){ %>
//# if(hasPermi('cms:site:edit')){
actions.push('<a href="${ctx}/cms/site/form?siteCode='+row.siteCode+'" class="btnList" title="${text("编辑站点")}"><i class="fa fa-pencil"></i></a>&nbsp;');
if (row.status == Global.STATUS_NORMAL){
actions.push('<a href="${ctx}/cms/site/disable?siteCode='+row.siteCode+'" class="btnList" title="${text("停用站点")}" data-confirm="${text("确认要停用该站点吗?")}"><i class="glyphicon glyphicon-ban-circle"></i></a>&nbsp;');
@@ -78,17 +78,17 @@ $('#dataGrid').dataGrid({
actions.push('<a href="${ctx}/cms/site/enable?siteCode='+row.siteCode+'" class="btnList" title="${text("启用站点")}" data-confirm="${text("确认要启用该站点吗?")}"><i class="glyphicon glyphicon-ok-circle"></i></a>&nbsp;');
}
actions.push('<a href="${ctx}/cms/site/delete?siteCode='+row.siteCode+'" class="btnList" title="${text("删除站点")}" data-confirm="${text("确认要删除该站点吗?")}"><i class="fa fa-trash-o"></i></a>&nbsp;');
//<% if(hasPermi('cms:site:rebuildIndex')){ %>
//# if(hasPermi('cms:site:rebuildIndex')){
actions.push('<a href="${ctx}/cms/site/rebuildIndex?siteCode='+row.siteCode+'" class="btnList" title="${text("重建该站点索引")}" data-confirm="${text("确认重建该站点文章索引吗")}"><i class="fa fa-crosshairs"></i></a>&nbsp;');
//<% } %>
//# }
if (row.status == Global.STATUS_NORMAL){
actions.push('<a href="${ctxFront}/index-'+row.siteCode+'" target="_blank" title="${text("访问站点")}"><i class="fa fa-globe"></i></a>&nbsp;');
}
//<% } %>
//# }
return actions.join('');
}}
],
// 加载成功后执行事件
//# // 加载成功后执行事件
ajaxSuccess: function(data){
}

View File

@@ -34,13 +34,13 @@
</div>
<% } %>
<script>
// 初始化布局
//# // 初始化布局
$('body').layout({
west__size : 300
});
// 主页框架
//# // 主页框架
var win = $("#mainFrame")[0].contentWindow;
// 树结构初始化加载
//# // 树结构初始化加载
var setting = {
view : { selectedMulti : false },
data : { key : { title : "title" }, simpleData : { enable : true } },
@@ -67,7 +67,7 @@ var setting = {
}, null, null, js.text('loading.message'));
};
loadTree();
// 工具栏按钮绑定
//# // 工具栏按钮绑定
$('#btnExpand').click(function() {
tree.expandAll(true);
$(this).hide();

View File

@@ -1,17 +1,17 @@
<% layout('/layouts/default.html', {title: '访问日志表管理', libs: ['validate','fileupload']}){ %>
<div class="main-content">
<div class="box box-main">
<div class="box-header with-border">
<div class="box-title">
<i class="fa fa-list-alt"></i> ${text(visitLog.isNewRecord ? '新增访问日志表' : '编辑访问日志表')}
</div>
<div class="box-tools pull-right">
<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button>
</div>
</div>
<#form:form id="inputForm" model="${visitLog}" action="${ctx}/cms/visitLog/save" method="post" class="form-horizontal">
<div class="box-body">
<div class="form-unit">${text('基本信息')}</div>
<% layout('/layouts/default.html', {title: '访问日志表管理', libs: ['validate','fileupload']}){ %>
<div class="main-content">
<div class="box box-main">
<div class="box-header with-border">
<div class="box-title">
<i class="fa fa-list-alt"></i> ${text(visitLog.isNewRecord ? '新增访问日志表' : '编辑访问日志表')}
</div>
<div class="box-tools pull-right hide">
<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button>
</div>
</div>
<#form:form id="inputForm" model="${visitLog}" action="${ctx}/cms/visitLog/save" method="post" class="form-horizontal">
<div class="box-body">
<div class="form-unit">${text('基本信息')}</div>
<#form:hidden path="id"/>
<div class="row">
<div class="col-xs-6">
@@ -335,32 +335,32 @@
</div>
</div>
</div>
</div>
<div class="box-footer">
<div class="row">
<div class="col-sm-offset-2 col-sm-10">
<% if (hasPermi('cms:visitLog:edit')){ %>
<button type="submit" class="btn btn-sm btn-primary" id="btnSubmit"><i class="fa fa-check"></i> ${text('保 存')}</button>&nbsp;
<% } %>
<button type="button" class="btn btn-sm btn-default" id="btnCancel" onclick="js.closeCurrentTabPage()"><i class="fa fa-reply-all"></i> ${text('关 闭')}</button>
</div>
</div>
</div>
</#form:form>
</div>
</div>
<% } %>
<script>
$("#inputForm").validate({
submitHandler: function(form){
js.ajaxSubmitForm($(form), function(data){
js.showMessage(data.message);
if(data.result == Global.TRUE){
js.closeCurrentTabPage(function(contentWindow){
contentWindow.page();
});
}
}, "json");
}
});
</div>
<div class="box-footer">
<div class="row">
<div class="col-sm-offset-2 col-sm-10">
<% if (hasPermi('cms:visitLog:edit')){ %>
<button type="submit" class="btn btn-sm btn-primary" id="btnSubmit"><i class="fa fa-check"></i> ${text('保 存')}</button>&nbsp;
<% } %>
<button type="button" class="btn btn-sm btn-default" id="btnCancel" onclick="js.closeCurrentTabPage()"><i class="fa fa-reply-all"></i> ${text('关 闭')}</button>
</div>
</div>
</div>
</#form:form>
</div>
</div>
<% } %>
<script>
$("#inputForm").validate({
submitHandler: function(form){
js.ajaxSubmitForm($(form), function(data){
js.showMessage(data.message);
if(data.result == Global.TRUE){
js.closeCurrentTabPage(function(contentWindow){
contentWindow.page();
});
}
}, "json");
}
});
</script>

View File

@@ -53,8 +53,8 @@
<div class="form-group">
<button type="submit" class="btn btn-primary btn-sm">${text('查询')}</button>
<button type="reset" class="btn btn-default btn-sm isQuick">${text('重置')}</button>
<button type="submit" class="btn btn-primary btn-sm"><i class="glyphicon glyphicon-search"></i> ${text('查询')}</button>
<button type="reset" class="btn btn-default btn-sm isQuick"><i class="glyphicon glyphicon-repeat"></i> ${text('重置')}</button>
</div>
</#form:form>
<table id="dataGrid"></table>
@@ -64,7 +64,7 @@
</div>
<% } %>
<script>
// 初始化DataGrid对象
//# // 初始化DataGrid对象
$('#dataGrid').dataGrid({
searchForm: $("#searchForm"),
columnModel: [
@@ -91,7 +91,7 @@ $('#dataGrid').dataGrid({
{header:'${text('操作')}', name:'actions', width:120, formatter: function(val, obj, row, act){
var actions = [];
//<% if(hasPermi('cms:visitLog:edit')){ %>
//# if(hasPermi('cms:visitLog:edit')){
actions.push('<a href="${ctx}/cms/visitLog/form?id='+row.id+'" class="btnList" title="${text('编辑访问日志表')}"><i class="fa fa-pencil"></i></a>&nbsp;');
if (row.status == Global.STATUS_NORMAL){
actions.push('<a href="${ctx}/cms/visitLog/disable?id='+row.id+'" class="btnList" title="${text('停用访问日志表')}" data-confirm="${text('确认要停用该访问日志表吗')}"><i class="glyphicon glyphicon-ban-circle"></i></a>&nbsp;');
@@ -100,11 +100,11 @@ $('#dataGrid').dataGrid({
actions.push('<a href="${ctx}/cms/visitLog/enable?id='+row.id+'" class="btnList" title="${text('启用访问日志表')}" data-confirm="${text('确认要启用该访问日志表吗')}"><i class="glyphicon glyphicon-ok-circle"></i></a>&nbsp;');
}
actions.push('<a href="${ctx}/cms/visitLog/delete?id='+row.id+'" class="btnList" title="${text('删除访问日志表')}" data-confirm="${text('确认要删除该访问日志表吗')}"><i class="fa fa-trash-o"></i></a>&nbsp;');
//<% } %>
//# }
return actions.join('');
}}
],
// 加载成功后执行事件
//# // 加载成功后执行事件
ajaxSuccess: function(data){
}

View File

@@ -6,12 +6,15 @@ rem *
rem * Author: ThinkGem@163.com
rem */
echo.
echo [<5B><>Ϣ] <20><><EFBFBD>𹤳̰汾<EFBFBD><EFBFBD>Nexus<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
echo [<5B><>Ϣ] <20><><EFBFBD>𹤳̵<EFBFBD>Maven<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
echo.
%~d0
cd %~dp0
call mvn -v
echo.
cd ..
call mvn clean deploy -Dmaven.test.skip=true -Pdeploy

View File

@@ -4,10 +4,12 @@
# * No deletion without permission, or be held responsible to law.
# *
# * Author: ThinkGem@163.com
# *
# */
echo ""
echo "[信息] 部署工程版本到Nexus服务器。"
echo "[信息] 部署工程到Maven服务器。"
echo ""
mvn -v
echo ""
cd ..

View File

@@ -12,6 +12,9 @@ echo.
%~d0
cd %~dp0
call mvn -v
echo.
cd ..
call mvn clean install -Dmaven.test.skip=true -Ppackage

View File

@@ -4,10 +4,12 @@
# * No deletion without permission, or be held responsible to law.
# *
# * Author: ThinkGem@163.com
# *
# */
echo ""
echo "[信息] 打包Web工程,生成war/jar包文件。"
echo "[信息] 打包安装工程生成jar包文件。"
echo ""
mvn -v
echo ""
cd ..

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1006 KiB

After

Width:  |  Height:  |  Size: 3.3 MiB

BIN
modules/core/db/core.xlsx Normal file

Binary file not shown.

View File

@@ -476,6 +476,8 @@ CREATE TABLE js_sys_module
main_class_name varchar(500),
current_version varchar(50),
upgrade_info varchar(300),
gen_base_dir vargraphic(1000),
tpl_category varchar(200),
status char(1) DEFAULT '0' NOT NULL,
create_by varchar(64) NOT NULL,
create_date timestamp NOT NULL,
@@ -699,6 +701,7 @@ CREATE TABLE js_sys_role
desktop_url varchar(255),
data_scope char(1),
biz_scope varchar(255),
sys_codes vargraphic(500),
status char(1) DEFAULT '0' NOT NULL,
create_by varchar(64) NOT NULL,
create_date timestamp NOT NULL,

View File

@@ -476,6 +476,8 @@ CREATE TABLE js_sys_module
main_class_name varchar(500),
current_version varchar(50),
upgrade_info varchar(300),
gen_base_dir varchar(1000),
tpl_category varchar(200),
status char(1) DEFAULT '0' NOT NULL,
create_by varchar(64) NOT NULL,
create_date datetime NOT NULL,
@@ -699,6 +701,7 @@ CREATE TABLE js_sys_role
desktop_url varchar(255),
data_scope char(1),
biz_scope varchar(255),
sys_codes varchar(500),
status char(1) DEFAULT '0' NOT NULL,
create_by varchar(64) NOT NULL,
create_date datetime NOT NULL,

4534
modules/core/db/job.erm Normal file

File diff suppressed because it is too large Load Diff

BIN
modules/core/db/job.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 531 KiB

BIN
modules/core/db/job.xlsx Normal file

Binary file not shown.

View File

@@ -476,6 +476,8 @@ CREATE TABLE [js_sys_module]
[main_class_name] varchar(500),
[current_version] varchar(50),
[upgrade_info] varchar(300),
[gen_base_dir] nvarchar(1000),
[tpl_category] varchar(200),
[status] char(1) DEFAULT '0' NOT NULL,
[create_by] varchar(64) NOT NULL,
[create_date] datetime NOT NULL,
@@ -699,6 +701,7 @@ CREATE TABLE [js_sys_role]
[desktop_url] varchar(255),
[data_scope] char(1),
[biz_scope] varchar(255),
[sys_codes] nvarchar(500),
[status] char(1) DEFAULT '0' NOT NULL,
[create_by] varchar(64) NOT NULL,
[create_date] datetime NOT NULL,

View File

@@ -477,6 +477,8 @@ CREATE TABLE js_sys_module
main_class_name varchar(500) COMMENT '主类全名',
current_version varchar(50) COMMENT '当前版本',
upgrade_info varchar(300) COMMENT '升级信息',
gen_base_dir varchar(1000) COMMENT '生成基础路径',
tpl_category varchar(200) COMMENT '使用的模板',
status char(1) DEFAULT '0' NOT NULL COMMENT '状态0正常 1删除 2停用',
create_by varchar(64) NOT NULL COMMENT '创建者',
create_date datetime NOT NULL COMMENT '创建时间',
@@ -700,6 +702,7 @@ CREATE TABLE js_sys_role
desktop_url varchar(255) COMMENT '桌面地址(仪表盘地址)',
data_scope char(1) COMMENT '数据范围设置0未设置 1全部数据 2自定义数据',
biz_scope varchar(255) COMMENT '适应业务范围(不同的功能,不同的数据权限支持)',
sys_codes varchar(500) COMMENT '包含系统(多个用逗号隔开)',
status char(1) DEFAULT '0' NOT NULL COMMENT '状态0正常 1删除 2停用',
create_by varchar(64) NOT NULL COMMENT '创建者',
create_date datetime NOT NULL COMMENT '创建时间',

View File

@@ -476,6 +476,8 @@ CREATE TABLE js_sys_module
main_class_name varchar2(500),
current_version varchar2(50),
upgrade_info varchar2(300),
gen_base_dir nvarchar2(1000),
tpl_category varchar2(200),
status char(1) DEFAULT '0' NOT NULL,
create_by varchar2(64) NOT NULL,
create_date timestamp NOT NULL,
@@ -699,6 +701,7 @@ CREATE TABLE js_sys_role
desktop_url varchar2(255),
data_scope char(1),
biz_scope varchar2(255),
sys_codes nvarchar2(500),
status char(1) DEFAULT '0' NOT NULL,
create_by varchar2(64) NOT NULL,
create_date timestamp NOT NULL,
@@ -1335,6 +1338,8 @@ COMMENT ON COLUMN js_sys_module.description IS '模块描述';
COMMENT ON COLUMN js_sys_module.main_class_name IS '主类全名';
COMMENT ON COLUMN js_sys_module.current_version IS '当前版本';
COMMENT ON COLUMN js_sys_module.upgrade_info IS '升级信息';
COMMENT ON COLUMN js_sys_module.gen_base_dir IS '生成基础路径';
COMMENT ON COLUMN js_sys_module.tpl_category IS '使用的模板';
COMMENT ON COLUMN js_sys_module.status IS '状态0正常 1删除 2停用';
COMMENT ON COLUMN js_sys_module.create_by IS '创建者';
COMMENT ON COLUMN js_sys_module.create_date IS '创建时间';
@@ -1504,6 +1509,7 @@ COMMENT ON COLUMN js_sys_role.user_type IS '用户类型employee员工 member
COMMENT ON COLUMN js_sys_role.desktop_url IS '桌面地址(仪表盘地址)';
COMMENT ON COLUMN js_sys_role.data_scope IS '数据范围设置0未设置 1全部数据 2自定义数据';
COMMENT ON COLUMN js_sys_role.biz_scope IS '适应业务范围(不同的功能,不同的数据权限支持)';
COMMENT ON COLUMN js_sys_role.sys_codes IS '包含系统(多个用逗号隔开)';
COMMENT ON COLUMN js_sys_role.status IS '状态0正常 1删除 2停用';
COMMENT ON COLUMN js_sys_role.create_by IS '创建者';
COMMENT ON COLUMN js_sys_role.create_date IS '创建时间';

View File

@@ -476,6 +476,8 @@ CREATE TABLE js_sys_module
main_class_name varchar(500),
current_version varchar(50),
upgrade_info varchar(300),
gen_base_dir varchar(1000),
tpl_category varchar(200),
status char(1) DEFAULT '0' NOT NULL,
create_by varchar(64) NOT NULL,
create_date timestamp NOT NULL,
@@ -699,6 +701,7 @@ CREATE TABLE js_sys_role
desktop_url varchar(255),
data_scope char(1),
biz_scope varchar(255),
sys_codes varchar(500),
status char(1) DEFAULT '0' NOT NULL,
create_by varchar(64) NOT NULL,
create_date timestamp NOT NULL,
@@ -1335,6 +1338,8 @@ COMMENT ON COLUMN js_sys_module.description IS '模块描述';
COMMENT ON COLUMN js_sys_module.main_class_name IS '主类全名';
COMMENT ON COLUMN js_sys_module.current_version IS '当前版本';
COMMENT ON COLUMN js_sys_module.upgrade_info IS '升级信息';
COMMENT ON COLUMN js_sys_module.gen_base_dir IS '生成基础路径';
COMMENT ON COLUMN js_sys_module.tpl_category IS '使用的模板';
COMMENT ON COLUMN js_sys_module.status IS '状态0正常 1删除 2停用';
COMMENT ON COLUMN js_sys_module.create_by IS '创建者';
COMMENT ON COLUMN js_sys_module.create_date IS '创建时间';
@@ -1504,6 +1509,7 @@ COMMENT ON COLUMN js_sys_role.user_type IS '用户类型employee员工 member
COMMENT ON COLUMN js_sys_role.desktop_url IS '桌面地址(仪表盘地址)';
COMMENT ON COLUMN js_sys_role.data_scope IS '数据范围设置0未设置 1全部数据 2自定义数据';
COMMENT ON COLUMN js_sys_role.biz_scope IS '适应业务范围(不同的功能,不同的数据权限支持)';
COMMENT ON COLUMN js_sys_role.sys_codes IS '包含系统(多个用逗号隔开)';
COMMENT ON COLUMN js_sys_role.status IS '状态0正常 1删除 2停用';
COMMENT ON COLUMN js_sys_role.create_by IS '创建者';
COMMENT ON COLUMN js_sys_role.create_date IS '创建时间';

View File

@@ -6,7 +6,7 @@
<parent>
<groupId>com.jeesite</groupId>
<artifactId>jeesite-parent</artifactId>
<version>5.4.0-SNAPSHOT</version>
<version>5.7.0-SNAPSHOT</version>
<relativePath>../../parent/pom.xml</relativePath>
</parent>
@@ -29,6 +29,7 @@
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<!-- Oracle 11g -->
<dependency>
<groupId>com.oracle</groupId>
@@ -36,37 +37,33 @@
<version>11.2.0.3</version>
<scope>runtime</scope>
</dependency>
<!-- Oracle 12c
<!-- Oracle 12c 及以上版本
<dependency>
<groupId>com.oracle.ojdbc</groupId>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
<version>19.3.0.0</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.oracle.ojdbc</groupId>
<artifactId>orai18n</artifactId>
<version>19.3.0.0</version>
<scope>runtime</scope>
</dependency> -->
<!-- SqlServer 2008 -->
<!-- SqlServer 2008
<dependency>
<groupId>net.sourceforge.jtds</groupId>
<artifactId>jtds</artifactId>
<scope>runtime</scope>
</dependency>
<!-- SqlServer 2012
</dependency> -->
<!-- SqlServer 2012 及以上版本 -->
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<scope>runtime</scope>
</dependency> -->
</dependency>
<!-- PostgreSQL -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<!-- H2 DB
<dependency>
<groupId>com.h2database</groupId>
@@ -87,6 +84,11 @@
<artifactId>jeesite-framework</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<!--<artifactId>spring-boot-starter-undertow</artifactId>-->
</dependency>
<!-- ELK 日志收集 -->
<dependency>

View File

@@ -2,13 +2,20 @@
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
* No deletion without permission, or be held responsible to law.
*/
package com.jeesite.modules.config;
import java.util.Collection;
import java.util.Map;
import javax.servlet.Filter;
package com.jeesite.autoconfigure.core;
import com.jeesite.common.collect.ListUtils;
import com.jeesite.common.config.Global;
import com.jeesite.common.shiro.cas.CasOutHandler;
import com.jeesite.common.shiro.config.FilterChainDefinitionMap;
import com.jeesite.common.shiro.filter.*;
import com.jeesite.common.shiro.realm.AuthorizingRealm;
import com.jeesite.common.shiro.realm.CasAuthorizingRealm;
import com.jeesite.common.shiro.realm.LdapAuthorizingRealm;
import com.jeesite.common.shiro.session.SessionDAO;
import com.jeesite.common.shiro.session.SessionManager;
import com.jeesite.common.shiro.web.ShiroFilterFactoryBean;
import com.jeesite.common.shiro.web.WebSecurityManager;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.cas.CasSubjectFactory;
import org.apache.shiro.realm.Realm;
@@ -17,49 +24,33 @@ import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.web.filter.InvalidRequestFilter;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import com.jeesite.common.collect.ListUtils;
import com.jeesite.common.config.Global;
import com.jeesite.common.shiro.cas.CasOutHandler;
import com.jeesite.common.shiro.config.FilterChainDefinitionMap;
import com.jeesite.common.shiro.filter.CasFilter;
import com.jeesite.common.shiro.filter.FormFilter;
import com.jeesite.common.shiro.filter.InnerFilter;
import com.jeesite.common.shiro.filter.LdapFilter;
import com.jeesite.common.shiro.filter.LogoutFilter;
import com.jeesite.common.shiro.filter.PermissionsFilter;
import com.jeesite.common.shiro.filter.RolesFilter;
import com.jeesite.common.shiro.filter.UserFilter;
import com.jeesite.common.shiro.realm.AuthorizingRealm;
import com.jeesite.common.shiro.realm.CasAuthorizingRealm;
import com.jeesite.common.shiro.realm.LdapAuthorizingRealm;
import com.jeesite.common.shiro.session.SessionDAO;
import com.jeesite.common.shiro.session.SessionManager;
import com.jeesite.common.shiro.web.ShiroFilterFactoryBean;
import com.jeesite.common.shiro.web.WebSecurityManager;
import javax.servlet.Filter;
import java.util.Collection;
import java.util.Map;
/**
* Shiro配置
* @author ThinkGem
* @version 2021-7-6
* @version 2023-12-20
*/
@SuppressWarnings("deprecation")
@Configuration(proxyBeanMethods = false)
@AutoConfiguration(before = SessionAutoConfiguration.class)
@ConditionalOnProperty(name="user.enabled", havingValue="true", matchIfMissing=true)
public class ShiroConfig {
public class ShiroAutoConfiguration {
/**
* Apache Shiro Filter
*/
@Bean
@Bean("shiroFilterProxy")
@Order(Ordered.HIGHEST_PRECEDENCE + 5000)
@ConditionalOnMissingBean(name="shiroFilterProxy")
public FilterRegistrationBean<Filter> shiroFilterProxy(ShiroFilterFactoryBean shiroFilter) throws Exception {
@@ -69,14 +60,14 @@ public class ShiroConfig {
bean.setOrder(Ordered.HIGHEST_PRECEDENCE + 5000);
return bean;
}
/**
* 内部系统访问过滤器
*/
private InnerFilter shiroInnerFilter() {
return new InnerFilter();
}
/**
* CAS登录过滤器
*/
@@ -85,7 +76,7 @@ public class ShiroConfig {
bean.setAuthorizingRealm(casAuthorizingRealm);
return bean;
}
/**
* LDAP登录过滤器
*/
@@ -133,7 +124,7 @@ public class ShiroConfig {
private UserFilter shiroUserFilter() {
return new UserFilter();
}
/**
* 非法请求过滤器
*/
@@ -142,12 +133,13 @@ public class ShiroConfig {
bean.setBlockNonAscii(false);
return bean;
}
/**
* Shiro认证过滤器
*/
@Bean
public ShiroFilterFactoryBean shiroFilter(WebSecurityManager webSecurityManager, AuthorizingRealm authorizingRealm,
@Bean("shiroFilter")
@ConditionalOnMissingBean(name="shiroFilter")
public ShiroFilterFactoryBean shiroFilter(WebSecurityManager webSecurityManager, AuthorizingRealm authorizingRealm,
CasAuthorizingRealm casAuthorizingRealm, LdapAuthorizingRealm ldapAuthorizingRealm) {
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
bean.setSecurityManager(webSecurityManager);
@@ -169,30 +161,33 @@ public class ShiroConfig {
bean.setFilterChainDefinitionMap(chains.getObject());
return bean;
}
/**
* 系统安全认证实现类
*/
@Bean
public AuthorizingRealm authorizingRealm(SessionDAO sessionDAO) {
@Bean("authorizingRealm")
@ConditionalOnMissingBean(name="authorizingRealm")
public AuthorizingRealm authorizingRealm(@Qualifier("sessionDAO") SessionDAO sessionDAO) {
AuthorizingRealm bean = new AuthorizingRealm();
bean.setSessionDAO(sessionDAO);
return bean;
}
/**
* 单点登录信息句柄单点退出用
*/
@Bean
@Bean("casOutHandler")
@ConditionalOnMissingBean(name="casOutHandler")
public CasOutHandler casOutHandler() {
return new CasOutHandler();
}
/**
* CAS安全认证实现类
*/
@Bean
public CasAuthorizingRealm casAuthorizingRealm(SessionDAO sessionDAO, CasOutHandler casOutHandler) {
@Bean("casAuthorizingRealm")
@ConditionalOnMissingBean(name="casAuthorizingRealm")
public CasAuthorizingRealm casAuthorizingRealm(@Qualifier("sessionDAO") SessionDAO sessionDAO, CasOutHandler casOutHandler) {
CasAuthorizingRealm bean = new CasAuthorizingRealm();
bean.setSessionDAO(sessionDAO);
bean.setCasOutHandler(casOutHandler);
@@ -200,12 +195,13 @@ public class ShiroConfig {
bean.setCasServerCallbackUrl(Global.getProperty("shiro.casClientUrl") + Global.getAdminPath() + "/login-cas");
return bean;
}
/**
* LDAP安全认证实现类
*/
@Bean
public LdapAuthorizingRealm ldapAuthorizingRealm(SessionDAO sessionDAO, CasOutHandler casOutHandler) {
@Bean("ldapAuthorizingRealm")
@ConditionalOnMissingBean(name="ldapAuthorizingRealm")
public LdapAuthorizingRealm ldapAuthorizingRealm(@Qualifier("sessionDAO") SessionDAO sessionDAO, CasOutHandler casOutHandler) {
LdapAuthorizingRealm bean = new LdapAuthorizingRealm();
JndiLdapContextFactory contextFactory = (JndiLdapContextFactory) bean.getContextFactory();
contextFactory.setUrl(Global.getProperty("shiro.ldapUrl"/*, "ldap://127.0.0.1:389"*/));
@@ -217,9 +213,10 @@ public class ShiroConfig {
/**
* 定义Shiro安全管理配置
*/
@Bean
@Bean("webSecurityManager")
@ConditionalOnMissingBean(name="webSecurityManager")
public WebSecurityManager webSecurityManager(AuthorizingRealm authorizingRealm, CasAuthorizingRealm casAuthorizingRealm,
LdapAuthorizingRealm ldapAuthorizingRealm, SessionManager sessionManager, CacheManager shiroCacheManager) {
LdapAuthorizingRealm ldapAuthorizingRealm, SessionManager sessionManager, @Qualifier("shiroCacheManager") CacheManager shiroCacheManager) {
WebSecurityManager bean = new WebSecurityManager();
Collection<Realm> realms = ListUtils.newArrayList();
realms.add(authorizingRealm); // 第一个为权限授权控制类
@@ -232,21 +229,23 @@ public class ShiroConfig {
//bean.setRememberMeManager(null); // 关闭 RememberMe
return bean;
}
/**
* Shiro 生命周期处理器实现初始化和销毁回调
*/
@Bean(name="lifecycleBeanPostProcessor")
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
@Bean("lifecycleBeanPostProcessor")
@ConditionalOnMissingBean(name="lifecycleBeanPostProcessor")
public static LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}
/**
* Shiro 过滤器代理配置
*/
@Bean
@Bean("defaultAdvisorAutoProxyCreator")
@DependsOn({ "lifecycleBeanPostProcessor" })
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
@ConditionalOnMissingBean(name="defaultAdvisorAutoProxyCreator")
public static DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator bean = new DefaultAdvisorAutoProxyCreator();
bean.setProxyTargetClass(true);
return bean;
@@ -255,22 +254,11 @@ public class ShiroConfig {
/**
* 启用Shrio授权注解拦截方式AOP式方法级权限检查
*/
@Bean
@Bean("authorizationAttributeSourceAdvisor")
@ConditionalOnMissingBean(name="authorizationAttributeSourceAdvisor")
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(WebSecurityManager webSecurityManager) {
AuthorizationAttributeSourceAdvisor bean = new AuthorizationAttributeSourceAdvisor();
bean.setSecurityManager(webSecurityManager);
return bean;
}
// /**
// * 在方法中 注入 webSecurityManager 进行代理控制
// */
// @Bean
// public MethodInvokingFactoryBean methodInvokingFactoryBean(DefaultWebSecurityManager webSecurityManager) {
// MethodInvokingFactoryBean bean = new MethodInvokingFactoryBean();
// bean.setStaticMethod("org.apache.shiro.SecurityUtils.setSecurityManager");
// bean.setArguments(new Object[] { webSecurityManager });
// return bean;
// }
}

View File

@@ -14,6 +14,7 @@ import com.jeesite.common.lang.StringUtils;
import com.jeesite.common.network.IpUtils;
import com.jeesite.common.shiro.authc.FormToken;
import com.jeesite.common.shiro.realm.BaseAuthorizingRealm;
import com.jeesite.common.utils.SpringUtils;
import com.jeesite.common.web.CookieUtils;
import com.jeesite.common.web.http.ServletUtils;
import com.jeesite.modules.sys.entity.Log;
@@ -31,7 +32,6 @@ import org.apache.shiro.authz.UnauthorizedException;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.servlet.Cookie;
import org.apache.shiro.web.servlet.Cookie.SameSiteOptions;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.util.WebUtils;
import org.slf4j.Logger;
@@ -60,23 +60,21 @@ public class FormFilter extends org.apache.shiro.web.filter.authc.FormAuthentica
public static final String LOGIN_PARAM = "__login"; // 支持GET方式登录的参数
private static final Logger logger = LoggerFactory.getLogger(FormFilter.class);
private static FormFilter instance;
private static Cookie sessionIdCookie;
private static Cookie rememberUserCodeCookie;
private BaseAuthorizingRealm authorizingRealm;
private Cookie rememberUserCodeCookie; // 记住用户名Cookie
/**
* 构造方法
*/
public FormFilter() {
super();
rememberUserCodeCookie = new SimpleCookie();
sessionIdCookie = SpringUtils.getBean("sessionIdCookie");
rememberUserCodeCookie = new SimpleCookie(sessionIdCookie);
rememberUserCodeCookie.setName(REMEMBER_USERCODE_PARAM);
rememberUserCodeCookie.setPath(Global.getProperty("session.sessionIdCookiePath"));
rememberUserCodeCookie.setSecure(Global.getPropertyToBoolean("session.sessionIdCookieSecure", "false"));
rememberUserCodeCookie.setHttpOnly(Global.getPropertyToBoolean("session.sessionIdCookieHttpOnly", "true"));
String sameSite = Global.getProperty("session.sessionIdCookieSameSite", "Lax"); // Null、None、Lax、Strict
rememberUserCodeCookie.setSameSite(!"Null".equalsIgnoreCase(sameSite) ? SameSiteOptions.valueOf(StringUtils.upperCase(sameSite)) : null);
rememberUserCodeCookie.setMaxAge(Cookie.ONE_YEAR);
instance = this;
}
@@ -200,14 +198,6 @@ public class FormFilter extends org.apache.shiro.web.filter.authc.FormAuthentica
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
return (!isLoginRequest(request, response) && isPermissive(mappedValue)); // 不验证登录状态,只验证登录请求
}
/**
* 跳转登录页时,跳转到默认首页
*/
@Override
protected void redirectToLogin(ServletRequest request, ServletResponse response) throws IOException {
PermissionsFilter.redirectToDefaultPath(request, response);
}
/**
* 地址访问接入验证
@@ -255,6 +245,14 @@ public class FormFilter extends org.apache.shiro.web.filter.authc.FormAuthentica
boolean isLogin = WebUtils.isTrue(request, LOGIN_PARAM);
return super.isLoginSubmission(request, response) || isLogin;
}
/**
* 跳转登录页时,跳转到默认首页
*/
@Override
protected void redirectToLogin(ServletRequest request, ServletResponse response) throws IOException {
PermissionsFilter.redirectToDefaultPath(request, response);
}
/**
* 执行登录方法
@@ -361,20 +359,9 @@ public class FormFilter extends org.apache.shiro.web.filter.authc.FormAuthentica
// 是否显示验证码
data.put("isValidCodeLogin", Global.getConfigToInteger("sys.login.failedNumAfterValidCode", "200") == 0);
//获取当前会话对象
Session session = UserUtils.getSession();
data.put("sessionid", (String)session.getId());
// 如果登录设置了语言,则切换语言
if (paramMap.get("lang") != null){
Global.setLang((String)paramMap.get("lang"), request, response);
}
// 设置公共结果数据
setCommonData(request, response, data, paramMap);
data.put("result", "login");
data.put("demoMode", Global.isDemoMode());
data.put("useCorpModel", Global.isUseCorpModel()
&& Global.getConfigToBoolean("user.loginCodeCorpUnique", "false"));
data.put("title", Global.getProperty("productName"));
return data;
}
@@ -415,30 +402,47 @@ public class FormFilter extends org.apache.shiro.web.filter.authc.FormAuthentica
String corpCode = (String)paramMap.get("corpCode");
User user = UserUtils.getByLoginCode(username, corpCode);
LogUtils.saveLog(user, request, "登录失败", Log.TYPE_LOGIN_LOGOUT);
//获取当前会话对象
Session session = UserUtils.getSession();
data.put("sessionid", (String)session.getId());
// 如果登录设置了语言,则切换语言
// 设置公共结果数据
setCommonData(request, response, data, paramMap);
data.put("result", Global.FALSE);
return data;
}
/**
* 设置公共数据
* @author ThinkGem
*/
private static void setCommonData(HttpServletRequest request, HttpServletResponse response,
Map<String, Object> data, Map<String, Object> paramMap) {
if (ServletUtils.isAjaxRequest(request)) {
Session session = UserUtils.getSession();
data.put("sessionid", session.getId());
Cookie cookie = new SimpleCookie(sessionIdCookie);
cookie.setValue((String)session.getId());
cookie.saveTo(request, response);
}
if (paramMap.get("lang") != null){
Global.setLang((String)paramMap.get("lang"), request, response);
}
data.put("result", Global.FALSE);
data.put("demoMode", Global.isDemoMode());
data.put("useCorpModel", Global.isUseCorpModel()
&& Global.getConfigToBoolean("user.loginCodeCorpUnique", "false"));
data.put("title", Global.getProperty("productName"));
return data;
}
/**
* 获取登录页面数据
* @author ThinkGem
*/
public static Map<String, Object> getLoginSuccessData(User user, Session session) {
public static Map<String, Object> getLoginSuccessData(HttpServletRequest request, HttpServletResponse response,
User user, Session session) {
Map<String, Object> data = MapUtils.newHashMap();
if (ServletUtils.isAjaxRequest(request)) {
Cookie cookie = new SimpleCookie(sessionIdCookie);
cookie.setValue((String)session.getId());
cookie.saveTo(request, response);
}
data.put("user", user); // 设置当前用户信息
data.put("demoMode", Global.isDemoMode());
data.put("useCorpModel", Global.isUseCorpModel());
@@ -448,6 +452,7 @@ public class FormFilter extends org.apache.shiro.web.filter.authc.FormAuthentica
data.put("sysCode", session.getAttribute("sysCode"));
data.put("roleCode", session.getAttribute("roleCode"));
data.put("title", Global.getProperty("productName"));
data.put("lang", Global.getLang());
List<Map<String, Object>> roleList = ListUtils.newArrayList();
String desktopUrl = null;
for (Role role : user.getRoleList()){
@@ -455,6 +460,7 @@ public class FormFilter extends org.apache.shiro.web.filter.authc.FormAuthentica
roleMap.put("roleCode", role.getRoleCode());
roleMap.put("roleName", role.getRoleName());
roleMap.put("isShow", role.getIsShow());
roleMap.put("sysCodes", role.getSysCodes());
roleList.add(roleMap);
if (desktopUrl == null && StringUtils.isNotBlank(role.getDesktopUrl())) {
desktopUrl = role.getDesktopUrl();

View File

@@ -19,15 +19,17 @@ import javax.servlet.http.HttpServletRequest;
*/
public class InnerFilter extends AccessControlFilter {
private static final String[] prefixes = Global.getPropertyToArray("shiro.innerFilterAllowRemoteAddrs", "127.0.0.1");
@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
boolean result = false;
String[] prefixes = (String[])mappedValue;
if (prefixes == null){
prefixes = Global.getPropertyToArray("shiro.innerFilterAllowRemoteAddrs", "127.0.0.1");
prefixes = InnerFilter.prefixes;
}
if (prefixes != null && request instanceof HttpServletRequest){
String ip = request.getRemoteAddr();
String ip = request.getRemoteAddr() + "]";
for (String prefix : prefixes){
result = StringUtils.startsWithIgnoreCase(ip, StringUtils.trim(prefix));
if (result){

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