123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- import { Config, Inject, Provide } from '@midwayjs/core';
- import { get } from 'lodash';
- import { RoleService } from '../service/system/role.service';
- import { RedisService } from '@midwayjs/redis';
- import * as Crypto from 'crypto-js';
- import { Context } from '@midwayjs/koa';
- import { ServiceError, ErrorCode } from '../error/service.error';
- import { InjectEntityModel } from '@midwayjs/typeorm';
- import { Equal, Repository } from 'typeorm';
- import { LoginDTO, LoginType, UPwdDTO } from '../interface/login.interface';
- import { Opera } from '../frame/dbOpera';
- import { Admin } from '../entity/system/admin.entity';
- import * as bcrypt from 'bcryptjs';
- import { User } from '../entity/system/user.entity';
- @Provide()
- export class LoginService {
- @Inject()
- roleService: RoleService;
- @Inject()
- ctx: Context;
- @Config('loginSign')
- loginSign;
- @Config('jwt.secret')
- jwtSecret;
- @Config('jwt.expiresIn')
- jwtExpiresIn;
- @Inject()
- redisService: RedisService;
- @InjectEntityModel(Admin)
- adminModel: Repository<Admin>;
- @InjectEntityModel(User)
- userModel: Repository<User>;
- async onePointLogin(loginVo) {
- const { id, role } = loginVo;
- const rediskey = `${this.loginSign}:${role}:${id}`;
- // 随机字符串 验证用户登录用
- const str = this.randomStr();
- // 拼接成token内的登录code 加密前数据
- const val = `${rediskey}:${str}`;
- // 加密后存入token内
- const code = Crypto.AES.encrypt(val, this.jwtSecret).toString();
- // 设置redis登录记录 将 随机字符串存在redis中. 验证时需要将加密的字符串解密,解密后和redis中的对比验证
- await this.redisService.set(rediskey, str, 'EX', this.jwtExpiresIn);
- return code;
- }
- /**
- * 账密登录
- * @param data 用户名和密码
- * @param type 用户类型
- * @returns 用户信息/空值
- */
- async loginByAccount(data: LoginDTO, type: LoginType) {
- let model;
- if (type === LoginType.Admin) model = this.adminModel;
- else model = this.userModel;
- const user = await model.createQueryBuilder('t').where('t.account = :account', { account: data.account }).addSelect('t.password').getOne();
- if (!user) throw new ServiceError(ErrorCode.USER_NOT_FOUND);
- await this.checkAccountCanLogin(user, type);
- const result = bcrypt.compareSync(data.password, user.password);
- if (!result) throw new ServiceError(ErrorCode.BAD_PASSWORD);
- return user;
- }
- /**
- * 检查用户是否可以登录(从用户本身和角色检查)
- * @param user 用户信息
- * @param type 用户类型
- */
- async checkAccountCanLogin(user, type: LoginType) {
- // 判断是否可以使用:
- // 管理员: 超级管理员无视,直接往下; 普通管理员需要查看is_use是不是'0'
- // 其他用户需要看status是不是'1';
- if (type === 'Admin') {
- if (get(user, 'is_super') === '1') {
- if (get(user, 'is_use') === '1') throw new ServiceError(ErrorCode.USER_IS_DISABLED);
- }
- } else {
- if (get(user, 'status') !== '1') throw new ServiceError(ErrorCode.USER_IS_DISABLED);
- const qb = [
- { column: 'code', opera: [Opera.Equal], value: type },
- { column: 'is_use', opera: [Opera.Equal], value: '0' },
- ];
- const role = await this.roleService.fetch(qb);
- if (!role) throw new ServiceError(ErrorCode.ROLE_IS_DISABLED);
- }
- }
- // 修改密码
- async updatePwd(data: UPwdDTO, type: LoginType) {
- let model;
- if (type === LoginType.Admin) model = this.adminModel;
- else model = this.userModel;
- const user = await model.findOne({ where: { id: Equal(data.id) } });
- if (!user) new ServiceError(ErrorCode.USER_NOT_FOUND);
- await model.update({ id: data.id }, { password: data.password });
- }
- // 需要改的时候再用
- async wxAppLogin(openid: string, type: LoginType) {
- let model;
- if (type === LoginType.Admin) model = this.adminModel;
- else model = this.userModel;
- const user = await model.findOne({ where: { openid: Equal(openid) } });
- if (!user) throw new ServiceError(ErrorCode.USER_NOT_FOUND);
- return user;
- }
- randomStr(len = 32) {
- return Math.random().toString(36).slice(-len);
- }
- }
|