Browse Source

1.修改基础类
2.新增登录后获取通知消息的功能

olym 7 years ago
parent
commit
b7a640a7b9

+ 15 - 1
app/base/base_service.js

@@ -7,8 +7,10 @@
  * @date 2017/10/11
  * @version
  */
+
 const Service = require('egg').Service;
-// 数据模型基类
+// sql拼装器
+const SqlBuilder = require('../lib/sql_builder');
 class BaseService extends Service {
     /**
      * 构造函数
@@ -20,6 +22,7 @@ class BaseService extends Service {
         super(ctx);
         this.db = this.app.mysql;
         this.cache = this.app.redis;
+        this.sqlBuilder = null;
     }
 
     /**
@@ -42,6 +45,17 @@ class BaseService extends Service {
     }
 
     /**
+     * 初始化sqlBuilder
+     *
+     * @return {void}
+     */
+    initSqlBuilder() {
+        if (this.sqlBuilder === null) {
+            this.sqlBuilder = new SqlBuilder();
+        }
+    }
+
+    /**
      * 根据id查找数据
      *
      * @param {Number} id - 数据库中的id

+ 20 - 12
app/controller/login_controller.js

@@ -40,29 +40,37 @@ module.exports = app => {
             let loginType = ctx.request.body.type;
 
             try {
-                let result = false;
                 loginType = parseInt(loginType);
-                if (loginType === 1) {
-                    // 演示版登陆
-                    const username = ctx.request.body.username;
-                    const password = ctx.request.body.password;
-                    const sso = new SSO(ctx);
-                    result = await sso.loginValid(username, password);
-                } else {
-                    // 项目版登陆
-                    result = await ctx.service.projectAccount.accountLogin(ctx.request.body);
-                }
+                const result = await ctx.service.projectAccount.accountLogin(ctx.request.body, loginType);
 
                 if (!result) {
                     throw '登录失败';
                 }
-                ctx.body = 'success';
+                ctx.redirect('/login/test');
             } catch (error) {
                 console.log(error);
                 ctx.session.loginError = '用户名或密码错误';
                 ctx.redirect('/login');
             }
         }
+
+        /**
+         * 退出登录
+         *
+         * @param {Object} ctx - egg全局变量
+         * @return {void}
+         */
+        async logout(ctx) {
+            // 删除session并跳转
+            ctx.session = null;
+            ctx.redirect('/');
+        }
+
+        async test(ctx) {
+            const test = ctx.session.sessionUser;
+            console.log(test);
+            ctx.body = 'hello';
+        }
     }
 
     return LoginController;

+ 4 - 4
app/lib/sso.js

