Browse Source

用户登录

guhongwei 4 years ago
parent
commit
1efdca5070
6 changed files with 151 additions and 7 deletions
  1. 2 2
      app/controller/.user.js
  2. 34 0
      app/controller/login.js
  3. 3 3
      app/model/user.js
  4. 9 2
      app/router.js
  5. 82 0
      app/service/login.js
  6. 21 0
      app/service/user.js

+ 2 - 2
app/controller/.user.js

@@ -1,6 +1,6 @@
 module.exports = {
   create: {
-    requestBody: ["!name", "mobile", "password", "dept_id", "gender", "remark"],
+    requestBody: ["!name", "!mobile", "password", "dept_id", "gender", "remark"],
   },
   destroy: {
     params: ["!id"],
@@ -8,7 +8,7 @@ module.exports = {
   },
   update: {
     params: ["!id"],
-    requestBody: ["!name", "mobile", "password", "dept_id", "gender", "remark"],
+    requestBody: ["!name", "!mobile", "password", "dept_id", "gender", "remark"],
   },
   show: {
     parameters: {

+ 34 - 0
app/controller/login.js

@@ -0,0 +1,34 @@
+'use strict';
+
+const Controller = require('egg').Controller;
+
+// 登录管理
+class LoginController extends Controller {
+
+  constructor(ctx) {
+    super(ctx);
+    this.service = this.ctx.service.login;
+  }
+
+  async login() {
+    const res = await this.service.login(this.ctx.request.body);
+    this.ctx.ok({ data: res });
+  }
+
+  async token() {
+    const res = await this.service.token(this.ctx.request.body);
+    this.ctx.ok({ data: res });
+  }
+
+  async destroy() {
+    const res = await this.service.destroy(this.ctx.request.body);
+    this.ctx.ok({ data: res });
+  }
+
+  // async wxlogin() {
+  //   const res = await this.service.wxlogin(this.ctx.request.body);
+  //   this.ctx.ok({ data: res });
+  // }
+}
+
+module.exports = LoginController;

+ 3 - 3
app/model/user.js

@@ -7,9 +7,9 @@ const UserSchema = {
   name: { type: String, required: true, maxLength: 200 }, // 用户名称
   mobile: { type: String, required: true, maxLength: 200 }, // 手机号
   password: { type: Secret, select: false }, // 密码
-  dept_id: { type: String, required: true, maxLength: 200 }, // 部门id
-  gender: { type: String, required: true, maxLength: 200 }, // 性别
-  remark: { type: String, required: true, maxLength: 200 }, // 备注
+  dept_id: { type: String, required: false, maxLength: 200 }, // 部门id
+  gender: { type: String, required: false, maxLength: 200 }, // 性别
+  remark: { type: String, required: false, maxLength: 200 }, // 备注
 };
 
 const schema = new Schema(UserSchema, { toJSON: { virtuals: true } });

+ 9 - 2
app/router.js

@@ -10,6 +10,13 @@ module.exports = app => {
   router.post('test', '/api/servicezhwl/test/update/:id', controller.test.update);
 
   // 用户表
-  router.resources('user', '/api/servicezhwl/user', controller.test); // index、create、show、destroy
-  router.post('user', '/api/servicezhwl/user/update/:id', controller.test.update);
+  router.resources('user', '/api/servicezhwl/user', controller.user); // index、create、show、destroy
+  router.post('user', '/api/servicezhwl/user/update/:id', controller.user.update);
+
+  // 用户登录
+  router.post('/api/servicezhwl/login', controller.login.login);
+  // 根据token取得用户信息
+  router.post('/api/servicezhwl/token', controller.login.token);
+  // 用户退出登录
+  router.post('/api/servicezhwl/logout', controller.login.destroy);
 };

+ 82 - 0
app/service/login.js

@@ -0,0 +1,82 @@
+'use strict';
+
+const assert = require('assert');
+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.model = this.ctx.model.User;
+  }
+
+  // 用户登录
+  async login(data) {
+    const { mobile, password } = data;
+    // 根据用户输入的手机号查询其他用户表中是否存在相应数据
+    let user = await this.model.findOne({ mobile });
+    const flag = true;
+    if (!user) {
+      user = await this.model.findOne({ mobile });
+    }
+    // 如果用户不存在抛出异常
+    if (!user) {
+      throw new BusinessError(ErrorCode.USER_NOT_EXIST);
+    }
+    let _user = '';
+    // 将用户输入的密码进行加密并与查询到的用户数据密码相比对
+    const pasw = await this.createJwtPwd(password);
+    if (flag) {
+      // 手机
+      _user = await this.model.findOne({ mobile, pasw });
+    } else {
+      // 手机
+      _user = await this.model.findOne({ mobile, pasw });
+    }
+    if (_user === '') {
+      throw new BusinessError(ErrorCode.USER_NOT_EXIST);
+    }
+    // 取出用户的类型,根据用户类型返回相应信息
+    const state = uuid();
+    const key = `free:auth:state:${state}`;
+    const token = await this.createJwt(user);
+    await this.app.redis.set(key, token, 'EX', 60 * 60 * 24);
+    return { key };
+  }
+
+  // 创建登录Token
+  async createJwt({ id, name, mobile, dept_id, gender, remark }) {
+    const { secret, expiresIn = '1d' } = this.config.jwt;
+    const subject = mobile;
+    const res = { uid: id, name, mobile, dept_id, gender, remark };
+    const token = await jwt.sign(res, secret, { expiresIn, subject });
+    return token;
+  }
+
+  // 创建密码
+  async createJwtPwd(password) {
+    const { secret } = this.config.jwt;
+    const token = await jwt.sign(password, secret);
+    return token;
+  }
+
+  // 取得redis内token信息
+  async token({ key }) {
+    assert(key, 'key不能为空');
+    const token = await this.app.redis.get(key);
+    if (!token) {
+      throw new BusinessError(ErrorCode.SERVICE_FAULT, 'token已经过期');
+    }
+    return { token };
+  }
+
+  // 删除操作
+  async destroy({ key }) {
+    const res = await this.app.redis.del(key);
+    return res;
+  }
+}
+module.exports = LoginService;

+ 21 - 0
app/service/user.js

@@ -5,12 +5,33 @@ const _ = require('lodash');
 const { ObjectId } = require('mongoose').Types;
 const { CrudService } = require('naf-framework-mongoose/lib/service');
 const { UserError, ErrorCode } = require('naf-core').Error;
+const jwt = require('jsonwebtoken');
 
 class UserService extends CrudService {
   constructor(ctx) {
     super(ctx, 'user');
     this.model = this.ctx.model.User;
   }
+  // 创建登录Token
+  async createJwtPwd(password) {
+    const { secret } = this.config.jwt;
+    const token = await jwt.sign(password, secret);
+    return token;
+  }
+  async create(data) {
+    const { name, mobile, password } = data;
+    assert(name, '用户名不能为空');
+    assert(password, '密码不能为空');
+    const has_phone = await this.model.findOne({ mobile });
+    if (has_phone) {
+      throw new UserError('此身份手机号已被注册,请更换手机号');
+    } else {
+      const pas = await this.createJwtPwd(password);
+      data.password = { secret: pas };
+      const res = await this.model.create(data);
+      return res;
+    }
+  }
 }
 
 module.exports = UserService;