Jianghan 3 سال پیش
والد
کامیت
ca1808b2ea

+ 69 - 0
src/front/front.go

@@ -1,21 +1,49 @@
 package front
 
 import (
+	"fmt"
+	"mongodb"
 	qu "qfw/util"
+	"strconv"
 
 	"github.com/go-xweb/xweb"
+	. "util"
 )
 
+var UserMenu map[string][]map[string]interface{} //存储菜单
+
+func init() {
+	UserMenu = make(map[string][]map[string]interface{})
+}
+
 type Front struct {
 	*xweb.Action
 	index xweb.Mapper `xweb:"/front/index"` //index页面
 	//user
 	login     xweb.Mapper `xweb:"/"`                //登录页面
+	code      xweb.Mapper `xweb:"/code"`            //获取图片验证码
 	logout    xweb.Mapper `xweb:"/front/logout"`    //注销
 	updatePwd xweb.Mapper `xweb:"/front/updatepwd"` //更新密码
 	user      xweb.Mapper `xweb:"/front/user"`      //查所有用户
 	userDel   xweb.Mapper `xweb:"/front/user/del"`  //删除用户
 	userSave  xweb.Mapper `xweb:"/front/user/save"` //保存用户
+	//menu
+	menu           xweb.Mapper `xweb:"/front/menu"`            //查一级菜单
+	menuSave       xweb.Mapper `xweb:"/front/menu/save"`       //保存一级菜单
+	menuDel        xweb.Mapper `xweb:"/front/menu/del"`        //删除一级菜单
+	menuSecond     xweb.Mapper `xweb:"/front/menuSecond"`      //查二级菜单
+	menuSecondSave xweb.Mapper `xweb:"/front/menuSecond/save"` //保存二级菜单
+	menuSecondDel  xweb.Mapper `xweb:"/front/menuSecond/del"`  //删除二级菜单
+	personalMenu   xweb.Mapper `xweb:"/front/personalMenu"`
+	//role
+	roleManager    xweb.Mapper `xweb:"/front/role"`             //角色权限管理
+	roleNew        xweb.Mapper `xweb:"/front/role/save"`        //新增角色
+	roleEdit       xweb.Mapper `xweb:"/front/role/edit/(.*)"`   //角色权限查看
+	roleFirst      xweb.Mapper `xweb:"/front/role/first"`       //一级权限的查看
+	roleSecond     xweb.Mapper `xweb:"/front/role/second"`      //二级权限的查看
+	roleSave       xweb.Mapper `xweb:"/front/role/edit/save"`   //权限编辑保存
+	roleDel        xweb.Mapper `xweb:"/front/role/edit/del"`    //权限编辑删除
+	roleSecondEdit xweb.Mapper `xweb:"/front/role/second/edit"` //二级权限编辑
 
 }
 
@@ -23,3 +51,44 @@ func (f *Front) Index() {
 	defer qu.Catch()
 	f.Render("index.html")
 }
+
+
+func (f *Front) PersonalMenu() {
+	user := f.GetSession("user").(map[string]interface{})
+	list := UserMenu[qu.ObjToString(user["s_login"])]
+	f.ServeJson(map[string]interface{}{
+		"data": list,
+	})
+}
+
+func GetUserMenu(role int) []map[string]interface{} {
+	list := []map[string]interface{}{}
+	maps := map[string]interface{}{
+		"delete": false,
+	}
+	if role != 0 {
+		maps[fmt.Sprintf("role.%d", role)] = true
+	}
+	data, _ := Mgo.Find("menu_first", maps, nil, nil, false, -1, -1)
+	for _, d := range *data {
+		_id := d["_id"]
+		maps = map[string]interface{}{
+			"delete": false,
+			"s_pid":  mongodb.BsonIdToSId(_id),
+		}
+		if role != 0 {
+			maps[fmt.Sprintf("role.%d", role)] = true
+		}
+		secdatas, _ := Mgo.Find("menu_second", maps, nil, nil, false, -1, -1)
+		secmenumap := map[string]interface{}{}
+		for index, secdata := range *secdatas {
+			secmenumap[strconv.Itoa(index+1)] = secdata
+		}
+		if len(secmenumap) != 0 {
+			d["secondmenu"] = secmenumap
+		}
+		list = append(list, d)
+	}
+	return list
+}
+

+ 143 - 0
src/front/menu.go

@@ -0,0 +1,143 @@
+package front
+
+import (
+	"go.mongodb.org/mongo-driver/bson/primitive"
+	"mongodb"
+	qu "qfw/util"
+	"time"
+
+	. "util"
+
+	"go.mongodb.org/mongo-driver/bson"
+)
+
+func (f *Front) Menu() {
+	defer qu.Catch()
+	if f.Method() == "POST" {
+		data, _ := Mgo.Find("menu_first", `{"delete":false}`, `{"_id":1}`, nil, false, -1, -1)
+		f.ServeJson(map[string]interface{}{
+			"data": data,
+		})
+	} else {
+		f.Render("com/menu_first.html")
+	}
+}
+
+func (f *Front) MenuSave() {
+	defer qu.Catch()
+	name := f.GetString("name")
+	href := f.GetString("href")
+	css := f.GetString("css")
+	id := f.GetString("id")
+	query := bson.M{
+		"_id":    mongodb.StringTOBsonId(id),
+		"delete": false,
+	}
+	if id == "" {
+		query = bson.M{
+			"_id":    primitive.NewObjectID(),
+			"delete": false,
+		}
+	}
+	set := bson.M{
+		"$set": bson.M{
+			"s_name":       name,
+			"s_href":       href,
+			"s_css":        css,
+			"delete":       false,
+			"i_comeintime": time.Now().Unix(),
+		},
+	}
+	b := Mgo.Update("menu_first", query, set, true, false)
+	if b {
+		f.ServeJson(map[string]interface{}{
+			"rep": b,
+		})
+	}
+}
+
+func (f *Front) MenuDel() {
+	defer qu.Catch()
+	_id := f.GetString("_id")
+	query := bson.M{
+		"_id": mongodb.StringTOBsonId(_id),
+	}
+	set := bson.M{
+		"$set": bson.M{
+			"delete": true,
+		},
+	}
+	b := Mgo.Update("menu_first", query, set, false, false)
+	if b { //删除一级菜单下的二级菜单
+		Mgo.Update("menu_second", `{"s_pid":"`+_id+`"}`, set, false, true)
+	}
+	f.ServeJson(map[string]interface{}{
+		"rep": b,
+	})
+}
+
+func (f *Front) MenuSecond() {
+	defer qu.Catch()
+	id := f.GetString("id")
+	if f.Method() == "POST" {
+		data, _ := Mgo.Find("menu_second", `{"s_pid":"`+id+`","delete":false}`, `{"_id":1}`, nil, false, -1, -1)
+		f.ServeJson(map[string]interface{}{
+			"data": data,
+		})
+	} else {
+		f.T["id"] = id
+		f.Render("com/menu_second.html", &f.T)
+	}
+}
+
+func (f *Front) MenuSecondSave() {
+	defer qu.Catch()
+	name := f.GetString("name")
+	href := f.GetString("href")
+	css := f.GetString("css")
+	id := f.GetString("id")
+	pid := f.GetString("pid")
+	query := bson.M{
+		"_id":    mongodb.StringTOBsonId(id),
+		"delete": false,
+	}
+	if id == "" {
+		query = bson.M{
+			"_id":    primitive.NewObjectID(),
+			"delete": false,
+		}
+	}
+	set := bson.M{
+		"$set": bson.M{
+			"s_name":       name,
+			"s_href":       href,
+			"s_css":        css,
+			"delete":       false,
+			"s_pid":        pid,
+			"i_comeintime": time.Now().Unix(),
+		},
+	}
+	b := Mgo.Update("menu_second", query, set, true, false)
+	if b {
+		f.ServeJson(map[string]interface{}{
+			"rep": b,
+		})
+	}
+}
+
+func (f *Front) MenuSecondDel() {
+	defer qu.Catch()
+	_id := f.GetString("_id")
+	query := bson.M{
+		"_id": mongodb.StringTOBsonId(_id),
+	}
+	set := bson.M{
+		"$set": bson.M{
+			"delete": true,
+		},
+	}
+	b := Mgo.Update("menu_second", query, set, false, false)
+	f.ServeJson(map[string]interface{}{
+		"rep": b,
+	})
+}

