Compare commits

...

1887 Commits

Author SHA1 Message Date
mula.liu 2c894d9565 1.0.1 2025-04-11 11:22:59 +08:00
mula.liu ccdd2bb463 Commit local changes to README.md 2025-04-11 10:59:19 +08:00
mula.liu 299202fd51 v1.0.1 2025-04-11 10:39:32 +08:00
RuoYi 407f9f46d8 升级tomcat到最新版本9.0.102 2025-03-14 15:35:40 +08:00
RuoYi b1a4884c89 优化代码 2025-03-14 15:35:33 +08:00
RuoYi 45d8fe0c16 update pom.xml 2025-03-04 20:20:04 +08:00
RuoYi 63800dcbd1 优化导出Excel日期格式双击离开后与设定的格式不一致问题 2025-03-01 15:45:54 +08:00
RuoYi 7a787b5830 HttpUtils加入请求类型传参 2025-03-01 15:45:06 +08:00
RuoYi 30f31c63ff 优化空指针异常时日志无法记录错误信息问题 2025-02-28 19:48:59 +08:00
RuoYi 6c3e3af074 升级tomcat到最新版本9.0.100 2025-02-28 12:24:58 +08:00
RuoYi 21cd7b452a 新增表格参数(自定义radio/checkbox的name值) 2025-02-27 20:23:59 +08:00
RuoYi 53e20d414b 优化代码 2025-02-27 20:23:51 +08:00
RuoYi 9f1089ff71 添加新群号:180208928 2025-02-27 10:56:49 +08:00
RuoYi 5bbddedc80 移除login_name更新字段 2025-02-26 17:00:26 +08:00
RuoYi 2537abd095 修复successCallback方法对于非特定表格类型无响应问题(IBG6ZD) 2025-02-26 12:23:50 +08:00
RuoYi 568787a12a 修复定时任务参数值带括号时异常问题(IBEBOX) 2025-02-26 10:45:58 +08:00
RuoYi a3b8727b94 copyright 2025 2025-01-07 10:26:29 +08:00
RuoYi d98e2adb37 add permission 2024-12-30 12:09:24 +08:00
RuoYi e9e0718895 若依 v4.8.0 2024-12-26 10:14:55 +08:00
RuoYi adf61988fe 代码生成新增配置是否允许文件覆盖到本地 2024-12-25 12:00:03 +08:00
RuoYi 7c1cdcd73f 修复多选下拉框open导致页签空白问题(IBBP7A) 2024-12-24 23:59:56 +08:00
RuoYi e011eaea48 升级jquery.validate到最新版本v1.21.0 2024-12-24 19:52:48 +08:00
RuoYi 120d549170 优化select2下拉框必填背景色无法清空问题(IBB9XN) 2024-12-24 15:58:02 +08:00
若依 ddd858ca73
!536 Fix version 4.7.9 SQL Injection
Merge pull request !536 from mrlihd/fix-479-sqli
2024-12-24 04:00:09 +00:00
Linh Hoang 0cdb4c7b9c Add vertical tab to blacklist 2024-12-23 16:21:49 +00:00
RuoYi 9c9bbc8e2c update README 2024-12-13 20:17:14 +08:00
RuoYi 4aac0058ea 修复类匿名注解访问失效问题 2024-12-11 12:38:57 +08:00
RuoYi 6bc1a6aeb1 优化时间控件清除按钮样式问题(IBA1NL) 2024-12-10 16:30:36 +08:00
RuoYi 9a833095cf 优化导入带标题文件关闭清理(IB9Q9U) 2024-12-10 16:11:41 +08:00
RuoYi a47b6e350e 修复未被代理类匿名访问失效问题(IB4EJ0) 2024-12-10 14:20:56 +08:00
RuoYi e0aad97d59 优化表格图片预览动态路径显示问题 2024-12-10 13:28:45 +08:00
RuoYi 1aa973d300 列宽拖动长内容自适应显示 2024-12-07 14:19:06 +08:00
RuoYi 39ebc000f0 Excel注解支持wrapText是否允许内容换行 2024-12-03 08:45:32 +08:00
RuoYi 50a53dfc97 修复导出子列表对象只能在最后的问题 2024-12-02 20:35:58 +08:00
RuoYi 54ba9b8c02 update ry-ui.js 2024-11-13 21:55:39 +08:00
RuoYi e728c37b64 add timezone 2024-11-12 13:07:43 +08:00
RuoYi 0eaeba0298 update pom.xml 2024-11-08 16:30:36 +08:00
RuoYi 7b6ed52181 升级pom依赖到安全版本(IAWCAE) 2024-11-08 16:03:41 +08:00
RuoYi 72868aeb6f 支持自定义显示Excel属性列 2024-11-07 22:11:27 +08:00
RuoYi c0afd904d0 修复匿名注解空值无效的问题(IASXHN) 2024-11-06 20:53:06 +08:00
RuoYi cac84c1bab 升级spring-framework到安全版本(IASFCW) 2024-11-06 20:08:15 +08:00
RuoYi fb4f63c883 优化身份证脱敏正则 2024-10-21 17:20:08 +08:00
RuoYi 66ebd480e1 升级oshi到最新版本6.6.5 2024-10-18 20:41:43 +08:00
RuoYi 758dd95c07 添加新群号:232896766 2024-10-18 20:41:22 +08:00
RuoYi c0ce3fd7c2 修复角色禁用权限不失效问题 2024-09-21 10:58:42 +08:00
RuoYi 9b68013b2a 用户导入响应消息对名称安全处理 2024-09-13 21:13:04 +08:00
RuoYi c34d9f0c09 修复记住我请求头过大的问题 2024-09-09 10:29:12 +08:00
RuoYi 3b968d735f 修复记住我失效的问题(IAPHA4) 2024-09-06 20:16:22 +08:00
RuoYi b2a491c99a update content 2024-09-04 19:40:09 +08:00
RuoYi 13fffa0ba8 优化异步树表格折叠同步子状态 2024-09-03 19:07:24 +08:00
RuoYi d9fbae538b 升级oshi到最新版本6.6.3 2024-08-30 21:19:35 +08:00
RuoYi adb22846a4 update sqlkeyword 2024-08-30 21:14:12 +08:00
RuoYi 5bef005075 修改时间范围日期格式 2024-07-08 16:26:49 +08:00
RuoYi ad5cd1921e 升级commons.io到最新版本2.16.1 2024-07-03 11:39:00 +08:00
RuoYi c6c8f8b3fb remove sub resultType 2024-07-03 11:06:05 +08:00
RuoYi e9550ab5bd 优化代码 2024-06-27 16:44:51 +08:00
RuoYi 447542656a 修复主子表数据显示问题(IA61OI) 2024-06-24 17:19:49 +08:00
RuoYi 32e448b6b4 添加新群号:287843737 2024-06-13 14:59:19 +08:00
RuoYi 116bed00a5 优化数据权限代码 2024-06-13 14:58:04 +08:00
RuoYi 4f5bf990bf 若依 v4.7.9 2024-06-06 09:08:49 +08:00
RuoYi 0144cb855f 优化代码 2024-06-05 11:53:53 +08:00
RuoYi e8f9bfb5c6 新增表格示例(保存状态) 2024-06-03 13:31:33 +08:00
RuoYi 56b1354496 升级oshi到最新版本6.6.1 2024-06-03 13:31:11 +08:00
RuoYi 8e1a89bcbe 升级druid到最新版本1.2.23 2024-06-03 13:30:50 +08:00
RuoYi 4c9bfd8683 升级bootstrap-table到最新版本1.22.6 2024-06-03 13:29:36 +08:00
RuoYi ec6d84aa88 Excel注解新增属性comboReadDict 2024-06-02 19:08:47 +08:00
RuoYi 05c29a2a6c update mapper 2024-06-01 17:55:50 +08:00
RuoYi 18ef1ea816 update sql css 2024-06-01 17:45:01 +08:00
RuoYi 3c574b45dc 代码生成支持表单布局选项 2024-06-01 11:54:05 +08:00
RuoYi 0e08cc7ca4 优化代码生成模板格式 2024-06-01 09:55:33 +08:00
RuoYi b2d832edab 优化代码生成主子表关联查询方式 2024-06-01 09:31:17 +08:00
RuoYi 60889185d8 新增表格示例(全文检索) 2024-05-31 11:25:27 +08:00
RuoYi b95280aba2 优化导入Excel时设置dictType属性重复查缓存问题 2024-05-30 13:31:34 +08:00
RuoYi 96b2c0d9b7 update sql 2024-05-29 12:20:37 +08:00
RuoYi f0efa914fe 优化代码 2024-05-29 12:20:14 +08:00
RuoYi edb1c614d0 限制用户操作数据权限范围 2024-05-29 12:19:57 +08:00
RuoYi 61c2e96aaa 新增表格示例(虚拟滚动) 2024-05-13 10:58:48 +08:00
RuoYi f31e6bd1bb 优化树表格align属性在标题生效(I9FVBJ) 2024-04-18 09:48:01 +08:00
RuoYi f5805fd79e 新增Anonymous匿名访问不鉴权注解 2024-04-15 13:49:50 +08:00
RuoYi 55913e8707 升级spring-framework到安全版本,防止漏洞风险 2024-04-11 16:31:12 +08:00
RuoYi 45f71a5125 新增数据脱敏过滤注解 2024-04-08 13:14:40 +08:00
RuoYi 4218cf7cfd Excel注解ColumnType类型新增文本 2024-03-22 16:20:02 +08:00
RuoYi 4963454f23 升级oshi到最新版本6.5.0 2024-03-15 09:20:47 +08:00
RuoYi 85cf318a94 update locale 2024-03-13 17:09:00 +08:00
RuoYi 82a0eaed4a 优化代码 2024-03-13 16:33:13 +08:00
RuoYi f6ce55be47 定义统一Locale获取国际化(I8Z7DA) 2024-03-13 11:38:35 +08:00
RuoYi fd37e8b4a7 定时任务白名单配置范围缩小 2024-03-11 11:15:11 +08:00
RuoYi d43fea60e2 update copyright 2024 2024-03-11 09:40:08 +08:00
RuoYi 05075e21a3 joblog order by 2024-03-11 09:39:53 +08:00
RuoYi f2f6b25ed2 用户密码新增非法字符验证 2024-03-01 21:50:45 +08:00
RuoYi 4a5ea50a14 update gen pom.xml 2024-03-01 21:50:34 +08:00
RuoYi 81c1ffb07e 升级oshi到最新版本6.4.13 2024-02-29 14:14:01 +08:00
RuoYi 6dd8bbfc38 定时任务屏蔽违规的字符 2024-02-29 14:13:51 +08:00
RuoYi bcb6222c61 优化匹配方式 2024-02-29 14:13:38 +08:00
RuoYi 0ce40fc039 升级oshi到最新版本6.4.11 2024-01-19 11:54:25 +08:00
RuoYi 0cde5c2446 update http user-agent 2024-01-15 10:55:10 +08:00
若依 69714747d7
!481 【轻量级 PR】:更新HttpUtils中的默认User-Agent
Merge pull request !481 from coderWu/master
2024-01-15 02:25:30 +00:00
RuoYi 83b90c3267 通知公告新增详细显示 2024-01-12 11:57:22 +08:00
RuoYi 5b19d33af9 优化登录注册页面 2024-01-09 19:49:18 +08:00
RuoYi c8fd0b0470 优化登录注册页面 2024-01-09 19:46:56 +08:00
RuoYi 8c8d53a9cc 修复重置日期时出现的异常问题(I8PZFA) 2024-01-09 15:45:40 +08:00
coderwu f84b77993c 更新HttpUtils中的User-Agent 2024-01-08 22:24:56 +08:00
RuoYi 192c0c5241 修复tooltip单击复制文本不生效的问题 2024-01-08 15:18:03 +08:00
RuoYi 92d121175d 默认加载layer扩展皮肤 2024-01-08 15:15:04 +08:00
RuoYi d6e599d6ac 未修改初始密码弹框提醒 2024-01-04 11:24:07 +08:00
RuoYi a4c8026265 升级oshi到最新版本6.4.8 2023-12-05 11:36:30 +08:00
RuoYi 90022df5a6 升级commons.io到最新版本2.13.0 2023-12-05 11:36:12 +08:00
RuoYi 0699c2350a 添加新群号:174942938 2023-11-27 10:13:18 +08:00
RuoYi fd4fe83e9f 修复页签关闭后存在的跳转问题(I8JDIS) 2023-11-25 15:43:51 +08:00
RuoYi 4933ea6d2f 操作日志列表重置回第一页 2023-11-25 15:43:28 +08:00
RuoYi 07ddbfeabf 修复高频率定时任务不执行问题(I8IQSX) 2023-11-25 15:43:15 +08:00
RuoYi 8db4a059d9 若依 v4.7.8 2023-11-23 10:39:05 +08:00
RuoYi 11a59e7f77 update style 2023-11-22 15:12:00 +08:00
RuoYi f2f27c7ea3 升级jquery到最新版v3.7.1 2023-11-22 11:38:22 +08:00
RuoYi e3be485727 通用detail详细信息弹窗不显示按钮 2023-11-22 11:37:50 +08:00
RuoYi 752dd06cd9 升级druid到最新版本1.2.20 2023-11-22 11:08:46 +08:00
RuoYi a2d0fd7057 用户列表新增抽屉效果详细信息 2023-11-22 11:08:12 +08:00
RuoYi 09b41e8b24 用户列表新增抽屉效果详细信息 2023-11-22 09:20:42 +08:00
RuoYi 40835fa733 升级layui到最新版本v2.8.18 2023-11-22 09:13:45 +08:00
RuoYi b838533558 升级layer到最新版本v3.7.0 2023-11-22 09:06:35 +08:00
RuoYi 6994ee771c 角色列表显示数据权限 2023-11-21 22:23:29 +08:00
RuoYi 7be8b2fbe1 升级oshi到最新版本6.4.7 2023-11-20 12:09:11 +08:00
RuoYi 61bc1891c3 升级pagehelper到最新版1.4.7 2023-11-20 12:08:51 +08:00
RuoYi b7f015cd07 升级shiro到最新版本1.13.0 2023-11-20 12:08:30 +08:00
RuoYi d18cd2e662 重置密码鼠标按下显示密码 2023-11-20 12:07:39 +08:00
RuoYi 5f941c6b87 优化注释错误 2023-11-20 12:07:11 +08:00
RuoYi 7d91e58594 优化数字金额大写转换精度丢失问题 2023-11-10 16:29:24 +08:00
RuoYi d7f58f4128 升级oshi到最新版本6.4.6 2023-10-21 15:00:48 +08:00
RuoYi 52b9f43ea0 新增isScrollToTop页签切换滚动到顶部 2023-09-27 19:29:13 +08:00
RuoYi ff6845f5ce a标签#更换为javascript:; 2023-09-27 18:01:45 +08:00
RuoYi e4e2faa93b 修复用户管理跳转部门页签显示问题(I84PGJ) 2023-09-27 12:02:40 +08:00
RuoYi 8dd40158ec 操作日志列表新增IP地址查询 2023-09-26 09:19:30 +08:00
RuoYi 64e6ae4fe4 优化Tab页签切换,会滚动到页面顶部问题(I841ER) 2023-09-26 09:15:41 +08:00
RuoYi f05195d373 优化菜单管理类型为按钮状态可选(I7VZEJ) 2023-09-18 14:38:28 +08:00
RuoYi fbeacbb026 修复自定义字典样式不生效的问题 2023-09-14 17:46:28 +08:00
RuoYi 24d21eda23 修复横向菜单关闭最后一个页签状态问题(I7SVPK) 2023-09-14 10:31:10 +08:00
RuoYi 2cb417dab2 删除无用的传参 2023-09-01 09:40:26 +08:00
RuoYi 6c89c9896a 修复Excels导入时无法获取到dictType字典值问题(I7M4PW) 2023-08-21 15:59:06 +08:00
RuoYi 705e627908 Excel导入数据临时文件无法删除问题 2023-08-19 16:12:16 +08:00
RuoYi 049ca00930 升级oshi到最新版本6.4.4 2023-08-14 19:21:53 +08:00
RuoYi 43dd9ae664 Excel自定义数据处理器增加单元格/工作簿对象 2023-08-13 17:35:28 +08:00
RuoYi 8445d6a078 新增表格参数(数据值为空时显示的内容undefinedText) 2023-08-13 14:57:42 +08:00
RuoYi bf58ce6067 修复弹窗按钮启用禁用方法无效问题(I7L0WA) 2023-08-13 13:05:19 +08:00
RuoYi 364b471d2b 新增定时任务页去除状态选项(I7KU2E) 2023-08-13 11:35:27 +08:00
RuoYi c2deb14284 树表查询无数据时清除分页信息(I7OB0S) 2023-08-12 16:22:29 +08:00
RuoYi 2ebedeb5df 优化代码 2023-08-12 16:21:23 +08:00
RuoYi e4585f5dcb update maven-plugin 2023-08-12 16:20:33 +08:00
若依 62db29627a
!465 前端定时任务菜单中Cron表达式生成器中-日-选项中的--每小时--应为-每日
Merge pull request !465 from wpengsen/master
2023-08-12 08:09:42 +00:00
RuoYi b15106d139 升级shiro到最新版本1.12.0 2023-07-28 20:27:07 +08:00
wpengsen d7a2e80bf6 前端定时任务菜单中Cron表达式生成器中-日-选项中的--每小时--应为-每日 2023-07-20 10:30:21 +08:00
RuoYi e405becf9a 表格重置默认返回到第一页 2023-07-14 11:04:27 +08:00
RuoYi e8d8325ead 排序属性orderBy参数限制长度 2023-07-06 21:52:18 +08:00
RuoYi c21eb3507b 优化代码 2023-07-06 21:51:35 +08:00
RuoYi c92059d356 update sql 2023-07-06 21:49:52 +08:00
RuoYi b36ba5a16c 升级oshi到最新版本6.4.3 2023-06-29 19:36:45 +08:00
RuoYi cc74bde7be optimized code 2023-06-29 19:36:24 +08:00
RuoYi 7358a2027d 升级spring-boot到最新版本2.5.15 2023-06-23 16:25:39 +08:00
RuoYi 21ea871ada update application.yml 2023-06-23 16:24:41 +08:00
RuoYi 1207052749 修复表格行内编辑启用翻页记住选择无效问题(I72OMA) 2023-05-19 10:26:15 +08:00
RuoYi 6f8a388e8e 升级x-editable到最新版本1.5.3 2023-05-19 10:25:55 +08:00
RuoYi 03201c36e8 若依 v4.7.7 2023-04-14 08:32:07 +08:00
RuoYi aa7ee1aae1 升级oshi到最新版本6.4.1 2023-04-12 15:06:04 +08:00
RuoYi 07f9316935 优化导入用户时更新丢失岗位角色的问题 2023-04-10 18:20:28 +08:00
RuoYi 5e34d68d51 优化代码 2023-04-10 18:20:22 +08:00
RuoYi 5a07a91b50 升级jasny-bootstrap到最新版4.0.0 2023-04-07 19:38:29 +08:00
RuoYi 17abf826e9 优化用户导入更新时需获取用户编号问题 2023-04-07 19:20:38 +08:00
若依 eca27ed5a1
!448 优化用户导入
Merge pull request !448 from 周冰/master
2023-04-07 11:08:15 +00:00
RuoYi 466d8800fc 优化导出Excel时设置dictType属性重复查缓存问题 2023-04-06 15:23:06 +08:00
shui ada2cb426b 用户导入,更新时需获取用户id,用于更新数据 2023-04-03 13:35:32 +08:00
RuoYi f67600df28 支持自定义隐藏属性列过滤子对象 2023-03-17 14:54:24 +08:00
RuoYi 10bbb27684 修复用户注册唯一校验问题(I6MVZS) 2023-03-17 11:24:27 +08:00
若依 a32da911d1
!442 用户多角色,数据权限切面处理时可能出现权限抬升的情况。
Merge pull request !442 from 0慕容雪0/master
2023-03-17 03:21:13 +00:00
0慕容雪0 6a861498ca
update ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/DataScopeAspect.java.
Signed-off-by: 0慕容雪0 <ytu.mxh@163.com>
2023-03-11 04:28:09 +00:00
0慕容雪0 292ac30aa5
update ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/DataScopeAspect.java.
DataScopeAspect,数据权限切面处理类中,用户多角色情况下,若所有角色都不包含传递过来的权限字符,这个时候sqlString也会为空,会导致用户拥有全部数据权限,所以要限制一下, 可以根据conditions集合是否为空,来判断循环时所有角色是否都是在判断权限字符时continue了。
复现方法: 在使用@DataScope注解时permission定义了值,这个值所有角色不包含。


Signed-off-by: 0慕容雪0 <ytu.mxh@163.com>
2023-03-10 07:53:03 +00:00
RuoYi 1e91312f08 日志管理使用索引提升查询性能 2023-02-23 09:29:26 +08:00
RuoYi bee73e87a5 升级layui到最新版本2.7.6 2023-02-23 09:23:26 +08:00
RuoYi a1e2c6e1e6 修复isMatchedIp的参数判断产生空指针的问题 2023-02-22 10:30:49 +08:00
RuoYi 0bbe126125 移除apache/commons-fileupload依赖 2023-02-21 17:18:34 +08:00
RuoYi 590f6a302c 遗漏的优化代码 2023-02-21 16:19:33 +08:00
RuoYi 22470677d4 升级druid到最新版本1.2.16 2023-02-21 13:44:19 +08:00
RuoYi 7040cd26c6 优化代码 2023-02-21 13:43:52 +08:00
RuoYi ac1e66b4b6 日志注解支持排除指定的请求参数 2023-02-20 15:50:15 +08:00
RuoYi 658ed5791b update sql 2023-02-20 15:49:35 +08:00
RuoYi ef0a29552e 支持登录IP黑名单限制 2023-02-20 12:54:02 +08:00
RuoYi 99554659f0 修复异步表格树子项排序问题(I6G2YL) 2023-02-19 22:26:39 +08:00
RuoYi 995eb76c0f 修复冻结列不支持IE浏览器的问题(I6FD4W) 2023-02-19 20:54:55 +08:00
RuoYi dbb312b26e 修复主子表使用suggest插件无法新增问题(I6FA5Z) 2023-02-19 19:29:35 +08:00
RuoYi 9b476399f0 更新fontawesome图标示例 2023-02-19 14:54:08 +08:00
RuoYi e4f70b190c 优化前端属性提醒说明 2023-02-18 16:06:44 +08:00
RuoYi bb5f87658e 新增监控页面图标显示 2023-02-17 08:52:15 +08:00
RuoYi 00f2db99d8 操作日志新增消耗时间属性 2023-02-16 11:57:40 +08:00
RuoYi e26b65ca31 添加新群号:175104288 2023-02-11 12:16:15 +08:00
RuoYi cda00589a4 修复菜单栏快速点击导致展开折叠样式问题(I6CWMP) 2023-02-04 21:56:56 +08:00
RuoYi 3b75d93d6b 连接池Druid支持新的配置connectTimeout和socketTimeout(I6CLL8) 2023-02-04 20:11:34 +08:00
RuoYi 10fb654d23 修复异步加载表格树重置列表父节点展开异常问题(I6AGWH) 2023-02-04 17:32:31 +08:00
RuoYi 432d5ce1be 屏蔽定时任务bean违规的字符 2023-02-04 16:06:04 +08:00
RuoYi f2d5545092 update copyright 2023 2023-02-03 17:41:14 +08:00
若依 8939e21a29
!437 解决单体版本表格行拖拽操作后,列表底部的总共记录条数变成了undefined问题
Merge pull request !437 from chenxin04187/master
2023-02-03 08:43:46 +00:00
若依 b872a84a4a
!436 EhCacheManager改为从bean容器获取,不使用自动装配
Merge pull request !436 from oak/master
2023-02-03 08:31:19 +00:00
William Chen 311cb892a7 解决单体版本表格行拖拽操作后,列表底部的总共记录条数变成了undefined问题。
link https://gitee.com/y_project/RuoYi/issues/I68198
2023-01-23 22:19:34 +08:00
oak fab98274b1 EhCacheManager改为从bean容器获取,不使用自动装配。作用:自建SpringBoot模块如果引用了ruoyi-system并且没有使用shiro,启动会报错。 2023-01-23 16:38:33 +08:00
RuoYi 3e8b211789 升级jquery到最新版v3.6.3 2023-01-19 11:59:10 +08:00
RuoYi c92ed66436 修复页签属性refresh为undefined时页面被刷新问题 2023-01-12 17:31:30 +08:00
RuoYi f1233c85d7 主子表根据序号删除方法加入表格ID参数 2023-01-12 17:31:06 +08:00
RuoYi 9d02f8f7e7 若依 v4.7.6 2022-12-16 08:50:57 +08:00
RuoYi 70205922fc 优化代码 2022-12-13 15:45:13 +08:00
RuoYi f3d1f0afe2 修改参数键名时移除前缓存配置 2022-12-13 15:09:38 +08:00
RuoYi 7ee6ad8aec 升级pagehelper到最新版1.4.6 2022-12-13 14:23:20 +08:00
RuoYi 4ff9afac23 升级oshi到最新版本6.4.0 2022-12-13 14:21:58 +08:00
RuoYi 167970e5c4 优化SQL关键字检查防止注入 2022-12-13 13:17:17 +08:00
若依 29395be19a
!432 优化deleteFile方法返回值,接受File.delete的false返回值
Merge pull request !432 from 岳林/master
2022-12-12 05:48:17 +00:00
fanchenweimin da01f093f8 优化deleteFile方法返回值,接受File.delete的false返回值 2022-12-12 09:41:38 +08:00
RuoYi f53515eb70 升级druid到最新版本1.2.15 2022-12-07 11:55:23 +08:00
RuoYi 84dde0dcf2 升级kaptcha到最新版2.3.3 2022-12-07 10:58:07 +08:00
RuoYi df1c283335 定时任务违规的字符 2022-12-03 11:32:41 +08:00
RuoYi faa4bfaef3 升级oshi到最新版本6.3.2 2022-12-01 11:49:25 +08:00
若依 eef7ef6544
!426 升级shiro到最新版本1.10.1
Merge pull request !426 from Hacker/N/A
2022-11-25 11:05:20 +00:00
Hacker 22d42048ab
升级shiro到最新版本1.10.1
Signed-off-by: Hacker <721806280@qq.com>
2022-11-24 07:31:40 +00:00
RuoYi e5b905c455 优化用户管理重置时取消部门选择(I621OJ) 2022-11-21 13:39:09 +08:00
RuoYi c64f027e66 兼容Excel下拉框内容过多无法显示的问题(I61HCG) 2022-11-21 11:13:02 +08:00
RuoYi 96934ca139 修复操作日志类型多选导出不生效问题(I617FW) 2022-11-15 13:30:43 +08:00
RuoYi f4c763c84d 升级druid到最新版本1.2.14 2022-11-14 11:47:57 +08:00
RuoYi 8cd0d9f366 忽略不必要的属性数据返回 2022-11-12 11:57:08 +08:00
RuoYi 6a7f727f70 优化导出对象的子列表为空会出现[]问题(I60904) 2022-11-11 10:35:32 +08:00
RuoYi 62381f0472 修复sheet超出最大行数异常问题 2022-11-07 11:27:12 +08:00
若依 2952337f15
!420 update ruoyi-framework/src/main/java/com/ruoyi/framework/shiro/session/OnlineSessionFactory.java.
Merge pull request !420 from chenjh/N/A
2022-11-07 03:22:59 +00:00
chenjh c719be609a
update ruoyi-framework/src/main/java/com/ruoyi/framework/shiro/session/OnlineSessionFactory.java.
ServletUtils.getRequest()应改request,可能为空

Signed-off-by: chenjh <asgard2023@outlook.com>
2022-11-06 14:26:47 +00:00
RuoYi 6253e41658 升级oshi到最新版本6.3.0 2022-10-28 21:31:14 +08:00
RuoYi bd0e574268 优化select2搜索下拉后校验必填样式问题(I5VZY0) 2022-10-21 09:48:13 +08:00
RuoYi 6e176c807c 升级bootstrap-fileinput到最新版本5.5.2 2022-10-20 19:12:26 +08:00
RuoYi 2bdf12b1e1 升级shiro到最新版本1.10.0 2022-10-13 10:09:10 +08:00
RuoYi 67f2ba2aa9 修复导出包含空子列表数据异常的问题 2022-10-10 09:00:10 +08:00
RuoYi c105f44eb9 优化树形表格层级显示(I5TQ87) 2022-10-09 21:17:20 +08:00
RuoYi e23a6919af 优化topnav页缺少的样式右括号 2022-10-09 21:17:04 +08:00
RuoYi b362e58646 R isError and isSuccess static 2022-10-09 21:16:52 +08:00
RuoYi db3e571af0 优化代码生成同步后字典值NULL问题 2022-09-28 20:58:11 +08:00
RuoYi 52fe19e933 导入更新用户数据前校验数据权限 2022-09-28 20:58:02 +08:00
RuoYi 7b3ab45ecc 添加新群号:185760789 2022-09-28 10:56:36 +08:00
RuoYi e337f685bc 修改用户登录账号重复验证 2022-09-18 11:25:03 +08:00
RuoYi 13287e02eb 修复关闭父页签后提交无法跳转的问题(I5QBMO) 2022-09-12 10:34:00 +08:00
RuoYi d4a33eab94 优化代码 2022-09-09 10:09:56 +08:00
RuoYi 0ca327f538 若依 v4.7.5 2022-09-05 09:42:15 +08:00
RuoYi 31bd27fcf0 升级jquery到最新版3.6.1 2022-09-03 09:22:34 +08:00
RuoYi dcfc062c01 修复用户分配角色大于默认页数丢失问题(I5OJA8) 2022-09-02 10:19:32 +08:00
RuoYi daa8286804 AjaxResult错误消息结果类型的判断 2022-09-02 10:19:22 +08:00
RuoYi 5a3714e9bc 优化横向菜单下激活菜单样式 2022-08-27 11:54:15 +08:00
RuoYi abe1f0d63e 定时任务支持执行父类方法 2022-08-27 11:54:06 +08:00
RuoYi c95cb70af3 优化多角色数据权限匹配规则 2022-08-22 19:43:27 +08:00
RuoYi 47bd3c4c10 页签创建标题优先data-title属性(I4MC5L) 2022-08-22 19:41:08 +08:00
RuoYi 1c8f55c2c1 新增示例(进度条) 2022-08-20 18:52:26 +08:00
RuoYi 0f9558a825 自动设置切换多个树表格实例配置 2022-08-14 18:34:10 +08:00
RuoYi 8a4d37e975 菜单配置刷新时Tab页签切换时刷新 2022-08-14 10:32:24 +08:00
RuoYi 7fbabe1a8e 升级oshi到最新版本6.2.2 2022-08-14 09:19:19 +08:00
RuoYi 53cd4867df 修复树表onLoadSuccess不生效的问题 2022-08-10 13:07:28 +08:00
RuoYi 7aa4872cb9 优化导出对象的子列表判断条件 2022-08-10 12:47:46 +08:00
RuoYi 8fcc548d34 优化excel/scale属性导出单元格数值类型 2022-08-09 08:01:47 +08:00
RuoYi d318b719fc Excel支持导出对象的子列表方法 2022-08-07 18:19:27 +08:00
RuoYi d6db5963d5 数据逻辑删除不进行唯一验证 2022-08-03 15:54:58 +08:00
RuoYi d5f4bba084 新增主子表提交校验示例 2022-08-02 12:09:11 +08:00
RuoYi 960dee7756 增加对AjaxResult消息结果类型的判断 2022-08-02 12:08:18 +08:00
RuoYi 08f775da4b 优化任务过期不执行调度 2022-07-29 20:07:29 +08:00
RuoYi 2a0fcdea21 升级layui到最新版本v2.7.5 2022-07-28 19:54:55 +08:00
RuoYi 3f0a34e20f 自定义数据权限不排除重复 2022-07-26 14:43:09 +08:00
RuoYi 289161b8c6 升级pagehelper到最新版1.4.3 2022-07-22 14:53:25 +08:00
RuoYi 47b51fe965 支持自定义隐藏Excel属性列 2022-07-21 13:51:09 +08:00
RuoYi 0c0efc9455 Excel注解支持backgroundColor属性设置背景颜色 2022-07-20 09:32:11 +08:00
RuoYi dd86447176 优化多个相同角色数据导致权限SQL重复问题 2022-07-19 15:36:01 +08:00
RuoYi 3427223da2 升级oshi到最新版本6.2.1 2022-07-14 16:16:28 +08:00
RuoYi 1959b02220 升级shiro到最新版本1.9.1 2022-06-29 19:52:38 +08:00
RuoYi acf8ea428f 修改错误命名属性 2022-06-24 23:09:44 +08:00
RuoYi 6e476e40af 新增内容编码/解码方便插件集成使用 2022-06-22 17:46:07 +08:00
若依 25d07b11cc
!395 修复导入导出时,当某字段类型为字典类型或解析类型时,如果有分隔符时无法正确解析的问题
Merge pull request !395 from jinyangaction/master
2022-06-22 09:20:38 +00:00
jinyangcruise 36013e6139 修复导入导出时,当某字段类型为字典类型或解析类型时,如果有分隔符时无法正确解析的问题 2022-06-20 22:23:05 +08:00
RuoYi 87d3c9a93c 升级druid到最新版本1.2.11 2022-06-14 11:30:24 +08:00
RuoYi d1b3f4f397 优化druid开启wall过滤器出现的异常问题 2022-06-13 21:21:28 +08:00
RuoYi 5c5961f1b4 释放焦点,防止打开后按回车反复弹出(I5AA4V) 2022-06-08 19:52:07 +08:00
RuoYi e932a7ead1 若依 v4.7.4 2022-06-01 08:21:04 +08:00
RuoYi 20db92ecf5 修复代码生成拖拽多次出现的排序不正确问题 2022-05-31 09:46:51 +08:00
RuoYi e1c855b091 升级spring-boot到最新版本2.5.14 2022-05-26 11:05:19 +08:00
RuoYi 693498b877 添加新群号:213650505 2022-05-25 11:01:55 +08:00
RuoYi 0ef403d785 升级fastjson到最新版1.2.83 2022-05-24 09:20:26 +08:00
RuoYi d8b2a9a905 用户头像上传格式限制 2022-05-22 12:44:40 +08:00
RuoYi 6df2609d1a 修复客户端分页序号方法显示错误问题 2022-05-22 11:10:12 +08:00
RuoYi 608f05b21b 接口使用泛型使其看到响应属性字段 2022-05-20 10:54:16 +08:00
若依 8145485cff
!385 update ruoyi-common/src/main/java/com/ruoyi/common/core/text/Convert.java.
Merge pull request !385 from np/N/A
2022-05-20 02:48:54 +00:00
若依 7506ac77cb
!384 【轻量级PR】新增SpringUtils.getRequiredProperty,以静态方式获取配置文件中的值
Merge pull request !384 from 阿超/master
2022-05-20 02:48:48 +00:00
RuoYi 5142e2d668 升级oshi到最新版本6.1.6 2022-05-11 09:55:07 +08:00
RuoYi ef1cf982e3 优化excel创建表格样式 2022-05-09 16:57:05 +08:00
np 12d550d2b6
update ruoyi-common/src/main/java/com/ruoyi/common/core/text/Convert.java.
优化Switch case
2022-05-06 02:13:00 +00:00
VampireAchao 2304f95b13 新增SpringUtils.getRequiredProperty,以静态方式获取配置文件中的值 2022-05-04 22:38:03 +08:00
RuoYi a4be143104 升级spring-boot到最新版本2.5.13 2022-04-30 16:38:27 +08:00
RuoYi 0209ed0326 修改显示顺序orderNum类型为整型 2022-04-25 10:23:17 +08:00
RuoYi 55846c5658 Excel注解支持color字体颜色 2022-04-23 20:28:09 +08:00
RuoYi 799815c273 表格冻结列阴影效果显示 2022-04-23 20:27:57 +08:00
RuoYi baa689b098 树表格操作时保留ajaxParams初始参数 2022-04-22 10:04:01 +08:00
RuoYi e4bc44115a 设置分页参数默认值 2022-04-17 10:18:56 +08:00
RuoYi 53bb1da7a1 优化主子表单删方法 2022-04-17 10:18:19 +08:00
RuoYi 977ceb562e 新增获取不带后缀文件名称方法 2022-04-17 10:17:47 +08:00
RuoYi 0264da8d7c 主子表操作列新增单个删除 2022-04-16 21:42:30 +08:00
RuoYi 94e23ec0f8 检查定时任务bean所在包名是否为白名单配置 2022-04-16 21:42:09 +08:00
RuoYi 7610e138dc 字典类型必须以字母开头,且只能为(小写字母,数字,下滑线) 2022-04-16 21:41:24 +08:00
RuoYi b04c6833a3 升级shiro到最新版本1.9.0 2022-04-14 19:00:03 +08:00
RuoYi 035c326071 修复Excel注解prompt/combo同时使用不生效问题 2022-04-03 18:23:21 +08:00
RuoYi e7660d94c9 用户缓存信息添加部门ancestors祖级列表 2022-04-03 18:22:11 +08:00
RuoYi 5f996472e1 修复URL类型回退键被禁止问题 2022-04-03 18:19:44 +08:00
RuoYi 7cbdc0eb8e 优化菜单侧边栏滚动条尺寸及颜色 2022-04-03 18:19:02 +08:00
RuoYi 615aa58bea 升级spring-boot到最新版本2.5.12 防止RCE漏洞 2022-04-02 10:05:49 +08:00
RuoYi de7e2f1bfc 新增清理分页的线程变量方法 2022-03-31 11:52:39 +08:00
RuoYi 41bf76a49f 升级spring-boot到最新版本2.5.11 2022-03-30 10:47:27 +08:00
RuoYi 2a2744a1bf 升级fastjson到最新版1.2.80 2022-03-30 10:47:15 +08:00
RuoYi 757c0eebaf 优化IP地址获取到多个的问题 2022-03-27 11:31:48 +08:00
RuoYi f60cb25245 优化导出excel单元格验证,包含变更为开头.防止正常内容被替换 2022-03-27 11:08:58 +08:00
RuoYi 199eb3f191 添加新群号:139845794 2022-03-24 09:48:37 +08:00
清溪先生 c1de1113c4 修复初始化多表格处理回调函数时获取的表格配置不一致的问题。 2022-03-22 20:40:20 +08:00
RuoYi 19803715be 自定义ShiroFilterFactoryBean防止中文请求被拦截 2022-03-17 19:53:16 +08:00
RuoYi d60d0425bc 优化导出数据LocalDateTime类型无数据问题 2022-03-15 14:38:32 +08:00
RuoYi 28387c46e2 文件上传兼容Weblogic环境 2022-03-09 10:01:11 +08:00
RuoYi 6e06a6a9e8 修复导入Excel时字典字段类型为Long转义为空问题 2022-03-05 08:39:01 +08:00
RuoYi 9a60c27785 修复表格打印组件不识别多层对象属性值问题(I4V7YV) 2022-03-02 19:31:40 +08:00
RuoYi 4613984fb4 若依 v4.7.3 2022-03-01 09:03:50 +08:00
RuoYi 893b29cae8 升级spring-boot到最新版本2.5.10 2022-02-26 09:41:33 +08:00
RuoYi b99efad19c 优化Excel格式化不同类型的日期对象 2022-02-26 09:40:59 +08:00
RuoYi 034e7ec9f0 优化上传文件名称命名规则 2022-02-25 14:54:45 +08:00
RuoYi 72540d01ab 文件上传接口新增原/新文件名返回参数 2022-02-24 15:17:55 +08:00
若依 85677a3349
!373 代码生成预览隐藏临时的文本域.
Merge pull request !373 from Hacker/N/A
2022-02-23 12:51:37 +00:00
Hacker b5301a3632
代码生成预览隐藏临时的文本域. 2022-02-23 10:11:57 +00:00
RuoYi c2743f949e 页面若未匹配到字典标签则返回原字典值 2022-02-23 16:57:07 +08:00
RuoYi a7350294e8 代码生成预览支持复制内容 2022-02-23 09:03:31 +08:00
RuoYi 6d531fb173 优化国际化配置多余的zh请求问题 2022-02-22 17:23:23 +08:00
RuoYi 18517b6dc5 定时任务默认保存到内存中更高效 2022-02-22 17:20:44 +08:00
RuoYi 27889b0a14 表格树支持分页/异步加载 2022-02-22 10:41:19 +08:00
RuoYi 6bd0dc8e05 升级bootstrap-table到最新版本1.19.1 2022-02-21 09:06:55 +08:00
RuoYi 248fe926c5 优化任务队列满时任务拒绝策略 2022-02-21 08:58:40 +08:00
RuoYi 8c6546f5d8 服务监控新增运行参数信息显示 2022-02-20 14:37:33 +08:00
RuoYi b04eac0566 升级pagehelper到最新版1.4.1 2022-02-20 12:16:18 +08:00
RuoYi 6984644313 升级spring-boot-mybatis到最新版2.2.2 2022-02-20 12:16:03 +08:00
RuoYi 174520d259 升级oshi到最新版本6.1.2 2022-02-19 20:59:24 +08:00
RuoYi e4a22fabc5 代码生成同步保留必填/类型选项 2022-02-13 20:57:16 +08:00
RuoYi d770e73e31 fix value 'baos' is always 'null' 2022-02-13 20:54:21 +08:00
RuoYi e73877f0a2 update gitignore 2022-02-12 21:23:16 +08:00
RuoYi 0086cc9f53 优化代码 2022-02-12 21:23:07 +08:00
RuoYi 2f4c975615 修复Xss注解字段值为空时的异常问题 2022-02-10 17:22:33 +08:00
清溪先生 bbfe5889ea
增加StringUtils的导包
Merge pull request !368 from 清溪先生/master
2022-02-02 04:16:54 +00:00
清溪先生 8b2177673b 增加StringUtils的导包 2022-02-02 12:05:25 +08:00
清溪先生 eb0602033d
!367 修复了@xss注解字段值为null时的空指针异常问题
Merge pull request !367 from 清溪先生/master
2022-01-30 13:51:52 +00:00
Awen 210d75be8e 修复了@xss注解字段值为null时的空指针异常问题 2022-01-30 21:45:20 +08:00
RuoYi ed1e7e69a8 用户访问控制时校验数据权限,防止越权 2022-01-27 11:13:59 +08:00
RuoYi e9ebf86ac8 导出Excel时屏蔽公式,防止CSV注入风险 2022-01-27 11:09:50 +08:00
RuoYi 8faea4836d update ry.bat 2022-01-27 11:07:40 +08:00
RuoYi 30f821be49 升级spring-boot到最新版本2.5.9 2022-01-23 11:02:45 +08:00
若依 3361f420c4
!365 修改 ECharts 官网地址为最新
Merge pull request !365 from 网游之鱼/N/A
2022-01-23 03:02:03 +00:00
网游之鱼 07357a8b75
修改 ECharts 官网地址为最新 2022-01-22 05:50:33 +00:00
RuoYi c009c88a5b 添加新群号:298522656 2022-01-21 17:02:23 +08:00
RuoYi 40715336e3 优化加载字典缓存数据 2022-01-14 11:50:14 +08:00
RuoYi 16ec346493 优化代码生成字段更新未同步 2022-01-14 11:50:02 +08:00
RuoYi a11fb3ddf7 update copyright 2022 2022-01-14 09:56:45 +08:00
RuoYi 063ee7f773 定时任务屏蔽违规的字符 2022-01-14 09:56:19 +08:00
RuoYi 008a461968 分页数据新增分页参数合理化参数 2022-01-07 12:28:08 +08:00
RuoYi 36f428d928 优化新版Chrome浏览器回退出现的遮罩层 2022-01-07 11:26:35 +08:00
RuoYi 871c0a115d 修正文字错误 2022-01-07 11:26:24 +08:00
RuoYi 6c3f0c36ff 定时任务目标字符串验证包名白名单 2022-01-06 14:31:09 +08:00
RuoYi 26c76deb5f 定时任务目标字符串过滤参数 2022-01-05 14:46:10 +08:00
RuoYi 20e2b60370 update donate 2022-01-04 20:30:07 +08:00
若依 503e9c3a8e
Create FUNDING.yml 2022-01-04 19:48:30 +08:00
RuoYi cea74fec35 update README.md 2022-01-04 10:36:46 +08:00
RuoYi 9cca7839bc 表格父子视图添加点击事件打开示例 2022-01-02 11:05:51 +08:00
RuoYi 8bcbdc3160 升级log4j2到2.17.1,防止漏洞风险 2021-12-30 14:24:28 +08:00
RuoYi a9e38fa54d 升级spring-boot到最新版本2.5.8 2021-12-27 12:28:12 +08:00
RuoYi a5573315a1 修复EMAIL类型回退键被禁止问题 2021-12-24 10:14:25 +08:00
若依 d7ed5a1f73 !358 解决IE11上传预览不显示的问题
Merge pull request !358 from 网游之鱼/master
2021-12-24 02:08:31 +00:00
RuoYi 4c9c67927b 若依 v4.7.2 2021-12-23 08:39:07 +08:00
hbwf 4a53b718b1 解决IE11上传预览不显示的问题 2021-12-22 11:52:46 +08:00
RuoYi 6f42d2e821 升级oshi到最新版本v5.8.6 2021-12-22 09:57:26 +08:00
RuoYi 07cc5dfa51 升级thymeleaf到最新版3.0.14 阻止远程代码执行漏洞 2021-12-22 09:27:15 +08:00
RuoYi 22881ccb59 工具类异常使用UtilException 2021-12-21 13:55:55 +08:00
RuoYi c44c280b21 升级fastjson到最新版1.2.79 2021-12-21 13:21:16 +08:00
RuoYi 452da5caeb 代码生成创建表检查关键字,防止注入风险 2021-12-21 13:21:03 +08:00
RuoYi c78758e32d 升级log4j2到安全版本,防止漏洞风险 2021-12-19 19:59:32 +08:00
RuoYi 4b7e9152c6 请求分页方法设置成通用方便灵活调用 2021-12-18 10:00:52 +08:00
RuoYi e8e149719a 代码生成创建按钮添加超级管理员权限 2021-12-18 10:00:43 +08:00
若依 d2730a187e !356 前端添加单独的二代身份证校验
Merge pull request !356 from 网游之鱼/N/A
2021-12-18 01:38:24 +00:00
网游之鱼 068483ac6a
前端添加单独的二代身份证校验 2021-12-16 08:40:12 +00:00
RuoYi e597cdead4 优化日期类型错误提示与图标重叠问题 2021-12-16 10:21:33 +08:00
若依 25340da2e2 !355 update ruoyi-admin/src/main/resources/static/ruoyi/css/ry-ui.css.
Merge pull request !355 from 风晓/N/A
2021-12-16 02:18:43 +00:00
风晓 02375cbe7d
update ruoyi-admin/src/main/resources/static/ruoyi/css/ry-ui.css.
日期类型后面会有一个日历的图标,3px的偏移量太小了,错误提示信息会与那个图标重叠。设置为40px可以避开那个日历小图标
2021-12-15 10:46:09 +00:00
RuoYi 5587d39d42 自定义xss校验注解实现 2021-12-15 10:44:40 +08:00
RuoYi ae8f069cbc 升级log4j2到安全版本,防止漏洞风险 2021-12-14 12:09:49 +08:00
RuoYi d6f7423d59 升级log4j2到安全版本,防止漏洞风险 2021-12-14 10:18:11 +08:00
RuoYi 2a3981268a 优化查询用户的角色组&岗位组代码 2021-12-10 21:28:36 +08:00
若依 40263f9549 !350 修复多参数逗号分隔的问题
Merge pull request !350 from 网游之鱼/N/A
2021-12-10 13:27:26 +00:00
RuoYi be8cb965e3 修复插件一起使用出现的已声明报错问题 2021-12-05 11:34:35 +08:00
RuoYi 8a92dc8257 tomcat update 2021-12-02 16:40:39 +08:00
Ricky 2cd634a8de 代码生成主子表优化 2021-11-29 09:23:07 +08:00
网游之鱼 a23af96034 修复多参数逗号分隔的问题 2021-11-26 07:45:50 +00:00
coderyang 78abc63c06 升级velocity到最新版本2.3(语法升级) 2021-11-25 17:24:24 +08:00
RuoYi ba9b483472 进入修改页面方法添加权限标识 2021-11-24 13:55:22 +08:00
RuoYi a21b875402 优化修改/授权角色实时生效 2021-11-24 13:22:54 +08:00
RuoYi 366459e8f3 优化新增部门时验证用户所属部门 2021-11-24 11:45:11 +08:00
RuoYi 7414626137 升级velocity到最新版本2.3 2021-11-24 11:15:17 +08:00
RuoYi 9ff9eb30aa 添加新群号:264355400 2021-11-20 12:01:36 +08:00
RuoYi 4d6ff66187 添加新群号:298522656 2021-11-19 18:40:23 +08:00
RuoYi 0bc9bd2cfb 代码生成主子表模板删除方法缺少事务 2021-11-18 17:58:20 +08:00
RuoYi 7cd98d6dd0 任务参数忽略双引号中的逗号 2021-11-16 11:51:59 +08:00
RuoYi 6d3c988768 若依 v4.7.1 2021-11-10 09:12:31 +08:00
RuoYi 618b81bc93 增加sendGet无参请求方法 2021-11-09 16:52:38 +08:00
RuoYi 16248b6e12 添加新群号:264355400 2021-11-09 09:03:21 +08:00
RuoYi ceba6a91f0 表格实例切换event不能为空 2021-11-08 15:32:57 +08:00
若依 d005057c98 !341 update ruoyi-admin/src/main/resources/static/ruoyi/js/common.js.
Merge pull request !341 from Hacker/N/A
2021-11-01 07:28:19 +00:00
若依 e4738da6fa !340 update ruoyi-admin/src/main/resources/static/ruoyi/js/ry-ui.js.
Merge pull request !340 from Hacker/N/A
2021-11-01 07:22:39 +00:00
Hacker ed8834075e update ruoyi-admin/src/main/resources/static/ruoyi/js/common.js.
input 数字输入框无法删除内容
2021-11-01 07:22:37 +00:00
Hacker 13bba13d6a update ruoyi-admin/src/main/resources/static/ruoyi/js/ry-ui.js. 2021-11-01 07:21:20 +00:00
RuoYi e0b7910d5e 修复无法被反转义问题 2021-10-30 10:58:58 +08:00
RuoYi 086458b89d 多表格切换表单查询参数 2021-10-30 10:28:20 +08:00
RuoYi 775d77ee6d 任务屏蔽违规字符 2021-10-30 10:27:07 +08:00
RuoYi 7c1fa482ba 页签关闭右侧清除iframe元素 2021-10-28 15:45:37 +08:00
RuoYi 7be993eb8d 升级spring-boot到最新版本2.5.6 2021-10-27 15:10:28 +08:00
Ricky 5a9e87c60d 替换自定义验证注解 2021-10-26 16:44:18 +08:00
RuoYi 5f836d249c update ry.sh. 2021-10-22 14:49:41 +08:00
若依 1d0175fb87 !337 修正别字
Merge pull request !337 from 网游之鱼/N/A
2021-10-22 03:24:05 +00:00
网游之鱼 774cff9c52 修正别字 2021-10-16 06:49:37 +00:00
RuoYi 51251331cf 升级oshi到最新版本v5.8.2 2021-10-14 11:58:31 +08:00
若依 2b1c90d249 !335 修改阿里云 Maven 仓库地址为新版地址
Merge pull request !335 from 网游之鱼/N/A
2021-10-14 03:57:24 +00:00
coderyang 14ca1e5c40 注释掉前端传到后端的排序字段 2021-10-13 15:43:13 +08:00
RuoYi 0efa04946b 升级spring-boot-mybatis到最新版2.2.0 2021-10-12 09:57:23 +08:00
RuoYi 96286d5836 升级pagehelper到最新版1.4.0 2021-10-12 09:57:05 +08:00
RuoYi 07e933de5c 升级spring-boot到最新版本2.5.5 2021-10-12 09:56:25 +08:00
Ricky 2ec5eab7bb 调整表单向导文字描述 2021-10-12 09:01:44 +08:00
网游之鱼 601cc1060c 修改阿里云 Maven 仓库地址为新版地址 2021-10-11 01:10:58 +00:00
RuoYi a6bc8e342d Excel导入支持@Excels注解 2021-10-10 16:04:51 +08:00
RuoYi 30c603a733 升级druid到最新版1.2.8 2021-10-10 09:43:16 +08:00
RuoYi a10d09f293 修复select2回退键被禁止问题 2021-10-09 09:39:38 +08:00
RuoYi 5493e21bfd 导入模板添加默认参数 2021-10-09 09:39:26 +08:00
若依 59217e59d0 !334 增加 sendGet 无参判断
Merge pull request !334 from 网游之鱼/N/A
2021-10-09 01:29:52 +00:00
网游之鱼 03b977f5cb 增加 sendGet 无参判断 2021-10-08 03:41:22 +00:00
RuoYi b8a8583598 修复apple/webkit浏览器时间无法格式化 2021-10-03 20:04:38 +08:00
RuoYi 4f50365ac1 设置mybatis默认的执行器 2021-10-03 20:04:21 +08:00
Ricky ee9ff26594 修复新窗口打开页面关闭弹窗报错 2021-09-30 15:58:21 +08:00
Ricky af7339f3b0 优化导入Excel 2021-09-30 15:57:30 +08:00
Ricky 0224f58e52 修复拖拽行数据错位问题 2021-09-30 15:55:38 +08:00
RuoYi 05ee2d0bf4 修正swagger没有指定dataTypeClass导致启动出现warn日志 2021-09-29 18:58:30 +08:00
RuoYi 54d338807e 优化代码生成创建表结构功能 2021-09-29 18:57:52 +08:00
若依 4b6ed674b3 !333 update ruoyi-generator/src/main/resources/templates/tool/gen/edit.html.
Merge pull request !333 from 偶滴神啊/N/A
2021-09-29 10:56:19 +00:00
若依 32ec900f87 !332 启动脚本中参数[-jar]和参数值[AppName]对应写到一起
Merge pull request !332 from lixifun/启动脚本修改
2021-09-29 10:54:21 +00:00
若依 5b160a275b !331 代码生成的模块增加创建表功能。
Merge pull request !331 from 刘宗奇/master
2021-09-29 10:35:37 +00:00
偶滴神啊 c6b6295b26 update ruoyi-generator/src/main/resources/templates/tool/gen/edit.html.
我本地碰到了  undefined 的时候 
var html = $.common.sprintf("<input class='form-control' type='text' name='columns[%s].dictType' value='%s' id='columns_dict_%s'>", index, value, row.columnId);
不生效
2021-09-29 03:41:26 +00:00
lixifun c11ac2e565 启动脚本中的 参数 [-jar] 和参数值 [AppName] 对应写到一起 2021-09-27 14:13:26 +08:00
liuzongqi 912366563b 代码生成功能,增加创建表的功能。 2021-09-26 16:04:44 +08:00
RuoYi 61007b2905 Excel注解支持导入导出标题信息 2021-09-26 09:00:36 +08:00
RuoYi db83718aa6 修复树表代码生成短字段无法识别问题 2021-09-25 09:57:40 +08:00
若依 4c46e41525 !329 🔥 Remove code. 移除无用代码
Merge pull request !329 from Hacker/N/A
2021-09-25 01:54:25 +00:00
RuoYi 69d31e301f 优化记录登录信息,防止不必要的修改 2021-09-24 14:47:25 +08:00
Hacker 314f0e94da 🔥 Remove code. 移除无用代码
Remove code. 移除无用代码
2021-09-24 03:22:59 +00:00
RuoYi ff3d2134a5 新增是否开启页签功能 2021-09-24 09:22:43 +08:00
RuoYi 4a6194274a 升级fastjson到最新版1.2.78 2021-09-24 08:52:30 +08:00
RuoYi bf222b392b 升级thymeleaf-extras-shiro到最新版本v2.1.0 2021-09-23 15:34:58 +08:00
RuoYi 7aebe466d9 Excel注解支持自定义数据处理器 2021-09-22 09:02:39 +08:00
RuoYi 777b05ce6a 防重提交注解支持配置间隔时间/提示消息 2021-09-20 18:43:55 +08:00
RuoYi 9046b96941 reset dataSourceAspect 2021-09-20 18:41:13 +08:00
RuoYi eb6f4c7f92 优化aop语法,使用spring自动注入注解 2021-09-19 08:50:44 +08:00
RuoYi d3899a8d9e 防止Excel导入图片可能出现的异常 2021-09-19 08:50:31 +08:00
RuoYi 4315c0983d 修复富文本回退键被禁止&控制台报错问题 2021-09-18 20:09:01 +08:00
RuoYi 3ea3edc6ba update year 2021-09-18 09:51:04 +08:00
RuoYi dc18ca2274 修复后端主子表代码模板方法名生成错误问题 2021-09-18 09:50:18 +08:00
RuoYi 8fadbef031 日志注解新增是否保存响应参数 2021-09-16 08:58:19 +08:00
RuoYi 7187161621 禁止后退键(Backspace) 2021-09-14 17:07:38 +08:00
RuoYi 17afe54f6f 升级bootstrap-fileinput到最新版本v5.2.4 2021-09-10 15:38:29 +08:00
若依 8ed485c28f !328 update ruoyi-admin/src/main/resources/static/ruoyi/login.js.
Merge pull request !328 from 孙鹏/N/A
2021-09-10 07:31:32 +00:00
孙鹏 b307655251 update ruoyi-admin/src/main/resources/static/ruoyi/login.js.
修改了在IntelliJ IDEA中 ‘空格’ 展示为 ‘NBSP’ 的问题。
2021-09-10 06:40:51 +00:00
RuoYi 38f7ecb671 实例演示中增加多层窗口获取值 2021-09-06 16:44:29 +08:00
RuoYi f51b4f40f1 弹出层openOptions增加动画属性 2021-09-06 16:44:05 +08:00
若依 1530644de5 !327 小写不起作用,大写后功能正常
Merge pull request !327 from yangyang/N/A
2021-09-06 08:19:35 +00:00
yangyang 79fee39b2a 小写不起作用,大写后功能正常 2021-09-06 03:39:26 +00:00
RuoYi c44c9187a9 代码生成导入表按创建时间排序 2021-09-03 09:54:57 +08:00
RuoYi bf2d2cbeb3 若依 v4.7.0 2021-09-01 09:03:16 +08:00
RuoYi 1878b10daa 优化一些小细节 2021-08-31 18:38:21 +08:00
RuoYi 50d200d5c8 删除多余的引用 2021-08-31 16:13:30 +08:00
RuoYi 1b7cead33e 升级shiro到最新版本v1.8.0 2021-08-31 14:32:49 +08:00
RuoYi 164aa611c4 插件引用添加版本参数 2021-08-31 11:12:32 +08:00
RuoYi 8d1ef8586e 升级bootstrap-select到最新版本v1.13.18 2021-08-31 10:39:04 +08:00
RuoYi e4b8b0c30c 升级bootstrap-suggest到最新版本v0.1.29 2021-08-31 10:36:31 +08:00
RuoYi 2c99259a37 升级jquery.validate到最新版本v1.19.3 2021-08-31 10:32:26 +08:00
RuoYi e9f9fc4b92 升级duallistbox到最新版本v3.0.9 2021-08-31 10:28:55 +08:00
RuoYi 58e58915c6 升级cropper到最新版本v1.5.12 2021-08-31 10:26:28 +08:00
RuoYi 007cadbecb 升级select2到最新版v4.0.13 2021-08-31 10:23:05 +08:00
RuoYi 6d27c8bbc7 升级layui到最新版本v2.6.8 2021-08-31 10:16:44 +08:00
RuoYi 9bad76fe22 升级laydate到最新版本v5.3.1 2021-08-31 10:13:10 +08:00
RuoYi 56e09726f4 升级layer到最新版本v3.5.1 2021-08-31 10:11:02 +08:00
RuoYi 3a46b2231e 升级icheck到最新版1.0.3 2021-08-31 10:05:30 +08:00
RuoYi fe31918f76 升级jquery到最新版3.6.0 2021-08-31 09:43:56 +08:00
RuoYi 489ab40a8c 优化弹出层显示在顶层窗口 2021-08-30 16:26:26 +08:00
RuoYi f68f4824cd 优化部门列表树排除条件 2021-08-30 15:05:33 +08:00
RuoYi 08fc4740d5 表单重置开始/结束时间控件 2021-08-27 11:51:20 +08:00
RuoYi 1bbf7b8a03 表达式生成器窗口最大最小化 2021-08-27 11:51:06 +08:00
RuoYi f100ed7cca 修改时检查用户数据权限范围 2021-08-24 15:27:04 +08:00
RuoYi 44cb080932 定时任务对检查异常进行事务回滚 2021-08-24 11:15:45 +08:00
RuoYi 8f1f47e60e 添加新群号:101526938 2021-08-21 09:41:07 +08:00
RuoYi 5e4c71a3aa 补充定时任务表字段注释 2021-08-20 11:06:28 +08:00
RuoYi 5334d8b2a5 定时任务屏蔽ldap远程调用 2021-08-19 12:26:14 +08:00
RuoYi 2796a96872 优化异常信息 2021-08-16 15:13:04 +08:00
RuoYi 51a5cc65c7 修正方法名单词拼写错误 2021-08-16 10:30:15 +08:00
RuoYi 184cc11d1c Excel注解图片导入兼容xls 2021-08-13 10:49:19 +08:00
RuoYi 5ca33901c5 补充遗漏的@Override注解 2021-08-13 10:16:33 +08:00
RuoYi 4ec04eda71 定时任务支持在线生成cron表达式 2021-08-12 16:29:50 +08:00
RuoYi e39f8f9127 Excel注解支持Image图片导入 2021-08-11 09:35:05 +08:00
若依 f34cd1d9b8 !321 update ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java.
Merge pull request !321 from Hacker/N/A
2021-08-11 01:31:57 +00:00
Hacker 3bf25cc829 update ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java. 2021-08-10 03:40:35 +00:00
RuoYi 0606663fe8 支持配置是否开启记住我功能 2021-08-10 11:39:17 +08:00
若依 89719f0570 !320 update ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java.
Merge pull request !320 from Hacker/N/A
2021-08-10 03:32:24 +00:00
若依 6acfb0d5d9 !319 update ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java.
Merge pull request !319 from Hacker/N/A
2021-08-10 03:32:08 +00:00
Hacker 3f874d04ed update ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java. 2021-08-10 02:48:50 +00:00
RuoYi fba8008c81 移动端进入首页设置默认样式 2021-08-09 17:36:40 +08:00
Hacker e8782ab4bf update ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java. 2021-08-09 08:10:26 +00:00
RuoYi 4142a733b8 升级bootstrap-fileinput到最新版本5.2.3 2021-08-08 16:48:42 +08:00
RuoYi 3601972228 update bin 2021-08-08 16:48:26 +08:00
RuoYi ef41439260 优化用户不能删除自己 2021-08-06 13:25:11 +08:00
RuoYi e037173e14 提取通用方法到基类控制器 2021-08-06 13:23:38 +08:00
RuoYi a87b1c93c0 默认开始/结束时间绑定控件选择类型 2021-08-06 13:16:02 +08:00
RuoYi 0247a2d965 富文本默认dialogsInBody属性 2021-07-31 17:44:11 +08:00
RuoYi a64d575319 升级commons.io到最新版本v2.11.0 2021-07-31 17:17:53 +08:00
RuoYi c7317ee5b2 优化代码生成模板 2021-07-30 22:16:11 +08:00
RuoYi 1710eeba98 优化代码生成模板 2021-07-30 21:10:17 +08:00
RuoYi db9bd47422 启用父部门状态排除顶级节点 2021-07-30 11:57:33 +08:00
RuoYi 42c7c4fdc6 定时任务屏蔽http(s)远程调用 2021-07-30 10:20:01 +08:00
RuoYi c7e0292da3 查询表格指定列值增加deDuplication是否去重属性 2021-07-30 10:19:46 +08:00
RuoYi 9d83ffab2a 代码生成富文本默认dialogsInBody属性 2021-07-30 10:19:26 +08:00
RuoYi eed4caa44f 修改部门顶级节点报错问题 2021-07-30 10:18:37 +08:00
RuoYi 27277b51d7 优化XSS跨站脚本过滤 2021-07-28 16:37:56 +08:00
RuoYi 15c7578692 去除默认分页合理化参数 2021-07-25 10:36:42 +08:00
RuoYi 57da9f7ffe 升级oshi到最新版本v5.8.0 2021-07-23 18:54:16 +08:00
RuoYi a9c2d891bc 调度日志详细页添加关闭按钮 2021-07-14 13:57:50 +08:00
若依 7af4a4a3b6 !309 修复菜单风格为横向菜单时,因未添加绝对路径导致菜单跳转404的问题
Merge pull request !309 from 轩先生/master
2021-07-12 09:15:59 +00:00
dingyixuan 9727c0846b 修复顶部一级菜单未添加绝对路径导致菜单跳转404的问题 2021-07-12 13:15:19 +08:00
RuoYi 1312c1b20a 升级oshi到最新版本v5.7.5 2021-07-09 10:54:25 +08:00
若依 4ab671f211 !301 当URL请求异常时,增加对请求URL的记录,便于排查问题
Merge pull request !301 from 无名丶小辈/master
2021-07-09 02:34:24 +00:00
若依 8abcd5dda1 !300 common.js 251行标点符号的小问题
Merge pull request !300 from lyqwer/N/A
2021-07-09 02:34:07 +00:00
RuoYi 06edfaddb8 新增示例(多图上传) 2021-07-06 17:54:39 +08:00
RuoYi 7a72ce37e6 升级summernote到最新版本v0.8.18 2021-07-02 18:46:18 +08:00
RuoYi 5f55ce945b 防止富文本点击按钮弹框时,页面会回到顶部 2021-07-02 18:45:38 +08:00
RuoYi 61d65783d6 delete js.map 2021-07-02 18:42:17 +08:00
Ricky 0bcfaafb96 去除多余的favicon.ico引入 2021-07-02 09:33:30 +08:00
RuoYi 1063cd7dcf 若依 v4.6.2 2021-07-01 09:07:37 +08:00
RuoYi f765dbc2f6 优化表格树显示 2021-06-29 20:15:53 +08:00
无名丶小辈 7528a595fc update ruoyi-framework/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java.
当访问异常时,增加对请求URL的记录,便于排查问题
2021-06-24 08:30:47 +00:00
lyqwer 608e7bd792 common.js 251行标点符号的小问题 2021-06-24 07:34:23 +00:00
Ricky b016f3a47f 修复登录页面弹窗文字不显示的问题 2021-06-24 10:31:18 +08:00
RuoYi e431e6d486 升级pagehelper到最新版1.3.1 2021-06-22 17:52:48 +08:00
RuoYi b57f68ed27 允许手动设置对称加密秘钥 2021-06-22 17:52:16 +08:00
Ricky f63590c116 优化表格行拖拽事件处理 2021-06-18 11:37:41 +08:00
Ricky 47075cb6f5 修复示例弹层js报错 2021-06-18 09:21:27 +08:00
若依 abd48b2172 !299 update ry.sh.
Merge pull request !299 from RhythmLian/N/A
2021-06-17 13:26:42 +00:00
RhythmLian e71387b44c update ry.sh. 2021-06-17 05:15:13 +00:00
RuoYi 5fb9263ff5 升级commons.fileupload到最新版本v1.4 2021-06-16 09:11:29 +08:00
RuoYi e235b00e53 升级commons.io到最新版本v2.10.0 2021-06-16 09:10:58 +08:00
RuoYi c11dcc4ee8 新增表格示例(自定义视图分页) 2021-06-15 09:23:24 +08:00
RuoYi 75b7f01723 定时任务屏蔽rmi远程调用 2021-06-15 09:22:55 +08:00
zhangmrit 26dbf4f6a0 刷新options配置 2021-06-10 22:39:20 +08:00
RuoYi 14c1512a94 升级oshi到最新版本v5.7.4 2021-06-10 15:25:39 +08:00
RuoYi d431e50bdf 优化部门启用状态 2021-06-10 15:25:28 +08:00
RuoYi dcf28440f7 新增表格参数(是否支持打印页面showPrint) 2021-06-10 11:11:54 +08:00
RuoYi 3111b66bdb 区分Byte[]类型防止出现死循环 2021-06-10 10:49:07 +08:00
RuoYi f9ba364d9f 限制超级管理员不允许操作 2021-06-10 10:26:11 +08:00
RuoYi 5018a471b7 升级swagger到最新版本v3.0.0 2021-06-09 19:54:38 +08:00
RuoYi 2abe90a93c 升级swagger到最新版本v3.0.0 2021-06-08 15:24:56 +08:00
RuoYi 1b6ca940a6 修复导出角色数据范围翻译缺少仅本人 2021-06-08 15:18:25 +08:00
RuoYi 4b59c590e0 导出Excel文件支持数据流下载方式 2021-06-03 19:19:06 +08:00
RuoYi 3283955284 升级bootstrap-table到最新版本v1.18.3 2021-06-02 17:25:47 +08:00
RuoYi 39bd0225b6 调整main路径下样式路径 2021-06-02 10:56:14 +08:00
Ricky 3e3882a2af 优化图片工具类读取文件 2021-06-02 08:35:27 +08:00
Ricky 48b24be2ef 调整用户测试接口swagger注解 2021-06-01 15:48:26 +08:00
Ricky b6090c6fcd 增加表格重置分页的参数 2021-06-01 09:39:08 +08:00
RuoYi 24b1aa3761 添加bat脚本执行应用 2021-05-31 12:08:49 +08:00
RuoYi da8f3b4cf8 修复表格图片预览移动端宽高无效问题 2021-05-27 16:04:37 +08:00
RuoYi b7c8258399 行拖拽重命名reorder-row-js 2021-05-27 14:57:33 +08:00
RuoYi e1cab589f2 修复两处存在SQL注入漏洞问题 2021-05-27 14:17:34 +08:00
RuoYi dfe7c1a4a3 添加新群号:201531282 2021-05-27 09:15:29 +08:00
RuoYi 2abe93d45b 集成yuicompressor实现(CSS/JS压缩) 2021-05-27 09:15:14 +08:00
RuoYi 387a3f838d 优化参数&字典缓存操作 2021-05-26 19:52:01 +08:00
RuoYi fe204ad7c5 修复druid最新版本数据监控页面刷新后空白问题 2021-05-26 18:14:55 +08:00
RuoYi 1b7c5258f5 新增表格参数(导出方式&导出文件类型) 2021-05-24 10:40:36 +08:00
RuoYi 2a826bd5b5 修正mapper模板注释 2021-05-24 10:38:12 +08:00
RuoYi 293513dc64 修复请求形参未传值记录日志异常问题 2021-05-24 10:37:59 +08:00
RuoYi e821dc6b50 修正方法名单词拼写错误 2021-05-24 10:37:39 +08:00
RuoYi 0e02eb24fa 升级fastjson到最新版1.2.76 2021-05-23 20:07:32 +08:00
RuoYi 6d3518546a 升级druid到最新版本v1.2.6 2021-05-23 20:07:13 +08:00
RuoYi fc5f715a77 升级layer到最新版本v3.5.0 2021-05-16 11:02:53 +08:00
RuoYi b580af1bf3 升级layui到最新版本v2.6.6 2021-05-16 11:02:38 +08:00
RuoYi 478a807ffd 升级laydate到最新版本v5.3.0 2021-05-16 11:02:18 +08:00
RuoYi 4d55f5df17 动态生成密匙,防止默认密钥泄露 2021-05-15 21:54:32 +08:00
RuoYi b9b2b866b2 使用预定义的常量,避免实例化对象 2021-05-11 10:35:49 +08:00
若依 4efad1cd1b !289 [bug修复]树级结构更新子节点的anecstors字段时应把replace替换为replaceFirst
Merge pull request !289 from zhengxl5566/master
2021-05-11 10:27:54 +08:00
若依 f392c41f3e !285 移除多余的if else
Merge pull request !285 from Hacker/N/A
2021-05-11 10:26:25 +08:00
若依 855dfd6b5b !288 [Bug修复]: 修复了删除操作日志时没有记录日志的bug
Merge pull request !288 from lyqwer/master
2021-05-11 10:23:34 +08:00
zhengxl5566 6a14c954e1 [fix]字符串替换bug,replace会从前往后替换所有target,"0,104".replace("0","0,1")的结果是"0,1,10,14"。
此处代码的本意是替换第一个符合的target字符串,应使用replaceFirst
2021-04-30 16:57:05 +08:00
Ricky e29357a612 实例演示弹层组件增加相册层示例 2021-04-30 14:04:25 +08:00
Ricky 1b4c35dbd7 主子表操作封装处理增加文本域类型 2021-04-30 13:43:21 +08:00
Ricky f0c32bc34b 实例演示中弹出表格增加以回调形式回显到父窗体 2021-04-30 13:10:04 +08:00
Ricky 0e9d6794f3 调整验证码路径和代码生成模板注释 2021-04-30 12:07:32 +08:00
ly b89d0573b8 [Bug修复]: 修复了删除操作日志时没有记录日志的bug,让部分权限狗清理作案痕迹时会留下马脚 2021-04-29 17:45:21 +08:00
RuoYi 0a6e493f95 新增示例(表格列拖拽) 2021-04-27 17:12:31 +08:00
RuoYi 0f17e5c433 日志注解兼容获取json类型的参数 2021-04-27 14:49:17 +08:00
Hacker 7648eab19f 移除多余的if else 2021-04-25 16:49:40 +08:00
Ricky d0401944ea 修复表单向导插件有滚动条时底部工具栏无法固定问题 2021-04-21 17:35:40 +08:00
Ricky 322c48882e 优化ExcelUtil空值处理 2021-04-21 09:36:21 +08:00
RuoYi 74f3520693 修正模板字符编码 2021-04-18 12:30:14 +08:00
RuoYi ec7f306a45 升级mybatis到最新版3.5.6 阻止远程代码执行漏洞 2021-04-18 12:28:49 +08:00
RuoYi 2b7ac9ab98 优化代码生成导出模板名称 2021-04-14 11:33:05 +08:00
xiaody.cn 04e00e2b39 修改密码长度提示与提醒一致 2021-04-14 10:55:10 +08:00
RuoYi 5d5dde4a16 若依 v4.6.1 2021-04-12 09:01:51 +08:00
RuoYi e698929ca9 修复横向菜单无法打开页签问题 2021-04-10 22:07:41 +08:00
Ricky a1c9bf1998 优化部门新增和主子表代码生成 2021-04-09 13:38:33 +08:00
RuoYi fa52c64c92 角色单条删除时使其逻辑删除 2021-04-09 12:53:11 +08:00
RuoYi 05dd2520b6 新增示例(导出选择列) 2021-04-08 11:26:43 +08:00
RuoYi 6f9c272b61 新增IE浏览器版本过低提示页面 2021-04-07 17:40:29 +08:00
若依 2ff4f51d0f !279 update ruoyi-admin/src/main/resources/static/ruoyi/js/ry-ui.js.
Merge pull request !279 from java小强/N/A
2021-04-07 17:36:20 +08:00
java小强 e4015e5257 update ruoyi-admin/src/main/resources/static/ruoyi/js/ry-ui.js. 2021-03-29 14:09:54 +08:00
RuoYi 67b3a4f7e2 解锁屏幕打开上次页签 2021-03-27 11:12:29 +08:00
RuoYi 04e7a314f8 个人信息添加手机&邮箱重复验证 2021-03-21 10:54:18 +08:00
RuoYi 9d3f806e0d 操作日志返回参数添加非空验证 2021-03-17 14:57:59 +08:00
RuoYi b773a09938 添加新群号 2021-03-16 16:15:39 +08:00
RuoYi c10c3966fb 数据监控默认账户密码防止越权访问 2021-03-13 10:25:31 +08:00
RuoYi bcbd6322e9 个人中心错误问题 2021-03-13 10:24:54 +08:00
RuoYi e58bad1ae7 velocity剔除commons-collections版本,防止3.2.1版本的反序列化漏洞 2021-03-13 10:24:42 +08:00
若依 27a3083e80 !268 将控制器基类的日志设置成 this.getClass(),这样在日志里就可以记录是在哪个控制器记录的
Merge pull request !268 from phper08/master
2021-03-13 10:13:06 +08:00
RuoYi 25a4b8c285 子表模板默认日期格式化 2021-03-07 12:27:46 +08:00
RuoYi 4a58de4841 升级oshi到最新版本v5.6.0 2021-03-03 13:37:45 +08:00
若依 895850128a !269 【支持MAC M1】服务监控时返回code500,提升jna版本对应新版MAC
Merge pull request !269 from 刘振/feat_upgrade_jna_version
2021-03-03 13:28:57 +08:00
劉振 3ee4dbcfcc 【支持MAC M1】服务监控时返回code500,提升jna版本对应新版MAC 2021-02-27 22:59:27 +09:00
phper08 8a78937164 update ruoyi-common/src/main/java/com/ruoyi/common/core/controller/BaseController.java.
将控制器基类的日志设置成 this.getClass(),这样在日志里就可以记录是在哪个控制器记录的
2021-02-26 14:48:54 +08:00
RuoYi fd8caa01e9 代码生成预览语言根据后缀名高亮显示 2021-02-20 11:06:36 +08:00
RuoYi d2cb20024f 升级SpringBoot到最新版本2.2.13 2021-02-20 11:06:03 +08:00
RuoYi 5889acf196 修改ip字段长度防止ipv6地址长度不够 2021-02-10 11:45:18 +08:00
RuoYi 487e6a3b3a 升级shiro到最新版1.7.1 阻止身份认证绕过漏洞 2021-02-10 11:35:54 +08:00
RuoYi 930308a16f 升级bootstrapTable相关组件到最新版本v1.18.2 2021-02-03 10:14:11 +08:00
RuoYi 15f9c354cd 升级bootstrapTable到最新版本v1.18.0 2021-02-03 10:12:34 +08:00
RuoYi bb367b6620 搜索建议选择后隐藏列表 2021-02-02 16:59:55 +08:00
Ricky 701411132d 主子表示例增加初始化数据 2021-02-01 11:01:51 +08:00
Ricky e69f043cad 优化Excel导入增加空行判断 2021-02-01 10:23:11 +08:00
Ricky 26e6bbcb6a 优化Excel导入增加空行判断 2021-02-01 10:21:34 +08:00
RuoYi 3d12a776bc update loading-sm.gif 2021-01-26 11:07:50 +08:00
RuoYi 68200c98c9 优化更多操作按钮左侧移入内容闪现消失情况 2021-01-24 11:20:11 +08:00
若依 c584de2d8f !257 update ruoyi-common/src/main/java/com/ruoyi/common/utils/html/EscapeUtil.java.
Merge pull request !257 from Hacker/N/A
2021-01-22 13:43:20 +08:00
Ricky 283d92e8aa 修复主子表提交中列隐藏后出现列偏移问题 2021-01-18 17:16:27 +08:00
Hacker f1454d7f82 update ruoyi-common/src/main/java/com/ruoyi/common/utils/html/EscapeUtil.java. 2021-01-18 11:06:33 +08:00
RuoYi bfde76cc2c 单据打印网页时通过hidden-print隐藏元素 2021-01-18 10:33:59 +08:00
RuoYi 3026e9f158 表格销毁清除记住选择数据 2021-01-17 13:19:15 +08:00
Ricky 12d7c4168d 调整Map通用处理工具类中数组参数拼接 2021-01-15 09:19:25 +08:00
RuoYi 74f3bef334 update README.md 2021-01-14 10:12:49 +08:00
RuoYi d4efa77bb6 升级fastjson到最新版1.2.75 2021-01-13 17:12:46 +08:00
Ricky 0ceb2bde2b 增加表格动态列demo 2021-01-11 16:15:42 +08:00
RuoYi bf6ec64f15 代码生成选择主子表关联元素必填 2021-01-11 11:36:29 +08:00
RuoYi 033017c0ab 修复导入数据为负浮点数时,导入结果会丢失精度问题 2021-01-11 11:34:54 +08:00
RuoYi e1c2a28752 升级druid到最新版本v1.2.4 2021-01-06 12:09:33 +08:00
RuoYi 6ba25e1b4a 单据打印示例按钮隐藏 2021-01-06 12:09:22 +08:00
Ricky 082b5d70b1 tree根据Id和Name选中指定节点增加空判断 2020-12-31 11:30:19 +08:00
RuoYi 3faa23b7c0 若依 v4.6.0 2021-01-01 10:07:25 +08:00
RuoYi 9c643e7c08 添加新群号 2020-12-29 10:05:25 +08:00
RuoYi e6fd0c3661 初始列默认字段类型 2020-12-28 16:05:39 +08:00
若依 d95dbf235e !253 代码生成: 数据库文本类型生成表单文本域
Merge pull request !253 from dawn9117/N/A
2020-12-28 15:26:36 +08:00
dawn9117 583b8b79b0 代码生成: 数据库文本类型生成表单文本域 2020-12-28 10:13:27 +08:00
RuoYi 243b993751 Excel注解支持Image图片导出 2020-12-27 10:03:10 +08:00
RuoYi 73ee7bc485 代码生成日期控件区分范围 2020-12-25 09:34:25 +08:00
RuoYi a1ec9a6508 防止错误页返回主页出现嵌套问题 2020-12-24 17:40:03 +08:00
RuoYi de6fa42721 新增示例(标签 & 提示) 2020-12-24 16:50:39 +08:00
RuoYi 9d81ccb528 添加单据打印示例 2020-12-24 12:14:57 +08:00
RuoYi 9abeb6ac41 弹出层openOptions移动端自适应 2020-12-24 12:14:37 +08:00
若依 5e6226a39c !252 update pom.xml.
Merge pull request !252 from Hacker/N/A
2020-12-23 18:21:25 +08:00
Hacker 0098b5cc2a update pom.xml. 2020-12-22 17:58:30 +08:00
若依 bc0a1c8fe0 !251 公共方法(addFull添加信息 全屏)在无参数时没有替换url中参数字符为空的问题
Merge pull request !251 from 小光/master
2020-12-22 17:05:40 +08:00
小光 681fddc387 公共方法(addFull添加信息 全屏)在无参数时没有替换url中参数字符为空的问题 2020-12-22 17:02:50 +08:00
若依 d6a2d09f95 !249 修复主子表editColumn table dataIndex循环bug
Merge pull request !249 from dawn9117/N/A
2020-12-22 14:50:05 +08:00
RuoYi 926f5881ac 使用widthUnit定义选项单位 2020-12-22 14:13:49 +08:00
若依 0499cd8d97 !237 浏览文件解决bootstrap-treetable,表头跟表格宽度不同步的问题
Merge pull request !237 from Vmo/master
2020-12-22 13:34:36 +08:00
dawn9117 223f5d6532 修复主子表editColumn table dataIndex循环bug 2020-12-22 11:10:13 +08:00
RuoYi 3e37ba5f1f 新增表格参数(自定义打印页面模板printPageBuilder) 2020-12-21 12:32:25 +08:00
RuoYi 697a989ab3 新增表格参数(自定义打印页面模板printPageBuilder) 2020-12-21 12:24:09 +08:00
若依 e5f914277e !246 1、修复请求返回值未使用常量web_status.SUCCESS的问题。
Merge pull request !246 from kagome2014/N/A
2020-12-21 10:29:34 +08:00
kagome2014 0c8a6935f2 1、修复请求返回值未使用常量web_status.SUCCESS的问题。 2020-12-21 10:23:02 +08:00
RuoYi bda12d5016 升级SpringBoot到最新版本2.2.12 提升启动速度 2020-12-16 10:05:01 +08:00
RuoYi 78eed9cd56 菜单新增是否刷新页面 2020-12-14 17:36:54 +08:00
RuoYi 9c92d8f87d 新增选项卡是否刷新属性 2020-12-14 15:08:10 +08:00
RuoYi f0e4e1a1a6 修改表格初始参数sortName默认值为undefined 2020-12-12 11:40:43 +08:00
RuoYi 5ac8aea155 获取属性的get方法空值验证 2020-12-12 11:40:31 +08:00
idevmo 2cf1b00b33 解决bootstrap-treetable,表头跟表格宽度不同步的问题 2020-12-11 14:52:34 +08:00
RuoYi 10ac990d36 修复生成主子表外键名错误 2020-12-11 10:30:34 +08:00
若依 ed91f217d2 !235 修复online sessionId大小写bug;修复代码生成: 生成主子表代码, 子表新增数据报错
Merge pull request !235 from dawn9117/N/A
2020-12-11 10:02:29 +08:00
dawn9117 edfaa1210a 修复online sessionId大小写bug;
修复代码生成: 生成主子表代码, 子表新增数据报错
2020-12-09 15:35:11 +08:00
RuoYi ded17a552d 删除用户和角色解绑关联 2020-12-09 10:14:10 +08:00
RuoYi fb480530c8 新增锁定屏幕功能 2020-12-08 15:35:24 +08:00
RuoYi 832b1f4e14 回显数据字典防止空值 2020-12-08 15:34:05 +08:00
若依 9116b722a4 !233 浏览文件密码强度字符范围提示
Merge pull request !233 from Byron.Liu/develop
2020-12-07 14:02:49 +08:00
RuoYi 3f114ccc15 防止匿名访问进行过滤 2020-12-07 13:52:51 +08:00
Byron.Liu f884fc927f 密码强度字符范围提示 2020-12-07 11:33:06 +08:00
RuoYi 438fcc0928 新增密码字符范围提示 2020-12-04 10:48:43 +08:00
RuoYi 35a49e9462 主子表操作添加通用addColumn方法 2020-12-04 10:48:32 +08:00
RuoYi 59ad2b1d5e 升级bitwalker到最新版本1.21 2020-12-04 10:48:18 +08:00
RuoYi 69160bf0da 升级poi到最新版本4.1.2 2020-12-03 12:40:13 +08:00
RuoYi 9e994023a8 Excel支持注解align对齐方式 2020-12-03 12:38:22 +08:00
RuoYi d14ce06afd 升级bootstrap-fileinput到最新版本5.1.3 2020-12-02 15:32:38 +08:00
RuoYi 7776b82c18 表格树加载完成触发tooltip方法 2020-12-02 14:59:26 +08:00
RuoYi 1e761c7e66 升级SpringBoot到最新版本2.1.18 2020-11-30 09:58:21 +08:00
RuoYi c6962a1f8d 修正转换字符串的目标字符集属性 2020-11-30 09:58:10 +08:00
RuoYi 17ab56cf53 新增表格参数(是否显示行间隔色striped) 2020-11-29 17:02:06 +08:00
RuoYi fa69ae7b49 升级bootstrapTable相关组件到最新版本v1.18.0 2020-11-29 16:31:53 +08:00
RuoYi ad3d75c9f2 升级bootstrapTable到最新版本v1.18.0 2020-11-29 16:31:26 +08:00
RuoYi cdccfcbf9b 代码生成删除多余的数字float类型 2020-11-28 11:52:40 +08:00
RuoYi 9d30a4652c Excel支持导入Boolean型数据 2020-11-28 11:51:41 +08:00
若依 c0d66fffcd !230 update ruoyi-common/src/main/java/com/ruoyi/common/utils/reflect/ReflectUtils.java.
Merge pull request !230 from fatfish517/N/A
2020-11-28 11:27:10 +08:00
若依 c7262e4c3e !229 update ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java.
Merge pull request !229 from fatfish517/N/A
2020-11-28 11:27:07 +08:00
若依 07826c687a !232 修复用户详细页面用户编号格式错位
Merge pull request !232 from 嘿白熊/master
2020-11-28 11:20:28 +08:00
X.B-H f3aa0bc673 详细信息展示格式修复 2020-11-27 13:36:45 +08:00
RuoYi 07694e8f40 新增表格参数(渲染完成后执行的事件onPostBody) 2020-11-26 10:22:24 +08:00
RuoYi 08430b192f 防止未初始参数脚本导致的异常 2020-11-25 18:35:17 +08:00
若依 9aa405c203 !231 修复封装类转基础数据空指针异常
Merge pull request !231 from RamaYuYang/master
2020-11-25 18:26:20 +08:00
yuyang bc96bbc9ac 修复Integer为null转基础类型空指针 2020-11-25 13:25:39 +08:00
RuoYi e6500ee26a 升级oshi到最新版本v5.3.6 2020-11-24 16:01:47 +08:00
fatfish517 a8b569a24d update ruoyi-common/src/main/java/com/ruoyi/common/utils/reflect/ReflectUtils.java. 2020-11-24 10:48:34 +08:00
fatfish517 ed0deeb230 update ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java. 2020-11-24 10:45:19 +08:00
RuoYi 30850c1fdf 新增缓存监控功能 2020-11-23 10:18:58 +08:00
RuoYi 784cc3a10f session配置永不过期,不删除在线会话信息 2020-11-23 10:06:00 +08:00
RuoYi 34445af291 树表溢出元素内容隐藏 2020-11-20 11:40:39 +08:00
RuoYi 680ad3a5e0 若依 v4.5.1 2020-11-18 09:36:21 +08:00
RuoYi a825075dd5 全局配置保持和其他应用命名相同 2020-11-17 10:34:04 +08:00
RuoYi 18f6366f2e 阻止任意文件下载漏洞 2020-11-17 09:33:36 +08:00
RuoYi 6ca8c712e3 升级shiro到最新版1.7.0 阻止权限绕过漏洞 2020-11-16 15:10:51 +08:00
RuoYi cefb14e521 新增表格行触发事件(onCheck、onUncheck、onCheckAll、onUncheckAll) 2020-11-12 10:30:15 +08:00
RuoYi c27ea9d3f4 修复多页签关闭非当前选项出现空白问题 2020-11-11 12:17:16 +08:00
RuoYi 80bf31dcbc 升级druid到最新版本v1.2.2 2020-11-05 14:01:19 +08:00
RuoYi 79ab6b558a 2020年双十一云服务器优惠,错过又要等一年 2020-11-04 16:54:55 +08:00
RuoYi 1c83adc507 去除多余的代码 2020-11-04 16:54:36 +08:00
RuoYi 4b265bb193 代码生成预览支持高亮显示 2020-11-04 12:02:51 +08:00
RuoYi 057a390bff mapperLocations配置支持分隔符 2020-11-02 17:05:08 +08:00
若依 f32dd2bd07 !224 MyBatisConfig mapperLocations 不能识别 , 分隔
Merge pull request !224 from GodOfBug/master
2020-11-02 17:01:43 +08:00
GodOfBug 06cde445b5 修复mapperLocations问题 2020-11-02 16:21:35 +08:00
RuoYi 7a6a109a8c 权限调整 2020-10-22 19:58:32 +08:00
Ricky a955d38ef1 个人中心头像和上传头像增加默认图片 2020-10-22 18:07:59 +08:00
RuoYi 685e090f2f 权限调整 2020-10-22 17:13:10 +08:00
Ricky 207126847e 个人中心头像和上传头像增加默认图片 2020-10-22 09:40:31 +08:00
RuoYi 64a0a05b14 若依 v4.5.0 2020-10-20 09:41:15 +08:00
RuoYi 5332756526 修复代码生成模板文件上传组件缺少ctx的问题 2020-10-19 13:32:13 +08:00
Ricky 260370c328 修复代码生成模板文件上传组件缺少ctx的问题 2020-10-19 12:44:55 +08:00
RuoYi 707b51b247 格式化前端代码 2020-10-18 12:05:21 +08:00
RuoYi 896cbb0842 关闭缓存统计信息 2020-10-17 19:24:27 +08:00
RuoYi d59bd8b8c4 修正拼写错误 2020-10-17 17:55:36 +08:00
RuoYi ee8a9ad78b 去除用户手机邮箱部门必填验证 2020-10-17 09:58:55 +08:00
RuoYi 509a6e1a73 注册账号设置默认用户名称及密码最后更新时间 2020-10-17 09:56:08 +08:00
RuoYi 64c865cc70 添加检查密码范围支持的特殊字符包括:~!@#$%^&*()-=_+ 2020-10-16 10:04:51 +08:00
RuoYi 471c8825ba 账号密码支持自定义更新周期 2020-10-15 17:34:26 +08:00
RuoYi e0523d1c2d 初始密码支持自定义修改策略 2020-10-15 13:27:46 +08:00
RuoYi aa0c930682 用户修改新密码不能与旧密码相同 2020-10-15 13:15:08 +08:00
RuoYi 182c377ecb 调整sql默认时间 2020-10-15 13:06:19 +08:00
RuoYi 3f9d0cf2ea 新增日期格式化方法 2020-10-14 14:38:37 +08:00
若依 951a4d3707 !222 解决代码生成没有bit类型的问题
Merge pull request !222 from natsuki-kining/master
2020-10-13 18:02:10 +08:00
natsuki_kining 0139ed2a07 解决代码生成没有bit类型的问题 2020-10-13 17:35:02 +08:00
RuoYi 74ec5204fe 树结构加载添加callBack回调方法 2020-10-13 12:05:06 +08:00
Ricky 7d8b7ba2d5 解决用户管理页面滚动返回顶部条失效 2020-10-12 11:47:15 +08:00
RuoYi 406889ae07 升级pagehelper到最新版1.3.0 2020-10-10 16:25:51 +08:00
Ricky be47059951 回显数据字典(字符串数组)增加空值判断 2020-10-10 12:01:19 +08:00
RuoYi 5fd26b2d47 升级druid到最新版本v1.2.1 2020-10-09 11:51:45 +08:00
RuoYi 12f4d99dcf 升级fastjson到最新版1.2.74 2020-10-09 11:50:38 +08:00
RuoYi 6019db240a 更换过期二维码 2020-10-09 11:50:10 +08:00
RuoYi 1f0b417d9d 修改前端密码长度校验和错误提示不符问题 2020-10-06 16:42:10 +08:00
RuoYi 22efbd0bcf jna指定版本 2020-10-03 11:51:36 +08:00
RuoYi 5a769dbdb2 update README.md 2020-09-30 19:29:17 +08:00
RuoYi 63f394b0e9 优化代码 2020-09-30 15:57:06 +08:00
若依 80ff14f88f !211 代码生成增加createBy、updateBy
Merge pull request !211 from Wanchen/master
2020-09-30 15:55:04 +08:00
若依 a12b54dcbf !214 AjaxResult重写put方法,以方便链式调用
Merge pull request !214 from 刘星/master
2020-09-30 15:52:36 +08:00
若依 d2059ee282 !217 增强验证码校验的语义,更易懂
Merge pull request !217 from Gszekt/N/A
2020-09-30 15:43:55 +08:00
若依 a5d9dd8068 !220 修改session同步逻辑错误
Merge pull request !220 from Gszekt/master
2020-09-29 19:55:47 +08:00
Gszekt 145660138c 修改session同步逻辑错误 2020-09-29 19:23:37 +08:00
RuoYi 74445e76c3 添加导入数据弹出窗体自定义宽高 2020-09-29 17:48:37 +08:00
RuoYi 03c952d819 用户信息参数返回忽略掉密码字段 2020-09-29 17:08:36 +08:00
Gszekt 8610033c26 增强验证码校验的语义,更易懂 2020-09-28 20:27:57 +08:00
RuoYi 613a21edd0 升级bootstrap-fileinput到最新版本5.1.2 2020-09-24 20:11:28 +08:00
RuoYi 0c93087b58 升级oshi到最新版本v5.2.5 2020-09-22 18:16:27 +08:00
RuoYi aa8e0e765d 修正文字错误 2020-09-22 11:00:10 +08:00
RuoYi b277995c64 修正文字错误 2020-09-22 10:59:24 +08:00
RuoYi dc2a723c1b 修正语义错误&删除多余方法 2020-09-22 09:53:08 +08:00
RuoYi ffb2d2bc87 修改主子表提交示例代码 2020-09-22 09:26:40 +08:00
liuxing dd0c5a2bfb AjaxResult重写put方法,以方便链式调用 2020-09-19 12:23:30 +08:00
RuoYi 8c1e893657 升级springboot到2.1.17 提升安全性 2020-09-18 16:42:44 +08:00
Ricky 5d73b1d8de 优化$.modal.close方法 2020-09-18 12:13:31 +08:00
RuoYi 59a45cf5ad 导入excel整形值校验优化 2020-09-17 17:10:17 +08:00
RuoYi acfb6a56bb 菜单&数据权限新增(展开/折叠 全选/全不选 父子联动) 2020-09-16 11:47:22 +08:00
RuoYi b7e20b48cb 表单向导插件更换为jquery-smartwizard 2020-09-15 17:39:54 +08:00
Ricky 4e5923a763 替换表单向导插件为jquery-smartwizard 2020-09-15 16:55:13 +08:00
RuoYi c523be9f34 新增表格列宽拖动插件 2020-09-15 14:09:29 +08:00
Ricky ded9916649 优化页脚显示控制的判断表达式 2020-09-15 09:51:17 +08:00
RuoYi b20ad52d6a 输入框组验证错误后置图标提示颜色 2020-09-14 15:45:03 +08:00
RuoYi e118d94b24 限制系统内置参数不允许删除 2020-09-14 15:00:29 +08:00
RuoYi 1a46a430b6 添加新群号 2020-09-14 10:33:55 +08:00
RuoYi 3cff281172 新增是否开启页脚功能 2020-09-11 17:00:12 +08:00
Ricky a1ded39bb6 修复窗体大小改变后浮动提示框失效问题 2020-09-11 13:33:24 +08:00
Ricky dab0a4f0d0 修复点击左上角返回首页,浏览器刷新导致之前的菜单重新弹出;超出字符提示增加换行 2020-09-11 10:44:03 +08:00
Ricky 3039601c42 修复点击左上角返回首页,浏览器刷新导致之前的菜单重新弹出;超出字符提示增加换行 2020-09-11 10:42:54 +08:00
Ricky 5c40ca6eb8 修复菜单收起时当前选中菜单和展开的子菜单间存在间隔 2020-09-10 14:45:41 +08:00
Ricky a1e7c5be0c 修复菜单收起时当前选中菜单和展开的子菜单间存在间隔 2020-09-10 13:56:56 +08:00
RuoYi 7e615f6c84 新增表格参数(通过自定义函数设置标题样式headerStyle) 2020-09-10 11:19:16 +08:00
Ricky c90e6f5fba 调整字符串格式化(%s )参数为空时转为空字符串 2020-09-10 09:10:12 +08:00
Wan Chen 9b40918a35 代码生成增加createBy、updateBy 2020-09-09 18:28:29 +08:00
RuoYi fc2b73f2a8 Excel导出类型NUMERIC支持精度浮点类型 2020-09-09 11:27:02 +08:00
RuoYi 7b3517f699 降级druid到版本v1.1.22,防止出现一些错误 2020-09-09 10:07:42 +08:00
RuoYi 510feabe4b 修改页签行高 2020-09-07 12:04:09 +08:00
若依 b4c27fa22b !205 update ruoyi-admin/src/main/resources/templates/index-topnav.html.
Merge pull request !205 from Hacker/N/A
2020-09-04 17:01:01 +08:00
Ricky b3c3759e55 数据字典缓存空值处理 2020-09-04 15:37:58 +08:00
Hacker 4ec66e6a9f update ruoyi-admin/src/main/resources/templates/index-topnav.html.
实例菜单开关控制
2020-09-04 14:03:41 +08:00
RuoYi 6b67ebb818 升级druid到最新版本v1.1.23 2020-09-04 13:46:39 +08:00
RuoYi 5d41851048 去除mini菜单窗口底部波浪线 2020-09-04 13:46:28 +08:00
Ricky 255799ea3a 生成代码补充必填样式 2020-09-04 11:56:54 +08:00
Ricky 8a5744f492 新增菜单导航显示风格(default为左侧导航菜单,topnav为顶部导航菜单) 2020-09-04 11:36:45 +08:00
RuoYi 468fa72041 新增菜单导航显示风格(default为左侧导航菜单,topnav为顶部导航菜单) 2020-09-03 20:36:54 +08:00
RuoYi b4aa7232a0 新增菜单导航显示风格(default为左侧导航菜单,topnav为顶部导航菜单) 2020-09-03 15:41:29 +08:00
RuoYi 2b0e3546ff 新增菜单导航显示风格(default为左侧导航菜单,topnav为顶部导航菜单) 2020-09-03 12:57:44 +08:00
RuoYi bf1e52fd9d 新增菜单导航显示风格(default为左侧导航菜单,topnav为顶部导航菜单) 2020-09-03 10:03:49 +08:00
RuoYi 947120d136 新增表格参数(通过自定义函数设置页脚样式footerStyle) 2020-08-29 11:44:24 +08:00
RuoYi ae7c436730 上传媒体类型添加视频格式 2020-08-29 11:43:36 +08:00
RuoYi 3dc4cb78e5 数据权限判断参数类型 2020-08-28 15:37:16 +08:00
RuoYi 118cd15204 修正数据库字符串类型nvarchar 2020-08-28 14:14:50 +08:00
RuoYi b9c4796a27 优化递归子节点 2020-08-28 10:30:02 +08:00
Ricky 2f25abaaf2 修复多表格搜索formId无效 2020-08-27 13:28:58 +08:00
Ricky cc35627ab1 添加Ajax局部刷新demo 2020-08-26 16:33:19 +08:00
RuoYi adcdd046d2 导出Excel调整targetAttr获取值方法,防止get方法不规范 2020-08-26 15:39:19 +08:00
RuoYi 00392e6809 生成页面时不忽略remark属性 2020-08-26 14:12:55 +08:00
RuoYi d506a69290 字典数据列表页添加关闭按钮 2020-08-26 13:35:36 +08:00
RuoYi feec4f236e Excel注解支持自动统计数据总和 2020-08-26 11:17:37 +08:00
RuoYi e36334c50a 若依 4.4 2020-08-24 08:41:53 +08:00
RuoYi 9f21f8816a 同步表结构不存在,提示错误信息 2020-08-23 10:11:08 +08:00
RuoYi 7aedaf2085 修改表格行内编辑示例旧值参数 2020-08-20 14:57:05 +08:00
RuoYi 895c290cbf 设置默认排序顺序 2020-08-19 17:05:09 +08:00
若依 346670b197 !198 update pom.xml.
Merge pull request !198 from PorcupineBoy/N/A
2020-08-19 10:55:54 +08:00
PorcupineBoy 7ad0a35ba2 update pom.xml.
shiro 1.5.3版本 有高危漏洞,升级为 1.6.0版本
fastjson 1.2.70版本有高危漏洞,需升级为1.2.73
2020-08-19 10:51:14 +08:00
RuoYi 0d0a2ecc5a Excel注解支持设置BigDecimal精度&舍入规则 2020-08-19 10:37:38 +08:00
RuoYi dc82712597 代码生成支持同步数据库 2020-08-18 11:41:00 +08:00
RuoYi 9ab3a297bd 操作日志记录排除敏感属性字段 2020-08-17 11:46:56 +08:00
RuoYi 03174f1ead 修复页面存在多表格,回调函数res数据不正确问题 2020-08-17 10:00:26 +08:00
RuoYi a4b0a7c0bb 强退删除用户会话 2020-08-16 11:03:17 +08:00
若依 4b8d578f4d !196 修复不同浏览器附件下载中文名乱码的问题
Merge pull request !196 from zhengxiaolong/master
2020-08-16 10:56:13 +08:00
zhengxl5566 b369317800 修复不同浏览器下附件中文名乱码的bug
采用[RFC 6266]定义的标注写法,兼容市面上所有主流浏览器
详情请浏览本人原创文章:https://segmentfault.com/a/1190000023601065
2020-08-14 15:05:13 +08:00
xie_xiangrui@163.com d957acd899 add @Override 2020-08-11 21:02:33 +08:00
RuoYi e7d791ddf0 表格树标题内容支持html语义化标签 2020-08-11 18:21:15 +08:00
RuoYi a0ada99856 主子表示例添加日期格式案例 2020-08-11 17:34:10 +08:00
RuoYi cdbf0e2264 强退&过期清理登录帐号缓存会话 2020-08-10 16:08:03 +08:00
RuoYi 134e559704 操作日志查询方式调整 2020-08-07 18:36:05 +08:00
RuoYi dd9b2cd617 修复注释错误 2020-08-07 16:45:17 +08:00
RuoYi 07e2d69ebf Merge branch 'master' of https://github.com/yangzongzhuan/RuoYi 2020-08-07 11:15:10 +08:00
RuoYi 0d65960e86 修复更新表格插件后导致的记住我错误 2020-08-07 11:13:09 +08:00
RuoYi e1191c56b2 修复更新表格插件后导致的主子表错误 2020-08-07 11:07:52 +08:00
RuoYi cec1d3adcb 代码生成支持富文本控件 2020-08-07 09:27:11 +08:00
RuoYi a4c4f737a8 菜单页签联动优化 2020-08-06 13:35:21 +08:00
RuoYi c0c62001a9 唯一限制条件只返回单条数据 2020-08-05 14:21:31 +08:00
RuoYi 4a64a9269a 修改Excel设置STRING单元格类型 2020-08-05 13:01:03 +08:00
RuoYi 30278a0451 字符串isEmpty判断是否为空 2020-08-04 10:33:33 +08:00
若依 f80a312b9b !195 update ruoyi-admin/src/main/resources/templates/system/user/profile/profile.html.
Merge pull request !195 from Hacker/N/A
2020-08-04 10:21:28 +08:00
Hacker 674d236007 update ruoyi-admin/src/main/resources/templates/system/user/profile/profile.html. 2020-08-04 09:25:34 +08:00
RuoYi 4e211c4871 修复更新表格插件后导致的主子表错误 2020-08-03 17:06:33 +08:00
RuoYi 43788e0590 用户密码支持自定义配置规则 2020-08-03 12:06:47 +08:00
RuoYi 8bf5140a72 用户密码支持自定义配置规则 2020-08-03 11:40:51 +08:00
RuoYi 3d2d88287a 用户邮箱长度限制50 2020-08-03 09:56:57 +08:00
RuoYi 6d5b261c7d 修复多表格无法设置实例配置问题 2020-07-31 16:16:11 +08:00
RuoYi 2eb5752cc1 修复自定义context-path,首页favicon.ico无法加载问题 2020-07-30 10:54:17 +08:00
RuoYi 43ce484f36 添加获取当前的环境配置方法 2020-07-30 10:36:10 +08:00
若依 277d42c12b !194 update ruoyi-common/src/main/java/com/ruoyi/common/utils/spring/SpringUtils.java.
Merge pull request !194 from Hacker/N/A
2020-07-30 10:31:00 +08:00
RuoYi 2651383ab2 新增表格打印配置插件 2020-07-29 19:27:56 +08:00
RuoYi 25022bfef2 Merge branch 'master' of https://gitee.com/y_project/RuoYi 2020-07-29 19:22:42 +08:00
RuoYi 98ee5e9772 新增表格自动刷新插件 2020-07-29 19:21:40 +08:00
Awen acbf27bc26 给表格列超出指定长度浮动提示的input指定一个宽度,避免鼠标鼠标悬浮单元格部分位置才显示提示。 2020-07-29 19:16:56 +08:00
Hacker aa62d63920 update ruoyi-common/src/main/java/com/ruoyi/common/utils/spring/SpringUtils.java. 2020-07-29 17:53:09 +08:00
RuoYi 31c3d4021e HTML过滤器改为将html转义 2020-07-28 17:21:24 +08:00
RuoYi 3025017d0f 表格样式优化 2020-07-27 17:54:03 +08:00
RuoYi 514ccd2c75 表格样式优化 2020-07-27 17:35:37 +08:00
RuoYi 7a8e047c6f 新增表格参数(自定义加载文本的字体大小loadingFontSize) 2020-07-27 10:49:36 +08:00
RuoYi be3adb875f 表格请求方式method支持自定义配置 2020-07-27 09:40:15 +08:00
RuoYi 18d80cc78e 升级表格行编辑&移动端适应插件 2020-07-27 09:17:30 +08:00
RuoYi b1c60695e6 更换表格冻结列插件 2020-07-27 09:15:51 +08:00
RuoYi 4a6e5a0fba 升级bootstrapTable到最新版本1.17.1 2020-07-27 09:12:45 +08:00
RuoYi a9775607e0 修复配置应用的访问路径首页页签重复问题 2020-07-26 18:39:47 +08:00
RuoYi d7f7da596f openTab打开时滚动到当前页签 2020-07-26 15:50:26 +08:00
RuoYi 6c8a389f9a 截取返回参数长度,防止超出异常 2020-07-21 11:28:10 +08:00
Sxile 0f3d67367a 修复form表单id重复 2020-07-20 15:34:24 +08:00
RuoYi 49e20200f1 字符未使用下划线不进行驼峰式处理 2020-07-19 12:25:50 +08:00
RuoYi f726bf25ce update appname 2020-07-19 12:25:21 +08:00
RuoYi 7fb5382c10 编码文件名修改为uuid方式 2020-07-17 09:10:11 +08:00
若依 e75258a72b !191 update ruoyi-admin/src/main/resources/templates/system/user/profile/profile.html.
Merge pull request !191 from Hacker/N/A
2020-07-17 08:57:57 +08:00
Hacker ffc16b032d update ruoyi-admin/src/main/resources/templates/system/user/profile/profile.html.
优化项-修改头像样式,鼠标移入悬停遮罩,点击到上传头像页面
2020-07-17 08:51:19 +08:00
RuoYi f42b8c7a83 定时任务cron表达式验证 2020-07-16 17:09:15 +08:00
RuoYi ddbb1aa170 format pom 2020-07-16 16:19:28 +08:00
RuoYi c8b42c5b82 拆分表格插件,按需引入 2020-07-13 20:42:43 +08:00
RuoYi 7d1b67a8b7 兼容IE浏览器对象不支持toBlob属性或方法问题 2020-07-13 12:47:47 +08:00
RuoYi b09955f369 Merge branch 'master' of https://gitee.com/y_project/RuoYi 2020-07-13 10:55:10 +08:00
RuoYi e7838317d0 更换图片裁剪工具为cropper 2020-07-13 10:54:21 +08:00
Awen 1aa2d7a5cc Merge branch 'master' of gitee.com:y_project/RuoYi 2020-07-12 15:09:38 +08:00
Awen 8b4aef15cf 修改切换“浅蓝”主题,首页菜单字体和主题背景颜色冲突的问题。 2020-07-12 15:07:56 +08:00
RuoYi d56d6ac5ac Excel支持sort导出排序 2020-07-10 11:54:19 +08:00
若依 8d165f4919 !187 update ruoyi-admin/src/main/resources/static/ruoyi/css/ry-ui.css.
文本区(多行文本框)补齐必填错误提示背景。原只有文字提示。
2020-07-10 11:02:53 +08:00
abbfun 44895c3d17 update ruoyi-admin/src/main/resources/static/ruoyi/css/ry-ui.css.
文本区(多行文本框)补齐必填错误提示背景。原只有文字提示。
2020-07-10 10:00:35 +08:00
若依 29a30a25c2 !186 update ruoyi-admin/src/main/resources/static/css/style.css.
Merge pull request !186 from Hacker/N/A
2020-07-10 09:09:57 +08:00
Hacker 77c4a350d4 update ruoyi-admin/src/main/resources/static/css/style.css.
修正聊天窗口样式
2020-07-08 20:58:48 +08:00
Awen a1dba1ad1c 修正聊天窗口样式 2020-07-08 18:34:22 +08:00
RuoYi ecaf13caa3 代码生成支持自定义路径 2020-07-08 18:20:43 +08:00
RuoYi 58bbf6c36d 代码生成支持自定义路径 2020-07-08 17:22:14 +08:00
RuoYi 154b8d9db8 代码生成支持选择上级菜单 2020-07-08 17:07:49 +08:00
RuoYi b7aa9f3f42 代码生成支持选择上级菜单 2020-07-08 13:29:24 +08:00
RuoYi 44df8c4c8b 代码生成支持上传控件 2020-07-07 17:08:31 +08:00
RuoYi 23b98a3ef8 用户分配角色不允许选择超级管理员角色 2020-07-07 12:38:17 +08:00
RuoYi 18a7915079 添加右侧冻结列示例 2020-07-06 22:01:31 +08:00
RuoYi 68b5b80299 冻结列右侧自适应 2020-07-06 21:51:42 +08:00
若依 c426de4dee !181 update ruoyi-framework/src/main/java/com/ruoyi/framework/config/ShiroConfig.java.
Merge pull request !181 from Hacker/N/A
2020-07-06 17:54:01 +08:00
若依 92911e840e !180 update ruoyi-admin/src/main/resources/static/css/style.css.
Merge pull request !180 from Hacker/N/A
2020-07-06 17:53:50 +08:00
Hacker 781fd7dd1a update ruoyi-framework/src/main/java/com/ruoyi/framework/config/ShiroConfig.java.
java doc
2020-07-06 17:48:40 +08:00
Hacker f079622e11 update ruoyi-admin/src/main/resources/static/css/style.css.
聊天窗口样式发送者的内容区分左右样式,而非nth-child(2n+1)
2020-07-06 17:38:07 +08:00
RuoYi c52ba00f4f 修复表格冻结列错位问题 2020-07-06 15:32:29 +08:00
RuoYi 7c48bc3184 若依 4.3.1 2020-07-04 22:40:47 +08:00
RuoYi 91986f13f8 国家信息安全漏洞(请务必保持cipherKey密钥唯一性) 2020-07-04 20:52:27 +08:00
RuoYi 7728ad9eb4 检查字符支持小数点&降级改成异常提醒 2020-07-04 11:36:59 +08:00
RuoYi 868aed4079 openOptions函数中加入自定义maxmin属性 2020-06-29 14:55:27 +08:00
RuoYi 9627ba9e1d 支持openOptions方法最大化 2020-06-28 17:25:14 +08:00
RuoYi e0e305c423 验证码清除,防止多次使用。 2020-06-28 16:34:23 +08:00
若依 ed4280379d !169 修改验证码使用后仍可用的问题
Merge pull request !169 from goodhal/master
2020-06-28 16:05:20 +08:00
RuoYi 233089b3e6 支持openOptions方法多个按钮回调 2020-06-28 11:44:12 +08:00
RuoYi bb0e7bd563 右键页签操作实现与菜单联动 2020-06-28 09:49:41 +08:00
tys 7bca4fcbc4 关闭顶部tab页时,左侧菜单定位到当前显示页 2020-06-27 22:19:14 +08:00
RuoYi 1b7a735f9c 升级shiro到最新版1.5.3 阻止权限绕过漏洞 2020-06-26 09:53:10 +08:00
RuoYi 829dfafdaa 新增isLinkage支持页签与菜单联动 2020-06-24 22:23:42 +08:00
RuoYi 5a59670124 修改代码生成导入表结构出现异常页面不提醒问题 2020-06-24 18:12:26 +08:00
RuoYi 2499685a31 如果加载头像时发生了错误,则显示一个默认头像 2020-06-24 10:39:02 +08:00
RuoYi a3bb603382 Excel支持dictType读取字符串组内容 2020-06-23 21:05:38 +08:00
RuoYi 9ad3cc0b9a Excel导出支持字典类型 2020-06-23 20:59:23 +08:00
RuoYi 7e259cd101 若依 4.3 2020-06-22 08:37:35 +08:00
RuoYi 3846329c82 代码生成主子表序号调整 2020-06-21 23:04:09 +08:00
RuoYi 326fe6a63f Excel支持readConverterExp读取字符串组内容 2020-06-21 11:19:15 +08:00
RuoYi 5321200c6e 修复jquery表单序列化时复选框未选中不会序列化到对象中去问题 2020-06-21 10:08:46 +08:00
RuoYi 82d913c7de 代码生成显示类型支持复选框 2020-06-20 17:52:05 +08:00
RuoYi 0df61a6336 新增回显数据字典(字符串数组) 2020-06-20 17:22:04 +08:00
RuoYi 68a4e6de5f 创建用户不允许选择系统管理员角色 2020-06-20 15:03:39 +08:00
RuoYi 84e447e170 用户信息添加输入框组图标&鼠标按下显示密码 2020-06-20 11:15:45 +08:00
RuoYi 4fcfe890c9 主子表生成模板多余逗号问题 2020-06-20 11:15:29 +08:00
RuoYi a3b51553fb 输入框组图标元素修改成圆角 2020-06-20 09:55:27 +08:00
RuoYi 7dc982aded 修复浏览器手动缩放比例后菜单无法自适应问题 2020-06-19 19:29:54 +08:00
Sxile 07c3a67b70 添加缺少的@ Override 2020-06-19 18:09:09 +08:00
Sxile 40333c6b16 添加{}使代码更容易理解 2020-06-19 18:02:35 +08:00
Sxile 942e609d36 常量接口修改为常量类 2020-06-19 16:00:42 +08:00
RuoYi 9f248e97f6 前端表单样式修改成圆角 2020-06-19 12:16:03 +08:00
RuoYi 9c763dceab ajaxSuccess判断修正 2020-06-18 13:33:54 +08:00
RuoYi 92d7c18879 HttpUtils.sendPost()方法,参数无需拼接参数到url 2020-06-18 10:36:24 +08:00
RuoYi e4919f1a62 HTML过滤器不替换&实体 2020-06-18 10:16:21 +08:00
RuoYi 052ab8866d 代码生成模板支持主子表 2020-06-17 09:43:15 +08:00
RuoYi 338138a0bc 代码生成浮点型改用BigDecimal 2020-06-17 08:56:06 +08:00
RuoYi fedb39c9ad 主子表示例添加序号&防止insertRow数据被初始化 2020-06-16 13:11:28 +08:00
RuoYi 128b35c2f6 新增示例(主子表提交) 2020-06-15 14:03:29 +08:00
RuoYi 57fed227f0 表单构建优化 2020-06-12 12:31:56 +08:00
RuoYi c3b9aa0daf 修复表单构建单选和多选框渲染问题 2020-06-10 20:27:02 +08:00
goodhal 690a9a6281 修改验证码在使用后仍可用的问题 2020-06-10 17:27:43 +08:00
RuoYi e91adcc28d 添加是否开启swagger配置 2020-06-08 12:20:28 +08:00
RuoYi 83981138e0 代码生成模板调整,字段为String并且必填则加空串条件 2020-06-07 15:54:17 +08:00
RuoYi c29d766cd8 字典数据查询列表根据dictSort升序排序 2020-06-04 14:26:40 +08:00
RuoYi 3ede0313f2 首页菜单显示调整 2020-06-04 13:49:28 +08:00
RuoYi e7248da61a 修复树表对imageView和tooltip方法无效问题。 2020-06-02 19:40:43 +08:00
RuoYi 05638550d5 添加cxselect参数手册地址 2020-06-02 11:53:32 +08:00
RuoYi 004e5b8af6 新增多级联动下拉示例 2020-06-02 11:06:01 +08:00
RuoYi 0544581ab9 升级fastjson到最新版1.2.70 修复高危安全漏洞 2020-06-01 10:14:10 +08:00
RuoYi 6b22fb86cb 示例demo页面清除html链接,防止点击后跳转出现404 2020-05-30 22:04:30 +08:00
RuoYi 6d5830a235 新增表格列参数(是否列选项可见ignore) 2020-05-29 17:11:32 +08:00
RuoYi 6aed57056c 修复部分情况节点不展开问题。 2020-05-29 11:29:06 +08:00
RuoYi 3f17e54cf9 README 2020-05-29 09:23:46 +08:00
RuoYi aea691537b 在线用户强退方法合并 2020-05-28 09:37:25 +08:00
若依 8c88957b69 !167 SysUserOnlineController疑问和建议
Merge pull request !167 from JoseK43326/master
2020-05-28 09:33:16 +08:00
JoseK43326 bb9d504d40 用户在线监测 部分修改建议 2020-05-27 20:50:46 +08:00
RuoYi 30b3909fc4 修复selectColumns方法获取子对象数据无效问题。 2020-05-23 21:43:24 +08:00
RuoYi f72d399f9a 修复selectColumns方法获取子对象数据无效问题。 2020-05-23 09:34:58 +08:00
RuoYi cb6ca423f8 README 2020-05-19 11:43:10 +08:00
RuoYi 1cb1743445 修改数据源类型优先级,先根据方法,再根据类 2020-05-19 11:05:24 +08:00
若依 f24da2fc98 !161 fix 类上数据源类型获取不到问题,修改优先级,先根据方法,再根据类
Merge pull request !161 from sdvdxl/master
2020-05-19 09:59:31 +08:00
杜龙少 0b85032ca8 Merge remote-tracking branch 'ruoyi-orgin/master' 2020-05-18 09:08:11 +08:00
RuoYi 9c54c5c37d 缺少 @Override 2020-05-16 17:16:44 +08:00
RuoYi 59e2d4a2df 修改上级部门(选择项排除本身和下级) 2020-05-15 15:30:08 +08:00
RuoYi dc6fe4c985 修复关闭标签页后刷新还是上次地址问题 2020-05-14 17:14:23 +08:00
RuoYi a8eeb652b2 通用http发送方法增加参数 contentType 编码类型 2020-05-14 14:36:22 +08:00
RuoYi 1af0fef99e 更换IP地址查询接口 2020-05-13 21:16:15 +08:00
RuoYi 7190516a27 淘宝IP接口不稳定,默认关闭。 2020-05-13 18:58:10 +08:00
RuoYi 7e34c2339f 新增表格参数(是否启用显示卡片视图cardView) 2020-05-07 14:07:18 +08:00
RuoYi 12f1ff894f 修复选择菜单后刷新页面,菜单箭头显示不对问题 2020-05-07 13:55:43 +08:00
RuoYi 8a9d298ffc 添加校验部门包含未停用的子部门 2020-05-07 12:15:04 +08:00
RuoYi 2c8365b605 针对性屏蔽Enter 2020-04-30 15:53:17 +08:00
RuoYi 27f40d0357 取消回车自动提交表单 2020-04-28 22:26:08 +08:00
RuoYi cb32d5cc90 新增表格参数(是否显示全屏按钮showFullscreen) 2020-04-23 14:24:49 +08:00
RuoYi 14bb9f3cba 'A','I','BUTTON' 标签忽略clickToSelect事件,防止点击操作按钮时选中。 2020-04-23 11:53:56 +08:00
RuoYi 0140de4546 新增表格参数(是否启用分页条无限循环的功能paginationLoop) 2020-04-23 11:10:18 +08:00
RuoYi e476fe6f5d Long类型比较相等问题调整 2020-04-21 19:50:36 +08:00
RuoYi 897ce6e3c2 表格添加显示/隐藏所有列方法 showAllColumns/hideAllColumns 2020-04-21 13:29:21 +08:00
杜龙少 6d115e602e fix 类上数据源类型获取不到问题,修改优先级,先根据方法,再根据类 2020-04-19 11:00:35 +08:00
RuoYi 2bba8c7b73 新增表格参数(是否显示表头showHeader) 2020-04-17 18:46:21 +08:00
RuoYi 1dbc11f708 邮箱显示截取部分字符串,防止低分辨率错位 2020-04-17 18:35:48 +08:00
RuoYi f9fbdb291b 优化查询条件label为时间对齐问题 2020-04-14 20:38:19 +08:00
若依 a3b3332fdd !160 fix bug: 字典排序值=0时无效
Merge pull request !160 from Errors0/fix0414
2020-04-14 20:31:06 +08:00
200cc 384b58ca11 fix bug: 字典排序值=0时无效 2020-04-14 15:35:16 +08:00
RuoYi 52423edb24 升级fastjson到最新版1.2.68 修复安全加固 2020-04-13 11:55:25 +08:00
RuoYi fed849beed list*.vm模板优化 2020-04-08 12:02:26 +08:00
RuoYi fe296cc8ba 删除无用注解 2020-04-08 11:14:16 +08:00
Sxile 6c94fe8b82 删除无用注解 2020-04-08 11:02:06 +08:00
RuoYi febd69e2b3 添加data数据加载属性及示例 2020-04-01 11:11:12 +08:00
RuoYi 55512bdbec 代码生成列属性根据sort排序 2020-04-01 10:38:57 +08:00
RuoYi 22d1e5882a 气泡弹出框特效移至通用js 2020-03-31 11:53:49 +08:00
RuoYi 2f24ab1692 图片预览事件属性修正 2020-03-30 18:54:19 +08:00
RuoYi 025731a04c @Override 注解缺失 2020-03-30 18:40:48 +08:00
RuoYi 28c861c6df 修复冻结列排序样式无效问题 2020-03-30 18:23:41 +08:00
RuoYi dcbc77b403 修复更多操作部分浏览器不兼容情况 2020-03-30 17:14:43 +08:00
RuoYi 1e6b78c349 升级Bootstrap版本到v3.3.7 2020-03-30 16:46:48 +08:00
RuoYi 4f57c28f2f 修复context-path的情况下个人中心刷新导致样式问题 2020-03-25 18:04:37 +08:00
RuoYi 2a718ba4d6 驱动移至admin模块 2020-03-25 14:55:32 +08:00
RuoYi ca9f87bff4 去掉多余的依赖 2020-03-25 12:14:24 +08:00
RuoYi e517741f99 全屏editFull打开适配表树 2020-03-25 12:03:51 +08:00
RuoYi d066539616 若依 4.2 2020-03-23 09:02:04 +08:00
RuoYi 5c736e96c9 页面滚动显示返回顶部按钮 2020-03-20 14:34:26 +08:00
RuoYi 0307599eed 移动端定时任务&角色管理更多操作可点击 2020-03-20 13:46:43 +08:00
RuoYi 55da596a80 定时任务&角色管理添加更多操作按钮 2020-03-20 13:21:30 +08:00
RuoYi 6fa8c991b8 移动端点击左侧目录不进行菜单切换 2020-03-19 13:48:15 +08:00
RuoYi 51f98aa0cb 代码生成细节优化 2020-03-18 23:05:26 +08:00
RuoYi 07042ac9b1 iframe框架页会话过期弹出超时提示 2020-03-18 22:57:03 +08:00
RuoYi 3df553c488 移动端登录不显示左侧菜单 2020-03-18 18:32:45 +08:00
RuoYi 5426ba9d5e 首页logo固定,不随菜单滚动 2020-03-18 16:06:22 +08:00
RuoYi 6b9ee80ca4 任务分组字典翻译(调度日志详细) 2020-03-18 15:37:47 +08:00
RuoYi 05b5b314ee 字典管理添加缓存读取 2020-03-18 15:03:52 +08:00
RuoYi f8491c36e2 字典数据列表标签显示样式 2020-03-18 12:45:53 +08:00
RuoYi 06751acbf9 参数管理支持缓存操作 2020-03-18 12:28:36 +08:00
RuoYi 567ab47ae9 日期控件清空结束时间设置开始默认值为2099-12-31 2020-03-14 15:34:33 +08:00
RuoYi 82f8dadbae 表格树添加获取数据后响应回调处理 2020-03-14 11:47:36 +08:00
RuoYi ca6a4b2ecf 批量替换表前缀调整 2020-03-13 21:56:29 +08:00
RuoYi 9247e004d0 调整包顺序 2020-02-28 21:37:56 +08:00
若依 e1e494de33 !153 支持表格导入模板的弹窗表单加入其它输入控件
Merge pull request !153 from ฅ(̳••̳)ฅ大步/master
2020-02-28 21:34:09 +08:00
ฅ(̳••̳)ฅ大步 3988b12e72 update ruoyi-admin/src/main/resources/static/ruoyi/js/ry-ui.js.
支持导入模板的表单可以添加除了file、updateSupport之外的输入控件。
2020-02-26 14:30:29 +08:00
RuoYi c6bf712de4 登录页面默认模式设置 2020-02-17 17:28:16 +08:00
RuoYi 18e0a2a27d 重置刷新表格树 2020-02-17 15:50:11 +08:00
RuoYi 6ce34b1790 新增支持导出数据字段排序 2020-02-17 12:16:13 +08:00
RuoYi b5678994da 修改代码生成部分细节问题 2020-02-10 14:59:31 +08:00
RuoYi 2aa98dcbe1 新增表格参数(是否单选checkbox) 2020-02-05 18:16:52 +08:00
RuoYi 96d0bd2581 README 2020-02-05 18:05:08 +08:00
RuoYi f826a79633 防止db字段名为一个字母导致出现生成异常 2020-02-02 15:41:56 +08:00
RuoYi c958d6ec83 添加新群号 2020-01-31 14:44:31 +08:00
RuoYi 5cb3430791 druid未授权不允许访问 2020-01-11 19:33:08 +08:00
RuoYi d93e43cc2c 表格树父节点兼容0,'0','',null 2020-01-03 17:31:12 +08:00
RuoYi 47f007ba97 添加新群号 2020-01-03 10:58:25 +08:00
RuoYi f96328ea6b 调整表格树兼容父节点判断 2020-01-02 19:29:55 +08:00
RuoYi 2d55917f2e 必填的项增加星号 2019-12-31 16:34:24 +08:00
RuoYi 1c6e5cf665 修复select2不显示校验错误信息 2019-12-25 16:59:12 +08:00
RuoYi 9d316c44d2 HTML过滤器不替换双引号为&quot;,防止json格式无效 2019-12-20 17:27:17 +08:00
RuoYi 2f8422278a 添加HTML过滤器,用于去除XSS漏洞隐患 2019-12-19 17:04:32 +08:00
RuoYi 98dd156396 修复多数据源下enabled=false导致读取不到bean导致异常问题 2019-12-19 16:10:10 +08:00
RuoYi b65263fdd7 修复翻页记住选择项数据问题 2019-12-19 14:21:31 +08:00
RuoYi 21992c1be7 用户邮箱长度限制20 2019-12-16 11:44:20 +08:00
RuoYi d80c1d2a73 修改错误页面返回主页出现嵌套问题 2019-12-10 17:20:43 +08:00
RuoYi 55978c7f15 表格浮动提示单双引号转义 2019-12-10 09:55:23 +08:00
RuoYi b2012e699b 阿里云服务器89元/年,双12年末特惠,爆款产品限时1折 2019-12-09 11:32:53 +08:00
RuoYi 382d1868be 阿里云服务器89元/年,双12年末特惠,爆款产品限时1折 2019-12-09 11:25:49 +08:00
RuoYi 82df046e59 添加新群号 2019-12-04 11:44:26 +08:00
RuoYi 4f116a6a77 更新前后端分离版本链接 2019-12-03 18:05:28 +08:00
RuoYi 77d3db4cb0 代码生成防止缓存内的数据没有及时写入到zip文件 2019-12-02 15:02:31 +08:00
RuoYi 1155bcb22d 支持配置四级菜单 2019-11-27 11:05:10 +08:00
RuoYi 208c4a8417 升级shiro到最新版1.4.2 阻止rememberMe漏洞攻击 2019-11-26 15:33:42 +08:00
RuoYi 62a0018041 升级summernote到最新版本v0.8.12 2019-11-25 12:24:49 +08:00
RuoYi f276a83956 侧边栏添加一套深蓝色主题 2019-11-22 09:41:04 +08:00
RuoYi 28b8f3e36f Excel注解dateFormat属性为字符串时间时格式处理 2019-11-21 16:33:34 +08:00
若依 56a6e940c2 !146 浏览代码时间字符串处理
Merge pull request !146 from 厚积薄发/master
2019-11-21 16:31:37 +08:00
厚积薄发 868edbc88c 时间字符串处理 2019-11-21 10:15:24 +08:00
RuoYi b05a539970 支持mode配置history(表示去掉地址栏的#) 2019-11-21 09:59:45 +08:00
若依 2c48aedda7 !144 修复War部署无法正常shutdown,ehcache内存泄漏
Merge pull request !144 from wayneliquan/master
2019-11-20 18:52:32 +08:00
zhanliquan 87b8d032ca 修复War部署无法正常shutdown,ehcache内存泄漏
Signed-off-by: zhanliquan <zhanliquanit@foxmail.com>
2019-11-20 18:07:54 +08:00
zhanliquan 080237cabf 修复War部署无法正常shutdown,ehcache内存泄漏
Signed-off-by: zhanliquan <zhanliquanit@foxmail.com>
2019-11-20 16:54:22 +08:00
RuoYi 005418e065 修复代码生成短字段无法识别问题 2019-11-20 10:44:02 +08:00
RuoYi b32111f1ab 修复war包部署情况下404、500等页面样式丢失问题 2019-11-18 12:01:38 +08:00
RuoYi 25f51371f5 代码生成模板增加导出功能日志记录 2019-11-16 11:58:07 +08:00
RuoYi 14bad9bf20 2019年度最受欢迎中国开源软件评选
请给若依/RuoYi 投票,谢谢。
2019-11-15 09:55:32 +08:00
若依 da2d0ba32f !143 serviceImpl模版 update方法判断bug修正
Merge pull request !143 from shenbururen/master
2019-11-13 14:55:27 +08:00
shenbururen 0b34c3e910 serviceImpl模版 update方法判断bug修正
应该判断updateTime字段。
2019-11-13 14:03:26 +08:00
RuoYi 1557a858ea 代码生成唯一编号调整为tableId 2019-11-12 15:12:13 +08:00
RuoYi 9a0098cca1 代码生成查询时忽略大小写&翻页记住选中&表注释未填写也允许导入 2019-11-12 15:00:47 +08:00
RuoYi fe8c142cd6 修改select2选择数量限制提示语 2019-11-08 10:47:07 +08:00
RuoYi 5346af9ab0 全局配置类修改为注解,防止多环境配置下读取问题。 2019-11-07 17:33:28 +08:00
RuoYi de1979212a 修复多表格情况下,firstLoad只对第一个表格生效 2019-11-07 15:22:42 +08:00
RuoYi aa0f33b5e7 处理打包出现警告问题 2019-11-06 17:04:25 +08:00
RuoYi ecb77e2be4 默认主题样式,防止网速慢情况下出现空白 2019-11-06 14:28:23 +08:00
RuoYi db9d1a7720 修复文件上传多级目录识别问题 2019-11-01 09:31:26 +08:00
RuoYi 6ad6f90968 解码url,防止中文导致页面不能加载问题 2019-10-31 15:25:23 +08:00
RuoYi b1b0542f72 右键Tab页刷新事件重复请求问题 2019-10-31 11:32:45 +08:00
RuoYi 7e749c25c6 阿里云服务器86元/年,双11冰点底价,错过再等1年 2019-10-24 09:37:19 +08:00
RuoYi 23bbd23032 若依 4.1 2019-10-22 10:18:36 +08:00
RuoYi 68f65cf77b 若依 4.1 2019-10-22 09:55:16 +08:00
RuoYi 9b93a151fb 支持多表格实例操作 2019-10-21 12:14:52 +08:00
RuoYi 3e18ca6613 支持多表格实例操作 2019-10-21 11:37:50 +08:00
RuoYi a3e946b57e 浮动提示方法tooltip支持弹窗 2019-10-18 17:59:54 +08:00
RuoYi 0ebd155be4 浮动提示方法tooltip支持弹窗 2019-10-18 17:20:57 +08:00
RuoYi 660fc42750 汉化select2插件 2019-10-18 15:02:04 +08:00
RuoYi 46b08d9474 字典数据支持模糊条件查询 2019-10-18 11:23:10 +08:00
RuoYi 9ac3ca79f8 代码生成支持模糊条件查询 2019-10-18 09:36:27 +08:00
RuoYi 7eade0d43c 添加页签全屏方法 2019-10-17 19:39:56 +08:00
RuoYi cf2ae2bccb 增加清除表单验证错误信息方法 2019-10-17 18:39:57 +08:00
RuoYi f9a2f9e0f4 支持iframe局部刷新页面 2019-10-17 10:45:19 +08:00
RuoYi 01f40d91ec 支持在线切换主题 2019-10-16 13:43:19 +08:00
RuoYi dd57a4fb1a 设置mybatis全局的配置文件 2019-10-15 15:39:15 +08:00
RuoYi 69cc7a4111 代码生成实体根据模板区分不同父字段 2019-10-15 12:45:55 +08:00
RuoYi 9f5067fbad 用户唯一校验参数属性名修正 2019-10-15 10:57:49 +08:00
若依 c3a6f4af6a !140 添加用户时,用户名、手机号、邮箱唯一校验参数修正
Merge pull request !140 from BoazJun/master
2019-10-15 10:56:28 +08:00
dlnu_wqj ac9666db76 添加用户时,用户名、手机号、邮箱唯一校验参数修正 2019-10-14 15:51:14 +08:00
若依 2d064a9723 !138 修改注释中错误的方法形参名
Merge pull request !138 from lywjlong/master
2019-10-09 12:57:14 +08:00
wangjianlong 01de32cc58 修改注释 2019-10-09 12:42:22 +08:00
若依 39fdb02022 !137 fix: 预览图片设置的高宽参数颠倒
Merge pull request !137 from Dulk/fix_bug
2019-10-09 11:52:48 +08:00
deng-cc e0f091819b fix: 预览设置的高宽参数颠倒 2019-10-09 11:45:33 +08:00
RuoYi b2cbc3b28c 新增账户解锁操作 2019-10-08 16:17:23 +08:00
cain 3d10d26110 Merge remote-tracking branch 'origin/master' 2019-10-08 15:36:09 +08:00
cain f4ab77f80a 账户锁定新增解锁功能 2019-10-08 15:35:36 +08:00
RuoYi 9532ad5fcd 删除多余注解 2019-10-08 11:53:47 +08:00
cain d1c5ec58df Merge remote-tracking branch 'origin/master' 2019-10-08 09:12:16 +08:00
RuoYi 509032ff8b 修改项目扩展链接 2019-10-05 21:34:33 +08:00
RuoYi 1447fc413b 组件文档地址修改 2019-10-04 17:45:44 +08:00
RuoYi 661b6fe5d5 管理员用户&角色不允许操作 2019-10-03 09:45:41 +08:00
若依 ac97d15a7f !136 optgroup标签下多选后表单值转json丢失
Merge pull request !136 from Dulk/fix-optgroup_value_jsonOverride_bug
2019-09-30 12:56:03 +08:00
若依 83ed5fc243 !135 mybatis别名类扫描通配符,无法支持多路径情况
Merge pull request !135 from Dulk/fix-mybatis_aliasScan_bug
2019-09-30 12:54:40 +08:00
RuoYi 39b063ff6a 去掉jsoup调用自定义转义工具 2019-09-30 12:43:56 +08:00
deng-cc 1166be1ea0 fix:修复optgroup标签多选后值转json后丢失的问题 2019-09-30 11:47:46 +08:00
deng-cc 4a44e097a2 fix:修复mybatis别名类扫描无法配置多目录的情况 2019-09-30 11:16:18 +08:00
RuoYi 2d07fcb4b4 选中/取消事件顺序调整 2019-09-30 11:07:11 +08:00
RuoYi 81ec67d4ea 分页记住选择指定列值数据问题修正 2019-09-29 15:53:10 +08:00
cain 3d9f48c365 Merge remote-tracking branch 'origin/master' 2019-09-28 14:37:42 +08:00
RuoYi f600cdf527 添加时间轴示例 2019-09-27 16:27:02 +08:00
cain d66b5811f7 Revert "解决翻页记住选择时获取指定列值的问题"
This reverts commit af6a313
2019-09-26 12:00:45 +08:00
cain af6a313d06 解决翻页记住选择时获取指定列值的问题 2019-09-26 11:49:31 +08:00
RuoYi cf211fa19c 默认配置表格支持移动端适配 2019-09-25 21:56:33 +08:00
RuoYi e1d2d72282 Merge branch 'master' of https://gitee.com/y_project/RuoYi 2019-09-25 19:48:40 +08:00
RuoYi ee8fb0e87b 添加表格父子视图示例 2019-09-25 19:48:29 +08:00
cain a6367e9453 Merge remote-tracking branch 'origin/master' 2019-09-25 19:07:12 +08:00
cain 65640603d1 代码生成sql脚本添加导出按钮 2019-09-25 19:06:50 +08:00
RuoYi 925d2b13d8 表格行内编辑示例添加校验及下拉选项 2019-09-25 18:54:22 +08:00
RuoYi c2e425aa12 添加表格行内编辑示例 2019-09-24 16:18:28 +08:00
RuoYi 538e7dcc29 调整查询条件文本宽度默认为65px 2019-09-23 17:11:22 +08:00
若依 ad8e475bb7 !131 模板少了覆盖标签
Merge pull request !131 from wind/ruoyi
2019-09-23 16:52:44 +08:00
wind f5071e0c4d 模板少了覆盖标签 2019-09-23 16:51:21 +08:00
RuoYi c24758f451 指定 VFS 的实现 2019-09-23 16:14:54 +08:00
RuoYi f83a8ff4c0 升级fastjson到最新版1.2.60 阻止漏洞攻击 2019-09-20 21:10:00 +08:00
RuoYi e6bacada22 升级echarts到最新版4.2.1 2019-09-20 20:39:17 +08:00
RuoYi 16270ae869 操作日志新增返回参数 2019-09-20 19:07:22 +08:00
RuoYi 64f0e9d282 初始多表格demo修改 2019-09-20 18:22:34 +08:00
RuoYi d5d2ae1da8 支持通配符扫描任意多个包(无需配置多个包路径),以及防止出现类名重复异常 2019-09-17 20:13:04 +08:00
RuoYi 6dfc2a0a3d 表单构建日期选择元素调整 2019-09-14 09:05:05 +08:00
RuoYi 0f7952b9d5 添加isUser,便于校验用户是否已登录 2019-09-12 19:35:41 +08:00
RuoYi fcc889ca07 Shiro权限支持多种情况验证 2019-09-12 19:19:54 +08:00
RuoYi 362374d0b7 代码生成表前缀配置支持多个 2019-09-11 19:06:57 +08:00
若依 c6c71a7e70 !128 修复代码生成Add、Edit页面多日期选择器只有第一个生效的bug
Merge pull request !128 from SnowFox/master
2019-09-11 18:57:55 +08:00
若依 e1a38a3bd5 !127 自动生成代码 Tree型 add/edit 页面生成不正确
Merge pull request !127 from Dulk/fix-genTree
2019-09-11 18:40:47 +08:00
jingjie520 f169eaf6cc 修复代码生成Add、Edit页面多日期选择器只有第一个生效的bug 2019-09-06 15:10:26 +08:00
deng-cc c920d3ec5b fix:修复树形类型的代码生成的部分必要属性无法显示 2019-09-05 17:01:18 +08:00
deng-cc ac5f45d11a fix:修订代码自动生成中Tree型的Domain属性重复
GenTableColumn.java
public static boolean isSuperColumn(String javaField)
基类有两种,BaseEntity 和 TreeEntity,其中父类忽略的属性中只包含了 BaseEntity 的属性,而没有包含 TreeEntity 中的属性
如此生成的Tree型Domain中,父类已有属性会重复生成
另,为 TreeEntity 添加了 祖级列表属性 ancestors
2019-09-04 16:49:08 +08:00
RuoYi e4984b85f2 修复非表格插件情况下重置出现异常 2019-09-02 12:05:44 +08:00
RuoYi 1bd8dd00d1 修复富文本编辑器有序列表冲突 2019-09-02 11:45:38 +08:00
RuoYi 29ac3e21b2 上传完成回显完成高度调整 2019-09-01 21:49:17 +08:00
若依 7acd197389 !125 演示上传完成回显完成字样只显示一半
Merge pull request !125 from wind/ruoyi
2019-09-01 21:45:10 +08:00
wind 025d28d80d 演示上传完成回显 2019-08-30 17:49:55 +08:00
若依 7d26bfb247 !124 修改自动去除表前缀属性autoRemovePre注释
Merge pull request !124 from RACSU/master
2019-08-30 14:01:28 +08:00
racsu 2c0042c3df 修改自动去除表前缀属性autoRemovePre注释 2019-08-30 10:32:28 +08:00
若依 5a7fcde102 !123 头像裁剪超出预览框,修改高度为450
Merge pull request !123 from wind/ruoyi
2019-08-29 09:40:35 +08:00
wind 5be2aaae15 头像裁剪超出预览框,修改高度为450 2019-08-28 22:52:32 +08:00
RuoYi 1b302b9bde 修复自动去除表前缀配置无效问题 2019-08-28 17:54:05 +08:00
RuoYi 5c7f6b7c7d 按钮可见不显示(权限标识控制) 2019-08-27 09:45:29 +08:00
RuoYi a1d9354de7 修复expireTime会话超时时间无效问题 2019-08-25 22:16:58 +08:00
RuoYi 2a6761d47e Merge branch 'master' of https://gitee.com/y_project/RuoYi 2019-08-23 14:06:52 +08:00
gcii 18786fc669 删除多余提交的代码 2019-08-23 14:05:19 +08:00
gcii 67e6aa0067 修复添加用户页面使用搜索功能后不选择部门会默认选择根目录的bug 2019-08-23 11:55:05 +08:00
RuoYi 12e68fab27 新增本地资源通用下载方法 2019-08-23 10:36:03 +08:00
RuoYi 478520572c 操作日志记录新增请求方式 2019-08-22 21:54:35 +08:00
若依 e7050f5a38 !119 代码生成单选按钮组bug修复
Merge pull request !119 from SnowFox/master
2019-08-22 21:45:14 +08:00
若依 79197b1977 !120 修复表格树bug
Merge pull request !120 from Lunaticf/master
2019-08-22 21:37:32 +08:00
center-liu bf68719e2e 修复表格树bug 2019-08-22 16:03:33 +08:00
jingjie520 9b45b78ba7 修复多组同类数据字典生成的单选按钮点击Label选择项的错误 2019-08-22 10:57:25 +08:00
RuoYi ca48d313a2 修改select2的下拉框的宽度不会随着浏览器的拖拉而改变 2019-08-18 11:01:21 +08:00
RuoYi d9fabe556c 生成模板默认值修改 2019-08-10 18:20:56 +08:00
RuoYi 12ef6d07cf 去掉多余字段 2019-08-10 11:09:41 +08:00
RuoYi bed647427b 修复代码生成树表异常 2019-08-10 11:00:14 +08:00
RuoYi d408e2bf54 主键标识换成大写,防止识别出现问题 2019-08-08 16:42:38 +08:00
RuoYi b5cef34426 未设置主键列默认首个字段为主键信息 2019-08-08 16:24:09 +08:00
若依 129cea08ce !116 代码生成文件名带空格
Merge pull request !116 from BreakLo0p/master
2019-08-08 14:14:48 +08:00
Rex cd10f48f53 代码生成文件名带空格问题 2019-08-08 13:47:19 +08:00
gcii a2c1bfef8f 修复代码生成模块查询条件忘记加where 2019-08-08 10:52:01 +08:00
RuoYi 47f4fce2ab 若依 4.0 2019-08-08 10:35:20 +08:00
RuoYi 1c3541cc05 若依 4.0 2019-08-08 08:53:12 +08:00
RuoYi 5f05734e46 滚动条样式调整 2019-08-05 09:57:16 +08:00
RuoYi e5ab665c57 检查属性是否改变修改为克隆方式(防止热部署出现强转异常) 2019-08-04 11:45:49 +08:00
RuoYi c3417792d9 修改样式名称 2019-08-04 11:01:50 +08:00
RuoYi 174ed02058 Excel支持设置导出类型&更换样式 2019-08-04 09:43:25 +08:00
RuoYi e944409f5e 个人中心手机端显示问题优化 2019-08-03 18:23:41 +08:00
若依 713ccf26e2 !115 浏览代码 解决数据权限只有本部门及以下时候,可能出现数据权限越界的情况
Merge pull request !115 from RACSU/master
2019-08-03 16:43:52 +08:00
RuoYi 3ee87354c8 弹出层指定shadeClose参数选项 2019-08-03 10:40:38 +08:00
RuoYi e942bcf033 修正角色KEY值错误 2019-07-31 20:40:29 +08:00
RACSU dea394a93d 解决数据权限只有本部门及以下时候,可能出现数据权限越界的情况 2019-07-29 22:23:48 +08:00
若依 54ce56564b !113 SysUserMapper.xml 查询语句sql字段重复
Merge pull request !113 from RACSU/master
2019-07-28 21:31:22 +08:00
RACSU ae1d354d4c 更新 SysUserMapper.xml
查询语句sql字段重复,可能引起分页插件报错
2019-07-28 21:27:12 +08:00
RuoYi 20c17d6077 更新演示图 2019-07-27 20:38:19 +08:00
RuoYi abb951a889 条件限制一级菜单href跳转 2019-07-27 18:12:40 +08:00
RuoYi 72a1585e26 树表格添加responseHandler(请求获取数据后处理回调函数,校验异常状态提醒) 2019-07-27 14:36:31 +08:00
RuoYi 38c84fbdc6 修正fileinput图路径 2019-07-27 13:36:36 +08:00
若依 d67ff9bf2c !109 现有 ExcelUtil无法读取公式计算的值
Merge pull request !109 from 厚积薄发/master
2019-07-27 10:50:54 +08:00
RuoYi 986e5bb9bd 新增侧边栏浅色主题(参数管理配置) 2019-07-27 10:40:32 +08:00
RuoYi ba05c28bcf 防止表单重复提交注解移至common模块 2019-07-26 20:29:42 +08:00
RuoYi 71ff337ee0 多数据源支持类注解(允许继承父类的注解) 2019-07-26 20:19:47 +08:00
RuoYi 9e2c685870 支持配置一级菜单href跳转 2019-07-26 19:00:30 +08:00
厚积薄发 75d1872b02 更新 ExcelUtil.java
读取单元格公式的值
2019-07-25 09:17:52 +08:00
RuoYi 9cf4b8935f 冻结列去除选中背景 2019-07-24 19:21:59 +08:00
RuoYi aa5d2b9fe8 添加富文本编辑器示例 2019-07-22 11:59:49 +08:00
RuoYi 76b3c381c3 文件上传修改按钮背景及添加加载动画 2019-07-22 08:52:51 +08:00
RuoYi c923dae619 冻结列适配固定高度 2019-07-21 15:24:05 +08:00
RuoYi 7b0902477d 添加控制台管理用户名和密码 2019-07-21 11:35:36 +08:00
若依 126c4bc8c3 !108 部门修改bug修复
Merge pull request !108 from Ucer/master
2019-07-20 11:22:14 +08:00
ucer a9e300d063 修改部门-添加验证 2019-07-20 11:08:23 +08:00
cain 05331eb99d 新增table选中背景色
修复普通用户打开菜单管理内容为空(缺少字段)
2019-07-19 12:38:57 +08:00
RuoYi adbf5b05ec 新增后台校验 2019-07-19 10:13:11 +08:00
RuoYi bf6c66a77b 新增自定义数据校验 2019-07-19 09:53:45 +08:00
RuoYi 3fc965e0e7 新增@RepeatSubmit注解防止表单重复提交 2019-07-19 09:51:42 +08:00
RuoYi 7e10d16f6c 添加角色权限字符提示信息 2019-07-18 10:46:19 +08:00
RuoYi d9d63cc09d 数据权限为仅本人且没有userAlias别名不查询任何数据 2019-07-17 20:51:28 +08:00
RuoYi dcd6f2252f 文件路径更换 2019-07-17 09:28:15 +08:00
RuoYi 7922cabb5b 添加选卡页同一页签打开&关闭指定demo&更换可操作样式 2019-07-16 15:23:13 +08:00
RuoYi 900de5db80 当前用户重置密码修改缓存 2019-07-16 09:05:23 +08:00
RuoYi bf49b35978 添加选择菜单背景颜色 2019-07-15 08:51:45 +08:00
RuoYi 0df49fcfe8 新增角色数据权限配(仅本人数据权限) 2019-07-14 16:00:14 +08:00
RuoYi fcde715553 验证码参数调整 2019-07-14 12:06:23 +08:00
RuoYi 08ca506cfb 新增卡片列表demo 2019-07-13 19:19:50 +08:00
RuoYi b757c5b7b3 更新密码重置用户信息 2019-07-13 18:23:28 +08:00
RuoYi 9c927e621d IE用户管理界面右侧留白问题 2019-07-13 18:13:23 +08:00
RuoYi 8ebf1504de 修改表格汇总缺少像素问题 2019-07-13 17:16:44 +08:00
RuoYi e315357dd2 新增parentTab选卡页同一页签打开 2019-07-13 16:14:47 +08:00
RuoYi 7b96954b2f 手机端隐藏区域 2019-07-12 17:04:08 +08:00
RuoYi 0c3cac9537 字典类型增加任务分组 2019-07-12 14:51:25 +08:00
RuoYi 2a5065420c 新增firstLoad是否首次请求加载数据,对于查询数据较大可以配置false 2019-07-12 12:32:04 +08:00
RuoYi 3bc161366a 修改错误字眼 2019-07-12 11:40:20 +08:00
RuoYi 3be95bc577 任务日志增加分组条件查询 2019-07-12 10:11:42 +08:00
RuoYi 8c5d7fd336 更新sql脚本 2019-07-12 09:49:41 +08:00
RuoYi d21284f325 定时任务支持Class类调用&多类型参数 2019-07-12 09:37:19 +08:00
RuoYi e7a0f97315 新增列超出指定长度浮动提示(单击文本复制列) 2019-07-11 19:03:03 +08:00
RuoYi 2b20edeff8 上传文件windows去除盘符 2019-07-11 11:55:08 +08:00
RuoYi 304da21e6d 上传文件修改为返回完整路径 2019-07-11 10:53:18 +08:00
RuoYi 8dfa1834e3 表格图片预览支持设置宽高 2019-07-11 10:01:14 +08:00
RuoYi d01f35deeb 表格树新增showSearch是否显示检索信息 2019-07-11 09:24:52 +08:00
RuoYi a4da433a6d 修复对象包含多个Excels导出异常问题 2019-07-10 18:37:43 +08:00
gcii fbddde13c3 重置按钮刷新表格 2019-07-10 17:19:46 +08:00
RuoYi eb7ef55aab 树表格支持多层级访问 2019-07-10 09:07:24 +08:00
RuoYi 6c47f48e06 数据字典是否默认字段获取调整 2019-07-09 18:43:12 +08:00
RuoYi 9e67d8272e 添加用户页面岗位选择框提示 2019-07-09 17:54:18 +08:00
gcii fbe8e6997e 添加用户页面岗位选择框提示 2019-07-09 17:37:26 +08:00
RuoYi 8c912f3906 表格底部下边框防重叠 2019-07-09 17:17:56 +08:00
RuoYi 8caf674f94 添加summernote富文本字号fontsize 2019-07-08 11:14:20 +08:00
RuoYi 7d94c9fcb4 后台校验手机&邮箱不能重复 2019-07-08 08:55:59 +08:00
RuoYi ff878564e4 addr防止空地址校验 2019-06-30 19:47:32 +08:00
liuhulu da5cca0b90 fix,主要针对头像问题进行修复。1.创建账号不保存头像bug。2,查询账号信息时不查询头像bug。3,首页头像显示永远显示默认头像bug。 2019-06-29 22:20:01 +08:00
RuoYi e27297311c 解决表格列设置sortName无效问题 2019-06-27 14:05:40 +08:00
RuoYi 5593a7e7e6 main去掉多余的js 2019-06-26 10:55:05 +08:00
RuoYi a2a75a7fce 更换image表格图片地址 2019-06-25 10:56:33 +08:00
RuoYi 4ca9cb9bab 模板删除多余btn-del 2019-06-25 10:24:24 +08:00
RuoYi b743caeb6c 首页添加统计模板 2019-06-23 13:44:53 +08:00
RuoYi 2565627e7e 页面间隙调整 2019-06-21 19:28:43 +08:00
RuoYi d4096da4f5 修改树方法替换 2019-06-20 11:03:47 +08:00
RuoYi afb19d8ba6 表格树单元格超出部分隐藏显示省略号 2019-06-19 18:12:25 +08:00
RuoYi e7805c988b 修改刷新方法 2019-06-19 16:59:28 +08:00
RuoYi 911fb59e56 新增表格拖拽示例 2019-06-19 16:21:22 +08:00
gcii 080c66d12b 查询按钮bug修复 2019-06-19 14:45:42 +08:00
RuoYi 9dc5db7557 curd图标错误调整 2019-06-18 22:18:36 +08:00
RuoYi 370c047ff8 datetime示例3添加事件click 2019-06-18 22:06:47 +08:00
RuoYi 7d6cdabc09 添加表格动态增删改查示例 2019-06-18 21:56:08 +08:00
RuoYi 1c235dc7f6 优化获取地址方法请求两次 2019-06-18 18:49:41 +08:00
RuoYi ff67062c7f 修改菜单权限显示问题 2019-06-17 13:29:40 +08:00
RuoYi 91dd624048 导入修改为模板渲染 2019-06-15 11:24:03 +08:00
RuoYi ce18a9e86d 修改菜单选中状态失效问题 2019-06-15 10:18:57 +08:00
RuoYi d2e5bd1e43 修改用户更新描述空串不更新问题 2019-06-15 10:18:44 +08:00
RuoYi c7c7d40e4d 选项卡样式优化 2019-06-14 18:55:10 +08:00
RuoYi e0af01d16c 选项卡样式优化 2019-06-14 18:48:01 +08:00
若依 58673fa502 !102 浮点数运算类更新过期方法
Merge pull request !102 from GeBron/master
2019-06-13 17:40:36 +08:00
若依 a1523e3bfd !100 单例模式
Merge pull request !100 from geekymv/master
2019-06-13 17:35:08 +08:00
若依 53fbd6c974 !104 启动时报错,日志目录需要配置,修改使用手册
Merge pull request !104 from jyking/master
2019-06-13 17:34:47 +08:00
jykingiMac f8165653b5 启动时报错,日志目录需要配置,修改使用手册增加:
3.1.4 日志配置
编辑src/main/ resources目录下的logback.yml 文件
<property name="log.path" value="/home/ruoyi/logs" />
改为自己需要的路径
<property name="log.path" value="/Users/jyking/project/logs" />
2019-06-13 08:45:24 +08:00
jykingiMac 2c31fc9e48 启动时报错,日志目录需要配置,修改使用手册增加:
3.1.3 日志配置
编辑src/main/ resources目录下的logback.yml 文件
<property name="log.path" value="/home/ruoyi/logs" />
改为自己需要的路径
<property name="log.path" value="/Users/jyking/project/logs" />
2019-06-13 08:43:13 +08:00
jykingiMac 1e665986a0 启动时报错,日志目录需要配置,修改使用手册增加:
3.1.3 日志配置
编辑src/main/ resources目录下的logback.yml 文件
<property name="log.path" value="/home/ruoyi/logs" />
改为自己需要的路径
<property name="log.path" value="/Users/jyking/project/logs" />
2019-06-13 08:35:58 +08:00
jykingiMac 2eec1a116c 启动时报错,日志目录需要配置,修改使用手册增加:
3.1.3 日志配置配置
编辑src/main/ resources目录下的logback.yml 文件
<property name="log.path" value="/home/ruoyi/logs" />
改为自己需要的路径
<property name="log.path" value="/Users/jyking/project/logs" />
2019-06-13 08:33:13 +08:00
GeBron fed4f1077d 更新过期的方法
BigDecimal.ROUND_HALF_UP 从 jdk9 开始标记为过期,替换为 RoundingMode.HALF_UP (since 1.5)
2019-06-12 17:28:18 +08:00
RuoYi d76c57a691 Excel导出子对象支持多个字段 2019-06-12 16:48:23 +08:00
RuoYi 90de1067d8 角色导出数据范围表达式添加部门 2019-06-12 10:51:05 +08:00
RuoYi 51b8bf85aa 移除select页面多余的js代码 2019-06-11 17:07:29 +08:00
RuoYi d74166f719 在线用户列表设置唯一列 2019-06-10 17:21:53 +08:00
RuoYi 0eeb5b8930 导航栏logo宽度调整 2019-06-06 09:07:50 +08:00
RuoYi f2b69c99e6 退出登录清理缓存 2019-06-05 19:02:07 +08:00
RuoYi f96aeca790 部门及以下数据权限(调整为以下及所有子节点) 2019-06-05 18:18:25 +08:00
geekymv 27283e75c3 单例模式 2019-06-05 16:46:36 +08:00
RuoYi 6bc852918e 详细操作样式调整 2019-06-05 15:29:33 +08:00
RuoYi fd3ffcbd89 收起菜单左侧浮动显示 2019-06-05 14:37:32 +08:00
RuoYi ea23976fde 添加新群号 2019-06-05 10:36:54 +08:00
RuoYi b46735fd78 新增同一个用户最大会话数控制 2019-06-04 16:34:11 +08:00
RuoYi d4b353d8f2 添加报表插件及示例 2019-06-04 09:22:41 +08:00
RuoYi 580ba66114 实例演示开关配置条件隐藏更换为成立才显示 2019-06-04 08:23:41 +08:00
RuoYi 77d41b279d 修改菜单及部门排序规则 2019-06-03 23:09:53 +08:00
RuoYi 9ce273c359 修改菜单及部门排序规则 2019-06-03 22:17:44 +08:00
RuoYi 36738bca90 若依 3.4 2019-06-03 09:19:57 +08:00
RuoYi dfd65fbeb8 后台校验登录账户不能重复 2019-06-02 21:25:33 +08:00
RuoYi 49001edac8 剔除页签操作功能 2019-06-02 11:16:25 +08:00
RuoYi 7b4c8f89e1 新增关闭左侧/关闭右侧/新窗口打开 2019-06-01 17:09:28 +08:00
RuoYi b1f4952cde 导入Excel根据表头与注解名匹配 2019-06-01 14:42:33 +08:00
若依 999cd996fd !95 excel表格完善
Merge pull request !95 from 厚积薄发/master
2019-06-01 14:38:36 +08:00
RuoYi 55a4bfe70c 根据配置控制是否过滤 2019-06-01 14:12:40 +08:00
厚积薄发 bfba5ebbfa 完善excel 2019-06-01 13:20:23 +08:00
RuoYi bff44efcb0 操作栏支持详细按钮 2019-06-01 11:30:39 +08:00
RuoYi 7b36d1f60c submitHandler添加回调参数 2019-06-01 08:20:49 +08:00
RuoYi 54e05bae60 右键菜单选择器更换 2019-05-31 19:10:16 +08:00
RuoYi 50515e1aff 新增角色配置本部门及以下数据权限 2019-05-31 13:55:02 +08:00
RuoYi d1b440fc0d 优化业务校验失败普通请求跳转页面 2019-05-31 13:15:47 +08:00
RuoYi cd3dbd775b 新增显示细节视图 2019-05-30 17:30:35 +08:00
RuoYi 36e59c99f9 菜单权限标识提示 2019-05-30 13:24:45 +08:00
RuoYi 94aafdcf7e 菜单管理新增打开方式 2019-05-30 13:18:16 +08:00
RuoYi 17dd48e51d 左侧的菜单栏宽度调整 2019-05-30 09:40:03 +08:00
RuoYi 1f9b26ae23 去除监控页面底部的广告 2019-05-29 13:24:15 +08:00
RuoYi 79138d5d2f 添加一些触发的事件 2019-05-29 11:50:03 +08:00
RuoYi 65d01c2cee 添加一些触发的事件 2019-05-29 09:00:59 +08:00
RuoYi 202bf1ce65 添加exportOptions属性,防止前端导出无法忽略操作列 2019-05-28 17:44:46 +08:00
RuoYi 8a18c46b84 修改角色数据权限更新会话信息 2019-05-27 18:48:07 +08:00
若依 590fe13004 !93 抽取重复代码到一个方法并修改方法为private级别
Merge pull request !93 from lywjlong/master
2019-05-27 18:39:09 +08:00
wangjianlong 74834fd24e 抽取重复代码到一个方法并修改方法为private级别 2019-05-27 14:41:37 +08:00
RuoYi ba55256630 升级select2到最新版4.0.7 2019-05-25 09:32:38 +08:00
若依 661db11765 !90 抽取重复代码到一个方法
Merge pull request !90 from lywjlong/master
2019-05-25 09:28:12 +08:00
RuoYi 89c4659911 左侧菜单最后一个li样式问题 2019-05-24 10:14:35 +08:00
RuoYi c78802481e 通用mybatis-config移入admin模块 2019-05-24 09:00:49 +08:00
wangjianlong 30a7806328 抽取重复代码到一个方法 2019-05-23 19:04:13 +08:00
RuoYi 14c278554f 防止swagger2.9.2页面报类型转换错误 2019-05-23 17:49:07 +08:00
RuoYi 428d718f75 升级swagger到最新版2.9.2 2019-05-23 13:36:56 +08:00
RuoYi 8076277497 新增页签右键操作 2019-05-23 12:33:09 +08:00
若依 7d7c052771 !89 修复脚本文件乱码问题
Merge pull request !89 from lywjlong/master
2019-05-23 10:11:48 +08:00
lywjlong b743bddb46 修复脚本乱码问题 2019-05-22 23:32:33 +08:00
RuoYi 8968c9730d 修复定时任务权限标识错误 2019-05-22 17:41:12 +08:00
RuoYi cb2232353a 新增点击某行触发的事件 2019-05-20 17:13:29 +08:00
RuoYi c480d769a5 路径分隔符调整 2019-05-19 18:28:57 +08:00
RuoYi a1df41ddde 路径分隔符调整 2019-05-19 17:13:26 +08:00
RuoYi b95aadf198 防止富文本滚动触底回弹 2019-05-17 21:29:04 +08:00
RuoYi 4d45edbf52 修复左侧菜单最后一个li样式问题 2019-05-17 20:41:51 +08:00
RuoYi 854b9426b9 修正遗漏回调函数callback 2019-05-17 17:41:11 +08:00
RuoYi 30cb122bdf 文件上传blob类型处理 2019-05-17 17:35:24 +08:00
RuoYi e16f3a9af9 支持上传任意格式文件 2019-05-17 08:49:20 +08:00
RuoYi 96d8e621e2 下拉框样式优化 2019-05-16 21:50:15 +08:00
RuoYi 1818af2a08 修复角色权限注解失效问题 2019-05-16 13:10:08 +08:00
RuoYi efa3dbbd43 服务器拼团优惠活动 2019-05-15 21:50:58 +08:00
RuoYi f85b5202dc 支持响应完成后的回调函数 2019-05-15 19:03:54 +08:00
RuoYi f96113d55d 新增getPrincipalProperty方法,用于前端及其他模块获取当前用户信息 2019-05-15 10:45:12 +08:00
RuoYi bddb502427 升级jquery.slimscroll到最新版1.3.8 2019-05-14 21:10:17 +08:00
RuoYi c17de82c6b 修改测试参数类型 2019-05-14 20:42:48 +08:00
chenzz d2930ae84f !87 解决在没有选择操作类型时点击搜索出错问题
Merge pull request !87 from chenzz/chenzz-master-patch-16951
2019-05-14 19:08:13 +08:00
RuoYi 9be8716776 新增本部门数据权限 2019-05-14 18:59:12 +08:00
chenzz a2d95a8083 解决在没有选择操作类型时点击搜索出错问题 2019-05-14 16:33:20 +08:00
RuoYi 7555e5aef1 查询条件支持下拉多选 2019-05-14 12:23:59 +08:00
RuoYi 0bad889607 防止操作跳到页面顶端 2019-05-13 19:03:32 +08:00
RuoYi 7662c1eeab 修改冻结列全选框问题 2019-05-13 16:21:40 +08:00
RuoYi 7d6537cc8d 修改冻结列全选框问题 2019-05-13 11:44:02 +08:00
EasyProgramming 06f2fa25c0 !86 修复修改部门层级BUG
Merge pull request !86 from EasyProgramming/fix
2019-05-13 09:36:39 +08:00
zbz 962ab735b5 fix(ruoyi-system):修复修改部门层级BUG
Closes https://gitee.com/y_project/RuoYi/issues/IW1SB
2019-05-08 17:09:59 +08:00
RuoYi b8d1b54e22 美化切换开关 2019-05-05 19:28:12 +08:00
RuoYi b90b1704cf 更换切换开关 2019-05-05 19:14:49 +08:00
RuoYi 07dc3ee287 select2-bootstrap美化下拉框 2019-05-05 17:52:02 +08:00
RuoYi 27c0a440d7 添加图片预览imageView方法 2019-05-05 16:41:43 +08:00
RuoYi 342eda526d 添加视频教程链接 2019-05-04 17:16:07 +08:00
RuoYi 0145494497 左右冻结列同时启用显示问题 2019-04-28 13:31:03 +08:00
RuoYi 7329cbdceb 删除多余代码 2019-04-28 12:58:34 +08:00
lywjlong 8af0afc80d !85 修复权限校验失败跳转页面配置错误的bug
Merge pull request !85 from lywjlong/master
2019-04-28 10:01:41 +08:00
RuoYi 1f9b001648 图片放大效果 2019-04-26 23:00:16 +08:00
wangjianlong 125934592c 修复权限校验失败跳转页面配置错误的bug 2019-04-26 18:21:32 +08:00
RuoYi d9aa73a7ad 国际化资源文件调整 2019-04-24 14:42:12 +08:00
RuoYi ce9463569f 新增五群:1366522 2019-04-23 17:26:39 +08:00
RuoYi 29127c07d3 通知公告布局调整 2019-04-21 14:27:45 +08:00
RuoYi b180a59497 新增查询表格树指定列值 2019-04-21 13:23:54 +08:00
RuoYi 8483e25250 新增rowStyle支持 2019-04-21 12:48:58 +08:00
RuoYi a0a12636ef 优化了一些小问题 2019-04-21 12:05:44 +08:00
RuoYi a2ca643a3a 只有列超出指定长度才浮动提示 2019-04-18 12:46:13 +08:00
RuoYi ff10fe098e 完善swagger2测试案例 2019-04-18 10:48:35 +08:00
RuoYi 72359f3b01 更改系统接口扫描方式 2019-04-17 22:24:55 +08:00
RuoYi 2d58091792 优化自定义条件查询方法 2019-04-12 19:28:21 +08:00
RuoYi 2ad741c4e8 Constants部分常量添加final修饰 2019-04-12 19:10:52 +08:00
Tz 5d84c7fcb0 !84 4级或者更多级组织结构,修改最小组织结构归属时,选择判定失效
Merge pull request !84 from 哈哈/master
2019-04-12 19:04:34 +08:00
RyzeBB d8883da034 提交人:weidu
提交描述:4级或者更多级组织结构,修改最小组织结构归属时,选择判定失效
提交时间:2019-04-12
2019-04-12 15:12:47 +08:00
RuoYi cdaa3da76a 文件名编码迁移至工具类 2019-04-12 12:44:51 +08:00
RuoYi bbcbf1ce9d 去除统计代码 2019-04-10 17:47:56 +08:00
RuoYi 867cd57ae8 字典回显默认样式去背景 2019-04-10 16:18:22 +08:00
RuoYi 0bf1717b65 修复rememberSelected属性设置为true时保留选中状态 2019-04-10 15:37:04 +08:00
RuoYi 83a96a2327 变更任务状态时,保留任务其它属性。 2019-04-10 12:35:38 +08:00
okayliao ab866e8a34 !83 fix:变更任务状态时,保留任务其它属性。
Merge pull request !83 from okayliao/develop
2019-04-10 12:32:51 +08:00
javacspring 5b29b2098b !82 日期控件功问题修复及功能增强
Merge pull request !82 from javacspring/develop
2019-04-10 12:27:11 +08:00
okayliao 4675691035 fix:变更任务状态时,保留任务其它属性。 2019-04-09 17:29:12 +08:00
RuoYi d92be7b3a3 屏蔽基类字段实体生成 2019-04-07 23:27:54 +08:00
RuoYi 99e85093e1 新增角色权限权限可见性,字典状态限制。 2019-04-07 22:16:17 +08:00
chenw 49a9b3e015 1.修复 页面多个日期控制时无法独立显示格式问题
2.新增 日期控件增加选定回调功能、增加控制按键自定义功能
3.新增 控制通过扩展属性data-btn、data-callback实现功能自定义
2019-04-04 18:58:46 +08:00
RuoYi f48b9ff9b9 优化js方法 2019-04-03 18:15:31 +08:00
RuoYi 9312fe6dfb 操作日志新增状态查询&热部署重启菜单丢失修复 2019-04-03 17:39:41 +08:00
RuoYi 1790fceda9 日志配置注释 2019-04-02 17:26:59 +08:00
RuoYi 25232575e3 修改冻结显示问题 2019-04-02 12:57:19 +08:00
RuoYi 7913796730 若依3.3 2019-04-01 08:34:44 +08:00
RuoYi 87b7e8665a 若依3.3 2019-03-31 12:56:04 +08:00
RuoYi 7e67c233dc 表单生成html多行文本不能识别问题 2019-03-25 20:02:12 +08:00
RuoYi 0cec24d90b 集成组件beanutils 2019-03-20 20:58:41 +08:00
RuoYi 6874736a20 增加rootIdValue配置项可指定根节点 2019-03-19 11:47:33 +08:00
RuoYi cd199be6aa 添加新群号 2019-03-18 11:55:21 +08:00
dhx920 fc51f0ce80 !79 修正DynamicDataSourceContextHolder类中三处DataSource拼写错误
Merge pull request !79 from dhx920/master
2019-03-18 11:18:31 +08:00
dhx920 316b126c8f 修正DynamicDataSourceContextHolder类中三处DataSource拼写错误 2019-03-18 11:08:41 +08:00
RuoYi f7a9f33882 按下不触发校验,防止造成资源浪费 2019-03-17 22:27:44 +08:00
RuoYi a805d23afe 权限错误消息提醒添加注释,方便理解 2019-03-17 22:14:37 +08:00
RuoYi fb2887b3bf 修复菜单为“目录”,perms字段保存为NULL编辑角色权限问题 2019-03-17 21:26:01 +08:00
RuoYi 92d98a2a6e 修复IE浏览器导出功能报错 2019-03-17 20:52:45 +08:00
RuoYi d066bf022b 菜单表格树第一级默认不展开 2019-03-17 19:47:35 +08:00
RuoYi e26b65459e 线程异常打印方法移入工具类 2019-03-15 19:02:28 +08:00
RuoYi 00a661e325 捕获线程池执行任务抛出的异常 2019-03-15 18:19:23 +08:00
geekymv 975829f2c0 !78 记录异常日志(默认情况下,线程池会捕获任务抛出的所有异常,但是不做任何处理)
Merge pull request !78 from geekymv/master
2019-03-15 18:14:26 +08:00
RuoYi 9bf809061e 权限校验失败 如果请求为ajax返回json,普通请求跳转页面 2019-03-14 19:41:26 +08:00
geekymv c9dad631df 记录异常日志(默认情况下,线程池会捕获任务抛出的所有异常,但是不做任何处理) 2019-03-13 22:14:03 +08:00
RuoYi 47f5d7a7b7 定时任务导出增加并发执行字段 2019-03-13 20:24:12 +08:00
RuoYi e34b4ea63d 定时任务支持并发控制 2019-03-13 19:45:12 +08:00
RuoYi 9fc42511c6 datetimepicker 汉化 2019-03-13 13:52:09 +08:00
RuoYi c9bd08c2de 修复定时任务执行失败后入库状态为成功 2019-03-13 13:41:40 +08:00
RuoYi 4b8d64f16f 启用点击选中行 2019-03-13 12:41:29 +08:00
RuoYi 32e2e212a7 事务由Controller迁移到Service 2019-03-09 22:21:09 +08:00
RuoYi aa478f2bd6 增加日期控件显示类型及回显格式扩展选项 2019-03-09 21:29:19 +08:00
RuoYi d27d739558 代码生成配置classpath引用文件 2019-03-09 21:14:55 +08:00
RuoYi 4f84560710 修复字典值为0/1时无法输出问题 2019-03-08 16:31:02 +08:00
RuoYi 29e20870fc 调整部分包路径 2019-03-08 16:11:24 +08:00
RuoYi a9f378218b 默认显示Sql监控 2019-03-08 15:25:24 +08:00
RuoYi 9531875401 调整部分包路径 2019-03-08 14:44:38 +08:00
RuoYi 1b193bcc65 关闭选项卡激活滚动 2019-03-07 13:48:40 +08:00
RuoYi 2d32b0d9c2 新增分页跳转到指定页码 2019-03-07 12:57:15 +08:00
RuoYi f1ba270a47 去除多余注释 2019-03-05 22:57:53 +08:00
RuoYi 8a2bba86eb 新增表格销毁方法 2019-03-05 15:51:15 +08:00
RuoYi 9ad6c1b998 更换prompt名称 2019-03-05 15:29:13 +08:00
流光 eca0b9f89b !74 修复 @Excel 注解 prompt 属性使用报错
Merge pull request !74 from 流光/master
2019-03-05 14:52:18 +08:00
RuoYi 536ee476cb 修复在firefox浏览器显示高度问题 2019-03-05 14:42:23 +08:00
stickdream 67b5ff894e 修复@Excel注解 prompt 属性使用报错 2019-03-03 00:56:52 +08:00
RuoYi a469435499 数据被加载触发工具条按钮禁用/启用 2019-03-01 16:03:23 +08:00
RuoYi 1d01d20b49 Ztree树结构优化 2019-03-01 15:26:04 +08:00
RuoYi 161c0f1a67 更新readme 2019-02-28 23:06:00 +08:00
RuoYi b554c46825 手机端自适应优化 2019-02-28 20:52:07 +08:00
RuoYi 402fc9c4eb 文本框、下拉框、时间控件宽度调整 2019-02-28 20:05:12 +08:00
RuoYi a0f07f786a 新增下拉按钮切换 2019-02-28 16:23:09 +08:00
RuoYi 8a37d2ae24 检查字符,防止注入绕过 2019-02-28 13:03:02 +08:00
RuoYi 9c50dd8c2d 添加druid白名单 2019-02-28 12:12:21 +08:00
RuoYi 807b723116 修复界面存在的一些安全问题 2019-02-27 12:29:03 +08:00
RuoYi d399160a0b 表格ID自定义及默认值修改,合并editTree到edit 2019-02-26 16:10:49 +08:00
RuoYi dacf0bfe66 添加表格的高度 2019-02-25 20:02:01 +08:00
RuoYi cf1b00c409 添加表头样式 2019-02-25 15:55:42 +08:00
RuoYi b033c858b8 表单验证优化 2019-02-25 13:19:06 +08:00
RuoYi 6a3ba38b45 新增方法(addTab、editTab) 2019-02-24 14:51:43 +08:00
lsm121 90131d1338 !71 强制退出用户时更新缓存
Merge pull request !71 from lsm121/master
2019-02-22 16:10:47 +08:00
okayliao 2d319a8d0c !73 fix:操作日志页面,权限码错误
Merge pull request !73 from okayliao/master
2019-02-21 12:41:02 +08:00
okayliao 84b39901af fix:操作日志页面,权限码错误 2019-02-18 23:48:38 +08:00
okayliao 877e8edb09 !72 fix:登录地点 字段名错误
Merge pull request !72 from okayliao/develop
2019-02-15 17:55:15 +08:00
RuoYi 2d588ed873 登录地点字段名错误 2019-02-15 17:49:34 +08:00
RuoYi f1f7d7e4fc 使用jsonview展示操作日志参数 2019-02-15 17:46:24 +08:00
okayliao f3ea70c32c fix:登录地点 字段名错误 2019-02-15 16:50:27 +08:00
RuoYi fe4677bcf5 验证码禁用自动记录 2019-02-15 16:07:25 +08:00
RuoYi c03613f317 弹出层增加回调事件 2019-02-15 15:27:41 +08:00
RuoYi cc67d57cef 新增表格客户端分页选项 2019-02-15 14:12:03 +08:00
RuoYi 742846b421 上传文件按日期存储及部分文件路径位置 2019-01-31 11:45:55 +08:00
RuoYi 4829163bab 导入导出支持父类字段 2019-01-31 09:33:02 +08:00
lsm121 3c92ab7463 踢出用户时更新ehcash缓存 2019-01-30 13:08:00 +08:00
RuoYi 2de9f07449 修复combo属性Excel兼容性问题 2019-01-29 17:15:01 +08:00
RuoYi 97260b02cb 个人头像为图片服务器跨域问题 2019-01-29 11:23:16 +08:00
RuoYi af64be2a31 避免ehcache配置文件一直被占用,无法完全销毁项目重新部署 2019-01-29 10:07:57 +08:00
okayliao 0a0a6982f7 !70 fix: 关闭验证码时,保持 "记住我" 间距
Merge pull request !70 from okayliao/master
2019-01-29 09:13:24 +08:00
okayliao 3270db75af fix: 关闭验证码时,保持 "记住我" 间距 2019-01-28 23:08:56 +08:00
okayliao 0d69164acd !69 fix:导入按钮图标错误
Merge pull request !69 from okayliao/master
2019-01-28 18:44:09 +08:00
okayliao a5507dace7 Merge branch 'master' into develop
* master:
  升级datepicker拓展
  修复全屏模式下,详情弹窗被遮盖
2019-01-28 15:20:54 +08:00
okayliao 0ced39f2d6 fix:导出按钮图标错误 2019-01-28 15:20:04 +08:00
RuoYi c5968b76ec 升级datepicker拓展 2019-01-28 13:59:59 +08:00
RuoYi d5014c754c 修复全屏模式下,详情弹窗被遮盖 2019-01-28 13:18:05 +08:00
RuoYi a8b7ba00ac 修改tip默认值20 2019-01-25 20:14:10 +08:00
RuoYi 894090c39f 新增表格浮动提示方法 2019-01-25 17:48:17 +08:00
RuoYi 6b74dcb95f 支持左右列冻结 2019-01-25 11:08:13 +08:00
RuoYi 170e736c44 新增支持冻结列 2019-01-25 10:26:22 +08:00
RuoYi 25d7c2c1f7 spring工具类移至common 2019-01-24 21:56:45 +08:00
RuoYi d5a89621a9 线程池统一管理 2019-01-24 16:31:50 +08:00
okayliao c6bd84818a !68 fix: Mapper文件错误
Merge pull request !68 from okayliao/master
2019-01-24 11:51:26 +08:00
okayliao 262ee4eb5c fix: Mapper 文件错误 2019-01-22 15:44:47 +08:00
RuoYi 00a10ed8df 代码生成列extra属性 2019-01-21 15:25:12 +08:00
RuoYi c064115501 bootstrap-table-mobile.js 2019-01-21 14:46:09 +08:00
RuoYi eae8c660cf 部分字段设置可修改为空 2019-01-18 16:40:56 +08:00
RuoYi f5af4e8204 添加使用文档 2019-01-18 15:59:03 +08:00
RuoYi 2f535082f2 获取完整的服务地址 2019-01-17 15:05:44 +08:00
RuoYi d872c66d19 若依3.2 2019-01-16 23:14:37 +08:00
yutel 1042b40cfc !65 代码生成包名修改
Merge pull request !65 from yutel/master
2019-01-16 18:08:19 +08:00
yutel 070f7bc6bd 更新 Controller.java.vm
解决代码生成时找不到ExcelUtil.java类的问题
2019-01-16 18:02:16 +08:00
RuoYi 4f1c99293f pom 3.2 2019-01-16 15:28:32 +08:00
RuoYi 57fa243747 若依3.2 2019-01-16 14:56:27 +08:00
GeBron 04f2607398 !64 去掉注释中多余参数说明
Merge pull request !64 from GeBron/master
2019-01-16 13:24:46 +08:00
GeBron 01caa02f5e 去掉注释中多余参数说明 2019-01-16 12:58:21 +08:00
RuoYi e37ec9f8fa 用户管理移动端默认隐藏左侧布局 2019-01-13 12:26:09 +08:00
RuoYi 122e8b61a0 详细信息弹出层显示在顶层 2019-01-12 12:08:41 +08:00
RuoYi 2345dfdf42 调整初始密码位置 2019-01-11 10:34:34 +08:00
RuoYi 77550e2f11 用户导入初始密码 2019-01-11 10:14:31 +08:00
RuoYi ca5b4bc852 用户导入 2019-01-11 09:50:16 +08:00
RuoYi 5fc9a63231 新增用户导入权限 2019-01-10 19:51:31 +08:00
ziry 958be505c9 !62 修改样式文件小BUG及改用接口ISysUserOnlineService
Merge pull request !62 from ziry/master
2019-01-10 19:09:55 +08:00
RuoYi ec8c7f1d79 支持用户数据导入 2019-01-10 19:06:15 +08:00
ziry 030b61bc37 修改样式文件小BUG 2019-01-10 15:50:43 +08:00
RuoYi 619e1d241a 升级summernote到最新版本v0.8.11 2019-01-09 16:22:45 +08:00
RuoYi dc07b97cdb 字典数据根据选择下拉新增 2019-01-08 19:30:24 +08:00
RuoYi dd37524b04 修复个人信息修改漏洞 2019-01-08 15:56:49 +08:00
ziry 8c0ebd008e 更新 SysUserOnlineController.java ,改用接口ISysUserOnlineService 2019-01-08 15:42:08 +08:00
RuoYi 0c76d45349 新增修改全屏/确认取消按钮 2019-01-04 11:37:35 +08:00
若依 6237ddb3dc !60 SysJobMapper.deleteJobById改为通过ID删除及修改注释与方法参数对应
Merge pull request !60 from ziry/master
2018-12-29 17:47:01 +08:00
ziry 8643dde074 改为通过ID删除 2018-12-29 16:32:17 +08:00
ziry d22fa29b65 修改注释与方法参数对应 2018-12-29 16:28:54 +08:00
ziry b66097c004 更新 banner.txt
修复启动佛祖保佑图小瑕疵
2018-12-29 15:25:32 +08:00
RuoYi d30dc35e59 代码格式化 2018-12-29 15:18:28 +08:00
RuoYi 87c38706cd Merge branch 'master' of https://gitee.com/y_project/RuoYi 2018-12-29 15:05:53 +08:00
RuoYi f04c1fed50 线程池代码优化 2018-12-29 15:05:29 +08:00
xjt283525476 4474c533e6 !59 修复驼峰转下划线拼接时,简称缩写作为前缀时,转换后首字母后追加了下划线,同时做了代码优化,利于阅读
Merge pull request !59 from xjt283525476/master
2018-12-29 14:25:47 +08:00
xjt283525476 4374a24f79 修复驼峰转下划线拼接时,简称缩写作为前缀时,转换后首字母后追加了下划线 2018-12-29 14:04:16 +08:00
RuoYi 383d082194 类位置迁移 2018-12-29 12:25:46 +08:00
RuoYi e9a7cc7bc7 去除序号居中 2018-12-29 12:04:53 +08:00
xjt283525476 8b07f8925f !57 因笔误导致无意义的判断,同时还会出现空指针异常
Merge pull request !57 from xjt283525476/master
2018-12-29 10:21:58 +08:00
j3east 2af817d8dc !58 解决tomcat无法退出问题
Merge pull request !58 from j3east/j3east
2018-12-29 10:21:17 +08:00
cj 0e240cb244 代码风格和项目保持一致 2018-12-28 23:05:53 +08:00
cj fc834b35cb 一键打war包 2018-12-28 22:55:31 +08:00
cj 4fa795dee9 确保应用退出时能关闭后台线程 2018-12-28 22:54:38 +08:00
RuoYi 33788ecd02 ry-ui新增序列号生成方法 2018-12-28 17:33:15 +08:00
RuoYi 3d3017804d Excel注解支持多级获取 2018-12-28 16:15:56 +08:00
wangchl 63ee2ba2e7 修复会出现空指针异常 2018-12-28 14:23:23 +08:00
xjt283525476 aac46aa353 修复明显笔误 2018-12-27 19:41:56 +08:00
RuoYi c6e4daedd4 摸版edit缺少; 2018-12-27 11:43:16 +08:00
GeBron 6b9b8ed889 !56 修改注释中的参数名称
Merge pull request !56 from GeBron/master
2018-12-25 23:29:09 +08:00
RuoYi 1f000d9f84 Merge branch 'master' of https://gitee.com/y_project/RuoYi 2018-12-25 23:26:52 +08:00
RuoYi 9d5a702e1f 新增方法$.operate.get(url) 2018-12-25 23:24:38 +08:00
GeBron bb1831f609 修改注释中的参数名称 2018-12-25 20:35:18 +08:00
RuoYi c628cf7ee7 去掉多余; 2018-12-25 17:16:27 +08:00
RuoYi 1de73da333 会话检查优化 2018-12-25 11:56:16 +08:00
RuoYi c404de1773 reset 2018-12-20 19:41:56 +08:00
wangchl cfcd48b6b2 取消配置文件配置从数据源,改为直接从数据库中直接读取 2018-12-20 14:24:02 +08:00
RuoYi a87e1d019d 修正getSubject命名 2018-12-19 18:10:44 +08:00
RuoYi ef91e71d7b 修正登录必填项位置偏移 2018-12-19 14:58:06 +08:00
zhangmrit 3bacfc5951 !55 模板
Merge pull request !55 from zhangmrit/ruoyi
2018-12-19 14:54:18 +08:00
zhangmrit b5cd54da66 时区 2018-12-19 14:51:08 +08:00
zhangmrit 0e9925a481 mysql时区和模板修复 2018-12-19 13:55:27 +08:00
RuoYi 7943b765ca 升级MYSQL驱动 2018-12-18 18:16:29 +08:00
RuoYi a74e58f7d5 升级SpringBoot到最新版本2.1.1 2018-12-17 22:32:37 +08:00
RuoYi ea58f8db9c 添加群号 2018-12-14 17:25:04 +08:00
RuoYi 89e21eecea 验证码配置补齐注释 2018-12-14 12:43:31 +08:00
RuoYi 35df1dbcdf 验证码文本字符间距修正 2018-12-14 12:30:33 +08:00
RuoYi 0972bba763 Merge branch 'master' of https://gitee.com/y_project/RuoYi 2018-12-12 13:26:16 +08:00
RuoYi 583b06ca9a 登录界面去除iCheck插件改为自定义css(提升响应速度及部分背景图不适应) 2018-12-12 13:26:01 +08:00
RuoYi 6a4b1898b1 Merge branch 'master' of https://gitee.com/y_project/RuoYi 2018-12-08 23:11:16 +08:00
RuoYi 268f0a6321 陆陆续续收到一些打赏,为了更好的体验已用于演示服务器升级。谢谢各位小伙伴
(2核8G云服务器5M带宽)
2018-12-08 23:11:02 +08:00
RuoYi e56a7e7e57 磁盘(光驱)验证除数不为零 2018-12-06 11:44:20 +08:00
RuoYi 9d225fecb9 修正部门菜单排序字段无效 2018-12-03 20:47:33 +08:00
RuoYi d24481f9a5 部门修改不允许最后层级节点选择 2018-12-01 18:39:54 +08:00
RuoYi 6a592827e8 若依 3.1 2018-12-01 16:14:19 +08:00
RuoYi 451caf12fc 修正选中菜单项无效 2018-11-30 11:37:50 +08:00
zhangmrit 7517b1baa9 !46 多余的标签
Merge pull request !46 from zhangmrit/ruoyi
2018-11-28 19:03:37 +08:00
zhangmrit 5d582331d3 多余的标签 2018-11-28 18:32:55 +08:00
tenchiwuyo 2d99d2c286 !45 补全@Override注解;修正注释中参数项;
Merge pull request !45 from tenchiwuyo/master
2018-11-28 16:47:42 +08:00
andy d881d45829 补全@Override注解;修正注释中参数项; 2018-11-28 16:19:53 +08:00
chenzz 66aabcd2b4 !43 修复菜单,部门管理tree控件展开/折叠不可用问题
Merge pull request !43 from chenzz/Branch_bug_fix
2018-11-26 15:37:18 +08:00
chenzz 6128d816de 修复菜单,部门管理tree控件展开/折叠不可用问题 2018-11-26 15:35:37 +08:00
RuoYi 553358aa12 新增提交静默更新表格方法 2018-11-25 17:27:57 +08:00
RuoYi 650f89ac13 任务日志新增详细 2018-11-24 16:13:35 +08:00
RuoYi 1292dcf579 Excel注解新增 height/width/suffix/defaultValue 2018-11-24 08:54:01 +08:00
RuoYi 1c1078565a Merge branch 'master' of https://gitee.com/y_project/RuoYi 2018-11-23 22:43:53 +08:00
RuoYi 4d2d5defb9 Excel注解新增 dateFormat日期格式/readConverterExp读取内容转表达式 2018-11-23 22:43:20 +08:00
wangchl 75f27dc536 删出冗余代码 2018-11-23 17:16:48 +08:00
RuoYi aa06f1adc5 代码生成datas变量全局 2018-11-23 13:26:03 +08:00
RuoYi a42c824e92 文件路径保持与packageName一致 2018-11-22 21:33:57 +08:00
RuoYi 67e87bde94 在线用户服务修改 2018-11-22 13:03:57 +08:00
若依 a2735adc57 !39 ruoyi-system模块下SysUserOnlineServiceImpl未实现ISysUserOnlineService
Merge pull request !39 from TyroneGo/master
2018-11-22 12:35:11 +08:00
Tyrone 80bda1909c SysUserOnlineServiceImpl类没有实现ISysUserOnlineService 2018-11-22 10:27:16 +08:00
RuoYi a46738dd9d 会话获取Principal 2018-11-22 09:28:06 +08:00
RuoYi c96b73bbda 代码生成优化 2018-11-21 23:37:09 +08:00
RuoYi 4fed9a1e50 Merge branch 'master' of https://gitee.com/y_project/RuoYi 2018-11-19 18:05:57 +08:00
RuoYi b0495c23a6 修复热部署引起Null 2018-11-19 18:05:44 +08:00
若依 007a4e5275 !36 注解丢失
Merge pull request !36 from 麦洛/master
2018-11-19 17:06:20 +08:00
麦洛 bf01219420 添加丢失的 @Override注解 2018-11-19 15:43:18 +08:00
RuoYi bcb7ba19f9 系统用户会话命名sysUser 2018-11-18 18:17:40 +08:00
RuoYi d870710af1 系统用户会话命名sysUser 2018-11-18 18:02:20 +08:00
RuoYi 6244e6bf18 全局ajax提示 2018-11-15 18:34:05 +08:00
RuoYi c1be1659ea 增加关闭全屏 2018-11-15 15:33:03 +08:00
RuoYi 6cda301f43 选项卡新增全屏显示 2018-11-15 13:35:41 +08:00
wangchl e5b314cc96 修复定时任务无法删除参数问题 2018-11-15 12:07:20 +08:00
RuoYi 3383418837 新增打包文件 2018-11-15 08:58:54 +08:00
RuoYi 3a44c4e765 日志详细优化 2018-11-14 23:08:52 +08:00
RuoYi 0c5da2cf17 上传头像提交修改 2018-11-14 18:29:59 +08:00
CharlesSong ecfba42651 !34 BaseController迁移到framework模块的com.ruoyi.web.base路径下
Merge pull request !34 from CharlesSong/master
2018-11-13 16:55:24 +08:00
CharlesSong 26b4f598e2 为了便于二次开发依赖framework项目
1.BaseController迁移到framework com.ruoyi.web.base中
2.admin中的properties 放到root pom中
2018-11-13 16:48:44 +08:00
RuoYi 737c2d8515 前台日期格式转化 2018-11-13 13:07:00 +08:00
RuoYi 8a005a088d 2018年度最受欢迎中国开源软件评选
请给若依/RuoYi 投票,谢谢支持。
https://www.oschina.net/project/top_cn_2018?sort=1
2018-11-12 10:57:54 +08:00
RuoYi dcc534bb2d 2018年度最受欢迎中国开源软件评选
请给若依/RuoYi 投票,谢谢支持。
https://www.oschina.net/project/top_cn_2018?sort=1
2018-11-12 10:55:37 +08:00
RuoYi ebc6a1ade2 登录失败清空验证码 2018-11-07 22:25:36 +08:00
RuoYi 834089ef08 Merge branch 'master' of https://gitee.com/y_project/RuoYi 2018-11-01 17:49:35 +08:00
RuoYi d30b66b633 阿里云双11活动1折团 2018-11-01 17:49:23 +08:00
RuoYi 6a4894e9d1 Merge branch 'master' of https://gitee.com/y_project/RuoYi 2018-10-27 21:39:36 +08:00
RuoYi a44aa5db42 校验cron表达式是否有效 2018-10-27 21:39:01 +08:00
RuoYi 71c3274333 修改finalName 2018-10-26 13:29:07 +08:00
RuoYi 1961ca5197 添加warName 2018-10-26 13:21:40 +08:00
RuoYi ba2d7f418d 部署war包启动说明 2018-10-26 13:01:30 +08:00
RuoYi 83b4c25137 扫描路径修改 2018-10-18 16:48:05 +08:00
RuoYi 6ee8053a9b 内网不查询地址 2018-10-16 20:21:59 +08:00
Skqing 7b0e1c46c5 !32 判断如果是内网IP则不去获取IP地址
Merge pull request !32 from Skqing/master
2018-10-16 19:57:55 +08:00
tenchiwuyo 6c99bc1059 !33 修正参数名称
Merge pull request !33 from tenchiwuyo/master
2018-10-16 19:54:17 +08:00
andy f0dadb0123 Merge remote-tracking branch 'origin/master' 2018-10-16 16:19:16 +08:00
andy 6afaae0c05 修正参数名称,deptId改为operId 2018-10-16 16:17:24 +08:00
Skqing e4b9638bd5 判断如果是内网IP则不去获取IP地址 2018-10-16 12:47:09 +08:00
Administrator 27dee2a63a 增加16号段的电话号码验证 2018-10-15 20:38:16 +08:00
RuoYi 260feb7cef 优化一些细节 2018-10-12 14:10:25 +08:00
tenchiwuyo c778cd2ac9 !31 表格增加行间隔色配置项
Merge pull request !31 from tenchiwuyo/master
2018-10-12 13:28:59 +08:00
andy 9660e30ca5 增加表格是否行间隔色的option配置项 2018-10-12 13:21:08 +08:00
RuoYi 5285003dee 修复个人信息-修改密码 2018-10-11 20:27:34 +08:00
RuoYi b5e8432e2f 代码生成路径调整 2018-10-10 21:56:19 +08:00
j3east 4ac96a8348 !30 gitignore更新
Merge pull request !30 from j3east/master
2018-10-09 17:25:02 +08:00
cj f7a0c94c16 不能直接忽略所有名为build的文件夹,因为源代码目录中含也有名为build的文件夹, 2018-10-09 15:39:01 +08:00
RuoYi 16dc6ab57e 父部门不能选择&选择树自适应 2018-10-08 13:41:45 +08:00
j3east 5b2664a87a !29 添加gitignore
Merge pull request !29 from j3east/master
2018-10-07 23:26:20 +08:00
cj 5070f1325f 添加 gitignore 2018-10-07 23:22:16 +08:00
RuoYi bc48c80240 swagger2-UI 2018-10-07 23:10:09 +08:00
kuangbx ebe67e7bde Merge remote-tracking branch 'origin/master'
# Conflicts:
#	ruoyi-admin/pom.xml
#	ruoyi-framework/pom.xml
2018-10-07 22:29:19 +08:00
kuangbx 211a0ab746 [修改内容]调整Pom依赖,目前ruoyi-admin只依赖ruoyi-framework,ruoyi-framework依赖ruoyi-system,ruoyi-generator,ruoyi-quartz。ruoyi-common为基础模块。
[修改人]匡宝旭
[修改时间]2018-10-07 22:06
[备注]编译,打包,测试均通过
2018-10-07 22:06:58 +08:00
RuoYi 2f0c5d2b03 若依 3.0 2018-10-07 21:36:22 +08:00
RuoYi e166127c9f 若依 3.0 2018-10-07 14:16:47 +08:00
RuoYi fed3aa8231 更新演示图 2018-10-06 13:11:13 +08:00
RuoYi aca37844ba 权限标识修改 2018-10-05 19:27:24 +08:00
RuoYi 8b4ea05391 部门/菜单支持(展开/折叠) 2018-10-05 18:43:41 +08:00
RuoYi 5e5c21e14f format 2018-10-03 23:11:09 +08:00
RuoYi c85f36fa1f 固定按钮位置(提交/关闭) 2018-10-03 21:44:14 +08:00
RuoYi e68e13bc16 新增清空(登录、操作、调度)日志 2018-10-03 17:42:25 +08:00
RuoYi fffeef3db5 新增表格检索折叠按钮 2018-10-01 21:32:01 +08:00
RuoYi 4425b81e6d 新增数据权限过滤注解 2018-09-30 17:11:29 +08:00
RuoYi eb2a24dc3c name错误修正 2018-09-29 13:33:41 +08:00
luwenlong cf0c212681 !27 时间格式添加报错
代码生成insert时间格式判断
2018-09-28 17:36:30 +08:00
luwenlong 0b0502f308 解决生成的成袋,时间格式添加错误 2018-09-28 17:18:18 +08:00
RuoYi e1c7db101c 配置context-path默认图片加载问题. 2018-09-27 09:02:58 +08:00
RuoYi b64bb61207 laydate.css 2018-09-21 14:57:07 +08:00
RuoYi c2ef17218a Merge branch 'master' of https://gitee.com/y_project/RuoYi 2018-09-21 14:46:45 +08:00
RuoYi 7d5167b373 时间限制&升级到最新版 2018-09-21 14:46:21 +08:00
RuoYi 8ce5bb4fdf 日志打印输出替换 2018-09-20 19:54:06 +08:00
j3east 9148bb33c3 !26 让【用户管理-账号初始密码】这个参数名副其实
账号初始密码
2018-09-20 09:00:12 +08:00
cj 800d3d5710 重置密码时,默认从参数表中获取 2018-09-19 21:16:53 +08:00
RuoYi f89b4215a1 新域名 ruoyi.vip 2018-09-19 14:18:34 +08:00
RuoYi 9d581bec25 文件上传路径 2018-09-18 18:51:13 +08:00
RuoYi b6048e5429 1、去掉ry-ui.min
2、登录去掉密码显示,
3、导出调整为绝对路径
4、新增一个detail详细方法
2018-09-18 17:43:31 +08:00
RuoYi ac14519d76 新增群号 2018-09-14 11:15:34 +08:00
RuoYi 84068a2e2e 升级poi到最新版3.17 2018-09-04 16:49:23 +08:00
RuoYi 1cb672f8bd 修改头像显示当前图片 2018-09-04 13:14:46 +08:00
RuoYi 4fe158fa94 若依 2.4 2018-09-03 08:45:08 +08:00
RuoYi a4c1912ab2 云产品通用代金券 2018-08-30 17:53:25 +08:00
RuoYi 62151b0c95 阿里云优惠活动(2CPU 4GRAM 1M带宽 40G高效云盘) 2018-08-30 16:30:38 +08:00
RuoYi 32ab3189ac 弹层外区域关闭 2018-08-27 16:02:32 +08:00
liuhulu c6d3e8235f Merge branch 'master' of https://gitee.com/y_project/RuoYi.git 2018-08-27 15:39:56 +08:00
liuhulu 4472dd7b49 增加弹窗功能,点击阴影部分关闭弹窗。 2018-08-27 15:38:52 +08:00
RuoYi 399b20f903 remove fonts 2018-08-27 15:17:37 +08:00
RuoYi 4516d2ef93 漏提交~ 2018-08-27 09:00:36 +08:00
RuoYi 27881c8635 excel导入文件优化 2018-08-26 23:36:30 +08:00
RuoYi f16e013812 增加重置按钮 2018-08-25 10:42:10 +08:00
RuoYi 8cf0c3e806 代码生成路径调整 2018-08-24 15:02:18 +08:00
RuoYi 14a77a8435 部门&菜单alert换成msg 2018-08-23 22:37:51 +08:00
RuoYi eea1061772 备注更换为文本区域 2018-08-23 20:34:23 +08:00
RuoYi 1a5e3606d2 一波细节优化 2018-08-23 17:06:31 +08:00
RuoYi 58f21c0350 修复在线用户-点击登录时间进行排序时报错 2018-08-22 19:47:46 +08:00
RuoYi 7c99e72067 菜单类型必填校验 2018-08-19 13:23:51 +08:00
RuoYi 372c198d13 占位符显示问题 2018-08-19 12:03:05 +08:00
RuoYi 9631720a38 采用枚举类型 2018-08-18 23:51:19 +08:00
RuoYi e5c9aca10f 优化默认返回 2018-08-18 20:32:07 +08:00
RuoYi f096e03342 Merge branch 'master' of https://gitee.com/y_project/RuoYi 2018-08-17 14:55:33 +08:00
RuoYi cac5130504 优化表格样式~ 2018-08-17 14:55:10 +08:00
RuoYi 43b7bfa28d 回显样式修改成下拉框 2018-08-15 22:29:21 +08:00
RuoYi e93e0c4cb7 format 2018-08-15 14:00:23 +08:00
liuhulu f9c82e1f14 1,增加异步管理和工厂两类。
2,修改常规操作为异步同步到数据库。
3,修改登陆日志为异步同步到数据库。
4,修改session为异步同步到数据库。

fix issue:登陆/操作等操作响应时间长。
2018-08-15 12:20:09 +08:00
RuoYi fd75ee49d6 部门修改同步ancestor 2018-08-14 11:56:41 +08:00
RuoYi f67d7179cd xss加入配置文件 2018-08-13 21:40:50 +08:00
RuoYi e8eaeadbb0 新增xss过滤开关 2018-08-10 18:12:28 +08:00
RuoYi bb7799c1aa 新增地址开关 2018-08-10 14:37:33 +08:00
RuoYi 07ffcbf6eb 获取ip地址开关 2018-08-10 14:36:31 +08:00
RuoYi d7dc50a157 methodParams字段修正 2018-08-10 11:13:16 +08:00
RuoYi b0f9dc804a 修正菜单状态类型 2018-08-09 22:55:14 +08:00
RuoYi b7c95affc8 菜单状态查询优化 2018-08-09 22:45:59 +08:00
RuoYi 6bf77f610e 菜单选择设置默认值 2018-08-08 20:58:47 +08:00
RuoYi c42f2d9f3a 部门选择设置默认值 2018-08-08 20:29:05 +08:00
wangchl 79a4f8b30b 修复部门管理新增、编辑点击上级部门确定后再次点击时404错误 2018-08-08 18:46:25 +08:00
RuoYi 54c1079cf4 配置tomcat基础配置 2018-08-08 09:16:59 +08:00
RuoYi d394307901 支持无限级查询 2018-08-07 22:28:11 +08:00
RuoYi 3d37041193 reset 2018-08-07 09:58:17 +08:00
wangchl b438c7c1ad 集成Redis,并封装常用方法 2018-08-07 09:46:21 +08:00
wangchl db8f960b0d 优化部分查询SQL 2018-08-06 11:45:26 +08:00
RuoYi 127b532825 若依 2.3 2018-08-05 12:49:07 +08:00
RuoYi 92fffea429 岗位名称编码唯一校验 2018-08-05 11:05:26 +08:00
RuoYi 32975b3ed7 支持多数据源 2018-08-06 09:00:12 +08:00
RuoYi 6d714b0008 Merge branch 'master' of https://gitee.com/y_project/RuoYi 2018-08-03 10:32:30 +08:00
RuoYi adedb39132 404错误提示修正 2018-08-03 10:32:00 +08:00
RuoYi fc862841ad 优化条件判断 2018-08-01 20:17:55 +08:00
RuoYi f6798b90bf v1.0.2 2018-08-01 17:13:07 +08:00
RuoYi 468281ee06 若依环境使用手册v1.0.2 2018-08-01 17:11:57 +08:00
RuoYi 8467b7e62c TreeTable优化 2018-08-01 14:28:02 +08:00
RuoYi 336faf6feb 角色权限唯一校验 2018-08-01 13:17:11 +08:00
RuoYi 982ce06cde 完善导出权限 2018-08-01 11:42:13 +08:00
RuoYi c7595fe5b6 样式优化 2018-08-01 10:12:34 +08:00
RuoYi a647e22dd3 样式优化 2018-08-01 10:07:28 +08:00
RuoYi 8b4d3cecb4 退出方法修改 2018-07-30 17:45:25 +08:00
wangchl afea140046 提交角色禁用后可正常进入系统 2018-07-30 15:03:20 +08:00
wangchl f1bb10606b mybatis/system/MenuMapper.xml 2018-07-30 14:36:36 +08:00
RuoYi 95b5b12c4d 角色岗位禁用显示置灰 2018-07-30 10:31:40 +08:00
RuoYi 06e25ac4a3 角色岗位禁用显示置灰 2018-07-30 10:29:02 +08:00
RuoYi 7d74dfd0f4 删除多余js 2018-07-29 20:19:21 +08:00
RuoYi f6f8c0b03a reset 2018-07-29 17:04:32 +08:00
yangzhengze 2401c5552e !18 数据权限基础
Merge pull request !18 from yangzhengze/master
2018-07-29 15:48:31 +08:00
RuoYi 743caa2911 手机打开弹出层自适应 2018-07-28 20:42:00 +08:00
RuoYi 9d47a4c6cc 遗漏注释补充 2018-07-28 18:31:41 +08:00
RuoYi 6dc56c6e8d 代码生成新增 toString 2018-07-28 12:20:01 +08:00
RuoYi 470b234528 treetable 2018-07-28 12:10:04 +08:00
Swifly 0047773f24 !17 更新treetable,之前的方案数据量大性能太差
Merge pull request !17 from Swifly/master
2018-07-27 23:34:01 +08:00
Swifly dbfcd39a7e 更新 bootstrap-treetable.css 2018-07-27 23:22:20 +08:00
cyf783 28dd8a0dee 更新treetable,之前的方案数据量大性能太差 2018-07-27 23:16:59 +08:00
RuoYi 7d733d868c 查询优化 2018-07-27 21:56:08 +08:00
RuoYi d5d7cd6592 优化下载文件 2018-07-27 21:02:50 +08:00
RuoYi 4d9c611a7e 优化下载文件 2018-07-27 21:02:30 +08:00
RuoYi 43bde8362b 部门删除校验条件修改 2018-07-26 17:47:14 +08:00
RuoYi 791c767aed 一些优化细节 2018-07-26 12:37:33 +08:00
RuoYi f65728611a 下载数据加载遮罩层 2018-07-25 20:07:07 +08:00
RuoYi 67bd4d3141 inherit 2018-07-25 17:23:41 +08:00
诺墨 f22af6d423 Merge pull request !15 from 诺墨/master 2018-07-24 22:39:38 +08:00
RuoYi f081c89e73 字典数据条件修改 2018-07-24 22:11:04 +08:00
诺墨 0fe4b96933 更正错别字 2018-07-24 21:59:53 +08:00
RuoYi c42b3d8648 添加配置注释 2018-07-24 16:16:19 +08:00
RuoYi 9f8cb8759b format 2018-07-24 10:01:39 +08:00
inotgaoshou cb7af9a547 Merge branch 'master' of https://gitee.com/y_project/RuoYi 2018-07-24 00:23:02 +08:00
inotgaoshou 49ef4086fa 优化代码中 条件 != “”的判断 2018-07-24 00:20:01 +08:00
RuoYi 19b8317cb3 代码生成insert后缀处理 2018-07-23 21:34:33 +08:00
RuoYi ef5687b71c 修改字典同步修改数据 2018-07-23 20:34:01 +08:00
RuoYi 58b4a50fdb 修改密码更换方法 2018-07-23 17:35:56 +08:00
RuoYi 535f2fafc4 支持表格不分页 2018-07-23 15:33:28 +08:00
RuoYi 4e45e4638f 若依2.2版本发布 2018-07-23 10:26:52 +08:00
RuoYi ec71a50a5e 删除fileinput 2018-07-23 09:38:35 +08:00
RuoYi 3ca80dca88 若依2.2版本发布 2018-07-22 23:08:40 +08:00
RuoYi cc9c67cdfb 若依2.2版本发布 2018-07-22 23:05:50 +08:00
Leonhardt92 9e8d80a699 提交ip查询的测试用例 2018-07-22 14:11:19 +08:00
Leonhardt92 48ad8fa0fd 提交ip查询的测试用例 2018-07-22 14:09:41 +08:00
Leonhardt92 7764f42c90 提交完整的测试用例 2018-07-22 14:04:36 +08:00
Leonhardt92 6fb6494223 提交测试用例 2018-07-22 13:43:12 +08:00
RuoYi 95c103fa48 新增执行策略 2018-07-20 17:22:52 +08:00
RuoYi 9a64a3ba4c 新增执行策略 2018-07-20 17:21:43 +08:00
RuoYi 509f17018a 时间查询&排序支持一波 2018-07-19 21:17:17 +08:00
RuoYi 45d1a161bf 支持time类型 2018-07-17 10:31:10 +08:00
RuoYi 1997fe5f74 删除批量新增方法 2018-07-16 11:52:03 +08:00
RuoYi 024d7fbc6a 修正form名称 2018-07-15 20:39:59 +08:00
RuoYi 116f3ac6fc 部门非空条件判断 2018-07-15 10:31:01 +08:00
RuoYi 2f6e6736ca 表格支持边框 2018-07-14 23:16:38 +08:00
RuoYi d891a2ee2b 去掉自定义导出注解column列 2018-07-14 23:15:17 +08:00
RuoYi ffd020d872 更换菜单刷新方法 2018-07-14 18:27:46 +08:00
RuoYi 8de7693f2e 支持查询&统一样式(菜单管理,部门管理) 2018-07-14 18:00:38 +08:00
RuoYi 6cade5fa2a 名字修改 2018-07-14 14:50:56 +08:00
RuoYi d3df335751 Merge branch 'master' of https://gitee.com/y_project/RuoYi 2018-07-14 14:44:40 +08:00
RuoYi 7b38324453 README 2018-07-14 14:44:28 +08:00
蚂蚁 b7d3d1144b Merge pull request !14 from 蚂蚁/master 2018-07-14 10:41:06 +08:00
lxy 1a72fb129d 添加多行文本框 2018-07-14 10:26:13 +08:00
RuoYi 0414c25f9a 支持时间查询(操作日志,登录日志,调度日志) 2018-07-13 22:54:49 +08:00
yangzhengze c7780960fb !13 修复 文件上传配置已经弃用问题
Merge pull request !13 from yangzhengze/master
2018-07-13 11:15:30 +08:00
yangzhengze e132850a40 修复文件上传配置已经弃用 2018-07-13 11:10:57 +08:00
RuoYi 5d0e3a7034 修复热部署转换问题 2018-07-12 18:07:04 +08:00
RuoYi 9ff8613336 修复remark错误 2018-07-12 10:09:33 +08:00
RuoYi 886b05c085 unix编码 2018-07-12 09:59:31 +08:00
RuoYi c7300ddd03 Merge branch 'master' of https://gitee.com/y_project/RuoYi 2018-07-12 09:58:22 +08:00
RuoYi df12e06a3d 优化一些细节 2018-07-12 09:58:12 +08:00
RuoYi e55a42c21f 修复批量生成代码异常问题 2018-07-09 20:38:57 +08:00
RuoYi b8b49209ca 若依 2.1 2018-07-09 09:50:58 +08:00
RuoYi 014ded3996 若依 2.1 2018-07-09 09:42:51 +08:00
RuoYi f8528c19a1 若依 2.1 2018-07-09 09:38:12 +08:00
RuoYi 57773e6eff 若依 2.1 2018-07-09 08:44:52 +08:00
RuoYi a66f603437 delete 2.0 2018-07-09 08:43:49 +08:00
RuoYi 5370f12686 升级pom 2018-07-06 18:04:21 +08:00
RuoYi 8571de0181 若依 2.0 2018-07-03 09:18:28 +08:00
RuoYi 848a0a813f 若依 2.0 2018-07-02 21:35:21 +08:00
RuoYi 5c9ac4e9c8 若依 2.0 2018-07-02 15:26:38 +08:00
RuoYi 2a809d221a 若依 2.0 2018-07-02 14:50:47 +08:00
RuoYi d84737f417 若依 2.0 2018-07-02 11:51:10 +08:00
RuoYi c7c2b542fc 若依 2.0 2018-07-02 10:21:22 +08:00
RuoYi 8d9a76a067 若依 2.0 2018-07-02 09:32:45 +08:00
RuoYi ffd68de51b 若依 2.0 2018-07-02 09:14:43 +08:00
RuoYi fccd5830a4 delete ruoyi 1.1.6 2018-07-02 09:12:48 +08:00
RuoYi 35a2114fc8 模板Post 2018-06-29 19:29:14 +08:00
RuoYi 5f0fa0d42f 优化代码 2018-06-15 15:25:59 +08:00
RuoYi 81b1d1c219 编码 2018-06-21 15:12:16 +08:00
RuoYi 94e56cced5 concat 修改 2018-06-21 14:45:19 +08:00
yangzhengze 36dfecdc16 !12 优化用户批量导入流程和提示信息
Merge pull request !12 from yangzhengze/master
2018-06-06 13:50:40 +08:00
yangzhengze 859d0fe554 更新用户批量导入提示信息 2018-06-06 13:42:31 +08:00
yangzhengze e5684cb6d8 优化批量添加用户提示信息。 2018-06-06 13:23:17 +08:00
yangzhengze 33db69e4fe !11 增加通过Excel文件批量添加用户功能
Merge pull request !11 from yangzhengze/master
2018-06-06 08:56:48 +08:00
yangzhengze dbb2d6a810 更改用户导入模板 2018-06-05 23:20:47 +08:00
yangzhengze 7b52f1f258 更新pom.xml 2018-06-05 23:08:25 +08:00
yangzhengze dcbd2b2210 1.优化上传个人头像错误提示框。
2.增加bootstrap fileinput插件。
3.增加通过Excel文件批量添加用户功能。
2018-06-05 23:03:11 +08:00
RuoYi c5b2b8d5ca 删除方法 2018-06-04 18:22:25 +08:00
RuoYi fe307344b7 兼容分辨率 2018-06-04 12:29:24 +08:00
RuoYi c33c31733e 修正提示 2018-06-03 22:15:04 +08:00
RuoYi 3baaf1929e v1.1.6 发布 2018-06-03 19:34:04 +08:00
RuoYi 5bd1e2bd5f text name 2018-06-01 17:20:29 +08:00
RuoYi ec8d651e3b treegrid居中 2018-06-01 17:10:09 +08:00
RuoYi 60f982e315 提示修正 2018-06-01 09:29:29 +08:00
yangzhengze ba8b136580 !9 修复更改个人头像上传文件类型限定为图片。
Merge pull request !9 from yangzhengze/master
2018-05-31 21:53:43 +08:00
yangzhengze 5096b2267c 修复更改个人头像上传文件类型限定为图片。 2018-05-31 17:14:10 +08:00
RuoYi 4bc46c5fbf swagger 测试方法 2018-05-31 14:21:53 +08:00
RuoYi 8d71859e4c 系统接口 2018-05-31 13:00:34 +08:00
RuoYi e335336064 排序数字校验 2018-05-31 11:46:53 +08:00
yangzhengze e78dc2983f !8 修复断网时出现获取地点错误Bug,改成友好提示。
Merge pull request !8 from yangzhengze/master
2018-05-30 13:43:11 +08:00
yangzhengze 91ea8bffa7 修复断网时出现获取地点错误Bug,改成友好提示。 2018-05-30 12:37:52 +08:00
yangzhengze a21ac8e244 !7 使用Swagger2增加系统api接口, 更新sql,增加测试类
Merge pull request !7 from yangzhengze/master
2018-05-30 11:44:55 +08:00
yangzhengze 41c8576479 优化Swagger2,增加测试类 2018-05-30 11:18:16 +08:00
yangzhengze 2bbd8361d9 更新sql,增加系统api接口 2018-05-29 23:16:39 +08:00
yangzhengze a5fe27fa60 更新sql,增加系统api接口 2018-05-29 23:15:50 +08:00
yangzhengze eb28b5d534 增加swagger接口 2018-05-29 22:53:20 +08:00
yangzhengze 55156b74f3 !6 强制退出时, 退出logout地址,shiro去清除session,防止出现shiro报没有权限错误。
Merge pull request !6 from yangzhengze/master
2018-05-29 11:13:14 +08:00
yangzhengze fd8271553f 强制退出时, 退出logout地址,shiro去清除session,防止出现shiro报没有权限错误。 2018-05-29 11:09:00 +08:00
yangzhengze 90f1ffee63 !5 增加操作日志操作地点、登录日志的登录地点、在线用户登录地点。
Merge pull request !5 from yangzhengze/master
2018-05-29 09:51:12 +08:00
yangzhengze bebafd34b5 增加地点 2018-05-29 09:20:16 +08:00
yangzhengze 1e66da2dd7 1.增加操作日志操作地点、登录日志的登录地点、在线用户登录地点。 2018-05-29 01:37:23 +08:00
若依 c4e18cbfeb !4 用户列表增加部门列和前端全部更改了thymeleaf解析
Merge pull request !4 from yangzhengze/master
2018-05-27 16:55:33 +08:00
yangzhengze faf83c61cc 1.用户列表增加部门列。
2.更改了全部的thymleaf解析。
2018-05-27 14:58:13 +08:00
RuoYi dca60ce43a 若依开源1.1.5发布 2018-05-26 14:29:29 +08:00
RuoYi 595b0312f5 若依开源 1.1.5发布 2018-05-26 14:27:56 +08:00
RuoYi 548f3c2867 注释修正 2018-05-25 18:16:47 +08:00
RuoYi 98fdbff3d8 样式lable换成text 2018-05-25 11:12:14 +08:00
RuoYi 1ca11c9873 UPDATE README 2018-05-24 21:29:00 +08:00
RuoYi 7d5e2eaefd 用户逻辑删除&不允许删除修改管理员 2018-05-24 21:07:59 +08:00
RuoYi 11e4c65372 参数配置排序 2018-05-24 16:59:37 +08:00
RuoYi 4c05b04889 按钮样式调整 2018-05-24 12:55:00 +08:00
RuoYi 2cf599b461 update MIT 2018-05-24 10:36:22 +08:00
RuoYi 970fbb23f8 菜单、部门样式调整 2018-05-24 09:56:57 +08:00
RuoYi ce80396188 数据字典应用 2018-05-23 22:33:18 +08:00
RuoYi 3c5abd5669 Date类型生成处理 2018-05-23 13:55:13 +08:00
RuoYi 532c43ec35 生成代码执行关闭 2018-05-23 10:58:33 +08:00
若依 372eab160a !3 修复代码生成模版中Controller的模版
Merge pull request !3 from Argan Wang/master
2018-05-23 10:49:41 +08:00
Argan 7e2608ef5d fix code-gen Controller template 2018-05-23 10:41:13 +08:00
RuoYi e223e695d5 新增弹窗状态码 modal_status 2018-05-23 09:43:52 +08:00
RuoYi 4de464dc2d 设置全局ajax超时处理 2018-05-22 22:46:40 +08:00
RuoYi 95fc2f2d83 新增用户登陆IP,登陆时间 2018-05-22 22:00:04 +08:00
RuoYi e009cf9708 修复切换Tab错误 2018-05-22 17:38:57 +08:00
RuoYi 2e9445b29e 格式化 2018-05-21 17:24:16 +08:00
liuhulu 7886e2bb9a fix log record,add sync model. 2018-05-21 17:10:23 +08:00
RuoYi c41b58d478 登录失败刷新验证码 2018-05-21 14:50:13 +08:00
RuoYi 6ff61b101f 后台系统摸版 2018-05-21 12:33:10 +08:00
RuoYi b0adc60751 提交后台系统摸版 2018-05-21 12:31:11 +08:00
RuoYi 01d61b1d0e 若依开源1.1.4发布 2018-05-20 09:25:01 +08:00
RuoYi fab59267ed 支持手机号码、邮箱登录 2018-05-18 23:20:19 +08:00
RuoYi a624ac009e 支持模糊查询 2018-05-16 21:44:27 +08:00
RuoYi cc27d85b1a 修复已知bug 2018-05-16 21:20:06 +08:00
RuoYi f85ab94422 数据字典JS加载修复 2018-05-14 15:31:29 +08:00
RuoYi 1bf7f753bf ... 2018-05-13 19:44:03 +08:00
RuoYi 5da5e996ac 若依开源1.1.3发布 2018-05-13 15:11:07 +08:00
RuoYi 784c020fbd 若依开源1.1.3发布 2018-05-13 15:10:15 +08:00
RuoYi 20070163c2 del log 2018-05-09 18:15:47 +08:00
RuoYi 8ee61e9c8c 批量删除操作不记录 2018-05-09 18:15:11 +08:00
RuoYi ab3716c4f4 用户密码长度校验 2018-05-08 11:07:50 +08:00
RuoYi 7734f950fa 新增用户部门必填校验 2018-05-07 20:34:24 +08:00
RuoYi a728b5775f v12版本切换 2018-05-06 15:11:56 +08:00
RuoYi 2e2b160748 去掉多余字符 2018-05-06 14:37:18 +08:00
RuoYi bc97c75da9 图片路径 2018-05-06 14:31:59 +08:00
RuoYi 4a0cbafa52 优化部门停用不显示 2018-05-06 13:58:10 +08:00
RuoYi 9d18d298e7 若依开源1.1.2发布 2018-05-06 12:43:07 +08:00
RuoYi 6f6a9c8ca0 新增个人信息修改 2018-05-05 02:06:25 +08:00
RuoYi ba37447239 新增个人信息 2018-05-04 22:26:04 +08:00
RuoYi 66a904d71e 新增校验 2018-05-04 20:25:14 +08:00
RuoYi c7613a9ff5 构建器路径修复 2018-05-04 13:32:25 +08:00
RuoYi fd56ac4c7f 路径设置 2018-05-03 10:17:43 +08:00
RuoYi ab7f4a04df 更换返回对象 2018-05-03 09:26:13 +08:00
RuoYi 62ffb9c2e7 若依环境使用手册v1.0.1 2018-04-28 21:47:23 +08:00
RuoYi 55ccae57f8 优化JS路径 2018-04-28 21:39:42 +08:00
RuoYi e74c244cdc 提交部分路径修改 2018-04-28 17:58:11 +08:00
RuoYi 4802563837 更新war部署说明 2018-04-28 16:23:00 +08:00
RuoYi 9376208d10 删除多余; 2018-04-28 15:03:06 +08:00
RuoYi 2d84e9183b 构建器路径修改 2018-04-28 14:09:01 +08:00
RuoYi c1c617abbe 更换调度日志、批量生成代码图标 2018-04-28 10:16:46 +08:00
RuoYi 21a743056c 优化操作消息 2018-04-27 13:29:57 +08:00
wangxinxx 1788566a63 !2 更新了页面的th声明及Css/js文件的href属性,模板设计与后端可分离
Merge pull request !2 from wangxinxx/master
2018-04-27 12:40:48 +08:00
RuoYi a19b31dbc5 新增演示地址 2018-04-27 10:53:24 +08:00
RuoYi b2203fce02 添加首页图 2018-04-26 21:57:22 +08:00
RuoYi 1bf49dbf5e 调整首页布局 2018-04-26 21:53:26 +08:00
wangxinxx a20b092a31 更新th声明,login.html/index.html页面的css/js部分增加thymeleaf属性,可通过浏览器直接打开并显示效果。 2018-04-26 17:56:59 +08:00
RuoYi 311118d37e Merge branch 'master' of https://gitee.com/y_project/RuoYi 2018-04-26 16:04:19 +08:00
RuoYi cda62b328c 修改删除方法 2018-04-26 16:04:01 +08:00
RuoYi 1cfb9c4a44 若依环境使用手册v1.0 2018-04-25 23:51:47 +08:00
RuoYi 2800f57cd2 若依环境使用手册v1.0 2018-04-25 23:34:50 +08:00
RuoYi 3e0f08748d 若依环境使用手册v1.0 2018-04-25 23:32:28 +08:00
RuoYi 3de058bb56 若依环境搭建手册v1.0 2018-04-25 23:28:53 +08:00
RuoYi 6481297a64 Merge branch 'master' of https://gitee.com/y_project/RuoYi 2018-04-25 22:17:14 +08:00
RuoYi 4bb10357f6 优化代码 2018-04-25 22:16:41 +08:00
RuoYi cbe386eb83 更新描述&图 2018-04-25 11:08:04 +08:00
RuoYi e384582504 去除捐赠 2018-04-24 23:51:43 +08:00
RuoYi dacd7155b5 注释修正 2018-04-24 14:56:13 +08:00
RuoYi b7c123e2d3 修正单词拼写错误 2018-04-24 14:06:50 +08:00
RuoYi 7677f1efe5 矢量图,质量过关提供 2018-04-23 13:09:21 +08:00
RuoYi 4fd7c2ce1d 数据建模,枫叶的寄托提供 2018-04-23 10:28:31 +08:00
RuoYi d00235228a 菜单图标选择路径修改 2018-04-23 09:50:06 +08:00
RuoYi 262ee25d8e 若依开源1.1.1发布 2018-04-23 00:00:29 +08:00
740 changed files with 164331 additions and 0 deletions

BIN
.DS_Store vendored 100644

Binary file not shown.

1
.github/FUNDING.yml vendored 100644
View File

@ -0,0 +1 @@
custom: http://doc.ruoyi.vip/ruoyi/other/donate.html

49
.gitignore vendored
View File

@ -1,3 +1,51 @@
<<<<<<< HEAD
######################################################################
# Build Tools
.gradle
/build/
!gradle/wrapper/gradle-wrapper.jar
target/
!.mvn/wrapper/maven-wrapper.jar
######################################################################
# IDE
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### JRebel ###
rebel.xml
### NetBeans ###
nbproject/private/
build/*
nbbuild/
dist/
nbdist/
.nb-gradle/
######################################################################
# Others
*.log
*.xml.versionsBackup
*.swp
!*/build/*.java
!*/build/*.html
!*/build/*.xml
=======
# ---> Java
# Compiled class file
*.class
@ -24,3 +72,4 @@
hs_err_pid*
replay_pid*
>>>>>>> c801920fb42d7235b4c6bde29bc433b89846e064

20
LICENSE 100644
View File

@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2018 RuoYi
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

12
bin/clean.bat 100644
View File

@ -0,0 +1,12 @@
@echo off
echo.
echo [信息] 清理工程target生成路径。
echo.
%~d0
cd %~dp0
cd ..
call mvn clean
pause

12
bin/package.bat 100644
View File

@ -0,0 +1,12 @@
@echo off
echo.
echo [信息] 打包Web工程生成war/jar包文件。
echo.
%~d0
cd %~dp0
cd ..
call mvn clean package -Dmaven.test.skip=true
pause

14
bin/run.bat 100644
View File

@ -0,0 +1,14 @@
@echo off
echo.
echo [信息] 使用Jar命令运行Web工程。
echo.
cd %~dp0
cd ../ruoyi-admin/target
set JAVA_OPTS=-Xms256m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m
java -jar %JAVA_OPTS% ruoyi-admin.jar
cd bin
pause

Binary file not shown.

297
pom.xml 100644
View File

@ -0,0 +1,297 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId>
<version>4.8.0</version>
<name>ruoyi</name>
<url>http://sip.unissens.tech</url>
<description>汇智SIP管理系统</description>
<properties>
<ruoyi.version>4.8.0</ruoyi.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
<spring-boot.version>2.5.15</spring-boot.version>
<shiro.version>1.13.0</shiro.version>
<thymeleaf.extras.shiro.version>2.1.0</thymeleaf.extras.shiro.version>
<druid.version>1.2.23</druid.version>
<bitwalker.version>1.21</bitwalker.version>
<kaptcha.version>2.3.3</kaptcha.version>
<swagger.version>3.0.0</swagger.version>
<pagehelper.boot.version>1.4.7</pagehelper.boot.version>
<fastjson.version>1.2.83</fastjson.version>
<oshi.version>6.6.5</oshi.version>
<commons.io.version>2.16.1</commons.io.version>
<poi.version>4.1.2</poi.version>
<velocity.version>2.3</velocity.version>
<!-- override dependency version -->
<tomcat.version>9.0.102</tomcat.version>
<logback.version>1.2.13</logback.version>
<spring-framework.version>5.3.39</spring-framework.version>
</properties>
<!-- 依赖声明 -->
<dependencyManagement>
<dependencies>
<!-- 覆盖SpringFramework的依赖配置-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>${spring-framework.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- SpringBoot的依赖配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- 覆盖logback的依赖配置-->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
<!-- 覆盖tomcat的依赖配置-->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>${tomcat.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-el</artifactId>
<version>${tomcat.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-websocket</artifactId>
<version>${tomcat.version}</version>
</dependency>
<!-- 阿里数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${druid.version}</version>
</dependency>
<!-- 验证码 -->
<dependency>
<groupId>pro.fessional</groupId>
<artifactId>kaptcha</artifactId>
<version>${kaptcha.version}</version>
</dependency>
<!-- Shiro核心框架 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>${shiro.version}</version>
</dependency>
<!-- Shiro使用Spring框架 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>${shiro.version}</version>
</dependency>
<!-- Shiro使用EhCache缓存框架 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>${shiro.version}</version>
</dependency>
<!-- thymeleaf模板引擎和shiro框架的整合 -->
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>${thymeleaf.extras.shiro.version}</version>
</dependency>
<!-- 解析客户端操作系统、浏览器等 -->
<dependency>
<groupId>eu.bitwalker</groupId>
<artifactId>UserAgentUtils</artifactId>
<version>${bitwalker.version}</version>
</dependency>
<!-- pagehelper 分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>${pagehelper.boot.version}</version>
</dependency>
<!-- 获取系统信息 -->
<dependency>
<groupId>com.github.oshi</groupId>
<artifactId>oshi-core</artifactId>
<version>${oshi.version}</version>
</dependency>
<!-- Swagger3依赖 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>${swagger.version}</version>
<exclusions>
<exclusion>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- io常用工具类 -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons.io.version}</version>
</dependency>
<!-- excel工具 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>${poi.version}</version>
</dependency>
<!-- velocity代码生成使用模板 -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>${velocity.version}</version>
</dependency>
<!-- 阿里JSON解析器 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<!-- 定时任务-->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-quartz</artifactId>
<version>${ruoyi.version}</version>
</dependency>
<!-- 代码生成-->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-generator</artifactId>
<version>${ruoyi.version}</version>
</dependency>
<!-- 核心模块-->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-framework</artifactId>
<version>${ruoyi.version}</version>
</dependency>
<!-- 系统模块-->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-system</artifactId>
<version>${ruoyi.version}</version>
</dependency>
<!-- 通用工具-->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId>
<version>${ruoyi.version}</version>
</dependency>
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-sip</artifactId>
<version>${ruoyi.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<modules>
<module>ruoyi-admin</module>
<module>ruoyi-framework</module>
<module>ruoyi-system</module>
<module>ruoyi-quartz</module>
<module>ruoyi-generator</module>
<module>ruoyi-common</module>
<module>ruoyi-sip</module>
</modules>
<packaging>pom</packaging>
<dependencies>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>public</id>
<name>aliyun nexus</name>
<url>https://maven.aliyun.com/repository/public</url>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>public</id>
<name>aliyun nexus</name>
<url>https://maven.aliyun.com/repository/public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>

BIN
ruoyi-admin/.DS_Store vendored 100644

Binary file not shown.

140
ruoyi-admin/pom.xml 100644
View File

@ -0,0 +1,140 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId>
<version>4.8.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<artifactId>ruoyi-admin</artifactId>
<description>
web服务入口
</description>
<dependencies>
<!-- SpringBoot集成thymeleaf模板 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- spring-boot-devtools -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional> <!-- 表示依赖不会传递 -->
</dependency>
<!-- swagger3-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
</dependency>
<!-- 防止进入swagger页面报类型转换错误排除3.0.0中的引用手动增加1.6.2版本 -->
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
<version>1.6.2</version>
</dependency>
<!-- Mysql驱动包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- 核心模块-->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-framework</artifactId>
</dependency>
<!-- 定时任务-->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-quartz</artifactId>
</dependency>
<!-- 代码生成-->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-generator</artifactId>
</dependency>
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-sip</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.5.15</version>
<configuration>
<fork>true</fork> <!-- 如果没有该配置devtools不会生效 -->
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<warName>${project.artifactId}</warName>
</configuration>
</plugin>
<!-- YUI Compressor (CSS/JS压缩)
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>yuicompressor-maven-plugin</artifactId>
<version>1.5.1</version>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>compress</goal>
</goals>
</execution>
</executions>
<configuration>
<encoding>UTF-8</encoding>
<jswarn>false</jswarn>
<nosuffix>true</nosuffix>
<linebreakpos>50000</linebreakpos>
<sourceDirectory>src/main/resources/static</sourceDirectory>
<force>true</force>
<includes>
<include>**/*.js</include>
<include>**/*.css</include>
</includes>
<excludes>
<exclude>**/*.min.js</exclude>
<exclude>**/*.min.css</exclude>
<exclude>**/fileinput.js</exclude>
<exclude>**/validate/**</exclude>
<exclude>**/bootstrap-table/**</exclude>
</excludes>
</configuration>
</plugin> -->
</plugins>
<finalName>${project.artifactId}</finalName>
</build>
</project>

BIN
ruoyi-admin/src/.DS_Store vendored 100644

Binary file not shown.

BIN
ruoyi-admin/src/main/.DS_Store vendored 100644

Binary file not shown.

View File

@ -0,0 +1,30 @@
package com.ruoyi;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
/**
*
*
* @author ruoyi
*/
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
public class RuoYiApplication
{
public static void main(String[] args)
{
// System.setProperty("spring.devtools.restart.enabled", "false");
SpringApplication.run(RuoYiApplication.class, args);
System.out.println("(♥◠‿◠)ノ゙ 若依启动成功 ლ(´ڡ`ლ)゙ \n" +
" .-------. ____ __ \n" +
" | _ _ \\ \\ \\ / / \n" +
" | ( ' ) | \\ _. / ' \n" +
" |(_ o _) / _( )_ .' \n" +
" | (_,_).' __ ___(_ o _)' \n" +
" | |\\ \\ | || |(_,_)' \n" +
" | | \\ `' /| `-' / \n" +
" | | \\ / \\ / \n" +
" ''-' `'-' `-..-' ");
}
}

View File

@ -0,0 +1,18 @@
package com.ruoyi;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
/**
* web
*
* @author ruoyi
*/
public class RuoYiServletInitializer extends SpringBootServletInitializer
{
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application)
{
return application.sources(RuoYiApplication.class);
}
}

View File

@ -0,0 +1,165 @@
package com.ruoyi.web.controller.common;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.config.ServerConfig;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.file.FileUtils;
/**
*
*
* @author ruoyi
*/
@Controller
@RequestMapping("/common")
public class CommonController
{
private static final Logger log = LoggerFactory.getLogger(CommonController.class);
@Autowired
private ServerConfig serverConfig;
private static final String FILE_DELIMETER = ",";
/**
*
*
* @param fileName
* @param delete
*/
@GetMapping("/download")
public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request)
{
try
{
if (!FileUtils.checkAllowDownload(fileName))
{
throw new Exception(StringUtils.format("文件名称({})非法,不允许下载。 ", fileName));
}
String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1);
String filePath = RuoYiConfig.getDownloadPath() + fileName;
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
FileUtils.setAttachmentResponseHeader(response, realFileName);
FileUtils.writeBytes(filePath, response.getOutputStream());
if (delete)
{
FileUtils.deleteFile(filePath);
}
}
catch (Exception e)
{
log.error("下载文件失败", e);
}
}
/**
*
*/
@PostMapping("/upload")
@ResponseBody
public AjaxResult uploadFile(MultipartFile file) throws Exception
{
try
{
// 上传文件路径
String filePath = RuoYiConfig.getUploadPath();
// 上传并返回新文件名称
String fileName = FileUploadUtils.upload(filePath, file);
String url = serverConfig.getUrl() + fileName;
AjaxResult ajax = AjaxResult.success();
ajax.put("url", url);
ajax.put("fileName", fileName);
ajax.put("newFileName", FileUtils.getName(fileName));
ajax.put("originalFilename", file.getOriginalFilename());
return ajax;
}
catch (Exception e)
{
return AjaxResult.error(e.getMessage());
}
}
/**
*
*/
@PostMapping("/uploads")
@ResponseBody
public AjaxResult uploadFiles(List<MultipartFile> files) throws Exception
{
try
{
// 上传文件路径
String filePath = RuoYiConfig.getUploadPath();
List<String> urls = new ArrayList<String>();
List<String> fileNames = new ArrayList<String>();
List<String> newFileNames = new ArrayList<String>();
List<String> originalFilenames = new ArrayList<String>();
for (MultipartFile file : files)
{
// 上传并返回新文件名称
String fileName = FileUploadUtils.upload(filePath, file);
String url = serverConfig.getUrl() + fileName;
urls.add(url);
fileNames.add(fileName);
newFileNames.add(FileUtils.getName(fileName));
originalFilenames.add(file.getOriginalFilename());
}
AjaxResult ajax = AjaxResult.success();
ajax.put("urls", StringUtils.join(urls, FILE_DELIMETER));
ajax.put("fileNames", StringUtils.join(fileNames, FILE_DELIMETER));
ajax.put("newFileNames", StringUtils.join(newFileNames, FILE_DELIMETER));
ajax.put("originalFilenames", StringUtils.join(originalFilenames, FILE_DELIMETER));
return ajax;
}
catch (Exception e)
{
return AjaxResult.error(e.getMessage());
}
}
/**
*
*/
@GetMapping("/download/resource")
public void resourceDownload(String resource, HttpServletRequest request, HttpServletResponse response) throws Exception
{
try
{
if (!FileUtils.checkAllowDownload(resource))
{
throw new Exception(StringUtils.format("资源文件({})非法,不允许下载。 ", resource));
}
// 本地资源路径
String localPath = RuoYiConfig.getProfile();
// 数据库资源地址
String downloadPath = localPath + StringUtils.substringAfter(resource, Constants.RESOURCE_PREFIX);
// 下载名称
String downloadName = StringUtils.substringAfterLast(downloadPath, "/");
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
FileUtils.setAttachmentResponseHeader(response, downloadName);
FileUtils.writeBytes(downloadPath, response.getOutputStream());
}
catch (Exception e)
{
log.error("下载文件失败", e);
}
}
}

View File

@ -0,0 +1,98 @@
package com.ruoyi.web.controller.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
/**
*
*
* @author ruoyi
*/
@Controller
@RequestMapping("/demo/modal")
public class DemoDialogController
{
private String prefix = "demo/modal";
/**
*
*/
@GetMapping("/dialog")
public String dialog()
{
return prefix + "/dialog";
}
/**
*
*/
@GetMapping("/layer")
public String layer()
{
return prefix + "/layer";
}
/**
*
*/
@GetMapping("/form")
public String form()
{
return prefix + "/form";
}
/**
*
*/
@GetMapping("/table")
public String table()
{
return prefix + "/table";
}
/**
* check
*/
@GetMapping("/check")
public String check()
{
return prefix + "/table/check";
}
/**
* radio
*/
@GetMapping("/radio")
public String radio()
{
return prefix + "/table/radio";
}
/**
*
*/
@GetMapping("/parent")
public String parent()
{
return prefix + "/table/parent";
}
/**
* frame1
*/
@GetMapping("/frame1")
public String frame1()
{
return prefix + "/table/frame1";
}
/**
* frame2
*/
@GetMapping("/frame2")
public String frame2()
{
return prefix + "/table/frame2";
}
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,35 @@
package com.ruoyi.web.controller.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
/**
*
*
* @author ruoyi
*/
@Controller
@RequestMapping("/demo/icon")
public class DemoIconController
{
private String prefix = "demo/icon";
/**
* FontAwesome
*/
@GetMapping("/fontawesome")
public String fontAwesome()
{
return prefix + "/fontawesome";
}
/**
* Glyphicons
*/
@GetMapping("/glyphicons")
public String glyphicons()
{
return prefix + "/glyphicons";
}
}

View File

@ -0,0 +1,326 @@
package com.ruoyi.web.controller.demo.controller;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.PageDomain;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.page.TableSupport;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.web.controller.demo.domain.CustomerModel;
import com.ruoyi.web.controller.demo.domain.UserOperateModel;
/**
*
*
* @author ruoyi
*/
@Controller
@RequestMapping("/demo/operate")
public class DemoOperateController extends BaseController
{
private String prefix = "demo/operate";
private final static Map<Integer, UserOperateModel> users = new LinkedHashMap<Integer, UserOperateModel>();
{
users.put(1, new UserOperateModel(1, "1000001", "测试1", "0", "15888888888", "ry@qq.com", 150.0, "0"));
users.put(2, new UserOperateModel(2, "1000002", "测试2", "1", "15666666666", "ry@qq.com", 180.0, "1"));
users.put(3, new UserOperateModel(3, "1000003", "测试3", "0", "15666666666", "ry@qq.com", 110.0, "1"));
users.put(4, new UserOperateModel(4, "1000004", "测试4", "1", "15666666666", "ry@qq.com", 220.0, "1"));
users.put(5, new UserOperateModel(5, "1000005", "测试5", "0", "15666666666", "ry@qq.com", 140.0, "1"));
users.put(6, new UserOperateModel(6, "1000006", "测试6", "1", "15666666666", "ry@qq.com", 330.0, "1"));
users.put(7, new UserOperateModel(7, "1000007", "测试7", "0", "15666666666", "ry@qq.com", 160.0, "1"));
users.put(8, new UserOperateModel(8, "1000008", "测试8", "1", "15666666666", "ry@qq.com", 170.0, "1"));
users.put(9, new UserOperateModel(9, "1000009", "测试9", "0", "15666666666", "ry@qq.com", 180.0, "1"));
users.put(10, new UserOperateModel(10, "1000010", "测试10", "0", "15666666666", "ry@qq.com", 210.0, "1"));
users.put(11, new UserOperateModel(11, "1000011", "测试11", "1", "15666666666", "ry@qq.com", 110.0, "1"));
users.put(12, new UserOperateModel(12, "1000012", "测试12", "0", "15666666666", "ry@qq.com", 120.0, "1"));
users.put(13, new UserOperateModel(13, "1000013", "测试13", "1", "15666666666", "ry@qq.com", 380.0, "1"));
users.put(14, new UserOperateModel(14, "1000014", "测试14", "0", "15666666666", "ry@qq.com", 280.0, "1"));
users.put(15, new UserOperateModel(15, "1000015", "测试15", "0", "15666666666", "ry@qq.com", 570.0, "1"));
users.put(16, new UserOperateModel(16, "1000016", "测试16", "1", "15666666666", "ry@qq.com", 260.0, "1"));
users.put(17, new UserOperateModel(17, "1000017", "测试17", "1", "15666666666", "ry@qq.com", 210.0, "1"));
users.put(18, new UserOperateModel(18, "1000018", "测试18", "1", "15666666666", "ry@qq.com", 340.0, "1"));
users.put(19, new UserOperateModel(19, "1000019", "测试19", "1", "15666666666", "ry@qq.com", 160.0, "1"));
users.put(20, new UserOperateModel(20, "1000020", "测试20", "1", "15666666666", "ry@qq.com", 220.0, "1"));
users.put(21, new UserOperateModel(21, "1000021", "测试21", "1", "15666666666", "ry@qq.com", 120.0, "1"));
users.put(22, new UserOperateModel(22, "1000022", "测试22", "1", "15666666666", "ry@qq.com", 130.0, "1"));
users.put(23, new UserOperateModel(23, "1000023", "测试23", "1", "15666666666", "ry@qq.com", 490.0, "1"));
users.put(24, new UserOperateModel(24, "1000024", "测试24", "1", "15666666666", "ry@qq.com", 570.0, "1"));
users.put(25, new UserOperateModel(25, "1000025", "测试25", "1", "15666666666", "ry@qq.com", 250.0, "1"));
users.put(26, new UserOperateModel(26, "1000026", "测试26", "1", "15666666666", "ry@qq.com", 250.0, "1"));
}
/**
*
*/
@GetMapping("/table")
public String table()
{
return prefix + "/table";
}
/**
*
*/
@GetMapping("/other")
public String other()
{
return prefix + "/other";
}
/**
*
*/
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(UserOperateModel userModel)
{
TableDataInfo rspData = new TableDataInfo();
List<UserOperateModel> userList = new ArrayList<UserOperateModel>(users.values());
// 查询条件过滤
if (StringUtils.isNotEmpty(userModel.getSearchValue()))
{
userList.clear();
for (Map.Entry<Integer, UserOperateModel> entry : users.entrySet())
{
if (entry.getValue().getUserName().equals(userModel.getSearchValue()))
{
userList.add(entry.getValue());
}
}
}
else if (StringUtils.isNotEmpty(userModel.getUserName()))
{
userList.clear();
for (Map.Entry<Integer, UserOperateModel> entry : users.entrySet())
{
if (entry.getValue().getUserName().equals(userModel.getUserName()))
{
userList.add(entry.getValue());
}
}
}
PageDomain pageDomain = TableSupport.buildPageRequest();
if (null == pageDomain.getPageNum() || null == pageDomain.getPageSize())
{
rspData.setRows(userList);
rspData.setTotal(userList.size());
return rspData;
}
Integer pageNum = (pageDomain.getPageNum() - 1) * 10;
Integer pageSize = pageDomain.getPageNum() * 10;
if (pageSize > userList.size())
{
pageSize = userList.size();
}
rspData.setRows(userList.subList(pageNum, pageSize));
rspData.setTotal(userList.size());
return rspData;
}
/**
*
*/
@GetMapping("/add")
public String add(ModelMap mmap)
{
return prefix + "/add";
}
/**
*
*/
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(UserOperateModel user)
{
Integer userId = users.size() + 1;
user.setUserId(userId);
return AjaxResult.success(users.put(userId, user));
}
/**
*
*/
@PostMapping("/customer/add")
@ResponseBody
public AjaxResult addSave(CustomerModel customerModel)
{
System.out.println(customerModel.toString());
return AjaxResult.success();
}
/**
*
*/
@GetMapping("/edit/{userId}")
public String edit(@PathVariable("userId") Integer userId, ModelMap mmap)
{
mmap.put("user", users.get(userId));
return prefix + "/edit";
}
/**
*
*/
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(UserOperateModel user)
{
return AjaxResult.success(users.put(user.getUserId(), user));
}
/**
*
*/
@PostMapping("/export")
@ResponseBody
public AjaxResult export(UserOperateModel user)
{
List<UserOperateModel> list = new ArrayList<UserOperateModel>(users.values());
ExcelUtil<UserOperateModel> util = new ExcelUtil<UserOperateModel>(UserOperateModel.class);
return util.exportExcel(list, "用户数据");
}
/**
*
*/
@GetMapping("/importTemplate")
@ResponseBody
public AjaxResult importTemplate()
{
ExcelUtil<UserOperateModel> util = new ExcelUtil<UserOperateModel>(UserOperateModel.class);
return util.importTemplateExcel("用户数据");
}
/**
*
*/
@PostMapping("/importData")
@ResponseBody
public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception
{
ExcelUtil<UserOperateModel> util = new ExcelUtil<UserOperateModel>(UserOperateModel.class);
List<UserOperateModel> userList = util.importExcel(file.getInputStream());
String message = importUser(userList, updateSupport);
return AjaxResult.success(message);
}
/**
*
*/
@PostMapping("/remove")
@ResponseBody
public AjaxResult remove(String ids)
{
Integer[] userIds = Convert.toIntArray(ids);
for (Integer userId : userIds)
{
users.remove(userId);
}
return AjaxResult.success();
}
/**
*
*/
@GetMapping("/detail/{userId}")
public String detail(@PathVariable("userId") Integer userId, ModelMap mmap)
{
mmap.put("user", users.get(userId));
return prefix + "/detail";
}
@PostMapping("/clean")
@ResponseBody
public AjaxResult clean()
{
users.clear();
return success();
}
/**
*
*
* @param userList
* @param isUpdateSupport
* @return
*/
public String importUser(List<UserOperateModel> userList, Boolean isUpdateSupport)
{
if (StringUtils.isNull(userList) || userList.size() == 0)
{
throw new ServiceException("导入用户数据不能为空!");
}
int successNum = 0;
int failureNum = 0;
StringBuilder successMsg = new StringBuilder();
StringBuilder failureMsg = new StringBuilder();
for (UserOperateModel user : userList)
{
try
{
// 验证是否存在这个用户
boolean userFlag = false;
for (Map.Entry<Integer, UserOperateModel> entry : users.entrySet())
{
if (entry.getValue().getUserName().equals(user.getUserName()))
{
userFlag = true;
break;
}
}
if (!userFlag)
{
Integer userId = users.size() + 1;
user.setUserId(userId);
users.put(userId, user);
successNum++;
successMsg.append("<br/>" + successNum + "、用户 " + user.getUserName() + " 导入成功");
}
else if (isUpdateSupport)
{
users.put(user.getUserId(), user);
successNum++;
successMsg.append("<br/>" + successNum + "、用户 " + user.getUserName() + " 更新成功");
}
else
{
failureNum++;
failureMsg.append("<br/>" + failureNum + "、用户 " + user.getUserName() + " 已存在");
}
}
catch (Exception e)
{
failureNum++;
String msg = "<br/>" + failureNum + "、账号 " + user.getUserName() + " 导入失败:";
failureMsg.append(msg + e.getMessage());
}
}
if (failureNum > 0)
{
failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:");
throw new ServiceException(failureMsg.toString());
}
else
{
successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:");
}
return successMsg.toString();
}
}

View File

@ -0,0 +1,53 @@
package com.ruoyi.web.controller.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
/**
*
*
* @author ruoyi
*/
@Controller
@RequestMapping("/demo/report")
public class DemoReportController
{
private String prefix = "demo/report";
/**
* ECharts
*/
@GetMapping("/echarts")
public String echarts()
{
return prefix + "/echarts";
}
/**
*
*/
@GetMapping("/peity")
public String peity()
{
return prefix + "/peity";
}
/**
* 线
*/
@GetMapping("/sparkline")
public String sparkline()
{
return prefix + "/sparkline";
}
/**
*
*/
@GetMapping("/metrics")
public String metrics()
{
return prefix + "/metrics";
}
}

View File

@ -0,0 +1,116 @@
package com.ruoyi.web.controller.demo.domain;
import java.util.List;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
/**
*
*
* @author ruoyi
*/
public class CustomerModel
{
/**
*
*/
private String name;
/**
*
*/
private String phonenumber;
/**
*
*/
private String sex;
/**
*
*/
private String birthday;
/**
*
*/
private String remark;
/**
*
*/
private List<GoodsModel> goods;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getPhonenumber()
{
return phonenumber;
}
public void setPhonenumber(String phonenumber)
{
this.phonenumber = phonenumber;
}
public String getSex()
{
return sex;
}
public void setSex(String sex)
{
this.sex = sex;
}
public String getBirthday()
{
return birthday;
}
public void setBirthday(String birthday)
{
this.birthday = birthday;
}
public String getRemark()
{
return remark;
}
public void setRemark(String remark)
{
this.remark = remark;
}
public List<GoodsModel> getGoods()
{
return goods;
}
public void setGoods(List<GoodsModel> goods)
{
this.goods = goods;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("name", getName())
.append("phonenumber", getPhonenumber())
.append("sex", getSex())
.append("birthday", getBirthday())
.append("goods", getGoods())
.append("remark", getRemark())
.toString();
}
}

View File

@ -0,0 +1,99 @@
package com.ruoyi.web.controller.demo.domain;
import java.util.Date;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
/**
*
*
* @author ruoyi
*/
public class GoodsModel
{
/**
*
*/
private String name;
/**
*
*/
private Integer weight;
/**
*
*/
private Double price;
/**
*
*/
private Date date;
/**
*
*/
private String type;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public Integer getWeight()
{
return weight;
}
public void setWeight(Integer weight)
{
this.weight = weight;
}
public Double getPrice()
{
return price;
}
public void setPrice(Double price)
{
this.price = price;
}
public Date getDate()
{
return date;
}
public void setDate(Date date)
{
this.date = date;
}
public String getType()
{
return type;
}
public void setType(String type)
{
this.type = type;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("name", getName())
.append("weight", getWeight())
.append("price", getPrice())
.append("date", getDate())
.append("type", getType())
.toString();
}
}

View File

@ -0,0 +1,149 @@
package com.ruoyi.web.controller.demo.domain;
import java.util.Date;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.annotation.Excel.Type;
import com.ruoyi.common.core.domain.BaseEntity;
import com.ruoyi.common.utils.DateUtils;
public class UserOperateModel extends BaseEntity
{
private static final long serialVersionUID = 1L;
private int userId;
@Excel(name = "用户编号")
private String userCode;
@Excel(name = "用户姓名")
private String userName;
@Excel(name = "用户性别", readConverterExp = "0=男,1=女,2=未知")
private String userSex;
@Excel(name = "用户手机")
private String userPhone;
@Excel(name = "用户邮箱")
private String userEmail;
@Excel(name = "用户余额")
private double userBalance;
@Excel(name = "用户状态", readConverterExp = "0=正常,1=停用")
private String status;
@Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Type.EXPORT)
private Date createTime;
public UserOperateModel()
{
}
public UserOperateModel(int userId, String userCode, String userName, String userSex, String userPhone,
String userEmail, double userBalance, String status)
{
this.userId = userId;
this.userCode = userCode;
this.userName = userName;
this.userSex = userSex;
this.userPhone = userPhone;
this.userEmail = userEmail;
this.userBalance = userBalance;
this.status = status;
this.createTime = DateUtils.getNowDate();
}
public int getUserId()
{
return userId;
}
public void setUserId(int userId)
{
this.userId = userId;
}
public String getUserCode()
{
return userCode;
}
public void setUserCode(String userCode)
{
this.userCode = userCode;
}
public String getUserName()
{
return userName;
}
public void setUserName(String userName)
{
this.userName = userName;
}
public String getUserSex()
{
return userSex;
}
public void setUserSex(String userSex)
{
this.userSex = userSex;
}
public String getUserPhone()
{
return userPhone;
}
public void setUserPhone(String userPhone)
{
this.userPhone = userPhone;
}
public String getUserEmail()
{
return userEmail;
}
public void setUserEmail(String userEmail)
{
this.userEmail = userEmail;
}
public double getUserBalance()
{
return userBalance;
}
public void setUserBalance(double userBalance)
{
this.userBalance = userBalance;
}
public String getStatus()
{
return status;
}
public void setStatus(String status)
{
this.status = status;
}
@Override
public Date getCreateTime()
{
return createTime;
}
@Override
public void setCreateTime(Date createTime)
{
this.createTime = createTime;
}
}

View File

@ -0,0 +1,90 @@
package com.ruoyi.web.controller.monitor;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.framework.web.service.CacheService;
/**
*
*
* @author ruoyi
*/
@Controller
@RequestMapping("/monitor/cache")
public class CacheController extends BaseController
{
private String prefix = "monitor/cache";
@Autowired
private CacheService cacheService;
@RequiresPermissions("monitor:cache:view")
@GetMapping()
public String cache(ModelMap mmap)
{
mmap.put("cacheNames", cacheService.getCacheNames());
return prefix + "/cache";
}
@RequiresPermissions("monitor:cache:view")
@PostMapping("/getNames")
public String getCacheNames(String fragment, ModelMap mmap)
{
mmap.put("cacheNames", cacheService.getCacheNames());
return prefix + "/cache::" + fragment;
}
@RequiresPermissions("monitor:cache:view")
@PostMapping("/getKeys")
public String getCacheKeys(String fragment, String cacheName, ModelMap mmap)
{
mmap.put("cacheName", cacheName);
mmap.put("cacheKeys", cacheService.getCacheKeys(cacheName));
return prefix + "/cache::" + fragment;
}
@RequiresPermissions("monitor:cache:view")
@PostMapping("/getValue")
public String getCacheValue(String fragment, String cacheName, String cacheKey, ModelMap mmap)
{
mmap.put("cacheName", cacheName);
mmap.put("cacheKey", cacheKey);
mmap.put("cacheValue", cacheService.getCacheValue(cacheName, cacheKey));
return prefix + "/cache::" + fragment;
}
@RequiresPermissions("monitor:cache:view")
@PostMapping("/clearCacheName")
@ResponseBody
public AjaxResult clearCacheName(String cacheName, ModelMap mmap)
{
cacheService.clearCacheName(cacheName);
return AjaxResult.success();
}
@RequiresPermissions("monitor:cache:view")
@PostMapping("/clearCacheKey")
@ResponseBody
public AjaxResult clearCacheKey(String cacheName, String cacheKey, ModelMap mmap)
{
cacheService.clearCacheKey(cacheName, cacheKey);
return AjaxResult.success();
}
@RequiresPermissions("monitor:cache:view")
@GetMapping("/clearAll")
@ResponseBody
public AjaxResult clearAll(ModelMap mmap)
{
cacheService.clearAll();
return AjaxResult.success();
}
}

View File

@ -0,0 +1,26 @@
package com.ruoyi.web.controller.monitor;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import com.ruoyi.common.core.controller.BaseController;
/**
* druid
*
* @author ruoyi
*/
@Controller
@RequestMapping("/monitor/data")
public class DruidController extends BaseController
{
private String prefix = "/druid";
@RequiresPermissions("monitor:data:view")
@GetMapping()
public String index()
{
return redirect(prefix + "/index.html");
}
}

View File

@ -0,0 +1,31 @@
package com.ruoyi.web.controller.monitor;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.framework.web.domain.Server;
/**
*
*
* @author ruoyi
*/
@Controller
@RequestMapping("/monitor/server")
public class ServerController extends BaseController
{
private String prefix = "monitor/server";
@RequiresPermissions("monitor:server:view")
@GetMapping()
public String server(ModelMap mmap) throws Exception
{
Server server = new Server();
server.copyTo();
mmap.put("server", server);
return prefix + "/server";
}
}

View File

@ -0,0 +1,94 @@
package com.ruoyi.web.controller.monitor;
import java.util.List;
import com.ruoyi.framework.shiro.service.SysPasswordService;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.SysLogininfor;
import com.ruoyi.system.service.ISysLogininforService;
/**
* 访
*
* @author ruoyi
*/
@Controller
@RequestMapping("/monitor/logininfor")
public class SysLogininforController extends BaseController
{
private String prefix = "monitor/logininfor";
@Autowired
private ISysLogininforService logininforService;
@Autowired
private SysPasswordService passwordService;
@RequiresPermissions("monitor:logininfor:view")
@GetMapping()
public String logininfor()
{
return prefix + "/logininfor";
}
@RequiresPermissions("monitor:logininfor:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(SysLogininfor logininfor)
{
startPage();
List<SysLogininfor> list = logininforService.selectLogininforList(logininfor);
return getDataTable(list);
}
@Log(title = "登录日志", businessType = BusinessType.EXPORT)
@RequiresPermissions("monitor:logininfor:export")
@PostMapping("/export")
@ResponseBody
public AjaxResult export(SysLogininfor logininfor)
{
List<SysLogininfor> list = logininforService.selectLogininforList(logininfor);
ExcelUtil<SysLogininfor> util = new ExcelUtil<SysLogininfor>(SysLogininfor.class);
return util.exportExcel(list, "登录日志");
}
@RequiresPermissions("monitor:logininfor:remove")
@Log(title = "登录日志", businessType = BusinessType.DELETE)
@PostMapping("/remove")
@ResponseBody
public AjaxResult remove(String ids)
{
return toAjax(logininforService.deleteLogininforByIds(ids));
}
@RequiresPermissions("monitor:logininfor:remove")
@Log(title = "登录日志", businessType = BusinessType.CLEAN)
@PostMapping("/clean")
@ResponseBody
public AjaxResult clean()
{
logininforService.cleanLogininfor();
return success();
}
@RequiresPermissions("monitor:logininfor:unlock")
@Log(title = "账户解锁", businessType = BusinessType.OTHER)
@PostMapping("/unlock")
@ResponseBody
public AjaxResult unlock(String loginName)
{
passwordService.clearLoginRecordCache(loginName);
return success();
}
}

View File

@ -0,0 +1,90 @@
package com.ruoyi.web.controller.monitor;
import java.util.List;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.SysOperLog;
import com.ruoyi.system.service.ISysOperLogService;
/**
*
*
* @author ruoyi
*/
@Controller
@RequestMapping("/monitor/operlog")
public class SysOperlogController extends BaseController
{
private String prefix = "monitor/operlog";
@Autowired
private ISysOperLogService operLogService;
@RequiresPermissions("monitor:operlog:view")
@GetMapping()
public String operlog()
{
return prefix + "/operlog";
}
@RequiresPermissions("monitor:operlog:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(SysOperLog operLog)
{
startPage();
List<SysOperLog> list = operLogService.selectOperLogList(operLog);
return getDataTable(list);
}
@Log(title = "操作日志", businessType = BusinessType.EXPORT)
@RequiresPermissions("monitor:operlog:export")
@PostMapping("/export")
@ResponseBody
public AjaxResult export(SysOperLog operLog)
{
List<SysOperLog> list = operLogService.selectOperLogList(operLog);
ExcelUtil<SysOperLog> util = new ExcelUtil<SysOperLog>(SysOperLog.class);
return util.exportExcel(list, "操作日志");
}
@Log(title = "操作日志", businessType = BusinessType.DELETE)
@RequiresPermissions("monitor:operlog:remove")
@PostMapping("/remove")
@ResponseBody
public AjaxResult remove(String ids)
{
return toAjax(operLogService.deleteOperLogByIds(ids));
}
@RequiresPermissions("monitor:operlog:detail")
@GetMapping("/detail/{operId}")
public String detail(@PathVariable("operId") Long operId, ModelMap mmap)
{
mmap.put("operLog", operLogService.selectOperLogById(operId));
return prefix + "/detail";
}
@Log(title = "操作日志", businessType = BusinessType.CLEAN)
@RequiresPermissions("monitor:operlog:remove")
@PostMapping("/clean")
@ResponseBody
public AjaxResult clean()
{
operLogService.cleanOperLog();
return success();
}
}

View File

@ -0,0 +1,88 @@
package com.ruoyi.web.controller.monitor;
import java.util.List;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.enums.OnlineStatus;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.framework.shiro.session.OnlineSession;
import com.ruoyi.framework.shiro.session.OnlineSessionDAO;
import com.ruoyi.system.domain.SysUserOnline;
import com.ruoyi.system.service.ISysUserOnlineService;
/**
* 线
*
* @author ruoyi
*/
@Controller
@RequestMapping("/monitor/online")
public class SysUserOnlineController extends BaseController
{
private String prefix = "monitor/online";
@Autowired
private ISysUserOnlineService userOnlineService;
@Autowired
private OnlineSessionDAO onlineSessionDAO;
@RequiresPermissions("monitor:online:view")
@GetMapping()
public String online()
{
return prefix + "/online";
}
@RequiresPermissions("monitor:online:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(SysUserOnline userOnline)
{
startPage();
List<SysUserOnline> list = userOnlineService.selectUserOnlineList(userOnline);
return getDataTable(list);
}
@RequiresPermissions(value = { "monitor:online:batchForceLogout", "monitor:online:forceLogout" }, logical = Logical.OR)
@Log(title = "在线用户", businessType = BusinessType.FORCE)
@PostMapping("/batchForceLogout")
@ResponseBody
public AjaxResult batchForceLogout(String ids)
{
for (String sessionId : Convert.toStrArray(ids))
{
SysUserOnline online = userOnlineService.selectOnlineById(sessionId);
if (online == null)
{
return error("用户已下线");
}
OnlineSession onlineSession = (OnlineSession) onlineSessionDAO.readSession(online.getSessionId());
if (onlineSession == null)
{
return error("用户已下线");
}
if (sessionId.equals(ShiroUtils.getSessionId()))
{
return error("当前登录用户无法强退");
}
onlineSessionDAO.delete(onlineSession);
online.setStatus(OnlineStatus.off_line);
userOnlineService.saveOnline(online);
userOnlineService.removeUserCache(online.getLoginName(), sessionId);
}
return success();
}
}

View File

@ -0,0 +1,92 @@
package com.ruoyi.web.controller.system;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import com.google.code.kaptcha.Constants;
import com.google.code.kaptcha.Producer;
import com.ruoyi.common.core.controller.BaseController;
/**
*
*
* @author ruoyi
*/
@Controller
@RequestMapping("/captcha")
public class SysCaptchaController extends BaseController
{
@Resource(name = "captchaProducer")
private Producer captchaProducer;
@Resource(name = "captchaProducerMath")
private Producer captchaProducerMath;
/**
*
*/
@GetMapping(value = "/captchaImage")
public ModelAndView getKaptchaImage(HttpServletRequest request, HttpServletResponse response)
{
ServletOutputStream out = null;
try
{
HttpSession session = request.getSession();
response.setDateHeader("Expires", 0);
response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
response.addHeader("Cache-Control", "post-check=0, pre-check=0");
response.setHeader("Pragma", "no-cache");
response.setContentType("image/jpeg");
String type = request.getParameter("type");
String capStr = null;
String code = null;
BufferedImage bi = null;
if ("math".equals(type))
{
String capText = captchaProducerMath.createText();
capStr = capText.substring(0, capText.lastIndexOf("@"));
code = capText.substring(capText.lastIndexOf("@") + 1);
bi = captchaProducerMath.createImage(capStr);
}
else if ("char".equals(type))
{
capStr = code = captchaProducer.createText();
bi = captchaProducer.createImage(capStr);
}
session.setAttribute(Constants.KAPTCHA_SESSION_KEY, code);
out = response.getOutputStream();
ImageIO.write(bi, "jpg", out);
out.flush();
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
try
{
if (out != null)
{
out.close();
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
return null;
}
}

View File

@ -0,0 +1,158 @@
package com.ruoyi.web.controller.system;
import java.util.List;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.SysConfig;
import com.ruoyi.system.service.ISysConfigService;
/**
*
*
* @author ruoyi
*/
@Controller
@RequestMapping("/system/config")
public class SysConfigController extends BaseController
{
private String prefix = "system/config";
@Autowired
private ISysConfigService configService;
@RequiresPermissions("system:config:view")
@GetMapping()
public String config()
{
return prefix + "/config";
}
/**
*
*/
@RequiresPermissions("system:config:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(SysConfig config)
{
startPage();
List<SysConfig> list = configService.selectConfigList(config);
return getDataTable(list);
}
@Log(title = "参数管理", businessType = BusinessType.EXPORT)
@RequiresPermissions("system:config:export")
@PostMapping("/export")
@ResponseBody
public AjaxResult export(SysConfig config)
{
List<SysConfig> list = configService.selectConfigList(config);
ExcelUtil<SysConfig> util = new ExcelUtil<SysConfig>(SysConfig.class);
return util.exportExcel(list, "参数数据");
}
/**
*
*/
@RequiresPermissions("system:config:add")
@GetMapping("/add")
public String add()
{
return prefix + "/add";
}
/**
*
*/
@RequiresPermissions("system:config:add")
@Log(title = "参数管理", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(@Validated SysConfig config)
{
if (!configService.checkConfigKeyUnique(config))
{
return error("新增参数'" + config.getConfigName() + "'失败,参数键名已存在");
}
config.setCreateBy(getLoginName());
return toAjax(configService.insertConfig(config));
}
/**
*
*/
@RequiresPermissions("system:config:edit")
@GetMapping("/edit/{configId}")
public String edit(@PathVariable("configId") Long configId, ModelMap mmap)
{
mmap.put("config", configService.selectConfigById(configId));
return prefix + "/edit";
}
/**
*
*/
@RequiresPermissions("system:config:edit")
@Log(title = "参数管理", businessType = BusinessType.UPDATE)
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(@Validated SysConfig config)
{
if (!configService.checkConfigKeyUnique(config))
{
return error("修改参数'" + config.getConfigName() + "'失败,参数键名已存在");
}
config.setUpdateBy(getLoginName());
return toAjax(configService.updateConfig(config));
}
/**
*
*/
@RequiresPermissions("system:config:remove")
@Log(title = "参数管理", businessType = BusinessType.DELETE)
@PostMapping("/remove")
@ResponseBody
public AjaxResult remove(String ids)
{
configService.deleteConfigByIds(ids);
return success();
}
/**
*
*/
@RequiresPermissions("system:config:remove")
@Log(title = "参数管理", businessType = BusinessType.CLEAN)
@GetMapping("/refreshCache")
@ResponseBody
public AjaxResult refreshCache()
{
configService.resetConfigCache();
return success();
}
/**
*
*/
@PostMapping("/checkConfigKeyUnique")
@ResponseBody
public boolean checkConfigKeyUnique(SysConfig config)
{
return configService.checkConfigKeyUnique(config);
}
}

View File

@ -0,0 +1,189 @@
package com.ruoyi.web.controller.system;
import java.util.List;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.Ztree;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.service.ISysDeptService;
/**
*
*
* @author ruoyi
*/
@Controller
@RequestMapping("/system/dept")
public class SysDeptController extends BaseController
{
private String prefix = "system/dept";
@Autowired
private ISysDeptService deptService;
@RequiresPermissions("system:dept:view")
@GetMapping()
public String dept()
{
return prefix + "/dept";
}
@RequiresPermissions("system:dept:list")
@PostMapping("/list")
@ResponseBody
public List<SysDept> list(SysDept dept)
{
List<SysDept> deptList = deptService.selectDeptList(dept);
return deptList;
}
/**
*
*/
@RequiresPermissions("system:dept:add")
@GetMapping("/add/{parentId}")
public String add(@PathVariable("parentId") Long parentId, ModelMap mmap)
{
if (!getSysUser().isAdmin())
{
parentId = getSysUser().getDeptId();
}
mmap.put("dept", deptService.selectDeptById(parentId));
return prefix + "/add";
}
/**
*
*/
@Log(title = "部门管理", businessType = BusinessType.INSERT)
@RequiresPermissions("system:dept:add")
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(@Validated SysDept dept)
{
if (!deptService.checkDeptNameUnique(dept))
{
return error("新增部门'" + dept.getDeptName() + "'失败,部门名称已存在");
}
dept.setCreateBy(getLoginName());
return toAjax(deptService.insertDept(dept));
}
/**
*
*/
@RequiresPermissions("system:dept:edit")
@GetMapping("/edit/{deptId}")
public String edit(@PathVariable("deptId") Long deptId, ModelMap mmap)
{
deptService.checkDeptDataScope(deptId);
SysDept dept = deptService.selectDeptById(deptId);
if (StringUtils.isNotNull(dept) && 100L == deptId)
{
dept.setParentName("无");
}
mmap.put("dept", dept);
return prefix + "/edit";
}
/**
*
*/
@Log(title = "部门管理", businessType = BusinessType.UPDATE)
@RequiresPermissions("system:dept:edit")
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(@Validated SysDept dept)
{
Long deptId = dept.getDeptId();
deptService.checkDeptDataScope(deptId);
if (!deptService.checkDeptNameUnique(dept))
{
return error("修改部门'" + dept.getDeptName() + "'失败,部门名称已存在");
}
else if (dept.getParentId().equals(deptId))
{
return error("修改部门'" + dept.getDeptName() + "'失败,上级部门不能是自己");
}
else if (StringUtils.equals(UserConstants.DEPT_DISABLE, dept.getStatus()) && deptService.selectNormalChildrenDeptById(deptId) > 0)
{
return AjaxResult.error("该部门包含未停用的子部门!");
}
dept.setUpdateBy(getLoginName());
return toAjax(deptService.updateDept(dept));
}
/**
*
*/
@Log(title = "部门管理", businessType = BusinessType.DELETE)
@RequiresPermissions("system:dept:remove")
@GetMapping("/remove/{deptId}")
@ResponseBody
public AjaxResult remove(@PathVariable("deptId") Long deptId)
{
if (deptService.selectDeptCount(deptId) > 0)
{
return AjaxResult.warn("存在下级部门,不允许删除");
}
if (deptService.checkDeptExistUser(deptId))
{
return AjaxResult.warn("部门存在用户,不允许删除");
}
deptService.checkDeptDataScope(deptId);
return toAjax(deptService.deleteDeptById(deptId));
}
/**
*
*/
@PostMapping("/checkDeptNameUnique")
@ResponseBody
public boolean checkDeptNameUnique(SysDept dept)
{
return deptService.checkDeptNameUnique(dept);
}
/**
*
*
* @param deptId ID
* @param excludeId ID
*/
@RequiresPermissions("system:dept:list")
@GetMapping(value = { "/selectDeptTree/{deptId}", "/selectDeptTree/{deptId}/{excludeId}" })
public String selectDeptTree(@PathVariable("deptId") Long deptId, @PathVariable(value = "excludeId", required = false) Long excludeId, ModelMap mmap)
{
mmap.put("dept", deptService.selectDeptById(deptId));
mmap.put("excludeId", excludeId);
return prefix + "/tree";
}
/**
*
*/
@RequiresPermissions("system:dept:list")
@GetMapping("/treeData/{excludeId}")
@ResponseBody
public List<Ztree> treeDataExcludeChild(@PathVariable(value = "excludeId", required = false) Long excludeId)
{
SysDept dept = new SysDept();
dept.setExcludeId(excludeId);
List<Ztree> ztrees = deptService.selectDeptTreeExcludeChild(dept);
return ztrees;
}
}

View File

@ -0,0 +1,122 @@
package com.ruoyi.web.controller.system;
import java.util.List;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.service.ISysDictDataService;
/**
*
*
* @author ruoyi
*/
@Controller
@RequestMapping("/system/dict/data")
public class SysDictDataController extends BaseController
{
private String prefix = "system/dict/data";
@Autowired
private ISysDictDataService dictDataService;
@RequiresPermissions("system:dict:view")
@GetMapping()
public String dictData()
{
return prefix + "/data";
}
@PostMapping("/list")
@RequiresPermissions("system:dict:list")
@ResponseBody
public TableDataInfo list(SysDictData dictData)
{
startPage();
List<SysDictData> list = dictDataService.selectDictDataList(dictData);
return getDataTable(list);
}
@Log(title = "字典数据", businessType = BusinessType.EXPORT)
@RequiresPermissions("system:dict:export")
@PostMapping("/export")
@ResponseBody
public AjaxResult export(SysDictData dictData)
{
List<SysDictData> list = dictDataService.selectDictDataList(dictData);
ExcelUtil<SysDictData> util = new ExcelUtil<SysDictData>(SysDictData.class);
return util.exportExcel(list, "字典数据");
}
/**
*
*/
@RequiresPermissions("system:dict:add")
@GetMapping("/add/{dictType}")
public String add(@PathVariable("dictType") String dictType, ModelMap mmap)
{
mmap.put("dictType", dictType);
return prefix + "/add";
}
/**
*
*/
@Log(title = "字典数据", businessType = BusinessType.INSERT)
@RequiresPermissions("system:dict:add")
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(@Validated SysDictData dict)
{
dict.setCreateBy(getLoginName());
return toAjax(dictDataService.insertDictData(dict));
}
/**
*
*/
@RequiresPermissions("system:dict:edit")
@GetMapping("/edit/{dictCode}")
public String edit(@PathVariable("dictCode") Long dictCode, ModelMap mmap)
{
mmap.put("dict", dictDataService.selectDictDataById(dictCode));
return prefix + "/edit";
}
/**
*
*/
@Log(title = "字典数据", businessType = BusinessType.UPDATE)
@RequiresPermissions("system:dict:edit")
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(@Validated SysDictData dict)
{
dict.setUpdateBy(getLoginName());
return toAjax(dictDataService.updateDictData(dict));
}
@Log(title = "字典数据", businessType = BusinessType.DELETE)
@RequiresPermissions("system:dict:remove")
@PostMapping("/remove")
@ResponseBody
public AjaxResult remove(String ids)
{
dictDataService.deleteDictDataByIds(ids);
return success();
}
}

View File

@ -0,0 +1,188 @@
package com.ruoyi.web.controller.system;
import java.util.List;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.Ztree;
import com.ruoyi.common.core.domain.entity.SysDictType;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.service.ISysDictTypeService;
/**
*
*
* @author ruoyi
*/
@Controller
@RequestMapping("/system/dict")
public class SysDictTypeController extends BaseController
{
private String prefix = "system/dict/type";
@Autowired
private ISysDictTypeService dictTypeService;
@RequiresPermissions("system:dict:view")
@GetMapping()
public String dictType()
{
return prefix + "/type";
}
@PostMapping("/list")
@RequiresPermissions("system:dict:list")
@ResponseBody
public TableDataInfo list(SysDictType dictType)
{
startPage();
List<SysDictType> list = dictTypeService.selectDictTypeList(dictType);
return getDataTable(list);
}
@Log(title = "字典类型", businessType = BusinessType.EXPORT)
@RequiresPermissions("system:dict:export")
@PostMapping("/export")
@ResponseBody
public AjaxResult export(SysDictType dictType)
{
List<SysDictType> list = dictTypeService.selectDictTypeList(dictType);
ExcelUtil<SysDictType> util = new ExcelUtil<SysDictType>(SysDictType.class);
return util.exportExcel(list, "字典类型");
}
/**
*
*/
@RequiresPermissions("system:dict:add")
@GetMapping("/add")
public String add()
{
return prefix + "/add";
}
/**
*
*/
@Log(title = "字典类型", businessType = BusinessType.INSERT)
@RequiresPermissions("system:dict:add")
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(@Validated SysDictType dict)
{
if (!dictTypeService.checkDictTypeUnique(dict))
{
return error("新增字典'" + dict.getDictName() + "'失败,字典类型已存在");
}
dict.setCreateBy(getLoginName());
return toAjax(dictTypeService.insertDictType(dict));
}
/**
*
*/
@RequiresPermissions("system:dict:edit")
@GetMapping("/edit/{dictId}")
public String edit(@PathVariable("dictId") Long dictId, ModelMap mmap)
{
mmap.put("dict", dictTypeService.selectDictTypeById(dictId));
return prefix + "/edit";
}
/**
*
*/
@Log(title = "字典类型", businessType = BusinessType.UPDATE)
@RequiresPermissions("system:dict:edit")
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(@Validated SysDictType dict)
{
if (!dictTypeService.checkDictTypeUnique(dict))
{
return error("修改字典'" + dict.getDictName() + "'失败,字典类型已存在");
}
dict.setUpdateBy(getLoginName());
return toAjax(dictTypeService.updateDictType(dict));
}
@Log(title = "字典类型", businessType = BusinessType.DELETE)
@RequiresPermissions("system:dict:remove")
@PostMapping("/remove")
@ResponseBody
public AjaxResult remove(String ids)
{
dictTypeService.deleteDictTypeByIds(ids);
return success();
}
/**
*
*/
@RequiresPermissions("system:dict:remove")
@Log(title = "字典类型", businessType = BusinessType.CLEAN)
@GetMapping("/refreshCache")
@ResponseBody
public AjaxResult refreshCache()
{
dictTypeService.resetDictCache();
return success();
}
/**
*
*/
@RequiresPermissions("system:dict:list")
@GetMapping("/detail/{dictId}")
public String detail(@PathVariable("dictId") Long dictId, ModelMap mmap)
{
mmap.put("dict", dictTypeService.selectDictTypeById(dictId));
mmap.put("dictList", dictTypeService.selectDictTypeAll());
return "system/dict/data/data";
}
/**
*
*/
@PostMapping("/checkDictTypeUnique")
@ResponseBody
public boolean checkDictTypeUnique(SysDictType dictType)
{
return dictTypeService.checkDictTypeUnique(dictType);
}
/**
*
*/
@GetMapping("/selectDictTree/{columnId}/{dictType}")
public String selectDeptTree(@PathVariable("columnId") Long columnId, @PathVariable("dictType") String dictType, ModelMap mmap)
{
mmap.put("columnId", columnId);
mmap.put("dict", dictTypeService.selectDictTypeByType(dictType));
return prefix + "/tree";
}
/**
*
*/
@GetMapping("/treeData")
@ResponseBody
public List<Ztree> treeData()
{
List<Ztree> ztrees = dictTypeService.selectDictTree(new SysDictType());
return ztrees;
}
}

View File

@ -0,0 +1,178 @@
package com.ruoyi.web.controller.system;
import java.util.Date;
import java.util.List;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.ShiroConstants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysMenu;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.utils.CookieUtils;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.shiro.service.SysPasswordService;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysMenuService;
/**
*
*
* @author ruoyi
*/
@Controller
public class SysIndexController extends BaseController
{
@Autowired
private ISysMenuService menuService;
@Autowired
private ISysConfigService configService;
@Autowired
private SysPasswordService passwordService;
// 系统首页
@GetMapping("/index")
public String index(ModelMap mmap)
{
// 取身份信息
SysUser user = getSysUser();
// 根据用户id取出菜单
List<SysMenu> menus = menuService.selectMenusByUser(user);
mmap.put("menus", menus);
mmap.put("user", user);
mmap.put("sideTheme", configService.selectConfigByKey("sys.index.sideTheme"));
mmap.put("skinName", configService.selectConfigByKey("sys.index.skinName"));
Boolean footer = Convert.toBool(configService.selectConfigByKey("sys.index.footer"), true);
Boolean tagsView = Convert.toBool(configService.selectConfigByKey("sys.index.tagsView"), true);
mmap.put("footer", footer);
mmap.put("tagsView", tagsView);
mmap.put("mainClass", contentMainClass(footer, tagsView));
mmap.put("copyrightYear", RuoYiConfig.getCopyrightYear());
mmap.put("demoEnabled", RuoYiConfig.isDemoEnabled());
mmap.put("isDefaultModifyPwd", initPasswordIsModify(user.getPwdUpdateDate()));
mmap.put("isPasswordExpired", passwordIsExpiration(user.getPwdUpdateDate()));
mmap.put("isMobile", ServletUtils.checkAgentIsMobile(ServletUtils.getRequest().getHeader("User-Agent")));
// 菜单导航显示风格
String menuStyle = configService.selectConfigByKey("sys.index.menuStyle");
// 移动端,默认使左侧导航菜单,否则取默认配置
String indexStyle = ServletUtils.checkAgentIsMobile(ServletUtils.getRequest().getHeader("User-Agent")) ? "index" : menuStyle;
// 优先Cookie配置导航菜单
Cookie[] cookies = ServletUtils.getRequest().getCookies();
for (Cookie cookie : cookies)
{
if (StringUtils.isNotEmpty(cookie.getName()) && "nav-style".equalsIgnoreCase(cookie.getName()))
{
indexStyle = cookie.getValue();
break;
}
}
String webIndex = "topnav".equalsIgnoreCase(indexStyle) ? "index-topnav" : "index";
return webIndex;
}
// 锁定屏幕
@GetMapping("/lockscreen")
public String lockscreen(ModelMap mmap)
{
mmap.put("user", getSysUser());
ServletUtils.getSession().setAttribute(ShiroConstants.LOCK_SCREEN, true);
return "lock";
}
// 解锁屏幕
@PostMapping("/unlockscreen")
@ResponseBody
public AjaxResult unlockscreen(String password)
{
SysUser user = getSysUser();
if (StringUtils.isNull(user))
{
return AjaxResult.error("服务器超时,请重新登录");
}
if (passwordService.matches(user, password))
{
ServletUtils.getSession().removeAttribute(ShiroConstants.LOCK_SCREEN);
return AjaxResult.success();
}
return AjaxResult.error("密码不正确,请重新输入。");
}
// 切换主题
@GetMapping("/system/switchSkin")
public String switchSkin()
{
return "skin";
}
// 切换菜单
@GetMapping("/system/menuStyle/{style}")
public void menuStyle(@PathVariable String style, HttpServletResponse response)
{
CookieUtils.setCookie(response, "nav-style", style);
}
// 系统介绍
@GetMapping("/system/main")
public String main(ModelMap mmap)
{
mmap.put("version", RuoYiConfig.getVersion());
return "main";
}
// content-main class
public String contentMainClass(Boolean footer, Boolean tagsView)
{
if (!footer && !tagsView)
{
return "tagsview-footer-hide";
}
else if (!footer)
{
return "footer-hide";
}
else if (!tagsView)
{
return "tagsview-hide";
}
return StringUtils.EMPTY;
}
// 检查初始密码是否提醒修改
public boolean initPasswordIsModify(Date pwdUpdateDate)
{
Integer initPasswordModify = Convert.toInt(configService.selectConfigByKey("sys.account.initPasswordModify"));
return initPasswordModify != null && initPasswordModify == 1 && pwdUpdateDate == null;
}
// 检查密码是否过期
public boolean passwordIsExpiration(Date pwdUpdateDate)
{
Integer passwordValidateDays = Convert.toInt(configService.selectConfigByKey("sys.account.passwordValidateDays"));
if (passwordValidateDays != null && passwordValidateDays > 0)
{
if (StringUtils.isNull(pwdUpdateDate))
{
// 如果从未修改过初始密码,直接提醒过期
return true;
}
Date nowDate = DateUtils.getNowDate();
return DateUtils.differentDaysByMillisecond(nowDate, pwdUpdateDate) > passwordValidateDays;
}
return false;
}
}

View File

@ -0,0 +1,82 @@
package com.ruoyi.web.controller.system;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.web.service.ConfigService;
/**
*
*
* @author ruoyi
*/
@Controller
public class SysLoginController extends BaseController
{
/**
*
*/
@Value("${shiro.rememberMe.enabled: false}")
private boolean rememberMe;
@Autowired
private ConfigService configService;
@GetMapping("/login")
public String login(HttpServletRequest request, HttpServletResponse response, ModelMap mmap)
{
// 如果是Ajax请求返回Json字符串。
if (ServletUtils.isAjaxRequest(request))
{
return ServletUtils.renderString(response, "{\"code\":\"1\",\"msg\":\"未登录或登录超时。请重新登录\"}");
}
// 是否开启记住我
mmap.put("isRemembered", rememberMe);
// 是否开启用户注册
mmap.put("isAllowRegister", Convert.toBool(configService.getKey("sys.account.registerUser"), false));
return "login";
}
@PostMapping("/login")
@ResponseBody
public AjaxResult ajaxLogin(String username, String password, Boolean rememberMe)
{
UsernamePasswordToken token = new UsernamePasswordToken(username, password, rememberMe);
Subject subject = SecurityUtils.getSubject();
try
{
subject.login(token);
return success();
}
catch (AuthenticationException e)
{
String msg = "用户或密码错误";
if (StringUtils.isNotEmpty(e.getMessage()))
{
msg = e.getMessage();
}
return error(msg);
}
}
@GetMapping("/unauth")
public String unauth()
{
return "error/unauth";
}
}

View File

@ -0,0 +1,198 @@
package com.ruoyi.web.controller.system;
import java.util.List;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.Ztree;
import com.ruoyi.common.core.domain.entity.SysMenu;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.framework.shiro.util.AuthorizationUtils;
import com.ruoyi.system.service.ISysMenuService;
/**
*
*
* @author ruoyi
*/
@Controller
@RequestMapping("/system/menu")
public class SysMenuController extends BaseController
{
private String prefix = "system/menu";
@Autowired
private ISysMenuService menuService;
@RequiresPermissions("system:menu:view")
@GetMapping()
public String menu()
{
return prefix + "/menu";
}
@RequiresPermissions("system:menu:list")
@PostMapping("/list")
@ResponseBody
public List<SysMenu> list(SysMenu menu)
{
Long userId = ShiroUtils.getUserId();
List<SysMenu> menuList = menuService.selectMenuList(menu, userId);
return menuList;
}
/**
*
*/
@Log(title = "菜单管理", businessType = BusinessType.DELETE)
@RequiresPermissions("system:menu:remove")
@GetMapping("/remove/{menuId}")
@ResponseBody
public AjaxResult remove(@PathVariable("menuId") Long menuId)
{
if (menuService.selectCountMenuByParentId(menuId) > 0)
{
return AjaxResult.warn("存在子菜单,不允许删除");
}
if (menuService.selectCountRoleMenuByMenuId(menuId) > 0)
{
return AjaxResult.warn("菜单已分配,不允许删除");
}
AuthorizationUtils.clearAllCachedAuthorizationInfo();
return toAjax(menuService.deleteMenuById(menuId));
}
/**
*
*/
@RequiresPermissions("system:menu:add")
@GetMapping("/add/{parentId}")
public String add(@PathVariable("parentId") Long parentId, ModelMap mmap)
{
SysMenu menu = null;
if (0L != parentId)
{
menu = menuService.selectMenuById(parentId);
}
else
{
menu = new SysMenu();
menu.setMenuId(0L);
menu.setMenuName("主目录");
}
mmap.put("menu", menu);
return prefix + "/add";
}
/**
*
*/
@Log(title = "菜单管理", businessType = BusinessType.INSERT)
@RequiresPermissions("system:menu:add")
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(@Validated SysMenu menu)
{
if (!menuService.checkMenuNameUnique(menu))
{
return error("新增菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
}
menu.setCreateBy(getLoginName());
AuthorizationUtils.clearAllCachedAuthorizationInfo();
return toAjax(menuService.insertMenu(menu));
}
/**
*
*/
@RequiresPermissions("system:menu:edit")
@GetMapping("/edit/{menuId}")
public String edit(@PathVariable("menuId") Long menuId, ModelMap mmap)
{
mmap.put("menu", menuService.selectMenuById(menuId));
return prefix + "/edit";
}
/**
*
*/
@Log(title = "菜单管理", businessType = BusinessType.UPDATE)
@RequiresPermissions("system:menu:edit")
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(@Validated SysMenu menu)
{
if (!menuService.checkMenuNameUnique(menu))
{
return error("修改菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
}
menu.setUpdateBy(getLoginName());
AuthorizationUtils.clearAllCachedAuthorizationInfo();
return toAjax(menuService.updateMenu(menu));
}
/**
*
*/
@GetMapping("/icon")
public String icon()
{
return prefix + "/icon";
}
/**
*
*/
@PostMapping("/checkMenuNameUnique")
@ResponseBody
public boolean checkMenuNameUnique(SysMenu menu)
{
return menuService.checkMenuNameUnique(menu);
}
/**
*
*/
@GetMapping("/roleMenuTreeData")
@ResponseBody
public List<Ztree> roleMenuTreeData(SysRole role)
{
Long userId = ShiroUtils.getUserId();
List<Ztree> ztrees = menuService.roleMenuTreeData(role, userId);
return ztrees;
}
/**
*
*/
@GetMapping("/menuTreeData")
@ResponseBody
public List<Ztree> menuTreeData()
{
Long userId = ShiroUtils.getUserId();
List<Ztree> ztrees = menuService.menuTreeData(userId);
return ztrees;
}
/**
*
*/
@GetMapping("/selectMenuTree/{menuId}")
public String selectMenuTree(@PathVariable("menuId") Long menuId, ModelMap mmap)
{
mmap.put("menu", menuService.selectMenuById(menuId));
return prefix + "/tree";
}
}

View File

@ -0,0 +1,125 @@
package com.ruoyi.web.controller.system;
import java.util.List;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.system.domain.SysNotice;
import com.ruoyi.system.service.ISysNoticeService;
/**
*
*
* @author ruoyi
*/
@Controller
@RequestMapping("/system/notice")
public class SysNoticeController extends BaseController
{
private String prefix = "system/notice";
@Autowired
private ISysNoticeService noticeService;
@RequiresPermissions("system:notice:view")
@GetMapping()
public String notice()
{
return prefix + "/notice";
}
/**
*
*/
@RequiresPermissions("system:notice:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(SysNotice notice)
{
startPage();
List<SysNotice> list = noticeService.selectNoticeList(notice);
return getDataTable(list);
}
/**
*
*/
@RequiresPermissions("system:notice:add")
@GetMapping("/add")
public String add()
{
return prefix + "/add";
}
/**
*
*/
@RequiresPermissions("system:notice:add")
@Log(title = "通知公告", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(@Validated SysNotice notice)
{
notice.setCreateBy(getLoginName());
return toAjax(noticeService.insertNotice(notice));
}
/**
*
*/
@RequiresPermissions("system:notice:edit")
@GetMapping("/edit/{noticeId}")
public String edit(@PathVariable("noticeId") Long noticeId, ModelMap mmap)
{
mmap.put("notice", noticeService.selectNoticeById(noticeId));
return prefix + "/edit";
}
/**
*
*/
@RequiresPermissions("system:notice:edit")
@Log(title = "通知公告", businessType = BusinessType.UPDATE)
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(@Validated SysNotice notice)
{
notice.setUpdateBy(getLoginName());
return toAjax(noticeService.updateNotice(notice));
}
/**
*
*/
@RequiresPermissions("system:notice:list")
@GetMapping("/view/{noticeId}")
public String view(@PathVariable("noticeId") Long noticeId, ModelMap mmap)
{
mmap.put("notice", noticeService.selectNoticeById(noticeId));
return prefix + "/view";
}
/**
*
*/
@RequiresPermissions("system:notice:remove")
@Log(title = "通知公告", businessType = BusinessType.DELETE)
@PostMapping("/remove")
@ResponseBody
public AjaxResult remove(String ids)
{
return toAjax(noticeService.deleteNoticeByIds(ids));
}
}

View File

@ -0,0 +1,156 @@
package com.ruoyi.web.controller.system;
import java.util.List;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.SysPost;
import com.ruoyi.system.service.ISysPostService;
/**
*
*
* @author ruoyi
*/
@Controller
@RequestMapping("/system/post")
public class SysPostController extends BaseController
{
private String prefix = "system/post";
@Autowired
private ISysPostService postService;
@RequiresPermissions("system:post:view")
@GetMapping()
public String operlog()
{
return prefix + "/post";
}
@RequiresPermissions("system:post:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(SysPost post)
{
startPage();
List<SysPost> list = postService.selectPostList(post);
return getDataTable(list);
}
@Log(title = "岗位管理", businessType = BusinessType.EXPORT)
@RequiresPermissions("system:post:export")
@PostMapping("/export")
@ResponseBody
public AjaxResult export(SysPost post)
{
List<SysPost> list = postService.selectPostList(post);
ExcelUtil<SysPost> util = new ExcelUtil<SysPost>(SysPost.class);
return util.exportExcel(list, "岗位数据");
}
@RequiresPermissions("system:post:remove")
@Log(title = "岗位管理", businessType = BusinessType.DELETE)
@PostMapping("/remove")
@ResponseBody
public AjaxResult remove(String ids)
{
return toAjax(postService.deletePostByIds(ids));
}
/**
*
*/
@RequiresPermissions("system:post:add")
@GetMapping("/add")
public String add()
{
return prefix + "/add";
}
/**
*
*/
@RequiresPermissions("system:post:add")
@Log(title = "岗位管理", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(@Validated SysPost post)
{
if (!postService.checkPostNameUnique(post))
{
return error("新增岗位'" + post.getPostName() + "'失败,岗位名称已存在");
}
else if (!postService.checkPostCodeUnique(post))
{
return error("新增岗位'" + post.getPostName() + "'失败,岗位编码已存在");
}
post.setCreateBy(getLoginName());
return toAjax(postService.insertPost(post));
}
/**
*
*/
@RequiresPermissions("system:post:edit")
@GetMapping("/edit/{postId}")
public String edit(@PathVariable("postId") Long postId, ModelMap mmap)
{
mmap.put("post", postService.selectPostById(postId));
return prefix + "/edit";
}
/**
*
*/
@RequiresPermissions("system:post:edit")
@Log(title = "岗位管理", businessType = BusinessType.UPDATE)
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(@Validated SysPost post)
{
if (!postService.checkPostNameUnique(post))
{
return error("修改岗位'" + post.getPostName() + "'失败,岗位名称已存在");
}
else if (!postService.checkPostCodeUnique(post))
{
return error("修改岗位'" + post.getPostName() + "'失败,岗位编码已存在");
}
post.setUpdateBy(getLoginName());
return toAjax(postService.updatePost(post));
}
/**
*
*/
@PostMapping("/checkPostNameUnique")
@ResponseBody
public boolean checkPostNameUnique(SysPost post)
{
return postService.checkPostNameUnique(post);
}
/**
*
*/
@PostMapping("/checkPostCodeUnique")
@ResponseBody
public boolean checkPostCodeUnique(SysPost post)
{
return postService.checkPostCodeUnique(post);
}
}

View File

@ -0,0 +1,181 @@
package com.ruoyi.web.controller.system;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.file.MimeTypeUtils;
import com.ruoyi.framework.shiro.service.SysPasswordService;
import com.ruoyi.system.service.ISysUserService;
/**
*
*
* @author ruoyi
*/
@Controller
@RequestMapping("/system/user/profile")
public class SysProfileController extends BaseController
{
private static final Logger log = LoggerFactory.getLogger(SysProfileController.class);
private String prefix = "system/user/profile";
@Autowired
private ISysUserService userService;
@Autowired
private SysPasswordService passwordService;
/**
*
*/
@GetMapping()
public String profile(ModelMap mmap)
{
SysUser user = getSysUser();
mmap.put("user", user);
mmap.put("roleGroup", userService.selectUserRoleGroup(user.getUserId()));
mmap.put("postGroup", userService.selectUserPostGroup(user.getUserId()));
return prefix + "/profile";
}
@GetMapping("/checkPassword")
@ResponseBody
public boolean checkPassword(String password)
{
SysUser user = getSysUser();
return passwordService.matches(user, password);
}
@GetMapping("/resetPwd")
public String resetPwd(ModelMap mmap)
{
SysUser user = getSysUser();
mmap.put("user", userService.selectUserById(user.getUserId()));
return prefix + "/resetPwd";
}
@Log(title = "重置密码", businessType = BusinessType.UPDATE)
@PostMapping("/resetPwd")
@ResponseBody
public AjaxResult resetPwd(String oldPassword, String newPassword)
{
SysUser user = getSysUser();
if (!passwordService.matches(user, oldPassword))
{
return error("修改密码失败,旧密码错误");
}
if (passwordService.matches(user, newPassword))
{
return error("新密码不能与旧密码相同");
}
user.setSalt(ShiroUtils.randomSalt());
user.setPassword(passwordService.encryptPassword(user.getLoginName(), newPassword, user.getSalt()));
user.setPwdUpdateDate(DateUtils.getNowDate());
if (userService.resetUserPwd(user) > 0)
{
setSysUser(userService.selectUserById(user.getUserId()));
return success();
}
return error("修改密码异常,请联系管理员");
}
/**
*
*/
@GetMapping("/edit")
public String edit(ModelMap mmap)
{
SysUser user = getSysUser();
mmap.put("user", userService.selectUserById(user.getUserId()));
return prefix + "/edit";
}
/**
*
*/
@GetMapping("/avatar")
public String avatar(ModelMap mmap)
{
SysUser user = getSysUser();
mmap.put("user", userService.selectUserById(user.getUserId()));
return prefix + "/avatar";
}
/**
*
*/
@Log(title = "个人信息", businessType = BusinessType.UPDATE)
@PostMapping("/update")
@ResponseBody
public AjaxResult update(SysUser user)
{
SysUser currentUser = getSysUser();
currentUser.setUserName(user.getUserName());
currentUser.setEmail(user.getEmail());
currentUser.setPhonenumber(user.getPhonenumber());
currentUser.setSex(user.getSex());
if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(currentUser))
{
return error("修改用户'" + currentUser.getLoginName() + "'失败,手机号码已存在");
}
else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(currentUser))
{
return error("修改用户'" + currentUser.getLoginName() + "'失败,邮箱账号已存在");
}
if (userService.updateUserInfo(currentUser) > 0)
{
setSysUser(userService.selectUserById(currentUser.getUserId()));
return success();
}
return error();
}
/**
*
*/
@Log(title = "个人信息", businessType = BusinessType.UPDATE)
@PostMapping("/updateAvatar")
@ResponseBody
public AjaxResult updateAvatar(@RequestParam("avatarfile") MultipartFile file)
{
SysUser currentUser = getSysUser();
try
{
if (!file.isEmpty())
{
String avatar = FileUploadUtils.upload(RuoYiConfig.getAvatarPath(), file, MimeTypeUtils.IMAGE_EXTENSION);
currentUser.setAvatar(avatar);
if (userService.updateUserInfo(currentUser) > 0)
{
setSysUser(userService.selectUserById(currentUser.getUserId()));
return success();
}
}
return error();
}
catch (Exception e)
{
log.error("修改头像失败!", e);
return error(e.getMessage());
}
}
}

View File

@ -0,0 +1,46 @@
package com.ruoyi.web.controller.system;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.shiro.service.SysRegisterService;
import com.ruoyi.system.service.ISysConfigService;
/**
*
*
* @author ruoyi
*/
@Controller
public class SysRegisterController extends BaseController
{
@Autowired
private SysRegisterService registerService;
@Autowired
private ISysConfigService configService;
@GetMapping("/register")
public String register()
{
return "register";
}
@PostMapping("/register")
@ResponseBody
public AjaxResult ajaxRegister(SysUser user)
{
if (!("true".equals(configService.selectConfigByKey("sys.account.registerUser"))))
{
return error("当前系统没有开启注册功能!");
}
String msg = registerService.register(user);
return StringUtils.isEmpty(msg) ? success() : error(msg);
}
}

View File

@ -0,0 +1,324 @@
package com.ruoyi.web.controller.system;
import java.util.List;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.Ztree;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.shiro.util.AuthorizationUtils;
import com.ruoyi.system.domain.SysUserRole;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.ISysRoleService;
import com.ruoyi.system.service.ISysUserService;
/**
*
*
* @author ruoyi
*/
@Controller
@RequestMapping("/system/role")
public class SysRoleController extends BaseController
{
private String prefix = "system/role";
@Autowired
private ISysRoleService roleService;
@Autowired
private ISysUserService userService;
@Autowired
private ISysDeptService deptService;
@RequiresPermissions("system:role:view")
@GetMapping()
public String role()
{
return prefix + "/role";
}
@RequiresPermissions("system:role:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(SysRole role)
{
startPage();
List<SysRole> list = roleService.selectRoleList(role);
return getDataTable(list);
}
@Log(title = "角色管理", businessType = BusinessType.EXPORT)
@RequiresPermissions("system:role:export")
@PostMapping("/export")
@ResponseBody
public AjaxResult export(SysRole role)
{
List<SysRole> list = roleService.selectRoleList(role);
ExcelUtil<SysRole> util = new ExcelUtil<SysRole>(SysRole.class);
return util.exportExcel(list, "角色数据");
}
/**
*
*/
@RequiresPermissions("system:role:add")
@GetMapping("/add")
public String add()
{
return prefix + "/add";
}
/**
*
*/
@RequiresPermissions("system:role:add")
@Log(title = "角色管理", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(@Validated SysRole role)
{
if (!roleService.checkRoleNameUnique(role))
{
return error("新增角色'" + role.getRoleName() + "'失败,角色名称已存在");
}
else if (!roleService.checkRoleKeyUnique(role))
{
return error("新增角色'" + role.getRoleName() + "'失败,角色权限已存在");
}
role.setCreateBy(getLoginName());
AuthorizationUtils.clearAllCachedAuthorizationInfo();
return toAjax(roleService.insertRole(role));
}
/**
*
*/
@RequiresPermissions("system:role:edit")
@GetMapping("/edit/{roleId}")
public String edit(@PathVariable("roleId") Long roleId, ModelMap mmap)
{
roleService.checkRoleDataScope(roleId);
mmap.put("role", roleService.selectRoleById(roleId));
return prefix + "/edit";
}
/**
*
*/
@RequiresPermissions("system:role:edit")
@Log(title = "角色管理", businessType = BusinessType.UPDATE)
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(@Validated SysRole role)
{
roleService.checkRoleAllowed(role);
roleService.checkRoleDataScope(role.getRoleId());
if (!roleService.checkRoleNameUnique(role))
{
return error("修改角色'" + role.getRoleName() + "'失败,角色名称已存在");
}
else if (!roleService.checkRoleKeyUnique(role))
{
return error("修改角色'" + role.getRoleName() + "'失败,角色权限已存在");
}
role.setUpdateBy(getLoginName());
AuthorizationUtils.clearAllCachedAuthorizationInfo();
return toAjax(roleService.updateRole(role));
}
/**
*
*/
@GetMapping("/authDataScope/{roleId}")
public String authDataScope(@PathVariable("roleId") Long roleId, ModelMap mmap)
{
mmap.put("role", roleService.selectRoleById(roleId));
return prefix + "/dataScope";
}
/**
*
*/
@RequiresPermissions("system:role:edit")
@Log(title = "角色管理", businessType = BusinessType.UPDATE)
@PostMapping("/authDataScope")
@ResponseBody
public AjaxResult authDataScopeSave(SysRole role)
{
roleService.checkRoleAllowed(role);
roleService.checkRoleDataScope(role.getRoleId());
role.setUpdateBy(getLoginName());
if (roleService.authDataScope(role) > 0)
{
setSysUser(userService.selectUserById(getUserId()));
return success();
}
return error();
}
@RequiresPermissions("system:role:remove")
@Log(title = "角色管理", businessType = BusinessType.DELETE)
@PostMapping("/remove")
@ResponseBody
public AjaxResult remove(String ids)
{
return toAjax(roleService.deleteRoleByIds(ids));
}
/**
*
*/
@PostMapping("/checkRoleNameUnique")
@ResponseBody
public boolean checkRoleNameUnique(SysRole role)
{
return roleService.checkRoleNameUnique(role);
}
/**
*
*/
@PostMapping("/checkRoleKeyUnique")
@ResponseBody
public boolean checkRoleKeyUnique(SysRole role)
{
return roleService.checkRoleKeyUnique(role);
}
/**
*
*/
@GetMapping("/selectMenuTree")
public String selectMenuTree()
{
return prefix + "/tree";
}
/**
*
*/
@Log(title = "角色管理", businessType = BusinessType.UPDATE)
@RequiresPermissions("system:role:edit")
@PostMapping("/changeStatus")
@ResponseBody
public AjaxResult changeStatus(SysRole role)
{
roleService.checkRoleAllowed(role);
roleService.checkRoleDataScope(role.getRoleId());
return toAjax(roleService.changeStatus(role));
}
/**
*
*/
@RequiresPermissions("system:role:edit")
@GetMapping("/authUser/{roleId}")
public String authUser(@PathVariable("roleId") Long roleId, ModelMap mmap)
{
mmap.put("role", roleService.selectRoleById(roleId));
return prefix + "/authUser";
}
/**
*
*/
@RequiresPermissions("system:role:list")
@PostMapping("/authUser/allocatedList")
@ResponseBody
public TableDataInfo allocatedList(SysUser user)
{
startPage();
List<SysUser> list = userService.selectAllocatedList(user);
return getDataTable(list);
}
/**
*
*/
@RequiresPermissions("system:role:edit")
@Log(title = "角色管理", businessType = BusinessType.GRANT)
@PostMapping("/authUser/cancel")
@ResponseBody
public AjaxResult cancelAuthUser(SysUserRole userRole)
{
return toAjax(roleService.deleteAuthUser(userRole));
}
/**
*
*/
@RequiresPermissions("system:role:edit")
@Log(title = "角色管理", businessType = BusinessType.GRANT)
@PostMapping("/authUser/cancelAll")
@ResponseBody
public AjaxResult cancelAuthUserAll(Long roleId, String userIds)
{
return toAjax(roleService.deleteAuthUsers(roleId, userIds));
}
/**
*
*/
@RequiresPermissions("system:role:list")
@GetMapping("/authUser/selectUser/{roleId}")
public String selectUser(@PathVariable("roleId") Long roleId, ModelMap mmap)
{
mmap.put("role", roleService.selectRoleById(roleId));
return prefix + "/selectUser";
}
/**
*
*/
@RequiresPermissions("system:role:list")
@PostMapping("/authUser/unallocatedList")
@ResponseBody
public TableDataInfo unallocatedList(SysUser user)
{
startPage();
List<SysUser> list = userService.selectUnallocatedList(user);
return getDataTable(list);
}
/**
*
*/
@RequiresPermissions("system:role:edit")
@Log(title = "角色管理", businessType = BusinessType.GRANT)
@PostMapping("/authUser/selectAll")
@ResponseBody
public AjaxResult selectAuthUserAll(Long roleId, String userIds)
{
roleService.checkRoleDataScope(roleId);
return toAjax(roleService.insertAuthUsers(roleId, userIds));
}
/**
*
*/
@RequiresPermissions("system:role:edit")
@GetMapping("/deptTreeData")
@ResponseBody
public List<Ztree> deptTreeData(SysRole role)
{
List<Ztree> ztrees = deptService.roleDeptTreeData(role);
return ztrees;
}
}

View File

@ -0,0 +1,355 @@
package com.ruoyi.web.controller.system;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.Ztree;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.shiro.service.SysPasswordService;
import com.ruoyi.framework.shiro.util.AuthorizationUtils;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.ISysPostService;
import com.ruoyi.system.service.ISysRoleService;
import com.ruoyi.system.service.ISysUserService;
/**
*
*
* @author ruoyi
*/
@Controller
@RequestMapping("/system/user")
public class SysUserController extends BaseController
{
private String prefix = "system/user";
@Autowired
private ISysUserService userService;
@Autowired
private ISysRoleService roleService;
@Autowired
private ISysDeptService deptService;
@Autowired
private ISysPostService postService;
@Autowired
private SysPasswordService passwordService;
@RequiresPermissions("system:user:view")
@GetMapping()
public String user()
{
return prefix + "/user";
}
@RequiresPermissions("system:user:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(SysUser user)
{
startPage();
List<SysUser> list = userService.selectUserList(user);
return getDataTable(list);
}
@Log(title = "用户管理", businessType = BusinessType.EXPORT)
@RequiresPermissions("system:user:export")
@PostMapping("/export")
@ResponseBody
public AjaxResult export(SysUser user)
{
List<SysUser> list = userService.selectUserList(user);
ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
return util.exportExcel(list, "用户数据");
}
@Log(title = "用户管理", businessType = BusinessType.IMPORT)
@RequiresPermissions("system:user:import")
@PostMapping("/importData")
@ResponseBody
public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception
{
ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
List<SysUser> userList = util.importExcel(file.getInputStream());
String message = userService.importUser(userList, updateSupport, getLoginName());
return AjaxResult.success(message);
}
@RequiresPermissions("system:user:view")
@GetMapping("/importTemplate")
@ResponseBody
public AjaxResult importTemplate()
{
ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
return util.importTemplateExcel("用户数据");
}
/**
*
*/
@RequiresPermissions("system:user:add")
@GetMapping("/add")
public String add(ModelMap mmap)
{
mmap.put("roles", roleService.selectRoleAll().stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
mmap.put("posts", postService.selectPostAll());
return prefix + "/add";
}
/**
*
*/
@RequiresPermissions("system:user:add")
@Log(title = "用户管理", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(@Validated SysUser user)
{
deptService.checkDeptDataScope(user.getDeptId());
roleService.checkRoleDataScope(user.getRoleIds());
if (!userService.checkLoginNameUnique(user))
{
return error("新增用户'" + user.getLoginName() + "'失败,登录账号已存在");
}
else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user))
{
return error("新增用户'" + user.getLoginName() + "'失败,手机号码已存在");
}
else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user))
{
return error("新增用户'" + user.getLoginName() + "'失败,邮箱账号已存在");
}
user.setSalt(ShiroUtils.randomSalt());
user.setPassword(passwordService.encryptPassword(user.getLoginName(), user.getPassword(), user.getSalt()));
user.setPwdUpdateDate(DateUtils.getNowDate());
user.setCreateBy(getLoginName());
return toAjax(userService.insertUser(user));
}
/**
*
*/
@RequiresPermissions("system:user:edit")
@GetMapping("/edit/{userId}")
public String edit(@PathVariable("userId") Long userId, ModelMap mmap)
{
userService.checkUserDataScope(userId);
List<SysRole> roles = roleService.selectRolesByUserId(userId);
mmap.put("user", userService.selectUserById(userId));
mmap.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
mmap.put("posts", postService.selectPostsByUserId(userId));
return prefix + "/edit";
}
/**
*
*/
@RequiresPermissions("system:user:list")
@GetMapping("/view/{userId}")
public String view(@PathVariable("userId") Long userId, ModelMap mmap)
{
userService.checkUserDataScope(userId);
mmap.put("user", userService.selectUserById(userId));
mmap.put("roleGroup", userService.selectUserRoleGroup(userId));
mmap.put("postGroup", userService.selectUserPostGroup(userId));
return prefix + "/view";
}
/**
*
*/
@RequiresPermissions("system:user:edit")
@Log(title = "用户管理", businessType = BusinessType.UPDATE)
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(@Validated SysUser user)
{
userService.checkUserAllowed(user);
userService.checkUserDataScope(user.getUserId());
deptService.checkDeptDataScope(user.getDeptId());
roleService.checkRoleDataScope(user.getRoleIds());
if (!userService.checkLoginNameUnique(user))
{
return error("修改用户'" + user.getLoginName() + "'失败,登录账号已存在");
}
else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user))
{
return error("修改用户'" + user.getLoginName() + "'失败,手机号码已存在");
}
else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user))
{
return error("修改用户'" + user.getLoginName() + "'失败,邮箱账号已存在");
}
user.setUpdateBy(getLoginName());
AuthorizationUtils.clearAllCachedAuthorizationInfo();
return toAjax(userService.updateUser(user));
}
@RequiresPermissions("system:user:resetPwd")
@GetMapping("/resetPwd/{userId}")
public String resetPwd(@PathVariable("userId") Long userId, ModelMap mmap)
{
mmap.put("user", userService.selectUserById(userId));
return prefix + "/resetPwd";
}
@RequiresPermissions("system:user:resetPwd")
@Log(title = "重置密码", businessType = BusinessType.UPDATE)
@PostMapping("/resetPwd")
@ResponseBody
public AjaxResult resetPwdSave(SysUser user)
{
userService.checkUserAllowed(user);
userService.checkUserDataScope(user.getUserId());
user.setSalt(ShiroUtils.randomSalt());
user.setPassword(passwordService.encryptPassword(user.getLoginName(), user.getPassword(), user.getSalt()));
if (userService.resetUserPwd(user) > 0)
{
if (ShiroUtils.getUserId().longValue() == user.getUserId().longValue())
{
setSysUser(userService.selectUserById(user.getUserId()));
}
return success();
}
return error();
}
/**
*
*/
@RequiresPermissions("system:user:edit")
@GetMapping("/authRole/{userId}")
public String authRole(@PathVariable("userId") Long userId, ModelMap mmap)
{
SysUser user = userService.selectUserById(userId);
// 获取用户所属的角色列表
List<SysRole> roles = roleService.selectRolesByUserId(userId);
mmap.put("user", user);
mmap.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
return prefix + "/authRole";
}
/**
*
*/
@RequiresPermissions("system:user:edit")
@Log(title = "用户管理", businessType = BusinessType.GRANT)
@PostMapping("/authRole/insertAuthRole")
@ResponseBody
public AjaxResult insertAuthRole(Long userId, Long[] roleIds)
{
userService.checkUserDataScope(userId);
roleService.checkRoleDataScope(roleIds);
userService.insertUserAuth(userId, roleIds);
AuthorizationUtils.clearAllCachedAuthorizationInfo();
return success();
}
@RequiresPermissions("system:user:remove")
@Log(title = "用户管理", businessType = BusinessType.DELETE)
@PostMapping("/remove")
@ResponseBody
public AjaxResult remove(String ids)
{
if (ArrayUtils.contains(Convert.toLongArray(ids), getUserId()))
{
return error("当前用户不能删除");
}
return toAjax(userService.deleteUserByIds(ids));
}
/**
*
*/
@PostMapping("/checkLoginNameUnique")
@ResponseBody
public boolean checkLoginNameUnique(SysUser user)
{
return userService.checkLoginNameUnique(user);
}
/**
*
*/
@PostMapping("/checkPhoneUnique")
@ResponseBody
public boolean checkPhoneUnique(SysUser user)
{
return userService.checkPhoneUnique(user);
}
/**
* email
*/
@PostMapping("/checkEmailUnique")
@ResponseBody
public boolean checkEmailUnique(SysUser user)
{
return userService.checkEmailUnique(user);
}
/**
*
*/
@Log(title = "用户管理", businessType = BusinessType.UPDATE)
@RequiresPermissions("system:user:edit")
@PostMapping("/changeStatus")
@ResponseBody
public AjaxResult changeStatus(SysUser user)
{
userService.checkUserAllowed(user);
userService.checkUserDataScope(user.getUserId());
return toAjax(userService.changeStatus(user));
}
/**
*
*/
@RequiresPermissions("system:user:list")
@GetMapping("/deptTreeData")
@ResponseBody
public List<Ztree> deptTreeData()
{
List<Ztree> ztrees = deptService.selectDeptTree(new SysDept());
return ztrees;
}
/**
*
*
* @param deptId ID
*/
@RequiresPermissions("system:user:list")
@GetMapping("/selectDeptTree/{deptId}")
public String selectDeptTree(@PathVariable("deptId") Long deptId, ModelMap mmap)
{
mmap.put("dept", deptService.selectDeptById(deptId));
return prefix + "/deptTree";
}
}

View File

@ -0,0 +1,26 @@
package com.ruoyi.web.controller.tool;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import com.ruoyi.common.core.controller.BaseController;
/**
* build
*
* @author ruoyi
*/
@Controller
@RequestMapping("/tool/build")
public class BuildController extends BaseController
{
private String prefix = "tool/build";
@RequiresPermissions("tool:build:view")
@GetMapping()
public String build()
{
return prefix + "/build";
}
}

View File

@ -0,0 +1,24 @@
package com.ruoyi.web.controller.tool;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import com.ruoyi.common.core.controller.BaseController;
/**
* swagger
*
* @author ruoyi
*/
@Controller
@RequestMapping("/tool/swagger")
public class SwaggerController extends BaseController
{
@RequiresPermissions("tool:swagger:view")
@GetMapping()
public String index()
{
return redirect("/swagger-ui/index.html");
}
}

View File

@ -0,0 +1,183 @@
package com.ruoyi.web.controller.tool;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.utils.StringUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
/**
* swagger
*
* @author ruoyi
*/
@Api("用户信息管理")
@RestController
@RequestMapping("/test/user")
public class TestController extends BaseController
{
private final static Map<Integer, UserEntity> users = new LinkedHashMap<Integer, UserEntity>();
{
users.put(1, new UserEntity(1, "admin", "admin123", "15888888888"));
users.put(2, new UserEntity(2, "ry", "admin123", "15666666666"));
}
@ApiOperation("获取用户列表")
@GetMapping("/list")
public R<List<UserEntity>> userList()
{
List<UserEntity> userList = new ArrayList<UserEntity>(users.values());
return R.ok(userList);
}
@ApiOperation("获取用户详细")
@ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class)
@GetMapping("/{userId}")
public R<UserEntity> getUser(@PathVariable Integer userId)
{
if (!users.isEmpty() && users.containsKey(userId))
{
return R.ok(users.get(userId));
}
else
{
return R.fail("用户不存在");
}
}
@ApiOperation("新增用户")
@ApiImplicitParams({
@ApiImplicitParam(name = "userId", value = "用户id", dataType = "Integer", dataTypeClass = Integer.class),
@ApiImplicitParam(name = "username", value = "用户名称", dataType = "String", dataTypeClass = String.class),
@ApiImplicitParam(name = "password", value = "用户密码", dataType = "String", dataTypeClass = String.class),
@ApiImplicitParam(name = "mobile", value = "用户手机", dataType = "String", dataTypeClass = String.class)
})
@PostMapping("/save")
public R<String> save(UserEntity user)
{
if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId()))
{
return R.fail("用户ID不能为空");
}
users.put(user.getUserId(), user);
return R.ok();
}
@ApiOperation("更新用户")
@PutMapping("/update")
public R<String> update(@RequestBody UserEntity user)
{
if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId()))
{
return R.fail("用户ID不能为空");
}
if (users.isEmpty() || !users.containsKey(user.getUserId()))
{
return R.fail("用户不存在");
}
users.remove(user.getUserId());
users.put(user.getUserId(), user);
return R.ok();
}
@ApiOperation("删除用户信息")
@ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class)
@DeleteMapping("/{userId}")
public R<String> delete(@PathVariable Integer userId)
{
if (!users.isEmpty() && users.containsKey(userId))
{
users.remove(userId);
return R.ok();
}
else
{
return R.fail("用户不存在");
}
}
}
@ApiModel(value = "UserEntity", description = "用户实体")
class UserEntity
{
@ApiModelProperty("用户ID")
private Integer userId;
@ApiModelProperty("用户名称")
private String username;
@ApiModelProperty("用户密码")
private String password;
@ApiModelProperty("用户手机")
private String mobile;
public UserEntity()
{
}
public UserEntity(Integer userId, String username, String password, String mobile)
{
this.userId = userId;
this.username = username;
this.password = password;
this.mobile = mobile;
}
public Integer getUserId()
{
return userId;
}
public void setUserId(Integer userId)
{
this.userId = userId;
}
public String getUsername()
{
return username;
}
public void setUsername(String username)
{
this.username = username;
}
public String getPassword()
{
return password;
}
public void setPassword(String password)
{
this.password = password;
}
public String getMobile()
{
return mobile;
}
public void setMobile(String mobile)
{
this.mobile = mobile;
}
}

View File

@ -0,0 +1,67 @@
package com.ruoyi.web.core.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.ruoyi.common.config.RuoYiConfig;
import io.swagger.annotations.ApiOperation;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
/**
* Swagger2
*
* @author ruoyi
*/
@Configuration
public class SwaggerConfig
{
/** 是否开启swagger */
@Value("${swagger.enabled}")
private boolean enabled;
/**
* API
*/
@Bean
public Docket createRestApi()
{
return new Docket(DocumentationType.OAS_30)
// 是否启用Swagger
.enable(enabled)
// 用来创建该API的基本信息展示在文档的页面中自定义展示的信息
.apiInfo(apiInfo())
// 设置哪些接口暴露给Swagger展示
.select()
// 扫描所有有注解的api用这种方式更灵活
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
// 扫描指定包中的swagger注解
//.apis(RequestHandlerSelectors.basePackage("com.ruoyi.project.tool.swagger"))
// 扫描所有 .apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build();
}
/**
*
*/
private ApiInfo apiInfo()
{
// 用ApiInfoBuilder进行定制
return new ApiInfoBuilder()
// 设置标题
.title("标题若依管理系统_接口文档")
// 描述
.description("描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...")
// 作者信息
.contact(new Contact(RuoYiConfig.getName(), null, null))
// 版本
.version("版本号:" + RuoYiConfig.getVersion())
.build();
}
}

Binary file not shown.

View File

@ -0,0 +1,61 @@
# 数据源配置
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
druid:
# 主库数据源
master:
url: jdbc:mysql://localhost:3306/unis_pms?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root
password: sagacity
# 从库数据源
slave:
# 从数据源开关/默认关闭
enabled: false
url:
username:
password:
# 初始连接数
initialSize: 5
# 最小连接池数量
minIdle: 10
# 最大连接池数量
maxActive: 20
# 配置获取连接等待超时的时间
maxWait: 60000
# 配置连接超时时间
connectTimeout: 30000
# 配置网络超时时间
socketTimeout: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: 300000
# 配置一个连接在池中最大生存的时间,单位是毫秒
maxEvictableIdleTimeMillis: 900000
# 配置检测连接是否有效
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
webStatFilter:
enabled: true
statViewServlet:
enabled: true
# 设置白名单,不填则允许所有访问
allow:
url-pattern: /druid/*
# 控制台管理用户名和密码
login-username: ruoyi
login-password: 123456
filter:
stat:
enabled: true
# 慢SQL记录
log-slow-sql: true
slow-sql-millis: 1000
merge-sql: true
wall:
config:
multi-statement-allow: true

View File

@ -0,0 +1,142 @@
# 项目相关配置
ruoyi:
# 名称
name: RuoYi
# 版本
version: 4.8.0
# 版权年份
copyrightYear: 2025
# 实例演示开关
demoEnabled: true
# 文件路径 示例( Windows配置D:/ruoyi/uploadPathLinux配置 /home/ruoyi/uploadPath
profile: ruoyi/uploadPath
# 获取ip地址开关
addressEnabled: false
# 开发环境配置
server:
# 服务器的HTTP端口默认为80
port: 8080
servlet:
# 应用的访问路径
context-path: /
tomcat:
# tomcat的URI编码
uri-encoding: UTF-8
# 连接数满后的排队数默认为100
accept-count: 1000
threads:
# tomcat最大线程数默认为200
max: 800
# Tomcat启动初始化的线程数默认值10
min-spare: 100
# 日志配置
logging:
level:
com.ruoyi: debug
org.springframework: warn
# 用户配置
user:
password:
# 密码错误{maxRetryCount}次锁定10分钟
maxRetryCount: 5
# Spring配置
spring:
# 模板引擎
thymeleaf:
mode: HTML
encoding: utf-8
# 禁用缓存
cache: false
# 资源信息
messages:
# 国际化资源文件路径
basename: static/i18n/messages
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss
profiles:
active: druid
# 文件上传
servlet:
multipart:
# 单个文件大小
max-file-size: 10MB
# 设置总上传的文件大小
max-request-size: 20MB
# 服务模块
devtools:
restart:
# 热部署开关
enabled: true
# MyBatis
mybatis:
# 搜索指定包别名
typeAliasesPackage: com.ruoyi.**.domain
# 配置mapper的扫描找到所有的mapper.xml映射文件
mapperLocations: classpath*:mapper/**/*Mapper.xml
# 加载全局的配置文件
configLocation: classpath:mybatis/mybatis-config.xml
# PageHelper分页插件
pagehelper:
helperDialect: mysql
supportMethodsArguments: true
params: count=countSql
# Shiro
shiro:
user:
# 登录地址
loginUrl: /login
# 权限认证失败地址
unauthorizedUrl: /unauth
# 首页地址
indexUrl: /index
# 验证码开关
captchaEnabled: true
# 验证码类型 math 数字计算 char 字符验证
captchaType: math
cookie:
# 设置Cookie的域名 默认空,即当前访问的域名
domain:
# 设置cookie的有效访问路径
path: /
# 设置HttpOnly属性
httpOnly: true
# 设置Cookie的过期时间天为单位
maxAge: 30
# 设置密钥务必保持唯一性生成方式直接拷贝到main运行即可Base64.encodeToString(CipherUtils.generateNewKey(128, "AES").getEncoded()) 默认启动生成随机秘钥随机秘钥会导致之前客户端RememberMe Cookie无效如设置固定秘钥RememberMe Cookie则有效
cipherKey:
session:
# Session超时时间-1代表永不过期默认30分钟
expireTime: 30
# 同步session到数据库的周期默认1分钟
dbSyncPeriod: 1
# 相隔多久检查一次session的有效性默认就是10分钟
validationInterval: 10
# 同一个用户最大会话数比如2的意思是同一个账号允许最多同时两个人登录默认-1不限制
maxSession: -1
# 踢出之前登录的/之后登录的用户,默认踢出之前登录的用户
kickoutAfter: false
rememberMe:
# 是否开启记住我
enabled: true
# 防止XSS攻击
xss:
# 过滤开关
enabled: true
# 排除链接(多个用逗号分隔)
excludes: /system/notice/*
# 匹配链接
urlPatterns: /system/*,/monitor/*,/tool/*
# Swagger配置
swagger:
# 是否开启swagger
enabled: true

View File

@ -0,0 +1,24 @@
Application Version: ${ruoyi.version}
Spring Boot Version: ${spring-boot.version}
////////////////////////////////////////////////////////////////////
// _ooOoo_ //
// o8888888o //
// 88" . "88 //
// (| ^_^ |) //
// O\ = /O //
// ____/`---'\____ //
// .' \\| |// `. //
// / \\||| : |||// \ //
// / _||||| -:- |||||- \ //
// | | \\\ - /// | | //
// | \_| ''\---/'' | | //
// \ .-\__ `-` ___/-. / //
// ___`. .' /--.--\ `. . ___ //
// ."" '< `.___\_<|>_/___.' >'"". //
// | | : `- \`.;`\ _ /`;.`/ - ` : | | //
// \ \ `-. \_ __\ /__ _/ .-` / / //
// ========`-.____`-.___\_____/___.-`____.-'======== //
// `=---=' //
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ //
// 佛祖保佑 永不宕机 永无BUG //
////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>
<ehcache name="ruoyi" updateCheck="false">
<!-- 磁盘缓存位置 -->
<diskStore path="java.io.tmpdir"/>
<!-- maxEntriesLocalHeap:堆内存中最大缓存对象数0没有限制 -->
<!-- maxElementsInMemory 在内存中缓存的element的最大数目。-->
<!-- eternal:elements是否永久有效如果为truetimeouts将被忽略element将永不过期 -->
<!-- timeToIdleSeconds:失效前的空闲秒数当eternal为false时这个属性才有效0为不限制 -->
<!-- timeToLiveSeconds:失效前的存活秒数创建时间到失效时间的间隔为存活时间当eternal为false时这个属性才有效0为不限制 -->
<!-- overflowToDisk 如果内存中数据超过内存限制,是否要缓存到磁盘上 -->
<!-- statistics是否收集统计信息。如果需要监控缓存使用情况应该打开这个选项。默认为关闭统计会影响性能。设置statistics="true"开启统计 -->
<!-- 默认缓存 -->
<defaultCache
maxEntriesLocalHeap="1000"
eternal="false"
timeToIdleSeconds="3600"
timeToLiveSeconds="3600"
overflowToDisk="false">
</defaultCache>
<!-- 登录记录缓存 锁定10分钟 -->
<cache name="loginRecordCache"
maxEntriesLocalHeap="2000"
eternal="false"
timeToIdleSeconds="600"
timeToLiveSeconds="0"
overflowToDisk="false"
statistics="false">
</cache>
<!-- 系统活跃用户缓存 -->
<cache name="sys-userCache"
maxEntriesLocalHeap="10000"
overflowToDisk="false"
eternal="false"
diskPersistent="false"
timeToLiveSeconds="0"
timeToIdleSeconds="0"
statistics="false">
</cache>
<!-- 系统用户授权缓存 没必要过期 -->
<cache name="sys-authCache"
maxEntriesLocalHeap="10000"
overflowToDisk="false"
eternal="false"
diskPersistent="false"
timeToLiveSeconds="0"
timeToIdleSeconds="0"
memoryStoreEvictionPolicy="LRU"
statistics="false"/>
<!-- 系统缓存 -->
<cache name="sys-cache"
maxEntriesLocalHeap="1000"
eternal="true"
overflowToDisk="true"
statistics="false">
</cache>
<!-- 系统参数缓存 -->
<cache name="sys-config"
maxEntriesLocalHeap="1000"
eternal="true"
overflowToDisk="true"
statistics="false">
</cache>
<!-- 系统字典缓存 -->
<cache name="sys-dict"
maxEntriesLocalHeap="1000"
eternal="true"
overflowToDisk="true"
statistics="false">
</cache>
<!-- 系统会话缓存 -->
<cache name="shiro-activeSessionCache"
maxEntriesLocalHeap="10000"
overflowToDisk="false"
eternal="false"
diskPersistent="false"
timeToLiveSeconds="0"
timeToIdleSeconds="0"
statistics="false"/>
</ehcache>

View File

@ -0,0 +1,93 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 日志存放路径 -->
<property name="log.path" value="/Users/jiliu/WorkSpace/java/RuoYi/logs" />
<!-- 日志输出格式 -->
<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
<!-- 控制台输出 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<!-- 系统日志输出 -->
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/sys-info.log</file>
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>INFO</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/sys-error.log</file>
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/sys-error.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>ERROR</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 用户访问日志输出 -->
<appender name="sys-user" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/sys-user.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 按天回滚 daily -->
<fileNamePattern>${log.path}/sys-user.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<!-- 系统模块日志级别控制 -->
<logger name="com.ruoyi" level="info" />
<!-- Spring日志级别控制 -->
<logger name="org.springframework" level="warn" />
<root level="info">
<appender-ref ref="console" />
</root>
<!--系统操作日志-->
<root level="info">
<appender-ref ref="file_info" />
<appender-ref ref="file_error" />
</root>
<!--系统用户操作日志-->
<logger name="sys-user" level="info">
<appender-ref ref="sys-user"/>
</logger>
</configuration>

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 全局参数 -->
<settings>
<!-- 使全局的映射器启用或禁用缓存 -->
<setting name="cacheEnabled" value="true" />
<!-- 允许JDBC 支持自动生成主键 -->
<setting name="useGeneratedKeys" value="true" />
<!-- 配置默认的执行器.SIMPLE就是普通执行器;REUSE执行器会重用预处理语句(prepared statements);BATCH执行器将重用语句并执行批量更新 -->
<setting name="defaultExecutorType" value="SIMPLE" />
<!-- 指定 MyBatis 所用日志的具体实现 -->
<setting name="logImpl" value="SLF4J" />
<!-- 使用驼峰命名法转换字段 -->
<!-- <setting name="mapUnderscoreToCamelCase" value="true"/> -->
</settings>
</configuration>

View File

@ -0,0 +1,617 @@
/*jshint curly:true, eqeqeq:true, laxbreak:true, noempty:false */
/*
The MIT License (MIT)
Copyright (c) 2007-2013 Einar Lielmanis and contributors.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation files
(the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Style HTML
---------------
Written by Nochum Sossonko, (nsossonko@hotmail.com)
Based on code initially developed by: Einar Lielmanis, <elfz@laacz.lv>
http://jsbeautifier.org/
Usage:
style_html(html_source);
style_html(html_source, options);
The options are:
indent_size (default 4) indentation size,
indent_char (default space) character to indent with,
max_char (default 250) - maximum amount of characters per line (0 = disable)
brace_style (default "collapse") - "collapse" | "expand" | "end-expand"
put braces on the same line as control statements (default), or put braces on own line (Allman / ANSI style), or just put end braces on own line.
unformatted (defaults to inline tags) - list of tags, that shouldn't be reformatted
indent_scripts (default normal) - "keep"|"separate"|"normal"
e.g.
style_html(html_source, {
'indent_size': 2,
'indent_char': ' ',
'max_char': 78,
'brace_style': 'expand',
'unformatted': ['a', 'sub', 'sup', 'b', 'i', 'u']
});
*/
(function() {
function style_html(html_source, options, js_beautify, css_beautify) {
//Wrapper function to invoke all the necessary constructors and deal with the output.
var multi_parser,
indent_size,
indent_character,
max_char,
brace_style,
unformatted;
options = options || {};
indent_size = options.indent_size || 4;
indent_character = options.indent_char || ' ';
brace_style = options.brace_style || 'collapse';
max_char = options.max_char === 0 ? Infinity : options.max_char || 250;
unformatted = options.unformatted || ['a', 'span', 'bdo', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'sub', 'sup', 'tt', 'i', 'b', 'big', 'small', 'u', 's', 'strike', 'font', 'ins', 'del', 'pre', 'address', 'dt', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
function Parser() {
this.pos = 0; //Parser position
this.token = '';
this.current_mode = 'CONTENT'; //reflects the current Parser mode: TAG/CONTENT
this.tags = { //An object to hold tags, their position, and their parent-tags, initiated with default values
parent: 'parent1',
parentcount: 1,
parent1: ''
};
this.tag_type = '';
this.token_text = this.last_token = this.last_text = this.token_type = '';
this.Utils = { //Uilities made available to the various functions
whitespace: "\n\r\t ".split(''),
single_token: 'br,input,link,meta,!doctype,basefont,base,area,hr,wbr,param,img,isindex,?xml,embed,?php,?,?='.split(','), //all the single tags for HTML
extra_liners: 'head,body,/html'.split(','), //for tags that need a line of whitespace before them
in_array: function (what, arr) {
for (var i=0; i<arr.length; i++) {
if (what === arr[i]) {
return true;
}
}
return false;
}
};
this.get_content = function () { //function to capture regular content between tags
var input_char = '',
content = [],
space = false; //if a space is needed
while (this.input.charAt(this.pos) !== '<') {
if (this.pos >= this.input.length) {
return content.length?content.join(''):['', 'TK_EOF'];
}
input_char = this.input.charAt(this.pos);
this.pos++;
this.line_char_count++;
if (this.Utils.in_array(input_char, this.Utils.whitespace)) {
if (content.length) {
space = true;
}
this.line_char_count--;
continue; //don't want to insert unnecessary space
}
else if (space) {
if (this.line_char_count >= this.max_char) { //insert a line when the max_char is reached
content.push('\n');
for (var i=0; i<this.indent_level; i++) {
content.push(this.indent_string);
}
this.line_char_count = 0;
}
else{
content.push(' ');
this.line_char_count++;
}
space = false;
}
content.push(input_char); //letter at-a-time (or string) inserted to an array
}
return content.length?content.join(''):'';
};
this.get_contents_to = function (name) { //get the full content of a script or style to pass to js_beautify
if (this.pos === this.input.length) {
return ['', 'TK_EOF'];
}
var input_char = '';
var content = '';
var reg_match = new RegExp('</' + name + '\\s*>', 'igm');
reg_match.lastIndex = this.pos;
var reg_array = reg_match.exec(this.input);
var end_script = reg_array?reg_array.index:this.input.length; //absolute end of script
if(this.pos < end_script) { //get everything in between the script tags
content = this.input.substring(this.pos, end_script);
this.pos = end_script;
}
return content;
};
this.record_tag = function (tag){ //function to record a tag and its parent in this.tags Object
if (this.tags[tag + 'count']) { //check for the existence of this tag type
this.tags[tag + 'count']++;
this.tags[tag + this.tags[tag + 'count']] = this.indent_level; //and record the present indent level
}
else { //otherwise initialize this tag type
this.tags[tag + 'count'] = 1;
this.tags[tag + this.tags[tag + 'count']] = this.indent_level; //and record the present indent level
}
this.tags[tag + this.tags[tag + 'count'] + 'parent'] = this.tags.parent; //set the parent (i.e. in the case of a div this.tags.div1parent)
this.tags.parent = tag + this.tags[tag + 'count']; //and make this the current parent (i.e. in the case of a div 'div1')
};
this.retrieve_tag = function (tag) { //function to retrieve the opening tag to the corresponding closer
if (this.tags[tag + 'count']) { //if the openener is not in the Object we ignore it
var temp_parent = this.tags.parent; //check to see if it's a closable tag.
while (temp_parent) { //till we reach '' (the initial value);
if (tag + this.tags[tag + 'count'] === temp_parent) { //if this is it use it
break;
}
temp_parent = this.tags[temp_parent + 'parent']; //otherwise keep on climbing up the DOM Tree
}
if (temp_parent) { //if we caught something
this.indent_level = this.tags[tag + this.tags[tag + 'count']]; //set the indent_level accordingly
this.tags.parent = this.tags[temp_parent + 'parent']; //and set the current parent
}
delete this.tags[tag + this.tags[tag + 'count'] + 'parent']; //delete the closed tags parent reference...
delete this.tags[tag + this.tags[tag + 'count']]; //...and the tag itself
if (this.tags[tag + 'count'] === 1) {
delete this.tags[tag + 'count'];
}
else {
this.tags[tag + 'count']--;
}
}
};
this.get_tag = function (peek) { //function to get a full tag and parse its type
var input_char = '',
content = [],
comment = '',
space = false,
tag_start, tag_end,
orig_pos = this.pos,
orig_line_char_count = this.line_char_count;
peek = peek !== undefined ? peek : false;
do {
if (this.pos >= this.input.length) {
if (peek) {
this.pos = orig_pos;
this.line_char_count = orig_line_char_count;
}
return content.length?content.join(''):['', 'TK_EOF'];
}
input_char = this.input.charAt(this.pos);
this.pos++;
this.line_char_count++;
if (this.Utils.in_array(input_char, this.Utils.whitespace)) { //don't want to insert unnecessary space
space = true;
this.line_char_count--;
continue;
}
if (input_char === "'" || input_char === '"') {
if (!content[1] || content[1] !== '!') { //if we're in a comment strings don't get treated specially
input_char += this.get_unformatted(input_char);
space = true;
}
}
if (input_char === '=') { //no space before =
space = false;
}
if (content.length && content[content.length-1] !== '=' && input_char !== '>' && space) {
//no space after = or before >
if (this.line_char_count >= this.max_char) {
this.print_newline(false, content);
this.line_char_count = 0;
}
else {
content.push(' ');
this.line_char_count++;
}
space = false;
}
if (input_char === '<') {
tag_start = this.pos - 1;
}
content.push(input_char); //inserts character at-a-time (or string)
} while (input_char !== '>');
var tag_complete = content.join('');
var tag_index;
if (tag_complete.indexOf(' ') !== -1) { //if there's whitespace, thats where the tag name ends
tag_index = tag_complete.indexOf(' ');
}
else { //otherwise go with the tag ending
tag_index = tag_complete.indexOf('>');
}
var tag_check = tag_complete.substring(1, tag_index).toLowerCase();
if (tag_complete.charAt(tag_complete.length-2) === '/' ||
this.Utils.in_array(tag_check, this.Utils.single_token)) { //if this tag name is a single tag type (either in the list or has a closing /)
if ( ! peek) {
this.tag_type = 'SINGLE';
}
}
else if (tag_check === 'script') { //for later script handling
if ( ! peek) {
this.record_tag(tag_check);
this.tag_type = 'SCRIPT';
}
}
else if (tag_check === 'style') { //for future style handling (for now it justs uses get_content)
if ( ! peek) {
this.record_tag(tag_check);
this.tag_type = 'STYLE';
}
}
else if (this.is_unformatted(tag_check, unformatted)) { // do not reformat the "unformatted" tags
comment = this.get_unformatted('</'+tag_check+'>', tag_complete); //...delegate to get_unformatted function
content.push(comment);
// Preserve collapsed whitespace either before or after this tag.
if (tag_start > 0 && this.Utils.in_array(this.input.charAt(tag_start - 1), this.Utils.whitespace)){
content.splice(0, 0, this.input.charAt(tag_start - 1));
}
tag_end = this.pos - 1;
if (this.Utils.in_array(this.input.charAt(tag_end + 1), this.Utils.whitespace)){
content.push(this.input.charAt(tag_end + 1));
}
this.tag_type = 'SINGLE';
}
else if (tag_check.charAt(0) === '!') { //peek for <!-- comment
if (tag_check.indexOf('[if') !== -1) { //peek for <!--[if conditional comment
if (tag_complete.indexOf('!IE') !== -1) { //this type needs a closing --> so...
comment = this.get_unformatted('-->', tag_complete); //...delegate to get_unformatted
content.push(comment);
}
if ( ! peek) {
this.tag_type = 'START';
}
}
else if (tag_check.indexOf('[endif') !== -1) {//peek for <!--[endif end conditional comment
this.tag_type = 'END';
this.unindent();
}
else if (tag_check.indexOf('[cdata[') !== -1) { //if it's a <[cdata[ comment...
comment = this.get_unformatted(']]>', tag_complete); //...delegate to get_unformatted function
content.push(comment);
if ( ! peek) {
this.tag_type = 'SINGLE'; //<![CDATA[ comments are treated like single tags
}
}
else {
comment = this.get_unformatted('-->', tag_complete);
content.push(comment);
this.tag_type = 'SINGLE';
}
}
else if ( ! peek) {
if (tag_check.charAt(0) === '/') { //this tag is a double tag so check for tag-ending
this.retrieve_tag(tag_check.substring(1)); //remove it and all ancestors
this.tag_type = 'END';
}
else { //otherwise it's a start-tag
this.record_tag(tag_check); //push it on the tag stack
this.tag_type = 'START';
}
if (this.Utils.in_array(tag_check, this.Utils.extra_liners)) { //check if this double needs an extra line
this.print_newline(true, this.output);
}
}
if (peek) {
this.pos = orig_pos;
this.line_char_count = orig_line_char_count;
}
return content.join(''); //returns fully formatted tag
};
this.get_unformatted = function (delimiter, orig_tag) { //function to return unformatted content in its entirety
if (orig_tag && orig_tag.toLowerCase().indexOf(delimiter) !== -1) {
return '';
}
var input_char = '';
var content = '';
var space = true;
do {
if (this.pos >= this.input.length) {
return content;
}
input_char = this.input.charAt(this.pos);
this.pos++;
if (this.Utils.in_array(input_char, this.Utils.whitespace)) {
if (!space) {
this.line_char_count--;
continue;
}
if (input_char === '\n' || input_char === '\r') {
content += '\n';
/* Don't change tab indention for unformatted blocks. If using code for html editing, this will greatly affect <pre> tags if they are specified in the 'unformatted array'
for (var i=0; i<this.indent_level; i++) {
content += this.indent_string;
}
space = false; //...and make sure other indentation is erased
*/
this.line_char_count = 0;
continue;
}
}
content += input_char;
this.line_char_count++;
space = true;
} while (content.toLowerCase().indexOf(delimiter) === -1);
return content;
};
this.get_token = function () { //initial handler for token-retrieval
var token;
if (this.last_token === 'TK_TAG_SCRIPT' || this.last_token === 'TK_TAG_STYLE') { //check if we need to format javascript
var type = this.last_token.substr(7);
token = this.get_contents_to(type);
if (typeof token !== 'string') {
return token;
}
return [token, 'TK_' + type];
}
if (this.current_mode === 'CONTENT') {
token = this.get_content();
if (typeof token !== 'string') {
return token;
}
else {
return [token, 'TK_CONTENT'];
}
}
if (this.current_mode === 'TAG') {
token = this.get_tag();
if (typeof token !== 'string') {
return token;
}
else {
var tag_name_type = 'TK_TAG_' + this.tag_type;
return [token, tag_name_type];
}
}
};
this.get_full_indent = function (level) {
level = this.indent_level + level || 0;
if (level < 1) {
return '';
}
return Array(level + 1).join(this.indent_string);
};
this.is_unformatted = function(tag_check, unformatted) {
//is this an HTML5 block-level link?
if (!this.Utils.in_array(tag_check, unformatted)){
return false;
}
if (tag_check.toLowerCase() !== 'a' || !this.Utils.in_array('a', unformatted)){
return true;
}
//at this point we have an tag; is its first child something we want to remain
//unformatted?
var next_tag = this.get_tag(true /* peek. */);
// tets next_tag to see if it is just html tag (no external content)
var tag = (next_tag || "").match(/^\s*<\s*\/?([a-z]*)\s*[^>]*>\s*$/);
// if next_tag comes back but is not an isolated tag, then
// let's treat the 'a' tag as having content
// and respect the unformatted option
if (!tag || this.Utils.in_array(tag, unformatted)){
return true;
} else {
return false;
}
};
this.printer = function (js_source, indent_character, indent_size, max_char, brace_style) { //handles input/output and some other printing functions
this.input = js_source || ''; //gets the input for the Parser
this.output = [];
this.indent_character = indent_character;
this.indent_string = '';
this.indent_size = indent_size;
this.brace_style = brace_style;
this.indent_level = 0;
this.max_char = max_char;
this.line_char_count = 0; //count to see if max_char was exceeded
for (var i=0; i<this.indent_size; i++) {
this.indent_string += this.indent_character;
}
this.print_newline = function (ignore, arr) {
this.line_char_count = 0;
if (!arr || !arr.length) {
return;
}
if (!ignore) { //we might want the extra line
while (this.Utils.in_array(arr[arr.length-1], this.Utils.whitespace)) {
arr.pop();
}
}
arr.push('\n');
for (var i=0; i<this.indent_level; i++) {
arr.push(this.indent_string);
}
};
this.print_token = function (text) {
this.output.push(text);
};
this.indent = function () {
this.indent_level++;
};
this.unindent = function () {
if (this.indent_level > 0) {
this.indent_level--;
}
};
};
return this;
}
/*_____________________--------------------_____________________*/
multi_parser = new Parser(); //wrapping functions Parser
multi_parser.printer(html_source, indent_character, indent_size, max_char, brace_style); //initialize starting values
while (true) {
var t = multi_parser.get_token();
multi_parser.token_text = t[0];
multi_parser.token_type = t[1];
if (multi_parser.token_type === 'TK_EOF') {
break;
}
switch (multi_parser.token_type) {
case 'TK_TAG_START':
multi_parser.print_newline(false, multi_parser.output);
multi_parser.print_token(multi_parser.token_text);
multi_parser.indent();
multi_parser.current_mode = 'CONTENT';
break;
case 'TK_TAG_STYLE':
case 'TK_TAG_SCRIPT':
multi_parser.print_newline(false, multi_parser.output);
multi_parser.print_token(multi_parser.token_text);
multi_parser.current_mode = 'CONTENT';
break;
case 'TK_TAG_END':
//Print new line only if the tag has no content and has child
if (multi_parser.last_token === 'TK_CONTENT' && multi_parser.last_text === '') {
var tag_name = multi_parser.token_text.match(/\w+/)[0];
var tag_extracted_from_last_output = multi_parser.output[multi_parser.output.length -1].match(/<\s*(\w+)/);
if (tag_extracted_from_last_output === null || tag_extracted_from_last_output[1] !== tag_name) {
multi_parser.print_newline(true, multi_parser.output);
}
}
multi_parser.print_token(multi_parser.token_text);
multi_parser.current_mode = 'CONTENT';
break;
case 'TK_TAG_SINGLE':
// Don't add a newline before elements that should remain unformatted.
var tag_check = multi_parser.token_text.match(/^\s*<([a-z]+)/i);
if (!tag_check || !multi_parser.Utils.in_array(tag_check[1], unformatted)){
multi_parser.print_newline(false, multi_parser.output);
}
multi_parser.print_token(multi_parser.token_text);
multi_parser.current_mode = 'CONTENT';
break;
case 'TK_CONTENT':
if (multi_parser.token_text !== '') {
multi_parser.print_token(multi_parser.token_text);
}
multi_parser.current_mode = 'TAG';
break;
case 'TK_STYLE':
case 'TK_SCRIPT':
if (multi_parser.token_text !== '') {
multi_parser.output.push('\n');
var text = multi_parser.token_text,
_beautifier,
script_indent_level = 1;
if (multi_parser.token_type === 'TK_SCRIPT') {
_beautifier = typeof js_beautify === 'function' && js_beautify;
} else if (multi_parser.token_type === 'TK_STYLE') {
_beautifier = typeof css_beautify === 'function' && css_beautify;
}
if (options.indent_scripts === "keep") {
script_indent_level = 0;
} else if (options.indent_scripts === "separate") {
script_indent_level = -multi_parser.indent_level;
}
var indentation = multi_parser.get_full_indent(script_indent_level);
if (_beautifier) {
// call the Beautifier if avaliable
text = _beautifier(text.replace(/^\s*/, indentation), options);
} else {
// simply indent the string otherwise
var white = text.match(/^\s*/)[0];
var _level = white.match(/[^\n\r]*$/)[0].split(multi_parser.indent_string).length - 1;
var reindent = multi_parser.get_full_indent(script_indent_level -_level);
text = text.replace(/^\s*/, indentation)
.replace(/\r\n|\r|\n/g, '\n' + reindent)
.replace(/\s*$/, '');
}
if (text) {
multi_parser.print_token(text);
multi_parser.print_newline(true, multi_parser.output);
}
}
multi_parser.current_mode = 'TAG';
break;
}
multi_parser.last_token = multi_parser.token_type;
multi_parser.last_text = multi_parser.token_text;
}
return multi_parser.output.join('');
}
// If we're running a web page and don't have either of the above, add our one global
window.html_beautify = function(html_source, options) {
return style_html(html_source, options, window.js_beautify, window.css_beautify);
};
}());

View File

@ -0,0 +1,620 @@
/*!
* jQuery blockUI plugin
* Version 2.70.0-2014.11.23
* Requires jQuery v1.7 or later
*
* Examples at: http://malsup.com/jquery/block/
* Copyright (c) 2007-2013 M. Alsup
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
* Thanks to Amir-Hossein Sobhi for some excellent contributions!
*/
;(function() {
/*jshint eqeqeq:false curly:false latedef:false */
"use strict";
function setup($) {
$.fn._fadeIn = $.fn.fadeIn;
var noOp = $.noop || function() {};
// this bit is to ensure we don't call setExpression when we shouldn't (with extra muscle to handle
// confusing userAgent strings on Vista)
var msie = /MSIE/.test(navigator.userAgent);
var ie6 = /MSIE 6.0/.test(navigator.userAgent) && ! /MSIE 8.0/.test(navigator.userAgent);
var mode = document.documentMode || 0;
var setExpr = $.isFunction( document.createElement('div').style.setExpression );
// global $ methods for blocking/unblocking the entire page
$.blockUI = function(opts) { install(window, opts); };
$.unblockUI = function(opts) { remove(window, opts); };
// convenience method for quick growl-like notifications (http://www.google.com/search?q=growl)
$.growlUI = function(title, message, timeout, onClose) {
var $m = $('<div class="growlUI"></div>');
if (title) $m.append('<h1>'+title+'</h1>');
if (message) $m.append('<h2>'+message+'</h2>');
if (timeout === undefined) timeout = 3000;
// Added by konapun: Set timeout to 30 seconds if this growl is moused over, like normal toast notifications
var callBlock = function(opts) {
opts = opts || {};
$.blockUI({
message: $m,
fadeIn : typeof opts.fadeIn !== 'undefined' ? opts.fadeIn : 700,
fadeOut: typeof opts.fadeOut !== 'undefined' ? opts.fadeOut : 1000,
timeout: typeof opts.timeout !== 'undefined' ? opts.timeout : timeout,
centerY: false,
showOverlay: false,
onUnblock: onClose,
css: $.blockUI.defaults.growlCSS
});
};
callBlock();
var nonmousedOpacity = $m.css('opacity');
$m.mouseover(function() {
callBlock({
fadeIn: 0,
timeout: 30000
});
var displayBlock = $('.blockMsg');
displayBlock.stop(); // cancel fadeout if it has started
displayBlock.fadeTo(300, 1); // make it easier to read the message by removing transparency
}).mouseout(function() {
$('.blockMsg').fadeOut(1000);
});
// End konapun additions
};
// plugin method for blocking element content
$.fn.block = function(opts) {
if ( this[0] === window ) {
$.blockUI( opts );
return this;
}
var fullOpts = $.extend({}, $.blockUI.defaults, opts || {});
this.each(function() {
var $el = $(this);
if (fullOpts.ignoreIfBlocked && $el.data('blockUI.isBlocked'))
return;
$el.unblock({ fadeOut: 0 });
});
return this.each(function() {
if ($.css(this,'position') == 'static') {
this.style.position = 'relative';
$(this).data('blockUI.static', true);
}
this.style.zoom = 1; // force 'hasLayout' in ie
install(this, opts);
});
};
// plugin method for unblocking element content
$.fn.unblock = function(opts) {
if ( this[0] === window ) {
$.unblockUI( opts );
return this;
}
return this.each(function() {
remove(this, opts);
});
};
$.blockUI.version = 2.70; // 2nd generation blocking at no extra cost!
// override these in your code to change the default behavior and style
$.blockUI.defaults = {
// message displayed when blocking (use null for no message)
message: '<div class="loaderbox"><div class="loading-activity"></div> 加载中......</div>',
title: null, // title string; only used when theme == true
draggable: true, // only used when theme == true (requires jquery-ui.js to be loaded)
theme: false, // set to true to use with jQuery UI themes
// styles for the message when blocking; if you wish to disable
// these and use an external stylesheet then do this in your code:
// $.blockUI.defaults.css = {};
css: {
padding: 0,
margin: 0,
width: '30%',
top: '40%',
left: '35%',
textAlign: 'center',
color: '#000',
border: '0px',
backgroundColor:'transparent',
cursor: 'wait'
},
// minimal style set used when themes are used
themedCSS: {
width: '30%',
top: '40%',
left: '35%'
},
// styles for the overlay
overlayCSS: {
backgroundColor: '#000',
opacity: 0.6,
cursor: 'wait'
},
// style to replace wait cursor before unblocking to correct issue
// of lingering wait cursor
cursorReset: 'default',
// styles applied when using $.growlUI
growlCSS: {
width: '350px',
top: '10px',
left: '',
right: '10px',
border: 'none',
padding: '5px',
opacity: 0.6,
cursor: 'default',
color: '#fff',
backgroundColor: '#000',
'-webkit-border-radius':'10px',
'-moz-border-radius': '10px',
'border-radius': '10px'
},
// IE issues: 'about:blank' fails on HTTPS and javascript:false is s-l-o-w
// (hat tip to Jorge H. N. de Vasconcelos)
/*jshint scripturl:true */
iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank',
// force usage of iframe in non-IE browsers (handy for blocking applets)
forceIframe: false,
// z-index for the blocking overlay
baseZ: 1000,
// set these to true to have the message automatically centered
centerX: true, // <-- only effects element blocking (page block controlled via css above)
centerY: true,
// allow body element to be stetched in ie6; this makes blocking look better
// on "short" pages. disable if you wish to prevent changes to the body height
allowBodyStretch: true,
// enable if you want key and mouse events to be disabled for content that is blocked
bindEvents: true,
// be default blockUI will supress tab navigation from leaving blocking content
// (if bindEvents is true)
constrainTabKey: true,
// fadeIn time in millis; set to 0 to disable fadeIn on block
fadeIn: 200,
// fadeOut time in millis; set to 0 to disable fadeOut on unblock
fadeOut: 400,
// time in millis to wait before auto-unblocking; set to 0 to disable auto-unblock
timeout: 0,
// disable if you don't want to show the overlay
showOverlay: true,
// if true, focus will be placed in the first available input field when
// page blocking
focusInput: true,
// elements that can receive focus
focusableElements: ':input:enabled:visible',
// suppresses the use of overlay styles on FF/Linux (due to performance issues with opacity)
// no longer needed in 2012
// applyPlatformOpacityRules: true,
// callback method invoked when fadeIn has completed and blocking message is visible
onBlock: null,
// callback method invoked when unblocking has completed; the callback is
// passed the element that has been unblocked (which is the window object for page
// blocks) and the options that were passed to the unblock call:
// onUnblock(element, options)
onUnblock: null,
// callback method invoked when the overlay area is clicked.
// setting this will turn the cursor to a pointer, otherwise cursor defined in overlayCss will be used.
onOverlayClick: null,
// don't ask; if you really must know: http://groups.google.com/group/jquery-en/browse_thread/thread/36640a8730503595/2f6a79a77a78e493#2f6a79a77a78e493
quirksmodeOffsetHack: 4,
// class name of the message block
blockMsgClass: 'blockMsg',
// if it is already blocked, then ignore it (don't unblock and reblock)
ignoreIfBlocked: false
};
// private data and functions follow...
var pageBlock = null;
var pageBlockEls = [];
function install(el, opts) {
var css, themedCSS;
var full = (el == window);
var msg = (opts && opts.message !== undefined ? opts.message : undefined);
opts = $.extend({}, $.blockUI.defaults, opts || {});
if (opts.ignoreIfBlocked && $(el).data('blockUI.isBlocked'))
return;
opts.overlayCSS = $.extend({}, $.blockUI.defaults.overlayCSS, opts.overlayCSS || {});
css = $.extend({}, $.blockUI.defaults.css, opts.css || {});
if (opts.onOverlayClick)
opts.overlayCSS.cursor = 'pointer';
themedCSS = $.extend({}, $.blockUI.defaults.themedCSS, opts.themedCSS || {});
msg = msg === undefined ? opts.message : msg;
// remove the current block (if there is one)
if (full && pageBlock)
remove(window, {fadeOut:0});
// if an existing element is being used as the blocking content then we capture
// its current place in the DOM (and current display style) so we can restore
// it when we unblock
if (msg && typeof msg != 'string' && (msg.parentNode || msg.jquery)) {
var node = msg.jquery ? msg[0] : msg;
var data = {};
$(el).data('blockUI.history', data);
data.el = node;
data.parent = node.parentNode;
data.display = node.style.display;
data.position = node.style.position;
if (data.parent)
data.parent.removeChild(node);
}
$(el).data('blockUI.onUnblock', opts.onUnblock);
var z = opts.baseZ;
// blockUI uses 3 layers for blocking, for simplicity they are all used on every platform;
// layer1 is the iframe layer which is used to supress bleed through of underlying content
// layer2 is the overlay layer which has opacity and a wait cursor (by default)
// layer3 is the message content that is displayed while blocking
var lyr1, lyr2, lyr3, s;
if (msie || opts.forceIframe)
lyr1 = $('<iframe class="blockUI" style="z-index:'+ (z++) +';display:none;border:none;margin:0;padding:0;position:absolute;width:100%;height:100%;top:0;left:0" src="'+opts.iframeSrc+'"></iframe>');
else
lyr1 = $('<div class="blockUI" style="display:none"></div>');
if (opts.theme)
lyr2 = $('<div class="blockUI blockOverlay ui-widget-overlay" style="z-index:'+ (z++) +';display:none"></div>');
else
lyr2 = $('<div class="blockUI blockOverlay" style="z-index:'+ (z++) +';display:none;border:none;margin:0;padding:0;width:100%;height:100%;top:0;left:0"></div>');
if (opts.theme && full) {
s = '<div class="blockUI ' + opts.blockMsgClass + ' blockPage ui-dialog ui-widget ui-corner-all" style="z-index:'+(z+10)+';display:none;position:fixed">';
if ( opts.title ) {
s += '<div class="ui-widget-header ui-dialog-titlebar ui-corner-all blockTitle">'+(opts.title || '&nbsp;')+'</div>';
}
s += '<div class="ui-widget-content ui-dialog-content"></div>';
s += '</div>';
}
else if (opts.theme) {
s = '<div class="blockUI ' + opts.blockMsgClass + ' blockElement ui-dialog ui-widget ui-corner-all" style="z-index:'+(z+10)+';display:none;position:absolute">';
if ( opts.title ) {
s += '<div class="ui-widget-header ui-dialog-titlebar ui-corner-all blockTitle">'+(opts.title || '&nbsp;')+'</div>';
}
s += '<div class="ui-widget-content ui-dialog-content"></div>';
s += '</div>';
}
else if (full) {
s = '<div class="blockUI ' + opts.blockMsgClass + ' blockPage" style="z-index:'+(z+10)+';display:none;position:fixed"></div>';
}
else {
s = '<div class="blockUI ' + opts.blockMsgClass + ' blockElement" style="z-index:'+(z+10)+';display:none;position:absolute"></div>';
}
lyr3 = $(s);
// if we have a message, style it
if (msg) {
if (opts.theme) {
lyr3.css(themedCSS);
lyr3.addClass('ui-widget-content');
}
else
lyr3.css(css);
}
// style the overlay
if (!opts.theme /*&& (!opts.applyPlatformOpacityRules)*/)
lyr2.css(opts.overlayCSS);
lyr2.css('position', full ? 'fixed' : 'absolute');
// make iframe layer transparent in IE
if (msie || opts.forceIframe)
lyr1.css('opacity',0.0);
//$([lyr1[0],lyr2[0],lyr3[0]]).appendTo(full ? 'body' : el);
var layers = [lyr1,lyr2,lyr3], $par = full ? $('body') : $(el);
$.each(layers, function() {
this.appendTo($par);
});
if (opts.theme && opts.draggable && $.fn.draggable) {
lyr3.draggable({
handle: '.ui-dialog-titlebar',
cancel: 'li'
});
}
// ie7 must use absolute positioning in quirks mode and to account for activex issues (when scrolling)
var expr = setExpr && (!$.support.boxModel || $('object,embed', full ? null : el).length > 0);
if (ie6 || expr) {
// give body 100% height
if (full && opts.allowBodyStretch && $.support.boxModel)
$('html,body').css('height','100%');
// fix ie6 issue when blocked element has a border width
if ((ie6 || !$.support.boxModel) && !full) {
var t = sz(el,'borderTopWidth'), l = sz(el,'borderLeftWidth');
var fixT = t ? '(0 - '+t+')' : 0;
var fixL = l ? '(0 - '+l+')' : 0;
}
// simulate fixed position
$.each(layers, function(i,o) {
var s = o[0].style;
s.position = 'absolute';
if (i < 2) {
if (full)
s.setExpression('height','Math.max(document.body.scrollHeight, document.body.offsetHeight) - (jQuery.support.boxModel?0:'+opts.quirksmodeOffsetHack+') + "px"');
else
s.setExpression('height','this.parentNode.offsetHeight + "px"');
if (full)
s.setExpression('width','jQuery.support.boxModel && document.documentElement.clientWidth || document.body.clientWidth + "px"');
else
s.setExpression('width','this.parentNode.offsetWidth + "px"');
if (fixL) s.setExpression('left', fixL);
if (fixT) s.setExpression('top', fixT);
}
else if (opts.centerY) {
if (full) s.setExpression('top','(document.documentElement.clientHeight || document.body.clientHeight) / 2 - (this.offsetHeight / 2) + (blah = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + "px"');
s.marginTop = 0;
}
else if (!opts.centerY && full) {
var top = (opts.css && opts.css.top) ? parseInt(opts.css.top, 10) : 0;
var expression = '((document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + '+top+') + "px"';
s.setExpression('top',expression);
}
});
}
// show the message
if (msg) {
if (opts.theme)
lyr3.find('.ui-widget-content').append(msg);
else
lyr3.append(msg);
if (msg.jquery || msg.nodeType)
$(msg).show();
}
if ((msie || opts.forceIframe) && opts.showOverlay)
lyr1.show(); // opacity is zero
if (opts.fadeIn) {
var cb = opts.onBlock ? opts.onBlock : noOp;
var cb1 = (opts.showOverlay && !msg) ? cb : noOp;
var cb2 = msg ? cb : noOp;
if (opts.showOverlay)
lyr2._fadeIn(opts.fadeIn, cb1);
if (msg)
lyr3._fadeIn(opts.fadeIn, cb2);
}
else {
if (opts.showOverlay)
lyr2.show();
if (msg)
lyr3.show();
if (opts.onBlock)
opts.onBlock.bind(lyr3)();
}
// bind key and mouse events
bind(1, el, opts);
if (full) {
pageBlock = lyr3[0];
pageBlockEls = $(opts.focusableElements,pageBlock);
if (opts.focusInput)
setTimeout(focus, 20);
}
else
center(lyr3[0], opts.centerX, opts.centerY);
if (opts.timeout) {
// auto-unblock
var to = setTimeout(function() {
if (full)
$.unblockUI(opts);
else
$(el).unblock(opts);
}, opts.timeout);
$(el).data('blockUI.timeout', to);
}
}
// remove the block
function remove(el, opts) {
var count;
var full = (el == window);
var $el = $(el);
var data = $el.data('blockUI.history');
var to = $el.data('blockUI.timeout');
if (to) {
clearTimeout(to);
$el.removeData('blockUI.timeout');
}
opts = $.extend({}, $.blockUI.defaults, opts || {});
bind(0, el, opts); // unbind events
if (opts.onUnblock === null) {
opts.onUnblock = $el.data('blockUI.onUnblock');
$el.removeData('blockUI.onUnblock');
}
var els;
if (full) // crazy selector to handle odd field errors in ie6/7
els = $('body').children().filter('.blockUI').add('body > .blockUI');
else
els = $el.find('>.blockUI');
// fix cursor issue
if ( opts.cursorReset ) {
if ( els.length > 1 )
els[1].style.cursor = opts.cursorReset;
if ( els.length > 2 )
els[2].style.cursor = opts.cursorReset;
}
if (full)
pageBlock = pageBlockEls = null;
if (opts.fadeOut) {
count = els.length;
els.stop().fadeOut(opts.fadeOut, function() {
if ( --count === 0)
reset(els,data,opts,el);
});
}
else
reset(els, data, opts, el);
}
// move blocking element back into the DOM where it started
function reset(els,data,opts,el) {
var $el = $(el);
if ( $el.data('blockUI.isBlocked') )
return;
els.each(function(i,o) {
// remove via DOM calls so we don't lose event handlers
if (this.parentNode)
this.parentNode.removeChild(this);
});
if (data && data.el) {
data.el.style.display = data.display;
data.el.style.position = data.position;
data.el.style.cursor = 'default'; // #59
if (data.parent)
data.parent.appendChild(data.el);
$el.removeData('blockUI.history');
}
if ($el.data('blockUI.static')) {
$el.css('position', 'static'); // #22
}
if (typeof opts.onUnblock == 'function')
opts.onUnblock(el,opts);
// fix issue in Safari 6 where block artifacts remain until reflow
var body = $(document.body), w = body.width(), cssW = body[0].style.width;
body.width(w-1).width(w);
body[0].style.width = cssW;
}
// bind/unbind the handler
function bind(b, el, opts) {
var full = el == window, $el = $(el);
// don't bother unbinding if there is nothing to unbind
if (!b && (full && !pageBlock || !full && !$el.data('blockUI.isBlocked')))
return;
$el.data('blockUI.isBlocked', b);
// don't bind events when overlay is not in use or if bindEvents is false
if (!full || !opts.bindEvents || (b && !opts.showOverlay))
return;
// bind anchors and inputs for mouse and key events
var events = 'mousedown mouseup keydown keypress keyup touchstart touchend touchmove';
if (b)
$(document).bind(events, opts, handler);
else
$(document).unbind(events, handler);
// former impl...
// var $e = $('a,:input');
// b ? $e.bind(events, opts, handler) : $e.unbind(events, handler);
}
// event handler to suppress keyboard/mouse events when blocking
function handler(e) {
// allow tab navigation (conditionally)
if (e.type === 'keydown' && e.keyCode && e.keyCode == 9) {
if (pageBlock && e.data.constrainTabKey) {
var els = pageBlockEls;
var fwd = !e.shiftKey && e.target === els[els.length-1];
var back = e.shiftKey && e.target === els[0];
if (fwd || back) {
setTimeout(function(){focus(back);},10);
return false;
}
}
}
var opts = e.data;
var target = $(e.target);
if (target.hasClass('blockOverlay') && opts.onOverlayClick)
opts.onOverlayClick(e);
// allow events within the message content
if (target.parents('div.' + opts.blockMsgClass).length > 0)
return true;
// allow events for content that is not being blocked
return target.parents().children().filter('div.blockUI').length === 0;
}
function focus(back) {
if (!pageBlockEls)
return;
var e = pageBlockEls[back===true ? pageBlockEls.length-1 : 0];
if (e)
e.focus();
}
function center(el, x, y) {
var p = el.parentNode, s = el.style;
var l = ((p.offsetWidth - el.offsetWidth)/2) - sz(p,'borderLeftWidth');
var t = ((p.offsetHeight - el.offsetHeight)/2) - sz(p,'borderTopWidth');
if (x) s.left = l > 0 ? (l+'px') : '0';
if (y) s.top = t > 0 ? (t+'px') : '0';
}
function sz(el, p) {
return parseInt($.css(el,p),10)||0;
}
}
/*global define:true */
if (typeof define === 'function' && define.amd && define.amd.jQuery) {
define(['jquery'], setup);
} else {
setup(jQuery);
}
})();

View File

@ -0,0 +1,688 @@
/*!
* bootstrap-fileinput v5.5.2
* http://plugins.krajee.com/file-input
*
* Krajee default styling for bootstrap-fileinput.
*
* Author: Kartik Visweswaran
* Copyright: 2014 - 2022, Kartik Visweswaran, Krajee.com
*
* Licensed under the BSD-3-Clause
* https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md
*/
.file-loading input[type=file],
input[type=file].file-loading {
width: 0;
height: 0;
}
.file-no-browse {
position: absolute;
left: 50%;
bottom: 20%;
width: 1px;
height: 1px;
font-size: 0;
opacity: 0;
border: none;
background: none;
outline: none;
box-shadow: none;
}
.kv-hidden,
.file-caption-icon,
.file-zoom-dialog .modal-header:before,
.file-zoom-dialog .modal-header:after,
.file-input-new .file-preview,
.file-input-new .close,
.file-input-new .glyphicon-file,
.file-input-new .fileinput-remove-button,
.file-input-new .fileinput-upload-button,
.file-input-new .no-browse .input-group-btn,
.file-input-ajax-new .fileinput-remove-button,
.file-input-ajax-new .fileinput-upload-button,
.file-input-ajax-new .no-browse .input-group-btn,
.hide-content .kv-file-content,
.is-locked .fileinput-upload-button,
.is-locked .fileinput-remove-button {
display: none;
}
.file-caption .input-group {
align-items: center;
}
.btn-file input[type=file],
.file-caption-icon,
.file-preview .fileinput-remove,
.krajee-default .file-thumb-progress,
.file-zoom-dialog .btn-navigate,
.file-zoom-dialog .floating-buttons {
position: absolute;
}
.file-caption-icon .kv-caption-icon {
line-height: inherit;
}
.file-input,
.file-loading:before,
.btn-file,
.file-caption,
.file-preview,
.krajee-default.file-preview-frame,
.krajee-default .file-thumbnail-footer,
.file-zoom-dialog .modal-dialog {
position: relative;
}
.file-error-message pre,
.file-error-message ul,
.krajee-default .file-actions,
.krajee-default .file-other-error {
text-align: left;
}
.file-error-message pre,
.file-error-message ul {
margin: 0;
}
.krajee-default .file-drag-handle,
.krajee-default .file-upload-indicator {
float: left;
margin-top: 10px;
width: 16px;
height: 16px;
}
.file-thumb-progress .progress,
.file-thumb-progress .progress-bar {
font-family: Verdana, Helvetica, sans-serif;
font-size: 0.7rem;
}
.krajee-default .file-thumb-progress .progress,
.kv-upload-progress .progress {
background-color: #ccc;
}
.krajee-default .file-caption-info,
.krajee-default .file-size-info {
display: block;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 160px;
height: 15px;
margin: auto;
}
.file-zoom-content > .file-object.type-video,
.file-zoom-content > .file-object.type-flash,
.file-zoom-content > .file-object.type-image {
max-width: 100%;
max-height: 100%;
width: auto;
}
.file-zoom-content > .file-object.type-video,
.file-zoom-content > .file-object.type-flash {
height: 100%;
}
.file-zoom-content > .file-object.type-pdf,
.file-zoom-content > .file-object.type-html,
.file-zoom-content > .file-object.type-text,
.file-zoom-content > .file-object.type-default {
width: 100%;
}
.file-loading:before {
content: " Loading...";
display: inline-block;
padding-left: 20px;
line-height: 16px;
font-size: 13px;
font-variant: small-caps;
color: #999;
background: transparent url(loading.gif) top left no-repeat;
}
.file-object {
margin: 0 0 -5px 0;
padding: 0;
}
.btn-file {
overflow: hidden;
}
.btn-file input[type=file] {
top: 0;
left: 0;
min-width: 100%;
min-height: 100%;
text-align: right;
opacity: 0;
background: none repeat scroll 0 0 transparent;
cursor: inherit;
display: block;
}
.btn-file ::-ms-browse {
font-size: 10000px;
width: 100%;
height: 100%;
}
.file-caption.icon-visible .file-caption-icon {
display: inline-block;
}
.file-caption.icon-visible .file-caption-name {
padding-left: 25px;
}
.file-caption.icon-visible > .input-group-lg .file-caption-name {
padding-left: 30px;
}
.file-caption.icon-visible > .input-group-sm .file-caption-name {
padding-left: 22px;
}
.file-caption-name:not(.file-caption-disabled) {
background-color: transparent;
}
.file-caption-name.file-processing {
font-style: italic;
border-color: #bbb;
opacity: 0.5;
}
.file-caption-icon {
padding: 7px 5px;
left: 4px;
}
.input-group-lg .file-caption-icon {
font-size: 1.25rem;
}
.input-group-sm .file-caption-icon {
font-size: 0.875rem;
padding: 0.25rem;
}
.file-error-message {
color: #a94442;
background-color: #f2dede;
margin: 5px;
border: 1px solid #ebccd1;
border-radius: 4px;
padding: 15px;
}
.file-error-message pre {
margin: 5px 0;
}
.file-caption-disabled {
background-color: #eee;
cursor: not-allowed;
opacity: 1;
}
.file-preview {
border-radius: 5px;
border: 1px solid #ddd;
padding: 8px;
width: 100%;
margin-bottom: 5px;
}
.file-preview .btn-xs {
padding: 1px 5px;
font-size: 12px;
line-height: 1.5;
border-radius: 3px;
}
.file-preview .fileinput-remove {
top: 1px;
right: 1px;
line-height: 10px;
}
.file-preview .clickable {
cursor: pointer;
}
.file-preview-image {
font: 40px Impact, Charcoal, sans-serif;
color: #008000;
width: auto;
height: auto;
max-width: 100%;
max-height: 100%;
}
.krajee-default.file-preview-frame {
margin: 8px;
border: 1px solid rgba(0, 0, 0, 0.2);
box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.2);
padding: 6px;
float: left;
text-align: center;
}
.krajee-default.file-preview-frame .kv-file-content {
width: 213px;
height: 160px;
}
.krajee-default.file-preview-frame .kv-file-content.kv-pdf-rendered {
width: 400px;
}
.krajee-default.file-preview-frame[data-template="audio"] .kv-file-content {
width: 240px;
height: 55px;
}
.krajee-default.file-preview-frame .file-thumbnail-footer {
height: 70px;
}
.krajee-default.file-preview-frame:not(.file-preview-error):hover {
border: 1px solid rgba(0, 0, 0, 0.3);
box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.4);
}
.krajee-default .file-preview-text {
color: #428bca;
border: 1px solid #ddd;
outline: none;
resize: none;
}
.krajee-default .file-preview-html {
border: 1px solid #ddd;
}
.krajee-default .file-other-icon {
font-size: 6em;
line-height: 1;
}
.krajee-default .file-footer-buttons {
float: right;
}
.krajee-default .file-footer-caption {
display: block;
text-align: center;
padding-top: 4px;
font-size: 11px;
color: #999;
margin-bottom: 30px;
}
.file-upload-stats {
font-size: 10px;
text-align: center;
width: 100%;
}
.kv-upload-progress .file-upload-stats {
font-size: 12px;
margin: -10px 0 5px;
}
.krajee-default .file-preview-error {
opacity: 0.65;
box-shadow: none;
}
.krajee-default .file-thumb-progress {
top: 37px;
left: 0;
right: 0;
}
.krajee-default.kvsortable-ghost {
background: #e1edf7;
border: 2px solid #a1abff;
}
.krajee-default .file-preview-other:hover {
opacity: 0.8;
}
.krajee-default .file-preview-frame:not(.file-preview-error) .file-footer-caption:hover {
color: #000;
}
.kv-upload-progress .progress {
height: 20px;
margin: 10px 0;
overflow: hidden;
}
.kv-upload-progress .progress-bar {
height: 20px;
font-family: Verdana, Helvetica, sans-serif;
}
/*noinspection CssOverwrittenProperties*/
.file-zoom-dialog .file-other-icon {
font-size: 22em;
font-size: 50vmin;
}
.file-zoom-dialog .modal-dialog {
width: auto;
}
.file-zoom-dialog .modal-header {
display: flex;
align-items: center;
justify-content: space-between;
}
.file-zoom-dialog .btn-navigate {
margin: 0 0.1rem;
padding: 0;
font-size: 1.2rem;
width: 2.4rem;
height: 2.4rem;
top: 50%;
border-radius: 50%;
text-align: center;
}
.btn-navigate * {
width: auto;
}
.file-zoom-dialog .floating-buttons {
top: 5px;
right: 10px;
}
.file-zoom-dialog .btn-kv-prev {
left: 0;
}
.file-zoom-dialog .btn-kv-next {
right: 0;
}
.file-zoom-dialog .kv-zoom-header {
padding: 0.5rem;
}
.file-zoom-dialog .kv-zoom-body {
padding: 0.25rem;
}
.file-zoom-dialog .kv-zoom-description {
position: absolute;
opacity: 0.8;
font-size: 0.8rem;
background-color: #1a1a1a;
padding: 1rem;
text-align: center;
border-radius: 0.5rem;
color: #fff;
left: 15%;
right: 15%;
bottom: 15%;
}
.file-zoom-dialog .kv-desc-hide {
float: right;
color: #fff;
padding: 0 0.1rem;
background: none;
border: none;
}
.file-zoom-dialog .kv-desc-hide:hover {
opacity: 0.7;
}
.file-zoom-dialog .kv-desc-hide:focus {
opacity: 0.9;
}
.file-input-new .no-browse .form-control {
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
}
.file-input-ajax-new .no-browse .form-control {
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
}
.file-caption {
width: 100%;
position: relative;
}
.file-thumb-loading {
background: transparent url(loading.gif) no-repeat scroll center center content-box !important;
}
.file-drop-zone {
border: 1px dashed #aaa;
min-height: 260px;
border-radius: 4px;
text-align: center;
vertical-align: middle;
margin: 12px 15px 12px 12px;
padding: 5px;
}
.file-drop-zone.clickable:hover {
border: 2px dashed #999;
}
.file-drop-zone.clickable:focus {
border: 2px solid #5acde2;
}
.file-drop-zone .file-preview-thumbnails {
cursor: default;
}
.file-drop-zone-title {
color: #aaa;
font-size: 1.6em;
text-align: center;
padding: 85px 10px;
cursor: default;
}
.file-highlighted {
border: 2px dashed #999 !important;
background-color: #eee;
}
.file-uploading {
background: url(loading-sm.gif) no-repeat center bottom 10px;
opacity: 0.65;
}
.file-zoom-fullscreen .modal-dialog {
min-width: 100%;
margin: 0;
}
.file-zoom-fullscreen .modal-content {
border-radius: 0;
box-shadow: none;
min-height: 100vh;
}
.file-zoom-fullscreen .kv-zoom-body {
overflow-y: auto;
}
.floating-buttons {
z-index: 3000;
}
.floating-buttons .btn-kv {
margin-left: 3px;
z-index: 3000;
}
.kv-zoom-actions {
min-width: 140px;
}
.kv-zoom-actions .btn-kv {
margin-left: 3px;
}
.file-zoom-content {
text-align: center;
white-space: nowrap;
min-height: 300px;
}
.file-zoom-content:hover {
background: transparent;
}
.file-zoom-content .file-preview-image {
max-height: 100%;
}
.file-zoom-content .file-preview-video {
max-height: 100%;
}
.file-zoom-content > .file-object.type-image {
height: auto;
min-height: inherit;
}
.file-zoom-content > .file-object.type-audio {
width: auto;
height: 30px;
}
@media (min-width: 576px) {
.file-zoom-dialog .modal-dialog {
max-width: 500px;
}
}
@media (min-width: 992px) {
.file-zoom-dialog .modal-lg {
max-width: 800px;
}
}
@media (max-width: 767px) {
.file-preview-thumbnails {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.file-zoom-dialog .modal-header {
flex-direction: column;
}
}
@media (max-width: 350px) {
.krajee-default.file-preview-frame:not([data-template="audio"]) .kv-file-content {
width: 160px;
}
}
@media (max-width: 420px) {
.krajee-default.file-preview-frame .kv-file-content.kv-pdf-rendered {
width: 100%;
}
}
.file-loading[dir=rtl]:before {
background: transparent url(loading.gif) top right no-repeat;
padding-left: 0;
padding-right: 20px;
}
.clickable .file-drop-zone-title {
cursor: pointer;
}
.file-sortable .file-drag-handle:hover {
opacity: 0.7;
}
.file-sortable .file-drag-handle {
cursor: grab;
opacity: 1;
}
.file-grabbing,
.file-grabbing * {
cursor: not-allowed !important;
}
.file-grabbing .file-preview-thumbnails * {
cursor: grabbing !important;
}
.file-preview-frame.sortable-chosen {
background-color: #d9edf7;
border-color: #17a2b8;
box-shadow: none !important;
}
.file-preview .kv-zoom-cache {
display: none;
}
.file-preview-other-frame, .file-preview-object, .kv-file-content, .kv-zoom-body {
display: flex;
align-items: center;
justify-content: center;
}
.btn-kv-rotate,
.kv-file-rotate {
display: none;
}
.rotatable:not(.hide-rotate) .btn-kv-rotate,
.rotatable:not(.hide-rotate) .kv-file-rotate {
display: inline-block;
}
.rotatable .file-zoom-detail,
.rotatable .kv-file-content,
.rotatable .kv-file-content > :first-child {
transform-origin: center center;
}
.rotate-animate {
transition: transform 0.3s ease;
}
.kv-overflow-hidden {
overflow: hidden;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 847 B

View File

@ -0,0 +1,459 @@
/*!
* Bootstrap-select v1.13.18 (https://developer.snapappointments.com/bootstrap-select)
*
* Copyright 2012-2020 SnapAppointments, LLC
* Licensed under MIT (https://github.com/snapappointments/bootstrap-select/blob/master/LICENSE)
*/
@-webkit-keyframes bs-notify-fadeOut {
0% {
opacity: 0.9;
}
100% {
opacity: 0;
}
}
@-o-keyframes bs-notify-fadeOut {
0% {
opacity: 0.9;
}
100% {
opacity: 0;
}
}
@keyframes bs-notify-fadeOut {
0% {
opacity: 0.9;
}
100% {
opacity: 0;
}
}
select.bs-select-hidden,
.bootstrap-select > select.bs-select-hidden,
select.selectpicker {
display: none !important;
}
.bootstrap-select {
width: 220px \0;
/*IE9 and below*/
vertical-align: middle;
}
.bootstrap-select > .dropdown-toggle {
position: relative;
width: 100%;
text-align: right;
white-space: nowrap;
display: -webkit-inline-box;
display: -webkit-inline-flex;
display: -ms-inline-flexbox;
display: inline-flex;
-webkit-box-align: center;
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: justify;
-webkit-justify-content: space-between;
-ms-flex-pack: justify;
justify-content: space-between;
}
.bootstrap-select > .dropdown-toggle:after {
margin-top: -1px;
}
.bootstrap-select > .dropdown-toggle.bs-placeholder,
.bootstrap-select > .dropdown-toggle.bs-placeholder:hover,
.bootstrap-select > .dropdown-toggle.bs-placeholder:focus,
.bootstrap-select > .dropdown-toggle.bs-placeholder:active {
color: #999;
}
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-primary,
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-secondary,
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-success,
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-danger,
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-info,
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-dark,
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-primary:hover,
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-secondary:hover,
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-success:hover,
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-danger:hover,
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-info:hover,
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-dark:hover,
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-primary:focus,
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-secondary:focus,
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-success:focus,
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-danger:focus,
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-info:focus,
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-dark:focus,
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-primary:active,
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-secondary:active,
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-success:active,
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-danger:active,
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-info:active,
.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-dark:active {
color: rgba(255, 255, 255, 0.5);
}
.bootstrap-select > select {
position: absolute !important;
bottom: 0;
left: 50%;
display: block !important;
width: 0.5px !important;
height: 100% !important;
padding: 0 !important;
opacity: 0 !important;
border: none;
z-index: 0 !important;
}
.bootstrap-select > select.mobile-device {
top: 0;
left: 0;
display: block !important;
width: 100% !important;
z-index: 2 !important;
}
.has-error .bootstrap-select .dropdown-toggle,
.error .bootstrap-select .dropdown-toggle,
.bootstrap-select.is-invalid .dropdown-toggle,
.was-validated .bootstrap-select select:invalid + .dropdown-toggle {
border-color: #b94a48;
}
.bootstrap-select.is-valid .dropdown-toggle,
.was-validated .bootstrap-select select:valid + .dropdown-toggle {
border-color: #28a745;
}
.bootstrap-select.fit-width {
width: auto !important;
}
.bootstrap-select:not([class*="col-"]):not([class*="form-control"]):not(.input-group-btn) {
width: 220px;
}
.bootstrap-select > select.mobile-device:focus + .dropdown-toggle,
.bootstrap-select .dropdown-toggle:focus {
outline: thin dotted #333333 !important;
outline: 5px auto -webkit-focus-ring-color !important;
outline-offset: -2px;
}
.bootstrap-select.form-control {
margin-bottom: 0;
padding: 0;
border: none;
height: auto;
}
:not(.input-group) > .bootstrap-select.form-control:not([class*="col-"]) {
width: 100%;
}
.bootstrap-select.form-control.input-group-btn {
float: none;
z-index: auto;
}
.form-inline .bootstrap-select,
.form-inline .bootstrap-select.form-control:not([class*="col-"]) {
width: auto;
}
.bootstrap-select:not(.input-group-btn),
.bootstrap-select[class*="col-"] {
float: none;
display: inline-block;
margin-left: 0;
}
.bootstrap-select.dropdown-menu-right,
.bootstrap-select[class*="col-"].dropdown-menu-right,
.row .bootstrap-select[class*="col-"].dropdown-menu-right {
float: right;
}
.form-inline .bootstrap-select,
.form-horizontal .bootstrap-select,
.form-group .bootstrap-select {
margin-bottom: 0;
}
.form-group-lg .bootstrap-select.form-control,
.form-group-sm .bootstrap-select.form-control {
padding: 0;
}
.form-group-lg .bootstrap-select.form-control .dropdown-toggle,
.form-group-sm .bootstrap-select.form-control .dropdown-toggle {
height: 100%;
font-size: inherit;
line-height: inherit;
border-radius: inherit;
}
.bootstrap-select.form-control-sm .dropdown-toggle,
.bootstrap-select.form-control-lg .dropdown-toggle {
font-size: inherit;
line-height: inherit;
border-radius: inherit;
}
.bootstrap-select.form-control-sm .dropdown-toggle {
padding: 0.25rem 0.5rem;
}
.bootstrap-select.form-control-lg .dropdown-toggle {
padding: 0.5rem 1rem;
}
.form-inline .bootstrap-select .form-control {
width: 100%;
}
.bootstrap-select.disabled,
.bootstrap-select > .disabled {
cursor: not-allowed;
}
.bootstrap-select.disabled:focus,
.bootstrap-select > .disabled:focus {
outline: none !important;
}
.bootstrap-select.bs-container {
position: absolute;
top: 0;
left: 0;
height: 0 !important;
padding: 0 !important;
}
.bootstrap-select.bs-container .dropdown-menu {
z-index: 1060;
}
.bootstrap-select .dropdown-toggle .filter-option {
position: static;
top: 0;
left: 0;
float: left;
height: 100%;
width: 100%;
text-align: left;
overflow: hidden;
-webkit-box-flex: 0;
-webkit-flex: 0 1 auto;
-ms-flex: 0 1 auto;
flex: 0 1 auto;
}
.bs3.bootstrap-select .dropdown-toggle .filter-option {
padding-right: inherit;
}
.input-group .bs3-has-addon.bootstrap-select .dropdown-toggle .filter-option {
position: absolute;
padding-top: inherit;
padding-bottom: inherit;
padding-left: inherit;
float: none;
}
.input-group .bs3-has-addon.bootstrap-select .dropdown-toggle .filter-option .filter-option-inner {
padding-right: inherit;
}
.bootstrap-select .dropdown-toggle .filter-option-inner-inner {
overflow: hidden;
}
.bootstrap-select .dropdown-toggle .filter-expand {
width: 0 !important;
float: left;
opacity: 0 !important;
overflow: hidden;
}
.bootstrap-select .dropdown-toggle .caret {
position: absolute;
top: 50%;
right: 12px;
margin-top: -2px;
vertical-align: middle;
}
.input-group .bootstrap-select.form-control .dropdown-toggle {
border-radius: inherit;
}
.bootstrap-select[class*="col-"] .dropdown-toggle {
width: 100%;
}
.bootstrap-select .dropdown-menu {
min-width: 100%;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.bootstrap-select .dropdown-menu > .inner:focus {
outline: none !important;
}
.bootstrap-select .dropdown-menu.inner {
position: static;
float: none;
border: 0;
padding: 0;
margin: 0;
border-radius: 0;
-webkit-box-shadow: none;
box-shadow: none;
}
.bootstrap-select .dropdown-menu li {
position: relative;
}
.bootstrap-select .dropdown-menu li.active small {
color: rgba(255, 255, 255, 0.5) !important;
}
.bootstrap-select .dropdown-menu li.disabled a {
cursor: not-allowed;
}
.bootstrap-select .dropdown-menu li a {
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.bootstrap-select .dropdown-menu li a.opt {
position: relative;
padding-left: 2.25em;
}
.bootstrap-select .dropdown-menu li a span.check-mark {
display: none;
}
.bootstrap-select .dropdown-menu li a span.text {
display: inline-block;
}
.bootstrap-select .dropdown-menu li small {
padding-left: 0.5em;
}
.bootstrap-select .dropdown-menu .notify {
position: absolute;
bottom: 5px;
width: 96%;
margin: 0 2%;
min-height: 26px;
padding: 3px 5px;
background: #f5f5f5;
border: 1px solid #e3e3e3;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
pointer-events: none;
opacity: 0.9;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.bootstrap-select .dropdown-menu .notify.fadeOut {
-webkit-animation: 300ms linear 750ms forwards bs-notify-fadeOut;
-o-animation: 300ms linear 750ms forwards bs-notify-fadeOut;
animation: 300ms linear 750ms forwards bs-notify-fadeOut;
}
.bootstrap-select .no-results {
padding: 3px;
background: #f5f5f5;
margin: 0 5px;
white-space: nowrap;
}
.bootstrap-select.fit-width .dropdown-toggle .filter-option {
position: static;
display: inline;
padding: 0;
}
.bootstrap-select.fit-width .dropdown-toggle .filter-option-inner,
.bootstrap-select.fit-width .dropdown-toggle .filter-option-inner-inner {
display: inline;
}
.bootstrap-select.fit-width .dropdown-toggle .bs-caret:before {
content: '\00a0';
}
.bootstrap-select.fit-width .dropdown-toggle .caret {
position: static;
top: auto;
margin-top: -1px;
}
.bootstrap-select.show-tick .dropdown-menu .selected span.check-mark {
position: absolute;
display: inline-block;
right: 15px;
top: 5px;
}
.bootstrap-select.show-tick .dropdown-menu li a span.text {
margin-right: 34px;
}
.bootstrap-select .bs-ok-default:after {
content: '';
display: block;
width: 0.5em;
height: 1em;
border-style: solid;
border-width: 0 0.26em 0.26em 0;
-webkit-transform-style: preserve-3d;
transform-style: preserve-3d;
-webkit-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
}
.bootstrap-select.show-menu-arrow.open > .dropdown-toggle,
.bootstrap-select.show-menu-arrow.show > .dropdown-toggle {
z-index: 1061;
}
.bootstrap-select.show-menu-arrow .dropdown-toggle .filter-option:before {
content: '';
border-left: 7px solid transparent;
border-right: 7px solid transparent;
border-bottom: 7px solid rgba(204, 204, 204, 0.2);
position: absolute;
bottom: -4px;
left: 9px;
display: none;
}
.bootstrap-select.show-menu-arrow .dropdown-toggle .filter-option:after {
content: '';
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-bottom: 6px solid white;
position: absolute;
bottom: -4px;
left: 10px;
display: none;
}
.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle .filter-option:before {
bottom: auto;
top: -4px;
border-top: 7px solid rgba(204, 204, 204, 0.2);
border-bottom: 0;
}
.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle .filter-option:after {
bottom: auto;
top: -4px;
border-top: 6px solid white;
border-bottom: 0;
}
.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle .filter-option:before {
right: 12px;
left: auto;
}
.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle .filter-option:after {
right: 13px;
left: auto;
}
.bootstrap-select.show-menu-arrow.open > .dropdown-toggle .filter-option:before,
.bootstrap-select.show-menu-arrow.show > .dropdown-toggle .filter-option:before,
.bootstrap-select.show-menu-arrow.open > .dropdown-toggle .filter-option:after,
.bootstrap-select.show-menu-arrow.show > .dropdown-toggle .filter-option:after {
display: block;
}
.bs-searchbox,
.bs-actionsbox,
.bs-donebutton {
padding: 4px 8px;
}
.bs-actionsbox {
width: 100%;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.bs-actionsbox .btn-group button {
width: 50%;
}
.bs-donebutton {
float: left;
width: 100%;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.bs-donebutton .btn-group button {
width: 100%;
}
.bs-searchbox + .bs-actionsbox {
padding: 0 8px 4px;
}
.bs-searchbox .form-control {
margin-bottom: 0;
width: 100%;
float: none;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,95 @@
/**
* @author: Alec Fenichel
* @webSite: https://fenichelar.com
* @update: zhixin wen <wenzhixin2010@gmail.com>
*/
var Utils = $.fn.bootstrapTable.utils
$.extend($.fn.bootstrapTable.defaults, {
autoRefresh: false,
showAutoRefresh: true,
autoRefreshInterval: 60,
autoRefreshSilent: true,
autoRefreshStatus: true,
autoRefreshFunction: null
})
$.extend($.fn.bootstrapTable.defaults.icons, {
autoRefresh: {
bootstrap3: 'glyphicon-time icon-time',
bootstrap5: 'bi-clock',
materialize: 'access_time',
'bootstrap-table': 'icon-clock'
}[$.fn.bootstrapTable.theme] || 'fa-clock'
})
$.extend($.fn.bootstrapTable.locales, {
formatAutoRefresh () {
return 'Auto Refresh'
}
})
$.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales)
$.BootstrapTable = class extends $.BootstrapTable {
init (...args) {
super.init(...args)
if (this.options.autoRefresh && this.options.autoRefreshStatus) {
this.setupRefreshInterval()
}
}
initToolbar (...args) {
if (this.options.autoRefresh) {
this.buttons = Object.assign(this.buttons, {
autoRefresh: {
html: `
<button class="auto-refresh ${this.constants.buttonsClass}
${this.options.autoRefreshStatus ? ` ${this.constants.classes.buttonActive}` : ''}"
type="button" name="autoRefresh" title="${this.options.formatAutoRefresh()}">
${this.options.showButtonIcons ? Utils.sprintf(this.constants.html.icon, this.options.iconsPrefix, this.options.icons.autoRefresh) : ''}
${this.options.showButtonText ? this.options.formatAutoRefresh() : ''}
</button>
`,
event: this.toggleAutoRefresh
}
})
}
super.initToolbar(...args)
}
toggleAutoRefresh () {
if (this.options.autoRefresh) {
if (this.options.autoRefreshStatus) {
clearInterval(this.options.autoRefreshFunction)
this.$toolbar.find('>.columns .auto-refresh')
.removeClass(this.constants.classes.buttonActive)
} else {
this.setupRefreshInterval()
this.$toolbar.find('>.columns .auto-refresh')
.addClass(this.constants.classes.buttonActive)
}
this.options.autoRefreshStatus = !this.options.autoRefreshStatus
}
}
destroy () {
if (this.options.autoRefresh && this.options.autoRefreshStatus) {
clearInterval(this.options.autoRefreshFunction)
}
super.destroy()
}
setupRefreshInterval () {
this.options.autoRefreshFunction = setInterval(() => {
if (!this.options.autoRefresh || !this.options.autoRefreshStatus) {
return
}
this.refresh({ silent: this.options.autoRefreshSilent })
}, this.options.autoRefreshInterval * 1000)
}
}

View File

@ -0,0 +1,606 @@
/**
* @author: Dennis Hernández
* @update zhixin wen <wenzhixin2010@gmail.com>
*/
var Utils = $.fn.bootstrapTable.utils
var UtilsCookie = {
cookieIds: {
sortOrder: 'bs.table.sortOrder',
sortName: 'bs.table.sortName',
sortPriority: 'bs.table.sortPriority',
pageNumber: 'bs.table.pageNumber',
pageList: 'bs.table.pageList',
hiddenColumns: 'bs.table.hiddenColumns',
cardView: 'bs.table.cardView',
customView: 'bs.table.customView',
searchText: 'bs.table.searchText',
reorderColumns: 'bs.table.reorderColumns',
filterControl: 'bs.table.filterControl',
filterBy: 'bs.table.filterBy'
},
getCurrentHeader (that) {
return that.options.height ? that.$tableHeader : that.$header
},
getCurrentSearchControls (that) {
return that.options.height ? 'table select, table input' : 'select, input'
},
isCookieSupportedByBrowser () {
return navigator.cookieEnabled
},
isCookieEnabled (that, cookieName) {
return that.options.cookiesEnabled.includes(cookieName)
},
setCookie (that, cookieName, cookieValue) {
if (
!that.options.cookie ||
!UtilsCookie.isCookieEnabled(that, cookieName)
) {
return
}
return that._storage.setItem(`${that.options.cookieIdTable}.${cookieName}`, cookieValue)
},
getCookie (that, cookieName) {
if (
!cookieName ||
!UtilsCookie.isCookieEnabled(that, cookieName)
) {
return null
}
return that._storage.getItem(`${that.options.cookieIdTable}.${cookieName}`)
},
deleteCookie (that, cookieName) {
return that._storage.removeItem(`${that.options.cookieIdTable}.${cookieName}`)
},
calculateExpiration (cookieExpire) {
const time = cookieExpire.replace(/[0-9]*/, '') // s,mi,h,d,m,y
cookieExpire = cookieExpire.replace(/[A-Za-z]{1,2}/, '') // number
switch (time.toLowerCase()) {
case 's':
cookieExpire = +cookieExpire
break
case 'mi':
cookieExpire *= 60
break
case 'h':
cookieExpire = cookieExpire * 60 * 60
break
case 'd':
cookieExpire = cookieExpire * 24 * 60 * 60
break
case 'm':
cookieExpire = cookieExpire * 30 * 24 * 60 * 60
break
case 'y':
cookieExpire = cookieExpire * 365 * 24 * 60 * 60
break
default:
cookieExpire = undefined
break
}
if (!cookieExpire) {
return ''
}
const d = new Date()
d.setTime(d.getTime() + cookieExpire * 1000)
return d.toGMTString()
},
initCookieFilters (that) {
setTimeout(() => {
const parsedCookieFilters = JSON.parse(
UtilsCookie.getCookie(that, UtilsCookie.cookieIds.filterControl))
if (!that._filterControlValuesLoaded && parsedCookieFilters) {
const cachedFilters = {}
const header = UtilsCookie.getCurrentHeader(that)
const searchControls = UtilsCookie.getCurrentSearchControls(that)
const applyCookieFilters = (element, filteredCookies) => {
filteredCookies.forEach(cookie => {
const value = element.value.toString()
const text = cookie.text
if (
text === '' ||
element.type === 'radio' &&
value !== text
) {
return
}
if (
element.tagName === 'INPUT' &&
element.type === 'radio' &&
value === text
) {
element.checked = true
cachedFilters[cookie.field] = text
} else if (element.tagName === 'INPUT') {
element.value = text
cachedFilters[cookie.field] = text
} else if (
element.tagName === 'SELECT' &&
that.options.filterControlContainer
) {
element.value = text
cachedFilters[cookie.field] = text
} else if (text !== '' && element.tagName === 'SELECT') {
cachedFilters[cookie.field] = text
for (const currentElement of element) {
if (currentElement.value === text) {
currentElement.selected = true
return
}
}
const option = document.createElement('option')
option.value = text
option.text = text
element.add(option, element[1])
element.selectedIndex = 1
}
})
}
let filterContainer = header
if (that.options.filterControlContainer) {
filterContainer = $(`${that.options.filterControlContainer}`)
}
filterContainer.find(searchControls).each(function () {
const field = $(this).closest('[data-field]').data('field')
const filteredCookies = parsedCookieFilters.filter(cookie => cookie.field === field)
applyCookieFilters(this, filteredCookies)
})
that.initColumnSearch(cachedFilters)
that._filterControlValuesLoaded = true
that.initServer()
}
}, 250)
}
}
Object.assign($.fn.bootstrapTable.defaults, {
cookie: false,
cookieExpire: '2h',
cookiePath: null,
cookieDomain: null,
cookieSecure: null,
cookieSameSite: 'Lax',
cookieIdTable: '',
cookiesEnabled: [
'bs.table.sortOrder', 'bs.table.sortName', 'bs.table.sortPriority',
'bs.table.pageNumber', 'bs.table.pageList',
'bs.table.hiddenColumns', 'bs.table.searchText',
'bs.table.filterControl', 'bs.table.filterBy',
'bs.table.reorderColumns', 'bs.table.cardView', 'bs.table.customView'
],
cookieStorage: 'cookieStorage', // localStorage, sessionStorage, customStorage
cookieCustomStorageGet: null,
cookieCustomStorageSet: null,
cookieCustomStorageDelete: null,
// internal variable
_filterControls: [],
_filterControlValuesLoaded: false,
_storage: {
setItem: undefined,
getItem: undefined,
removeItem: undefined
}
})
$.fn.bootstrapTable.methods.push('getCookies')
$.fn.bootstrapTable.methods.push('deleteCookie')
Object.assign($.fn.bootstrapTable.utils, {
setCookie: UtilsCookie.setCookie,
getCookie: UtilsCookie.getCookie
})
$.BootstrapTable = class extends $.BootstrapTable {
init () {
if (this.options.cookie) {
if (
this.options.cookieStorage === 'cookieStorage' &&
!UtilsCookie.isCookieSupportedByBrowser()
) {
throw new Error('Cookies are not enabled in this browser.')
}
this.configureStorage()
// FilterBy logic
const filterByCookieValue = UtilsCookie.getCookie(this, UtilsCookie.cookieIds.filterBy)
if (typeof filterByCookieValue === 'boolean' && !filterByCookieValue) {
throw new Error('The cookie value of filterBy must be a json!')
}
let filterByCookie = {}
try {
filterByCookie = JSON.parse(filterByCookieValue)
} catch (e) {
throw new Error('Could not parse the json of the filterBy cookie!')
}
this.filterColumns = filterByCookie ? filterByCookie : {}
// FilterControl logic
this._filterControls = []
this._filterControlValuesLoaded = false
this.options.cookiesEnabled = typeof this.options.cookiesEnabled === 'string' ?
this.options.cookiesEnabled.replace('[', '').replace(']', '')
.replace(/'/g, '').replace(/ /g, '').split(',') :
this.options.cookiesEnabled
if (this.options.filterControl) {
const that = this
this.$el.on('column-search.bs.table', (e, field, text) => {
let isNewField = true
for (let i = 0; i < that._filterControls.length; i++) {
if (that._filterControls[i].field === field) {
that._filterControls[i].text = text
isNewField = false
break
}
}
if (isNewField) {
that._filterControls.push({
field,
text
})
}
UtilsCookie.setCookie(that, UtilsCookie.cookieIds.filterControl, JSON.stringify(that._filterControls))
}).on('created-controls.bs.table', UtilsCookie.initCookieFilters(that))
}
}
super.init()
}
initServer (...args) {
if (
this.options.cookie &&
this.options.filterControl &&
!this._filterControlValuesLoaded
) {
const cookie = JSON.parse(UtilsCookie.getCookie(this, UtilsCookie.cookieIds.filterControl))
if (cookie) {
return
}
}
super.initServer(...args)
}
initTable (...args) {
super.initTable(...args)
this.initCookie()
}
onSort (...args) {
super.onSort(...args)
if (!this.options.cookie) {
return
}
if (this.options.sortName === undefined || this.options.sortOrder === undefined) {
UtilsCookie.deleteCookie(this, UtilsCookie.cookieIds.sortName)
UtilsCookie.deleteCookie(this, UtilsCookie.cookieIds.sortOrder)
} else {
this.options.sortPriority = null
UtilsCookie.deleteCookie(this, UtilsCookie.cookieIds.sortPriority)
UtilsCookie.setCookie(this, UtilsCookie.cookieIds.sortOrder, this.options.sortOrder)
UtilsCookie.setCookie(this, UtilsCookie.cookieIds.sortName, this.options.sortName)
}
}
onMultipleSort (...args) {
super.onMultipleSort(...args)
if (!this.options.cookie) {
return
}
if (this.options.sortPriority === undefined) {
UtilsCookie.deleteCookie(this, UtilsCookie.cookieIds.sortPriority)
} else {
this.options.sortName = undefined
this.options.sortOrder = undefined
UtilsCookie.deleteCookie(this, UtilsCookie.cookieIds.sortName)
UtilsCookie.deleteCookie(this, UtilsCookie.cookieIds.sortOrder)
UtilsCookie.setCookie(this, UtilsCookie.cookieIds.sortPriority, JSON.stringify(this.options.sortPriority))
}
}
onPageNumber (...args) {
super.onPageNumber(...args)
if (!this.options.cookie) {
return
}
UtilsCookie.setCookie(this, UtilsCookie.cookieIds.pageNumber, this.options.pageNumber)
}
onPageListChange (...args) {
super.onPageListChange(...args)
if (!this.options.cookie) {
return
}
UtilsCookie.setCookie(this, UtilsCookie.cookieIds.pageList,
this.options.pageSize === this.options.formatAllRows() ? 'all' : this.options.pageSize)
UtilsCookie.setCookie(this, UtilsCookie.cookieIds.pageNumber, this.options.pageNumber)
}
onPagePre (...args) {
super.onPagePre(...args)
if (!this.options.cookie) {
return
}
UtilsCookie.setCookie(this, UtilsCookie.cookieIds.pageNumber, this.options.pageNumber)
}
onPageNext (...args) {
super.onPageNext(...args)
if (!this.options.cookie) {
return
}
UtilsCookie.setCookie(this, UtilsCookie.cookieIds.pageNumber, this.options.pageNumber)
}
_toggleColumn (...args) {
super._toggleColumn(...args)
if (!this.options.cookie) {
return
}
UtilsCookie.setCookie(this, UtilsCookie.cookieIds.hiddenColumns, JSON.stringify(this.getHiddenColumns().map(column => column.field)))
}
_toggleAllColumns (...args) {
super._toggleAllColumns(...args)
if (!this.options.cookie) {
return
}
UtilsCookie.setCookie(this, UtilsCookie.cookieIds.hiddenColumns, JSON.stringify(this.getHiddenColumns().map(column => column.field)))
}
toggleView () {
super.toggleView()
UtilsCookie.setCookie(this, UtilsCookie.cookieIds.cardView, this.options.cardView)
}
toggleCustomView () {
super.toggleCustomView()
UtilsCookie.setCookie(this, UtilsCookie.cookieIds.customView, this.customViewDefaultView)
}
selectPage (page) {
super.selectPage(page)
if (!this.options.cookie) {
return
}
UtilsCookie.setCookie(this, UtilsCookie.cookieIds.pageNumber, page)
}
onSearch (event) {
super.onSearch(event, arguments.length > 1 ? arguments[1] : true)
if (!this.options.cookie) {
return
}
if (this.options.search) {
UtilsCookie.setCookie(this, UtilsCookie.cookieIds.searchText, this.searchText)
}
UtilsCookie.setCookie(this, UtilsCookie.cookieIds.pageNumber, this.options.pageNumber)
}
initHeader (...args) {
if (this.options.reorderableColumns && this.options.cookie) {
this.columnsSortOrder = JSON.parse(UtilsCookie.getCookie(this, UtilsCookie.cookieIds.reorderColumns))
}
super.initHeader(...args)
}
persistReorderColumnsState (that) {
UtilsCookie.setCookie(that, UtilsCookie.cookieIds.reorderColumns, JSON.stringify(that.columnsSortOrder))
}
filterBy (...args) {
super.filterBy(...args)
if (!this.options.cookie) {
return
}
UtilsCookie.setCookie(this, UtilsCookie.cookieIds.filterBy, JSON.stringify(this.filterColumns))
}
initCookie () {
if (!this.options.cookie) {
return
}
if (this.options.cookieIdTable === '' || this.options.cookieExpire === '') {
console.error('Configuration error. Please review the cookieIdTable and the cookieExpire property. If the properties are correct, then this browser does not support cookies.')
this.options.cookie = false // Make sure that the cookie extension is disabled
return
}
const sortOrderCookie = UtilsCookie.getCookie(this, UtilsCookie.cookieIds.sortOrder)
const sortOrderNameCookie = UtilsCookie.getCookie(this, UtilsCookie.cookieIds.sortName)
let sortPriorityCookie = UtilsCookie.getCookie(this, UtilsCookie.cookieIds.sortPriority)
const pageNumberCookie = UtilsCookie.getCookie(this, UtilsCookie.cookieIds.pageNumber)
const pageListCookie = UtilsCookie.getCookie(this, UtilsCookie.cookieIds.pageList)
const searchTextCookie = UtilsCookie.getCookie(this, UtilsCookie.cookieIds.searchText)
const cardViewCookie = UtilsCookie.getCookie(this, UtilsCookie.cookieIds.cardView)
const customViewCookie = UtilsCookie.getCookie(this, UtilsCookie.cookieIds.customView)
const hiddenColumnsCookieValue = UtilsCookie.getCookie(this, UtilsCookie.cookieIds.hiddenColumns)
let hiddenColumnsCookie = {}
try {
hiddenColumnsCookie = JSON.parse(hiddenColumnsCookieValue)
} catch (e) {
throw new Error('Could not parse the json of the hidden columns cookie!', hiddenColumnsCookieValue)
}
try {
sortPriorityCookie = JSON.parse(sortPriorityCookie)
} catch (e) {
throw new Error('Could not parse the json of the sortPriority cookie!', sortPriorityCookie)
}
if (!sortPriorityCookie) {
// sortOrder
this.options.sortOrder = sortOrderCookie ? sortOrderCookie : this.options.sortOrder
// sortName
this.options.sortName = sortOrderNameCookie ? sortOrderNameCookie : this.options.sortName
} else {
this.options.sortOrder = undefined
this.options.sortName = undefined
}
// sortPriority
this.options.sortPriority = sortPriorityCookie ? sortPriorityCookie : this.options.sortPriority
if (this.options.sortOrder || this.options.sortName) {
// sortPriority
this.options.sortPriority = null
}
// pageNumber
this.options.pageNumber = pageNumberCookie ? +pageNumberCookie : this.options.pageNumber
// pageSize
this.options.pageSize = pageListCookie ? pageListCookie === 'all' ?
this.options.formatAllRows() : +pageListCookie : this.options.pageSize
// searchText
if (UtilsCookie.isCookieEnabled(this, UtilsCookie.cookieIds.searchText) && this.options.searchText === '') {
this.options.searchText = searchTextCookie ? searchTextCookie : ''
}
// cardView
if (cardViewCookie !== null) {
this.options.cardView = cardViewCookie === 'true' ? cardViewCookie : false
}
this.customViewDefaultView = customViewCookie === 'true'
if (hiddenColumnsCookie) {
for (const column of this.columns) {
if (!column.switchable) {
continue
}
column.visible = this.isSelectionColumn(column) ||
!hiddenColumnsCookie.includes(column.field)
}
}
}
getCookies () {
const bootstrapTable = this
const cookies = {}
for (const [key, value] of Object.entries(UtilsCookie.cookieIds)) {
cookies[key] = UtilsCookie.getCookie(bootstrapTable, value)
if (key === 'columns' || key === 'hiddenColumns' || key === 'sortPriority') {
cookies[key] = JSON.parse(cookies[key])
}
}
return cookies
}
deleteCookie (cookieName) {
if (!cookieName) {
return
}
UtilsCookie.deleteCookie(this, UtilsCookie.cookieIds[cookieName])
}
configureStorage () {
const that = this
this._storage = {}
switch (this.options.cookieStorage) {
case 'cookieStorage':
this._storage.setItem = function (cookieName, cookieValue) {
document.cookie = [
cookieName, '=', encodeURIComponent(cookieValue),
`; expires=${UtilsCookie.calculateExpiration(that.options.cookieExpire)}`,
that.options.cookiePath ? `; path=${that.options.cookiePath}` : '',
that.options.cookieDomain ? `; domain=${that.options.cookieDomain}` : '',
that.options.cookieSecure ? '; secure' : '',
`;SameSite=${that.options.cookieSameSite}`
].join('')
}
this._storage.getItem = function (cookieName) {
const value = `; ${document.cookie}`
const parts = value.split(`; ${cookieName}=`)
return parts.length === 2 ? decodeURIComponent(parts.pop().split(';').shift()) : null
}
this._storage.removeItem = function (cookieName) {
document.cookie = [
encodeURIComponent(cookieName), '=',
'; expires=Thu, 01 Jan 1970 00:00:00 GMT',
that.options.cookiePath ? `; path=${that.options.cookiePath}` : '',
that.options.cookieDomain ? `; domain=${that.options.cookieDomain}` : '',
`;SameSite=${that.options.cookieSameSite}`
].join('')
}
break
case 'localStorage':
this._storage.setItem = function (cookieName, cookieValue) {
localStorage.setItem(cookieName, cookieValue)
}
this._storage.getItem = function (cookieName) {
return localStorage.getItem(cookieName)
}
this._storage.removeItem = function (cookieName) {
localStorage.removeItem(cookieName)
}
break
case 'sessionStorage':
this._storage.setItem = function (cookieName, cookieValue) {
sessionStorage.setItem(cookieName, cookieValue)
}
this._storage.getItem = function (cookieName) {
return sessionStorage.getItem(cookieName)
}
this._storage.removeItem = function (cookieName) {
sessionStorage.removeItem(cookieName)
}
break
case 'customStorage':
if (
!this.options.cookieCustomStorageSet ||
!this.options.cookieCustomStorageGet ||
!this.options.cookieCustomStorageDelete
) {
throw new Error('The following options must be set while using the customStorage: cookieCustomStorageSet, cookieCustomStorageGet and cookieCustomStorageDelete')
}
this._storage.setItem = function (cookieName, cookieValue) {
Utils.calculateObjectValue(that.options, that.options.cookieCustomStorageSet, [cookieName, cookieValue], '')
}
this._storage.getItem = function (cookieName) {
return Utils.calculateObjectValue(that.options, that.options.cookieCustomStorageGet, [cookieName], '')
}
this._storage.removeItem = function (cookieName) {
Utils.calculateObjectValue(that.options, that.options.cookieCustomStorageDelete, [cookieName], '')
}
break
default:
throw new Error('Storage method not supported.')
}
}
}

View File

@ -0,0 +1,135 @@
/**
* @author: Dustin Utecht
* @github: https://github.com/UtechtDustin
*/
var Utils = $.fn.bootstrapTable.utils
Object.assign($.fn.bootstrapTable.defaults, {
customView: false,
showCustomView: false,
customViewDefaultView: false
})
Object.assign($.fn.bootstrapTable.defaults.icons, {
customViewOn: {
bootstrap3: 'glyphicon glyphicon-list',
bootstrap5: 'bi-list',
bootstrap4: 'fa fa-list',
semantic: 'fa fa-list',
foundation: 'fa fa-list',
bulma: 'fa fa-list',
materialize: 'list'
}[$.fn.bootstrapTable.theme] || 'fa-list',
customViewOff: {
bootstrap3: 'glyphicon glyphicon-eye-open',
bootstrap5: 'bi-grid',
bootstrap4: 'fa fa-th',
semantic: 'fa fa-th',
foundation: 'fa fa-th',
bulma: 'fa fa-th',
materialize: 'grid_on'
}[$.fn.bootstrapTable.theme] || 'fa-th'
})
Object.assign($.fn.bootstrapTable.defaults, {
onCustomViewPostBody () {
return false
},
onCustomViewPreBody () {
return false
},
onToggleCustomView () {
return false
}
})
Object.assign($.fn.bootstrapTable.locales, {
formatToggleCustomViewOn () {
return 'Show custom view'
},
formatToggleCustomViewOff () {
return 'Hide custom view'
}
})
Object.assign($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales)
$.fn.bootstrapTable.methods.push('toggleCustomView')
Object.assign($.fn.bootstrapTable.events, {
'custom-view-post-body.bs.table': 'onCustomViewPostBody',
'custom-view-pre-body.bs.table': 'onCustomViewPreBody',
'toggle-custom-view.bs.table': 'onToggleCustomView'
})
$.BootstrapTable = class extends $.BootstrapTable {
init () {
this.customViewDefaultView = this.options.customViewDefaultView
super.init()
}
initToolbar (...args) {
if (this.options.customView && this.options.showCustomView) {
this.buttons = Object.assign(this.buttons, {
customView: {
text: this.options.customViewDefaultView ? this.options.formatToggleCustomViewOff() : this.options.formatToggleCustomViewOn(),
icon: this.options.customViewDefaultView ? this.options.icons.customViewOn : this.options.icons.customViewOff,
event: this.toggleCustomView,
attributes: {
'aria-label': this.options.customViewDefaultView ? this.options.formatToggleCustomViewOff() : this.options.formatToggleCustomViewOn(),
title: this.options.customViewDefaultView ? this.options.formatToggleCustomViewOff() : this.options.formatToggleCustomViewOn()
}
}
})
}
super.initToolbar(...args)
}
initBody () {
super.initBody()
if (!this.options.customView) {
return
}
const $table = this.$el
const $customViewContainer = this.$container.find('.fixed-table-custom-view')
$table.hide()
$customViewContainer.hide()
if (!this.options.customView || !this.customViewDefaultView) {
$table.show()
return
}
const data = this.getData().slice(this.pageFrom - 1, this.pageTo)
const value = Utils.calculateObjectValue(this, this.options.customView, [data], '')
this.trigger('custom-view-pre-body', data, value)
if ($customViewContainer.length === 1) {
$customViewContainer.show().html(value)
} else {
this.$tableBody.after(`<div class="fixed-table-custom-view">${value}</div>`)
}
this.trigger('custom-view-post-body', data, value)
}
toggleCustomView () {
this.customViewDefaultView = !this.customViewDefaultView
const icon = this.options.showButtonIcons ? this.customViewDefaultView ? this.options.icons.customViewOn : this.options.icons.customViewOff : ''
const text = this.options.showButtonText ? this.customViewDefaultView ? this.options.formatToggleCustomViewOff() : this.options.formatToggleCustomViewOn() : ''
this.$toolbar.find('button[name="customView"]')
.html(`${Utils.sprintf(this.constants.html.icon, this.options.iconsPrefix, icon)} ${text}`)
.attr('aria-label', text)
.attr('title', text)
this.initBody()
this.trigger('toggle-custom-view', this.customViewDefaultView)
}
}

View File

@ -0,0 +1,674 @@
/*! X-editable - v1.5.3
* In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery
* http://github.com/vitalets/x-editable
* Copyright (c) 2019 Vitaliy Potapov; Licensed MIT */
.editableform {
margin-bottom: 0; /* overwrites bootstrap margin */
}
.editableform .control-group {
margin-bottom: 0; /* overwrites bootstrap margin */
white-space: nowrap; /* prevent wrapping buttons on new line */
line-height: 20px; /* overwriting bootstrap line-height. See #133 */
}
/*
BS3 fix: stop css from breaking when the form is inside a popup and inside a form with the class .form-horizontal
See: https://github.com/vitalets/x-editable/issues/682
*/
.form-horizontal .editable-popup .editableform .form-group {
margin-left:0;
margin-right:0;
}
/*
BS3 width:1005 for inputs breaks editable form in popup
See: https://github.com/vitalets/x-editable/issues/393
*/
.editableform .form-control {
width: auto;
}
.editable-buttons {
display: inline-block; /* should be inline to take effect of parent's white-space: nowrap */
vertical-align: top;
margin-left: 7px;
/* inline-block emulation for IE7*/
zoom: 1;
*display: inline;
}
.editable-buttons.editable-buttons-bottom {
display: block;
margin-top: 7px;
margin-left: 0;
}
.editable-input {
vertical-align: top;
display: inline-block; /* should be inline to take effect of parent's white-space: nowrap */
width: auto; /* bootstrap-responsive has width: 100% that breakes layout */
white-space: normal; /* reset white-space decalred in parent*/
/* display-inline emulation for IE7*/
zoom: 1;
*display: inline;
}
.editable-buttons .editable-cancel {
margin-left: 7px;
}
/*for jquery-ui buttons need set height to look more pretty*/
.editable-buttons button.ui-button-icon-only {
height: 24px;
width: 30px;
}
.editableform-loading {
background: url('loading.gif') center center no-repeat;
height: 25px;
width: auto;
min-width: 25px;
}
.editable-inline .editableform-loading {
background-position: left 5px;
}
.editable-error-block {
max-width: 300px;
margin: 5px 0 0 0;
width: auto;
white-space: normal;
}
/*add padding for jquery ui*/
.editable-error-block.ui-state-error {
padding: 3px;
}
.editable-error {
color: red;
}
/* ---- For specific types ---- */
.editableform .editable-date {
padding: 0;
margin: 0;
float: left;
}
/* move datepicker icon to center of add-on button. See https://github.com/vitalets/x-editable/issues/183 */
.editable-inline .add-on .icon-th {
margin-top: 3px;
margin-left: 1px;
}
/* checklist vertical alignment */
.editable-checklist label input[type="checkbox"],
.editable-checklist label span {
vertical-align: middle;
margin: 0;
}
.editable-checklist label {
white-space: nowrap;
}
/* set exact width of textarea to fit buttons toolbar */
.editable-wysihtml5 {
width: 566px;
height: 250px;
}
/* clear button shown as link in date inputs */
.editable-clear {
clear: both;
font-size: 0.9em;
text-decoration: none;
text-align: right;
}
/* IOS-style clear button for text inputs */
.editable-clear-x {
background: url('clear.png') center center no-repeat;
display: block;
width: 13px;
height: 13px;
position: absolute;
opacity: 0.6;
z-index: 100;
top: 50%;
right: 6px;
margin-top: -6px;
}
.editable-clear-x:hover {
opacity: 1;
}
.editable-pre-wrapped {
white-space: pre-wrap;
}
.editable-container.editable-popup {
max-width: none !important; /* without this rule poshytip/tooltip does not stretch */
}
.editable-container.popover {
width: auto; /* without this rule popover does not stretch */
}
.editable-container.editable-inline {
display: inline-block;
vertical-align: middle;
width: auto;
/* inline-block emulation for IE7*/
zoom: 1;
*display: inline;
}
.editable-container.ui-widget {
font-size: inherit; /* jqueryui widget font 1.1em too big, overwrite it */
z-index: 9990; /* should be less than select2 dropdown z-index to close dropdown first when click */
}
.editable-click,
a.editable-click,
a.editable-click:hover {
text-decoration: none;
border-bottom: dashed 1px #0088cc;
}
.editable-click.editable-disabled,
a.editable-click.editable-disabled,
a.editable-click.editable-disabled:hover {
color: #585858;
cursor: default;
border-bottom: none;
}
.editable-empty, .editable-empty:hover, .editable-empty:focus{
font-style: italic;
color: #DD1144;
/* border-bottom: none; */
text-decoration: none;
}
.editable-unsaved {
font-weight: bold;
}
.editable-unsaved:after {
/* content: '*'*/
}
.editable-bg-transition {
-webkit-transition: background-color 1400ms ease-out;
-moz-transition: background-color 1400ms ease-out;
-o-transition: background-color 1400ms ease-out;
-ms-transition: background-color 1400ms ease-out;
transition: background-color 1400ms ease-out;
}
/*see https://github.com/vitalets/x-editable/issues/139 */
.form-horizontal .editable
{
padding-top: 5px;
display:inline-block;
}
/*!
* Datepicker for Bootstrap
*
* Copyright 2012 Stefan Petre
* Improvements by Andrew Rowls
* Licensed under the Apache License v2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
*/
.datepicker {
padding: 4px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
direction: ltr;
/*.dow {
border-top: 1px solid #ddd !important;
}*/
}
.datepicker-inline {
width: 220px;
}
.datepicker.datepicker-rtl {
direction: rtl;
}
.datepicker.datepicker-rtl table tr td span {
float: right;
}
.datepicker-dropdown {
top: 0;
left: 0;
}
.datepicker-dropdown:before {
content: '';
display: inline-block;
border-left: 7px solid transparent;
border-right: 7px solid transparent;
border-bottom: 7px solid #ccc;
border-bottom-color: rgba(0, 0, 0, 0.2);
position: absolute;
top: -7px;
left: 6px;
}
.datepicker-dropdown:after {
content: '';
display: inline-block;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-bottom: 6px solid #ffffff;
position: absolute;
top: -6px;
left: 7px;
}
.datepicker > div {
display: none;
}
.datepicker.days div.datepicker-days {
display: block;
}
.datepicker.months div.datepicker-months {
display: block;
}
.datepicker.years div.datepicker-years {
display: block;
}
.datepicker table {
margin: 0;
}
.datepicker td,
.datepicker th {
text-align: center;
width: 20px;
height: 20px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
border: none;
}
.table-striped .datepicker table tr td,
.table-striped .datepicker table tr th {
background-color: transparent;
}
.datepicker table tr td.day:hover {
background: #eeeeee;
cursor: pointer;
}
.datepicker table tr td.old,
.datepicker table tr td.new {
color: #999999;
}
.datepicker table tr td.disabled,
.datepicker table tr td.disabled:hover {
background: none;
color: #999999;
cursor: default;
}
.datepicker table tr td.today,
.datepicker table tr td.today:hover,
.datepicker table tr td.today.disabled,
.datepicker table tr td.today.disabled:hover {
background-color: #fde19a;
background-image: -moz-linear-gradient(top, #fdd49a, #fdf59a);
background-image: -ms-linear-gradient(top, #fdd49a, #fdf59a);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fdd49a), to(#fdf59a));
background-image: -webkit-linear-gradient(top, #fdd49a, #fdf59a);
background-image: -o-linear-gradient(top, #fdd49a, #fdf59a);
background-image: linear-gradient(top, #fdd49a, #fdf59a);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fdd49a', endColorstr='#fdf59a', GradientType=0);
border-color: #fdf59a #fdf59a #fbed50;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
color: #000;
}
.datepicker table tr td.today:hover,
.datepicker table tr td.today:hover:hover,
.datepicker table tr td.today.disabled:hover,
.datepicker table tr td.today.disabled:hover:hover,
.datepicker table tr td.today:active,
.datepicker table tr td.today:hover:active,
.datepicker table tr td.today.disabled:active,
.datepicker table tr td.today.disabled:hover:active,
.datepicker table tr td.today.active,
.datepicker table tr td.today:hover.active,
.datepicker table tr td.today.disabled.active,
.datepicker table tr td.today.disabled:hover.active,
.datepicker table tr td.today.disabled,
.datepicker table tr td.today:hover.disabled,
.datepicker table tr td.today.disabled.disabled,
.datepicker table tr td.today.disabled:hover.disabled,
.datepicker table tr td.today[disabled],
.datepicker table tr td.today:hover[disabled],
.datepicker table tr td.today.disabled[disabled],
.datepicker table tr td.today.disabled:hover[disabled] {
background-color: #fdf59a;
}
.datepicker table tr td.today:active,
.datepicker table tr td.today:hover:active,
.datepicker table tr td.today.disabled:active,
.datepicker table tr td.today.disabled:hover:active,
.datepicker table tr td.today.active,
.datepicker table tr td.today:hover.active,
.datepicker table tr td.today.disabled.active,
.datepicker table tr td.today.disabled:hover.active {
background-color: #fbf069 \9;
}
.datepicker table tr td.today:hover:hover {
color: #000;
}
.datepicker table tr td.today.active:hover {
color: #fff;
}
.datepicker table tr td.range,
.datepicker table tr td.range:hover,
.datepicker table tr td.range.disabled,
.datepicker table tr td.range.disabled:hover {
background: #eeeeee;
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0;
}
.datepicker table tr td.range.today,
.datepicker table tr td.range.today:hover,
.datepicker table tr td.range.today.disabled,
.datepicker table tr td.range.today.disabled:hover {
background-color: #f3d17a;
background-image: -moz-linear-gradient(top, #f3c17a, #f3e97a);
background-image: -ms-linear-gradient(top, #f3c17a, #f3e97a);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f3c17a), to(#f3e97a));
background-image: -webkit-linear-gradient(top, #f3c17a, #f3e97a);
background-image: -o-linear-gradient(top, #f3c17a, #f3e97a);
background-image: linear-gradient(top, #f3c17a, #f3e97a);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f3c17a', endColorstr='#f3e97a', GradientType=0);
border-color: #f3e97a #f3e97a #edde34;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0;
}
.datepicker table tr td.range.today:hover,
.datepicker table tr td.range.today:hover:hover,
.datepicker table tr td.range.today.disabled:hover,
.datepicker table tr td.range.today.disabled:hover:hover,
.datepicker table tr td.range.today:active,
.datepicker table tr td.range.today:hover:active,
.datepicker table tr td.range.today.disabled:active,
.datepicker table tr td.range.today.disabled:hover:active,
.datepicker table tr td.range.today.active,
.datepicker table tr td.range.today:hover.active,
.datepicker table tr td.range.today.disabled.active,
.datepicker table tr td.range.today.disabled:hover.active,
.datepicker table tr td.range.today.disabled,
.datepicker table tr td.range.today:hover.disabled,
.datepicker table tr td.range.today.disabled.disabled,
.datepicker table tr td.range.today.disabled:hover.disabled,
.datepicker table tr td.range.today[disabled],
.datepicker table tr td.range.today:hover[disabled],
.datepicker table tr td.range.today.disabled[disabled],
.datepicker table tr td.range.today.disabled:hover[disabled] {
background-color: #f3e97a;
}
.datepicker table tr td.range.today:active,
.datepicker table tr td.range.today:hover:active,
.datepicker table tr td.range.today.disabled:active,
.datepicker table tr td.range.today.disabled:hover:active,
.datepicker table tr td.range.today.active,
.datepicker table tr td.range.today:hover.active,
.datepicker table tr td.range.today.disabled.active,
.datepicker table tr td.range.today.disabled:hover.active {
background-color: #efe24b \9;
}
.datepicker table tr td.selected,
.datepicker table tr td.selected:hover,
.datepicker table tr td.selected.disabled,
.datepicker table tr td.selected.disabled:hover {
background-color: #9e9e9e;
background-image: -moz-linear-gradient(top, #b3b3b3, #808080);
background-image: -ms-linear-gradient(top, #b3b3b3, #808080);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#b3b3b3), to(#808080));
background-image: -webkit-linear-gradient(top, #b3b3b3, #808080);
background-image: -o-linear-gradient(top, #b3b3b3, #808080);
background-image: linear-gradient(top, #b3b3b3, #808080);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#b3b3b3', endColorstr='#808080', GradientType=0);
border-color: #808080 #808080 #595959;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
color: #fff;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
.datepicker table tr td.selected:hover,
.datepicker table tr td.selected:hover:hover,
.datepicker table tr td.selected.disabled:hover,
.datepicker table tr td.selected.disabled:hover:hover,
.datepicker table tr td.selected:active,
.datepicker table tr td.selected:hover:active,
.datepicker table tr td.selected.disabled:active,
.datepicker table tr td.selected.disabled:hover:active,
.datepicker table tr td.selected.active,
.datepicker table tr td.selected:hover.active,
.datepicker table tr td.selected.disabled.active,
.datepicker table tr td.selected.disabled:hover.active,
.datepicker table tr td.selected.disabled,
.datepicker table tr td.selected:hover.disabled,
.datepicker table tr td.selected.disabled.disabled,
.datepicker table tr td.selected.disabled:hover.disabled,
.datepicker table tr td.selected[disabled],
.datepicker table tr td.selected:hover[disabled],
.datepicker table tr td.selected.disabled[disabled],
.datepicker table tr td.selected.disabled:hover[disabled] {
background-color: #808080;
}
.datepicker table tr td.selected:active,
.datepicker table tr td.selected:hover:active,
.datepicker table tr td.selected.disabled:active,
.datepicker table tr td.selected.disabled:hover:active,
.datepicker table tr td.selected.active,
.datepicker table tr td.selected:hover.active,
.datepicker table tr td.selected.disabled.active,
.datepicker table tr td.selected.disabled:hover.active {
background-color: #666666 \9;
}
.datepicker table tr td.active,
.datepicker table tr td.active:hover,
.datepicker table tr td.active.disabled,
.datepicker table tr td.active.disabled:hover {
background-color: #006dcc;
background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
background-image: -ms-linear-gradient(top, #0088cc, #0044cc);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
background-image: -o-linear-gradient(top, #0088cc, #0044cc);
background-image: linear-gradient(top, #0088cc, #0044cc);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);
border-color: #0044cc #0044cc #002a80;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
color: #fff;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
.datepicker table tr td.active:hover,
.datepicker table tr td.active:hover:hover,
.datepicker table tr td.active.disabled:hover,
.datepicker table tr td.active.disabled:hover:hover,
.datepicker table tr td.active:active,
.datepicker table tr td.active:hover:active,
.datepicker table tr td.active.disabled:active,
.datepicker table tr td.active.disabled:hover:active,
.datepicker table tr td.active.active,
.datepicker table tr td.active:hover.active,
.datepicker table tr td.active.disabled.active,
.datepicker table tr td.active.disabled:hover.active,
.datepicker table tr td.active.disabled,
.datepicker table tr td.active:hover.disabled,
.datepicker table tr td.active.disabled.disabled,
.datepicker table tr td.active.disabled:hover.disabled,
.datepicker table tr td.active[disabled],
.datepicker table tr td.active:hover[disabled],
.datepicker table tr td.active.disabled[disabled],
.datepicker table tr td.active.disabled:hover[disabled] {
background-color: #0044cc;
}
.datepicker table tr td.active:active,
.datepicker table tr td.active:hover:active,
.datepicker table tr td.active.disabled:active,
.datepicker table tr td.active.disabled:hover:active,
.datepicker table tr td.active.active,
.datepicker table tr td.active:hover.active,
.datepicker table tr td.active.disabled.active,
.datepicker table tr td.active.disabled:hover.active {
background-color: #003399 \9;
}
.datepicker table tr td span {
display: block;
width: 23%;
height: 54px;
line-height: 54px;
float: left;
margin: 1%;
cursor: pointer;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
}
.datepicker table tr td span:hover {
background: #eeeeee;
}
.datepicker table tr td span.disabled,
.datepicker table tr td span.disabled:hover {
background: none;
color: #999999;
cursor: default;
}
.datepicker table tr td span.active,
.datepicker table tr td span.active:hover,
.datepicker table tr td span.active.disabled,
.datepicker table tr td span.active.disabled:hover {
background-color: #006dcc;
background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
background-image: -ms-linear-gradient(top, #0088cc, #0044cc);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
background-image: -o-linear-gradient(top, #0088cc, #0044cc);
background-image: linear-gradient(top, #0088cc, #0044cc);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);
border-color: #0044cc #0044cc #002a80;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
color: #fff;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
.datepicker table tr td span.active:hover,
.datepicker table tr td span.active:hover:hover,
.datepicker table tr td span.active.disabled:hover,
.datepicker table tr td span.active.disabled:hover:hover,
.datepicker table tr td span.active:active,
.datepicker table tr td span.active:hover:active,
.datepicker table tr td span.active.disabled:active,
.datepicker table tr td span.active.disabled:hover:active,
.datepicker table tr td span.active.active,
.datepicker table tr td span.active:hover.active,
.datepicker table tr td span.active.disabled.active,
.datepicker table tr td span.active.disabled:hover.active,
.datepicker table tr td span.active.disabled,
.datepicker table tr td span.active:hover.disabled,
.datepicker table tr td span.active.disabled.disabled,
.datepicker table tr td span.active.disabled:hover.disabled,
.datepicker table tr td span.active[disabled],
.datepicker table tr td span.active:hover[disabled],
.datepicker table tr td span.active.disabled[disabled],
.datepicker table tr td span.active.disabled:hover[disabled] {
background-color: #0044cc;
}
.datepicker table tr td span.active:active,
.datepicker table tr td span.active:hover:active,
.datepicker table tr td span.active.disabled:active,
.datepicker table tr td span.active.disabled:hover:active,
.datepicker table tr td span.active.active,
.datepicker table tr td span.active:hover.active,
.datepicker table tr td span.active.disabled.active,
.datepicker table tr td span.active.disabled:hover.active {
background-color: #003399 \9;
}
.datepicker table tr td span.old,
.datepicker table tr td span.new {
color: #999999;
}
.datepicker th.datepicker-switch {
width: 145px;
}
.datepicker thead tr:first-child th,
.datepicker tfoot tr th {
cursor: pointer;
}
.datepicker thead tr:first-child th:hover,
.datepicker tfoot tr th:hover {
background: #eeeeee;
}
.datepicker .cw {
font-size: 10px;
width: 12px;
padding: 0 2px 0 5px;
vertical-align: middle;
}
.datepicker thead tr:first-child th.cw {
cursor: default;
background-color: transparent;
}
.input-append.date .add-on i,
.input-prepend.date .add-on i {
display: block;
cursor: pointer;
width: 16px;
height: 16px;
}
.input-daterange input {
text-align: center;
}
.input-daterange input:first-child {
-webkit-border-radius: 3px 0 0 3px;
-moz-border-radius: 3px 0 0 3px;
border-radius: 3px 0 0 3px;
}
.input-daterange input:last-child {
-webkit-border-radius: 0 3px 3px 0;
-moz-border-radius: 0 3px 3px 0;
border-radius: 0 3px 3px 0;
}
.input-daterange .add-on {
display: inline-block;
width: auto;
min-width: 16px;
height: 18px;
padding: 4px 5px;
font-weight: normal;
line-height: 18px;
text-align: center;
text-shadow: 0 1px 0 #ffffff;
vertical-align: middle;
background-color: #eeeeee;
border: 1px solid #ccc;
margin-left: -5px;
margin-right: -5px;
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,189 @@
/* eslint-disable no-unused-vars */
/**
* @author zhixin wen <wenzhixin2010@gmail.com>
* extensions: https://github.com/vitalets/x-editable
*/
var Utils = $.fn.bootstrapTable.utils
$.extend($.fn.bootstrapTable.defaults, {
editable: true,
onEditableInit () {
return false
},
onEditableSave (field, row, rowIndex, oldValue, $el) {
return false
},
onEditableShown (field, row, $el, editable) {
return false
},
onEditableHidden (field, row, $el, reason) {
return false
}
})
$.extend($.fn.bootstrapTable.columnDefaults, {
alwaysUseFormatter: false
})
$.extend($.fn.bootstrapTable.events, {
'editable-init.bs.table': 'onEditableInit',
'editable-save.bs.table': 'onEditableSave',
'editable-shown.bs.table': 'onEditableShown',
'editable-hidden.bs.table': 'onEditableHidden'
})
$.BootstrapTable = class extends $.BootstrapTable {
initTable () {
super.initTable()
if (!this.options.editable) {
return
}
this.editedCells = []
$.each(this.columns, (i, column) => {
if (!column.editable) {
return
}
const editableOptions = {}
const editableDataMarkup = []
const editableDataPrefix = 'editable-'
const processDataOptions = (key, value) => {
// Replace camel case with dashes.
const dashKey = key.replace(/([A-Z])/g, $1 => `-${$1.toLowerCase()}`)
if (dashKey.indexOf(editableDataPrefix) === 0) {
editableOptions[dashKey.replace(editableDataPrefix, 'data-')] = value
}
}
$.each(this.options, processDataOptions)
column.formatter = column.formatter || (value => value)
column._formatter = column._formatter ? column._formatter : column.formatter
column.formatter = (value, row, index, field) => {
let result = Utils.calculateObjectValue(column, column._formatter, [value, row, index], value)
result = typeof result === 'undefined' || result === null ? this.options.undefinedText : result
if (this.options.uniqueId !== undefined && !column.alwaysUseFormatter) {
const uniqueId = Utils.getItemField(row, this.options.uniqueId, false)
if ($.inArray(column.field + uniqueId, this.editedCells) !== -1) {
result = value
}
}
$.each(column, processDataOptions)
$.each(editableOptions, (key, value) => {
editableDataMarkup.push(` ${key}="${value}"`)
})
let noEditFormatter = false
const editableOpts = Utils.calculateObjectValue(column,
column.editable, [index, row], {})
if (editableOpts.hasOwnProperty('noEditFormatter')) {
noEditFormatter = editableOpts.noEditFormatter(value, row, index, field)
}
if (noEditFormatter === false) {
return `<a href="javascript:void(0)"
data-name="${column.field}"
data-pk="${row[this.options.idField]}"
data-value="${result}"
${editableDataMarkup.join('')}></a>`
}
return noEditFormatter
}
})
}
initBody (fixedScroll) {
super.initBody(fixedScroll)
if (!this.options.editable) {
return
}
$.each(this.columns, (i, column) => {
if (!column.editable) {
return
}
const data = this.getData({ escape: true })
const $field = this.$body.find(`a[data-name="${column.field}"]`)
$field.each((i, element) => {
const $element = $(element)
const $tr = $element.closest('tr')
const index = $tr.data('index')
const row = data[index]
const editableOpts = Utils.calculateObjectValue(column,
column.editable, [index, row, $element], {})
$element.editable(editableOpts)
})
$field.off('save').on('save', ({ currentTarget }, { submitValue }) => {
const $this = $(currentTarget)
const data = this.getData()
const rowIndex = $this.parents('tr[data-index]').data('index')
const row = data[rowIndex]
const oldValue = row[column.field]
if (this.options.uniqueId !== undefined && !column.alwaysUseFormatter) {
const uniqueId = Utils.getItemField(row, this.options.uniqueId, false)
if ($.inArray(column.field + uniqueId, this.editedCells) === -1) {
this.editedCells.push(column.field + uniqueId)
}
}
submitValue = Utils.escapeHTML(submitValue)
$this.data('value', submitValue)
row[column.field] = submitValue
this.trigger('editable-save', column.field, row, rowIndex, oldValue, $this)
this.initBody()
})
$field.off('shown').on('shown', ({ currentTarget }, editable) => {
const $this = $(currentTarget)
const data = this.getData()
const rowIndex = $this.parents('tr[data-index]').data('index')
const row = data[rowIndex]
this.trigger('editable-shown', column.field, row, $this, editable)
})
$field.off('hidden').on('hidden', ({ currentTarget }, reason) => {
const $this = $(currentTarget)
const data = this.getData()
const rowIndex = $this.parents('tr[data-index]').data('index')
const row = data[rowIndex]
this.trigger('editable-hidden', column.field, row, $this, reason)
})
})
this.trigger('editable-init')
}
getData (params) {
const data = super.getData(params)
if (params && params.escape) {
for (const row of data) {
for (const [key, value] of Object.entries(row)) {
if (typeof(value) !== "number") {
row[key] = Utils.unescapeHTML(value)
}
}
}
}
return data
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -0,0 +1,335 @@
/**
* @author zhixin wen <wenzhixin2010@gmail.com>
* extensions: https://github.com/hhurz/tableExport.jquery.plugin
*/
var Utils = $.fn.bootstrapTable.utils
const TYPE_NAME = {
json: 'JSON',
xml: 'XML',
png: 'PNG',
csv: 'CSV',
txt: 'TXT',
sql: 'SQL',
doc: 'MS-Word',
excel: 'MS-Excel',
xlsx: 'MS-Excel (OpenXML)',
powerpoint: 'MS-Powerpoint',
pdf: 'PDF'
}
Object.assign($.fn.bootstrapTable.defaults, {
showExport: false,
exportDataType: 'basic', // basic, all, selected
exportTypes: ['json', 'xml', 'csv', 'txt', 'sql', 'excel'],
exportOptions: {},
exportFooter: false
})
Object.assign($.fn.bootstrapTable.columnDefaults, {
forceExport: false,
forceHide: false
})
Object.assign($.fn.bootstrapTable.defaults.icons, {
export: {
bootstrap3: 'glyphicon-export icon-share',
bootstrap5: 'bi-download',
materialize: 'file_download',
'bootstrap-table': 'icon-download'
}[$.fn.bootstrapTable.theme] || 'fa-download'
})
Object.assign($.fn.bootstrapTable.locales, {
formatExport () {
return 'Export data'
}
})
Object.assign($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales)
$.fn.bootstrapTable.methods.push('exportTable')
Object.assign($.fn.bootstrapTable.defaults, {
// eslint-disable-next-line no-unused-vars
onExportSaved (exportedRows) {
return false
},
onExportStarted () {
return false
}
})
Object.assign($.fn.bootstrapTable.events, {
'export-saved.bs.table': 'onExportSaved',
'export-started.bs.table': 'onExportStarted'
})
$.BootstrapTable = class extends $.BootstrapTable {
initToolbar (...args) {
const o = this.options
let exportTypes = o.exportTypes
this.showToolbar = this.showToolbar || o.showExport
if (this.options.showExport) {
if (typeof exportTypes === 'string') {
const types = exportTypes.slice(1, -1).replace(/ /g, '').split(',')
exportTypes = types.map(t => t.slice(1, -1))
}
if (typeof o.exportOptions === 'string') {
o.exportOptions = Utils.calculateObjectValue(null, o.exportOptions)
}
this.$export = this.$toolbar.find('>.columns div.export')
if (this.$export.length) {
this.updateExportButton()
return
}
this.buttons = Object.assign(this.buttons, {
export: {
html:
() => {
if (exportTypes.length === 1) {
return `
<div class="export ${this.constants.classes.buttonsDropdown}"
data-type="${exportTypes[0]}">
<button class="${this.constants.buttonsClass}"
aria-label="${o.formatExport()}"
type="button"
title="${o.formatExport()}">
${o.showButtonIcons ? Utils.sprintf(this.constants.html.icon, o.iconsPrefix, o.icons.export) : ''}
${o.showButtonText ? o.formatExport() : ''}
</button>
</div>
`
}
const html = []
html.push(`
<div class="export ${this.constants.classes.buttonsDropdown}">
<button class="${this.constants.buttonsClass} dropdown-toggle"
aria-label="${o.formatExport()}"
${this.constants.dataToggle}="dropdown"
type="button"
title="${o.formatExport()}">
${o.showButtonIcons ? Utils.sprintf(this.constants.html.icon, o.iconsPrefix, o.icons.export) : ''}
${o.showButtonText ? o.formatExport() : ''}
${this.constants.html.dropdownCaret}
</button>
${this.constants.html.toolbarDropdown[0]}
`)
for (const type of exportTypes) {
if (TYPE_NAME.hasOwnProperty(type)) {
const $item = $(Utils.sprintf(this.constants.html.pageDropdownItem, '', TYPE_NAME[type]))
$item.attr('data-type', type)
html.push($item.prop('outerHTML'))
}
}
html.push(this.constants.html.toolbarDropdown[1], '</div>')
return html.join('')
}
}
})
}
super.initToolbar(...args)
this.$export = this.$toolbar.find('>.columns div.export')
if (!this.options.showExport) {
return
}
this.updateExportButton()
let $exportButtons = this.$export.find('[data-type]')
if (exportTypes.length === 1) {
$exportButtons = this.$export
}
$exportButtons.click(e => {
e.preventDefault()
this.trigger('export-started')
this.exportTable({
type: $(e.currentTarget).data('type')
})
})
this.handleToolbar()
}
handleToolbar () {
if (!this.$export) {
return
}
if (super.handleToolbar) {
super.handleToolbar()
}
}
exportTable (options) {
const o = this.options
const stateField = this.header.stateField
const isCardView = o.cardView
const doExport = callback => {
if (stateField) {
this.hideColumn(stateField)
}
if (isCardView) {
this.toggleView()
}
this.columns.forEach(row => {
if (row.forceHide) {
this.hideColumn(row.field)
}
})
const data = this.getData()
if (o.detailView && o.detailViewIcon) {
const detailViewIndex = o.detailViewAlign === 'left' ? 0 : this.getVisibleFields().length + Utils.getDetailViewIndexOffset(this.options)
o.exportOptions.ignoreColumn = [detailViewIndex].concat(o.exportOptions.ignoreColumn || [])
}
if (o.exportFooter && o.height) {
const $footerRow = this.$tableFooter.find('tr').first()
const footerData = {}
const footerHtml = []
$.each($footerRow.children(), (index, footerCell) => {
const footerCellHtml = $(footerCell).children('.th-inner').first().html()
footerData[this.columns[index].field] = footerCellHtml === '&nbsp;' ? null : footerCellHtml
// grab footer cell text into cell index-based array
footerHtml.push(footerCellHtml)
})
this.$body.append(this.$body.children().last()[0].outerHTML)
const $lastTableRow = this.$body.children().last()
$.each($lastTableRow.children(), (index, lastTableRowCell) => {
$(lastTableRowCell).html(footerHtml[index])
})
}
const hiddenColumns = this.getHiddenColumns()
hiddenColumns.forEach(row => {
if (row.forceExport) {
this.showColumn(row.field)
}
})
if (typeof o.exportOptions.fileName === 'function') {
options.fileName = o.exportOptions.fileName()
}
this.$el.tableExport(Utils.extend({
onAfterSaveToFile: () => {
if (o.exportFooter) {
this.load(data)
}
if (stateField) {
this.showColumn(stateField)
}
if (isCardView) {
this.toggleView()
}
hiddenColumns.forEach(row => {
if (row.forceExport) {
this.hideColumn(row.field)
}
})
this.columns.forEach(row => {
if (row.forceHide) {
this.showColumn(row.field)
}
})
if (callback) callback()
}
}, o.exportOptions, options))
}
if (o.exportDataType === 'all' && o.pagination) {
const eventName = o.sidePagination === 'server' ?
'post-body.bs.table' : 'page-change.bs.table'
const virtualScroll = this.options.virtualScroll
this.$el.one(eventName, () => {
setTimeout(() => {
const data = this.getData()
doExport(() => {
this.options.virtualScroll = virtualScroll
this.togglePagination()
})
this.trigger('export-saved', data)
}, 0)
})
this.options.virtualScroll = false
this.togglePagination()
} else if (o.exportDataType === 'selected') {
let data = this.getData()
let selectedData = this.getSelections()
const pagination = o.pagination
if (!selectedData.length) {
return
}
if (o.sidePagination === 'server') {
data = {
total: o.totalRows,
[this.options.dataField]: data
}
selectedData = {
total: selectedData.length,
[this.options.dataField]: selectedData
}
}
this.load(selectedData)
if (pagination) {
this.togglePagination()
}
doExport(() => {
if (pagination) {
this.togglePagination()
}
this.load(data)
})
this.trigger('export-saved', selectedData)
} else {
doExport()
this.trigger('export-saved', this.getData(true))
}
}
updateSelected () {
super.updateSelected()
this.updateExportButton()
}
updateExportButton () {
if (this.options.exportDataType === 'selected') {
this.$export.find('> button')
.prop('disabled', !this.getSelections().length)
}
}
}

View File

@ -0,0 +1,92 @@
/*
tableExport.jquery.plugin
Version 1.10.24
Copyright (c) 2015-2021 hhurz, https://github.com/hhurz/tableExport.jquery.plugin
Based on https://github.com/kayalshri/tableExport.jquery.plugin
Licensed under the MIT License
*/
var $jscomp=$jscomp||{};$jscomp.scope={};$jscomp.findInternal=function(d,k,y){d instanceof String&&(d=String(d));for(var C=d.length,v=0;v<C;v++){var R=d[v];if(k.call(y,R,v,d))return{i:v,v:R}}return{i:-1,v:void 0}};$jscomp.ASSUME_ES5=!1;$jscomp.ASSUME_NO_NATIVE_MAP=!1;$jscomp.ASSUME_NO_NATIVE_SET=!1;$jscomp.defineProperty=$jscomp.ASSUME_ES5||"function"==typeof Object.defineProperties?Object.defineProperty:function(d,k,y){d!=Array.prototype&&d!=Object.prototype&&(d[k]=y.value)};
$jscomp.getGlobal=function(d){return"undefined"!=typeof window&&window===d?d:"undefined"!=typeof global&&null!=global?global:d};$jscomp.global=$jscomp.getGlobal(this);$jscomp.polyfill=function(d,k,y,C){if(k){y=$jscomp.global;d=d.split(".");for(C=0;C<d.length-1;C++){var v=d[C];v in y||(y[v]={});y=y[v]}d=d[d.length-1];C=y[d];k=k(C);k!=C&&null!=k&&$jscomp.defineProperty(y,d,{configurable:!0,writable:!0,value:k})}};
$jscomp.polyfill("Array.prototype.find",function(d){return d?d:function(d,y){return $jscomp.findInternal(this,d,y).v}},"es6","es3");
(function(d){d.fn.tableExport=function(k){function y(b){var c=[];v(b,"thead").each(function(){c.push.apply(c,v(d(this),a.theadSelector).toArray())});return c}function C(b){var c=[];v(b,"tbody").each(function(){c.push.apply(c,v(d(this),a.tbodySelector).toArray())});a.tfootSelector.length&&v(b,"tfoot").each(function(){c.push.apply(c,v(d(this),a.tfootSelector).toArray())});return c}function v(b,a){var c=b[0].tagName,q=b.parents(c).length;return b.find(a).filter(function(){return q===d(this).closest(c).parents(c).length})}
function R(b){var a=[],e=0,q=0,f=0;d(b).find("thead").first().find("th").each(function(b,c){b=void 0!==d(c).attr("data-field");"undefined"!==typeof c.parentNode.rowIndex&&q!==c.parentNode.rowIndex&&(q=c.parentNode.rowIndex,e=f=0);var h=J(c);for(e+=h?h:1;f<e;)a[f]=b?d(c).attr("data-field"):f.toString(),f++});return a}function I(b){var a="undefined"!==typeof b[0].rowIndex,e=!1===a&&"undefined"!==typeof b[0].cellIndex,q=e||a?Ja(b):b.is(":visible"),f=b.attr("data-tableexport-display");e&&"none"!==f&&
"always"!==f&&(b=d(b[0].parentNode),a="undefined"!==typeof b[0].rowIndex,f=b.attr("data-tableexport-display"));a&&"none"!==f&&"always"!==f&&(f=b.closest("table").attr("data-tableexport-display"));return"none"!==f&&(!0===q||"always"===f)}function Ja(b){var a=[];V&&(a=K.filter(function(){var a=!1;this.nodeType===b[0].nodeType&&("undefined"!==typeof this.rowIndex&&this.rowIndex===b[0].rowIndex?a=!0:"undefined"!==typeof this.cellIndex&&this.cellIndex===b[0].cellIndex&&"undefined"!==typeof this.parentNode.rowIndex&&
"undefined"!==typeof b[0].parentNode.rowIndex&&this.parentNode.rowIndex===b[0].parentNode.rowIndex&&(a=!0));return a}));return!1===V||0===a.length}function ta(b,c,e){var q=!1;I(b)?0<a.ignoreColumn.length&&(-1!==d.inArray(e,a.ignoreColumn)||-1!==d.inArray(e-c,a.ignoreColumn)||S.length>e&&"undefined"!==typeof S[e]&&-1!==d.inArray(S[e],a.ignoreColumn))&&(q=!0):q=!0;return q}function E(b,c,e,q,f){if("function"===typeof f){var h=!1;"function"===typeof a.onIgnoreRow&&(h=a.onIgnoreRow(d(b),e));if(!1===h&&
(0===a.ignoreRow.length||-1===d.inArray(e,a.ignoreRow)&&-1===d.inArray(e-q,a.ignoreRow))&&I(d(b))){b=v(d(b),c);var n=b.length,l=0,u=0;b.each(function(){var b=d(this),a=J(this),c=T(this),h;d.each(G,function(){if(e>this.s.r&&e<=this.e.r&&l>=this.s.c&&l<=this.e.c)for(h=0;h<=this.e.c-this.s.c;++h)n++,u++,f(null,e,l++)});if(c||a)a=a||1,G.push({s:{r:e,c:l},e:{r:e+(c||1)-1,c:l+a-1}});!1===ta(b,n,u++)&&f(this,e,l++);if(1<a)for(h=0;h<a-1;++h)u++,f(null,e,l++)});d.each(G,function(){if(e>=this.s.r&&e<=this.e.r&&
l>=this.s.c&&l<=this.e.c)for(ea=0;ea<=this.e.c-this.s.c;++ea)f(null,e,l++)})}}}function ua(b,a,e,d){if("undefined"!==typeof d.images&&(e=d.images[e],"undefined"!==typeof e)){a=a.getBoundingClientRect();var c=b.width/b.height,h=a.width/a.height,q=b.width,l=b.height,u=19.049976/25.4,g=0;h<=c?(l=Math.min(b.height,a.height),q=a.width*l/a.height):h>c&&(q=Math.min(b.width,a.width),l=a.height*q/a.width);q*=u;l*=u;l<b.height&&(g=(b.height-l)/2);try{d.doc.addImage(e.src,b.textPos.x,b.y+g,q,l)}catch(Pa){}b.textPos.x+=
q}}function va(b,c){if("string"===a.outputMode)return b.output();if("base64"===a.outputMode)return L(b.output());if("window"===a.outputMode)window.URL=window.URL||window.webkitURL,window.open(window.URL.createObjectURL(b.output("blob")));else try{var e=b.output("blob");saveAs(e,a.fileName+".pdf")}catch(q){ka(a.fileName+".pdf","data:application/pdf"+(c?"":";base64")+",",c?b.output("blob"):b.output())}}function wa(b,a,e){var c=0;"undefined"!==typeof e&&(c=e.colspan);if(0<=c){for(var f=b.width,d=b.textPos.x,
n=a.table.columns.indexOf(a.column),l=1;l<c;l++)f+=a.table.columns[n+l].width;1<c&&("right"===b.styles.halign?d=b.textPos.x+f-b.width:"center"===b.styles.halign&&(d=b.textPos.x+(f-b.width)/2));b.width=f;b.textPos.x=d;"undefined"!==typeof e&&1<e.rowspan&&(b.height*=e.rowspan);if("middle"===b.styles.valign||"bottom"===b.styles.valign)e=("string"===typeof b.text?b.text.split(/\r\n|\r|\n/g):b.text).length||1,2<e&&(b.textPos.y-=(2-1.15)/2*a.row.styles.fontSize*(e-2)/3);return!0}return!1}function xa(b,
a,e){"undefined"!==typeof b&&null!==b&&(b.hasAttribute("data-tableexport-canvas")?(a=(new Date).getTime(),d(b).attr("data-tableexport-canvas",a),e.images[a]={url:'[data-tableexport-canvas="'+a+'"]',src:null}):"undefined"!==a&&null!=a&&a.each(function(){if(d(this).is("img")){var a=ya(this.src);e.images[a]={url:this.src,src:this.src}}xa(b,d(this).children(),e)}))}function Ka(b,a){function c(b){if(b.url)if(b.src){var c=new Image;q=++f;c.crossOrigin="Anonymous";c.onerror=c.onload=function(){if(c.complete&&
(0===c.src.indexOf("data:image/")&&(c.width=b.width||c.width||0,c.height=b.height||c.height||0),c.width+c.height)){var e=document.createElement("canvas"),d=e.getContext("2d");e.width=c.width;e.height=c.height;d.drawImage(c,0,0);b.src=e.toDataURL("image/png")}--f||a(q)};c.src=b.url}else{var e=d(b.url);e.length&&(q=++f,html2canvas(e[0]).then(function(c){b.src=c.toDataURL("image/png");--f||a(q)}))}}var q=0,f=0;if("undefined"!==typeof b.images)for(var h in b.images)b.images.hasOwnProperty(h)&&c(b.images[h]);
(b=f)||(a(q),b=void 0);return b}function za(b,c,e){c.each(function(){if(d(this).is("div")){var c=fa(M(this,"background-color"),[255,255,255]),f=fa(M(this,"border-top-color"),[0,0,0]),h=ha(this,"border-top-width",a.jspdf.unit),n=this.getBoundingClientRect(),l=this.offsetLeft*e.wScaleFactor,u=this.offsetTop*e.hScaleFactor,g=n.width*e.wScaleFactor;n=n.height*e.hScaleFactor;e.doc.setDrawColor.apply(void 0,f);e.doc.setFillColor.apply(void 0,c);e.doc.setLineWidth(h);e.doc.rect(b.x+l,b.y+u,g,n,h?"FD":"F")}else d(this).is("img")&&
(c=ya(this.src),ua(b,this,c,e));za(b,d(this).children(),e)})}function Aa(b,c,e){if("function"===typeof e.onAutotableText)e.onAutotableText(e.doc,b,c);else{var q=b.textPos.x,f=b.textPos.y,h={halign:b.styles.halign,valign:b.styles.valign};if(c.length){for(c=c[0];c.previousSibling;)c=c.previousSibling;for(var n=!1,l=!1;c;){var u=c.innerText||c.textContent||"",g=u.length&&" "===u[0]?" ":"",k=1<u.length&&" "===u[u.length-1]?" ":"";!0!==a.preserve.leadingWS&&(u=g+la(u));!0!==a.preserve.trailingWS&&(u=ma(u)+
k);d(c).is("br")&&(q=b.textPos.x,f+=e.doc.internal.getFontSize());d(c).is("b")?n=!0:d(c).is("i")&&(l=!0);(n||l)&&e.doc.setFontType(n&&l?"bolditalic":n?"bold":"italic");if(g=e.doc.getStringUnitWidth(u)*e.doc.internal.getFontSize()){"linebreak"===b.styles.overflow&&q>b.textPos.x&&q+g>b.textPos.x+b.width&&(0<=".,!%*;:=-".indexOf(u.charAt(0))&&(k=u.charAt(0),g=e.doc.getStringUnitWidth(k)*e.doc.internal.getFontSize(),q+g<=b.textPos.x+b.width&&(e.doc.autoTableText(k,q,f,h),u=u.substring(1,u.length)),g=
e.doc.getStringUnitWidth(u)*e.doc.internal.getFontSize()),q=b.textPos.x,f+=e.doc.internal.getFontSize());if("visible"!==b.styles.overflow)for(;u.length&&q+g>b.textPos.x+b.width;)u=u.substring(0,u.length-1),g=e.doc.getStringUnitWidth(u)*e.doc.internal.getFontSize();e.doc.autoTableText(u,q,f,h);q+=g}if(n||l)d(c).is("b")?n=!1:d(c).is("i")&&(l=!1),e.doc.setFontType(n||l?n?"bold":"italic":"normal");c=c.nextSibling}b.textPos.x=q;b.textPos.y=f}else e.doc.autoTableText(b.text,b.textPos.x,b.textPos.y,h)}}
function W(b,a,e){return null==b?"":b.toString().replace(new RegExp(null==a?"":a.toString().replace(/([.*+?^=!:${}()|\[\]\/\\])/g,"\\$1"),"g"),e)}function la(b){return null==b?"":b.toString().replace(/^\s+/,"")}function ma(b){return null==b?"":b.toString().replace(/\s+$/,"")}function La(b){if(0===a.date.html.length)return!1;a.date.pattern.lastIndex=0;var c=a.date.pattern.exec(b);if(null==c)return!1;b=+c[a.date.match_y];if(0>b||8099<b)return!1;var e=1*c[a.date.match_m];c=1*c[a.date.match_d];if(!isFinite(c))return!1;
var d=new Date(b,e-1,c,0,0,0);return d.getFullYear()===b&&d.getMonth()===e-1&&d.getDate()===c?new Date(Date.UTC(b,e-1,c,0,0,0)):!1}function na(b){b=b||"0";""!==a.numbers.html.thousandsSeparator&&(b=W(b,a.numbers.html.thousandsSeparator,""));"."!==a.numbers.html.decimalMark&&(b=W(b,a.numbers.html.decimalMark,"."));return"number"===typeof b||!1!==jQuery.isNumeric(b)?b:!1}function Ma(b){-1<b.indexOf("%")?(b=na(b.replace(/%/g,"")),!1!==b&&(b/=100)):b=!1;return b}function D(b,c,e,q){var f="",h="text";
if(null!==b){var n=d(b);n.removeData("teUserDefText");if(n[0].hasAttribute("data-tableexport-canvas"))var l="";else if(n[0].hasAttribute("data-tableexport-value"))l=(l=n.attr("data-tableexport-value"))?l+"":"",n.data("teUserDefText",1);else if(l=n.html(),"function"===typeof a.onCellHtmlData)l=a.onCellHtmlData(n,c,e,l),n.data("teUserDefText",1);else if(""!==l){b=d.parseHTML(l);var g=0,k=0;l="";d.each(b,function(){if(d(this).is("input"))l+=n.find("input").eq(g++).val();else if(d(this).is("select"))l+=
n.find("select option:selected").eq(k++).text();else if(d(this).is("br"))l+="<br>";else{if("undefined"===typeof d(this).html())l+=d(this).text();else if(void 0===jQuery().bootstrapTable||!1===d(this).hasClass("fht-cell")&&!1===d(this).hasClass("filterControl")&&0===n.parents(".detail-view").length)l+=d(this).html();if(d(this).is("a")){var b=n.find("a").attr("href")||"";f="function"===typeof a.onCellHtmlHyperlink?f+a.onCellHtmlHyperlink(n,c,e,b,l):"href"===a.htmlHyperlink?f+b:f+l;l=""}}})}if(l&&""!==
l&&!0===a.htmlContent)f=d.trim(l);else if(l&&""!==l)if(""!==n.attr("data-tableexport-cellformat")){var m=l.replace(/\n/g,"\u2028").replace(/(<\s*br([^>]*)>)/gi,"\u2060"),p=d("<div/>").html(m).contents();b=!1;m="";d.each(p.text().split("\u2028"),function(b,c){0<b&&(m+=" ");!0!==a.preserve.leadingWS&&(c=la(c));m+=!0!==a.preserve.trailingWS?ma(c):c});d.each(m.split("\u2060"),function(b,c){0<b&&(f+="\n");!0!==a.preserve.leadingWS&&(c=la(c));!0!==a.preserve.trailingWS&&(c=ma(c));f+=c.replace(/\u00AD/g,
"")});f=f.replace(/\u00A0/g," ");if("json"===a.type||"excel"===a.type&&"xmlss"===a.mso.fileFormat||!1===a.numbers.output)b=na(f),!1!==b&&(h="number",f=Number(b));else if(a.numbers.html.decimalMark!==a.numbers.output.decimalMark||a.numbers.html.thousandsSeparator!==a.numbers.output.thousandsSeparator)if(b=na(f),!1!==b){p=(""+b.substr(0>b?1:0)).split(".");1===p.length&&(p[1]="");var t=3<p[0].length?p[0].length%3:0;h="number";f=(0>b?"-":"")+(a.numbers.output.thousandsSeparator?(t?p[0].substr(0,t)+a.numbers.output.thousandsSeparator:
"")+p[0].substr(t).replace(/(\d{3})(?=\d)/g,"$1"+a.numbers.output.thousandsSeparator):p[0])+(p[1].length?a.numbers.output.decimalMark+p[1]:"")}}else f=l;!0===a.escape&&(f=escape(f));"function"===typeof a.onCellData&&(f=a.onCellData(n,c,e,f,h),n.data("teUserDefText",1))}void 0!==q&&(q.type=h);return f}function Ba(b){return 0<b.length&&!0===a.preventInjection&&0<="=+-@".indexOf(b.charAt(0))?"'"+b:b}function Na(b,a,e){return a+"-"+e.toLowerCase()}function fa(b,a){(b=/^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/.exec(b))&&
(a=[parseInt(b[1]),parseInt(b[2]),parseInt(b[3])]);return a}function Ca(b){var a=M(b,"text-align"),e=M(b,"font-weight"),d=M(b,"font-style"),f="";"start"===a&&(a="rtl"===M(b,"direction")?"right":"left");700<=e&&(f="bold");"italic"===d&&(f+=d);""===f&&(f="normal");a={style:{align:a,bcolor:fa(M(b,"background-color"),[255,255,255]),color:fa(M(b,"color"),[0,0,0]),fstyle:f},colspan:J(b),rowspan:T(b)};null!==b&&(b=b.getBoundingClientRect(),a.rect={width:b.width,height:b.height});return a}function J(b){var a=
d(b).attr("data-tableexport-colspan");"undefined"===typeof a&&d(b).is("[colspan]")&&(a=d(b).attr("colspan"));return parseInt(a)||0}function T(b){var a=d(b).attr("data-tableexport-rowspan");"undefined"===typeof a&&d(b).is("[rowspan]")&&(a=d(b).attr("rowspan"));return parseInt(a)||0}function M(a,c){try{return window.getComputedStyle?(c=c.replace(/([a-z])([A-Z])/,Na),window.getComputedStyle(a,null).getPropertyValue(c)):a.currentStyle?a.currentStyle[c]:a.style[c]}catch(e){}return""}function ha(a,c,e){c=
M(a,c).match(/\d+/);if(null!==c){c=c[0];a=a.parentElement;var b=document.createElement("div");b.style.overflow="hidden";b.style.visibility="hidden";a.appendChild(b);b.style.width=100+e;e=100/b.offsetWidth;a.removeChild(b);return c*e}return 0}function Oa(a){for(var b=new ArrayBuffer(a.length),e=new Uint8Array(b),d=0;d!==a.length;++d)e[d]=a.charCodeAt(d)&255;return b}function oa(a){var b=a.c,e="";for(++b;b;b=Math.floor((b-1)/26))e=String.fromCharCode((b-1)%26+65)+e;return e+(""+(a.r+1))}function pa(a,
c){if("undefined"===typeof c||"number"===typeof c)return pa(a.s,a.e);"string"!==typeof a&&(a=oa(a));"string"!==typeof c&&(c=oa(c));return a===c?a:a+":"+c}function Da(a,c){var b=Number(a);if(isFinite(b))return b;var d=1;""!==c.thousandsSeparator&&(a=a.replace(new RegExp("([\\d])"+c.thousandsSeparator+"([\\d])","g"),"$1$2"));"."!==c.decimalMark&&(a=a.replace(new RegExp("([\\d])"+c.decimalMark+"([\\d])","g"),"$1.$2"));a=a.replace(/[$]/g,"").replace(/[%]/g,function(){d*=100;return""});if(isFinite(b=Number(a)))return b/
d;a=a.replace(/[(](.*)[)]/,function(a,b){d=-d;return b});return isFinite(b=Number(a))?b/d:b}function ya(a){var b=0,d;if(0===a.length)return b;var q=0;for(d=a.length;q<d;q++){var f=a.charCodeAt(q);b=(b<<5)-b+f;b|=0}return b}function N(b,c,d,q,f,h){var e=!0;"function"===typeof a.onBeforeSaveToFile&&(e=a.onBeforeSaveToFile(b,c,d,q,f),"boolean"!==typeof e&&(e=!0));if(e)try{if(Ea=new Blob([b],{type:d+";charset="+q}),saveAs(Ea,c,!1===h),"function"===typeof a.onAfterSaveToFile)a.onAfterSaveToFile(b,c)}catch(l){ka(c,
"data:"+d+(q.length?";charset="+q:"")+(f.length?";"+f:"")+",",h?"\ufeff"+b:b)}}function ka(b,c,d){var e=window.navigator.userAgent;if(!1!==b&&window.navigator.msSaveOrOpenBlob)window.navigator.msSaveOrOpenBlob(new Blob([d]),b);else if(!1!==b&&(0<e.indexOf("MSIE ")||e.match(/Trident.*rv\:11\./))){if(c=document.createElement("iframe")){document.body.appendChild(c);c.setAttribute("style","display:none");c.contentDocument.open("txt/plain","replace");c.contentDocument.write(d);c.contentDocument.close();
c.contentWindow.focus();switch(b.substr(b.lastIndexOf(".")+1)){case "doc":case "json":case "png":case "pdf":case "xls":case "xlsx":b+=".txt"}c.contentDocument.execCommand("SaveAs",!0,b);document.body.removeChild(c)}}else{var f=document.createElement("a");if(f){var h=null;f.style.display="none";!1!==b?f.download=b:f.target="_blank";"object"===typeof d?(window.URL=window.URL||window.webkitURL,e=[],e.push(d),h=window.URL.createObjectURL(new Blob(e,{type:c})),f.href=h):0<=c.toLowerCase().indexOf("base64,")?
f.href=c+L(d):f.href=c+encodeURIComponent(d);document.body.appendChild(f);if(document.createEvent)null===ia&&(ia=document.createEvent("MouseEvents")),ia.initEvent("click",!0,!1),f.dispatchEvent(ia);else if(document.createEventObject)f.fireEvent("onclick");else if("function"===typeof f.onclick)f.onclick();setTimeout(function(){h&&window.URL.revokeObjectURL(h);document.body.removeChild(f);if("function"===typeof a.onAfterSaveToFile)a.onAfterSaveToFile(d,b)},100)}}}function L(a){var b,d="",q=0;if("string"===
typeof a){a=a.replace(/\x0d\x0a/g,"\n");var f="";for(b=0;b<a.length;b++){var h=a.charCodeAt(b);128>h?f+=String.fromCharCode(h):(127<h&&2048>h?f+=String.fromCharCode(h>>6|192):(f+=String.fromCharCode(h>>12|224),f+=String.fromCharCode(h>>6&63|128)),f+=String.fromCharCode(h&63|128))}a=f}for(;q<a.length;){var n=a.charCodeAt(q++);f=a.charCodeAt(q++);b=a.charCodeAt(q++);h=n>>2;n=(n&3)<<4|f>>4;var l=(f&15)<<2|b>>6;var g=b&63;isNaN(f)?l=g=64:isNaN(b)&&(g=64);d=d+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(h)+
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(n)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(l)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(g)}return d}var a={csvEnclosure:'"',csvSeparator:",",csvUseBOM:!0,date:{html:"dd/mm/yyyy"},displayTableName:!1,escape:!1,exportHiddenCells:!1,fileName:"tableExport",htmlContent:!1,htmlHyperlink:"content",ignoreColumn:[],ignoreRow:[],jsonScope:"all",jspdf:{orientation:"p",
unit:"pt",format:"a4",margins:{left:20,right:10,top:10,bottom:10},onDocCreated:null,autotable:{styles:{cellPadding:2,rowHeight:12,fontSize:8,fillColor:255,textColor:50,fontStyle:"normal",overflow:"ellipsize",halign:"inherit",valign:"middle"},headerStyles:{fillColor:[52,73,94],textColor:255,fontStyle:"bold",halign:"inherit",valign:"middle"},alternateRowStyles:{fillColor:245},tableExport:{doc:null,onAfterAutotable:null,onBeforeAutotable:null,onAutotableText:null,onTable:null,outputImages:!0}}},mso:{fileFormat:"xlshtml",
onMsoNumberFormat:null,pageFormat:"a4",pageOrientation:"portrait",rtl:!1,styles:[],worksheetName:"",xslx:{formatId:{date:14,numbers:2}}},numbers:{html:{decimalMark:".",thousandsSeparator:","},output:{decimalMark:".",thousandsSeparator:","}},onAfterSaveToFile:null,onBeforeSaveToFile:null,onCellData:null,onCellHtmlData:null,onCellHtmlHyperlink:null,onIgnoreRow:null,onTableExportBegin:null,onTableExportEnd:null,outputMode:"file",pdfmake:{enabled:!1,docDefinition:{pageSize:"A4",pageOrientation:"portrait",
styles:{header:{background:"#34495E",color:"#FFFFFF",bold:!0,alignment:"center",fillColor:"#34495E"},alternateRow:{fillColor:"#f5f5f5"}},defaultStyle:{color:"#000000",fontSize:8,font:"Roboto"}},fonts:{}},preserve:{leadingWS:!1,trailingWS:!1},preventInjection:!0,sql:{tableEnclosure:"`",columnEnclosure:"`"},tbodySelector:"tr",tfootSelector:"tr",theadSelector:"tr",tableName:"Table",type:"csv"},O={a0:[2383.94,3370.39],a1:[1683.78,2383.94],a2:[1190.55,1683.78],a3:[841.89,1190.55],a4:[595.28,841.89],a5:[419.53,
595.28],a6:[297.64,419.53],a7:[209.76,297.64],a8:[147.4,209.76],a9:[104.88,147.4],a10:[73.7,104.88],b0:[2834.65,4008.19],b1:[2004.09,2834.65],b2:[1417.32,2004.09],b3:[1000.63,1417.32],b4:[708.66,1000.63],b5:[498.9,708.66],b6:[354.33,498.9],b7:[249.45,354.33],b8:[175.75,249.45],b9:[124.72,175.75],b10:[87.87,124.72],c0:[2599.37,3676.54],c1:[1836.85,2599.37],c2:[1298.27,1836.85],c3:[918.43,1298.27],c4:[649.13,918.43],c5:[459.21,649.13],c6:[323.15,459.21],c7:[229.61,323.15],c8:[161.57,229.61],c9:[113.39,
161.57],c10:[79.37,113.39],dl:[311.81,623.62],letter:[612,792],"government-letter":[576,756],legal:[612,1008],"junior-legal":[576,360],ledger:[1224,792],tabloid:[792,1224],"credit-card":[153,243]},B=this,ia=null,r=[],w=[],p=0,t="",S=[],G=[],Ea,K=[],V=!1;d.extend(!0,a,k);"xlsx"===a.type&&(a.mso.fileFormat=a.type,a.type="excel");"undefined"!==typeof a.excelFileFormat&&"undefined"===a.mso.fileFormat&&(a.mso.fileFormat=a.excelFileFormat);"undefined"!==typeof a.excelPageFormat&&"undefined"===a.mso.pageFormat&&
(a.mso.pageFormat=a.excelPageFormat);"undefined"!==typeof a.excelPageOrientation&&"undefined"===a.mso.pageOrientation&&(a.mso.pageOrientation=a.excelPageOrientation);"undefined"!==typeof a.excelRTL&&"undefined"===a.mso.rtl&&(a.mso.rtl=a.excelRTL);"undefined"!==typeof a.excelstyles&&"undefined"===a.mso.styles&&(a.mso.styles=a.excelstyles);"undefined"!==typeof a.onMsoNumberFormat&&"undefined"===a.mso.onMsoNumberFormat&&(a.mso.onMsoNumberFormat=a.onMsoNumberFormat);"undefined"!==typeof a.worksheetName&&
"undefined"===a.mso.worksheetName&&(a.mso.worksheetName=a.worksheetName);a.mso.pageOrientation="l"===a.mso.pageOrientation.substr(0,1)?"landscape":"portrait";a.date.html=a.date.html||"";if(a.date.html.length){k=[];k.dd="(3[01]|[12][0-9]|0?[1-9])";k.mm="(1[012]|0?[1-9])";k.yyyy="((?:1[6-9]|2[0-2])\\d{2})";k.yy="(\\d{2})";var z=a.date.html.match(/[^a-zA-Z0-9]/)[0];z=a.date.html.toLowerCase().split(z);a.date.regex="^\\s*";a.date.regex+=k[z[0]];a.date.regex+="(.)";a.date.regex+=k[z[1]];a.date.regex+=
"\\2";a.date.regex+=k[z[2]];a.date.regex+="\\s*$";a.date.pattern=new RegExp(a.date.regex,"g");k=z.indexOf("dd")+1;a.date.match_d=k+(1<k?1:0);k=z.indexOf("mm")+1;a.date.match_m=k+(1<k?1:0);k=(0<=z.indexOf("yyyy")?z.indexOf("yyyy"):z.indexOf("yy"))+1;a.date.match_y=k+(1<k?1:0)}S=R(B);if("function"===typeof a.onTableExportBegin)a.onTableExportBegin();if("csv"===a.type||"tsv"===a.type||"txt"===a.type){var P="",Z=0;G=[];p=0;var qa=function(b,c,e){b.each(function(){t="";E(this,c,p,e+b.length,function(b,
c,d){var e=t,f="";if(null!==b)if(b=D(b,c,d),c=null===b||""===b?"":b.toString(),"tsv"===a.type)b instanceof Date&&b.toLocaleString(),f=W(c,"\t"," ");else if(b instanceof Date)f=a.csvEnclosure+b.toLocaleString()+a.csvEnclosure;else if(f=Ba(c),f=W(f,a.csvEnclosure,a.csvEnclosure+a.csvEnclosure),0<=f.indexOf(a.csvSeparator)||/[\r\n ]/g.test(f))f=a.csvEnclosure+f+a.csvEnclosure;t=e+(f+("tsv"===a.type?"\t":a.csvSeparator))});t=d.trim(t).substring(0,t.length-1);0<t.length&&(0<P.length&&(P+="\n"),P+=t);p++});
return b.length};Z+=qa(d(B).find("thead").first().find(a.theadSelector),"th,td",Z);v(d(B),"tbody").each(function(){Z+=qa(v(d(this),a.tbodySelector),"td,th",Z)});a.tfootSelector.length&&qa(d(B).find("tfoot").first().find(a.tfootSelector),"td,th",Z);P+="\n";if("string"===a.outputMode)return P;if("base64"===a.outputMode)return L(P);if("window"===a.outputMode){ka(!1,"data:text/"+("csv"===a.type?"csv":"plain")+";charset=utf-8,",P);return}N(P,a.fileName+"."+a.type,"text/"+("csv"===a.type?"csv":"plain"),
"utf-8","","csv"===a.type&&a.csvUseBOM)}else if("sql"===a.type){p=0;G=[];var A="INSERT INTO "+a.sql.tableEnclosure+a.tableName+a.sql.tableEnclosure+" (";r=y(d(B));d(r).each(function(){E(this,"th,td",p,r.length,function(b,c,d){b=D(b,c,d)||"";-1<b.indexOf(a.sql.columnEnclosure)&&(b=W(b.toString(),a.sql.columnEnclosure,a.sql.columnEnclosure+a.sql.columnEnclosure));A+=a.sql.columnEnclosure+b+a.sql.columnEnclosure+","});p++;A=d.trim(A).substring(0,A.length-1)});A+=") VALUES ";w=C(d(B));d(w).each(function(){t=
"";E(this,"td,th",p,r.length+w.length,function(a,c,d){a=D(a,c,d)||"";-1<a.indexOf("'")&&(a=W(a.toString(),"'","''"));t+="'"+a+"',"});3<t.length&&(A+="("+t,A=d.trim(A).substring(0,A.length-1),A+="),");p++});A=d.trim(A).substring(0,A.length-1);A+=";";if("string"===a.outputMode)return A;if("base64"===a.outputMode)return L(A);N(A,a.fileName+".sql","application/sql","utf-8","",!1)}else if("json"===a.type){var X=[];G=[];r=y(d(B));d(r).each(function(){var a=[];E(this,"th,td",p,r.length,function(b,d,g){a.push(D(b,
d,g))});X.push(a)});var ra=[];w=C(d(B));d(w).each(function(){var a={},c=0;E(this,"td,th",p,r.length+w.length,function(b,d,f){X.length?a[X[X.length-1][c]]=D(b,d,f):a[c]=D(b,d,f);c++});!1===d.isEmptyObject(a)&&ra.push(a);p++});k="head"===a.jsonScope?JSON.stringify(X):"data"===a.jsonScope?JSON.stringify(ra):JSON.stringify({header:X,data:ra});if("string"===a.outputMode)return k;if("base64"===a.outputMode)return L(k);N(k,a.fileName+".json","application/json","utf-8","base64",!1)}else if("xml"===a.type){p=
0;G=[];var Q='<?xml version="1.0" encoding="utf-8"?>';Q+="<tabledata><fields>";r=y(d(B));d(r).each(function(){E(this,"th,td",p,r.length,function(a,d,e){Q+="<field>"+D(a,d,e)+"</field>"});p++});Q+="</fields><data>";var Fa=1;w=C(d(B));d(w).each(function(){var a=1;t="";E(this,"td,th",p,r.length+w.length,function(b,d,g){t+="<column-"+a+">"+D(b,d,g)+"</column-"+a+">";a++});0<t.length&&"<column-1></column-1>"!==t&&(Q+='<row id="'+Fa+'">'+t+"</row>",Fa++);p++});Q+="</data></tabledata>";if("string"===a.outputMode)return Q;
if("base64"===a.outputMode)return L(Q);N(Q,a.fileName+".xml","application/xml","utf-8","base64",!1)}else if("excel"===a.type&&"xmlss"===a.mso.fileFormat){var sa=[],F=[];d(B).filter(function(){return I(d(this))}).each(function(){function b(a,b,c){var f=[];d(a).each(function(){var b=0,e=0;t="";E(this,"td,th",p,c+a.length,function(a,c,h){if(null!==a){var l="";c=D(a,c,h);h="String";if(!1!==jQuery.isNumeric(c))h="Number";else{var n=Ma(c);!1!==n&&(c=n,h="Number",l+=' ss:StyleID="pct1"')}"Number"!==h&&(c=
c.replace(/\n/g,"<br>"));n=J(a);a=T(a);d.each(f,function(){if(p>=this.s.r&&p<=this.e.r&&e>=this.s.c&&e<=this.e.c)for(var a=0;a<=this.e.c-this.s.c;++a)e++,b++});if(a||n)a=a||1,n=n||1,f.push({s:{r:p,c:e},e:{r:p+a-1,c:e+n-1}});1<n&&(l+=' ss:MergeAcross="'+(n-1)+'"',e+=n-1);1<a&&(l+=' ss:MergeDown="'+(a-1)+'" ss:StyleID="rsp1"');0<b&&(l+=' ss:Index="'+(e+1)+'"',b=0);t+="<Cell"+l+'><Data ss:Type="'+h+'">'+d("<div />").text(c).html()+"</Data></Cell>\r";e++}});0<t.length&&(H+='<Row ss:AutoFitHeight="0">\r'+
t+"</Row>\r");p++});return a.length}var c=d(this),e="";"string"===typeof a.mso.worksheetName&&a.mso.worksheetName.length?e=a.mso.worksheetName+" "+(F.length+1):"undefined"!==typeof a.mso.worksheetName[F.length]&&(e=a.mso.worksheetName[F.length]);e.length||(e=c.find("caption").text()||"");e.length||(e="Table "+(F.length+1));e=d.trim(e.replace(/[\\\/[\]*:?'"]/g,"").substring(0,31));F.push(d("<div />").text(e).html());!1===a.exportHiddenCells&&(K=c.find("tr, th, td").filter(":hidden"),V=0<K.length);
p=0;S=R(this);H="<Table>\r";e=b(y(c),"th,td",0);b(C(c),"td,th",e);H+="</Table>\r";sa.push(H)});k={};z={};for(var m,aa,Y=0,ea=F.length;Y<ea;Y++)m=F[Y],aa=k[m],aa=k[m]=null==aa?1:aa+1,2===aa&&(F[z[m]]=F[z[m]].substring(0,29)+"-1"),1<k[m]?F[Y]=F[Y].substring(0,29)+"-"+k[m]:z[m]=Y;k='<?xml version="1.0" encoding="UTF-8"?>\r<?mso-application progid="Excel.Sheet"?>\r<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"\r xmlns:o="urn:schemas-microsoft-com:office:office"\r xmlns:x="urn:schemas-microsoft-com:office:excel"\r xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"\r xmlns:html="http://www.w3.org/TR/REC-html40">\r<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">\r <Created>'+
(new Date).toISOString()+'</Created>\r</DocumentProperties>\r<OfficeDocumentSettings xmlns="urn:schemas-microsoft-com:office:office">\r <AllowPNG/>\r</OfficeDocumentSettings>\r<ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">\r <WindowHeight>9000</WindowHeight>\r <WindowWidth>13860</WindowWidth>\r <WindowTopX>0</WindowTopX>\r <WindowTopY>0</WindowTopY>\r <ProtectStructure>False</ProtectStructure>\r <ProtectWindows>False</ProtectWindows>\r</ExcelWorkbook>\r<Styles>\r <Style ss:ID="Default" ss:Name="Normal">\r <Alignment ss:Vertical="Bottom"/>\r <Borders/>\r <Font/>\r <Interior/>\r <NumberFormat/>\r <Protection/>\r </Style>\r <Style ss:ID="rsp1">\r <Alignment ss:Vertical="Center"/>\r </Style>\r <Style ss:ID="pct1">\r <NumberFormat ss:Format="Percent"/>\r </Style>\r</Styles>\r';
for(z=0;z<sa.length;z++)k+='<Worksheet ss:Name="'+F[z]+'" ss:RightToLeft="'+(a.mso.rtl?"1":"0")+'">\r'+sa[z],k=a.mso.rtl?k+'<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">\r<DisplayRightToLeft/>\r</WorksheetOptions>\r':k+'<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel"/>\r',k+="</Worksheet>\r";k+="</Workbook>\r";if("string"===a.outputMode)return k;if("base64"===a.outputMode)return L(k);N(k,a.fileName+".xml","application/xml","utf-8","base64",!1)}else if("excel"===
a.type&&"xlsx"===a.mso.fileFormat){var ba=[],Ga=XLSX.utils.book_new();d(B).filter(function(){return I(d(this))}).each(function(){for(var b=d(this),c={},e=this.getElementsByTagName("tr"),g={s:{r:0,c:0},e:{r:0,c:0}},f=[],h,n=[],l=0,u=0,k,m,p,t,r,w=XLSX.SSF.get_table();l<e.length&&1E7>u;++l)if(k=e[l],m=!1,"function"===typeof a.onIgnoreRow&&(m=a.onIgnoreRow(d(k),l)),!0!==m&&(0===a.ignoreRow.length||-1===d.inArray(l,a.ignoreRow)&&-1===d.inArray(l-e.length,a.ignoreRow))&&!1!==I(d(k))){var y=k.children,
B=0;for(k=0;k<y.length;++k)r=y[k],t=+J(r)||1,B+=t;var z=0;for(k=m=0;k<y.length;++k)if(r=y[k],t=+J(r)||1,h=k+z,!ta(d(r),B,h+(h<m?m-h:0))){z+=t-1;for(h=0;h<f.length;++h){var v=f[h];v.s.c==m&&v.s.r<=u&&u<=v.e.r&&(m=v.e.c+1,h=-1)}(0<(p=+T(r))||1<t)&&f.push({s:{r:u,c:m},e:{r:u+(p||1)-1,c:m+t-1}});var C={type:""};h=D(r,l,k+z,C);v={t:"s",v:h};var A="";if(""!==(d(r).attr("data-tableexport-cellformat")||"")){var x=parseInt(d(r).attr("data-tableexport-xlsxformatid")||0);0===x&&"function"===typeof a.mso.xslx.formatId.numbers&&
(x=a.mso.xslx.formatId.numbers(d(r),l,k+z));0===x&&"function"===typeof a.mso.xslx.formatId.date&&(x=a.mso.xslx.formatId.date(d(r),l,k+z));if(49===x||"@"===x)A="s";else if("number"===C.type||0<x&&14>x||36<x&&41>x||48===x)A="n";else if("date"===C.type||13<x&&37>x||44<x&&48>x||56===x)A="d"}else A="s";if(null!=h)if(0===h.length)v.t="z";else if(0!==h.trim().length)if("s"===A)d(r).find("a").length&&(h="href"!==a.htmlHyperlink?h:"",v={f:'=HYPERLINK("'+d(r).find("a").attr("href")+(h.length?'","'+h:"")+'")'});
else if("function"===C.type)v={f:h};else if("TRUE"===h)v={t:"b",v:!0};else if("FALSE"===h)v={t:"b",v:!1};else if("n"===A||isFinite(Da(h,a.numbers.output))){if(r=Da(h,a.numbers.output),0===x&&"function"!==typeof a.mso.xslx.formatId.numbers&&(x=a.mso.xslx.formatId.numbers),isFinite(r)||isFinite(h))v={t:"n",v:isFinite(r)?r:h,z:"string"===typeof x?x:x in w?w[x]:"0.00"}}else if(!1!==(r=La(h))||"d"===A)0===x&&"function"!==typeof a.mso.xslx.formatId.date&&(x=a.mso.xslx.formatId.date),v={t:"d",v:!1!==r?r:
h,z:"string"===typeof x?x:x in w?w[x]:"m/d/yy"};c[oa({c:m,r:u})]=v;g.e.c<m&&(g.e.c=m);m+=t}++u}f.length&&(c["!merges"]=f);n.length&&(c["!rows"]=n);g.e.r=u-1;c["!ref"]=pa(g);1E7<=u&&(c["!fullref"]=pa((g.e.r=e.length-l+u-1,g)));e="";"string"===typeof a.mso.worksheetName&&a.mso.worksheetName.length?e=a.mso.worksheetName+" "+(ba.length+1):"undefined"!==typeof a.mso.worksheetName[ba.length]&&(e=a.mso.worksheetName[ba.length]);e.length||(e=b.find("caption").text()||"");e.length||(e="Table "+(ba.length+
1));e=d.trim(e.replace(/[\\\/[\]*:?'"]/g,"").substring(0,31));ba.push(e);XLSX.utils.book_append_sheet(Ga,c,e)});k=XLSX.write(Ga,{type:"binary",bookType:a.mso.fileFormat,bookSST:!1});N(Oa(k),a.fileName+"."+a.mso.fileFormat,"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","UTF-8","",!1)}else if("excel"===a.type||"xls"===a.type||"word"===a.type||"doc"===a.type){k="excel"===a.type||"xls"===a.type?"excel":"word";z="excel"===k?"xls":"doc";m='xmlns:x="urn:schemas-microsoft-com:office:'+
k+'"';var H="",ca="";d(B).filter(function(){return I(d(this))}).each(function(){var b=d(this);""===ca&&(ca=a.mso.worksheetName||b.find("caption").text()||"Table",ca=d.trim(ca.replace(/[\\\/[\]*:?'"]/g,"").substring(0,31)));!1===a.exportHiddenCells&&(K=b.find("tr, th, td").filter(":hidden"),V=0<K.length);p=0;G=[];S=R(this);H+="<table><thead>";r=y(b);d(r).each(function(){var b=d(this);t="";E(this,"th,td",p,r.length,function(d,c,f){if(null!==d){var e="";t+="<th";if(a.mso.styles.length){var n=document.defaultView.getComputedStyle(d,
null),l=document.defaultView.getComputedStyle(b[0],null),g;for(g in a.mso.styles){var k=n[a.mso.styles[g]];""===k&&(k=l[a.mso.styles[g]]);""!==k&&"0px none rgb(0, 0, 0)"!==k&&"rgba(0, 0, 0, 0)"!==k&&(e+=""===e?'style="':";",e+=a.mso.styles[g]+":"+k)}}""!==e&&(t+=" "+e+'"');e=J(d);0<e&&(t+=' colspan="'+e+'"');e=T(d);0<e&&(t+=' rowspan="'+e+'"');t+=">"+D(d,c,f)+"</th>"}});0<t.length&&(H+="<tr>"+t+"</tr>");p++});H+="</thead><tbody>";w=C(b);d(w).each(function(){var b=d(this);t="";E(this,"td,th",p,r.length+
w.length,function(c,g,f){if(null!==c){var e=D(c,g,f),n="",l=d(c).attr("data-tableexport-msonumberformat");"undefined"===typeof l&&"function"===typeof a.mso.onMsoNumberFormat&&(l=a.mso.onMsoNumberFormat(c,g,f));"undefined"!==typeof l&&""!==l&&(n="style=\"mso-number-format:'"+l+"'");if(a.mso.styles.length){g=document.defaultView.getComputedStyle(c,null);f=document.defaultView.getComputedStyle(b[0],null);for(var k in a.mso.styles)l=g[a.mso.styles[k]],""===l&&(l=f[a.mso.styles[k]]),""!==l&&"0px none rgb(0, 0, 0)"!==
l&&"rgba(0, 0, 0, 0)"!==l&&(n+=""===n?'style="':";",n+=a.mso.styles[k]+":"+l)}t+="<td";""!==n&&(t+=" "+n+'"');n=J(c);0<n&&(t+=' colspan="'+n+'"');c=T(c);0<c&&(t+=' rowspan="'+c+'"');"string"===typeof e&&""!==e&&(e=Ba(e),e=e.replace(/\n/g,"<br>"));t+=">"+e+"</td>"}});0<t.length&&(H+="<tr>"+t+"</tr>");p++});a.displayTableName&&(H+="<tr><td></td></tr><tr><td></td></tr><tr><td>"+D(d("<p>"+a.tableName+"</p>"))+"</td></tr>");H+="</tbody></table>"});m='<html xmlns:o="urn:schemas-microsoft-com:office:office" '+
m+' xmlns="http://www.w3.org/TR/REC-html40">'+('<meta http-equiv="content-type" content="application/vnd.ms-'+k+'; charset=UTF-8">')+"<head>";"excel"===k&&(m+="\x3c!--[if gte mso 9]>",m+="<xml>",m+="<x:ExcelWorkbook>",m+="<x:ExcelWorksheets>",m+="<x:ExcelWorksheet>",m+="<x:Name>",m+=ca,m+="</x:Name>",m+="<x:WorksheetOptions>",m+="<x:DisplayGridlines/>",a.mso.rtl&&(m+="<x:DisplayRightToLeft/>"),m+="</x:WorksheetOptions>",m+="</x:ExcelWorksheet>",m+="</x:ExcelWorksheets>",m+="</x:ExcelWorkbook>",m+=
"</xml>",m+="<![endif]--\x3e");m+="<style>";m+="@page { size:"+a.mso.pageOrientation+"; mso-page-orientation:"+a.mso.pageOrientation+"; }";m+="@page Section1 {size:"+O[a.mso.pageFormat][0]+"pt "+O[a.mso.pageFormat][1]+"pt";m+="; margin:1.0in 1.25in 1.0in 1.25in;mso-header-margin:.5in;mso-footer-margin:.5in;mso-paper-source:0;}";m+="div.Section1 {page:Section1;}";m+="@page Section2 {size:"+O[a.mso.pageFormat][1]+"pt "+O[a.mso.pageFormat][0]+"pt";m+=";mso-page-orientation:"+a.mso.pageOrientation+";margin:1.25in 1.0in 1.25in 1.0in;mso-header-margin:.5in;mso-footer-margin:.5in;mso-paper-source:0;}";
m+="div.Section2 {page:Section2;}";m+="br {mso-data-placement:same-cell;}";m+="</style>";m+="</head>";m+="<body>";m+='<div class="Section'+("landscape"===a.mso.pageOrientation?"2":"1")+'">';m+=H;m+="</div>";m+="</body>";m+="</html>";if("string"===a.outputMode)return m;if("base64"===a.outputMode)return L(m);N(m,a.fileName+"."+z,"application/vnd.ms-"+k,"","base64",!1)}else if("png"===a.type)html2canvas(d(B)[0]).then(function(b){b=b.toDataURL();for(var c=atob(b.substring(22)),d=new ArrayBuffer(c.length),
g=new Uint8Array(d),f=0;f<c.length;f++)g[f]=c.charCodeAt(f);if("string"===a.outputMode)return c;if("base64"===a.outputMode)return L(b);"window"===a.outputMode?window.open(b):N(d,a.fileName+".png","image/png","","",!1)});else if("pdf"===a.type)if(!0===a.pdfmake.enabled){var U={content:[]};d.extend(!0,U,a.pdfmake.docDefinition);G=[];d(B).filter(function(){return I(d(this))}).each(function(){var b=d(this),c=[],e=[];p=0;var g=function(a,b,c){var f=0;d(a).each(function(){var a=[];E(this,b,p,c,function(c,
d,f){if("undefined"!==typeof c&&null!==c){var e=J(c),h=T(c);c={text:D(c,d,f)||" "};if(1<e||1<h)c.colSpan=e||1,c.rowSpan=h||1}else c={text:" "};0<=b.indexOf("th")&&(c.style="header");a.push(c)});for(var d=a.length;d<c;d++)a.push("");a.length&&e.push(a);f<a.length&&(f=a.length);p++});return f};r=y(b);for(var f=g(r,"th,td",r.length),h=c.length;h<f;h++)c.push("*");w=C(b);f=g(w,"td",r.length+w.length);for(h=c.length;h<f;h++)c.push("*");U.content.push({table:{headerRows:r.length?r.length:null,widths:c,
body:e},layout:{layout:"noBorders",hLineStyle:function(a,b){return 0},vLineWidth:function(a,b){return 0},hLineColor:function(b,c){return b<c.table.headerRows?a.pdfmake.docDefinition.styles.header.background:a.pdfmake.docDefinition.styles.alternateRow.fillColor},vLineColor:function(b,c){return b<c.table.headerRows?a.pdfmake.docDefinition.styles.header.background:a.pdfmake.docDefinition.styles.alternateRow.fillColor},fillColor:function(b,c,d){return 0===b%2?a.pdfmake.docDefinition.styles.alternateRow.fillColor:
null}},pageBreak:U.content.length?"before":void 0})});"undefined"!==typeof pdfMake&&"undefined"!==typeof pdfMake.createPdf&&(pdfMake.fonts={Roboto:{normal:"Roboto-Regular.ttf",bold:"Roboto-Medium.ttf",italics:"Roboto-Italic.ttf",bolditalics:"Roboto-MediumItalic.ttf"}},pdfMake.vfs.hasOwnProperty("Mirza-Regular.ttf")?(U.defaultStyle.font="Mirza",d.extend(!0,pdfMake.fonts,{Mirza:{normal:"Mirza-Regular.ttf",bold:"Mirza-Bold.ttf",italics:"Mirza-Medium.ttf",bolditalics:"Mirza-SemiBold.ttf"}})):pdfMake.vfs.hasOwnProperty("gbsn00lp.ttf")?
(U.defaultStyle.font="gbsn00lp",d.extend(!0,pdfMake.fonts,{gbsn00lp:{normal:"gbsn00lp.ttf",bold:"gbsn00lp.ttf",italics:"gbsn00lp.ttf",bolditalics:"gbsn00lp.ttf"}})):pdfMake.vfs.hasOwnProperty("ZCOOLXiaoWei-Regular.ttf")&&(U.defaultStyle.font="ZCOOLXiaoWei",d.extend(!0,pdfMake.fonts,{ZCOOLXiaoWei:{normal:"ZCOOLXiaoWei-Regular.ttf",bold:"ZCOOLXiaoWei-Regular.ttf",italics:"ZCOOLXiaoWei-Regular.ttf",bolditalics:"ZCOOLXiaoWei-Regular.ttf"}})),d.extend(!0,pdfMake.fonts,a.pdfmake.fonts),pdfMake.createPdf(U).getBuffer(function(b){N(b,
a.fileName+".pdf","application/pdf","","",!1)}))}else if(!1===a.jspdf.autotable){k={dim:{w:ha(d(B).first().get(0),"width","mm"),h:ha(d(B).first().get(0),"height","mm")},pagesplit:!1};var Ha=new jsPDF(a.jspdf.orientation,a.jspdf.unit,a.jspdf.format);Ha.addHTML(d(B).first(),a.jspdf.margins.left,a.jspdf.margins.top,k,function(){va(Ha,!1)})}else{var g=a.jspdf.autotable.tableExport;if("string"===typeof a.jspdf.format&&"bestfit"===a.jspdf.format.toLowerCase()){var ja="",da="",Ia=0;d(B).each(function(){if(I(d(this))){var a=
ha(d(this).get(0),"width","pt");if(a>Ia){a>O.a0[0]&&(ja="a0",da="l");for(var c in O)O.hasOwnProperty(c)&&O[c][1]>a&&(ja=c,da="l",O[c][0]>a&&(da="p"));Ia=a}}});a.jspdf.format=""===ja?"a4":ja;a.jspdf.orientation=""===da?"w":da}if(null==g.doc&&(g.doc=new jsPDF(a.jspdf.orientation,a.jspdf.unit,a.jspdf.format),g.wScaleFactor=1,g.hScaleFactor=1,"function"===typeof a.jspdf.onDocCreated))a.jspdf.onDocCreated(g.doc);!0===g.outputImages&&(g.images={});"undefined"!==typeof g.images&&(d(B).filter(function(){return I(d(this))}).each(function(){var b=
0;G=[];!1===a.exportHiddenCells&&(K=d(this).find("tr, th, td").filter(":hidden"),V=0<K.length);r=y(d(this));w=C(d(this));d(w).each(function(){E(this,"td,th",r.length+b,r.length+w.length,function(a){xa(a,d(a).children(),g)});b++})}),r=[],w=[]);Ka(g,function(){d(B).filter(function(){return I(d(this))}).each(function(){var b;p=0;G=[];!1===a.exportHiddenCells&&(K=d(this).find("tr, th, td").filter(":hidden"),V=0<K.length);S=R(this);g.columns=[];g.rows=[];g.teCells={};if("function"===typeof g.onTable&&
!1===g.onTable(d(this),a))return!0;a.jspdf.autotable.tableExport=null;var c=d.extend(!0,{},a.jspdf.autotable);a.jspdf.autotable.tableExport=g;c.margin={};d.extend(!0,c.margin,a.jspdf.margins);c.tableExport=g;"function"!==typeof c.beforePageContent&&(c.beforePageContent=function(a){if(1===a.pageCount){var b=a.table.rows.concat(a.table.headerRow);d.each(b,function(){0<this.height&&(this.height+=(2-1.15)/2*this.styles.fontSize,a.table.height+=(2-1.15)/2*this.styles.fontSize)})}});"function"!==typeof c.createdHeaderCell&&
(c.createdHeaderCell=function(a,b){a.styles=d.extend({},b.row.styles);if("undefined"!==typeof g.columns[b.column.dataKey]){var e=g.columns[b.column.dataKey];if("undefined"!==typeof e.rect){a.contentWidth=e.rect.width;if("undefined"===typeof g.heightRatio||0===g.heightRatio){var f=b.row.raw[b.column.dataKey].rowspan?b.row.raw[b.column.dataKey].rect.height/b.row.raw[b.column.dataKey].rowspan:b.row.raw[b.column.dataKey].rect.height;g.heightRatio=a.styles.rowHeight/f}f=b.row.raw[b.column.dataKey].rect.height*
g.heightRatio;f>a.styles.rowHeight&&(a.styles.rowHeight=f)}a.styles.halign="inherit"===c.headerStyles.halign?"center":c.headerStyles.halign;a.styles.valign=c.headerStyles.valign;"undefined"!==typeof e.style&&!0!==e.style.hidden&&("inherit"===c.headerStyles.halign&&(a.styles.halign=e.style.align),"inherit"===c.styles.fillColor&&(a.styles.fillColor=e.style.bcolor),"inherit"===c.styles.textColor&&(a.styles.textColor=e.style.color),"inherit"===c.styles.fontStyle&&(a.styles.fontStyle=e.style.fstyle))}});
"function"!==typeof c.createdCell&&(c.createdCell=function(a,b){b=g.teCells[b.row.index+":"+b.column.dataKey];a.styles.halign="inherit"===c.styles.halign?"center":c.styles.halign;a.styles.valign=c.styles.valign;"undefined"!==typeof b&&"undefined"!==typeof b.style&&!0!==b.style.hidden&&("inherit"===c.styles.halign&&(a.styles.halign=b.style.align),"inherit"===c.styles.fillColor&&(a.styles.fillColor=b.style.bcolor),"inherit"===c.styles.textColor&&(a.styles.textColor=b.style.color),"inherit"===c.styles.fontStyle&&
(a.styles.fontStyle=b.style.fstyle))});"function"!==typeof c.drawHeaderCell&&(c.drawHeaderCell=function(a,b){var c=g.columns[b.column.dataKey];return(!0!==c.style.hasOwnProperty("hidden")||!0!==c.style.hidden)&&0<=c.rowIndex?wa(a,b,c):!1});"function"!==typeof c.drawCell&&(c.drawCell=function(a,b){var c=g.teCells[b.row.index+":"+b.column.dataKey];if(!0!==("undefined"!==typeof c&&c.isCanvas))wa(a,b,c)&&(g.doc.rect(a.x,a.y,a.width,a.height,a.styles.fillStyle),"undefined"===typeof c||"undefined"!==typeof c.hasUserDefText&&
!0===c.hasUserDefText||"undefined"===typeof c.elements||!c.elements.length?Aa(a,{},g):(b=a.height/c.rect.height,b>g.hScaleFactor&&(g.hScaleFactor=b),g.wScaleFactor=a.width/c.rect.width,b=a.textPos.y,za(a,c.elements,g),a.textPos.y=b,Aa(a,c.elements,g)));else{c=c.elements[0];var e=d(c).attr("data-tableexport-canvas"),f=c.getBoundingClientRect();a.width=f.width*g.wScaleFactor;a.height=f.height*g.hScaleFactor;b.row.height=a.height;ua(a,c,e,g)}return!1});g.headerrows=[];r=y(d(this));d(r).each(function(){b=
0;g.headerrows[p]=[];E(this,"th,td",p,r.length,function(a,c,d){var e=Ca(a);e.title=D(a,c,d);e.key=b++;e.rowIndex=p;g.headerrows[p].push(e)});p++});if(0<p)for(var e=p-1;0<=e;)d.each(g.headerrows[e],function(){var a=this;0<e&&null===this.rect&&(a=g.headerrows[e-1][this.key]);null!==a&&0<=a.rowIndex&&(!0!==a.style.hasOwnProperty("hidden")||!0!==a.style.hidden)&&g.columns.push(a)}),e=0<g.columns.length?-1:e-1;var k=0;w=[];w=C(d(this));d(w).each(function(){var a=[];b=0;E(this,"td,th",p,r.length+w.length,
function(c,e,f){if("undefined"===typeof g.columns[b]){var h={title:"",key:b,style:{hidden:!0}};g.columns.push(h)}a.push(D(c,e,f));"undefined"!==typeof c&&null!==c?(h=Ca(c),h.isCanvas=c.hasAttribute("data-tableexport-canvas"),h.elements=h.isCanvas?d(c):d(c).children(),"undefined"!==typeof d(c).data("teUserDefText")&&(h.hasUserDefText=!0)):(h=d.extend(!0,{},g.teCells[k+":"+(b-1)]),h.colspan=-1);g.teCells[k+":"+b++]=h});a.length&&(g.rows.push(a),k++);p++});if("function"===typeof g.onBeforeAutotable)g.onBeforeAutotable(d(this),
g.columns,g.rows,c);g.doc.autoTable(g.columns,g.rows,c);if("function"===typeof g.onAfterAutotable)g.onAfterAutotable(d(this),c);a.jspdf.autotable.startY=g.doc.autoTableEndPosY()+c.margin.top});va(g.doc,"undefined"!==typeof g.images&&!1===jQuery.isEmptyObject(g.images));"undefined"!==typeof g.headerrows&&(g.headerrows.length=0);"undefined"!==typeof g.columns&&(g.columns.length=0);"undefined"!==typeof g.rows&&(g.rows.length=0);delete g.doc;g.doc=null})}if("function"===typeof a.onTableExportEnd)a.onTableExportEnd();
return this}})(jQuery);

View File

@ -0,0 +1,123 @@
/**
* @author: Dennis Hernández
* @update zhixin wen <wenzhixin2010@gmail.com>
*/
const debounce = (func, wait) => {
let timeout = 0
return (...args) => {
const later = () => {
timeout = 0
func(...args)
}
clearTimeout(timeout)
timeout = setTimeout(later, wait)
}
}
Object.assign($.fn.bootstrapTable.defaults, {
mobileResponsive: false,
minWidth: 562,
minHeight: undefined,
heightThreshold: 100, // just slightly larger than mobile chrome's auto-hiding toolbar
checkOnInit: true,
columnsHidden: []
})
$.BootstrapTable = class extends $.BootstrapTable {
init (...args) {
super.init(...args)
if (!this.options.mobileResponsive || !this.options.minWidth) {
return
}
if (this.options.minWidth < 100 && this.options.resizable) {
console.warn('The minWidth when the resizable extension is active should be greater or equal than 100')
this.options.minWidth = 100
}
let old = {
width: $(window).width(),
height: $(window).height()
}
$(window).on('resize orientationchange', debounce(() => {
// reset view if height has only changed by at least the threshold.
const width = $(window).width()
const height = $(window).height()
const $activeElement = $(document.activeElement)
if ($activeElement.length && ['INPUT', 'SELECT', 'TEXTAREA'].includes($activeElement.prop('nodeName'))) {
return
}
if (
Math.abs(old.height - height) > this.options.heightThreshold ||
old.width !== width
) {
this.changeView(width, height)
old = {
width,
height
}
}
}, 200))
if (this.options.checkOnInit) {
const width = $(window).width()
const height = $(window).height()
this.changeView(width, height)
old = {
width,
height
}
}
}
conditionCardView () {
this.changeTableView(false)
this.showHideColumns(false)
}
conditionFullView () {
this.changeTableView(true)
this.showHideColumns(true)
}
changeTableView (cardViewState) {
this.options.cardView = cardViewState
this.toggleView()
}
showHideColumns (checked) {
if (this.options.columnsHidden.length > 0) {
this.columns.forEach(column => {
if (this.options.columnsHidden.includes(column.field)) {
if (column.visible !== checked) {
this._toggleColumn(this.fieldsColumnsIndex[column.field], checked, true)
}
}
})
}
}
changeView (width, height) {
if (this.options.minHeight) {
if (width <= this.options.minWidth && height <= this.options.minHeight) {
this.conditionCardView()
} else if (width > this.options.minWidth && height > this.options.minHeight) {
this.conditionFullView()
}
} else if (width <= this.options.minWidth) {
this.conditionCardView()
} else if (width > this.options.minWidth) {
this.conditionFullView()
}
this.resetView()
}
}

View File

@ -0,0 +1,312 @@
/**
* @update zhixin wen <wenzhixin2010@gmail.com>
*/
var Utils = $.fn.bootstrapTable.utils
function printPageBuilderDefault (table, styles) {
return `
<html>
<head>
${styles}
<style type="text/css" media="print">
@page {
size: auto;
margin: 25px 0 25px 0;
}
</style>
<style type="text/css" media="all">
table {
border-collapse: collapse;
font-size: 12px;
}
table, th, td {
border: 1px solid grey;
}
th, td {
text-align: center;
vertical-align: middle;
}
p {
font-weight: bold;
margin-left:20px;
}
table {
width: 94%;
margin-left: 3%;
margin-right: 3%;
}
div.bs-table-print {
text-align: center;
}
</style>
</head>
<title>Print Table</title>
<body>
<p>Printed on: ${new Date} </p>
<div class="bs-table-print">${table}</div>
</body>
</html>
`
}
Object.assign($.fn.bootstrapTable.locales, {
formatPrint () {
return 'Print'
}
})
Object.assign($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales)
Object.assign($.fn.bootstrapTable.defaults, {
showPrint: false,
printAsFilteredAndSortedOnUI: true,
printSortColumn: undefined,
printSortOrder: 'asc',
printStyles: [],
printPageBuilder (table, styles) {
return printPageBuilderDefault(table, styles)
}
})
Object.assign($.fn.bootstrapTable.columnDefaults, {
printFilter: undefined,
printIgnore: false,
printFormatter: undefined
})
Object.assign($.fn.bootstrapTable.defaults.icons, {
print: {
bootstrap3: 'glyphicon-print icon-share',
bootstrap5: 'bi-printer',
'bootstrap-table': 'icon-printer'
}[$.fn.bootstrapTable.theme] || 'fa-print'
})
$.BootstrapTable = class extends $.BootstrapTable {
init (...args) {
super.init(...args)
if (!this.options.showPrint) {
return
}
this.mergedCells = []
}
initToolbar (...args) {
this.showToolbar = this.showToolbar || this.options.showPrint
if (this.options.showPrint) {
this.buttons = Object.assign(this.buttons, {
print: {
text: this.options.formatPrint(),
icon: this.options.icons.print,
event: () => {
this.doPrint(this.options.printAsFilteredAndSortedOnUI ? this.getData() : this.options.data.slice(0))
},
attributes: {
'aria-label': this.options.formatPrint(),
title: this.options.formatPrint()
}
}
})
}
super.initToolbar(...args)
}
mergeCells (options) {
super.mergeCells(options)
if (!this.options.showPrint) {
return
}
let col = this.getVisibleFields().indexOf(options.field)
if (Utils.hasDetailViewIcon(this.options)) {
col += 1
}
this.mergedCells.push({
row: options.index,
col,
rowspan: options.rowspan || 1,
colspan: options.colspan || 1
})
}
doPrint (data) {
const canPrint = column => {
return !column.printIgnore && column.visible
}
const formatValue = (row, i, column) => {
const value_ = Utils.getItemField(row, column.field, this.options.escape, column.escape)
const value = Utils.calculateObjectValue(column,
column.printFormatter || column.formatter,
[value_, row, i], value_)
return typeof value === 'undefined' || value === null ?
this.options.undefinedText : value
}
const buildTable = (data, columnsArray) => {
const dir = this.$el.attr('dir') || 'ltr'
const html = [`<table dir="${dir}"><thead>`]
for (const columns of columnsArray) {
html.push('<tr>')
for (let h = 0; h < columns.length; h++) {
if (canPrint(columns[h])) {
html.push(
`<th
${Utils.sprintf(' rowspan="%s"', columns[h].rowspan)}
${Utils.sprintf(' colspan="%s"', columns[h].colspan)}
>${columns[h].title}</th>`)
}
}
html.push('</tr>')
}
html.push('</thead><tbody>')
const notRender = []
if (this.mergedCells) {
for (let mc = 0; mc < this.mergedCells.length; mc++) {
const currentMergedCell = this.mergedCells[mc]
for (let rs = 0; rs < currentMergedCell.rowspan; rs++) {
const row = currentMergedCell.row + rs
for (let cs = 0; cs < currentMergedCell.colspan; cs++) {
const col = currentMergedCell.col + cs
notRender.push(`${row},${col}`)
}
}
}
}
for (let i = 0; i < data.length; i++) {
html.push('<tr>')
const columns = columnsArray.flat(1)
columns.sort((c1, c2) => {
return c1.colspanIndex - c2.colspanIndex
})
for (let j = 0; j < columns.length; j++) {
if (columns[j].colspanGroup > 0) continue
let rowspan = 0
let colspan = 0
if (this.mergedCells) {
for (let mc = 0; mc < this.mergedCells.length; mc++) {
const currentMergedCell = this.mergedCells[mc]
if (currentMergedCell.col === j && currentMergedCell.row === i) {
rowspan = currentMergedCell.rowspan
colspan = currentMergedCell.colspan
}
}
}
if (
canPrint(columns[j]) &&
(
!notRender.includes(`${i},${j}`) ||
rowspan > 0 && colspan > 0
)
) {
if (rowspan > 0 && colspan > 0) {
html.push(`<td ${Utils.sprintf(' rowspan="%s"', rowspan)} ${Utils.sprintf(' colspan="%s"', colspan)}>`, formatValue(data[i], i, columns[j]), '</td>')
} else {
html.push('<td>', formatValue(data[i], i, columns[j]), '</td>')
}
}
}
html.push('</tr>')
}
html.push('</tbody>')
if (this.options.showFooter) {
html.push('<footer><tr>')
for (const columns of columnsArray) {
for (let h = 0; h < columns.length; h++) {
if (canPrint(columns)) {
const footerData = Utils.trToData(columns, this.$el.find('>tfoot>tr'))
const footerValue = Utils.calculateObjectValue(columns[h], columns[h].footerFormatter, [data], footerData[0] && footerData[0][columns[h].field] || '')
html.push(`<th>${footerValue}</th>`)
}
}
}
html.push('</tr></footer>')
}
html.push('</table>')
return html.join('')
}
const sortRows = (data, colName, sortOrder) => {
if (!colName) {
return data
}
let reverse = sortOrder !== 'asc'
reverse = -(+reverse || -1)
return data.sort((a, b) => reverse * a[colName].localeCompare(b[colName]))
}
const filterRow = (row, filters) => {
for (let index = 0; index < filters.length; ++index) {
if (row[filters[index].colName] !== filters[index].value) {
return false
}
}
return true
}
const filterRows = (data, filters) => data.filter(row => filterRow(row, filters))
const getColumnFilters = columns => !columns || !columns[0] ? [] : columns[0].filter(col => col.printFilter).map(col => ({
colName: col.field,
value: col.printFilter
}))
data = filterRows(data, getColumnFilters(this.options.columns))
data = sortRows(data, this.options.printSortColumn, this.options.printSortOrder)
const table = buildTable(data, this.options.columns)
const newWin = window.open('')
const printStyles = typeof this.options.printStyles === 'string' ?
this.options.printStyles.replace(/\[|\]| /g, '').toLowerCase().split(',') :
this.options.printStyles
const styles = printStyles.map(it =>
`<link rel="stylesheet" href="${it}" />`).join('')
const calculatedPrintPage = Utils.calculateObjectValue(this, this.options.printPageBuilder,
[table, styles], printPageBuilderDefault(table, styles))
const startPrint = () => {
newWin.focus()
newWin.print()
newWin.close()
}
newWin.document.write(calculatedPrintPage)
newWin.document.close()
if (printStyles.length) {
const links = document.getElementsByTagName('link')
const lastLink = links[links.length - 1]
lastLink.onload = startPrint
} else {
startPrint()
}
}
}

View File

@ -0,0 +1,212 @@
/**
* @author: Dennis Hernández
* @update: https://github.com/wenzhixin
* @version: v1.2.0
*/
$.akottr.dragtable.prototype._restoreState = function (persistObj) {
let i = 0
for (const [field, value] of Object.entries(persistObj)) {
const $th = this.originalTable.el.find(`th[data-field="${field}"]`)
if (!$th.length) {
i++
continue
}
this.originalTable.startIndex = $th.prevAll().length + 1
this.originalTable.endIndex = parseInt(value, 10) + 1 - i
this._bubbleCols()
}
}
// From MDN site, https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
const filterFn = () => {
if (!Array.prototype.filter) {
Array.prototype.filter = function (fun/* , thisArg*/) {
if (this === undefined || this === null) {
throw new TypeError()
}
const t = Object(this)
const len = t.length >>> 0
if (typeof fun !== 'function') {
throw new TypeError()
}
const res = []
const thisArg = arguments.length >= 2 ? arguments[1] : undefined
for (let i = 0; i < len; i++) {
if (i in t) {
const val = t[i]
// NOTE: Technically this should Object.defineProperty at
// the next index, as push can be affected by
// properties on Object.prototype and Array.prototype.
// But this method's new, and collisions should be
// rare, so use the more-compatible alternative.
if (fun.call(thisArg, val, i, t)) {
res.push(val)
}
}
}
return res
}
}
}
Object.assign($.fn.bootstrapTable.defaults, {
reorderableColumns: false,
maxMovingRows: 10,
// eslint-disable-next-line no-unused-vars
onReorderColumn (headerFields) {
return false
},
dragaccept: null
})
Object.assign($.fn.bootstrapTable.events, {
'reorder-column.bs.table': 'onReorderColumn'
})
$.fn.bootstrapTable.methods.push('orderColumns')
$.BootstrapTable = class extends $.BootstrapTable {
initHeader (...args) {
super.initHeader(...args)
if (!this.options.reorderableColumns) {
return
}
this.makeColumnsReorderable()
}
_toggleColumn (...args) {
super._toggleColumn(...args)
if (!this.options.reorderableColumns) {
return
}
this.makeColumnsReorderable()
}
toggleView (...args) {
super.toggleView(...args)
if (!this.options.reorderableColumns) {
return
}
if (this.options.cardView) {
return
}
this.makeColumnsReorderable()
}
resetView (...args) {
super.resetView(...args)
if (!this.options.reorderableColumns) {
return
}
this.makeColumnsReorderable()
}
makeColumnsReorderable (order = null) {
try {
$(this.$el).dragtable('destroy')
} catch (e) {
// do nothing
}
$(this.$el).dragtable({
maxMovingRows: this.options.maxMovingRows,
dragaccept: this.options.dragaccept,
clickDelay: 200,
dragHandle: '.th-inner',
restoreState: order ? order : this.columnsSortOrder,
beforeStop: table => {
const sortOrder = {}
table.el.find('th').each((i, el) => {
sortOrder[$(el).data('field')] = i
})
this.columnsSortOrder = sortOrder
if (this.options.cookie) {
this.persistReorderColumnsState(this)
}
const ths = []
const formatters = []
const columns = []
let columnsHidden = []
let columnIndex = -1
const optionsColumns = []
this.$header.find('th:not(.detail)').each((i, el) => {
ths.push($(el).data('field'))
formatters.push($(el).data('formatter'))
})
// Exist columns not shown
if (ths.length < this.columns.length) {
columnsHidden = this.columns.filter(column => !column.visible)
for (let i = 0; i < columnsHidden.length; i++) {
ths.push(columnsHidden[i].field)
formatters.push(columnsHidden[i].formatter)
}
}
for (let i = 0; i < ths.length; i++) {
columnIndex = this.fieldsColumnsIndex[ths[i]]
if (columnIndex !== -1) {
this.fieldsColumnsIndex[ths[i]] = i
this.columns[columnIndex].fieldIndex = i
columns.push(this.columns[columnIndex])
}
}
this.columns = columns
filterFn() // Support <IE9
$.each(this.columns, (i, column) => {
let found = false
const field = column.field
this.options.columns[0].filter(item => {
if (!found && item['field'] === field) {
optionsColumns.push(item)
found = true
return false
}
return true
})
})
this.options.columns[0] = optionsColumns
this.header.fields = ths
this.header.formatters = formatters
this.initHeader()
this.initToolbar()
this.initSearchText()
this.initBody()
this.resetView()
this.trigger('reorder-column', ths)
}
})
}
orderColumns (order) {
this.columnsSortOrder = order
this.makeColumnsReorderable()
}
}

View File

@ -0,0 +1,145 @@
/**
* @author: Dennis Hernández
* @update zhixin wen <wenzhixin2010@gmail.com>
*/
const rowAttr = (row, index) => ({
id: `customId_${index}`
})
Object.assign($.fn.bootstrapTable.defaults, {
reorderableRows: false,
onDragStyle: null,
onDropStyle: null,
onDragClass: 'reorder-rows-on-drag-class',
dragHandle: '>tbody>tr>td:not(.bs-checkbox)',
useRowAttrFunc: false,
// eslint-disable-next-line no-unused-vars
onReorderRowsDrag (row) {
return false
},
// eslint-disable-next-line no-unused-vars
onReorderRowsDrop (row) {
return false
},
// eslint-disable-next-line no-unused-vars
onReorderRow (newData) {
return false
},
onDragStop () {},
onAllowDrop () {
return true
}
})
Object.assign($.fn.bootstrapTable.events, {
'reorder-row.bs.table': 'onReorderRow'
})
$.BootstrapTable = class extends $.BootstrapTable {
init (...args) {
if (!this.options.reorderableRows) {
super.init(...args)
return
}
if (this.options.useRowAttrFunc) {
this.options.rowAttributes = rowAttr
}
const onPostBody = this.options.onPostBody
this.options.onPostBody = () => {
setTimeout(() => {
this.makeRowsReorderable()
onPostBody.call(this.options, this.options.data)
}, 1)
}
super.init(...args)
}
makeRowsReorderable () {
this.$el.tableDnD({
onDragStyle: this.options.onDragStyle,
onDropStyle: this.options.onDropStyle,
onDragClass: this.options.onDragClass,
onAllowDrop: (hoveredRow, draggedRow) => this.onAllowDrop(hoveredRow, draggedRow),
onDragStop: (table, draggedRow) => this.onDragStop(table, draggedRow),
onDragStart: (table, droppedRow) => this.onDropStart(table, droppedRow),
onDrop: (table, droppedRow) => this.onDrop(table, droppedRow),
dragHandle: this.options.dragHandle
})
}
onDropStart (table, draggingTd) {
this.$draggingTd = $(draggingTd).css('cursor', 'move')
this.draggingIndex = $(this.$draggingTd.parent()).data('index')
// Call the user defined function
this.options.onReorderRowsDrag(this.data[this.draggingIndex])
}
onDragStop (table, draggedRow) {
const rowIndexDraggedRow = $(draggedRow).data('index')
const draggedRowItem = this.data[rowIndexDraggedRow]
this.options.onDragStop(table, draggedRowItem, draggedRow)
}
onAllowDrop (hoveredRow, draggedRow) {
const rowIndexDraggedRow = $(draggedRow).data('index')
const rowIndexHoveredRow = $(hoveredRow).data('index')
const draggedRowItem = this.data[rowIndexDraggedRow]
const hoveredRowItem = this.data[rowIndexHoveredRow]
return this.options.onAllowDrop(hoveredRowItem, draggedRowItem, hoveredRow, draggedRow)
}
onDrop (table) {
this.$draggingTd.css('cursor', '')
const pageNum = this.options.pageNumber
const pageSize = this.options.pageSize
const newData = []
for (let i = 0; i < table.tBodies[0].rows.length; i++) {
const $tr = $(table.tBodies[0].rows[i])
newData.push(this.data[$tr.data('index')])
$tr.data('index', i)
}
const draggingRow = this.data[this.draggingIndex]
const droppedIndex = newData.indexOf(this.data[this.draggingIndex])
const droppedRow = this.data[droppedIndex]
const index = (pageNum - 1) * pageSize + this.options.data.indexOf(this.data[droppedIndex])
this.options.data.splice(this.options.data.indexOf(draggingRow), 1)
this.options.data.splice(index, 0, draggingRow)
this.initSearch()
if (this.options.sidePagination === 'server') {
this.data = [...this.options.data]
}
// Call the user defined function
this.options.onReorderRowsDrop(droppedRow)
// Call the event reorder-row
this.trigger('reorder-row', newData, draggingRow, droppedRow)
}
initSearch () {
this.ignoreInitSort = true
super.initSearch()
}
initSort () {
if (this.ignoreInitSort) {
this.ignoreInitSort = false
return
}
super.initSort()
}
}

View File

@ -0,0 +1,603 @@
/**
* TableDnD plug-in for JQuery, allows you to drag and drop table rows
* You can set up various options to control how the system will work
* Copyright (c) Denis Howlett <denish@isocra.com>
* License: MIT.
* See https://github.com/isocra/TableDnD
*/
!function ($, window, document, undefined) {
var startEvent = 'touchstart mousedown',
moveEvent = 'touchmove mousemove',
endEvent = 'touchend mouseup';
$(document).ready(function () {
function parseStyle(css) {
var objMap = {},
parts = css.match(/([^;:]+)/g) || [];
while (parts.length)
objMap[parts.shift()] = parts.shift().trim();
return objMap;
}
$('table').each(function () {
if ($(this).data('table') === 'dnd') {
$(this).tableDnD({
onDragStyle: $(this).data('ondragstyle') && parseStyle($(this).data('ondragstyle')) || null,
onDropStyle: $(this).data('ondropstyle') && parseStyle($(this).data('ondropstyle')) || null,
onDragClass: $(this).data('ondragclass') === undefined && "tDnD_whileDrag" || $(this).data('ondragclass'),
onDrop: $(this).data('ondrop') && new Function('table', 'row', $(this).data('ondrop')), // 'return eval("'+$(this).data('ondrop')+'");') || null,
onDragStart: $(this).data('ondragstart') && new Function('table', 'row' ,$(this).data('ondragstart')), // 'return eval("'+$(this).data('ondragstart')+'");') || null,
onDragStop: $(this).data('ondragstop') && new Function('table', 'row' ,$(this).data('ondragstop')),
scrollAmount: $(this).data('scrollamount') || 5,
sensitivity: $(this).data('sensitivity') || 10,
hierarchyLevel: $(this).data('hierarchylevel') || 0,
indentArtifact: $(this).data('indentartifact') || '<div class="indent">&nbsp;</div>',
autoWidthAdjust: $(this).data('autowidthadjust') || true,
autoCleanRelations: $(this).data('autocleanrelations') || true,
jsonPretifySeparator: $(this).data('jsonpretifyseparator') || '\t',
serializeRegexp: $(this).data('serializeregexp') && new RegExp($(this).data('serializeregexp')) || /[^\-]*$/,
serializeParamName: $(this).data('serializeparamname') || false,
dragHandle: $(this).data('draghandle') || null
});
}
});
});
jQuery.tableDnD = {
/** Keep hold of the current table being dragged */
currentTable: null,
/** Keep hold of the current drag object if any */
dragObject: null,
/** The current mouse offset */
mouseOffset: null,
/** Remember the old value of X and Y so that we don't do too much processing */
oldX: 0,
oldY: 0,
/** Actually build the structure */
build: function(options) {
// Set up the defaults if any
this.each(function() {
// This is bound to each matching table, set up the defaults and override with user options
this.tableDnDConfig = $.extend({
onDragStyle: null,
onDropStyle: null,
// Add in the default class for whileDragging
onDragClass: "tDnD_whileDrag",
onDrop: null,
onDragStart: null,
onDragStop: null,
scrollAmount: 5,
/** Sensitivity setting will throttle the trigger rate for movement detection */
sensitivity: 10,
/** Hierarchy level to support parent child. 0 switches this functionality off */
hierarchyLevel: 0,
/** The html artifact to prepend the first cell with as indentation */
indentArtifact: '<div class="indent">&nbsp;</div>',
/** Automatically adjust width of first cell */
autoWidthAdjust: true,
/** Automatic clean-up to ensure relationship integrity */
autoCleanRelations: true,
/** Specify a number (4) as number of spaces or any indent string for JSON.stringify */
jsonPretifySeparator: '\t',
/** The regular expression to use to trim row IDs */
serializeRegexp: /[^\-]*$/,
/** If you want to specify another parameter name instead of the table ID */
serializeParamName: false,
/** If you give the name of a class here, then only Cells with this class will be draggable */
dragHandle: null
}, options || {});
// Now make the rows draggable
$.tableDnD.makeDraggable(this);
// Prepare hierarchy support
this.tableDnDConfig.hierarchyLevel
&& $.tableDnD.makeIndented(this);
});
// Don't break the chain
return this;
},
makeIndented: function (table) {
var config = table.tableDnDConfig,
rows = table.rows,
firstCell = $(rows).first().find('td:first')[0],
indentLevel = 0,
cellWidth = 0,
longestCell,
tableStyle;
if ($(table).hasClass('indtd'))
return null;
tableStyle = $(table).addClass('indtd').attr('style');
$(table).css({whiteSpace: "nowrap"});
for (var w = 0; w < rows.length; w++) {
if (cellWidth < $(rows[w]).find('td:first').text().length) {
cellWidth = $(rows[w]).find('td:first').text().length;
longestCell = w;
}
}
$(firstCell).css({width: 'auto'});
for (w = 0; w < config.hierarchyLevel; w++)
$(rows[longestCell]).find('td:first').prepend(config.indentArtifact);
firstCell && $(firstCell).css({width: firstCell.offsetWidth});
tableStyle && $(table).css(tableStyle);
for (w = 0; w < config.hierarchyLevel; w++)
$(rows[longestCell]).find('td:first').children(':first').remove();
config.hierarchyLevel
&& $(rows).each(function () {
indentLevel = $(this).data('level') || 0;
indentLevel <= config.hierarchyLevel
&& $(this).data('level', indentLevel)
|| $(this).data('level', 0);
for (var i = 0; i < $(this).data('level'); i++)
$(this).find('td:first').prepend(config.indentArtifact);
});
return this;
},
/** This function makes all the rows on the table draggable apart from those marked as "NoDrag" */
makeDraggable: function(table) {
var config = table.tableDnDConfig;
config.dragHandle
// We only need to add the event to the specified cells
&& $(config.dragHandle, table).each(function() {
if (! $(this).hasClass("nodrag")) {
// The cell is bound to "this"
$(this).bind(startEvent, function(e) {
if (e.target.tagName === "TD" && event.target.className !== "nodrag") {
$.tableDnD.initialiseDrag($(this).parents('tr')[0], table, this, e, config);
return false;
}
return true;
});
}
})
// For backwards compatibility, we add the event to the whole row
// get all the rows as a wrapped set
|| $(table.rows).each(function() {
// Iterate through each row, the row is bound to "this"
if (! $(this).hasClass("nodrag")) {
$(this).bind(startEvent, function(e) {
if (e.target.tagName === "TD" && event.target.className !== "nodrag") {
$.tableDnD.initialiseDrag(this, table, this, e, config);
return false;
}
}).css("cursor", "move"); // Store the tableDnD object
} else {
$(this).css("cursor", ""); // Remove the cursor if we don't have the nodrag class
}
});
},
currentOrder: function() {
var rows = this.currentTable.rows;
return $.map(rows, function (val) {
return ($(val).data('level') + val.id).replace(/\s/g, '');
}).join('');
},
initialiseDrag: function(dragObject, table, target, e, config) {
this.dragObject = dragObject;
this.currentTable = table;
this.mouseOffset = this.getMouseOffset(target, e);
this.originalOrder = this.currentOrder();
// Now we need to capture the mouse up and mouse move event
// We can use bind so that we don't interfere with other event handlers
$(document)
.bind(moveEvent, this.mousemove)
.bind(endEvent, this.mouseup);
// Call the onDragStart method if there is one
config.onDragStart
&& config.onDragStart(table, target);
},
updateTables: function() {
this.each(function() {
// this is now bound to each matching table
if (this.tableDnDConfig)
$.tableDnD.makeDraggable(this);
});
},
/** Get the mouse coordinates from the event (allowing for browser differences) */
mouseCoords: function(e) {
if (e.originalEvent.changedTouches)
return {
x: e.originalEvent.changedTouches[0].clientX,
y: e.originalEvent.changedTouches[0].clientY
};
if(e.pageX || e.pageY)
return {
x: e.pageX,
y: e.pageY
};
return {
x: e.clientX + document.body.scrollLeft - document.body.clientLeft,
y: e.clientY + document.body.scrollTop - document.body.clientTop
};
},
/** Given a target element and a mouse eent, get the mouse offset from that element.
To do this we need the element's position and the mouse position */
getMouseOffset: function(target, e) {
var mousePos,
docPos;
e = e || window.event;
docPos = this.getPosition(target);
mousePos = this.mouseCoords(e);
return {
x: mousePos.x - docPos.x,
y: mousePos.y - docPos.y
};
},
/** Get the position of an element by going up the DOM tree and adding up all the offsets */
getPosition: function(element) {
var left = 0,
top = 0;
// Safari fix -- thanks to Luis Chato for this!
// Safari 2 doesn't correctly grab the offsetTop of a table row
// this is detailed here:
// http://jacob.peargrove.com/blog/2006/technical/table-row-offsettop-bug-in-safari/
// the solution is likewise noted there, grab the offset of a table cell in the row - the firstChild.
// note that firefox will return a text node as a first child, so designing a more thorough
// solution may need to take that into account, for now this seems to work in firefox, safari, ie
if (element.offsetHeight === 0)
element = element.firstChild; // a table cell
while (element.offsetParent) {
left += element.offsetLeft;
top += element.offsetTop;
element = element.offsetParent;
}
left += element.offsetLeft;
top += element.offsetTop;
return {
x: left,
y: top
};
},
autoScroll: function (mousePos) {
var config = this.currentTable.tableDnDConfig,
yOffset = window.pageYOffset,
windowHeight = window.innerHeight
? window.innerHeight
: document.documentElement.clientHeight
? document.documentElement.clientHeight
: document.body.clientHeight;
// Windows version
// yOffset=document.body.scrollTop;
if (document.all)
if (typeof document.compatMode !== 'undefined'
&& document.compatMode !== 'BackCompat')
yOffset = document.documentElement.scrollTop;
else if (typeof document.body !== 'undefined')
yOffset = document.body.scrollTop;
mousePos.y - yOffset < config.scrollAmount
&& window.scrollBy(0, - config.scrollAmount)
|| windowHeight - (mousePos.y - yOffset) < config.scrollAmount
&& window.scrollBy(0, config.scrollAmount);
},
moveVerticle: function (moving, currentRow) {
if (0 !== moving.vertical
// If we're over a row then move the dragged row to there so that the user sees the
// effect dynamically
&& currentRow
&& this.dragObject !== currentRow
&& this.dragObject.parentNode === currentRow.parentNode)
0 > moving.vertical
&& this.dragObject.parentNode.insertBefore(this.dragObject, currentRow.nextSibling)
|| 0 < moving.vertical
&& this.dragObject.parentNode.insertBefore(this.dragObject, currentRow);
},
moveHorizontal: function (moving, currentRow) {
var config = this.currentTable.tableDnDConfig,
currentLevel;
if (!config.hierarchyLevel
|| 0 === moving.horizontal
// We only care if moving left or right on the current row
|| !currentRow
|| this.dragObject !== currentRow)
return null;
currentLevel = $(currentRow).data('level');
0 < moving.horizontal
&& currentLevel > 0
&& $(currentRow).find('td:first').children(':first').remove()
&& $(currentRow).data('level', --currentLevel);
0 > moving.horizontal
&& currentLevel < config.hierarchyLevel
&& $(currentRow).prev().data('level') >= currentLevel
&& $(currentRow).children(':first').prepend(config.indentArtifact)
&& $(currentRow).data('level', ++currentLevel);
},
mousemove: function(e) {
var dragObj = $($.tableDnD.dragObject),
config = $.tableDnD.currentTable.tableDnDConfig,
currentRow,
mousePos,
moving,
x,
y;
e && e.preventDefault();
if (!$.tableDnD.dragObject)
return false;
// prevent touch device screen scrolling
e.type === 'touchmove'
&& event.preventDefault(); // TODO verify this is event and not really e
// update the style to show we're dragging
config.onDragClass
&& dragObj.addClass(config.onDragClass)
|| dragObj.css(config.onDragStyle);
mousePos = $.tableDnD.mouseCoords(e);
x = mousePos.x - $.tableDnD.mouseOffset.x;
y = mousePos.y - $.tableDnD.mouseOffset.y;
// auto scroll the window
$.tableDnD.autoScroll(mousePos);
currentRow = $.tableDnD.findDropTargetRow(dragObj, y);
moving = $.tableDnD.findDragDirection(x, y);
$.tableDnD.moveVerticle(moving, currentRow);
$.tableDnD.moveHorizontal(moving, currentRow);
return false;
},
findDragDirection: function (x,y) {
var sensitivity = this.currentTable.tableDnDConfig.sensitivity,
oldX = this.oldX,
oldY = this.oldY,
xMin = oldX - sensitivity,
xMax = oldX + sensitivity,
yMin = oldY - sensitivity,
yMax = oldY + sensitivity,
moving = {
horizontal: x >= xMin && x <= xMax ? 0 : x > oldX ? -1 : 1,
vertical : y >= yMin && y <= yMax ? 0 : y > oldY ? -1 : 1
};
// update the old value
if (moving.horizontal !== 0)
this.oldX = x;
if (moving.vertical !== 0)
this.oldY = y;
return moving;
},
/** We're only worried about the y position really, because we can only move rows up and down */
findDropTargetRow: function(draggedRow, y) {
var rowHeight = 0,
rows = this.currentTable.rows,
config = this.currentTable.tableDnDConfig,
rowY = 0,
row = null;
for (var i = 0; i < rows.length; i++) {
row = rows[i];
rowY = this.getPosition(row).y;
rowHeight = parseInt(row.offsetHeight) / 2;
if (row.offsetHeight === 0) {
rowY = this.getPosition(row.firstChild).y;
rowHeight = parseInt(row.firstChild.offsetHeight) / 2;
}
// Because we always have to insert before, we need to offset the height a bit
if (y > (rowY - rowHeight) && y < (rowY + rowHeight))
// that's the row we're over
// If it's the same as the current row, ignore it
if (draggedRow.is(row)
|| (config.onAllowDrop
&& !config.onAllowDrop(draggedRow, row))
// If a row has nodrop class, then don't allow dropping (inspired by John Tarr and Famic)
|| $(row).hasClass("nodrop"))
return null;
else
return row;
}
return null;
},
processMouseup: function() {
if (!this.currentTable || !this.dragObject)
return null;
var config = this.currentTable.tableDnDConfig,
droppedRow = this.dragObject,
parentLevel = 0,
myLevel = 0;
// Unbind the event handlers
$(document)
.unbind(moveEvent, this.mousemove)
.unbind(endEvent, this.mouseup);
config.hierarchyLevel
&& config.autoCleanRelations
&& $(this.currentTable.rows).first().find('td:first').children().each(function () {
myLevel = $(this).parents('tr:first').data('level');
myLevel
&& $(this).parents('tr:first').data('level', --myLevel)
&& $(this).remove();
})
&& config.hierarchyLevel > 1
&& $(this.currentTable.rows).each(function () {
myLevel = $(this).data('level');
if (myLevel > 1) {
parentLevel = $(this).prev().data('level');
while (myLevel > parentLevel + 1) {
$(this).find('td:first').children(':first').remove();
$(this).data('level', --myLevel);
}
}
});
// If we have a dragObject, then we need to release it,
// The row will already have been moved to the right place so we just reset stuff
config.onDragClass
&& $(droppedRow).removeClass(config.onDragClass)
|| $(droppedRow).css(config.onDropStyle);
this.dragObject = null;
// Call the onDrop method if there is one
config.onDrop
&& this.originalOrder !== this.currentOrder()
&& $(droppedRow).hide().fadeIn('fast')
&& config.onDrop(this.currentTable, droppedRow);
// Call the onDragStop method if there is one
config.onDragStop
&& config.onDragStop(this.currentTable, droppedRow);
this.currentTable = null; // let go of the table too
},
mouseup: function(e) {
e && e.preventDefault();
$.tableDnD.processMouseup();
return false;
},
jsonize: function(pretify) {
var table = this.currentTable;
if (pretify)
return JSON.stringify(
this.tableData(table),
null,
table.tableDnDConfig.jsonPretifySeparator
);
return JSON.stringify(this.tableData(table));
},
serialize: function() {
return $.param(this.tableData(this.currentTable));
},
serializeTable: function(table) {
var result = "";
var paramName = table.tableDnDConfig.serializeParamName || table.id;
var rows = table.rows;
for (var i=0; i<rows.length; i++) {
if (result.length > 0) result += "&";
var rowId = rows[i].id;
if (rowId && table.tableDnDConfig && table.tableDnDConfig.serializeRegexp) {
rowId = rowId.match(table.tableDnDConfig.serializeRegexp)[0];
result += paramName + '[]=' + rowId;
}
}
return result;
},
serializeTables: function() {
var result = [];
$('table').each(function() {
this.id && result.push($.param($.tableDnD.tableData(this)));
});
return result.join('&');
},
tableData: function (table) {
var config = table.tableDnDConfig,
previousIDs = [],
currentLevel = 0,
indentLevel = 0,
rowID = null,
data = {},
getSerializeRegexp,
paramName,
currentID,
rows;
if (!table)
table = this.currentTable;
if (!table || !table.rows || !table.rows.length)
return {error: { code: 500, message: "Not a valid table."}};
if (!table.id && !config.serializeParamName)
return {error: { code: 500, message: "No serializable unique id provided."}};
rows = config.autoCleanRelations
&& table.rows
|| $.makeArray(table.rows);
paramName = config.serializeParamName || table.id;
currentID = paramName;
getSerializeRegexp = function (rowId) {
if (rowId && config && config.serializeRegexp)
return rowId.match(config.serializeRegexp)[0];
return rowId;
};
data[currentID] = [];
!config.autoCleanRelations
&& $(rows[0]).data('level')
&& rows.unshift({id: 'undefined'});
for (var i=0; i < rows.length; i++) {
if (config.hierarchyLevel) {
indentLevel = $(rows[i]).data('level') || 0;
if (indentLevel === 0) {
currentID = paramName;
previousIDs = [];
}
else if (indentLevel > currentLevel) {
previousIDs.push([currentID, currentLevel]);
currentID = getSerializeRegexp(rows[i-1].id);
}
else if (indentLevel < currentLevel) {
for (var h = 0; h < previousIDs.length; h++) {
if (previousIDs[h][1] === indentLevel)
currentID = previousIDs[h][0];
if (previousIDs[h][1] >= currentLevel)
previousIDs[h][1] = 0;
}
}
currentLevel = indentLevel;
if (!$.isArray(data[currentID]))
data[currentID] = [];
rowID = getSerializeRegexp(rows[i].id);
rowID && data[currentID].push(rowID);
}
else {
rowID = getSerializeRegexp(rows[i].id);
rowID && data[currentID].push(rowID);
}
}
return data;
}
};
jQuery.fn.extend(
{
tableDnD : $.tableDnD.build,
tableDnDUpdate : $.tableDnD.updateTables,
tableDnDSerialize : $.proxy($.tableDnD.serialize, $.tableDnD),
tableDnDSerializeAll : $.tableDnD.serializeTables,
tableDnDData : $.proxy($.tableDnD.tableData, $.tableDnD)
}
);
}(jQuery, window, window.document);

View File

@ -0,0 +1,68 @@
/**
* @author: Dennis Hernández
* @version: v2.0.0
*/
const isInit = that => that.$el.data('resizableColumns') !== undefined
const initResizable = that => {
if (
that.options.resizable &&
!that.options.cardView &&
!isInit(that) &&
that.$el.is(':visible')
) {
that.$el.resizableColumns({
store: window.store
})
}
}
const destroy = that => {
if (isInit(that)) {
that.$el.data('resizableColumns').destroy()
}
}
const reInitResizable = that => {
destroy(that)
initResizable(that)
}
Object.assign($.fn.bootstrapTable.defaults, {
resizable: false
})
$.BootstrapTable = class extends $.BootstrapTable {
initBody (...args) {
super.initBody(...args)
this.$el.off('column-switch.bs.table page-change.bs.table')
.on('column-switch.bs.table page-change.bs.table', () => {
reInitResizable(this)
})
reInitResizable(this)
}
toggleView (...args) {
super.toggleView(...args)
if (this.options.resizable && this.options.cardView) {
// Destroy the plugin
destroy(this)
}
}
resetView (...args) {
super.resetView(...args)
if (this.options.resizable) {
// because in fitHeader function, we use setTimeout(func, 100);
setTimeout(() => {
initResizable(this)
}, 100)
}
}
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,109 @@
/**
* Bootstrap Table Chinese translation
* Author: Zhixin Wen<wenzhixin2010@gmail.com>
*/
$.fn.bootstrapTable.locales['zh-CN'] = {
formatShowSearch: function formatShowSearch() {
return '隐藏/显示搜索';
},
formatPageGo: function formatPageGo() {
return '跳转';
},
formatCopyRows: function formatCopyRows() {
return '复制行';
},
formatPrint: function formatPrint() {
return '打印';
},
formatLoadingMessage: function formatLoadingMessage() {
return '正在努力地加载数据中,请稍候';
},
formatRecordsPerPage: function formatRecordsPerPage(pageNumber) {
return "每页显示 ".concat(pageNumber, " 条记录");
},
formatShowingRows: function formatShowingRows(pageFrom, pageTo, totalRows, totalNotFiltered) {
if (totalNotFiltered !== undefined && totalNotFiltered > 0 && totalNotFiltered > totalRows) {
return "显示第 ".concat(pageFrom, " 到第 ").concat(pageTo, " 条记录,总共 ").concat(totalRows, " 条记录(从 ").concat(totalNotFiltered, " 总记录中过滤)");
}
return "显示第 ".concat(pageFrom, " 到第 ").concat(pageTo, " 条记录,总共 ").concat(totalRows, " 条记录");
},
formatSRPaginationPreText: function formatSRPaginationPreText() {
return '上一页';
},
formatSRPaginationPageText: function formatSRPaginationPageText(page) {
return "第".concat(page, "页");
},
formatSRPaginationNextText: function formatSRPaginationNextText() {
return '下一页';
},
formatDetailPagination: function formatDetailPagination(totalRows) {
return "总共 ".concat(totalRows, " 条记录");
},
formatClearSearch: function formatClearSearch() {
return '清空过滤';
},
formatSearch: function formatSearch() {
return '搜索';
},
formatNoMatches: function formatNoMatches() {
return '没有找到匹配的记录';
},
formatPaginationSwitch: function formatPaginationSwitch() {
return '隐藏/显示分页';
},
formatPaginationSwitchDown: function formatPaginationSwitchDown() {
return '显示分页';
},
formatPaginationSwitchUp: function formatPaginationSwitchUp() {
return '隐藏分页';
},
formatRefresh: function formatRefresh() {
return '刷新';
},
formatToggle: function formatToggle() {
return '切换';
},
formatToggleOn: function formatToggleOn() {
return '显示卡片视图';
},
formatToggleOff: function formatToggleOff() {
return '隐藏卡片视图';
},
formatColumns: function formatColumns() {
return '列';
},
formatColumnsToggleAll: function formatColumnsToggleAll() {
return '切换所有';
},
formatFullscreen: function formatFullscreen() {
return '全屏';
},
formatAllRows: function formatAllRows() {
return '所有';
},
formatAutoRefresh: function formatAutoRefresh() {
return '自动刷新';
},
formatExport: function formatExport() {
return '导出数据';
},
formatJumpTo: function formatJumpTo() {
return '跳转';
},
formatAdvancedSearch: function formatAdvancedSearch() {
return '高级搜索';
},
formatAdvancedCloseButton: function formatAdvancedCloseButton() {
return '关闭';
},
formatFilterControlSwitch: function formatFilterControlSwitch() {
return '隐藏/显示过滤控制';
},
formatFilterControlSwitchHide: function formatFilterControlSwitchHide() {
return '隐藏过滤控制';
},
formatFilterControlSwitchShow: function formatFilterControlSwitchShow() {
return '显示过滤控制';
}
};
$.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['zh-CN']);

View File

@ -0,0 +1 @@
$.fn.bootstrapTable.locales["zh-CN"]={formatShowSearch:function formatShowSearch(){return"隐藏/显示搜索"},formatPageGo:function formatPageGo(){return"跳转"},formatCopyRows:function formatCopyRows(){return"复制行"},formatPrint:function formatPrint(){return"打印"},formatLoadingMessage:function formatLoadingMessage(){return"正在努力地加载数据中,请稍候"},formatRecordsPerPage:function formatRecordsPerPage(pageNumber){return"每页显示 ".concat(pageNumber," 条记录")},formatShowingRows:function formatShowingRows(pageFrom,pageTo,totalRows,totalNotFiltered){if(totalNotFiltered!==undefined&&totalNotFiltered>0&&totalNotFiltered>totalRows){return"显示第 ".concat(pageFrom," 到第 ").concat(pageTo," 条记录,总共 ").concat(totalRows," 条记录(从 ").concat(totalNotFiltered," 总记录中过滤)")}return"显示第 ".concat(pageFrom," 到第 ").concat(pageTo," 条记录,总共 ").concat(totalRows," 条记录")},formatSRPaginationPreText:function formatSRPaginationPreText(){return"上一页"},formatSRPaginationPageText:function formatSRPaginationPageText(page){return"第".concat(page,"页")},formatSRPaginationNextText:function formatSRPaginationNextText(){return"下一页"},formatDetailPagination:function formatDetailPagination(totalRows){return"总共 ".concat(totalRows," 条记录")},formatClearSearch:function formatClearSearch(){return"清空过滤"},formatSearch:function formatSearch(){return"搜索"},formatNoMatches:function formatNoMatches(){return"没有找到匹配的记录"},formatPaginationSwitch:function formatPaginationSwitch(){return"隐藏/显示分页"},formatPaginationSwitchDown:function formatPaginationSwitchDown(){return"显示分页"},formatPaginationSwitchUp:function formatPaginationSwitchUp(){return"隐藏分页"},formatRefresh:function formatRefresh(){return"刷新"},formatToggle:function formatToggle(){return"切换"},formatToggleOn:function formatToggleOn(){return"显示卡片视图"},formatToggleOff:function formatToggleOff(){return"隐藏卡片视图"},formatColumns:function formatColumns(){return"列"},formatColumnsToggleAll:function formatColumnsToggleAll(){return"切换所有"},formatFullscreen:function formatFullscreen(){return"全屏"},formatAllRows:function formatAllRows(){return"所有"},formatAutoRefresh:function formatAutoRefresh(){return"自动刷新"},formatExport:function formatExport(){return"导出数据"},formatJumpTo:function formatJumpTo(){return"跳转"},formatAdvancedSearch:function formatAdvancedSearch(){return"高级搜索"},formatAdvancedCloseButton:function formatAdvancedCloseButton(){return"关闭"},formatFilterControlSwitch:function formatFilterControlSwitch(){return"隐藏/显示过滤控制"},formatFilterControlSwitchHide:function formatFilterControlSwitchHide(){return"隐藏过滤控制"},formatFilterControlSwitchShow:function formatFilterControlSwitchShow(){return"显示过滤控制"}};$.extend($.fn.bootstrapTable.defaults,$.fn.bootstrapTable.locales["zh-CN"]);

View File

@ -0,0 +1,304 @@
/*!
* Cropper.js v1.5.12
* https://fengyuanchen.github.io/cropperjs
*
* Copyright 2015-present Chen Fengyuan
* Released under the MIT license
*
* Date: 2021-06-12T08:00:11.623Z
*/
.cropper-container {
direction: ltr;
font-size: 0;
line-height: 0;
position: relative;
-ms-touch-action: none;
touch-action: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.cropper-container img {
display: block;
height: 100%;
image-orientation: 0deg;
max-height: none !important;
max-width: none !important;
min-height: 0 !important;
min-width: 0 !important;
width: 100%;
}
.cropper-wrap-box,
.cropper-canvas,
.cropper-drag-box,
.cropper-crop-box,
.cropper-modal {
bottom: 0;
left: 0;
position: absolute;
right: 0;
top: 0;
}
.cropper-wrap-box,
.cropper-canvas {
overflow: hidden;
}
.cropper-drag-box {
background-color: #fff;
opacity: 0;
}
.cropper-modal {
background-color: #000;
opacity: 0.5;
}
.cropper-view-box {
display: block;
height: 100%;
outline: 1px solid #39f;
outline-color: rgba(51, 153, 255, 0.75);
overflow: hidden;
width: 100%;
}
.cropper-dashed {
border: 0 dashed #eee;
display: block;
opacity: 0.5;
position: absolute;
}
.cropper-dashed.dashed-h {
border-bottom-width: 1px;
border-top-width: 1px;
height: calc(100% / 3);
left: 0;
top: calc(100% / 3);
width: 100%;
}
.cropper-dashed.dashed-v {
border-left-width: 1px;
border-right-width: 1px;
height: 100%;
left: calc(100% / 3);
top: 0;
width: calc(100% / 3);
}
.cropper-center {
display: block;
height: 0;
left: 50%;
opacity: 0.75;
position: absolute;
top: 50%;
width: 0;
}
.cropper-center::before,
.cropper-center::after {
background-color: #eee;
content: ' ';
display: block;
position: absolute;
}
.cropper-center::before {
height: 1px;
left: -3px;
top: 0;
width: 7px;
}
.cropper-center::after {
height: 7px;
left: 0;
top: -3px;
width: 1px;
}
.cropper-face,
.cropper-line,
.cropper-point {
display: block;
height: 100%;
opacity: 0.1;
position: absolute;
width: 100%;
}
.cropper-face {
background-color: #fff;
left: 0;
top: 0;
}
.cropper-line {
background-color: #39f;
}
.cropper-line.line-e {
cursor: ew-resize;
right: -3px;
top: 0;
width: 5px;
}
.cropper-line.line-n {
cursor: ns-resize;
height: 5px;
left: 0;
top: -3px;
}
.cropper-line.line-w {
cursor: ew-resize;
left: -3px;
top: 0;
width: 5px;
}
.cropper-line.line-s {
bottom: -3px;
cursor: ns-resize;
height: 5px;
left: 0;
}
.cropper-point {
background-color: #39f;
height: 5px;
opacity: 0.75;
width: 5px;
}
.cropper-point.point-e {
cursor: ew-resize;
margin-top: -3px;
right: -3px;
top: 50%;
}
.cropper-point.point-n {
cursor: ns-resize;
left: 50%;
margin-left: -3px;
top: -3px;
}
.cropper-point.point-w {
cursor: ew-resize;
left: -3px;
margin-top: -3px;
top: 50%;
}
.cropper-point.point-s {
bottom: -3px;
cursor: s-resize;
left: 50%;
margin-left: -3px;
}
.cropper-point.point-ne {
cursor: nesw-resize;
right: -3px;
top: -3px;
}
.cropper-point.point-nw {
cursor: nwse-resize;
left: -3px;
top: -3px;
}
.cropper-point.point-sw {
bottom: -3px;
cursor: nesw-resize;
left: -3px;
}
.cropper-point.point-se {
bottom: -3px;
cursor: nwse-resize;
height: 20px;
opacity: 1;
right: -3px;
width: 20px;
}
@media (min-width: 768px) {
.cropper-point.point-se {
height: 15px;
width: 15px;
}
}
@media (min-width: 992px) {
.cropper-point.point-se {
height: 10px;
width: 10px;
}
}
@media (min-width: 1200px) {
.cropper-point.point-se {
height: 5px;
opacity: 0.75;
width: 5px;
}
}
.cropper-point.point-se::before {
background-color: #39f;
bottom: -50%;
content: ' ';
display: block;
height: 200%;
opacity: 0;
position: absolute;
right: -50%;
width: 200%;
}
.cropper-invisible {
opacity: 0;
}
.cropper-bg {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC');
}
.cropper-hide {
display: block;
height: 0;
position: absolute;
width: 0;
}
.cropper-hidden {
display: none !important;
}
.cropper-move {
cursor: move;
}
.cropper-crop {
cursor: crosshair;
}
.cropper-disabled .cropper-drag-box,
.cropper-disabled .cropper-face,
.cropper-disabled .cropper-line,
.cropper-disabled .cropper-point {
cursor: not-allowed;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,9 @@
/*!
* Cropper.js v1.5.12
* https://fengyuanchen.github.io/cropperjs
*
* Copyright 2015-present Chen Fengyuan
* Released under the MIT license
*
* Date: 2021-06-12T08:00:11.623Z
*/.cropper-container{direction:ltr;font-size:0;line-height:0;position:relative;-ms-touch-action:none;touch-action:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.cropper-container img{image-orientation:0deg;display:block;height:100%;max-height:none!important;max-width:none!important;min-height:0!important;min-width:0!important;width:100%}.cropper-canvas,.cropper-crop-box,.cropper-drag-box,.cropper-modal,.cropper-wrap-box{bottom:0;left:0;position:absolute;right:0;top:0}.cropper-canvas,.cropper-wrap-box{overflow:hidden}.cropper-drag-box{background-color:#fff;opacity:0}.cropper-modal{background-color:#000;opacity:.5}.cropper-view-box{display:block;height:100%;outline:1px solid #39f;outline-color:rgba(51,153,255,.75);overflow:hidden;width:100%}.cropper-dashed{border:0 dashed #eee;display:block;opacity:.5;position:absolute}.cropper-dashed.dashed-h{border-bottom-width:1px;border-top-width:1px;height:33.33333%;left:0;top:33.33333%;width:100%}.cropper-dashed.dashed-v{border-left-width:1px;border-right-width:1px;height:100%;left:33.33333%;top:0;width:33.33333%}.cropper-center{display:block;height:0;left:50%;opacity:.75;position:absolute;top:50%;width:0}.cropper-center:after,.cropper-center:before{background-color:#eee;content:" ";display:block;position:absolute}.cropper-center:before{height:1px;left:-3px;top:0;width:7px}.cropper-center:after{height:7px;left:0;top:-3px;width:1px}.cropper-face,.cropper-line,.cropper-point{display:block;height:100%;opacity:.1;position:absolute;width:100%}.cropper-face{background-color:#fff;left:0;top:0}.cropper-line{background-color:#39f}.cropper-line.line-e{cursor:ew-resize;right:-3px;top:0;width:5px}.cropper-line.line-n{cursor:ns-resize;height:5px;left:0;top:-3px}.cropper-line.line-w{cursor:ew-resize;left:-3px;top:0;width:5px}.cropper-line.line-s{bottom:-3px;cursor:ns-resize;height:5px;left:0}.cropper-point{background-color:#39f;height:5px;opacity:.75;width:5px}.cropper-point.point-e{cursor:ew-resize;margin-top:-3px;right:-3px;top:50%}.cropper-point.point-n{cursor:ns-resize;left:50%;margin-left:-3px;top:-3px}.cropper-point.point-w{cursor:ew-resize;left:-3px;margin-top:-3px;top:50%}.cropper-point.point-s{bottom:-3px;cursor:s-resize;left:50%;margin-left:-3px}.cropper-point.point-ne{cursor:nesw-resize;right:-3px;top:-3px}.cropper-point.point-nw{cursor:nwse-resize;left:-3px;top:-3px}.cropper-point.point-sw{bottom:-3px;cursor:nesw-resize;left:-3px}.cropper-point.point-se{bottom:-3px;cursor:nwse-resize;height:20px;opacity:1;right:-3px;width:20px}@media (min-width:768px){.cropper-point.point-se{height:15px;width:15px}}@media (min-width:992px){.cropper-point.point-se{height:10px;width:10px}}@media (min-width:1200px){.cropper-point.point-se{height:5px;opacity:.75;width:5px}}.cropper-point.point-se:before{background-color:#39f;bottom:-50%;content:" ";display:block;height:200%;opacity:0;position:absolute;right:-50%;width:200%}.cropper-invisible{opacity:0}.cropper-bg{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC")}.cropper-hide{display:block;height:0;position:absolute;width:0}.cropper-hidden{display:none!important}.cropper-move{cursor:move}.cropper-crop{cursor:crosshair}.cropper-disabled .cropper-drag-box,.cropper-disabled .cropper-face,.cropper-disabled .cropper-line,.cropper-disabled .cropper-point{cursor:not-allowed}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,406 @@
/*!
* jQuery cxSelect
* @name jquery.cxselect.js
* @version 1.4.2
* @date 2017-09-26
* @author ciaoca
* @email ciaoca@gmail.com
* @site https://github.com/ciaoca/cxSelect
* @license Released under the MIT license
*/
(function(factory) {
if (typeof define === 'function' && define.amd) {
define(['jquery'], factory);
} else {
factory(window.jQuery || window.Zepto || window.$);
};
}(function($) {
var cxSelect = function() {
var self = this;
var dom, settings, callback;
// 分配参数
for (var i = 0, l = arguments.length; i < l; i++) {
if (cxSelect.isJquery(arguments[i]) || cxSelect.isZepto(arguments[i])) {
dom = arguments[i];
} else if (cxSelect.isElement(arguments[i])) {
dom = $(arguments[i]);
} else if (typeof arguments[i] === 'function') {
callback = arguments[i];
} else if (typeof arguments[i] === 'object') {
settings = arguments[i];
};
};
var api = new cxSelect.init(dom, settings);
if (typeof callback === 'function') {
callback(api);
};
return api;
};
cxSelect.isElement = function(o){
if (o && (typeof HTMLElement === 'function' || typeof HTMLElement === 'object') && o instanceof HTMLElement) {
return true;
} else {
return (o && o.nodeType && o.nodeType === 1) ? true : false;
};
};
cxSelect.isJquery = function(o){
return (o && o.length && (typeof jQuery === 'function' || typeof jQuery === 'object') && o instanceof jQuery) ? true : false;
};
cxSelect.isZepto = function(o){
return (o && o.length && (typeof Zepto === 'function' || typeof Zepto === 'object') && Zepto.zepto.isZ(o)) ? true : false;
};
cxSelect.getIndex = function(n, required) {
return required ? n : n - 1;
};
cxSelect.getData = function(data, space) {
if (typeof space === 'string' && space.length) {
space = space.split('.');
for (var i = 0, l = space.length; i < l; i++) {
data = data[space[i]];
};
};
return data;
};
cxSelect.init = function(dom, settings) {
var self = this;
if (!cxSelect.isJquery(dom) && !cxSelect.isZepto(dom)) {return};
var theSelect = {
dom: {
box: dom
}
};
self.attach = cxSelect.attach.bind(theSelect);
self.detach = cxSelect.detach.bind(theSelect);
self.setOptions = cxSelect.setOptions.bind(theSelect);
self.clear = cxSelect.clear.bind(theSelect);
theSelect.changeEvent = function() {
cxSelect.selectChange.call(theSelect, this.className);
};
theSelect.settings = $.extend({}, $.cxSelect.defaults, settings, {
url: theSelect.dom.box.data('url'),
emptyStyle: theSelect.dom.box.data('emptyStyle'),
required: theSelect.dom.box.data('required'),
firstTitle: theSelect.dom.box.data('firstTitle'),
firstValue: theSelect.dom.box.data('firstValue'),
jsonSpace: theSelect.dom.box.data('jsonSpace'),
jsonName: theSelect.dom.box.data('jsonName'),
jsonValue: theSelect.dom.box.data('jsonValue'),
jsonSub: theSelect.dom.box.data('jsonSub')
});
var _dataSelects = theSelect.dom.box.data('selects');
if (typeof _dataSelects === 'string' && _dataSelects.length) {
theSelect.settings.selects = _dataSelects.split(',');
};
self.setOptions();
self.attach();
// 使用独立接口获取数据
if (!theSelect.settings.url && !theSelect.settings.data) {
cxSelect.start.apply(theSelect);
// 设置自定义数据
} else if ($.isArray(theSelect.settings.data)) {
cxSelect.start.call(theSelect, theSelect.settings.data);
// 设置 URL通过 Ajax 获取数据
} else if (typeof theSelect.settings.url === 'string' && theSelect.settings.url.length) {
$.getJSON(theSelect.settings.url, function(json) {
cxSelect.start.call(theSelect, json);
});
};
};
// 设置参数
cxSelect.setOptions = function(opts) {
var self = this;
if (opts) {
$.extend(self.settings, opts);
};
// 初次或重设选择器组
if (!$.isArray(self.selectArray) || !self.selectArray.length || (opts && opts.selects)) {
self.selectArray = [];
if ($.isArray(self.settings.selects) && self.settings.selects.length) {
var _tempSelect;
for (var i = 0, l = self.settings.selects.length; i < l; i++) {
_tempSelect = self.dom.box.find('select.' + self.settings.selects[i]);
if (!_tempSelect || !_tempSelect.length) {break};
self.selectArray.push(_tempSelect);
};
};
};
if (opts) {
if (!$.isArray(opts.data) && typeof opts.url === 'string' && opts.url.length) {
$.getJSON(self.settings.url, function(json) {
cxSelect.start.call(self, json);
});
} else {
cxSelect.start.call(self, opts.data);
};
};
};
// 绑定
cxSelect.attach = function() {
var self = this;
if (!self.attachStatus) {
self.dom.box.on('change', 'select', self.changeEvent);
};
if (typeof self.attachStatus === 'boolean') {
cxSelect.start.call(self);
};
self.attachStatus = true;
};
// 移除绑定
cxSelect.detach = function() {
var self = this;
self.dom.box.off('change', 'select', self.changeEvent);
self.attachStatus = false;
};
// 清空选项
cxSelect.clear = function(index) {
var self = this;
var _style = {
display: '',
visibility: ''
};
index = isNaN(index) ? 0 : index;
// 清空后面的 select
for (var i = index, l = self.selectArray.length; i < l; i++) {
self.selectArray[i].empty().prop('disabled', true);
if (self.settings.emptyStyle === 'none') {
_style.display = 'none';
} else if (self.settings.emptyStyle === 'hidden') {
_style.visibility = 'hidden';
};
self.selectArray[i].css(_style);
};
};
cxSelect.start = function(data) {
var self = this;
if ($.isArray(data)) {
self.settings.data = cxSelect.getData(data, self.settings.jsonSpace);
};
if (!self.selectArray.length) {return};
// 保存默认值
for (var i = 0, l = self.selectArray.length; i < l; i++) {
if (typeof self.selectArray[i].attr('data-value') !== 'string' && self.selectArray[i][0].options.length) {
self.selectArray[i].attr('data-value', self.selectArray[i].val());
};
};
if (self.settings.data || (typeof self.selectArray[0].data('url') === 'string' && self.selectArray[0].data('url').length)) {
cxSelect.getOptionData.call(self, 0);
} else if (self.selectArray[0][0].options.length && typeof self.selectArray[0].attr('data-value') === 'string' && self.selectArray[0].attr('data-value').length) {
self.selectArray[0].val(self.selectArray[0].attr('data-value'));
cxSelect.getOptionData.call(self, 1);
} else {
self.selectArray[0].prop('disabled', false).css({
'display': '',
'visibility': ''
});
};
};
// 获取选项数据
cxSelect.getOptionData = function(index) {
var self = this;
if (typeof index !== 'number' || isNaN(index) || index < 0 || index >= self.selectArray.length) {return};
var _indexPrev = index - 1;
var _select = self.selectArray[index];
var _selectData;
var _valueIndex;
var _dataUrl = _select.data('url');
var _jsonSpace = typeof _select.data('jsonSpace') === 'undefined' ? self.settings.jsonSpace : _select.data('jsonSpace');
var _query = {};
var _queryName;
var _selectName;
var _selectValue;
cxSelect.clear.call(self, index);
// 使用独立接口
if (typeof _dataUrl === 'string' && _dataUrl.length) {
if (index > 0) {
for (var i = 0, j = 1; i < index; i++, j++) {
_queryName = self.selectArray[j].data('queryName');
_selectName = self.selectArray[i].attr('name');
_selectValue = self.selectArray[i].val();
if (typeof _queryName === 'string' && _queryName.length) {
_query[_queryName] = _selectValue;
} else if (typeof _selectName === 'string' && _selectName.length) {
_query[_selectName] = _selectValue;
};
};
};
$.getJSON(_dataUrl, _query, function(json) {
_selectData = cxSelect.getData(json, _jsonSpace);
cxSelect.buildOption.call(self, index, _selectData);
});
// 使用整合数据
} else if (self.settings.data && typeof self.settings.data === 'object') {
_selectData = self.settings.data;
for (var i = 0; i < index; i++) {
_valueIndex = cxSelect.getIndex(self.selectArray[i][0].selectedIndex, typeof self.selectArray[i].data('required') === 'boolean' ? self.selectArray[i].data('required') : self.settings.required);
if (typeof _selectData[_valueIndex] === 'object' && $.isArray(_selectData[_valueIndex][self.settings.jsonSub]) && _selectData[_valueIndex][self.settings.jsonSub].length) {
_selectData = _selectData[_valueIndex][self.settings.jsonSub];
} else {
_selectData = null;
break;
};
};
cxSelect.buildOption.call(self, index, _selectData);
};
};
// 构建选项列表
cxSelect.buildOption = function(index, data) {
var self = this;
var _select = self.selectArray[index];
var _required = typeof _select.data('required') === 'boolean' ? _select.data('required') : self.settings.required;
var _firstTitle = typeof _select.data('firstTitle') === 'undefined' ? self.settings.firstTitle : _select.data('firstTitle');
var _firstValue = typeof _select.data('firstValue') === 'undefined' ? self.settings.firstValue : _select.data('firstValue');
var _jsonName = typeof _select.data('jsonName') === 'undefined' ? self.settings.jsonName : _select.data('jsonName');
var _jsonValue = typeof _select.data('jsonValue') === 'undefined' ? self.settings.jsonValue : _select.data('jsonValue');
if (!$.isArray(data)) {return};
var _html = !_required ? '<option value="' + String(_firstValue) + '">' + String(_firstTitle) + '</option>' : '';
// 区分标题、值的数据
if (typeof _jsonName === 'string' && _jsonName.length) {
// 无值字段时使用标题作为值
if (typeof _jsonValue !== 'string' || !_jsonValue.length) {
_jsonValue = _jsonName;
};
for (var i = 0, l = data.length; i < l; i++) {
_html += '<option value="' + String(data[i][_jsonValue]) + '">' + String(data[i][_jsonName]) + '</option>';
};
// 数组即为值的数据
} else {
for (var i = 0, l = data.length; i < l; i++) {
_html += '<option value="' + String(data[i]) + '">' + String(data[i]) + '</option>';
};
};
_select.html(_html).prop('disabled', false).css({
'display': '',
'visibility': ''
});
// 初次加载设置默认值
if (typeof _select.attr('data-value') === 'string') {
_select.val(String(_select.attr('data-value'))).removeAttr('data-value');
if (_select[0].selectedIndex < 0) {
_select[0].options[0].selected = true;
};
};
if (_required || _select[0].selectedIndex > 0) {
_select.trigger('change');
};
};
// 改变选择时的处理
cxSelect.selectChange = function(name) {
var self = this;
if (typeof name !== 'string' || !name.length) {return};
var index;
name = name.replace(/\s+/g, ',');
name = ',' + name + ',';
// 获取当前 select 位置
for (var i = 0, l = self.selectArray.length; i < l; i++) {
if (name.indexOf(',' + self.settings.selects[i] + ',') > -1) {
index = i;
break;
};
};
if (typeof index === 'number' && index > -1) {
index += 1;
cxSelect.getOptionData.call(self, index);
};
};
$.cxSelect = function() {
return cxSelect.apply(this, arguments);
};
// 默认值
$.cxSelect.defaults = {
selects: [], // 下拉选框组
url: null, // 列表数据文件路径URL或数组数据
data: null, // 自定义数据
emptyStyle: null, // 无数据状态显示方式
required: false, // 是否为必选
firstTitle: '请选择', // 第一个选项的标题
firstValue: '', // 第一个选项的值
jsonSpace: '', // 数据命名空间
jsonName: 'n', // 数据标题字段名称
jsonValue: '', // 数据值字段名称
jsonSub: 's' // 子集数据字段名称
};
$.fn.cxSelect = function(settings, callback) {
this.each(function(i) {
$.cxSelect(this, settings, callback);
});
return this;
};
}));

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,418 @@
/*!
* Datetimepicker for Bootstrap
*
* Copyright 2012 Stefan Petre
* Improvements by Andrew Rowls
* Licensed under the Apache License v2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
*/
.datetimepicker {
padding: 4px;
margin-top: 1px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
direction: ltr;
}
.datetimepicker-inline {
width: 220px;
}
.datetimepicker.datetimepicker-rtl {
direction: rtl;
}
.datetimepicker.datetimepicker-rtl table tr td span {
float: right;
}
.datetimepicker-dropdown, .datetimepicker-dropdown-left {
top: 0;
left: 0;
}
[class*=" datetimepicker-dropdown"]:before {
content: '';
display: inline-block;
border-left: 7px solid transparent;
border-right: 7px solid transparent;
border-bottom: 7px solid #cccccc;
border-bottom-color: rgba(0, 0, 0, 0.2);
position: absolute;
}
[class*=" datetimepicker-dropdown"]:after {
content: '';
display: inline-block;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-bottom: 6px solid #ffffff;
position: absolute;
}
[class*=" datetimepicker-dropdown-top"]:before {
content: '';
display: inline-block;
border-left: 7px solid transparent;
border-right: 7px solid transparent;
border-top: 7px solid #cccccc;
border-top-color: rgba(0, 0, 0, 0.2);
border-bottom: 0;
}
[class*=" datetimepicker-dropdown-top"]:after {
content: '';
display: inline-block;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-top: 6px solid #ffffff;
border-bottom: 0;
}
.datetimepicker-dropdown-bottom-left:before {
top: -7px;
right: 6px;
}
.datetimepicker-dropdown-bottom-left:after {
top: -6px;
right: 7px;
}
.datetimepicker-dropdown-bottom-right:before {
top: -7px;
left: 6px;
}
.datetimepicker-dropdown-bottom-right:after {
top: -6px;
left: 7px;
}
.datetimepicker-dropdown-top-left:before {
bottom: -7px;
right: 6px;
}
.datetimepicker-dropdown-top-left:after {
bottom: -6px;
right: 7px;
}
.datetimepicker-dropdown-top-right:before {
bottom: -7px;
left: 6px;
}
.datetimepicker-dropdown-top-right:after {
bottom: -6px;
left: 7px;
}
.datetimepicker > div {
display: none;
}
.datetimepicker.minutes div.datetimepicker-minutes {
display: block;
}
.datetimepicker.hours div.datetimepicker-hours {
display: block;
}
.datetimepicker.days div.datetimepicker-days {
display: block;
}
.datetimepicker.months div.datetimepicker-months {
display: block;
}
.datetimepicker.years div.datetimepicker-years {
display: block;
}
.datetimepicker table {
margin: 0;
}
.datetimepicker td,
.datetimepicker th {
text-align: center;
width: 20px;
height: 20px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
border: none;
}
.table-striped .datetimepicker table tr td,
.table-striped .datetimepicker table tr th {
background-color: transparent;
}
.datetimepicker table tr td.minute:hover {
background: #eeeeee;
cursor: pointer;
}
.datetimepicker table tr td.hour:hover {
background: #eeeeee;
cursor: pointer;
}
.datetimepicker table tr td.day:hover {
background: #eeeeee;
cursor: pointer;
}
.datetimepicker table tr td.old,
.datetimepicker table tr td.new {
color: #999999;
}
.datetimepicker table tr td.disabled,
.datetimepicker table tr td.disabled:hover {
background: none;
color: #999999;
cursor: default;
}
.datetimepicker table tr td.today,
.datetimepicker table tr td.today:hover,
.datetimepicker table tr td.today.disabled,
.datetimepicker table tr td.today.disabled:hover {
background-color: #fde19a;
background-image: -moz-linear-gradient(top, #fdd49a, #fdf59a);
background-image: -ms-linear-gradient(top, #fdd49a, #fdf59a);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fdd49a), to(#fdf59a));
background-image: -webkit-linear-gradient(top, #fdd49a, #fdf59a);
background-image: -o-linear-gradient(top, #fdd49a, #fdf59a);
background-image: linear-gradient(to bottom, #fdd49a, #fdf59a);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fdd49a', endColorstr='#fdf59a', GradientType=0);
border-color: #fdf59a #fdf59a #fbed50;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
}
.datetimepicker table tr td.today:hover,
.datetimepicker table tr td.today:hover:hover,
.datetimepicker table tr td.today.disabled:hover,
.datetimepicker table tr td.today.disabled:hover:hover,
.datetimepicker table tr td.today:active,
.datetimepicker table tr td.today:hover:active,
.datetimepicker table tr td.today.disabled:active,
.datetimepicker table tr td.today.disabled:hover:active,
.datetimepicker table tr td.today.active,
.datetimepicker table tr td.today:hover.active,
.datetimepicker table tr td.today.disabled.active,
.datetimepicker table tr td.today.disabled:hover.active,
.datetimepicker table tr td.today.disabled,
.datetimepicker table tr td.today:hover.disabled,
.datetimepicker table tr td.today.disabled.disabled,
.datetimepicker table tr td.today.disabled:hover.disabled,
.datetimepicker table tr td.today[disabled],
.datetimepicker table tr td.today:hover[disabled],
.datetimepicker table tr td.today.disabled[disabled],
.datetimepicker table tr td.today.disabled:hover[disabled] {
background-color: #fdf59a;
}
.datetimepicker table tr td.today:active,
.datetimepicker table tr td.today:hover:active,
.datetimepicker table tr td.today.disabled:active,
.datetimepicker table tr td.today.disabled:hover:active,
.datetimepicker table tr td.today.active,
.datetimepicker table tr td.today:hover.active,
.datetimepicker table tr td.today.disabled.active,
.datetimepicker table tr td.today.disabled:hover.active {
background-color: #fbf069;
}
.datetimepicker table tr td.active,
.datetimepicker table tr td.active:hover,
.datetimepicker table tr td.active.disabled,
.datetimepicker table tr td.active.disabled:hover {
background-color: #006dcc;
background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
background-image: -ms-linear-gradient(top, #0088cc, #0044cc);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
background-image: -o-linear-gradient(top, #0088cc, #0044cc);
background-image: linear-gradient(to bottom, #0088cc, #0044cc);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);
border-color: #0044cc #0044cc #002a80;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
color: #ffffff;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
.datetimepicker table tr td.active:hover,
.datetimepicker table tr td.active:hover:hover,
.datetimepicker table tr td.active.disabled:hover,
.datetimepicker table tr td.active.disabled:hover:hover,
.datetimepicker table tr td.active:active,
.datetimepicker table tr td.active:hover:active,
.datetimepicker table tr td.active.disabled:active,
.datetimepicker table tr td.active.disabled:hover:active,
.datetimepicker table tr td.active.active,
.datetimepicker table tr td.active:hover.active,
.datetimepicker table tr td.active.disabled.active,
.datetimepicker table tr td.active.disabled:hover.active,
.datetimepicker table tr td.active.disabled,
.datetimepicker table tr td.active:hover.disabled,
.datetimepicker table tr td.active.disabled.disabled,
.datetimepicker table tr td.active.disabled:hover.disabled,
.datetimepicker table tr td.active[disabled],
.datetimepicker table tr td.active:hover[disabled],
.datetimepicker table tr td.active.disabled[disabled],
.datetimepicker table tr td.active.disabled:hover[disabled] {
background-color: #0044cc;
}
.datetimepicker table tr td.active:active,
.datetimepicker table tr td.active:hover:active,
.datetimepicker table tr td.active.disabled:active,
.datetimepicker table tr td.active.disabled:hover:active,
.datetimepicker table tr td.active.active,
.datetimepicker table tr td.active:hover.active,
.datetimepicker table tr td.active.disabled.active,
.datetimepicker table tr td.active.disabled:hover.active {
background-color: #003399;
}
.datetimepicker table tr td span {
display: block;
width: 23%;
height: 54px;
line-height: 54px;
float: left;
margin: 1%;
cursor: pointer;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
}
.datetimepicker .datetimepicker-hours span {
height: 26px;
line-height: 26px;
}
.datetimepicker .datetimepicker-hours table tr td span.hour_am,
.datetimepicker .datetimepicker-hours table tr td span.hour_pm {
width: 14.6%;
}
.datetimepicker .datetimepicker-hours fieldset legend,
.datetimepicker .datetimepicker-minutes fieldset legend {
margin-bottom: inherit;
line-height: 30px;
}
.datetimepicker .datetimepicker-minutes span {
height: 26px;
line-height: 26px;
}
.datetimepicker table tr td span:hover {
background: #eeeeee;
}
.datetimepicker table tr td span.disabled,
.datetimepicker table tr td span.disabled:hover {
background: none;
color: #999999;
cursor: default;
}
.datetimepicker table tr td span.active,
.datetimepicker table tr td span.active:hover,
.datetimepicker table tr td span.active.disabled,
.datetimepicker table tr td span.active.disabled:hover {
background-color: #006dcc;
background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
background-image: -ms-linear-gradient(top, #0088cc, #0044cc);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
background-image: -o-linear-gradient(top, #0088cc, #0044cc);
background-image: linear-gradient(to bottom, #0088cc, #0044cc);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);
border-color: #0044cc #0044cc #002a80;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
color: #ffffff;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
.datetimepicker table tr td span.active:hover,
.datetimepicker table tr td span.active:hover:hover,
.datetimepicker table tr td span.active.disabled:hover,
.datetimepicker table tr td span.active.disabled:hover:hover,
.datetimepicker table tr td span.active:active,
.datetimepicker table tr td span.active:hover:active,
.datetimepicker table tr td span.active.disabled:active,
.datetimepicker table tr td span.active.disabled:hover:active,
.datetimepicker table tr td span.active.active,
.datetimepicker table tr td span.active:hover.active,
.datetimepicker table tr td span.active.disabled.active,
.datetimepicker table tr td span.active.disabled:hover.active,
.datetimepicker table tr td span.active.disabled,
.datetimepicker table tr td span.active:hover.disabled,
.datetimepicker table tr td span.active.disabled.disabled,
.datetimepicker table tr td span.active.disabled:hover.disabled,
.datetimepicker table tr td span.active[disabled],
.datetimepicker table tr td span.active:hover[disabled],
.datetimepicker table tr td span.active.disabled[disabled],
.datetimepicker table tr td span.active.disabled:hover[disabled] {
background-color: #0044cc;
}
.datetimepicker table tr td span.active:active,
.datetimepicker table tr td span.active:hover:active,
.datetimepicker table tr td span.active.disabled:active,
.datetimepicker table tr td span.active.disabled:hover:active,
.datetimepicker table tr td span.active.active,
.datetimepicker table tr td span.active:hover.active,
.datetimepicker table tr td span.active.disabled.active,
.datetimepicker table tr td span.active.disabled:hover.active {
background-color: #003399;
}
.datetimepicker table tr td span.old {
color: #999999;
}
.datetimepicker th.switch {
width: 145px;
}
.datetimepicker th span.glyphicon {
pointer-events: none;
}
.datetimepicker thead tr:first-child th,
.datetimepicker tfoot th {
cursor: pointer;
}
.datetimepicker thead tr:first-child th:hover,
.datetimepicker tfoot th:hover {
background: #eeeeee;
}
.input-append.date .add-on i,
.input-prepend.date .add-on i,
.input-group.date .input-group-addon span {
cursor: pointer;
width: 14px;
height: 14px;
}

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