@@ -2,21 +2,35 @@ import { Injectable, HttpException, HttpStatus, Logger } from '@nestjs/common';
2
2
import { LoginDto } from '../../controllers/login/dto/login.dto' ;
3
3
import { AccountEntity } from '../../entities/account.entity' ;
4
4
import { InjectRepository } from '@nestjs/typeorm' ;
5
- import { Repository , getConnection } from 'typeorm' ;
5
+ import { Repository , getConnection , SelectQueryBuilder } from 'typeorm' ;
6
6
import { ToolsService } from '@src/modules/shared/services/tools/tools.service' ;
7
7
import { isMobilePhone , isEmail } from 'class-validator' ;
8
8
import { AccountLastLoginEntity } from '../../entities/account.last.login.entity' ;
9
9
import { LoginVo } from '../../controllers/login/vo/login.vo' ;
10
+ import { AccountTokenEntity } from '../../entities/account.token.entity' ;
11
+ import { ConfigService , InjectConfig } from 'nestjs-config' ;
12
+ import moment from 'moment' ;
13
+ import { usernameReg } from '@src/constants' ;
10
14
15
+ interface IAccount {
16
+ id : number ;
17
+ username : string ;
18
+ email : string ;
19
+ mobile : string ;
20
+ isSuper : number ;
21
+ platform : number ;
22
+ }
11
23
@Injectable ( )
12
24
export class LoginService {
13
25
private logger : Logger = new Logger ( LoginService . name ) ;
14
26
constructor (
15
- @InjectRepository ( AccountEntity )
16
- private readonly accountRepository : Repository < AccountEntity > ,
17
27
@InjectRepository ( AccountLastLoginEntity )
18
28
private readonly accountLastLoginRepository : Repository < AccountLastLoginEntity > ,
29
+ @InjectRepository ( AccountTokenEntity )
30
+ private readonly accountTokenRepository : Repository < AccountTokenEntity > ,
19
31
private readonly toolsService : ToolsService ,
32
+ @InjectConfig ( )
33
+ private readonly configService : ConfigService ,
20
34
) { }
21
35
22
36
/**
@@ -31,44 +45,75 @@ export class LoginService {
31
45
async adminLogin ( loginDto : LoginDto , ipAddress : string ) : Promise < LoginVo > {
32
46
try {
33
47
const { username, password } = loginDto ;
34
- let sqlPassword : string | undefined ;
35
- let findAccount : AccountEntity | undefined ;
48
+ type TypeAccountFindResult = Extract < AccountEntity , IAccount > | undefined ;
49
+ let findAccount : TypeAccountFindResult ;
50
+ const queryBuilder = this . queryLoginBuilder ;
51
+ // 根据手机号码查询
36
52
if ( isMobilePhone ( username , 'zh-CN' ) ) {
37
- const findResult : Pick < AccountEntity , 'password' > | undefined = await getConnection ( )
38
- . createQueryBuilder ( AccountEntity , 'account' )
39
- . select ( [ ] )
40
- . addSelect ( 'account.password' , 'password' )
53
+ findAccount = await queryBuilder
41
54
. where ( '(account.mobile = :mobile)' , { mobile : username } )
42
55
. getRawOne ( ) ;
43
- sqlPassword = findResult ?. password ;
44
- findAccount = await this . accountRepository . findOne ( { where : { mobile : username } } ) ;
45
56
} else if ( isEmail ( username ) ) {
46
- const findResult : Pick < AccountEntity , 'password' > | undefined = await getConnection ( )
47
- . createQueryBuilder ( AccountEntity , 'account' )
48
- . select ( [ ] )
49
- . addSelect ( 'account.password' , 'password' )
57
+ // 根据邮箱查询
58
+ findAccount = await queryBuilder
50
59
. where ( '(account.email = :email)' , { email : username } )
51
60
. getRawOne ( ) ;
52
- sqlPassword = findResult ?. password ;
53
- findAccount = await this . accountRepository . findOne ( { where : { email : username } } ) ;
54
61
} else {
55
- const findResult : Pick < AccountEntity , 'password' > | undefined = await getConnection ( )
56
- . createQueryBuilder ( AccountEntity , 'account' )
57
- . select ( [ ] )
58
- . addSelect ( 'account.password' , 'password' )
62
+ // 用户名查询
63
+ findAccount = await queryBuilder
59
64
. where ( '(account.username = :username)' , { username } )
60
65
. getRawOne ( ) ;
61
- sqlPassword = findResult ?. password ;
62
- findAccount = await this . accountRepository . findOne ( { where : { username } } ) ;
63
66
}
64
- if ( sqlPassword && this . toolsService . checkPassword ( password , sqlPassword ) && findAccount ) {
67
+ if (
68
+ findAccount &&
69
+ findAccount . password &&
70
+ this . toolsService . checkPassword ( password , findAccount . password )
71
+ ) {
72
+ // 记录最后登录时间和ip地址
65
73
const lastLogin = this . accountLastLoginRepository . create ( {
66
74
accountId : findAccount . id ,
67
75
lastLoginIp : ipAddress ,
68
76
} ) ;
69
77
await this . accountLastLoginRepository . save ( lastLogin ) ;
70
78
this . logger . log ( '当前用户' , findAccount ) ;
71
- return Object . assign ( findAccount , { token : this . toolsService . generateToken ( findAccount ) } ) ;
79
+ // 生成token存储到token表中并且返回给前端
80
+ const token = this . toolsService . uuidToken ;
81
+ const { id, username, email, mobile, isSuper, platform } =
82
+ this . filterAccountField ( findAccount ) ;
83
+ const tokenExpire : number = this . configService . get ( 'admin.tokenExpire' ) ;
84
+ const accountToken = {
85
+ userId : id ,
86
+ username,
87
+ email,
88
+ mobile,
89
+ isSuper,
90
+ platform,
91
+ token,
92
+ // 设置token失效时间
93
+ expireTime : moment ( ) . add ( tokenExpire , 'day' ) . format ( 'YYYY-MM-DD HH:mm:ss' ) ,
94
+ } ;
95
+ // 先判断之前是否有记录,有记录就更新,没记录就创建
96
+ const accountTokenResult : Pick < AccountTokenEntity , 'id' > | undefined =
97
+ await this . accountTokenRepository . findOne ( {
98
+ where : { userId : id } ,
99
+ select : [ 'id' ] ,
100
+ } ) ;
101
+ if ( accountTokenResult ?. id ) {
102
+ await this . accountTokenRepository . update ( { id : accountTokenResult . id } , accountToken ) ;
103
+ } else {
104
+ const accountTokenSave : AccountTokenEntity =
105
+ this . accountTokenRepository . create ( accountToken ) ;
106
+ await this . accountTokenRepository . save ( accountTokenSave ) ;
107
+ }
108
+ return {
109
+ token,
110
+ id,
111
+ username,
112
+ email,
113
+ mobile,
114
+ isSuper,
115
+ platform,
116
+ } ;
72
117
} else {
73
118
throw new HttpException ( '用户名或密码错误' , HttpStatus . OK ) ;
74
119
}
@@ -77,4 +122,45 @@ export class LoginService {
77
122
throw new HttpException ( '用户名或密码错误' , HttpStatus . OK ) ;
78
123
}
79
124
}
125
+
126
+ /**
127
+ * @Author : 水痕
128
+ * @Date : 2021-07-26 09:07:15
129
+ * @LastEditors : 水痕
130
+ * @Description : 公共的查询部分
131
+ * @param {* }
132
+ * @return {* }
133
+ */
134
+ private get queryLoginBuilder ( ) : SelectQueryBuilder < AccountEntity > {
135
+ return getConnection ( )
136
+ . createQueryBuilder ( AccountEntity , 'account' )
137
+ . select ( 'account.id' , 'id' )
138
+ . addSelect ( 'account.username' , 'username' )
139
+ . addSelect ( 'account.mobile' , 'mobile' )
140
+ . addSelect ( 'account.email' , 'email' )
141
+ . addSelect ( 'account.platform' , 'platform' )
142
+ . addSelect ( 'account.isSuper' , 'isSuper' )
143
+ . addSelect ( 'account.password' , 'password' ) ;
144
+ }
145
+
146
+ /**
147
+ * @Author : 水痕
148
+ * @Date : 2021-07-26 10:15:17
149
+ * @LastEditors : 水痕
150
+ * @Description : 过来字段
151
+ * @param {IAccount } accountInfo
152
+ * @return {* }
153
+ */
154
+ private filterAccountField ( accountInfo : IAccount ) : IAccount {
155
+ const { username, mobile, email } = accountInfo ;
156
+ const _mobile = isMobilePhone ( mobile , 'zh-CN' ) ? mobile : '' ;
157
+ const _email = isEmail ( email ) ? email : '' ;
158
+ const _username = usernameReg . test ( username ) ? username : '' ;
159
+ return {
160
+ ...accountInfo ,
161
+ username : _username ,
162
+ mobile : _mobile ,
163
+ email : _email ,
164
+ } ;
165
+ }
80
166
}
0 commit comments