+ 222 - 0
src/front/role.go

@@ -0,0 +1,222 @@
+package front
+
+import (
+	"encoding/json"
+	"go.mongodb.org/mongo-driver/bson"
+	"mongodb"
+	qu "qfw/util"
+	. "util"
+)
+
+func (f *Front) RoleManager() {
+	defer qu.Catch()
+	if f.Method() == "POST" {
+		data, _ := Mgo.Find("role", nil, nil, nil, false, -1, -1)
+		f.ServeJson(map[string]interface{}{
+			"data": data,
+		})
+	} else {
+		f.Render("com/role.html")
+	}
+}
+
+func (f *Front) RoleNew() {
+	defer qu.Catch()
+	if f.Method() == "POST" {
+		name := f.GetString("role_name")
+		level := f.GetString("role_level")
+		_id := f.GetString("_id")
+		if _id != "" {
+			set := bson.M{
+				"$set": bson.M{
+					"name":  name,
+					"level": level,
+				},
+			}
+			bol := Mgo.UpdateById("role", mongodb.StringTOBsonId(_id), set)
+			if bol {
+				f.ServeJson(map[string]interface{}{
+					"rep": true,
+				})
+			}
+		} else {
+			_id := Mgo.Save("role", bson.M{"name": name, "level": level})
+			if _id != "" {
+				f.ServeJson(map[string]interface{}{
+					"rep": true,
+				})
+			}
+		}
+	} else {
+		f.Render("com/role.html")
+	}
+}
+
+func (f *Front) RoleEdit(role string) {
+	defer qu.Catch()
+	if f.Method() == "POST" {
+		maps := map[string]interface{}{
+			"role." + role: true,
+		}
+		data, _ := Mgo.Find("menu_first", maps, nil, nil, false, -1, -1)
+		f.ServeJson(map[string]interface{}{
+			"data": data,
+		})
+	} else {
+		f.T["role"] = role
+		f.Render("com/role_edit.html", &f.T)
+	}
+}
+
+func (f *Front) RoleFirst() {
+	defer qu.Catch()
+	data, _ := Mgo.Find("menu_first", `{"delete":false}`, nil, nil, false, -1, -1)
+	f.ServeJson(map[string]interface{}{
+		"data": data,
+	})
+}
+
+func (f *Front) RoleSecond() {
+	defer qu.Catch()
+	pid := f.GetString("_pid")
+	query := bson.M{
+		"s_pid": pid,
+	}
+	data, _ := Mgo.Find("menu_second", query, nil, nil, false, -1, -1)
+	f.ServeJson(map[string]interface{}{
+		"data": data,
+	})
+}
+
+func (f *Front) RoleSave() {
+	defer qu.Catch()
+	pid := f.GetString("_id")
+	role := f.GetString("role")
+	secondStr := f.GetString("secondStr")   //右边 选中的
+	secondStr1 := f.GetString("secondStr1") //左边 未选中的
+
+	secondmenus := make([]string, 0)
+	secondmenus1 := make([]string, 0)
+	s_id := json.Unmarshal([]byte(secondStr), &secondmenus)
+	s_id1 := json.Unmarshal([]byte(secondStr1), &secondmenus1)
+
+	if s_id == nil && s_id1 == nil {
+		for _, v := range secondmenus {
+			maps := map[string]interface{}{
+				"_id": mongodb.StringTOBsonId(v),
+			}
+			data := map[string]interface{}{
+				"role." + role: true,
+			}
+			data1 := map[string]interface{}{
+				"$set": data,
+			}
+			Mgo.Update("menu_second", maps, data1, true, false)
+		}
+		for _, v := range secondmenus1 {
+			maps := map[string]interface{}{
+				"_id": mongodb.StringTOBsonId(v),
+			}
+			data := map[string]interface{}{
+				"role." + role: false,
+			}
+			data1 := map[string]interface{}{
+				"$set": data,
+			}
+			Mgo.Update("menu_second", maps, data1, true, false)
+		}
+	}
+	b := false
+	if (len(secondmenus) == 0 && len(secondmenus1) == 0) || (len(secondmenus) > 0) {
+		maps := map[string]interface{}{
+			"_id": mongodb.StringTOBsonId(pid),
+		}
+		data := map[string]interface{}{
+			"role." + role: true,
+		}
+		data1 := map[string]interface{}{
+			"$set": data,
+		}
+		b = Mgo.Update("menu_first", maps, data1, true, false)
+	}
+	if len(secondmenus) == 0 && len(secondmenus1) > 0 {
+		maps := map[string]interface{}{
+			"_id": mongodb.StringTOBsonId(pid),
+		}
+		data := map[string]interface{}{
+			"role." + role: false,
+		}
+		data1 := map[string]interface{}{
+			"$set": data,
+		}
+		b = Mgo.Update("menu_first", maps, data1, true, false)
+	}
+	f.ServeJson(map[string]interface{}{
+		"rep": b,
+	})
+}
+
+func (f *Front) RoleDel() {
+	defer qu.Catch()
+	_id := f.GetString("_id")
+	role := f.GetString("role")
+	maps := map[string]interface{}{
+		"_id": mongodb.StringTOBsonId(_id),
+	}
+	data := map[string]interface{}{
+		"role." + role: false,
+	}
+	data1 := map[string]interface{}{
+		"$set": data,
+	}
+	b := Mgo.Update("menu_first", maps, data1, true, false)
+	maps = map[string]interface{}{
+		"s_pid": _id,
+	}
+	count, _ := Mgo.Find("menu_second", maps, nil, nil, false, -1, -1)
+	if len(*count) != 0 {
+		for _, c := range *count {
+			maps = map[string]interface{}{
+				"_id": c["_id"],
+			}
+			Mgo.Update("menu_second", maps, data1, true, false)
+		}
+	}
+	f.ServeJson(map[string]interface{}{
+		"rep": b,
+	})
+}
+
+func (f *Front) RoleSecondEdit() {
+	defer qu.Catch()
+	menuid := f.GetString("_id")
+	mark := f.GetString("mark")
+	role := f.GetString("role")
+	if mark == "" {
+		maps := map[string]interface{}{
+			"s_pid": menuid,
+		}
+		datas, _ := Mgo.Find("menu_second", maps, nil, nil, false, -1, -1)
+		f.ServeJson(map[string]interface{}{
+			"data": datas,
+		})
+	} else {
+		maps := map[string]interface{}{
+			"s_pid":        menuid,
+			"role." + role: true,
+		}
+		data, _ := Mgo.Find("menu_second", maps, nil, nil, false, -1, -1)
+		maps1 := map[string]interface{}{
+			"s_pid":        menuid,
+			"role." + role: false,
+		}
+		name, _ := Mgo.FindById("menu_first", menuid, `{s_name:1}`)
+		s_name := (*name)["s_name"]
+		data1, _ := Mgo.Find("menu_second", maps1, nil, nil, false, -1, -1)
+		f.ServeJson(map[string]interface{}{
+			"name":  s_name,
+			"data":  data,
+			"data1": data1,
+		})
+	}
+}

