Compare commits
73 Commits
Author | SHA1 | Date | |
---|---|---|---|
d066539616 | |||
5c736e96c9 | |||
0307599eed | |||
55da596a80 | |||
6fa8c991b8 | |||
51f98aa0cb | |||
07042ac9b1 | |||
3df553c488 | |||
5426ba9d5e | |||
6b9ee80ca4 | |||
05b5b314ee | |||
f8491c36e2 | |||
06751acbf9 | |||
567ab47ae9 | |||
82f8dadbae | |||
ca6a4b2ecf | |||
9247e004d0 | |||
e1e494de33 | |||
3988b12e72 | |||
c6bf712de4 | |||
18e0a2a27d | |||
6ce34b1790 | |||
b5678994da | |||
2aa98dcbe1 | |||
96d0bd2581 | |||
f826a79633 | |||
c958d6ec83 | |||
5cb3430791 | |||
d93e43cc2c | |||
47f007ba97 | |||
f96328ea6b | |||
2d55917f2e | |||
1c6e5cf665 | |||
9d316c44d2 | |||
2f8422278a | |||
98dd156396 | |||
b65263fdd7 | |||
21992c1be7 | |||
d80c1d2a73 | |||
55978c7f15 | |||
b2012e699b | |||
382d1868be | |||
82df046e59 | |||
4f116a6a77 | |||
77d3db4cb0 | |||
1155bcb22d | |||
208c4a8417 | |||
62a0018041 | |||
f276a83956 | |||
28b8f3e36f | |||
56a6e940c2 | |||
868edbc88c | |||
b05a539970 | |||
2c48aedda7 | |||
87b8d032ca | |||
080237cabf | |||
005418e065 | |||
b32111f1ab | |||
25f51371f5 | |||
14bad9bf20 | |||
da2d0ba32f | |||
0b34c3e910 | |||
1557a858ea | |||
9a0098cca1 | |||
fe8c142cd6 | |||
5346af9ab0 | |||
de1979212a | |||
aa0f33b5e7 | |||
ecb77e2be4 | |||
db9d1a7720 | |||
6ad6f90968 | |||
b1b0542f72 | |||
7e749c25c6 |
@ -4,11 +4,11 @@
|
||||
|
||||
性别男,若依是给还没有出生女儿取的名字(寓意:你若不离不弃,我必生死相依)
|
||||
|
||||
若依参考后台模板。有需要可自行到群内下载。
|
||||
> 如需前后端分离版本,请移步 [RuoYi-Vue](https://gitee.com/y_project/RuoYi-Vue)
|
||||
|
||||
> 如需单应用,请移步 [RuoYi-fast](https://gitee.com/y_project/RuoYi-fast) `(保持同步更新)`,如需其他版本,请移步 [项目扩展](http://doc.ruoyi.vip/ruoyi/document/xmkz.html) `(不定时更新)`
|
||||
|
||||
> 阿里云通用云产品1888优惠券 :[点我领取](https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=brki8iof) 腾讯云通用云产品2860优惠券 :[点我领取](https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console) `(仅限新用户)`
|
||||
> 阿里云通用云产品1888优惠券 :[点我领取](https://www.aliyun.com/minisite/goods?userCode=brki8iof) 腾讯云通用云产品2860优惠券 :[点我领取](https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console) `(仅限新用户)`
|
||||
|
||||
> 阿里云Hi拼购 限量爆款 低至199元/年 [点我进入](https://www.aliyun.com/acts/hi-group-buying?userCode=brki8iof) `(仅限新用户)`
|
||||
|
||||
@ -80,11 +80,11 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://oscimg.oschina.net/oscnet/bed2b98a44e7ae820c2885329e711965c28.jpg"/></td>
|
||||
<td><img src="https://oscimg.oschina.net/oscnet/5f3d39a141f21f81b90536f391b8408f1fa.jpg"/></td>
|
||||
<td><img src="https://oscimg.oschina.net/oscnet/up-6d73c2140ce694e3de4c05035fdc1868d4c.png"/></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
## 若依交流群
|
||||
|
||||
QQ群: [](https://jq.qq.com/?_wv=1027&k=5HBAaYN) [](https://jq.qq.com/?_wv=1027&k=5cHeRVW) [](https://jq.qq.com/?_wv=1027&k=53R0L5Z) [](https://jq.qq.com/?_wv=1027&k=5g75dCU) [](https://jq.qq.com/?_wv=1027&k=58cPoHA) [](https://jq.qq.com/?_wv=1027&k=5Ofd4Pb) [](https://jq.qq.com/?_wv=1027&k=5yugASz) [](https://jq.qq.com/?_wv=1027&k=5Rf3d2P) 点击按钮入群。
|
||||
QQ群: [](https://jq.qq.com/?_wv=1027&k=5HBAaYN) [](https://jq.qq.com/?_wv=1027&k=5cHeRVW) [](https://jq.qq.com/?_wv=1027&k=53R0L5Z) [](https://jq.qq.com/?_wv=1027&k=5g75dCU) [](https://jq.qq.com/?_wv=1027&k=58cPoHA) [](https://jq.qq.com/?_wv=1027&k=5Ofd4Pb) [](https://jq.qq.com/?_wv=1027&k=5yugASz) [](https://jq.qq.com/?_wv=1027&k=5Rf3d2P) [](https://jq.qq.com/?_wv=1027&k=5ZIjaeP) [](https://jq.qq.com/?_wv=1027&k=5CJw1jY) [](https://jq.qq.com/?_wv=1027&k=5omzbKc)
|
7
pom.xml
7
pom.xml
@ -6,18 +6,18 @@
|
||||
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi</artifactId>
|
||||
<version>4.1.0</version>
|
||||
<version>4.2.0</version>
|
||||
|
||||
<name>ruoyi</name>
|
||||
<url>http://www.ruoyi.vip</url>
|
||||
<description>若依管理系统</description>
|
||||
|
||||
<properties>
|
||||
<ruoyi.version>4.1.0</ruoyi.version>
|
||||
<ruoyi.version>4.2.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>
|
||||
<shiro.version>1.4.1</shiro.version>
|
||||
<shiro.version>1.4.2</shiro.version>
|
||||
<thymeleaf.extras.shiro.version>2.0.0</thymeleaf.extras.shiro.version>
|
||||
<mybatis.boot.version>1.3.2</mybatis.boot.version>
|
||||
<druid.version>1.1.14</druid.version>
|
||||
@ -228,6 +228,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.1</version>
|
||||
<configuration>
|
||||
<source>${java.version}</source>
|
||||
<target>${java.version}</target>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>ruoyi</artifactId>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<version>4.1.0</version>
|
||||
<version>4.2.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<packaging>jar</packaging>
|
||||
@ -80,6 +80,7 @@
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>2.1.1.RELEASE</version>
|
||||
<configuration>
|
||||
<fork>true</fork> <!-- 如果没有该配置,devtools不会生效 -->
|
||||
</configuration>
|
||||
@ -97,11 +98,11 @@
|
||||
<version>3.0.0</version>
|
||||
<configuration>
|
||||
<failOnMissingWebXml>false</failOnMissingWebXml>
|
||||
<warName>${artifactId}</warName>
|
||||
<warName>${project.artifactId}</warName>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<finalName>${artifactId}</finalName>
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
</build>
|
||||
|
||||
</project>
|
@ -132,6 +132,19 @@ public class SysConfigController extends BaseController
|
||||
return toAjax(configService.deleteConfigByIds(ids));
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空缓存
|
||||
*/
|
||||
@RequiresPermissions("system:config:remove")
|
||||
@Log(title = "参数管理", businessType = BusinessType.CLEAN)
|
||||
@GetMapping("/clearCache")
|
||||
@ResponseBody
|
||||
public AjaxResult clearCache()
|
||||
{
|
||||
configService.clearCache();
|
||||
return success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验参数键名
|
||||
*/
|
||||
|
@ -125,14 +125,20 @@ public class SysDictTypeController extends BaseController
|
||||
@ResponseBody
|
||||
public AjaxResult remove(String ids)
|
||||
{
|
||||
try
|
||||
{
|
||||
return toAjax(dictTypeService.deleteDictTypeByIds(ids));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return error(e.getMessage());
|
||||
}
|
||||
return toAjax(dictTypeService.deleteDictTypeByIds(ids));
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空缓存
|
||||
*/
|
||||
@RequiresPermissions("system:dict:remove")
|
||||
@Log(title = "字典类型", businessType = BusinessType.CLEAN)
|
||||
@GetMapping("/clearCache")
|
||||
@ResponseBody
|
||||
public AjaxResult clearCache()
|
||||
{
|
||||
dictTypeService.clearCache();
|
||||
return success();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -10,6 +10,7 @@ import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.framework.util.ShiroUtils;
|
||||
import com.ruoyi.system.domain.SysMenu;
|
||||
import com.ruoyi.system.domain.SysUser;
|
||||
import com.ruoyi.system.service.ISysConfigService;
|
||||
import com.ruoyi.system.service.ISysMenuService;
|
||||
|
||||
/**
|
||||
@ -23,6 +24,9 @@ public class SysIndexController extends BaseController
|
||||
@Autowired
|
||||
private ISysMenuService menuService;
|
||||
|
||||
@Autowired
|
||||
private ISysConfigService configService;
|
||||
|
||||
// 系统首页
|
||||
@GetMapping("/index")
|
||||
public String index(ModelMap mmap)
|
||||
@ -33,6 +37,8 @@ public class SysIndexController extends BaseController
|
||||
List<SysMenu> menus = menuService.selectMenusByUser(user);
|
||||
mmap.put("menus", menus);
|
||||
mmap.put("user", user);
|
||||
mmap.put("sideTheme", configService.selectConfigByKey("sys.index.sideTheme"));
|
||||
mmap.put("skinName", configService.selectConfigByKey("sys.index.skinName"));
|
||||
mmap.put("copyrightYear", Global.getCopyrightYear());
|
||||
mmap.put("demoEnabled", Global.isDemoEnabled());
|
||||
return "index";
|
||||
|
@ -0,0 +1,46 @@
|
||||
package com.ruoyi.web.controller.system;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.framework.shiro.service.SysRegisterService;
|
||||
import com.ruoyi.system.domain.SysUser;
|
||||
import com.ruoyi.system.service.ISysConfigService;
|
||||
|
||||
/**
|
||||
* 注册验证
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Controller
|
||||
public class SysRegisterController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private SysRegisterService registerService;
|
||||
|
||||
@Autowired
|
||||
private ISysConfigService configService;
|
||||
|
||||
@GetMapping("/register")
|
||||
public String register()
|
||||
{
|
||||
return "register";
|
||||
}
|
||||
|
||||
@PostMapping("/register")
|
||||
@ResponseBody
|
||||
public AjaxResult ajaxRegister(SysUser user)
|
||||
{
|
||||
if (!("true".equals(configService.selectConfigByKey("sys.account.registerUser"))))
|
||||
{
|
||||
return error("当前系统没有开启注册功能!");
|
||||
}
|
||||
String msg = registerService.register(user);
|
||||
return StringUtils.isEmpty(msg) ? success() : error(msg);
|
||||
}
|
||||
}
|
@ -22,6 +22,7 @@ import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||
import com.ruoyi.framework.shiro.service.SysPasswordService;
|
||||
import com.ruoyi.framework.util.ShiroUtils;
|
||||
import com.ruoyi.system.domain.SysUser;
|
||||
import com.ruoyi.system.domain.SysUserRole;
|
||||
import com.ruoyi.system.service.ISysPostService;
|
||||
import com.ruoyi.system.service.ISysRoleService;
|
||||
import com.ruoyi.system.service.ISysUserService;
|
||||
@ -200,6 +201,33 @@ public class SysUserController extends BaseController
|
||||
return error();
|
||||
}
|
||||
|
||||
/**
|
||||
* 进入授权角色页
|
||||
*/
|
||||
@GetMapping("/authRole/{userId}")
|
||||
public String authRole(@PathVariable("userId") Long userId, ModelMap mmap)
|
||||
{
|
||||
SysUser user = userService.selectUserById(userId);
|
||||
// 获取用户所属的角色列表
|
||||
List<SysUserRole> userRoles = userService.selectUserRoleByUserId(userId);
|
||||
mmap.put("user", user);
|
||||
mmap.put("userRoles", userRoles);
|
||||
return prefix + "/authRole";
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户授权角色
|
||||
*/
|
||||
@RequiresPermissions("system:user:add")
|
||||
@Log(title = "用户管理", businessType = BusinessType.GRANT)
|
||||
@PostMapping("/authRole/insertAuthRole")
|
||||
@ResponseBody
|
||||
public AjaxResult insertAuthRole(Long userId, Long[] roleIds)
|
||||
{
|
||||
userService.insertUserAuth(userId, roleIds);
|
||||
return success();
|
||||
}
|
||||
|
||||
@RequiresPermissions("system:user:remove")
|
||||
@Log(title = "用户管理", businessType = BusinessType.DELETE)
|
||||
@PostMapping("/remove")
|
||||
|
@ -3,7 +3,7 @@ ruoyi:
|
||||
# 名称
|
||||
name: RuoYi
|
||||
# 版本
|
||||
version: 4.1.0
|
||||
version: 4.2.0
|
||||
# 版权年份
|
||||
copyrightYear: 2019
|
||||
# 实例演示开关
|
||||
|
@ -41,7 +41,31 @@
|
||||
timeToIdleSeconds="0"
|
||||
statistics="true">
|
||||
</cache>
|
||||
|
||||
|
||||
<!-- 系统缓存 -->
|
||||
<cache name="sys-cache"
|
||||
maxEntriesLocalHeap="1000"
|
||||
eternal="true"
|
||||
overflowToDisk="true"
|
||||
statistics="true">
|
||||
</cache>
|
||||
|
||||
<!-- 系统参数缓存 -->
|
||||
<cache name="sys-config"
|
||||
maxEntriesLocalHeap="1000"
|
||||
eternal="true"
|
||||
overflowToDisk="true"
|
||||
statistics="true">
|
||||
</cache>
|
||||
|
||||
<!-- 系统字典缓存 -->
|
||||
<cache name="sys-dict"
|
||||
maxEntriesLocalHeap="1000"
|
||||
eternal="true"
|
||||
overflowToDisk="true"
|
||||
statistics="true">
|
||||
</cache>
|
||||
|
||||
<!-- 系统会话缓存 -->
|
||||
<cache name="shiro-activeSessionCache"
|
||||
maxElementsInMemory="10000"
|
||||
@ -52,6 +76,6 @@
|
||||
diskPersistent="true"
|
||||
diskExpiryThreadIntervalSeconds="600">
|
||||
</cache>
|
||||
|
||||
|
||||
</ehcache>
|
||||
|
File diff suppressed because one or more lines are too long
@ -29,7 +29,7 @@
|
||||
|
||||
$.extend($.fn.bootstrapTable.locales, {
|
||||
formatExport: function () {
|
||||
return 'Export data';
|
||||
return '导出';
|
||||
}
|
||||
});
|
||||
$.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales);
|
||||
|
@ -241,19 +241,26 @@
|
||||
// 缓存并格式化数据
|
||||
var formatData = function(data) {
|
||||
var _root = options.rootIdValue ? options.rootIdValue : null;
|
||||
var firstCode = data[0][options.parentCode];
|
||||
// 父节点属性列表
|
||||
var parentCodes = [];
|
||||
var rootFlag = false;
|
||||
$.each(data, function(index, item) {
|
||||
if($.inArray(item[options.parentCode], parentCodes) == -1){
|
||||
parentCodes.push(item[options.parentCode]);
|
||||
}
|
||||
});
|
||||
$.each(data, function(index, item) {
|
||||
// 添加一个默认属性,用来判断当前节点有没有被显示
|
||||
item.isShow = false;
|
||||
// 这里兼容几种常见Root节点写法
|
||||
// 默认的几种判断
|
||||
// 顶级节点校验判断,兼容0,'0','',null
|
||||
var _defaultRootFlag = item[options.parentCode] == '0' ||
|
||||
item[options.parentCode] == 0 ||
|
||||
item[options.parentCode] == null ||
|
||||
item[options.parentCode] == firstCode ||
|
||||
item[options.parentCode] == '';
|
||||
item[options.parentCode] == 0 ||
|
||||
item[options.parentCode] == null ||
|
||||
item[options.parentCode] == '' ||
|
||||
$.inArray(item[options.code], parentCodes) > 0 && !rootFlag;
|
||||
if (!item[options.parentCode] || (_root ? (item[options.parentCode] == options.rootIdValue) : _defaultRootFlag)) {
|
||||
if (!target.data_list["_root_"]) {
|
||||
rootFlag = true;
|
||||
if (!target.data_list["_root_"]) {
|
||||
target.data_list["_root_"] = [];
|
||||
}
|
||||
if (!target.data_obj["id_" + item[options.code]]) {
|
||||
|
@ -4614,7 +4614,7 @@ S2.define('select2/i18n/en',[],function () {
|
||||
return '载入更多结果…';
|
||||
},
|
||||
maximumSelected: function (args) {
|
||||
var message = '最多只能选择' + args.maximum + '个项目';
|
||||
var message = '最多只能' + args.maximum + '个选项';
|
||||
|
||||
if (args.maximum != 1) {
|
||||
message += 's';
|
||||
|
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -5778,7 +5778,7 @@ td.visible-lg {
|
||||
display: table-cell !important;
|
||||
}
|
||||
}
|
||||
.hidden-xs {
|
||||
.summernote .hidden-xs {
|
||||
display: block !important;
|
||||
}
|
||||
tr.hidden-xs {
|
||||
|
@ -1,155 +1,155 @@
|
||||
(function($) {
|
||||
$.extend($.summernote.lang, {
|
||||
'zh-CN': {
|
||||
font: {
|
||||
bold: '粗体',
|
||||
italic: '斜体',
|
||||
underline: '下划线',
|
||||
clear: '清除格式',
|
||||
height: '行高',
|
||||
name: '字体',
|
||||
strikethrough: '删除线',
|
||||
subscript: '下标',
|
||||
superscript: '上标',
|
||||
size: '字号'
|
||||
},
|
||||
image: {
|
||||
image: '图片',
|
||||
insert: '插入图片',
|
||||
resizeFull: '缩放至 100%',
|
||||
resizeHalf: '缩放至 50%',
|
||||
resizeQuarter: '缩放至 25%',
|
||||
floatLeft: '靠左浮动',
|
||||
floatRight: '靠右浮动',
|
||||
floatNone: '取消浮动',
|
||||
shapeRounded: '形状: 圆角',
|
||||
shapeCircle: '形状: 圆',
|
||||
shapeThumbnail: '形状: 缩略图',
|
||||
shapeNone: '形状: 无',
|
||||
dragImageHere: '将图片拖拽至此处',
|
||||
dropImage: '拖拽图片或文本',
|
||||
selectFromFiles: '从本地上传',
|
||||
maximumFileSize: '文件大小最大值',
|
||||
maximumFileSizeError: '文件大小超出最大值。',
|
||||
url: '图片地址',
|
||||
remove: '移除图片',
|
||||
original: '原始图片'
|
||||
},
|
||||
video: {
|
||||
video: '视频',
|
||||
videoLink: '视频链接',
|
||||
insert: '插入视频',
|
||||
url: '视频地址',
|
||||
providers: '(优酷, 腾讯, Instagram, DailyMotion, Youtube等)'
|
||||
},
|
||||
link: {
|
||||
link: '链接',
|
||||
insert: '插入链接',
|
||||
unlink: '去除链接',
|
||||
edit: '编辑链接',
|
||||
textToDisplay: '显示文本',
|
||||
url: '链接地址',
|
||||
openInNewWindow: '在新窗口打开'
|
||||
},
|
||||
table: {
|
||||
table: '表格',
|
||||
addRowAbove: '在上方插入行',
|
||||
addRowBelow: '在下方插入行',
|
||||
addColLeft: '在左侧插入列',
|
||||
addColRight: '在右侧插入列',
|
||||
delRow: '删除行',
|
||||
delCol: '删除列',
|
||||
delTable: '删除表格'
|
||||
},
|
||||
hr: {
|
||||
insert: '水平线'
|
||||
},
|
||||
style: {
|
||||
style: '样式',
|
||||
p: '普通',
|
||||
blockquote: '引用',
|
||||
pre: '代码',
|
||||
h1: '标题 1',
|
||||
h2: '标题 2',
|
||||
h3: '标题 3',
|
||||
h4: '标题 4',
|
||||
h5: '标题 5',
|
||||
h6: '标题 6'
|
||||
},
|
||||
lists: {
|
||||
unordered: '无序列表',
|
||||
ordered: '有序列表'
|
||||
},
|
||||
options: {
|
||||
help: '帮助',
|
||||
fullscreen: '全屏',
|
||||
codeview: '源代码'
|
||||
},
|
||||
paragraph: {
|
||||
paragraph: '段落',
|
||||
outdent: '减少缩进',
|
||||
indent: '增加缩进',
|
||||
left: '左对齐',
|
||||
center: '居中对齐',
|
||||
right: '右对齐',
|
||||
justify: '两端对齐'
|
||||
},
|
||||
color: {
|
||||
recent: '最近使用',
|
||||
more: '更多',
|
||||
background: '背景',
|
||||
foreground: '前景',
|
||||
transparent: '透明',
|
||||
setTransparent: '透明',
|
||||
reset: '重置',
|
||||
resetToDefault: '默认'
|
||||
},
|
||||
shortcut: {
|
||||
shortcuts: '快捷键',
|
||||
close: '关闭',
|
||||
textFormatting: '文本格式',
|
||||
action: '动作',
|
||||
paragraphFormatting: '段落格式',
|
||||
documentStyle: '文档样式',
|
||||
extraKeys: '额外按键'
|
||||
},
|
||||
help: {
|
||||
insertParagraph: '插入段落',
|
||||
undo: '撤销',
|
||||
redo: '重做',
|
||||
tab: '增加缩进',
|
||||
untab: '减少缩进',
|
||||
bold: '粗体',
|
||||
italic: '斜体',
|
||||
underline: '下划线',
|
||||
strikethrough: '删除线',
|
||||
removeFormat: '清除格式',
|
||||
justifyLeft: '左对齐',
|
||||
justifyCenter: '居中对齐',
|
||||
justifyRight: '右对齐',
|
||||
justifyFull: '两端对齐',
|
||||
insertUnorderedList: '无序列表',
|
||||
insertOrderedList: '有序列表',
|
||||
outdent: '减少缩进',
|
||||
indent: '增加缩进',
|
||||
formatPara: '设置选中内容样式为 普通',
|
||||
formatH1: '设置选中内容样式为 标题1',
|
||||
formatH2: '设置选中内容样式为 标题2',
|
||||
formatH3: '设置选中内容样式为 标题3',
|
||||
formatH4: '设置选中内容样式为 标题4',
|
||||
formatH5: '设置选中内容样式为 标题5',
|
||||
formatH6: '设置选中内容样式为 标题6',
|
||||
insertHorizontalRule: '插入水平线',
|
||||
'linkDialog.show': '显示链接对话框'
|
||||
},
|
||||
history: {
|
||||
undo: '撤销',
|
||||
redo: '重做'
|
||||
},
|
||||
specialChar: {
|
||||
specialChar: '特殊字符',
|
||||
select: '选取特殊字符'
|
||||
}
|
||||
}
|
||||
});
|
||||
})(jQuery);
|
||||
(function($) {
|
||||
$.extend($.summernote.lang, {
|
||||
'zh-CN': {
|
||||
font: {
|
||||
bold: '粗体',
|
||||
italic: '斜体',
|
||||
underline: '下划线',
|
||||
clear: '清除格式',
|
||||
height: '行高',
|
||||
name: '字体',
|
||||
strikethrough: '删除线',
|
||||
subscript: '下标',
|
||||
superscript: '上标',
|
||||
size: '字号',
|
||||
},
|
||||
image: {
|
||||
image: '图片',
|
||||
insert: '插入图片',
|
||||
resizeFull: '缩放至 100%',
|
||||
resizeHalf: '缩放至 50%',
|
||||
resizeQuarter: '缩放至 25%',
|
||||
floatLeft: '靠左浮动',
|
||||
floatRight: '靠右浮动',
|
||||
floatNone: '取消浮动',
|
||||
shapeRounded: '形状: 圆角',
|
||||
shapeCircle: '形状: 圆',
|
||||
shapeThumbnail: '形状: 缩略图',
|
||||
shapeNone: '形状: 无',
|
||||
dragImageHere: '将图片拖拽至此处',
|
||||
dropImage: '拖拽图片或文本',
|
||||
selectFromFiles: '从本地上传',
|
||||
maximumFileSize: '文件大小最大值',
|
||||
maximumFileSizeError: '文件大小超出最大值。',
|
||||
url: '图片地址',
|
||||
remove: '移除图片',
|
||||
original: '原始图片',
|
||||
},
|
||||
video: {
|
||||
video: '视频',
|
||||
videoLink: '视频链接',
|
||||
insert: '插入视频',
|
||||
url: '视频地址',
|
||||
providers: '(优酷, 腾讯, Instagram, DailyMotion, Youtube等)',
|
||||
},
|
||||
link: {
|
||||
link: '链接',
|
||||
insert: '插入链接',
|
||||
unlink: '去除链接',
|
||||
edit: '编辑链接',
|
||||
textToDisplay: '显示文本',
|
||||
url: '链接地址',
|
||||
openInNewWindow: '在新窗口打开',
|
||||
},
|
||||
table: {
|
||||
table: '表格',
|
||||
addRowAbove: '在上方插入行',
|
||||
addRowBelow: '在下方插入行',
|
||||
addColLeft: '在左侧插入列',
|
||||
addColRight: '在右侧插入列',
|
||||
delRow: '删除行',
|
||||
delCol: '删除列',
|
||||
delTable: '删除表格',
|
||||
},
|
||||
hr: {
|
||||
insert: '水平线',
|
||||
},
|
||||
style: {
|
||||
style: '样式',
|
||||
p: '普通',
|
||||
blockquote: '引用',
|
||||
pre: '代码',
|
||||
h1: '标题 1',
|
||||
h2: '标题 2',
|
||||
h3: '标题 3',
|
||||
h4: '标题 4',
|
||||
h5: '标题 5',
|
||||
h6: '标题 6',
|
||||
},
|
||||
lists: {
|
||||
unordered: '无序列表',
|
||||
ordered: '有序列表',
|
||||
},
|
||||
options: {
|
||||
help: '帮助',
|
||||
fullscreen: '全屏',
|
||||
codeview: '源代码',
|
||||
},
|
||||
paragraph: {
|
||||
paragraph: '段落',
|
||||
outdent: '减少缩进',
|
||||
indent: '增加缩进',
|
||||
left: '左对齐',
|
||||
center: '居中对齐',
|
||||
right: '右对齐',
|
||||
justify: '两端对齐',
|
||||
},
|
||||
color: {
|
||||
recent: '最近使用',
|
||||
more: '更多',
|
||||
background: '背景',
|
||||
foreground: '前景',
|
||||
transparent: '透明',
|
||||
setTransparent: '透明',
|
||||
reset: '重置',
|
||||
resetToDefault: '默认',
|
||||
},
|
||||
shortcut: {
|
||||
shortcuts: '快捷键',
|
||||
close: '关闭',
|
||||
textFormatting: '文本格式',
|
||||
action: '动作',
|
||||
paragraphFormatting: '段落格式',
|
||||
documentStyle: '文档样式',
|
||||
extraKeys: '额外按键',
|
||||
},
|
||||
help: {
|
||||
insertParagraph: '插入段落',
|
||||
undo: '撤销',
|
||||
redo: '重做',
|
||||
tab: '增加缩进',
|
||||
untab: '减少缩进',
|
||||
bold: '粗体',
|
||||
italic: '斜体',
|
||||
underline: '下划线',
|
||||
strikethrough: '删除线',
|
||||
removeFormat: '清除格式',
|
||||
justifyLeft: '左对齐',
|
||||
justifyCenter: '居中对齐',
|
||||
justifyRight: '右对齐',
|
||||
justifyFull: '两端对齐',
|
||||
insertUnorderedList: '无序列表',
|
||||
insertOrderedList: '有序列表',
|
||||
outdent: '减少缩进',
|
||||
indent: '增加缩进',
|
||||
formatPara: '设置选中内容样式为 普通',
|
||||
formatH1: '设置选中内容样式为 标题1',
|
||||
formatH2: '设置选中内容样式为 标题2',
|
||||
formatH3: '设置选中内容样式为 标题3',
|
||||
formatH4: '设置选中内容样式为 标题4',
|
||||
formatH5: '设置选中内容样式为 标题5',
|
||||
formatH6: '设置选中内容样式为 标题6',
|
||||
insertHorizontalRule: '插入水平线',
|
||||
'linkDialog.show': '显示链接对话框',
|
||||
},
|
||||
history: {
|
||||
undo: '撤销',
|
||||
redo: '重做',
|
||||
},
|
||||
specialChar: {
|
||||
specialChar: '特殊字符',
|
||||
select: '选取特殊字符',
|
||||
},
|
||||
},
|
||||
});
|
||||
})(jQuery);
|
||||
|
@ -1,3 +0,0 @@
|
||||
/*! Summernote v0.8.11 | (c) 2013- Alan Hong and other contributors | MIT license */
|
||||
|
||||
!function(e){e.extend(e.summernote.lang,{"zh-CN":{font:{bold:"粗体",italic:"斜体",underline:"下划线",clear:"清除格式",height:"行高",name:"字体",strikethrough:"删除线",subscript:"下标",superscript:"上标",size:"字号"},image:{image:"图片",insert:"插入图片",resizeFull:"缩放至 100%",resizeHalf:"缩放至 50%",resizeQuarter:"缩放至 25%",floatLeft:"靠左浮动",floatRight:"靠右浮动",floatNone:"取消浮动",shapeRounded:"形状: 圆角",shapeCircle:"形状: 圆",shapeThumbnail:"形状: 缩略图",shapeNone:"形状: 无",dragImageHere:"将图片拖拽至此处",dropImage:"拖拽图片或文本",selectFromFiles:"从本地上传",maximumFileSize:"文件大小最大值",maximumFileSizeError:"文件大小超出最大值。",url:"图片地址",remove:"移除图片",original:"原始图片"},video:{video:"视频",videoLink:"视频链接",insert:"插入视频",url:"视频地址",providers:"(优酷, 腾讯, Instagram, DailyMotion, Youtube等)"},link:{link:"链接",insert:"插入链接",unlink:"去除链接",edit:"编辑链接",textToDisplay:"显示文本",url:"链接地址",openInNewWindow:"在新窗口打开"},table:{table:"表格",addRowAbove:"在上方插入行",addRowBelow:"在下方插入行",addColLeft:"在左侧插入列",addColRight:"在右侧插入列",delRow:"删除行",delCol:"删除列",delTable:"删除表格"},hr:{insert:"水平线"},style:{style:"样式",p:"普通",blockquote:"引用",pre:"代码",h1:"标题 1",h2:"标题 2",h3:"标题 3",h4:"标题 4",h5:"标题 5",h6:"标题 6"},lists:{unordered:"无序列表",ordered:"有序列表"},options:{help:"帮助",fullscreen:"全屏",codeview:"源代码"},paragraph:{paragraph:"段落",outdent:"减少缩进",indent:"增加缩进",left:"左对齐",center:"居中对齐",right:"右对齐",justify:"两端对齐"},color:{recent:"最近使用",more:"更多",background:"背景",foreground:"前景",transparent:"透明",setTransparent:"透明",reset:"重置",resetToDefault:"默认"},shortcut:{shortcuts:"快捷键",close:"关闭",textFormatting:"文本格式",action:"动作",paragraphFormatting:"段落格式",documentStyle:"文档样式",extraKeys:"额外按键"},help:{insertParagraph:"插入段落",undo:"撤销",redo:"重做",tab:"增加缩进",untab:"减少缩进",bold:"粗体",italic:"斜体",underline:"下划线",strikethrough:"删除线",removeFormat:"清除格式",justifyLeft:"左对齐",justifyCenter:"居中对齐",justifyRight:"右对齐",justifyFull:"两端对齐",insertUnorderedList:"无序列表",insertOrderedList:"有序列表",outdent:"减少缩进",indent:"增加缩进",formatPara:"设置选中内容样式为 普通",formatH1:"设置选中内容样式为 标题1",formatH2:"设置选中内容样式为 标题2",formatH3:"设置选中内容样式为 标题3",formatH4:"设置选中内容样式为 标题4",formatH5:"设置选中内容样式为 标题5",formatH6:"设置选中内容样式为 标题6",insertHorizontalRule:"插入水平线","linkDialog.show":"显示链接对话框"},history:{undo:"撤销",redo:"重做"},specialChar:{specialChar:"特殊字符",select:"选取特殊字符"}}})}(jQuery);
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@ -5,7 +5,7 @@
|
||||
*
|
||||
*/
|
||||
/** 蓝色主题 skin-blue **/
|
||||
.skin-blue .navbar {
|
||||
.navbar, .skin-blue .navbar {
|
||||
background-color: #3c8dbc
|
||||
}
|
||||
|
||||
@ -103,11 +103,6 @@
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
.skin-blue .nav>li>.treeview-menu {
|
||||
margin: 0 1px;
|
||||
background: #2c3b41
|
||||
}
|
||||
|
||||
.skin-blue .sidebar a {
|
||||
color: #b8c7ce
|
||||
}
|
||||
@ -116,15 +111,6 @@
|
||||
text-decoration: none
|
||||
}
|
||||
|
||||
.skin-blue .treeview-menu>li>a {
|
||||
color: #8aa4af
|
||||
}
|
||||
|
||||
.skin-blue .treeview-menu>li.active>a,
|
||||
.skin-blue .treeview-menu>li>a:hover {
|
||||
color: #fff
|
||||
}
|
||||
|
||||
.skin-blue .sidebar-form {
|
||||
border-radius: 3px;
|
||||
border: 1px solid #374850;
|
||||
@ -292,11 +278,6 @@
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
.skin-green .nav>li>.treeview-menu {
|
||||
margin: 0 1px;
|
||||
background: #2c3b41
|
||||
}
|
||||
|
||||
.skin-green .sidebar a {
|
||||
color: #b8c7ce
|
||||
}
|
||||
@ -305,15 +286,6 @@
|
||||
text-decoration: none
|
||||
}
|
||||
|
||||
.skin-green .treeview-menu>li>a {
|
||||
color: #8aa4af
|
||||
}
|
||||
|
||||
.skin-green .treeview-menu>li.active>a,
|
||||
.skin-green .treeview-menu>li>a:hover {
|
||||
color: #fff
|
||||
}
|
||||
|
||||
.skin-green .sidebar-form {
|
||||
border-radius: 3px;
|
||||
border: 1px solid #374850;
|
||||
@ -457,11 +429,6 @@
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
}
|
||||
|
||||
.skin-red .nav>li>.treeview-menu {
|
||||
margin: 0 1px;
|
||||
background: #2c3b41
|
||||
}
|
||||
|
||||
.skin-red .sidebar a {
|
||||
color: #b8c7ce
|
||||
}
|
||||
@ -470,15 +437,6 @@
|
||||
text-decoration: none
|
||||
}
|
||||
|
||||
.skin-red .treeview-menu>li>a {
|
||||
color: #8aa4af
|
||||
}
|
||||
|
||||
.skin-red .treeview-menu>li.active>a,
|
||||
.skin-red .treeview-menu>li>a:hover {
|
||||
color: #fff
|
||||
}
|
||||
|
||||
.skin-red .sidebar-form {
|
||||
border-radius: 3px;
|
||||
border: 1px solid #374850;
|
||||
@ -622,11 +580,6 @@
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
}
|
||||
|
||||
.skin-yellow .nav>li>.treeview-menu {
|
||||
margin: 0 1px;
|
||||
background: #2c3b41
|
||||
}
|
||||
|
||||
.skin-yellow .sidebar a {
|
||||
color: #b8c7ce
|
||||
}
|
||||
@ -635,15 +588,6 @@
|
||||
text-decoration: none
|
||||
}
|
||||
|
||||
.skin-yellow .treeview-menu>li>a {
|
||||
color: #8aa4af
|
||||
}
|
||||
|
||||
.skin-yellow .treeview-menu>li.active>a,
|
||||
.skin-yellow .treeview-menu>li>a:hover {
|
||||
color: #fff
|
||||
}
|
||||
|
||||
.skin-yellow .sidebar-form {
|
||||
border-radius: 3px;
|
||||
border: 1px solid #374850;
|
||||
@ -787,11 +731,6 @@
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
}
|
||||
|
||||
.skin-purple .nav>li>.treeview-menu {
|
||||
margin: 0 1px;
|
||||
background: #2c3b41
|
||||
}
|
||||
|
||||
.skin-purple .sidebar a {
|
||||
color: #b8c7ce
|
||||
}
|
||||
@ -800,15 +739,6 @@
|
||||
text-decoration: none
|
||||
}
|
||||
|
||||
.skin-purple .treeview-menu>li>a {
|
||||
color: #8aa4af
|
||||
}
|
||||
|
||||
.skin-purple .treeview-menu>li.active>a,
|
||||
.skin-purple .treeview-menu>li>a:hover {
|
||||
color: #fff
|
||||
}
|
||||
|
||||
.skin-purple .sidebar-form {
|
||||
border-radius: 3px;
|
||||
border: 1px solid #374850;
|
||||
@ -855,7 +785,7 @@
|
||||
* NAME - .theme-dark/theme-light
|
||||
*
|
||||
*/
|
||||
/** 深色主题 .theme-dark **/
|
||||
/** 深黑主题 .theme-dark **/
|
||||
.theme-dark .user-panel>.info>p, .theme-dark .user-panel>.info, .theme-dark .user-panel>.info>a{
|
||||
color: #fff
|
||||
}
|
||||
@ -961,4 +891,94 @@
|
||||
.fixed-sidebar.theme-light.mini-navbar .nav li:hover>.nav-second-level {
|
||||
background-color: #f9fafc;
|
||||
}
|
||||
|
||||
|
||||
/** 深蓝主题 theme-light **/
|
||||
/**
|
||||
.skin-blue.theme-blue .logo, .skin-white.theme-blue .logo {
|
||||
background-color: rgba(15,41,80,1) !important;
|
||||
color: #fff;
|
||||
}
|
||||
**/
|
||||
.theme-blue .user-panel>.info>p, .theme-blue .user-panel>.info, .theme-blue .user-panel>.info>a{
|
||||
color: #a3b1cc
|
||||
}
|
||||
|
||||
.theme-blue .nav>li.active{
|
||||
background-color: rgba(15,41,80,1);
|
||||
}
|
||||
|
||||
.theme-blue .navbar-static-side {
|
||||
background-color: rgba(15,41,80,1);
|
||||
box-shadow: 2px 0 2px 0 rgba(29,35,41,.05);
|
||||
}
|
||||
|
||||
.theme-blue .user-panel {
|
||||
background-color: rgba(15,41,80,1);
|
||||
}
|
||||
|
||||
.theme-blue .navbar-default .nav>li>a {
|
||||
color: #a3b1cc;
|
||||
}
|
||||
|
||||
.theme-blue.skin-blue .navbar-default .nav>li.active>a {
|
||||
color: #1890ff;
|
||||
}
|
||||
|
||||
.theme-blue.skin-blue .navbar-default .nav>li.selected>a,
|
||||
.theme-blue.skin-blue .navbar-default .nav>li.selected>a:focus {
|
||||
background-color: #1890ff;
|
||||
}
|
||||
|
||||
.theme-blue.skin-green .navbar-default .nav>li.active>a {
|
||||
color: #52c41a;
|
||||
}
|
||||
|
||||
.theme-blue.skin-green .navbar-default .nav>li.selected>a,
|
||||
.theme-blue.skin-green .navbar-default .nav>li.selected>a:focus {
|
||||
background-color: #52c41a;
|
||||
color: rgba(255,255,255,1);
|
||||
}
|
||||
|
||||
.theme-blue.skin-purple .navbar-default .nav>li.active>a {
|
||||
color: rgb(114, 46, 209);
|
||||
}
|
||||
|
||||
.theme-blue.skin-purple .navbar-default .nav>li.selected>a,
|
||||
.theme-blue.skin-purple .navbar-default .nav>li.selected>a:focus {
|
||||
background-color: #722ed1;
|
||||
color: rgba(255,255,255,1);
|
||||
}
|
||||
|
||||
.theme-blue.skin-red .navbar-default .nav>li.active>a {
|
||||
color: rgb(245, 34, 45);
|
||||
}
|
||||
|
||||
.theme-blue.skin-red .navbar-default .nav>li.selected>a,
|
||||
.theme-blue.skin-red .navbar-default .nav>li.selected>a:focus {
|
||||
background-color: #f5222d;
|
||||
color: rgba(255,255,255,1);
|
||||
}
|
||||
|
||||
.theme-blue.skin-yellow .navbar-default .nav>li.active>a {
|
||||
color: rgb(250, 173, 20);
|
||||
}
|
||||
|
||||
.theme-blue.skin-yellow .navbar-default .nav>li.selected>a,
|
||||
.theme-blue.skin-yellow .navbar-default .nav>li.selected>a:focus {
|
||||
background-color: #faad14;
|
||||
color: rgba(255,255,255,1);
|
||||
}
|
||||
|
||||
.theme-blue .navbar-default .nav>li>a:hover,
|
||||
.theme-blue .navbar-default .nav>li>a:focus {
|
||||
background-color: rgba(15,41,80,1);
|
||||
box-shadow: 2px 0 2px 0 rgba(29,35,41,.05);
|
||||
}
|
||||
|
||||
.fixed-sidebar.theme-blue.mini-navbar .nav li:hover>a> span.nav-label {
|
||||
background-color: rgba(15,41,80,1);
|
||||
}
|
||||
|
||||
.fixed-sidebar.theme-blue.mini-navbar .nav li:hover>.nav-second-level {
|
||||
background-color: rgba(15,41,80,1);
|
||||
}
|
||||
|
@ -763,15 +763,15 @@ body.canvas-menu.mini-navbar nav.navbar-static-side {
|
||||
}
|
||||
|
||||
.btn-default {
|
||||
background-color: #c2c2c2;
|
||||
border-color: #c2c2c2;
|
||||
color: #FFFFFF;
|
||||
background-color: #f4f4f4;
|
||||
border-color: #ddd;
|
||||
color: #444;
|
||||
}
|
||||
|
||||
.btn-default:hover, .btn-default:focus, .btn-default:active, .btn-default.active, .open .dropdown-toggle.btn-default {
|
||||
background-color: #bababa;
|
||||
border-color: #bababa;
|
||||
color: #FFFFFF;
|
||||
background-color: #e7e7e7;
|
||||
border-color: #e7e7e7;
|
||||
color: #444;
|
||||
}
|
||||
|
||||
.btn-default:active, .btn-default.active, .open .dropdown-toggle.btn-default {
|
||||
@ -6939,7 +6939,7 @@ body.rtls .top-navigation .footer.fixed, body.rtls.top-navigation .footer.fixed
|
||||
background: #f5f5f5;
|
||||
}
|
||||
|
||||
.nav .logo {
|
||||
nav .logo {
|
||||
background-color: #367fa9;
|
||||
color: #fff;
|
||||
border-bottom: 0 solid transparent;
|
||||
|
@ -18,6 +18,7 @@ user.password.not.valid=* 5-50个字符
|
||||
user.email.not.valid=邮箱格式错误
|
||||
user.mobile.phone.number.not.valid=手机号格式错误
|
||||
user.login.success=登录成功
|
||||
user.register.success=注册成功
|
||||
user.notfound=请重新登录
|
||||
user.forcelogout=管理员强制退出,请重新登录
|
||||
user.unknown.error=未知错误,请重新登录
|
||||
|
@ -322,12 +322,18 @@
|
||||
}
|
||||
|
||||
/** 表单验证 样式布局 **/
|
||||
.control-label.is-required:before {
|
||||
content: '* ';
|
||||
color: red;
|
||||
}
|
||||
|
||||
label.error {
|
||||
position: absolute;
|
||||
right: 18px;
|
||||
top: 10px;
|
||||
color: #ef392b;
|
||||
font-size: 12px
|
||||
font-size: 12px;
|
||||
z-index:99;
|
||||
}
|
||||
|
||||
.input-group label.error {
|
||||
@ -638,7 +644,7 @@ label {
|
||||
margin: 5px 15px 5px 0px;
|
||||
}
|
||||
|
||||
.select-list li p{
|
||||
.select-list li p, .select-list li label:not(.radio-box){
|
||||
float: left;
|
||||
width: 65px;
|
||||
margin: 5px 5px 5px 0px;
|
||||
@ -811,12 +817,26 @@ label {
|
||||
border: 0px!important;
|
||||
}
|
||||
|
||||
.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 {
|
||||
.table-striped table>thead>tr>th, .table-striped table>tbody>tr>th, .table-striped table>tfoot>tr>th, .table-striped table>thead>tr>td, .table-striped table>tbody>tr>td, .table-striped table>tfoot>tr>td {
|
||||
border-bottom: 1px solid #e7eaec!important;
|
||||
background-color: transparent;
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
|
||||
.table-bordered table>thead>tr>th:first-child, .table-bordered table>tbody>tr>td:first-child {
|
||||
border-left: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.table-bordered table>thead>tr>th:last-child, .table-bordered table>tbody>tr>td:last-child {
|
||||
border-right: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.table-bordered table>thead>tr>th, .table-bordered table>tbody>tr>td {
|
||||
border-top: 1px solid #ddd!important;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.fixed-table-footer {
|
||||
border-top: 0px solid #ddd;
|
||||
}
|
||||
@ -838,10 +858,6 @@ label {
|
||||
background-color: #eff3f8;
|
||||
}
|
||||
|
||||
.table-bordered td,.table-bordered th {
|
||||
border: 1px solid #ddd!important
|
||||
}
|
||||
|
||||
.fixed-table-container thead th >.both{
|
||||
display: inline-block
|
||||
}
|
||||
@ -893,7 +909,7 @@ 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{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 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 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;}
|
||||
@ -998,6 +1014,50 @@ label {
|
||||
background-color: #F5F5F5;
|
||||
}
|
||||
|
||||
/** 气泡弹出框样式 **/
|
||||
.popover {
|
||||
font-size: 13px;
|
||||
max-width: unset;
|
||||
}
|
||||
|
||||
.popover-title {
|
||||
padding: 8px 14px;
|
||||
margin: 0 !important;
|
||||
font-size: 14px;
|
||||
background-color: #f7f7f7;
|
||||
border-bottom: 1px solid #ebebeb;
|
||||
border-radius: 5px 5px 0 0;
|
||||
}
|
||||
|
||||
.popover-content {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
/** 向上滚动样式 **/
|
||||
#scroll-up {
|
||||
border-width: 0;
|
||||
position: fixed;
|
||||
right: 2px;
|
||||
z-index: 99;
|
||||
-webkit-transition-duration: .3s;
|
||||
transition-duration: .3s;
|
||||
opacity: 0;
|
||||
filter: alpha(opacity=0);
|
||||
bottom: -24px;
|
||||
visibility: hidden;
|
||||
background-color: #aaa;
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
#scroll-up.display {
|
||||
opacity: .7;
|
||||
filter: alpha(opacity=70);
|
||||
bottom: 2px;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
height: 10px;
|
||||
|
@ -7,14 +7,16 @@ layer.config({
|
||||
skin: 'layer-ext-moon'
|
||||
});
|
||||
|
||||
var isMobile = $.common.isMobile() || $(window).width() < 769;
|
||||
|
||||
$(function() {
|
||||
// MetsiMenu
|
||||
$('#side-menu').metisMenu();
|
||||
|
||||
//固定菜单栏
|
||||
// 固定菜单栏
|
||||
$(function() {
|
||||
$('.sidebar-collapse').slimScroll({
|
||||
height: '100%',
|
||||
height: '96%',
|
||||
railOpacity: 0.9,
|
||||
alwaysVisible: false
|
||||
});
|
||||
@ -22,16 +24,21 @@ $(function() {
|
||||
|
||||
// 菜单切换
|
||||
$('.navbar-minimalize').click(function() {
|
||||
$("body").toggleClass("mini-navbar");
|
||||
if (isMobile) {
|
||||
$("body").toggleClass("canvas-menu");
|
||||
} else {
|
||||
$("body").toggleClass("mini-navbar");
|
||||
}
|
||||
SmoothlyMenu();
|
||||
});
|
||||
|
||||
|
||||
$('#side-menu>li').click(function() {
|
||||
if ($('body').hasClass('mini-navbar')) {
|
||||
if ($('body').hasClass('canvas-menu mini-navbar')) {
|
||||
NavToggle();
|
||||
}
|
||||
|
||||
});
|
||||
$('#side-menu>li li a').click(function() {
|
||||
$('#side-menu>li li a:not(:has(span))').click(function() {
|
||||
if ($(window).width() < 769) {
|
||||
NavToggle();
|
||||
}
|
||||
@ -49,9 +56,8 @@ $(function() {
|
||||
$(window).bind("load resize",
|
||||
function() {
|
||||
if ($(this).width() < 769) {
|
||||
$('body').addClass('mini-navbar');
|
||||
$('.navbar-static-side').fadeIn();
|
||||
$(".sidebar-collapse .logo").addClass("hide");
|
||||
$('body').addClass('canvas-menu');
|
||||
$("nav .logo").addClass("hide");
|
||||
$(".slimScrollDiv").css({ "overflow":"hidden" })
|
||||
}
|
||||
});
|
||||
@ -60,21 +66,27 @@ function NavToggle() {
|
||||
$('.navbar-minimalize').trigger('click');
|
||||
}
|
||||
|
||||
function fixedSidebar() {
|
||||
$('#side-menu').hide();
|
||||
$("nav .logo").addClass("hide");
|
||||
setTimeout(function() {
|
||||
$('#side-menu').fadeIn(500);
|
||||
},
|
||||
100);
|
||||
}
|
||||
|
||||
function SmoothlyMenu() {
|
||||
if (!$('body').hasClass('mini-navbar')) {
|
||||
$('#side-menu').hide();
|
||||
$(".sidebar-collapse .logo").removeClass("hide");
|
||||
setTimeout(function() {
|
||||
$('#side-menu').fadeIn(500);
|
||||
},
|
||||
100);
|
||||
} else if ($('body').hasClass('fixed-sidebar')) {
|
||||
$('#side-menu').hide();
|
||||
$(".sidebar-collapse .logo").addClass("hide");
|
||||
setTimeout(function() {
|
||||
$('#side-menu').fadeIn(500);
|
||||
},
|
||||
300);
|
||||
if (isMobile && !$('body').hasClass('canvas-menu')) {
|
||||
$('.navbar-static-side').fadeIn();
|
||||
fixedSidebar();
|
||||
} else if (!isMobile &&!$('body').hasClass('mini-navbar')) {
|
||||
fixedSidebar();
|
||||
$("nav .logo").removeClass("hide");
|
||||
} else if (isMobile && $('body').hasClass('fixed-sidebar')) {
|
||||
$('.navbar-static-side').fadeOut();
|
||||
fixedSidebar();
|
||||
} else if (!isMobile && $('body').hasClass('fixed-sidebar')) {
|
||||
fixedSidebar();
|
||||
} else {
|
||||
$('#side-menu').removeAttr('style');
|
||||
}
|
||||
@ -482,9 +494,13 @@ $(function() {
|
||||
|
||||
// 设置锚点
|
||||
function setIframeUrl(href) {
|
||||
var nowUrl = window.location.href;
|
||||
var newUrl = nowUrl.substring(0, nowUrl.indexOf("#"));
|
||||
window.location.href = newUrl + "#" + href;
|
||||
if($.common.equals("history", mode)) {
|
||||
storage.set('publicPath', href);
|
||||
} else {
|
||||
var nowUrl = window.location.href;
|
||||
var newUrl = nowUrl.substring(0, nowUrl.indexOf("#"));
|
||||
window.location.href = newUrl + "#" + href;
|
||||
}
|
||||
}
|
||||
|
||||
$(window).keydown(function(event) {
|
||||
@ -571,7 +587,6 @@ $(function() {
|
||||
setActiveTab(this);
|
||||
var target = $('.RuoYi_iframe[data-id="' + this.data('id') + '"]');
|
||||
var url = target.attr('src');
|
||||
target.attr('src', url).ready();
|
||||
$.modal.loading("数据加载中,请稍后...");
|
||||
target.attr('src', url).load(function () {
|
||||
$.modal.closeLoading();
|
||||
@ -588,4 +603,4 @@ $(function() {
|
||||
},
|
||||
}
|
||||
})
|
||||
});
|
||||
});
|
||||
|
@ -12,6 +12,11 @@ $(function() {
|
||||
});
|
||||
}
|
||||
|
||||
// 回到顶部绑定
|
||||
if ($.fn.toTop !== undefined) {
|
||||
$('#scroll-up').toTop();
|
||||
}
|
||||
|
||||
// select2复选框事件绑定
|
||||
if ($.fn.select2 !== undefined) {
|
||||
$.fn.select2.defaults.set( "theme", "bootstrap" );
|
||||
@ -66,9 +71,9 @@ $(function() {
|
||||
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 = '';
|
||||
startDate.config.max.year = '2099';
|
||||
startDate.config.max.month = '12';
|
||||
startDate.config.max.date = '31';
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -154,6 +159,49 @@ $(function() {
|
||||
});
|
||||
});
|
||||
|
||||
(function ($) {
|
||||
'use strict';
|
||||
$.fn.toTop = function(opt) {
|
||||
var elem = this;
|
||||
var win = $(window);
|
||||
var doc = $('html, body');
|
||||
var options = $.extend({
|
||||
autohide: true,
|
||||
offset: 50,
|
||||
speed: 500,
|
||||
position: true,
|
||||
right: 15,
|
||||
bottom: 5
|
||||
}, opt);
|
||||
elem.css({
|
||||
'cursor': 'pointer'
|
||||
});
|
||||
if (options.autohide) {
|
||||
elem.css('display', 'none');
|
||||
}
|
||||
if (options.position) {
|
||||
elem.css({
|
||||
'position': 'fixed',
|
||||
'right': options.right,
|
||||
'bottom': options.bottom,
|
||||
});
|
||||
}
|
||||
elem.click(function() {
|
||||
doc.animate({
|
||||
scrollTop: 0
|
||||
}, options.speed);
|
||||
});
|
||||
win.scroll(function() {
|
||||
var scrolling = win.scrollTop();
|
||||
if (options.autohide) {
|
||||
if (scrolling > options.offset) {
|
||||
elem.fadeIn(options.speed);
|
||||
} else elem.fadeOut(options.speed);
|
||||
}
|
||||
});
|
||||
};
|
||||
})(jQuery);
|
||||
|
||||
/** 刷新选项卡 */
|
||||
var refreshItem = function(){
|
||||
var topWindow = $(window.parent.document);
|
||||
|
@ -58,6 +58,7 @@ var table = {
|
||||
showToggle: true,
|
||||
showExport: false,
|
||||
clickToSelect: false,
|
||||
singleSelect: false,
|
||||
mobileResponsive: true,
|
||||
rememberSelected: false,
|
||||
fixedColumns: false,
|
||||
@ -72,6 +73,7 @@ var table = {
|
||||
table.config[options.id] = options;
|
||||
$.table.initEvent();
|
||||
$('#' + options.id).bootstrapTable({
|
||||
id: options.id,
|
||||
url: options.url, // 请求后台的URL(*)
|
||||
contentType: "application/x-www-form-urlencoded", // 编码类型
|
||||
method: 'post', // 请求方式(*)
|
||||
@ -102,6 +104,7 @@ var table = {
|
||||
showExport: options.showExport, // 是否支持导出文件
|
||||
uniqueId: options.uniqueId, // 唯 一的标识符
|
||||
clickToSelect: options.clickToSelect, // 是否启用点击选中行
|
||||
singleSelect: options.singleSelect, // 是否单选checkbox
|
||||
mobileResponsive: options.mobileResponsive, // 是否支持移动端适配
|
||||
detailView: options.detailView, // 是否启用显示细节视图
|
||||
onClickRow: options.onClickRow, // 点击某行触发的事件
|
||||
@ -250,7 +253,27 @@ var table = {
|
||||
table.options.onLoadSuccess(data);
|
||||
}
|
||||
// 浮动提示框特效
|
||||
$("[data-toggle='tooltip']").tooltip();
|
||||
$(".table [data-toggle='tooltip']").tooltip();
|
||||
|
||||
// 气泡弹出框特效
|
||||
$('.table [data-toggle="popover"]').each(function() {
|
||||
$(this).popover({ trigger: "manual", html: true, animation: false, container: "body", placement: "left"
|
||||
}).on("mouseenter",
|
||||
function() {
|
||||
var _this = this;
|
||||
$(this).popover("show");
|
||||
$(".popover").on("mouseleave", function() {
|
||||
$(_this).popover('hide');
|
||||
});
|
||||
}).on("mouseleave",
|
||||
function() {
|
||||
var _this = this;
|
||||
setTimeout(function() {
|
||||
if (!$(".popover:hover").length)
|
||||
$(_this).popover("hide");
|
||||
}, 100);
|
||||
});
|
||||
});
|
||||
},
|
||||
// 表格销毁
|
||||
destroy: function (tableId) {
|
||||
@ -273,10 +296,11 @@ var table = {
|
||||
var _target = $.common.isEmpty(target) ? 'copy' : target;
|
||||
if (_value.length > _length) {
|
||||
_text = _value.substr(0, _length) + "...";
|
||||
_value = _value.replace(/\'/g,"’");
|
||||
_value = _value.replace(/\'/g,"'");
|
||||
_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' data-target='%s' title='%s'>%s</a>", _target, _value, _text));
|
||||
actions.push($.common.sprintf('<a href="###" class="tooltip-show" data-toggle="tooltip" data-target="%s" title="%s">%s</a>', _target, _value, _text));
|
||||
return actions.join('');
|
||||
} else {
|
||||
_text = _value;
|
||||
@ -341,8 +365,12 @@ var table = {
|
||||
table.set();
|
||||
$.modal.confirm("确定导出所有" + table.options.modalName + "吗?", function() {
|
||||
var currentId = $.common.isEmpty(formId) ? $('form').attr('id') : formId;
|
||||
var params = $("#" + table.options.id).bootstrapTable('getOptions');
|
||||
var dataParam = $("#" + currentId).serializeArray();
|
||||
dataParam.push({ "name": "orderByColumn", "value": params.sortName });
|
||||
dataParam.push({ "name": "isAsc", "value": params.sortOrder });
|
||||
$.modal.loading("正在导出数据,请稍后...");
|
||||
$.post(table.options.exportUrl, $("#" + currentId).serializeArray(), function(result) {
|
||||
$.post(table.options.exportUrl, dataParam, function(result) {
|
||||
if (result.code == web_status.SUCCESS) {
|
||||
window.location.href = ctx + "common/download?fileName=" + encodeURI(result.msg) + "&delete=" + true;
|
||||
} else if (result.code == web_status.WARNING) {
|
||||
@ -391,9 +419,7 @@ var table = {
|
||||
}
|
||||
var index = layer.load(2, {shade: false});
|
||||
$.modal.disable();
|
||||
var formData = new FormData();
|
||||
formData.append("file", $('#file')[0].files[0]);
|
||||
formData.append("updateSupport", $("input[name='updateSupport']").is(':checked'));
|
||||
var formData = new FormData(layero.find('form')[0]);
|
||||
$.ajax({
|
||||
url: table.options.importUrl,
|
||||
data: formData,
|
||||
@ -526,7 +552,7 @@ var table = {
|
||||
height: options.height, // 表格树的高度
|
||||
expandColumn: options.expandColumn, // 在哪一列上面显示展开按钮
|
||||
striped: options.striped, // 是否显示行间隔色
|
||||
bordered: true, // 是否显示边框
|
||||
bordered: false, // 是否显示边框
|
||||
toolbar: '#' + options.toolbar, // 指定工作栏
|
||||
showSearch: options.showSearch, // 是否显示检索信息
|
||||
showRefresh: options.showRefresh, // 是否显示刷新按钮
|
||||
@ -555,12 +581,15 @@ var table = {
|
||||
return $.common.uniqueFn(rows);
|
||||
},
|
||||
// 请求获取数据后处理回调函数,校验异常状态提醒
|
||||
responseHandler: function(data) {
|
||||
if (data.code != undefined && data.code != 0) {
|
||||
$.modal.alertWarning(data.msg);
|
||||
responseHandler: function(res) {
|
||||
if (typeof table.options.responseHandler == "function") {
|
||||
table.options.responseHandler(res);
|
||||
}
|
||||
if (res.code != undefined && res.code != 0) {
|
||||
$.modal.alertWarning(res.msg);
|
||||
return [];
|
||||
} else {
|
||||
return data;
|
||||
return res;
|
||||
}
|
||||
},
|
||||
},
|
||||
@ -577,6 +606,12 @@ var table = {
|
||||
} else{
|
||||
$("#" + tableId).bootstrapTable('refresh');
|
||||
}
|
||||
} else if (table.options.type == table_type.bootstrapTreeTable) {
|
||||
if($.common.isEmpty(tableId)){
|
||||
$("#" + table.options.id).bootstrapTreeTable('refresh', []);
|
||||
} else{
|
||||
$("#" + tableId).bootstrapTreeTable('refresh', []);
|
||||
}
|
||||
}
|
||||
},
|
||||
// 获取选中复选框项
|
||||
@ -695,7 +730,7 @@ var table = {
|
||||
// 弹出层指定宽度
|
||||
open: function (title, url, width, height, callback) {
|
||||
//如果是移动端,就使用自适应大小弹窗
|
||||
if (navigator.userAgent.match(/(iPhone|iPod|Android|ios)/i)) {
|
||||
if ($.common.isMobile()) {
|
||||
width = 'auto';
|
||||
height = 'auto';
|
||||
}
|
||||
@ -767,7 +802,7 @@ var table = {
|
||||
// 弹出层全屏
|
||||
openFull: function (title, url, width, height) {
|
||||
//如果是移动端,就使用自适应大小弹窗
|
||||
if (navigator.userAgent.match(/(iPhone|iPod|Android|ios)/i)) {
|
||||
if ($.common.isMobile()) {
|
||||
width = 'auto';
|
||||
height = 'auto';
|
||||
}
|
||||
@ -880,7 +915,7 @@ var table = {
|
||||
var _width = $.common.isEmpty(width) ? "800" : width;
|
||||
var _height = $.common.isEmpty(height) ? ($(window).height() - 50) : height;
|
||||
//如果是移动端,就使用自适应大小弹窗
|
||||
if (navigator.userAgent.match(/(iPhone|iPod|Android|ios)/i)) {
|
||||
if ($.common.isMobile()) {
|
||||
_width = 'auto';
|
||||
_height = 'auto';
|
||||
}
|
||||
@ -1089,7 +1124,9 @@ var table = {
|
||||
} else if (result.code == web_status.SUCCESS && table.options.type == table_type.bootstrapTreeTable) {
|
||||
$.modal.msgSuccess(result.msg);
|
||||
$.treeTable.refresh();
|
||||
} else if (result.code == web_status.WARNING) {
|
||||
} else if (result.code == web_status.SUCCESS && table.option.type == undefined) {
|
||||
$.modal.msgSuccess(result.msg)
|
||||
} else if (result.code == web_status.WARNING) {
|
||||
$.modal.alertWarning(result.msg)
|
||||
} else {
|
||||
$.modal.alertError(result.msg);
|
||||
@ -1469,7 +1506,11 @@ var table = {
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
},
|
||||
// 判断移动端
|
||||
isMobile: function () {
|
||||
return navigator.userAgent.match(/(Android|iPhone|SymbianOS|Windows Phone|iPad|iPod)/i);
|
||||
},
|
||||
}
|
||||
});
|
||||
})(jQuery);
|
||||
|
@ -26,7 +26,7 @@ function login() {
|
||||
data: {
|
||||
"username": username,
|
||||
"password": password,
|
||||
"validateCode" : validateCode,
|
||||
"validateCode": validateCode,
|
||||
"rememberMe": rememberMe
|
||||
},
|
||||
success: function(r) {
|
||||
|
82
ruoyi-admin/src/main/resources/static/ruoyi/register.js
Normal file
82
ruoyi-admin/src/main/resources/static/ruoyi/register.js
Normal file
@ -0,0 +1,82 @@
|
||||
|
||||
$(function() {
|
||||
validateRule();
|
||||
$('.imgcode').click(function() {
|
||||
var url = ctx + "captcha/captchaImage?type=" + captchaType + "&s=" + Math.random();
|
||||
$(".imgcode").attr("src", url);
|
||||
});
|
||||
});
|
||||
|
||||
$.validator.setDefaults({
|
||||
submitHandler: function() {
|
||||
register();
|
||||
}
|
||||
});
|
||||
|
||||
function register() {
|
||||
$.modal.loading($("#btnSubmit").data("loading"));
|
||||
var username = $.common.trim($("input[name='username']").val());
|
||||
var password = $.common.trim($("input[name='password']").val());
|
||||
var validateCode = $("input[name='validateCode']").val();
|
||||
$.ajax({
|
||||
type: "post",
|
||||
url: ctx + "register",
|
||||
data: {
|
||||
"loginName": username,
|
||||
"password": password,
|
||||
"validateCode": validateCode
|
||||
},
|
||||
success: function(r) {
|
||||
if (r.code == 0) {
|
||||
layer.alert("<font color='red'>恭喜你,您的账号 " + username + " 注册成功!</font>", {
|
||||
icon: 1,
|
||||
title: "系统提示"
|
||||
},
|
||||
function(index) {
|
||||
//关闭弹窗
|
||||
layer.close(index);
|
||||
location.href = ctx + 'login';
|
||||
});
|
||||
} else {
|
||||
$.modal.closeLoading();
|
||||
$('.imgcode').click();
|
||||
$(".code").val("");
|
||||
$.modal.msg(r.msg);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function validateRule() {
|
||||
var icon = "<i class='fa fa-times-circle'></i> ";
|
||||
$("#registerForm").validate({
|
||||
rules: {
|
||||
username: {
|
||||
required: true,
|
||||
minlength: 2
|
||||
},
|
||||
password: {
|
||||
required: true,
|
||||
minlength: 5
|
||||
},
|
||||
confirmPassword: {
|
||||
required: true,
|
||||
equalTo: "[name='password']"
|
||||
}
|
||||
},
|
||||
messages: {
|
||||
username: {
|
||||
required: icon + "请输入您的用户名",
|
||||
minlength: icon + "用户名不能小于2个字符"
|
||||
},
|
||||
password: {
|
||||
required: icon + "请输入您的密码",
|
||||
minlength: icon + "密码不能小于5个字符",
|
||||
},
|
||||
confirmPassword: {
|
||||
required: icon + "请再次输入您的密码",
|
||||
equalTo: icon + "两次密码输入不一致"
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
@ -17,7 +17,7 @@
|
||||
<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.1.0
|
||||
<b>当前版本:</b>v4.2.0
|
||||
</p>
|
||||
<p>
|
||||
<span class="label label-warning">免费开源</span>
|
||||
@ -56,7 +56,7 @@
|
||||
<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.1.0
|
||||
<b>当前版本:</b>v4.2.0
|
||||
</p>
|
||||
<p>
|
||||
<span class="label label-warning">开源免费</span>
|
||||
|
@ -9,7 +9,7 @@
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label"><span style="color: red; ">*</span>用户名称:</label>
|
||||
<label class="col-sm-4 control-label is-required">用户名称:</label>
|
||||
<div class="col-sm-8">
|
||||
<input name="userName" placeholder="请输入用户名称" class="form-control" type="text">
|
||||
</div>
|
||||
@ -17,7 +17,7 @@
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label"><span style="color: red; ">*</span>归属部门:</label>
|
||||
<label class="col-sm-4 control-label is-required">归属部门:</label>
|
||||
<div class="col-sm-8">
|
||||
<div class="input-group">
|
||||
<input name="deptName" type="text" placeholder="请选择归属部门" class="form-control">
|
||||
@ -30,7 +30,7 @@
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label"><span style="color: red; ">*</span>手机号码:</label>
|
||||
<label class="col-sm-4 control-label is-required">手机号码:</label>
|
||||
<div class="col-sm-8">
|
||||
<input name="phonenumber" placeholder="请输入手机号码" class="form-control" type="text">
|
||||
</div>
|
||||
@ -38,7 +38,7 @@
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label"><span style="color: red; ">*</span>邮箱:</label>
|
||||
<label class="col-sm-4 control-label is-required">邮箱:</label>
|
||||
<div class="col-sm-8">
|
||||
<input name="email" class="form-control" type="text" placeholder="请输入邮箱">
|
||||
</div>
|
||||
@ -48,7 +48,7 @@
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label"><span style="color: red; ">*</span>登录账号:</label>
|
||||
<label class="col-sm-4 control-label is-required">登录账号:</label>
|
||||
<div class="col-sm-8">
|
||||
<input name="loginName" placeholder="请输入登录账号" class="form-control" type="text">
|
||||
</div>
|
||||
@ -56,7 +56,7 @@
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label"><span style="color: red; ">*</span>登录密码:</label>
|
||||
<label class="col-sm-4 control-label is-required">登录密码:</label>
|
||||
<div class="col-sm-8">
|
||||
<input name="password" placeholder="请输入登录密码" class="form-control" type="password">
|
||||
</div>
|
||||
|
@ -13,7 +13,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label ">用户姓名:</label>
|
||||
<label class="col-sm-3 control-label">用户姓名:</label>
|
||||
<div class="col-sm-8">
|
||||
<input class="form-control" type="text" name="userName" id="userName" required>
|
||||
</div>
|
||||
|
@ -11,7 +11,7 @@
|
||||
<div class="form-control-static" th:text="${user.userCode}"></div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label ">用户姓名:</label>
|
||||
<label class="col-sm-3 control-label">用户姓名:</label>
|
||||
<div class="col-sm-8">
|
||||
<div class="form-control-static" th:text="${user.userName}"></div>
|
||||
</div>
|
||||
|
@ -14,7 +14,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label ">用户姓名:</label>
|
||||
<label class="col-sm-3 control-label">用户姓名:</label>
|
||||
<div class="col-sm-8">
|
||||
<input class="form-control" type="text" name="userName" id="userName" th:field="*{userName}" required>
|
||||
</div>
|
||||
|
@ -77,12 +77,12 @@
|
||||
});
|
||||
|
||||
initChildTable = function(index, row, $detail) {
|
||||
var cur_table = $detail.html('<table style="table-layout:fixed"></table>').find('table');
|
||||
$(cur_table).bootstrapTable({
|
||||
var childTable = $detail.html('<table style="table-layout:fixed"></table>').find('table');
|
||||
$(childTable).bootstrapTable({
|
||||
url: prefix + "/list",
|
||||
method: 'post',
|
||||
sidePagination: "server",
|
||||
contentType: "application/x-www-form-urlencoded", // 编码类型
|
||||
contentType: "application/x-www-form-urlencoded",
|
||||
queryParams : {
|
||||
userName: '测试8'
|
||||
},
|
||||
|
@ -97,19 +97,19 @@
|
||||
<div class="select-list">
|
||||
<ul>
|
||||
<li>
|
||||
<p style="width: 80px">商户编号:</p>
|
||||
<label style="width: 80px">商户编号:</label>
|
||||
<input type="text" name="userId"/>
|
||||
</li>
|
||||
<li>
|
||||
<p style="width: 80px">订单号:</p>
|
||||
<label style="width: 80px">订单号:</label>
|
||||
<input type="text" name="orderNo"/>
|
||||
</li>
|
||||
<li>
|
||||
<p style="width: 80px">日期:</p>
|
||||
<label style="width: 80px">日期:</label>
|
||||
<input type="text" class="time-input" placeholder="日期"/>
|
||||
</li>
|
||||
<li class="select-selectpicker">
|
||||
<p style="width: 80px">状态:</p>
|
||||
<label style="width: 80px">状态:</label>
|
||||
<select class="selectpicker" data-none-selected-text="请选择" multiple>
|
||||
<option value="">所有</option>
|
||||
<option value="0">初始</option>
|
||||
@ -119,7 +119,7 @@
|
||||
</select>
|
||||
</li>
|
||||
<li>
|
||||
<p style="width: 80px">供货商通道:</p>
|
||||
<label style="width: 80px">供货商通道:</label>
|
||||
<select>
|
||||
<option value="">所有</option>
|
||||
<option value="0">腾讯</option>
|
||||
@ -128,7 +128,7 @@
|
||||
</select>
|
||||
</li>
|
||||
<li>
|
||||
<p style="width: 80px">来源:</p>
|
||||
<label style="width: 80px">来源:</label>
|
||||
<select>
|
||||
<option value="">所有</option>
|
||||
<option value="0">手机</option>
|
||||
@ -137,7 +137,7 @@
|
||||
</select>
|
||||
</li>
|
||||
<li>
|
||||
<p style="width: 80px">运营商:</p>
|
||||
<label style="width: 80px">运营商:</label>
|
||||
<select>
|
||||
<option value="">所有</option>
|
||||
<option value="0">移动</option>
|
||||
@ -146,7 +146,7 @@
|
||||
</select>
|
||||
</li>
|
||||
<li class="select-time">
|
||||
<p style="width: 80px">回调时间:</p>
|
||||
<label style="width: 80px">回调时间:</label>
|
||||
<input type="text" class="time-input" placeholder="开始时间"/>
|
||||
<span>-</span>
|
||||
<input type="text" class="time-input" placeholder="结束时间"/>
|
||||
|
@ -4,9 +4,9 @@
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>RuoYi - 404</title>
|
||||
<link href="/css/bootstrap.min.css" rel="stylesheet"/>
|
||||
<link href="/css/animate.css" rel="stylesheet"/>
|
||||
<link href="/css/style.css" rel="stylesheet"/>
|
||||
<link th:href="@{/css/bootstrap.min.css}" rel="stylesheet"/>
|
||||
<link th:href="@{/css/animate.css}" rel="stylesheet"/>
|
||||
<link th:href="@{/css/style.css}" rel="stylesheet"/>
|
||||
</head>
|
||||
<body class="gray-bg">
|
||||
<div class="middle-box text-center animated fadeInDown">
|
||||
@ -14,8 +14,14 @@
|
||||
<h3 class="font-bold">找不到网页!</h3>
|
||||
<div class="error-desc">
|
||||
对不起,您正在寻找的页面不存在。尝试检查URL的错误,然后按浏览器上的刷新按钮或尝试在我们的应用程序中找到其他内容。
|
||||
<a href="javascript:top.document.location.href='/'" class="btn btn-primary m-t">主页</a>
|
||||
<a href="javascript:index()" class="btn btn-primary m-t">主页</a>
|
||||
</div>
|
||||
</div>
|
||||
<script th:inline="javascript">
|
||||
var ctx = [[@{/}]];
|
||||
function index() {
|
||||
window.parent.frames.location.href = ctx + "index";
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -4,9 +4,9 @@
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>RuoYi - 500</title>
|
||||
<link href="/css/bootstrap.min.css" rel="stylesheet"/>
|
||||
<link href="/css/animate.css" rel="stylesheet"/>
|
||||
<link href="/css/style.css" rel="stylesheet"/>
|
||||
<link th:href="@{/css/bootstrap.min.css}" rel="stylesheet"/>
|
||||
<link th:href="@{/css/animate.css}" rel="stylesheet"/>
|
||||
<link th:href="@{/css/style.css}" rel="stylesheet"/>
|
||||
</head>
|
||||
<body class="gray-bg">
|
||||
<div class="middle-box text-center animated fadeInDown">
|
||||
@ -15,8 +15,14 @@
|
||||
|
||||
<div class="error-desc">
|
||||
服务器遇到意外事件,不允许完成请求。我们抱歉。您可以返回主页面。
|
||||
<a href="javascript:top.document.location.href='/'" class="btn btn-primary m-t">主页</a>
|
||||
<a href="javascript:index()" class="btn btn-primary m-t">主页</a>
|
||||
</div>
|
||||
</div>
|
||||
<script th:inline="javascript">
|
||||
var ctx = [[@{/}]];
|
||||
function index() {
|
||||
window.parent.frames.location.href = ctx + "index";
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -4,9 +4,9 @@
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>RuoYi - 403</title>
|
||||
<link href="/css/bootstrap.min.css" rel="stylesheet"/>
|
||||
<link href="/css/animate.css" rel="stylesheet"/>
|
||||
<link href="/css/style.css" rel="stylesheet"/>
|
||||
<link th:href="@{/css/bootstrap.min.css}" rel="stylesheet"/>
|
||||
<link th:href="@{/css/animate.css}" rel="stylesheet"/>
|
||||
<link th:href="@{/css/style.css}" rel="stylesheet"/>
|
||||
</head>
|
||||
<body class="gray-bg">
|
||||
<div class="middle-box text-center animated fadeInDown">
|
||||
|
@ -4,9 +4,9 @@
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>RuoYi - 403</title>
|
||||
<link href="/css/bootstrap.min.css" rel="stylesheet"/>
|
||||
<link href="/css/animate.css" rel="stylesheet"/>
|
||||
<link href="/css/style.css" rel="stylesheet"/>
|
||||
<link th:href="@{/css/bootstrap.min.css}" rel="stylesheet"/>
|
||||
<link th:href="@{/css/animate.css}" rel="stylesheet"/>
|
||||
<link th:href="@{/css/style.css}" rel="stylesheet"/>
|
||||
</head>
|
||||
<body class="gray-bg">
|
||||
<div class="middle-box text-center animated fadeInDown">
|
||||
@ -15,8 +15,14 @@
|
||||
|
||||
<div class="error-desc">
|
||||
对不起,您没有访问权限,请不要进行非法操作!您可以返回主页面
|
||||
<a href="javascript:top.document.location.href='/'" class="btn btn-outline btn-primary btn-xs">返回主页</a>
|
||||
<a href="javascript:index()" class="btn btn-outline btn-primary btn-xs">返回主页</a>
|
||||
</div>
|
||||
</div>
|
||||
<script th:inline="javascript">
|
||||
var ctx = [[@{/}]];
|
||||
function index() {
|
||||
window.parent.frames.location.href = ctx + "index";
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -2,6 +2,7 @@
|
||||
<head th:fragment=header(title)>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="keywords" content="">
|
||||
<meta name="description" content="">
|
||||
<title th:text="${title}"></title>
|
||||
@ -11,16 +12,17 @@
|
||||
<!-- bootstrap-table 表格插件样式 -->
|
||||
<link th:href="@{/ajax/libs/bootstrap-table/bootstrap-table.min.css}" rel="stylesheet"/>
|
||||
<link th:href="@{/css/animate.css}" rel="stylesheet"/>
|
||||
<link th:href="@{/css/style.css}" rel="stylesheet"/>
|
||||
<link th:href="@{/css/style.css?v=20200318}" rel="stylesheet"/>
|
||||
<link th:href="@{/ruoyi/css/ry-ui.css}" rel="stylesheet"/>
|
||||
</head>
|
||||
|
||||
<!-- 通用JS -->
|
||||
<div th:fragment="footer">
|
||||
<a id="scroll-up" href="#" class="btn btn-sm display"><i class="fa fa-angle-double-up"></i></a>
|
||||
<script th:src="@{/js/jquery.min.js}"></script>
|
||||
<script th:src="@{/js/bootstrap.min.js}"></script>
|
||||
<!-- bootstrap-table 表格插件 -->
|
||||
<script th:src="@{/ajax/libs/bootstrap-table/bootstrap-table.min.js}"></script>
|
||||
<script th:src="@{/ajax/libs/bootstrap-table/bootstrap-table.min.js?v=20191219}"></script>
|
||||
<script th:src="@{/ajax/libs/bootstrap-table/locale/bootstrap-table-zh-CN.min.js}"></script>
|
||||
<script th:src="@{/ajax/libs/bootstrap-table/extensions/mobile/bootstrap-table-mobile.js}"></script>
|
||||
<script th:src="@{/ajax/libs/bootstrap-table/extensions/toolbar/bootstrap-table-toolbar.min.js}"></script>
|
||||
@ -39,8 +41,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=4.1.0}"></script>
|
||||
<script th:src="@{/ruoyi/js/ry-ui.js?v=4.1.0}"></script>
|
||||
<script th:src="@{/ruoyi/js/common.js?v=4.2.0}"></script>
|
||||
<script th:src="@{/ruoyi/js/ry-ui.js?v=4.2.0}"></script>
|
||||
<script th:inline="javascript"> var ctx = [[@{/}]]; </script>
|
||||
</div>
|
||||
|
||||
@ -74,7 +76,7 @@
|
||||
<link th:href="@{/ajax/libs/datapicker/bootstrap-datetimepicker.min.css}" rel="stylesheet"/>
|
||||
</div>
|
||||
<div th:fragment="datetimepicker-js">
|
||||
<script th:src="@{/ajax/libs//datapicker/bootstrap-datetimepicker.min.js}"></script>
|
||||
<script th:src="@{/ajax/libs/datapicker/bootstrap-datetimepicker.min.js}"></script>
|
||||
</div>
|
||||
|
||||
<!-- ui布局插件 -->
|
||||
|
@ -5,9 +5,8 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="renderer" content="webkit">
|
||||
<title>若依系统首页</title>
|
||||
<!--[if lt IE 9]>
|
||||
<meta http-equiv="refresh" content="0;ie.html"/>
|
||||
<![endif]-->
|
||||
<!-- 避免IE使用兼容模式 -->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<link th:href="@{favicon.ico}" rel="stylesheet"/>
|
||||
<link th:href="@{/css/bootstrap.min.css}" rel="stylesheet"/>
|
||||
<link th:href="@{/css/jquery.contextMenu.min.css}" rel="stylesheet"/>
|
||||
@ -15,7 +14,7 @@
|
||||
<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=4.1.0}" rel="stylesheet"/>
|
||||
<link th:href="@{/ruoyi/css/ry-ui.css?v=4.2.0}" rel="stylesheet"/>
|
||||
</head>
|
||||
<body class="fixed-sidebar full-height-layout gray-bg" style="overflow: hidden">
|
||||
<div id="wrapper">
|
||||
@ -25,13 +24,13 @@
|
||||
<div class="nav-close">
|
||||
<i class="fa fa-times-circle"></i>
|
||||
</div>
|
||||
<a th:href="@{/index}">
|
||||
<li class="logo hidden-xs">
|
||||
<span class="logo-lg">RuoYi</span>
|
||||
</li>
|
||||
</a>
|
||||
<div class="sidebar-collapse">
|
||||
<ul class="nav" id="side-menu">
|
||||
<a th:href="@{/index}">
|
||||
<li class="logo">
|
||||
<span class="logo-lg" >RuoYi</span>
|
||||
</li>
|
||||
</a>
|
||||
<li>
|
||||
<div class="user-panel">
|
||||
<a class="menuItem" title="个人中心" th:href="@{/system/user/profile}">
|
||||
@ -64,7 +63,13 @@
|
||||
<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>
|
||||
<ul th:if="${not #lists.isEmpty(cmenu.children)}" class="nav nav-third-level">
|
||||
<li th:each="emenu : ${cmenu.children}"><a th:class="${emenu.target == ''} ? |menuItem| : ${emenu.target}" th:text="${emenu.menuName}" th:href="@{${emenu.url}}">三级菜单</a></li>
|
||||
<li th:each="emenu : ${cmenu.children}">
|
||||
<a th:if="${#lists.isEmpty(emenu.children)}" th:class="${emenu.target == ''} ? |menuItem| : ${emenu.target}" th:text="${emenu.menuName}" th:href="@{${emenu.url}}">三级菜单</a>
|
||||
<a th:if="${not #lists.isEmpty(emenu.children)}" href="#">[[${emenu.menuName}]]<span class="fa arrow"></span></a>
|
||||
<ul th:if="${not #lists.isEmpty(emenu.children)}" class="nav nav-four-level">
|
||||
<li th:each="fmenu : ${emenu.children}"><a th:if="${#lists.isEmpty(fmenu.children)}" th:class="${fmenu.target == ''} ? |menuItem| : ${fmenu.target}" th:text="${fmenu.menuName}" th:href="@{${fmenu.url}}">四级菜单</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
@ -175,13 +180,13 @@
|
||||
</a>
|
||||
</div>
|
||||
<ul class="nav navbar-top-links navbar-right welcome-message">
|
||||
<li><a title="视频教程" href="http://doc.ruoyi.vip/ruoyi/document/spjc.html" target="_blank"><i class="fa fa-video-camera"></i> 视频教程</a></li>
|
||||
<li><a title="视频教程" href="http://doc.ruoyi.vip/ruoyi/document/spjc.html" target="_blank"><i class="fa fa-video-camera"></i> 视频教程</a></li>
|
||||
<li><a title="开发文档" href="http://doc.ruoyi.vip" target="_blank"><i class="fa fa-question-circle"></i> 开发文档</a></li>
|
||||
<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} : @{${user.avatar}}" class="user-image">
|
||||
<span class="hidden-xs">[[${user.userName}]]</span>
|
||||
<span class="hidden-xs">[[${#strings.defaultString(user.userName, '-')}]]</span>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li class="mt5">
|
||||
@ -241,22 +246,28 @@
|
||||
<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=4.1.0}"></script>
|
||||
<script th:src="@{/ruoyi/js/common.js?v=4.1.0}"></script>
|
||||
<script th:src="@{/ruoyi/js/ry-ui.js?v=4.2.0}"></script>
|
||||
<script th:src="@{/ruoyi/js/common.js?v=4.2.0}"></script>
|
||||
<script th:src="@{/ruoyi/index.js}"></script>
|
||||
<script th:src="@{/ajax/libs/fullscreen/jquery.fullscreen.js}"></script>
|
||||
<script th:inline="javascript">
|
||||
var ctx = [[@{/}]];
|
||||
// 皮肤缓存
|
||||
var skin = storage.get("skin");
|
||||
// history(表示去掉地址的#)否则地址以"#"形式展示
|
||||
var mode = "history";
|
||||
// 历史访问路径缓存
|
||||
var historyPath = storage.get("historyPath");
|
||||
// 排除非左侧菜单链接
|
||||
var excludesUrl = ["/system/user/profile"];
|
||||
|
||||
// 本地主题优先,未设置取系统配置
|
||||
if($.common.isNotEmpty(skin)){
|
||||
$("body").addClass(skin.split('|')[0]);
|
||||
$("body").addClass(skin.split('|')[1]);
|
||||
} else {
|
||||
var sideTheme = [[${@config.getKey('sys.index.sideTheme')}]];
|
||||
var skinName = [[${@config.getKey('sys.index.skinName')}]];
|
||||
$("body").addClass(sideTheme);
|
||||
$("body").addClass(skinName);
|
||||
$("body").addClass([[${sideTheme}]]);
|
||||
$("body").addClass([[${skinName}]]);
|
||||
}
|
||||
|
||||
/* 用户管理-重置密码 */
|
||||
@ -275,18 +286,27 @@ function switchSkin() {
|
||||
})
|
||||
}
|
||||
|
||||
// 排除非左侧菜单链接
|
||||
var excludesUrl = ["/system/user/profile"];
|
||||
/** 刷新时访问路径页签 */
|
||||
function applyPath(url) {
|
||||
$('a[href$="' + decodeURI(url) + '"]').click();
|
||||
if($.inArray(url, excludesUrl)){
|
||||
$('a[href$="' + url + '"]').parent("li").addClass("selected").parents("li").addClass("active").end().parents("ul").addClass("in");
|
||||
}
|
||||
}
|
||||
|
||||
$(function() {
|
||||
var hash = location.hash;
|
||||
if (hash !== '') {
|
||||
var url = hash.substring(1, hash.length);
|
||||
$('a[href$="' + url + '"]').click();
|
||||
if($.inArray(url, excludesUrl)){
|
||||
$('a[href$="' + url + '"]').parent("li").addClass("selected").parents("li").addClass("active").end().parents("ul").addClass("in");
|
||||
}
|
||||
}
|
||||
if($.common.equals("history", mode) && window.performance.navigation.type == 1) {
|
||||
var url = storage.get('publicPath');
|
||||
if ($.common.isNotEmpty(url)) {
|
||||
applyPath(url);
|
||||
}
|
||||
} else {
|
||||
var hash = location.hash;
|
||||
if ($.common.isNotEmpty(hash)) {
|
||||
var url = hash.substring(1, hash.length);
|
||||
applyPath(url);
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
@ -3,26 +3,24 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
|
||||
|
||||
<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=4.1.0}" rel="stylesheet"/>
|
||||
<!--[if lt IE 9]>
|
||||
<meta http-equiv="refresh" content="0;ie.html" />
|
||||
<![endif]-->
|
||||
<link href="../static/ruoyi/css/ry-ui.css" th:href="@{/ruoyi/css/ry-ui.css?v=4.2.0}" rel="stylesheet"/>
|
||||
<!-- 360浏览器急速模式 -->
|
||||
<meta name="renderer" content="webkit">
|
||||
<!-- 避免IE使用兼容模式 -->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<link rel="shortcut icon" href="../static/favicon.ico" th:href="@{favicon.ico}"/>
|
||||
<style type="text/css">label.error { position:inherit; }</style>
|
||||
<script>
|
||||
if(window.top!==window.self){window.top.location=window.location};
|
||||
if(window.top!==window.self){alert('未登录或登录超时。请重新登录');window.top.location=window.location};
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body class="signin">
|
||||
|
||||
<div class="signinpanel">
|
||||
<div class="row">
|
||||
<div class="col-sm-7">
|
||||
@ -39,18 +37,18 @@
|
||||
<li><i class="fa fa-arrow-circle-o-right m-r-xs"></i> Thymeleaf</li>
|
||||
<li><i class="fa fa-arrow-circle-o-right m-r-xs"></i> Bootstrap</li>
|
||||
</ul>
|
||||
<strong>还没有账号? <a href="#">立即注册»</a></strong>
|
||||
<strong th:if="${@config.getKey('sys.account.registerUser')}">还没有账号? <a th:href="@{/register}">立即注册»</a></strong>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-5">
|
||||
<form id="signupForm">
|
||||
<form id="signupForm" autocomplete="off">
|
||||
<h4 class="no-margins">登录:</h4>
|
||||
<p class="m-t-md">你若不离不弃,我必生死相依</p>
|
||||
<input type="text" name="username" class="form-control uname" placeholder="用户名" value="admin" />
|
||||
<input type="password" name="password" class="form-control pword" placeholder="密码" value="admin123" />
|
||||
<div class="row m-t" th:if="${captchaEnabled==true}">
|
||||
<div class="col-xs-6">
|
||||
<input type="text" name="validateCode" class="form-control code" placeholder="验证码" maxlength="5" autocomplete="off">
|
||||
<input type="text" name="validateCode" class="form-control code" placeholder="验证码" maxlength="5" />
|
||||
</div>
|
||||
<div class="col-xs-6">
|
||||
<a href="javascript:void(0);" title="点击更换验证码">
|
||||
@ -80,7 +78,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=4.1.0}"></script>
|
||||
<script src="../static/ruoyi/js/ry-ui.js" th:src="@{/ruoyi/js/ry-ui.js?v=4.2.0}"></script>
|
||||
<script src="../static/ruoyi/login.js" th:src="@{/ruoyi/login.js}"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -17,11 +17,9 @@
|
||||
<div class="col-sm-12">
|
||||
<blockquote class="text-warning" style="font-size:14px">
|
||||
领取阿里云通用云产品1888优惠券
|
||||
<br><a target="_blank" href="https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=brki8iof">https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=brki8iof</a><br>
|
||||
<br><a target="_blank" href="https://www.aliyun.com/minisite/goods?userCode=brki8iof">https://www.aliyun.com/minisite/goods?userCode=brki8iof</a><br>
|
||||
领取腾讯云通用云产品2860优惠券
|
||||
<br><a target="_blank" href="https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console">https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console</a><br>
|
||||
阿里云Hi拼购 限量爆款 低至199元/年
|
||||
<br><a target="_blank" href="https://www.aliyun.com/acts/hi-group-buying?userCode=brki8iof">https://www.aliyun.com/acts/hi-group-buying?userCode=brki8iof</a>
|
||||
<h4 class="text-danger">云产品通用红包,可叠加官网常规优惠使用。(仅限新用户)</h4>
|
||||
</blockquote>
|
||||
|
||||
@ -81,7 +79,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> <s>满1366522</s> <s>满1382251</s> <s>满1145125</s> <a href="https://jq.qq.com/?_wv=1027&k=5IdFWW8" target="_blank">86752435</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> <s>满1145125</s> <s>满86752435</s> <s>满134072510</s> <s>满210336300</s> <a href="https://jq.qq.com/?_wv=1027&k=5omzbKc" target="_blank">339522636</a>
|
||||
</p>
|
||||
<p><i class="fa fa-weixin"></i> 微信:<a href="javascript:;">/ *若依</a>
|
||||
</p>
|
||||
@ -98,13 +96,78 @@
|
||||
<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="#v42">v4.2.0</a><code class="pull-right">2020.03.23</code>
|
||||
</h5>
|
||||
</div>
|
||||
<div id="v42" class="panel-collapse collapse in">
|
||||
<div class="panel-body">
|
||||
<ol>
|
||||
<li>用户管理添加分配角色页面</li>
|
||||
<li>定时任务添加调度日志按钮</li>
|
||||
<li>新增是否开启用户注册功能</li>
|
||||
<li>新增页面滚动显示返回顶部按钮</li>
|
||||
<li>用户&角色&任务添加更多操作按钮</li>
|
||||
<li>iframe框架页会话过期弹出超时提示</li>
|
||||
<li>移动端登录不显示左侧菜单</li>
|
||||
<li>侧边栏添加一套深蓝色主题</li>
|
||||
<li>首页logo固定,不随菜单滚动</li>
|
||||
<li>支持mode配置history(表示去掉地址栏的#)</li>
|
||||
<li>任务分组字典翻译(调度日志详细)</li>
|
||||
<li>字典管理添加缓存读取</li>
|
||||
<li>字典数据列表标签显示样式</li>
|
||||
<li>参数管理支持缓存操作</li>
|
||||
<li>日期控件清空结束时间设置开始默认值为2099-12-31</li>
|
||||
<li>表格树添加获取数据后响应回调处理</li>
|
||||
<li>批量替换表前缀调整</li>
|
||||
<li>支持表格导入模板的弹窗表单加入其它输入控件</li>
|
||||
<li>表单重置刷新表格树</li>
|
||||
<li>新增支持导出数据字段排序</li>
|
||||
<li>新增表格参数(是否单选checkbox)</li>
|
||||
<li>druid未授权不允许访问</li>
|
||||
<li>表格树父节点兼容0,'0','',null</li>
|
||||
<li>表单必填的项添加星号</li>
|
||||
<li>修复select2不显示校验错误信息</li>
|
||||
<li>添加自定义HTML过滤器</li>
|
||||
<li>修复多数据源下开关关闭出现异常问题</li>
|
||||
<li>修复翻页记住选择项数据问题</li>
|
||||
<li>用户邮箱长度限制20</li>
|
||||
<li>修改错误页面返回主页出现嵌套问题</li>
|
||||
<li>表格浮动提示单双引号转义</li>
|
||||
<li>支持配置四级菜单</li>
|
||||
<li>升级shiro到最新版1.4.2 阻止rememberMe漏洞攻击</li>
|
||||
<li>升级summernote到最新版本v0.8.12</li>
|
||||
<li>导入Excel根据dateFormat属性格式处理</li>
|
||||
<li>修复War部署无法正常shutdown,ehcache内存泄漏</li>
|
||||
<li>修复代码生成短字段无法识别问题</li>
|
||||
<li>修复serviceImpl模版,修改方法判断日期错误</li>
|
||||
<li>代码生成模板增加导出功能日志记录</li>
|
||||
<li>代码生成唯一编号调整为tableId</li>
|
||||
<li>代码生成查询时忽略大小写</li>
|
||||
<li>代码生成支持翻页记住选中</li>
|
||||
<li>代码生成表注释未填写也允许导入</li>
|
||||
<li>Global全局配置类修改为注解,防止多环境配置下读取问题</li>
|
||||
<li>修复多表格情况下,firstLoad只对第一个表格生效</li>
|
||||
<li>处理Maven打包出现警告问题</li>
|
||||
<li>默认主题样式,防止网速慢情况下出现空白</li>
|
||||
<li>修复文件上传多级目录识别问题</li>
|
||||
<li>锚链接解码url,防止中文导致页面不能加载问题</li>
|
||||
<li>修复右键Tab页刷新事件重复请求问题</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="#v41">v4.1.0</a><code class="pull-right">2019.10.22</code>
|
||||
</h5>
|
||||
</div>
|
||||
<div id="v41" class="panel-collapse collapse in">
|
||||
<div id="v41" class="panel-collapse collapse">
|
||||
<div class="panel-body">
|
||||
<ol>
|
||||
<li>支持多表格实例操作</li>
|
||||
@ -144,7 +207,7 @@
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h5 class="panel-title">
|
||||
@ -205,8 +268,8 @@
|
||||
<li>其他细节优化</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h5 class="panel-title">
|
||||
|
@ -155,8 +155,9 @@
|
||||
}
|
||||
|
||||
function resetPre() {
|
||||
$.form.reset();
|
||||
$("#operlog-form")[0].reset();
|
||||
$("#businessTypes").selectpicker('refresh');
|
||||
$.table.search('operlog-form', 'bootstrap-table');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
83
ruoyi-admin/src/main/resources/templates/register.html
Normal file
83
ruoyi-admin/src/main/resources/templates/register.html
Normal file
@ -0,0 +1,83 @@
|
||||
<!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, maximum-scale=1.0">
|
||||
<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=4.2.0}" rel="stylesheet"/>
|
||||
<!-- 360浏览器急速模式 -->
|
||||
<meta name="renderer" content="webkit">
|
||||
<!-- 避免IE使用兼容模式 -->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<link rel="shortcut icon" href="../static/favicon.ico" th:href="@{favicon.ico}"/>
|
||||
<style type="text/css">label.error { position:inherit; }</style>
|
||||
</head>
|
||||
<body class="signin">
|
||||
<div class="signinpanel">
|
||||
<div class="row">
|
||||
<div class="col-sm-7">
|
||||
<div class="signin-info">
|
||||
<div class="logopanel m-b">
|
||||
<h1><img alt="[ 若依 ]" src="../static/ruoyi.png" th:src="@{/ruoyi.png}"></h1>
|
||||
</div>
|
||||
<div class="m-b"></div>
|
||||
<h4>欢迎使用 <strong>若依 后台管理系统</strong></h4>
|
||||
<ul class="m-b">
|
||||
<li><i class="fa fa-arrow-circle-o-right m-r-xs"></i> SpringBoot</li>
|
||||
<li><i class="fa fa-arrow-circle-o-right m-r-xs"></i> Mybatis</li>
|
||||
<li><i class="fa fa-arrow-circle-o-right m-r-xs"></i> Shiro</li>
|
||||
<li><i class="fa fa-arrow-circle-o-right m-r-xs"></i> Thymeleaf</li>
|
||||
<li><i class="fa fa-arrow-circle-o-right m-r-xs"></i> Bootstrap</li>
|
||||
</ul>
|
||||
<strong>已经注册过? <a th:href="@{/login}">直接登录»</a></strong>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-5">
|
||||
<form id="registerForm" autocomplete="off">
|
||||
<h4 class="no-margins">注册:</h4>
|
||||
<p class="m-t-md">你若不离不弃,我必生死相依</p>
|
||||
<input type="text" name="username" class="form-control uname" placeholder="用户名" maxlength="20" />
|
||||
<input type="password" name="password" class="form-control pword" placeholder="密码" maxlength="20" />
|
||||
<input type="password" name="confirmPassword" class="form-control pword" placeholder="确认密码" maxlength="20" />
|
||||
<div class="row m-t" th:if="${captchaEnabled==true}">
|
||||
<div class="col-xs-6">
|
||||
<input type="text" name="validateCode" class="form-control code" placeholder="验证码" maxlength="5" >
|
||||
</div>
|
||||
<div class="col-xs-6">
|
||||
<a href="javascript:void(0);" title="点击更换验证码">
|
||||
<img th:src="@{captcha/captchaImage(type=${captchaType})}" class="imgcode" width="85%"/>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="checkbox-custom" th:classappend="${captchaEnabled==false} ? 'm-t'">
|
||||
<input type="checkbox" id="acceptTerm" name="acceptTerm"> <label for="acceptTerm">我已阅读并同意</label>
|
||||
<a href="https://gitee.com/y_project/RuoYi/blob/master/README.md" target="_blank">使用条款</a>
|
||||
</div>
|
||||
<button class="btn btn-success btn-block" id="btnSubmit" data-loading="正在验证注册,请稍后...">注册</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="signup-footer">
|
||||
<div class="pull-left">
|
||||
© 2019 All Rights Reserved. RuoYi <br>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script th:inline="javascript"> var ctx = [[@{/}]]; var captchaType = [[${captchaType}]]; </script>
|
||||
<!-- 全局js -->
|
||||
<script src="../static/js/jquery.min.js" th:src="@{/js/jquery.min.js}"></script>
|
||||
<script src="../static/js/bootstrap.min.js" th:src="@{/js/bootstrap.min.js}"></script>
|
||||
<!-- 验证插件 -->
|
||||
<script src="../static/ajax/libs/validate/jquery.validate.min.js" th:src="@{/ajax/libs/validate/jquery.validate.min.js}"></script>
|
||||
<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=4.2.0}"></script>
|
||||
<script src="../static/ruoyi/register.js" th:src="@{/ruoyi/register.js}"></script>
|
||||
</body>
|
||||
</html>
|
@ -118,16 +118,35 @@
|
||||
</a>
|
||||
<p class="text-center">黄灰</p>
|
||||
</li>
|
||||
|
||||
<li style="float:left; width: 33.33333%; padding: 5px;">
|
||||
<a href="javascript:" data-skin="skin-blue|theme-blue" style="display: block; box-shadow: 0 0 3px rgba(0,0,0,0.4)" class="clearfix full-opacity-hover">
|
||||
<span style="width: 20%; float: left; height: 13px; background: #367fa9"></span>
|
||||
<span style="width: 80%; float: left; height: 13px; background: #3c8dbc"></span>
|
||||
<span style="width: 20%; float: left; height: 30px; background: rgba(15,41,80,1)"></span>
|
||||
<span style="width: 80%; float: left; height: 30px; background: #f4f5f7"></span>
|
||||
</a>
|
||||
<p class="text-center">蓝浅(新)</p>
|
||||
</li>
|
||||
<li style="float:left; width: 33.33333%; padding: 5px;">
|
||||
<a href="javascript:" data-skin="skin-green|theme-blue" style="display: block; box-shadow: 0 0 3px rgba(0,0,0,0.4)" class="clearfix full-opacity-hover">
|
||||
<span style="width: 20%; float: left; height: 13px; background: #008d4c"></span>
|
||||
<span style="width: 80%; float: left; height: 13px; background: #00a65a"></span>
|
||||
<span style="width: 20%; float: left; height: 30px; background: rgba(15,41,80,1)"></span>
|
||||
<span style="width: 80%; float: left; height: 30px; background: #f4f5f7"></span>
|
||||
</a>
|
||||
<p class="text-center">绿浅(新)</p>
|
||||
</li>
|
||||
</ul>
|
||||
</body>
|
||||
<script th:src="@{/js/jquery.min.js}"></script>
|
||||
<script th:src="@{/ruoyi/js/common.js?v=4.1.0}"></script>
|
||||
<script th:src="@{/ruoyi/js/common.js?v=4.2.0}"></script>
|
||||
<script type="text/javascript">
|
||||
//皮肤样式列表
|
||||
var skins = ["skin-blue", "skin-green", "skin-purple", "skin-red", "skin-yellow"];
|
||||
|
||||
// 主题样式列表
|
||||
var themes = ["theme-dark", "theme-light"];
|
||||
var themes = ["theme-dark", "theme-light", "theme-blue"];
|
||||
|
||||
$("[data-skin]").on('click',
|
||||
function(e) {
|
||||
|
@ -7,19 +7,19 @@
|
||||
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
|
||||
<form class="form-horizontal m" id="form-config-add" name="form-config-add">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">参数名称:</label>
|
||||
<label class="col-sm-3 control-label is-required">参数名称:</label>
|
||||
<div class="col-sm-8">
|
||||
<input id="configName" name="configName" class="form-control" type="text" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">参数键名:</label>
|
||||
<label class="col-sm-3 control-label is-required">参数键名:</label>
|
||||
<div class="col-sm-8">
|
||||
<input id="configKey" name="configKey" class="form-control" type="text" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">参数键值:</label>
|
||||
<label class="col-sm-3 control-label is-required">参数键值:</label>
|
||||
<div class="col-sm-8">
|
||||
<input id="configValue" name="configValue" class="form-control" type="text" required>
|
||||
</div>
|
||||
|
@ -50,6 +50,9 @@
|
||||
<a class="btn btn-warning" onclick="$.table.exportExcel()" shiro:hasPermission="system:config:export">
|
||||
<i class="fa fa-download"></i> 导出
|
||||
</a>
|
||||
<a class="btn btn-danger" onclick="clearCache()" shiro:hasPermission="system:config:remove">
|
||||
<i class="fa fa-refresh"></i> 清理缓存
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-sm-12 select-table table-striped">
|
||||
<table id="bootstrap-table"></table>
|
||||
@ -131,6 +134,11 @@
|
||||
};
|
||||
$.table.init(options);
|
||||
});
|
||||
|
||||
/** 清理参数缓存 */
|
||||
function clearCache() {
|
||||
$.operate.get(prefix + "/clearCache");
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -8,19 +8,19 @@
|
||||
<form class="form-horizontal m" id="form-config-edit" th:object="${config}">
|
||||
<input id="configId" name="configId" th:field="*{configId}" type="hidden">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">参数名称:</label>
|
||||
<label class="col-sm-3 control-label is-required">参数名称:</label>
|
||||
<div class="col-sm-8">
|
||||
<input id="configName" name="configName" th:field="*{configName}" class="form-control" type="text" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">参数键名:</label>
|
||||
<label class="col-sm-3 control-label is-required">参数键名:</label>
|
||||
<div class="col-sm-8">
|
||||
<input id="configKey" name="configKey" th:field="*{configKey}" class="form-control" type="text" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">参数键值:</label>
|
||||
<label class="col-sm-3 control-label is-required">参数键值:</label>
|
||||
<div class="col-sm-8">
|
||||
<input id="configValue" name="configValue" th:field="*{configValue}" class="form-control" type="text" required>
|
||||
</div>
|
||||
|
@ -8,7 +8,7 @@
|
||||
<form class="form-horizontal m" id="form-dept-add">
|
||||
<input id="treeId" name="parentId" type="hidden" th:value="${dept.deptId}" />
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label ">上级部门:</label>
|
||||
<label class="col-sm-3 control-label">上级部门:</label>
|
||||
<div class="col-sm-8">
|
||||
<div class="input-group">
|
||||
<input class="form-control" type="text" onclick="selectDeptTree()" id="treeName" readonly="true" th:value="${dept.deptName}">
|
||||
@ -17,13 +17,13 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">部门名称:</label>
|
||||
<label class="col-sm-3 control-label is-required">部门名称:</label>
|
||||
<div class="col-sm-8">
|
||||
<input class="form-control" type="text" name="deptName" id="deptName" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">显示排序:</label>
|
||||
<label class="col-sm-3 control-label is-required">显示排序:</label>
|
||||
<div class="col-sm-8">
|
||||
<input class="form-control" type="text" name="orderNum" required>
|
||||
</div>
|
||||
|
@ -9,7 +9,7 @@
|
||||
<input name="deptId" type="hidden" th:field="*{deptId}" />
|
||||
<input id="treeId" name="parentId" type="hidden" th:field="*{parentId}" />
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label ">上级部门:</label>
|
||||
<label class="col-sm-3 control-label">上级部门:</label>
|
||||
<div class="col-sm-8">
|
||||
<div class="input-group">
|
||||
<input class="form-control" type="text" id="treeName" onclick="selectDeptTree()" readonly="true" th:field="*{parentName}">
|
||||
@ -18,13 +18,13 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">部门名称:</label>
|
||||
<label class="col-sm-3 control-label is-required">部门名称:</label>
|
||||
<div class="col-sm-8">
|
||||
<input class="form-control" type="text" name="deptName" th:field="*{deptName}" id="deptName" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">显示排序:</label>
|
||||
<label class="col-sm-3 control-label is-required">显示排序:</label>
|
||||
<div class="col-sm-8">
|
||||
<input class="form-control" type="text" name="orderNum" th:field="*{orderNum}" required>
|
||||
</div>
|
||||
|
@ -7,13 +7,13 @@
|
||||
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
|
||||
<form class="form-horizontal m" id="form-dict-add">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label ">字典标签:</label>
|
||||
<label class="col-sm-3 control-label is-required">字典标签:</label>
|
||||
<div class="col-sm-8">
|
||||
<input class="form-control" type="text" name="dictLabel" id="dictLabel" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label ">字典键值:</label>
|
||||
<label class="col-sm-3 control-label is-required">字典键值:</label>
|
||||
<div class="col-sm-8">
|
||||
<input class="form-control" type="text" name="dictValue" id="dictValue" required>
|
||||
</div>
|
||||
@ -31,7 +31,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">字典排序:</label>
|
||||
<label class="col-sm-3 control-label is-required">字典排序:</label>
|
||||
<div class="col-sm-8">
|
||||
<input class="form-control" type="text" name="dictSort" required>
|
||||
</div>
|
||||
|
@ -82,7 +82,11 @@
|
||||
},
|
||||
{
|
||||
field: 'dictLabel',
|
||||
title: '字典标签'
|
||||
title: '字典标签',
|
||||
formatter: function(value, row, index) {
|
||||
var listClass = $.common.equals("default", row.listClass) || $.common.isEmpty(row.listClass) ? "" : "badge badge-" + row.listClass;
|
||||
return $.common.sprintf("<span class='%s'>%s</span>", listClass, value);
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'dictValue',
|
||||
|
@ -8,13 +8,13 @@
|
||||
<form class="form-horizontal m" id="form-dict-edit" th:object="${dict}">
|
||||
<input name="dictCode" type="hidden" th:field="*{dictCode}" />
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label ">字典标签:</label>
|
||||
<label class="col-sm-3 control-label is-required">字典标签:</label>
|
||||
<div class="col-sm-8">
|
||||
<input class="form-control" type="text" name="dictLabel" id="dictLabel" th:field="*{dictLabel}" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label ">字典键值:</label>
|
||||
<label class="col-sm-3 control-label is-required">字典键值:</label>
|
||||
<div class="col-sm-8">
|
||||
<input class="form-control" type="text" name="dictValue" id="dictValue" th:field="*{dictValue}" required>
|
||||
</div>
|
||||
@ -32,7 +32,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">字典排序:</label>
|
||||
<label class="col-sm-3 control-label is-required">字典排序:</label>
|
||||
<div class="col-sm-8">
|
||||
<input class="form-control" type="text" name="dictSort" th:field="*{dictSort}" required>
|
||||
</div>
|
||||
|
@ -7,13 +7,13 @@
|
||||
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
|
||||
<form class="form-horizontal m" id="form-dict-add">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label ">字典名称:</label>
|
||||
<label class="col-sm-3 control-label is-required">字典名称:</label>
|
||||
<div class="col-sm-8">
|
||||
<input class="form-control" type="text" name="dictName" id="dictName" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">字典类型:</label>
|
||||
<label class="col-sm-3 control-label is-required">字典类型:</label>
|
||||
<div class="col-sm-8">
|
||||
<input class="form-control" type="text" name="dictType" id="dictType" required>
|
||||
</div>
|
||||
|
@ -8,13 +8,13 @@
|
||||
<form class="form-horizontal m" id="form-dict-edit" th:object="${dict}">
|
||||
<input id="dictId" name="dictId" type="hidden" th:field="*{dictId}" />
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label ">字典名称:</label>
|
||||
<label class="col-sm-3 control-label is-required">字典名称:</label>
|
||||
<div class="col-sm-8">
|
||||
<input class="form-control" type="text" name="dictName" id="dictName" th:field="*{dictName}" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">字典类型:</label>
|
||||
<label class="col-sm-3 control-label is-required">字典类型:</label>
|
||||
<div class="col-sm-8">
|
||||
<input class="form-control" type="text" name="dictType" id="dictType" th:field="*{dictType}" required>
|
||||
</div>
|
||||
|
@ -50,6 +50,9 @@
|
||||
<a class="btn btn-warning" onclick="$.table.exportExcel()" shiro:hasPermission="system:dict:export">
|
||||
<i class="fa fa-download"></i> 导出
|
||||
</a>
|
||||
<a class="btn btn-danger" onclick="clearCache()" shiro:hasPermission="system:dict:remove">
|
||||
<i class="fa fa-refresh"></i> 清理缓存
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 select-table table-striped">
|
||||
@ -105,7 +108,10 @@
|
||||
},
|
||||
{
|
||||
field: 'remark',
|
||||
title: '备注'
|
||||
title: '备注',
|
||||
formatter: function(value, row, index) {
|
||||
return $.table.tooltip(value);
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'createTime',
|
||||
@ -132,6 +138,11 @@
|
||||
var url = prefix + '/detail/' + dictId;
|
||||
$.modal.openTab("字典数据", url);
|
||||
}
|
||||
|
||||
/** 清理字典缓存 */
|
||||
function clearCache() {
|
||||
$.operate.get(prefix + "/clearCache");
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -8,7 +8,7 @@
|
||||
<form class="form-horizontal m" id="form-menu-add">
|
||||
<input id="treeId" name="parentId" type="hidden" th:value="${menu.menuId}" />
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label ">上级菜单:</label>
|
||||
<label class="col-sm-3 control-label">上级菜单:</label>
|
||||
<div class="col-sm-8">
|
||||
<div class="input-group">
|
||||
<input class="form-control" type="text" onclick="selectMenuTree()" id="treeName" readonly="true" th:value="${menu.menuName}">
|
||||
@ -17,7 +17,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">菜单类型:</label>
|
||||
<label class="col-sm-3 control-label is-required">菜单类型:</label>
|
||||
<div class="col-sm-8">
|
||||
<label class="radio-box"> <input type="radio" name="menuType" value="M" /> 目录 </label>
|
||||
<label class="radio-box"> <input type="radio" name="menuType" value="C" /> 菜单 </label>
|
||||
@ -25,7 +25,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">菜单名称:</label>
|
||||
<label class="col-sm-3 control-label is-required">菜单名称:</label>
|
||||
<div class="col-sm-8">
|
||||
<input class="form-control" type="text" name="menuName" id="menuName" required>
|
||||
</div>
|
||||
@ -53,7 +53,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">显示排序:</label>
|
||||
<label class="col-sm-3 control-label is-required">显示排序:</label>
|
||||
<div class="col-sm-8">
|
||||
<input class="form-control" type="text" name="orderNum" required>
|
||||
</div>
|
||||
|
@ -9,7 +9,7 @@
|
||||
<input name="menuId" type="hidden" th:field="*{menuId}" />
|
||||
<input id="treeId" name="parentId" type="hidden" th:field="*{parentId}" />
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label ">上级菜单:</label>
|
||||
<label class="col-sm-3 control-label">上级菜单:</label>
|
||||
<div class="col-sm-8">
|
||||
<div class="input-group">
|
||||
<input class="form-control" type="text" onclick="selectMenuTree()" id="treeName" readonly="true" th:value="${menu.parentName == null ? '无' : menu.parentName}">
|
||||
@ -18,7 +18,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">菜单类型:</label>
|
||||
<label class="col-sm-3 control-label is-required">菜单类型:</label>
|
||||
<div class="col-sm-8">
|
||||
<label class="radio-box"> <input type="radio" th:field="*{menuType}" name="menuType" value="M" /> 目录 </label>
|
||||
<label class="radio-box"> <input type="radio" th:field="*{menuType}" name="menuType" value="C" /> 菜单 </label>
|
||||
@ -26,7 +26,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">菜单名称:</label>
|
||||
<label class="col-sm-3 control-label is-required">菜单名称:</label>
|
||||
<div class="col-sm-8">
|
||||
<input class="form-control" type="text" name="menuName" id="menuName" th:field="*{menuName}" required>
|
||||
</div>
|
||||
@ -54,7 +54,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">显示排序:</label>
|
||||
<label class="col-sm-3 control-label is-required">显示排序:</label>
|
||||
<div class="col-sm-8">
|
||||
<input class="form-control" type="text" name="orderNum" th:field="*{orderNum}" required>
|
||||
</div>
|
||||
|
@ -91,7 +91,10 @@
|
||||
field: 'url',
|
||||
title: '请求地址',
|
||||
width: '15%',
|
||||
align: "left"
|
||||
align: "left",
|
||||
formatter: function(value, row, index) {
|
||||
return $.table.tooltip(value);
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '类型',
|
||||
@ -127,6 +130,9 @@
|
||||
title: '权限标识',
|
||||
width: '15%',
|
||||
align: "left",
|
||||
formatter: function(value, row, index) {
|
||||
return $.table.tooltip(value);
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
|
@ -8,7 +8,7 @@
|
||||
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
|
||||
<form class="form-horizontal m" id="form-notice-add">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-2 control-label">公告标题:</label>
|
||||
<label class="col-sm-2 control-label is-required">公告标题:</label>
|
||||
<div class="col-sm-10">
|
||||
<input id="noticeTitle" name="noticeTitle" class="form-control" type="text" required>
|
||||
</div>
|
||||
|
@ -9,7 +9,7 @@
|
||||
<form class="form-horizontal m" id="form-notice-edit" th:object="${notice}">
|
||||
<input id="noticeId" name="noticeId" th:field="*{noticeId}" type="hidden">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-2 control-label">公告标题:</label>
|
||||
<label class="col-sm-2 control-label is-required">公告标题:</label>
|
||||
<div class="col-sm-10">
|
||||
<input id="noticeTitle" name="noticeTitle" th:field="*{noticeTitle}" class="form-control" type="text" required>
|
||||
</div>
|
||||
|
@ -7,19 +7,19 @@
|
||||
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
|
||||
<form class="form-horizontal m" id="form-post-add">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">岗位名称:</label>
|
||||
<label class="col-sm-3 control-label is-required">岗位名称:</label>
|
||||
<div class="col-sm-8">
|
||||
<input class="form-control" type="text" name="postName" id="postName" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label ">岗位编码:</label>
|
||||
<label class="col-sm-3 control-label is-required">岗位编码:</label>
|
||||
<div class="col-sm-8">
|
||||
<input class="form-control" type="text" name="postCode" id="postCode" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">显示顺序:</label>
|
||||
<label class="col-sm-3 control-label is-required">显示顺序:</label>
|
||||
<div class="col-sm-8">
|
||||
<input class="form-control" type="text" name="postSort" id="postSort" required>
|
||||
</div>
|
||||
|
@ -8,19 +8,19 @@
|
||||
<form class="form-horizontal m" id="form-post-edit" th:object="${post}">
|
||||
<input id="postId" name="postId" type="hidden" th:field="*{postId}"/>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">岗位名称:</label>
|
||||
<label class="col-sm-3 control-label is-required">岗位名称:</label>
|
||||
<div class="col-sm-8">
|
||||
<input class="form-control" type="text" name="postName" id="postName" th:field="*{postName}" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label ">岗位编码:</label>
|
||||
<label class="col-sm-3 control-label is-required">岗位编码:</label>
|
||||
<div class="col-sm-8">
|
||||
<input class="form-control" type="text" name="postCode" id="postCode" th:field="*{postCode}" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">显示顺序:</label>
|
||||
<label class="col-sm-3 control-label is-required">显示顺序:</label>
|
||||
<div class="col-sm-8">
|
||||
<input class="form-control" type="text" name="postSort" id="postSort" th:field="*{postSort}" required>
|
||||
</div>
|
||||
|
@ -8,20 +8,20 @@
|
||||
<div class="wrapper wrapper-content animated fadeInRight ibox-content">
|
||||
<form class="form-horizontal m" id="form-role-add">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label ">角色名称:</label>
|
||||
<label class="col-sm-3 control-label is-required">角色名称:</label>
|
||||
<div class="col-sm-8">
|
||||
<input class="form-control" type="text" name="roleName" id="roleName" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">权限字符:</label>
|
||||
<label class="col-sm-3 control-label is-required">权限字符:</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">
|
||||
<label class="col-sm-3 control-label">显示顺序:</label>
|
||||
<label class="col-sm-3 control-label is-required">显示顺序:</label>
|
||||
<div class="col-sm-8">
|
||||
<input class="form-control" type="text" name="roleSort" id="roleSort" required>
|
||||
</div>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<!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('角色用户分配')" />
|
||||
<th:block th:include="include :: header('角色分配用户')" />
|
||||
</head>
|
||||
<body class="gray-bg">
|
||||
<div class="container-div">
|
||||
|
@ -9,7 +9,7 @@
|
||||
<form class="form-horizontal m" id="form-role-edit" th:object="${role}">
|
||||
<input id="roleId" name="roleId" type="hidden" th:field="*{roleId}"/>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label ">角色名称:</label>
|
||||
<label class="col-sm-3 control-label">角色名称:</label>
|
||||
<div class="col-sm-8">
|
||||
<input class="form-control" type="text" name="roleName" id="roleName" th:field="*{roleName}" readonly="true"/>
|
||||
</div>
|
||||
|
@ -9,20 +9,20 @@
|
||||
<form class="form-horizontal m" id="form-role-edit" th:object="${role}">
|
||||
<input id="roleId" name="roleId" type="hidden" th:field="*{roleId}"/>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label ">角色名称:</label>
|
||||
<label class="col-sm-3 control-label is-required">角色名称:</label>
|
||||
<div class="col-sm-8">
|
||||
<input class="form-control" type="text" name="roleName" id="roleName" th:field="*{roleName}" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">权限字符:</label>
|
||||
<label class="col-sm-3 control-label is-required">权限字符:</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">
|
||||
<label class="col-sm-3 control-label">显示顺序:</label>
|
||||
<label class="col-sm-3 control-label is-required">显示顺序:</label>
|
||||
<div class="col-sm-8">
|
||||
<input class="form-control" type="text" name="roleSort" id="roleSort" th:field="*{roleSort}" required>
|
||||
</div>
|
||||
|
@ -114,9 +114,11 @@
|
||||
formatter: function(value, row, index) {
|
||||
var actions = [];
|
||||
actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="$.operate.edit(\'' + row.roleId + '\')"><i class="fa fa-edit"></i>编辑</a> ');
|
||||
actions.push('<a class="btn btn-primary btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="authDataScope(\'' + row.roleId + '\')"><i class="fa fa-check-square-o"></i>数据权限</a> ');
|
||||
actions.push('<a class="btn btn-info btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="authUser(\'' + row.roleId + '\')"><i class="fa fa-user"></i>分配用户</a> ');
|
||||
actions.push('<a class="btn btn-danger btn-xs ' + removeFlag + '" href="javascript:void(0)" onclick="$.operate.remove(\'' + row.roleId + '\')"><i class="fa fa-remove"></i>删除</a> ');
|
||||
var more = [];
|
||||
more.push("<a class='btn btn-default btn-xs " + editFlag + "' href='javascript:void(0)' onclick='authDataScope(" + row.roleId + ")'><i class='fa fa-check-square-o'></i>数据权限</a> ");
|
||||
more.push("<a class='btn btn-default btn-xs " + editFlag + "' href='javascript:void(0)' onclick='authUser(" + row.roleId + ")'><i class='fa fa-user'></i>分配用户</a>");
|
||||
actions.push('<a class="btn btn-info btn-xs" role="button" data-toggle="popover" data-content="' + more.join('') + '"><i class="fa fa-chevron-circle-right"></i>更多操作</a>');
|
||||
return actions.join('');
|
||||
}
|
||||
}]
|
||||
|
@ -12,7 +12,7 @@
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label"><span style="color: red; ">*</span>用户名称:</label>
|
||||
<label class="col-sm-4 control-label is-required">用户名称:</label>
|
||||
<div class="col-sm-8">
|
||||
<input name="userName" placeholder="请输入用户名称" class="form-control" type="text" maxlength="30" required>
|
||||
</div>
|
||||
@ -20,7 +20,7 @@
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label"><span style="color: red; ">*</span>归属部门:</label>
|
||||
<label class="col-sm-4 control-label is-required">归属部门:</label>
|
||||
<div class="col-sm-8">
|
||||
<div class="input-group">
|
||||
<input name="deptName" onclick="selectDeptTree()" id="treeName" type="text" placeholder="请选择归属部门" class="form-control" required>
|
||||
@ -33,7 +33,7 @@
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label"><span style="color: red; ">*</span>手机号码:</label>
|
||||
<label class="col-sm-4 control-label is-required">手机号码:</label>
|
||||
<div class="col-sm-8">
|
||||
<input id="phonenumber" name="phonenumber" placeholder="请输入手机号码" class="form-control" type="text" maxlength="11" required>
|
||||
</div>
|
||||
@ -41,9 +41,9 @@
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label"><span style="color: red; ">*</span>邮箱:</label>
|
||||
<label class="col-sm-4 control-label is-required">邮箱:</label>
|
||||
<div class="col-sm-8">
|
||||
<input id="email" name="email" class="form-control email" type="text" maxlength="50" placeholder="请输入邮箱" required>
|
||||
<input id="email" name="email" class="form-control email" type="text" maxlength="20" placeholder="请输入邮箱" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -51,7 +51,7 @@
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label"><span style="color: red; ">*</span>登录账号:</label>
|
||||
<label class="col-sm-4 control-label is-required">登录账号:</label>
|
||||
<div class="col-sm-8">
|
||||
<input id="loginName" name="loginName" placeholder="请输入登录账号" class="form-control" type="text" maxlength="30" required>
|
||||
</div>
|
||||
@ -59,7 +59,7 @@
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label"><span style="color: red; ">*</span>登录密码:</label>
|
||||
<label class="col-sm-4 control-label is-required">登录密码:</label>
|
||||
<div class="col-sm-8">
|
||||
<input name="password" placeholder="请输入登录密码" class="form-control" type="password" th:value="${@config.getKey('sys.user.initPassword')}" required>
|
||||
</div>
|
||||
@ -248,7 +248,7 @@
|
||||
|
||||
$(function() {
|
||||
$('#post').select2({
|
||||
placeholder:"请选择岗位",
|
||||
placeholder: "请选择岗位",
|
||||
allowClear: true
|
||||
});
|
||||
})
|
||||
|
@ -0,0 +1,103 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
|
||||
<head>
|
||||
<th:block th:include="include :: header('用户分配角色')" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="main-content">
|
||||
<form id="form-user-add" class="form-horizontal">
|
||||
<input type="hidden" id="userId" name="userId" th:value="${user.userId}">
|
||||
<h4 class="form-header h4">基本信息</h4>
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label is-required">用户名称:</label>
|
||||
<div class="col-sm-8">
|
||||
<input name="userName" class="form-control" type="text" disabled th:value="${user.userName}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label is-required">登录账号:</label>
|
||||
<div class="col-sm-8">
|
||||
<input name="loginName" class="form-control" type="text" disabled th:value="${user.loginName}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h4 class="form-header h4">分配角色</h4>
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="col-sm-12 select-table table-striped">
|
||||
<table id="bootstrap-table"></table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-offset-5 col-sm-10">
|
||||
<button type="button" class="btn btn-sm btn-primary" onclick="submitHandler()"><i class="fa fa-check"></i>保 存</button>
|
||||
<button type="button" class="btn btn-sm btn-danger" onclick="closeItem()"><i class="fa fa-reply-all"></i>关 闭 </button>
|
||||
</div>
|
||||
</div>
|
||||
<th:block th:include="include :: footer" />
|
||||
<script th:inline="javascript">
|
||||
var prefix = ctx + "system/user/authRole";
|
||||
var userRoles = [[${userRoles}]]
|
||||
|
||||
$(function() {
|
||||
var options = {
|
||||
url: ctx + "system/role/list",
|
||||
sortName: "roleSort",
|
||||
showSearch: false,
|
||||
showRefresh: false,
|
||||
showToggle: false,
|
||||
showColumns: false,
|
||||
clickToSelect: true,
|
||||
columns: [{
|
||||
checkbox: true,
|
||||
formatter:function (value, row, index) {
|
||||
for (var i = 0; i < userRoles.length; i++) {
|
||||
if (userRoles[i].roleId == row.roleId) {
|
||||
return { checked: true };
|
||||
}
|
||||
}
|
||||
return { checked: false };
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'roleId',
|
||||
title: '角色编号'
|
||||
},
|
||||
{
|
||||
field: 'roleName',
|
||||
title: '角色名称',
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
field: 'roleKey',
|
||||
title: '权限字符',
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
field: 'createTime',
|
||||
title: '创建时间',
|
||||
sortable: true
|
||||
}]
|
||||
};
|
||||
$.table.init(options);
|
||||
});
|
||||
|
||||
/* 添加角色-提交 */
|
||||
function submitHandler(index, layero){
|
||||
var rows = $.table.selectFirstColumns();
|
||||
var data = { "userId": $("#userId").val(), "roleIds": rows.join() };
|
||||
$.operate.saveTab(prefix + "/insertAuthRole", data);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -13,7 +13,7 @@
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label"><span style="color: red; ">*</span>用户名称:</label>
|
||||
<label class="col-sm-4 control-label is-required">用户名称:</label>
|
||||
<div class="col-sm-8">
|
||||
<input name="userName" placeholder="请输入用户名称" class="form-control" type="text" maxlength="30" th:field="*{userName}" required>
|
||||
</div>
|
||||
@ -21,7 +21,7 @@
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label"><span style="color: red; ">*</span>归属部门:</label>
|
||||
<label class="col-sm-4 control-label is-required">归属部门:</label>
|
||||
<div class="col-sm-8">
|
||||
<div class="input-group">
|
||||
<input class="form-control" type="text" name="deptName" onclick="selectDeptTree()" id="treeName" th:field="*{dept.deptName}" required>
|
||||
@ -34,7 +34,7 @@
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label"><span style="color: red; ">*</span>手机号码:</label>
|
||||
<label class="col-sm-4 control-label is-required">手机号码:</label>
|
||||
<div class="col-sm-8">
|
||||
<input name="phonenumber" placeholder="请输入手机号码" class="form-control" type="text" maxlength="11" th:field="*{phonenumber}" required>
|
||||
</div>
|
||||
@ -42,9 +42,9 @@
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label"><span style="color: red; ">*</span>邮箱:</label>
|
||||
<label class="col-sm-4 control-label is-required">邮箱:</label>
|
||||
<div class="col-sm-8">
|
||||
<input name="email" class="form-control email" type="text" maxlength="50" placeholder="请输入邮箱" th:field="*{email}" required>
|
||||
<input name="email" class="form-control email" type="text" maxlength="20" placeholder="请输入邮箱" th:field="*{email}" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -52,7 +52,7 @@
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-4 control-label"><span style="color: red; ">*</span>登录账号:</label>
|
||||
<label class="col-sm-4 control-label is-required">登录账号:</label>
|
||||
<div class="col-sm-8">
|
||||
<input class="form-control" type="text" readonly="true" th:field="*{loginName}"/>
|
||||
</div>
|
||||
@ -219,7 +219,7 @@
|
||||
|
||||
$(function() {
|
||||
$('#post').select2({
|
||||
placeholder:"请选择岗位",
|
||||
placeholder: "请选择岗位",
|
||||
allowClear: true
|
||||
});
|
||||
})
|
||||
|
@ -27,7 +27,7 @@
|
||||
<b class="font-noraml">手机号码:</b>
|
||||
<p class="pull-right">[[${user.phonenumber}]]</p>
|
||||
</li>
|
||||
<li class="list-group-item"><i class="fa fa-group"></i>
|
||||
<li class="list-group-item" th:if="${user.dept?.deptName != null}"><i class="fa fa-group"></i>
|
||||
<b class="font-noraml">所属部门:</b>
|
||||
<p class="pull-right" >[[${user.dept?.deptName}]] / [[${#strings.defaultString(postGroup,'无岗位')}]]</p>
|
||||
</li>
|
||||
|
@ -8,7 +8,7 @@
|
||||
<form class="form-horizontal m" id="form-user-resetPwd">
|
||||
<input name="userId" type="hidden" th:value="${user.userId}" />
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label ">登录名称:</label>
|
||||
<label class="col-sm-3 control-label">登录名称:</label>
|
||||
<div class="col-sm-8">
|
||||
<input class="form-control" type="text" readonly="true" name="loginName" th:value="${user.loginName}"/>
|
||||
</div>
|
||||
|
@ -8,7 +8,7 @@
|
||||
<form class="form-horizontal m" id="form-user-resetPwd">
|
||||
<input name="userId" type="hidden" th:value="${user.userId}" />
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label ">登录名称:</label>
|
||||
<label class="col-sm-3 control-label">登录名称:</label>
|
||||
<div class="col-sm-8">
|
||||
<input class="form-control" type="text" readonly="true" name="loginName" th:value="${user.loginName}"/>
|
||||
</div>
|
||||
|
@ -166,7 +166,10 @@
|
||||
var actions = [];
|
||||
actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="$.operate.editTab(\'' + row.userId + '\')"><i class="fa fa-edit"></i>编辑</a> ');
|
||||
actions.push('<a class="btn btn-danger btn-xs ' + removeFlag + '" href="javascript:void(0)" onclick="$.operate.remove(\'' + row.userId + '\')"><i class="fa fa-remove"></i>删除</a> ');
|
||||
actions.push('<a class="btn btn-info btn-xs ' + resetPwdFlag + '" href="javascript:void(0)" onclick="resetPwd(\'' + row.userId + '\')"><i class="fa fa-key"></i>重置</a>');
|
||||
var more = [];
|
||||
more.push("<a class='btn btn-default btn-xs " + resetPwdFlag + "' href='javascript:void(0)' onclick='resetPwd(" + row.userId + ")'><i class='fa fa-key'></i>重置密码</a> ");
|
||||
more.push("<a class='btn btn-default btn-xs " + editFlag + "' href='javascript:void(0)' onclick='authRole(" + row.userId + ")'><i class='fa fa-check-square-o'></i>分配角色</a>");
|
||||
actions.push('<a class="btn btn-info btn-xs" role="button" data-toggle="popover" data-content="' + more.join('') + '"><i class="fa fa-chevron-circle-right"></i>更多操作</a>');
|
||||
return actions.join('');
|
||||
}
|
||||
}]
|
||||
@ -219,6 +222,12 @@
|
||||
$.modal.open("重置密码", url, '800', '300');
|
||||
}
|
||||
|
||||
/* 用户管理-分配角色 */
|
||||
function authRole(userId) {
|
||||
var url = prefix + '/authRole/' + userId;
|
||||
$.modal.openTab("用户分配角色", url);
|
||||
}
|
||||
|
||||
/* 用户状态显示 */
|
||||
function statusTools(row) {
|
||||
if (row.status == 1) {
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>ruoyi</artifactId>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<version>4.1.0</version>
|
||||
<version>4.2.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
@ -1,119 +1,93 @@
|
||||
package com.ruoyi.common.config;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.common.utils.YamlUtil;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 全局配置类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "ruoyi")
|
||||
public class Global
|
||||
{
|
||||
private static final Logger log = LoggerFactory.getLogger(Global.class);
|
||||
/** 项目名称 */
|
||||
private static String name;
|
||||
|
||||
private static String NAME = "application.yml";
|
||||
/** 版本 */
|
||||
private static String version;
|
||||
|
||||
/**
|
||||
* 当前对象实例
|
||||
*/
|
||||
private static Global global;
|
||||
/** 版权年份 */
|
||||
private static String copyrightYear;
|
||||
|
||||
/**
|
||||
* 保存全局属性值
|
||||
*/
|
||||
private static Map<String, String> map = new HashMap<String, String>();
|
||||
/** 实例演示开关 */
|
||||
private static boolean demoEnabled;
|
||||
|
||||
private Global()
|
||||
{
|
||||
}
|
||||
/** 上传路径 */
|
||||
private static String profile;
|
||||
|
||||
/**
|
||||
* 静态工厂方法
|
||||
*/
|
||||
public static synchronized Global getInstance()
|
||||
{
|
||||
if (global == null)
|
||||
{
|
||||
global = new Global();
|
||||
}
|
||||
return global;
|
||||
}
|
||||
/** 获取地址开关 */
|
||||
private static boolean addressEnabled;
|
||||
|
||||
/**
|
||||
* 获取配置
|
||||
*/
|
||||
public static String getConfig(String key)
|
||||
{
|
||||
String value = map.get(key);
|
||||
if (value == null)
|
||||
{
|
||||
Map<?, ?> yamlMap = null;
|
||||
try
|
||||
{
|
||||
yamlMap = YamlUtil.loadYaml(NAME);
|
||||
value = String.valueOf(YamlUtil.getProperty(yamlMap, key));
|
||||
map.put(key, value != null ? value : StringUtils.EMPTY);
|
||||
}
|
||||
catch (FileNotFoundException e)
|
||||
{
|
||||
log.error("获取全局配置异常 {}", key);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取项目名称
|
||||
*/
|
||||
public static String getName()
|
||||
{
|
||||
return StringUtils.nvl(getConfig("ruoyi.name"), "RuoYi");
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name)
|
||||
{
|
||||
Global.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取项目版本
|
||||
*/
|
||||
public static String getVersion()
|
||||
{
|
||||
return StringUtils.nvl(getConfig("ruoyi.version"), "4.1.0");
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(String version)
|
||||
{
|
||||
Global.version = version;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取版权年份
|
||||
*/
|
||||
public static String getCopyrightYear()
|
||||
{
|
||||
return StringUtils.nvl(getConfig("ruoyi.copyrightYear"), "2019");
|
||||
return copyrightYear;
|
||||
}
|
||||
|
||||
/**
|
||||
* 实例演示开关
|
||||
*/
|
||||
public static String isDemoEnabled()
|
||||
public void setCopyrightYear(String copyrightYear)
|
||||
{
|
||||
return StringUtils.nvl(getConfig("ruoyi.demoEnabled"), "true");
|
||||
Global.copyrightYear = copyrightYear;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取ip地址开关
|
||||
*/
|
||||
public static Boolean isAddressEnabled()
|
||||
public static boolean isDemoEnabled()
|
||||
{
|
||||
return Boolean.valueOf(getConfig("ruoyi.addressEnabled"));
|
||||
return demoEnabled;
|
||||
}
|
||||
|
||||
public void setDemoEnabled(boolean demoEnabled)
|
||||
{
|
||||
Global.demoEnabled = demoEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件上传路径
|
||||
*/
|
||||
public static String getProfile()
|
||||
{
|
||||
return getConfig("ruoyi.profile");
|
||||
return profile;
|
||||
}
|
||||
|
||||
public void setProfile(String profile)
|
||||
{
|
||||
Global.profile = profile;
|
||||
}
|
||||
|
||||
public static boolean isAddressEnabled()
|
||||
{
|
||||
return addressEnabled;
|
||||
}
|
||||
|
||||
public void setAddressEnabled(boolean addressEnabled)
|
||||
{
|
||||
Global.addressEnabled = addressEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -31,17 +31,17 @@ public class Constants
|
||||
* 注销
|
||||
*/
|
||||
public static final String LOGOUT = "Logout";
|
||||
|
||||
/**
|
||||
* 注册
|
||||
*/
|
||||
public static final String REGISTER = "Register";
|
||||
|
||||
/**
|
||||
* 登录失败
|
||||
*/
|
||||
public static final String LOGIN_FAIL = "Error";
|
||||
|
||||
/**
|
||||
* 自动去除表前缀
|
||||
*/
|
||||
public static final String AUTO_REOMVE_PRE = "true";
|
||||
|
||||
/**
|
||||
* 当前记录起始索引
|
||||
*/
|
||||
@ -62,6 +62,26 @@ public class Constants
|
||||
*/
|
||||
public static final String IS_ASC = "isAsc";
|
||||
|
||||
/**
|
||||
* 参数管理 cache name
|
||||
*/
|
||||
public static final String SYS_CONFIG_CACHE = "sys-config";
|
||||
|
||||
/**
|
||||
* 参数管理 cache key
|
||||
*/
|
||||
public static final String SYS_CONFIG_KEY = "sys_config:";
|
||||
|
||||
/**
|
||||
* 字典管理 cache name
|
||||
*/
|
||||
public static final String SYS_DICT_CACHE = "sys-dict";
|
||||
|
||||
/**
|
||||
* 字典管理 cache key
|
||||
*/
|
||||
public static final String SYS_DICT_KEY = "sys_dict:";
|
||||
|
||||
/**
|
||||
* 资源映射路径 前缀
|
||||
*/
|
||||
|
@ -20,22 +20,22 @@ public interface ShiroConstants
|
||||
/**
|
||||
* 消息key
|
||||
*/
|
||||
public static String MESSAGE = "message";
|
||||
public static final String MESSAGE = "message";
|
||||
|
||||
/**
|
||||
* 错误key
|
||||
*/
|
||||
public static String ERROR = "errorMsg";
|
||||
public static final String ERROR = "errorMsg";
|
||||
|
||||
/**
|
||||
* 编码格式
|
||||
*/
|
||||
public static String ENCODING = "UTF-8";
|
||||
public static final String ENCODING = "UTF-8";
|
||||
|
||||
/**
|
||||
* 当前在线会话
|
||||
*/
|
||||
public String ONLINE_SESSION = "online_session";
|
||||
public static final String ONLINE_SESSION = "online_session";
|
||||
|
||||
/**
|
||||
* 验证码key
|
||||
|
@ -89,6 +89,12 @@ public class UserConstants
|
||||
public static final int PASSWORD_MIN_LENGTH = 5;
|
||||
public static final int PASSWORD_MAX_LENGTH = 20;
|
||||
|
||||
/**
|
||||
* 用户类型
|
||||
*/
|
||||
public static final String SYSTEM_USER_TYPE = "00";
|
||||
public static final String REGISTER_USER_TYPE = "01";
|
||||
|
||||
/**
|
||||
* 手机号码格式限制
|
||||
*/
|
||||
|
@ -63,6 +63,19 @@ public class BaseController
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置请求排序数据
|
||||
*/
|
||||
protected void startOrderBy()
|
||||
{
|
||||
PageDomain pageDomain = TableSupport.buildPageRequest();
|
||||
if (StringUtils.isNotEmpty(pageDomain.getOrderBy()))
|
||||
{
|
||||
String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());
|
||||
PageHelper.orderBy(orderBy);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取request
|
||||
*/
|
||||
|
@ -0,0 +1,187 @@
|
||||
package com.ruoyi.common.utils;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import org.apache.shiro.cache.Cache;
|
||||
import org.apache.shiro.cache.CacheManager;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import com.ruoyi.common.utils.spring.SpringUtils;
|
||||
|
||||
/**
|
||||
* Cache工具类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class CacheUtils
|
||||
{
|
||||
private static Logger logger = LoggerFactory.getLogger(CacheUtils.class);
|
||||
|
||||
private static CacheManager cacheManager = SpringUtils.getBean(CacheManager.class);
|
||||
|
||||
private static final String SYS_CACHE = "sys-cache";
|
||||
|
||||
/**
|
||||
* 获取SYS_CACHE缓存
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public static Object get(String key)
|
||||
{
|
||||
return get(SYS_CACHE, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取SYS_CACHE缓存
|
||||
*
|
||||
* @param key
|
||||
* @param defaultValue
|
||||
* @return
|
||||
*/
|
||||
public static Object get(String key, Object defaultValue)
|
||||
{
|
||||
Object value = get(key);
|
||||
return value != null ? value : defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入SYS_CACHE缓存
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public static void put(String key, Object value)
|
||||
{
|
||||
put(SYS_CACHE, key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从SYS_CACHE缓存中移除
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public static void remove(String key)
|
||||
{
|
||||
remove(SYS_CACHE, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取缓存
|
||||
*
|
||||
* @param cacheName
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public static Object get(String cacheName, String key)
|
||||
{
|
||||
return getCache(cacheName).get(getKey(key));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取缓存
|
||||
*
|
||||
* @param cacheName
|
||||
* @param key
|
||||
* @param defaultValue
|
||||
* @return
|
||||
*/
|
||||
public static Object get(String cacheName, String key, Object defaultValue)
|
||||
{
|
||||
Object value = get(cacheName, getKey(key));
|
||||
return value != null ? value : defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入缓存
|
||||
*
|
||||
* @param cacheName
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
public static void put(String cacheName, String key, Object value)
|
||||
{
|
||||
getCache(cacheName).put(getKey(key), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从缓存中移除
|
||||
*
|
||||
* @param cacheName
|
||||
* @param key
|
||||
*/
|
||||
public static void remove(String cacheName, String key)
|
||||
{
|
||||
getCache(cacheName).remove(getKey(key));
|
||||
}
|
||||
|
||||
/**
|
||||
* 从缓存中移除所有
|
||||
*
|
||||
* @param cacheName
|
||||
*/
|
||||
public static void removeAll(String cacheName)
|
||||
{
|
||||
Cache<String, Object> cache = getCache(cacheName);
|
||||
Set<String> keys = cache.keys();
|
||||
for (Iterator<String> it = keys.iterator(); it.hasNext();)
|
||||
{
|
||||
cache.remove(it.next());
|
||||
}
|
||||
logger.info("清理缓存: {} => {}", cacheName, keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从缓存中移除指定key
|
||||
*
|
||||
* @param keys
|
||||
*/
|
||||
public static void removeByKeys(Set<String> keys)
|
||||
{
|
||||
removeByKeys(SYS_CACHE, keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从缓存中移除指定key
|
||||
*
|
||||
* @param cacheName
|
||||
* @param keys
|
||||
*/
|
||||
public static void removeByKeys(String cacheName, Set<String> keys)
|
||||
{
|
||||
for (Iterator<String> it = keys.iterator(); it.hasNext();)
|
||||
{
|
||||
remove(it.next());
|
||||
}
|
||||
logger.info("清理缓存: {} => {}", cacheName, keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取缓存键名
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
private static String getKey(String key)
|
||||
{
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得一个Cache,没有则显示日志。
|
||||
*
|
||||
* @param cacheName
|
||||
* @return
|
||||
*/
|
||||
private static Cache<String, Object> getCache(String cacheName)
|
||||
{
|
||||
Cache<String, Object> cache = cacheManager.getCache(cacheName);
|
||||
if (cache == null)
|
||||
{
|
||||
throw new RuntimeException("当前系统中没有定义“" + cacheName + "”这个缓存。");
|
||||
}
|
||||
return cache;
|
||||
}
|
||||
|
||||
}
|
@ -395,4 +395,10 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T cast(Object obj)
|
||||
{
|
||||
return (T) obj;
|
||||
}
|
||||
}
|
@ -91,7 +91,7 @@ public class FileUploadUtils
|
||||
*
|
||||
* @param baseDir 相对应用的基目录
|
||||
* @param file 上传的文件
|
||||
* @param extension 上传文件类型
|
||||
* @param allowedExtension 上传文件类型
|
||||
* @return 返回上传成功的文件名
|
||||
* @throws FileSizeLimitExceededException 如果超出最大大小
|
||||
* @throws FileNameLengthLimitExceededException 文件名太长
|
||||
@ -146,7 +146,7 @@ public class FileUploadUtils
|
||||
|
||||
private static final String getPathFileName(String uploadDir, String fileName) throws IOException
|
||||
{
|
||||
int dirLastIndex = uploadDir.lastIndexOf("/") + 1;
|
||||
int dirLastIndex = Global.getProfile().length() + 1;
|
||||
String currentDir = StringUtils.substring(uploadDir, dirLastIndex);
|
||||
String pathFileName = Constants.RESOURCE_PREFIX + "/" + currentDir + "/" + fileName;
|
||||
return pathFileName;
|
||||
|
@ -58,7 +58,7 @@ public class EscapeUtil
|
||||
*/
|
||||
public static String clean(String content)
|
||||
{
|
||||
return content.replaceAll(RE_HTML_MARK, "");
|
||||
return new HTMLFilter().filter(content);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -145,6 +145,8 @@ public class EscapeUtil
|
||||
public static void main(String[] args)
|
||||
{
|
||||
String html = "<script>alert(1);</script>";
|
||||
// String html = "<scr<script>ipt>alert(\"XSS\")</scr<script>ipt>";
|
||||
// String html = "<123";
|
||||
System.out.println(EscapeUtil.clean(html));
|
||||
System.out.println(EscapeUtil.escape(html));
|
||||
System.out.println(EscapeUtil.unescape(html));
|
||||
|
@ -0,0 +1,570 @@
|
||||
package com.ruoyi.common.utils.html;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* HTML过滤器,用于去除XSS漏洞隐患。
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public final class HTMLFilter
|
||||
{
|
||||
/**
|
||||
* regex flag union representing /si modifiers in php
|
||||
**/
|
||||
private static final int REGEX_FLAGS_SI = Pattern.CASE_INSENSITIVE | Pattern.DOTALL;
|
||||
private static final Pattern P_COMMENTS = Pattern.compile("<!--(.*?)-->", Pattern.DOTALL);
|
||||
private static final Pattern P_COMMENT = Pattern.compile("^!--(.*)--$", REGEX_FLAGS_SI);
|
||||
private static final Pattern P_TAGS = Pattern.compile("<(.*?)>", Pattern.DOTALL);
|
||||
private static final Pattern P_END_TAG = Pattern.compile("^/([a-z0-9]+)", REGEX_FLAGS_SI);
|
||||
private static final Pattern P_START_TAG = Pattern.compile("^([a-z0-9]+)(.*?)(/?)$", REGEX_FLAGS_SI);
|
||||
private static final Pattern P_QUOTED_ATTRIBUTES = Pattern.compile("([a-z0-9]+)=([\"'])(.*?)\\2", REGEX_FLAGS_SI);
|
||||
private static final Pattern P_UNQUOTED_ATTRIBUTES = Pattern.compile("([a-z0-9]+)(=)([^\"\\s']+)", REGEX_FLAGS_SI);
|
||||
private static final Pattern P_PROTOCOL = Pattern.compile("^([^:]+):", REGEX_FLAGS_SI);
|
||||
private static final Pattern P_ENTITY = Pattern.compile("&#(\\d+);?");
|
||||
private static final Pattern P_ENTITY_UNICODE = Pattern.compile("&#x([0-9a-f]+);?");
|
||||
private static final Pattern P_ENCODE = Pattern.compile("%([0-9a-f]{2});?");
|
||||
private static final Pattern P_VALID_ENTITIES = Pattern.compile("&([^&;]*)(?=(;|&|$))");
|
||||
private static final Pattern P_VALID_QUOTES = Pattern.compile("(>|^)([^<]+?)(<|$)", Pattern.DOTALL);
|
||||
private static final Pattern P_END_ARROW = Pattern.compile("^>");
|
||||
// private static final Pattern P_BODY_TO_END = Pattern.compile("<([^>]*?)(?=<|$)");
|
||||
private static final Pattern P_XML_CONTENT = Pattern.compile("(^|>)([^<]*?)(?=>)");
|
||||
private static final Pattern P_STRAY_LEFT_ARROW = Pattern.compile("<([^>]*?)(?=<|$)");
|
||||
private static final Pattern P_STRAY_RIGHT_ARROW = Pattern.compile("(^|>)([^<]*?)(?=>)");
|
||||
private static final Pattern P_AMP = Pattern.compile("&");
|
||||
private static final Pattern P_QUOTE = Pattern.compile("\"");
|
||||
private static final Pattern P_LEFT_ARROW = Pattern.compile("<");
|
||||
private static final Pattern P_RIGHT_ARROW = Pattern.compile(">");
|
||||
private static final Pattern P_BOTH_ARROWS = Pattern.compile("<>");
|
||||
|
||||
// @xxx could grow large... maybe use sesat's ReferenceMap
|
||||
private static final ConcurrentMap<String, Pattern> P_REMOVE_PAIR_BLANKS = new ConcurrentHashMap<>();
|
||||
private static final ConcurrentMap<String, Pattern> P_REMOVE_SELF_BLANKS = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* set of allowed html elements, along with allowed attributes for each element
|
||||
**/
|
||||
private final Map<String, List<String>> vAllowed;
|
||||
/**
|
||||
* counts of open tags for each (allowable) html element
|
||||
**/
|
||||
private final Map<String, Integer> vTagCounts = new HashMap<>();
|
||||
|
||||
/**
|
||||
* html elements which must always be self-closing (e.g. "<img />")
|
||||
**/
|
||||
private final String[] vSelfClosingTags;
|
||||
/**
|
||||
* html elements which must always have separate opening and closing tags (e.g. "<b></b>")
|
||||
**/
|
||||
private final String[] vNeedClosingTags;
|
||||
/**
|
||||
* set of disallowed html elements
|
||||
**/
|
||||
private final String[] vDisallowed;
|
||||
/**
|
||||
* attributes which should be checked for valid protocols
|
||||
**/
|
||||
private final String[] vProtocolAtts;
|
||||
/**
|
||||
* allowed protocols
|
||||
**/
|
||||
private final String[] vAllowedProtocols;
|
||||
/**
|
||||
* tags which should be removed if they contain no content (e.g. "<b></b>" or "<b />")
|
||||
**/
|
||||
private final String[] vRemoveBlanks;
|
||||
/**
|
||||
* entities allowed within html markup
|
||||
**/
|
||||
private final String[] vAllowedEntities;
|
||||
/**
|
||||
* flag determining whether comments are allowed in input String.
|
||||
*/
|
||||
private final boolean stripComment;
|
||||
private final boolean encodeQuotes;
|
||||
/**
|
||||
* flag determining whether to try to make tags when presented with "unbalanced" angle brackets (e.g. "<b text </b>"
|
||||
* becomes "<b> text </b>"). If set to false, unbalanced angle brackets will be html escaped.
|
||||
*/
|
||||
private final boolean alwaysMakeTags;
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
public HTMLFilter()
|
||||
{
|
||||
vAllowed = new HashMap<>();
|
||||
|
||||
final ArrayList<String> a_atts = new ArrayList<>();
|
||||
a_atts.add("href");
|
||||
a_atts.add("target");
|
||||
vAllowed.put("a", a_atts);
|
||||
|
||||
final ArrayList<String> img_atts = new ArrayList<>();
|
||||
img_atts.add("src");
|
||||
img_atts.add("width");
|
||||
img_atts.add("height");
|
||||
img_atts.add("alt");
|
||||
vAllowed.put("img", img_atts);
|
||||
|
||||
final ArrayList<String> no_atts = new ArrayList<>();
|
||||
vAllowed.put("b", no_atts);
|
||||
vAllowed.put("strong", no_atts);
|
||||
vAllowed.put("i", no_atts);
|
||||
vAllowed.put("em", no_atts);
|
||||
|
||||
vSelfClosingTags = new String[] { "img" };
|
||||
vNeedClosingTags = new String[] { "a", "b", "strong", "i", "em" };
|
||||
vDisallowed = new String[] {};
|
||||
vAllowedProtocols = new String[] { "http", "mailto", "https" }; // no ftp.
|
||||
vProtocolAtts = new String[] { "src", "href" };
|
||||
vRemoveBlanks = new String[] { "a", "b", "strong", "i", "em" };
|
||||
vAllowedEntities = new String[] { "amp", "gt", "lt", "quot" };
|
||||
stripComment = true;
|
||||
encodeQuotes = true;
|
||||
alwaysMakeTags = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Map-parameter configurable constructor.
|
||||
*
|
||||
* @param conf map containing configuration. keys match field names.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public HTMLFilter(final Map<String, Object> conf)
|
||||
{
|
||||
|
||||
assert conf.containsKey("vAllowed") : "configuration requires vAllowed";
|
||||
assert conf.containsKey("vSelfClosingTags") : "configuration requires vSelfClosingTags";
|
||||
assert conf.containsKey("vNeedClosingTags") : "configuration requires vNeedClosingTags";
|
||||
assert conf.containsKey("vDisallowed") : "configuration requires vDisallowed";
|
||||
assert conf.containsKey("vAllowedProtocols") : "configuration requires vAllowedProtocols";
|
||||
assert conf.containsKey("vProtocolAtts") : "configuration requires vProtocolAtts";
|
||||
assert conf.containsKey("vRemoveBlanks") : "configuration requires vRemoveBlanks";
|
||||
assert conf.containsKey("vAllowedEntities") : "configuration requires vAllowedEntities";
|
||||
|
||||
vAllowed = Collections.unmodifiableMap((HashMap<String, List<String>>) conf.get("vAllowed"));
|
||||
vSelfClosingTags = (String[]) conf.get("vSelfClosingTags");
|
||||
vNeedClosingTags = (String[]) conf.get("vNeedClosingTags");
|
||||
vDisallowed = (String[]) conf.get("vDisallowed");
|
||||
vAllowedProtocols = (String[]) conf.get("vAllowedProtocols");
|
||||
vProtocolAtts = (String[]) conf.get("vProtocolAtts");
|
||||
vRemoveBlanks = (String[]) conf.get("vRemoveBlanks");
|
||||
vAllowedEntities = (String[]) conf.get("vAllowedEntities");
|
||||
stripComment = conf.containsKey("stripComment") ? (Boolean) conf.get("stripComment") : true;
|
||||
encodeQuotes = conf.containsKey("encodeQuotes") ? (Boolean) conf.get("encodeQuotes") : true;
|
||||
alwaysMakeTags = conf.containsKey("alwaysMakeTags") ? (Boolean) conf.get("alwaysMakeTags") : true;
|
||||
}
|
||||
|
||||
private void reset()
|
||||
{
|
||||
vTagCounts.clear();
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// my versions of some PHP library functions
|
||||
public static String chr(final int decimal)
|
||||
{
|
||||
return String.valueOf((char) decimal);
|
||||
}
|
||||
|
||||
public static String htmlSpecialChars(final String s)
|
||||
{
|
||||
String result = s;
|
||||
result = regexReplace(P_AMP, "&", result);
|
||||
result = regexReplace(P_QUOTE, """, result);
|
||||
result = regexReplace(P_LEFT_ARROW, "<", result);
|
||||
result = regexReplace(P_RIGHT_ARROW, ">", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* given a user submitted input String, filter out any invalid or restricted html.
|
||||
*
|
||||
* @param input text (i.e. submitted by a user) than may contain html
|
||||
* @return "clean" version of input, with only valid, whitelisted html elements allowed
|
||||
*/
|
||||
public String filter(final String input)
|
||||
{
|
||||
reset();
|
||||
String s = input;
|
||||
|
||||
s = escapeComments(s);
|
||||
|
||||
s = balanceHTML(s);
|
||||
|
||||
s = checkTags(s);
|
||||
|
||||
s = processRemoveBlanks(s);
|
||||
|
||||
s = validateEntities(s);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
public boolean isAlwaysMakeTags()
|
||||
{
|
||||
return alwaysMakeTags;
|
||||
}
|
||||
|
||||
public boolean isStripComments()
|
||||
{
|
||||
return stripComment;
|
||||
}
|
||||
|
||||
private String escapeComments(final String s)
|
||||
{
|
||||
final Matcher m = P_COMMENTS.matcher(s);
|
||||
final StringBuffer buf = new StringBuffer();
|
||||
if (m.find())
|
||||
{
|
||||
final String match = m.group(1); // (.*?)
|
||||
m.appendReplacement(buf, Matcher.quoteReplacement("<!--" + htmlSpecialChars(match) + "-->"));
|
||||
}
|
||||
m.appendTail(buf);
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
private String balanceHTML(String s)
|
||||
{
|
||||
if (alwaysMakeTags)
|
||||
{
|
||||
//
|
||||
// try and form html
|
||||
//
|
||||
s = regexReplace(P_END_ARROW, "", s);
|
||||
// 不追加结束标签
|
||||
// s = regexReplace(P_BODY_TO_END, "<$1>", s);
|
||||
s = regexReplace(P_XML_CONTENT, "$1<$2", s);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// escape stray brackets
|
||||
//
|
||||
s = regexReplace(P_STRAY_LEFT_ARROW, "<$1", s);
|
||||
s = regexReplace(P_STRAY_RIGHT_ARROW, "$1$2><", s);
|
||||
|
||||
//
|
||||
// the last regexp causes '<>' entities to appear
|
||||
// (we need to do a lookahead assertion so that the last bracket can
|
||||
// be used in the next pass of the regexp)
|
||||
//
|
||||
s = regexReplace(P_BOTH_ARROWS, "", s);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
private String checkTags(String s)
|
||||
{
|
||||
Matcher m = P_TAGS.matcher(s);
|
||||
|
||||
final StringBuffer buf = new StringBuffer();
|
||||
while (m.find())
|
||||
{
|
||||
String replaceStr = m.group(1);
|
||||
replaceStr = processTag(replaceStr);
|
||||
m.appendReplacement(buf, Matcher.quoteReplacement(replaceStr));
|
||||
}
|
||||
m.appendTail(buf);
|
||||
|
||||
// these get tallied in processTag
|
||||
// (remember to reset before subsequent calls to filter method)
|
||||
final StringBuilder sBuilder = new StringBuilder(buf.toString());
|
||||
for (String key : vTagCounts.keySet())
|
||||
{
|
||||
for (int ii = 0; ii < vTagCounts.get(key); ii++)
|
||||
{
|
||||
sBuilder.append("</").append(key).append(">");
|
||||
}
|
||||
}
|
||||
s = sBuilder.toString();
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
private String processRemoveBlanks(final String s)
|
||||
{
|
||||
String result = s;
|
||||
for (String tag : vRemoveBlanks)
|
||||
{
|
||||
if (!P_REMOVE_PAIR_BLANKS.containsKey(tag))
|
||||
{
|
||||
P_REMOVE_PAIR_BLANKS.putIfAbsent(tag, Pattern.compile("<" + tag + "(\\s[^>]*)?></" + tag + ">"));
|
||||
}
|
||||
result = regexReplace(P_REMOVE_PAIR_BLANKS.get(tag), "", result);
|
||||
if (!P_REMOVE_SELF_BLANKS.containsKey(tag))
|
||||
{
|
||||
P_REMOVE_SELF_BLANKS.putIfAbsent(tag, Pattern.compile("<" + tag + "(\\s[^>]*)?/>"));
|
||||
}
|
||||
result = regexReplace(P_REMOVE_SELF_BLANKS.get(tag), "", result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static String regexReplace(final Pattern regex_pattern, final String replacement, final String s)
|
||||
{
|
||||
Matcher m = regex_pattern.matcher(s);
|
||||
return m.replaceAll(replacement);
|
||||
}
|
||||
|
||||
private String processTag(final String s)
|
||||
{
|
||||
// ending tags
|
||||
Matcher m = P_END_TAG.matcher(s);
|
||||
if (m.find())
|
||||
{
|
||||
final String name = m.group(1).toLowerCase();
|
||||
if (allowed(name))
|
||||
{
|
||||
if (false == inArray(name, vSelfClosingTags))
|
||||
{
|
||||
if (vTagCounts.containsKey(name))
|
||||
{
|
||||
vTagCounts.put(name, vTagCounts.get(name) - 1);
|
||||
return "</" + name + ">";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// starting tags
|
||||
m = P_START_TAG.matcher(s);
|
||||
if (m.find())
|
||||
{
|
||||
final String name = m.group(1).toLowerCase();
|
||||
final String body = m.group(2);
|
||||
String ending = m.group(3);
|
||||
|
||||
// debug( "in a starting tag, name='" + name + "'; body='" + body + "'; ending='" + ending + "'" );
|
||||
if (allowed(name))
|
||||
{
|
||||
final StringBuilder params = new StringBuilder();
|
||||
|
||||
final Matcher m2 = P_QUOTED_ATTRIBUTES.matcher(body);
|
||||
final Matcher m3 = P_UNQUOTED_ATTRIBUTES.matcher(body);
|
||||
final List<String> paramNames = new ArrayList<>();
|
||||
final List<String> paramValues = new ArrayList<>();
|
||||
while (m2.find())
|
||||
{
|
||||
paramNames.add(m2.group(1)); // ([a-z0-9]+)
|
||||
paramValues.add(m2.group(3)); // (.*?)
|
||||
}
|
||||
while (m3.find())
|
||||
{
|
||||
paramNames.add(m3.group(1)); // ([a-z0-9]+)
|
||||
paramValues.add(m3.group(3)); // ([^\"\\s']+)
|
||||
}
|
||||
|
||||
String paramName, paramValue;
|
||||
for (int ii = 0; ii < paramNames.size(); ii++)
|
||||
{
|
||||
paramName = paramNames.get(ii).toLowerCase();
|
||||
paramValue = paramValues.get(ii);
|
||||
|
||||
// debug( "paramName='" + paramName + "'" );
|
||||
// debug( "paramValue='" + paramValue + "'" );
|
||||
// debug( "allowed? " + vAllowed.get( name ).contains( paramName ) );
|
||||
|
||||
if (allowedAttribute(name, paramName))
|
||||
{
|
||||
if (inArray(paramName, vProtocolAtts))
|
||||
{
|
||||
paramValue = processParamProtocol(paramValue);
|
||||
}
|
||||
params.append(' ').append(paramName).append("=\"").append(paramValue).append("\"");
|
||||
}
|
||||
}
|
||||
|
||||
if (inArray(name, vSelfClosingTags))
|
||||
{
|
||||
ending = " /";
|
||||
}
|
||||
|
||||
if (inArray(name, vNeedClosingTags))
|
||||
{
|
||||
ending = "";
|
||||
}
|
||||
|
||||
if (ending == null || ending.length() < 1)
|
||||
{
|
||||
if (vTagCounts.containsKey(name))
|
||||
{
|
||||
vTagCounts.put(name, vTagCounts.get(name) + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
vTagCounts.put(name, 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ending = " /";
|
||||
}
|
||||
return "<" + name + params + ending + ">";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
// comments
|
||||
m = P_COMMENT.matcher(s);
|
||||
if (!stripComment && m.find())
|
||||
{
|
||||
return "<" + m.group() + ">";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
private String processParamProtocol(String s)
|
||||
{
|
||||
s = decodeEntities(s);
|
||||
final Matcher m = P_PROTOCOL.matcher(s);
|
||||
if (m.find())
|
||||
{
|
||||
final String protocol = m.group(1);
|
||||
if (!inArray(protocol, vAllowedProtocols))
|
||||
{
|
||||
// bad protocol, turn into local anchor link instead
|
||||
s = "#" + s.substring(protocol.length() + 1);
|
||||
if (s.startsWith("#//"))
|
||||
{
|
||||
s = "#" + s.substring(3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
private String decodeEntities(String s)
|
||||
{
|
||||
StringBuffer buf = new StringBuffer();
|
||||
|
||||
Matcher m = P_ENTITY.matcher(s);
|
||||
while (m.find())
|
||||
{
|
||||
final String match = m.group(1);
|
||||
final int decimal = Integer.decode(match).intValue();
|
||||
m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal)));
|
||||
}
|
||||
m.appendTail(buf);
|
||||
s = buf.toString();
|
||||
|
||||
buf = new StringBuffer();
|
||||
m = P_ENTITY_UNICODE.matcher(s);
|
||||
while (m.find())
|
||||
{
|
||||
final String match = m.group(1);
|
||||
final int decimal = Integer.valueOf(match, 16).intValue();
|
||||
m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal)));
|
||||
}
|
||||
m.appendTail(buf);
|
||||
s = buf.toString();
|
||||
|
||||
buf = new StringBuffer();
|
||||
m = P_ENCODE.matcher(s);
|
||||
while (m.find())
|
||||
{
|
||||
final String match = m.group(1);
|
||||
final int decimal = Integer.valueOf(match, 16).intValue();
|
||||
m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal)));
|
||||
}
|
||||
m.appendTail(buf);
|
||||
s = buf.toString();
|
||||
|
||||
s = validateEntities(s);
|
||||
return s;
|
||||
}
|
||||
|
||||
private String validateEntities(final String s)
|
||||
{
|
||||
StringBuffer buf = new StringBuffer();
|
||||
|
||||
// validate entities throughout the string
|
||||
Matcher m = P_VALID_ENTITIES.matcher(s);
|
||||
while (m.find())
|
||||
{
|
||||
final String one = m.group(1); // ([^&;]*)
|
||||
final String two = m.group(2); // (?=(;|&|$))
|
||||
m.appendReplacement(buf, Matcher.quoteReplacement(checkEntity(one, two)));
|
||||
}
|
||||
m.appendTail(buf);
|
||||
|
||||
return encodeQuotes(buf.toString());
|
||||
}
|
||||
|
||||
private String encodeQuotes(final String s)
|
||||
{
|
||||
if (encodeQuotes)
|
||||
{
|
||||
StringBuffer buf = new StringBuffer();
|
||||
Matcher m = P_VALID_QUOTES.matcher(s);
|
||||
while (m.find())
|
||||
{
|
||||
final String one = m.group(1); // (>|^)
|
||||
final String two = m.group(2); // ([^<]+?)
|
||||
final String three = m.group(3); // (<|$)
|
||||
// 不替换双引号为",防止json格式无效 regexReplace(P_QUOTE, """, two)
|
||||
m.appendReplacement(buf, Matcher.quoteReplacement(one + two + three));
|
||||
}
|
||||
m.appendTail(buf);
|
||||
return buf.toString();
|
||||
}
|
||||
else
|
||||
{
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
private String checkEntity(final String preamble, final String term)
|
||||
{
|
||||
|
||||
return ";".equals(term) && isValidEntity(preamble) ? '&' + preamble : "&" + preamble;
|
||||
}
|
||||
|
||||
private boolean isValidEntity(final String entity)
|
||||
{
|
||||
return inArray(entity, vAllowedEntities);
|
||||
}
|
||||
|
||||
private static boolean inArray(final String s, final String[] array)
|
||||
{
|
||||
for (String item : array)
|
||||
{
|
||||
if (item != null && item.equals(s))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean allowed(final String name)
|
||||
{
|
||||
return (vAllowed.isEmpty() || vAllowed.containsKey(name)) && !inArray(name, vDisallowed);
|
||||
}
|
||||
|
||||
private boolean allowedAttribute(final String name, final String paramName)
|
||||
{
|
||||
return allowed(name) && (vAllowed.isEmpty() || vAllowed.get(name).contains(paramName));
|
||||
}
|
||||
}
|
@ -224,7 +224,15 @@ public class ExcelUtil<T>
|
||||
}
|
||||
else
|
||||
{
|
||||
val = Convert.toStr(val);
|
||||
String dateFormat = field.getAnnotation(Excel.class).dateFormat();
|
||||
if (StringUtils.isNotEmpty(dateFormat))
|
||||
{
|
||||
val = DateUtils.parseDateToStr(dateFormat, (Date) val);
|
||||
}
|
||||
else
|
||||
{
|
||||
val = Convert.toStr(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((Integer.TYPE == fieldType) || (Integer.class == fieldType))
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>ruoyi</artifactId>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<version>4.1.0</version>
|
||||
<version>4.2.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@ -47,7 +47,7 @@
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!-- Shiro使用Srping框架 -->
|
||||
<!-- Shiro使用Spring框架 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.shiro</groupId>
|
||||
<artifactId>shiro-spring</artifactId>
|
||||
|
@ -92,7 +92,8 @@ public class DataScopeAspect
|
||||
*
|
||||
* @param joinPoint 切点
|
||||
* @param user 用户
|
||||
* @param alias 别名
|
||||
* @param deptAlias 部门别名
|
||||
* @param userAlias 用户别名
|
||||
*/
|
||||
public static void dataScopeFilter(JoinPoint joinPoint, SysUser user, String deptAlias, String userAlias)
|
||||
{
|
||||
|
@ -20,6 +20,7 @@ import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
|
||||
import com.alibaba.druid.spring.boot.autoconfigure.properties.DruidStatProperties;
|
||||
import com.alibaba.druid.util.Utils;
|
||||
import com.ruoyi.common.enums.DataSourceType;
|
||||
import com.ruoyi.common.utils.spring.SpringUtils;
|
||||
import com.ruoyi.framework.config.properties.DruidProperties;
|
||||
import com.ruoyi.framework.datasource.DynamicDataSource;
|
||||
|
||||
@ -50,14 +51,33 @@ public class DruidConfig
|
||||
|
||||
@Bean(name = "dynamicDataSource")
|
||||
@Primary
|
||||
public DynamicDataSource dataSource(DataSource masterDataSource, DataSource slaveDataSource)
|
||||
public DynamicDataSource dataSource(DataSource masterDataSource)
|
||||
{
|
||||
Map<Object, Object> targetDataSources = new HashMap<>();
|
||||
targetDataSources.put(DataSourceType.MASTER.name(), masterDataSource);
|
||||
targetDataSources.put(DataSourceType.SLAVE.name(), slaveDataSource);
|
||||
setDataSource(targetDataSources, DataSourceType.SLAVE.name(), "slaveDataSource");
|
||||
return new DynamicDataSource(masterDataSource, targetDataSources);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置数据源
|
||||
*
|
||||
* @param targetDataSources 备选数据源集合
|
||||
* @param sourceName 数据源名称
|
||||
* @param beanName bean名称
|
||||
*/
|
||||
public void setDataSource(Map<Object, Object> targetDataSources, String sourceName, String beanName)
|
||||
{
|
||||
try
|
||||
{
|
||||
DataSource dataSource = SpringUtils.getBean(beanName);
|
||||
targetDataSources.put(sourceName, dataSource);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 去除监控页面底部的广告
|
||||
*/
|
||||
@ -79,6 +99,7 @@ public class DruidConfig
|
||||
public void init(javax.servlet.FilterConfig filterConfig) throws ServletException
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
|
||||
throws IOException, ServletException
|
||||
@ -93,6 +114,7 @@ public class DruidConfig
|
||||
text = text.replaceAll("powered.*?shrek.wang</a>", "");
|
||||
response.getWriter().write(text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy()
|
||||
{
|
||||
|
@ -199,7 +199,7 @@ public class ShiroConfig
|
||||
* 安全管理器
|
||||
*/
|
||||
@Bean
|
||||
public SecurityManager securityManager(UserRealm userRealm, SpringSessionValidationScheduler springSessionValidationScheduler)
|
||||
public SecurityManager securityManager(UserRealm userRealm)
|
||||
{
|
||||
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
|
||||
// 设置realm.
|
||||
@ -249,12 +249,13 @@ public class ShiroConfig
|
||||
filterChainDefinitionMap.put("/ajax/**", "anon");
|
||||
filterChainDefinitionMap.put("/js/**", "anon");
|
||||
filterChainDefinitionMap.put("/ruoyi/**", "anon");
|
||||
filterChainDefinitionMap.put("/druid/**", "anon");
|
||||
filterChainDefinitionMap.put("/captcha/captchaImage**", "anon");
|
||||
// 退出 logout地址,shiro去清除session
|
||||
filterChainDefinitionMap.put("/logout", "logout");
|
||||
// 不需要拦截的访问
|
||||
filterChainDefinitionMap.put("/login", "anon,captchaValidate");
|
||||
// 注册相关
|
||||
filterChainDefinitionMap.put("/register", "anon,captchaValidate");
|
||||
// 系统权限列表
|
||||
// filterChainDefinitionMap.putAll(SpringUtils.getBean(IMenuService.class).selectPermsAll());
|
||||
|
||||
|
@ -47,7 +47,7 @@ public abstract class RepeatSubmitInterceptor extends HandlerInterceptorAdapter
|
||||
/**
|
||||
* 验证是否重复提交由子类实现具体的防重复提交的规则
|
||||
*
|
||||
* @param httpServletRequest
|
||||
* @param request
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
|
@ -1,6 +1,8 @@
|
||||
package com.ruoyi.framework.manager;
|
||||
|
||||
import com.ruoyi.framework.shiro.web.session.SpringSessionValidationScheduler;
|
||||
import net.sf.ehcache.CacheManager;
|
||||
import org.apache.shiro.cache.ehcache.EhCacheManager;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -20,11 +22,15 @@ public class ShutdownManager
|
||||
@Autowired(required = false)
|
||||
private SpringSessionValidationScheduler springSessionValidationScheduler;
|
||||
|
||||
@Autowired(required = false)
|
||||
private EhCacheManager ehCacheManager;
|
||||
|
||||
@PreDestroy
|
||||
public void destroy()
|
||||
{
|
||||
shutdownSpringSessionValidationScheduler();
|
||||
shutdownAsyncManager();
|
||||
shutdownEhCacheManager();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -61,4 +67,21 @@ public class ShutdownManager
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private void shutdownEhCacheManager()
|
||||
{
|
||||
try
|
||||
{
|
||||
logger.info("====关闭缓存====");
|
||||
if (ehCacheManager != null)
|
||||
{
|
||||
CacheManager cacheManager = ehCacheManager.getCacheManager();
|
||||
cacheManager.shutdown();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user