123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- 'use strict';
- const assert = require('assert');
- const _ = require('lodash');
- const { ObjectId } = require('mongoose').Types;
- const { CrudService } = require('naf-framework-mongoose/lib/service');
- const { BusinessError, ErrorCode } = require('naf-core').Error;
- const jwt = require('jsonwebtoken');
- const uuid = require('uuid');
- class LoginService extends CrudService {
- constructor(ctx) {
- super(ctx, 'login');
- this.uModel = this.ctx.model.User;
- this.stuModel = this.ctx.model.Student;
- this.tModel = this.ctx.model.Teacher;
- this.schModel = this.ctx.model.School;
- this.hModel = this.ctx.model.Headteacher;
- }
- async login(data) {
- const { mobile, passwd } = data;
- assert(mobile, 'mobile不能为空');
- // assert(/^\d{11}$/i.test(mobile), 'mobile无效');
- assert(passwd, 'passwd不能为空');
- const res = await this.uModel.findOne({ mobile }, '+passwd');
- if (!res) {
- throw new BusinessError(ErrorCode.USER_NOT_EXIST);
- }
- // 验证密码
- console.log('sjk-->' + res.passwd.secret);
- console.log('sr-->' + passwd);
- if (res.passwd.secret !== passwd) {
- throw new BusinessError(ErrorCode.BAD_PASSWORD);
- }
- return await this.createJwt(res);
- }
- // 创建登录Token
- async createJwt({ _id, name, mobile, openid, type, uid, status }) {
- const { secret, expiresIn = '1d', issuer = type } = this.config.jwt;
- const subject = mobile;
- let _userid = '';
- let res = {};
- // 身份,0、中心管理元1、班主任用户2、学校用户3、教师4、学生
- if (type === '0') {
- _userid = _id.toString();
- res = { userid: _userid, name, type, id: _id, status };
- } else if (type === '1') {
- _userid = uid.toString();
- const result = await this.hModel.findById(_userid);
- res = { userid: _userid, name, type, id: _id, status };
- } else if (type === '2') {
- _userid = uid.toString();
- const result = await this.schModel.findById(_userid);
- res = { userid: _userid, code: result.code, name, type, id: _id, status };
- } else if (type === '3') {
- _userid = uid.toString();
- const result = await this.tModel.findById(_userid);
- res = { userid: _userid, schid: result.schid, schname: result.schname, name, subid: result.subid, type, id: _id, status };
- } else if (type === '4') {
- _userid = uid;
- console.log('进入查询--' + _userid);
- const result = await this.stuModel.findById(_userid);
- console.log(result);
- res = { userid: _userid, schid: result.schid, schname: result.school_name, termid: result.termid, batchid: result.batchid, classid: result.classid, bedroomid: result.bedroomid, bedroom: result.bedroom, job: result.job, name, type, id: _id, status, planid: result.planid };
- }
- const token = await jwt.sign(res, secret, { expiresIn, issuer, subject });
- return token;
- }
- // 微信校验mq接口
- async wxcheck(data) {
- const { qrcode, openid } = data;
- assert(qrcode, 'qrcode不能为空');
- assert(openid, 'openid不能为空');
- // TODO: 发布扫码成功消息
- console.log('qrcode-->' + qrcode);
- const { mq } = this.ctx;
- const ex = 'qrcode.login';
- const parm = {
- durable: true,
- headers: {
- openid,
- } };
- if (mq) {
- await mq.topic(ex, qrcode, 'scaned', parm);
- }
- }
- // 微信登录接口
- async wxlogin(data) {
- const { qrcode, openid } = data;
- assert(qrcode, 'qrcode不能为空');
- assert(openid, 'openid不能为空');
- const res = await this.uModel.findOne({ openid });
- if (!res) {
- throw new BusinessError(ErrorCode.USER_NOT_EXIST);
- }
- const result = await this.createJwt(res);
- return result;
- }
- async userbind(data) {
- const { qrcode, openid } = data;
- assert(qrcode, 'qrcode不能为空');
- assert(openid, 'openid不能为空');
- const key = `naf:qrcode:login:${qrcode}`;
- const status = await this.app.redis.get(key);
- if (!status) {
- throw new BusinessError(ErrorCode.SERVICE_FAULT, '二维码已过期');
- }
- if (status !== 'pending') {
- throw new BusinessError(ErrorCode.SERVICE_FAULT, '二维码状态无效');
- }
- const res = await this.uModel.findOne({ openid });
- if (!res) {
- throw new BusinessError(ErrorCode.USER_NOT_EXIST);
- }
- const result = await this.createJwt(res);
- // TODO: 修改二维码状态,登录凭证保存到redis
- await this.app.redis.set(key, `scaned:${result}`, 'EX', 600);
- // TODO: 发布扫码成功消息
- const { mq } = this.ctx;
- const ex = 'qrcode.login';
- if (mq) {
- await mq.topic(ex, qrcode, 'scaned', { durable: true });
- }
- }
- /**
- * 创建二维码
- * 随机生成二维码,并保存在Redis中,状态初始为pending
- * 状态描述:
- * pending - 等待扫码
- * consumed - 使用二维码登录完成
- * ${jwt.token} - Jwt登录凭证
- */
- async createQrcode() {
- const qrcode = uuid();
- const key = `naf:qrcode:login:${qrcode}`;
- await this.app.redis.set(key, 'pending', 'EX', 600);
- return qrcode;
- }
- // 使用二维码换取登录凭证
- async qrcodeLogin(qrcode) {
- assert(qrcode, 'qrcode不能为空');
- const key = `naf:qrcode:login:${qrcode}`;
- const val = await this.app.redis.get(key);
- if (!val) {
- throw new BusinessError(ErrorCode.SERVICE_FAULT, '二维码已过期');
- }
- const [ status, token ] = val.split(':', 2);
- if (status !== 'scaned' || !token) {
- throw new BusinessError(ErrorCode.SERVICE_FAULT, '二维码状态无效');
- }
- // TODO: 修改二维码状态
- await this.app.redis.set(key, 'consumed', 'EX', 600);
- return { token };
- }
- // 检查二维码状态
- async checkQrcode(qrcode) {
- assert(qrcode, 'qrcode不能为空');
- const key = `naf:qrcode:login:${qrcode}`;
- const val = await this.app.redis.get(key);
- if (!val) {
- throw new BusinessError(ErrorCode.SERVICE_FAULT, '二维码已过期');
- }
- const [ status ] = val.split(':', 2);
- return { status };
- }
- }
- module.exports = LoginService;
|