+ 68 - 8
src/front/user.go

@@ -1,40 +1,100 @@
 package front
 
 import (
+	"github.com/dchest/captcha"
+	"github.com/gorilla/sessions"
 	mgo "mongodb"
 	qu "qfw/util"
 	. "util"
 )
 
+var store = sessions.NewCookieStore([]byte("jianyu_secret20210422"))
+
 func (f *Front) Login() {
 	defer qu.Catch()
 	if f.Method() == "POST" {
 		username := f.GetString("username")
 		password := f.GetString("pwd")
+		imgCode := f.GetString("imgCode")
 		passwordEn := qu.SE.EncodeString(password)
-		qu.Debug(username, passwordEn)
+		qu.Debug(username, passwordEn, imgCode)
+		session, err := store.Get(f.Request, "dataTagLoginImgCode")
+		if err != nil {
+			qu.Debug("图片验证码session获取失败-%s \n", username)
+			f.ServeJson(map[string]interface{}{
+				"code":    0,
+				"status":  false,
+				"message": "获取失败",
+			})
+			return
+		}
+		code := qu.ObjToString(session.Values["dataTagLoginImgCode"])
+		if code == "" {
+			qu.Debug("图片验证码过期-%s \n", username)
+			f.ServeJson(map[string]interface{}{
+				"checked":  false,
+				"message": "图片验证码过期",
+			})
+			return
+		}
+		if !captcha.VerifyString(code, imgCode) {
+			qu.Debug("图片验证码错误-%s \n", username)
+			f.ServeJson(map[string]interface{}{
+				"checked":  false,
+				"message": "图片验证码错误",
+			})
+			return
+		}
 		query := map[string]interface{}{
-			"name":     username,
-			"password": passwordEn,
+			"s_name":     username,
+			"s_password": passwordEn,
 		}
 		user, _ := Mgo.FindOne("user", query)
 		checked := false
 		if user != nil && len(*user) > 0 {
 			checked = true
 			f.SetSession("user", map[string]interface{}{
-				"name":     (*user)["name"],
-				"role":     (*user)["role"],
-				"pwd":      password,
-				"username": username,
+				"s_name":     	(*user)["s_name"],
+				"i_role":     	(*user)["i_role"],
+				"s_pwd":      	password,
+				"s_login": 		username,
 				"id":       mgo.BsonIdToSId((*user)["_id"]),
 			})
+			UserMenu[username] = GetUserMenu(qu.IntAll((*user)["i_role"]))
 		}
 		f.ServeJson(map[string]interface{}{
 			"checked": checked,
+			"message": "账号或密码错误",
 		})
 	} else {
-		f.Render("login.html")
+		_ = f.Render("login.html")
+	}
+}
+
+// 获取图片验证码
+func (f *Front) Code() {
+	id := captcha.NewLen(4)
+	//r := &http.Request{}
+	f.Request.Header.Add("Cache-Control", "no-cache, no-store, must-revalidate")
+	f.Request.Header.Add("Pragma", "no-cache")
+	f.Request.Header.Add("Expires", "0")
+	f.Request.Header.Add("Content-Type", "image/png")
+	w := f.ResponseWriter
+	session, err := store.Get(f.Request, "dataTagLoginImgCode")
+	if err != nil {
+		qu.Debug("session1获取失败")
+		return
+	}
+	session.Values["dataTagLoginImgCode"] = id
+	session.Options.MaxAge = 60
+	if err := session.Save(f.Request, w); err != nil {
+		qu.Debug("session1保存错误,验证码 ", id)
+	}
+	err2 := captcha.WriteImage(w, id, 90, 30)
+	if err2 != nil {
+		qu.Debug("生成图片验证码错误,验证码 ", id)
 	}
+	return
 }
 
 func (f *Front) Logout() {

+ 1 - 1
src/web/templates/com/footer.html

@@ -1,6 +1,6 @@
 	<footer class="main-footer no-print">
 	   <div class="pull-right hidden-xs">
-	     <b>Dada Process</b>
+	     <b>Dada Validation</b>
 	   </div>
 	   <strong>Jianyu &copy; </strong> All rights
 	   reserved.

+ 3 - 3
src/web/templates/com/header.html

@@ -2,9 +2,9 @@
     <!-- Logo -->
     <a href="/front/index" class="logo">
       <!-- mini logo for sidebar mini 50x50 pixels -->
-      <span class="logo-mini"><b>ProcessPlatform</b></span>
+      <span class="logo-mini"><b>ValidationPlatform</b></span>
       <!-- logo for regular state and mobile devices -->
-      <span class="logo-lg"><b>Process Platform</b></span>
+      <span class="logo-lg"><b>Validation Platform</b></span>
     </a>
     <!-- Header Navbar -->
     <nav class="navbar navbar-static-top" role="navigation">
@@ -22,7 +22,7 @@
               <!-- The user image in the navbar-->
               <img src="/dist/img/user2-160x160.jpg" class="user-image" alt="User Image">
               <!-- hidden-xs hides the username on small devices so only the image appears. -->
-           		<span class="hidden-xs">{{(session "user").name}}</span>
+           		<span class="hidden-xs">{{(session "user").s_login}}</span>
 			</a>
           	</li>
 			<li><a href="/front/logout"><span class="hidden-xs">注销</span></a></li>

+ 93 - 24
src/web/templates/com/menu.html

@@ -1,25 +1,94 @@
 <aside class="main-sidebar">
-	<section class="sidebar" style="height: auto;">
-		<ul id="menu" class="sidebar-menu tree" data-widget="tree">
-			<li class="header">
-				HEADER
-			</li>
-			<li class="treeview menu-open">
-				<a href="#"><i class="fa fa-navicon"></i><span>权限管理</span><span class="pull-right-container"><i class="fa fa-angle-left pull-right"></i></span></a>
-				<ul class="treeview-menu" style="display: block;">
-					<li><a href="/front/user"><i class="fa fa-link"></i>人员管理</a></li>
-					<li><a href="/front/user/role"><i class="fa fa-link"></i>角色管理</a></li>
-          <li><a href="/front/user/menu"><i class="fa fa-link"></i>菜单管理</a></li>
-				</ul>
-			</li>
-			<li><a href="/front/task"><i class="fa fa-navicon"></i><span>任务管理</span></a></li>
-		  <li class="treeview">
-				<a href="#"><i class="fa fa-navicon"></i><span>测试</span><span class="pull-right-container"><i class="fa fa-angle-left pull-right"></i></span></a>
-				<ul class="treeview-menu">
-					<li><a href="/front/test1"><i class="fa fa-link"></i>测试1</a></li>
-          <li><a href="/front/test2"><i class="fa fa-link"></i>测试2</a></li>
-				</ul>
-			</li>
-    </ul>
-	</section>
-</aside>
+    <section class="sidebar">
+      <ul id="menu" class="sidebar-menu" data-widget="tree">
+        <li class="header">HEADER</li>
+        <!-- Optionally, you can add icons to the links -->
+        <!--
+		<li class="treeview">
+          	<a href="#"><i class="fa fa-clock-o"></i> <span>任务管理</span>
+            <span class="pull-right-container">
+                <i class="fa fa-angle-left pull-right"></i>
+            </span>
+          	</a>
+          	<ul class="treeview-menu">
+	            <li><a href="/admin/task"><i class="fa fa-link"></i>抽取任务</a></li>
+				<li><a href="/admin/task/export"><i class="fa fa-link"></i>导出任务</a></li>
+			</ul>
+        </li>
+		<li><a href="/admin/version"><i class="fa fa-navicon"></i><span>版本管理</span></a></li>
+		<li><a href="/admin/audit/recogfield"><i class="fa fa-navicon"></i><span>质量审核</span></a></li>
+		<li class="treeview">
+          	<a href="#"><i class="fa fa-laptop"></i> <span>统计</span>
+            <span class="pull-right-container">
+                <i class="fa fa-angle-left pull-right"></i>
+            </span>
+          	</a>
+          	<ul class="treeview-menu">
+	            <li><a href="/front/menuff"><i class="fa fa-circle-o"></i>菜单</a></li>
+			</ul>
+        </li>
+		<li><a href="/front/usertest"><i class="fa fa-navicon"></i><span>结果追踪</span></a></li>
+        <li><a href="/admin/distribution"><i class="fa fa-laptop"></i> <span>分布式抽取</span></a></li>
+		<li class="treeview">
+			<a href="/admin/user"><i class="fa fa-link"></i> <span>权限管理</span>
+			<span class="pull-right-container">
+                <i class="fa fa-angle-left pull-right"></i>
+            </span></a>
+          	<ul class="treeview-menu">
+	            <li><a href="/front/user"><i class="fa fa-circle-o"></i>人员管理</a></li>
+				<li><a href="/admin/rule/pre"><i class="fa fa-circle-o"></i>角色管理</a></li>
+				<li><a href="/front/menu"><i class="fa fa-circle-o"></i>菜单管理</a></li>
+			</ul>
+		</li>-->
+      </ul>
+    </section>
+	<span id="role" class="hidden">{{(session "user").i_role}}</span>
+</aside>
+<script>
+$(function () {
+	$.post('/front/personalMenu','',function (data,status) {
+		for(var a=0;a<data.data.length;a++) {
+            var info=data.data[a]
+		    if (info.secondmenu){
+                var str=""
+               	for(var sec=1;sec<=Object.keys(info.secondmenu).length;sec++){
+                    var ro=$("#role").text()
+                    if(ro=="0" || info.secondmenu[sec.toString(10)].role[ro] ) {
+                        str = str + '<li><a href=' + info.secondmenu[sec.toString(10)].s_href + '><i class="' + info.secondmenu[sec.toString(10)].s_css + '"></i>' + info.secondmenu[sec.toString(10)].s_name + '</a></li>'
+                    }
+                }
+                $('#menu').append('<li class="treeview">' +
+                        '          <a href="#"><i class="'+info.s_css+'"></i> <span>'+info.s_name+'</span>' +
+                        '            <span class="pull-right-container">' +
+                        '                <i class="fa fa-angle-left pull-right"></i>' +
+                        '            </span>' +
+                        '          </a>' +
+                        '          <ul class="treeview-menu">' + str+ '</ul>' +
+                        '        </li>')
+			}else{
+                $('#menu').append('<li><a href='+info.s_href+'><i class="'+info.s_css+'"></i> <span>'+info.s_name+'</span></a></li>')
+			}
+        }
+    })
+})
+function menuActive(name){
+    setTimeout(function(){
+      $(".sidebar-menu").tree();
+    	$(".sidebar-menu").filter(".menu-open").removeClass("menu-open");
+    	$(".sidebar-menu").filter(".active").removeClass("active");
+        var a;
+    	$(".sidebar-menu a").each(function(i){
+    		if($(this).attr("href").endsWith(name)){
+    			a=$(this)
+    		}
+    	});
+      if (!a) {
+        return menuActive(name)
+      }
+        a.parent().addClass("active");
+        a.parent().parent().parent().addClass("active");
+        a.parent().parent().parent().addClass("menu-open");
+    },100);
+}
+ 
+</script>

+ 181 - 0
src/web/templates/com/menu_first.html

@@ -0,0 +1,181 @@
+{{include "com/inc.html"}}
+<!-- Main Header -->
+{{include "com/header.html"}}
+<!-- Left side column. 权限菜单 -->
+{{include "com/menu.html"}}
+
+<!-- Content Wrapper. Contains page content -->
+<div class="content-wrapper">
+    <section class="content-header">
+        <h1>
+            <small><button type="button" class="btn btn-primary" data-toggle="modal" onclick="add()">新增菜单</button></small>
+        </h1>
+        <ol class="breadcrumb">
+            <li><a href="/front/menu"><i class="fa fa-dashboard"></i> 菜单管理</a></li>
+        </ol>
+    </section>
+    <!-- Main content -->
+    <section class="content">
+        <div class="row">
+            <div class="col-xs-12">
+                <div class="box">
+                    <div class="box-body">
+                        <table id="dataTable" class="table table-bordered table-hover">
+                            <thead>
+                            <tr>
+                                <th>名字</th>
+                                <th>链接</th>
+                                <th>样式</th>
+                                <th>二级菜单</th>
+                                <th>操作</th>
+                            </tr>
+                            </thead>
+                        </table>
+                    </div>
+                    <!-- /.box-body -->
+                </div>
+                <!-- /.box -->
+            </div>
+        </div>
+    </section>
+</div>
+
+<div class="modal fade" id="modal-info">
+    <div class="modal-dialog">
+        <form id="userform" class="form-horizontal" role="form">
+            <div class="modal-content">
+                <div class="modal-header">
+                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                        <span aria-hidden="true">&times;</span></button>
+                    <h4 class="modal-title">菜单信息</h4>
+                </div>
+                <div class="modal-body">
+                    <div class="form-group">
+                        <label for="code" class="col-sm-2 control-label">菜单名称:</label>
+                        <div class="col-sm-10">
+                            <input id="name" name="name" type="text" class="form-control" placeholder="请输入名称">
+                        </div>
+                    </div>
+                    <div class="form-group">
+                        <label for="code" class="col-sm-2 control-label">链接:</label>
+                        <div class="col-sm-10">
+                            <input id="href" name="href" type="text" class="form-control" placeholder="请输入链接">
+                        </div>
+                    </div>
+                    <div class="form-group">
+                        <label for="site" class="col-sm-2 control-label">样式:</label>
+                        <div class="col-sm-10">
+                            <input id="css"  name="css" type="text" class="form-control" placeholder="请输入图标样式" value="fa fa-laptop">
+                        </div>
+                    </div>
+                    <!--<div class="form-group">
+                        <label for="modify" class="col-sm-2 control-label">二级菜单:</label>
+                        <div id="secondmenu" class="col-sm-10">
+                            <input type="button" value="+" onclick="append()"></input>
+                        </div>
+                    </div>-->
+                </div>
+                <div class="modal-footer">
+                    <button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
+                    <button type="button" class="btn btn-primary" onclick="save()">保存</button>
+                </div>
+            </div>
+            <!-- /.modal-content -->
+        </form>
+        <input type="hidden" id="_id">
+
+    </div>
+    <!-- /.modal-dialog -->
+</div>
+<!-- /.modal -->
+
+<!-- footer -->
+{{include "com/footer.html"}}
+
+<script>
+	var id="";
+    menuActive("menu");
+	$(function () {
+        ttable=$('#dataTable').DataTable({
+            "paging"      : true,
+            "lengthChange": false,
+            "searching"   : true,
+            "ordering"    : true,
+            "info"        : true,
+            "autoWidth"   : false,
+            "ajax": {
+                "url": "/front/menu",
+                "type": "post",
+                "data":{}
+            },
+            "language": {
+                "url": "/dist/js/dataTables.chinese.lang"
+            },
+            "columns": [
+                { "data": "s_name"},
+                { "data": "s_href"},
+                { "data": "s_css"},
+                {"data":"secondmenu",render:function(val,a,row){
+                    return '<a class="btn btn-sm btn-success" href="/front/menuSecond?id='+row._id+'">进入二级菜单</a>'
+                }},
+                {"data":"_id",render:function(val,a,row){
+                        return  "<a href='#' onclick='edit(\""+row['s_name']+"\",\""+row['s_href']+"\",\""+row['s_css']+"\",\""+row['_id']+"\")'><i class='fa fa-fw fa-edit text-yellow'></i></a> &nbsp;"+
+                                "<a href='#' onclick='del(\""+val+"\")'><i class='fa fa-fw fa-trash text-red'></i></a>"
+                    }}
+            ]
+        });
+        //ttable.on('init.dt', function () {});
+    })
+	
+	function add(){
+		id="";
+		$("#modal-info #name").val("");
+		$("#modal-info #href").val("");
+		$("#modal-info").modal("show");
+	}
+	function edit(name,href,css,_id){
+		id=_id;
+		$("#modal-info #name").val(name);
+		$("#modal-info #href").val(href);
+		$("#modal-info #css").val(css);
+		$("#modal-info").modal("show");
+	}
+	function save(){
+		var name=$("#modal-info #name").val();
+		var href=$("#modal-info #href").val();
+		var css=$("#modal-info #css").val();
+		if(name==""||css==""){
+			alert("表单填写不完整!")
+			return false;
+		}
+		$.ajax({
+			url:"/front/menu/save",
+			type:"post",
+			data:{"name":name,"href":href,"css":css,"id":id},
+			success:function(r){
+				if(r.rep){
+					$("#modal-info").modal("hide");
+					ttable.ajax.reload();
+				}else{
+					alert("保存失败");
+				}
+			}
+		})
+	}
+	function del(_id){
+		showConfirm("确定删除?", function() {
+			$.ajax({
+				url:"/front/menu/del",
+				type:"post",
+				data:{"_id":_id},
+				success:function(r){
+					if(r.rep){				
+						ttable.ajax.reload();
+					}else{
+						showTip("删除失败", 1000, function() {});
+					}
+				}
+			})
+		});
+	}
+</script>

+ 174 - 0
src/web/templates/com/menu_second.html

@@ -0,0 +1,174 @@
+{{include "com/inc.html"}}
+<!-- Main Header -->
+{{include "com/header.html"}}
+<!-- Left side column. 权限菜单 -->
+{{include "com/menu.html"}}
+
+
+<!-- Content Wrapper. Contains page content -->
+<div class="content-wrapper">
+    <section class="content-header">
+        <h1>
+            <small><button type="button" class="btn btn-primary" data-toggle="modal" onclick="add()">新增二级菜单</button></small>
+        </h1>
+        <ol class="breadcrumb">
+            <li><a href="/front/menu"><i class="fa fa-dashboard"></i> 菜单管理</a></li>
+            <li><a href="/front/menuSecond?id={{.T.id}}"><i class="fa fa-dashboard"></i> 二级菜单管理</a></li>
+        </ol>
+    </section>
+    <!-- Main content -->
+    <section class="content">
+        <div class="row">
+            <div class="col-xs-12">
+                <div class="box">
+                    <div class="box-body">
+                        <table id="dataTable" class="table table-bordered table-hover">
+                            <thead>
+                            <tr>
+                                <th>名字</th>
+                                <th>链接</th>
+                                <th>样式</th>
+                                <th>操作</th>
+                            </tr>
+                            </thead>
+                        </table>
+                    </div>
+                    <!-- /.box-body -->
+                </div>
+                <!-- /.box -->
+            </div>
+        </div>
+    </section>
+</div>
+
+<div class="modal fade" id="modal-info">
+    <div class="modal-dialog">
+        <form id="userform" class="form-horizontal" role="form">
+            <div class="modal-content">
+                <div class="modal-header">
+                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                        <span aria-hidden="true">&times;</span></button>
+                    <h4 class="modal-title">二级菜单信息</h4>
+                </div>
+                <div class="modal-body">
+                    <div class="form-group">
+                        <label for="code" class="col-sm-2 control-label">菜单名称:</label>
+                        <div class="col-sm-10">
+                            <input id="name" name="name" type="text" class="form-control" placeholder="请输入名称">
+                        </div>
+                    </div>
+                    <div class="form-group">
+                        <label for="code" class="col-sm-2 control-label">链接:</label>
+                        <div class="col-sm-10">
+                            <input id="href" name="href" type="text" class="form-control" placeholder="请输入链接">
+                        </div>
+                    </div>
+                    <div class="form-group">
+                        <label for="site" class="col-sm-2 control-label">样式:</label>
+                        <div class="col-sm-10">
+                            <input id="css"  name="css" type="text" class="form-control" placeholder="请输入图标样式" value="fa fa-circle-o">
+                        </div>
+                    </div>
+                </div>
+                <div class="modal-footer">
+                    <button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
+                    <button type="button" class="btn btn-primary" onclick="save()">保存</button>
+                </div>
+            </div>
+            <!-- /.modal-content -->
+        </form>
+        <input type="hidden" id="_id">
+    </div>
+    <!-- /.modal-dialog -->
+</div>
+<!-- /.modal -->
+
+<!-- footer -->
+{{include "com/footer.html"}}
+
+<script>
+	var pid={{.T.id}};
+	var id="";
+    menuActive("menu")
+    $(function () {
+        ttable=$('#dataTable').DataTable({
+            "paging"      : true,
+            "lengthChange": false,
+            "searching"   : true,
+            "ordering"    : true,
+            "info"        : true,
+            "autoWidth"   : false,
+            "ajax": {
+                "url": "/front/menuSecond",
+                "type": "post",
+                "data":{"id":{{.T.id}}}
+            },
+            "language": {
+                "url": "/dist/js/dataTables.chinese.lang"
+            },
+            "columns": [
+                { "data": "s_name"},
+                { "data": "s_href"},
+                { "data": "s_css"},
+                { "data":"_id",render:function(val,a,row){
+                        return  "<a href='#' onclick='edit(\""+row['s_name']+"\",\""+row['s_href']+"\",\""+row['s_css']+"\",\""+row['_id']+"\")'><i class='fa fa-fw fa-edit text-yellow'></i></a> &nbsp;"+
+                                "<a href='#' onclick='del(\""+val+"\")'><i class='fa fa-fw fa-trash text-red'></i></a>"
+                }}
+
+            ]
+        });
+        //ttable.on('init.dt', function () {});
+    })
+	
+	function add(){
+		id="";
+		$("#modal-info #name").val("");
+		$("#modal-info #href").val("");
+		$("#modal-info").modal("show");
+	}
+	function edit(name,href,css,_id){
+		id=_id;
+		$("#modal-info #name").val(name);
+		$("#modal-info #href").val(href);
+		$("#modal-info #css").val(css);
+		$("#modal-info").modal("show");
+	}
+	function save(){
+		var name=$("#modal-info #name").val();
+		var href=$("#modal-info #href").val();
+		var css=$("#modal-info #css").val();
+		if(name==""||href==""||css==""){
+			alert("表单填写不完整!")
+			return false;
+		}
+		$.ajax({
+			url:"/front/menuSecond/save",
+			type:"post",
+			data:{"name":name,"href":href,"css":css,"pid":pid,"id":id},
+			success:function(r){
+				if(r.rep){
+					$("#modal-info").modal("hide");
+					ttable.ajax.reload();
+				}else{
+					alert("保存失败");
+				}
+			}
+		})
+	}
+	function del(_id){
+		showConfirm("确定删除?", function() {
+			$.ajax({
+				url:"/front/menuSecond/del",
+				type:"post",
+				data:{"_id":_id},
+				success:function(r){
+					if(r.rep){				
+						ttable.ajax.reload();
+					}else{
+						showTip("删除失败", 1000, function() {});
+					}
+				}
+			})
+		});
+	}
+</script>

+ 146 - 0
src/web/templates/com/role.html

@@ -0,0 +1,146 @@
+{{include "com/inc.html"}}
+<!-- Main Header -->
+{{include "com/header.html"}}
+<!-- Left side column. 权限菜单 -->
+{{include "com/menu.html"}}
+
+<!-- Content Wrapper. Contains page content -->
+<div class="content-wrapper">
+    <section class="content-header">
+        <h1>
+            <small><a onclick="addRole()" class="btn btn-primary opr">新增角色</a></small>
+        </h1>
+        <ol class="breadcrumb">
+            <li><a href="/front/role"><i class="fa fa-dashboard"></i> 角色管理</a></li>
+        </ol>
+    </section>
+    <!-- Main content -->
+    <section class="content">
+        <div class="row">
+            <div class="col-xs-12">
+                <div class="box">
+                    <div class="box-body">
+                        <table id="dataTable" class="table table-bordered table-hover">
+                            <thead>
+                            <tr>
+                                <th>角色名称</th>
+                                <th>编辑</th>
+                            </tr>
+                            </thead>
+                        </table>
+                    </div>
+                    <!-- /.box-body -->
+                </div>
+                <!-- /.box -->
+            </div>
+        </div>
+    </section>
+</div>
+
+<div class="modal fade" id="modal-new-role" tabindex="-1" role="dialog" aria-hidden="true">
+    <div class="modal-dialog">
+        <div class="modal-content">
+            <div class="modal-header">
+                <div class="modal-header">
+                    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+                    <div class="edit-form">
+                        <div class="edit-info">
+                            <span class="glyphicon glyphicon-ok-sign" aria-hidden="true"></span>
+                            <span>新增角色</span>
+                        </div>
+                        <form class="form-horizontal text-center">
+                            <div class="form-group">
+                                <label class="col-sm-3 control-label"><span style="color:red;">* </span>角色名称</label>
+                                <div class="col-sm-5">
+                                    <input type="text" required class="form-control" placeholder="名称" id="role_name"/></div>
+                            </div>
+                            <div class="form-group">
+                                <label class="col-sm-3 control-label"><span style="color:red;">* </span>角色等级</label>
+                                <div class="col-sm-5">
+                                    <input type="text" required class="form-control" style="max-width: 100%" placeholder="2/3/4" id="role_level"/></div>
+                            </div>
+                        </form>
+                    </div>
+                </div>
+                <div class="modal-footer">
+                    <input type="button" onclick="saveRole()" class="btn btn-primary saveBtn" value="保存">
+                    <input type="button" onclick="cancelModel()" class="btn btn-default" style="margin-left: 24px"
+                           value="取消">
+                </div>
+            </div>
+        </div>
+    </div><!-- /.modal -->
+</div>
+<!-- footer -->
+{{include "com/footer.html"}}
+<script>
+    menuActive("role")
+    var _id = ""
+
+    ttable = $('#dataTable').DataTable({
+        "paging"      : true,
+        "lengthChange": false,
+        "searching"   : false,
+        "ordering"    : false,
+        "info"        : true,
+        "autoWidth"   : false,
+        "ajax": {
+            "url": "/front/role",
+            "type": "post",
+            "data": {}
+        },
+        "language": {
+            "url": "/dist/js/dataTables.chinese.lang"
+        },
+        "columns": [
+            { "data": "name"},
+            { "data": "level", render: function(val, a, row){
+                if (val == "0") {
+                    return "<a class='btn btn-sm btn-danger disabled'>编辑</a> &nbsp;" +
+                        "<a class='btn btn-sm btn-success' href='/front/role/edit/"+val+"'>角色菜单</a>"
+                }else {
+                    return "<a class='btn btn-sm btn-danger' onclick='editRole(\""+row['_id']+"\",\""+row['name']+"\",\""+row['level']+"\")'>编辑</a> &nbsp;" +
+                        "<a class='btn btn-sm btn-success' href='/front/role/edit/"+val+"'>角色菜单</a>"
+                }
+            }}
+        ]
+    });
+
+    function addRole() {
+        _id = ""
+        $('#role_name').val("")
+        $('#role_level').val("")
+        $('#modal-new-role').modal("show");
+    }
+    function cancelModel() {
+        $('#modal-new-role').modal("hide");
+    }
+    function saveRole() {
+        var name = $('#role_name').val();
+        var levle = $('#role_level').val();
+        if (name == "" || levle == "") {
+            alert("请填写必填项")
+            return
+        }
+        $.ajax({
+            url:"/front/role/save",
+            type:"post",
+            data:{"role_name": name, "role_level": levle, "_id": _id},
+            success:function(r){
+                if(r.rep){
+                    $("#modal-new-role").modal("hide");
+                    ttable.ajax.reload();
+                }else{
+                    alert("保存失败");
+                }
+            }
+        })
+    }
+    function editRole(id, name, level) {
+        _id = id
+        $('#role_name').val(name)
+        $('#role_level').val(level)
+        $('#modal-new-role').modal("show");
+    }
+</script>
+

+ 280 - 0
src/web/templates/com/role_edit.html

@@ -0,0 +1,280 @@
+{{include "com/inc.html"}}
+<!-- Main Header -->
+{{include "com/header.html"}}
+<!-- Left side column. 权限菜单 -->
+{{include "com/menu.html"}}
+
+<head>
+    <style>
+
+        #selectclear2 select {
+            width:190px;
+            height:167px;
+            padding:5px;
+        }
+        #selectclear2{
+            display: flex;
+            flex-direction: row;
+        }
+        #selectclear2 .move{
+            display: flex;
+            flex-direction: column;
+            margin: 20px 25px
+        }
+        #selectclear2 .move button{
+            margin: 1px 0px;
+            padding: 4px 6px;
+        }
+        #selectclear2 .doublebox {
+            text-align:center;
+        }
+
+
+    </style>
+</head>
+
+<!-- Content Wrapper. Contains page content -->
+<div class="content-wrapper">
+    <section class="content-header">
+        <h1>
+            <small><button type="button" class="btn btn-primary" data-toggle="modal" data-target="#modal-info" onclick="formReset()">新增角色菜单</button></small>
+        </h1>
+        <ol class="breadcrumb">
+            <li><a href="/front/role"><i class="fa fa-dashboard"></i> 角色管理</a></li>
+            <li><a href="/front/role/edit/{{.T.role}}"><i class="fa fa-dashboard"></i> 角色菜单管理</a></li>
+        </ol>
+    </section>
+    <!-- Main content -->
+    <section class="content">
+        <div class="row">
+            <div class="col-xs-12">
+                <div class="box">
+                    <div class="box-body">
+                        <table id="dataTable" class="table table-bordered table-hover">
+                            <thead>
+                            <tr>
+                                <th>一级菜单</th>
+                                <th>操作</th>
+                            </tr>
+                            </thead>
+                        </table>
+                    </div>
+                    <!-- /.box-body -->
+                </div>
+                <!-- /.box -->
+            </div>
+        </div>
+    </section>
+</div>
+
+<div class="modal fade" id="modal-info">
+    <div class="modal-dialog">
+        <form id="userform" class="form-horizontal" role="form">
+            <div class="modal-content">
+                <div class="modal-header">
+                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                        <span aria-hidden="true">&times;</span></button>
+                    <h4 class="modal-title">菜单信息</h4>
+                </div>
+                <div class="modal-body">
+                    <div class="form-group">
+                        <label for="code" class="col-sm-2 control-label">菜单名称:</label>
+                        <div class="col-sm-10">
+                            <select id="menu2" name="role" class="form-control" onchange="menu()">
+                            </select>
+                        </div>
+                    </div>
+                    <div class="form-group">
+                        <label for="code" class="col-sm-2 control-label">二级菜单:</label>
+                        <div class="col-sm-10" id="selectclear2">
+                            <div class="doublebox">
+                                <select multiple="multiple" id="select3" style="overflow-x: scroll;"></select>
+                            </div>
+                            <div class="move">
+                                <button type="button" id="up2" class="btn btn-primary">上移</button>
+                                <button type="button" id="right2" class="btn btn-primary">右移</button>
+                                <button type="button" id="left2" class="btn btn-primary">左移</button>
+                                <button type="button" id="down2" class="btn btn-primary">下移</button>
+                            </div>
+                            <div class="doublebox">
+                                <select multiple="multiple" id="select4" style="overflow-x: scroll;"></select>
+                            </div>
+                        </div>
+                    </div>
+                    <!--<div class="form-group">
+                        <label for="modify" class="col-sm-2 control-label">二级菜单:</label>
+                        <div id="secondmenu" class="col-sm-10">
+                            <input type="button" value="+" onclick="append()"></input>
+                        </div>
+                    </div>-->
+                </div>
+                <div class="modal-footer">
+                    <button type="button" class="btn btn-default" data-dismiss="modal" onclick="formReset()">取消</button>
+                    <button type="button" class="btn btn-primary" onclick="save()">保存</button>
+                </div>
+            </div>
+            <!-- /.modal-content -->
+        </form>
+        <input type="hidden" id="_id">
+    </div>
+    <!-- /.modal-dialog -->
+</div>
+<!-- /.modal -->
+
+<!-- footer -->
+{{include "com/footer.html"}}
+
+<script>
+    menuActive("role")
+    $(function () {
+        ttable=$('#dataTable').DataTable({
+            "paging"      : true,
+            "lengthChange": false,
+            "searching"   : true,
+            "ordering"    : true,
+            "info"        : true,
+            "autoWidth"   : false,
+            "ajax": {
+                "url": "/front/role/edit/{{.T.role}}",
+                "type": "post",
+                "data": {}
+            },
+            "language": {
+                "url": "/dist/js/dataTables.chinese.lang"
+            },
+            "columns": [
+                { "data": "s_name",render:function(val,a,row){
+                        return row.s_name}},
+                {"data":"_id",render:function(val,a,row){
+                        return "<a href='#' onclick='edit(\""+val+"\")'><i class='fa fa-fw fa-edit text-yellow'></i></a> &nbsp;"+
+                        "<a href='#' onclick='del(\""+val+"\")'><i class='fa fa-fw fa-trash text-red'></i></a>"
+                    }}
+            ]
+        });
+        //ttable.on('init.dt', function () {});
+    })
+    function formReset(){
+        $("#_id").val("")
+        $("#menu2").empty()
+        $("#select3").empty();
+        $("#select4").empty();
+        $("#menu2").append("<option value=''>--请选择--</option>")
+        $("#menu2").attr("disabled",false);
+        $.post("/front/role/first",'',function (data, status) {
+            for(var a=0;a<data.data.length;a++) {
+                $("#menu2").append("<option value="+data.data[a]._id+">"+data.data[a].s_name+"</option>")
+            }
+        })
+        $("#modal-info-addclear").modal("show");
+    }
+    function menu() {
+        $("#select3").empty();
+        $("#select4").empty();
+        $.post("/front/role/second",{"_pid":$("#menu2").val()},function (data,status) {
+            if(data.data){
+                for(var a=0;a<data.data.length;a++){
+                    $("#select3").append("<option title='"+data.data[a].s_name+"' value='"+data.data[a]._id+"'>"+data.data[a].s_name+"</option>");
+                }
+            }
+        })
+    }
+    function save(){
+        pid=$("#menu2").val()
+        var clearArr = [];
+        var clearArr1 = [];
+        $("#select4 option").each(function(i,val){
+            clearArr[i] = this.value
+        })
+        $("#select3 option").each(function(i,val){
+            clearArr1[i] = this.value
+        })
+        var secondStr = JSON.stringify(clearArr)
+        var secondStr1 = JSON.stringify(clearArr1)
+       if(pid == ""){
+            alert("表单填写不完整!");
+            return false;
+        }
+        $.ajax({
+            url:"/front/role/edit/save",
+            type:"post",
+            data:{"role":{{.T.role}},"_id":pid,"secondStr":secondStr,"secondStr1":secondStr1},
+            success:function(r){
+                if(r.rep){
+                    $("#userform")[0].reset();
+                    $("#modal-info").modal("hide");
+                    ttable.ajax.reload();
+                }else{
+                    alert("保存失败");
+                }
+            }
+        })
+    }
+    function del(_id){
+        showConfirm("确定删除?", function() {
+            $.ajax({
+                url:"/front/role/edit/del",
+                type:"post",
+                data:{"_id":_id,"role":{{.T.role}}},
+                success:function(r){
+                    if(r.rep){
+                        ttable.ajax.reload();
+                    }else{
+                        showTip("删除失败", 1000, function() {});
+                    }
+                }
+            })
+        });
+    }
+    function edit(_id){
+        $("#menu2").empty()
+        $("#select3").empty();
+        $("#select4").empty();
+        $("#_id").val(_id)
+        mark=$("#_id").val()
+        $.ajax({
+            url:"/front/role/second/edit",
+            type:"post",
+            data:{"_id":_id,"mark":mark,"role":{{.T.role}}},
+            success:function(r){
+                if(r){
+                    $("#menu2").append("<option value="+_id+">"+r.name+"</option>")
+                    $("#menu2").attr("disabled",true);
+                    for(var a=0;a<r.data1.length;a++){
+                        $("#select3").append("<option title='"+r.data1[a].s_name+"' value='"+r.data1[a]._id+"'>"+r.data1[a].s_name+"</option>");
+                    }
+                    for(var a=0;a<r.data.length;a++){
+                        $("#select4").append("<option title='"+r.data[a].s_name+"' value='"+r.data[a]._id+"'>"+r.data[a].s_name+"</option>");
+                    }
+                }
+            }
+        })
+        $("#modal-info").modal("show");
+    }
+
+    $("#selectclear2 #right2").click(function(){
+        $("#select3 option:selected").appendTo("#select4");
+    });
+    //左移
+    $("#selectclear2 #left2").click(function(){
+        $("#select4 option:selected").appendTo("#select3");
+    });
+    $("#selectclear2 #up2,#selectclear2 #down2").click(function() {
+        var $opt = $("#select4 option:selected:first");
+        if (!$opt.length){
+            return;
+        }
+        if (this.id == "up2"){
+            $opt.prev().before($opt);
+        }else{
+            $opt.next().after($opt);
+        }
+    });
+    //双击右移
+    $("#selectclear2 #select3").dblclick(function(){
+        $("#selectclear2 #select3 option:selected").appendTo("#select4");
+    });
+    //双击左移
+    $("#selectclear2 #select4").dblclick(function(){
+        $("#selectclear2 #select4 option:selected").appendTo("#select3");
+    });
+</script>

