فهرست منبع

1.CLD登录接入
2.权限配置以及权限控制

caiaolin 8 سال پیش
والد
کامیت
fbc7e2bfaf

+ 47 - 15
modules/common/base/base_controller.js

@@ -53,24 +53,57 @@ class BaseController {
                 controller = actionInfo[0];
                 action = actionInfo[1];
                 break;
+            default:
+                controller = actionInfo[0];
+                break;
         }
 
-        // 菜单数据
-        response.locals.menu = menuData;
-        // 二级菜单数据
-        response.locals.secondMenu = menuData[controller] !== undefined && menuData[controller].children !== undefined ?
-            menuData[controller].children : {};
+        try {
+            // 校验权限
+            let currentPermission = request.session.managerData.permission;
+            currentPermission = currentPermission.split(',');
+            let withoutPermission = ['login', 'dashboard'];
+            // 工具页面整合
+            let toolPermission = ['rationRepository', 'stdBillsmain'];
+            let hasToolPermission = false;
+            if (controller === 'tool') {
+                for (let tmpPermission of toolPermission) {
+                    if (currentPermission.indexOf(tmpPermission) >= 0) {
+                        hasToolPermission = true;
+                        break;
+                    }
+                }
+            }
+
+            if (!hasToolPermission && withoutPermission.indexOf(controller) < 0 &&
+                (currentPermission.length <= 0 || currentPermission.indexOf(controller)) < 0) {
+                console.log(currentPermission);
+                console.log(controller);
+
+                throw '没有权限';
+            }
+
+            // 菜单数据
+            response.locals.menu = menuData;
+            // 二级菜单数据
+            response.locals.secondMenu = menuData[controller] !== undefined && menuData[controller].children !== undefined ?
+                menuData[controller].children : {};
 
-        // url相关数据
-        response.locals.urlQuery = JSON.stringify(urlInfo.query);
-        response.locals.controller = controller;
-        response.locals.action = action;
+            // url相关数据
+            response.locals.urlQuery = JSON.stringify(urlInfo.query);
+            response.locals.controller = controller;
+            response.locals.action = action;
 
-        // 用户session数据
-        response.locals.manager = request.session.managerData;
+            // 用户session数据
+            response.locals.manager = request.session.managerData;
 
-        // moment工具
-        response.locals.moment = Moment;
+            // moment工具
+            response.locals.moment = Moment;
+        } catch (error) {
+            console.log(error);
+            response.redirect('/dashboard');
+            return;
+        }
 
         next();
     }
@@ -102,9 +135,8 @@ class BaseController {
             }
 
         } catch (error) {
-            console.log(error);
-            // 未登录
             response.redirect('/login');
+            return;
         }
 
         next();

+ 3 - 4
modules/common/base/base_model.js

