feat: 完善用户和登录

This commit is contained in:
yunpeng 2023-04-16 19:33:27 +08:00
parent b14b88a662
commit 6a9a421c61
5 changed files with 47 additions and 56 deletions

View File

@ -7,5 +7,9 @@ import { UserInfoEntity } from '../../entity/info';
@CoolController({ @CoolController({
api: ['add', 'delete', 'update', 'info', 'list', 'page'], api: ['add', 'delete', 'update', 'info', 'list', 'page'],
entity: UserInfoEntity, entity: UserInfoEntity,
pageQueryOp: {
keyWordLikeFields: ['nickName', 'phone', 'labels', 'id'],
fieldEq: ['status', 'loginType'],
},
}) })
export class AdminUserInfoController extends BaseController {} export class AdminUserInfoController extends BaseController {}

View File

@ -26,6 +26,9 @@ export class UserInfoEntity extends BaseEntity {
@Column({ comment: '状态 0-禁用 1-正常', default: 1 }) @Column({ comment: '状态 0-禁用 1-正常', default: 1 })
status: number; status: number;
@Column({ comment: '登录方式 0-小程序 1-公众号 2-H5', default: 0 }) @Column({ comment: '登录方式 0-小程序 1-公众号 2-H5 3-APP', default: 0 })
loginType: number; loginType: number;
@Column({ comment: '标签,多个标签按“,”隔开', nullable: true })
labels: string;
} }

View File