+ 51 - 35
src/web/templates/login.html

@@ -3,7 +3,7 @@
 <head>
   <meta charset="utf-8">
   <meta http-equiv="X-UA-Compatible" content="IE=edge">
-  <title>Data Process | Log in</title>
+  <title>Data Validation | Log in</title>
   <!-- Tell the browser to be responsive to screen width -->
   <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
   <!-- Bootstrap 3.3.7 -->
@@ -30,7 +30,7 @@
 <body class="hold-transition login-page">
 <div class="login-box">
   <div class="login-logo">
-    <b>Data Process</b>
+    <b>Data Validation</b>
   </div>
   <!-- /.login-logo -->
   <div class="login-box-body">
@@ -45,6 +45,12 @@
         <input id="pwd" type="password" class="form-control" placeholder="请输入密码">
         <span class="glyphicon glyphicon-lock form-control-feedback"></span>
       </div>
+      <div class="form-group has-feedback">
+        <input id="verifyImgCode" class="form-control" placeholder="请输入验证码">
+        <img style="cursor:pointer ;z-index: 5;position: absolute;right: 1px;width: 100px;top: 1px"
+          alt="点击刷新验证码" src="/code" id="verifyImg">
+      </div>
+
       <div class="row">
         <!-- /.col -->
         <div class="col-xs-12">
