Pre Merge pull request !9 from 黄新宇/master
commit
e0d49eaed6
@ -0,0 +1,93 @@
|
||||
package com.xxl.job.admin.controller;
|
||||
|
||||
import com.xxl.job.admin.controller.annotation.PermessionLimit;
|
||||
import com.xxl.job.admin.core.model.XxlJobUser;
|
||||
import com.xxl.job.admin.core.util.I18nUtil;
|
||||
import com.xxl.job.admin.dao.XxlJobUserDao;
|
||||
import com.xxl.job.core.biz.model.ReturnT;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.util.DigestUtils;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* job group controller
|
||||
* @author xuxueli 2016-10-02 20:52:56
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/jobuser")
|
||||
public class JobUserController {
|
||||
|
||||
@Resource
|
||||
public XxlJobUserDao xxlJobUserDao;
|
||||
|
||||
@RequestMapping
|
||||
public String index(Model model) {
|
||||
List<XxlJobUser> list = xxlJobUserDao.findAll();
|
||||
model.addAttribute("list", list);
|
||||
return "jobuser/jobuser.index";
|
||||
}
|
||||
|
||||
@RequestMapping("/save")
|
||||
@ResponseBody
|
||||
@PermessionLimit(write=true)
|
||||
public ReturnT<String> save(XxlJobUser xxlJobUser){
|
||||
|
||||
// valid
|
||||
if (xxlJobUser.getUserName()==null || StringUtils.isBlank(xxlJobUser.getUserName())) {
|
||||
return new ReturnT<String>(500, (I18nUtil.getString("system_please_input")+"userName") );
|
||||
}
|
||||
if (xxlJobUser.getUserName().length()<5 || xxlJobUser.getUserName().length()>16) {
|
||||
return new ReturnT<String>(500, I18nUtil.getString("user_name_error") );
|
||||
}
|
||||
if (xxlJobUser.getPassword().length()<5 || xxlJobUser.getPassword().length()>32) {
|
||||
return new ReturnT<String>(500, I18nUtil.getString("user_password_error") );
|
||||
}
|
||||
|
||||
String password = DigestUtils.md5DigestAsHex(String.valueOf(xxlJobUser.getPassword()).getBytes());
|
||||
xxlJobUser.setPassword(password);
|
||||
xxlJobUser.setLastLoginTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
|
||||
int ret = xxlJobUserDao.save(xxlJobUser);
|
||||
return (ret>0)?ReturnT.SUCCESS:ReturnT.FAIL;
|
||||
}
|
||||
|
||||
@RequestMapping("/update")
|
||||
@ResponseBody
|
||||
@PermessionLimit(write=true)
|
||||
public ReturnT<String> update(XxlJobUser xxlJobUser){
|
||||
// valid
|
||||
if (xxlJobUser.getUserName()==null || StringUtils.isBlank(xxlJobUser.getUserName())) {
|
||||
return new ReturnT<String>(500, (I18nUtil.getString("system_please_input")+"userName") );
|
||||
}
|
||||
if (xxlJobUser.getUserName().length()<5 || xxlJobUser.getUserName().length()>16) {
|
||||
return new ReturnT<String>(500, I18nUtil.getString("user_name_error") );
|
||||
}
|
||||
if (xxlJobUser.getPassword()!=null && StringUtils.isNotBlank(xxlJobUser.getPassword())) {
|
||||
if (xxlJobUser.getPassword().length()<5 || xxlJobUser.getPassword().length()>32) {
|
||||
return new ReturnT<String>(500, I18nUtil.getString("user_password_error") );
|
||||
}
|
||||
String password = DigestUtils.md5DigestAsHex(String.valueOf(xxlJobUser.getPassword()).getBytes());
|
||||
xxlJobUser.setPassword(password);
|
||||
}
|
||||
xxlJobUserDao.update(xxlJobUser);
|
||||
return ReturnT.SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@RequestMapping("/remove")
|
||||
@ResponseBody
|
||||
@PermessionLimit(write=true)
|
||||
public ReturnT<String> remove(String username){
|
||||
int ret = xxlJobUserDao.remove(username);
|
||||
return (ret>0)?ReturnT.SUCCESS:ReturnT.FAIL;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,107 @@
|
||||
package com.xxl.job.admin.controller.interceptor;
|
||||
|
||||
import com.xxl.job.admin.controller.annotation.PermessionLimit;
|
||||
import com.xxl.job.admin.core.conf.XxlJobAdminConfig;
|
||||
import com.xxl.job.admin.core.model.XxlJobUser;
|
||||
import com.xxl.job.admin.core.util.AESUtil;
|
||||
import com.xxl.job.admin.core.util.CookieUtil;
|
||||
import com.xxl.job.admin.core.util.SpringApplicationContextHolder;
|
||||
import com.xxl.job.admin.dao.XxlJobUserDao;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.DigestUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 权限拦截, 升级简易版
|
||||
*
|
||||
* @author hxy 2019-03-09 15:06:24
|
||||
*/
|
||||
@Component
|
||||
public class MorePermissionInterceptor extends PermissionInterceptor {
|
||||
|
||||
private static String startStr = "dpMwh2AsPgh";
|
||||
|
||||
public static String getAesKey() {
|
||||
String str = SpringApplicationContextHolder.getSpringBeanForClass(XxlJobAdminConfig.class).getAesKey();
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
public static String getLoginIdentityToken( String username, int authority) {
|
||||
String token = null;
|
||||
try {
|
||||
token = AESUtil.encrypt(startStr+username+"_"+authority,getAesKey());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
public static boolean login(HttpServletResponse response, String username, String password, boolean ifRemember){
|
||||
XxlJobUserDao xxlJobUserDao = ((XxlJobUserDao) SpringApplicationContextHolder.getSpringBean("xxlJobUserDao"));
|
||||
XxlJobUser xxlJobUser = xxlJobUserDao.findByUserName(username);
|
||||
if(xxlJobUser==null||!xxlJobUser.getPassword().equals(DigestUtils.md5DigestAsHex(String.valueOf(password).getBytes()))){
|
||||
return false;
|
||||
}
|
||||
|
||||
// do login
|
||||
CookieUtil.set(response, LOGIN_IDENTITY_KEY, getLoginIdentityToken(xxlJobUser.getUserName(),xxlJobUser.isAuthority()?1:0), ifRemember);
|
||||
xxlJobUserDao.update(xxlJobUser.setPassword(null)
|
||||
.setLastLoginTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())));
|
||||
return true;
|
||||
}
|
||||
|
||||
public static int ifAuthority(HttpServletRequest request){
|
||||
String indentityInfo = CookieUtil.getValue(request, LOGIN_IDENTITY_KEY);
|
||||
if(StringUtils.isEmpty(indentityInfo)) return -1;
|
||||
String str = null;
|
||||
try {
|
||||
str = AESUtil.decrypt(indentityInfo,getAesKey());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (indentityInfo==null || !str.startsWith(startStr)) {
|
||||
return -1;
|
||||
}
|
||||
return Integer.parseInt(str.split("_")[1]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||
|
||||
if (!(handler instanceof HandlerMethod)) {
|
||||
return super.preHandle(request, response, handler);
|
||||
}
|
||||
|
||||
int authority = ifAuthority(request);
|
||||
|
||||
HandlerMethod method = (HandlerMethod)handler;
|
||||
PermessionLimit permission = method.getMethodAnnotation(PermessionLimit.class);
|
||||
//未登陆
|
||||
if (authority==-1) {
|
||||
if (permission == null || permission.limit()) {
|
||||
response.sendRedirect(request.getContextPath() + "/toLogin");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//没有写权限
|
||||
if(permission != null&&authority==0&&permission.write()){
|
||||
response.sendRedirect(request.getContextPath() + "/toLogin");
|
||||
return false;
|
||||
}
|
||||
|
||||
request.setAttribute("authority",authority);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
package com.xxl.job.admin.core.model;
|
||||
|
||||
public class XxlJobUser {
|
||||
|
||||
private String userName;
|
||||
private String password;
|
||||
private boolean authority;
|
||||
private String lastLoginTime;
|
||||
|
||||
public XxlJobUser() {
|
||||
}
|
||||
|
||||
public XxlJobUser(String userName, String password, boolean authority, String lastLoginTime) {
|
||||
this.userName = userName;
|
||||
this.password = password;
|
||||
this.authority = authority;
|
||||
this.lastLoginTime = lastLoginTime;
|
||||
}
|
||||
|
||||
public String getUserName() {
|
||||
return userName;
|
||||
}
|
||||
|
||||
public XxlJobUser setUserName(String userName) {
|
||||
this.userName = userName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public XxlJobUser setPassword(String password) {
|
||||
this.password = password;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isAuthority() {
|
||||
return authority;
|
||||
}
|
||||
|
||||
public XxlJobUser setAuthority(boolean authority) {
|
||||
this.authority = authority;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getLastLoginTime() {
|
||||
return lastLoginTime;
|
||||
}
|
||||
|
||||
public XxlJobUser setLastLoginTime(String lastLoginTime) {
|
||||
this.lastLoginTime = lastLoginTime;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "XxlJobUser{" +
|
||||
"userName='" + userName + '\'' +
|
||||
", password='" + password + '\'' +
|
||||
", authority=" + authority +
|
||||
", lastLoginTime='" + lastLoginTime + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -0,0 +1,94 @@
|
||||
package com.xxl.job.admin.core.util;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
/**
|
||||
* @Author 黄新宇
|
||||
* @Date 2018/5/8 下午1:50
|
||||
* @Description TODO
|
||||
**/
|
||||
public class AESUtil {
|
||||
|
||||
private static final String KEY_AES = "AES";
|
||||
|
||||
private static final String DEFULT_KEY = "NAFOS_KEY_DEFULT";
|
||||
|
||||
public static String encrypt(String src, String key) throws Exception {
|
||||
if (key == null || key.length() != 16) {
|
||||
throw new Exception("key不满足条件"+key);
|
||||
}
|
||||
byte[] raw = key.getBytes();
|
||||
SecretKeySpec skeySpec = new SecretKeySpec(raw, KEY_AES);
|
||||
Cipher cipher = Cipher.getInstance(KEY_AES);
|
||||
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
|
||||
byte[] encrypted = cipher.doFinal(src.getBytes());
|
||||
return byte2hex(encrypted);
|
||||
}
|
||||
|
||||
public static String decrypt(String src, String key) throws Exception {
|
||||
if (key == null || key.length() != 16) {
|
||||
throw new Exception("key不满足条件"+key);
|
||||
}
|
||||
byte[] raw = key.getBytes();
|
||||
SecretKeySpec skeySpec = new SecretKeySpec(raw, KEY_AES);
|
||||
Cipher cipher = Cipher.getInstance(KEY_AES);
|
||||
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
|
||||
byte[] encrypted1 = hex2byte(src);
|
||||
byte[] original = cipher.doFinal(encrypted1);
|
||||
String originalString = new String(original);
|
||||
return originalString;
|
||||
}
|
||||
|
||||
public static String encrypt(String src) throws Exception {
|
||||
byte[] raw = DEFULT_KEY.getBytes();
|
||||
SecretKeySpec skeySpec = new SecretKeySpec(raw, KEY_AES);
|
||||
Cipher cipher = Cipher.getInstance(KEY_AES);
|
||||
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
|
||||
byte[] encrypted = cipher.doFinal(src.getBytes());
|
||||
return byte2hex(encrypted);
|
||||
}
|
||||
|
||||
public static String decrypt(String src) throws Exception {
|
||||
byte[] raw = DEFULT_KEY.getBytes();
|
||||
SecretKeySpec skeySpec = new SecretKeySpec(raw, KEY_AES);
|
||||
Cipher cipher = Cipher.getInstance(KEY_AES);
|
||||
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
|
||||
byte[] encrypted1 = hex2byte(src);
|
||||
byte[] original = cipher.doFinal(encrypted1);
|
||||
String originalString = new String(original);
|
||||
return originalString;
|
||||
}
|
||||
|
||||
public static byte[] hex2byte(String strhex) {
|
||||
if (strhex == null) {
|
||||
return null;
|
||||
}
|
||||
int l = strhex.length();
|
||||
if (l % 2 == 1) {
|
||||
return null;
|
||||
}
|
||||
byte[] b = new byte[l / 2];
|
||||
for (int i = 0; i != l / 2; i++) {
|
||||
b[i] = (byte) Integer.parseInt(strhex.substring(i * 2, i * 2 + 2),
|
||||
16);
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
public static String byte2hex(byte[] b) {
|
||||
String hs = "";
|
||||
String stmp = "";
|
||||
for (int n = 0; n < b.length; n++) {
|
||||
stmp = (Integer.toHexString(b[n] & 0XFF));
|
||||
if (stmp.length() == 1) {
|
||||
hs = hs + "0" + stmp;
|
||||
} else {
|
||||
hs = hs + stmp;
|
||||
}
|
||||
}
|
||||
return hs.toUpperCase();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,25 @@
|
||||
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;
|
||||
|
||||
/**
|
||||
* Created by xuxueli on 16/9/30.
|
||||
*/
|
||||
@Mapper
|
||||
public interface XxlJobUserDao {
|
||||
|
||||
public List<XxlJobUser> findAll();
|
||||
|
||||
public XxlJobUser findByUserName(@Param("userName") String userName);
|
||||
|
||||
public int save(XxlJobUser xxlJobGroup);
|
||||
|
||||
public int update(XxlJobUser xxlJobGroup);
|
||||
|
||||
public int remove(@Param("userName") String userName);
|
||||
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
<?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="user_name" property="userName" />
|
||||
<result column="password" property="password" />
|
||||
<result column="authority" property="authority" />
|
||||
<result column="last_login_time" property="lastLoginTime" />
|
||||
</resultMap>
|
||||
|
||||
<sql id="Base_Column_List">
|
||||
t.user_name,
|
||||
t.password,
|
||||
t.authority,
|
||||
t.last_login_time
|
||||
</sql>
|
||||
|
||||
<select id="findAll" resultMap="XxlJobUser">
|
||||
SELECT t.user_name,
|
||||
t.authority,
|
||||
t.last_login_time
|
||||
FROM XXL_JOB_QRTZ_TRIGGER_USER AS t
|
||||
ORDER BY t.last_login_time desc
|
||||
</select>
|
||||
|
||||
<select id="findByUserName" parameterType="java.lang.String" resultMap="XxlJobUser">
|
||||
SELECT <include refid="Base_Column_List" />
|
||||
FROM XXL_JOB_QRTZ_TRIGGER_USER AS t
|
||||
WHERE t.user_name = #{userName}
|
||||
</select>
|
||||
|
||||
<insert id="save" parameterType="com.xxl.job.admin.core.model.XxlJobUser" >
|
||||
INSERT INTO XXL_JOB_QRTZ_TRIGGER_USER ( `user_name`, `password`, `authority`, `last_login_time`)
|
||||
values ( #{userName}, #{password}, #{authority}, #{lastLoginTime});
|
||||
</insert>
|
||||
|
||||
<update id="update" parameterType="com.xxl.job.admin.core.model.XxlJobUser" >
|
||||
UPDATE XXL_JOB_QRTZ_TRIGGER_USER
|
||||
SET
|
||||
<if test="password != null" >
|
||||
`password` = #{password},
|
||||
</if>
|
||||
<if test="lastLoginTime != null" >
|
||||
`last_login_time` = #{lastLoginTime},
|
||||
</if>
|
||||
`authority` = #{authority}
|
||||
WHERE user_name = #{userName}
|
||||
</update>
|
||||
|
||||
<delete id="remove" parameterType="java.lang.String" >
|
||||
DELETE FROM XXL_JOB_QRTZ_TRIGGER_USER
|
||||
WHERE user_name = #{userName}
|
||||
</delete>
|
||||
|
||||
|
||||
|
||||
</mapper>
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,161 @@
|
||||
<!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.user_manager}</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 "jobuser" />
|
||||
|
||||
<!-- Content Wrapper. Contains page content -->
|
||||
<div class="content-wrapper">
|
||||
<!-- Content Header (Page header) -->
|
||||
<section class="content-header">
|
||||
<h1>${I18n.user_manager}</h1>
|
||||
</section>
|
||||
|
||||
<!-- Main content -->
|
||||
<section class="content">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<div class="box">
|
||||
<div class="box-header">
|
||||
<h3 class="box-title">${I18n.user_list}</h3>
|
||||
<button class="btn btn-info btn-xs pull-left2 add" >${I18n.user_add}</button>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<table id="joblog_list" class="table table-bordered table-striped display" width="100%" >
|
||||
<thead>
|
||||
<tr>
|
||||
<th name="order" >${I18n.user_login_username}</th>
|
||||
<th name="title" >${I18n.user_authority}</th>
|
||||
<th name="addressType" >${I18n.user_last_login_time}</th>
|
||||
<th name="operate" >${I18n.system_opt}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<#if list?exists && list?size gt 0>
|
||||
<#list list as user>
|
||||
<tr>
|
||||
<td>${user.userName}</td>
|
||||
<td><#if user.authority>${I18n.user_authority_1}<#else>${I18n.user_authority_0}</#if></td>
|
||||
<td>${user.lastLoginTime}</td>
|
||||
|
||||
<td>
|
||||
<button class="btn btn-warning btn-xs update"
|
||||
userName="${user.userName}"
|
||||
authority="${user.authority?string("1","0")}"
|
||||
password=" "
|
||||
>${I18n.system_opt_edit}</button>
|
||||
<button class="btn btn-danger btn-xs remove" username="${user.userName}" >${I18n.system_opt_del}</button>
|
||||
</td>
|
||||
</tr>
|
||||
</#list>
|
||||
</#if>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</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_login_username}<font color="red">*</font></label>
|
||||
<div class="col-sm-10"><input type="text" class="form-control" name="userName" placeholder="${I18n.system_please_input}${I18n.user_login_username}" maxlength="64" ></div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="lastname" class="col-sm-2 control-label">${I18n.user_login_password}<font color="red">*</font></label>
|
||||
<div class="col-sm-10"><input type="text" class="form-control" name="password" placeholder="${I18n.system_please_input}${I18n.user_login_password}" maxlength="12" ></div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="lastname" class="col-sm-2 control-label">${I18n.user_authority}<font color="red">*</font></label>
|
||||
<div class="col-sm-10">
|
||||
<input type="radio" name="authority" value="0" checked />${I18n.user_authority_0}
|
||||
|
||||
<input type="radio" name="authority" value="1" />${I18n.user_authority_1}
|
||||
</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_login_username}<font color="red">*</font></label>
|
||||
<div class="col-sm-10"><input type="text" class="form-control" name="userName" placeholder="${I18n.system_please_input}${I18n.user_login_username}" maxlength="64" ></div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="lastname" class="col-sm-2 control-label">${I18n.user_login_password}<font color="red">*</font></label>
|
||||
<div class="col-sm-10"><input type="text" class="form-control" name="password" placeholder="${I18n.system_please_input}${I18n.user_login_password}" maxlength="12" ></div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="lastname" class="col-sm-2 control-label">${I18n.user_authority}<font color="red">*</font></label>
|
||||
<div class="col-sm-10">
|
||||
<input type="radio" name="authority" value="0" checked />${I18n.user_authority_0}
|
||||
|
||||
<input type="radio" name="authority" value="1" />${I18n.user_authority_1}
|
||||
</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>
|
||||
|
||||
<!-- footer -->
|
||||
<@netCommon.commonFooter />
|
||||
</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>
|
||||
<#-- jquery.validate -->
|
||||
<script src="${request.contextPath}/static/plugins/jquery/jquery.validate.min.js"></script>
|
||||
<script src="${request.contextPath}/static/js/jobuser.index.1.js"></script>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in new issue