/** * 后台管理员数据模型 * * @author CaiAoLin * @date 2017/6/1 * @version */ 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} */ constructor() { let parent = super(); parent.model = ManagerSchema; parent.init(); } /** * 设置场景 * * @param {string} scene * @return {void} */ setScene(scene = '') { switch (scene) { // 更改密码验证规则 case 'changePassword': this.model.schema.path('password').required(true); break; // CLD新增 case 'cldInsert': this.model.schema.path('username').required(true); this.model.schema.path('create_time').required(true); this.model.schema.path('office').required(true); break; } } /** * 获取列表 * * @param {object} condition * @param {number} page * @return {Promise} */ getList(condition = null, page = 1) { page = parseInt(page); page = page <= 1 ? 1 : page; let option = {page: page}; return this.db.find(condition, null, option); } /** * 用户密码加密 * * @param {string} token * @param {string} password * @return {string} */ encryptPassword(token, password) { let encryptPassword = crypto.createHmac('sha1', token).update(password) .digest().toString('base64'); return encryptPassword; } /** * 更改密码 * * @param {string} username * @param {string} password * @param {string} newPassword * @throws {string} * @return {Promise} */ async changePassword(username, password, newPassword) { // 查找对应用户 let managerData = await this.findDataByCondition({username: username}); if (managerData.length <= 0) { return false; } // 验证旧密码 let encryptPassword = this.encryptPassword(managerData.token, password); if (encryptPassword !== managerData.password) { throw '用户名或密码错误'; } // 加密新密码 let encryptNewPassword = this.encryptPassword(managerData.token, newPassword); let result = await this.db.update({username: username}, {password: encryptNewPassword}); return result.ok === 1; } /** * 登录信息校验 * * @param {String} username * @param {String} password * @return {Promise} */ async validLogin(username, password) { let managerData = await this.findDataByCondition({username: username}); // 没有找到对应数据 if (managerData === null || managerData._id === undefined) { throw {code: 44001, err: '用户名或密码错误'}; } // 是否禁止登录 if (managerData.can_login !== 1) { throw {code: 44002, err: '用户名不存在'}; } // 如果不是超级管理员登录则走CLD接口登录流程 if (username !== this.adminUsername) { let CLDLoginInfo = await this.CLDLogin(username, password, managerData); managerData = CLDLoginInfo; } else { // 加密密码 let encryptPassword = this.encryptPassword(managerData.token, password); if (encryptPassword !== managerData.password) { throw {code: 44001, err: '用户名或密码错误'}; } } return managerData; } /** * 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.CLDRequest(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, can_login: 0 }; result = this.db.create(insertData); return result; } /** * CLD请求 * * @param {Object} postOption * @return {Promise} */ CLDRequest(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]; } /** * 新增管理员 * * @param {Object} data * @return {Promise} */ async createManager(data) { if (Object.keys(data).length <= 0) { throw '数据格式错误'; } let result = await this.db.create(data); return result; } } export default ManagerModel;