@@ -65,41 +71,51 @@
 <!-- iCheck -->
 <script src="/plugins/iCheck/icheck.min.js"></script>
 <script>
-$(function () {
-  	$('input').iCheck({
-    	checkboxClass: 'icheckbox_square-blue',
-    	radioClass: 'iradio_square-blue',
-    	increaseArea: '20%' /* optional */
- 	});
+    $(function () {
+        $('input').iCheck({
+            checkboxClass: 'icheckbox_square-blue',
+            radioClass: 'iradio_square-blue',
+            increaseArea: '20%' /* optional */
+        });
+
+        document.onkeydown = function (event) {
+            var e = event || window.event;
+            if (e && e.keyCode == 13) { //回车键的键值为13
+               login();
+            }
+        };
+    });
+
+    // 获取图片验证码
+    $("#verifyImg").click(function () {
+        $(this)[0].src = '/code?' + Math.random()
+    })
 	
-	document.onkeydown = function (event) {
-        var e = event || window.event;
-        if (e && e.keyCode == 13) { //回车键的键值为13
-           login();
+    function login(){
+        var username = $("#username").val().trim().replace(/\s/g,"");
+        var pwd = $("#pwd").val().trim().replace(/\s/g,"");
+        if(username==""||pwd==""){
+            alert("账号和密码不能为空")
+            return
         }
-    }; 
-});
-	
-function login(){
-	var username = $("#username").val().trim().replace(/\s/g,"");
-	var pwd = $("#pwd").val().trim().replace(/\s/g,"");
-	if(username==""||pwd==""){
-		alert("账号和密码不能为空")
-		return false;
-	}
-	$.ajax({
-		url:"/",
-		type:"post",
-		data:{"username":username,"pwd":pwd},
-		success:function(r){
-			if(r.checked){
-				window.location.href="/front/index"
-			}else{
-				alert("fail");
-			}
-		}
-	})
-}
+        if ($("#verifyImgCode").val().trim().replace(/\s/g, "").length === 4) {
+            $.ajax({
+                url:"/",
+                type:"post",
+                data:{"username": username,"pwd": pwd,"imgCode": $("#verifyImgCode").val()},
+                success:function(r){
+                    if(r.checked){
+                        window.location.href="/front/index"
+                    }else{
+                        alert(r.message);
+                    }
+                }
+            })
+        } else {
+            $("#verifyImg")[0].src = '/code?' + Math.random()
+            alert("图片验证码有误,请重填");
+        }
+    }
 
 </script>
 </body>