@ -15,7 +15,7 @@ export class UserWxEntity extends BaseEntity {
openid: string; openid: string;
@Column({ comment: '头像', nullable: true }) @Column({ comment: '头像', nullable: true })
avatarUrl: number; avatarUrl: string;
@Column({ comment: '昵称', nullable: true }) @Column({ comment: '昵称', nullable: true })
nickName: string; nickName: string;

View File

@ -87,37 +87,24 @@ export class UserLoginService extends BaseService {
province: wxUserInfo.province, province: wxUserInfo.province,
country: wxUserInfo.country, country: wxUserInfo.country,
}); });
return this.wxLoginToken(wxUserInfo); return this.wxLoginToken(wxUserInfo, 1);
} else { } else {
throw new Error('微信登录失败'); throw new CoolCommException('微信登录失败');
} }
} }
/** /**
* * / (chooseAvatar进行获取)
* @param wxUserInfo * @param wxUserInfo
* @returns * @returns
*/ */
async saveWxInfo(wxUserInfo) { async saveWxInfo(wxUserInfo) {
const find: any = {}; const wxInfo = await this.userWxEntity.findOneBy({ openid: wxUserInfo.openid });
if (wxUserInfo.unionid) { if (!wxInfo) {
find.unionid = wxUserInfo.unionid; await this.userWxEntity.insert(wxInfo);
} }
if (wxUserInfo.openid) { await this.userWxEntity.save(Object.assign(wxInfo, wxUserInfo));
find.openid = wxUserInfo.openid; return wxInfo;
}
let wxInfo: any = await this.userWxEntity.findOneBy(find);
if (wxInfo) {
delete wxUserInfo.avatarUrl;
wxUserInfo.id = wxInfo.id;
} else {
// 微信的链接会失效,需要保存到本地
wxUserInfo.avatarUrl = await this.file.downAndUpload(
wxUserInfo.avatarUrl
);
}
await this.userWxEntity.save(wxUserInfo);
return wxUserInfo;
} }
/** /**
@ -133,30 +120,35 @@ export class UserLoginService extends BaseService {
iv iv
); );
if (wxUserInfo) { if (wxUserInfo) {
// 保存
wxUserInfo = await this.saveWxInfo(wxUserInfo); wxUserInfo = await this.saveWxInfo(wxUserInfo);
return this.wxLoginToken(wxUserInfo); return this.wxLoginToken(wxUserInfo, 0);
} }
} }
/** /**
* token * token
* @param wxUserInfo * @param wxUserInfo
* @param loginType 0- 1- 2-H5
* @returns * @returns
*/ */
async wxLoginToken(wxUserInfo) { async wxLoginToken(wxUserInfo, loginType) {
const unionid = wxUserInfo.unionid ? wxUserInfo.unionid : wxUserInfo.openid; const unionid = wxUserInfo.unionid ? wxUserInfo.unionid : wxUserInfo.openid;
let userInfo: any = await this.userInfoEntity.findOneBy({ unionid }); let userInfo: UserInfoEntity = await this.userInfoEntity.findOneBy({ unionid });
if (!userInfo) { if (!userInfo) {
userInfo = { userInfo = new UserInfoEntity();
Object.assign(userInfo, {
unionid, unionid,
nickName: wxUserInfo.nickName, loginType,
avatarUrl: wxUserInfo.avatarUrl, ...wxUserInfo
gender: wxUserInfo.gender, });
};
await this.userInfoEntity.insert(userInfo); await this.userInfoEntity.insert(userInfo);
return this.token({ userId: userInfo.id });
} }
if (userInfo.status === 0) {
throw new CoolCommException('您已违规被禁用');
}
// 更新登录时间
await this.userInfoEntity.save(Object.assign(userInfo, wxUserInfo));
return this.token({ userId: userInfo.id });
} }
/** /**

View File

@ -2,6 +2,10 @@ import { Config, Provide } from '@midwayjs/decorator';
import { BaseService, CoolCommException } from '@cool-midway/core'; import { BaseService, CoolCommException } from '@cool-midway/core';
import axios from 'axios'; import axios from 'axios';
import * as crypto from 'crypto'; import * as crypto from 'crypto';
import * as _ from 'lodash';
// 微信请求域名
const wxBaseUrl = 'https://api.weixin.qq.com';
/** /**
* *
@ -26,9 +30,8 @@ export class UserWxService extends BaseService {
* @param secret * @param secret
*/ */
public async getWxToken(type = 'mp') { public async getWxToken(type = 'mp') {
//@ts-ignore
const conf = this.config.wx[type]; const conf = this.config.wx[type];
return await axios.get('https://api.weixin.qq.com/cgi-bin/token', { return await axios.get(wxBaseUrl + '/cgi-bin/token', {
params: { params: {
grant_type: 'client_credential', grant_type: 'client_credential',
appid: conf.appid, appid: conf.appid,
@ -43,7 +46,7 @@ export class UserWxService extends BaseService {
*/ */
async openOrMpUserInfo(token) { async openOrMpUserInfo(token) {
return await axios return await axios
.get('https://api.weixin.qq.com/sns/userinfo', { .get(wxBaseUrl + '/sns/userinfo', {
params: { params: {
access_token: token.access_token, access_token: token.access_token,
openid: token.openid, openid: token.openid,
@ -56,13 +59,13 @@ export class UserWxService extends BaseService {
} }
/** /**
* token * token
* @param code * @param code
* @param conf * @param conf
*/ */
async openOrMpToken(code, conf) { async openOrMpToken(code, conf) {
const result = await axios.get( const result = await axios.get(
'https://api.weixin.qq.com/sns/oauth2/access_token', wxBaseUrl + '/sns/oauth2/access_token',
{ {
params: { params: {
appid: conf.appid, appid: conf.appid,
@ -83,7 +86,7 @@ export class UserWxService extends BaseService {
async miniSession(code) { async miniSession(code) {
const { appid, secret } = this.config.wx.mini; const { appid, secret } = this.config.wx.mini;
const result = await axios.get( const result = await axios.get(
'https://api.weixin.qq.com/sns/jscode2session', wxBaseUrl + '/sns/jscode2session',
{ {
params: { params: {
appid, appid,
@ -113,15 +116,10 @@ export class UserWxService extends BaseService {
iv, iv,
session.session_key session.session_key
); );
if (info) { delete info['watermark'];
delete info['watermark']; info.openid = session['openid'];
return { info.unionid = session['unionid'];
...info, return _.pickBy({ ...info });
openid: session['openid'],
unionid: session['unionid'],
};
}
return null;
} }
/** /**
@ -149,17 +147,11 @@ export class UserWxService extends BaseService {
encryptedData = Buffer.from(encryptedData, 'base64'); encryptedData = Buffer.from(encryptedData, 'base64');
iv = Buffer.from(iv, 'base64'); iv = Buffer.from(iv, 'base64');
try { try {
// 解密
const decipher = crypto.createDecipheriv('aes-128-cbc', sessionKey, iv); const decipher = crypto.createDecipheriv('aes-128-cbc', sessionKey, iv);
// 设置自动 padding 为 true删除填充补位
decipher.setAutoPadding(true); decipher.setAutoPadding(true);
// @ts-ignore
let decoded = decipher.update(encryptedData, 'binary', 'utf8'); let decoded = decipher.update(encryptedData, 'binary', 'utf8');
// @ts-ignore
decoded += decipher.final('utf8'); decoded += decipher.final('utf8');
// @ts-ignore return JSON.parse(decoded);
decoded = JSON.parse(decoded);
return decoded;
} catch (err) { } catch (err) {
throw new CoolCommException('获得信息失败'); throw new CoolCommException('获得信息失败');
} }