Compare commits

...

1422 Commits
v3.2 ... master

Author SHA1 Message Date
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
645 changed files with 102535 additions and 33898 deletions

1
.github/FUNDING.yml vendored Normal file
View File

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

3
.gitignore vendored
View File

@ -25,6 +25,8 @@ target/
*.iml *.iml
*.ipr *.ipr
### JRebel ###
rebel.xml
### NetBeans ### ### NetBeans ###
nbproject/private/ nbproject/private/
build/* build/*
@ -37,6 +39,7 @@ nbdist/
# Others # Others
*.log *.log
*.xml.versionsBackup *.xml.versionsBackup
*.swp
!*/build/*.java !*/build/*.java
!*/build/*.html !*/build/*.html

View File

@ -1,14 +1,26 @@
<p align="center">
<img alt="logo" src="https://oscimg.oschina.net/oscnet/up-dd77653d7c9f197dd9d93684f3c8dcfbab6.png">
</p>
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">RuoYi v4.7.9</h1>
<h4 align="center">基于SpringBoot开发的轻量级Java快速开发框架</h4>
<p align="center">
<a href="https://gitee.com/y_project/RuoYi/stargazers"><img src="https://gitee.com/y_project/RuoYi/badge/star.svg?theme=gvp"></a>
<a href="https://gitee.com/y_project/RuoYi"><img src="https://img.shields.io/badge/RuoYi-v4.7.9-brightgreen.svg"></a>
<a href="https://gitee.com/y_project/RuoYi/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a>
</p>
## 平台简介 ## 平台简介
一直想做一款后台管理系统看了很多优秀的开源项目但是发现没有合适的。于是利用空闲休息时间开始自己写了一套后台系统。如此有了若依。她可以用于所有的Web应用程序如网站管理后台网站会员中心CMSCRMOA。所有前端后台代码封装过后十分精简易上手出错概率低。同时支持移动客户端访问。系统会陆续更新一些实用功能。 一直想做一款后台管理系统看了很多优秀的开源项目但是发现没有合适的。于是利用空闲休息时间开始自己写了一套后台系统。如此有了若依。她可以用于所有的Web应用程序如网站管理后台网站会员中心CMSCRMOA。所有前端后台代码封装过后十分精简易上手出错概率低。同时支持移动客户端访问。系统会陆续更新一些实用功能。
性别男,若依是给还没有出生女儿取的名字(寓意:你若不离不弃,我必生死相依) 性别男,若依是给女儿取的名字(寓意:你若不离不弃,我必生死相依)
若依基于hplus和inspinia两套后台系统模板开发。有需要可自行到群内下载。 若依是一套全部开源的快速开发平台,毫无保留给个人及企业免费使用
> RuoYi从3.0开始,进行模块拆分,将原先的单应用转变为多模块,如需单应用,请移步 [RuoYi-fast](https://gitee.com/y_project/RuoYi-fast) * 前后端分离版本,请移步[RuoYi-Vue](https://gitee.com/y_project/RuoYi-Vue),微服务版本,请移步[RuoYi-Cloud](https://gitee.com/y_project/RuoYi-Cloud)
* 感谢 [hplus](https://gitee.com/hplus_admin/hplus) 后台主题 UI 框架。
> 推荐使用阿里云部署,通用云产品代金券 [点我领取](https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=brki8iof) * 阿里云折扣场:[点我进入](http://aly.ruoyi.vip),腾讯云秒杀场:[点我进入](http://txy.ruoyi.vip)&nbsp;&nbsp;
* 阿里云优惠券:[点我领取](https://www.aliyun.com/minisite/goods?userCode=brki8iof&share_source=copy_link),腾讯云优惠券:[点我领取](https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console)&nbsp;&nbsp;
## 内置功能 ## 内置功能
@ -24,49 +36,67 @@
10. 登录日志:系统登录日志记录查询包含登录异常。 10. 登录日志:系统登录日志记录查询包含登录异常。
11. 在线用户:当前系统中活跃用户状态监控。 11. 在线用户:当前系统中活跃用户状态监控。
12. 定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。 12. 定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。
13. 代码生成前后端代码的生成java、html、xml、sql)支持CRUD下载 。 13. 代码生成前后端代码的生成java、html、xml、sql支持CRUD下载 。
14. 系统接口根据业务代码自动生成相关的api接口文档。 14. 系统接口根据业务代码自动生成相关的api接口文档。
15. 服务监控监视当前系统CPU、内存、磁盘、堆栈等相关信息。 15. 服务监控监视当前系统CPU、内存、磁盘、堆栈等相关信息。
16. 在线构建器拖动表单元素生成相应的HTML代码。 16. 缓存监控:对系统的缓存查询,删除、清空等操作。
17. 连接池监视监视当前系统数据库连接池状态可进行分析SQL找出系统性能瓶颈。 17. 在线构建器拖动表单元素生成相应的HTML代码。
18. 连接池监视监视当前系统数据库连接池状态可进行分析SQL找出系统性能瓶颈。
## 在线体验 ## 在线体验
> admin/admin123
> 陆陆续续收到一些打赏,为了更好的体验已用于演示服务器升级。谢谢各位小伙伴。 - admin/admin123
- 陆陆续续收到一些打赏,为了更好的体验已用于演示服务器升级。谢谢各位小伙伴。
演示地址http://ruoyi.vip 演示地址http://ruoyi.vip
文档地址http://doc.ruoyi.vip 文档地址http://doc.ruoyi.vip
## 演示图 ## 演示图
<table> <table>
<tr> <tr>
<td><img src="https://oscimg.oschina.net/oscnet/25b5e333768d013d45a990c152dbe4d9d6e.jpg"/></td> <td><img src="https://oscimg.oschina.net/oscnet/up-42e518aa72a24d228427a1261cb3679f395.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/dfadf4d864242745486aa0167110dfcbeb8.jpg"/></td> <td><img src="https://oscimg.oschina.net/oscnet/up-7f20dd0edba25e5187c5c4dd3ec7d3d9797.png"/></td>
</tr> </tr>
<tr> <tr>
<td><img src="https://oscimg.oschina.net/oscnet/2e1ed87df9b476ed73ed650df20cf009b78.jpg"/></td> <td><img src="https://oscimg.oschina.net/oscnet/up-2dae3d87f6a8ca05057db059cd9a411d51d.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/91bef110740ba9e36ff00804f8748a787fb.jpg"/></td> <td><img src="https://oscimg.oschina.net/oscnet/up-ea4d98423471e55fba784694e45d12bd4bb.png"/></td>
</tr> </tr>
<tr> <tr>
<td><img src="https://oscimg.oschina.net/oscnet/9a2851988f4e7433c9322154534865f57d7.jpg"/></td> <td><img src="https://oscimg.oschina.net/oscnet/up-7f6c6e9f5873efca09bd2870ee8468b8fce.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/396293f80b1e8cce8671f56c296bee78a3a.jpg"/></td> <td><img src="https://oscimg.oschina.net/oscnet/up-c708b65f2c382a03f69fe1efa8d341e6cff.png"/></td>
</tr> </tr>
<tr> <tr>
<td><img src="https://oscimg.oschina.net/oscnet/787b3b06430a403655b48b9bcd1fa829555.jpg"/></td> <td><img src="https://oscimg.oschina.net/oscnet/up-9ab586c47dd5c7b92bca0d727962c90e3b8.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/a51820009836276b778bc89d4d0e217e26d.jpg"/></td> <td><img src="https://oscimg.oschina.net/oscnet/up-ef954122a2080e02013112db21754b955c6.png"/></td>
</tr> </tr>
<tr> <tr>
<td><img src="https://oscimg.oschina.net/oscnet/5fb138478adeda6825e206d21f67ecd0625.jpg"/></td> <td><img src="https://oscimg.oschina.net/oscnet/up-088edb4d531e122415a1e2342bccb1a9691.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/fa2f027a10707a4eb4fc47d5ea1c3d2b772.jpg"/></td> <td><img src="https://oscimg.oschina.net/oscnet/up-f886fe19bd820c0efae82f680223cac196c.png"/></td>
</tr> </tr>
<tr> <tr>
<td><img src="https://oscimg.oschina.net/oscnet/a714056081523b7dfa782cda866e8be4adc.jpg"/></td> <td><img src="https://oscimg.oschina.net/oscnet/up-c7a2eb71fa65d6e660294b4bccca613d638.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/ab4b5797dfb2bc68c4974ad5458bd5f5bcf.jpg"/></td> <td><img src="https://oscimg.oschina.net/oscnet/up-e60137fb0787defe613bd83331dc4755a70.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-7c51c1b5758f0a0f92ed3c60469b7526f9f.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-15181aed45bb2461aa97b594cbf2f86ea5f.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-83326ad52ea63f67233d126226738054d98.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-3bd6d31e913b70df00107db51d64ef81df7.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-70a2225836bc82042a6785edf6299e2586a.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-0184d6ab01fdc6667a14327fcaf8b46345d.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-64d8086dc2c02c8f71170290482f7640098.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-5e4daac0bb59612c5038448acbcef235e3a.png"/></td>
</tr> </tr>
</table> </table>
## 若依交流群 ## 若依交流群
QQ群 [![加入QQ群](https://img.shields.io/badge/已满-1389287-blue.svg)](https://jq.qq.com/?_wv=1027&k=5HBAaYN) [![加入QQ群](https://img.shields.io/badge/已满-1679294-blue.svg)](https://jq.qq.com/?_wv=1027&k=5cHeRVW) [![加入QQ群](https://img.shields.io/badge/QQ群-1529866-blue.svg)](https://jq.qq.com/?_wv=1027&k=53R0L5Z) 点击按钮入群。 QQ群 [![加入QQ群](https://img.shields.io/badge/已满-1389287-blue.svg)](https://jq.qq.com/?_wv=1027&k=5HBAaYN) [![加入QQ群](https://img.shields.io/badge/已满-1679294-blue.svg)](https://jq.qq.com/?_wv=1027&k=5cHeRVW) [![加入QQ群](https://img.shields.io/badge/已满-1529866-blue.svg)](https://jq.qq.com/?_wv=1027&k=53R0L5Z) [![加入QQ群](https://img.shields.io/badge/已满-1772718-blue.svg)](https://jq.qq.com/?_wv=1027&k=5g75dCU) [![加入QQ群](https://img.shields.io/badge/已满-1366522-blue.svg)](https://jq.qq.com/?_wv=1027&k=58cPoHA) [![加入QQ群](https://img.shields.io/badge/已满-1382251-blue.svg)](https://jq.qq.com/?_wv=1027&k=5Ofd4Pb) [![加入QQ群](https://img.shields.io/badge/已满-1145125-blue.svg)](https://jq.qq.com/?_wv=1027&k=5yugASz) [![加入QQ群](https://img.shields.io/badge/已满-86752435-blue.svg)](https://jq.qq.com/?_wv=1027&k=5Rf3d2P) [![加入QQ群](https://img.shields.io/badge/已满-134072510-blue.svg)](https://jq.qq.com/?_wv=1027&k=5ZIjaeP) [![加入QQ群](https://img.shields.io/badge/已满-210336300-blue.svg)](https://jq.qq.com/?_wv=1027&k=5CJw1jY) [![加入QQ群](https://img.shields.io/badge/已满-339522636-blue.svg)](https://jq.qq.com/?_wv=1027&k=5omzbKc) [![加入QQ群](https://img.shields.io/badge/已满-130035985-blue.svg)](https://jq.qq.com/?_wv=1027&k=qPIKBb7s) [![加入QQ群](https://img.shields.io/badge/已满-143151071-blue.svg)](https://jq.qq.com/?_wv=1027&k=4NsjKbtU) [![加入QQ群](https://img.shields.io/badge/已满-158781320-blue.svg)](https://jq.qq.com/?_wv=1027&k=VD2pkz2G) [![加入QQ群](https://img.shields.io/badge/已满-201531282-blue.svg)](https://jq.qq.com/?_wv=1027&k=HlshFwkJ) [![加入QQ群](https://img.shields.io/badge/已满-101526938-blue.svg)](https://jq.qq.com/?_wv=1027&k=0ARRrO9V) [![加入QQ群](https://img.shields.io/badge/已满-264355400-blue.svg)](https://jq.qq.com/?_wv=1027&k=up9k3ZXJ) [![加入QQ群](https://img.shields.io/badge/已满-298522656-blue.svg)](https://jq.qq.com/?_wv=1027&k=540WfdEr) [![加入QQ群](https://img.shields.io/badge/已满-139845794-blue.svg)](https://jq.qq.com/?_wv=1027&k=ss91fC4t) [![加入QQ群](https://img.shields.io/badge/已满-185760789-blue.svg)](https://jq.qq.com/?_wv=1027&k=Cqd66IKe) [![加入QQ群](https://img.shields.io/badge/已满-175104288-blue.svg)](https://jq.qq.com/?_wv=1027&k=7FplYUnR) [![加入QQ群](https://img.shields.io/badge/已满-174942938-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=lqMHu_5Fskm7H2S1vNAQTtzAUokVydwc&authKey=ptw0Fpch5pbNocML3CIJKKqZBaq2DI7cusKuzIgfMNiY3t9Pvd9hP%2BA8WYx3yaY1&noverify=0&group_code=174942938) [![加入QQ群](https://img.shields.io/badge/287843737-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=blYlRDmwZXSXI5pVrPPU7ZJ1stFJ6Q2Q&authKey=ForGBWffHVlPt9NE3d7g4DoOIouBh%2BqvAj2lp1CLReHfZAUaK7SRrdwsChKpRJDJ&noverify=0&group_code=287843737)

View File

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

View File

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

14
bin/run.bat Normal file
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

View File

@ -41,6 +41,12 @@
如对模板有特殊需求可自行修改。编辑src/main/ resources/templates/vm目录下 如对模板有特殊需求可自行修改。编辑src/main/ resources/templates/vm目录下
3.1.4 日志配置
编辑src/main/ resources目录下的logback.yml 文件
<property name="log.path" value="/home/ruoyi/logs" />
改为自己需要的路径
3.2 启动及验证 3.2 启动及验证
启动RuoYiApplication.java 出现如下图表示启动成功 启动RuoYiApplication.java 出现如下图表示启动成功
@ -48,7 +54,7 @@
若能正确展示登录页面,并能成功登录,登录后菜单及页面展示正常,则表明环境搭建成功。 若能正确展示登录页面,并能成功登录,登录后菜单及页面展示正常,则表明环境搭建成功。
默认密码为 admin/admin123 默认密码为 admin/admin123
演示地址http://www.ruoyi.club 演示地址http://ruoyi.vip
@ -77,3 +83,7 @@
4.2 Jar方式部署 4.2 Jar方式部署
执行命令java - jar RuoYi.jar 执行命令java - jar RuoYi.jar
脚本执行ry.sh start 启动stop 停止 脚本执行ry.sh start 启动stop 停止
演示地址ruoyi.vip
文档地址doc.ruoyi.vip

223
pom.xml
View File

@ -1,42 +1,198 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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"> 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> <modelVersion>4.0.0</modelVersion>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<version>3.2</version> <version>4.7.9</version>
<name>ruoyi</name> <name>ruoyi</name>
<url>http://www.ruoyi.vip</url> <url>http://www.ruoyi.vip</url>
<description>若依管理系统</description> <description>若依管理系统</description>
<properties> <properties>
<ruoyi.version>3.2</ruoyi.version> <ruoyi.version>4.7.9</ruoyi.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version> <java.version>1.8</java.version>
<shiro.version>1.4.0</shiro.version> <maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
<thymeleaf.extras.shiro.version>2.0.0</thymeleaf.extras.shiro.version> <shiro.version>1.13.0</shiro.version>
<mybatis.boot.version>1.3.2</mybatis.boot.version> <spring-framework.version>5.3.33</spring-framework.version>
<druid.version>1.1.10</druid.version> <thymeleaf.extras.shiro.version>2.1.0</thymeleaf.extras.shiro.version>
<bitwalker.version>1.19</bitwalker.version> <druid.version>1.2.23</druid.version>
<kaptcha.version>2.3.2</kaptcha.version> <bitwalker.version>1.21</bitwalker.version>
<swagger.version>2.7.0</swagger.version> <kaptcha.version>2.3.3</kaptcha.version>
<pagehelper.boot.version>1.2.5</pagehelper.boot.version> <swagger.version>3.0.0</swagger.version>
<oshi.version>3.9.1</oshi.version> <pagehelper.boot.version>1.4.7</pagehelper.boot.version>
<fastjson.version>1.2.83</fastjson.version>
<oshi.version>6.6.1</oshi.version>
<commons.io.version>2.13.0</commons.io.version>
<poi.version>4.1.2</poi.version>
<velocity.version>2.3</velocity.version>
</properties> </properties>
<!-- 依赖声明 -->
<dependencyManagement> <dependencyManagement>
<dependencies> <dependencies>
<!-- SpringFramework的依赖配置-->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework</groupId>
<artifactId>spring-boot-dependencies</artifactId> <artifactId>spring-framework-bom</artifactId>
<version>2.1.1.RELEASE</version> <version>${spring-framework.version}</version>
<type>pom</type> <type>pom</type>
<scope>import</scope> <scope>import</scope>
</dependency> </dependency>
<!-- SpringBoot的依赖配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.5.15</version>
<type>pom</type>
<scope>import</scope>
</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>
</dependencies> </dependencies>
</dependencyManagement> </dependencyManagement>
@ -53,36 +209,6 @@
<dependencies> <dependencies>
<!--Spring框架基本的核心工具-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<!-- SpringBoot集成mybatis框架 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis.boot.version}</version>
</dependency>
<!-- Mysql驱动包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<!-- 日志工具类 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
</dependencies> </dependencies>
<build> <build>
@ -90,6 +216,7 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration> <configuration>
<source>${java.version}</source> <source>${java.version}</source>
<target>${java.version}</target> <target>${java.version}</target>
@ -103,7 +230,7 @@
<repository> <repository>
<id>public</id> <id>public</id>
<name>aliyun nexus</name> <name>aliyun nexus</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url> <url>https://maven.aliyun.com/repository/public</url>
<releases> <releases>
<enabled>true</enabled> <enabled>true</enabled>
</releases> </releases>
@ -114,7 +241,7 @@
<pluginRepository> <pluginRepository>
<id>public</id> <id>public</id>
<name>aliyun nexus</name> <name>aliyun nexus</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url> <url>https://maven.aliyun.com/repository/public</url>
<releases> <releases>
<enabled>true</enabled> <enabled>true</enabled>
</releases> </releases>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<version>3.2</version> <version>4.7.9</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging> <packaging>jar</packaging>
@ -15,9 +15,14 @@
web服务入口 web服务入口
</description> </description>
<dependencies> <dependencies>
<!-- SpringBoot集成thymeleaf模板 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- spring-boot-devtools --> <!-- spring-boot-devtools -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
@ -25,25 +30,41 @@
<optional>true</optional> <!-- 表示依赖不会传递 --> <optional>true</optional> <!-- 表示依赖不会传递 -->
</dependency> </dependency>
<!-- swagger2--> <!-- swagger3-->
<dependency> <dependency>
<groupId>io.springfox</groupId> <groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId> <artifactId>springfox-boot-starter</artifactId>
<version>${swagger.version}</version>
</dependency> </dependency>
<!-- swagger2-UI--> <!-- 防止进入swagger页面报类型转换错误排除3.0.0中的引用手动增加1.6.2版本 -->
<dependency> <dependency>
<groupId>io.springfox</groupId> <groupId>io.swagger</groupId>
<artifactId>springfox-swagger-ui</artifactId> <artifactId>swagger-models</artifactId>
<version>${swagger.version}</version> <version>1.6.2</version>
</dependency>
<!-- Mysql驱动包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency> </dependency>
<!-- 核心模块--> <!-- 核心模块-->
<dependency> <dependency>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-framework</artifactId> <artifactId>ruoyi-framework</artifactId>
<version>${ruoyi.version}</version> </dependency>
<!-- 定时任务-->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-quartz</artifactId>
</dependency>
<!-- 代码生成-->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-generator</artifactId>
</dependency> </dependency>
</dependencies> </dependencies>
@ -53,6 +74,7 @@
<plugin> <plugin>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId> <artifactId>spring-boot-maven-plugin</artifactId>
<version>2.5.15</version>
<configuration> <configuration>
<fork>true</fork> <!-- 如果没有该配置devtools不会生效 --> <fork>true</fork> <!-- 如果没有该配置devtools不会生效 -->
</configuration> </configuration>
@ -70,11 +92,44 @@
<version>3.0.0</version> <version>3.0.0</version>
<configuration> <configuration>
<failOnMissingWebXml>false</failOnMissingWebXml> <failOnMissingWebXml>false</failOnMissingWebXml>
<warName>${artifactId}</warName> <warName>${project.artifactId}</warName>
</configuration> </configuration>
</plugin> </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> </plugins>
<finalName>${artifactId}</finalName> <finalName>${project.artifactId}</finalName>
</build> </build>
</project> </project>

View File

@ -1,6 +1,5 @@
package com.ruoyi; package com.ruoyi;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
@ -11,7 +10,6 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
* @author ruoyi * @author ruoyi
*/ */
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class }) @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
@MapperScan("com.ruoyi.*.mapper")
public class RuoYiApplication public class RuoYiApplication
{ {
public static void main(String[] args) public static void main(String[] args)

View File

@ -1,22 +1,26 @@
package com.ruoyi.web.controller.common; package com.ruoyi.web.controller.common;
import java.io.UnsupportedEncodingException; import java.util.ArrayList;
import java.net.URLEncoder; import java.util.List;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping; 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.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.base.AjaxResult; import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.config.Global; 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; import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.framework.config.ServerConfig;
import com.ruoyi.framework.util.FileUploadUtils;
/** /**
* 通用请求处理 * 通用请求处理
@ -24,36 +28,36 @@ import com.ruoyi.framework.util.FileUploadUtils;
* @author ruoyi * @author ruoyi
*/ */
@Controller @Controller
@RequestMapping("/common")
public class CommonController public class CommonController
{ {
private static final Logger log = LoggerFactory.getLogger(CommonController.class); private static final Logger log = LoggerFactory.getLogger(CommonController.class);
/**
* 文件上传路径
*/
public static final String UPLOAD_PATH = "/profile/upload/";
@Autowired @Autowired
private ServerConfig serverConfig; private ServerConfig serverConfig;
private static final String FILE_DELIMETER = ",";
/** /**
* 通用下载请求 * 通用下载请求
* *
* @param fileName 文件名称 * @param fileName 文件名称
* @param delete 是否删除 * @param delete 是否删除
*/ */
@GetMapping("common/download") @GetMapping("/download")
public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request) public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request)
{ {
String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1);
try try
{ {
String filePath = Global.getDownloadPath() + fileName; 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.setCharacterEncoding("utf-8"); response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
response.setContentType("multipart/form-data"); FileUtils.setAttachmentResponseHeader(response, realFileName);
response.setHeader("Content-Disposition",
"attachment;fileName=" + setFileDownloadHeader(request, realFileName));
FileUtils.writeBytes(filePath, response.getOutputStream()); FileUtils.writeBytes(filePath, response.getOutputStream());
if (delete) if (delete)
{ {
@ -67,22 +71,24 @@ public class CommonController
} }
/** /**
* 通用上传请求 * 通用上传请求单个
*/ */
@PostMapping("/common/upload") @PostMapping("/upload")
@ResponseBody @ResponseBody
public AjaxResult uploadFile(MultipartFile file) throws Exception public AjaxResult uploadFile(MultipartFile file) throws Exception
{ {
try try
{ {
// 上传文件路径 // 上传文件路径
String filePath = Global.getUploadPath(); String filePath = RuoYiConfig.getUploadPath();
// 上传并返回新文件名称 // 上传并返回新文件名称
String fileName = FileUploadUtils.upload(filePath, file); String fileName = FileUploadUtils.upload(filePath, file);
String url = serverConfig.getUrl() + UPLOAD_PATH + fileName; String url = serverConfig.getUrl() + fileName;
AjaxResult ajax = AjaxResult.success(); AjaxResult ajax = AjaxResult.success();
ajax.put("fileName", fileName);
ajax.put("url", url); ajax.put("url", url);
ajax.put("fileName", fileName);
ajax.put("newFileName", FileUtils.getName(fileName));
ajax.put("originalFilename", file.getOriginalFilename());
return ajax; return ajax;
} }
catch (Exception e) catch (Exception e)
@ -91,31 +97,70 @@ public class CommonController
} }
} }
public String setFileDownloadHeader(HttpServletRequest request, String fileName) throws UnsupportedEncodingException /**
* 通用上传请求多个
*/
@PostMapping("/uploads")
@ResponseBody
public AjaxResult uploadFiles(List<MultipartFile> files) throws Exception
{ {
final String agent = request.getHeader("USER-AGENT"); try
String filename = fileName;
if (agent.contains("MSIE"))
{ {
// IE浏览器 // 上传文件路径
filename = URLEncoder.encode(filename, "utf-8"); String filePath = RuoYiConfig.getUploadPath();
filename = filename.replace("+", " "); 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());
} }
else if (agent.contains("Firefox")) AjaxResult ajax = AjaxResult.success();
{ ajax.put("urls", StringUtils.join(urls, FILE_DELIMETER));
// 火狐浏览器 ajax.put("fileNames", StringUtils.join(fileNames, FILE_DELIMETER));
filename = new String(fileName.getBytes(), "ISO8859-1"); ajax.put("newFileNames", StringUtils.join(newFileNames, FILE_DELIMETER));
ajax.put("originalFilenames", StringUtils.join(originalFilenames, FILE_DELIMETER));
return ajax;
} }
else if (agent.contains("Chrome")) catch (Exception e)
{ {
// google浏览器 return AjaxResult.error(e.getMessage());
filename = URLEncoder.encode(filename, "utf-8");
} }
else }
/**
* 本地资源通用下载
*/
@GetMapping("/download/resource")
public void resourceDownload(String resource, HttpServletRequest request, HttpServletResponse response)
throws Exception
{ {
// 其它浏览器 try
filename = URLEncoder.encode(filename, "utf-8"); {
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);
} }
return filename;
} }
} }

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

