user.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. 'use strict';
  2. const { CrudService } = require('naf-framework-mongoose-free/lib/service');
  3. const { BusinessError, ErrorCode } = require('naf-core').Error;
  4. const _ = require('lodash');
  5. const assert = require('assert');
  6. //
  7. class UserService extends CrudService {
  8. constructor(ctx) {
  9. super(ctx, 'user');
  10. this.redis = this.app.redis;
  11. this.model = this.ctx.model.User.User;
  12. this.emailKey = 'bindEmail:';
  13. this.httpUtil = this.ctx.service.util.httpUtil;
  14. this.emailServiceUrl = _.get(this.app, 'config.httpPrefix.email');
  15. this.emailServiceConfig = _.get(this.app, 'config.emailConfig.config');
  16. this.conenctCode = '&&';
  17. }
  18. async beforeCreate(data) {
  19. const openid = _.get(data, 'openid');
  20. const phone = _.get(data, 'phone');
  21. if (!openid && phone) {
  22. const num = await this.model.count({ phone });
  23. if (num > 0) throw new BusinessError(ErrorCode.DATA_EXISTED, '该手机号已注册');
  24. } else if (openid) {
  25. const num = await this.model.count({ openid });
  26. if (num > 0) throw new BusinessError(ErrorCode.DATA_EXISTED, '该微信号已注册');
  27. }
  28. return data;
  29. }
  30. async resetPwd({ id }, { password }) {
  31. const data = await this.model.findById(id);
  32. if (!data) throw new BusinessError(ErrorCode.USER_NOT_EXIST);
  33. data.password = { secret: password };
  34. await data.save();
  35. }
  36. /**
  37. * 登陆
  38. * @param {Object} body 登陆参数
  39. * @param body.phone 账户
  40. * @param body.password 密码
  41. */
  42. async login({ phone, password }) {
  43. const { populate } = this.getRefMods();
  44. let user = await this.model.findOne({ phone }, '+password').populate(populate);
  45. if (!user) throw new BusinessError(ErrorCode.USER_NOT_EXIST);
  46. const { password: upwd, status } = user;
  47. if (status !== '0') throw new BusinessError(ErrorCode.USER_NOT_BIND, '该账号处于禁止使用状态');
  48. if (password !== upwd.secret) throw new BusinessError(ErrorCode.BAD_PASSWORD);
  49. // // 使用redis存储,后续的任何操作进行token的校验
  50. // await this.setUserInRedis(user);
  51. user = JSON.parse(JSON.stringify(user));
  52. delete user.password;
  53. delete user.meta;
  54. delete user.__v;
  55. const token = this.ctx.service.util.jwt.encrypt(user);
  56. return token;
  57. }
  58. /**
  59. * 微信登录
  60. * @param {Object} body 登陆参数
  61. * @param body.openid 微信小程序的openid
  62. */
  63. async wxLogin({ openid }) {
  64. const { populate } = this.getRefMods();
  65. const user = await this.model.findOne({ openid }).populate(populate);
  66. if (!user) throw new BusinessError(ErrorCode.USER_NOT_EXIST);
  67. const { status } = user;
  68. if (status !== '0') throw new BusinessError(ErrorCode.USER_NOT_BIND, '该账号处于禁止使用状态');
  69. delete user.meta;
  70. delete user.__v;
  71. const token = this.ctx.service.util.jwt.encrypt(user);
  72. return token;
  73. }
  74. /**
  75. * 绑定邮箱验证码
  76. * @param {Object} body 请求体
  77. * @param body.id 用户id
  78. * @param body.email 用户要绑定的邮箱
  79. */
  80. async toBindEmail({ id, email }) {
  81. const code = _.random(100000, 999999);
  82. const value = `${email}${this.conenctCode}${code}`;
  83. await this.redis.set(`${this.emailKey}${id}`, value, 'EX', 300);
  84. // 发邮件
  85. const data = { config: this.emailServiceConfig, template: 'bindEmail', receiver: email, params: { code } };
  86. const url = `${this.emailServiceUrl}/sendEmail`;
  87. await this.httpUtil.cpost(url, data);
  88. }
  89. async checkBindEmail({ code, id, email }) {
  90. const redisData = await this.redis.get(`${this.emailKey}${id}`);
  91. if (!redisData) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '验证码已超时');
  92. const arr = redisData.split(this.conenctCode);
  93. const rEmail = _.head(arr);
  94. const rCode = _.last(arr);
  95. if (code !== rCode) throw new BusinessError(ErrorCode.DATA_INVALID, '验证码错误');
  96. if (email !== rEmail) throw new BusinessError(ErrorCode.DATA_INVALID, '要绑定的邮箱与接收验证码的邮箱不是同一个邮箱');
  97. await this.model.updateOne({ _id: id }, { email });
  98. await this.redis.del(`${this.emailKey}${id}`);
  99. }
  100. }
  101. module.exports = UserService;