@@ -21,6 +21,7 @@ class SSO {
     constructor(ctx) {
         this.authUrl = 'http://sso.smartcost.com.cn/api/jzlogin';
         this.ctx = ctx;
+        this.accountID = 0;
     }
 
     /**
@@ -48,10 +49,9 @@ class SSO {
             }
 
             // 如果验证成功,则新增SSO数据到数据库
-            const addResult = await this.ctx.service.customer.addSSOUser(responseData[0]);
-            if (!addResult) {
-                console.log('sso user add error');
-            }
+            const customerId = await this.ctx.service.customer.addSSOUser(responseData[0]);
+            this.accountID = customerId;
+
             // 更新用户登录时间
             const updateData = {
                 last_login: new Date().getTime() / 1000,

+ 9 - 6
app/middleware/session_auth.js

@@ -12,20 +12,23 @@ module.exports = options => {
     return function* sessionAuth(next) {
         try {
             // 判断session
-            const managerSession = this.session.managerSession;
-            if (managerSession === undefined) {
+            const sessionUser = this.session.sessionUser;
+            if (sessionUser === undefined) {
                 throw '不存在session';
             }
             // 校验session
-            if (managerSession.username === undefined || managerSession.loginTime === undefined) {
+            if (sessionUser.account === undefined || sessionUser.loginTime === undefined) {
                 throw '用户数据不完整';
             }
             // 校验session
-            const sessionToken = crypto.createHmac('sha1', managerSession.loginTime + '')
-                .update(managerSession.username).digest().toString('base64');
-            if (sessionToken !== managerSession.sessionToken) {
+            const sessionToken = crypto.createHmac('sha1', sessionUser.loginTime + '')
+                .update(sessionUser.account).digest().toString('base64');
+            if (sessionToken !== sessionUser.sessionToken) {
                 throw 'session数据错误';
             }
+
+            // 同步消息
+            yield this.service.notify.syncNotifyData();
         } catch (error) {
             return this.redirect('/');
         }

+ 5 - 0
app/router.js

@@ -2,9 +2,14 @@
 
 module.exports = app => {
 
+    // session验证中间件
+    const sessionAuth = app.middlewares.sessionAuth();
 
     // 控制面板相关
     app.get('/login', 'loginController.index');
+    app.get('/', 'loginController.index');
     app.post('/login', 'loginController.login');
+    app.get('/logout', 'loginController.logout');
+    app.get('/login/test', sessionAuth, 'loginController.test');
 
 };

+ 6 - 8
app/service/customer.js

@@ -8,8 +8,6 @@
  * @version
  */
 
-// sql拼装器
-const SqlBuilder = require('../lib/sql_builder');
 module.exports = app => {
 
     class Customer extends app.BaseService {
@@ -32,17 +30,17 @@ module.exports = app => {
          * @return {void}
          */
         searchFilter(data) {
-            this.sqlBuilder = new SqlBuilder();
+            this.initSqlBuilder();
         }
 
         /**
          * 新增SSO用户
          *
          * @param {Object} data - 接口返回的数据
-         * @return {Boolean} - 新增结果
+         * @return {Number} - 返回新增数据的id
          */
         async addSSOUser(data) {
-            let result = false;
+            let result = 0;
             if (Object.keys(data).length <= 0 || data.useremail === undefined) {
                 return result;
             }
@@ -50,8 +48,8 @@ module.exports = app => {
             // 先查找是否存在
             const customerData = await this.db.get(this.tableName, { email: data.useremail });
             if (customerData !== null) {
-                // 存在则直接返回结果
-                return true;
+                // 存在则直接返回id
+                return customerData.id;
             }
             const insertData = {
                 email: data.useremail,
@@ -60,7 +58,7 @@ module.exports = app => {
             };
             result = await this.db.insert(this.tableName, insertData);
 
-            return result.affectedRows > 0;
+            return result.insertId;
         }
     }
 

+ 52 - 0
app/service/message.js

@@ -0,0 +1,52 @@
+'use strict';
+
+/**
+ * 消息数据模型
+ *
+ * @author CaiAoLin
+ * @date 2017/11/23
+ * @version
+ */
+module.exports = app => {
+
+    class Message extends app.BaseService {
+
+        /**
+         * 构造函数
+         *
+         * @param {Object} ctx - egg全局变量
+         * @return {void}
+         */
+        constructor(ctx) {
+            super(ctx);
+            this.tableName = 'message';
+        }
+
+        /**
+         * 获取消息数据
+         *
+         * @param {Number} startTime - 时间标记位(获取这个时间点之后的数据)
+         * @return {Array} - 返回消息数据
+         */
+        async getMessage(startTime) {
+            this.initSqlBuilder();
+            this.sqlBuilder.setAndWhere('release_time', {
+                value: startTime,
+                operate: '>=',
+            });
+
+            // 获取用户数据
+            this.sqlBuilder.setAndWhere('type', {
+                value: 2,
+                operate: '=',
+            });
+
+            const [sql, sqlParam] = this.sqlBuilder.build(this.tableName);
+            const result = await this.db.query(sql, sqlParam);
+
+            return result;
+        }
+    }
+
+    return Message;
+};

+ 80 - 0
app/service/notify.js

@@ -0,0 +1,80 @@
+'use strict';
+
+/**
+ * 用户通知相关数据模型
+ *
+ * @author CaiAoLin
+ * @date 2017/11/22
+ * @version
+ */
+module.exports = app => {
+
+    class Notify extends app.BaseService {
+
+        /**
+         * 构造函数
+         *
+         * @param {Object} ctx - egg全局变量
+         * @return {void}
+         */
+        constructor(ctx) {
+            super(ctx);
+            this.tableName = 'notify';
+        }
+
+        /**
+         * 同步当前用户的通知数据
+         *
+         * @return {Boolean}
+         */
+        async syncNotifyData() {
+            let result = false;
+            // 获取session中的数据
+            const sessionUser = this.ctx.session.sessionUser;
+            if (sessionUser === null || sessionUser === undefined) {
+                return result;
+            }
+            try {
+                // 获取当前用户最后一条数据
+                const condition = {
+                    where: { uid: sessionUser.accountId, type: sessionUser.loginType },
+                    orders: [['id', 'DESC']],
+                    limit: 1,
+                };
+
+                const lastData = await this.db.select(this.tableName, condition);
+                const lastMessageTime = lastData.length <= 0 ? 0 : lastData[0].create_time;
+
+                // 获取后台设置的消息数据
+                const messageData = await this.ctx.service.message.getMessage(lastMessageTime);
+                // 如果已经是最新的消息则直接返回
+                if (messageData.length <= 0) {
+                    return true;
+                }
+
+                // 新增通知数据
+                const currentTime = new Date().getTime() / 1000;
+                const insertData = [];
+                for (const message of messageData) {
+                    const tmp = {
+                        mid: message.id,
+                        create_time: currentTime,
+                        uid: sessionUser.accountId,
+                        type: sessionUser.loginType,
+                    };
+                    insertData.push(tmp);
+                }
+
+                const operate = this.db.insert(this.tableName, insertData);
+                result = operate.affectedRows > 0;
+            } catch (error) {
+                console.log(error);
+                result = false;
+            }
+
+            return result;
+        }
+    }
+
+    return Notify;
+};

+ 4 - 5
app/service/project.js

@@ -8,7 +8,6 @@
  * @version
  */
 
-const SqlBuilder = require('../lib/sql_builder');
 module.exports = app => {
 
     class Project extends app.BaseService {
@@ -38,16 +37,16 @@ module.exports = app => {
          */
         async getProjectByCode(code) {
             // 获取项目状态为非禁止的项目
-            const sqlBuilder = new SqlBuilder();
-            sqlBuilder.setAndWhere('code', {
+            this.initSqlBuilder();
+            this.sqlBuilder.setAndWhere('code', {
                 value: this.db.escape(code),
                 operate: '=',
             });
-            sqlBuilder.setAndWhere('status', {
+            this.sqlBuilder.setAndWhere('status', {
                 value: this.status.DISABLE,
                 operate: '<',
             });
-            const [sql, sqlParam] = sqlBuilder.build(this.tableName);
+            const [sql, sqlParam] = this.sqlBuilder.build(this.tableName);
             const projectData = await this.db.queryOne(sql, sqlParam);
             return projectData;
         }

+ 59 - 27
app/service/project_account.js

@@ -42,6 +42,11 @@ module.exports = app => {
                         project: { type: 'string', required: true, min: 13 },
                     };
                     break;
+                case 'ssoLogin':
+                    rule = {
+                        username: { type: 'string', required: true, min: 2 },
+                        password: { type: 'string', required: true, min: 4 },
+                    };
                 default:
                     break;
             }
@@ -53,49 +58,76 @@ module.exports = app => {
          * 账号登录
          *
          * @param {Object} data - 表单post数据
+         * @param {Number} loginType - 登录类型 1 | 2
          * @return {Boolean} - 返回登录结果
          */
-        async accountLogin(data) {
+        async accountLogin(data, loginType) {
             let result = false;
             try {
                 // 验证数据
-                const rule = this.rule('login');
+                const scene = loginType === 1 ? 'ssoLogin' : 'login';
+                const rule = this.rule(scene);
                 this.ctx.validate(rule, data);
 
-                // 查找项目数据
-                const projectData = await this.ctx.service.project.getProjectByCode(data.project.toString());
-                if (projectData === null) {
-                    throw '不存在项目数据';
-                }
+                let accountData = {};
+                if (loginType === 2) {
+                    // 查找项目数据
+                    const projectData = await this.ctx.service.project.getProjectByCode(data.project.toString());
+                    if (projectData === null) {
+                        throw '不存在项目数据';
+                    }
 
-                // 查找对应数据
-                const accountData = await this.db.get(this.tableName, {
-                    account: data.account,
-                    project_id: projectData.id,
-                });
+                    // 查找对应数据
+                    accountData = await this.db.get(this.tableName, {
+                        account: data.account,
+                        project_id: projectData.id,
+                    });
 
-                if (accountData === null) {
-                    throw '不存在对应用户数据';
-                }
+                    if (accountData === null) {
+                        throw '不存在对应用户数据';
+                    }
 
-                // 判断密码
-                if (accountData.is_admin === 1) {
-                    // 管理员则用sso通道判断
-                    const sso = new SSO(this.ctx);
-                    result = await sso.loginValid(data.account, data.project_password.toString());
+                    // 判断密码
+                    if (accountData.is_admin === 1) {
+                        // 管理员则用sso通道判断
+                        const sso = new SSO(this.ctx);
+                        result = await sso.loginValid(data.account, data.project_password.toString());
+                    } else {
+                        // 加密密码
+                        const encryptPassword = crypto.createHmac('sha1', data.account).update(data.project_password)
+                            .digest().toString('base64');
+                        result = encryptPassword === accountData.password;
+                    }
                 } else {
-                    // 加密密码
-                    const encryptPassword = crypto.createHmac('sha1', data.account).update(data.project_password)
-                        .digest().toString('base64');
-                    result = encryptPassword === accountData.password;
+                    // sso登录(演示版)
+                    const sso = new SSO(this.ctx);
+                    result = await sso.loginValid(data.username, data.password.toString());
+                    accountData.account = data.username;
+                    accountData.id = sso.accountID;
+                    console.log(accountData);
                 }
 
+
                 // 如果成功则更新登录时间
                 if (result) {
-                    const updateData = {
-                        last_login: new Date().getTime() / 1000,
+                    const currentTime = new Date().getTime() / 1000;
+                    if (loginType === 2) {
+                        const updateData = {
+                            last_login: currentTime,
+                        };
+                        await this.update(updateData, { id: accountData.id });
+                    }
+                    // 加密token
+                    const sessionToken = crypto.createHmac('sha1', currentTime + '').update(accountData.account)
+                        .digest().toString('base64');
+                    // 存入session
+                    this.ctx.session.sessionUser = {
+                        account: accountData.account,
+                        accountId: accountData.id,
+                        loginTime: currentTime,
+                        sessionToken,
+                        loginType,
                     };
-                    await this.update(updateData, { id: accountData.id });
                 }
             } catch (error) {
                 console.log(error);

+ 1 - 1
app/view/login/login.ejs

@@ -12,7 +12,7 @@
 <body class="login-body">
 <div class="container">
     <!--演示版-->
-    <form class="form-signin" method="post" action="">
+    <form class="form-signin" method="post" action="/login">
         <h1 class="d-flex justify-content-center mb-4">计量支付</h1>
         <nav class="nav nav-tabs nav-justified mb-3" role="tablist" id="login-tab">
             <a class="nav-item nav-link active" data-toggle="tab" data-type="1" href="#preview" role="tab">演示版登录</a>