@@ -120,12 +120,11 @@ class BaseModel {
      * @return {Promise}
      */
     async updateById(id, updateData) {
-        id = parseInt(id);
-        if (isNaN(id) || id <= 0 || Object.keys(updateData).length <= 0) {
+        if (Object.keys(updateData).length <= 0) {
             return false;
         }
-
-        let result = await this.db.update({id: id}, updateData);
+        let condition = typeof id === 'number' ? {id: id} : {_id: id};
+        let result = await this.db.update(condition, updateData);
 
         return result.ok !== undefined && result.ok === 1;
     }

+ 3 - 13
modules/users/controllers/login_controller.js

@@ -46,18 +46,7 @@ class LoginController extends BaseController {
             msg: ''
         };
         try {
-            let managerData = await managerModel.findDataByCondition({username: username});
-
-            // 没有找到对应数据
-            if (managerData === null || managerData._id === undefined) {
-                throw {code: 44001, err: '用户名或密码错误'};
-            }
-
-            // 加密密码
-            let encryptPassword = managerModel.encryptPassword(managerData.token, password);
-            if (encryptPassword !== managerData.password) {
-                throw {code: 44001, err: '用户名或密码错误'};
-            }
+            let managerData = await managerModel.validLogin(username, password);
 
             // 成功后写入session
             let currentTime = new Date().getTime();
@@ -68,7 +57,8 @@ class LoginController extends BaseController {
                 username: managerData.username,
                 loginTime: currentTime,
                 sessionToken: sessionToken,
-                userID: managerData.id
+                userID: managerData.id,
+                permission: managerData.permission === undefined ? '' : managerData.permission
             };
             request.session.managerData = managerSession;
         } catch (error) {

+ 42 - 6
modules/users/controllers/manager_controller.js

@@ -36,6 +36,28 @@ class ManagerController extends BaseController {
 
             // 获取管理员列表
             managerList = await managerModel.getList(null, page);
+
+            // 整理数据
+            if (managerList.length > 0) {
+                for (let tmp in managerList) {
+                    let permission = managerList[tmp].permission;
+                    permission = permission.split(',');
+
+                    if (permission.length <= 0) {
+                        continue;
+                    }
+
+                    let permissionString = [];
+                    for (let name of permission) {
+                        if (managerModel.permission[name] === undefined) {
+                            continue;
+                        }
+                        permissionString.push(managerModel.permission[name]);
+                    }
+                    permissionString = permissionString.join(',');
+                    managerList[tmp].permissionStr = permissionString;
+                }
+            }
         } catch (error) {
 
         }
@@ -43,30 +65,44 @@ class ManagerController extends BaseController {
         let renderData = {
             managerList: managerList,
             pages: pageData,
-            layout: 'users/views/layout/layout'
+            layout: 'users/views/layout/layout',
         };
         response.render('users/views/manager/index', renderData);
     }
 
     /**
-     * 编辑管理员
+     * 保存管理员
      *
      * @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 managerData = {};
+
+        let responseData = {
+            err: 0,
+            msg: ""
+        };
         try {
+            if (id === '' || id === undefined) {
+                throw 'id有误';
+            }
             let managerModel = new ManagerModel();
-            managerData = await managerModel.findDataByCondition({id: id});
+            let result = await managerModel.updateById(id, {permission: permission, can_login: canLogin});
+
+            if (!result) {
+                throw '修改失败';
+            }
 
         } catch (error) {
-            console.log(error);
+            responseData.err = 1;
+            responseData.msg = error;
         }
 
-        response.end('111');
+        response.json(responseData);
     }
 
     /**

+ 165 - 0
modules/users/models/manager_model.js

@@ -8,10 +8,31 @@
 import BaseModel from "../../common/base/base_model";
 import ManagerSchema from "./schemas/manager";
 import crypto from "crypto";
+import Request from "request";
 
 class ManagerModel extends BaseModel {
 
     /**
+     * 超级用户用户名
+     *
+     * @var {String}
+     */
+    adminUsername = 'admin';
+
+    /**
+     * 用户权限
+     *
+     * @var
+     */
+    permission = {
+        'manager': '用户管理',
+        'notify': '通知管理',
+        'stdBillsmain': '清单规则编辑器',
+        'rationRepository': '定额编辑器',
+        'report': '报表模板',
+    };
+
+    /**
      * 构造函数
      *
      * @return {void}
@@ -34,6 +55,13 @@ class ManagerModel extends BaseModel {
             case 'changePassword':
                 this.model.schema.path('password').required(true);
                 break;
+            // CLD新增
+            case 'cldInsert':
+                this.model.schema.path('username').required(true);
+                this.model.schema.path('last_login').required(true);
+                this.model.schema.path('create_time').required(true);
+                this.model.schema.path('office').required(true);
+                break;
         }
     }
 
@@ -95,6 +123,143 @@ class ManagerModel extends BaseModel {
     }
 
     /**
+     * 登录信息校验
+     *
+     * @param {String} username
+     * @param {String} password
+     * @return {Promise}
+     */
+    async validLogin(username, password) {
+        let managerData = await this.findDataByCondition({username: username});
+
+        // 如果不是超级管理员登录则走CLD接口登录流程
+        if (username !== this.adminUsername) {
+            let CLDLoginInfo = await this.CLDLogin(username, password, managerData);
+            managerData = CLDLoginInfo;
+        } else {
+            this.validPassword(password, managerData);
+        }
+
+        return managerData;
+    }
+
+    /**
+     * 验证密码
+     *
+     * @param {String} password
+     * @param {Object} managerData
+     * @return {void}
+     */
+    validPassword(password, managerData) {
+        // 没有找到对应数据
+        if (managerData === null || managerData._id === undefined) {
+            throw {code: 44001, err: '用户名或密码错误'};
+        }
+
+        // 加密密码
+        let encryptPassword = this.encryptPassword(managerData.token, password);
+        if (encryptPassword !== managerData.password) {
+            throw {code: 44001, err: '用户名或密码错误'};
+        }
+    }
+
+    /**
+     * CLD登录
+     *
+     * @param {String} username
+     * @param {String} password
+     * @param {Object} managerData
+     * @return {Promise}
+     */
+    async CLDLogin(username, password, managerData) {
+        let result = managerData;
+        if (username === '' || password === '') {
+            throw {code: 44001, err: '用户名或密码错误'};
+        }
+        let CLDUrl = 'http://cld.smartcost.com.cn/api/auth';
+        // 生成加密token
+        let [encryptToken, postTime] = this.generateCLDToken();
+        let postData = {
+            username: username,
+            password: password,
+            time: postTime,
+            token: encryptToken,
+            app: 'scConstruct'
+        };
+
+        let postOption = {
+            url: CLDUrl,
+            form: postData,
+            encoding: 'utf8'
+        };
+        let responseData = await this.CLDLoginRequest(postOption);
+        // 登录成功后,存在此用户则直接返回
+        if (managerData) {
+            return result;
+        }
+
+        // 不存在则新增
+        this.setScene('cldInsert');
+        let current = new Date().getTime();
+        let insertData = {
+            username: username,
+            password: '',
+            token: '',
+            create_time: current,
+            last_login: current,
+            office: responseData.office
+        };
+        result = this.db.create(insertData);
+
+        return result;
+    }
+
+    /**
+     * CLD登录请求
+     *
+     * @param {Object} postOption
+     * @return {Promise}
+     */
+    CLDLoginRequest(postOption) {
+        return new Promise(function(resolve, reject) {
+            // 发起请求
+            Request.post(postOption, function(error, response, body) {
+                if (error || response.statusCode !== 200) {
+                    console.log(response.statusCode + ':' + error);
+                    reject({code: 44002, err: '接口请求出错'});
+                    return;
+                }
+
+                body = JSON.parse(body);
+
+                // 如果接口返回错误
+                if (body.err !== 0) {
+                    reject({code: body.err, err: '登录失败'});
+                    return;
+                }
+
+                resolve(body.data);
+            });
+        });
+    }
+
+    /**
+     * 生成CLD Token
+     *
+     * @return {Array}
+     */
+    generateCLDToken() {
+        // 加密内容
+        let token = 'sc@ConS!tru@ct*88';
+        let currentTime = new Date().getTime();
+        currentTime = parseFloat(currentTime / 1000).toFixed(0);
+
+        let encryptToken = this.encryptPassword(token, (token + currentTime));
+
+        return [encryptToken, currentTime];
+    }
+
+    /**
      * 创建管理员用户
      *
      * @return {Promise}

+ 4 - 4
modules/users/models/schemas/manager.js

@@ -44,10 +44,10 @@ let modelSchema = {
         type: Number,
         default: 1
     },
-    // 角色id
-    role: {
-        type: Number,
-        default: 0
+    // 权限
+    permission: {
+        type: String,
+        default: ''
     },
     // 办事处
     office: {

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

@@ -16,7 +16,7 @@ module.exports =function (app) {
     // 管理员列表action
     router.get('/', managerController.auth, managerController.init, managerController.index);
     // 修改管理员
-    router.get('/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);
     // 超级管理员action

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

@@ -0,0 +1,80 @@
+/**
+ * 后台管理相关js
+ *
+ * @author CaiAoLin
+ * @date 2017/7/25
+ * @version
+ */
+$(document).ready(function() {
+    let selectId = '';
+    // 编辑用户
+    $(".edit").click(function() {
+        // 获取当前点击的数据
+        let canLogin = $(this).data('login');
+        if (canLogin) {
+            $("input[name='can_login']").attr('checked', 'checked');
+        } else {
+            $("input[name='can_login']").removeAttr('checked');
+        }
+
+        // 获取权限
+        let permission = $(this).data('permission');
+        permission = permission.split(',');
+
+        $("input[name='permission[]']").each(function(index) {
+            let permissionName = $(this).data('permission');
+
+            if (permission.indexOf(permissionName) < 0) {
+                $(this).removeAttr('checked');
+                return true;
+            }
+            $(this).attr('checked', 'checked');
+        });
+
+        selectId = $(this).data('id');
+        $('#edit-account').modal('show');
+    });
+
+
+    // 编辑后保存
+    let isSaving = false;
+    $("#save-manager").click(function() {
+        if (selectId === '' || isSaving) {
+            return false;
+        }
+
+        // 获取权限
+        let permission = [];
+        $("input[name='permission[]']:checked").each(function(index) {
+            let permissionName = $(this).data('permission');
+            permission.push(permissionName);
+        });
+        permission = permission.join(',');
+
+        // 获取是否可登录
+        let login = $("input[name='can_login']").is(':checked');
+
+        $.ajax({
+            url: '/manager/modify/' + selectId,
+            type: 'post',
+            data: {permission: permission, login: login ? 1 : 0},
+            dataType: 'json',
+            error: function() {
+                isSaving = false;
+            },
+            beforeSend: function() {
+                isSaving = true;
+            },
+            success: function(response) {
+                isSaving = false;
+                if (response.err === 0) {
+                    $('#edit-account').modal('hide');
+                } else {
+                    let msg = response.msg === undefined ? '未知错误' : response.msg;
+                    alert(msg);
+                }
+            }
+        });
+    });
+
+});

+ 43 - 0
web/users/views/layout/layout.html

@@ -55,4 +55,47 @@
         <%- body %>
     </div>
 </div>
+<div class="modal fade" id="edit-account" 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">编辑账号</h4>
+            </div>
+            <div class="modal-body">
+                <div class="form-group">
+                    <label>权限</label>
+                    <div class="checkbox">
+                        <label>
+                            <input type="checkbox" name="permission[]" data-permission="manager"> 用户管理
+                        </label>&nbsp;
+                        <label>
+                            <input type="checkbox" name="permission[]" data-permission="notify"> 通知管理
+                        </label>&nbsp;
+                        <label>
+                            <input type="checkbox" name="permission[]" data-permission="stdBillsmain"> 清单规则编辑器
+                        </label>&nbsp;
+                        <label>
+                            <input type="checkbox" name="permission[]" data-permission="rationRepository"> 定额编辑器
+                        </label>&nbsp;
+                        <label>
+                            <input type="checkbox" name="permission[]" data-permission="report"> 报表模板
+                        </label>
+                    </div>
+                </div>
+                <div class="form-group">
+                    <label>禁止登录</label>
+                    <div class="checkbox">
+                        <label>
+                            <input type="checkbox" name="can_login"> 是
+                        </label>
+                    </div>
+                </div>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-primary" id="save-manager">确定</button>
+            </div>
+        </div>
+    </div>
+</div>
 </body>

+ 5 - 3
web/users/views/manager/index.html

@@ -34,9 +34,11 @@
                 <tr>
                     <td><%= manager.username %></td>
                     <td><%= manager.office %></td>
-                    <td>用户管理,通知管理,工具,后台管理</td>
+                    <td><%= manager.permissionStr %></td>
                     <td>
-                        <a href="/manager/modify/<%= manager._id %>" class="btn btn-xs">编辑</a>
+                        <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>
                         <% } %>
@@ -51,4 +53,4 @@
         </div>
     </div>
 </div>
-</div>
+<script type="text/javascript" src="/web/users/js/manager.js"></script>