Skip to content
项目
群组
代码片段
帮助
正在加载...
登录
切换导航
X
XXL-JOB
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
靳帅
XXL-JOB
Commits
b3b9ff80
提交
b3b9ff80
authored
5月 04, 2019
作者:
xuxueli
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
用户管理:支持在线维护系统用户
上级
b32791b0
隐藏空白字符变更
内嵌
并排
正在显示
11 个修改的文件
包含
808 行增加
和
1 行删除
+808
-1
XXL-JOB官方文档.md
doc/XXL-JOB官方文档.md
+1
-1
tables_xxl_job.sql
doc/db/tables_xxl_job.sql
+10
-0
UserController.java
...ain/java/com/xxl/job/admin/controller/UserController.java
+124
-0
XxlJobUser.java
...rc/main/java/com/xxl/job/admin/core/model/XxlJobUser.java
+54
-0
XxlJobUserDao.java
...in/src/main/java/com/xxl/job/admin/dao/XxlJobUserDao.java
+29
-0
message.properties
xxl-job-admin/src/main/resources/i18n/message.properties
+15
-0
message_en.properties
xxl-job-admin/src/main/resources/i18n/message_en.properties
+15
-0
XxlJobUserMapper.xml
...in/src/main/resources/mybatis-mapper/XxlJobUserMapper.xml
+82
-0
user.index.1.js
xxl-job-admin/src/main/resources/static/js/user.index.1.js
+298
-0
common.macro.ftl
...dmin/src/main/resources/templates/common/common.macro.ftl
+1
-0
user.index.ftl
...ob-admin/src/main/resources/templates/user/user.index.ftl
+179
-0
没有找到文件。
doc/XXL-JOB官方文档.md
浏览文件 @
b3b9ff80
...
...
@@ -1469,7 +1469,7 @@ Tips: 历史版本(V1.3.x)目前已经Release至稳定版本, 进入维护阶段
-
1、
[
规划中
]
移除quartz:精简底层实现,优化已知问题;
-
触发:单节点周期性触发,运行事件如delayqueue;
-
调度:集群竞争,负载方式协同处理,竞争-加入时间轮-释放-竞争;
-
2、
[
规划中
]
用户管理:支持在线维护系统用户;
-
2、用户管理:支持在线维护系统用户;
-
3、
[
规划中
]
权限管理:执行器为粒度分配权限,核心操作校验权限,暂定管理员、普通用户两种角色;
-
4、调度日志优化:支持设置日志保留天数,过期日志天维度记录报表,并清理;调度报表汇总实时数据和报表;
-
5、调度线程池参数调优;
...
...
doc/db/tables_xxl_job.sql
浏览文件 @
b3b9ff80
...
...
@@ -224,10 +224,20 @@ CREATE TABLE `XXL_JOB_QRTZ_TRIGGER_GROUP` (
PRIMARY
KEY
(
`id`
)
)
ENGINE
=
InnoDB
DEFAULT
CHARSET
=
utf8
;
CREATE
TABLE
`XXL_JOB_QRTZ_USER`
(
`id`
int
(
11
)
NOT
NULL
AUTO_INCREMENT
,
`username`
varchar
(
50
)
NOT
NULL
COMMENT
'账号'
,
`password`
varchar
(
50
)
NOT
NULL
COMMENT
'密码'
,
`role`
tinyint
(
4
)
NOT
NULL
COMMENT
'角色:0-普通用户、1-管理员'
,
`permission`
varchar
(
255
)
DEFAULT
NULL
COMMENT
'权限:执行器ID列表,多个逗号分割'
,
PRIMARY
KEY
(
`id`
),
UNIQUE
KEY
`i_username`
(
`username`
)
USING
BTREE
)
ENGINE
=
InnoDB
DEFAULT
CHARSET
=
utf8
;
INSERT
INTO
`XXL_JOB_QRTZ_TRIGGER_GROUP`
(
`id`
,
`app_name`
,
`title`
,
`order`
,
`address_type`
,
`address_list`
)
VALUES
(
1
,
'xxl-job-executor-sample'
,
'示例执行器'
,
1
,
0
,
NULL
);
INSERT
INTO
`XXL_JOB_QRTZ_TRIGGER_INFO`
(
`id`
,
`job_group`
,
`job_cron`
,
`job_desc`
,
`add_time`
,
`update_time`
,
`author`
,
`alarm_email`
,
`executor_route_strategy`
,
`executor_handler`
,
`executor_param`
,
`executor_block_strategy`
,
`executor_timeout`
,
`executor_fail_retry_count`
,
`glue_type`
,
`glue_source`
,
`glue_remark`
,
`glue_updatetime`
,
`child_jobid`
)
VALUES
(
1
,
1
,
'0 0 0 * * ? *'
,
'测试任务1'
,
'2018-11-03 22:21:31'
,
'2018-11-03 22:21:31'
,
'XXL'
,
''
,
'FIRST'
,
'demoJobHandler'
,
''
,
'SERIAL_EXECUTION'
,
0
,
0
,
'BEAN'
,
''
,
'GLUE代码初始化'
,
'2018-11-03 22:21:31'
,
''
);
INSERT
INTO
`XXL_JOB_QRTZ_USER`
(
`id`
,
`username`
,
`password`
,
`role`
,
`permission`
)
VALUES
(
1
,
'admin'
,
'49ba59abbe56e057'
,
1
,
NULL
);
commit
;
xxl-job-admin/src/main/java/com/xxl/job/admin/controller/UserController.java
0 → 100644
浏览文件 @
b3b9ff80
package
com
.
xxl
.
job
.
admin
.
controller
;
import
com.xxl.job.admin.core.model.XxlJobGroup
;
import
com.xxl.job.admin.core.model.XxlJobUser
;
import
com.xxl.job.admin.core.util.I18nUtil
;
import
com.xxl.job.admin.dao.XxlJobGroupDao
;
import
com.xxl.job.admin.dao.XxlJobUserDao
;
import
com.xxl.job.core.biz.model.ReturnT
;
import
org.springframework.stereotype.Controller
;
import
org.springframework.ui.Model
;
import
org.springframework.util.DigestUtils
;
import
org.springframework.util.StringUtils
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RequestParam
;
import
org.springframework.web.bind.annotation.ResponseBody
;
import
javax.annotation.Resource
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
/**
* @author xuxueli 2019-05-04 16:39:50
*/
@Controller
@RequestMapping
(
"/user"
)
public
class
UserController
{
@Resource
private
XxlJobUserDao
xxlJobUserDao
;
@Resource
private
XxlJobGroupDao
xxlJobGroupDao
;
@RequestMapping
public
String
index
(
Model
model
)
{
// 执行器列表
List
<
XxlJobGroup
>
groupList
=
xxlJobGroupDao
.
findAll
();
model
.
addAttribute
(
"groupList"
,
groupList
);
return
"user/user.index"
;
}
@RequestMapping
(
"/pageList"
)
@ResponseBody
public
Map
<
String
,
Object
>
pageList
(
@RequestParam
(
required
=
false
,
defaultValue
=
"0"
)
int
start
,
@RequestParam
(
required
=
false
,
defaultValue
=
"10"
)
int
length
,
String
username
)
{
// page list
List
<
XxlJobUser
>
list
=
xxlJobUserDao
.
pageList
(
start
,
length
,
username
);
int
list_count
=
xxlJobUserDao
.
pageListCount
(
start
,
length
,
username
);
// package result
Map
<
String
,
Object
>
maps
=
new
HashMap
<
String
,
Object
>();
maps
.
put
(
"recordsTotal"
,
list_count
);
// 总记录数
maps
.
put
(
"recordsFiltered"
,
list_count
);
// 过滤后的总记录数
maps
.
put
(
"data"
,
list
);
// 分页列表
return
maps
;
}
@RequestMapping
(
"/add"
)
@ResponseBody
public
ReturnT
<
String
>
add
(
XxlJobUser
xxlJobUser
)
{
// valid username
if
(!
StringUtils
.
hasText
(
xxlJobUser
.
getUsername
()))
{
return
new
ReturnT
<
String
>(
ReturnT
.
FAIL_CODE
,
I18nUtil
.
getString
(
"system_please_input"
)+
I18nUtil
.
getString
(
"user_username"
)
);
}
xxlJobUser
.
setUsername
(
xxlJobUser
.
getUsername
().
trim
());
if
(!(
xxlJobUser
.
getUsername
().
length
()>=
4
&&
xxlJobUser
.
getUsername
().
length
()<=
20
))
{
return
new
ReturnT
<
String
>(
ReturnT
.
FAIL_CODE
,
I18nUtil
.
getString
(
"system_lengh_limit"
)+
"[4-20]"
);
}
// valid password
if
(!
StringUtils
.
hasText
(
xxlJobUser
.
getPassword
()))
{
return
new
ReturnT
<
String
>(
ReturnT
.
FAIL_CODE
,
I18nUtil
.
getString
(
"system_please_input"
)+
I18nUtil
.
getString
(
"user_password"
)
);
}
xxlJobUser
.
setPassword
(
xxlJobUser
.
getPassword
().
trim
());
if
(!(
xxlJobUser
.
getPassword
().
length
()>=
4
&&
xxlJobUser
.
getPassword
().
length
()<=
20
))
{
return
new
ReturnT
<
String
>(
ReturnT
.
FAIL_CODE
,
I18nUtil
.
getString
(
"system_lengh_limit"
)+
"[4-20]"
);
}
// md5 password
xxlJobUser
.
setPassword
(
DigestUtils
.
md5DigestAsHex
(
xxlJobUser
.
getPassword
().
getBytes
()));
// check repeat
XxlJobUser
existUser
=
xxlJobUserDao
.
loadByUserName
(
xxlJobUser
.
getUsername
());
if
(
existUser
!=
null
)
{
return
new
ReturnT
<
String
>(
ReturnT
.
FAIL_CODE
,
I18nUtil
.
getString
(
"user_username_repeat"
)
);
}
// write
xxlJobUserDao
.
save
(
xxlJobUser
);
return
ReturnT
.
SUCCESS
;
}
@RequestMapping
(
"/update"
)
@ResponseBody
public
ReturnT
<
String
>
update
(
XxlJobUser
xxlJobUser
)
{
// valid password
if
(
StringUtils
.
hasText
(
xxlJobUser
.
getPassword
()))
{
xxlJobUser
.
setPassword
(
xxlJobUser
.
getPassword
().
trim
());
if
(!(
xxlJobUser
.
getPassword
().
length
()>=
4
&&
xxlJobUser
.
getPassword
().
length
()<=
20
))
{
return
new
ReturnT
<
String
>(
ReturnT
.
FAIL_CODE
,
I18nUtil
.
getString
(
"system_lengh_limit"
)+
"[4-20]"
);
}
// md5 password
xxlJobUser
.
setPassword
(
DigestUtils
.
md5DigestAsHex
(
xxlJobUser
.
getPassword
().
getBytes
()));
}
else
{
xxlJobUser
.
setPassword
(
null
);
}
// write
xxlJobUserDao
.
update
(
xxlJobUser
);
return
ReturnT
.
SUCCESS
;
}
@RequestMapping
(
"/remove"
)
@ResponseBody
public
ReturnT
<
String
>
remove
(
int
id
)
{
xxlJobUserDao
.
delete
(
id
);
return
ReturnT
.
SUCCESS
;
}
}
xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobUser.java
0 → 100644
浏览文件 @
b3b9ff80
package
com
.
xxl
.
job
.
admin
.
core
.
model
;
/**
* @author xuxueli 2019-05-04 16:43:12
*/
public
class
XxlJobUser
{
private
int
id
;
private
String
username
;
// 账号
private
String
password
;
// 密码
private
int
role
;
// 角色:0-普通用户、1-管理员
private
String
permission
;
// 权限:执行器ID列表,多个逗号分割
public
int
getId
()
{
return
id
;
}
public
void
setId
(
int
id
)
{
this
.
id
=
id
;
}
public
String
getUsername
()
{
return
username
;
}
public
void
setUsername
(
String
username
)
{
this
.
username
=
username
;
}
public
String
getPassword
()
{
return
password
;
}
public
void
setPassword
(
String
password
)
{
this
.
password
=
password
;
}
public
int
getRole
()
{
return
role
;
}
public
void
setRole
(
int
role
)
{
this
.
role
=
role
;
}
public
String
getPermission
()
{
return
permission
;
}
public
void
setPermission
(
String
permission
)
{
this
.
permission
=
permission
;
}
}
xxl-job-admin/src/main/java/com/xxl/job/admin/dao/XxlJobUserDao.java
0 → 100644
浏览文件 @
b3b9ff80
package
com
.
xxl
.
job
.
admin
.
dao
;
import
com.xxl.job.admin.core.model.XxlJobUser
;
import
org.apache.ibatis.annotations.Mapper
;
import
org.apache.ibatis.annotations.Param
;
import
java.util.List
;
/**
* @author xuxueli 2019-05-04 16:44:59
*/
@Mapper
public
interface
XxlJobUserDao
{
public
List
<
XxlJobUser
>
pageList
(
@Param
(
"offset"
)
int
offset
,
@Param
(
"pagesize"
)
int
pagesize
,
@Param
(
"username"
)
String
username
);
public
int
pageListCount
(
@Param
(
"offset"
)
int
offset
,
@Param
(
"pagesize"
)
int
pagesize
,
@Param
(
"username"
)
String
username
);
public
XxlJobUser
loadByUserName
(
@Param
(
"username"
)
String
username
);
public
int
save
(
XxlJobUser
xxlJobUser
);
public
int
update
(
XxlJobUser
xxlJobUser
);
public
int
delete
(
@Param
(
"id"
)
int
id
);
}
xxl-job-admin/src/main/resources/i18n/message.properties
浏览文件 @
b3b9ff80
...
...
@@ -31,6 +31,7 @@ system_unvalid=非法
system_not_found
=
不存在
system_nav
=
导航
system_digits
=
整数
system_lengh_limit
=
长度限制
## daterangepicker
daterangepicker_ranges_recent_hour
=
最近一小时
...
...
@@ -229,6 +230,19 @@ jobconf_trigger_type_parent=父任务触发
jobconf_trigger_type_api
=
API触发
jobconf_trigger_type_retry
=
失败重试触发
## user
user_manage
=
用户管理
user_username
=
账号
user_password
=
密码
user_role
=
角色
user_role_admin
=
管理员
user_role_normal
=
普通用户
user_permission
=
权限
user_add
=
新增用户
user_update
=
更新用户
user_username_repeat
=
账号重复
user_password_update_placeholder
=
请输入新密码,为空则不更新密码
## help
job_help
=
使用教程
job_help_document
=
官方文档
\ No newline at end of file
xxl-job-admin/src/main/resources/i18n/message_en.properties
浏览文件 @
b3b9ff80
...
...
@@ -31,6 +31,7 @@ system_unvalid=illegal
system_not_found
=
not exist
system_nav
=
Navigation
system_digits
=
digits
system_lengh_limit
=
Length limit
## daterangepicker
daterangepicker_ranges_recent_hour
=
recent one hour
...
...
@@ -229,6 +230,19 @@ jobconf_trigger_type_parent=Parent job trigger
jobconf_trigger_type_api
=
Api trigger
jobconf_trigger_type_retry
=
Fail retry trigger
## user
user_manage
=
=User Manage
user_username
=
Username
user_password
=
Password
user_role
=
Role
user_role_admin
=
Admin User
user_role_normal
=
Normal User
user_permission
=
Permission
user_add
=
Add User
user_update
=
Edit User
user_username_repeat
=
Username Repeat
user_password_update_placeholder
=
Please input password, empty means not update
## help
job_help
=
Tutorial
job_help_document
=
Official Document
\ No newline at end of file
xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobUserMapper.xml
0 → 100644
浏览文件 @
b3b9ff80
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper
namespace=
"com.xxl.job.admin.dao.XxlJobUserDao"
>
<resultMap
id=
"XxlJobUser"
type=
"com.xxl.job.admin.core.model.XxlJobUser"
>
<result
column=
"id"
property=
"id"
/>
<result
column=
"username"
property=
"username"
/>
<result
column=
"password"
property=
"password"
/>
<result
column=
"role"
property=
"role"
/>
<result
column=
"permission"
property=
"permission"
/>
</resultMap>
<sql
id=
"Base_Column_List"
>
t.id,
t.username,
t.password,
t.role,
t.permission
</sql>
<select
id=
"pageList"
parameterType=
"java.util.HashMap"
resultMap=
"XxlJobUser"
>
SELECT
<include
refid=
"Base_Column_List"
/>
FROM XXL_JOB_QRTZ_USER AS t
<trim
prefix=
"WHERE"
prefixOverrides=
"AND | OR"
>
<if
test=
"username != null and username != ''"
>
AND t.username like CONCAT(CONCAT('%', #{username}), '%')
</if>
</trim>
ORDER BY username ASC
LIMIT #{offset}, #{pagesize}
</select>
<select
id=
"pageListCount"
parameterType=
"java.util.HashMap"
resultType=
"int"
>
SELECT count(1)
FROM XXL_JOB_QRTZ_USER AS t
<trim
prefix=
"WHERE"
prefixOverrides=
"AND | OR"
>
<if
test=
"username != null and username != ''"
>
AND t.username like CONCAT(CONCAT('%', #{username}), '%')
</if>
</trim>
</select>
<select
id=
"loadByUserName"
parameterType=
"java.util.HashMap"
resultMap=
"XxlJobUser"
>
SELECT
<include
refid=
"Base_Column_List"
/>
FROM XXL_JOB_QRTZ_USER AS t
WHERE t.username = #{username}
</select>
<insert
id=
"save"
parameterType=
"com.xxl.job.admin.core.model.XxlJobUser"
useGeneratedKeys=
"true"
keyProperty=
"id"
>
INSERT INTO XXL_JOB_QRTZ_USER (
username,
password,
role,
permission
) VALUES (
#{username},
#{password},
#{role},
#{permission}
);
</insert>
<update
id=
"update"
parameterType=
"com.xxl.job.admin.core.model.XxlJobUser"
>
UPDATE XXL_JOB_QRTZ_USER
SET
<if
test=
"password != null and password != ''"
>
password = #{password},
</if>
role = #{role},
permission = #{permission}
WHERE id = #{id}
</update>
<delete
id=
"delete"
parameterType=
"java.util.HashMap"
>
DELETE
FROM XXL_JOB_QRTZ_USER
WHERE id = #{id}
</delete>
</mapper>
\ No newline at end of file
xxl-job-admin/src/main/resources/static/js/user.index.1.js
0 → 100644
浏览文件 @
b3b9ff80
$
(
function
()
{
// init date tables
var
userListTable
=
$
(
"#user_list"
).
dataTable
({
"deferRender"
:
true
,
"processing"
:
true
,
"serverSide"
:
true
,
"ajax"
:
{
url
:
base_url
+
"/user/pageList"
,
type
:
"post"
,
data
:
function
(
d
)
{
var
obj
=
{};
obj
.
username
=
$
(
'#username'
).
val
();
obj
.
start
=
d
.
start
;
obj
.
length
=
d
.
length
;
return
obj
;
}
},
"searching"
:
false
,
"ordering"
:
false
,
//"scrollX": true, // scroll x,close self-adaption
"columns"
:
[
{
"data"
:
'id'
,
"visible"
:
false
,
"width"
:
'10%'
},
{
"data"
:
'username'
,
"visible"
:
true
,
"width"
:
'20%'
},
{
"data"
:
'password'
,
"visible"
:
true
,
"width"
:
'20%'
},
{
"data"
:
'role'
,
"visible"
:
true
,
"width"
:
'10%'
,
"render"
:
function
(
data
,
type
,
row
)
{
if
(
data
==
1
)
{
return
I18n
.
user_role_admin
}
else
{
return
I18n
.
user_role_normal
}
}
},
{
"data"
:
'permission'
,
"width"
:
'10%'
,
"visible"
:
true
},
{
"data"
:
I18n
.
system_opt
,
"width"
:
'15%'
,
"render"
:
function
(
data
,
type
,
row
)
{
return
function
(){
// html
tableData
[
'key'
+
row
.
id
]
=
row
;
var
html
=
'<p id="'
+
row
.
id
+
'" >'
+
'<button class="btn btn-warning btn-xs update" type="button">'
+
I18n
.
system_opt_edit
+
'</button> '
+
'<button class="btn btn-danger btn-xs delete" type="button">'
+
I18n
.
system_opt_del
+
'</button> '
+
'</p>'
;
return
html
;
};
}
}
],
"language"
:
{
"sProcessing"
:
I18n
.
dataTable_sProcessing
,
"sLengthMenu"
:
I18n
.
dataTable_sLengthMenu
,
"sZeroRecords"
:
I18n
.
dataTable_sZeroRecords
,
"sInfo"
:
I18n
.
dataTable_sInfo
,
"sInfoEmpty"
:
I18n
.
dataTable_sInfoEmpty
,
"sInfoFiltered"
:
I18n
.
dataTable_sInfoFiltered
,
"sInfoPostFix"
:
""
,
"sSearch"
:
I18n
.
dataTable_sSearch
,
"sUrl"
:
""
,
"sEmptyTable"
:
I18n
.
dataTable_sEmptyTable
,
"sLoadingRecords"
:
I18n
.
dataTable_sLoadingRecords
,
"sInfoThousands"
:
","
,
"oPaginate"
:
{
"sFirst"
:
I18n
.
dataTable_sFirst
,
"sPrevious"
:
I18n
.
dataTable_sPrevious
,
"sNext"
:
I18n
.
dataTable_sNext
,
"sLast"
:
I18n
.
dataTable_sLast
},
"oAria"
:
{
"sSortAscending"
:
I18n
.
dataTable_sSortAscending
,
"sSortDescending"
:
I18n
.
dataTable_sSortDescending
}
}
});
// table data
var
tableData
=
{};
// search btn
$
(
'#searchBtn'
).
on
(
'click'
,
function
(){
userListTable
.
fnDraw
();
});
// job operate
$
(
"#user_list"
).
on
(
'click'
,
'.delete'
,
function
()
{
var
id
=
$
(
this
).
parent
(
'p'
).
attr
(
"id"
);
layer
.
confirm
(
I18n
.
system_ok
+
I18n
.
system_opt_del
+
'?'
,
{
icon
:
3
,
title
:
I18n
.
system_tips
,
btn
:
[
I18n
.
system_ok
,
I18n
.
system_cancel
]
},
function
(
index
){
layer
.
close
(
index
);
$
.
ajax
({
type
:
'POST'
,
url
:
base_url
+
"/user/remove"
,
data
:
{
"id"
:
id
},
dataType
:
"json"
,
success
:
function
(
data
){
if
(
data
.
code
==
200
)
{
layer
.
msg
(
I18n
.
system_success
);
userListTable
.
fnDraw
(
false
);
}
else
{
layer
.
msg
(
data
.
msg
||
I18n
.
system_opt_del
+
I18n
.
system_fail
);
}
}
});
});
});
// add
$
(
".add"
).
click
(
function
(){
$
(
'#addModal'
).
modal
({
backdrop
:
false
,
keyboard
:
false
}).
modal
(
'show'
);
});
var
addModalValidate
=
$
(
"#addModal .form"
).
validate
({
errorElement
:
'span'
,
errorClass
:
'help-block'
,
focusInvalid
:
true
,
rules
:
{
username
:
{
required
:
true
,
rangelength
:[
4
,
20
]
},
password
:
{
required
:
true
,
rangelength
:[
4
,
20
]
}
},
messages
:
{
username
:
{
required
:
I18n
.
system_please_input
+
I18n
.
user_username
,
rangelength
:
I18n
.
system_lengh_limit
+
"[4-20]"
},
password
:
{
required
:
I18n
.
system_please_input
+
I18n
.
user_password
,
rangelength
:
I18n
.
system_lengh_limit
+
"[4-20]"
}
},
highlight
:
function
(
element
)
{
$
(
element
).
closest
(
'.form-group'
).
addClass
(
'has-error'
);
},
success
:
function
(
label
)
{
label
.
closest
(
'.form-group'
).
removeClass
(
'has-error'
);
label
.
remove
();
},
errorPlacement
:
function
(
error
,
element
)
{
element
.
parent
(
'div'
).
append
(
error
);
},
submitHandler
:
function
(
form
)
{
var
permissionArr
=
[];
$
(
"#addModal .form input[name=permission]:checked"
).
each
(
function
(){
permissionArr
.
push
(
$
(
this
).
val
());
});
var
paramData
=
{
"username"
:
$
(
"#addModal .form input[name=username]"
).
val
(),
"password"
:
$
(
"#addModal .form input[name=password]"
).
val
(),
"role"
:
$
(
"#addModal .form input[name=role]:checked"
).
val
(),
"permission"
:
permissionArr
.
join
(
','
)
};
$
.
post
(
base_url
+
"/user/add"
,
paramData
,
function
(
data
,
status
)
{
if
(
data
.
code
==
"200"
)
{
$
(
'#addModal'
).
modal
(
'hide'
);
layer
.
msg
(
I18n
.
system_add_suc
);
userListTable
.
fnDraw
();
}
else
{
layer
.
open
({
title
:
I18n
.
system_tips
,
btn
:
[
I18n
.
system_ok
],
content
:
(
data
.
msg
||
I18n
.
system_add_fail
),
icon
:
'2'
});
}
});
}
});
$
(
"#addModal"
).
on
(
'hide.bs.modal'
,
function
()
{
$
(
"#addModal .form"
)[
0
].
reset
();
addModalValidate
.
resetForm
();
$
(
"#addModal .form .form-group"
).
removeClass
(
"has-error"
);
$
(
".remote_panel"
).
show
();
// remote
});
// update
$
(
"#user_list"
).
on
(
'click'
,
'.update'
,
function
()
{
var
id
=
$
(
this
).
parent
(
'p'
).
attr
(
"id"
);
var
row
=
tableData
[
'key'
+
id
];
// base data
$
(
"#updateModal .form input[name='id']"
).
val
(
row
.
id
);
$
(
"#updateModal .form input[name='username']"
).
val
(
row
.
username
);
$
(
"#updateModal .form input[name='password']"
).
val
(
''
);
$
(
"#updateModal .form input[name='role']"
).
each
(
function
()
{
if
(
$
(
this
).
val
()
==
row
.
role
)
{
$
(
this
).
prop
(
"checked"
,
true
);
}
else
{
$
(
this
).
prop
(
"checked"
,
false
);
}
});
var
permissionArr
=
[];
if
(
row
.
permission
)
{
permissionArr
=
row
.
permission
.
split
(
","
);
}
$
(
"#updateModal .form input[name='permission']"
).
removeProp
(
'checked'
);
$
(
"#updateModal .form input[name='permission']"
).
each
(
function
()
{
if
(
$
.
inArray
(
$
(
this
).
val
(),
permissionArr
)
>
-
1
)
{
$
(
this
).
prop
(
"checked"
,
true
);
}
else
{
$
(
this
).
prop
(
"checked"
,
false
);
}
});
// show
$
(
'#updateModal'
).
modal
({
backdrop
:
false
,
keyboard
:
false
}).
modal
(
'show'
);
});
var
updateModalValidate
=
$
(
"#updateModal .form"
).
validate
({
errorElement
:
'span'
,
errorClass
:
'help-block'
,
focusInvalid
:
true
,
highlight
:
function
(
element
)
{
$
(
element
).
closest
(
'.form-group'
).
addClass
(
'has-error'
);
},
success
:
function
(
label
)
{
label
.
closest
(
'.form-group'
).
removeClass
(
'has-error'
);
label
.
remove
();
},
errorPlacement
:
function
(
error
,
element
)
{
element
.
parent
(
'div'
).
append
(
error
);
},
submitHandler
:
function
(
form
)
{
var
permissionArr
=
[];
$
(
"#updateModal .form input[name=permission]:checked"
).
each
(
function
(){
permissionArr
.
push
(
$
(
this
).
val
());
});
var
paramData
=
{
"id"
:
$
(
"#updateModal .form input[name=id]"
).
val
(),
"username"
:
$
(
"#updateModal .form input[name=username]"
).
val
(),
"password"
:
$
(
"#updateModal .form input[name=password]"
).
val
(),
"role"
:
$
(
"#updateModal .form input[name=role]:checked"
).
val
(),
"permission"
:
permissionArr
.
join
(
','
)
};
$
.
post
(
base_url
+
"/user/update"
,
paramData
,
function
(
data
,
status
)
{
if
(
data
.
code
==
"200"
)
{
$
(
'#updateModal'
).
modal
(
'hide'
);
layer
.
msg
(
I18n
.
system_update_suc
);
userListTable
.
fnDraw
();
}
else
{
layer
.
open
({
title
:
I18n
.
system_tips
,
btn
:
[
I18n
.
system_ok
],
content
:
(
data
.
msg
||
I18n
.
system_update_fail
),
icon
:
'2'
});
}
});
}
});
$
(
"#updateModal"
).
on
(
'hide.bs.modal'
,
function
()
{
$
(
"#updateModal .form"
)[
0
].
reset
();
updateModalValidate
.
resetForm
();
$
(
"#updateModal .form .form-group"
).
removeClass
(
"has-error"
);
$
(
".remote_panel"
).
show
();
// remote
});
});
xxl-job-admin/src/main/resources/templates/common/common.macro.ftl
浏览文件 @
b3b9ff80
...
...
@@ -103,6 +103,7 @@
<li class="nav-click <#if pageName == "jobinfo">active</#if>" ><a href="${request.contextPath}/jobinfo"><i class="fa fa-circle-o text-yellow"></i><span>${I18n.jobinfo_name}</span></a></li>
<li class="nav-click <#if pageName == "joblog">active</#if>" ><a href="${request.contextPath}/joblog"><i class="fa fa-circle-o text-green"></i><span>${I18n.joblog_name}</span></a></li>
<li class="nav-click <#if pageName == "jobgroup">active</#if>" ><a href="${request.contextPath}/jobgroup"><i class="fa fa-circle-o text-red"></i><span>${I18n.jobgroup_name}</span></a></li>
<li class="nav-click <#if pageName == "user">active</#if>" ><a href="${request.contextPath}/user"><i class="fa fa-circle-o text-purple"></i><span>${I18n.user_manage}</span></a></li>
<li class="nav-click <#if pageName == "help">active</#if>" ><a href="${request.contextPath}/help"><i class="fa fa-circle-o text-gray"></i><span>${I18n.job_help}</span></a></li>
</ul>
</section>
...
...
xxl-job-admin/src/main/resources/templates/user/user.index.ftl
0 → 100644
浏览文件 @
b3b9ff80
<!DOCTYPE html>
<html>
<head>
<
#
import
"../
common
/
common
.
macro
.
ftl
"
as
netCommon
>
<
@
netCommon
.
commonStyle
/>
<!-- DataTables -->
<link
rel=
"stylesheet"
href=
"${request.contextPath}/static/adminlte/bower_components/datatables.net-bs/css/dataTables.bootstrap.min.css"
>
<title>
${I18n.admin_name}
</title>
</head>
<body
class=
"hold-transition skin-blue sidebar-mini <#if cookieMap?exists && cookieMap["
xxljob_adminlte_settings
"]?
exists
&&
"
off
"
==
cookieMap
["
xxljob_adminlte_settings
"].
value
>
sidebar-collapse
</
#
if>
">
<div
class=
"wrapper"
>
<!-- header -->
<
@
netCommon
.
commonHeader
/>
<!-- left -->
<
@
netCommon
.
commonLeft
"
user
"
/>
<!-- Content Wrapper. Contains page content -->
<div
class=
"content-wrapper"
>
<!-- Content Header (Page header) -->
<section
class=
"content-header"
>
<h1>
${I18n.user_manage}
</h1>
</section>
<!-- Main content -->
<section
class=
"content"
>
<div
class=
"row"
>
<div
class=
"col-xs-3"
>
<div
class=
"input-group"
>
<span
class=
"input-group-addon"
>
${I18n.user_username}
</span>
<input
type=
"text"
class=
"form-control"
id=
"username"
autocomplete=
"on"
>
</div>
</div>
<div
class=
"col-xs-1"
>
<button
class=
"btn btn-block btn-info"
id=
"searchBtn"
>
${I18n.system_search}
</button>
</div>
<div
class=
"col-xs-2"
>
<button
class=
"btn btn-block btn-success add"
type=
"button"
>
${I18n.user_add}
</button>
</div>
</div>
<div
class=
"row"
>
<div
class=
"col-xs-12"
>
<div
class=
"box"
>
<div
class=
"box-body"
>
<table
id=
"user_list"
class=
"table table-bordered table-striped"
width=
"100%"
>
<thead>
<tr>
<th
name=
"id"
>
ID
</th>
<th
name=
"username"
>
${I18n.user_username}
</th>
<th
name=
"password"
>
${I18n.user_password}
</th>
<th
name=
"role"
>
${I18n.user_role}
</th>
<th
name=
"permission"
>
${I18n.user_permission}
</th>
<th>
${I18n.system_opt}
</th>
</tr>
</thead>
<tbody></tbody>
<tfoot></tfoot>
</table>
</div>
</div>
</div>
</div>
</section>
</div>
<!-- footer -->
<
@
netCommon
.
commonFooter
/>
</div>
<!-- 新增.模态框 -->
<div
class=
"modal fade"
id=
"addModal"
tabindex=
"-1"
role=
"dialog"
aria-hidden=
"true"
>
<div
class=
"modal-dialog"
>
<div
class=
"modal-content"
>
<div
class=
"modal-header"
>
<h4
class=
"modal-title"
>
${I18n.user_add}
</h4>
</div>
<div
class=
"modal-body"
>
<form
class=
"form-horizontal form"
role=
"form"
>
<div
class=
"form-group"
>
<label
for=
"lastname"
class=
"col-sm-2 control-label"
>
${I18n.user_username}
<font
color=
"red"
>
*
</font></label>
<div
class=
"col-sm-8"
><input
type=
"text"
class=
"form-control"
name=
"username"
placeholder=
"${I18n.system_please_input}${I18n.user_username}"
maxlength=
"50"
></div>
</div>
<div
class=
"form-group"
>
<label
for=
"lastname"
class=
"col-sm-2 control-label"
>
${I18n.user_password}
<font
color=
"red"
>
*
</font></label>
<div
class=
"col-sm-8"
><input
type=
"text"
class=
"form-control"
name=
"password"
placeholder=
"${I18n.system_please_input}${I18n.user_password}"
maxlength=
"50"
></div>
</div>
<div
class=
"form-group"
>
<label
for=
"lastname"
class=
"col-sm-2 control-label"
>
${I18n.user_role}
<font
color=
"red"
>
*
</font></label>
<div
class=
"col-sm-10"
>
<input
type=
"radio"
name=
"role"
value=
"0"
checked
/>
${I18n.user_role_normal}
<input
type=
"radio"
name=
"role"
value=
"1"
/>
${I18n.user_role_admin}
</div>
</div>
<div
class=
"form-group"
>
<label
for=
"lastname"
class=
"col-sm-2 control-label"
>
${I18n.user_permission}
<font
color=
"black"
>
*
</font></label>
<div
class=
"col-sm-10"
>
<
#
if
groupList
?
exists
&&
groupList
?
size
gt
0
>
<
#
list
groupList
as
item
>
<input
type=
"checkbox"
name=
"permission"
value=
"${item.id}"
/>
${item.title}(${item.appName})
<br>
</
#
list>
</
#
if>
</div>
</div>
<hr>
<div
class=
"form-group"
>
<div
class=
"col-sm-offset-3 col-sm-6"
>
<button
type=
"submit"
class=
"btn btn-primary"
>
${I18n.system_save}
</button>
<button
type=
"button"
class=
"btn btn-default"
data-dismiss=
"modal"
>
${I18n.system_cancel}
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
<!-- 更新.模态框 -->
<div
class=
"modal fade"
id=
"updateModal"
tabindex=
"-1"
role=
"dialog"
aria-hidden=
"true"
>
<div
class=
"modal-dialog"
>
<div
class=
"modal-content"
>
<div
class=
"modal-header"
>
<h4
class=
"modal-title"
>
${I18n.user_update}
</h4>
</div>
<div
class=
"modal-body"
>
<form
class=
"form-horizontal form"
role=
"form"
>
<div
class=
"form-group"
>
<label
for=
"lastname"
class=
"col-sm-2 control-label"
>
${I18n.user_username}
<font
color=
"red"
>
*
</font></label>
<div
class=
"col-sm-8"
><input
type=
"text"
class=
"form-control"
name=
"username"
placeholder=
"${I18n.system_please_input}${I18n.user_username}"
maxlength=
"50"
readonly
></div>
</div>
<div
class=
"form-group"
>
<label
for=
"lastname"
class=
"col-sm-2 control-label"
>
${I18n.user_password}
<font
color=
"red"
>
*
</font></label>
<div
class=
"col-sm-8"
><input
type=
"text"
class=
"form-control"
name=
"password"
placeholder=
"${I18n.user_password_update_placeholder}"
maxlength=
"50"
></div>
</div>
<div
class=
"form-group"
>
<label
for=
"lastname"
class=
"col-sm-2 control-label"
>
${I18n.user_role}
<font
color=
"red"
>
*
</font></label>
<div
class=
"col-sm-10"
>
<input
type=
"radio"
name=
"role"
value=
"0"
/>
${I18n.user_role_normal}
<input
type=
"radio"
name=
"role"
value=
"1"
/>
${I18n.user_role_admin}
</div>
</div>
<div
class=
"form-group"
>
<label
for=
"lastname"
class=
"col-sm-2 control-label"
>
${I18n.user_permission}
<font
color=
"black"
>
*
</font></label>
<div
class=
"col-sm-10"
>
<
#
if
groupList
?
exists
&&
groupList
?
size
gt
0
>
<
#
list
groupList
as
item
>
<input
type=
"checkbox"
name=
"permission"
value=
"${item.id}"
/>
${item.title}(${item.appName})
<br>
</
#
list>
</
#
if>
</div>
</div>
<hr>
<div
class=
"form-group"
>
<div
class=
"col-sm-offset-3 col-sm-6"
>
<button
type=
"submit"
class=
"btn btn-primary"
>
${I18n.system_save}
</button>
<button
type=
"button"
class=
"btn btn-default"
data-dismiss=
"modal"
>
${I18n.system_cancel}
</button>
<input
type=
"hidden"
name=
"id"
>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
<
@
netCommon
.
commonScript
/>
<!-- DataTables -->
<script
src=
"${request.contextPath}/static/adminlte/bower_components/datatables.net/js/jquery.dataTables.min.js"
></script>
<script
src=
"${request.contextPath}/static/adminlte/bower_components/datatables.net-bs/js/dataTables.bootstrap.min.js"
></script>
<script
src=
"${request.contextPath}/static/plugins/jquery/jquery.validate.min.js"
></script>
<script
src=
"${request.contextPath}/static/js/user.index.1.js"
></script>
</body>
</html>
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论