manager_model.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. /**
  2. * 后台管理员数据模型
  3. *
  4. * @author CaiAoLin
  5. * @date 2017/6/1
  6. * @version
  7. */
  8. import mongoose from "mongoose";
  9. import BaseModel from "../../common/base/base_model";
  10. import crypto from "crypto";
  11. import Request from "request";
  12. class ManagerModel extends BaseModel {
  13. /**
  14. * 超级用户用户名
  15. *
  16. * @var {String}
  17. */
  18. adminUsername = 'admin';
  19. /**
  20. * 用户权限
  21. *
  22. * @var
  23. */
  24. permission = {
  25. 'user': '用户管理',
  26. 'notify': '通知管理',
  27. 'stdBillsmain': '清单规则编辑器',
  28. 'rationRepository': '定额编辑器',
  29. 'report': '报表模板',
  30. };
  31. /**
  32. * 构造函数
  33. *
  34. * @return {void}
  35. */
  36. constructor() {
  37. let parent = super();
  38. parent.model = mongoose.model('manager');
  39. parent.init();
  40. }
  41. /**
  42. * 设置场景
  43. *
  44. * @param {string} scene
  45. * @return {void}
  46. */
  47. setScene(scene = '') {
  48. switch (scene) {
  49. // 更改密码验证规则
  50. case 'changePassword':
  51. this.model.schema.path('password').required(true);
  52. break;
  53. // CLD新增
  54. case 'cldInsert':
  55. this.model.schema.path('username').required(true);
  56. this.model.schema.path('create_time').required(true);
  57. this.model.schema.path('office').required(true);
  58. break;
  59. }
  60. }
  61. /**
  62. * 获取过滤条件
  63. *
  64. * @return {Object}
  65. */
  66. getFilterCondition(request) {
  67. let condition = {};
  68. let office = request.query.office;
  69. if (office !== '' && office !== undefined) {
  70. condition.office = parseInt(office);
  71. }
  72. let permission = request.query.permission;
  73. if (permission !== undefined) {
  74. // 0 :权限为空的情况
  75. condition.permission = permission === '0' ? '' : permission;
  76. }
  77. return condition;
  78. }
  79. /**
  80. * 获取按创建时间倒序列表
  81. *
  82. * @param {object} condition
  83. * @param {number} page
  84. * @return {Promise}
  85. */
  86. getList(condition = null, page = 1) {
  87. page = parseInt(page);
  88. page = page <= 1 ? 1 : page;
  89. let option = {page: page, sort: {create_time:-1}};
  90. return this.db.find(condition, null, option);
  91. }
  92. /**
  93. * 用户密码加密
  94. *
  95. * @param {string} token
  96. * @param {string} password
  97. * @return {string}
  98. */
  99. encryptPassword(token, password) {
  100. let encryptPassword = crypto.createHmac('sha1', token).update(password)
  101. .digest().toString('base64');
  102. return encryptPassword;
  103. }
  104. /**
  105. * 更改密码
  106. *
  107. * @param {string} username
  108. * @param {string} password
  109. * @param {string} newPassword
  110. * @throws {string}
  111. * @return {Promise}
  112. */
  113. async changePassword(username, password, newPassword) {
  114. // 查找对应用户
  115. let managerData = await this.findDataByCondition({username: username});
  116. if (managerData.length <= 0) {
  117. return false;
  118. }
  119. // 验证旧密码
  120. let encryptPassword = this.encryptPassword(managerData.token, password);
  121. if (encryptPassword !== managerData.password) {
  122. throw '用户名或密码错误';
  123. }
  124. // 加密新密码
  125. let encryptNewPassword = this.encryptPassword(managerData.token, newPassword);
  126. let result = await this.db.update({username: username}, {password: encryptNewPassword});
  127. return result.ok === 1;
  128. }
  129. /**
  130. * 财审平台需要临时登录,只能看某个清单精灵库
  131. */
  132. temporaryLogin(username, password) {
  133. const users = [
  134. { name: '中洲一', pwd: '123456' },
  135. { name: '中洲二', pwd: '123456' },
  136. { name: '中洲三', pwd: '123456' },
  137. { name: '中洲四', pwd: '123456' },
  138. { name: '中洲五', pwd: '123456' },
  139. { name: '财审一', pwd: '123456' },
  140. { name: '财审二', pwd: '123456' },
  141. { name: '财审三', pwd: '123456' },
  142. { name: '财审四', pwd: '123456' },
  143. { name: '财审五', pwd: '123456' },
  144. { name: '财审六', pwd: '123456' },
  145. { name: '财审七', pwd: '123456' },
  146. { name: '财审八', pwd: '123456' },
  147. { name: '财审九', pwd: '123456' },
  148. { name: '财审十', pwd: '123456' },
  149. ];
  150. const user = users.find(item => item.name === username && item.pwd === password);
  151. if (!user) {
  152. return null;
  153. }
  154. return {
  155. can_login: 1,
  156. create_time: Date.now(),
  157. id: `tempUser${user.name}`,
  158. isNew: false,
  159. last_login: Date.now(),
  160. login_info: '',
  161. login_ip: '',
  162. username: user.name,
  163. isTemporary: true,
  164. }
  165. }
  166. /**
  167. * 登录信息校验
  168. *
  169. * @param {String} username
  170. * @param {String} password
  171. * @return {Promise}
  172. */
  173. async validLogin(username, password) {
  174. const tempUser = this.temporaryLogin(username, password);
  175. if (tempUser) {
  176. return tempUser;
  177. }
  178. let managerData = await this.findDataByCondition({username: username});
  179. // 没有找到对应数据
  180. /*if (managerData === null || managerData._id === undefined) {
  181. throw {code: 44001, err: '用户名或密码错误'};
  182. }*/
  183. // 是否禁止登录
  184. if (managerData && managerData.can_login !== 1) {
  185. throw {code: 44002, err: '账号被停用'};
  186. }
  187. // 如果不是超级管理员登录则走CLD接口登录流程
  188. if (managerData === null || managerData._id === undefined || username !== this.adminUsername) {
  189. let CLDLoginInfo = await this.CLDLogin(username, password, managerData);
  190. if (CLDLoginInfo.can_login !== 1) {
  191. throw {code: 44002, err: '账号被停用'};
  192. }
  193. managerData = CLDLoginInfo;
  194. } else {
  195. // 加密密码
  196. let encryptPassword = this.encryptPassword(managerData.token, password);
  197. if (encryptPassword !== managerData.password) {
  198. throw {code: 44001, err: '用户名或密码错误'};
  199. }
  200. }
  201. return managerData;
  202. }
  203. /**
  204. * CLD登录
  205. *
  206. * @param {String} username
  207. * @param {String} password
  208. * @param {Object} managerData
  209. * @return {Promise}
  210. */
  211. async CLDLogin(username, password, managerData) {
  212. let result = managerData;
  213. if (username === '' || password === '') {
  214. throw {code: 44001, err: '用户名或密码错误'};
  215. }
  216. let CLDUrl = 'http://cld.smartcost.com.cn/api/auth';
  217. // 生成加密token
  218. let [encryptToken, postTime] = this.generateCLDToken();
  219. let postData = {
  220. username: username,
  221. password: password,
  222. time: postTime,
  223. token: encryptToken,
  224. app: 'scConstruct'
  225. };
  226. let postOption = {
  227. url: CLDUrl,
  228. form: postData,
  229. encoding: 'utf8'
  230. };
  231. let responseData = await this.CLDRequest(postOption);
  232. // 登录成功后,存在此用户则直接返回
  233. if (managerData) {
  234. let updateData = {
  235. username: responseData.username,
  236. office: responseData.office,
  237. position: responseData.position,
  238. };
  239. await this.db.update({_id: managerData._id }, updateData);
  240. managerData.username = responseData.username;
  241. managerData.office = responseData.office;
  242. managerData.position = responseData.position;
  243. return result;
  244. }
  245. // 不存在则新增
  246. this.setScene('cldInsert');
  247. let current = new Date().getTime();
  248. //cld账号登录的统一设置可以看到用户管理和允许登录
  249. let insertData = {
  250. username: username,
  251. password: '',
  252. token: '',
  253. create_time: current,
  254. last_login: current,
  255. office: responseData.office,
  256. position: responseData.position,
  257. permission: '',
  258. can_login: 0
  259. };
  260. result = this.db.create(insertData);
  261. return result;
  262. }
  263. /**
  264. * CLD请求
  265. *
  266. * @param {Object} postOption
  267. * @return {Promise}
  268. */
  269. CLDRequest(postOption) {
  270. return new Promise(function(resolve, reject) {
  271. // 发起请求
  272. Request.post(postOption, function(error, response, body) {
  273. console.log(`body`);
  274. console.log(body);
  275. if (error || response.statusCode !== 200) {
  276. console.log(response.statusCode + ':' + error);
  277. reject({code: 44002, err: '接口请求出错'});
  278. return;
  279. }
  280. body = JSON.parse(body);
  281. // 如果接口返回错误
  282. if (body.err !== 0) {
  283. reject({code: body.err, err: '接口返回错误'});
  284. return;
  285. }
  286. resolve(body.data);
  287. });
  288. });
  289. }
  290. /**
  291. * 生成CLD Token
  292. *
  293. * @return {Array}
  294. */
  295. generateCLDToken() {
  296. // 加密内容
  297. let token = 'sc@ConS!tru@ct*88';
  298. let currentTime = new Date().getTime();
  299. currentTime = parseFloat(currentTime / 1000).toFixed(0);
  300. let encryptToken = this.encryptPassword(token, (token + currentTime));
  301. return [encryptToken, currentTime];
  302. }
  303. /**
  304. * 新增管理员
  305. *
  306. * @param {Object} data
  307. * @return {Promise}
  308. */
  309. async createManager(data) {
  310. if (Object.keys(data).length <= 0) {
  311. throw '数据格式错误';
  312. }
  313. let result = await this.db.create(data);
  314. return result;
  315. }
  316. /**
  317. * 删除后台用户权限
  318. * @param permission
  319. * @return {Promise.<void>}
  320. */
  321. async updateByPermission(permission) {
  322. let result = await this.db.update({permission: permission}, {permission: ''});
  323. return result.ok === 1;
  324. }
  325. }
  326. export default ManagerModel;