@ -4,7 +4,7 @@ import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import com.ruoyi.framework.web.base.BaseController; import com.ruoyi.common.core.controller.BaseController;
/** /**
* druid 监控 * druid 监控
@ -15,12 +15,12 @@ import com.ruoyi.framework.web.base.BaseController;
@RequestMapping("/monitor/data") @RequestMapping("/monitor/data")
public class DruidController extends BaseController public class DruidController extends BaseController
{ {
private String prefix = "/monitor/druid"; private String prefix = "/druid";
@RequiresPermissions("monitor:data:view") @RequiresPermissions("monitor:data:view")
@GetMapping() @GetMapping()
public String index() public String index()
{ {
return redirect(prefix + "/index"); return redirect(prefix + "/index.html");
} }
} }

View File

@ -5,7 +5,7 @@ import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap; import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import com.ruoyi.framework.web.base.BaseController; import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.framework.web.domain.Server; import com.ruoyi.framework.web.domain.Server;
/** /**

View File

@ -1,171 +0,0 @@
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.base.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.page.TableDataInfo;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.util.ShiroUtils;
import com.ruoyi.quartz.domain.SysJob;
import com.ruoyi.quartz.service.ISysJobService;
import com.ruoyi.framework.web.base.BaseController;
/**
* 调度任务信息操作处理
*
* @author ruoyi
*/
@Controller
@RequestMapping("/monitor/job")
public class SysJobController extends BaseController
{
private String prefix = "monitor/job";
@Autowired
private ISysJobService jobService;
@RequiresPermissions("monitor:job:view")
@GetMapping()
public String job()
{
return prefix + "/job";
}
@RequiresPermissions("monitor:job:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(SysJob job)
{
startPage();
List<SysJob> list = jobService.selectJobList(job);
return getDataTable(list);
}
@Log(title = "定时任务", businessType = BusinessType.EXPORT)
@RequiresPermissions("monitor:job:export")
@PostMapping("/export")
@ResponseBody
public AjaxResult export(SysJob job)
{
List<SysJob> list = jobService.selectJobList(job);
ExcelUtil<SysJob> util = new ExcelUtil<SysJob>(SysJob.class);
return util.exportExcel(list, "定时任务");
}
@Log(title = "定时任务", businessType = BusinessType.DELETE)
@RequiresPermissions("monitor:job:remove")
@PostMapping("/remove")
@ResponseBody
public AjaxResult remove(String ids)
{
try
{
jobService.deleteJobByIds(ids);
return success();
}
catch (Exception e)
{
e.printStackTrace();
return error(e.getMessage());
}
}
@RequiresPermissions("monitor:job:detail")
@GetMapping("/detail/{jobId}")
public String detail(@PathVariable("jobId") Long jobId, ModelMap mmap)
{
mmap.put("name", "job");
mmap.put("job", jobService.selectJobById(jobId));
return prefix + "/detail";
}
/**
* 任务调度状态修改
*/
@Log(title = "定时任务", businessType = BusinessType.UPDATE)
@RequiresPermissions("monitor:job:changeStatus")
@PostMapping("/changeStatus")
@ResponseBody
public AjaxResult changeStatus(SysJob job)
{
job.setUpdateBy(ShiroUtils.getLoginName());
return toAjax(jobService.changeStatus(job));
}
/**
* 任务调度立即执行一次
*/
@Log(title = "定时任务", businessType = BusinessType.UPDATE)
@RequiresPermissions("monitor:job:changeStatus")
@PostMapping("/run")
@ResponseBody
public AjaxResult run(SysJob job)
{
return toAjax(jobService.run(job));
}
/**
* 新增调度
*/
@GetMapping("/add")
public String add()
{
return prefix + "/add";
}
/**
* 新增保存调度
*/
@Log(title = "定时任务", businessType = BusinessType.INSERT)
@RequiresPermissions("monitor:job:add")
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(SysJob job)
{
job.setCreateBy(ShiroUtils.getLoginName());
return toAjax(jobService.insertJobCron(job));
}
/**
* 修改调度
*/
@GetMapping("/edit/{jobId}")
public String edit(@PathVariable("jobId") Long jobId, ModelMap mmap)
{
mmap.put("job", jobService.selectJobById(jobId));
return prefix + "/edit";
}
/**
* 修改保存调度
*/
@Log(title = "定时任务", businessType = BusinessType.UPDATE)
@RequiresPermissions("monitor:job:edit")
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(SysJob job)
{
job.setUpdateBy(ShiroUtils.getLoginName());
return toAjax(jobService.updateJobCron(job));
}
/**
* 校验cron表达式是否有效
*/
@PostMapping("/checkCronExpressionIsValid")
@ResponseBody
public boolean checkCronExpressionIsValid(SysJob job)
{
return jobService.checkCronExpressionIsValid(job.getCronExpression());
}
}

View File

@ -1,6 +1,7 @@
package com.ruoyi.web.controller.monitor; package com.ruoyi.web.controller.monitor;
import java.util.List; import java.util.List;
import com.ruoyi.framework.shiro.service.SysPasswordService;
import org.apache.shiro.authz.annotation.RequiresPermissions; import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
@ -9,13 +10,13 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.base.AjaxResult; 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.enums.BusinessType;
import com.ruoyi.common.page.TableDataInfo;
import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.SysLogininfor; import com.ruoyi.system.domain.SysLogininfor;
import com.ruoyi.system.service.ISysLogininforService; import com.ruoyi.system.service.ISysLogininforService;
import com.ruoyi.framework.web.base.BaseController;
/** /**
* 系统访问记录 * 系统访问记录
@ -31,6 +32,9 @@ public class SysLogininforController extends BaseController
@Autowired @Autowired
private ISysLogininforService logininforService; private ISysLogininforService logininforService;
@Autowired
private SysPasswordService passwordService;
@RequiresPermissions("monitor:logininfor:view") @RequiresPermissions("monitor:logininfor:view")
@GetMapping() @GetMapping()
public String logininfor() public String logininfor()
@ -48,7 +52,7 @@ public class SysLogininforController extends BaseController
return getDataTable(list); return getDataTable(list);
} }
@Log(title = "日志", businessType = BusinessType.EXPORT) @Log(title = "日志", businessType = BusinessType.EXPORT)
@RequiresPermissions("monitor:logininfor:export") @RequiresPermissions("monitor:logininfor:export")
@PostMapping("/export") @PostMapping("/export")
@ResponseBody @ResponseBody
@ -56,11 +60,11 @@ public class SysLogininforController extends BaseController
{ {
List<SysLogininfor> list = logininforService.selectLogininforList(logininfor); List<SysLogininfor> list = logininforService.selectLogininforList(logininfor);
ExcelUtil<SysLogininfor> util = new ExcelUtil<SysLogininfor>(SysLogininfor.class); ExcelUtil<SysLogininfor> util = new ExcelUtil<SysLogininfor>(SysLogininfor.class);
return util.exportExcel(list, "日志"); return util.exportExcel(list, "日志");
} }
@RequiresPermissions("monitor:logininfor:remove") @RequiresPermissions("monitor:logininfor:remove")
@Log(title = "日志", businessType = BusinessType.DELETE) @Log(title = "日志", businessType = BusinessType.DELETE)
@PostMapping("/remove") @PostMapping("/remove")
@ResponseBody @ResponseBody
public AjaxResult remove(String ids) public AjaxResult remove(String ids)
@ -69,7 +73,7 @@ public class SysLogininforController extends BaseController
} }
@RequiresPermissions("monitor:logininfor:remove") @RequiresPermissions("monitor:logininfor:remove")
@Log(title = "日志", businessType = BusinessType.CLEAN) @Log(title = "日志", businessType = BusinessType.CLEAN)
@PostMapping("/clean") @PostMapping("/clean")
@ResponseBody @ResponseBody
public AjaxResult clean() public AjaxResult clean()
@ -77,4 +81,14 @@ public class SysLogininforController extends BaseController
logininforService.cleanLogininfor(); logininforService.cleanLogininfor();
return success(); 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

@ -11,13 +11,13 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.base.AjaxResult; 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.enums.BusinessType;
import com.ruoyi.common.page.TableDataInfo;
import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.SysOperLog; import com.ruoyi.system.domain.SysOperLog;
import com.ruoyi.system.service.ISysOperLogService; import com.ruoyi.system.service.ISysOperLogService;
import com.ruoyi.framework.web.base.BaseController;
/** /**
* 操作日志记录 * 操作日志记录
@ -61,6 +61,7 @@ public class SysOperlogController extends BaseController
return util.exportExcel(list, "操作日志"); return util.exportExcel(list, "操作日志");
} }
@Log(title = "操作日志", businessType = BusinessType.DELETE)
@RequiresPermissions("monitor:operlog:remove") @RequiresPermissions("monitor:operlog:remove")
@PostMapping("/remove") @PostMapping("/remove")
@ResponseBody @ResponseBody

View File

@ -1,25 +1,26 @@
package com.ruoyi.web.controller.monitor; package com.ruoyi.web.controller.monitor;
import java.util.List; import java.util.List;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions; import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; 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.bind.annotation.ResponseBody;
import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.base.AjaxResult; 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.BusinessType;
import com.ruoyi.common.enums.OnlineStatus; import com.ruoyi.common.enums.OnlineStatus;
import com.ruoyi.common.page.TableDataInfo; import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.framework.shiro.session.OnlineSession; import com.ruoyi.framework.shiro.session.OnlineSession;
import com.ruoyi.framework.shiro.session.OnlineSessionDAO; import com.ruoyi.framework.shiro.session.OnlineSessionDAO;
import com.ruoyi.framework.util.ShiroUtils;
import com.ruoyi.system.domain.SysUserOnline; import com.ruoyi.system.domain.SysUserOnline;
import com.ruoyi.system.service.ISysUserOnlineService; import com.ruoyi.system.service.ISysUserOnlineService;
import com.ruoyi.framework.web.base.BaseController;
/** /**
* 在线用户监控 * 在线用户监控
@ -55,13 +56,13 @@ public class SysUserOnlineController extends BaseController
return getDataTable(list); return getDataTable(list);
} }
@RequiresPermissions("monitor:online:batchForceLogout") @RequiresPermissions(value = { "monitor:online:batchForceLogout", "monitor:online:forceLogout" }, logical = Logical.OR)
@Log(title = "在线用户", businessType = BusinessType.FORCE) @Log(title = "在线用户", businessType = BusinessType.FORCE)
@PostMapping("/batchForceLogout") @PostMapping("/batchForceLogout")
@ResponseBody @ResponseBody
public AjaxResult batchForceLogout(@RequestParam("ids[]") String[] ids) public AjaxResult batchForceLogout(String ids)
{ {
for (String sessionId : ids) for (String sessionId : Convert.toStrArray(ids))
{ {
SysUserOnline online = userOnlineService.selectOnlineById(sessionId); SysUserOnline online = userOnlineService.selectOnlineById(sessionId);
if (online == null) if (online == null)
@ -75,38 +76,13 @@ public class SysUserOnlineController extends BaseController
} }
if (sessionId.equals(ShiroUtils.getSessionId())) if (sessionId.equals(ShiroUtils.getSessionId()))
{ {
return error("当前登用户无法强退"); return error("当前登用户无法强退");
} }
onlineSession.setStatus(OnlineStatus.off_line); onlineSessionDAO.delete(onlineSession);
online.setStatus(OnlineStatus.off_line); online.setStatus(OnlineStatus.off_line);
userOnlineService.saveOnline(online); userOnlineService.saveOnline(online);
userOnlineService.removeUserCache(online.getLoginName(), sessionId);
} }
return success(); return success();
} }
@RequiresPermissions("monitor:online:forceLogout")
@Log(title = "在线用户", businessType = BusinessType.FORCE)
@PostMapping("/forceLogout")
@ResponseBody
public AjaxResult forceLogout(String sessionId)
{
SysUserOnline online = userOnlineService.selectOnlineById(sessionId);
if (sessionId.equals(ShiroUtils.getSessionId()))
{
return error("当前登陆用户无法强退");
}
if (online == null)
{
return error("用户已下线");
}
OnlineSession onlineSession = (OnlineSession) onlineSessionDAO.readSession(online.getSessionId());
if (onlineSession == null)
{
return error("用户已下线");
}
onlineSession.setStatus(OnlineStatus.off_line);
online.setStatus(OnlineStatus.off_line);
userOnlineService.saveOnline(online);
return success();
}
} }

View File

@ -14,7 +14,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.ModelAndView;
import com.google.code.kaptcha.Constants; import com.google.code.kaptcha.Constants;
import com.google.code.kaptcha.Producer; import com.google.code.kaptcha.Producer;
import com.ruoyi.framework.web.base.BaseController; import com.ruoyi.common.core.controller.BaseController;
/** /**
* 图片验证码支持算术形式 * 图片验证码支持算术形式

View File

@ -5,20 +5,20 @@ import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap; import org.springframework.ui.ModelMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.base.AjaxResult; 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.enums.BusinessType;
import com.ruoyi.common.page.TableDataInfo;
import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.util.ShiroUtils;
import com.ruoyi.system.domain.SysConfig; import com.ruoyi.system.domain.SysConfig;
import com.ruoyi.system.service.ISysConfigService; import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.framework.web.base.BaseController;
/** /**
* 参数配置 信息操作处理 * 参数配置 信息操作处理
@ -81,15 +81,20 @@ public class SysConfigController extends BaseController
@Log(title = "参数管理", businessType = BusinessType.INSERT) @Log(title = "参数管理", businessType = BusinessType.INSERT)
@PostMapping("/add") @PostMapping("/add")
@ResponseBody @ResponseBody
public AjaxResult addSave(SysConfig config) public AjaxResult addSave(@Validated SysConfig config)
{ {
config.setCreateBy(ShiroUtils.getLoginName()); if (!configService.checkConfigKeyUnique(config))
{
return error("新增参数'" + config.getConfigName() + "'失败,参数键名已存在");
}
config.setCreateBy(getLoginName());
return toAjax(configService.insertConfig(config)); return toAjax(configService.insertConfig(config));
} }
/** /**
* 修改参数配置 * 修改参数配置
*/ */
@RequiresPermissions("system:config:edit")
@GetMapping("/edit/{configId}") @GetMapping("/edit/{configId}")
public String edit(@PathVariable("configId") Long configId, ModelMap mmap) public String edit(@PathVariable("configId") Long configId, ModelMap mmap)
{ {
@ -104,9 +109,13 @@ public class SysConfigController extends BaseController
@Log(title = "参数管理", businessType = BusinessType.UPDATE) @Log(title = "参数管理", businessType = BusinessType.UPDATE)
@PostMapping("/edit") @PostMapping("/edit")
@ResponseBody @ResponseBody
public AjaxResult editSave(SysConfig config) public AjaxResult editSave(@Validated SysConfig config)
{ {
config.setUpdateBy(ShiroUtils.getLoginName()); if (!configService.checkConfigKeyUnique(config))
{
return error("修改参数'" + config.getConfigName() + "'失败,参数键名已存在");
}
config.setUpdateBy(getLoginName());
return toAjax(configService.updateConfig(config)); return toAjax(configService.updateConfig(config));
} }
@ -119,7 +128,21 @@ public class SysConfigController extends BaseController
@ResponseBody @ResponseBody
public AjaxResult remove(String ids) public AjaxResult remove(String ids)
{ {
return toAjax(configService.deleteConfigByIds(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();
} }
/** /**
@ -127,7 +150,7 @@ public class SysConfigController extends BaseController
*/ */
@PostMapping("/checkConfigKeyUnique") @PostMapping("/checkConfigKeyUnique")
@ResponseBody @ResponseBody
public String checkConfigKeyUnique(SysConfig config) public boolean checkConfigKeyUnique(SysConfig config)
{ {
return configService.checkConfigKeyUnique(config); return configService.checkConfigKeyUnique(config);
} }

View File

@ -1,25 +1,25 @@
package com.ruoyi.web.controller.system; package com.ruoyi.web.controller.system;
import java.util.List; import java.util.List;
import java.util.Map;
import org.apache.shiro.authz.annotation.RequiresPermissions; import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap; import org.springframework.ui.ModelMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.base.AjaxResult; 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.enums.BusinessType;
import com.ruoyi.framework.util.ShiroUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.SysDept;
import com.ruoyi.system.domain.SysRole;
import com.ruoyi.system.service.ISysDeptService; import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.framework.web.base.BaseController;
/** /**
* 部门信息 * 部门信息
@ -43,7 +43,7 @@ public class SysDeptController extends BaseController
} }
@RequiresPermissions("system:dept:list") @RequiresPermissions("system:dept:list")
@GetMapping("/list") @PostMapping("/list")
@ResponseBody @ResponseBody
public List<SysDept> list(SysDept dept) public List<SysDept> list(SysDept dept)
{ {
@ -57,6 +57,10 @@ public class SysDeptController extends BaseController
@GetMapping("/add/{parentId}") @GetMapping("/add/{parentId}")
public String add(@PathVariable("parentId") Long parentId, ModelMap mmap) public String add(@PathVariable("parentId") Long parentId, ModelMap mmap)
{ {
if (!getSysUser().isAdmin())
{
parentId = getSysUser().getDeptId();
}
mmap.put("dept", deptService.selectDeptById(parentId)); mmap.put("dept", deptService.selectDeptById(parentId));
return prefix + "/add"; return prefix + "/add";
} }
@ -68,18 +72,24 @@ public class SysDeptController extends BaseController
@RequiresPermissions("system:dept:add") @RequiresPermissions("system:dept:add")
@PostMapping("/add") @PostMapping("/add")
@ResponseBody @ResponseBody
public AjaxResult addSave(SysDept dept) public AjaxResult addSave(@Validated SysDept dept)
{ {
dept.setCreateBy(ShiroUtils.getLoginName()); if (!deptService.checkDeptNameUnique(dept))
{
return error("新增部门'" + dept.getDeptName() + "'失败,部门名称已存在");
}
dept.setCreateBy(getLoginName());
return toAjax(deptService.insertDept(dept)); return toAjax(deptService.insertDept(dept));
} }
/** /**
* 修改 * 修改部门
*/ */
@RequiresPermissions("system:dept:edit")
@GetMapping("/edit/{deptId}") @GetMapping("/edit/{deptId}")
public String edit(@PathVariable("deptId") Long deptId, ModelMap mmap) public String edit(@PathVariable("deptId") Long deptId, ModelMap mmap)
{ {
deptService.checkDeptDataScope(deptId);
SysDept dept = deptService.selectDeptById(deptId); SysDept dept = deptService.selectDeptById(deptId);
if (StringUtils.isNotNull(dept) && 100L == deptId) if (StringUtils.isNotNull(dept) && 100L == deptId)
{ {
@ -90,15 +100,29 @@ public class SysDeptController extends BaseController
} }
/** /**
* 保存 * 修改保存部门
*/ */
@Log(title = "部门管理", businessType = BusinessType.UPDATE) @Log(title = "部门管理", businessType = BusinessType.UPDATE)
@RequiresPermissions("system:dept:edit") @RequiresPermissions("system:dept:edit")
@PostMapping("/edit") @PostMapping("/edit")
@ResponseBody @ResponseBody
public AjaxResult editSave(SysDept dept) public AjaxResult editSave(@Validated SysDept dept)
{ {
dept.setUpdateBy(ShiroUtils.getLoginName()); 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)); return toAjax(deptService.updateDept(dept));
} }
@ -107,18 +131,19 @@ public class SysDeptController extends BaseController
*/ */
@Log(title = "部门管理", businessType = BusinessType.DELETE) @Log(title = "部门管理", businessType = BusinessType.DELETE)
@RequiresPermissions("system:dept:remove") @RequiresPermissions("system:dept:remove")
@PostMapping("/remove/{deptId}") @GetMapping("/remove/{deptId}")
@ResponseBody @ResponseBody
public AjaxResult remove(@PathVariable("deptId") Long deptId) public AjaxResult remove(@PathVariable("deptId") Long deptId)
{ {
if (deptService.selectDeptCount(deptId) > 0) if (deptService.selectDeptCount(deptId) > 0)
{ {
return error(1, "存在下级部门,不允许删除"); return AjaxResult.warn("存在下级部门,不允许删除");
} }
if (deptService.checkDeptExistUser(deptId)) if (deptService.checkDeptExistUser(deptId))
{ {
return error(1, "部门存在用户,不允许删除"); return AjaxResult.warn("部门存在用户,不允许删除");
} }
deptService.checkDeptDataScope(deptId);
return toAjax(deptService.deleteDeptById(deptId)); return toAjax(deptService.deleteDeptById(deptId));
} }
@ -127,40 +152,36 @@ public class SysDeptController extends BaseController
*/ */
@PostMapping("/checkDeptNameUnique") @PostMapping("/checkDeptNameUnique")
@ResponseBody @ResponseBody
public String checkDeptNameUnique(SysDept dept) public boolean checkDeptNameUnique(SysDept dept)
{ {
return deptService.checkDeptNameUnique(dept); return deptService.checkDeptNameUnique(dept);
} }
/** /**
* 选择部门树 * 选择部门树
*
* @param deptId 部门ID
* @param excludeId 排除ID
*/ */
@GetMapping("/selectDeptTree/{deptId}") @GetMapping(value = { "/selectDeptTree/{deptId}", "/selectDeptTree/{deptId}/{excludeId}" })
public String selectDeptTree(@PathVariable("deptId") Long deptId, ModelMap mmap) public String selectDeptTree(@PathVariable("deptId") Long deptId,
@PathVariable(value = "excludeId", required = false) Long excludeId, ModelMap mmap)
{ {
mmap.put("dept", deptService.selectDeptById(deptId)); mmap.put("dept", deptService.selectDeptById(deptId));
mmap.put("excludeId", excludeId);
return prefix + "/tree"; return prefix + "/tree";
} }
/** /**
* 加载部门列表树 * 加载部门列表树排除下级
*/ */
@GetMapping("/treeData") @GetMapping("/treeData/{excludeId}")
@ResponseBody @ResponseBody
public List<Map<String, Object>> treeData() public List<Ztree> treeDataExcludeChild(@PathVariable(value = "excludeId", required = false) Long excludeId)
{ {
List<Map<String, Object>> tree = deptService.selectDeptTree(new SysDept()); SysDept dept = new SysDept();
return tree; dept.setExcludeId(excludeId);
} List<Ztree> ztrees = deptService.selectDeptTreeExcludeChild(dept);
return ztrees;
/**
* 加载角色部门数据权限列表树
*/
@GetMapping("/roleDeptTreeData")
@ResponseBody
public List<Map<String, Object>> deptTreeData(SysRole role)
{
List<Map<String, Object>> tree = deptService.roleDeptTreeData(role);
return tree;
} }
} }

View File

@ -5,20 +5,20 @@ import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap; import org.springframework.ui.ModelMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.base.AjaxResult; 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.enums.BusinessType;
import com.ruoyi.common.page.TableDataInfo;
import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.util.ShiroUtils;
import com.ruoyi.system.domain.SysDictData;
import com.ruoyi.system.service.ISysDictDataService; import com.ruoyi.system.service.ISysDictDataService;
import com.ruoyi.framework.web.base.BaseController;
/** /**
* 数据字典信息 * 数据字典信息
@ -79,15 +79,16 @@ public class SysDictDataController extends BaseController
@RequiresPermissions("system:dict:add") @RequiresPermissions("system:dict:add")
@PostMapping("/add") @PostMapping("/add")
@ResponseBody @ResponseBody
public AjaxResult addSave(SysDictData dict) public AjaxResult addSave(@Validated SysDictData dict)
{ {
dict.setCreateBy(ShiroUtils.getLoginName()); dict.setCreateBy(getLoginName());
return toAjax(dictDataService.insertDictData(dict)); return toAjax(dictDataService.insertDictData(dict));
} }
/** /**
* 修改字典类型 * 修改字典类型
*/ */
@RequiresPermissions("system:dict:edit")
@GetMapping("/edit/{dictCode}") @GetMapping("/edit/{dictCode}")
public String edit(@PathVariable("dictCode") Long dictCode, ModelMap mmap) public String edit(@PathVariable("dictCode") Long dictCode, ModelMap mmap)
{ {
@ -102,9 +103,9 @@ public class SysDictDataController extends BaseController
@RequiresPermissions("system:dict:edit") @RequiresPermissions("system:dict:edit")
@PostMapping("/edit") @PostMapping("/edit")
@ResponseBody @ResponseBody
public AjaxResult editSave(SysDictData dict) public AjaxResult editSave(@Validated SysDictData dict)
{ {
dict.setUpdateBy(ShiroUtils.getLoginName()); dict.setUpdateBy(getLoginName());
return toAjax(dictDataService.updateDictData(dict)); return toAjax(dictDataService.updateDictData(dict));
} }
@ -114,6 +115,7 @@ public class SysDictDataController extends BaseController
@ResponseBody @ResponseBody
public AjaxResult remove(String ids) public AjaxResult remove(String ids)
{ {
return toAjax(dictDataService.deleteDictDataByIds(ids)); dictDataService.deleteDictDataByIds(ids);
return success();
} }
} }

View File

@ -5,20 +5,21 @@ import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap; import org.springframework.ui.ModelMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.base.AjaxResult; 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.enums.BusinessType;
import com.ruoyi.common.page.TableDataInfo;
import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.util.ShiroUtils;
import com.ruoyi.system.domain.SysDictType;
import com.ruoyi.system.service.ISysDictTypeService; import com.ruoyi.system.service.ISysDictTypeService;
import com.ruoyi.framework.web.base.BaseController;
/** /**
* 数据字典信息 * 数据字典信息
@ -79,15 +80,20 @@ public class SysDictTypeController extends BaseController
@RequiresPermissions("system:dict:add") @RequiresPermissions("system:dict:add")
@PostMapping("/add") @PostMapping("/add")
@ResponseBody @ResponseBody
public AjaxResult addSave(SysDictType dict) public AjaxResult addSave(@Validated SysDictType dict)
{ {
dict.setCreateBy(ShiroUtils.getLoginName()); if (!dictTypeService.checkDictTypeUnique(dict))
{
return error("新增字典'" + dict.getDictName() + "'失败,字典类型已存在");
}
dict.setCreateBy(getLoginName());
return toAjax(dictTypeService.insertDictType(dict)); return toAjax(dictTypeService.insertDictType(dict));
} }
/** /**
* 修改字典类型 * 修改字典类型
*/ */
@RequiresPermissions("system:dict:edit")
@GetMapping("/edit/{dictId}") @GetMapping("/edit/{dictId}")
public String edit(@PathVariable("dictId") Long dictId, ModelMap mmap) public String edit(@PathVariable("dictId") Long dictId, ModelMap mmap)
{ {
@ -102,9 +108,13 @@ public class SysDictTypeController extends BaseController
@RequiresPermissions("system:dict:edit") @RequiresPermissions("system:dict:edit")
@PostMapping("/edit") @PostMapping("/edit")
@ResponseBody @ResponseBody
public AjaxResult editSave(SysDictType dict) public AjaxResult editSave(@Validated SysDictType dict)
{ {
dict.setUpdateBy(ShiroUtils.getLoginName()); if (!dictTypeService.checkDictTypeUnique(dict))
{
return error("修改字典'" + dict.getDictName() + "'失败,字典类型已存在");
}
dict.setUpdateBy(getLoginName());
return toAjax(dictTypeService.updateDictType(dict)); return toAjax(dictTypeService.updateDictType(dict));
} }
@ -114,14 +124,21 @@ public class SysDictTypeController extends BaseController
@ResponseBody @ResponseBody
public AjaxResult remove(String ids) public AjaxResult remove(String ids)
{ {
try dictTypeService.deleteDictTypeByIds(ids);
{ return success();
return toAjax(dictTypeService.deleteDictTypeByIds(ids));
} }
catch (Exception e)
/**
* 刷新字典缓存
*/
@RequiresPermissions("system:dict:remove")
@Log(title = "字典类型", businessType = BusinessType.CLEAN)
@GetMapping("/refreshCache")
@ResponseBody
public AjaxResult refreshCache()
{ {
return error(e.getMessage()); dictTypeService.resetDictCache();
} return success();
} }
/** /**
@ -141,8 +158,31 @@ public class SysDictTypeController extends BaseController
*/ */
@PostMapping("/checkDictTypeUnique") @PostMapping("/checkDictTypeUnique")
@ResponseBody @ResponseBody
public String checkDictTypeUnique(SysDictType dictType) public boolean checkDictTypeUnique(SysDictType dictType)
{ {
return dictTypeService.checkDictTypeUnique(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

@ -1,15 +1,30 @@
package com.ruoyi.web.controller.system; package com.ruoyi.web.controller.system;
import java.util.Date;
import java.util.List; import java.util.List;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap; import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import com.ruoyi.common.config.Global; import org.springframework.web.bind.annotation.PathVariable;
import com.ruoyi.system.domain.SysMenu; import org.springframework.web.bind.annotation.PostMapping;
import com.ruoyi.system.domain.SysUser; 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; import com.ruoyi.system.service.ISysMenuService;
import com.ruoyi.framework.web.base.BaseController;
/** /**
* 首页 业务处理 * 首页 业务处理
@ -22,6 +37,12 @@ public class SysIndexController extends BaseController
@Autowired @Autowired
private ISysMenuService menuService; private ISysMenuService menuService;
@Autowired
private ISysConfigService configService;
@Autowired
private SysPasswordService passwordService;
// 系统首页 // 系统首页
@GetMapping("/index") @GetMapping("/index")
public String index(ModelMap mmap) public String index(ModelMap mmap)
@ -32,15 +53,126 @@ public class SysIndexController extends BaseController
List<SysMenu> menus = menuService.selectMenusByUser(user); List<SysMenu> menus = menuService.selectMenusByUser(user);
mmap.put("menus", menus); mmap.put("menus", menus);
mmap.put("user", user); mmap.put("user", user);
mmap.put("copyrightYear", Global.getCopyrightYear()); mmap.put("sideTheme", configService.selectConfigByKey("sys.index.sideTheme"));
return "index"; 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") @GetMapping("/system/main")
public String main(ModelMap mmap) public String main(ModelMap mmap)
{ {
mmap.put("version", Global.getVersion()); mmap.put("version", RuoYiConfig.getVersion());
return "main"; 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

@ -6,14 +6,19 @@ import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject; 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.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.base.AjaxResult; 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.common.utils.StringUtils;
import com.ruoyi.framework.util.ServletUtils; import com.ruoyi.framework.web.service.ConfigService;
import com.ruoyi.framework.web.base.BaseController;
/** /**
* 登录验证 * 登录验证
@ -23,15 +28,27 @@ import com.ruoyi.framework.web.base.BaseController;
@Controller @Controller
public class SysLoginController extends BaseController public class SysLoginController extends BaseController
{ {
/**
* 是否开启记住我功能
*/
@Value("${shiro.rememberMe.enabled: false}")
private boolean rememberMe;
@Autowired
private ConfigService configService;
@GetMapping("/login") @GetMapping("/login")
public String login(HttpServletRequest request, HttpServletResponse response) public String login(HttpServletRequest request, HttpServletResponse response, ModelMap mmap)
{ {
// 如果是Ajax请求返回Json字符串 // 如果是Ajax请求返回Json字符串
if (ServletUtils.isAjaxRequest(request)) if (ServletUtils.isAjaxRequest(request))
{ {
return ServletUtils.renderString(response, "{\"code\":\"1\",\"msg\":\"未登录或登录超时。请重新登录\"}"); return ServletUtils.renderString(response, "{\"code\":\"1\",\"msg\":\"未登录或登录超时。请重新登录\"}");
} }
// 是否开启记住我
mmap.put("isRemembered", rememberMe);
// 是否开启用户注册
mmap.put("isAllowRegister", Convert.toBool(configService.getKey("sys.account.registerUser"), false));
return "login"; return "login";
} }
@ -60,6 +77,6 @@ public class SysLoginController extends BaseController
@GetMapping("/unauth") @GetMapping("/unauth")
public String unauth() public String unauth()
{ {
return "/error/unauth"; return "error/unauth";
} }
} }

View File

@ -1,24 +1,26 @@
package com.ruoyi.web.controller.system; package com.ruoyi.web.controller.system;
import java.util.List; import java.util.List;
import java.util.Map;
import org.apache.shiro.authz.annotation.RequiresPermissions; import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap; import org.springframework.ui.ModelMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.base.AjaxResult; 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.enums.BusinessType;
import com.ruoyi.framework.util.ShiroUtils; import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.system.domain.SysMenu; import com.ruoyi.framework.shiro.util.AuthorizationUtils;
import com.ruoyi.system.domain.SysRole;
import com.ruoyi.system.service.ISysMenuService; import com.ruoyi.system.service.ISysMenuService;
import com.ruoyi.framework.web.base.BaseController;
/** /**
* 菜单信息 * 菜单信息
@ -42,11 +44,12 @@ public class SysMenuController extends BaseController
} }
@RequiresPermissions("system:menu:list") @RequiresPermissions("system:menu:list")
@GetMapping("/list") @PostMapping("/list")
@ResponseBody @ResponseBody
public List<SysMenu> list(SysMenu menu) public List<SysMenu> list(SysMenu menu)
{ {
List<SysMenu> menuList = menuService.selectMenuList(menu); Long userId = ShiroUtils.getUserId();
List<SysMenu> menuList = menuService.selectMenuList(menu, userId);
return menuList; return menuList;
} }
@ -55,19 +58,19 @@ public class SysMenuController extends BaseController
*/ */
@Log(title = "菜单管理", businessType = BusinessType.DELETE) @Log(title = "菜单管理", businessType = BusinessType.DELETE)
@RequiresPermissions("system:menu:remove") @RequiresPermissions("system:menu:remove")
@PostMapping("/remove/{menuId}") @GetMapping("/remove/{menuId}")
@ResponseBody @ResponseBody
public AjaxResult remove(@PathVariable("menuId") Long menuId) public AjaxResult remove(@PathVariable("menuId") Long menuId)
{ {
if (menuService.selectCountMenuByParentId(menuId) > 0) if (menuService.selectCountMenuByParentId(menuId) > 0)
{ {
return error(1, "存在子菜单,不允许删除"); return AjaxResult.warn("存在子菜单,不允许删除");
} }
if (menuService.selectCountRoleMenuByMenuId(menuId) > 0) if (menuService.selectCountRoleMenuByMenuId(menuId) > 0)
{ {
return error(1, "菜单已分配,不允许删除"); return AjaxResult.warn("菜单已分配,不允许删除");
} }
ShiroUtils.clearCachedAuthorizationInfo(); AuthorizationUtils.clearAllCachedAuthorizationInfo();
return toAjax(menuService.deleteMenuById(menuId)); return toAjax(menuService.deleteMenuById(menuId));
} }
@ -99,16 +102,21 @@ public class SysMenuController extends BaseController
@RequiresPermissions("system:menu:add") @RequiresPermissions("system:menu:add")
@PostMapping("/add") @PostMapping("/add")
@ResponseBody @ResponseBody
public AjaxResult addSave(SysMenu menu) public AjaxResult addSave(@Validated SysMenu menu)
{ {
menu.setCreateBy(ShiroUtils.getLoginName()); if (!menuService.checkMenuNameUnique(menu))
ShiroUtils.clearCachedAuthorizationInfo(); {
return error("新增菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
}
menu.setCreateBy(getLoginName());
AuthorizationUtils.clearAllCachedAuthorizationInfo();
return toAjax(menuService.insertMenu(menu)); return toAjax(menuService.insertMenu(menu));
} }
/** /**
* 修改菜单 * 修改菜单
*/ */
@RequiresPermissions("system:menu:edit")
@GetMapping("/edit/{menuId}") @GetMapping("/edit/{menuId}")
public String edit(@PathVariable("menuId") Long menuId, ModelMap mmap) public String edit(@PathVariable("menuId") Long menuId, ModelMap mmap)
{ {
@ -123,10 +131,14 @@ public class SysMenuController extends BaseController
@RequiresPermissions("system:menu:edit") @RequiresPermissions("system:menu:edit")
@PostMapping("/edit") @PostMapping("/edit")
@ResponseBody @ResponseBody
public AjaxResult editSave(SysMenu menu) public AjaxResult editSave(@Validated SysMenu menu)
{ {
menu.setUpdateBy(ShiroUtils.getLoginName()); if (!menuService.checkMenuNameUnique(menu))
ShiroUtils.clearCachedAuthorizationInfo(); {
return error("修改菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
}
menu.setUpdateBy(getLoginName());
AuthorizationUtils.clearAllCachedAuthorizationInfo();
return toAjax(menuService.updateMenu(menu)); return toAjax(menuService.updateMenu(menu));
} }
@ -144,7 +156,7 @@ public class SysMenuController extends BaseController
*/ */
@PostMapping("/checkMenuNameUnique") @PostMapping("/checkMenuNameUnique")
@ResponseBody @ResponseBody
public String checkMenuNameUnique(SysMenu menu) public boolean checkMenuNameUnique(SysMenu menu)
{ {
return menuService.checkMenuNameUnique(menu); return menuService.checkMenuNameUnique(menu);
} }
@ -154,10 +166,11 @@ public class SysMenuController extends BaseController
*/ */
@GetMapping("/roleMenuTreeData") @GetMapping("/roleMenuTreeData")
@ResponseBody @ResponseBody
public List<Map<String, Object>> roleMenuTreeData(SysRole role) public List<Ztree> roleMenuTreeData(SysRole role)
{ {
List<Map<String, Object>> tree = menuService.roleMenuTreeData(role); Long userId = ShiroUtils.getUserId();
return tree; List<Ztree> ztrees = menuService.roleMenuTreeData(role, userId);
return ztrees;
} }
/** /**
@ -165,10 +178,11 @@ public class SysMenuController extends BaseController
*/ */
@GetMapping("/menuTreeData") @GetMapping("/menuTreeData")
@ResponseBody @ResponseBody
public List<Map<String, Object>> menuTreeData(SysRole role) public List<Ztree> menuTreeData()
{ {
List<Map<String, Object>> tree = menuService.menuTreeData(); Long userId = ShiroUtils.getUserId();
return tree; List<Ztree> ztrees = menuService.menuTreeData(userId);
return ztrees;
} }
/** /**

View File

@ -5,19 +5,19 @@ import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap; import org.springframework.ui.ModelMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.base.AjaxResult; 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.enums.BusinessType;
import com.ruoyi.common.page.TableDataInfo;
import com.ruoyi.framework.util.ShiroUtils;
import com.ruoyi.system.domain.SysNotice; import com.ruoyi.system.domain.SysNotice;
import com.ruoyi.system.service.ISysNoticeService; import com.ruoyi.system.service.ISysNoticeService;
import com.ruoyi.framework.web.base.BaseController;
/** /**
* 公告 信息操作处理 * 公告 信息操作处理
@ -69,15 +69,16 @@ public class SysNoticeController extends BaseController
@Log(title = "通知公告", businessType = BusinessType.INSERT) @Log(title = "通知公告", businessType = BusinessType.INSERT)
@PostMapping("/add") @PostMapping("/add")
@ResponseBody @ResponseBody
public AjaxResult addSave(SysNotice notice) public AjaxResult addSave(@Validated SysNotice notice)
{ {
notice.setCreateBy(ShiroUtils.getLoginName()); notice.setCreateBy(getLoginName());
return toAjax(noticeService.insertNotice(notice)); return toAjax(noticeService.insertNotice(notice));
} }
/** /**
* 修改公告 * 修改公告
*/ */
@RequiresPermissions("system:notice:edit")
@GetMapping("/edit/{noticeId}") @GetMapping("/edit/{noticeId}")
public String edit(@PathVariable("noticeId") Long noticeId, ModelMap mmap) public String edit(@PathVariable("noticeId") Long noticeId, ModelMap mmap)
{ {
@ -92,12 +93,23 @@ public class SysNoticeController extends BaseController
@Log(title = "通知公告", businessType = BusinessType.UPDATE) @Log(title = "通知公告", businessType = BusinessType.UPDATE)
@PostMapping("/edit") @PostMapping("/edit")
@ResponseBody @ResponseBody
public AjaxResult editSave(SysNotice notice) public AjaxResult editSave(@Validated SysNotice notice)
{ {
notice.setUpdateBy(ShiroUtils.getLoginName()); notice.setUpdateBy(getLoginName());
return toAjax(noticeService.updateNotice(notice)); 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";
}
/** /**
* 删除公告 * 删除公告
*/ */

View File

@ -5,20 +5,20 @@ import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap; import org.springframework.ui.ModelMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.base.AjaxResult; 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.enums.BusinessType;
import com.ruoyi.common.page.TableDataInfo;
import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.util.ShiroUtils;
import com.ruoyi.system.domain.SysPost; import com.ruoyi.system.domain.SysPost;
import com.ruoyi.system.service.ISysPostService; import com.ruoyi.system.service.ISysPostService;
import com.ruoyi.framework.web.base.BaseController;
/** /**
* 岗位信息操作处理 * 岗位信息操作处理
@ -94,15 +94,24 @@ public class SysPostController extends BaseController
@Log(title = "岗位管理", businessType = BusinessType.INSERT) @Log(title = "岗位管理", businessType = BusinessType.INSERT)
@PostMapping("/add") @PostMapping("/add")
@ResponseBody @ResponseBody
public AjaxResult addSave(SysPost post) public AjaxResult addSave(@Validated SysPost post)
{ {
post.setCreateBy(ShiroUtils.getLoginName()); 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)); return toAjax(postService.insertPost(post));
} }
/** /**
* 修改岗位 * 修改岗位
*/ */
@RequiresPermissions("system:post:edit")
@GetMapping("/edit/{postId}") @GetMapping("/edit/{postId}")
public String edit(@PathVariable("postId") Long postId, ModelMap mmap) public String edit(@PathVariable("postId") Long postId, ModelMap mmap)
{ {
@ -117,9 +126,17 @@ public class SysPostController extends BaseController
@Log(title = "岗位管理", businessType = BusinessType.UPDATE) @Log(title = "岗位管理", businessType = BusinessType.UPDATE)
@PostMapping("/edit") @PostMapping("/edit")
@ResponseBody @ResponseBody
public AjaxResult editSave(SysPost post) public AjaxResult editSave(@Validated SysPost post)
{ {
post.setUpdateBy(ShiroUtils.getLoginName()); 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)); return toAjax(postService.updatePost(post));
} }
@ -128,7 +145,7 @@ public class SysPostController extends BaseController
*/ */
@PostMapping("/checkPostNameUnique") @PostMapping("/checkPostNameUnique")
@ResponseBody @ResponseBody
public String checkPostNameUnique(SysPost post) public boolean checkPostNameUnique(SysPost post)
{ {
return postService.checkPostNameUnique(post); return postService.checkPostNameUnique(post);
} }
@ -138,7 +155,7 @@ public class SysPostController extends BaseController
*/ */
@PostMapping("/checkPostCodeUnique") @PostMapping("/checkPostCodeUnique")
@ResponseBody @ResponseBody
public String checkPostCodeUnique(SysPost post) public boolean checkPostCodeUnique(SysPost post)
{ {
return postService.checkPostCodeUnique(post); return postService.checkPostCodeUnique(post);
} }

View File

@ -12,17 +12,18 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.base.AjaxResult; import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.config.Global; 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.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.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.framework.shiro.service.SysPasswordService;
import com.ruoyi.framework.util.FileUploadUtils;
import com.ruoyi.framework.util.ShiroUtils;
import com.ruoyi.system.domain.SysUser;
import com.ruoyi.system.service.ISysDictDataService;
import com.ruoyi.system.service.ISysUserService; import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.framework.web.base.BaseController;
/** /**
* 个人信息 业务处理 * 个人信息 业务处理
@ -43,9 +44,6 @@ public class SysProfileController extends BaseController
@Autowired @Autowired
private SysPasswordService passwordService; private SysPasswordService passwordService;
@Autowired
private ISysDictDataService dictDataService;
/** /**
* 个人信息 * 个人信息
*/ */
@ -53,7 +51,6 @@ public class SysProfileController extends BaseController
public String profile(ModelMap mmap) public String profile(ModelMap mmap)
{ {
SysUser user = getSysUser(); SysUser user = getSysUser();
user.setSex(dictDataService.selectDictLabel("sys_user_sex", user.getSex()));
mmap.put("user", user); mmap.put("user", user);
mmap.put("roleGroup", userService.selectUserRoleGroup(user.getUserId())); mmap.put("roleGroup", userService.selectUserRoleGroup(user.getUserId()));
mmap.put("postGroup", userService.selectUserPostGroup(user.getUserId())); mmap.put("postGroup", userService.selectUserPostGroup(user.getUserId()));
@ -65,11 +62,7 @@ public class SysProfileController extends BaseController
public boolean checkPassword(String password) public boolean checkPassword(String password)
{ {
SysUser user = getSysUser(); SysUser user = getSysUser();
if (passwordService.matches(user, password)) return passwordService.matches(user, password);
{
return true;
}
return false;
} }
@GetMapping("/resetPwd") @GetMapping("/resetPwd")
@ -86,21 +79,23 @@ public class SysProfileController extends BaseController
public AjaxResult resetPwd(String oldPassword, String newPassword) public AjaxResult resetPwd(String oldPassword, String newPassword)
{ {
SysUser user = getSysUser(); SysUser user = getSysUser();
if (StringUtils.isNotEmpty(newPassword) && passwordService.matches(user, oldPassword)) if (!passwordService.matches(user, oldPassword))
{ {
return error("修改密码失败,旧密码错误");
}
if (passwordService.matches(user, newPassword))
{
return error("新密码不能与旧密码相同");
}
user.setSalt(ShiroUtils.randomSalt()); user.setSalt(ShiroUtils.randomSalt());
user.setPassword(passwordService.encryptPassword(user.getLoginName(), newPassword, user.getSalt())); user.setPassword(passwordService.encryptPassword(user.getLoginName(), newPassword, user.getSalt()));
user.setPwdUpdateDate(DateUtils.getNowDate());
if (userService.resetUserPwd(user) > 0) if (userService.resetUserPwd(user) > 0)
{ {
setSysUser(userService.selectUserById(user.getUserId())); setSysUser(userService.selectUserById(user.getUserId()));
return success(); return success();
} }
return error(); return error("修改密码异常,请联系管理员");
}
else
{
return error("修改密码失败,旧密码错误");
}
} }
/** /**
@ -138,6 +133,14 @@ public class SysProfileController extends BaseController
currentUser.setEmail(user.getEmail()); currentUser.setEmail(user.getEmail());
currentUser.setPhonenumber(user.getPhonenumber()); currentUser.setPhonenumber(user.getPhonenumber());
currentUser.setSex(user.getSex()); 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) if (userService.updateUserInfo(currentUser) > 0)
{ {
setSysUser(userService.selectUserById(currentUser.getUserId())); setSysUser(userService.selectUserById(currentUser.getUserId()));
@ -159,7 +162,7 @@ public class SysProfileController extends BaseController
{ {
if (!file.isEmpty()) if (!file.isEmpty())
{ {
String avatar = FileUploadUtils.upload(Global.getAvatarPath(), file); String avatar = FileUploadUtils.upload(RuoYiConfig.getAvatarPath(), file, MimeTypeUtils.IMAGE_EXTENSION);
currentUser.setAvatar(avatar); currentUser.setAvatar(avatar);
if (userService.updateUserInfo(currentUser) > 0) if (userService.updateUserInfo(currentUser) > 0)
{ {

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

@ -4,22 +4,27 @@ import java.util.List;
import org.apache.shiro.authz.annotation.RequiresPermissions; import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap; import org.springframework.ui.ModelMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.base.AjaxResult; 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.enums.BusinessType;
import com.ruoyi.common.page.TableDataInfo;
import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.util.ShiroUtils; import com.ruoyi.framework.shiro.util.AuthorizationUtils;
import com.ruoyi.system.domain.SysRole; import com.ruoyi.system.domain.SysUserRole;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.ISysRoleService; import com.ruoyi.system.service.ISysRoleService;
import com.ruoyi.framework.web.base.BaseController; import com.ruoyi.system.service.ISysUserService;
/** /**
* 角色信息 * 角色信息
@ -35,6 +40,12 @@ public class SysRoleController extends BaseController
@Autowired @Autowired
private ISysRoleService roleService; private ISysRoleService roleService;
@Autowired
private ISysUserService userService;
@Autowired
private ISysDeptService deptService;
@RequiresPermissions("system:role:view") @RequiresPermissions("system:role:view")
@GetMapping() @GetMapping()
public String role() public String role()
@ -78,12 +89,19 @@ public class SysRoleController extends BaseController
@RequiresPermissions("system:role:add") @RequiresPermissions("system:role:add")
@Log(title = "角色管理", businessType = BusinessType.INSERT) @Log(title = "角色管理", businessType = BusinessType.INSERT)
@PostMapping("/add") @PostMapping("/add")
@Transactional(rollbackFor = Exception.class)
@ResponseBody @ResponseBody
public AjaxResult addSave(SysRole role) public AjaxResult addSave(@Validated SysRole role)
{ {
role.setCreateBy(ShiroUtils.getLoginName()); if (!roleService.checkRoleNameUnique(role))
ShiroUtils.clearCachedAuthorizationInfo(); {
return error("新增角色'" + role.getRoleName() + "'失败,角色名称已存在");
}
else if (!roleService.checkRoleKeyUnique(role))
{
return error("新增角色'" + role.getRoleName() + "'失败,角色权限已存在");
}
role.setCreateBy(getLoginName());
AuthorizationUtils.clearAllCachedAuthorizationInfo();
return toAjax(roleService.insertRole(role)); return toAjax(roleService.insertRole(role));
} }
@ -91,9 +109,11 @@ public class SysRoleController extends BaseController
/** /**
* 修改角色 * 修改角色
*/ */
@RequiresPermissions("system:role:edit")
@GetMapping("/edit/{roleId}") @GetMapping("/edit/{roleId}")
public String edit(@PathVariable("roleId") Long roleId, ModelMap mmap) public String edit(@PathVariable("roleId") Long roleId, ModelMap mmap)
{ {
roleService.checkRoleDataScope(roleId);
mmap.put("role", roleService.selectRoleById(roleId)); mmap.put("role", roleService.selectRoleById(roleId));
return prefix + "/edit"; return prefix + "/edit";
} }
@ -104,37 +124,52 @@ public class SysRoleController extends BaseController
@RequiresPermissions("system:role:edit") @RequiresPermissions("system:role:edit")
@Log(title = "角色管理", businessType = BusinessType.UPDATE) @Log(title = "角色管理", businessType = BusinessType.UPDATE)
@PostMapping("/edit") @PostMapping("/edit")
@Transactional(rollbackFor = Exception.class)
@ResponseBody @ResponseBody
public AjaxResult editSave(SysRole role) public AjaxResult editSave(@Validated SysRole role)
{ {
role.setUpdateBy(ShiroUtils.getLoginName()); roleService.checkRoleAllowed(role);
ShiroUtils.clearCachedAuthorizationInfo(); 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)); return toAjax(roleService.updateRole(role));
} }
/** /**
* 新增数据权限 * 角色分配数据权限
*/ */
@GetMapping("/rule/{roleId}") @GetMapping("/authDataScope/{roleId}")
public String rule(@PathVariable("roleId") Long roleId, ModelMap mmap) public String authDataScope(@PathVariable("roleId") Long roleId, ModelMap mmap)
{ {
mmap.put("role", roleService.selectRoleById(roleId)); mmap.put("role", roleService.selectRoleById(roleId));
return prefix + "/rule"; return prefix + "/dataScope";
} }
/** /**
* 修改保存数据权限 * 保存角色分配数据权限
*/ */
@RequiresPermissions("system:role:edit") @RequiresPermissions("system:role:edit")
@Log(title = "角色管理", businessType = BusinessType.UPDATE) @Log(title = "角色管理", businessType = BusinessType.UPDATE)
@PostMapping("/rule") @PostMapping("/authDataScope")
@Transactional(rollbackFor = Exception.class)
@ResponseBody @ResponseBody
public AjaxResult ruleSave(SysRole role) public AjaxResult authDataScopeSave(SysRole role)
{ {
role.setUpdateBy(ShiroUtils.getLoginName()); roleService.checkRoleAllowed(role);
return toAjax(roleService.updateRule(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") @RequiresPermissions("system:role:remove")
@ -142,23 +177,16 @@ public class SysRoleController extends BaseController
@PostMapping("/remove") @PostMapping("/remove")
@ResponseBody @ResponseBody
public AjaxResult remove(String ids) public AjaxResult remove(String ids)
{
try
{ {
return toAjax(roleService.deleteRoleByIds(ids)); return toAjax(roleService.deleteRoleByIds(ids));
} }
catch (Exception e)
{
return error(e.getMessage());
}
}
/** /**
* 校验角色名称 * 校验角色名称
*/ */
@PostMapping("/checkRoleNameUnique") @PostMapping("/checkRoleNameUnique")
@ResponseBody @ResponseBody
public String checkRoleNameUnique(SysRole role) public boolean checkRoleNameUnique(SysRole role)
{ {
return roleService.checkRoleNameUnique(role); return roleService.checkRoleNameUnique(role);
} }
@ -168,7 +196,7 @@ public class SysRoleController extends BaseController
*/ */
@PostMapping("/checkRoleKeyUnique") @PostMapping("/checkRoleKeyUnique")
@ResponseBody @ResponseBody
public String checkRoleKeyUnique(SysRole role) public boolean checkRoleKeyUnique(SysRole role)
{ {
return roleService.checkRoleKeyUnique(role); return roleService.checkRoleKeyUnique(role);
} }
@ -191,6 +219,104 @@ public class SysRoleController extends BaseController
@ResponseBody @ResponseBody
public AjaxResult changeStatus(SysRole role) public AjaxResult changeStatus(SysRole role)
{ {
roleService.checkRoleAllowed(role);
roleService.checkRoleDataScope(role.getRoleId());
return toAjax(roleService.changeStatus(role)); 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));
}
/**
* 选择用户
*/
@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

@ -1,11 +1,13 @@
package com.ruoyi.web.controller.system; package com.ruoyi.web.controller.system;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions; import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap; import org.springframework.ui.ModelMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
@ -13,15 +15,22 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.base.AjaxResult; 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.enums.BusinessType;
import com.ruoyi.common.page.TableDataInfo; import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.shiro.service.SysPasswordService; import com.ruoyi.framework.shiro.service.SysPasswordService;
import com.ruoyi.framework.util.ShiroUtils; import com.ruoyi.framework.shiro.util.AuthorizationUtils;
import com.ruoyi.framework.web.base.BaseController; import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.domain.SysUser;
import com.ruoyi.system.service.ISysPostService; import com.ruoyi.system.service.ISysPostService;
import com.ruoyi.system.service.ISysRoleService; import com.ruoyi.system.service.ISysRoleService;
import com.ruoyi.system.service.ISysUserService; import com.ruoyi.system.service.ISysUserService;
@ -43,6 +52,9 @@ public class SysUserController extends BaseController
@Autowired @Autowired
private ISysRoleService roleService; private ISysRoleService roleService;
@Autowired
private ISysDeptService deptService;
@Autowired @Autowired
private ISysPostService postService; private ISysPostService postService;
@ -85,8 +97,7 @@ public class SysUserController extends BaseController
{ {
ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class); ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
List<SysUser> userList = util.importExcel(file.getInputStream()); List<SysUser> userList = util.importExcel(file.getInputStream());
String operName = getSysUser().getLoginName(); String message = userService.importUser(userList, updateSupport, getLoginName());
String message = userService.importUser(userList, updateSupport, operName);
return AjaxResult.success(message); return AjaxResult.success(message);
} }
@ -105,7 +116,7 @@ public class SysUserController extends BaseController
@GetMapping("/add") @GetMapping("/add")
public String add(ModelMap mmap) public String add(ModelMap mmap)
{ {
mmap.put("roles", roleService.selectRoleAll()); mmap.put("roles", roleService.selectRoleAll().stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
mmap.put("posts", postService.selectPostAll()); mmap.put("posts", postService.selectPostAll());
return prefix + "/add"; return prefix + "/add";
} }
@ -116,52 +127,90 @@ public class SysUserController extends BaseController
@RequiresPermissions("system:user:add") @RequiresPermissions("system:user:add")
@Log(title = "用户管理", businessType = BusinessType.INSERT) @Log(title = "用户管理", businessType = BusinessType.INSERT)
@PostMapping("/add") @PostMapping("/add")
@Transactional(rollbackFor = Exception.class)
@ResponseBody @ResponseBody
public AjaxResult addSave(SysUser user) public AjaxResult addSave(@Validated SysUser user)
{ {
if (StringUtils.isNotNull(user.getUserId()) && SysUser.isAdmin(user.getUserId())) deptService.checkDeptDataScope(user.getDeptId());
roleService.checkRoleDataScope(user.getRoleIds());
if (!userService.checkLoginNameUnique(user))
{ {
return error("不允许修改超级管理员用户"); 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.setSalt(ShiroUtils.randomSalt());
user.setPassword(passwordService.encryptPassword(user.getLoginName(), user.getPassword(), user.getSalt())); user.setPassword(passwordService.encryptPassword(user.getLoginName(), user.getPassword(), user.getSalt()));
user.setCreateBy(ShiroUtils.getLoginName()); user.setPwdUpdateDate(DateUtils.getNowDate());
user.setCreateBy(getLoginName());
return toAjax(userService.insertUser(user)); return toAjax(userService.insertUser(user));
} }
/** /**
* 修改用户 * 修改用户
*/ */
@RequiresPermissions("system:user:edit")
@GetMapping("/edit/{userId}") @GetMapping("/edit/{userId}")
public String edit(@PathVariable("userId") Long userId, ModelMap mmap) 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("user", userService.selectUserById(userId));
mmap.put("roles", roleService.selectRolesByUserId(userId)); mmap.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
mmap.put("posts", postService.selectPostsByUserId(userId)); mmap.put("posts", postService.selectPostsByUserId(userId));
return prefix + "/edit"; 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") @RequiresPermissions("system:user:edit")
@Log(title = "用户管理", businessType = BusinessType.UPDATE) @Log(title = "用户管理", businessType = BusinessType.UPDATE)
@PostMapping("/edit") @PostMapping("/edit")
@Transactional(rollbackFor = Exception.class)
@ResponseBody @ResponseBody
public AjaxResult editSave(SysUser user) public AjaxResult editSave(@Validated SysUser user)
{ {
if (StringUtils.isNotNull(user.getUserId()) && SysUser.isAdmin(user.getUserId())) userService.checkUserAllowed(user);
userService.checkUserDataScope(user.getUserId());
deptService.checkDeptDataScope(user.getDeptId());
roleService.checkRoleDataScope(user.getRoleIds());
if (!userService.checkLoginNameUnique(user))
{ {
return error("不允许修改超级管理员用户"); return error("修改用户'" + user.getLoginName() + "'失败,登录账号已存在");
} }
user.setUpdateBy(ShiroUtils.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)); return toAjax(userService.updateUser(user));
} }
@RequiresPermissions("system:user:resetPwd") @RequiresPermissions("system:user:resetPwd")
@Log(title = "重置密码", businessType = BusinessType.UPDATE)
@GetMapping("/resetPwd/{userId}") @GetMapping("/resetPwd/{userId}")
public String resetPwd(@PathVariable("userId") Long userId, ModelMap mmap) public String resetPwd(@PathVariable("userId") Long userId, ModelMap mmap)
{ {
@ -175,9 +224,49 @@ public class SysUserController extends BaseController
@ResponseBody @ResponseBody
public AjaxResult resetPwdSave(SysUser user) public AjaxResult resetPwdSave(SysUser user)
{ {
userService.checkUserAllowed(user);
userService.checkUserDataScope(user.getUserId());
user.setSalt(ShiroUtils.randomSalt()); user.setSalt(ShiroUtils.randomSalt());
user.setPassword(passwordService.encryptPassword(user.getLoginName(), user.getPassword(), user.getSalt())); user.setPassword(passwordService.encryptPassword(user.getLoginName(), user.getPassword(), user.getSalt()));
return toAjax(userService.resetUserPwd(user)); if (userService.resetUserPwd(user) > 0)
{
if (ShiroUtils.getUserId().longValue() == user.getUserId().longValue())
{
setSysUser(userService.selectUserById(user.getUserId()));
}
return success();
}
return error();
}
/**
* 进入授权角色页
*/
@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") @RequiresPermissions("system:user:remove")
@ -186,24 +275,21 @@ public class SysUserController extends BaseController
@ResponseBody @ResponseBody
public AjaxResult remove(String ids) public AjaxResult remove(String ids)
{ {
try if (ArrayUtils.contains(Convert.toLongArray(ids), getUserId()))
{ {
return error("当前用户不能删除");
}
return toAjax(userService.deleteUserByIds(ids)); return toAjax(userService.deleteUserByIds(ids));
} }
catch (Exception e)
{
return error(e.getMessage());
}
}
/** /**
* 校验用户名 * 校验用户名
*/ */
@PostMapping("/checkLoginNameUnique") @PostMapping("/checkLoginNameUnique")
@ResponseBody @ResponseBody
public String checkLoginNameUnique(SysUser user) public boolean checkLoginNameUnique(SysUser user)
{ {
return userService.checkLoginNameUnique(user.getLoginName()); return userService.checkLoginNameUnique(user);
} }
/** /**
@ -211,7 +297,7 @@ public class SysUserController extends BaseController
*/ */
@PostMapping("/checkPhoneUnique") @PostMapping("/checkPhoneUnique")
@ResponseBody @ResponseBody
public String checkPhoneUnique(SysUser user) public boolean checkPhoneUnique(SysUser user)
{ {
return userService.checkPhoneUnique(user); return userService.checkPhoneUnique(user);
} }
@ -221,7 +307,7 @@ public class SysUserController extends BaseController
*/ */
@PostMapping("/checkEmailUnique") @PostMapping("/checkEmailUnique")
@ResponseBody @ResponseBody
public String checkEmailUnique(SysUser user) public boolean checkEmailUnique(SysUser user)
{ {
return userService.checkEmailUnique(user); return userService.checkEmailUnique(user);
} }
@ -235,6 +321,33 @@ public class SysUserController extends BaseController
@ResponseBody @ResponseBody
public AjaxResult changeStatus(SysUser user) public AjaxResult changeStatus(SysUser user)
{ {
userService.checkUserAllowed(user);
userService.checkUserDataScope(user.getUserId());
return toAjax(userService.changeStatus(user)); 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

@ -4,7 +4,7 @@ import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import com.ruoyi.framework.web.base.BaseController; import com.ruoyi.common.core.controller.BaseController;
/** /**
* build 表单构建 * build 表单构建

View File

@ -1,89 +0,0 @@
package com.ruoyi.web.controller.tool;
import java.io.IOException;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.IOUtils;
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.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.enums.BusinessType;
import com.ruoyi.common.page.TableDataInfo;
import com.ruoyi.common.support.Convert;
import com.ruoyi.generator.domain.TableInfo;
import com.ruoyi.generator.service.IGenService;
import com.ruoyi.framework.web.base.BaseController;
/**
* 代码生成 操作处理
*
* @author ruoyi
*/
@Controller
@RequestMapping("/tool/gen")
public class GenController extends BaseController
{
private String prefix = "tool/gen";
@Autowired
private IGenService genService;
@RequiresPermissions("tool:gen:view")
@GetMapping()
public String gen()
{
return prefix + "/gen";
}
@RequiresPermissions("tool:gen:list")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(TableInfo tableInfo)
{
startPage();
List<TableInfo> list = genService.selectTableList(tableInfo);
return getDataTable(list);
}
/**
* 生成代码
*/
@RequiresPermissions("tool:gen:code")
@Log(title = "代码生成", businessType = BusinessType.GENCODE)
@GetMapping("/genCode/{tableName}")
public void genCode(HttpServletResponse response, @PathVariable("tableName") String tableName) throws IOException
{
byte[] data = genService.generatorCode(tableName);
response.reset();
response.setHeader("Content-Disposition", "attachment; filename=\"ruoyi.zip\"");
response.addHeader("Content-Length", "" + data.length);
response.setContentType("application/octet-stream; charset=UTF-8");
IOUtils.write(data, response.getOutputStream());
}
/**
* 批量生成代码
*/
@RequiresPermissions("tool:gen:code")
@Log(title = "代码生成", businessType = BusinessType.GENCODE)
@GetMapping("/batchGenCode")
@ResponseBody
public void batchGenCode(HttpServletResponse response, String tables) throws IOException
{
String[] tableNames = Convert.toStrArray(tables);
byte[] data = genService.generatorCode(tableNames);
response.reset();
response.setHeader("Content-Disposition", "attachment; filename=\"ruoyi.zip\"");
response.addHeader("Content-Length", "" + data.length);
response.setContentType("application/octet-stream; charset=UTF-8");
IOUtils.write(data, response.getOutputStream());
}
}

View File

@ -4,7 +4,7 @@ import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import com.ruoyi.framework.web.base.BaseController; import com.ruoyi.common.core.controller.BaseController;
/** /**
* swagger 接口 * swagger 接口
@ -19,6 +19,6 @@ public class SwaggerController extends BaseController
@GetMapping() @GetMapping()
public String index() public String index()
{ {
return redirect("/swagger-ui.html"); return redirect("/swagger-ui/index.html");
} }
} }

View File

@ -1,119 +1,152 @@
package com.ruoyi.web.controller.tool; package com.ruoyi.web.controller.tool;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping; 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.PostMapping;
import org.springframework.web.bind.annotation.PutMapping; 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.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.base.AjaxResult; import com.ruoyi.common.core.domain.R;
import com.ruoyi.framework.web.base.BaseController; import com.ruoyi.common.utils.StringUtils;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam; 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; import io.swagger.annotations.ApiOperation;
/** /**
* swagger 测试方法 * swagger 用户测试方法
* *
* @author ruoyi * @author ruoyi
*/ */
@Api("用户信息管理") @Api("用户信息管理")
@RestController @RestController
@RequestMapping("/test/*") @RequestMapping("/test/user")
public class TestController extends BaseController public class TestController extends BaseController
{ {
private final static List<Test> testList = new ArrayList<>(); private final static Map<Integer, UserEntity> users = new LinkedHashMap<Integer, UserEntity>();
{ {
testList.add(new Test("1", "admin", "admin123")); users.put(1, new UserEntity(1, "admin", "admin123", "15888888888"));
testList.add(new Test("2", "ry", "admin123")); users.put(2, new UserEntity(2, "ry", "admin123", "15666666666"));
} }
@ApiOperation("获取列表") @ApiOperation("获取用户列表")
@GetMapping("list") @GetMapping("/list")
public List<Test> testList() public R<List<UserEntity>> userList()
{ {
return testList; 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("新增用户") @ApiOperation("新增用户")
@PostMapping("save") @ApiImplicitParams({
public AjaxResult save(Test test) @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)
{ {
return testList.add(test) ? success() : error(); if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId()))
{
return R.fail("用户ID不能为空");
}
users.put(user.getUserId(), user);
return R.ok();
} }
@ApiOperation("更新用户") @ApiOperation("更新用户")
@ApiImplicitParam(name = "Test", value = "单个用户信息", dataType = "Test") @PutMapping("/update")
@PutMapping("update") public R<String> update(@RequestBody UserEntity user)
public AjaxResult update(Test test)
{ {
return testList.remove(test) && testList.add(test) ? success() : error(); 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("删除用户") @ApiOperation("删除用户信息")
@ApiImplicitParam(name = "Tests", value = "单个用户信息", dataType = "Test") @ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class)
@DeleteMapping("delete") @DeleteMapping("/{userId}")
public AjaxResult delete(Test test) public R<String> delete(@PathVariable Integer userId)
{ {
return testList.remove(test) ? success() : error(); if (!users.isEmpty() && users.containsKey(userId))
{
users.remove(userId);
return R.ok();
}
else
{
return R.fail("用户不存在");
}
} }
} }
class Test @ApiModel(value = "UserEntity", description = "用户实体")
class UserEntity
{ {
private String userId; @ApiModelProperty("用户ID")
private Integer userId;
@ApiModelProperty("用户名称")
private String username; private String username;
@ApiModelProperty("用户密码")
private String password; private String password;
public Test() @ApiModelProperty("用户手机")
private String mobile;
public UserEntity()
{ {
} }
public Test(String userId, String username, String password) public UserEntity(Integer userId, String username, String password, String mobile)
{ {
this.userId = userId; this.userId = userId;
this.username = username; this.username = username;
this.password = password; this.password = password;
this.mobile = mobile;
} }
@Override public Integer getUserId()
public boolean equals(Object o)
{
if (this == o)
{
return true;
}
if (o == null || getClass() != o.getClass())
{
return false;
}
Test test = (Test) o;
return userId != null ? userId.equals(test.userId) : test.userId == null;
}
@Override
public int hashCode()
{
int result = userId != null ? userId.hashCode() : 0;
result = 31 * result + (username != null ? username.hashCode() : 0);
result = 31 * result + (password != null ? password.hashCode() : 0);
return result;
}
public String getUserId()
{ {
return userId; return userId;
} }
public void setUserId(String userId) public void setUserId(Integer userId)
{ {
this.userId = userId; this.userId = userId;
} }
@ -137,4 +170,14 @@ class Test
{ {
this.password = password; this.password = password;
} }
public String getMobile()
{
return mobile;
}
public void setMobile(String mobile)
{
this.mobile = mobile;
}
} }

View File

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

View File

@ -24,6 +24,10 @@ spring:
maxActive: 20 maxActive: 20
# 配置获取连接等待超时的时间 # 配置获取连接等待超时的时间
maxWait: 60000 maxWait: 60000
# 配置连接超时时间
connectTimeout: 30000
# 配置网络超时时间
socketTimeout: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 60000 timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒 # 配置一个连接在池中最小生存的时间,单位是毫秒
@ -35,11 +39,19 @@ spring:
testWhileIdle: true testWhileIdle: true
testOnBorrow: false testOnBorrow: false
testOnReturn: false testOnReturn: false
webStatFilter:
enabled: true
statViewServlet: statViewServlet:
enabled: true enabled: true
url-pattern: /monitor/druid/* # 设置白名单,不填则允许所有访问
allow:
url-pattern: /druid/*
# 控制台管理用户名和密码
login-username: ruoyi
login-password: 123456
filter: filter:
stat: stat:
enabled: true
# 慢SQL记录 # 慢SQL记录
log-slow-sql: true log-slow-sql: true
slow-sql-millis: 1000 slow-sql-millis: 1000

View File

@ -3,35 +3,39 @@ ruoyi:
# 名称 # 名称
name: RuoYi name: RuoYi
# 版本 # 版本
version: 3.2.0 version: 4.7.9
# 版权年份 # 版权年份
copyrightYear: 2019 copyrightYear: 2024
# 文件上传路径 # 实例演示开关
profile: D:/profile/ demoEnabled: true
# 文件路径 示例( Windows配置D:/ruoyi/uploadPathLinux配置 /home/ruoyi/uploadPath
profile: D:/ruoyi/uploadPath
# 获取ip地址开关 # 获取ip地址开关
addressEnabled: true addressEnabled: false
# 开发环境配置 # 开发环境配置
server: server:
# 服务端口 # 服务器的HTTP端口默认为80
port: 80 port: 80
servlet: servlet:
# 项目contextPath # 应用的访问路径
context-path: / context-path: /
tomcat: tomcat:
# tomcat的URI编码 # tomcat的URI编码
uri-encoding: UTF-8 uri-encoding: UTF-8
# 连接数满后的排队数默认为100
accept-count: 1000
threads:
# tomcat最大线程数默认为200 # tomcat最大线程数默认为200
max-threads: 800 max: 800
# Tomcat启动初始化的线程数默认值25 # Tomcat启动初始化的线程数默认值10
min-spare-threads: 30 min-spare: 100
# 日志配置 # 日志配置
logging: logging:
level: level:
com.ruoyi: debug com.ruoyi: debug
org.springframework: WARN org.springframework: warn
org.spring.springboot.dao: debug
# 用户配置 # 用户配置
user: user:
@ -50,7 +54,7 @@ spring:
# 资源信息 # 资源信息
messages: messages:
# 国际化资源文件路径 # 国际化资源文件路径
basename: i18n/messages basename: static/i18n/messages
jackson: jackson:
time-zone: GMT+8 time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss date-format: yyyy-MM-dd HH:mm:ss
@ -59,8 +63,10 @@ spring:
# 文件上传 # 文件上传
servlet: servlet:
multipart: multipart:
max-file-size: 30MB # 单个文件大小
max-request-size: 30MB max-file-size: 10MB
# 设置总上传的文件大小
max-request-size: 20MB
# 服务模块 # 服务模块
devtools: devtools:
restart: restart:
@ -70,16 +76,15 @@ spring:
# MyBatis # MyBatis
mybatis: mybatis:
# 搜索指定包别名 # 搜索指定包别名
typeAliasesPackage: com.ruoyi typeAliasesPackage: com.ruoyi.**.domain
# 配置mapper的扫描找到所有的mapper.xml映射文件 # 配置mapper的扫描找到所有的mapper.xml映射文件
mapperLocations: classpath*:mapper/**/*Mapper.xml mapperLocations: classpath*:mapper/**/*Mapper.xml
# 加载全局的配置文件 # 加载全局的配置文件
configLocation: classpath:mapper/mybatis-config.xml configLocation: classpath:mybatis/mybatis-config.xml
# PageHelper分页插件 # PageHelper分页插件
pagehelper: pagehelper:
helperDialect: mysql helperDialect: mysql
reasonable: true
supportMethodsArguments: true supportMethodsArguments: true
params: count=countSql params: count=countSql
@ -94,7 +99,7 @@ shiro:
indexUrl: /index indexUrl: /index
# 验证码开关 # 验证码开关
captchaEnabled: true captchaEnabled: true
# 验证码类型 math 数组计算 char 字符 # 验证码类型 math 数字计算 char 字符验证
captchaType: math captchaType: math
cookie: cookie:
# 设置Cookie的域名 默认空,即当前访问的域名 # 设置Cookie的域名 默认空,即当前访问的域名
@ -105,13 +110,22 @@ shiro:
httpOnly: true httpOnly: true
# 设置Cookie的过期时间天为单位 # 设置Cookie的过期时间天为单位
maxAge: 30 maxAge: 30
# 设置密钥务必保持唯一性生成方式直接拷贝到main运行即可Base64.encodeToString(CipherUtils.generateNewKey(128, "AES").getEncoded()) 默认启动生成随机秘钥随机秘钥会导致之前客户端RememberMe Cookie无效如设置固定秘钥RememberMe Cookie则有效
cipherKey:
session: session:
# Session超时时间默认30分钟 # Session超时时间-1代表永不过期默认30分钟
expireTime: 30 expireTime: 30
# 同步session到数据库的周期默认1分钟 # 同步session到数据库的周期默认1分钟
dbSyncPeriod: 1 dbSyncPeriod: 1
# 相隔多久检查一次session的有效性默认就是10分钟 # 相隔多久检查一次session的有效性默认就是10分钟
validationInterval: 10 validationInterval: 10
# 同一个用户最大会话数比如2的意思是同一个账号允许最多同时两个人登录默认-1不限制
maxSession: -1
# 踢出之前登录的/之后登录的用户,默认踢出之前登录的用户
kickoutAfter: false
rememberMe:
# 是否开启记住我
enabled: true
# 防止XSS攻击 # 防止XSS攻击
xss: xss:
@ -122,13 +136,7 @@ xss:
# 匹配链接 # 匹配链接
urlPatterns: /system/*,/monitor/*,/tool/* urlPatterns: /system/*,/monitor/*,/tool/*
# 代码生成 # Swagger配置
gen: swagger:
# 作者 # 是否开启swagger
author: ruoyi enabled: true
# 默认生成包路径 system 需改成自己的模块名称 如 system monitor tool
packageName: com.ruoyi.system
# 自动去除表前缀默认是true
autoRemovePre: true
# 表前缀(类名不会包含表前缀)
tablePrefix: sys_

View File

@ -4,6 +4,14 @@
<!-- 磁盘缓存位置 --> <!-- 磁盘缓存位置 -->
<diskStore path="java.io.tmpdir"/> <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 <defaultCache
maxEntriesLocalHeap="1000" maxEntriesLocalHeap="1000"
@ -20,8 +28,64 @@
timeToIdleSeconds="600" timeToIdleSeconds="600"
timeToLiveSeconds="0" timeToLiveSeconds="0"
overflowToDisk="false" overflowToDisk="false"
statistics="true"> statistics="false">
</cache> </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> </ehcache>

View File

@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<!-- 日志存放路径 -->
<property name="log.path" value="/home/ruoyi/logs" /> <property name="log.path" value="/home/ruoyi/logs" />
<!-- 日志输出格式 -->
<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" /> <property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
<!-- 控制台输出 --> <!-- 控制台输出 -->
@ -14,8 +15,9 @@
<!-- 系统日志输出 --> <!-- 系统日志输出 -->
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender"> <appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/sys-info.log</file> <file>${log.path}/sys-info.log</file>
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 按天回滚 daily --> <!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern> <fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 60天 --> <!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory> <maxHistory>60</maxHistory>
@ -24,15 +26,20 @@
<pattern>${log.pattern}</pattern> <pattern>${log.pattern}</pattern>
</encoder> </encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter"> <filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>INFO</level> <level>INFO</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch> <onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch> <onMismatch>DENY</onMismatch>
</filter> </filter>
</appender> </appender>
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender"> <appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/sys-error.log</file> <file>${log.path}/sys-error.log</file>
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/sys-error.%d{yyyy-MM-dd}.log</fileNamePattern> <fileNamePattern>${log.path}/sys-error.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 60天 --> <!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory> <maxHistory>60</maxHistory>
@ -41,8 +48,11 @@
<pattern>${log.pattern}</pattern> <pattern>${log.pattern}</pattern>
</encoder> </encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter"> <filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>ERROR</level> <level>ERROR</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch> <onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch> <onMismatch>DENY</onMismatch>
</filter> </filter>
</appender> </appender>
@ -61,13 +71,10 @@
</encoder> </encoder>
</appender> </appender>
<!-- 显示形成的sql、使用的参数、结果集 --> <!-- 系统模块日志级别控制 -->
<!--
<logger name="java.sql" level="debug" />
<logger name="org.springframework.jdbc" level="debug" />
-->
<logger name="com.ruoyi" level="info" /> <logger name="com.ruoyi" level="info" />
<!-- Spring日志级别控制 -->
<logger name="org.springframework" level="warn" />
<root level="info"> <root level="info">
<appender-ref ref="console" /> <appender-ref ref="console" />

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,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 it is too large Load Diff

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 it is too large Load Diff

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

File diff suppressed because one or more lines are too long

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

@ -1,146 +1,189 @@
/* eslint-disable no-unused-vars */
/** /**
* @author zhixin wen <wenzhixin2010@gmail.com> * @author zhixin wen <wenzhixin2010@gmail.com>
* extensions: https://github.com/vitalets/x-editable * extensions: https://github.com/vitalets/x-editable
*/ */
(function($) { var Utils = $.fn.bootstrapTable.utils
'use strict'; $.extend($.fn.bootstrapTable.defaults, {
$.extend($.fn.bootstrapTable.defaults, {
editable: true, editable: true,
onEditableInit: function() { onEditableInit () {
return false; return false
}, },
onEditableSave: function(field, row, oldValue, $el) { onEditableSave (field, row, rowIndex, oldValue, $el) {
return false; return false
}, },
onEditableShown: function(field, row, $el, editable) { onEditableShown (field, row, $el, editable) {
return false; return false
}, },
onEditableHidden: function(field, row, $el, reason) { onEditableHidden (field, row, $el, reason) {
return false; return false
} }
}); })
$.extend($.fn.bootstrapTable.Constructor.EVENTS, { $.extend($.fn.bootstrapTable.columnDefaults, {
alwaysUseFormatter: false
})
$.extend($.fn.bootstrapTable.events, {
'editable-init.bs.table': 'onEditableInit', 'editable-init.bs.table': 'onEditableInit',
'editable-save.bs.table': 'onEditableSave', 'editable-save.bs.table': 'onEditableSave',
'editable-shown.bs.table': 'onEditableShown', 'editable-shown.bs.table': 'onEditableShown',
'editable-hidden.bs.table': 'onEditableHidden' 'editable-hidden.bs.table': 'onEditableHidden'
}); })
var BootstrapTable = $.fn.bootstrapTable.Constructor, $.BootstrapTable = class extends $.BootstrapTable {
_initTable = BootstrapTable.prototype.initTable, initTable () {
_initBody = BootstrapTable.prototype.initBody; super.initTable()
BootstrapTable.prototype.initTable = function() {
var that = this;
_initTable.apply(this, Array.prototype.slice.apply(arguments));
if (!this.options.editable) { if (!this.options.editable) {
return; return
} }
$.each(this.columns, function(i, column) { this.editedCells = []
$.each(this.columns, (i, column) => {
if (!column.editable) { if (!column.editable) {
return; return
} }
var editableOptions = {}, const editableOptions = {}
editableDataMarkup = [], const editableDataMarkup = []
editableDataPrefix = 'editable-'; const editableDataPrefix = 'editable-'
const processDataOptions = (key, value) => {
var processDataOptions = function(key, value) {
// Replace camel case with dashes. // Replace camel case with dashes.
var dashKey = key.replace(/([A-Z])/g, function($1) { const dashKey = key.replace(/([A-Z])/g, $1 => `-${$1.toLowerCase()}`)
return "-" + $1.toLowerCase();
}); if (dashKey.indexOf(editableDataPrefix) === 0) {
if (dashKey.slice(0, editableDataPrefix.length) == editableDataPrefix) { editableOptions[dashKey.replace(editableDataPrefix, 'data-')] = value
var dataKey = dashKey.replace(editableDataPrefix, 'data-');
editableOptions[dataKey] = value;
} }
};
$.each(that.options, processDataOptions);
column.formatter = column.formatter || function(value, row, index) {
return value;
};
column._formatter = column._formatter ? column._formatter : column.formatter;
column.formatter = function(value, row, index) {
var result = column._formatter ? column._formatter(value, row, index) : value;
$.each(column, processDataOptions);
$.each(editableOptions, function(key, value) {
editableDataMarkup.push(' ' + key + '="' + value + '"');
});
var _dont_edit_formatter = false;
if (column.editable.hasOwnProperty('noeditFormatter')) {
_dont_edit_formatter = column.editable.noeditFormatter(value, row, index);
} }
if (_dont_edit_formatter === false) { $.each(this.options, processDataOptions)
return ['<a href="javascript:void(0)"',
' data-name="' + column.field + '"', column.formatter = column.formatter || (value => value)
' data-pk="' + row[that.options.idField] + '"', column._formatter = column._formatter ? column._formatter : column.formatter
' data-value="' + result + '"', column.formatter = (value, row, index, field) => {
editableDataMarkup.join(''), let result = Utils.calculateObjectValue(column, column._formatter, [value, row, index], value)
'>' + '</a>'
].join(''); result = typeof result === 'undefined' || result === null ? this.options.undefinedText : result
} else { if (this.options.uniqueId !== undefined && !column.alwaysUseFormatter) {
return _dont_edit_formatter; const uniqueId = Utils.getItemField(row, this.options.uniqueId, false)
if ($.inArray(column.field + uniqueId, this.editedCells) !== -1) {
result = value
}
} }
}; $.each(column, processDataOptions)
});
};
BootstrapTable.prototype.initBody = function() { $.each(editableOptions, (key, value) => {
var that = this; editableDataMarkup.push(` ${key}="${value}"`)
_initBody.apply(this, Array.prototype.slice.apply(arguments)); })
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) { if (!this.options.editable) {
return; return
} }
$.each(this.columns, function(i, column) { $.each(this.columns, (i, column) => {
if (!column.editable) { if (!column.editable) {
return; return
} }
that.$body.find('a[data-name="' + column.field + '"]').editable(column.editable) const data = this.getData({ escape: true })
.off('save').on('save', function(e, params) { const $field = this.$body.find(`a[data-name="${column.field}"]`)
var data = that.getData(),
index = $(this).parents('tr[data-index]').data('index'),
row = data[index],
oldValue = row[column.field];
$(this).data('value', params.submitValue); $field.each((i, element) => {
row[column.field] = params.submitValue; const $element = $(element)
that.trigger('editable-save', column.field, row, oldValue, $(this)); const $tr = $element.closest('tr')
that.resetFooter(); const index = $tr.data('index')
}); const row = data[index]
that.$body.find('a[data-name="' + column.field + '"]').editable(column.editable)
.off('shown').on('shown', function(e, editable) {
var data = that.getData(),
index = $(this).parents('tr[data-index]').data('index'),
row = data[index];
that.trigger('editable-shown', column.field, row, $(this), editable); const editableOpts = Utils.calculateObjectValue(column,
}); column.editable, [index, row, $element], {})
that.$body.find('a[data-name="' + column.field + '"]').editable(column.editable)
.off('hidden').on('hidden', function(e, reason) {
var data = that.getData(),
index = $(this).parents('tr[data-index]').data('index'),
row = data[index];
that.trigger('editable-hidden', column.field, row, $(this), reason); $element.editable(editableOpts)
}); })
});
this.trigger('editable-init');
};
})(jQuery); $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
}
}

View File

@ -1,7 +0,0 @@
/*
* bootstrap-table - v1.11.0 - 2016-07-02
* https://github.com/wenzhixin/bootstrap-table
* Copyright (c) 2016 zhixin wen
* Licensed MIT License
*/
!function(a){"use strict";a.extend(a.fn.bootstrapTable.defaults,{editable:!0,onEditableInit:function(){return!1},onEditableSave:function(){return!1},onEditableShown:function(){return!1},onEditableHidden:function(){return!1}}),a.extend(a.fn.bootstrapTable.Constructor.EVENTS,{"editable-init.bs.table":"onEditableInit","editable-save.bs.table":"onEditableSave","editable-shown.bs.table":"onEditableShown","editable-hidden.bs.table":"onEditableHidden"});var b=a.fn.bootstrapTable.Constructor,c=b.prototype.initTable,d=b.prototype.initBody;b.prototype.initTable=function(){var b=this;c.apply(this,Array.prototype.slice.apply(arguments)),this.options.editable&&a.each(this.columns,function(c,d){if(d.editable){var e={},f=[],g="editable-",h=function(a,b){var c=a.replace(/([A-Z])/g,function(a){return"-"+a.toLowerCase()});if(c.slice(0,g.length)==g){var d=c.replace(g,"data-");e[d]=b}};a.each(b.options,h),d.formatter=d.formatter||function(a){return a},d._formatter=d._formatter?d._formatter:d.formatter,d.formatter=function(c,g,i){var j=d._formatter?d._formatter(c,g,i):c;a.each(d,h),a.each(e,function(a,b){f.push(" "+a+'="'+b+'"')});var k=!1;return d.editable.hasOwnProperty("noeditFormatter")&&(k=d.editable.noeditFormatter(c,g,i)),k===!1?['<a href="javascript:void(0)"',' data-name="'+d.field+'"',' data-pk="'+g[b.options.idField]+'"',' data-value="'+j+'"',f.join(""),"></a>"].join(""):k}}})},b.prototype.initBody=function(){var b=this;d.apply(this,Array.prototype.slice.apply(arguments)),this.options.editable&&(a.each(this.columns,function(c,d){d.editable&&(b.$body.find('a[data-name="'+d.field+'"]').editable(d.editable).off("save").on("save",function(c,e){var f=b.getData(),g=a(this).parents("tr[data-index]").data("index"),h=f[g],i=h[d.field];a(this).data("value",e.submitValue),h[d.field]=e.submitValue,b.trigger("editable-save",d.field,h,i,a(this)),b.resetFooter()}),b.$body.find('a[data-name="'+d.field+'"]').editable(d.editable).off("shown").on("shown",function(c,e){var f=b.getData(),g=a(this).parents("tr[data-index]").data("index"),h=f[g];b.trigger("editable-shown",d.field,h,a(this),e)}),b.$body.find('a[data-name="'+d.field+'"]').editable(d.editable).off("hidden").on("hidden",function(c,e){var f=b.getData(),g=a(this).parents("tr[data-index]").data("index"),h=f[g];b.trigger("editable-hidden",d.field,h,a(this),e)}))}),this.trigger("editable-init"))}}(jQuery);

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -1,119 +1,335 @@
/** /**
* @author zhixin wen <wenzhixin2010@gmail.com> * @author zhixin wen <wenzhixin2010@gmail.com>
* extensions: https://github.com/kayalshri/tableExport.jquery.plugin * extensions: https://github.com/hhurz/tableExport.jquery.plugin
*/ */
(function ($) { var Utils = $.fn.bootstrapTable.utils
'use strict';
var sprintf = $.fn.bootstrapTable.utils.sprintf;
var TYPE_NAME = { const TYPE_NAME = {
json: 'JSON',
xml: 'XML',
png: 'PNG',
csv: 'CSV', csv: 'CSV',
txt: 'TXT', txt: 'TXT',
doc: 'Word', sql: 'SQL',
excel: 'Excel' doc: 'MS-Word',
}; excel: 'MS-Excel',
xlsx: 'MS-Excel (OpenXML)',
powerpoint: 'MS-Powerpoint',
pdf: 'PDF'
}
$.extend($.fn.bootstrapTable.defaults, { Object.assign($.fn.bootstrapTable.defaults, {
showExport: false, showExport: false,
exportDataType: 'all', // basic, all, selected exportDataType: 'basic', // basic, all, selected
exportTypes: ['csv', 'txt', 'doc', 'excel'], exportTypes: ['json', 'xml', 'csv', 'txt', 'sql', 'excel'],
exportOptions: { exportOptions: {},
ignoreColumn: [0] //忽略列索引 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)
$.extend($.fn.bootstrapTable.defaults.icons, { $.fn.bootstrapTable.methods.push('exportTable')
export: 'glyphicon glyphicon-save'
});
$.extend($.fn.bootstrapTable.locales, { Object.assign($.fn.bootstrapTable.defaults, {
formatExport: function () { // eslint-disable-next-line no-unused-vars
return 'Export data'; onExportSaved (exportedRows) {
return false
},
onExportStarted () {
return false
} }
}); })
$.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales);
var BootstrapTable = $.fn.bootstrapTable.Constructor, Object.assign($.fn.bootstrapTable.events, {
_initToolbar = BootstrapTable.prototype.initToolbar; 'export-saved.bs.table': 'onExportSaved',
'export-started.bs.table': 'onExportStarted'
})
BootstrapTable.prototype.initToolbar = function () { $.BootstrapTable = class extends $.BootstrapTable {
this.showToolbar = this.options.showExport; initToolbar (...args) {
const o = this.options
let exportTypes = o.exportTypes
_initToolbar.apply(this, Array.prototype.slice.apply(arguments)); this.showToolbar = this.showToolbar || o.showExport
if (this.options.showExport) { if (this.options.showExport) {
var that = this,
$btnGroup = this.$toolbar.find('>.btn-group'),
$export = $btnGroup.find('div.export');
if (!$export.length) { if (typeof exportTypes === 'string') {
$export = $([ const types = exportTypes.slice(1, -1).replace(/ /g, '').split(',')
'<div class="export btn-group">',
'<button class="btn' +
sprintf(' btn-%s', this.options.buttonsClass) +
sprintf(' btn-%s', this.options.iconSize) +
' dropdown-toggle" ' +
'title="' + this.options.formatExport() + '" ' +
'data-toggle="dropdown" type="button">',
sprintf('<i class="%s %s"></i> ', this.options.iconsPrefix, this.options.icons.export),
'<span class="caret"></span>',
'</button>',
'<ul class="dropdown-menu" role="menu">',
'</ul>',
'</div>'].join('')).appendTo($btnGroup);
var $menu = $export.find('.dropdown-menu'), exportTypes = types.map(t => t.slice(1, -1))
exportTypes = this.options.exportTypes;
if (typeof this.options.exportTypes === 'string') {
var types = this.options.exportTypes.slice(1, -1).replace(/ /g, '').split(',');
exportTypes = [];
$.each(types, function (i, value) {
exportTypes.push(value.slice(1, -1));
});
} }
$.each(exportTypes, function (i, type) {
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)) { if (TYPE_NAME.hasOwnProperty(type)) {
$menu.append(['<li data-type="' + type + '">', const $item = $(Utils.sprintf(this.constants.html.pageDropdownItem, '', TYPE_NAME[type]))
'<a href="javascript:void(0)">',
TYPE_NAME[type], $item.attr('data-type', type)
'</a>', html.push($item.prop('outerHTML'))
'</li>'].join('')); }
} }
});
$menu.find('li').click(function () { html.push(this.constants.html.toolbarDropdown[1], '</div>')
var type = $(this).data('type'), return html.join('')
doExport = function () { }
that.$el.tableExport($.extend({}, that.options.exportOptions, { }
type: type, })
escape: false }
}));
};
if (that.options.exportDataType === 'all' && that.options.pagination) { super.initToolbar(...args)
that.$el.one(that.options.sidePagination === 'server' ? 'post-body.bs.table' : 'page-change.bs.table', function () { this.$export = this.$toolbar.find('>.columns div.export')
doExport();
that.togglePagination(); if (!this.options.showExport) {
}); return
that.togglePagination(); }
} else if (that.options.exportDataType === 'selected') {
//修改sidePagination属性为server无法导出选中数据 this.updateExportButton()
var trs = that.$body.children(); let $exportButtons = this.$export.find('[data-type]')
for (var i = 0; i < trs.length; i++) {
var $this = $(trs[i]); if (exportTypes.length === 1) {
if(!$this.find(sprintf('[name="%s"]',that.options.selectItemName)).prop('checked')){ $exportButtons = this.$export
$this['hide'](); }
}}
doExport(); $exportButtons.click(e => {
that.getRowsHidden(true); 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 { } else {
doExport(); doExport()
} this.trigger('export-saved', this.getData(true))
});
} }
} }
};
})(jQuery); 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

@ -1,92 +1,123 @@
/** /**
* 基于bootstrap-table-mobile修改 * @author: Dennis Hernández
* 修正部分iPhone手机不显示卡片视图 * @update zhixin wen <wenzhixin2010@gmail.com>
* Copyright (c) 2019 ruoyi
*/ */
!function ($) {
'use strict'; const debounce = (func, wait) => {
let timeout = 0
var resetView = function (that) { return (...args) => {
if (that.options.height || that.options.showFooter) { const later = () => {
setTimeout(that.resetView(), 1); timeout = 0
} func(...args)
};
// 判断是否 iphone
var isIPhone = function () {
let browserName = navigator.userAgent.toLowerCase();
return /(iphone)/i.test(browserName);
};
var changeView = function (that, width, height) {
if (that.options.minHeight) {
if (checkValuesLessEqual(width, that.options.minWidth) && checkValuesLessEqual(height, that.options.minHeight)) {
conditionCardView(that);
} else if (checkValuesGreater(width, that.options.minWidth) && checkValuesGreater(height, that.options.minHeight)) {
conditionFullView(that);
}
} else {
if (checkValuesLessEqual(width, that.options.minWidth) || isIPhone()) {
conditionCardView(that);
} else if (checkValuesGreater(width, that.options.minWidth)) {
conditionFullView(that);
}
} }
resetView(that); clearTimeout(timeout)
}; timeout = setTimeout(later, wait)
}
}
var checkValuesLessEqual = function (currentValue, targetValue) { Object.assign($.fn.bootstrapTable.defaults, {
return currentValue <= targetValue;
};
var checkValuesGreater = function (currentValue, targetValue) {
return currentValue > targetValue;
};
var conditionCardView = function (that) {
changeTableView(that, false);
};
var conditionFullView = function (that) {
changeTableView(that, true);
};
var changeTableView = function (that, cardViewState) {
that.options.cardView = cardViewState;
that.toggleView();
};
$.extend($.fn.bootstrapTable.defaults, {
mobileResponsive: false, mobileResponsive: false,
minWidth: 562, minWidth: 562,
minHeight: undefined, minHeight: undefined,
heightThreshold: 100, // just slightly larger than mobile chrome's auto-hiding toolbar
checkOnInit: true, checkOnInit: true,
toggled: false columnsHidden: []
}); })
var BootstrapTable = $.fn.bootstrapTable.Constructor, $.BootstrapTable = class extends $.BootstrapTable {
_init = BootstrapTable.prototype.init; init (...args) {
super.init(...args)
BootstrapTable.prototype.init = function () { if (!this.options.mobileResponsive || !this.options.minWidth) {
_init.apply(this, Array.prototype.slice.apply(arguments)); return
if (!this.options.mobileResponsive) {
return;
} }
if (!this.options.minWidth) { if (this.options.minWidth < 100 && this.options.resizable) {
return; console.warn('The minWidth when the resizable extension is active should be greater or equal than 100')
this.options.minWidth = 100
} }
var that = this; let old = {
$(window).resize(function () { width: $(window).width(),
changeView(that, $(this).width(), $(this).height()) 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) { if (this.options.checkOnInit) {
changeView(this, $(window).width(), $(window).height()); const width = $(window).width()
const height = $(window).height()
this.changeView(width, height)
old = {
width,
height
} }
}; }
}(jQuery); }
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

@ -1,211 +0,0 @@
/**
* @author: aperez <aperez@datadec.es>
* @version: v2.0.0
*
* @update Dennis Hernández <http://djhvscf.github.io/Blog>
*/
!function($) {
'use strict';
var firstLoad = false;
var sprintf = $.fn.bootstrapTable.utils.sprintf;
var showAvdSearch = function(pColumns, searchTitle, searchText, that) {
if (!$("#avdSearchModal" + "_" + that.options.idTable).hasClass("modal")) {
var vModal = sprintf("<div id=\"avdSearchModal%s\" class=\"modal fade\" tabindex=\"-1\" role=\"dialog\" aria-labelledby=\"mySmallModalLabel\" aria-hidden=\"true\">", "_" + that.options.idTable);
vModal += "<div class=\"modal-dialog modal-xs\">";
vModal += " <div class=\"modal-content\">";
vModal += " <div class=\"modal-header\">";
vModal += " <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-hidden=\"true\" >&times;</button>";
vModal += sprintf(" <h4 class=\"modal-title\">%s</h4>", searchTitle);
vModal += " </div>";
vModal += " <div class=\"modal-body modal-body-custom\">";
vModal += sprintf(" <div class=\"container-fluid\" id=\"avdSearchModalContent%s\" style=\"padding-right: 0px;padding-left: 0px;\" >", "_" + that.options.idTable);
vModal += " </div>";
vModal += " </div>";
vModal += " </div>";
vModal += " </div>";
vModal += "</div>";
$("body").append($(vModal));
var vFormAvd = createFormAvd(pColumns, searchText, that),
timeoutId = 0;;
$('#avdSearchModalContent' + "_" + that.options.idTable).append(vFormAvd.join(''));
$('#' + that.options.idForm).off('keyup blur', 'input').on('keyup blur', 'input', function (event) {
clearTimeout(timeoutId);
timeoutId = setTimeout(function () {
that.onColumnAdvancedSearch(event);
}, that.options.searchTimeOut);
});
$("#btnCloseAvd" + "_" + that.options.idTable).click(function() {
$("#avdSearchModal" + "_" + that.options.idTable).modal('hide');
});
$("#avdSearchModal" + "_" + that.options.idTable).modal();
} else {
$("#avdSearchModal" + "_" + that.options.idTable).modal();
}
};
var createFormAvd = function(pColumns, searchText, that) {
var htmlForm = [];
htmlForm.push(sprintf('<form class="form-horizontal" id="%s" action="%s" >', that.options.idForm, that.options.actionForm));
for (var i in pColumns) {
var vObjCol = pColumns[i];
if (!vObjCol.checkbox && vObjCol.visible && vObjCol.searchable) {
htmlForm.push('<div class="form-group">');
htmlForm.push(sprintf('<label class="col-sm-4 control-label">%s</label>', vObjCol.title));
htmlForm.push('<div class="col-sm-6">');
htmlForm.push(sprintf('<input type="text" class="form-control input-md" name="%s" placeholder="%s" id="%s">', vObjCol.field, vObjCol.title, vObjCol.field));
htmlForm.push('</div>');
htmlForm.push('</div>');
}
}
htmlForm.push('<div class="form-group">');
htmlForm.push('<div class="col-sm-offset-9 col-sm-3">');
htmlForm.push(sprintf('<button type="button" id="btnCloseAvd%s" class="btn btn-default" >%s</button>', "_" + that.options.idTable, searchText));
htmlForm.push('</div>');
htmlForm.push('</div>');
htmlForm.push('</form>');
return htmlForm;
};
$.extend($.fn.bootstrapTable.defaults, {
advancedSearch: false,
idForm: 'advancedSearch',
actionForm: '',
idTable: undefined,
onColumnAdvancedSearch: function (field, text) {
return false;
}
});
$.extend($.fn.bootstrapTable.defaults.icons, {
advancedSearchIcon: 'glyphicon-chevron-down'
});
$.extend($.fn.bootstrapTable.Constructor.EVENTS, {
'column-advanced-search.bs.table': 'onColumnAdvancedSearch'
});
$.extend($.fn.bootstrapTable.locales, {
formatAdvancedSearch: function() {
return 'Advanced search';
},
formatAdvancedCloseButton: function() {
return "Close";
}
});
$.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales);
var BootstrapTable = $.fn.bootstrapTable.Constructor,
_initToolbar = BootstrapTable.prototype.initToolbar,
_load = BootstrapTable.prototype.load,
_initSearch = BootstrapTable.prototype.initSearch;
BootstrapTable.prototype.initToolbar = function() {
_initToolbar.apply(this, Array.prototype.slice.apply(arguments));
if (!this.options.search) {
return;
}
if (!this.options.advancedSearch) {
return;
}
if (!this.options.idTable) {
return;
}
var that = this,
html = [];
html.push(sprintf('<div class="columns columns-%s btn-group pull-%s" role="group">', this.options.buttonsAlign, this.options.buttonsAlign));
html.push(sprintf('<button class="btn btn-default%s' + '" type="button" name="advancedSearch" title="%s">', that.options.iconSize === undefined ? '' : ' btn-' + that.options.iconSize, that.options.formatAdvancedSearch()));
html.push(sprintf('<i class="%s %s"></i>', that.options.iconsPrefix, that.options.icons.advancedSearchIcon))
html.push('</button></div>');
that.$toolbar.prepend(html.join(''));
that.$toolbar.find('button[name="advancedSearch"]')
.off('click').on('click', function() {
showAvdSearch(that.columns, that.options.formatAdvancedSearch(), that.options.formatAdvancedCloseButton(), that);
});
};
BootstrapTable.prototype.load = function(data) {
_load.apply(this, Array.prototype.slice.apply(arguments));
if (!this.options.advancedSearch) {
return;
}
if (typeof this.options.idTable === 'undefined') {
return;
} else {
if (!firstLoad) {
var height = parseInt($(".bootstrap-table").height());
height += 10;
$("#" + this.options.idTable).bootstrapTable("resetView", {height: height});
firstLoad = true;
}
}
};
BootstrapTable.prototype.initSearch = function () {
_initSearch.apply(this, Array.prototype.slice.apply(arguments));
if (!this.options.advancedSearch) {
return;
}
var that = this;
var fp = $.isEmptyObject(this.filterColumnsPartial) ? null : this.filterColumnsPartial;
this.data = fp ? $.grep(this.data, function (item, i) {
for (var key in fp) {
var fval = fp[key].toLowerCase();
var value = item[key];
value = $.fn.bootstrapTable.utils.calculateObjectValue(that.header,
that.header.formatters[$.inArray(key, that.header.fields)],
[value, item, i], value);
if (!($.inArray(key, that.header.fields) !== -1 &&
(typeof value === 'string' || typeof value === 'number') &&
(value + '').toLowerCase().indexOf(fval) !== -1)) {
return false;
}
}
return true;
}) : this.data;
};
BootstrapTable.prototype.onColumnAdvancedSearch = function (event) {
var text = $.trim($(event.currentTarget).val());
var $field = $(event.currentTarget)[0].id;
if ($.isEmptyObject(this.filterColumnsPartial)) {
this.filterColumnsPartial = {};
}
if (text) {
this.filterColumnsPartial[$field] = text;
} else {
delete this.filterColumnsPartial[$field];
}
this.options.pageNumber = 1;
this.onSearch(event);
this.updatePagination();
this.trigger('column-advanced-search', $field, text);
};
}(jQuery);

View File

@ -1,7 +0,0 @@
/*
* bootstrap-table - v1.11.0 - 2016-07-02
* https://github.com/wenzhixin/bootstrap-table
* Copyright (c) 2016 zhixin wen
* Licensed MIT License
*/
!function(a){"use strict";var b=!1,c=a.fn.bootstrapTable.utils.sprintf,d=function(b,d,f,g){if(a("#avdSearchModal_"+g.options.idTable).hasClass("modal"))a("#avdSearchModal_"+g.options.idTable).modal();else{var h=c('<div id="avdSearchModal%s" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel" aria-hidden="true">',"_"+g.options.idTable);h+='<div class="modal-dialog modal-xs">',h+=' <div class="modal-content">',h+=' <div class="modal-header">',h+=' <button type="button" class="close" data-dismiss="modal" aria-hidden="true" >&times;</button>',h+=c(' <h4 class="modal-title">%s</h4>',d),h+=" </div>",h+=' <div class="modal-body modal-body-custom">',h+=c(' <div class="container-fluid" id="avdSearchModalContent%s" style="padding-right: 0px;padding-left: 0px;" >',"_"+g.options.idTable),h+=" </div>",h+=" </div>",h+=" </div>",h+=" </div>",h+="</div>",a("body").append(a(h));var i=e(b,f,g),j=0;a("#avdSearchModalContent_"+g.options.idTable).append(i.join("")),a("#"+g.options.idForm).off("keyup blur","input").on("keyup blur","input",function(a){clearTimeout(j),j=setTimeout(function(){g.onColumnAdvancedSearch(a)},g.options.searchTimeOut)}),a("#btnCloseAvd_"+g.options.idTable).click(function(){a("#avdSearchModal_"+g.options.idTable).modal("hide")}),a("#avdSearchModal_"+g.options.idTable).modal()}},e=function(a,b,d){var e=[];e.push(c('<form class="form-horizontal" id="%s" action="%s" >',d.options.idForm,d.options.actionForm));for(var f in a){var g=a[f];!g.checkbox&&g.visible&&g.searchable&&(e.push('<div class="form-group">'),e.push(c('<label class="col-sm-4 control-label">%s</label>',g.title)),e.push('<div class="col-sm-6">'),e.push(c('<input type="text" class="form-control input-md" name="%s" placeholder="%s" id="%s">',g.field,g.title,g.field)),e.push("</div>"),e.push("</div>"))}return e.push('<div class="form-group">'),e.push('<div class="col-sm-offset-9 col-sm-3">'),e.push(c('<button type="button" id="btnCloseAvd%s" class="btn btn-default" >%s</button>',"_"+d.options.idTable,b)),e.push("</div>"),e.push("</div>"),e.push("</form>"),e};a.extend(a.fn.bootstrapTable.defaults,{advancedSearch:!1,idForm:"advancedSearch",actionForm:"",idTable:void 0,onColumnAdvancedSearch:function(){return!1}}),a.extend(a.fn.bootstrapTable.defaults.icons,{advancedSearchIcon:"glyphicon-chevron-down"}),a.extend(a.fn.bootstrapTable.Constructor.EVENTS,{"column-advanced-search.bs.table":"onColumnAdvancedSearch"}),a.extend(a.fn.bootstrapTable.locales,{formatAdvancedSearch:function(){return"Advanced search"},formatAdvancedCloseButton:function(){return"Close"}}),a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales);var f=a.fn.bootstrapTable.Constructor,g=f.prototype.initToolbar,h=f.prototype.load,i=f.prototype.initSearch;f.prototype.initToolbar=function(){if(g.apply(this,Array.prototype.slice.apply(arguments)),this.options.search&&this.options.advancedSearch&&this.options.idTable){var a=this,b=[];b.push(c('<div class="columns columns-%s btn-group pull-%s" role="group">',this.options.buttonsAlign,this.options.buttonsAlign)),b.push(c('<button class="btn btn-default%s" type="button" name="advancedSearch" title="%s">',void 0===a.options.iconSize?"":" btn-"+a.options.iconSize,a.options.formatAdvancedSearch())),b.push(c('<i class="%s %s"></i>',a.options.iconsPrefix,a.options.icons.advancedSearchIcon)),b.push("</button></div>"),a.$toolbar.prepend(b.join("")),a.$toolbar.find('button[name="advancedSearch"]').off("click").on("click",function(){d(a.columns,a.options.formatAdvancedSearch(),a.options.formatAdvancedCloseButton(),a)})}},f.prototype.load=function(){if(h.apply(this,Array.prototype.slice.apply(arguments)),this.options.advancedSearch&&"undefined"!=typeof this.options.idTable&&!b){var c=parseInt(a(".bootstrap-table").height());c+=10,a("#"+this.options.idTable).bootstrapTable("resetView",{height:c}),b=!0}},f.prototype.initSearch=function(){if(i.apply(this,Array.prototype.slice.apply(arguments)),this.options.advancedSearch){var b=this,c=a.isEmptyObject(this.filterColumnsPartial)?null:this.filterColumnsPartial;this.data=c?a.grep(this.data,function(d,e){for(var f in c){var g=c[f].toLowerCase(),h=d[f];if(h=a.fn.bootstrapTable.utils.calculateObjectValue(b.header,b.header.formatters[a.inArray(f,b.header.fields)],[h,d,e],h),-1===a.inArray(f,b.header.fields)||"string"!=typeof h&&"number"!=typeof h||-1===(h+"").toLowerCase().indexOf(g))return!1}return!0}):this.data}},f.prototype.onColumnAdvancedSearch=function(b){var c=a.trim(a(b.currentTarget).val()),d=a(b.currentTarget)[0].id;a.isEmptyObject(this.filterColumnsPartial)&&(this.filterColumnsPartial={}),c?this.filterColumnsPartial[d]=c:delete this.filterColumnsPartial[d],this.options.pageNumber=1,this.onSearch(b),this.updatePagination(),this.trigger("column-advanced-search",d,c)}}(jQuery);

View File

@ -1,7 +1,6 @@
/** /**
* bootstrapTreeTable * 基于bootstrapTreeTable/bootstrap-table-treegrid修改
* * Copyright (c) 2019 ruoyi
* @author swifly
*/ */
(function($) { (function($) {
"use strict"; "use strict";
@ -15,12 +14,14 @@
} }
// 如果是初始化组件 // 如果是初始化组件
options = $.extend({}, $.fn.bootstrapTreeTable.defaults, options || {}); options = $.extend({}, $.fn.bootstrapTreeTable.defaults, options || {});
target.hasSelectItem = false;// 是否有radio或checkbox target.hasSelectItem = false; // 是否有radio或checkbox
target.data_list = null; //用于缓存格式化后的数据-按父分组 target.data_list = null; // 用于缓存格式化后的数据-按父分组
target.data_obj = null; //用于缓存格式化后的数据-按id存对象 target.data_obj = null; // 用于缓存格式化后的数据-按id存对象
target.hiddenColumns = []; //用于存放被隐藏列的field target.hiddenColumns = []; // 用于存放被隐藏列的field
target.lastAjaxParams; //用户最后一次请求的参数 target.lastAjaxParams; // 用户最后一次请求的参数
target.isFixWidth=false; //是否有固定宽度 target.isFixWidth=false; // 是否有固定宽度
target.totalRows = 0; // 记录总数
target.totalPages = 0; // 总页数
// 初始化 // 初始化
var init = function() { var init = function() {
// 初始化容器 // 初始化容器
@ -71,6 +72,12 @@
var $rightToolbar = $('<div class="btn-group tool-right">'); var $rightToolbar = $('<div class="btn-group tool-right">');
$toolbar.append($rightToolbar); $toolbar.append($rightToolbar);
target.parent().before($toolbar); target.parent().before($toolbar);
// ruoyi 是否显示检索信息
if (options.showSearch) {
var $searchBtn = $('<button class="btn btn-default btn-outline" type="button" aria-label="search" title="搜索"><i class="glyphicon glyphicon-search"></i></button>');
$rightToolbar.append($searchBtn);
registerSearchBtnClickEvent($searchBtn);
}
// 是否显示刷新按钮 // 是否显示刷新按钮
if (options.showRefresh) { if (options.showRefresh) {
var $refreshBtn = $('<button class="btn btn-default btn-outline" type="button" aria-label="refresh" title="刷新"><i class="glyphicon glyphicon-repeat"></i></button>'); var $refreshBtn = $('<button class="btn btn-default btn-outline" type="button" aria-label="refresh" title="刷新"><i class="glyphicon glyphicon-repeat"></i></button>');
@ -123,12 +130,15 @@
target.hasSelectItem = true; target.hasSelectItem = true;
$th = $('<th style="width:36px"></th>'); $th = $('<th style="width:36px"></th>');
} else { } else {
$th = $('<th style="' + ((column.width) ? ('width:' + column.width) : '') + '" class="' + column.field + '_cls"></th>'); $th = $('<th style="' + ((column.width) ? ('width:' + column.width + ((column.widthUnit) ? column.widthUnit : 'px')) : '') + '" class="' + column.field + '_cls"></th>');
if (column.align) {
$th.css("text-align", column.align);
}
} }
if((!target.isFixWidth)&& column.width){ if((!target.isFixWidth)&& column.width){
target.isFixWidth = column.width.indexOf("px")>-1?true:false; target.isFixWidth = column.width.indexOf("px")>-1?true:false;
} }
$th.text(column.title); $th.html(column.title);
$thr.append($th); $thr.append($th);
}); });
var $thead = $('<thead class="treetable-thead"></thead>'); var $thead = $('<thead class="treetable-thead"></thead>');
@ -143,12 +153,30 @@
if (options.height) { if (options.height) {
$tbody.css("height", options.height); $tbody.css("height", options.height);
} }
if (options.pagination) {
var $pagination = $('<div class="fixed-table-pagination"></div>');
target.append($pagination);
}
} }
// 初始化数据服务 // 初始化数据服务
var initServer = function(parms) { var initServer = function(parms) {
if (options.pagination) {
if(parms == undefined || parms == null) {
parms = {};
}
parms[options.parentCode] = options.rootIdValue;
}
// 加载数据前先清空 // 加载数据前先清空
target.data_list = {}; target.data_list = {};
target.data_obj = {}; target.data_obj = {};
// 设置请求分页参数
if (options.pagination) {
var params = {};
params.offset = options.pageSize * (options.pageNumber - 1);
params.limit = options.pageSize;
var curParams = { pageSize: params.limit, pageNum: params.offset / params.limit + 1 };
parms = $.extend(curParams, parms);
}
var $tbody = target.find("tbody"); var $tbody = target.find("tbody");
// 添加加载loading // 添加加载loading
var $loading = '<tr><td colspan="' + options.columns.length + '"><div style="display: block;text-align: center;">正在努力地加载数据中,请稍候……</div></td></tr>' var $loading = '<tr><td colspan="' + options.columns.length + '"><div style="display: block;text-align: center;">正在努力地加载数据中,请稍候……</div></td></tr>'
@ -157,15 +185,17 @@
$.ajax({ $.ajax({
type: options.type, type: options.type,
url: options.url, url: options.url,
data: parms ? parms : options.ajaxParams, data: $.extend(parms, options.ajaxParams),
dataType: "JSON", dataType: "json",
success: function(data, textStatus, jqXHR) { success: function(data, textStatus, jqXHR) {
data = calculateObjectValue(options, options.responseHandler, [data], data);
renderTable(data); renderTable(data);
calculateObjectValue(options, options.onLoadSuccess, [data], data);
}, },
error: function(xhr, textStatus) { error: function(xhr, textStatus) {
var _errorMsg = '<tr><td colspan="' + options.columns.length + '"><div style="display: block;text-align: center;">' + xhr.responseText + '</div></td></tr>' var _errorMsg = '<tr><td colspan="' + options.columns.length + '"><div style="display: block;text-align: center;">' + xhr.responseText + '</div></td></tr>'
$tbody.html(_errorMsg); $tbody.html(_errorMsg);
}, }
}); });
} else { } else {
renderTable(options.data); renderTable(options.data);
@ -173,12 +203,25 @@
} }
// 加载完数据后渲染表格 // 加载完数据后渲染表格
var renderTable = function(data) { var renderTable = function(data) {
var list, totalPage = 0, currPage = 0;
if (options.pagination) {
list = data.rows; // 数据
currPage = options.pageNumber; // 当前页
totalPage = ~~((data.total - 1) / options.pageSize) + 1 // 总页数
target.totalPages = totalPage;
target.totalRows = data.total; // 总记录数
} else {
list = data;
}
data = list;
var $tbody = target.find("tbody"); var $tbody = target.find("tbody");
// 先清空 // 先清空
$tbody.html(""); $tbody.html("");
if (!data || data.length <= 0) { if (!data || data.length <= 0) {
var _empty = '<tr><td colspan="' + options.columns.length + '"><div style="display: block;text-align: center;">没有找到匹配的记录</div></td></tr>' var _empty = '<tr><td colspan="' + options.columns.length + '"><div style="display: block;text-align: center;">没有找到匹配的记录</div></td></tr>'
$tbody.html(_empty); $tbody.html(_empty);
options.pageNumber = 1;
initPagination(0, 0);
return; return;
} }
// 缓存并格式化数据 // 缓存并格式化数据
@ -189,22 +232,217 @@
if (rootNode) { if (rootNode) {
$.each(rootNode, function(i, item) { $.each(rootNode, function(i, item) {
var _child_row_id = "row_id_" + i var _child_row_id = "row_id_" + i
recursionNode(item, 1, _child_row_id, "row_root"); recursionNode(item, 1, _child_row_id, "row_root", item[options.code]);
}); });
} }
// 下边的操作主要是为了查询时让一些没有根节点的节点显示 // 下边的操作主要是为了查询时让一些没有根节点的节点显示
$.each(data, function(i, item) { $.each(data, function(i, item) {
if (!item.isShow) { if (!item.isShow) {
var tr = renderRow(item, false, 1, "", ""); var tr = renderRow(item, false, 1, "", "", options.pagination, item[options.code]);
$tbody.append(tr); $tbody.append(tr);
} }
}); });
target.append($tbody);
registerExpanderEvent(); registerExpanderEvent();
registerRowClickEvent(); registerRowClickEvent();
initHiddenColumns(); initHiddenColumns();
// 动态设置表头宽度 // 动态设置表头宽度
autoTheadWidth() autoTheadWidth();
if (options.pagination) {
initPagination(totalPage, currPage);
}
// 移动端适配
var treetableTable = $(target).parent('.treetable-table');
var availableHeight = treetableTable.outerWidth();
if($.common.isMobile() || availableHeight < 769){
var tableStyle = "width: " + availableHeight + "px;overflow: auto;position: relative;";
treetableTable.attr('style', tableStyle);
var w = 0;
$.each(options.columns, function(i, column) {
if (i == 0 && column.field == 'selectItem') {
w += 36;
} else {
w += 200;
}
});
$(target).attr('style','width:' + w +'px');
}
}
// 初始化分页
var initPagination = function (totalPage,currPage) {
var $pagination = target.find(".fixed-table-pagination");
$pagination.empty();
var html = [];
var pageFrom = (options.pageNumber - 1) * options.pageSize + 1;
var pageTo = options.pageNumber * options.pageSize;
if (pageTo > target.totalRows) {
pageTo = target.totalRows;
}
if (pageFrom > pageTo) {
pageFrom = pageTo;
}
html.push('<div class="pull-left pagination-detail">');
html.push('<span class="pagination-info">' + formatShowingRows(pageFrom, pageTo, target.totalRows) + '</span>');
var pageList = false;
$.each(options.pageList, function (i, page) {
if(target.totalRows > page){
pageList = true;
}
})
if(pageList){
var _page_list = [];
_page_list.push('<span class="page-list">');
_page_list.push('<span class="btn-group dropup">');
_page_list.push('<button type="button" class="btn btn-default btn-outline dropdown-toggle" data-toggle="dropdown">');
_page_list.push('<span class="page-size">' + options.pageSize + '</span>');
_page_list.push('<span class="caret"></span>');
_page_list.push('</button>');
_page_list.push('<ul class="dropdown-menu" role="menu">');
$.each(options.pageList, function (i, page) {
if(page == options.pageSize){
_page_list.push('<li class="active"><a href="javascript:void(0)">' + page + '</a></li>');
}
else if(page >= target.totalRows && i === 1){
_page_list.push('<li><a href="javascript:void(0)">' + page + '</a></li>');
}
else if(page <= target.totalRows){
_page_list.push('<li><a href="javascript:void(0)">' + page + '</a></li>');
}
})
_page_list.push('</ul>');
_page_list.push('</span>');
html.push(formatRecordsPerPage(_page_list.join('')))
html.push('</span>');
}
html.push('</div>');
if(totalPage > 1){
html.push('<div class="pull-right pagination">');
html.push('<ul class="pagination pagination-outline">');
html.push('<li class="page-pre"><a href="javascript:void(0)">' + options.paginationPreText + '</a></li>');
var from, to;
if (totalPage < 5) {
from = 1;
to = totalPage;
} else {
from = currPage - 2;
to = from + 4;
if (from < 1) {
from = 1;
to = 5;
}
if (to > totalPage) {
to = totalPage;
from = to - 4;
}
}
if (totalPage >= 6) {
if (currPage >= 3) {
html.push('<li class="page-first' + (1 == currPage ? ' active' : '') + '">', '<a href="javascript:void(0)">', 1, '</a>', '</li>');
from++;
}
if (currPage >= 4) {
if (currPage == 4 || totalPage == 6 || totalPage == 7) {
from--;
} else {
html.push('<li class="page-first-separator disabled">', '<a href="javascript:void(0)">...</a>', '</li>');
}
to--;
}
}
if (totalPage >= 7) {
if (currPage >= (totalPage - 2)) {
from--;
}
}
if (totalPage == 6) {
if (currPage >= (totalPage - 2)) {
to++;
}
} else if (totalPage >= 7) {
if (totalPage == 7 || currPage >= (totalPage - 3)) {
to++;
}
}
for (var i = from; i <= to; i++) {
html.push('<li class="page-number' + (i == currPage ? ' active' : '') + '">', '<a href="javascript:void(0)">', i, '</a>', '</li>');
}
if (totalPage >= 8) {
if (currPage <= (totalPage - 4)) {
html.push('<li class="page-last-separator disabled">', '<a href="javascript:void(0)">...</a>', '</li>');
}
}
if (totalPage >= 6) {
if (currPage <= (totalPage - 3)) {
html.push('<li class="page-last' + (totalPage === currPage ? ' active' : '') + '">', '<a href="javascript:void(0)">', totalPage, '</a>', '</li>');
}
}
html.push('<li class="page-next"><a href="javascript:void(0)">' + options.paginationNextText + '</a></li>');
html.push('</ul></div>');
}
$pagination.append(html.join(''));
var $pageList = $pagination.find('.page-list a');
var $pre = $pagination.find('.page-pre');
var $next = $pagination.find('.page-next');
var $number = $pagination.find('.page-number');
var $first = $pagination.find('.page-first');
var $last = $pagination.find('.page-last');
$pre.off('click').on('click', $.proxy(onPagePre, this));
$pageList.off('click').on('click', $.proxy(onPageListChange, this));
$number.off('click').on('click', $.proxy(onPageNumber, this));
$first.off('click').on('click', $.proxy(onPageFirst, this));
$last.off('click').on('click', $.proxy(onPageLast, this));
$next.off('click').on('click', $.proxy(onPageNext, this));
}
var onPageListChange = function(event){
var $this = $(event.currentTarget);
$this.parent().addClass('active').siblings().removeClass('active');
var $pagination = target.find(".fixed-table-pagination");
options.pageSize = $this.text().toUpperCase() === target.totalRows ? target.totalRows : + $this.text();
if(target.totalRows < options.pageSize * options.pageNumber){
options.pageNumber = 1;
}
$pagination.find('.page-size').text(options.pageSize);
initServer();
}
var onPagePre = function(event){
if ((options.pageNumber - 1) === 0) {
options.pageNumber = target.totalPages;
} else {
options.pageNumber--;
}
initServer();
}
var onPageNumber = function(event){
if (options.pageNumber == $(event.currentTarget).text()) {
return;
}
options.pageNumber = $(event.currentTarget).text();
initServer();
}
var onPageFirst = function(event){
options.pageNumber = 1;
initServer();
}
var onPageLast = function (event) {
options.pageNumber = target.totalPages;
initServer();
}
var onPageNext = function(event){
if ((options.pageNumber + 1) > target.totalPages) {
options.pageNumber = 1;
} else {
options.pageNumber++;
}
initServer();
} }
// 动态设置表头宽度 // 动态设置表头宽度
var autoTheadWidth = function(initFlag) { var autoTheadWidth = function(initFlag) {
@ -234,17 +472,34 @@
} }
// 缓存并格式化数据 // 缓存并格式化数据
var formatData = function(data) { var formatData = function(data) {
var _root = options.rootIdValue ? options.rootIdValue : null var _root = options.rootIdValue ? options.rootIdValue : null;
// 父节点属性列表
var parentCodes = [];
var rootFlag = false;
$.each(data, function(index, item) {
if($.inArray(item[options.parentCode], parentCodes) == -1){
parentCodes.push(item[options.parentCode]);
}
});
$.each(data, function(index, item) { $.each(data, function(index, item) {
// 添加一个默认属性,用来判断当前节点有没有被显示 // 添加一个默认属性,用来判断当前节点有没有被显示
item.isShow = false; item.isShow = false;
// 这里兼容几种常见Root节点写法 // 是否分页
// 默认的几种判断 if (options.pagination) {
if (item.isTreeLeaf == undefined || item.isTreeLeaf == null) {
item.isTreeLeaf = false;
} else {
item.isTreeLeaf = (item["isTreeLeaf"] == 1 ? true: false) || ((item["isTreeLeaf"] == 'true' || item["isTreeLeaf"] == true) ? true: false);
}
}
// 顶级节点校验判断兼容0,'0','',null
var _defaultRootFlag = item[options.parentCode] == '0' || var _defaultRootFlag = item[options.parentCode] == '0' ||
item[options.parentCode] == 0 || item[options.parentCode] == 0 ||
item[options.parentCode] == null || item[options.parentCode] == null ||
item[options.parentCode] == ''; item[options.parentCode] == '' ||
$.inArray(item[options.code], parentCodes) > 0 && !rootFlag;
if (!item[options.parentCode] || (_root ? (item[options.parentCode] == options.rootIdValue) : _defaultRootFlag)) { if (!item[options.parentCode] || (_root ? (item[options.parentCode] == options.rootIdValue) : _defaultRootFlag)) {
rootFlag = true;
if (!target.data_list["_root_"]) { if (!target.data_list["_root_"]) {
target.data_list["_root_"] = []; target.data_list["_root_"] = [];
} }
@ -263,26 +518,26 @@
}); });
} }
// 递归获取子节点并且设置子节点 // 递归获取子节点并且设置子节点
var recursionNode = function(parentNode, lv, row_id, p_id) { var recursionNode = function(parentNode, lv, row_id, p_id, k) {
var $tbody = target.find("tbody"); var $tbody = target.find("tbody");
var _ls = target.data_list["_n_" + parentNode[options.code]]; var _ls = target.data_list["_n_" + parentNode[options.code]];
var $tr = renderRow(parentNode, _ls ? true : false, lv, row_id, p_id); var $tr = renderRow(parentNode, _ls ? true : false, lv, row_id, p_id, options.pagination, k);
$tbody.append($tr); $tbody.append($tr);
if (_ls) { if (_ls) {
$.each(_ls, function(i, item) { $.each(_ls, function(i, item) {
var _child_row_id = row_id + "_" + i var _child_row_id = row_id + "_" + i
recursionNode(item, (lv + 1), _child_row_id, row_id) recursionNode(item, (lv + 1), _child_row_id, row_id, item[options.code])
}); });
} }
}; };
// 绘制行 // 绘制行
var renderRow = function(item, isP, lv, row_id, p_id) { var renderRow = function(item, isP, lv, row_id, p_id, _pagination, k) {
// 标记已显示 // 标记已显示
item.isShow = true; item.isShow = true;
item.row_id = row_id; item.row_id = row_id;
item.p_id = p_id; item.p_id = p_id;
item.lv = lv; item.lv = lv;
var $tr = $('<tr id="' + row_id + '" pid="' + p_id + '"></tr>'); var $tr = $('<tr id="' + row_id + '" data-id="' + k + '"pid="' + p_id + '"></tr>');
var _icon = options.expanderCollapsedClass; var _icon = options.expanderCollapsedClass;
if (options.expandAll) { if (options.expandAll) {
$tr.css("display", "table"); $tr.css("display", "table");
@ -297,6 +552,10 @@
$tr.css("display", "none"); $tr.css("display", "none");
} }
_icon = options.expanderCollapsedClass; _icon = options.expanderCollapsedClass;
} else if (_pagination) {
if (item.isTreeLeaf) {
_icon = options.expanderCollapsedClass;
}
} else { } else {
$tr.css("display", "none"); $tr.css("display", "none");
_icon = options.expanderCollapsedClass; _icon = options.expanderCollapsedClass;
@ -318,7 +577,7 @@
} else { } else {
var $td = $('<td name="' + column.field + '" class="' + column.field + '_cls"></td>'); var $td = $('<td name="' + column.field + '" class="' + column.field + '_cls"></td>');
if(column.width){ if(column.width){
$td.css("width",column.width); $td.css("width",column.width + (column.widthUnit ? column.widthUnit : 'px'));
} }
if(column.align){ if(column.align){
$td.css("text-align",column.align); $td.css("text-align",column.align);
@ -334,21 +593,29 @@
} }
// 增加formatter渲染 // 增加formatter渲染
if (column.formatter) { if (column.formatter) {
$td.html(column.formatter.call(this, item[column.field], item, index)); $td.html(column.formatter.call(this, getItemField(item, column.field), item, index));
} else { } else {
if(options.showTitle){ if(options.showTitle){
// 只在字段没有formatter时才添加title属性 // 只在字段没有formatter时才添加title属性
$td.attr("title",item[column.field]); $td.attr("title",item[column.field]);
} }
$td.text(item[column.field]); $td.text(getItemField(item, column.field));
} }
if (options.expandColumn == index) { if (options.expandColumn == index) {
if (_pagination) {
if (item["isTreeLeaf"]) {
$td.prepend('<span class="treetable-expander ' + _icon + '"></span>');
} else {
$td.prepend('<span class="treetable-expander"></span>')
}
} else {
if (!isP) { if (!isP) {
$td.prepend('<span class="treetable-expander"></span>') $td.prepend('<span class="treetable-expander"></span>')
} else { } else {
$td.prepend('<span class="treetable-expander ' + _icon + '"></span>') $td.prepend('<span class="treetable-expander ' + _icon + '"></span>');
} }
for (var int = 0; int < (lv - 1); int++) { }
for (var int = 0; int < (lv - options.expandColumn); int++) {
$td.prepend('<span class="treetable-indent"></span>') $td.prepend('<span class="treetable-indent"></span>')
} }
} }
@ -357,6 +624,12 @@
}); });
return $tr; return $tr;
} }
// 检索信息按钮点击事件
var registerSearchBtnClickEvent = function(btn) {
$(btn).off('click').on('click', function () {
$(".search-collapse").slideToggle();
});
}
// 注册刷新按钮点击事件 // 注册刷新按钮点击事件
var registerRefreshBtnClickEvent = function(btn) { var registerRefreshBtnClickEvent = function(btn) {
$(btn).off('click').on('click', function () { $(btn).off('click').on('click', function () {
@ -384,6 +657,15 @@
_ipt.prop('checked', true); _ipt.prop('checked', true);
target.find("tbody").find("tr").removeClass("treetable-selected"); target.find("tbody").find("tr").removeClass("treetable-selected");
$(this).addClass("treetable-selected"); $(this).addClass("treetable-selected");
} else if (_ipt.attr("type") == "checkbox") {
if (_ipt.prop('checked')) {
_ipt.prop('checked', true);
target.find("tbody").find("tr").removeClass("treetable-selected");
$(this).addClass("treetable-selected");
} else {
_ipt.prop('checked', false);
target.find("tbody").find("tr").removeClass("treetable-selected");
}
} else { } else {
if (_ipt.prop('checked')) { if (_ipt.prop('checked')) {
_ipt.prop('checked', false); _ipt.prop('checked', false);
@ -393,6 +675,8 @@
$(this).addClass("treetable-selected"); $(this).addClass("treetable-selected");
} }
} }
var _rowData = target.data_obj["id_" + $(this).data('id')];
calculateObjectValue(options, options.onClickRow, [_rowData], _rowData);
} }
}); });
} }
@ -405,7 +689,9 @@
if (_isExpanded || _isCollapsed) { if (_isExpanded || _isCollapsed) {
var tr = $(this).parent().parent(); var tr = $(this).parent().parent();
var row_id = tr.attr("id"); var row_id = tr.attr("id");
var _ls = target.find("tbody").find("tr[id^='" + row_id + "_']"); //下所有 var _id = tr.attr("data-id");
var _ls = target.find("tbody").find("tr[id^='" + row_id + "_']");
if (!options.pagination) {
if (_isExpanded) { if (_isExpanded) {
$(this).removeClass(options.expanderExpandedClass); $(this).removeClass(options.expanderExpandedClass);
$(this).addClass(options.expanderCollapsedClass); $(this).addClass(options.expanderCollapsedClass);
@ -419,14 +705,63 @@
$(this).addClass(options.expanderExpandedClass); $(this).addClass(options.expanderExpandedClass);
if (_ls && _ls.length > 0) { if (_ls && _ls.length > 0) {
$.each(_ls, function(index, item) { $.each(_ls, function(index, item) {
// 父icon
var _p_icon = $("#" + $(item).attr("pid")).children().eq(options.expandColumn).find(".treetable-expander"); var _p_icon = $("#" + $(item).attr("pid")).children().eq(options.expandColumn).find(".treetable-expander");
if (_p_icon.hasClass(options.expanderExpandedClass)) { var _p_display = $("#" + $(item).attr("pid")).css('display');
if (_p_icon.hasClass(options.expanderExpandedClass) && _p_display == 'table') {
$(item).css("display", "table"); $(item).css("display", "table");
} }
}); });
} }
} }
} else {
var _ls = target.find("tbody").find("tr[id^='" + row_id + "_']");
if (_ls && _ls.length > 0) {
if (_isExpanded) {
$.each(_ls, function(index, item) {
$(item).css("display", "none");
});
} else {
$.each(_ls, function(index, item) {
var _icon = $(item).eq(options.expandColumn).find(".treetable-expander");
if (_icon && _icon.hasClass(options.expanderExpandedClass)) {
$(item).css("display", "table");
} else {
$(item).css("display", "table");
}
});
}
} else {
if (options.pagination) {
var parms = {};
parms[options.parentCode] = _id;
if (options.dataUrl) {
$.ajax({
type: options.type,
url: options.dataUrl,
data: parms,
dataType: "json",
success: function(data, textStatus, jqXHR) {
$("#" + row_id + "_load").remove();
var list = data;
data = list;
target.appendData(data)
},
error: function(xhr, textStatus) {
var _errorMsg = '<tr><td colspan="' + options.columns.length + '"><div style="display: block;text-align: center;">' + xhr.responseText + '</div></td></tr>'
$("#" + row_id).after(_errorMsg);
}
});
}
}
}
if (_isExpanded) {
$(this).removeClass(options.expanderExpandedClass);
$(this).addClass(options.expanderCollapsedClass);
} else {
$(this).removeClass(options.expanderCollapsedClass);
$(this).addClass(options.expanderExpandedClass);
}
}
} }
}); });
} }
@ -439,8 +774,12 @@
} }
// 添加数据刷新表格 // 添加数据刷新表格
target.appendData = function(data) { target.appendData = function(data) {
data.reverse()
// 下边的操作主要是为了查询时让一些没有根节点的节点显示 // 下边的操作主要是为了查询时让一些没有根节点的节点显示
$.each(data, function(i, item) { $.each(data, function(i, item) {
if (options.pagination) {
item.__nodes = (item["nodes"] == 1 ? true: false) || ((item["nodes"] == 'true' || item["nodes"] == true) ? true: false);
}
var _data = target.data_obj["id_" + item[options.code]]; var _data = target.data_obj["id_" + item[options.code]];
var _p_data = target.data_obj["id_" + item[options.parentCode]]; var _p_data = target.data_obj["id_" + item[options.parentCode]];
var _c_list = target.data_list["_n_" + item[options.parentCode]]; var _c_list = target.data_list["_n_" + item[options.parentCode]];
@ -462,7 +801,7 @@
} }
_lv = _p_data.lv + 1; //如果有父 _lv = _p_data.lv + 1; //如果有父
// 绘制行 // 绘制行
tr = renderRow(item, false, _lv, row_id, p_id); tr = renderRow(item, true, _lv, row_id, p_id, options.pagination, item[options.code]);
var _p_icon = $("#" + _p_data.row_id).children().eq(options.expandColumn).find(".treetable-expander"); var _p_icon = $("#" + _p_data.row_id).children().eq(options.expandColumn).find(".treetable-expander");
var _isExpanded = _p_icon.hasClass(options.expanderExpandedClass); var _isExpanded = _p_icon.hasClass(options.expanderExpandedClass);
@ -484,12 +823,11 @@
} else { } else {
// 计算父的同级下一行 // 计算父的同级下一行
var _tmp_ls = _p_data.row_id.split("_"); var _tmp_ls = _p_data.row_id.split("_");
var _p_next = _p_data.row_id.substring(0, _p_data.row_id.length - 1) + (parseInt(_tmp_ls[_tmp_ls.length - 1]) + 1); var _p_next = _p_data.row_id.substring(0, _p_data.row_id.length - (_tmp_ls[_tmp_ls.length - 1] + "").length) + (parseInt(_tmp_ls[_tmp_ls.length - 1]) + 1);
// 画上 $("#" + _p_data.row_id).after(tr);
$("#" + _p_next).before(tr);
} }
} else { } else {
tr = renderRow(item, false, _lv, row_id, p_id); tr = renderRow(item, false, _lv, row_id, p_id, options.pagination, item[options.code]);
if (_data) { if (_data) {
$("#" + _data.row_id).before(tr); $("#" + _data.row_id).before(tr);
$("#" + _data.row_id).remove(); $("#" + _data.row_id).remove();
@ -573,6 +911,52 @@
$input.prop("checked", ''); $input.prop("checked", '');
} }
} }
// ruoyi 解析数据,支持多层级访问
var getItemField = function (item, field) {
var value = item;
if (typeof field !== 'string' || item.hasOwnProperty(field)) {
return item[field];
}
var props = field.split('.');
for (var p in props) {
value = value && value[props[p]];
}
return value;
};
// ruoyi 发起对目标(target)函数的调用
var calculateObjectValue = function (self, name, args, defaultValue) {
var func = name;
if (typeof name === 'string') {
var names = name.split('.');
if (names.length > 1) {
func = window;
$.each(names, function (i, f) {
func = func[f];
});
} else {
func = window[name];
}
}
if (typeof func === 'object') {
return func;
}
if (typeof func === 'function') {
return func.apply(self, args);
}
if (!func && typeof name === 'string' && sprintf.apply(this, [name].concat(args))) {
return sprintf.apply(this, [name].concat(args));
}
return defaultValue;
};
var formatRecordsPerPage = function (pageNumber) {
return '每页显示 ' + pageNumber + ' 条记录';
};
var formatShowingRows = function (pageFrom, pageTo, totalRows) {
return '显示第 ' + pageFrom + ' 到第 ' + pageTo + ' 条记录,总共 ' + totalRows + ' 条记录。';
};
// 初始化 // 初始化
init(); init();
return target; return target;
@ -645,26 +1029,40 @@
$.fn.bootstrapTreeTable.defaults = { $.fn.bootstrapTreeTable.defaults = {
code: 'code', // 选取记录返回的值,用于设置父子关系 code: 'code', // 选取记录返回的值,用于设置父子关系
parentCode: 'parentCode', // 用于设置父子关系 parentCode: 'parentCode', // 用于设置父子关系
rootIdValue: null, // 设置根节点id值----可指定根节点默认为null,"",0,"0" rootIdValue: 0, // 设置根节点id值----可指定根节点默认为null,"",0,"0"
data: null, // 构造table的数据集合 data: null, // 构造table的数据集合
type: "GET", // 请求数据的ajax类型 type: "GET", // 请求数据的ajax类型
url: null, // 请求数据的ajax的url url: null, // 请求数据的ajax的url
ajaxParams: {}, // 请求数据的ajax的data属性 ajaxParams: {}, // 请求数据的ajax的data属性
expandColumn: 0, // 在哪一列上面显示展开按钮 expandColumn: 1, // 在哪一列上面显示展开按钮
expandAll: false, // 是否全部展开 expandAll: false, // 是否全部展开
expandFirst: true, // 是否默认第一级展开--expandAll为false时生效 expandFirst: true, // 是否默认第一级展开--expandAll为false时生效
striped: false, // 是否各行渐变色 striped: false, // 是否各行渐变色
bordered: true, // 是否显示边框 bordered: false, // 是否显示边框
hover: true, // 是否鼠标悬停 hover: true, // 是否鼠标悬停
condensed: false, // 是否紧缩表格 condensed: false, // 是否紧缩表格
columns: [], // 列 columns: [], // 列
toolbar: null, // 顶部工具条 toolbar: null, // 顶部工具条
height: 0, // 表格高度 height: 0, // 表格高度
pagination: false, // 是否显示分页
dataUrl: null, // 加载子节点异步请求数据url
pageNumber: 1, // 当前页条数
pageSize: 10, // 每页的记录行数
onClickRow: null, // 单击某行事件
pageList: [10, 25, 50], // 可供选择的每页的行数
showTitle: true, // 是否采用title属性显示字段内容被formatter格式化的字段不会显示 showTitle: true, // 是否采用title属性显示字段内容被formatter格式化的字段不会显示
showSearch: true, // 是否显示检索信息
showColumns: true, // 是否显示内容列下拉框 showColumns: true, // 是否显示内容列下拉框
showRefresh: true, // 是否显示刷新按钮 showRefresh: true, // 是否显示刷新按钮
paginationPreText: '&lsaquo;',
paginationNextText: '&rsaquo;',
expanderExpandedClass: 'glyphicon glyphicon-chevron-down', // 展开的按钮的图标 expanderExpandedClass: 'glyphicon glyphicon-chevron-down', // 展开的按钮的图标
expanderCollapsedClass: 'glyphicon glyphicon-chevron-right' // 缩起的按钮的图标 expanderCollapsedClass: 'glyphicon glyphicon-chevron-right', // 缩起的按钮的图标
responseHandler: function(res) {
return false;
},
onLoadSuccess: function(res) {
return false;
}
}; };
})(jQuery); })(jQuery);

File diff suppressed because one or more lines are too long

View File

@ -1,42 +1,109 @@
(function ($) { /**
'use strict'; * Bootstrap Table Chinese translation
* Author: Zhixin Wen<wenzhixin2010@gmail.com>
$.fn.bootstrapTable.locales['zh-CN'] = { */
formatLoadingMessage: function () { $.fn.bootstrapTable.locales['zh-CN'] = {
return '正在努力地加载数据中,请稍候……'; formatShowSearch: function formatShowSearch() {
return '隐藏/显示搜索';
}, },
formatRecordsPerPage: function (pageNumber) { formatPageGo: function formatPageGo() {
return pageNumber + ' 条记录每页'; return '跳转';
}, },
formatShowingRows: function (pageFrom, pageTo, totalRows) { formatCopyRows: function formatCopyRows() {
return '第 ' + pageFrom + ' 到 ' + pageTo + ' 条,共 ' + totalRows + ' 条记录。'; return '复制行';
}, },
formatSearch: function () { 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 '搜索'; return '搜索';
}, },
formatNoMatches: function () { formatNoMatches: function formatNoMatches() {
return '没有找到匹配的记录'; return '没有找到匹配的记录';
}, },
formatPaginationSwitch: function () { formatPaginationSwitch: function formatPaginationSwitch() {
return '隐藏/显示分页'; return '隐藏/显示分页';
}, },
formatRefresh: function () { formatPaginationSwitchDown: function formatPaginationSwitchDown() {
return '显示分页';
},
formatPaginationSwitchUp: function formatPaginationSwitchUp() {
return '隐藏分页';
},
formatRefresh: function formatRefresh() {
return '刷新'; return '刷新';
}, },
formatToggle: function () { formatToggle: function formatToggle() {
return '切换'; return '切换';
}, },
formatColumns: function () { formatToggleOn: function formatToggleOn() {
return '显示卡片视图';
},
formatToggleOff: function formatToggleOff() {
return '隐藏卡片视图';
},
formatColumns: function formatColumns() {
return '列'; return '列';
}, },
formatExport: function () { formatColumnsToggleAll: function formatColumnsToggleAll() {
return '切换所有';
},
formatFullscreen: function formatFullscreen() {
return '全屏';
},
formatAllRows: function formatAllRows() {
return '所有';
},
formatAutoRefresh: function formatAutoRefresh() {
return '自动刷新';
},
formatExport: function formatExport() {
return '导出数据'; return '导出数据';
}, },
formatClearFilters: function () { formatJumpTo: function formatJumpTo() {
return '清空过滤'; 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']);
$.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['zh-CN']);
})(jQuery);

View File

@ -1 +1 @@
(function($){$.fn.bootstrapTable.locales["zh-CN"]={formatLoadingMessage:function(){return"正在努力地加载数据中,请稍候……"},formatRecordsPerPage:function(pageNumber){return pageNumber+" 条记录每页"},formatShowingRows:function(pageFrom,pageTo,totalRows){return"第 "+pageFrom+" 到 "+pageTo+" 条,共 "+totalRows+" 条记录。"},formatSearch:function(){return"搜索"},formatNoMatches:function(){return"没有找到匹配的记录"},formatPaginationSwitch:function(){return"隐藏/显示分页"},formatRefresh:function(){return"刷新"},formatToggle:function(){return"切换"},formatColumns:function(){return"列"},formatExport:function(){return"导出数据"},formatClearFilters:function(){return"清空过滤"}};$.extend($.fn.bootstrapTable.defaults,$.fn.bootstrapTable.locales["zh-CN"])})(jQuery); $.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

@ -1,14 +0,0 @@
.bootstrap-tree-table .treetable-indent {width:16px; height: 16px; display: inline-block; position: relative;}
.bootstrap-tree-table .treetable-expander {width:16px; height: 16px; display: inline-block; position: relative; cursor: pointer;}
.bootstrap-tree-table .treetable-selected{background: #f5f5f5 !important;}
.bootstrap-tree-table .treetable-table{border:0 !important;margin-bottom:0}
.bootstrap-tree-table .treetable-table tbody {display:block;height:auto;overflow-y:auto;}
.bootstrap-tree-table .treetable-table thead, .treetable-table tbody tr {display:table;width:100%;table-layout:fixed;}
.bootstrap-tree-table .treetable-thead th{line-height:24px;border: 0 !important;border-radius: 4px;border-left:0px solid #e7eaec !important;border-bottom:1px solid #ccc!important;text-align: left;}
.bootstrap-tree-table .treetable-thead tr :first-child{border-left:0 !important}
.bootstrap-tree-table .treetable-tbody td{border: 0 !important;border-left:0px solid #e7eaec !important;border-bottom:1px solid #e7eaec!important;overflow: hidden; white-space: nowrap; text-overflow: ellipsis;}
.bootstrap-tree-table .treetable-tbody tr :first-child{border-left:0 !important}
.bootstrap-tree-table .treetable-bars .tool-left, .bootstrap-tree-table .treetable-bars .tool-right{margin-top: 10px; margin-bottom: 10px;}
.bootstrap-tree-table .treetable-bars .tool-left{float: left;}
.bootstrap-tree-table .treetable-bars .tool-right{float: right;}
.bootstrap-tree-table .treetable-bars .columns li label{display: block;padding: 3px 20px;clear: both;font-weight: 400;line-height: 1.428571429;max-width: 100%;margin-bottom: 5px;cursor:pointer;}

View File

@ -1,127 +0,0 @@
@charset "utf-8";
.container {
margin: 10px auto 0 auto;
position: relative;
font-family: 微软雅黑;
font-size: 12px;
}
.container p {
line-height: 12px;
line-height: 0px;
height: 0px;
margin: 10px;
color: #bbb
}
.action {
width: 400px;
height: 30px;
margin: 10px 0;
}
.cropped {
position: absolute;
left: 500px;
top: 0;
width: 200px;
border: 1px #ddd solid;
height: 440px;
padding: 4px;
box-shadow: 0px 0px 12px #ddd;
text-align: center;
}
.imageBox {
position: relative;
height: 400px;
width: 400px;
border: 1px solid #aaa;
background: #fff;
overflow: hidden;
background-repeat: no-repeat;
cursor: move;
box-shadow: 4px 4px 12px #B0B0B0;
}
.imageBox .thumbBox {
position: absolute;
top: 50%;
left: 50%;
width: 200px;
height: 200px;
margin-top: -100px;
margin-left: -100px;
box-sizing: border-box;
border: 1px solid rgb(102, 102, 102);
box-shadow: 0 0 0 1000px rgba(0, 0, 0, 0.5);
background: none repeat scroll 0% 0% transparent;
}
.imageBox .spinner {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
text-align: center;
line-height: 400px;
background: rgba(0,0,0,0.7);
}
.Btnsty_peyton{ float: right;
width: 46px;
display: inline-block;
margin-bottom: 10px;
height: 37px;
line-height: 37px;
font-size: 14px;
color: #FFFFFF;
margin:0px 2px;
background-color: #f38e81;
border-radius: 3px;
text-decoration: none;
cursor: pointer;
box-shadow: 0px 0px 5px #B0B0B0;
border: 0px #fff solid;}
/*选择文件上传*/
.new-contentarea {
width: 165px;
overflow:hidden;
margin: 0 auto;
position:relative;float:left;
}
.new-contentarea label {
width:100%;
height:100%;
display:block;
}
.new-contentarea input[type=file] {
width:188px;
height:60px;
background:#333;
margin: 0 auto;
position:absolute;
right:50%;
margin-right:-94px;
top:0;
right/*\**/:0px\9;
margin-right/*\**/:0px\9;
width/*\**/:10px\9;
opacity:0;
filter:alpha(opacity=0);
z-index:2;
}
a.upload-img{
width:165px;
display: inline-block;
margin-bottom: 10px;
height:37px;
line-height: 37px;
font-size: 14px;
color: #FFFFFF;
background-color: #f38e81;
border-radius: 3px;
text-decoration:none;
cursor:pointer;
border: 0px #fff solid;
box-shadow: 0px 0px 5px #B0B0B0;
}
a.upload-img:hover{
background-color: #ec7e70;
}
.tc{text-align:center;}

View File

@ -1,135 +0,0 @@
"use strict";
(function (factory) {
if (typeof define === 'function' && define.amd) {
define(['jquery'], factory);
} else {
factory(jQuery);
}
}(function ($) {
var cropbox = function(options, el){
var el = el || $(options.imageBox),
obj =
{
state : {},
ratio : 1,
options : options,
imageBox : el,
thumbBox : el.find(options.thumbBox),
spinner : el.find(options.spinner),
image : new Image(),
getDataURL: function ()
{
var width = this.thumbBox.width(),
height = this.thumbBox.height(),
canvas = document.createElement("canvas"),
dim = el.css('background-position').split(' '),
size = el.css('background-size').split(' '),
dx = parseInt(dim[0]) - el.width()/2 + width/2,
dy = parseInt(dim[1]) - el.height()/2 + height/2,
dw = parseInt(size[0]),
dh = parseInt(size[1]),
sh = parseInt(this.image.height),
sw = parseInt(this.image.width);
canvas.width = width;
canvas.height = height;
var context = canvas.getContext("2d");
context.drawImage(this.image, 0, 0, sw, sh, dx, dy, dw, dh);
var imageData = canvas.toDataURL('image/png');
return imageData;
},
getBlob: function()
{
var imageData = this.getDataURL();
var b64 = imageData.replace('data:image/png;base64,','');
var binary = atob(b64);
var array = [];
for (var i = 0; i < binary.length; i++) {
array.push(binary.charCodeAt(i));
}
return new Blob([new Uint8Array(array)], {type: 'image/png'});
},
zoomIn: function ()
{
this.ratio*=1.1;
setBackground();
},
zoomOut: function ()
{
this.ratio*=0.9;
setBackground();
}
},
setBackground = function()
{
var w = parseInt(obj.image.width)*obj.ratio;
var h = parseInt(obj.image.height)*obj.ratio;
var pw = (el.width() - w) / 2;
var ph = (el.height() - h) / 2;
el.css({
'background-image': 'url(' + obj.image.src + ')',
'background-size': w +'px ' + h + 'px',
'background-position': pw + 'px ' + ph + 'px',
'background-repeat': 'no-repeat'});
},
imgMouseDown = function(e)
{
e.stopImmediatePropagation();
obj.state.dragable = true;
obj.state.mouseX = e.clientX;
obj.state.mouseY = e.clientY;
},
imgMouseMove = function(e)
{
e.stopImmediatePropagation();
if (obj.state.dragable)
{
var x = e.clientX - obj.state.mouseX;
var y = e.clientY - obj.state.mouseY;
var bg = el.css('background-position').split(' ');
var bgX = x + parseInt(bg[0]);
var bgY = y + parseInt(bg[1]);
el.css('background-position', bgX +'px ' + bgY + 'px');
obj.state.mouseX = e.clientX;
obj.state.mouseY = e.clientY;
}
},
imgMouseUp = function(e)
{
e.stopImmediatePropagation();
obj.state.dragable = false;
},
zoomImage = function(e)
{
e.originalEvent.wheelDelta > 0 || e.originalEvent.detail < 0 ? obj.ratio*=1.1 : obj.ratio*=0.9;
setBackground();
}
obj.spinner.show();
obj.image.onload = function() {
obj.spinner.hide();
setBackground();
el.bind('mousedown', imgMouseDown);
el.bind('mousemove', imgMouseMove);
$(window).bind('mouseup', imgMouseUp);
el.bind('mousewheel DOMMouseScroll', zoomImage);
};
obj.image.src = options.imgSrc;
el.on('remove', function(){$(window).unbind('mouseup', imgMouseUp)});
return obj;
};
jQuery.fn.cropbox = function(options){
return new cropbox(options, this);
};
}));

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

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