From 6a9a421c61366184f92aea3f742a577d944d2879 Mon Sep 17 00:00:00 2001 From: yunpeng <153967808@qq.com> Date: Sun, 16 Apr 2023 19:33:27 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=8C=E5=96=84=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E5=92=8C=E7=99=BB=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/modules/user/controller/admin/info.ts | 4 ++ src/modules/user/entity/info.ts | 5 +- src/modules/user/entity/wx.ts | 2 +- src/modules/user/service/login.ts | 56 ++++++++++------------- src/modules/user/service/wx.ts | 36 ++++++--------- 5 files changed, 47 insertions(+), 56 deletions(-) diff --git a/src/modules/user/controller/admin/info.ts b/src/modules/user/controller/admin/info.ts index b83da4b..89f62a2 100644 --- a/src/modules/user/controller/admin/info.ts +++ b/src/modules/user/controller/admin/info.ts @@ -7,5 +7,9 @@ import { UserInfoEntity } from '../../entity/info'; @CoolController({ api: ['add', 'delete', 'update', 'info', 'list', 'page'], entity: UserInfoEntity, + pageQueryOp: { + keyWordLikeFields: ['nickName', 'phone', 'labels', 'id'], + fieldEq: ['status', 'loginType'], + }, }) export class AdminUserInfoController extends BaseController {} diff --git a/src/modules/user/entity/info.ts b/src/modules/user/entity/info.ts index 44048f0..df34eed 100644 --- a/src/modules/user/entity/info.ts +++ b/src/modules/user/entity/info.ts @@ -26,6 +26,9 @@ export class UserInfoEntity extends BaseEntity { @Column({ comment: '状态 0-禁用 1-正常', default: 1 }) status: number; - @Column({ comment: '登录方式 0-小程序 1-公众号 2-H5', default: 0 }) + @Column({ comment: '登录方式 0-小程序 1-公众号 2-H5 3-APP', default: 0 }) loginType: number; + + @Column({ comment: '标签,多个标签按“,”隔开', nullable: true }) + labels: string; } diff --git a/src/modules/user/entity/wx.ts b/src/modules/user/entity/wx.ts index 888e830..8af87f1 100644 --- a/src/modules/user/entity/wx.ts +++ b/src/modules/user/entity/wx.ts @@ -15,7 +15,7 @@ export class UserWxEntity extends BaseEntity { openid: string; @Column({ comment: '头像', nullable: true }) - avatarUrl: number; + avatarUrl: string; @Column({ comment: '昵称', nullable: true }) nickName: string; diff --git a/src/modules/user/service/login.ts b/src/modules/user/service/login.ts index 67cddf1..0a8c106 100644 --- a/src/modules/user/service/login.ts +++ b/src/modules/user/service/login.ts @@ -87,37 +87,24 @@ export class UserLoginService extends BaseService { province: wxUserInfo.province, country: wxUserInfo.country, }); - return this.wxLoginToken(wxUserInfo); + return this.wxLoginToken(wxUserInfo, 1); } else { - throw new Error('微信登录失败'); + throw new CoolCommException('微信登录失败'); } } /** - * 保存微信信息 - * @param wxUserInfo + * 保存/更新 微信信息(根据微信规则,用户头像昵称无法在此获取,需要通过chooseAvatar进行获取) + * @param wxUserInfo 微信里的用户信息 * @returns */ async saveWxInfo(wxUserInfo) { - const find: any = {}; - if (wxUserInfo.unionid) { - find.unionid = wxUserInfo.unionid; + const wxInfo = await this.userWxEntity.findOneBy({ openid: wxUserInfo.openid }); + if (!wxInfo) { + await this.userWxEntity.insert(wxInfo); } - if (wxUserInfo.openid) { - find.openid = wxUserInfo.openid; - } - 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; + await this.userWxEntity.save(Object.assign(wxInfo, wxUserInfo)); + return wxInfo; } /** @@ -133,30 +120,35 @@ export class UserLoginService extends BaseService { iv ); if (wxUserInfo) { - // 保存 wxUserInfo = await this.saveWxInfo(wxUserInfo); - return this.wxLoginToken(wxUserInfo); + return this.wxLoginToken(wxUserInfo, 0); } } /** * 微信登录 获得token * @param wxUserInfo 微信用户信息 + * @param loginType 登录方式 0-小程序 1-公众号 2-H5 * @returns */ - async wxLoginToken(wxUserInfo) { + async wxLoginToken(wxUserInfo, loginType) { 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) { - userInfo = { + userInfo = new UserInfoEntity(); + Object.assign(userInfo, { unionid, - nickName: wxUserInfo.nickName, - avatarUrl: wxUserInfo.avatarUrl, - gender: wxUserInfo.gender, - }; + loginType, + ...wxUserInfo + }); 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 }); } /** diff --git a/src/modules/user/service/wx.ts b/src/modules/user/service/wx.ts index 2d2ec87..46ab3a4 100644 --- a/src/modules/user/service/wx.ts +++ b/src/modules/user/service/wx.ts @@ -2,6 +2,10 @@ import { Config, Provide } from '@midwayjs/decorator'; import { BaseService, CoolCommException } from '@cool-midway/core'; import axios from 'axios'; 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 */ public async getWxToken(type = 'mp') { - //@ts-ignore 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: { grant_type: 'client_credential', appid: conf.appid, @@ -43,7 +46,7 @@ export class UserWxService extends BaseService { */ async openOrMpUserInfo(token) { return await axios - .get('https://api.weixin.qq.com/sns/userinfo', { + .get(wxBaseUrl + '/sns/userinfo', { params: { access_token: token.access_token, openid: token.openid, @@ -56,13 +59,13 @@ export class UserWxService extends BaseService { } /** - * 获得token嗯 + * 获得token * @param code * @param conf */ async openOrMpToken(code, conf) { const result = await axios.get( - 'https://api.weixin.qq.com/sns/oauth2/access_token', + wxBaseUrl + '/sns/oauth2/access_token', { params: { appid: conf.appid, @@ -83,7 +86,7 @@ export class UserWxService extends BaseService { async miniSession(code) { const { appid, secret } = this.config.wx.mini; const result = await axios.get( - 'https://api.weixin.qq.com/sns/jscode2session', + wxBaseUrl + '/sns/jscode2session', { params: { appid, @@ -113,15 +116,10 @@ export class UserWxService extends BaseService { iv, session.session_key ); - if (info) { - delete info['watermark']; - return { - ...info, - openid: session['openid'], - unionid: session['unionid'], - }; - } - return null; + delete info['watermark']; + info.openid = session['openid']; + info.unionid = session['unionid']; + return _.pickBy({ ...info }); } /** @@ -149,17 +147,11 @@ export class UserWxService extends BaseService { encryptedData = Buffer.from(encryptedData, 'base64'); iv = Buffer.from(iv, 'base64'); try { - // 解密 const decipher = crypto.createDecipheriv('aes-128-cbc', sessionKey, iv); - // 设置自动 padding 为 true,删除填充补位 decipher.setAutoPadding(true); - // @ts-ignore let decoded = decipher.update(encryptedData, 'binary', 'utf8'); - // @ts-ignore decoded += decipher.final('utf8'); - // @ts-ignore - decoded = JSON.parse(decoded); - return decoded; + return JSON.parse(decoded); } catch (err) { throw new CoolCommException('获得信息失败'); }