Просмотр исходного кода

后台cld用户权限功能添加,用户管理页面内容更新

laiguoran 7 лет назад
Родитель
Сommit
bae89cf5d4

+ 8 - 3
config/menu.js

@@ -22,12 +22,12 @@ let menuData = {
                 title: '普通用户',
                 url: '/user',
                 name: 'index',
-            }/*,
-            'test-user' : {
+            },
+            'testUser' : {
                 title: '测试用户',
                 url: '/user/test-user',
                 name: 'test-user',
-            }*/
+            }
         }
     },
     'notify': {
@@ -59,6 +59,11 @@ let menuData = {
                 url: '/manager',
                 name: 'index',
             },
+            'authority' : {
+                title: '权限组',
+                url: '/manager/authority',
+                name: 'authority',
+            },
             'admin' : {
                 title: '超级管理员',
                 url: '/manager/admin',

+ 49 - 0
modules/all_models/permission.js

@@ -0,0 +1,49 @@
+/**
+ * 后台管理权限数据模型
+ *
+ * @author EllisRan
+ * @date 2018/12/06
+ * @version
+ */
+import mongoose from "mongoose";
+
+let Schema = mongoose.Schema;
+let collectionName = 'permission';
+let modelSchema = {
+    // ID
+    ID: {
+        type: Number,
+        default: 0
+    },
+    // 权限名称
+    name: {
+        type: String,
+        index: true
+    },
+    // 控制器名称
+    controller: String,
+    // 针对工具里一个页面多个控制器的问题(特殊优化)
+    otherController: String,
+    // 方法名称
+    action: String,
+    // 路径
+    url: String,
+    // 图标类名
+    iconClass: String,
+    // 父级id(初始默认0为父级)
+    pid: {
+        type: Number,
+        default: 0
+    },
+    // 是否属于菜单列表里的
+    isMenu: {
+        type: Boolean,
+        default: true
+    },
+    // 创建时间
+    create_time: {
+        type: Number,
+        default: 0
+    },
+};
+mongoose.model(collectionName, new Schema(modelSchema, {versionKey: false, collection: collectionName}));

+ 26 - 0
modules/all_models/permission_group.js

@@ -0,0 +1,26 @@
+/**
+ * 后台管理权限组数据模型
+ *
+ * @author EllisRan
+ * @date 2018/12/06
+ * @version
+ */
+import mongoose from "mongoose";
+
+let Schema = mongoose.Schema;
+let collectionName = 'permission_group';
+let modelSchema = {
+    // 组名
+    name: {
+        type: String,
+        index: true
+    },
+    // 权限ID JSON列表
+    permission: String,
+    // 创建时间
+    create_time: {
+        type: Number,
+        default: 0
+    },
+};
+mongoose.model(collectionName, new Schema(modelSchema, {versionKey: false, collection: collectionName}));

+ 37 - 17
modules/common/base/base_controller.js

@@ -8,7 +8,7 @@
 import crypto from "crypto";
 import Url from "url";
 import Moment from "moment";
-import menuData from "../../../config/menu";
+// import menuData from "../../../config/menu";
 
 class BaseController {
 
@@ -65,35 +65,55 @@ class BaseController {
             console.log('enterINit');
             // 如果不适超级管理员则判断权限
             let sessionManager = request.session.managerData;
+            let MenuPermission = sessionManager.menuData;
             if (sessionManager.superAdmin !== 1) {
-                let currentPermission = sessionManager.permission;
-                // 校验权限
+                let currentPermission = sessionManager.toolPermission;
+                // MenuPermission = sessionManager.menuData;
+                // 校验权限 暂时只检测能否使用该controller名称的总权限,不细分
                 currentPermission = currentPermission.split(',');
                 let withoutPermission = ['login', 'dashboard'];
-                // 工具页面整合
-                let toolPermission = ['rationRepository', 'stdBillsmain', 'stdGljRepository'];
-                let hasToolPermission = false;
-                if (controller === 'tool') {
-                    for (let tmpPermission of toolPermission) {
-                        if (currentPermission.indexOf(tmpPermission) >= 0) {
-                            hasToolPermission = true;
-                            break;
-                        }
+
+                // 工具
+                let toolAllPermission = sessionManager.toolAllPermission;
+                toolAllPermission = toolAllPermission.split(',');
+                // let toolAllPermission = ['stdBillsmain', 'rationRepository', 'rpt_tpl', 'stdGljRepository',
+                //     'billsGuidance', 'clearJunk', 'billsTemplate', 'mainTreeCol',
+                //     'materialReplace', 'projectFeature', 'feeRate', 'calcProgram'];
+                let hasToolPermission = true;
+                if (toolAllPermission.indexOf(controller) >= 0 && currentPermission.indexOf(controller) < 0) {
+                    hasToolPermission = false;
+                }
+
+                let currentControllerPermission = '';
+                // let currentActionPermission = true;
+
+                if(withoutPermission.indexOf(controller) < 0) {
+                    if (MenuPermission.hasOwnProperty(controller)) {
+                        currentControllerPermission = MenuPermission[controller];
+
                     }
+
+                    // if (currentControllerPermission !== '' && action !== 'index') {
+                    //     if (currentControllerPermission.children.hasOwnProperty(action)) {
+                    //         currentActionPermission = true;
+                    //     }
+                    // } else if (action === 'index') {
+                    //     currentActionPermission = true
+                    // }
                 }
 
-                if (!hasToolPermission && withoutPermission.indexOf(controller) < 0 &&
-                    (currentPermission.length <= 0 || currentPermission.indexOf(controller)) < 0) {
+                if (withoutPermission.indexOf(controller) < 0 &&
+                    !(hasToolPermission || currentControllerPermission !== '')) {
 
                     throw '没有权限';
                 }
             }
 
             // 菜单数据
-            response.locals.menu = menuData;
+            response.locals.menu = MenuPermission;
             // 二级菜单数据
-            response.locals.secondMenu = menuData[controller] !== undefined && menuData[controller].children !== undefined ?
-                menuData[controller].children : {};
+            response.locals.secondMenu = MenuPermission[controller] !== undefined && MenuPermission[controller].children !== undefined ?
+                MenuPermission[controller].children : {};
 
             // url相关数据
             response.locals.urlQuery = JSON.stringify(urlInfo.query);

+ 132 - 1
modules/users/controllers/login_controller.js

@@ -7,6 +7,8 @@
  */
 import BaseController from "../../common/base/base_controller";
 import ManagerModel from "../models/manager_model";
+import PermissionModel from "../models/permission_model";
+import PermissionGroupModel from "../models/permission_group_model";
 import crypto from "crypto";
 
 import Test1Model from "../../../test/models/test1_model";
@@ -44,6 +46,8 @@ class LoginController extends BaseController {
         let username = request.body.username;
         let password = request.body.password;
         let managerModel = new ManagerModel();
+        let permissionModel = new PermissionModel();
+        let permissionGroupModel = new PermissionGroupModel();
 
         let responseData = {
             error: 0,
@@ -56,13 +60,140 @@ class LoginController extends BaseController {
             let currentTime = new Date().getTime();
             let sessionToken = crypto.createHmac('sha1', currentTime + '').update(managerData.username)
                 .digest().toString('base64');
+
+            // 对权限进行管理分类
+            let menuData = {
+                'dashboard': {
+                    title: '首页',
+                    url: '/dashboard',
+                    name: 'dashboard',
+                    iconClass: 'glyphicon glyphicon-home'
+                }
+            };
+            let toolMenuData = [];
+            let toolPermissionController = [];
+            if (managerData.super_admin !== 1) {
+                let permissionGroup = managerData.permission !== undefined && managerData.permission !== '' ?
+                    await permissionGroupModel.findDataByCondition({_id: managerData.permission}) : '';
+                // let otherPermission = [];
+                if (permissionGroup !== undefined && permissionGroup !== '' && permissionGroup.permission !== undefined && permissionGroup.permission !== '') {
+                    let permissionIdList = JSON.parse(permissionGroup.permission);
+                    for (let top of permissionIdList.top) {
+                        let permissionInfo = await permissionModel.findDataByCondition({_id:top});
+                        menuData[permissionInfo.controller] = {
+                            title: permissionInfo.name,
+                            url: permissionInfo.url,
+                            name: permissionInfo.controller,
+                            iconClass: 'glyphicon ' + permissionInfo.iconClass,
+                            children: {},
+                        }
+                    }
+                    for (let per in permissionIdList) {
+                        if (per !== 'top' && per !== 'tool') {
+                            let permissionArray = permissionIdList[per];
+                            for (let pa of permissionArray) {
+                                let permissionInfo = await permissionModel.findDataByCondition({_id:pa});
+                                if (permissionInfo !== undefined && permissionInfo !== '') {
+                                    if (permissionInfo.isMenu) {
+                                        // 属于二级菜单
+                                        let action = {
+                                            title: permissionInfo.name,
+                                            url: permissionInfo.url,
+                                            name: permissionInfo.action,
+                                        };
+                                        menuData[permissionInfo.controller].children[permissionInfo.action] = action;
+                                    } else {
+                                        // 其它权限
+                                        // otherPermission.push({
+                                        //     title: permissionInfo.name,
+                                        //     url: permissionInfo.url,
+                                        //     name: permissionInfo.action,
+                                        // });
+                                    }
+                                }
+                            }
+                        } else if (per === 'tool') {
+                            // 工具里的页面权限
+                            let permissionArray = permissionIdList[per];
+                            for (let pa of permissionArray) {
+                                let permissionInfo = await permissionModel.findDataByCondition({_id:pa});
+                                if (permissionInfo.isMenu) {
+                                    toolMenuData.push({
+                                        title: permissionInfo.name,
+                                        controller: permissionInfo.controller,
+                                        url: permissionInfo.url,
+                                        sort: permissionInfo.ID  // 用来排序
+                                    });
+                                }
+                                toolPermissionController.push(permissionInfo.controller);
+                                // 对于工具里的多个控制层进行优化处理
+                                if (permissionInfo.otherController !== undefined && permissionInfo.otherController !== '') {
+                                    for (let other of permissionInfo.otherController.split(',')) {
+                                        toolPermissionController.push(other);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            } else {
+                // 获取数据库菜单列表
+                let menuPermissionList = await permissionModel.getList({isMenu:true});
+                for (let menu of menuPermissionList) {
+                    if (menu.pid === 0) {
+                        menuData[menu.controller] = {
+                            title: menu.name,
+                            url: menu.url,
+                            name: menu.controller,
+                            iconClass: 'glyphicon ' + menu.iconClass,
+                            children: {},
+                        }
+                    } else if (menu.pid !== 4) {
+                        let action = {
+                            title: menu.name,
+                            url: menu.url,
+                            name: menu.action,
+                        };
+                        menuData[menu.controller].children[menu.action] = action;
+                    }
+                }
+                // 超级管理员二级菜单添加
+                menuData['manager'].children['admin'] = {
+                    title: '超级管理员',
+                    url: '/manager/admin',
+                    name: 'admin',
+                }
+            }
+            // 获取所有工具里的权限控制器名称
+            let toolAllPermission = [];
+            let toolAllPermissionList = await permissionModel.getList({pid:4});
+            for (let tool of toolAllPermissionList) {
+                toolAllPermission.push(tool.controller);
+                if (managerData.super_admin === 1) {
+                    toolMenuData.push({
+                        title: tool.name,
+                        controller: tool.controller,
+                        url: tool.url,
+                        sort: tool.ID  // 用来排序
+                    });
+                }
+                if (tool.otherController !== undefined && tool.otherController !== '') {
+                    for (let other of tool.otherController.split(',')) {
+                        toolAllPermission.push(other);
+                    }
+                }
+            }
+
             let managerSession = {
                 username: managerData.username,
                 real_name:managerData.real_name,
                 loginTime: currentTime,
                 sessionToken: sessionToken,
                 userID: managerData.id,
-                permission: managerData.permission === undefined ? '' : managerData.permission,
+                toolPermission: toolPermissionController.join(','),
+                toolMenuData: toolMenuData,
+                toolAllPermission: toolAllPermission.join(','),
+                menuData: menuData,
                 superAdmin: managerData.super_admin
             };
             request.session.managerData = managerSession;

+ 276 - 45
modules/users/controllers/manager_controller.js

@@ -7,8 +7,11 @@
  */
 import BaseController from "../../common/base/base_controller";
 import ManagerModel from "../models/manager_model";
+import PermissionModel from "../models/permission_model";
+import PermissionGroupModel from "../models/permission_group_model";
 import Config from "../../../config/config";
 let config = require("../../../config/config.js");
+import {default as category, List as categoryList} from "../../common/const/category_const.js";
 
 class ManagerController extends BaseController {
 
@@ -22,10 +25,12 @@ class ManagerController extends BaseController {
     async index(request, response) {
         let pageData = {};
         let managerList = [];
+        let permissionGroupList = [];
+        let filter = request.query;
         try {
             // 查找管理员用户列表
             let managerModel = new ManagerModel();
-            let total = await managerModel.count();
+            let total = await managerModel.count({super_admin: 0});
 
             // 分页数据
             let page = request.query.page === undefined ? 1 : request.query.page;
@@ -36,76 +41,128 @@ class ManagerController extends BaseController {
             };
 
             // 获取管理员列表
-            managerList = await managerModel.getList(null, page);
+            let condition = managerModel.getFilterCondition(request);
+            condition.super_admin = 0;
+            managerList = JSON.parse(JSON.stringify(await managerModel.getList(condition, page)));
 
-            // 整理数据
-            if (managerList.length > 0) {
-                for (let tmp in managerList) {
-                    let permission = managerList[tmp].permission;
-                    permission = permission.split(',');
+            let permissionGroupModel = new PermissionGroupModel();
+            let permissionModel = new PermissionModel();
 
-                    if (permission.length <= 0) {
-                        continue;
-                    }
+            // 添加特定数据到filter里
+            if (request.query.office !== undefined && request.query.office !== '') {
+                let officeInfo = await categoryList.find(function (item) {
+                    return item.id === parseInt(request.query.office);
+                });
+                filter.officeName = officeInfo.name
+            }
+            if (request.query.permission !== undefined && request.query.permission !== '0') {
+                let permissionGroupInfo = await permissionGroupModel.findDataByCondition({_id: request.query.permission});
+                filter.permissionGroupName = permissionGroupInfo.name;
+            }
 
-                    let permissionString = [];
-                    for (let name of permission) {
-                        if (managerModel.permission[name] === undefined) {
-                            continue;
+            // 获取权限组列表
+            permissionGroupList = JSON.parse(JSON.stringify(await permissionGroupModel.getList()));
+            if (permissionGroupList.length > 0) {
+                for (let tmp in permissionGroupList) {
+                    let topPermissionList = [];
+                    if (permissionGroupList[tmp].permission !== undefined && permissionGroupList[tmp].permission !== '') {
+                        let groupPermissionList = JSON.parse(permissionGroupList[tmp].permission);
+                        for (let p in groupPermissionList) {
+                            if (p === 'top') {
+                                for (let t of groupPermissionList[p]) {
+                                    let topInfo = await permissionModel.findDataByCondition({_id:t});
+                                    topPermissionList.push(topInfo.name);
+                                }
+                                break;
+                            }
                         }
-                        permissionString.push(managerModel.permission[name]);
                     }
-                    permissionString = permissionString.join(',');
-                    managerList[tmp].permissionStr = permissionString;
+                    permissionGroupList[tmp].top_name = topPermissionList.join(',');
                 }
             }
-        } catch (error) {
 
+            // 整理数据
+            if (managerList.length > 0) {
+                for (let tmp in managerList) {
+                    let cate = await categoryList.find(function (item) {
+                        return item.id === managerList[tmp].office;
+                    });
+                    managerList[tmp].officeName = cate !== undefined ? cate.name : '';
+
+                    let groupInfo = managerList[tmp].permission !== '' ? await permissionGroupModel.findDataByCondition({_id:managerList[tmp].permission}) : '';
+                    managerList[tmp].permissionName = groupInfo !== undefined && groupInfo !== '' ? groupInfo.name : '';
+                }
+            }
+        } catch (error) {
+            console.log(error);
         }
 
+        let permissionGroupList2 = JSON.stringify(permissionGroupList);
         let renderData = {
             managerList: managerList,
             pages: pageData,
+            categoryList: categoryList,
+            permissionGroupList: permissionGroupList,
+            permissionGroupList2: permissionGroupList2,
             layout: 'users/views/layout/layout',
+            filter: filter,
             LicenseKey:config.getLicenseKey(process.env.NODE_ENV)
         };
         response.render('users/views/manager/index', renderData);
     }
 
     /**
+     * 权限组分配(管理员页面)
+     * @param request
+     * @param response
+     * @return {Promise.<void>}
+     */
+    async groupSave(request, response) {
+        let id = request.body.manager_id;
+        let permission = request.body.permission !== '0' ? request.body.permission : '';
+        let managerModel = new ManagerModel();
+        let result = await managerModel.updateById(id, {permission: permission});
+
+        if (!result) {
+            throw '修改失败';
+        }
+        response.redirect(request.headers.referer);
+    }
+
+    /**
      * 保存管理员
      *
      * @param {object} request
      * @param {object} response
      * @return {void}
      */
-    async modify(request, response) {
-        let permission = request.body.permission;
-        let canLogin = request.body.login;
-        let id = request.params.id;
-
-        let responseData = {
-            err: 0,
-            msg: ""
-        };
-        try {
-            if (id === '' || id === undefined) {
-                throw 'id有误';
-            }
-            let managerModel = new ManagerModel();
-            let result = await managerModel.updateById(id, {permission: permission, can_login: canLogin});
-
-            if (!result) {
-                throw '修改失败';
-            }
-
-        } catch (error) {
-            responseData.err = 1;
-            responseData.msg = error;
-        }
-
-        response.json(responseData);
-    }
+    // async modify(request, response) {
+    //     let permission = request.body.permission;
+    //     let canLogin = request.body.login;
+    //     let id = request.params.id;
+    //
+    //     let responseData = {
+    //         err: 0,
+    //         msg: ""
+    //     };
+    //     try {
+    //         if (id === '' || id === undefined) {
+    //             throw 'id有误';
+    //         }
+    //         let managerModel = new ManagerModel();
+    //         let result = await managerModel.updateById(id, {permission: permission, can_login: canLogin});
+    //
+    //         if (!result) {
+    //             throw '修改失败';
+    //         }
+    //
+    //     } catch (error) {
+    //         responseData.err = 1;
+    //         responseData.msg = error;
+    //     }
+    //
+    //     response.json(responseData);
+    // }
 
     /**
      * 删除管理员
@@ -127,6 +184,27 @@ class ManagerController extends BaseController {
     }
 
     /**
+     * 操作管理员(启用和停用)
+     *
+     * @param {object} request
+     * @param {object} response
+     * @return {void}
+     */
+    async modify(request, response) {
+        let canLogin = request.params.login;
+        let id = request.params.id;
+
+        let managerModel = new ManagerModel();
+        let result = await managerModel.updateById(id, {can_login: canLogin});
+
+        // 修改成功
+        if (!result) {
+            throw '修改失败';
+        }
+        response.redirect(request.headers.referer);
+    }
+
+    /**
      * 超级管理员修改
      *
      * @param {object} request
@@ -192,6 +270,159 @@ class ManagerController extends BaseController {
         // let result = await managerModel.createManager();
         response.end('success');
     }
+
+    /**
+     * 权限组页面
+     * @param request
+     * @param response
+     * @return {Promise.<void>}
+     */
+    async authority(request, response) {
+        let pageData = {};
+        let groupList = [];
+        let topPermissionList = [];
+        let permissionList = [];
+        try {
+            // 获取最高级权限列表
+            let permissionModel = new PermissionModel();
+            topPermissionList = await permissionModel.getList({pid:0});
+
+            // 获取所有权限列表,按排序
+            permissionList = topPermissionList;
+            for (let index in permissionList) {
+                let count = await permissionModel.count({pid:permissionList[index].ID});
+                if (count > 0) {
+                    permissionList[index].secondPermissionList = await permissionModel.getList({pid: permissionList[index].ID});
+                } else {
+                    permissionList[index].secondPermissionList = [];
+                }
+                permissionList[index].count = count;
+            }
+
+            // 获取权限组列表
+            let permissionGroupModel = new PermissionGroupModel();
+            let total = await permissionGroupModel.count();
+
+            // 分页数据
+            let page = request.query.page === undefined ? 1 : request.query.page;
+            pageData = {
+                current: page,
+                total: parseInt(total / Config.pageSize),
+                queryData: response.locals.urlQuery
+            };
+
+            // 获取管理员列表
+            groupList = JSON.parse(JSON.stringify(await permissionGroupModel.getList(null, page)));
+
+            // 整理数据
+            if (groupList.length > 0) {
+                let managerModel = new ManagerModel();
+                for (let tmp in groupList) {
+                    let managerCount = await managerModel.count({permission: groupList[tmp]._id});
+                    groupList[tmp].manager_count = managerCount;
+                    let groupPermissionList = JSON.parse(groupList[tmp].permission);
+                    for (let p in groupPermissionList) {
+                        if (p === 'top') {
+                            let topPermissionList = [];
+                            for (let t of groupPermissionList[p]) {
+                                let topInfo = await permissionModel.findDataByCondition({_id:t});
+                                topPermissionList.push(topInfo.name);
+                            }
+                            groupList[tmp].top_name = topPermissionList.join(',');
+                        }
+                    }
+                }
+            }
+        } catch (error) {
+
+        }
+        let renderData = {
+            groupList: groupList,
+            topPermissionList: topPermissionList,
+            permissionList: permissionList,
+            pages: pageData,
+            layout: 'users/views/layout/layout',
+            LicenseKey:config.getLicenseKey(process.env.NODE_ENV)
+        };
+        response.render('users/views/manager/authority', renderData);
+    }
+
+    /**
+     * 权限组添加
+     * @param request
+     * @param response
+     * @return {Promise.<void>}
+     */
+    async authorityAdd(request, response) {
+        let permissionGroupModel = new PermissionGroupModel();
+        let result = await permissionGroupModel.createPermissionGroup(request.body);
+        if (!result) {
+            throw '添加失败';
+        }
+        response.redirect(request.headers.referer);
+    }
+
+    /**
+     * 权限组修改保存
+     * @param request
+     * @param response
+     * @return {Promise.<void>}
+     */
+    async authoritySave(request, response) {
+        let permissionGroupModel = new PermissionGroupModel();
+        let result = await permissionGroupModel.savePermissionGroup(request.body);
+        if (!result) {
+            throw '修改失败';
+        }
+        response.redirect(request.headers.referer);
+    }
+
+    /**
+     * 权限组删除
+     * @param request
+     * @param response
+     * @return {Promise.<void>}
+     */
+    async authorityDelete(request, response) {
+        let id = request.body.id;
+        try {
+            let permissionGroupModel = new PermissionGroupModel();
+            await permissionGroupModel.deleteById(id, true);
+            // 并清空用户所在权限组
+            let managerModel = new ManagerModel();
+            await managerModel.updateByPermission(id);
+        } catch(err) {
+            throw err;
+        }
+        response.redirect(request.headers.referer);
+    }
+
+    /**
+     * 权限添加接口
+     * @param request
+     * @param response
+     * @return {Promise.<void>}
+     */
+    async permissionAdd(request, response) {
+        let permissionModel = new PermissionModel();
+        let responseData = {
+            err: 0,
+            msg: ''
+        };
+        try {
+            permissionModel.setScene('insert');
+            let result = await permissionModel.createPermission(request.body);
+            if (!result) {
+                throw '添加失败';
+            }
+        } catch (error) {
+            console.log(error);
+            responseData.err = 1;
+            responseData.msg = error;
+        }
+
+        response.json(responseData);
+    }
 }
 
 export default ManagerController;

+ 3 - 0
modules/users/controllers/tool_controller.js

@@ -18,8 +18,11 @@ class ToolController extends BaseController {
      * @return {void}
      */
     index(request, response) {
+        let toolMenuData = request.session.managerData.toolMenuData;
+        console.log(toolMenuData);
         let renderData = {
             layout: 'users/views/layout/layout',
+            toolMenu: toolMenuData,
             LicenseKey:config.getLicenseKey(process.env.NODE_ENV)
         };
         response.render('users/views/tool/index', renderData);

+ 19 - 3
modules/users/controllers/user_controller.js

@@ -62,15 +62,22 @@ class UserController extends BaseController {
                 total: Math.ceil(total / Config.pageSize),
                 queryData: response.locals.urlQuery
             };
-            console.log("取用户信息=========================");
-            console.log(condition);
+            // console.log("取用户信息=========================");
+            // console.log(condition);
             // 获取用户列表
             userList = await userModel.getList(condition, page, Config.pageSize);
-            console.log(userList)
+            // console.log(userList)
         } catch (error) {
             console.log(error);
         }
 
+        // 用户管理二级菜单独立出来
+        let secondMenu = response.locals.secondMenu;
+        let userMenu = [];
+        for (let second in secondMenu) {
+            userMenu.push(secondMenu[second]);
+        }
+
         // 渲染数据
         let renderData = {
             compilationList:compilationList,
@@ -82,6 +89,7 @@ class UserController extends BaseController {
             total: total,
             filter: filter,
             model: userModel,
+            userMenu: userMenu,
             layout: 'users/views/layout/layout',
             LicenseKey:config.getLicenseKey(process.env.NODE_ENV)
         };
@@ -137,6 +145,13 @@ class UserController extends BaseController {
             console.log(error);
         }
 
+        // 用户管理二级菜单独立出来
+        let secondMenu = response.locals.secondMenu;
+        let userMenu = [];
+        for (let second in secondMenu) {
+            userMenu.push(secondMenu[second]);
+        }
+
         // 渲染数据
         let renderData = {
             compilationList:compilationList,
@@ -148,6 +163,7 @@ class UserController extends BaseController {
             total: total,
             filter: filter,
             model: userModel,
+            userMenu: userMenu,
             layout: 'users/views/layout/layout',
             LicenseKey:config.getLicenseKey(process.env.NODE_ENV)
         };

+ 35 - 3
modules/users/models/manager_model.js

@@ -65,7 +65,28 @@ class ManagerModel extends BaseModel {
     }
 
     /**
-     * 获取列表
+     * 获取过滤条件
+     *
+     * @return {Object}
+     */
+    getFilterCondition(request) {
+        let condition = {};
+        let office = request.query.office;
+        if (office !== '' && office !== undefined) {
+            condition.office = parseInt(office);
+        }
+
+        let permission = request.query.permission;
+        if (permission !== undefined) {
+            // 0 :权限为空的情况
+            condition.permission = permission === '0' ? '' : permission;
+        }
+
+        return condition;
+    }
+
+    /**
+     * 获取按创建时间倒序列表
      *
      * @param {object} condition
      * @param {number} page
@@ -74,7 +95,7 @@ class ManagerModel extends BaseModel {
     getList(condition = null, page = 1) {
         page = parseInt(page);
         page = page <= 1 ? 1 : page;
-        let option = {page: page};
+        let option = {page: page, sort: {create_time:-1}};
         return this.db.find(condition, null, option);
     }
 
@@ -205,7 +226,7 @@ class ManagerModel extends BaseModel {
             last_login: current,
             office: responseData.office,
             position: responseData.position,
-            permission: 'user',
+            permission: '',
             can_login: 1
         };
         result = this.db.create(insertData);
@@ -275,6 +296,17 @@ class ManagerModel extends BaseModel {
         return result;
     }
 
+    /**
+     * 删除后台用户权限
+     * @param permission
+     * @return {Promise.<void>}
+     */
+    async updateByPermission(permission) {
+        let result = await this.db.update({permission: permission}, {permission: ''});
+
+        return result.ok === 1;
+    }
+
 }
 
 export default ManagerModel;

+ 120 - 0
modules/users/models/permission_group_model.js

@@ -0,0 +1,120 @@
+/**
+ * 后台权限组数据模型
+ *
+ * @author EllisRan
+ * @date 2018/12/07
+ * @version
+ */
+import mongoose from "mongoose";
+import BaseModel from "../../common/base/base_model";
+
+class PermissionGroupModel extends BaseModel {
+
+    /**
+     * 构造函数
+     *
+     * @return {void}
+     */
+    constructor() {
+        let parent = super();
+        parent.model = mongoose.model('permission_group');
+        parent.init();
+    }
+
+    /**
+     * 新增权限
+     *
+     * @param {Object} data
+     * @return {Promise}
+     */
+    async createPermission(data) {
+        if (Object.keys(data).length <= 0) {
+            throw '数据格式错误';
+        }
+        data.create_time = new Date().getTime();
+        let result = await this.db.create(data);
+
+        return result;
+    }
+
+    /**
+     * 获取列表
+     *
+     * @param {object} condition
+     * @param {number} page
+     * @return {Promise}
+     */
+    async getList(condition = null, page = 1, pageSize = 30) {
+        page = parseInt(page);
+        page = page <= 1 ? 1 : page;
+        let option = {pageSize: pageSize, offset: parseInt((page - 1) * pageSize)};
+        console.log(condition);
+        let list = await this.db.find(condition, null, option);
+        list = list.length > 0 ? list : [];
+
+        return list;
+    }
+
+    /**
+     * 根据条件返回数据数量
+     *
+     * @param {object} condition
+     * @return {Promise}
+     */
+    async count(condition = null) {
+        let total = 0;
+        try {
+            total = await this.db.count(condition);
+        } catch (error) {
+            total = 0;
+        }
+        return total;
+    }
+
+    /**
+     * 新增权限组
+     *
+     * @param {Object} data
+     * @return {Promise}
+     */
+    async createPermissionGroup(data) {
+        if (Object.keys(data).length <= 0) {
+            throw '数据格式错误';
+        }
+        data.create_time = new Date().getTime();
+        let result = await this.db.create(data);
+
+        return result;
+    }
+
+    /**
+     * 修改权限组
+     *
+     * @param {Object} data
+     * @return {Promise}
+     */
+    async savePermissionGroup(data) {
+        if (Object.keys(data).length <= 0) {
+            throw '数据格式错误';
+        }
+        let permission = {
+            top: data.topPermission !== undefined ? data.topPermission : [],
+        };
+        for (let index in data) {
+            if (index.indexOf('permission_') > -1) {
+                let key = index.split('_')[1];
+                permission[key] = data[index];
+            }
+        }
+        let postData = {
+            name: data.name,
+            permission: JSON.stringify(permission),
+        };
+        let result = await this.updateById(data.id, postData);
+
+        return result;
+    }
+
+}
+
+export default PermissionGroupModel;

+ 77 - 0
modules/users/models/permission_model.js

@@ -0,0 +1,77 @@
+/**
+ * 后台权限数据模型
+ *
+ * @author EllisRan
+ * @date 2018/12/06
+ * @version
+ */
+import mongoose from "mongoose";
+import BaseModel from "../../common/base/base_model";
+
+class PermissionModel extends BaseModel {
+
+    /**
+     * 构造函数
+     *
+     * @return {void}
+     */
+    constructor() {
+        let parent = super();
+        parent.model = mongoose.model('permission');
+        parent.init();
+    }
+    /**
+     * 设置场景
+     *
+     * @param {string} scene
+     * @return {void}
+     */
+    setScene(scene = '') {
+        switch (scene) {
+            // 新增权限
+            case 'insert':
+                // this.model.schema.path('ID').required(true);
+                this.model.schema.path('name').required(true);
+                this.model.schema.path('controller').required(true);
+                this.model.schema.path('url').required(true);
+                this.model.schema.path('pid').required(true);
+                break;
+        }
+    }
+
+    /**
+     * 新增权限
+     *
+     * @param {Object} data
+     * @return {Promise}
+     */
+    async createPermission(data) {
+        if (Object.keys(data).length <= 0) {
+            throw '数据格式错误';
+        }
+        data.create_time = new Date().getTime();
+        let result = await this.db.create(data);
+
+        return result;
+    }
+
+    /**
+     * 获取列表
+     *
+     * @param {object} condition
+     * @param {number} page
+     * @return {Promise}
+     */
+    async getList(condition = null, page = 1, pageSize = 30) {
+        page = parseInt(page);
+        page = page <= 1 ? 1 : page;
+        let option = {pageSize: pageSize, offset: parseInt((page - 1) * pageSize), sort: {ID:1}};
+        let list = await this.db.find(condition, null, option);
+        list = list.length > 0 ? list : [];
+
+        return list;
+    }
+
+}
+
+export default PermissionModel;

+ 1 - 1
modules/users/models/user_model.js

@@ -85,7 +85,7 @@ class UserModel extends BaseModel {
     async getList(condition = null, page = 1, pageSize = 30) {
         page = parseInt(page);
         page = page <= 1 ? 1 : page;
-        let option = {pageSize: pageSize, offset: parseInt((page - 1) * pageSize)};
+        let option = {pageSize: pageSize, offset: parseInt((page - 1) * pageSize), sort: {_id:-1}};
 
         let userList = await this.db.find(condition, null, option);
         userList = userList.length > 0 ? userList : [];

+ 14 - 2
modules/users/routes/manager_route.js

@@ -16,12 +16,24 @@ module.exports =function (app) {
     // 管理员列表action
     router.get('/', managerController.auth, managerController.init, managerController.index);
     // 修改管理员
-    router.post('/modify/:id', managerController.auth, managerController.init, managerController.modify);
+    // router.post('/modify/:id', managerController.auth, managerController.init, managerController.modify);
     // 删除管理员
-    router.get('/delete/:id',managerController.auth,  managerController.init, managerController.delete);
+    // router.get('/delete/:id',managerController.auth,  managerController.init, managerController.delete);
+    // 管理员权限组分配
+    router.post('/group/save', managerController.auth, managerController.init, managerController.groupSave);
+    // 停用或启用管理员
+    router.get('/modify/:id/:login',managerController.auth,  managerController.init, managerController.modify);
     // 超级管理员action
     router.get('/admin', managerController.auth, managerController.init, managerController.admin);
     router.post('/admin', managerController.auth, managerController.init, managerController.adminSubmit);
+    // 权限组列表
+    router.get('/authority', managerController.auth, managerController.init, managerController.authority);
+    router.post('/authority/add', managerController.auth, managerController.init, managerController.authorityAdd);
+    router.post('/authority/save', managerController.auth, managerController.init, managerController.authoritySave);
+    router.post('/authority/delete', managerController.auth, managerController.init, managerController.authorityDelete);
+
+    // 权限添加接口
+    router.post('/permission/add', managerController.auth, managerController.init, managerController.permissionAdd);
 
     router.get('/create', managerController.create);
 

+ 1 - 1
modules/users/routes/user_route.js

@@ -14,7 +14,7 @@ const userController = new UserController();
 module.exports =function (app) {
     // action定义区域
     router.get('/', userController.auth, userController.init, userController.normalUsers);
-    router.get('/test-user', userController.auth, userController.init, userController.testUsers);
+    router.get('/testUser', userController.auth, userController.init, userController.testUsers);
     router.get('/search', userController.auth, userController.init, userController.search);
     router.post('/findByID', userController.auth, userController.init, userController.findByID);
     router.post('/getUserList', userController.auth, userController.init, userController.getUserList);

+ 110 - 0
web/users/js/manager.js

@@ -77,4 +77,114 @@ $(document).ready(function() {
         });
     });
 
+    // 编辑权限组权限
+    $('.edit_permission').on('click', function () {
+        // 清空权限列表
+        $('#id').val('');
+        $('#title1').val('');
+        $("input[type='checkbox']").prop('checked', false);
+        let group_id = $(this).attr('data-permission-id');
+        let group_name = $(this).attr('data-permission-name');
+        $('#id').val(group_id);
+        $('#title1').val(group_name);
+        if ($(this).attr('data-permission') !== '') {
+            let group_permission = JSON.parse($(this).attr('data-permission'));
+            for (let gp in group_permission) {
+                let plist = group_permission[gp];
+                for (let p of plist) {
+                    $("input[value='"+p+"'").prop('checked', true);
+                }
+            }
+        }
+    });
+
+    // 一级权限选中或取消
+    $("input[name='topPermission[]']").on('click', function () {
+        let id = $(this).attr('id');
+        if($(this).is(':checked')) {
+            // 选中
+            $("input[name='permission_"+id+"[]']").prop('checked', true);
+        } else {
+            // 取消选中
+            $("input[name='permission_"+id+"[]']").prop('checked', false);
+        }
+    });
+
+    // 二级权限选中或取消
+    $("input[name^='permission_']").on('click', function () {
+        let topid = $(this).attr('data-controller');
+        if($(this).is(':checked')) {
+            // 选中
+            $('#'+ topid).prop('checked', true);
+        } else {
+            // 取消选中(排除工具这个独立分离的url)
+            if (topid !== 'tool') {
+                // 不存在选中权限
+                if (!$("input[name='permission_"+ topid +"[]']").is(':checked')) {
+                    $('#'+ topid).prop('checked', false);
+                }
+            }
+        }
+    });
+
+    // 删除权限组传值
+    $('.del_permission').on('click', function () {
+        let id = $(this).data('id');
+        $('#delete_id').val(id);
+    });
+
+    // 账号管理权限组选择
+    $('.edit_group').on('click', function () {
+        let name = $(this).attr('data-name');
+        let id = $(this).attr('data-id');
+        let permission = $(this).attr('data-permission');
+        if (name !== '') {
+            $('#group_name').text(name);
+        } else {
+            $('#group_name').text('未分配');
+        }
+        $('#manager_id').val(id);
+        if (permission !== '') {
+            $('#group_permission').val(permission);
+        } else {
+            $('#group_permission').val(0);
+        }
+        let groupInfo = permissionGroupList.find(function (item) {
+            return item._id === permission;
+        });
+        let top_name = groupInfo !== undefined ? groupInfo.top_name : '';
+        $('#group_permission_name').text(top_name);
+    });
+
+    // 权限组变更时改变
+    $('#group_permission').change(function () {
+        let permission = $(this).val();
+        let groupInfo = permissionGroupList.find(function (item) {
+            return item._id === permission;
+        });
+        let top_name = groupInfo !== undefined ? groupInfo.top_name : '';
+        $('#group_permission_name').text(top_name);
+    });
+
+    // 选择框
+    $(".selector > li > a").click(function() {
+        let value = $(this).data("value");
+        let string = $(this).text();
+        let selector = $(this).parent().parent();
+        selector.next("input:hidden").val(value);
+        selector.prev("button").children("span").eq(0).html(string);
+
+        // 筛选结果跳转
+        console.log($('#office_select').val());
+        console.log($('#permission_select').val());
+        let query = [];
+        if ($('#office_select').val() !== 'all' && $('#office_select').val() !== '') {
+            query.push('office=' + $('#office_select').val());
+        }
+        if ($('#permission_select').val() !== 'all' && $('#permission_select').val() !== '') {
+            query.push('permission=' + $('#permission_select').val());
+        }
+        let requestUrl = query.join('&');
+        window.location.href = requestUrl !== '' ? '/manager?' + requestUrl :  '/manager';
+    });
 });

+ 137 - 0
web/users/views/manager/authority.html

@@ -0,0 +1,137 @@
+<%include ../layout/second_menu.html %>
+<div class="panel-content">
+    <div class="panel-title">
+        <div class="title-main">
+            <h2><%= secondMenu[action].title %>
+                <a href="#add-group" data-toggle="modal" data-target="#add-group" class="btn btn-default btn-sm pull-right">添加新组</a>
+            </h2>
+        </div>
+    </div>
+    <div class="content-wrap">
+        <div class="c-header">
+        </div>
+        <div class="c-body">
+            <table class="table table-hover">
+                <thead>
+                <tr>
+                    <th>组名</th>
+                    <th>权限</th>
+                    <th>使用账号</th>
+                    <th width="100">操作</th>
+                </tr>
+                </thead>
+                <tbody>
+                <% for (let group of groupList) { %>
+                <tr>
+                    <td><%= group.name %></td>
+                    <td><%= group.top_name %></td>
+                    <td><%= group.manager_count %></td>
+                    <td>
+                        <a href="#edit-group" class="edit_permission btn btn-xs"
+                           data-permission-id="<%= group._id %>"
+                           data-permission-name="<%= group.name %>"
+                           data-permission="<%= group.permission %>" data-toggle="modal" data-target="#edit-group">编辑</a>
+                        <a href="#del-group" data-id="<%= group._id %>" class="del_permission btn btn-xs text-danger" data-toggle="modal" data-target="#del-group">删除</a>
+                    </td>
+                </tr>
+                <% } %>
+                </tbody>
+            </table>
+            <nav aria-label="Page navigation">
+                <%include ../layout/page.html %>
+            </nav>
+        </div>
+    </div>
+</div>
+
+<script type="text/javascript" src="/web/users/js/manager.js"></script>
+<!-- 编辑组 -->
+<div class="modal fade" id="edit-group" tabindex="-1" role="dialog">
+    <div class="modal-dialog" role="document">
+        <form method="post" action="/manager/authority/save">
+            <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" id="myModalLabel1">编辑权限组</h4>
+                </div>
+                <div class="modal-body">
+                    <div class="form-group">
+                        <label for="title">组名</label>
+                        <input class="form-control" type="text" id="title1" name="name" placeholder="输入组名" value="">
+                        <input type="hidden" id="id" name="id" value="">
+                    </div>
+                    <div class="form-group">
+                        <label for="title">权限</label>
+                        <div class="checkbox" id="top_permission">
+                            <% for(let permission of topPermissionList){ %>
+                            <label><input type="checkbox" name="topPermission[]" id="<%= permission.controller %>" value="<%= permission._id %>"> <%= permission.name %> </label>&nbsp;
+                            <% } %>
+                        </div>
+                    </div>
+                    <!--打勾管理二级权限-->
+                    <% for (let permission of permissionList) { %>
+                    <% if (permission.count > 0) { %>
+                    <div class="form-group">
+                        <label for="title"><%= permission.name %>二级权限</label>
+                        <div class="checkbox" id="<%= permission.controller %>_permission">
+                            <% for(let second of permission.secondPermissionList){ %>
+                            <label>
+                                <input type="checkbox" data-controller="<%= permission.controller %>" name="permission_<%= permission.controller %>[]" value="<%= second._id %>"> <%= second.name %>
+                            </label>&nbsp;
+                            <% } %>
+                        </div>
+                    </div>
+                    <% } %>
+                    <% } %>
+                </div>
+                <div class="modal-footer">
+                    <button type="submit" class="btn btn-primary">确定</button>
+                </div>
+            </div>
+        </form>
+    </div>
+</div>
+<!-- 添加组 -->
+<div class="modal fade" id="add-group" tabindex="-1" role="dialog">
+    <div class="modal-dialog" role="document">
+        <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" id="myModalLabel2">添加新组</h4>
+            </div>
+            <form action="/manager/authority/add" method="post">
+                <div class="modal-body">
+                    <div class="form-group">
+                        <label for="title">组名</label>
+                        <input class="form-control" id="title" name="name" placeholder="输入组名">
+                    </div>
+                </div>
+                <div class="modal-footer">
+                    <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
+                    <button type="sumbit" class="btn btn-primary" >确认</button>
+                </div>
+            </form>
+        </div>
+    </div>
+</div>
+<!-- 删除组 -->
+<div class="modal fade" id="del-group" tabindex="-1" role="dialog">
+    <div class="modal-dialog" role="document">
+        <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" id="myModalLabel3">删除组</h4>
+            </div>
+            <div class="modal-body">
+                <h4>删除后,相关账号将无法正常使用。</h4>
+            </div>
+            <form action="/manager/authority/delete" method="post">
+                <input type="hidden" id="delete_id" name="id" value="">
+                <div class="modal-footer">
+                    <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
+                    <button type="submit" class="btn btn-danger" >确认删除</button>
+                </div>
+            </form>
+        </div>
+    </div>
+</div>

+ 82 - 16
web/users/views/manager/index.html

@@ -11,21 +11,38 @@
             <div class="btn-group">
                 <button type="button" class="btn btn-default dropdown-toggle btn-sm" data-toggle="dropdown"
                         aria-haspopup="true" aria-expanded="false">
-                    办事处 <span class="caret"></span>
+                    办事处:<span><%= filter.office === undefined ? '所有' : filter.officeName %></span> <span class="caret"></span>
                 </button>
-                <ul class="dropdown-menu">
-                    <li><a href="#">广东办</a></li>
-                    <li><a href="#">总部</a></li>
+                <ul class="dropdown-menu selector">
+                    <li><a href="javascript:void(0);" data-value="all">所有</a></li>
+                    <% for (let category of categoryList) { %>
+                    <li><a href="javascript:void(0);" data-value="<%= category.id %>"><%= category.name %></a></li>
+                    <% } %>
                 </ul>
+                <input type="hidden" id="office_select" value="<%= filter.office %>" />
+            </div>
+            <div class="btn-group">
+                <button type="button" class="btn btn-default dropdown-toggle btn-sm" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+                    权限组:<span><%= filter.permission === undefined ? '所有' : (filter.permission === '0' ? '未分配' : filter.permissionGroupName) %></span> <span class="caret"></span>
+                </button>
+                <ul class="dropdown-menu selector">
+                    <li><a href="javascript:void(0);" data-value="all">所有</a></li>
+                    <li><a href="javascript:void(0);" data-value="0">未分配</a></li>
+                    <% for (let pg of permissionGroupList) { %>
+                    <li><a href="javascript:void(0);" data-value="<%= pg._id %>"><%= pg.name %></a></li>
+                    <% } %>
+                </ul>
+                <input type="hidden" id="permission_select" value="<%= filter.permission %>" />
             </div>
         </div>
         <div class="c-body">
             <table class="table">
                 <thead>
                 <tr>
-                    <th>姓名</th>
+                    <th>姓名(CLD)</th>
                     <th>办事处</th>
-                    <th>权限</th>
+                    <th>权限组</th>
+                    <th>状态</th>
                     <th width="100">操作</th>
                 </tr>
                 </thead>
@@ -33,16 +50,14 @@
                 <% managerList.forEach(function(manager) { %>
                 <tr>
                     <td><%= manager.username %></td>
-                    <td><%= manager.office %></td>
-                    <td><%= manager.permissionStr %></td>
-                    <td>
-                        <a href="javascript:void(0);" class="edit btn btn-xs"
-                            data-permission="<%= manager.permission %>" data-login="<%= manager.can_login %>"
-                            data-id="<%= manager._id %>">编辑</a>
-                        <% if (manager.super_admin !== 1) { %>
-                        <a href="/manager/delete/<%= manager._id %>" class="btn btn-xs">删除</a>
-                        <% } %>
-                    </td>
+                    <td><%= manager.officeName %></td>
+                    <td><a href="#updatea" class="edit_group" data-id="<%= manager._id %>" data-name="<%= manager.permissionName %>" data-permission="<%= manager.permission %>" data-toggle="modal" data-target="#group"><% if (manager.permission !== '') { %><%= manager.permissionName %><% } else { %>未分配<% } %></a></td>
+                    <% if (manager.can_login === 1) { %>
+                    <td>正常</td>
+                    <% } else { %>
+                    <td class="text-danger"><i class="glyphicon glyphicon-minus-sign"></i> 停用</td>
+                    <% } %>
+                    <td><% if (manager.can_login === 1) { %><a href="/manager/modify/<%= manager._id %>/0" class="text-danger">停用</a><% } else { %><a href="/manager/modify/<%= manager._id %>/1" class="text-success">启用</a><% } %></td>
                 </tr>
                 <% }) %>
                 </tbody>
@@ -53,6 +68,9 @@
         </div>
     </div>
 </div>
+<script type="text/javascript">
+    let permissionGroupList = <%- permissionGroupList2 %>;
+</script>
 <script type="text/javascript" src="/web/users/js/manager.js"></script>
 <div class="modal fade" id="edit-account" tabindex="-1" role="dialog">
     <div class="modal-dialog" role="document">
@@ -96,4 +114,52 @@
             </div>
         </div>
     </div>
+</div>
+<!-- 更新账号 -->
+<div class="modal fade" id="updatea" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
+    <div class="modal-dialog" role="document">
+        <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" id="myModalLabel">CLD账号更新成功</h4>
+            </div>
+            <div class="modal-body">
+                <p>更新了2个账号:张三、王五</p>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-default" data-dismiss="modal">好的</button>
+            </div>
+        </div>
+    </div>
+</div>
+<!-- 权限组 -->
+<div class="modal fade" id="group" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
+    <div class="modal-dialog" role="document">
+        <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" id="myModalLabel2">权限组:<span id="group_name">销售权限</span></h4>
+            </div>
+            <form method="post" action="/manager/group/save">
+            <div class="modal-body">
+                <p>该组包含以下权限:</p>
+                <p id="group_permission_name">用户管理,通知管理,工具,后台管理</p>
+                <div class="form-group">
+                    <label class="title">更换组</label>
+                    <input type="hidden" value="" id="manager_id" name="manager_id">
+                    <select class="form-control" name="permission" id="group_permission">
+                        <option value="0">未分配</option>
+                        <% for (let pg of permissionGroupList) { %>
+                        <option value="<%= pg._id %>"><%= pg.name %></option>
+                        <% } %>
+                    </select>
+                </div>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
+                <button type="submit" class="btn btn-primary">确认修改</button>
+            </div>
+            </form>
+        </div>
+    </div>
 </div>

+ 141 - 133
web/users/views/tool/index.html

@@ -6,97 +6,105 @@
     </div>
     <div class="content-wrap">
         <div class="row">
+            <% for (let tool of toolMenu) { %>
             <div class="col-xs-6 mb-30 ">
                 <div class="c-body">
-                    <h2>清单规则编辑器
-                        <a id="billsLib" href="javascript:void(0);" class="btn btn-primary pull-right">进入</a>
-                    </h2>
-                </div>
-            </div>
-            <div class="col-xs-6 mb-30 ">
-                <div class="c-body">
-                    <h2>定额编辑器
-                        <a id="rationLib" href="javascript:void(0);" class="btn btn-primary pull-right">进入</a>
-                    </h2>
-                </div>
-            </div>
-            <div class="col-xs-6 mb-30 ">
-                <div class="c-body">
-                    <h2>报表模板
-                        <a id="rptTemplate" href="javascript:void(0);" class="btn btn-primary pull-right">进入</a>
-                    </h2>
-                </div>
-            </div>
-            <div class="col-xs-6 mb-30 ">
-                <div class="c-body">
-                    <h2>人材机库
-                        <a id="gljLib" href="javascript:void(0);" class="btn btn-primary pull-right">进入</a>
-                    </h2>
-                </div>
-            </div>
-            <div class="col-xs-6 mb-30 ">
-                <div class="c-body">
-                    <h2>清单指引编辑器
-                        <a id="billsGuidanceLib" href="javascript:void(0);" class="btn btn-primary pull-right">进入</a>
-                    </h2>
-                </div>
-            </div>
-            <div class="col-xs-6 mb-30 ">
-                <div class="c-body">
-                    <h2>清除项目残留数据
+                    <h2><%= tool.title %>
+                        <% if (tool.url === '/sysTools/api/clearJunkData' ) { %>
                         <a id="clearJunkBtn" href="javascript:void(0);" class="btn btn-primary pull-right">清除</a>
-                    </h2>
-                </div>
-            </div>
-            <div class="col-xs-6 mb-30 ">
-                <div class="c-body">
-                    <h2>清除项目假删除数据
+                        <% } else if (tool.url === '/sysTools/api/clearFakeData' ) { %>
                         <a id="clearFakeBtn" href="javascript:void(0);" class="btn btn-primary pull-right">清除</a>
+                        <% } else { %>
+                        <a id="<%= tool.controller %>" href="<%= tool.url %>" target="_blank" class="btn btn-primary pull-right">进入</a>
+                        <% } %>
                     </h2>
                 </div>
             </div>
-            <div class="col-xs-6 mb-30 ">
-                <div class="c-body">
-                    <h2>清单模板编辑器
-                        <a id="billTemplate" href="/billsTemplate/main" target="_blank" class="btn btn-primary pull-right">进入</a>
-                    </h2>
-                </div>
-            </div>
-            <div class="col-xs-6 mb-30 ">
-                <div class="c-body">
-                    <h2>列设置
-                        <a id="mainTreeCol" href="/mainTreeCol/main" target="_blank" class="btn btn-primary pull-right">进入</a>
-                    </h2>
-                </div>
-            </div>
-            <div class="col-xs-6 mb-30 ">
-                <div class="c-body">
-                    <h2>材料替换库
-                        <a id="materialReplace" href="/materialReplace/main" target="_blank" class="btn btn-primary pull-right">进入</a>
-                    </h2>
-                </div>
-            </div>
-            <div class="col-xs-6 mb-30 ">
-                <div class="c-body">
-                    <h2>工程特征库
-                        <a id="projectFeature" href="/projectFeature/main" target="_blank" class="btn btn-primary pull-right">进入</a>
-                    </h2>
-                </div>
-            </div>
-            <div class="col-xs-6 mb-30 ">
-                <div class="c-body">
-                    <h2>费率标准库
-                        <a id="feeRate" href="/feeRate/main" target="_blank" class="btn btn-primary pull-right">进入</a>
-                    </h2>
-                </div>
-            </div>
-            <div class="col-xs-6 mb-30 ">
-                <div class="c-body">
-                    <h2>计算程序模板库
-                        <a id="calcProgram" href="/calcProgram/main" target="_blank" class="btn btn-primary pull-right">进入</a>
-                    </h2>
-                </div>
-            </div>
+            <% } %>
+            <!--<div class="col-xs-6 mb-30 ">-->
+            <!--<div class="c-body">-->
+            <!--<h2>清单规则编辑器-->
+            <!--<a id="stdBillsmain" href="/stdBillsmain" target="_blank" class="btn btn-primary pull-right">进入</a>-->
+            <!--</h2>-->
+            <!--</div>-->
+            <!--</div>-->
+            <!--<div class="col-xs-6 mb-30 ">-->
+            <!--<div class="c-body">-->
+            <!--<h2>定额编辑器-->
+            <!--<a id="rationRepository" href="/rationRepository/main" target="_blank" class="btn btn-primary pull-right">进入</a>-->
+            <!--</h2>-->
+            <!--</div>-->
+            <!--</div>-->
+            <!--<div class="col-xs-6 mb-30 ">-->
+            <!--<div class="c-body">-->
+            <!--<h2>报表模板-->
+            <!--<a id="rpt_tpl" href="/rpt_tpl" target="_blank" class="btn btn-primary pull-right">进入</a>-->
+            <!--</h2>-->
+            <!--</div>-->
+            <!--</div>-->
+            <!--<div class="col-xs-6 mb-30 ">-->
+            <!--<div class="c-body">-->
+            <!--<h2>人材机库-->
+            <!--<a id="stdGljRepository" href="/stdGljRepository/main" target="_blank" class="btn btn-primary pull-right">进入</a>-->
+            <!--</h2>-->
+            <!--</div>-->
+            <!--</div>-->
+            <!--<div class="col-xs-6 mb-30 ">-->
+            <!--<div class="c-body">-->
+            <!--<h2>清单指引编辑器-->
+            <!--<a id="billsGuidance" href="/billsGuidance/main" target="_blank" class="btn btn-primary pull-right">进入</a>-->
+            <!--</h2>-->
+            <!--</div>-->
+            <!--</div>-->
+            <!--<div class="col-xs-6 mb-30 ">-->
+            <!--<div class="c-body">-->
+            <!--<h2>清除项目残留数据-->
+            <!--<a id="clearJunkBtn" href="javascript:void(0);" class="btn btn-primary pull-right">清除</a>-->
+            <!--</h2>-->
+            <!--</div>-->
+            <!--</div>-->
+            <!--<div class="col-xs-6 mb-30 ">-->
+            <!--<div class="c-body">-->
+            <!--<h2>清单模板编辑器-->
+            <!--<a id="billTemplate" href="/billsTemplate/main" target="_blank" class="btn btn-primary pull-right">进入</a>-->
+            <!--</h2>-->
+            <!--</div>-->
+            <!--</div>-->
+            <!--<div class="col-xs-6 mb-30 ">-->
+            <!--<div class="c-body">-->
+            <!--<h2>列设置-->
+            <!--<a id="mainTreeCol" href="/mainTreeCol/main" target="_blank" class="btn btn-primary pull-right">进入</a>-->
+            <!--</h2>-->
+            <!--</div>-->
+            <!--</div>-->
+            <!--<div class="col-xs-6 mb-30 ">-->
+            <!--<div class="c-body">-->
+            <!--<h2>材料替换库-->
+            <!--<a id="materialReplace" href="/materialReplace/main" target="_blank" class="btn btn-primary pull-right">进入</a>-->
+            <!--</h2>-->
+            <!--</div>-->
+            <!--</div>-->
+            <!--<div class="col-xs-6 mb-30 ">-->
+            <!--<div class="c-body">-->
+            <!--<h2>工程特征库-->
+            <!--<a id="projectFeature" href="/projectFeature/main" target="_blank" class="btn btn-primary pull-right">进入</a>-->
+            <!--</h2>-->
+            <!--</div>-->
+            <!--</div>-->
+            <!--<div class="col-xs-6 mb-30 ">-->
+            <!--<div class="c-body">-->
+            <!--<h2>费率标准库-->
+            <!--<a id="feeRate" href="/feeRate/main" target="_blank" class="btn btn-primary pull-right">进入</a>-->
+            <!--</h2>-->
+            <!--</div>-->
+            <!--</div>-->
+            <!--<div class="col-xs-6 mb-30 ">-->
+            <!--<div class="c-body">-->
+            <!--<h2>计算程序模板库-->
+            <!--<a id="calcProgram" href="/calcProgram/main" target="_blank" class="btn btn-primary pull-right">进入</a>-->
+            <!--</h2>-->
+            <!--</div>-->
+            <!--</div>-->
         </div>
     </div>
 </div>
@@ -153,45 +161,45 @@
 <script type="text/javascript" src="/public/web/PerfectLoad.js"></script>
 <script type="text/javascript">
     $(document).ready(function () {
-        $('#billsLib').click(function () {
-            let href = '/stdBillsmain';
-            let newTab = window.open('about:blank');
-            CommonAjax.get(href, {}, function () {
-               newTab.location.href = href;
-            });
-        });
-
-        $('#rationLib').click(function () {
-            let href = '/rationRepository/main';
-            let newTab = window.open('about:blank');
-            CommonAjax.get(href, {}, function () {
-               newTab.location.href = href;
-            });
-        });
-
-        $('#rptTemplate').click(function () {
-            let href = '/rpt_tpl';
-            let newTab = window.open('about:blank');
-            CommonAjax.get(href, {}, function () {
-               newTab.location.href = href;
-            });
-        });
-
-        $('#gljLib').click(function () {
-            let href = '/stdGljRepository/main';
-            let newTab = window.open('about:blank');
-            CommonAjax.get(href, {}, function () {
-               newTab.location.href = href;
-            });
-        });
-
-        $('#billsGuidanceLib').click(function () {
-            let href = '/billsGuidance/main';
-            let newTab = window.open('about:blank');
-            CommonAjax.get(href, {}, function () {
-               newTab.location.href = href;
-            });
-        });
+//        $('#billsLib').click(function () {
+//            let href = '/stdBillsmain';
+//            let newTab = window.open('about:blank');
+//            CommonAjax.get(href, {}, function () {
+//               newTab.location.href = href;
+//            });
+//        });
+//
+//        $('#rationLib').click(function () {
+//            let href = '/rationRepository/main';
+//            let newTab = window.open('about:blank');
+//            CommonAjax.get(href, {}, function () {
+//               newTab.location.href = href;
+//            });
+//        });
+//
+//        $('#rptTemplate').click(function () {
+//            let href = '/rpt_tpl';
+//            let newTab = window.open('about:blank');
+//            CommonAjax.get(href, {}, function () {
+//               newTab.location.href = href;
+//            });
+//        });
+//
+//        $('#gljLib').click(function () {
+//            let href = '/stdGljRepository/main';
+//            let newTab = window.open('about:blank');
+//            CommonAjax.get(href, {}, function () {
+//               newTab.location.href = href;
+//            });
+//        });
+//
+//        $('#billsGuidanceLib').click(function () {
+//            let href = '/billsGuidance/main';
+//            let newTab = window.open('about:blank');
+//            CommonAjax.get(href, {}, function () {
+//               newTab.location.href = href;
+//            });
+//        });
 
         $('#clearJunkBtn').click(function () {
             $('#clearJunkModal').modal('show');
@@ -201,19 +209,19 @@
         });
         $('#clearJunkY').click(function () {
             $.bootstrapLoading.start();
-             CommonAjax.post('/sysTools/api/clearJunkData', '', function (rstData) {
-             $.bootstrapLoading.end();
-             }, function () {
-             $.bootstrapLoading.end();
-             })
+            CommonAjax.post('/sysTools/api/clearJunkData', '', function (rstData) {
+                $.bootstrapLoading.end();
+            }, function () {
+                $.bootstrapLoading.end();
+            })
         });
         $('#clearFakeY').click(function () {
             $.bootstrapLoading.start();
-             CommonAjax.post('/sysTools/api/clearFakeData', '', function (rstData) {
-             $.bootstrapLoading.end();
-             }, function () {
-             $.bootstrapLoading.end();
-             })
+            CommonAjax.post('/sysTools/api/clearFakeData', '', function (rstData) {
+                $.bootstrapLoading.end();
+            }, function () {
+                $.bootstrapLoading.end();
+            })
         });
     });
 </script>

+ 11 - 5
web/users/views/user/index.html

@@ -1,8 +1,14 @@
-<%include ../layout/second_menu.html %>
 <div class="panel-content">
-    <div class="panel-title">
+    <div class="panel-title fluid">
         <div class="title-main">
-            <h2><%= secondMenu[action].title %></h2>
+            <% for (let menu of userMenu) { %>
+            <% if (menu.title === secondMenu[action].title) { %>
+            <%= menu.title %>
+            <% } else { %>
+            <a href="<%= menu.url %>" class="btn btn-primary btn-link" style="margin-left: 0;margin-right: 12px"><%= menu.title %></a>
+            <% } %>
+            <% } %>
+            <!--<h2><%= secondMenu[action].title %><a href="/user/testUser" class="btn btn-primary btn-link">测试用户</a></h2>-->
         </div>
     </div>
     <div class="content-wrap">
@@ -93,7 +99,7 @@
                     <th>企业地区</th>
                     <th>最近使用版本</th>
                     <th width="180">注册时间 / 最近登录</th>
-                    <th>详细</th>
+                    <!--<th>详细</th>-->
                 </tr>
                 </thead>
                 <tbody>
@@ -105,7 +111,7 @@
                     <td><%= model.province[user.province] %></td>
                     <td><%= compilationMap[user.latest_used]?compilationMap[user.latest_used].name:""%></td>
                     <td><%= moment(user.create_time).format('YYYY-MM-DD HH:mm:ss') %><br><%= user.latest_login?moment(user.latest_login).format('YYYY-MM-DD HH:mm:ss'):"" %></td>
-                    <td><a role="button" data-toggle="modal" data-target="#view" onclick='getUserInfo("<%= user._id.toString()%>")'>详细</a></td>
+                    <!--<td><a role="button" data-toggle="modal" data-target="#view" onclick='getUserInfo("<%= user._id.toString()%>")'>详细</a></td>-->
                     <!--<td><a href="#update" data-toggle="modal" data-target="#update" onclick='getUserUpgradeInfo("<%= user._id.toString()%>")'>升级</a></td>-->
                 </tr>
                 <% }) %>

+ 10 - 3
web/users/views/user/test_user.html

@@ -1,8 +1,15 @@
-<%include ../layout/second_menu.html %>
+<!--<%include ../layout/second_menu.html %>-->
 <div class="panel-content">
-    <div class="panel-title">
+    <div class="panel-title fluid">
         <div class="title-main">
-            <h2><%= secondMenu[action].title %>
+            <h2>
+                <% for (let menu of userMenu) { %>
+                <% if (menu.title === secondMenu[action].title) { %>
+                <%= menu.title %>
+                <% } else { %>
+                <a href="<%= menu.url %>" class="btn btn-primary btn-link" style="padding-left:0;margin-left: 0;margin-right: 12px"><%= menu.title %></a>
+                <% } %>
+                <% } %>
                 <a href="#news-add" data-toggle="modal" data-target="#news-add" class="btn btn-primary btn-sm pull-right">添加用户</a>
             </h2>
         </div>