115 Commits
Author SHA1 Message Date
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
若依andGitee 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
若依andGitee 54ce56564b !113 SysUserMapper.xml 查询语句sql字段重复
Merge pull request !113 from RACSU/master
2019-07-28 21:31:22 +08:00
RACSUandGitee 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
若依andGitee 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
厚积薄发andGitee 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
若依andGitee 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
若依andGitee 58673fa502 !102 浮点数运算类更新过期方法
Merge pull request !102 from GeBron/master
2019-06-13 17:40:36 +08:00
若依andGitee a1523e3bfd !100 单例模式
Merge pull request !100 from geekymv/master
2019-06-13 17:35:08 +08:00
若依andGitee 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
GeBronandGitee 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
226 changed files with 16446 additions and 3168 deletions
+25 -17
View File
@@ -6,11 +6,11 @@
若依参考后台模板。有需要可自行到群内下载。
> 如需单应用,请移步 [RuoYi-fast](https://gitee.com/y_project/RuoYi-fast) `(保持同步更新)`,如需Oracle版本,请移步 [RuoYi-oracle](http://doc.ruoyi.vip/#/standard/xmkz) `(不定时更新)`
> 如需单应用,请移步 [RuoYi-fast](https://gitee.com/y_project/RuoYi-fast) `(保持同步更新)`,如需其他版本,请移步 [项目扩展](http://doc.ruoyi.vip/#/standard/xmkz) `(不定时更新)`
> 阿里云通用云产品1888优惠券 [点我领取](https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=brki8iof)&nbsp;&nbsp;&nbsp;&nbsp;腾讯云通用云产品2860优惠券 [点我领取](https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console)&nbsp;&nbsp;`(仅限新用户)`
> 阿里云Hi拼购 限量爆款 低至199元/年 [https://www.aliyun.com/acts/hi-group-buying?userCode=brki8iof](https://www.aliyun.com/acts/hi-group-buying?userCode=brki8iof)&nbsp;&nbsp;`(仅限新用户)`
> 阿里云Hi拼购 限量爆款 低至199元/年 [点我进入](https://www.aliyun.com/acts/hi-group-buying?userCode=brki8iof)&nbsp;&nbsp;`(仅限新用户)`
## 内置功能
@@ -44,34 +44,42 @@
<table>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/25b5e333768d013d45a990c152dbe4d9d6e.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/5ac52ccc07a59f12205948c9408791f5c5b.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/e29fd81b2d43b517f99535564af41f9d1d5.jpg"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/66f8b5b24720dabe0e11ae84bd1ad4b038e.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/a46f34786bc9fc400697b6f3677be5bb3f0.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/629f1510fb6205f773c8c284863406b694f.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/9124eda87df0e72427cd63f458b813e3363.jpg"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/6010201b078dbc9e1d8c09c6a3e53f4344c.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/058928ad3a6e6de67b43d62d42dbf071355.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/438c59467afd0097cfbe9c89db932661687.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/72a015041db6843aca7f7b273688cb346f8.jpg"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/21acdcade5e306f2c5d7ae26993b4e6bd06.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/ad5ea3c4c2ea2e91d1f05f6cc384cbad2a1.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/ecb5f1c9929f1933f733f796749b2df73d9.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/e4283d500eb10e8dd8701e7742f7facb065.jpg"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/6ca845cca1701fbf71881efe4f341c82f99.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/e3aeb8fff585594f6e947218e14f2806ea1.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/2531dbf419a1b114e1177f8d2a120b8a9c3.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/8b740a42dddc1e5a8a150d97c5060df258b.jpg"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/197ddc2fdffc27020f8624bd7ca1a971f61.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/a2dabea752d7d70aede20908dee0b419829.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/00e642dc3515919b3760968cc496a12a849.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/f72d28a3e60413a4e1b5c7c2f45f962fd65.jpg"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/c5699c5726b5aebde71a37bb5163d840bc2.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/24740d59377e826d0d8664ebad66dc84abd.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/19222e495869a2a99fc31c5d2bd4539e1e7.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/264d25176f4e22b4b38e95fe6ce73775299.jpg"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/bbe7fe1048d29217ba73bd3ed88d6743b55.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/d85fbb59be27fb33f68bdbb6e8bc967c97b.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/bb902d2c54bad02a052e9a05e5f22a93df1.jpg"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/30cda883bb9a7f74f1454314e64f949942d.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/deebaaa8d6b14a419ed5911f49e3f222a6f.jpg"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/bed2b98a44e7ae820c2885329e711965c28.jpg"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/5f3d39a141f21f81b90536f391b8408f1fa.jpg"/></td>
</tr>
</table>
@@ -79,4 +87,4 @@
## 若依交流群
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群: [![加入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) 点击按钮入群。
Binary file not shown.
+10 -2
View File
@@ -6,14 +6,14 @@
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId>
<version>3.4</version>
<version>4.0.0</version>
<name>ruoyi</name>
<url>http://www.ruoyi.vip</url>
<description>若依管理系统</description>
<properties>
<ruoyi.version>3.4</ruoyi.version>
<ruoyi.version>4.0.0</ruoyi.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
@@ -25,6 +25,7 @@
<kaptcha.version>2.3.2</kaptcha.version>
<swagger.version>2.9.2</swagger.version>
<pagehelper.boot.version>1.2.5</pagehelper.boot.version>
<fastjson.version>1.2.47</fastjson.version>
<oshi.version>3.9.1</oshi.version>
<commons.io.version>2.5</commons.io.version>
<commons.fileupload.version>1.3.3</commons.fileupload.version>
@@ -167,6 +168,13 @@
<artifactId>velocity</artifactId>
<version>${velocity.version}</version>
</dependency>
<!-- 阿里JSON解析器 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<!-- 定时任务-->
<dependency>
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId>
<version>3.4</version>
<version>4.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
@@ -27,11 +27,6 @@ public class CommonController
{
private static final Logger log = LoggerFactory.getLogger(CommonController.class);
/**
* 文件上传路径
*/
public static final String UPLOAD_PATH = "/profile/upload/";
@Autowired
private ServerConfig serverConfig;
@@ -82,7 +77,7 @@ public class CommonController
String filePath = Global.getUploadPath();
// 上传并返回新文件名称
String fileName = FileUploadUtils.upload(filePath, file);
String url = serverConfig.getUrl() + UPLOAD_PATH + fileName;
String url = serverConfig.getUrl() + fileName;
AjaxResult ajax = AjaxResult.success();
ajax.put("fileName", fileName);
ajax.put("url", url);
@@ -136,6 +136,24 @@ public class DemoFormController
return prefix + "/basic";
}
/**
* 卡片列表
*/
@GetMapping("/cards")
public String cards()
{
return prefix + "/cards";
}
/**
* summernote 富文本编辑器
*/
@GetMapping("/summernote")
public String summernote()
{
return prefix + "/summernote";
}
/**
* 搜索自动补全
*/
@@ -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";
}
}
@@ -176,6 +176,24 @@ public class DemoTableController extends BaseController
return prefix + "/image";
}
/**
* 动态增删改查
*/
@GetMapping("/curd")
public String curd()
{
return prefix + "/curd";
}
/**
* 表格拖拽操作
*/
@GetMapping("/reorder")
public String reorder()
{
return prefix + "/reorder";
}
/**
* 表格其他操作
*/
@@ -15,7 +15,7 @@ import com.ruoyi.common.core.controller.BaseController;
@RequestMapping("/monitor/data")
public class DruidController extends BaseController
{
private String prefix = "/monitor/druid";
private String prefix = "/druid";
@RequiresPermissions("monitor:data:view")
@GetMapping()
@@ -5,12 +5,14 @@ import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
@@ -81,8 +83,12 @@ public class SysConfigController extends BaseController
@Log(title = "参数管理", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(SysConfig config)
public AjaxResult addSave(@Validated SysConfig config)
{
if (UserConstants.CONFIG_KEY_NOT_UNIQUE.equals(configService.checkConfigKeyUnique(config)))
{
return error("新增参数'" + config.getConfigName() + "'失败,参数键名已存在");
}
config.setCreateBy(ShiroUtils.getLoginName());
return toAjax(configService.insertConfig(config));
}
@@ -104,8 +110,12 @@ public class SysConfigController extends BaseController
@Log(title = "参数管理", businessType = BusinessType.UPDATE)
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(SysConfig config)
public AjaxResult editSave(@Validated SysConfig config)
{
if (UserConstants.CONFIG_KEY_NOT_UNIQUE.equals(configService.checkConfigKeyUnique(config)))
{
return error("修改参数'" + config.getConfigName() + "'失败,参数键名已存在");
}
config.setUpdateBy(ShiroUtils.getLoginName());
return toAjax(configService.updateConfig(config));
}
@@ -5,12 +5,14 @@ import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.Ztree;
@@ -43,7 +45,7 @@ public class SysDeptController extends BaseController
}
@RequiresPermissions("system:dept:list")
@GetMapping("/list")
@PostMapping("/list")
@ResponseBody
public List<SysDept> list(SysDept dept)
{
@@ -68,8 +70,12 @@ public class SysDeptController extends BaseController
@RequiresPermissions("system:dept:add")
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(SysDept dept)
public AjaxResult addSave(@Validated SysDept dept)
{
if (UserConstants.DEPT_NAME_NOT_UNIQUE.equals(deptService.checkDeptNameUnique(dept)))
{
return error("新增部门'" + dept.getDeptName() + "'失败,部门名称已存在");
}
dept.setCreateBy(ShiroUtils.getLoginName());
return toAjax(deptService.insertDept(dept));
}
@@ -96,8 +102,16 @@ public class SysDeptController extends BaseController
@RequiresPermissions("system:dept:edit")
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(SysDept dept)
public AjaxResult editSave(@Validated SysDept dept)
{
if (UserConstants.DEPT_NAME_NOT_UNIQUE.equals(deptService.checkDeptNameUnique(dept)))
{
return error("修改部门'" + dept.getDeptName() + "'失败,部门名称已存在");
}
else if (dept.getParentId().equals(dept.getDeptId()))
{
return error("修改部门'" + dept.getDeptName() + "'失败,上级部门不能是自己");
}
dept.setUpdateBy(ShiroUtils.getLoginName());
return toAjax(deptService.updateDept(dept));
}
@@ -5,6 +5,7 @@ import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
@@ -79,7 +80,7 @@ public class SysDictDataController extends BaseController
@RequiresPermissions("system:dict:add")
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(SysDictData dict)
public AjaxResult addSave(@Validated SysDictData dict)
{
dict.setCreateBy(ShiroUtils.getLoginName());
return toAjax(dictDataService.insertDictData(dict));
@@ -102,7 +103,7 @@ public class SysDictDataController extends BaseController
@RequiresPermissions("system:dict:edit")
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(SysDictData dict)
public AjaxResult editSave(@Validated SysDictData dict)
{
dict.setUpdateBy(ShiroUtils.getLoginName());
return toAjax(dictDataService.updateDictData(dict));
@@ -5,14 +5,17 @@ import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.Ztree;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
@@ -79,8 +82,12 @@ public class SysDictTypeController extends BaseController
@RequiresPermissions("system:dict:add")
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(SysDictType dict)
public AjaxResult addSave(@Validated SysDictType dict)
{
if (UserConstants.DICT_TYPE_NOT_UNIQUE.equals(dictTypeService.checkDictTypeUnique(dict)))
{
return error("新增字典'" + dict.getDictName() + "'失败,字典类型已存在");
}
dict.setCreateBy(ShiroUtils.getLoginName());
return toAjax(dictTypeService.insertDictType(dict));
}
@@ -102,8 +109,12 @@ public class SysDictTypeController extends BaseController
@RequiresPermissions("system:dict:edit")
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(SysDictType dict)
public AjaxResult editSave(@Validated SysDictType dict)
{
if (UserConstants.DICT_TYPE_NOT_UNIQUE.equals(dictTypeService.checkDictTypeUnique(dict)))
{
return error("修改字典'" + dict.getDictName() + "'失败,字典类型已存在");
}
dict.setUpdateBy(ShiroUtils.getLoginName());
return toAjax(dictTypeService.updateDictType(dict));
}
@@ -145,4 +156,27 @@ public class SysDictTypeController extends BaseController
{
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;
}
}
@@ -5,12 +5,14 @@ import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.Ztree;
@@ -42,11 +44,12 @@ public class SysMenuController extends BaseController
}
@RequiresPermissions("system:menu:list")
@GetMapping("/list")
@PostMapping("/list")
@ResponseBody
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;
}
@@ -99,8 +102,12 @@ public class SysMenuController extends BaseController
@RequiresPermissions("system:menu:add")
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(SysMenu menu)
public AjaxResult addSave(@Validated SysMenu menu)
{
if (UserConstants.MENU_NAME_NOT_UNIQUE.equals(menuService.checkMenuNameUnique(menu)))
{
return error("新增菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
}
menu.setCreateBy(ShiroUtils.getLoginName());
ShiroUtils.clearCachedAuthorizationInfo();
return toAjax(menuService.insertMenu(menu));
@@ -123,8 +130,12 @@ public class SysMenuController extends BaseController
@RequiresPermissions("system:menu:edit")
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(SysMenu menu)
public AjaxResult editSave(@Validated SysMenu menu)
{
if (UserConstants.MENU_NAME_NOT_UNIQUE.equals(menuService.checkMenuNameUnique(menu)))
{
return error("修改菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
}
menu.setUpdateBy(ShiroUtils.getLoginName());
ShiroUtils.clearCachedAuthorizationInfo();
return toAjax(menuService.updateMenu(menu));
@@ -156,7 +167,8 @@ public class SysMenuController extends BaseController
@ResponseBody
public List<Ztree> roleMenuTreeData(SysRole role)
{
List<Ztree> ztrees = menuService.roleMenuTreeData(role);
Long userId = ShiroUtils.getUserId();
List<Ztree> ztrees = menuService.roleMenuTreeData(role, userId);
return ztrees;
}
@@ -165,9 +177,10 @@ public class SysMenuController extends BaseController
*/
@GetMapping("/menuTreeData")
@ResponseBody
public List<Ztree> menuTreeData(SysRole role)
public List<Ztree> menuTreeData()
{
List<Ztree> ztrees = menuService.menuTreeData();
Long userId = ShiroUtils.getUserId();
List<Ztree> ztrees = menuService.menuTreeData(userId);
return ztrees;
}
@@ -5,12 +5,14 @@ import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
@@ -94,8 +96,16 @@ public class SysPostController extends BaseController
@Log(title = "岗位管理", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(SysPost post)
public AjaxResult addSave(@Validated SysPost post)
{
if (UserConstants.POST_NAME_NOT_UNIQUE.equals(postService.checkPostNameUnique(post)))
{
return error("新增岗位'" + post.getPostName() + "'失败,岗位名称已存在");
}
else if (UserConstants.POST_CODE_NOT_UNIQUE.equals(postService.checkPostCodeUnique(post)))
{
return error("新增岗位'" + post.getPostName() + "'失败,岗位编码已存在");
}
post.setCreateBy(ShiroUtils.getLoginName());
return toAjax(postService.insertPost(post));
}
@@ -117,8 +127,16 @@ public class SysPostController extends BaseController
@Log(title = "岗位管理", businessType = BusinessType.UPDATE)
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(SysPost post)
public AjaxResult editSave(@Validated SysPost post)
{
if (UserConstants.POST_NAME_NOT_UNIQUE.equals(postService.checkPostNameUnique(post)))
{
return error("修改岗位'" + post.getPostName() + "'失败,岗位名称已存在");
}
else if (UserConstants.POST_CODE_NOT_UNIQUE.equals(postService.checkPostCodeUnique(post)))
{
return error("修改岗位'" + post.getPostName() + "'失败,岗位编码已存在");
}
post.setUpdateBy(ShiroUtils.getLoginName());
return toAjax(postService.updatePost(post));
}
@@ -5,12 +5,14 @@ import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
@@ -84,8 +86,16 @@ public class SysRoleController extends BaseController
@Log(title = "角色管理", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(SysRole role)
public AjaxResult addSave(@Validated SysRole role)
{
if (UserConstants.ROLE_NAME_NOT_UNIQUE.equals(roleService.checkRoleNameUnique(role)))
{
return error("新增角色'" + role.getRoleName() + "'失败,角色名称已存在");
}
else if (UserConstants.ROLE_KEY_NOT_UNIQUE.equals(roleService.checkRoleKeyUnique(role)))
{
return error("新增角色'" + role.getRoleName() + "'失败,角色权限已存在");
}
role.setCreateBy(ShiroUtils.getLoginName());
ShiroUtils.clearCachedAuthorizationInfo();
return toAjax(roleService.insertRole(role));
@@ -109,8 +119,16 @@ public class SysRoleController extends BaseController
@Log(title = "角色管理", businessType = BusinessType.UPDATE)
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(SysRole role)
public AjaxResult editSave(@Validated SysRole role)
{
if (UserConstants.ROLE_NAME_NOT_UNIQUE.equals(roleService.checkRoleNameUnique(role)))
{
return error("修改角色'" + role.getRoleName() + "'失败,角色名称已存在");
}
else if (UserConstants.ROLE_KEY_NOT_UNIQUE.equals(roleService.checkRoleKeyUnique(role)))
{
return error("修改角色'" + role.getRoleName() + "'失败,角色权限已存在");
}
role.setUpdateBy(ShiroUtils.getLoginName());
ShiroUtils.clearCachedAuthorizationInfo();
return toAjax(roleService.updateRole(role));
@@ -5,6 +5,7 @@ import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
@@ -117,15 +118,19 @@ public class SysUserController extends BaseController
@Log(title = "用户管理", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(SysUser user)
public AjaxResult addSave(@Validated SysUser user)
{
if (StringUtils.isNotNull(user.getUserId()) && SysUser.isAdmin(user.getUserId()))
{
return error("不允许修改超级管理员用户");
}
if (UserConstants.USER_NAME_NOT_UNIQUE.equals(userService.checkLoginNameUnique(user.getLoginName())))
{
return error("保存用户'" + user.getLoginName() + "'失败,登录账号已存在");
return error("新增用户'" + user.getLoginName() + "'失败,登录账号已存在");
}
else if (UserConstants.USER_PHONE_NOT_UNIQUE.equals(userService.checkPhoneUnique(user)))
{
return error("新增用户'" + user.getLoginName() + "'失败,手机号码已存在");
}
else if (UserConstants.USER_EMAIL_NOT_UNIQUE.equals(userService.checkEmailUnique(user)))
{
return error("新增用户'" + user.getLoginName() + "'失败,邮箱账号已存在");
}
user.setSalt(ShiroUtils.randomSalt());
user.setPassword(passwordService.encryptPassword(user.getLoginName(), user.getPassword(), user.getSalt()));
@@ -152,12 +157,20 @@ public class SysUserController extends BaseController
@Log(title = "用户管理", businessType = BusinessType.UPDATE)
@PostMapping("/edit")
@ResponseBody
public AjaxResult editSave(SysUser user)
public AjaxResult editSave(@Validated SysUser user)
{
if (StringUtils.isNotNull(user.getUserId()) && SysUser.isAdmin(user.getUserId()))
{
return error("不允许修改超级管理员用户");
}
else if (UserConstants.USER_PHONE_NOT_UNIQUE.equals(userService.checkPhoneUnique(user)))
{
return error("修改用户'" + user.getLoginName() + "'失败,手机号码已存在");
}
else if (UserConstants.USER_EMAIL_NOT_UNIQUE.equals(userService.checkEmailUnique(user)))
{
return error("修改用户'" + user.getLoginName() + "'失败,邮箱账号已存在");
}
user.setUpdateBy(ShiroUtils.getLoginName());
return toAjax(userService.updateUser(user));
}
@@ -179,7 +192,15 @@ public class SysUserController extends BaseController
{
user.setSalt(ShiroUtils.randomSalt());
user.setPassword(passwordService.encryptPassword(user.getLoginName(), user.getPassword(), user.getSalt()));
return toAjax(userService.resetUserPwd(user));
if (userService.resetUserPwd(user) > 0)
{
if (ShiroUtils.getUserId() == user.getUserId())
{
ShiroUtils.setSysUser(userService.selectUserById(user.getUserId()));
}
return success();
}
return error();
}
@RequiresPermissions("system:user:remove")
@@ -41,7 +41,10 @@ spring:
enabled: true
# 设置白名单,不填则允许所有访问
allow:
url-pattern: /monitor/druid/*
url-pattern: /druid/*
# 控制台管理用户名和密码
login-username:
login-password:
filter:
stat:
enabled: true
@@ -3,13 +3,13 @@ ruoyi:
# 名称
name: RuoYi
# 版本
version: 3.4.0
version: 4.0.0
# 版权年份
copyrightYear: 2019
# 实例演示开关
demoEnabled: true
# 文件路径
profile: D:/profile/
# 文件路径 示例( Windows配置D:/ruoyi/uploadPathLinux配置 /home/ruoyi/uploadPath
profile: D:/ruoyi/uploadPath
# 获取ip地址开关
addressEnabled: true
@@ -115,6 +115,10 @@ shiro:
dbSyncPeriod: 1
# 相隔多久检查一次session的有效性,默认就是10分钟
validationInterval: 10
# 同一个用户最大会话数,比如2的意思是同一个账号允许最多同时两个人登录(默认-1不限制)
maxSession: -1
# 踢出之前登录的/之后登录的用户,默认踢出之前登录的用户
kickoutAfter: false
# 防止XSS攻击
xss:
@@ -22,6 +22,17 @@
overflowToDisk="false"
statistics="true">
</cache>
<!-- 系统活跃用户缓存 -->
<cache name="sys-userCache"
maxEntriesLocalHeap="10000"
overflowToDisk="false"
eternal="false"
diskPersistent="false"
timeToLiveSeconds="0"
timeToIdleSeconds="0"
statistics="true">
</cache>
</ehcache>
@@ -102,7 +102,7 @@
font-size: 13px;
font-variant: small-caps;
color: #999;
background: transparent url(../img/loading.gif) top left no-repeat;
background: transparent url(loading.gif) top left no-repeat;
}
.file-object {
@@ -397,7 +397,7 @@
}
.file-thumb-loading {
background: transparent url(../img/loading.gif) no-repeat scroll center center content-box !important;
background: transparent url(loading.gif) no-repeat scroll center center content-box !important;
}
.file-drop-zone {
@@ -434,7 +434,7 @@
}
.file-uploading {
background: url(../img/loading-sm.gif) no-repeat center bottom 10px;
background: url(loading-sm.gif) no-repeat center bottom 10px;
opacity: 0.65;
}
@@ -527,7 +527,7 @@
}
.file-loading[dir=rtl]:before {
background: transparent url(../img/loading.gif) top right no-repeat;
background: transparent url(loading.gif) top right no-repeat;
padding-left: 0;
padding-right: 20px;
}
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

File diff suppressed because one or more lines are too long
@@ -1,6 +1,6 @@
/**
* 基于bootstrap-table-fixed-columns修改
* 支持左右列冻结
* 支持左右列冻结、支持固定高度
* Copyright (c) 2019 ruoyi
*/
(function ($) {
@@ -22,17 +22,25 @@
this.timeoutHeaderColumns_ = 0;
this.timeoutBodyColumns_ = 0;
if (this.options.fixedColumns) {
this.$fixedBody = $([
this.$fixedHeader = $([
'<div class="left-fixed-table-columns">',
'<table>',
'<thead></thead>',
'</table>',
'</div>'].join(''));
this.$fixedHeader.find('table').attr('class', this.$el.attr('class'));
this.$fixedHeaderColumns = this.$fixedHeader.find('thead');
this.$tableHeader.before(this.$fixedHeader);
this.$fixedBody = $([
'<div class="left-fixed-body-columns">',
'<table>',
'<tbody></tbody>',
'</table>',
'</div>'].join(''));
this.$fixedBody.find('table').attr('class', this.$el.attr('class'));
this.$fixedHeaderColumns = this.$fixedBody.find('thead');
this.$fixedBodyColumns = this.$fixedBody.find('tbody');
this.$tableBody.before(this.$fixedBody);
}
@@ -86,7 +94,8 @@
this.$selectAll = $ltr.find('[name="btSelectAll"]');
this.$selectAll.on('click', function () {
var checked = $(this).prop('checked');
$(".left-fixed-table-columns input[name=btSelectItem]").filter(':enabled').prop('checked', checked);
$(".left-fixed-body-columns input[name=btSelectItem]").filter(':enabled').prop('checked', checked);
$('.fixed-table-body input[name=btSelectItem]').closest('tr').removeClass('selected');
});
}
};
@@ -167,12 +176,11 @@
if (that.options.detailView && !that.options.cardView) {
index = i - 1;
}
that.$fixedBody.find('thead th[data-field="' + visibleFields[index] + '"]')
.find('.fht-cell').width($this.innerWidth() - 1);
that.$fixedHeader.find('thead th[data-field="' + visibleFields[index] + '"]')
.find('.fht-cell').width($this.innerWidth());
headerWidth += $this.outerWidth();
});
this.$fixedBody.width(headerWidth - 1).show();
this.$fixedHeader.width(headerWidth + 2).show();
}
if (that.options.rightFixedColumns) {
this.$body.find('tr:first-child:not(.no-records-found) > *').each(function (i) {
@@ -197,27 +205,43 @@
BootstrapTable.prototype.fitBodyColumns = function () {
var that = this,
top = -(parseInt(this.$el.css('margin-top')) - 2),
height = this.$tableBody.height() - 2;
top = -(parseInt(this.$el.css('margin-top'))),
height = this.$tableBody.height();
if (that.options.fixedColumns) {
if (!this.$body.find('> tr[data-index]').length) {
this.$fixedBody.hide();
return;
}
if (!this.options.height) {
top = this.$fixedHeader.height()- 1;
height = height - top;
}
this.$fixedBody.css({
width: this.$fixedHeader.width(),
height: height,
top: top + 1
}).show();
this.$body.find('> tr').each(function (i) {
that.$fixedBody.find('tbody tr:eq(' + i + ')').height($(this).height());
that.$fixedBody.find('tr:eq(' + i + ')').height($(this).height() - 0.5);
var thattds = this;
that.$fixedBody.find('tr:eq(' + i + ')').find('td').each(function (j) {
$(this).width($($(thattds).find('td')[j]).width() + 1);
});
});
$("#" + $.table._option.id).on("check.bs.table uncheck.bs.table", function (e, rows, $element) {
$.btTable.on("check.bs.table uncheck.bs.table", function (e, rows, $element) {
var index= $element.data('index');
$(this).find('.bs-checkbox').find('input[data-index="' + index + '"]').prop("checked", true);
var selectFixedItem = $('.left-fixed-table-columns input[name=btSelectItem]');
var selectFixedItem = $('.left-fixed-body-columns input[name=btSelectItem]');
var checkAll = selectFixedItem.filter(':enabled').length &&
selectFixedItem.filter(':enabled').length ===
selectFixedItem.filter(':enabled').filter(':checked').length;
$(".left-fixed-table-columns input[name=btSelectAll]").prop('checked', checkAll);
$('.fixed-table-body input[name=btSelectItem]').closest('tr').removeClass('selected');
});
//// events
@@ -0,0 +1,117 @@
/**
* @author: Dennis Hernández
* 实现表格拖拽功能
* @version: v1.0.1
*/
(function ($) {
'use strict';
var isSearch = false;
var rowAttr = function (row, index) {
return {
id: 'customId_' + index
};
};
$.extend($.fn.bootstrapTable.defaults, {
reorderableRows: false,
onDragStyle: null,
onDropStyle: null,
onDragClass: "reorder_rows_onDragClass",
dragHandle: null,
useRowAttrFunc: false,
onReorderRowsDrag: function (table, row) {
return false;
},
onReorderRowsDrop: function (table, row) {
return false;
},
onReorderRow: function (newData) {
return false;
}
});
$.extend($.fn.bootstrapTable.Constructor.EVENTS, {
'reorder-row.bs.table': 'onReorderRow'
});
var BootstrapTable = $.fn.bootstrapTable.Constructor,
_init = BootstrapTable.prototype.init,
_initSearch = BootstrapTable.prototype.initSearch;
BootstrapTable.prototype.init = function () {
if (!this.options.reorderableRows) {
_init.apply(this, Array.prototype.slice.apply(arguments));
return;
}
var that = this;
if (this.options.useRowAttrFunc) {
this.options.rowAttributes = rowAttr;
}
var onPostBody = this.options.onPostBody;
this.options.onPostBody = function () {
setTimeout(function () {
that.makeRowsReorderable();
onPostBody.apply();
}, 1);
};
_init.apply(this, Array.prototype.slice.apply(arguments));
};
BootstrapTable.prototype.initSearch = function () {
_initSearch.apply(this, Array.prototype.slice.apply(arguments));
if (!this.options.reorderableRows) {
return;
}
//Known issue after search if you reorder the rows the data is not display properly
//isSearch = true;
};
BootstrapTable.prototype.makeRowsReorderable = function () {
if (this.options.cardView) {
return;
}
var that = this;
this.$el.tableDnD({
onDragStyle: that.options.onDragStyle,
onDropStyle: that.options.onDropStyle,
onDragClass: that.options.onDragClass,
onDrop: that.onDrop,
onDragStart: that.options.onReorderRowsDrag,
dragHandle: that.options.dragHandle
});
};
BootstrapTable.prototype.onDrop = function (table, droppedRow) {
var tableBs = $(table),
tableBsData = tableBs.data('bootstrap.table'),
tableBsOptions = tableBs.data('bootstrap.table').options,
row = null,
newData = [];
for (var i = 0; i < table.tBodies[0].rows.length; i++) {
row = $(table.tBodies[0].rows[i]);
newData.push(tableBsOptions.data[row.data('index')]);
row.data('index', i).attr('data-index', i);
}
tableBsOptions.data = tableBsOptions.data.slice(0, tableBsData.pageFrom - 1)
.concat(newData)
.concat(tableBsOptions.data.slice(tableBsData.pageTo));
//Call the user defined function
tableBsOptions.onReorderRowsDrop.apply(table, [table, droppedRow]);
//Call the event reorder-row
tableBsData.trigger('reorder-row', newData);
};
})(jQuery);
@@ -0,0 +1,598 @@
/**
* 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() {
// The cell is bound to "this"
$(this).bind(startEvent, function(e) {
$.tableDnD.initialiseDrag($(this).parents('tr')[0], table, this, e, config);
return false;
});
})
// 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);
@@ -70,6 +70,12 @@
var $rightToolbar = $('<div class="btn-group tool-right">');
$toolbar.append($rightToolbar);
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) {
var $refreshBtn = $('<button class="btn btn-default btn-outline" type="button" aria-label="refresh" title="刷新"><i class="glyphicon glyphicon-repeat"></i></button>');
@@ -159,6 +165,7 @@
data: parms ? parms : options.ajaxParams,
dataType: "JSON",
success: function(data, textStatus, jqXHR) {
data = calculateObjectValue(options, options.responseHandler, [data], data);
renderTable(data);
},
error: function(xhr, textStatus) {
@@ -233,13 +240,13 @@
}
// 缓存并格式化数据
var formatData = function(data) {
var _root = options.rootIdValue ? options.rootIdValue : null
var _root = options.rootIdValue ? options.rootIdValue : null;
var firstCode = data[0][options.parentCode];
$.each(data, function(index, item) {
// 添加一个默认属性,用来判断当前节点有没有被显示
item.isShow = false;
// 这里兼容几种常见Root节点写法
// 默认的几种判断
var firstCode = (0 == index ? item[options.parentCode] : '-');
var _defaultRootFlag = item[options.parentCode] == '0' ||
item[options.parentCode] == 0 ||
item[options.parentCode] == null ||
@@ -335,13 +342,13 @@
}
// 增加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 {
if(options.showTitle){
// 只在字段没有formatter时才添加title属性
$td.attr("title",item[column.field]);
}
$td.text(item[column.field]);
$td.text(getItemField(item, column.field));
}
if (options.expandColumn == index) {
if (!isP) {
@@ -358,6 +365,12 @@
});
return $tr;
}
// 检索信息按钮点击事件
var registerSearchBtnClickEvent = function(btn) {
$(btn).off('click').on('click', function () {
$(".search-collapse").slideToggle();
});
}
// 注册刷新按钮点击事件
var registerRefreshBtnClickEvent = function(btn) {
$(btn).off('click').on('click', function () {
@@ -583,6 +596,46 @@
$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;
};
// 初始化
init();
return target;
@@ -671,10 +724,13 @@
toolbar: null, // 顶部工具条
height: 0, // 表格高度
showTitle: true, // 是否采用title属性显示字段内容(被formatter格式化的字段不会显示)
showSearch: true, // 是否显示检索信息
showColumns: true, // 是否显示内容列下拉框
showRefresh: true, // 是否显示刷新按钮
expanderExpandedClass: 'glyphicon glyphicon-chevron-down', // 展开的按钮的图标
expanderCollapsedClass: 'glyphicon glyphicon-chevron-right' // 缩起的按钮的图标
expanderCollapsedClass: 'glyphicon glyphicon-chevron-right', // 缩起的按钮的图标
responseHandler: function(res) {
return false;
}
};
})(jQuery);
@@ -0,0 +1,315 @@
/* The MIT License
Copyright (c) 2011 by Michael Zinsmaier and nergal.dev
Copyright (c) 2012 by Thomas Ritou
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
/*
____________________________________________________
what it is:
____________________________________________________
curvedLines is a plugin for flot, that tries to display lines in a smoother way.
The plugin is based on nergal.dev's work https://code.google.com/p/flot/issues/detail?id=226
and further extended with a mode that forces the min/max points of the curves to be on the
points. Both modes are achieved through adding of more data points
=> 1) with large data sets you may get trouble
=> 2) if you want to display the points too, you have to plot them as 2nd data series over the lines
&& 3) consecutive x data points are not allowed to have the same value
This is version 0.5 of curvedLines so it will probably not work in every case. However
the basic form of use descirbed next works (:
Feel free to further improve the code
____________________________________________________
how to use it:
____________________________________________________
var d1 = [[5,5],[7,3],[9,12]];
var options = { series: { curvedLines: { active: true }}};
$.plot($("#placeholder"), [{data = d1, lines: { show: true}, curvedLines: {apply: true}}], options);
_____________________________________________________
options:
_____________________________________________________
active: bool true => plugin can be used
apply: bool true => series will be drawn as curved line
fit: bool true => forces the max,mins of the curve to be on the datapoints
curvePointFactor int defines how many "virtual" points are used per "real" data point to
emulate the curvedLines (points total = real points * curvePointFactor)
fitPointDist: int defines the x axis distance of the additional two points that are used
to enforce the min max condition.
+ line options (since v0.5 curved lines use flots line implementation for drawing
=> line options like fill, show ... are supported out of the box)
*/
/*
* v0.1 initial commit
* v0.15 negative values should work now (outcommented a negative -> 0 hook hope it does no harm)
* v0.2 added fill option (thanks to monemihir) and multi axis support (thanks to soewono effendi)
* v0.3 improved saddle handling and added basic handling of Dates
* v0.4 rewritten fill option (thomas ritou) mostly from original flot code (now fill between points rather than to graph bottom), corrected fill Opacity bug
* v0.5 rewritten instead of implementing a own draw function CurvedLines is now based on the processDatapoints flot hook (credits go to thomas ritou).
* This change breakes existing code however CurvedLines are now just many tiny straight lines to flot and therefore all flot lines options (like gradient fill,
* shadow) are now supported out of the box
* v0.6 flot 0.8 compatibility and some bug fixes
*/
(function($) {
var options = {
series : {
curvedLines : {
active : false,
apply: false,
fit : false,
curvePointFactor : 20,
fitPointDist : undefined
}
}
};
function init(plot) {
plot.hooks.processOptions.push(processOptions);
//if the plugin is active register processDatapoints method
function processOptions(plot, options) {
if (options.series.curvedLines.active) {
plot.hooks.processDatapoints.unshift(processDatapoints);
}
}
//only if the plugin is active
function processDatapoints(plot, series, datapoints) {
var nrPoints = datapoints.points.length / datapoints.pointsize;
var EPSILON = 0.5; //pretty large epsilon but save
if (series.curvedLines.apply == true && series.originSeries === undefined && nrPoints > (1 + EPSILON)) {
if (series.lines.fill) {
var pointsTop = calculateCurvePoints(datapoints, series.curvedLines, 1)
,pointsBottom = calculateCurvePoints(datapoints, series.curvedLines, 2); //flot makes sure for us that we've got a second y point if fill is true !
//Merge top and bottom curve
datapoints.pointsize = 3;
datapoints.points = [];
var j = 0;
var k = 0;
var i = 0;
var ps = 2;
while (i < pointsTop.length || j < pointsBottom.length) {
if (pointsTop[i] == pointsBottom[j]) {
datapoints.points[k] = pointsTop[i];
datapoints.points[k + 1] = pointsTop[i + 1];
datapoints.points[k + 2] = pointsBottom[j + 1];
j += ps;
i += ps;
} else if (pointsTop[i] < pointsBottom[j]) {
datapoints.points[k] = pointsTop[i];
datapoints.points[k + 1] = pointsTop[i + 1];
datapoints.points[k + 2] = k > 0 ? datapoints.points[k-1] : null;
i += ps;
} else {
datapoints.points[k] = pointsBottom[j];
datapoints.points[k + 1] = k > 1 ? datapoints.points[k-2] : null;
datapoints.points[k + 2] = pointsBottom[j + 1];
j += ps;
}
k += 3;
}
} else if (series.lines.lineWidth > 0) {
datapoints.points = calculateCurvePoints(datapoints, series.curvedLines, 1);
datapoints.pointsize = 2;
}
}
}
//no real idea whats going on here code mainly from https://code.google.com/p/flot/issues/detail?id=226
//if fit option is selected additional datapoints get inserted before the curve calculations in nergal.dev s code.
function calculateCurvePoints(datapoints, curvedLinesOptions, yPos) {
var points = datapoints.points, ps = datapoints.pointsize;
var num = curvedLinesOptions.curvePointFactor * (points.length / ps);
var xdata = new Array;
var ydata = new Array;
var curX = -1;
var curY = -1;
var j = 0;
if (curvedLinesOptions.fit) {
//insert a point before and after the "real" data point to force the line
//to have a max,min at the data point.
var fpDist;
if(typeof curvedLinesOptions.fitPointDist == 'undefined') {
//estimate it
var minX = points[0];
var maxX = points[points.length-ps];
fpDist = (maxX - minX) / (500 * 100); //x range / (estimated pixel length of placeholder * factor)
} else {
//use user defined value
fpDist = curvedLinesOptions.fitPointDist;
}
for (var i = 0; i < points.length; i += ps) {
var frontX;
var backX;
curX = i;
curY = i + yPos;
//add point X s
frontX = points[curX] - fpDist;
backX = points[curX] + fpDist;
var factor = 2;
while (frontX == points[curX] || backX == points[curX]) {
//inside the ulp
frontX = points[curX] - (fpDist * factor);
backX = points[curX] + (fpDist * factor);
factor++;
}
//add curve points
xdata[j] = frontX;
ydata[j] = points[curY];
j++;
xdata[j] = points[curX];
ydata[j] = points[curY];
j++;
xdata[j] = backX;
ydata[j] = points[curY];
j++;
}
} else {
//just use the datapoints
for (var i = 0; i < points.length; i += ps) {
curX = i;
curY = i + yPos;
xdata[j] = points[curX];
ydata[j] = points[curY];
j++;
}
}
var n = xdata.length;
var y2 = new Array();
var delta = new Array();
y2[0] = 0;
y2[n - 1] = 0;
delta[0] = 0;
for (var i = 1; i < n - 1; ++i) {
var d = (xdata[i + 1] - xdata[i - 1]);
if (d == 0) {
//point before current point and after current point need some space in between
return [];
}
var s = (xdata[i] - xdata[i - 1]) / d;
var p = s * y2[i - 1] + 2;
y2[i] = (s - 1) / p;
delta[i] = (ydata[i + 1] - ydata[i]) / (xdata[i + 1] - xdata[i]) - (ydata[i] - ydata[i - 1]) / (xdata[i] - xdata[i - 1]);
delta[i] = (6 * delta[i] / (xdata[i + 1] - xdata[i - 1]) - s * delta[i - 1]) / p;
}
for (var j = n - 2; j >= 0; --j) {
y2[j] = y2[j] * y2[j + 1] + delta[j];
}
// xmax - xmin / #points
var step = (xdata[n - 1] - xdata[0]) / (num - 1);
var xnew = new Array;
var ynew = new Array;
var result = new Array;
xnew[0] = xdata[0];
ynew[0] = ydata[0];
result.push(xnew[0]);
result.push(ynew[0]);
for ( j = 1; j < num; ++j) {
//new x point (sampling point for the created curve)
xnew[j] = xnew[0] + j * step;
var max = n - 1;
var min = 0;
while (max - min > 1) {
var k = Math.round((max + min) / 2);
if (xdata[k] > xnew[j]) {
max = k;
} else {
min = k;
}
}
//found point one to the left and one to the right of generated new point
var h = (xdata[max] - xdata[min]);
if (h == 0) {
//similar to above two points from original x data need some space between them
return [];
}
var a = (xdata[max] - xnew[j]) / h;
var b = (xnew[j] - xdata[min]) / h;
ynew[j] = a * ydata[min] + b * ydata[max] + ((a * a * a - a) * y2[min] + (b * b * b - b) * y2[max]) * (h * h) / 6;
result.push(xnew[j]);
result.push(ynew[j]);
}
return result;
}
}//end init
$.plot.plugins.push({
init : init,
options : options,
name : 'curvedLines',
version : '0.5'
});
})(jQuery);
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,750 @@
/*
Flot plugin for rendering pie charts. The plugin assumes the data is
coming is as a single data value for each series, and each of those
values is a positive value or zero (negative numbers don't make
any sense and will cause strange effects). The data values do
NOT need to be passed in as percentage values because it
internally calculates the total and percentages.
* Created by Brian Medendorp, June 2009
* Updated November 2009 with contributions from: btburnett3, Anthony Aragues and Xavi Ivars
* Changes:
2009-10-22: lineJoin set to round
2009-10-23: IE full circle fix, donut
2009-11-11: Added basic hover from btburnett3 - does not work in IE, and center is off in Chrome and Opera
2009-11-17: Added IE hover capability submitted by Anthony Aragues
2009-11-18: Added bug fix submitted by Xavi Ivars (issues with arrays when other JS libraries are included as well)
Available options are:
series: {
pie: {
show: true/false
radius: 0-1 for percentage of fullsize, or a specified pixel length, or 'auto'
innerRadius: 0-1 for percentage of fullsize or a specified pixel length, for creating a donut effect
startAngle: 0-2 factor of PI used for starting angle (in radians) i.e 3/2 starts at the top, 0 and 2 have the same result
tilt: 0-1 for percentage to tilt the pie, where 1 is no tilt, and 0 is completely flat (nothing will show)
offset: {
top: integer value to move the pie up or down
left: integer value to move the pie left or right, or 'auto'
},
stroke: {
color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#FFF')
width: integer pixel width of the stroke
},
label: {
show: true/false, or 'auto'
formatter: a user-defined function that modifies the text/style of the label text
radius: 0-1 for percentage of fullsize, or a specified pixel length
background: {
color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#000')
opacity: 0-1
},
threshold: 0-1 for the percentage value at which to hide labels (if they're too small)
},
combine: {
threshold: 0-1 for the percentage value at which to combine slices (if they're too small)
color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#CCC'), if null, the plugin will automatically use the color of the first slice to be combined
label: any text value of what the combined slice should be labeled
}
highlight: {
opacity: 0-1
}
}
}
More detail and specific examples can be found in the included HTML file.
*/
(function ($)
{
function init(plot) // this is the "body" of the plugin
{
var canvas = null;
var target = null;
var maxRadius = null;
var centerLeft = null;
var centerTop = null;
var total = 0;
var redraw = true;
var redrawAttempts = 10;
var shrink = 0.95;
var legendWidth = 0;
var processed = false;
var raw = false;
// interactive variables
var highlights = [];
// add hook to determine if pie plugin in enabled, and then perform necessary operations
plot.hooks.processOptions.push(checkPieEnabled);
plot.hooks.bindEvents.push(bindEvents);
// check to see if the pie plugin is enabled
function checkPieEnabled(plot, options)
{
if (options.series.pie.show)
{
//disable grid
options.grid.show = false;
// set labels.show
if (options.series.pie.label.show=='auto')
if (options.legend.show)
options.series.pie.label.show = false;
else
options.series.pie.label.show = true;
// set radius
if (options.series.pie.radius=='auto')
if (options.series.pie.label.show)
options.series.pie.radius = 3/4;
else
options.series.pie.radius = 1;
// ensure sane tilt
if (options.series.pie.tilt>1)
options.series.pie.tilt=1;
if (options.series.pie.tilt<0)
options.series.pie.tilt=0;
// add processData hook to do transformations on the data
plot.hooks.processDatapoints.push(processDatapoints);
plot.hooks.drawOverlay.push(drawOverlay);
// add draw hook
plot.hooks.draw.push(draw);
}
}
// bind hoverable events
function bindEvents(plot, eventHolder)
{
var options = plot.getOptions();
if (options.series.pie.show && options.grid.hoverable)
eventHolder.unbind('mousemove').mousemove(onMouseMove);
if (options.series.pie.show && options.grid.clickable)
eventHolder.unbind('click').click(onClick);
}
// debugging function that prints out an object
function alertObject(obj)
{
var msg = '';
function traverse(obj, depth)
{
if (!depth)
depth = 0;
for (var i = 0; i < obj.length; ++i)
{
for (var j=0; j<depth; j++)
msg += '\t';
if( typeof obj[i] == "object")
{ // its an object
msg += ''+i+':\n';
traverse(obj[i], depth+1);
}
else
{ // its a value
msg += ''+i+': '+obj[i]+'\n';
}
}
}
traverse(obj);
alert(msg);
}
function calcTotal(data)
{
for (var i = 0; i < data.length; ++i)
{
var item = parseFloat(data[i].data[0][1]);
if (item)
total += item;
}
}
function processDatapoints(plot, series, data, datapoints)
{
if (!processed)
{
processed = true;
canvas = plot.getCanvas();
target = $(canvas).parent();
options = plot.getOptions();
plot.setData(combine(plot.getData()));
}
}
function setupPie()
{
legendWidth = target.children().filter('.legend').children().width();
// calculate maximum radius and center point
maxRadius = Math.min(canvas.width,(canvas.height/options.series.pie.tilt))/2;
centerTop = (canvas.height/2)+options.series.pie.offset.top;
centerLeft = (canvas.width/2);
if (options.series.pie.offset.left=='auto')
if (options.legend.position.match('w'))
centerLeft += legendWidth/2;
else
centerLeft -= legendWidth/2;
else
centerLeft += options.series.pie.offset.left;
if (centerLeft<maxRadius)
centerLeft = maxRadius;
else if (centerLeft>canvas.width-maxRadius)
centerLeft = canvas.width-maxRadius;
}
function fixData(data)
{
for (var i = 0; i < data.length; ++i)
{
if (typeof(data[i].data)=='number')
data[i].data = [[1,data[i].data]];
else if (typeof(data[i].data)=='undefined' || typeof(data[i].data[0])=='undefined')
{
if (typeof(data[i].data)!='undefined' && typeof(data[i].data.label)!='undefined')
data[i].label = data[i].data.label; // fix weirdness coming from flot
data[i].data = [[1,0]];
}
}
return data;
}
function combine(data)
{
data = fixData(data);
calcTotal(data);
var combined = 0;
var numCombined = 0;
var color = options.series.pie.combine.color;
var newdata = [];
for (var i = 0; i < data.length; ++i)
{
// make sure its a number
data[i].data[0][1] = parseFloat(data[i].data[0][1]);
if (!data[i].data[0][1])
data[i].data[0][1] = 0;
if (data[i].data[0][1]/total<=options.series.pie.combine.threshold)
{
combined += data[i].data[0][1];
numCombined++;
if (!color)
color = data[i].color;
}
else
{
newdata.push({
data: [[1,data[i].data[0][1]]],
color: data[i].color,
label: data[i].label,
angle: (data[i].data[0][1]*(Math.PI*2))/total,
percent: (data[i].data[0][1]/total*100)
});
}
}
if (numCombined>0)
newdata.push({
data: [[1,combined]],
color: color,
label: options.series.pie.combine.label,
angle: (combined*(Math.PI*2))/total,
percent: (combined/total*100)
});
return newdata;
}
function draw(plot, newCtx)
{
if (!target) return; // if no series were passed
ctx = newCtx;
setupPie();
var slices = plot.getData();
var attempts = 0;
while (redraw && attempts<redrawAttempts)
{
redraw = false;
if (attempts>0)
maxRadius *= shrink;
attempts += 1;
clear();
if (options.series.pie.tilt<=0.8)
drawShadow();
drawPie();
}
if (attempts >= redrawAttempts) {
clear();
target.prepend('<div class="error">Could not draw pie with labels contained inside canvas</div>');
}
if ( plot.setSeries && plot.insertLegend )
{
plot.setSeries(slices);
plot.insertLegend();
}
// we're actually done at this point, just defining internal functions at this point
function clear()
{
ctx.clearRect(0,0,canvas.width,canvas.height);
target.children().filter('.pieLabel, .pieLabelBackground').remove();
}
function drawShadow()
{
var shadowLeft = 5;
var shadowTop = 15;
var edge = 10;
var alpha = 0.02;
// set radius
if (options.series.pie.radius>1)
var radius = options.series.pie.radius;
else
var radius = maxRadius * options.series.pie.radius;
if (radius>=(canvas.width/2)-shadowLeft || radius*options.series.pie.tilt>=(canvas.height/2)-shadowTop || radius<=edge)
return; // shadow would be outside canvas, so don't draw it
ctx.save();
ctx.translate(shadowLeft,shadowTop);
ctx.globalAlpha = alpha;
ctx.fillStyle = '#000';
// center and rotate to starting position
ctx.translate(centerLeft,centerTop);
ctx.scale(1, options.series.pie.tilt);
//radius -= edge;
for (var i=1; i<=edge; i++)
{
ctx.beginPath();
ctx.arc(0,0,radius,0,Math.PI*2,false);
ctx.fill();
radius -= i;
}
ctx.restore();
}
function drawPie()
{
startAngle = Math.PI*options.series.pie.startAngle;
// set radius
if (options.series.pie.radius>1)
var radius = options.series.pie.radius;
else
var radius = maxRadius * options.series.pie.radius;
// center and rotate to starting position
ctx.save();
ctx.translate(centerLeft,centerTop);
ctx.scale(1, options.series.pie.tilt);
//ctx.rotate(startAngle); // start at top; -- This doesn't work properly in Opera
// draw slices
ctx.save();
var currentAngle = startAngle;
for (var i = 0; i < slices.length; ++i)
{
slices[i].startAngle = currentAngle;
drawSlice(slices[i].angle, slices[i].color, true);
}
ctx.restore();
// draw slice outlines
ctx.save();
ctx.lineWidth = options.series.pie.stroke.width;
currentAngle = startAngle;
for (var i = 0; i < slices.length; ++i)
drawSlice(slices[i].angle, options.series.pie.stroke.color, false);
ctx.restore();
// draw donut hole
drawDonutHole(ctx);
// draw labels
if (options.series.pie.label.show)
drawLabels();
// restore to original state
ctx.restore();
function drawSlice(angle, color, fill)
{
if (angle<=0)
return;
if (fill)
ctx.fillStyle = color;
else
{
ctx.strokeStyle = color;
ctx.lineJoin = 'round';
}
ctx.beginPath();
if (Math.abs(angle - Math.PI*2) > 0.000000001)
ctx.moveTo(0,0); // Center of the pie
else if ($.browser.msie)
angle -= 0.0001;
//ctx.arc(0,0,radius,0,angle,false); // This doesn't work properly in Opera
ctx.arc(0,0,radius,currentAngle,currentAngle+angle,false);
ctx.closePath();
//ctx.rotate(angle); // This doesn't work properly in Opera
currentAngle += angle;
if (fill)
ctx.fill();
else
ctx.stroke();
}
function drawLabels()
{
var currentAngle = startAngle;
// set radius
if (options.series.pie.label.radius>1)
var radius = options.series.pie.label.radius;
else
var radius = maxRadius * options.series.pie.label.radius;
for (var i = 0; i < slices.length; ++i)
{
if (slices[i].percent >= options.series.pie.label.threshold*100)
drawLabel(slices[i], currentAngle, i);
currentAngle += slices[i].angle;
}
function drawLabel(slice, startAngle, index)
{
if (slice.data[0][1]==0)
return;
// format label text
var lf = options.legend.labelFormatter, text, plf = options.series.pie.label.formatter;
if (lf)
text = lf(slice.label, slice);
else
text = slice.label;
if (plf)
text = plf(text, slice);
var halfAngle = ((startAngle+slice.angle) + startAngle)/2;
var x = centerLeft + Math.round(Math.cos(halfAngle) * radius);
var y = centerTop + Math.round(Math.sin(halfAngle) * radius) * options.series.pie.tilt;
var html = '<span class="pieLabel" id="pieLabel'+index+'" style="position:absolute;top:' + y + 'px;left:' + x + 'px;">' + text + "</span>";
target.append(html);
var label = target.children('#pieLabel'+index);
var labelTop = (y - label.height()/2);
var labelLeft = (x - label.width()/2);
label.css('top', labelTop);
label.css('left', labelLeft);
// check to make sure that the label is not outside the canvas
if (0-labelTop>0 || 0-labelLeft>0 || canvas.height-(labelTop+label.height())<0 || canvas.width-(labelLeft+label.width())<0)
redraw = true;
if (options.series.pie.label.background.opacity != 0) {
// put in the transparent background separately to avoid blended labels and label boxes
var c = options.series.pie.label.background.color;
if (c == null) {
c = slice.color;
}
var pos = 'top:'+labelTop+'px;left:'+labelLeft+'px;';
$('<div class="pieLabelBackground" style="position:absolute;width:' + label.width() + 'px;height:' + label.height() + 'px;' + pos +'background-color:' + c + ';"> </div>').insertBefore(label).css('opacity', options.series.pie.label.background.opacity);
}
} // end individual label function
} // end drawLabels function
} // end drawPie function
} // end draw function
// Placed here because it needs to be accessed from multiple locations
function drawDonutHole(layer)
{
// draw donut hole
if(options.series.pie.innerRadius > 0)
{
// subtract the center
layer.save();
innerRadius = options.series.pie.innerRadius > 1 ? options.series.pie.innerRadius : maxRadius * options.series.pie.innerRadius;
layer.globalCompositeOperation = 'destination-out'; // this does not work with excanvas, but it will fall back to using the stroke color
layer.beginPath();
layer.fillStyle = options.series.pie.stroke.color;
layer.arc(0,0,innerRadius,0,Math.PI*2,false);
layer.fill();
layer.closePath();
layer.restore();
// add inner stroke
layer.save();
layer.beginPath();
layer.strokeStyle = options.series.pie.stroke.color;
layer.arc(0,0,innerRadius,0,Math.PI*2,false);
layer.stroke();
layer.closePath();
layer.restore();
// TODO: add extra shadow inside hole (with a mask) if the pie is tilted.
}
}
//-- Additional Interactive related functions --
function isPointInPoly(poly, pt)
{
for(var c = false, i = -1, l = poly.length, j = l - 1; ++i < l; j = i)
((poly[i][1] <= pt[1] && pt[1] < poly[j][1]) || (poly[j][1] <= pt[1] && pt[1]< poly[i][1]))
&& (pt[0] < (poly[j][0] - poly[i][0]) * (pt[1] - poly[i][1]) / (poly[j][1] - poly[i][1]) + poly[i][0])
&& (c = !c);
return c;
}
function findNearbySlice(mouseX, mouseY)
{
var slices = plot.getData(),
options = plot.getOptions(),
radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;
for (var i = 0; i < slices.length; ++i)
{
var s = slices[i];
if(s.pie.show)
{
ctx.save();
ctx.beginPath();
ctx.moveTo(0,0); // Center of the pie
//ctx.scale(1, options.series.pie.tilt); // this actually seems to break everything when here.
ctx.arc(0,0,radius,s.startAngle,s.startAngle+s.angle,false);
ctx.closePath();
x = mouseX-centerLeft;
y = mouseY-centerTop;
if(ctx.isPointInPath)
{
if (ctx.isPointInPath(mouseX-centerLeft, mouseY-centerTop))
{
//alert('found slice!');
ctx.restore();
return {datapoint: [s.percent, s.data], dataIndex: 0, series: s, seriesIndex: i};
}
}
else
{
// excanvas for IE doesn;t support isPointInPath, this is a workaround.
p1X = (radius * Math.cos(s.startAngle));
p1Y = (radius * Math.sin(s.startAngle));
p2X = (radius * Math.cos(s.startAngle+(s.angle/4)));
p2Y = (radius * Math.sin(s.startAngle+(s.angle/4)));
p3X = (radius * Math.cos(s.startAngle+(s.angle/2)));
p3Y = (radius * Math.sin(s.startAngle+(s.angle/2)));
p4X = (radius * Math.cos(s.startAngle+(s.angle/1.5)));
p4Y = (radius * Math.sin(s.startAngle+(s.angle/1.5)));
p5X = (radius * Math.cos(s.startAngle+s.angle));
p5Y = (radius * Math.sin(s.startAngle+s.angle));
arrPoly = [[0,0],[p1X,p1Y],[p2X,p2Y],[p3X,p3Y],[p4X,p4Y],[p5X,p5Y]];
arrPoint = [x,y];
// TODO: perhaps do some mathmatical trickery here with the Y-coordinate to compensate for pie tilt?
if(isPointInPoly(arrPoly, arrPoint))
{
ctx.restore();
return {datapoint: [s.percent, s.data], dataIndex: 0, series: s, seriesIndex: i};
}
}
ctx.restore();
}
}
return null;
}
function onMouseMove(e)
{
triggerClickHoverEvent('plothover', e);
}
function onClick(e)
{
triggerClickHoverEvent('plotclick', e);
}
// trigger click or hover event (they send the same parameters so we share their code)
function triggerClickHoverEvent(eventname, e)
{
var offset = plot.offset(),
canvasX = parseInt(e.pageX - offset.left),
canvasY = parseInt(e.pageY - offset.top),
item = findNearbySlice(canvasX, canvasY);
if (options.grid.autoHighlight)
{
// clear auto-highlights
for (var i = 0; i < highlights.length; ++i)
{
var h = highlights[i];
if (h.auto == eventname && !(item && h.series == item.series))
unhighlight(h.series);
}
}
// highlight the slice
if (item)
highlight(item.series, eventname);
// trigger any hover bind events
var pos = { pageX: e.pageX, pageY: e.pageY };
target.trigger(eventname, [ pos, item ]);
}
function highlight(s, auto)
{
if (typeof s == "number")
s = series[s];
var i = indexOfHighlight(s);
if (i == -1)
{
highlights.push({ series: s, auto: auto });
plot.triggerRedrawOverlay();
}
else if (!auto)
highlights[i].auto = false;
}
function unhighlight(s)
{
if (s == null)
{
highlights = [];
plot.triggerRedrawOverlay();
}
if (typeof s == "number")
s = series[s];
var i = indexOfHighlight(s);
if (i != -1)
{
highlights.splice(i, 1);
plot.triggerRedrawOverlay();
}
}
function indexOfHighlight(s)
{
for (var i = 0; i < highlights.length; ++i)
{
var h = highlights[i];
if (h.series == s)
return i;
}
return -1;
}
function drawOverlay(plot, octx)
{
//alert(options.series.pie.radius);
var options = plot.getOptions();
//alert(options.series.pie.radius);
var radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;
octx.save();
octx.translate(centerLeft, centerTop);
octx.scale(1, options.series.pie.tilt);
for (i = 0; i < highlights.length; ++i)
drawHighlight(highlights[i].series);
drawDonutHole(octx);
octx.restore();
function drawHighlight(series)
{
if (series.angle < 0) return;
//octx.fillStyle = parseColor(options.series.pie.highlight.color).scale(null, null, null, options.series.pie.highlight.opacity).toString();
octx.fillStyle = "rgba(255, 255, 255, "+options.series.pie.highlight.opacity+")"; // this is temporary until we have access to parseColor
octx.beginPath();
if (Math.abs(series.angle - Math.PI*2) > 0.000000001)
octx.moveTo(0,0); // Center of the pie
octx.arc(0,0,radius,series.startAngle,series.startAngle+series.angle,false);
octx.closePath();
octx.fill();
}
}
} // end init (plugin body)
// define pie specific options and their default values
var options = {
series: {
pie: {
show: false,
radius: 'auto', // actual radius of the visible pie (based on full calculated radius if <=1, or hard pixel value)
innerRadius:0, /* for donut */
startAngle: 3/2,
tilt: 1,
offset: {
top: 0,
left: 'auto'
},
stroke: {
color: '#FFF',
width: 1
},
label: {
show: 'auto',
formatter: function(label, slice){
return '<div style="font-size:x-small;text-align:center;padding:2px;color:'+slice.color+';">'+label+'<br/>'+Math.round(slice.percent)+'%</div>';
}, // formatter function
radius: 1, // radius at which to place the labels (based on full calculated radius if <=1, or hard pixel value)
background: {
color: null,
opacity: 0
},
threshold: 0 // percentage at which to hide the label (i.e. the slice is too narrow)
},
combine: {
threshold: -1, // percentage at which to combine little slices into one larger slice
color: null, // color to give the new slice (auto-generated if null)
label: 'Other' // label to give the new slice
},
highlight: {
//color: '#FFF', // will add this functionality once parseColor is available
opacity: 0.5
}
}
}
};
$.plot.plugins.push({
init: init,
options: options,
name: "pie",
version: "1.0"
});
})(jQuery);
@@ -0,0 +1,60 @@
/* Flot plugin for automatically redrawing plots as the placeholder resizes.
Copyright (c) 2007-2013 IOLA and Ole Laursen.
Licensed under the MIT license.
It works by listening for changes on the placeholder div (through the jQuery
resize event plugin) - if the size changes, it will redraw the plot.
There are no options. If you need to disable the plugin for some plots, you
can just fix the size of their placeholders.
*/
/* Inline dependency:
* jQuery resize event - v1.1 - 3/14/2010
* http://benalman.com/projects/jquery-resize-plugin/
*
* Copyright (c) 2010 "Cowboy" Ben Alman
* Dual licensed under the MIT and GPL licenses.
* http://benalman.com/about/license/
*/
(function($,h,c){var a=$([]),e=$.resize=$.extend($.resize,{}),i,k="setTimeout",j="resize",d=j+"-special-event",b="delay",f="throttleWindow";e[b]=250;e[f]=true;$.event.special[j]={setup:function(){if(!e[f]&&this[k]){return false}var l=$(this);a=a.add(l);$.data(this,d,{w:l.width(),h:l.height()});if(a.length===1){g()}},teardown:function(){if(!e[f]&&this[k]){return false}var l=$(this);a=a.not(l);l.removeData(d);if(!a.length){clearTimeout(i)}},add:function(l){if(!e[f]&&this[k]){return false}var n;function m(s,o,p){var q=$(this),r=$.data(this,d);r.w=o!==c?o:q.width();r.h=p!==c?p:q.height();n.apply(this,arguments)}if($.isFunction(l)){n=l;return m}else{n=l.handler;l.handler=m}}};function g(){i=h[k](function(){a.each(function(){var n=$(this),m=n.width(),l=n.height(),o=$.data(this,d);if(m!==o.w||l!==o.h){n.trigger(j,[o.w=m,o.h=l])}});g()},e[b])}})(jQuery,this);
(function ($) {
var options = { }; // no options
function init(plot) {
function onResize() {
var placeholder = plot.getPlaceholder();
// somebody might have hidden us and we can't plot
// when we don't have the dimensions
if (placeholder.width() == 0 || placeholder.height() == 0)
return;
plot.resize();
plot.setupGrid();
plot.draw();
}
function bindEvents(plot, eventHolder) {
plot.getPlaceholder().resize(onResize);
}
function shutdown(plot, eventHolder) {
plot.getPlaceholder().unbind("resize", onResize);
}
plot.hooks.bindEvents.push(bindEvents);
plot.hooks.shutdown.push(shutdown);
}
$.plot.plugins.push({
init: init,
options: options,
name: 'resize',
version: '1.0'
});
})(jQuery);
@@ -0,0 +1,212 @@
/**
* Flot plugin that provides spline interpolation for line graphs
* author: Alex Bardas < alex.bardas@gmail.com >
* modified by: Avi Kohn https://github.com/AMKohn
* based on the spline interpolation described at:
* http://scaledinnovation.com/analytics/splines/aboutSplines.html
*
* Example usage: (add in plot options series object)
* for linespline:
* series: {
* ...
* lines: {
* show: false
* },
* splines: {
* show: true,
* tension: x, (float between 0 and 1, defaults to 0.5),
* lineWidth: y (number, defaults to 2),
* fill: z (float between 0 .. 1 or false, as in flot documentation)
* },
* ...
* }
* areaspline:
* series: {
* ...
* lines: {
* show: true,
* lineWidth: 0, (line drawing will not execute)
* fill: x, (float between 0 .. 1, as in flot documentation)
* ...
* },
* splines: {
* show: true,
* tension: 0.5 (float between 0 and 1)
* },
* ...
* }
*
*/
(function($) {
'use strict'
/**
* @param {Number} x0, y0, x1, y1: coordinates of the end (knot) points of the segment
* @param {Number} x2, y2: the next knot (not connected, but needed to calculate p2)
* @param {Number} tension: control how far the control points spread
* @return {Array}: p1 -> control point, from x1 back toward x0
* p2 -> the next control point, returned to become the next segment's p1
*
* @api private
*/
function getControlPoints(x0, y0, x1, y1, x2, y2, tension) {
var pow = Math.pow,
sqrt = Math.sqrt,
d01, d12, fa, fb, p1x, p1y, p2x, p2y;
// Scaling factors: distances from this knot to the previous and following knots.
d01 = sqrt(pow(x1 - x0, 2) + pow(y1 - y0, 2));
d12 = sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2));
fa = tension * d01 / (d01 + d12);
fb = tension - fa;
p1x = x1 + fa * (x0 - x2);
p1y = y1 + fa * (y0 - y2);
p2x = x1 - fb * (x0 - x2);
p2y = y1 - fb * (y0 - y2);
return [p1x, p1y, p2x, p2y];
}
var line = [];
function drawLine(points, ctx, height, fill, seriesColor) {
var c = $.color.parse(seriesColor);
c.a = typeof fill == "number" ? fill : .3;
c.normalize();
c = c.toString();
ctx.beginPath();
ctx.moveTo(points[0][0], points[0][1]);
var plength = points.length;
for (var i = 0; i < plength; i++) {
ctx[points[i][3]].apply(ctx, points[i][2]);
}
ctx.stroke();
ctx.lineWidth = 0;
ctx.lineTo(points[plength - 1][0], height);
ctx.lineTo(points[0][0], height);
ctx.closePath();
if (fill !== false) {
ctx.fillStyle = c;
ctx.fill();
}
}
/**
* @param {Object} ctx: canvas context
* @param {String} type: accepted strings: 'bezier' or 'quadratic' (defaults to quadratic)
* @param {Array} points: 2 points for which to draw the interpolation
* @param {Array} cpoints: control points for those segment points
*
* @api private
*/
function queue(ctx, type, points, cpoints) {
if (type === void 0 || (type !== 'bezier' && type !== 'quadratic')) {
type = 'quadratic';
}
type = type + 'CurveTo';
if (line.length == 0) line.push([points[0], points[1], cpoints.concat(points.slice(2)), type]);
else if (type == "quadraticCurveTo" && points.length == 2) {
cpoints = cpoints.slice(0, 2).concat(points);
line.push([points[0], points[1], cpoints, type]);
}
else line.push([points[2], points[3], cpoints.concat(points.slice(2)), type]);
}
/**
* @param {Object} plot
* @param {Object} ctx: canvas context
* @param {Object} series
*
* @api private
*/
function drawSpline(plot, ctx, series) {
// Not interested if spline is not requested
if (series.splines.show !== true) {
return;
}
var cp = [],
// array of control points
tension = series.splines.tension || 0.5,
idx, x, y, points = series.datapoints.points,
ps = series.datapoints.pointsize,
plotOffset = plot.getPlotOffset(),
len = points.length,
pts = [];
line = [];
// Cannot display a linespline/areaspline if there are less than 3 points
if (len / ps < 4) {
$.extend(series.lines, series.splines);
return;
}
for (idx = 0; idx < len; idx += ps) {
x = points[idx];
y = points[idx + 1];
if (x == null || x < series.xaxis.min || x > series.xaxis.max || y < series.yaxis.min || y > series.yaxis.max) {
continue;
}
pts.push(series.xaxis.p2c(x) + plotOffset.left, series.yaxis.p2c(y) + plotOffset.top);
}
len = pts.length;
// Draw an open curve, not connected at the ends
for (idx = 0; idx < len - 2; idx += 2) {
cp = cp.concat(getControlPoints.apply(this, pts.slice(idx, idx + 6).concat([tension])));
}
ctx.save();
ctx.strokeStyle = series.color;
ctx.lineWidth = series.splines.lineWidth;
queue(ctx, 'quadratic', pts.slice(0, 4), cp.slice(0, 2));
for (idx = 2; idx < len - 3; idx += 2) {
queue(ctx, 'bezier', pts.slice(idx, idx + 4), cp.slice(2 * idx - 2, 2 * idx + 2));
}
queue(ctx, 'quadratic', pts.slice(len - 2, len), [cp[2 * len - 10], cp[2 * len - 9], pts[len - 4], pts[len - 3]]);
drawLine(line, ctx, plot.height() + 10, series.splines.fill, series.color);
ctx.restore();
}
$.plot.plugins.push({
init: function(plot) {
plot.hooks.drawSeries.push(drawSpline);
},
options: {
series: {
splines: {
show: false,
lineWidth: 2,
tension: 0.5,
fill: false
}
}
},
name: 'spline',
version: '0.8.2'
});
})(jQuery);
@@ -0,0 +1,71 @@
/* Flot plugin that adds some extra symbols for plotting points.
Copyright (c) 2007-2014 IOLA and Ole Laursen.
Licensed under the MIT license.
The symbols are accessed as strings through the standard symbol options:
series: {
points: {
symbol: "square" // or "diamond", "triangle", "cross"
}
}
*/
(function ($) {
function processRawData(plot, series, datapoints) {
// we normalize the area of each symbol so it is approximately the
// same as a circle of the given radius
var handlers = {
square: function (ctx, x, y, radius, shadow) {
// pi * r^2 = (2s)^2 => s = r * sqrt(pi)/2
var size = radius * Math.sqrt(Math.PI) / 2;
ctx.rect(x - size, y - size, size + size, size + size);
},
diamond: function (ctx, x, y, radius, shadow) {
// pi * r^2 = 2s^2 => s = r * sqrt(pi/2)
var size = radius * Math.sqrt(Math.PI / 2);
ctx.moveTo(x - size, y);
ctx.lineTo(x, y - size);
ctx.lineTo(x + size, y);
ctx.lineTo(x, y + size);
ctx.lineTo(x - size, y);
},
triangle: function (ctx, x, y, radius, shadow) {
// pi * r^2 = 1/2 * s^2 * sin (pi / 3) => s = r * sqrt(2 * pi / sin(pi / 3))
var size = radius * Math.sqrt(2 * Math.PI / Math.sin(Math.PI / 3));
var height = size * Math.sin(Math.PI / 3);
ctx.moveTo(x - size/2, y + height/2);
ctx.lineTo(x + size/2, y + height/2);
if (!shadow) {
ctx.lineTo(x, y - height/2);
ctx.lineTo(x - size/2, y + height/2);
}
},
cross: function (ctx, x, y, radius, shadow) {
// pi * r^2 = (2s)^2 => s = r * sqrt(pi)/2
var size = radius * Math.sqrt(Math.PI) / 2;
ctx.moveTo(x - size, y - size);
ctx.lineTo(x + size, y + size);
ctx.moveTo(x - size, y + size);
ctx.lineTo(x + size, y - size);
}
};
var s = series.points.symbol;
if (handlers[s])
series.points.symbol = handlers[s];
}
function init(plot) {
plot.hooks.processDatapoints.push(processRawData);
}
$.plot.plugins.push({
init: init,
name: 'symbols',
version: '1.0'
});
})(jQuery);
@@ -0,0 +1,12 @@
/*
* jquery.flot.tooltip
*
* description: easy-to-use tooltips for Flot charts
* version: 0.6.2
* author: Krzysztof Urbas @krzysu [myviews.pl]
* website: https://github.com/krzysu/flot.tooltip
*
* build on 2013-09-30
* released under MIT License, 2012
*/
(function(t){var o={tooltip:!1,tooltipOpts:{content:"%s | X: %x | Y: %y",xDateFormat:null,yDateFormat:null,shifts:{x:10,y:20},defaultTheme:!0,onHover:function(){}}},i=function(t){this.tipPosition={x:0,y:0},this.init(t)};i.prototype.init=function(o){function i(t){var o={};o.x=t.pageX,o.y=t.pageY,s.updateTooltipPosition(o)}function e(t,o,i){var e=s.getDomElement();if(i){var n;n=s.stringFormat(s.tooltipOptions.content,i),e.html(n),s.updateTooltipPosition({x:o.pageX,y:o.pageY}),e.css({left:s.tipPosition.x+s.tooltipOptions.shifts.x,top:s.tipPosition.y+s.tooltipOptions.shifts.y}).show(),"function"==typeof s.tooltipOptions.onHover&&s.tooltipOptions.onHover(i,e)}else e.hide().html("")}var s=this;o.hooks.bindEvents.push(function(o,n){s.plotOptions=o.getOptions(),s.plotOptions.tooltip!==!1&&void 0!==s.plotOptions.tooltip&&(s.tooltipOptions=s.plotOptions.tooltipOpts,s.getDomElement(),t(o.getPlaceholder()).bind("plothover",e),t(n).bind("mousemove",i))}),o.hooks.shutdown.push(function(o,s){t(o.getPlaceholder()).unbind("plothover",e),t(s).unbind("mousemove",i)})},i.prototype.getDomElement=function(){var o;return t("#flotTip").length>0?o=t("#flotTip"):(o=t("<div />").attr("id","flotTip"),o.appendTo("body").hide().css({position:"absolute"}),this.tooltipOptions.defaultTheme&&o.css({background:"#fff","z-index":"100",padding:"0.4em 0.6em","border-radius":"0.5em","font-size":"0.8em",border:"1px solid #111",display:"none","white-space":"nowrap"})),o},i.prototype.updateTooltipPosition=function(o){var i=t("#flotTip").outerWidth()+this.tooltipOptions.shifts.x,e=t("#flotTip").outerHeight()+this.tooltipOptions.shifts.y;o.x-t(window).scrollLeft()>t(window).innerWidth()-i&&(o.x-=i),o.y-t(window).scrollTop()>t(window).innerHeight()-e&&(o.y-=e),this.tipPosition.x=o.x,this.tipPosition.y=o.y},i.prototype.stringFormat=function(t,o){var i=/%p\.{0,1}(\d{0,})/,e=/%s/,s=/%x\.{0,1}(?:\d{0,})/,n=/%y\.{0,1}(?:\d{0,})/;return"function"==typeof t&&(t=t(o.series.label,o.series.data[o.dataIndex][0],o.series.data[o.dataIndex][1],o)),o.series.percent!==void 0&&(t=this.adjustValPrecision(i,t,o.series.percent)),o.series.label!==void 0&&(t=t.replace(e,o.series.label)),this.isTimeMode("xaxis",o)&&this.isXDateFormat(o)&&(t=t.replace(s,this.timestampToDate(o.series.data[o.dataIndex][0],this.tooltipOptions.xDateFormat))),this.isTimeMode("yaxis",o)&&this.isYDateFormat(o)&&(t=t.replace(n,this.timestampToDate(o.series.data[o.dataIndex][1],this.tooltipOptions.yDateFormat))),"number"==typeof o.series.data[o.dataIndex][0]&&(t=this.adjustValPrecision(s,t,o.series.data[o.dataIndex][0])),"number"==typeof o.series.data[o.dataIndex][1]&&(t=this.adjustValPrecision(n,t,o.series.data[o.dataIndex][1])),o.series.xaxis.tickFormatter!==void 0&&(t=t.replace(s,o.series.xaxis.tickFormatter(o.series.data[o.dataIndex][0],o.series.xaxis))),o.series.yaxis.tickFormatter!==void 0&&(t=t.replace(n,o.series.yaxis.tickFormatter(o.series.data[o.dataIndex][1],o.series.yaxis))),t},i.prototype.isTimeMode=function(t,o){return o.series[t].options.mode!==void 0&&"time"===o.series[t].options.mode},i.prototype.isXDateFormat=function(){return this.tooltipOptions.xDateFormat!==void 0&&null!==this.tooltipOptions.xDateFormat},i.prototype.isYDateFormat=function(){return this.tooltipOptions.yDateFormat!==void 0&&null!==this.tooltipOptions.yDateFormat},i.prototype.timestampToDate=function(o,i){var e=new Date(o);return t.plot.formatDate(e,i)},i.prototype.adjustValPrecision=function(t,o,i){var e,s=o.match(t);return null!==s&&""!==RegExp.$1&&(e=RegExp.$1,i=i.toFixed(e),o=o.replace(t,i)),o};var e=function(t){new i(t)};t.plot.plugins.push({init:e,options:o,name:"tooltip",version:"0.6.1"})})(jQuery);
File diff suppressed because one or more lines are too long
@@ -18,7 +18,7 @@ body .layer-ext-moon .layui-layer-title {
font-size: 14px;
height: 42px;
line-height: 42px;
border-bottom: 1px solid #eee;
border: none;
}
body .layer-ext-moon .layui-layer-content .layui-layer-ico {
File diff suppressed because one or more lines are too long
@@ -0,0 +1,13 @@
// Peity jQuery plugin version 2.0.3
// (c) 2014 Ben Pickles
//
// http://benpickles.github.io/peity
//
// Released under MIT license.
(function(e,q,h){var o=function(a,b){var c=q.createElementNS("http://www.w3.org/2000/svg",a);e.each(b,function(a,b){c.setAttribute(a,b)});return c},t="createElementNS"in q&&o("svg",{}).createSVGRect,r=1/(window.devicePixelRatio||1),j=e.fn.peity=function(a,b){t&&this.each(function(){var c=e(this),d=c.data("peity");if(d)a&&(d.type=a),e.extend(d.opts,b);else{var f=j.defaults[a],g={};e.each(c.data(),function(a,b){a in f&&(g[a]=b)});var h=e.extend({},f,g,b),d=new s(c,a,h);c.change(function(){d.draw()}).data("peity",
d)}d.draw()});return this},s=function(a,b,c){this.$el=a;this.type=b;this.opts=c},m=s.prototype;m.draw=function(){j.graphers[this.type].call(this,this.opts)};m.fill=function(){var a=this.opts.fill,b=a;e.isFunction(b)||(b=function(b,d){return a[d%a.length]});return b};m.prepare=function(a,b){var c;this.svg?c=e(this.svg).empty():(this.svg=o("svg",{"class":"peity"}),this.$el.hide().after(this.svg),c=e(this.svg).data("peity",this));this.svg.setAttribute("height",b);this.svg.setAttribute("width",a);return c};
m.values=function(){return e.map(this.$el.text().split(this.opts.delimiter),function(a){return parseFloat(a)})};j.defaults={};j.graphers={};j.register=function(a,b,c){this.defaults[a]=b;this.graphers[a]=c};j.register("pie",{delimiter:null,diameter:16,fill:["#ff9900","#fff4dd","#ffc66e"]},function(a){if(!a.delimiter){var b=this.$el.text().match(/[^0-9\.]/);a.delimiter=b?b[0]:","}b=this.values();if("/"==a.delimiter)var c=b[0],b=[c,h.max(0,b[1]-c)];for(var d=0,c=b.length,f=0;d<c;d++)f+=b[d];for(var a=
this.prepare(a.width||a.diameter,a.height||a.diameter),d=a.width(),g=a.height(),a=d/2,g=g/2,p=h.min(a,g),e=h.PI,j=this.fill(),i=-e/2,d=0;d<c;d++){var n=b[d],l=n/f,k;if(0!=l){if(1==l)k=o("circle",{cx:a,cy:g,r:p});else{k=2*l*e;var l=i+k,m=p*h.cos(i)+a,i=p*h.sin(i)+g,q=p*h.cos(l)+a,r=p*h.sin(l)+g;k=o("path",{d:["M",a,g,"L",m,i,"A",p,p,0,k>e?1:0,1,q,r,"Z"].join(" ")});i=l}k.setAttribute("fill",j.call(this,n,d,b));this.svg.appendChild(k)}}});j.register("line",{delimiter:",",fill:"#c6d9fd",height:16,max:null,
min:0,stroke:"#4d89f9",strokeWidth:1,width:32},function(a){var b=this.values();1==b.length&&b.push(b[0]);for(var c=h.max.apply(h,b.concat([a.max])),d=h.min.apply(h,b.concat([a.min])),f=this.prepare(a.width,a.height),g=f.width(),f=f.height()-a.strokeWidth,e=g/(b.length-1),c=c-d,j=0==c?f:f/c,m=f+d*j,c=[0,m],i=0;i<b.length;i++)c.push(i*e,f-j*(b[i]-d)+a.strokeWidth/2);c.push(g,m);b=o("polygon",{fill:a.fill,points:c.join(" ")});this.svg.appendChild(b);a.strokeWidth&&(a=o("polyline",{fill:"transparent",
points:c.slice(2,c.length-2).join(" "),stroke:a.stroke,"stroke-width":a.strokeWidth,"stroke-linecap":"square"}),this.svg.appendChild(a))});j.register("bar",{delimiter:",",fill:["#4D89F9"],gap:1,height:16,max:null,min:0,width:32},function(a){for(var b=this.values(),c=h.max.apply(h,b.concat([a.max])),d=h.min.apply(h,b.concat([a.min])),f=this.prepare(a.width,a.height),g=f.width(),f=f.height(),e=c-d,j=0==e?0:f/e,a=a.gap,g=(g+a)/b.length,m=this.fill(),i=0;i<b.length;i++){var n=b[i],l=f-j*(n-d),k=j*n;if(0==
k){if(k=r,0>=d&&0<c||0==e)l-=r}else 0>k&&(l+=k,k=-k);n=o("rect",{fill:m.call(this,n,i,b),x:i*g,y:l,width:g-a,height:k});this.svg.appendChild(n)}})})(jQuery,document,Math);
File diff suppressed because one or more lines are too long
@@ -7547,6 +7547,7 @@
toolbar: [
['style', ['style']],
['font', ['bold', 'underline', 'clear']],
['fontsize',['fontsize']],
['fontname', ['fontname']],
['color', ['color']],
['para', ['ul', 'ol', 'paragraph']],
File diff suppressed because one or more lines are too long
@@ -42,6 +42,12 @@ $(document).ready(function(){
var ip = /^(?:(?:2[0-4][0-9]\.)|(?:25[0-5]\.)|(?:1[0-9][0-9]\.)|(?:[1-9][0-9]\.)|(?:[0-9]\.)){3}(?:(?:2[0-4][0-9])|(?:25[0-5])|(?:1[0-9][0-9])|(?:[1-9][0-9])|(?:[0-9]))$/;
return this.optional(element) || (ip).test(value);
},"IP地址格式示例127.0.0.1");
jQuery.validator.addMethod("notEqual", function(value, element, param) {
return value != param;
}, $.validator.format("输入值不允许为{0}"));
jQuery.validator.addMethod("gt", function(value, element, param) {
return value > param;
}, $.validator.format("输入值必须大于{0}"));
//校验新旧密码是否相同
jQuery.validator.addMethod("isdiff",function(){
var p1=$("#pwdOld").val();
@@ -9,6 +9,12 @@
background-color: #3c8dbc
}
.skin-blue .navbar-default .nav>li.selected>a,
.skin-blue .navbar-default .nav>li.selected>a:focus {
background-color: #1890ff;
color: rgba(255,255,255,1);
}
.skin-blue .navbar .nav>li>a {
color: #fff
}
@@ -170,7 +176,7 @@
}
.skin-blue .content-tabs {
border-bottom: solid 2px #e7eaec;
border-bottom: 1px solid #e5e5e5;
}
.skin-blue.layout-top-nav>.logo {
@@ -188,8 +194,14 @@
background-color: #00a65a;
}
.skin-green .navbar-default .nav>li.selected>a,
.skin-green .navbar-default .nav>li.selected>a:focus {
background-color: #52c41a;
color: rgba(255,255,255,1);
}
.skin-green .content-tabs {
border-bottom: solid 2px #e7eaec;
border-bottom: 1px solid #e5e5e5;
}
.skin-green .navbar .nav>li>a {
@@ -347,6 +359,12 @@
background-color: #dd4b39
}
.skin-red .navbar-default .nav>li.selected>a,
.skin-red .navbar-default .nav>li.selected>a:focus {
background-color: #f5222d;
color: rgba(255,255,255,1);
}
.skin-red .navbar .nav>li>a {
color: #fff
}
@@ -436,7 +454,7 @@
}
.skin-red .content-tabs {
border-bottom: solid 2px #e7eaec;
border-bottom: 1px solid #e5e5e5;
}
.skin-red .nav>li>.treeview-menu {
@@ -506,6 +524,12 @@
background-color: #f39c12
}
.skin-yellow .navbar-default .nav>li.selected>a,
.skin-yellow .navbar-default .nav>li.selected>a:focus {
background-color: #faad14;
color: rgba(255,255,255,1);
}
.skin-yellow .navbar .nav>li>a {
color: #fff
}
@@ -595,8 +619,7 @@
}
.skin-yellow .content-tabs {
border-bottom: solid 2px #e7eaec;
border-bottom: 1px solid #e5e5e5;
}
.skin-yellow .nav>li>.treeview-menu {
@@ -666,6 +689,12 @@
background-color: #605ca8
}
.skin-purple .navbar-default .nav>li.selected>a,
.skin-purple .navbar-default .nav>li.selected>a:focus {
background-color: #722ed1;
color: rgba(255,255,255,1);
}
.skin-purple .navbar .nav>li>a {
color: #fff
}
@@ -755,8 +784,7 @@
}
.skin-purple .content-tabs {
border-bottom: solid 2px #e7eaec;
border-bottom: 1px solid #e5e5e5;
}
.skin-purple .nav>li>.treeview-menu {
@@ -820,3 +848,117 @@
border-bottom-right-radius: 2px;
border-bottom-left-radius: 0
}
/*
*
* 侧边栏主题 若依管理系统
* NAME - .theme-dark/theme-light
*
*/
/** 深色主题 .theme-dark **/
.theme-dark .user-panel>.info>p, .theme-dark .user-panel>.info, .theme-dark .user-panel>.info>a{
color: #fff
}
.theme-dark .nav>li.active {
background: #293846;
}
.theme-dark .navbar-static-side {
background-color: #2f4050;
}
.theme-dark .user-panel {
background-color: #2f4050;
}
.theme-dark .navbar-default .nav>li>a:hover,
.theme-dark .navbar-default .nav>li>a:focus {
background: #293846;
}
/** 浅色主题 theme-light **/
.theme-light .user-panel>.info>p, .theme-light .user-panel>.info, .theme-light .user-panel>.info>a{
color: #555
}
.theme-light .nav>li.active{
background: #f9fafc;
}
.theme-light .navbar-static-side {
background-color: #f9fafc;
box-shadow: 2px 0 2px 0 rgba(29,35,41,.05);
}
.theme-light .user-panel {
background-color: #f9fafc;
}
.theme-light .navbar-default .nav>li>a {
color: #777;
}
.theme-light.skin-blue .navbar-default .nav>li.active>a {
color: #1890ff;
}
.theme-light.skin-blue .navbar-default .nav>li.selected>a,
.theme-light.skin-blue .navbar-default .nav>li.selected>a:focus {
background-color: rgb(240, 245, 255);
color: rgb(47, 84, 235);
}
.theme-light.skin-green .navbar-default .nav>li.active>a {
color: #52c41a;
}
.theme-light.skin-green .navbar-default .nav>li.selected>a,
.theme-light.skin-green .navbar-default .nav>li.selected>a:focus {
background-color: rgb(246, 255, 237);
color: rgb(82, 196, 26);
}
.theme-light.skin-purple .navbar-default .nav>li.active>a {
color: rgb(114, 46, 209);
}
.theme-light.skin-purple .navbar-default .nav>li.selected>a,
.theme-light.skin-purple .navbar-default .nav>li.selected>a:focus {
background-color: #f9f0ff;
color: #722ed1;
}
.theme-light.skin-red .navbar-default .nav>li.active>a {
color: rgb(245, 34, 45);
}
.theme-light.skin-red .navbar-default .nav>li.selected>a,
.theme-light.skin-red .navbar-default .nav>li.selected>a:focus {
background-color: rgb(255, 241, 240);
color: rgb(245, 34, 45);
}
.theme-light.skin-yellow .navbar-default .nav>li.active>a {
color: rgb(250, 173, 20);
}
.theme-light.skin-yellow .navbar-default .nav>li.selected>a,
.theme-light.skin-yellow .navbar-default .nav>li.selected>a:focus {
background-color: #fffbe6;
color: #faad14;
}
.theme-light .navbar-default .nav>li>a:hover,
.theme-light .navbar-default .nav>li>a:focus {
background-color: rgb(240, 245, 255);
}
.fixed-sidebar.theme-light.mini-navbar .nav li:hover>a> span.nav-label {
background-color: #f9fafc;
}
.fixed-sidebar.theme-light.mini-navbar .nav li:hover>.nav-second-level {
background-color: #f9fafc;
}
@@ -3247,15 +3247,15 @@ body.body-small .footer.fixed {
/*CONTENTTABS*/
.content-tabs {
position: relative;
height: 42px;
height: 39px;
background: #fafafa;
line-height: 40px;
line-height: 38px;
}
.content-tabs .roll-nav, .page-tabs-list {
position: absolute;
width: 40px;
height: 40px;
width: 30px;
height: 38px;
text-align: center;
color: #999;
z-index: 2;
@@ -3285,9 +3285,9 @@ body.body-small .footer.fixed {
}
nav.page-tabs {
margin-left: 40px;
margin-left: 30px;
width: 100000px;
height: 40px;
height: 38px;
overflow: hidden;
}
@@ -3328,7 +3328,7 @@ nav.page-tabs .page-tabs-content {
.roll-right.tabReload {
background: #fff;
height: 40px;
height: 38px;
width: 60px;
outline: none;
}
@@ -3338,7 +3338,7 @@ nav.page-tabs .page-tabs-content {
}
#content-main {
height: calc(100% - 140px);
height: calc(100% - 127px);
overflow: hidden;
}
@@ -6858,42 +6858,6 @@ body.rtls .top-navigation .footer.fixed, body.rtls.top-navigation .footer.fixed
transition: all .3s ease-out 0s;
}
::-webkit-scrollbar-track {
background-color: #F5F5F5;
}
::-webkit-scrollbar {
width: 6px;
background-color: #F5F5F5;
}
::-webkit-scrollbar-thumb {
background-color: #999;
}
/*GO HOME*/
.gohome {
position: fixed;
top: 20px;
right: 20px;
z-index: 100;
}
.gohome a {
height: 38px;
width: 38px;
display: block;
background: #2f4050;
padding: 9px 8px;
text-align: center;
color: #fff;
border-radius: 50%;
opacity: .5;
}
.gohome a:hover {
opacity: 1;
}
@media only screen and (-webkit-min-device-pixel-ratio : 2) {
#content-main {
-webkit-overflow-scrolling: touch;
@@ -6987,7 +6951,7 @@ body.rtls .top-navigation .footer.fixed, body.rtls.top-navigation .footer.fixed
font-size: 20px;
line-height: 50px;
text-align: center;
width: 220px;
width: 200px;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
padding: 0 15px;
font-weight: 300;
@@ -0,0 +1,492 @@
/*!
* jQuery Templates Plugin 1.0.0pre
* http://github.com/jquery/jquery-tmpl
* Requires jQuery 1.4.2
*
* Copyright 2011, Software Freedom Conservancy, Inc.
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*/
(function( factory ) {
if (typeof define === 'function' && define.amd) {
// Loading from AMD script loader. Register as an anonymous module.
define( ['jquery'], factory );
} else {
// Browser using plain <script> tag
factory( jQuery );
}
}(function( jQuery ){
var oldManip = jQuery.fn.domManip, tmplItmAtt = "_tmplitem", htmlExpr = /^[^<]*(<[\w\W]+>)[^>]*$|\{\{\! /,
newTmplItems = {}, wrappedItems = {}, appendToTmplItems, topTmplItem = { key: 0, data: {} }, itemKey = 0, cloneIndex = 0, stack = [];
function newTmplItem( options, parentItem, fn, data ) {
// Returns a template item data structure for a new rendered instance of a template (a 'template item').
// The content field is a hierarchical array of strings and nested items (to be
// removed and replaced by nodes field of dom elements, once inserted in DOM).
var newItem = {
data: data || (data === 0 || data === false) ? data : (parentItem ? parentItem.data : {}),
_wrap: parentItem ? parentItem._wrap : null,
tmpl: null,
parent: parentItem || null,
nodes: [],
calls: tiCalls,
nest: tiNest,
wrap: tiWrap,
html: tiHtml,
update: tiUpdate
};
if ( options ) {
jQuery.extend( newItem, options, { nodes: [], parent: parentItem });
}
if ( fn ) {
// Build the hierarchical content to be used during insertion into DOM
newItem.tmpl = fn;
newItem._ctnt = newItem._ctnt || newItem.tmpl( jQuery, newItem );
newItem.key = ++itemKey;
// Keep track of new template item, until it is stored as jQuery Data on DOM element
(stack.length ? wrappedItems : newTmplItems)[itemKey] = newItem;
}
return newItem;
}
// Override appendTo etc., in order to provide support for targeting multiple elements. (This code would disappear if integrated in jquery core).
jQuery.each({
appendTo: "append",
prependTo: "prepend",
insertBefore: "before",
insertAfter: "after",
replaceAll: "replaceWith"
}, function( name, original ) {
jQuery.fn[ name ] = function( selector ) {
var ret = [], insert = jQuery( selector ), elems, i, l, tmplItems,
parent = this.length === 1 && this[0].parentNode;
appendToTmplItems = newTmplItems || {};
if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
insert[ original ]( this[0] );
ret = this;
} else {
for ( i = 0, l = insert.length; i < l; i++ ) {
cloneIndex = i;
elems = (i > 0 ? this.clone(true) : this).get();
jQuery( insert[i] )[ original ]( elems );
ret = ret.concat( elems );
}
cloneIndex = 0;
ret = this.pushStack( ret, name, insert.selector );
}
tmplItems = appendToTmplItems;
appendToTmplItems = null;
jQuery.tmpl.complete( tmplItems );
return ret;
};
});
jQuery.fn.extend({
// Use first wrapped element as template markup.
// Return wrapped set of template items, obtained by rendering template against data.
tmpl: function( data, options, parentItem ) {
return jQuery.tmpl( this[0], data, options, parentItem );
},
// Find which rendered template item the first wrapped DOM element belongs to
tmplItem: function() {
return jQuery.tmplItem( this[0] );
},
// Consider the first wrapped element as a template declaration, and get the compiled template or store it as a named template.
template: function( name ) {
return jQuery.template( name, this[0] );
},
domManip: function( args, table, callback, options ) {
if ( args[0] && jQuery.isArray( args[0] )) {
var dmArgs = jQuery.makeArray( arguments ), elems = args[0], elemsLength = elems.length, i = 0, tmplItem;
while ( i < elemsLength && !(tmplItem = jQuery.data( elems[i++], "tmplItem" ))) {}
if ( tmplItem && cloneIndex ) {
dmArgs[2] = function( fragClone ) {
// Handler called by oldManip when rendered template has been inserted into DOM.
jQuery.tmpl.afterManip( this, fragClone, callback );
};
}
oldManip.apply( this, dmArgs );
} else {
oldManip.apply( this, arguments );
}
cloneIndex = 0;
if ( !appendToTmplItems ) {
jQuery.tmpl.complete( newTmplItems );
}
return this;
}
});
jQuery.extend({
// Return wrapped set of template items, obtained by rendering template against data.
tmpl: function( tmpl, data, options, parentItem ) {
var ret, topLevel = !parentItem;
if ( topLevel ) {
// This is a top-level tmpl call (not from a nested template using {{tmpl}})
parentItem = topTmplItem;
tmpl = jQuery.template[tmpl] || jQuery.template( null, tmpl );
wrappedItems = {}; // Any wrapped items will be rebuilt, since this is top level
} else if ( !tmpl ) {
// The template item is already associated with DOM - this is a refresh.
// Re-evaluate rendered template for the parentItem
tmpl = parentItem.tmpl;
newTmplItems[parentItem.key] = parentItem;
parentItem.nodes = [];
if ( parentItem.wrapped ) {
updateWrapped( parentItem, parentItem.wrapped );
}
// Rebuild, without creating a new template item
return jQuery( build( parentItem, null, parentItem.tmpl( jQuery, parentItem ) ));
}
if ( !tmpl ) {
return []; // Could throw...
}
if ( typeof data === "function" ) {
data = data.call( parentItem || {} );
}
if ( options && options.wrapped ) {
updateWrapped( options, options.wrapped );
}
ret = jQuery.isArray( data ) ?
jQuery.map( data, function( dataItem ) {
return dataItem ? newTmplItem( options, parentItem, tmpl, dataItem ) : null;
}) :
[ newTmplItem( options, parentItem, tmpl, data ) ];
return topLevel ? jQuery( build( parentItem, null, ret ) ) : ret;
},
// Return rendered template item for an element.
tmplItem: function( elem ) {
var tmplItem;
if ( elem instanceof jQuery ) {
elem = elem[0];
}
while ( elem && elem.nodeType === 1 && !(tmplItem = jQuery.data( elem, "tmplItem" )) && (elem = elem.parentNode) ) {}
return tmplItem || topTmplItem;
},
// Set:
// Use $.template( name, tmpl ) to cache a named template,
// where tmpl is a template string, a script element or a jQuery instance wrapping a script element, etc.
// Use $( "selector" ).template( name ) to provide access by name to a script block template declaration.
// Get:
// Use $.template( name ) to access a cached template.
// Also $( selectorToScriptBlock ).template(), or $.template( null, templateString )
// will return the compiled template, without adding a name reference.
// If templateString includes at least one HTML tag, $.template( templateString ) is equivalent
// to $.template( null, templateString )
template: function( name, tmpl ) {
if (tmpl) {
// Compile template and associate with name
if ( typeof tmpl === "string" ) {
// This is an HTML string being passed directly in.
tmpl = buildTmplFn( tmpl );
} else if ( tmpl instanceof jQuery ) {
tmpl = tmpl[0] || {};
}
if ( tmpl.nodeType ) {
// If this is a template block, use cached copy, or generate tmpl function and cache.
tmpl = jQuery.data( tmpl, "tmpl" ) || jQuery.data( tmpl, "tmpl", buildTmplFn( tmpl.innerHTML ));
// Issue: In IE, if the container element is not a script block, the innerHTML will remove quotes from attribute values whenever the value does not include white space.
// This means that foo="${x}" will not work if the value of x includes white space: foo="${x}" -> foo=value of x.
// To correct this, include space in tag: foo="${ x }" -> foo="value of x"
}
return typeof name === "string" ? (jQuery.template[name] = tmpl) : tmpl;
}
// Return named compiled template
return name ? (typeof name !== "string" ? jQuery.template( null, name ):
(jQuery.template[name] ||
// If not in map, and not containing at least on HTML tag, treat as a selector.
// (If integrated with core, use quickExpr.exec)
jQuery.template( null, htmlExpr.test( name ) ? name : jQuery( name )))) : null;
},
encode: function( text ) {
// Do HTML encoding replacing < > & and ' and " by corresponding entities.
return ("" + text).split("<").join("&lt;").split(">").join("&gt;").split('"').join("&#34;").split("'").join("&#39;");
}
});
jQuery.extend( jQuery.tmpl, {
tag: {
"tmpl": {
_default: { $2: "null" },
open: "if($notnull_1){__=__.concat($item.nest($1,$2));}"
// tmpl target parameter can be of type function, so use $1, not $1a (so not auto detection of functions)
// This means that {{tmpl foo}} treats foo as a template (which IS a function).
// Explicit parens can be used if foo is a function that returns a template: {{tmpl foo()}}.
},
"wrap": {
_default: { $2: "null" },
open: "$item.calls(__,$1,$2);__=[];",
close: "call=$item.calls();__=call._.concat($item.wrap(call,__));"
},
"each": {
_default: { $2: "$index, $value" },
open: "if($notnull_1){$.each($1a,function($2){with(this){",
close: "}});}"
},
"if": {
open: "if(($notnull_1) && $1a){",
close: "}"
},
"else": {
_default: { $1: "true" },
open: "}else if(($notnull_1) && $1a){"
},
"html": {
// Unecoded expression evaluation.
open: "if($notnull_1){__.push($1a);}"
},
"=": {
// Encoded expression evaluation. Abbreviated form is ${}.
_default: { $1: "$data" },
open: "if($notnull_1){__.push($.encode($1a));}"
},
"!": {
// Comment tag. Skipped by parser
open: ""
}
},
// This stub can be overridden, e.g. in jquery.tmplPlus for providing rendered events
complete: function( items ) {
newTmplItems = {};
},
// Call this from code which overrides domManip, or equivalent
// Manage cloning/storing template items etc.
afterManip: function afterManip( elem, fragClone, callback ) {
// Provides cloned fragment ready for fixup prior to and after insertion into DOM
var content = fragClone.nodeType === 11 ?
jQuery.makeArray(fragClone.childNodes) :
fragClone.nodeType === 1 ? [fragClone] : [];
// Return fragment to original caller (e.g. append) for DOM insertion
callback.call( elem, fragClone );
// Fragment has been inserted:- Add inserted nodes to tmplItem data structure. Replace inserted element annotations by jQuery.data.
storeTmplItems( content );
cloneIndex++;
}
});
//========================== Private helper functions, used by code above ==========================
function build( tmplItem, nested, content ) {
// Convert hierarchical content into flat string array
// and finally return array of fragments ready for DOM insertion
var frag, ret = content ? jQuery.map( content, function( item ) {
return (typeof item === "string") ?
// Insert template item annotations, to be converted to jQuery.data( "tmplItem" ) when elems are inserted into DOM.
(tmplItem.key ? item.replace( /(<\w+)(?=[\s>])(?![^>]*_tmplitem)([^>]*)/g, "$1 " + tmplItmAtt + "=\"" + tmplItem.key + "\" $2" ) : item) :
// This is a child template item. Build nested template.
build( item, tmplItem, item._ctnt );
}) :
// If content is not defined, insert tmplItem directly. Not a template item. May be a string, or a string array, e.g. from {{html $item.html()}}.
tmplItem;
if ( nested ) {
return ret;
}
// top-level template
ret = ret.join("");
// Support templates which have initial or final text nodes, or consist only of text
// Also support HTML entities within the HTML markup.
ret.replace( /^\s*([^<\s][^<]*)?(<[\w\W]+>)([^>]*[^>\s])?\s*$/, function( all, before, middle, after) {
frag = jQuery( middle ).get();
storeTmplItems( frag );
if ( before ) {
frag = unencode( before ).concat(frag);
}
if ( after ) {
frag = frag.concat(unencode( after ));
}
});
return frag ? frag : unencode( ret );
}
function unencode( text ) {
// Use createElement, since createTextNode will not render HTML entities correctly
var el = document.createElement( "div" );
el.innerHTML = text;
return jQuery.makeArray(el.childNodes);
}
// Generate a reusable function that will serve to render a template against data
function buildTmplFn( markup ) {
return new Function("jQuery","$item",
// Use the variable __ to hold a string array while building the compiled template. (See https://github.com/jquery/jquery-tmpl/issues#issue/10).
"var $=jQuery,call,__=[],$data=$item.data;" +
// Introduce the data as local variables using with(){}
"with($data){__.push('" +
// Convert the template into pure JavaScript
jQuery.trim(markup)
.replace( /([\\'])/g, "\\$1" )
.replace( /[\r\t\n]/g, " " )
.replace( /\$\{([^\}]*)\}/g, "{{= $1}}" )
.replace( /\{\{(\/?)(\w+|.)(?:\(((?:[^\}]|\}(?!\}))*?)?\))?(?:\s+(.*?)?)?(\(((?:[^\}]|\}(?!\}))*?)\))?\s*\}\}/g,
function( all, slash, type, fnargs, target, parens, args ) {
var tag = jQuery.tmpl.tag[ type ], def, expr, exprAutoFnDetect;
if ( !tag ) {
throw "Unknown template tag: " + type;
}
def = tag._default || [];
if ( parens && !/\w$/.test(target)) {
target += parens;
parens = "";
}
if ( target ) {
target = unescape( target );
args = args ? ("," + unescape( args ) + ")") : (parens ? ")" : "");
// Support for target being things like a.toLowerCase();
// In that case don't call with template item as 'this' pointer. Just evaluate...
expr = parens ? (target.indexOf(".") > -1 ? target + unescape( parens ) : ("(" + target + ").call($item" + args)) : target;
exprAutoFnDetect = parens ? expr : "(typeof(" + target + ")==='function'?(" + target + ").call($item):(" + target + "))";
} else {
exprAutoFnDetect = expr = def.$1 || "null";
}
fnargs = unescape( fnargs );
return "');" +
tag[ slash ? "close" : "open" ]
.split( "$notnull_1" ).join( target ? "typeof(" + target + ")!=='undefined' && (" + target + ")!=null" : "true" )
.split( "$1a" ).join( exprAutoFnDetect )
.split( "$1" ).join( expr )
.split( "$2" ).join( fnargs || def.$2 || "" ) +
"__.push('";
}) +
"');}return __;"
);
}
function updateWrapped( options, wrapped ) {
// Build the wrapped content.
options._wrap = build( options, true,
// Suport imperative scenario in which options.wrapped can be set to a selector or an HTML string.
jQuery.isArray( wrapped ) ? wrapped : [htmlExpr.test( wrapped ) ? wrapped : jQuery( wrapped ).html()]
).join("");
}
function unescape( args ) {
return args ? args.replace( /\\'/g, "'").replace(/\\\\/g, "\\" ) : null;
}
function outerHtml( elem ) {
var div = document.createElement("div");
div.appendChild( elem.cloneNode(true) );
return div.innerHTML;
}
// Store template items in jQuery.data(), ensuring a unique tmplItem data data structure for each rendered template instance.
function storeTmplItems( content ) {
var keySuffix = "_" + cloneIndex, elem, elems, newClonedItems = {}, i, l, m;
for ( i = 0, l = content.length; i < l; i++ ) {
if ( (elem = content[i]).nodeType !== 1 ) {
continue;
}
elems = elem.getElementsByTagName("*");
for ( m = elems.length - 1; m >= 0; m-- ) {
processItemKey( elems[m] );
}
processItemKey( elem );
}
function processItemKey( el ) {
var pntKey, pntNode = el, pntItem, tmplItem, key;
// Ensure that each rendered template inserted into the DOM has its own template item,
if ( (key = el.getAttribute( tmplItmAtt ))) {
while ( pntNode.parentNode && (pntNode = pntNode.parentNode).nodeType === 1 && !(pntKey = pntNode.getAttribute( tmplItmAtt ))) { }
if ( pntKey !== key ) {
// The next ancestor with a _tmplitem expando is on a different key than this one.
// So this is a top-level element within this template item
// Set pntNode to the key of the parentNode, or to 0 if pntNode.parentNode is null, or pntNode is a fragment.
pntNode = pntNode.parentNode ? (pntNode.nodeType === 11 ? 0 : (pntNode.getAttribute( tmplItmAtt ) || 0)) : 0;
if ( !(tmplItem = newTmplItems[key]) ) {
// The item is for wrapped content, and was copied from the temporary parent wrappedItem.
tmplItem = wrappedItems[key];
tmplItem = newTmplItem( tmplItem, newTmplItems[pntNode]||wrappedItems[pntNode] );
tmplItem.key = ++itemKey;
newTmplItems[itemKey] = tmplItem;
}
if ( cloneIndex ) {
cloneTmplItem( key );
}
}
el.removeAttribute( tmplItmAtt );
} else if ( cloneIndex && (tmplItem = jQuery.data( el, "tmplItem" )) ) {
// This was a rendered element, cloned during append or appendTo etc.
// TmplItem stored in jQuery data has already been cloned in cloneCopyEvent. We must replace it with a fresh cloned tmplItem.
cloneTmplItem( tmplItem.key );
newTmplItems[tmplItem.key] = tmplItem;
pntNode = jQuery.data( el.parentNode, "tmplItem" );
pntNode = pntNode ? pntNode.key : 0;
}
if ( tmplItem ) {
pntItem = tmplItem;
// Find the template item of the parent element.
// (Using !=, not !==, since pntItem.key is number, and pntNode may be a string)
while ( pntItem && pntItem.key != pntNode ) {
// Add this element as a top-level node for this rendered template item, as well as for any
// ancestor items between this item and the item of its parent element
pntItem.nodes.push( el );
pntItem = pntItem.parent;
}
// Delete content built during rendering - reduce API surface area and memory use, and avoid exposing of stale data after rendering...
delete tmplItem._ctnt;
delete tmplItem._wrap;
// Store template item as jQuery data on the element
jQuery.data( el, "tmplItem", tmplItem );
}
function cloneTmplItem( key ) {
key = key + keySuffix;
tmplItem = newClonedItems[key] =
(newClonedItems[key] || newTmplItem( tmplItem, newTmplItems[tmplItem.parent.key + keySuffix] || tmplItem.parent ));
}
}
}
//---- Helper functions for template item ----
function tiCalls( content, tmpl, data, options ) {
if ( !content ) {
return stack.pop();
}
stack.push({ _: content, tmpl: tmpl, item:this, data: data, options: options });
}
function tiNest( tmpl, data, options ) {
// nested template, using {{tmpl}} tag
return jQuery.tmpl( jQuery.template( tmpl ), data, options, this );
}
function tiWrap( call, wrapped ) {
// nested template, using {{wrap}} tag
var options = call.options || {};
options.wrapped = wrapped;
// Apply the template, which may incorporate wrapped content,
return jQuery.tmpl( jQuery.template( call.tmpl ), call.data, options, call.item );
}
function tiHtml( filter, textOnly ) {
var wrapped = this._wrap;
return jQuery.map(
jQuery( jQuery.isArray( wrapped ) ? wrapped.join("") : wrapped ).filter( filter || "*" ),
function(e) {
return textOnly ?
e.innerText || e.textContent :
e.outerHTML || outerHtml(e);
});
}
function tiUpdate() {
var coll = this.nodes;
jQuery.tmpl( null, null, null, this).insertBefore( coll[0] );
jQuery( coll ).remove();
}
}));
@@ -5,12 +5,4 @@
* Version: 1.3.8
*
*/
(function(e){e.fn.extend({slimScroll:function(f){var a=e.extend({width:"auto",height:"250px",size:"7px",color:"#000",position:"right",distance:"1px",start:"top",opacity:.4,alwaysVisible:!1,disableFadeOut:!1,railVisible:!1,railColor:"#333",railOpacity:.2,railDraggable:!0,railClass:"slimScrollRail",barClass:"slimScrollBar",wrapperClass:"slimScrollDiv",allowPageScroll:!1,wheelStep:20,touchScrollStep:200,borderRadius:"7px",railBorderRadius:"7px"},f);this.each(function(){function v(d){if(r){d=d||window.event;
var c=0;d.wheelDelta&&(c=-d.wheelDelta/120);d.detail&&(c=d.detail/3);e(d.target||d.srcTarget||d.srcElement).closest("."+a.wrapperClass).is(b.parent())&&n(c,!0);d.preventDefault&&!k&&d.preventDefault();k||(d.returnValue=!1)}}function n(d,g,e){k=!1;var f=b.outerHeight()-c.outerHeight();g&&(g=parseInt(c.css("top"))+d*parseInt(a.wheelStep)/100*c.outerHeight(),g=Math.min(Math.max(g,0),f),g=0<d?Math.ceil(g):Math.floor(g),c.css({top:g+"px"}));l=parseInt(c.css("top"))/(b.outerHeight()-c.outerHeight());g=
l*(b[0].scrollHeight-b.outerHeight());e&&(g=d,d=g/b[0].scrollHeight*b.outerHeight(),d=Math.min(Math.max(d,0),f),c.css({top:d+"px"}));b.scrollTop(g);b.trigger("slimscrolling",~~g);w();p()}function x(){u=Math.max(b.outerHeight()/b[0].scrollHeight*b.outerHeight(),30);c.css({height:u+"px"});var a=u==b.outerHeight()?"none":"block";c.css({display:a})}function w(){x();clearTimeout(B);l==~~l?(k=a.allowPageScroll,C!=l&&b.trigger("slimscroll",0==~~l?"top":"bottom")):k=!1;C=l;u>=b.outerHeight()?k=!0:(c.stop(!0,
!0).fadeIn("fast"),a.railVisible&&m.stop(!0,!0).fadeIn("fast"))}function p(){a.alwaysVisible||(B=setTimeout(function(){a.disableFadeOut&&r||y||z||(c.fadeOut("slow"),m.fadeOut("slow"))},1E3))}var r,y,z,B,A,u,l,C,k=!1,b=e(this);if(b.parent().hasClass(a.wrapperClass)){var q=b.scrollTop(),c=b.siblings("."+a.barClass),m=b.siblings("."+a.railClass);x();if(e.isPlainObject(f)){if("height"in f&&"auto"==f.height){b.parent().css("height","auto");b.css("height","auto");var h=b.parent().parent().height();b.parent().css("height",
h);b.css("height",h)}else"height"in f&&(h=f.height,b.parent().css("height",h),b.css("height",h));if("scrollTo"in f)q=parseInt(a.scrollTo);else if("scrollBy"in f)q+=parseInt(a.scrollBy);else if("destroy"in f){c.remove();m.remove();b.unwrap();return}n(q,!1,!0)}}else if(!(e.isPlainObject(f)&&"destroy"in f)){a.height="auto"==a.height?b.parent().height():a.height;q=e("<div></div>").addClass(a.wrapperClass).css({position:"relative",overflow:"hidden",width:a.width,height:a.height});b.css({overflow:"hidden",
width:a.width,height:a.height});var m=e("<div></div>").addClass(a.railClass).css({width:a.size,height:"100%",position:"absolute",top:0,display:a.alwaysVisible&&a.railVisible?"block":"none","border-radius":a.railBorderRadius,background:a.railColor,opacity:a.railOpacity,zIndex:90}),c=e("<div></div>").addClass(a.barClass).css({background:a.color,width:a.size,position:"absolute",top:0,opacity:a.opacity,display:a.alwaysVisible?"block":"none","border-radius":a.borderRadius,BorderRadius:a.borderRadius,MozBorderRadius:a.borderRadius,
WebkitBorderRadius:a.borderRadius,zIndex:99}),h="right"==a.position?{right:a.distance}:{left:a.distance};m.css(h);c.css(h);b.wrap(q);b.parent().append(c);b.parent().append(m);a.railDraggable&&c.bind("mousedown",function(a){var b=e(document);z=!0;t=parseFloat(c.css("top"));pageY=a.pageY;b.bind("mousemove.slimscroll",function(a){currTop=t+a.pageY-pageY;c.css("top",currTop);n(0,c.position().top,!1)});b.bind("mouseup.slimscroll",function(a){z=!1;p();b.unbind(".slimscroll")});return!1}).bind("selectstart.slimscroll",
function(a){a.stopPropagation();a.preventDefault();return!1});m.hover(function(){w()},function(){p()});c.hover(function(){y=!0},function(){y=!1});b.hover(function(){r=!0;w();p()},function(){r=!1;p()});b.bind("touchstart",function(a,b){a.originalEvent.touches.length&&(A=a.originalEvent.touches[0].pageY)});b.bind("touchmove",function(b){k||b.originalEvent.preventDefault();b.originalEvent.touches.length&&(n((A-b.originalEvent.touches[0].pageY)/a.touchScrollStep,!0),A=b.originalEvent.touches[0].pageY)});
x();"bottom"===a.start?(c.css({top:b.outerHeight()-c.outerHeight()}),n(0,!0)):"top"!==a.start&&(n(e(a.start).position().top,null,!0),a.alwaysVisible||c.hide());window.addEventListener?(this.addEventListener("DOMMouseScroll",v,!1),this.addEventListener("mousewheel",v,!1)):document.attachEvent("onmousewheel",v)}});return this}});e.fn.extend({slimscroll:e.fn.slimScroll})})(jQuery);
(function(a){a.fn.extend({slimScroll:function(b){var c={width:"auto",height:"250px",size:"2px",color:"#000",position:"right",distance:"1px",start:"top",opacity:0.4,alwaysVisible:false,disableFadeOut:false,railVisible:false,railColor:"#333",railOpacity:0.2,railDraggable:true,railClass:"slimScrollRail",barClass:"slimScrollBar",wrapperClass:"slimScrollDiv",allowPageScroll:false,wheelStep:20,touchScrollStep:200,borderRadius:"7px",railBorderRadius:"7px"};var d=a.extend(c,b);this.each(function(){var z,s,l,q,C,u,p,k,m="<div></div>",w=30,r=false;var D=a(this);if(D.parent().hasClass(d.wrapperClass)){var i=D.scrollTop();x=D.siblings("."+d.barClass);e=D.siblings("."+d.railClass);E();if(a.isPlainObject(b)){if("height" in b&&b.height=="auto"){D.parent().css("height","auto");D.css("height","auto");var o=D.parent().parent().height();D.parent().css("height",o);D.css("height",o)}else{if("height" in b){var v=b.height;D.parent().css("height",v);D.css("height",v)}}if("scrollTo" in b){i=parseInt(d.scrollTo)}else{if("scrollBy" in b){i+=parseInt(d.scrollBy)}else{if("destroy" in b){x.remove();e.remove();D.unwrap();return}}}y(i,false,true)}return}else{if(a.isPlainObject(b)){if("destroy" in b){return}}}d.height=(d.height=="auto")?D.parent().height():d.height;var j=a(m).addClass(d.wrapperClass).css({position:"relative",width:d.width,height:d.height});D.css({width:d.width,height:d.height});var e=a(m).addClass(d.railClass).css({width:d.size,height:"100%",position:"absolute",top:0,display:(d.alwaysVisible&&d.railVisible)?"block":"none","border-radius":d.railBorderRadius,background:d.railColor,opacity:d.railOpacity,zIndex:90});var x=a(m).addClass(d.barClass).css({background:d.color,width:d.size,position:"absolute",top:0,opacity:d.opacity,display:d.alwaysVisible?"block":"none","border-radius":d.borderRadius,BorderRadius:d.borderRadius,MozBorderRadius:d.borderRadius,WebkitBorderRadius:d.borderRadius,zIndex:99});var f=(d.position=="right")?{right:d.distance}:{left:d.distance};e.css(f);x.css(f);D.wrap(j);D.parent().append(x);D.parent().append(e);if(d.railDraggable){x.bind("mousedown",function(h){var F=a(document);l=true;t=parseFloat(x.css("top"));pageY=h.pageY;F.bind("mousemove.slimscroll",function(G){currTop=t+G.pageY-pageY;x.css("top",currTop);y(0,x.position().top,false)});F.bind("mouseup.slimscroll",function(G){l=false;n();F.unbind(".slimscroll")});return false}).bind("selectstart.slimscroll",function(h){h.stopPropagation();h.preventDefault();return false})}e.hover(function(){g()},function(){n()});x.hover(function(){s=true},function(){s=false});D.hover(function(){z=true;g();n()},function(){z=false;n()});D.bind("touchstart",function(F,h){if(F.originalEvent.touches.length){C=F.originalEvent.touches[0].pageY}});D.bind("touchmove",function(F){if(!r){F.originalEvent.preventDefault()}if(F.originalEvent.touches.length){var h=(C-F.originalEvent.touches[0].pageY)/d.touchScrollStep;y(h,true);C=F.originalEvent.touches[0].pageY}});E();if(d.start==="bottom"){x.css({top:D.outerHeight()-x.outerHeight()});y(0,true)}else{if(d.start!=="top"){y(a(d.start).position().top,null,true);if(!d.alwaysVisible){x.hide()}}}A(this);function B(F){if(!z){return}var F=F||window.event;var G=0;if(F.wheelDelta){G=-F.wheelDelta/120}if(F.detail){G=F.detail/3}var h=F.target||F.srcTarget||F.srcElement;if(a(h).closest("."+d.wrapperClass).is(D.parent())){y(G,true)}if(F.preventDefault&&!r){F.preventDefault()}if(!r){F.returnValue=false}}function y(J,G,h){r=false;var I=J;var H=D.outerHeight()-x.outerHeight();if(G){I=parseInt(x.css("top"))+J*parseInt(d.wheelStep)/100*x.outerHeight();I=Math.min(Math.max(I,0),H);I=(J>0)?Math.ceil(I):Math.floor(I);x.css({top:I+"px"})}p=parseInt(x.css("top"))/(D.outerHeight()-x.outerHeight());I=p*(D[0].scrollHeight-D.outerHeight());if(h){I=J;var F=I/D[0].scrollHeight*D.outerHeight();F=Math.min(Math.max(F,0),H);x.css({top:F+"px"})}D.scrollTop(I);D.trigger("slimscrolling",~~I);g();n()}function A(h){if(window.addEventListener){h.addEventListener("DOMMouseScroll",B,false);h.addEventListener("mousewheel",B,false)}else{document.attachEvent("onmousewheel",B)}}function E(){u=Math.max((D.outerHeight()/D[0].scrollHeight)*D.outerHeight(),w);x.css({height:u+"px"});var h=u==D.outerHeight()?"none":"block";x.css({display:h})}function g(){E();clearTimeout(q);if(p==~~p){r=d.allowPageScroll;if(k!=p){var h=(~~p==0)?"top":"bottom";D.trigger("slimscroll",h)}}else{r=false}k=p;if(u>=D.outerHeight()){r=true;return}x.stop(true,true).fadeIn("fast");if(d.railVisible){e.stop(true,true).fadeIn("fast")}}function n(){if(!d.alwaysVisible){q=setTimeout(function(){if(!(d.disableFadeOut&&z)&&!s&&!l){x.fadeOut("slow");e.fadeOut("slow")}},1000)}}});return this}});a.fn.extend({slimscroll:a.fn.slimScroll})})(jQuery);
@@ -146,6 +146,12 @@
margin-right: 5px
}
.nav-tabs-custom>.nav-tabs>li.header {
padding-left: 5px;
font-size: 16px;
line-height: 30px;
}
.nav-tabs-custom>.nav-tabs>li.disabled>a {
color: #777
}
@@ -288,6 +294,12 @@
margin: 5px 0 5px -25px
}
@media ( min-width : 768px) {
.section-content .about {
padding-left: 0px
}
}
/** select2 样式修改 **/
.select2-container--default .select2-selection--multiple .select2-selection__choice {
background-color: #1AB394;
@@ -323,6 +335,11 @@ label.error {
right: 42px
}
.input-group.date label.error {
z-index:99;
right: 3px
}
.Validform_error,input.error,select.error {
background-color: #fbe2e2;
border-color: #c66161;
@@ -578,7 +595,7 @@ label {
}
.container-div {
padding: 10px 35px;
padding: 0px 28px;
height: 100%;
}
@@ -666,6 +683,12 @@ label {
background: #FFFFFF none
}
.file-input .btn-default {
color: inherit;
background: white;
border: 1px solid #e7eaec;
}
.select-list .btn-default {
color: #555;
padding: 5px 5px;
@@ -774,12 +797,20 @@ label {
border: 0px!important;
}
.table-striped .table, .fixed-table-container, table, .table-striped .table, .table>thead>tr>th, .table>tbody>tr>th, .table>tfoot>tr>th, .table>thead>tr>td, .table>tbody>tr>td, .table>tfoot>tr>td {
.table-striped .table, .table-striped .table, .table>thead>tr>th, .table>tbody>tr>th, .table>tfoot>tr>th, .table>thead>tr>td, .table>tbody>tr>td, .table>tfoot>tr>td {
border-bottom: 1px solid #e7eaec!important;
background-color: transparent!important;
border: 0px;
}
.fixed-table-footer {
border-top: 0px solid #ddd;
}
.fixed-table-container {
border: 0px solid #ddd;
}
.table-striped .table>thead>tr>th, .table-striped .table>tbody>tr>th {
border-bottom: 1px solid #ccc!important;
border-top: 0px!important;
@@ -802,14 +833,31 @@ label {
}
/** 表格冻结列样式 **/
.left-fixed-table-columns{
.left-fixed-table-columns, .left-fixed-body-columns {
position: absolute;
background-color: #fff;
display: none;
border-right:1px solid #ddd;
box-sizing: border-box;
overflow: hidden;
}
.left-fixed-table-columns .table, .left-fixed-body-columns .table {
border-right: 1px solid #ddd;
}
.left-fixed-table-columns .table.table-no-bordered, .left-fixed-body-columns .table.table-no-bordered {
border-right: 1px solid transparent;
}
.left-fixed-body-columns table {
position: absolute;
animation: none;
}
.bootstrap-table .table-hover > tbody > tr.hover > td {
background-color: #f5f5f5;
}
.right-fixed-table-columns{
position: absolute;
right:63px;
@@ -827,13 +875,13 @@ label {
.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;white-space: nowrap; text-overflow: ellipsis;}
.bootstrap-tree-table .treetable-tbody td{overflow:hidden;border: 0 !important;border-left:0px solid #e7eaec !important;border-bottom:1px solid #e7eaec!important;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;}
.bootstrap-tree-table .table{border-bottom: 0px solid #e7eaec!important;}
/** 首页样式 **/
.ax_close_max {
@@ -886,7 +934,7 @@ label {
padding-bottom:5px
}
.form-content {
.main-content {
background-color: #ffffff;
color: inherit;
padding: 10px 15px 15px 15px;
@@ -911,4 +959,34 @@ label {
height: 32px;
display: block;
float:left;
}
/** 表格拖拽样式 **/
.reorder_rows_onDragClass td {
color:yellow!important;
background-color:#999!important;
text-shadow:0 0 10px black,0 0 10px black,0 0 8px black,0 0 6px black,0 0 6px black;
box-shadow:0 12px 14px -12px #111 inset,0 -2px 2px -1px #333 inset
}
/** 表格选中样式 **/
.fixed-table-container .selected {
background-color: #E8F7FD;
color: #1890ff;
}
/** 滚动条样式 **/
::-webkit-scrollbar-track {
background-color: #F5F5F5;
}
::-webkit-scrollbar {
width: 6px;
height: 10px;
background-color: #F5F5F5;
}
::-webkit-scrollbar-thumb {
border-radius: 6px;
background-color: #999;
}
@@ -52,6 +52,7 @@ function() {
$('body').addClass('mini-navbar');
$('.navbar-static-side').fadeIn();
$(".sidebar-collapse .logo").addClass("hide");
$(".slimScrollDiv").css({ "overflow":"hidden" })
}
});
@@ -216,6 +217,8 @@ $(function() {
dataIndex = $(this).data('index'),
menuName = $.trim($(this).text()),
flag = true;
$(".nav ul li, .nav li").removeClass("selected");
$(this).parent("li").addClass("selected");
if (dataUrl == undefined || $.trim(dataUrl).length == 0) return false;
// 选项卡菜单已存在
@@ -131,9 +131,9 @@ $(function() {
var dataExpand = $.common.isEmpty($.table._option.expandAll) ? true : $.table._option.expandAll;
expandFlag = $.common.isEmpty(expandFlag) ? dataExpand : expandFlag;
if (!expandFlag) {
$('#' + $.table._option.id).bootstrapTreeTable('expandAll');
$.bttTable.bootstrapTreeTable('expandAll');
} else {
$('#' + $.table._option.id).bootstrapTreeTable('collapseAll');
$.bttTable.bootstrapTreeTable('collapseAll');
}
expandFlag = expandFlag ? false: true;
})
@@ -155,8 +155,16 @@ var refreshItem = function(){
}
/** 关闭选项卡 */
var closeItem = function(){
var closeItem = function(dataId){
var topWindow = $(window.parent.document);
if($.common.isNotEmpty(dataId)){
window.parent.$.modal.closeLoading();
// 根据dataId关闭指定选项卡
$('.menuTab[data-id="' + dataId + '"]', topWindow).remove();
// 移除相应tab对应的内容区
$('.mainContent .RuoYi_iframe[data-id="' + dataId + '"]', topWindow).remove();
return;
}
var panelUrl = window.frameElement.getAttribute('data-panel');
$('.page-tabs-content .active i', topWindow).click();
if($.common.isNotEmpty(panelUrl)){
@@ -4,8 +4,9 @@
*/
(function ($) {
$.extend({
_treeTable: {},
_tree: {},
btTable: {},
bttTable: {},
// 表格封装处理
table: {
_option: {},
@@ -24,6 +25,7 @@
toolbar: "toolbar",
striped: false,
escape: false,
firstLoad: true,
showFooter: false,
search: false,
showSearch: true,
@@ -43,6 +45,7 @@
};
var options = $.extend(defaults, options);
$.table._option = options;
$.btTable = $('#' + options.id);
$.table.initEvent();
$('#' + options.id).bootstrapTable({
url: options.url, // 请求后台的URL*
@@ -59,6 +62,7 @@
pageNumber: 1, // 初始化加载第一页,默认第一页
pageSize: options.pageSize, // 每页的记录行数(*
pageList: options.pageList, // 可供选择的每页的行数(*
firstLoad: options.firstLoad, // 是否首次请求加载数据,对于数据较大可以配置false
escape: options.escape, // 转义HTML字符串
showFooter: options.showFooter, // 是否显示表尾
iconSize: 'outline', // 图标大小:undefined默认的按钮尺寸 xs超小按钮sm小按钮lg大按钮
@@ -72,6 +76,7 @@
showColumns: options.showColumns, // 是否显示隐藏某列下拉框
showToggle: options.showToggle, // 是否显示详细视图和列表视图的切换按钮
showExport: options.showExport, // 是否支持导出文件
uniqueId: options.uniqueId, // 唯 一的标识符
clickToSelect: options.clickToSelect, // 是否启用点击选中行
detailView: options.detailView, // 是否启用显示细节视图
onClickRow: options.onClickRow, // 点击某行触发的事件
@@ -83,6 +88,7 @@
fixedNumber: options.fixedNumber, // 列冻结的个数(左侧)
rightFixedColumns: options.rightFixedColumns, // 是否启用冻结列(右侧)
rightFixedNumber: options.rightFixedNumber, // 列冻结的个数(右侧)
onReorderRow: options.onReorderRow, // 当拖拽结束后处理函数
queryParams: options.queryParams, // 传递参数(*
rowStyle: options.rowStyle, // 通过自定义函数设置行样式
columns: options.columns, // 显示列信息(*
@@ -130,15 +136,16 @@
// 初始化事件
initEvent: function(data) {
// 触发行点击事件 加载成功事件
$("#" + $.table._option.id).on("check.bs.table uncheck.bs.table check-all.bs.table uncheck-all.bs.table load-success.bs.table", function () {
$.btTable.on("check.bs.table uncheck.bs.table check-all.bs.table uncheck-all.bs.table load-success.bs.table", function () {
// 工具栏按钮控制
var rows = $.common.isEmpty($.table._option.uniqueId) ? $.table.selectFirstColumns() : $.table.selectColumns($.table._option.uniqueId);
$('#' + $.table._option.toolbar + ' .btn-del').toggleClass('disabled', !rows.length);
$('#' + $.table._option.toolbar + ' .btn-edit').toggleClass('disabled', rows.length!=1);
$('#' + $.table._option.toolbar + ' .btn-detail').toggleClass('disabled', rows.length!=1);
// 非多个禁用
$('#' + $.table._option.toolbar + ' .multiple').toggleClass('disabled', !rows.length);
// 非单个禁用
$('#' + $.table._option.toolbar + ' .single').toggleClass('disabled', rows.length!=1);
});
// 绑定选中事件、取消事件、全部选中、全部取消
$("#" + $.table._option.id).on("check.bs.table check-all.bs.table uncheck.bs.table uncheck-all.bs.table", function (e, rows) {
$.btTable.on("check.bs.table check-all.bs.table uncheck.bs.table uncheck-all.bs.table", function (e, rows) {
// 复选框分页保留保存选中数组
var rowIds = $.table.affectedRowIds(rows);
if ($.common.isNotEmpty($.table._option.rememberSelected) && $.table._option.rememberSelected) {
@@ -147,9 +154,11 @@
}
});
// 图片预览事件
$("#" + $.table._option.id).on('click', '.img-circle', function() {
$.btTable.on('click', '.img-circle', function() {
var src = $(this).attr('src');
var target = $(this).data('target');
var height = $(this).data('height');
var width = $(this).data('width');
if($.common.equals("self", target)) {
layer.open({
title: false,
@@ -157,12 +166,18 @@
closeBtn: true,
shadeClose: true,
area: ['auto', 'auto'],
content: "<img src='" + src + "' />"
content: "<img src='" + src + "' height='" + height + "' width='" + width + "'/>"
});
} else if ($.common.equals("blank", target)) {
window.open(src);
}
});
// 单击tooltip复制文本
$.btTable.on('click', '.tooltip-show', function() {
var input = $(this).prev();
input.select();
document.execCommand("copy");
});
},
// 当所有数据被加载时触发
onLoadSuccess: function(data) {
@@ -179,19 +194,23 @@
},
// 序列号生成
serialNumber: function (index) {
var table = $('#' + $.table._option.id).bootstrapTable('getOptions');
var table = $.btTable.bootstrapTable('getOptions');
var pageSize = table.pageSize;
var pageNumber = table.pageNumber;
return pageSize * (pageNumber - 1) + index + 1;
},
// 列超出指定长度浮动提示
// 列超出指定长度浮动提示(单击文本复制)
tooltip: function (value, length) {
var _length = $.common.isEmpty(length) ? 20 : length;
var _text = "";
var _value = $.common.nullToStr(value);
if (_value.length > _length) {
_text = _value.substr(0, _length) + "...";
return $.common.sprintf("<a href='#' class='tooltip-show' data-toggle='tooltip' title='%s'>%s</a>", _value, _text);
_value = _value.replace(/\'/g,"");
var actions = [];
actions.push($.common.sprintf('<input id="tooltip-show" style="opacity: 0;position: absolute;z-index:-1" type="text" value="%s"/>', _value));
actions.push($.common.sprintf("<a href='###' class='tooltip-show' data-toggle='tooltip' title='%s'>%s</a>", _value, _text));
return actions.join('');
} else {
_text = _value;
return _text;
@@ -210,12 +229,17 @@
return actions.join('');
},
// 图片预览
imageView: function (value, path, target) {
var _path = $.common.isEmpty(path) ? '/profile/upload' : path;
imageView: function (value, height, width, target) {
if ($.common.isEmpty(width)) {
width = 'auto';
}
if ($.common.isEmpty(height)) {
height = 'auto';
}
// blank or self
var _target = $.common.isEmpty(target) ? 'self' : target;
if ($.common.isNotEmpty(value)) {
return $.common.sprintf("<img class='img-circle img-xs' data-target='%s' src='%s/%s'/>", _target, _path, value);
return $.common.sprintf("<img class='img-circle img-xs' data-height='%s' data-width='%s' data-target='%s' src='%s'/>", width, height, _target, value);
} else {
return $.common.nullToStr(value);
}
@@ -223,7 +247,7 @@
// 搜索-默认第一个form
search: function(formId, data) {
var currentId = $.common.isEmpty(formId) ? $('form').attr('id') : formId;
var params = $("#" + $.table._option.id).bootstrapTable('getOptions');
var params = $.btTable.bootstrapTable('getOptions');
params.queryParams = function(params) {
var search = $.common.formToJSON(currentId);
if($.common.isNotEmpty(data)){
@@ -238,7 +262,7 @@
search.isAsc = params.order;
return search;
}
$("#" + $.table._option.id).bootstrapTable('refresh', params);
$.btTable.bootstrapTable('refresh', params);
},
// 导出数据
exportExcel: function(formId) {
@@ -271,8 +295,7 @@
},
// 导入数据
importExcel: function(formId) {
var currentId = $.common.isEmpty(formId) ? 'importForm' : formId;
$.form.reset(currentId);
var currentId = $.common.isEmpty(formId) ? 'importTpl' : formId;
layer.open({
type: 1,
area: ['400px', '230px'],
@@ -281,7 +304,7 @@
maxmin: true,
shade: 0.3,
title: '导入' + $.table._option.modalName + '数据',
content: $('#' + currentId),
content: $('#' + currentId).html(),
btn: ['<i class="fa fa-check"></i> 导入', '<i class="fa fa-remove"></i> 取消'],
// 弹层外区域关闭
shadeClose: true,
@@ -324,13 +347,13 @@
},
// 刷新表格
refresh: function() {
$("#" + $.table._option.id).bootstrapTable('refresh', {
$.btTable.bootstrapTable('refresh', {
silent: true
});
},
// 查询表格指定列值
selectColumns: function(column) {
var rows = $.map($('#' + $.table._option.id).bootstrapTable('getSelections'), function (row) {
var rows = $.map($.btTable.bootstrapTable('getSelections'), function (row) {
return row[column];
});
if ($.common.isNotEmpty($.table._option.rememberSelected) && $.table._option.rememberSelected) {
@@ -353,7 +376,7 @@
},
// 查询表格首列值
selectFirstColumns: function() {
var rows = $.map($('#' + $.table._option.id).bootstrapTable('getSelections'), function (row) {
var rows = $.map($.btTable.bootstrapTable('getSelections'), function (row) {
return row[$.table._option.columns[1].field];
});
if ($.common.isNotEmpty($.table._option.rememberSelected) && $.table._option.rememberSelected) {
@@ -366,7 +389,7 @@
var actions = [];
$.each(datas, function(index, dict) {
if (dict.dictValue == ('' + value)) {
var listClass = $.common.equals("default", dict.listClass) ? "" : "badge badge-" + dict.listClass;
var listClass = $.common.equals("default", dict.listClass) || $.common.isEmpty(dict.listClass) ? "" : "badge badge-" + dict.listClass;
actions.push($.common.sprintf("<span class='%s'>%s</span>", listClass, dict.dictLabel));
return false;
}
@@ -375,11 +398,11 @@
},
// 显示表格指定列
showColumn: function(column) {
$("#" + $.table._option.id).bootstrapTable('showColumn', column);
$.btTable.bootstrapTable('showColumn', column);
},
// 隐藏表格指定列
hideColumn: function(column) {
$("#" + $.table._option.id).bootstrapTable('hideColumn', column);
$.btTable.bootstrapTable('hideColumn', column);
}
},
// 表格树封装处理
@@ -395,6 +418,7 @@
toolbar: "toolbar",
striped: false,
expandColumn: 1,
showSearch: true,
showRefresh: true,
showColumns: true,
expandAll: true,
@@ -402,10 +426,10 @@
};
var options = $.extend(defaults, options);
$.table._option = options;
var treeTable = $('#' + options.id).bootstrapTreeTable({
$.bttTable = $('#' + options.id).bootstrapTreeTable({
code: options.code, // 用于设置父子关系
parentCode: options.parentCode, // 用于设置父子关系
type: 'get', // 请求方式(*
type: 'post', // 请求方式(*
url: options.url, // 请求后台的URL*
ajaxParams: options.ajaxParams, // 请求数据的ajax的data属性
rootIdValue: options.rootIdValue, // 设置指定根节点id值
@@ -414,31 +438,41 @@
striped: options.striped, // 是否显示行间隔色
bordered: true, // 是否显示边框
toolbar: '#' + options.toolbar, // 指定工作栏
showSearch: options.showSearch, // 是否显示检索信息
showRefresh: options.showRefresh, // 是否显示刷新按钮
showColumns: options.showColumns, // 是否显示隐藏某列下拉框
expandAll: options.expandAll, // 是否全部展开
expandFirst: options.expandFirst, // 是否默认第一级展开--expandAll为false时生效
columns: options.columns
columns: options.columns, // 显示列信息(*
responseHandler: $.treeTable.responseHandler // 当所有数据被加载时触发处理函数
});
$._treeTable = treeTable;
},
// 条件查询
search: function(formId) {
var currentId = $.common.isEmpty(formId) ? $('form').attr('id') : formId;
var params = $.common.formToJSON(currentId);
$._treeTable.bootstrapTreeTable('refresh', params);
$.bttTable.bootstrapTreeTable('refresh', params);
},
// 刷新
refresh: function() {
$._treeTable.bootstrapTreeTable('refresh');
$.bttTable.bootstrapTreeTable('refresh');
},
// 查询表格树指定列值
selectColumns: function(column) {
var rows = $.map($('#' + $.table._option.id).bootstrapTreeTable('getSelections'), function (row) {
var rows = $.map($.bttTable.bootstrapTreeTable('getSelections'), function (row) {
return row[column];
});
return $.common.uniqueFn(rows);
},
// 请求获取数据后处理回调函数,校验异常状态提醒
responseHandler: function(data) {
if (data.code != undefined && data.code != 0) {
$.modal.alertWarning(data.msg);
return [];
} else {
return data;
}
},
},
// 表单封装处理
form: {
@@ -446,6 +480,7 @@
reset: function(formId) {
var currentId = $.common.isEmpty(formId) ? $('form').attr('id') : formId;
$("#" + currentId)[0].reset();
$.btTable.bootstrapTable('refresh');
},
// 获取选中复选框项
selectCheckeds: function(name) {
@@ -569,16 +604,16 @@
}
if ($.common.isEmpty(title)) {
title = false;
};
}
if ($.common.isEmpty(url)) {
url = "/404.html";
};
}
if ($.common.isEmpty(width)) {
width = 800;
};
}
if ($.common.isEmpty(height)) {
height = ($(window).height() - 50);
};
}
if ($.common.isEmpty(callback)) {
callback = function(index, layero) {
var iframeWin = layero.find('iframe')[0];
@@ -623,7 +658,7 @@
fix: false,
area: [_width + 'px', _height + 'px'],
content: _url,
shadeClose: true,
shadeClose: $.common.isEmpty(options.shadeClose) ? true : options.shadeClose,
skin: options.skin,
btn: $.common.isEmpty(options.btn) ? _btn : options.btn,
yes: options.yes,
@@ -641,16 +676,16 @@
}
if ($.common.isEmpty(title)) {
title = false;
};
}
if ($.common.isEmpty(url)) {
url = "/404.html";
};
}
if ($.common.isEmpty(width)) {
width = 800;
};
}
if ($.common.isEmpty(height)) {
height = ($(window).height() - 50);
};
}
var index = layer.open({
type: 2,
area: [width + 'px', height + 'px'],
@@ -677,9 +712,15 @@
openTab: function (title, url) {
createMenuItem(url, title);
},
// 选卡页同一页签打开
parentTab: function (title, url) {
var dataId = window.frameElement.getAttribute('data-id');
createMenuItem(url, title);
closeItem(dataId);
},
// 关闭选项卡
closeTab: function () {
closeItem();
closeTab: function (dataId) {
closeItem(dataId);
},
// 禁用按钮
disable: function() {
@@ -743,7 +784,7 @@
width: width,
height: height,
url: $.operate.detailUrl(id),
skin: 'layui-layer-molv',
skin: 'layui-layer-gray',
btn: ['关闭'],
yes: function (index, layero) {
layer.close(index);
@@ -814,13 +855,13 @@
},
// 添加访问地址
addUrl: function(id) {
var url = $.common.isEmpty(id) ? $.table._option.createUrl : $.table._option.createUrl.replace("{id}", id);
var url = $.common.isEmpty(id) ? $.table._option.createUrl.replace("{id}", "") : $.table._option.createUrl.replace("{id}", id);
return url;
},
// 修改信息
edit: function(id) {
if($.common.isEmpty(id) && $.table._option.type == table_type.bootstrapTreeTable) {
var row = $('#' + $.table._option.id).bootstrapTreeTable('getSelections')[0];
var row = $.bttTable.bootstrapTreeTable('getSelections')[0];
if ($.common.isEmpty(row)) {
$.modal.alertWarning("请至少选择一条记录");
return;
@@ -1,5 +1,6 @@
$(function() {
validateKickout();
validateRule();
$('.imgcode').click(function() {
var url = ctx + "captcha/captchaImage?type=" + captchaType + "&s=" + Math.random();
@@ -62,3 +63,33 @@ function validateRule() {
}
})
}
function validateKickout() {
if (getParam("kickout") == 1) {
layer.alert("<font color='red'>您已在别处登录,请您修改密码或重新登录</font>", {
icon: 0,
title: "系统提示"
},
function(index) {
//关闭弹窗
layer.close(index);
if (top != self) {
top.location = self.location;
} else {
var url  =  location.search;
if (url) {
var oldUrl  = window.location.href;
var newUrl  = oldUrl.substring(0,  oldUrl.indexOf('?'));
self.location  = newUrl;
}
}
});
}
}
function getParam(paramName) {
var reg = new RegExp("(^|&)" + paramName + "=([^&]*)(&|$)");
var r = window.location.search.substr(1).match(reg);
if (r != null) return decodeURI(r[2]);
return null;
}
@@ -0,0 +1,319 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<th:block th:include="include :: header('卡片列表')" />
</head>
<body class="gray-bg">
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-sm-4">
<div class="ibox">
<div class="ibox-title">
<span class="label label-primary pull-right">NEW</span>
<h5>IT-01 - 设计部</h5>
</div>
<div class="ibox-content">
<h4>部门简介</h4>
<p>
平面设计(graphic design),也称为视觉传达设计,是以“视觉”作为沟通和表现的方式,透过多种方式来创造和结合符号、图片和文字,借此作出用来传达想法或讯息的视觉表现。
</p>
<div>
<span>当前项目进度:</span>
<div class="stat-percent">48%</div>
<div class="progress progress-mini">
<div style="width: 48%;" class="progress-bar"></div>
</div>
</div>
<div class="row m-t-sm">
<div class="col-sm-4">
<div class="font-bold">项目</div>
12
</div>
<div class="col-sm-4">
<div class="font-bold">周期</div>
4个月
</div>
<div class="col-sm-4 text-right">
<div class="font-bold">预算</div>
&yen;200,913 <i class="fa fa-level-up text-navy"></i>
</div>
</div>
</div>
</div>
<div class="ibox">
<div class="ibox-title">
<h5>IT-04 - 市场部</h5>
</div>
<div class="ibox-content">
<h4>部门简介</h4>
<p>
平面设计(graphic design),也称为视觉传达设计,是以“视觉”作为沟通和表现的方式,透过多种方式来创造和结合符号、图片和文字,借此作出用来传达想法或讯息的视觉表现。
</p>
<div>
<span>当前项目进度:</span>
<div class="stat-percent">32%</div>
<div class="progress progress-mini">
<div style="width: 32%;" class="progress-bar"></div>
</div>
</div>
<div class="row m-t-sm">
<div class="col-sm-4">
<div class="font-bold">项目</div>
24
</div>
<div class="col-sm-4">
<div class="font-bold">周期</div>
3个月
</div>
<div class="col-sm-4 text-right">
<div class="font-bold">预算</div>
&yen;190,325 <i class="fa fa-level-up text-navy"></i>
</div>
</div>
</div>
</div>
<div class="ibox">
<div class="ibox-title">
<h5>IT-07 - 财务部</h5>
</div>
<div class="ibox-content">
<h4>部门简介</h4>
<p>
平面设计(graphic design),也称为视觉传达设计,是以“视觉”作为沟通和表现的方式,透过多种方式来创造和结合符号、图片和文字,借此作出用来传达想法或讯息的视觉表现。
</p>
<div>
<span>当前项目进度:</span>
<div class="stat-percent">73%</div>
<div class="progress progress-mini">
<div style="width: 73%;" class="progress-bar"></div>
</div>
</div>
<div class="row m-t-sm">
<div class="col-sm-4">
<div class="font-bold">项目</div>
11
</div>
<div class="col-sm-4">
<div class="font-bold">周期</div>
6个月
</div>
<div class="col-sm-4 text-right">
<div class="font-bold">预算</div>
&yen;560,105 <i class="fa fa-level-up text-navy"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-sm-4">
<div class="ibox">
<div class="ibox-title">
<h5>IT-02 - 开发部</h5>
</div>
<div class="ibox-content">
<h4>部门简介</h4>
<p>
平面设计(graphic design),也称为视觉传达设计,是以“视觉”作为沟通和表现的方式,透过多种方式来创造和结合符号、图片和文字,借此作出用来传达想法或讯息的视觉表现。
</p>
<div>
<span>当前项目进度:</span>
<div class="stat-percent">61%</div>
<div class="progress progress-mini">
<div style="width: 61%;" class="progress-bar"></div>
</div>
</div>
<div class="row m-t-sm">
<div class="col-sm-4">
<div class="font-bold">项目</div>
43
</div>
<div class="col-sm-4">
<div class="font-bold">周期</div>
1个月
</div>
<div class="col-sm-4 text-right">
<div class="font-bold">预算</div>
&yen;705,913 <i class="fa fa-level-up text-navy"></i>
</div>
</div>
</div>
</div>
<div class="ibox">
<div class="ibox-title">
<span class="label label-warning pull-right">截止</span>
<h5>IT-05 - 管理层</h5>
</div>
<div class="ibox-content">
<h4>部门简介</h4>
<p>
平面设计(graphic design),也称为视觉传达设计,是以“视觉”作为沟通和表现的方式,透过多种方式来创造和结合符号、图片和文字,借此作出用来传达想法或讯息的视觉表现。
</p>
<div>
<span>当前项目进度:</span>
<div class="stat-percent">14%</div>
<div class="progress progress-mini">
<div style="width: 14%;" class="progress-bar"></div>
</div>
</div>
<div class="row m-t-sm">
<div class="col-sm-4">
<div class="font-bold">项目</div>
8
</div>
<div class="col-sm-4">
<div class="font-bold">周期</div>
7个月
</div>
<div class="col-sm-4 text-right">
<div class="font-bold">预算</div>
&yen;40,200 <i class="fa fa-level-up text-navy"></i>
</div>
</div>
</div>
</div>
<div class="ibox">
<div class="ibox-title">
<h5>IT-08 - 销售部</h5>
</div>
<div class="ibox-content">
<h4>部门简介</h4>
<p>
平面设计(graphic design),也称为视觉传达设计,是以“视觉”作为沟通和表现的方式,透过多种方式来创造和结合符号、图片和文字,借此作出用来传达想法或讯息的视觉表现。
</p>
<div>
<span>当前项目进度:</span>
<div class="stat-percent">25%</div>
<div class="progress progress-mini">
<div style="width: 25%;" class="progress-bar"></div>
</div>
</div>
<div class="row m-t-sm">
<div class="col-sm-4">
<div class="font-bold">项目</div>
25
</div>
<div class="col-sm-4">
<div class="font-bold">周期</div>
4个月
</div>
<div class="col-sm-4 text-right">
<div class="font-bold">预算</div>
&yen;140,105 <i class="fa fa-level-up text-navy"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-sm-4">
<div class="ibox">
<div class="ibox-title">
<h5>IT-02 - 销售部</h5>
</div>
<div class="ibox-content">
<h4>部门简介</h4>
<p>
平面设计(graphic design),也称为视觉传达设计,是以“视觉”作为沟通和表现的方式,透过多种方式来创造和结合符号、图片和文字,借此作出用来传达想法或讯息的视觉表现。
</p>
<div>
<span>当前项目进度:</span>
<div class="stat-percent">82%</div>
<div class="progress progress-mini">
<div style="width: 82%;" class="progress-bar"></div>
</div>
</div>
<div class="row m-t-sm">
<div class="col-sm-4">
<div class="font-bold">项目</div>
68
</div>
<div class="col-sm-4">
<div class="font-bold">周期</div>
2个月
</div>
<div class="col-sm-4 text-right">
<div class="font-bold">预算</div>
&yen;701,400 <i class="fa fa-level-up text-navy"></i>
</div>
</div>
</div>
</div>
<div class="ibox">
<div class="ibox-title">
<h5>IT-06 - 销售部</h5>
</div>
<div class="ibox-content">
<h4>部门简介</h4>
<p>
平面设计(graphic design),也称为视觉传达设计,是以“视觉”作为沟通和表现的方式,透过多种方式来创造和结合符号、图片和文字,借此作出用来传达想法或讯息的视觉表现。
</p>
<div>
<span>当前项目进度:</span>
<div class="stat-percent">26%</div>
<div class="progress progress-mini">
<div style="width: 26%;" class="progress-bar"></div>
</div>
</div>
<div class="row m-t-sm">
<div class="col-sm-4">
<div class="font-bold">项目</div>
16
</div>
<div class="col-sm-4">
<div class="font-bold">周期</div>
8个月
</div>
<div class="col-sm-4 text-right">
<div class="font-bold">预算</div>
&yen;160,100 <i class="fa fa-level-up text-navy"></i>
</div>
</div>
</div>
</div>
<div class="ibox">
<div class="ibox-title">
<h5>IT-09 - 销售部</h5>
</div>
<div class="ibox-content">
<h4>部门简介</h4>
<p>
平面设计(graphic design),也称为视觉传达设计,是以“视觉”作为沟通和表现的方式,透过多种方式来创造和结合符号、图片和文字,借此作出用来传达想法或讯息的视觉表现。
</p>
<div>
<span>当前项目进度:</span>
<div class="stat-percent">18%</div>
<div class="progress progress-mini">
<div style="width: 18%;" class="progress-bar"></div>
</div>
</div>
<div class="row m-t-sm">
<div class="col-sm-4">
<div class="font-bold">项目</div>
53
</div>
<div class="col-sm-4">
<div class="font-bold">周期</div>
9个月
</div>
<div class="col-sm-4 text-right">
<div class="font-bold">预算</div>
&yen;60,140 <i class="fa fa-level-up text-navy"></i>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<th:block th:include="include :: footer" />
</body>
</html>
@@ -183,7 +183,8 @@
laydate.render({
elem: '#laydate-demo-3',
type: 'datetime'
type: 'datetime',
trigger: 'click'
});
laydate.render({
@@ -144,116 +144,5 @@
<th:block th:include="include :: footer" />
<th:block th:include="include :: select2-js" />
<th:block th:include="include :: bootstrap-select-js" />
<script type="text/javascript">
$(function(){
<!-- datetimepicker示例 -->
$("#datetimepicker-demo-1").datetimepicker();
$("#datetimepicker-demo-2").datetimepicker({
format: "yyyy-mm-dd",
minView: "month",
autoclose: true
});
$("#datetimepicker-demo-3").datetimepicker({
format: "yyyy-mm-dd hh:ii:ss",
autoclose: true
});
$('.form_date').datetimepicker({
format: "yyyy-mm-dd",
minView: "month",
autoclose: true
});
$("#datetimepicker-startTime").datetimepicker({
format: 'yyyy-mm-dd',
minView: "month",
todayBtn: true,
autoclose: true,
endDate : new Date(),
}).on('changeDate', function(event) {
event.preventDefault();
event.stopPropagation();
var startTime = event.date;
$('#datetimepicker-endTime').datetimepicker('setStartDate', startTime);
});
$("#datetimepicker-endTime").datetimepicker({
format: 'yyyy-mm-dd',
minView: "month",
todayBtn: true,
autoclose: true,
endDate : new Date(),
}).on('changeDate', function(event) {
event.preventDefault();
event.stopPropagation();
var endTime = event.date;
$("#datetimepicker-startTime").datetimepicker('setEndDate', endTime);
});
<!-- laydate示例 -->
layui.use('laydate', function(){
var laydate = layui.laydate;
laydate.render({
elem: '#laydate-demo-1'
});
laydate.render({
elem: '#laydate-demo-2',
type: 'date'
});
laydate.render({
elem: '#laydate-demo-3',
type: 'datetime'
});
laydate.render({
elem: '#laydate-demo-4',
range: true
});
var startDate = laydate.render({
elem: '#laydate-startTime',
max: $('#laydate-endTime').val(),
theme: 'molv',
trigger: 'click',
done: function(value, date) {
// 结束时间大于开始时间
if (value !== '') {
endDate.config.min.year = date.year;
endDate.config.min.month = date.month - 1;
endDate.config.min.date = date.date;
} else {
endDate.config.min.year = '';
endDate.config.min.month = '';
endDate.config.min.date = '';
}
}
});
var endDate = laydate.render({
elem: '#laydate-endTime',
min: $('#laydate-startTime').val(),
theme: 'molv',
trigger: 'click',
done: function(value, date) {
// 开始时间小于结束时间
if (value !== '') {
startDate.config.max.year = date.year;
startDate.config.max.month = date.month - 1;
startDate.config.max.date = date.date;
} else {
startDate.config.max.year = '';
startDate.config.max.month = '';
startDate.config.max.date = '';
}
}
});
});
});
</script>
</body>
</html>
@@ -0,0 +1,93 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<th:block th:include="include :: header('Summernote富文本编辑器')" />
<th:block th:include="include :: summernote-css" />
</head>
<body class="gray-bg">
<div class="wrapper wrapper-content">
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>Summernote 富文本编辑器</h5>
</div>
<div class="ibox-content no-padding">
<div class="summernote">
<h2>若依后台管理系统</h2>
<p>ruoyi是一个完全响应式,基于Bootstrap3.3.6最新版本开发的扁平化主题,她采用了主流的左右两栏式布局,使用了Html5+CSS3等现代技术,她提供了诸多的强大的可以重新组合的UI组件,并集成了最新的jQuery版本(v2.1.1),当然,也集成了很多功能强大,用途广泛的就jQuery插件,她可以用于所有的Web应用程序,如<b>网站管理后台</b><b>网站会员中心</b><b>CMS</b><b>CRM</b><b>OA</b>等等,当然,您也可以对她进行深度定制,以做出更强系统。</p>
<p>
<b>当前版本:</b>v4.0.0
</p>
<p>
<span class="label label-warning">免费开源</span>
</p>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="ibox-content">
<h2>Summernote</h2>
<p>
Summernote是一个简单的基于Bootstrap的WYSIWYG富文本编辑器
</p>
<div class="alert alert-warning"> 官方文档请参考:
<a href="https://github.com/summernote/summernote">https://github.com/summernote/summernote</a>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>编辑/保存为html代码示例</h5>
<button id="edit" class="btn btn-primary btn-xs m-l-sm" onclick="edit()" type="button">编辑</button>
<button id="save" class="btn btn-primary btn-xs" onclick="save()" type="button">保存</button>
</div>
<div class="ibox-content" id="eg">
<div class="click2edit wrapper">
<h3>你好,若依 </h3>
<p>H+是一个完全响应式,基于Bootstrap3.3.6最新版本开发的扁平化主题,她采用了主流的左右两栏式布局,使用了Html5+CSS3等现代技术,她提供了诸多的强大的可以重新组合的UI组件,并集成了最新的jQuery版本(v2.1.1),当然,也集成了很多功能强大,用途广泛的就jQuery插件,她可以用于所有的Web应用程序,如<b>网站管理后台</b><b>网站会员中心</b><b>CMS</b><b>CRM</b><b>OA</b>等等,当然,您也可以对她进行深度定制,以做出更强系统。</p>
<p>
<b>当前版本:</b>v4.0.0
</p>
<p>
<span class="label label-warning">开源免费</span>
</p>
</div>
</div>
</div>
</div>
</div>
</div>
<th:block th:include="include :: footer" />
<th:block th:include="include :: summernote-js" />
<script>
$(document).ready(function () {
$('.summernote').summernote({
lang: 'zh-CN'
});
});
var edit = function () {
$("#eg").addClass("no-padding");
$('.click2edit').summernote({
lang: 'zh-CN',
focus: true
});
};
var save = function () {
$("#eg").removeClass("no-padding");
var aHTML = $('.click2edit').summernote('code');
$('.click2edit').summernote('destroy');
};
</script>
</body>
</html>
@@ -74,7 +74,7 @@
下面这个示例展示了如何在表单向导中使用 jQuery Validation 插件
</p>
<form id="form" action="http://www.zi-han.net/theme/hplus/form_wizard.html#" class="wizard-big">
<form id="form" action="" class="wizard-big">
<h1>账户</h1>
<fieldset>
<h2>账户信息</h2>
@@ -4,7 +4,7 @@
<th:block th:include="include :: header('新增用户')" />
</head>
<body>
<div class="form-content">
<div class="main-content">
<form id="form-user-add" class="form-horizontal">
<div class="row">
<div class="col-sm-6">
@@ -85,8 +85,10 @@
</div>
<div class="ibox-content">
<p>通过调用<code>$.modal.openTab()</code>实现。 </p>
<button type="button" class="btn btn-primary" id="button-open-6">打开</button>
<button type="button" class="btn btn-warning" id="button-open-7">关闭</button>
<button type="button" class="btn btn-primary" id="button-open-6">新窗口打开</button>
<button type="button" class="btn btn-warning" id="button-open-7">关闭当前</button>
<button type="button" class="btn btn-primary" id="button-open-14">选卡页同一页签打开</button>
<button type="button" class="btn btn-warning" id="button-open-15">关闭指定</button>
</div>
</div>
</div>
@@ -240,6 +242,15 @@
$("#button-open-13").click(function(){
layer.load(0, {shade: false}); // 0代表加载的风格,支持0-2
})
$("#button-open-14").click(function(){
$.modal.parentTab('添加用户', prefix + "/form");
})
$("#button-open-15").click(function(){
// 需要关闭窗口的url
$.modal.closeTab(prefix + "/form");
})
</script>
</body>
</html>
@@ -44,7 +44,7 @@
<label class="col-sm-3 control-label">用户状态:</label>
<div class="col-sm-8">
<div class="radio-box" th:each="dict : ${@dict.getType('sys_normal_disable')}">
<input type="radio" th:id="${dict.dictCode}" name="status" th:value="${dict.dictValue}" th:checked="${dict.isDefault == 'Y' ? true : false}">
<input type="radio" th:id="${dict.dictCode}" name="status" th:value="${dict.dictValue}" th:checked="${dict.default}">
<label th:for="${dict.dictCode}" th:text="${dict.dictLabel}"></label>
</div>
</div>
@@ -3,7 +3,75 @@
<head>
<th:block th:include="include :: header('其他操作')" />
</head>
<body class="gray-bg">
<body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal" id="form-demo-1">
<div class="form-group">
<label class="col-sm-2 control-label">用户名称:</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="userName"placeholder="请输入用户名称">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">手机号码:</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="phonenumber" maxlength="11"placeholder="请输入手机号码">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="button" class="btn btn-sm btn-primary" onclick="submit1()"><i class="fa fa-check"></i>保 存(不刷新当前页)</button>&nbsp;
</div>
</div>
</form>
<hr/>
<form class="form-horizontal" id="form-demo-2">
<div class="form-group">
<label class="col-sm-2 control-label">用户名称:</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="userName"placeholder="请输入用户名称">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">手机号码:</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="phonenumber" maxlength="11"placeholder="请输入手机号码">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="button" class="btn btn-sm btn-primary" onclick="submit2()"><i class="fa fa-check"></i>保 存(刷新当前页)</button>&nbsp;
</div>
</div>
</form>
</div>
<th:block th:include="include :: footer" />
<script type="text/javascript">
var prefix = ctx + "demo/operate";
function submit1(){
$.operate.saveModal(prefix + "/edit", $('#form-demo-1').serialize());
}
function submit2(){
$.ajax({
url: prefix + "/edit",
data: $('#form-demo-2').serialize(),
type: "post",
success: function(result) {
if (result.code == 0) {
layer.msg("保存成功,正在刷新数据请稍后……", {
icon: 1,
time: 500,
shade: [0.1, '#8F8F8F']
},function() {
location.reload();
});
} else {
alert(result.msg);
}
}
})
}
</script>
</body>
</html>
@@ -9,10 +9,10 @@
<a class="btn btn-success" onclick="$.operate.add()">
<i class="fa fa-plus"></i> 新增
</a>
<a class="btn btn-primary btn-edit disabled" onclick="$.operate.edit()">
<a class="btn btn-primary single disabled" onclick="$.operate.edit()">
<i class="fa fa-edit"></i> 修改
</a>
<a class="btn btn-danger btn-del disabled" onclick="$.operate.removeAll()">
<a class="btn btn-danger multiple disabled" onclick="$.operate.removeAll()">
<i class="fa fa-remove"></i> 删除
</a>
<a class="btn btn-info" onclick="$.table.importExcel()">
@@ -21,7 +21,7 @@
<a class="btn btn-warning" onclick="$.table.exportExcel()">
<i class="fa fa-download"></i> 导出
</a>
<a class="btn btn-info btn-detail disabled" onclick="$.operate.detail()">
<a class="btn btn-info single disabled" onclick="$.operate.detail()">
<i class="fa fa-search"></i> 详细
</a>
<a class="btn btn-danger" onclick="$.operate.clean()">
@@ -108,7 +108,8 @@
</script>
</body>
<!-- 导入区域 -->
<form id="importForm" enctype="multipart/form-data" class="mt20 mb10" style="display: none;">
<script id="importTpl" type="text/template">
<form enctype="multipart/form-data" class="mt20 mb10">
<div class="col-xs-offset-1">
<input type="file" id="file" name="file"/>
<div class="mt10 pt5">
@@ -120,4 +121,5 @@
</font>
</div>
</form>
</script>
</html>
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,478 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<th:block th:include="include :: header('图表组合')" />
</head>
<body class="gray-bg">
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-sm-3">
<div class="ibox">
<div class="ibox-content">
<h5 class="m-b-md">Q1 销量</h5>
<h2 class="text-navy">
<i class="fa fa-play fa-rotate-270"></i> 上升
</h2>
<small>更新时间:12天以前</small>
</div>
</div>
</div>
<div class="col-sm-3">
<div class="ibox">
<div class="ibox-content ">
<h5 class="m-b-md">Q2 销量</h5>
<h2 class="text-navy">
<i class="fa fa-play fa-rotate-270"></i> 上升
</h2>
<small>更新时间:12天以前</small>
</div>
</div>
</div>
<div class="col-sm-3">
<div class="ibox">
<div class="ibox-content">
<h5 class="m-b-md">Q3 销量</h5>
<h2 class="text-danger">
<i class="fa fa-play fa-rotate-90"></i> 下降
</h2>
<small>更新时间:12天以前</small>
</div>
</div>
</div>
<div class="col-sm-3">
<div class="ibox">
<div class="ibox-content">
<h5 class="m-b-md">Q4 销量</h5>
<h2 class="text-danger">
<i class="fa fa-play fa-rotate-90"></i> 下降
</h2>
<small>更新时间:12天以前</small>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-3">
<div class="ibox">
<div class="ibox-content">
<h5>本日访问量</h5>
<h2>198 009</h2>
<div id="sparkline1"></div>
</div>
</div>
</div>
<div class="col-sm-3">
<div class="ibox">
<div class="ibox-content">
<h5>本周访问量</h5>
<h2>65 000</h2>
<div id="sparkline2"></div>
</div>
</div>
</div>
<div class="col-sm-3">
<div class="ibox">
<div class="ibox-content">
<h5>本月访问量</h5>
<h2>680 900</h2>
<div id="sparkline3"></div>
</div>
</div>
</div>
<div class="col-sm-3">
<div class="ibox">
<div class="ibox-content">
<h5>平均停留时间</h5>
<h2>00:06:40</h2>
<div id="sparkline4"></div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-3">
<div class="ibox">
<div class="ibox-content">
<h5>使用率</h5>
<h2>65%</h2>
<div class="progress progress-mini">
<div style="width: 68%;" class="progress-bar"></div>
</div>
<div class="m-t-sm small">4:32更新</div>
</div>
</div>
</div>
<div class="col-sm-3">
<div class="ibox">
<div class="ibox-content">
<h5>使用率</h5>
<h2>50%</h2>
<div class="progress progress-mini">
<div style="width: 78%;" class="progress-bar"></div>
</div>
<div class="m-t-sm small">4:32更新</div>
</div>
</div>
</div>
<div class="col-sm-3">
<div class="ibox">
<div class="ibox-content">
<h5>使用率</h5>
<h2>14%</h2>
<div class="progress progress-mini">
<div style="width: 38%;" class="progress-bar progress-bar-danger"></div>
</div>
<div class="m-t-sm small">4:32更新</div>
</div>
</div>
</div>
<div class="col-sm-3">
<div class="ibox">
<div class="ibox-content">
<h5>使用率</h5>
<h2>20%</h2>
<div class="progress progress-mini">
<div style="width: 28%;" class="progress-bar progress-bar-danger"></div>
</div>
<div class="m-t-sm small">4:32更新</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-3">
<div class="ibox">
<div class="ibox-content">
<h5>百分比</h5>
<h2>42/20</h2>
<div class="text-center">
<div id="sparkline5"></div>
</div>
</div>
</div>
</div>
<div class="col-sm-3">
<div class="ibox">
<div class="ibox-content">
<h5>百分比</h5>
<h2>100/54</h2>
<div class="text-center">
<div id="sparkline6"></div>
</div>
</div>
</div>
</div>
<div class="col-sm-3">
<div class="ibox">
<div class="ibox-content">
<h5>百分比</h5>
<h2>685/211</h2>
<div class="text-center">
<div id="sparkline7"></div>
</div>
</div>
</div>
</div>
<div class="col-sm-3">
<div class="ibox">
<div class="ibox-content">
<h5>百分比</h5>
<h2>240/32</h2>
<div class="text-center">
<div id="sparkline8"></div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-3">
<div class="ibox">
<div class="ibox-content">
<h5>收入</h5>
<h1 class="no-margins">886,200</h1>
<div class="stat-percent font-bold text-navy">98% <i class="fa fa-bolt"></i></div>
<small>总收入</small>
</div>
</div>
</div>
<div class="col-sm-3">
<div class="ibox">
<div class="ibox-content">
<h5>本月收入</h5>
<h1 class="no-margins">1 738,200</h1>
<div class="stat-percent font-bold text-navy">98% <i class="fa fa-bolt"></i></div>
<small>总收入</small>
</div>
</div>
</div>
<div class="col-sm-3">
<div class="ibox">
<div class="ibox-content">
<h5>本日收入</h5>
<h1 class="no-margins">-200,100</h1>
<div class="stat-percent font-bold text-danger">12% <i class="fa fa-level-down"></i></div>
<small>总收入</small>
</div>
</div>
</div>
<div class="col-sm-3">
<div class="ibox">
<div class="ibox-content">
<h5>搜索有收入</h5>
<h1 class="no-margins">54,200</h1>
<div class="stat-percent font-bold text-danger">24% <i class="fa fa-level-down"></i></div>
<small>总收入</small>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-3">
<div class="ibox">
<div class="ibox-content">
<h5>预警</h5>
<table class="table table-stripped small m-t-md">
<tbody>
<tr>
<td class="no-borders">
<i class="fa fa-circle text-navy"></i>
</td>
<td class="no-borders">
示例 01
</td>
</tr>
<tr>
<td>
<i class="fa fa-circle text-navy"></i>
</td>
<td>
示例 02
</td>
</tr>
<tr>
<td>
<i class="fa fa-circle text-navy"></i>
</td>
<td>
示例 03
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="col-sm-3">
<div class="ibox">
<div class="ibox-content">
<h5>项目</h5>
<table class="table table-stripped small m-t-md">
<tbody>
<tr>
<td class="no-borders">
<i class="fa fa-circle text-navy"></i>
</td>
<td class="no-borders">
示例 01
</td>
</tr>
<tr>
<td>
<i class="fa fa-circle text-navy"></i>
</td>
<td>
示例 02
</td>
</tr>
<tr>
<td>
<i class="fa fa-circle text-navy"></i>
</td>
<td>
示例 03
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="col-sm-3">
<div class="ibox">
<div class="ibox-content">
<h5>消息</h5>
<table class="table table-stripped small m-t-md">
<tbody>
<tr>
<td class="no-borders">
<i class="fa fa-circle text-danger"></i>
</td>
<td class="no-borders">
示例 01
</td>
</tr>
<tr>
<td>
<i class="fa fa-circle text-danger"></i>
</td>
<td>
示例 02
</td>
</tr>
<tr>
<td>
<i class="fa fa-circle text-danger"></i>
</td>
<td>
示例 03
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="col-sm-3">
<div class="ibox">
<div class="ibox-content">
<h5>通知</h5>
<table class="table table-stripped small m-t-md">
<tbody>
<tr>
<td class="no-borders">
<i class="fa fa-circle text-danger"></i>
</td>
<td class="no-borders">
示例 01
</td>
</tr>
<tr>
<td>
<i class="fa fa-circle text-danger"></i>
</td>
<td>
示例 02
</td>
</tr>
<tr>
<td>
<i class="fa fa-circle text-danger"></i>
</td>
<td>
示例 03
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<th:block th:include="include :: footer" />
<th:block th:include="include :: peity-js" />
<th:block th:include="include :: sparkline-js" />
<script type="text/javascript">
$(document).ready(function () {
$("#sparkline1").sparkline([34, 43, 43, 35, 44, 32, 44, 52], {
type: 'line',
width: '100%',
height: '60',
lineColor: '#1ab394',
fillColor: "#ffffff"
});
$("#sparkline2").sparkline([24, 43, 43, 55, 44, 62, 44, 72], {
type: 'line',
width: '100%',
height: '60',
lineColor: '#1ab394',
fillColor: "#ffffff"
});
$("#sparkline3").sparkline([74, 43, 23, 55, 54, 32, 24, 12], {
type: 'line',
width: '100%',
height: '60',
lineColor: '#ed5565',
fillColor: "#ffffff"
});
$("#sparkline4").sparkline([24, 43, 33, 55, 64, 72, 44, 22], {
type: 'line',
width: '100%',
height: '60',
lineColor: '#ed5565',
fillColor: "#ffffff"
});
$("#sparkline5").sparkline([1, 4], {
type: 'pie',
height: '140',
sliceColors: ['#1ab394', '#F5F5F5']
});
$("#sparkline6").sparkline([5, 3], {
type: 'pie',
height: '140',
sliceColors: ['#1ab394', '#F5F5F5']
});
$("#sparkline7").sparkline([2, 2], {
type: 'pie',
height: '140',
sliceColors: ['#ed5565', '#F5F5F5']
});
$("#sparkline8").sparkline([2, 3], {
type: 'pie',
height: '140',
sliceColors: ['#ed5565', '#F5F5F5']
});
});
$(function() {
$("span.pie").peity("pie", {
fill: ['#1ab394', '#d7d7d7', '#ffffff']
})
$(".line").peity("line",{
fill: '#1ab394',
stroke:'#169c81',
})
$(".bar").peity("bar", {
fill: ["#1ab394", "#d7d7d7"]
})
$(".bar_dashboard").peity("bar", {
fill: ["#1ab394", "#d7d7d7"],
width:100
})
var updatingChart = $(".updating-chart").peity("line", { fill: '#1ab394',stroke:'#169c81', width: 64 })
setInterval(function() {
var random = Math.round(Math.random() * 10)
var values = updatingChart.text().split(",")
values.shift()
values.push(random)
updatingChart
.text(values.join(","))
.change()
}, 1000);
});
</script>
</body>
</html>
@@ -0,0 +1,206 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<th:block th:include="include :: header('图表')" />
</head>
<body class="gray-bg">
<div class="wrapper wrapper-content animated fadeInDown">
<div class="row">
<div class="col-sm-5">
<div class="jumbotron">
<h1>Peity图表</h1>
<p>是一个内嵌数据图形可视化的图表库</p>
<p><a href="http://benpickles.github.io/peity/" target="_blank" class="btn btn-primary btn-lg" role="button">了解 Peity</a>
</p>
</div>
</div>
<div class="col-sm-7">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>饼状图 <small>自定义颜色</small></h5>
<div class="ibox-tools">
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div>
<table class="table table-bordered white-bg">
<thead>
<tr>
<th>图表</th>
<th>代码</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<span class="pie">1/5</span>
</td>
<td>
<code>&lt;span class="pie"&gt;1/5&lt;/span&gt;</code>
</td>
</tr>
<tr>
<td>
<span class="pie">226/360</span>
</td>
<td>
<code>&lt;span class="pie"&gt;226/360&lt;/span&gt;</code>
</td>
</tr>
<tr>
<td>
<span class="pie">0.52/1.561</span>
</td>
<td>
<code>&lt;span class="pie"&gt;0.52/1.561&lt;/span&gt;</code>
</td>
</tr>
<tr>
<td>
<span class="pie">1,4</span>
</td>
<td>
<code>&lt;span class="pie"&gt;1,4&lt;/span&gt;</code>
</td>
</tr>
<tr>
<td>
<span class="pie">226,134</span>
</td>
<td>
<code>&lt;span class="pie"&gt;226,134&lt;/span&gt;</code>
</td>
</tr>
<tr>
<td>
<span class="pie">0.52,1.041</span>
</td>
<td>
<code>&lt;span class="pie"&gt;0.52,1.041&lt;/span&gt;</code>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>线性图</h5>
<div class="ibox-tools">
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div>
<table class="table table-bordered white-bg">
<thead>
<tr>
<th>图表</th>
<th>代码</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<span data-diameter="40" class="updating-chart">5,3,9,6,5,9,7,3,5,2,5,3,9,6,5,9,7,3,5,2</span>
</td>
<td>
<code>&lt;span class="line"&gt;5,3,9,6,5,9,7,3,5,2&lt;/span&gt;</code>
</td>
</tr>
<tr>
<td>
<span class="line">5,3,9,6,5,9,7,3,5,2</span>
</td>
<td>
<code>&lt;span class="line"&gt;5,3,9,6,5,9,7,3,5,2&lt;/span&gt;</code>
</td>
</tr>
<tr>
<td>
<span class="line">5,3,2,-1,-3,-2,2,3,5,2</span>
</td>
<td>
<code>&lt;span class="line"&gt;5,3,2,-1,-3,-2,2,3,5,2&lt;/span&gt;</code>
</td>
</tr>
<tr>
<td>
<span class="line">0,-3,-6,-4,-5,-4,-7,-3,-5,-2</span>
</td>
<td>
<code>&lt;span class="line"&gt;0,-3,-6,-4,-5,-4,-7,-3,-5,-2&lt;/span&gt;</code>
</td>
</tr>
<tr>
<td>
<span class="bar">5,3,9,6,5,9,7,3,5,2</span>
</td>
<td>
<code>&lt;span class="bar"&gt;5,3,9,6,5,9,7,3,5,2&lt;/span&gt;</code>
</td>
</tr>
<tr>
<td>
<span class="bar">5,3,2,-1,-3,-2,2,3,5,2</span>
</td>
<td>
<code>&lt;span class="bar"&gt;5,3,2,-1,-3,-2,2,3,5,2&lt;/span&gt;</code>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<th:block th:include="include :: footer" />
<th:block th:include="include :: peity-js" />
<script type="text/javascript">
$(function() {
$("span.pie").peity("pie", {
fill: ['#1ab394', '#d7d7d7', '#ffffff']
})
$(".line").peity("line",{
fill: '#1ab394',
stroke:'#169c81',
})
$(".bar").peity("bar", {
fill: ["#1ab394", "#d7d7d7"]
})
$(".bar_dashboard").peity("bar", {
fill: ["#1ab394", "#d7d7d7"],
width:100
})
var updatingChart = $(".updating-chart").peity("line", { fill: '#1ab394',stroke:'#169c81', width: 64 })
setInterval(function() {
var random = Math.round(Math.random() * 10)
var values = updatingChart.text().split(",")
values.shift()
values.push(random)
updatingChart
.text(values.join(","))
.change()
}, 1000);
});
</script>
</body>
</html>
@@ -0,0 +1,232 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<th:block th:include="include :: header('线状图')" />
</head>
<body class="gray-bg">
<div class="wrapper wrapper-content animated fadeInDown">
<div class="row">
<div class="col-sm-5">
<div class="jumbotron">
<h1>Sparkline</h1>
<p>这是另一个可视化图表库</p>
<p><a href="http://omnipotent.net/jquery.sparkline" target="_blank" class="btn btn-primary btn-lg" role="button">了解 Sparkline</a>
</p>
</div>
</div>
<div class="col-sm-7">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>Sparkline图表 <small>自定义颜色</small></h5>
<div class="ibox-tools">
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div>
<table class="table table-bordered white-bg">
<thead>
<tr>
<th>图表</th>
<th>类型</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<span id="sparkline1"></span>
</td>
<td>
内联线性图
</td>
</tr>
<tr>
<td>
<span id="sparkline2"></span>
</td>
<td>
柱状图
</td>
</tr>
<tr>
<td>
<span id="sparkline3"></span>
</td>
<td>
饼状图
</td>
</tr>
<tr>
<td>
<span id="sparkline4"></span>
</td>
<td>
长线性图
</td>
</tr>
<tr>
<td>
<span id="sparkline5"></span>
</td>
<td>
三态图
</td>
</tr>
<tr>
<td>
<span id="sparkline6"></span>
</td>
<td>
散点图
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-4">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>自定义饼状图尺寸</h5>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="graph_sparkline.html#">
<i class="fa fa-wrench"></i>
</a>
<ul class="dropdown-menu dropdown-user">
<li><a href="graph_sparkline.html#">选项1</a>
</li>
<li><a href="graph_sparkline.html#">选项2</a>
</li>
</ul>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content text-center h-200">
<span id="sparkline7"></span>
</div>
</div>
</div>
<div class="col-sm-4">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>自定义柱状图尺寸</h5>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="graph_sparkline.html#">
<i class="fa fa-wrench"></i>
</a>
<ul class="dropdown-menu dropdown-user">
<li><a href="graph_sparkline.html#">选项1</a>
</li>
<li><a href="graph_sparkline.html#">选项2</a>
</li>
</ul>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content text-center h-200">
<span id="sparkline8"></span>
</div>
</div>
</div>
<div class="col-sm-4">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>自定义线性图尺寸</h5>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="graph_sparkline.html#">
<i class="fa fa-wrench"></i>
</a>
<ul class="dropdown-menu dropdown-user">
<li><a href="graph_sparkline.html#">选项1</a>
</li>
<li><a href="graph_sparkline.html#">选项2</a>
</li>
</ul>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content text-center h-200">
<span id="sparkline9"></span>
</div>
</div>
</div>
</div>
</div>
<th:block th:include="include :: footer" />
<th:block th:include="include :: sparkline-js" />
<script type="text/javascript">
$(function () {
$("#sparkline1").sparkline([34, 43, 43, 35, 44, 32, 44, 52, 25], {
type: 'line',
lineColor: '#17997f',
fillColor: '#1ab394',
});
$("#sparkline2").sparkline([5, 6, 7, 2, 0, -4, -2, 4], {
type: 'bar',
barColor: '#1ab394',
negBarColor: '#c6c6c6'});
$("#sparkline3").sparkline([1, 1, 2], {
type: 'pie',
sliceColors: ['#1ab394', '#b3b3b3', '#e4f0fb']});
$("#sparkline4").sparkline([34, 43, 43, 35, 44, 32, 15, 22, 46, 33, 86, 54, 73, 53, 12, 53, 23, 65, 23, 63, 53, 42, 34, 56, 76, 15, 54, 23, 44], {
type: 'line',
lineColor: '#17997f',
fillColor: '#ffffff',
});
$("#sparkline5").sparkline([1, 1, 0, 1, -1, -1, 1, -1, 0, 0, 1, 1], {
type: 'tristate',
posBarColor: '#1ab394',
negBarColor: '#bfbfbf'});
$("#sparkline6").sparkline([4, 6, 7, 7, 4, 3, 2, 1, 4, 4, 5, 6, 3, 4, 5, 8, 7, 6, 9, 3, 2, 4, 1, 5, 6, 4, 3, 7, ], {
type: 'discrete',
lineColor: '#1ab394'});
$("#sparkline7").sparkline([52, 12, 44], {
type: 'pie',
height: '150px',
sliceColors: ['#1ab394', '#b3b3b3', '#e4f0fb']});
$("#sparkline8").sparkline([5, 6, 7, 2, 0, 4, 2, 4, 5, 7, 2, 4, 12, 14, 4, 2, 14, 12, 7], {
type: 'bar',
barWidth: 8,
height: '150px',
barColor: '#1ab394',
negBarColor: '#c6c6c6'});
$("#sparkline9").sparkline([34, 43, 43, 35, 44, 32, 15, 22, 46, 33, 86, 54, 73, 53, 12, 53, 23, 65, 23, 63, 53, 42, 34, 56, 76, 15, 54, 23, 44], {
type: 'line',
lineWidth: 1,
height: '150px',
lineColor: '#17997f',
fillColor: '#ffffff',
});
});
</script>
</body>
</html>
@@ -0,0 +1,178 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<th:block th:include="include :: header('动态增删改查')" />
</head>
<body class="gray-bg">
<div class="container-div">
<div class="btn-group-sm" id="toolbar" role="group">
<a class="btn btn-success" onclick="insertRow()">
<i class="fa fa-plus"></i> 新增行
</a>
<a class="btn btn-danger multiple disabled" onclick="removeRow()">
<i class="fa fa-remove"></i> 删除选择行
</a>
<a class="btn btn-danger" onclick="removeRowByUniqueId()">
<i class="fa fa-remove"></i> 根据值删除行
</a>
<a class="btn btn-danger" onclick="removeRowAll()">
<i class="fa fa-remove"></i> 删除所有行
</a>
<a class="btn btn-info" onclick="updateRow()">
<i class="fa fa-edit"></i> 修改行
</a>
<a class="btn btn-info" onclick="updateRowByUniqueId()">
<i class="fa fa-edit"></i> 根据值修改行
</a>
<a class="btn btn-info" onclick="getSelections()">
<i class="fa fa-search"></i> 查询选择数据
</a>
<a class="btn btn-info" onclick="getRowByUniqueId()">
<i class="fa fa-search"></i> 根据值查询行
</a>
<a class="btn btn-primary" onclick="getData()">
<i class="fa fa-search"></i> 查询所有数据
</a>
</div>
<div class="row">
<div class="col-sm-12 select-table table-striped">
<table id="bootstrap-table" data-mobile-responsive="true"></table>
</div>
</div>
</div>
<div th:include="include :: footer"></div>
<script th:inline="javascript">
var prefix = ctx + "demo/table";
$(function() {
var options = {
url: prefix + "/list",
showSearch: false,
showRefresh: false,
showToggle: false,
showColumns: false,
pagination: false,
uniqueId: "userId",
height: 400,
columns: [{
checkbox: true
},
{
field : 'userId',
title : '用户ID'
},
{
field : 'userCode',
title : '用户编号'
},
{
field : 'userName',
title : '用户姓名'
},
{
field : 'userPhone',
title : '用户手机'
},
{
field : 'userEmail',
title : '用户邮箱'
},
{
field : 'userBalance',
title : '用户余额'
}]
};
$.table.init(options);
});
/* 新增表格行 */
function insertRow(){
var randomId = 100 + ~~(Math.random() * 100)
$.btTable.bootstrapTable('insertRow', {
index: 0, // 你想插入到哪,0表示第一行
row: {
userId: randomId,
userCode: 2000000 + randomId,
userName: '测试' + randomId,
userPhone: '1588888888',
userEmail: 'ry1@qq.com',
userBalance: 10 + randomId,
}
})
}
/* 删除指定表格行 */
function removeRow(){
var ids = $.table.selectColumns("userId");
if (ids.length == 0) {
$.modal.alertWarning("请至少选择一条记录");
return;
}
$.btTable.bootstrapTable('remove', {
field: 'userId',
values: ids
})
}
/* 删除行ID值为1的数据 */
function removeRowByUniqueId(){
$.btTable.bootstrapTable('removeByUniqueId', 1)
}
/* 删除所有表格行 */
function removeRowAll(){
$.btTable.bootstrapTable('removeAll')
}
/* 修改表格行 */
function updateRow(){
var randomId = 100 + ~~(Math.random() * 100)
$.btTable.bootstrapTable('updateRow', {
index: 0, // 你想修改哪行,0表示第一行
row: {
userId: randomId,
userCode: 3000000 + randomId,
userName: '测试' + randomId,
userPhone: '1599999999',
userEmail: 'ry2@qq.com',
userBalance: 50 + randomId,
}
})
}
/* 修改行ID值为1的数据 */
function updateRowByUniqueId(){
var randomId = 100 + ~~(Math.random() * 100)
$.btTable.bootstrapTable('updateByUniqueId', {
id: 1,
row: {
userId: randomId,
userCode: 3000000 + randomId,
userName: '测试' + randomId,
userPhone: '1599999999',
userEmail: 'ry2@qq.com',
userBalance: 50 + randomId,
}
})
}
/* 查询表格所有数据值 */
function getData(){
var data = $.btTable.bootstrapTable('getData');
alert(JSON.stringify(data))
}
/* 查询行ID值为1的数据 */
function getRowByUniqueId(){
var data = $.btTable.bootstrapTable('getRowByUniqueId', 1);
alert(JSON.stringify(data))
}
/* 查询表格选择行数据值 */
function getSelections(){
var data = $.btTable.bootstrapTable('getSelections');
alert(JSON.stringify(data))
}
</script>
</body>
</html>
@@ -10,10 +10,10 @@
<a class="btn btn-success">
<i class="fa fa-plus"></i> 新增
</a>
<a class="btn btn-primary btn-edit disabled">
<a class="btn btn-primary single disabled">
<i class="fa fa-edit"></i> 修改
</a>
<a class="btn btn-danger btn-del disabled">
<a class="btn btn-danger multiple disabled">
<i class="fa fa-remove"></i> 删除
</a>
</div>
@@ -40,13 +40,12 @@
{
title: '图片',
formatter: function(value, row, index) {
// 图片自由组合
// 'img/profile.jpg' - 'http://ruoyi.vip/' 变成 http://ruoyi.vip/img/profile.jpg
// 'ruoyi.png' - 'http://ruoyi.vip/' 变成 http://ruoyi.vip/ruoyi.jpg
// 图片预览(注意:如存储在本地直接获取数据库路径,如有配置context-path需要使用ctx+路径)
// 如:/profile/upload/2019/08/08/3b7a839aced67397bac694d77611ce72.png
if(index % 2 == 0){
return $.table.imageView('img/profile.jpg', 'http://ruoyi.vip/');
return $.table.imageView('http://demo.ruoyi.vip/img/profile.jpg');
}else {
return $.table.imageView('ruoyi.png', 'http://ruoyi.vip/');
return $.table.imageView('http://demo.ruoyi.vip/ruoyi.png');
}
}
},
@@ -0,0 +1,75 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<th:block th:include="include :: header('表格拖拽操作')" />
</head>
<body class="gray-bg">
<div class="container-div">
<div class="row">
<div class="col-sm-12 select-table table-striped">
<p class="select-title">按住表格拖拽</p>
<table id="bootstrap-table" data-mobile-responsive="true"
data-use-row-attr-func="true"
data-reorderable-rows="true"></table>
</div>
</div>
</div>
<div th:include="include :: footer"></div>
<th:block th:include="include :: bootstrap-table-reorder-js" />
<script th:inline="javascript">
var prefix = ctx + "demo/table";
var datas = [[${@dict.getType('sys_normal_disable')}]];
$(function() {
var options = {
url: prefix + "/list",
showSearch: false,
showRefresh: false,
showToggle: false,
showColumns: false,
onReorderRow: function (data) {
//当拖拽结束后,data为整个表格的数据
console.log('拖拽结束' + JSON.stringify(data))
return false;
},
columns: [{
checkbox: true
},
{
field : 'userId',
title : '用户ID'
},
{
field : 'userCode',
title : '用户编号'
},
{
field : 'userName',
title : '用户姓名'
},
{
field : 'userPhone',
title : '用户手机'
},
{
field : 'userEmail',
title : '用户邮箱'
},
{
field : 'userBalance',
title : '用户余额'
},
{
field: 'status',
title: '用户状态',
align: 'center',
formatter: function(value, row, index) {
return $.table.selectDictLabel(datas, value);
}
}]
};
$.table.init(options);
});
</script>
</body>
</html>
@@ -39,8 +39,8 @@
<script th:src="@{/ajax/libs/iCheck/icheck.min.js}"></script>
<script th:src="@{/ajax/libs/layer/layer.min.js}"></script>
<script th:src="@{/ajax/libs/layui/layui.js}"></script>
<script th:src="@{/ruoyi/js/common.js?v=3.4.0}"></script>
<script th:src="@{/ruoyi/js/ry-ui.js?v=3.4.0}"></script>
<script th:src="@{/ruoyi/js/common.js?v=4.0.0}"></script>
<script th:src="@{/ruoyi/js/ry-ui.js?v=4.0.0}"></script>
<script th:inline="javascript"> var ctx = [[@{/}]]; </script>
</div>
@@ -151,4 +151,25 @@
</div>
<div th:fragment="jquery-steps-js">
<script th:src="@{/ajax/libs/staps/jquery.steps.min.js}"></script>
</div>
<!-- ECharts百度统计图表插件 -->
<div th:fragment="echarts-js">
<script th:src="@{/ajax/libs/report/echarts/echarts-all.js}"></script>
</div>
<!-- peity图表组合插件 -->
<div th:fragment="peity-js">
<script th:src="@{/ajax/libs/report/peity/jquery.peity.min.js}"></script>
</div>
<!-- sparkline线状图插件 -->
<div th:fragment="sparkline-js">
<script th:src="@{/ajax/libs/report/sparkline/jquery.sparkline.min.js}"></script>
</div>
<!-- 表格拖拽插件 -->
<div th:fragment="bootstrap-table-reorder-js">
<script th:src="@{/ajax/libs/bootstrap-table/extensions/reorder/bootstrap-table-reorder.js}"></script>
<script th:src="@{/ajax/libs/bootstrap-table/extensions/reorder/jquery.tablednd.js}"></script>
</div>
@@ -4,9 +4,7 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="renderer" content="webkit">
<title>若依管理系统首页</title>
<meta name="keywords" content="若依管理系统首页">
<meta name="description" content="若依管理系统首页">
<title>若依系统首页</title>
<!--[if lt IE 9]>
<meta http-equiv="refresh" content="0;ie.html"/>
<![endif]-->
@@ -17,9 +15,9 @@
<link th:href="@{/css/animate.css}" rel="stylesheet"/>
<link th:href="@{/css/style.css}" rel="stylesheet"/>
<link th:href="@{/css/skins.css}" rel="stylesheet"/>
<link th:href="@{/ruoyi/css/ry-ui.css?v=3.4.0}" rel="stylesheet"/>
<link th:href="@{/ruoyi/css/ry-ui.css?v=4.0.0}" rel="stylesheet"/>
</head>
<body class="fixed-sidebar full-height-layout gray-bg" style="overflow: hidden" th:classappend="${@config.getKey('sys.index.skinName')}">
<body class="fixed-sidebar full-height-layout gray-bg" style="overflow: hidden" th:classappend="|${@config.getKey('sys.index.sideTheme')} ${@config.getKey('sys.index.skinName')}|">
<div id="wrapper">
<!--左侧导航开始-->
@@ -37,7 +35,7 @@
<a class="menuItem" title="个人中心" th:href="@{/system/user/profile}">
<div class="hide" th:text="个人中心"></div>
<div class="pull-left image">
<img th:src="(${user.avatar} == '') ? @{/img/profile.jpg} : @{/profile/avatar/} + ${user.avatar}" class="img-circle" alt="User Image">
<img th:src="(${user.avatar} == '') ? @{/img/profile.jpg} : @{${user.avatar}}" class="img-circle" alt="User Image">
</div>
</a>
<div class="pull-left info">
@@ -54,12 +52,12 @@
</ul>
</li>
<li th:each="menu : ${menus}">
<a href="#">
<a th:class="@{${menu.url != '' && menu.url != '#'} ? ${menu.target}}" th:href="@{${menu.url == ''} ? |#| : ${menu.url}}">
<i class="fa fa-bar-chart-o" th:class="${menu.icon}"></i>
<span class="nav-label" th:text="${menu.menuName}">一级菜单</span>
<span class="fa arrow"></span>
<span th:class="${menu.url == '' || menu.url == '#'} ? |fa arrow|"></span>
</a>
<ul class="nav nav-second-level collapse">
<ul class="nav nav-second-level collapse">
<li th:each="cmenu : ${menu.children}">
<a th:if="${#lists.isEmpty(cmenu.children)}" th:class="${cmenu.target == ''} ? |menuItem| : ${cmenu.target}" th:utext="${cmenu.menuName}" th:href="@{${cmenu.url}}">二级菜单</a>
<a th:if="${not #lists.isEmpty(cmenu.children)}" href="#">[[${cmenu.menuName}]]<span class="fa arrow"></span></a>
@@ -69,7 +67,7 @@
</li>
</ul>
</li>
<li th:classappend="${demoEnabled==false} ? 'hidden'">
<li th:if="${demoEnabled}">
<a href="#"><i class="fa fa-desktop"></i><span class="nav-label">实例演示</span><span class="fa arrow"></span></a>
<ul class="nav nav-second-level collapse">
<li> <a>表单<span class="fa arrow"></span></a>
@@ -78,6 +76,7 @@
<li><a class="menuItem" th:href="@{/demo/form/grid}">栅格</a></li>
<li><a class="menuItem" th:href="@{/demo/form/select}">下拉框</a></li>
<li><a class="menuItem" th:href="@{/demo/form/basic}">基本表单</a></li>
<li><a class="menuItem" th:href="@{/demo/form/cards}">卡片列表</a></li>
<li><a class="menuItem" th:href="@{/demo/form/jasny}">功能扩展</a></li>
<li><a class="menuItem" th:href="@{/demo/form/sortable}">拖动排序</a></li>
<li><a class="menuItem" th:href="@{/demo/form/tabs_panels}">选项卡 & 面板</a></li>
@@ -85,6 +84,7 @@
<li><a class="menuItem" th:href="@{/demo/form/wizard}">表单向导</a></li>
<li><a class="menuItem" th:href="@{/demo/form/upload}">文件上传</a></li>
<li><a class="menuItem" th:href="@{/demo/form/datetime}">日期和时间</a></li>
<li><a class="menuItem" th:href="@{/demo/form/summernote}">富文本编辑器</a></li>
<li><a class="menuItem" th:href="@{/demo/form/duallistbox}">左右互选组件</a></li>
<li><a class="menuItem" th:href="@{/demo/form/autocomplete}">搜索自动补全</a></li>
</ul>
@@ -104,6 +104,8 @@
<li><a class="menuItem" th:href="@{/demo/table/event}">自定义触发事件</a></li>
<li><a class="menuItem" th:href="@{/demo/table/detail}">表格细节视图</a></li>
<li><a class="menuItem" th:href="@{/demo/table/image}">表格图片预览</a></li>
<li><a class="menuItem" th:href="@{/demo/table/curd}">动态增删改查</a></li>
<li><a class="menuItem" th:href="@{/demo/table/reorder}">表格拖拽操作</a></li>
<li><a class="menuItem" th:href="@{/demo/table/other}">表格其他操作</a></li>
</ul>
</li>
@@ -120,6 +122,14 @@
<li><a class="menuItem" th:href="@{/demo/operate/other}">其他</a></li>
</ul>
</li>
<li> <a>报表<span class="fa arrow"></span></a>
<ul class="nav nav-third-level">
<li><a class="menuItem" th:href="@{/demo/report/echarts}">百度ECharts</a></li>
<li><a class="menuItem" th:href="@{/demo/report/peity}">peity</a></li>
<li><a class="menuItem" th:href="@{/demo/report/sparkline}">sparkline</a></li>
<li><a class="menuItem" th:href="@{/demo/report/metrics}">图表组合</a></li>
</ul>
</li>
<li> <a>图标<span class="fa arrow"></span></a>
<ul class="nav nav-third-level">
<li><a class="menuItem" th:href="@{/demo/icon/fontawesome}">Font Awesome</a></li>
@@ -165,7 +175,7 @@
<li><a title="全屏显示" href="javascript:void(0)" id="fullScreen"><i class="fa fa-arrows-alt"></i> 全屏显示</a></li>
<li class="dropdown user-menu">
<a href="javascript:void(0)" class="dropdown-toggle" data-hover="dropdown">
<img th:src="(${user.avatar} == '') ? @{/img/profile.jpg} : @{/profile/avatar/} + ${user.avatar}" class="user-image">
<img th:src="(${user.avatar} == '') ? @{/img/profile.jpg} : @{${user.avatar}}" class="user-image">
<span class="hidden-xs">[[${user.userName}]]</span>
</a>
<ul class="dropdown-menu">
@@ -222,7 +232,7 @@
<script th:src="@{/js/jquery.contextMenu.min.js}"></script>
<script th:src="@{/ajax/libs/blockUI/jquery.blockUI.js}"></script>
<script th:src="@{/ajax/libs/layer/layer.min.js}"></script>
<script th:src="@{/ruoyi/js/ry-ui.js?v=3.4.0}"></script>
<script th:src="@{/ruoyi/js/ry-ui.js?v=4.0.0}"></script>
<script th:src="@{/ruoyi/index.js}"></script>
<script th:src="@{/ajax/libs/fullscreen/jquery.fullscreen.js}"></script>
<script th:inline="javascript">
@@ -4,14 +4,13 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
<title>若依管理系统</title>
<meta name="keywords" content="若依,若依开源,若依框架,若依系统,ruoyi">
<meta name="description" content="若依基于SpringBoot2.0的权限管理系统 易读易懂、界面简洁美观。 核心技术采用Spring、MyBatis、Shiro没有任何其它重度依赖">
<title>登录若依系统</title>
<meta name="description" content="若依后台管理框架">
<link href="../static/css/bootstrap.min.css" th:href="@{/css/bootstrap.min.css}" rel="stylesheet"/>
<link href="../static/css/font-awesome.min.css" th:href="@{/css/font-awesome.min.css}" rel="stylesheet"/>
<link href="../static/css/style.css" th:href="@{/css/style.css}" rel="stylesheet"/>
<link href="../static/css/login.min.css" th:href="@{/css/login.min.css}" rel="stylesheet"/>
<link href="../static/ruoyi/css/ry-ui.css" th:href="@{/ruoyi/css/ry-ui.css?v=3.4.0}" rel="stylesheet"/>
<link href="../static/ruoyi/css/ry-ui.css" th:href="@{/ruoyi/css/ry-ui.css?v=4.0.0}" rel="stylesheet"/>
<!--[if lt IE 9]>
<meta http-equiv="refresh" content="0;ie.html" />
<![endif]-->
@@ -69,7 +68,6 @@
<div class="signup-footer">
<div class="pull-left">
&copy; 2019 All Rights Reserved. RuoYi <br>
<a href="http://www.miitbeian.gov.cn/" target="_blank" rel="nofollow">粤ICP备18046899号</a><br>
</div>
</div>
</div>
@@ -82,7 +80,7 @@
<script src="../static/ajax/libs/validate/messages_zh.min.js" th:src="@{/ajax/libs/validate/messages_zh.min.js}"></script>
<script src="../static/ajax/libs/layer/layer.min.js" th:src="@{/ajax/libs/layer/layer.min.js}"></script>
<script src="../static/ajax/libs/blockUI/jquery.blockUI.js" th:src="@{/ajax/libs/blockUI/jquery.blockUI.js}"></script>
<script src="../static/ruoyi/js/ry-ui.js" th:src="@{/ruoyi/js/ry-ui.js?v=3.4.0}"></script>
<script src="../static/ruoyi/js/ry-ui.js" th:src="@{/ruoyi/js/ry-ui.js?v=4.0.0}"></script>
<script src="../static/ruoyi/login.js" th:src="@{/ruoyi/login.js}"></script>
</body>
</html>
@@ -81,7 +81,7 @@
<div class="ibox-content">
<p><i class="fa fa-send-o"></i> 官网:<a href="http://www.ruoyi.vip" target="_blank">http://www.ruoyi.vip</a>
</p>
<p><i class="fa fa-qq"></i> QQ群:<s>满1389287</s> <s>满1679294</s> <s>满1529866</s> <s>满1772718</s> <a href="https://jq.qq.com/?_wv=1027&k=5lJkVor" target="_blank">1366522</a>
<p><i class="fa fa-qq"></i> QQ群:<s>满1389287</s> <s>满1679294</s> <s>满1529866</s> <s>满1772718</s> <s>满1366522</s> <s>满1382251</s> <a href="https://jq.qq.com/?_wv=1027&k=5fdQ1eG" target="_blank">1145125</a>
</p>
<p><i class="fa fa-weixin"></i> 微信:<a href="javascript:;">/ *若依</a>
</p>
@@ -98,13 +98,75 @@
<div class="ibox-content no-padding">
<div class="panel-body">
<div class="panel-group" id="version">
<div class="panel panel-default">
<div class="panel-heading">
<h5 class="panel-title">
<a data-toggle="collapse" data-parent="#version" href="#v40">v4.0.0</a><code class="pull-right">2019.08.08</code>
</h5>
</div>
<div id="v40" class="panel-collapse collapse in">
<div class="panel-body">
<ol>
<li>代码生成支持预览、编辑,保存方案</li>
<li>新增防止表单重复提交注解</li>
<li>新增后端校验(和前端保持一致)</li>
<li>新增同一个用户最大会话数控制</li>
<li>Excel导出子对象支持多个字段</li>
<li>定时任务支持静态调用和多参数</li>
<li>定时任务增加分组条件查询</li>
<li>字典类型增加任务分组数据</li>
<li>新增表格是否首次加载数据</li>
<li>新增parentTab选项卡可在同一页签打开</li>
<li>多数据源支持类注解(允许继承父类的注解)</li>
<li>部门及以下数据权限(调整为以下及所有子节点)</li>
<li>新增角色数据权限配(仅本人数据权限)</li>
<li>修改菜单权限显示问题</li>
<li>上传文件修改路径及返回名称</li>
<li>添加报表插件及示例</li>
<li>添加首页统计模板</li>
<li>添加表格拖拽示例</li>
<li>添加卡片列表示例</li>
<li>添加富文本编辑器示例</li>
<li>添加表格动态增删改查示例</li>
<li>添加用户页面岗位选择框提示</li>
<li>点击菜单操作添加背景高亮显示</li>
<li>表格树新增showSearch是否显示检索信息</li>
<li>解决表格列设置sortName无效问题</li>
<li>表格图片预览支持自定义设置宽高</li>
<li>添加表格列浮动提示(单击文本复制)</li>
<li>PC端收起菜单后支持浮动显示</li>
<li>详细操作样式调整</li>
<li>修改用户更新描述空串不更新问题</li>
<li>导入修改为模板渲染</li>
<li>修改菜单及部门排序规则</li>
<li>角色导出数据范围表达式翻译</li>
<li>添加summernote富文本字体大小</li>
<li>优化表格底部下边框防重叠&汇总像素问题</li>
<li>树表格支持属性多层级访问</li>
<li>修复IE浏览器用户管理界面右侧留白问题</li>
<li>重置按钮刷新表格</li>
<li>重置密码更新用户缓存</li>
<li>优化验证码属性参数</li>
<li>支持数据监控配置用户名和密码</li>
<li>文件上传修改按钮背景及加载动画</li>
<li>支持配置一级菜单href跳转</li>
<li>侧边栏添加一套浅色主题</li>
<li>树表格添加回调函数(校验异常状态)</li>
<li>用户个人中心适配手机端显示</li>
<li>Excel支持设置导出类型&更换样式</li>
<li>检查属性改变修改为克隆方式(防止热部署强转异常)</li>
<li>其他细节优化</li>
</ol>
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h5 class="panel-title">
<a data-toggle="collapse" data-parent="#version" href="#v34">v3.4.0</a><code class="pull-right">2019.06.03</code>
</h5>
</div>
<div id="v34" class="panel-collapse collapse in">
<div id="v34" class="panel-collapse collapse">
<div class="panel-body">
<ol>
<li>新增实例演示菜单及demo</li>
@@ -0,0 +1,336 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>统计</title>
<link rel="shortcut icon" href="favicon.ico">
<link href="../static/css/bootstrap.min.css" th:href="@{/css/bootstrap.min.css}" rel="stylesheet"/>
<link href="../static/css/font-awesome.min.css" th:href="@{/css/font-awesome.min.css}" rel="stylesheet"/>
<link href="../static/css/main/animate.min.css" th:href="@{/css/main/animate.min.css}" rel="stylesheet"/>
<link href="../static/css/main/style.min862f.css" th:href="@{/css/main/style.min862f.css}" rel="stylesheet"/>
</head>
<body class="gray-bg">
<div class="wrapper wrapper-content">
<div class="row">
<div class="col-sm-3">
<div class="ibox float-e-margins">
<div class="ibox-title">
<span class="label label-success pull-right"></span>
<h5>收入</h5>
</div>
<div class="ibox-content">
<h1 class="no-margins">40 886,200</h1>
<div class="stat-percent font-bold text-success">98% <i class="fa fa-bolt"></i>
</div>
<small>总收入</small>
</div>
</div>
</div>
<div class="col-sm-3">
<div class="ibox float-e-margins">
<div class="ibox-title">
<span class="label label-info pull-right">全年</span>
<h5>订单</h5>
</div>
<div class="ibox-content">
<h1 class="no-margins">275,800</h1>
<div class="stat-percent font-bold text-info">20% <i class="fa fa-level-up"></i>
</div>
<small>新订单</small>
</div>
</div>
</div>
<div class="col-sm-3">
<div class="ibox float-e-margins">
<div class="ibox-title">
<span class="label label-primary pull-right">今天</span>
<h5>访客</h5>
</div>
<div class="ibox-content">
<h1 class="no-margins">106,120</h1>
<div class="stat-percent font-bold text-navy">44% <i class="fa fa-level-up"></i>
</div>
<small>新访客</small>
</div>
</div>
</div>
<div class="col-sm-3">
<div class="ibox float-e-margins">
<div class="ibox-title">
<span class="label label-danger pull-right">最近一个月</span>
<h5>活跃用户</h5>
</div>
<div class="ibox-content">
<h1 class="no-margins">80,600</h1>
<div class="stat-percent font-bold text-danger">38% <i class="fa fa-level-down"></i>
</div>
<small>12月</small>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>订单</h5>
<div class="pull-right">
<div class="btn-group">
<button type="button" class="btn btn-xs btn-white active"></button>
<button type="button" class="btn btn-xs btn-white"></button>
<button type="button" class="btn btn-xs btn-white"></button>
</div>
</div>
</div>
<div class="ibox-content">
<div class="row">
<div class="col-sm-9">
<div class="flot-chart">
<div class="flot-chart-content" id="flot-dashboard-chart"></div>
</div>
</div>
<div class="col-sm-3">
<ul class="stat-list">
<li>
<h2 class="no-margins">2,346</h2>
<small>订单总数</small>
<div class="stat-percent">48% <i class="fa fa-level-up text-navy"></i>
</div>
<div class="progress progress-mini">
<div style="width: 48%;" class="progress-bar"></div>
</div>
</li>
<li>
<h2 class="no-margins ">4,422</h2>
<small>最近一个月订单</small>
<div class="stat-percent">60% <i class="fa fa-level-down text-navy"></i>
</div>
<div class="progress progress-mini">
<div style="width: 60%;" class="progress-bar"></div>
</div>
</li>
<li>
<h2 class="no-margins ">9,180</h2>
<small>最近一个月销售额</small>
<div class="stat-percent">22% <i class="fa fa-bolt text-navy"></i>
</div>
<div class="progress progress-mini">
<div style="width: 22%;" class="progress-bar"></div>
</div>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>用户项目列表</h5>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
<table class="table table-hover no-margins">
<thead>
<tr>
<th>状态</th>
<th>日期</th>
<th>用户</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td><small>进行中...</small>
</td>
<td><i class="fa fa-clock-o"></i> 11:20</td>
<td>青衣5858</td>
<td class="text-navy"> <i class="fa fa-level-up"></i> 24%</td>
</tr>
<tr>
<td><span class="label label-warning">已取消</span>
</td>
<td><i class="fa fa-clock-o"></i> 10:40</td>
<td>徐子崴</td>
<td class="text-navy"> <i class="fa fa-level-up"></i> 66%</td>
</tr>
<tr>
<td><small>进行中...</small>
</td>
<td><i class="fa fa-clock-o"></i> 01:30</td>
<td>姜岚昕</td>
<td class="text-navy"> <i class="fa fa-level-up"></i> 54%</td>
</tr>
<tr>
<td><small>进行中...</small>
</td>
<td><i class="fa fa-clock-o"></i> 02:20</td>
<td>武汉大兵哥</td>
<td class="text-navy"> <i class="fa fa-level-up"></i> 12%</td>
</tr>
<tr>
<td><small>进行中...</small>
</td>
<td><i class="fa fa-clock-o"></i> 09:40</td>
<td>荆莹儿</td>
<td class="text-navy"> <i class="fa fa-level-up"></i> 22%</td>
</tr>
<tr>
<td><span class="label label-primary">已完成</span>
</td>
<td><i class="fa fa-clock-o"></i> 04:10</td>
<td>栾某某</td>
<td class="text-navy"> <i class="fa fa-level-up"></i> 66%</td>
</tr>
<tr>
<td><small>进行中...</small>
</td>
<td><i class="fa fa-clock-o"></i> 12:08</td>
<td>范范范二妮</td>
<td class="text-navy"> <i class="fa fa-level-up"></i> 23%</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
<script th:src="@{/js/jquery.min.js}"></script>
<script th:src="@{/js/bootstrap.min.js}"></script>
<script th:src="@{/ajax/libs/flot/jquery.flot.js}"></script>
<th:block th:include="include :: sparkline-js" />
<script type="text/javascript">
$(document).ready(function () {
var data2 = [
[gd(2012, 1, 1), 7], [gd(2012, 1, 2), 6], [gd(2012, 1, 3), 4], [gd(2012, 1, 4), 8],
[gd(2012, 1, 5), 9], [gd(2012, 1, 6), 7], [gd(2012, 1, 7), 5], [gd(2012, 1, 8), 4],
[gd(2012, 1, 9), 7], [gd(2012, 1, 10), 8], [gd(2012, 1, 11), 9], [gd(2012, 1, 12), 6],
[gd(2012, 1, 13), 4], [gd(2012, 1, 14), 5], [gd(2012, 1, 15), 11], [gd(2012, 1, 16), 8],
[gd(2012, 1, 17), 8], [gd(2012, 1, 18), 11], [gd(2012, 1, 19), 11], [gd(2012, 1, 20), 6],
[gd(2012, 1, 21), 6], [gd(2012, 1, 22), 8], [gd(2012, 1, 23), 11], [gd(2012, 1, 24), 13],
[gd(2012, 1, 25), 7], [gd(2012, 1, 26), 9], [gd(2012, 1, 27), 9], [gd(2012, 1, 28), 8],
[gd(2012, 1, 29), 5], [gd(2012, 1, 30), 8], [gd(2012, 1, 31), 25]
];
var data3 = [
[gd(2012, 1, 1), 800], [gd(2012, 1, 2), 500], [gd(2012, 1, 3), 600], [gd(2012, 1, 4), 700],
[gd(2012, 1, 5), 500], [gd(2012, 1, 6), 456], [gd(2012, 1, 7), 800], [gd(2012, 1, 8), 589],
[gd(2012, 1, 9), 467], [gd(2012, 1, 10), 876], [gd(2012, 1, 11), 689], [gd(2012, 1, 12), 700],
[gd(2012, 1, 13), 500], [gd(2012, 1, 14), 600], [gd(2012, 1, 15), 700], [gd(2012, 1, 16), 786],
[gd(2012, 1, 17), 345], [gd(2012, 1, 18), 888], [gd(2012, 1, 19), 888], [gd(2012, 1, 20), 888],
[gd(2012, 1, 21), 987], [gd(2012, 1, 22), 444], [gd(2012, 1, 23), 999], [gd(2012, 1, 24), 567],
[gd(2012, 1, 25), 786], [gd(2012, 1, 26), 666], [gd(2012, 1, 27), 888], [gd(2012, 1, 28), 900],
[gd(2012, 1, 29), 178], [gd(2012, 1, 30), 555], [gd(2012, 1, 31), 993]
];
var dataset = [
{
label: "订单数",
data: data3,
color: "#1ab394",
bars: {
show: true,
align: "center",
barWidth: 24 * 60 * 60 * 600,
lineWidth: 0
}
}, {
label: "付款数",
data: data2,
yaxis: 2,
color: "#464f88",
lines: {
lineWidth: 1,
show: true,
fill: true,
fillColor: {
colors: [{
opacity: 0.2
}, {
opacity: 0.2
}]
}
},
splines: {
show: false,
tension: 0.6,
lineWidth: 1,
fill: 0.1
},
}
];
var options = {
xaxis: {
mode: "time",
tickSize: [3, "day"],
tickLength: 0,
axisLabel: "Date",
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Arial',
axisLabelPadding: 10,
color: "#838383"
},
yaxes: [{
position: "left",
max: 1070,
color: "#838383",
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Arial',
axisLabelPadding: 3
}, {
position: "right",
clolor: "#838383",
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: ' Arial',
axisLabelPadding: 67
}
],
legend: {
noColumns: 1,
labelBoxBorderColor: "#000000",
position: "nw"
},
grid: {
hoverable: false,
borderWidth: 0,
color: '#838383'
}
};
function gd(year, month, day) {
return new Date(year, month - 1, day).getTime();
}
var previousPoint = null,
previousLabel = null;
$.plot($("#flot-dashboard-chart"), dataset, options);
});
</script>
</body>
</html>
@@ -38,7 +38,7 @@
</div>
<div class="btn-group-sm" id="toolbar" role="group">
<a class="btn btn-danger btn-del disabled" onclick="$.operate.removeAll()" shiro:hasPermission="monitor:logininfor:remove">
<a class="btn btn-danger multiple disabled" onclick="$.operate.removeAll()" shiro:hasPermission="monitor:logininfor:remove">
<i class="fa fa-remove"></i> 删除
</a>
<a class="btn btn-danger" onclick="$.operate.clean()" shiro:hasPermission="monitor:logininfor:remove">
@@ -26,7 +26,7 @@
</div>
<div class="btn-group-sm" id="toolbar" role="group">
<a class="btn btn-danger btn-del disabled" onclick="javascript:batchForceLogout()" shiro:hasPermission="monitor:online:batchForceLogout">
<a class="btn btn-danger multiple disabled" onclick="javascript:batchForceLogout()" shiro:hasPermission="monitor:online:batchForceLogout">
<i class="fa fa-sign-out"></i> 强退
</a>
</div>
@@ -43,6 +43,7 @@
$(function() {
var options = {
uniqueId: "sessionId",
url: prefix + "/list",
exportUrl: prefix + "/export",
sortName: "lastAccessTime",
@@ -44,7 +44,7 @@
</div>
<div class="btn-group-sm" id="toolbar" role="group">
<a class="btn btn-danger btn-del disabled" onclick="$.operate.removeAll()" shiro:hasPermission="monitor:operlog:remove">
<a class="btn btn-danger multiple disabled" onclick="$.operate.removeAll()" shiro:hasPermission="monitor:operlog:remove">
<i class="fa fa-remove"></i> 删除
</a>
<a class="btn btn-danger" onclick="$.operate.clean()" shiro:hasPermission="monitor:operlog:remove">
@@ -28,7 +28,7 @@
<label class="col-sm-3 control-label">系统内置:</label>
<div class="col-sm-8">
<div class="radio-box" th:each="dict : ${@dict.getType('sys_yes_no')}">
<input type="radio" th:id="${dict.dictCode}" name="configType" th:value="${dict.dictValue}" th:checked="${dict.isDefault == 'Y' ? true : false}">
<input type="radio" th:id="${dict.dictCode}" name="configType" th:value="${dict.dictValue}" th:checked="${dict.default}">
<label th:for="${dict.dictCode}" th:text="${dict.dictLabel}"></label>
</div>
</div>
@@ -41,10 +41,10 @@
<a class="btn btn-success" onclick="$.operate.add()" shiro:hasPermission="system:config:add">
<i class="fa fa-plus"></i> 新增
</a>
<a class="btn btn-primary btn-edit disabled" onclick="$.operate.edit()" shiro:hasPermission="system:config:edit">
<a class="btn btn-primary single disabled" onclick="$.operate.edit()" shiro:hasPermission="system:config:edit">
<i class="fa fa-edit"></i> 修改
</a>
<a class="btn btn-danger btn-del disabled" onclick="$.operate.removeAll()" shiro:hasPermission="system:config:remove">
<a class="btn btn-danger multiple disabled" onclick="$.operate.removeAll()" shiro:hasPermission="system:config:remove">
<i class="fa fa-remove"></i> 删除
</a>
<a class="btn btn-warning" onclick="$.table.exportExcel()" shiro:hasPermission="system:config:export">
@@ -50,7 +50,7 @@
<label class="col-sm-3 control-label">部门状态:</label>
<div class="col-sm-8">
<div class="radio-box" th:each="dict : ${@dict.getType('sys_normal_disable')}">
<input type="radio" th:id="${dict.dictCode}" name="status" th:value="${dict.dictValue}" th:checked="${dict.isDefault == 'Y' ? true : false}">
<input type="radio" th:id="${dict.dictCode}" name="status" th:value="${dict.dictValue}" th:checked="${dict.default}">
<label th:for="${dict.dictCode}" th:text="${dict.dictLabel}"></label>
</div>
</div>
@@ -40,7 +40,7 @@
</a>
</div>
<div class="col-sm-12 select-table table-striped">
<table id="bootstrap-tree-table" data-mobile-responsive="true"></table>
<table id="bootstrap-tree-table"></table>
</div>
</div>
</div>
@@ -55,7 +55,7 @@
<label class="col-sm-3 control-label">系统默认:</label>
<div class="col-sm-8">
<div class="radio-box" th:each="dict : ${@dict.getType('sys_yes_no')}">
<input type="radio" th:id="${dict.dictCode}" name="isDefault" th:value="${dict.dictValue}" th:checked="${dict.isDefault == 'Y' ? true : false}">
<input type="radio" th:id="${dict.dictCode}" name="isDefault" th:value="${dict.dictValue}" th:checked="${dict.default}">
<label th:for="${dict.dictCode}" th:text="${dict.dictLabel}"></label>
</div>
</div>
@@ -64,7 +64,7 @@
<label class="col-sm-3 control-label">状态:</label>
<div class="col-sm-8">
<div class="radio-box" th:each="dict : ${@dict.getType('sys_normal_disable')}">
<input type="radio" th:id="${dict.dictCode}" name="status" th:value="${dict.dictValue}" th:checked="${dict.isDefault == 'Y' ? true : false}">
<input type="radio" th:id="${dict.dictCode}" name="status" th:value="${dict.dictValue}" th:checked="${dict.default}">
<label th:for="${dict.dictCode}" th:text="${dict.dictLabel}"></label>
</div>
</div>
@@ -37,10 +37,10 @@
<a class="btn btn-success" onclick="add()" shiro:hasPermission="system:dict:add">
<i class="fa fa-plus"></i> 新增
</a>
<a class="btn btn-primary btn-edit disabled" onclick="$.operate.edit()" shiro:hasPermission="system:dict:edit">
<a class="btn btn-primary single disabled" onclick="$.operate.edit()" shiro:hasPermission="system:dict:edit">
<i class="fa fa-edit"></i> 修改
</a>
<a class="btn btn-danger btn-del disabled" onclick="$.operate.removeAll()" shiro:hasPermission="system:dict:remove">
<a class="btn btn-danger multiple disabled" onclick="$.operate.removeAll()" shiro:hasPermission="system:dict:remove">
<i class="fa fa-remove"></i> 删除
</a>
<a class="btn btn-warning" onclick="$.table.exportExcel()" shiro:hasPermission="system:dict:export">
@@ -22,7 +22,7 @@
<label class="col-sm-3 control-label">状态:</label>
<div class="col-sm-8">
<div class="radio-box" th:each="dict : ${@dict.getType('sys_normal_disable')}">
<input type="radio" th:id="${dict.dictCode}" name="status" th:value="${dict.dictValue}" th:checked="${dict.isDefault == 'Y' ? true : false}">
<input type="radio" th:id="${dict.dictCode}" name="status" th:value="${dict.dictValue}" th:checked="${dict.default}">
<label th:for="${dict.dictCode}" th:text="${dict.dictLabel}"></label>
</div>
</div>
@@ -0,0 +1,42 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
<head>
<th:block th:include="include :: header('字典树选择')" />
<th:block th:include="include :: ztree-css" />
</head>
<style>
body{height:auto;font-family: "Microsoft YaHei";}
button{font-family: "SimSun","Helvetica Neue",Helvetica,Arial;}
</style>
<body class="hold-transition box box-main">
<input id="columnId" type="hidden" th:value="${columnId}"/>
<input id="treeId" type="hidden" th:value="${dict?.dictId}"/>
<input id="dictType" type="hidden" th:value="${dict?.dictType}"/>
<div class="wrapper"><div class="treeShowHideButton" onclick="$.tree.toggleSearch();">
<label id="btnShow" title="显示搜索" style="display:none;"></label>
<label id="btnHide" title="隐藏搜索"></label>
</div>
<div class="treeSearchInput" id="search">
<label for="keyword">关键字:</label><input type="text" class="empty" id="keyword" maxlength="50">
<button class="btn" id="btn" onclick="$.tree.searchNode()"> 搜索 </button>
</div>
<div id="tree" class="ztree treeselect"></div>
</div>
<th:block th:include="include :: footer" />
<th:block th:include="include :: ztree-js" />
<script th:inline="javascript">
$(function() {
var url = ctx + "system/dict/treeData";
var options = {
url: url,
onClick : zOnClick
};
$.tree.init(options);
});
function zOnClick(event, treeId, treeNode) {
$("#dictType").val(treeNode.title);
}
</script>
</body>
</html>
@@ -41,10 +41,10 @@
<a class="btn btn-success" onclick="$.operate.add()" shiro:hasPermission="system:dict:add">
<i class="fa fa-plus"></i> 新增
</a>
<a class="btn btn-primary btn-edit disabled" onclick="$.operate.edit()" shiro:hasPermission="system:dict:edit">
<a class="btn btn-primary single disabled" onclick="$.operate.edit()" shiro:hasPermission="system:dict:edit">
<i class="fa fa-edit"></i> 修改
</a>
<a class="btn btn-danger btn-del disabled" onclick="$.operate.removeAll()" shiro:hasPermission="system:dict:remove">
<a class="btn btn-danger multiple disabled" onclick="$.operate.removeAll()" shiro:hasPermission="system:dict:remove">
<i class="fa fa-remove"></i> 删除
</a>
<a class="btn btn-warning" onclick="$.table.exportExcel()" shiro:hasPermission="system:dict:export">
@@ -130,7 +130,7 @@
/*字典列表-详细*/
function detail(dictId) {
var url = prefix + '/detail/' + dictId;
createMenuItem(url, "字典数据");
$.modal.openTab("字典数据", url);
}
</script>
</body>
@@ -73,7 +73,7 @@
<label class="col-sm-3 control-label">菜单状态:</label>
<div class="col-sm-8">
<div class="radio-box" th:each="dict : ${@dict.getType('sys_show_hide')}">
<input type="radio" th:id="${dict.dictCode}" name="visible" th:value="${dict.dictValue}" th:checked="${dict.isDefault == 'Y' ? true : false}">
<input type="radio" th:id="${dict.dictCode}" name="visible" th:value="${dict.dictValue}" th:checked="${dict.default}">
<label th:for="${dict.dictCode}" th:text="${dict.dictLabel}"></label>
</div>
</div>
@@ -146,16 +146,19 @@
$("#perms").parents(".form-group").hide();
$("#icon").parents(".form-group").show();
$("#target").parents(".form-group").hide();
$("input[name='visible']").parents(".form-group").show();
} else if (menuType == "C") {
$("#url").parents(".form-group").show();
$("#perms").parents(".form-group").show();
$("#icon").parents(".form-group").hide();
$("#icon").parents(".form-group").show();
$("#target").parents(".form-group").show();
$("input[name='visible']").parents(".form-group").show();
} else if (menuType == "F") {
$("#url").parents(".form-group").hide();
$("#perms").parents(".form-group").show();
$("#icon").parents(".form-group").hide();
$("#target").parents(".form-group").hide();
$("input[name='visible']").parents(".form-group").hide();
}
});
});
@@ -162,16 +162,19 @@
$("#perms").parents(".form-group").hide();
$("#icon").parents(".form-group").show();
$("#target").parents(".form-group").hide();
$("input[name='visible']").parents(".form-group").show();
} else if (menuType == "C") {
$("#url").parents(".form-group").show();
$("#perms").parents(".form-group").show();
$("#icon").parents(".form-group").hide();
$("#icon").parents(".form-group").show();
$("#target").parents(".form-group").show();
$("input[name='visible']").parents(".form-group").show();
} else if (menuType == "F") {
$("#url").parents(".form-group").hide();
$("#perms").parents(".form-group").show();
$("#icon").parents(".form-group").hide();
$("#target").parents(".form-group").hide();
$("input[name='visible']").parents(".form-group").hide();
}
}
@@ -40,7 +40,7 @@
</a>
</div>
<div class="col-sm-12 select-table table-striped">
<table id="bootstrap-tree-table" data-mobile-responsive="true"></table>
<table id="bootstrap-tree-table"></table>
</div>
</div>
</div>
@@ -32,7 +32,7 @@
<label class="col-sm-2 control-label">公告状态:</label>
<div class="col-sm-10">
<div class="radio-box" th:each="dict : ${@dict.getType('sys_notice_status')}">
<input type="radio" th:id="${dict.dictCode}" name="status" th:value="${dict.dictValue}" th:checked="${dict.isDefault == 'Y' ? true : false}">
<input type="radio" th:id="${dict.dictCode}" name="status" th:value="${dict.dictValue}" th:checked="${dict.default}">
<label th:for="${dict.dictCode}" th:text="${dict.dictLabel}"></label>
</div>
</div>
@@ -35,10 +35,10 @@
<a class="btn btn-success" onclick="$.operate.addFull()" shiro:hasPermission="system:notice:add">
<i class="fa fa-plus"></i> 新增
</a>
<a class="btn btn-primary btn-edit disabled" onclick="$.operate.editFull()" shiro:hasPermission="system:notice:edit">
<a class="btn btn-primary single disabled" onclick="$.operate.editFull()" shiro:hasPermission="system:notice:edit">
<i class="fa fa-edit"></i> 修改
</a>
<a class="btn btn-danger btn-del disabled" onclick="$.operate.removeAll()" shiro:hasPermission="system:notice:remove">
<a class="btn btn-danger multiple disabled" onclick="$.operate.removeAll()" shiro:hasPermission="system:notice:remove">
<i class="fa fa-remove"></i> 删除
</a>
</div>
@@ -28,7 +28,7 @@
<label class="col-sm-3 control-label">岗位状态:</label>
<div class="col-sm-8">
<div class="radio-box" th:each="dict : ${@dict.getType('sys_normal_disable')}">
<input type="radio" th:id="${dict.dictCode}" name="status" th:value="${dict.dictValue}" th:checked="${dict.isDefault == 'Y' ? true : false}">
<input type="radio" th:id="${dict.dictCode}" name="status" th:value="${dict.dictValue}" th:checked="${dict.default}">
<label th:for="${dict.dictCode}" th:text="${dict.dictLabel}"></label>
</div>
</div>
@@ -35,10 +35,10 @@
<a class="btn btn-success" onclick="$.operate.add()" shiro:hasPermission="system:post:add">
<i class="fa fa-plus"></i> 新增
</a>
<a class="btn btn-primary btn-edit disabled" onclick="$.operate.edit()" shiro:hasPermission="system:post:edit">
<a class="btn btn-primary single disabled" onclick="$.operate.edit()" shiro:hasPermission="system:post:edit">
<i class="fa fa-edit"></i> 修改
</a>
<a class="btn btn-danger btn-del disabled" onclick="$.operate.removeAll()" shiro:hasPermission="system:post:remove">
<a class="btn btn-danger multiple disabled" onclick="$.operate.removeAll()" shiro:hasPermission="system:post:remove">
<i class="fa fa-remove"></i> 删除
</a>
<a class="btn btn-warning" onclick="$.table.exportExcel()" shiro:hasPermission="system:post:export">
@@ -17,6 +17,7 @@
<label class="col-sm-3 control-label">权限字符:</label>
<div class="col-sm-8">
<input class="form-control" type="text" name="roleKey" id="roleKey" required>
<span class="help-block m-b-none"><i class="fa fa-info-circle"></i> 控制器中定义的权限字符,如:@RequiresRoles("")</span>
</div>
</div>
<div class="form-group">
@@ -86,8 +87,8 @@
type: "post",
dataType: "json",
data: {
"roleName" : function() {
return $.common.trim($("#roleName").val());
"roleKey" : function() {
return $.common.trim($("#roleKey").val());
}
},
dataFilter: function(data, type) {
@@ -30,7 +30,7 @@
<a class="btn btn-success" onclick="selectUser()" shiro:hasPermission="system:role:add">
<i class="fa fa-plus"></i> 添加用户
</a>
<a class="btn btn-danger btn-del disabled" onclick="cancelAuthUserAll()" shiro:hasPermission="system:role:remove">
<a class="btn btn-danger multiple disabled" onclick="cancelAuthUserAll()" shiro:hasPermission="system:role:remove">
<i class="fa fa-remove"></i> 批量取消授权
</a>
<a class="btn btn-warning" onclick="closeItem()">
@@ -68,7 +68,7 @@
{
field: 'userId',
title: '用户ID',
visible: false,
visible: false
},
{
field: 'loginName',
@@ -28,6 +28,7 @@
<option value="2" th:field="*{dataScope}">自定数据权限</option>
<option value="3" th:field="*{dataScope}">本部门数据权限</option>
<option value="4" th:field="*{dataScope}">本部门及以下数据权限</option>
<option value="5" th:field="*{dataScope}">仅本人数据权限</option>
</select>
<span class="help-block m-b-none"><i class="fa fa-info-circle"></i> 特殊情况下,设置为“自定数据权限”</span>
</div>
@@ -18,6 +18,7 @@
<label class="col-sm-3 control-label">权限字符:</label>
<div class="col-sm-8">
<input class="form-control" type="text" name="roleKey" id="roleKey" th:field="*{roleKey}" required>
<span class="help-block m-b-none"><i class="fa fa-info-circle"></i> 控制器中定义的权限字符,如:@RequiresRoles("")</span>
</div>
</div>
<div class="form-group">
@@ -41,10 +41,10 @@
<a class="btn btn-success" onclick="$.operate.add()" shiro:hasPermission="system:role:add">
<i class="fa fa-plus"></i> 新增
</a>
<a class="btn btn-primary btn-edit disabled" onclick="$.operate.edit()" shiro:hasPermission="system:role:edit">
<a class="btn btn-primary single disabled" onclick="$.operate.edit()" shiro:hasPermission="system:role:edit">
<i class="fa fa-edit"></i> 修改
</a>
<a class="btn btn-danger btn-del disabled" onclick="$.operate.removeAll()" shiro:hasPermission="system:role:remove">
<a class="btn btn-danger multiple disabled" onclick="$.operate.removeAll()" shiro:hasPermission="system:role:remove">
<i class="fa fa-remove"></i> 删除
</a>
<a class="btn btn-warning" onclick="$.table.exportExcel()" shiro:hasPermission="system:role:export">

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