project_account.js 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. 'use strict';
  2. /**
  3. * 项目账号数据模型
  4. *
  5. * @author CaiAoLin
  6. * @date 2017/11/16
  7. * @version
  8. */
  9. // 加密类
  10. const crypto = require('crypto');
  11. const SSO = require('../lib/sso');
  12. module.exports = app => {
  13. class ProjectAccount extends app.BaseService {
  14. /**
  15. * 构造函数
  16. *
  17. * @param {Object} ctx - egg全局变量
  18. * @return {void}
  19. */
  20. constructor(ctx) {
  21. super(ctx);
  22. this.tableName = 'project_account';
  23. }
  24. /**
  25. * 数据验证规则
  26. *
  27. * @param {String} scene - 场景
  28. * @return {Object} - 返回数据
  29. */
  30. rule(scene) {
  31. let rule = {};
  32. switch (scene) {
  33. case 'login':
  34. rule = {
  35. account: { type: 'string', required: true, min: 2 },
  36. project_password: { type: 'string', required: true, min: 4 },
  37. project: { type: 'string', required: true, min: 13 },
  38. };
  39. break;
  40. case 'ssoLogin':
  41. rule = {
  42. username: { type: 'string', required: true, min: 2 },
  43. password: { type: 'string', required: true, min: 4 },
  44. };
  45. break;
  46. case 'profileBase':
  47. rule = {
  48. name: { type: 'string', allowEmpty: true, max: 10 },
  49. company: { type: 'string', allowEmpty: true, max: 30 },
  50. role: { type: 'string', allowEmpty: true, max: 10 },
  51. mobile: { type: 'mobile', allowEmpty: true },
  52. telephone: { type: 'string', allowEmpty: true, max: 12 },
  53. };
  54. break;
  55. default:
  56. break;
  57. }
  58. return rule;
  59. }
  60. /**
  61. * 账号登录
  62. *
  63. * @param {Object} data - 表单post数据
  64. * @param {Number} loginType - 登录类型 1 | 2
  65. * @return {Boolean} - 返回登录结果
  66. */
  67. async accountLogin(data, loginType) {
  68. let result = false;
  69. try {
  70. // 验证数据
  71. const scene = loginType === 1 ? 'ssoLogin' : 'login';
  72. const rule = this.rule(scene);
  73. this.ctx.validate(rule, data);
  74. let accountData = {};
  75. let projectInfo = {};
  76. let projectList = [];
  77. if (loginType === 2) {
  78. // 查找项目数据
  79. const projectData = await this.ctx.service.project.getProjectByCode(data.project.toString());
  80. if (projectData === null) {
  81. throw '不存在项目数据';
  82. }
  83. projectInfo = {
  84. id: projectData.id,
  85. name: projectData.name,
  86. userAccount: projectData.user_account,
  87. };
  88. // 查找对应数据
  89. accountData = await this.db.get(this.tableName, {
  90. account: data.account,
  91. project_id: projectData.id,
  92. enable: 1,
  93. });
  94. if (accountData === null) {
  95. throw '不存在对应用户数据';
  96. }
  97. projectList = await this.getProjectInfoByAccount(data.account);
  98. // 判断密码
  99. if (accountData.is_admin === 1) {
  100. // 管理员则用sso通道判断
  101. const sso = new SSO(this.ctx);
  102. result = await sso.loginValid(data.account, data.project_password.toString());
  103. } else {
  104. // 加密密码
  105. const encryptPassword = crypto.createHmac('sha1', data.account).update(data.project_password)
  106. .digest().toString('base64');
  107. result = encryptPassword === accountData.password;
  108. }
  109. } else {
  110. // sso登录(演示版)
  111. const sso = new SSO(this.ctx);
  112. result = await sso.loginValid(data.username, data.password.toString());
  113. accountData.account = data.username;
  114. accountData.id = sso.accountID;
  115. }
  116. // 如果成功则更新登录时间
  117. if (result) {
  118. const currentTime = new Date().getTime() / 1000;
  119. if (loginType === 2) {
  120. const updateData = {
  121. last_login: currentTime,
  122. };
  123. await this.update(updateData, { id: accountData.id });
  124. }
  125. // 加密token
  126. const sessionToken = crypto.createHmac('sha1', currentTime + '').update(accountData.account)
  127. .digest().toString('base64');
  128. // 存入session
  129. this.ctx.session.sessionUser = {
  130. account: accountData.account,
  131. name: accountData.name,
  132. accountId: accountData.id,
  133. loginTime: currentTime,
  134. sessionToken,
  135. loginType,
  136. };
  137. this.ctx.session.sessionProject = projectInfo;
  138. this.ctx.session.sessionProjectList = projectList;
  139. }
  140. } catch (error) {
  141. console.log(error);
  142. result = false;
  143. }
  144. return result;
  145. }
  146. /**
  147. * 根据项目id获取用户列表
  148. *
  149. * @param {Number} projectId - 项目id
  150. * @return {Array} - 返回用户数据
  151. */
  152. async getAccountByProjectId(projectId) {
  153. const condition = {
  154. columns: ['id', 'account', 'name', 'company', 'role', 'mobile', 'telephone', 'enable'],
  155. where: { project_id: projectId, is_admin: 0 },
  156. };
  157. const accountList = await this.getAllDataByCondition(condition);
  158. return accountList;
  159. }
  160. /**
  161. * 停用/启用
  162. *
  163. * @param {Number} accountId - 账号id
  164. * @return {Boolean} - 返回操作结果
  165. */
  166. async enableAccount(accountId) {
  167. let result = false;
  168. const accountData = await this.getDataByCondition({ id: accountId });
  169. if (accountData === null) {
  170. return result;
  171. }
  172. const changeStatus = accountData.enable === 1 ? 0 : 1;
  173. result = await this.update({ enable: changeStatus }, { id: accountId });
  174. return result;
  175. }
  176. /**
  177. * 根据账号id查找对应的项目数据
  178. *
  179. * @param {Number} account - 账号
  180. * @return {Array} - 返回数据
  181. */
  182. async getProjectInfoByAccount(account) {
  183. let column = ['p.name', 'p.id', 'p.user_account'];
  184. column = column.join(',');
  185. const sql = 'SELECT ' + column + ' FROM ' +
  186. '?? AS pa ' +
  187. 'LEFT JOIN ?? AS p ' +
  188. 'ON pa.`project_id` = p.`id` ' +
  189. 'WHERE pa.`account` = ? ' +
  190. 'GROUP BY pa.`project_id`;';
  191. const sqlParam = [this.tableName, this.ctx.service.project.tableName, account];
  192. const projectInfo = await this.db.query(sql, sqlParam);
  193. return projectInfo;
  194. }
  195. /**
  196. * 修改用户数据
  197. *
  198. * @param {Object} data - post过来的数据
  199. * @param {Number} accountId - 账号id
  200. * @return {Boolean} - 返回修改结果
  201. */
  202. async save(data, accountId) {
  203. if (data._csrf !== undefined) {
  204. delete data._csrf;
  205. }
  206. accountId = parseInt(accountId);
  207. accountId = isNaN(accountId) ? 0 : accountId;
  208. let result = false;
  209. if (accountId <= 0) {
  210. return result;
  211. }
  212. data.id = accountId;
  213. // 更新数据
  214. const operate = await this.db.update(this.tableName, data);
  215. result = operate.affectedRows > 0;
  216. return result;
  217. }
  218. }
  219. return ProjectAccount;
  220. };