mirror of
https://github.com/cool-team-official/cool-admin-midway.git
synced 2026-01-19 12:20:30 +00:00
新增app用户模块
This commit is contained in:
parent
b14b88a662
commit
2987665a15
@ -4,6 +4,7 @@
|
|||||||
"description": "一个项目用COOL就够了",
|
"description": "一个项目用COOL就够了",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@alicloud/pop-core": "^1.7.12",
|
||||||
"@cool-midway/cloud": "^6.0.0",
|
"@cool-midway/cloud": "^6.0.0",
|
||||||
"@cool-midway/core": "^6.0.1",
|
"@cool-midway/core": "^6.0.1",
|
||||||
"@cool-midway/file": "^6.0.0",
|
"@cool-midway/file": "^6.0.0",
|
||||||
@ -25,7 +26,6 @@
|
|||||||
"@midwayjs/validate": "^3.10.7",
|
"@midwayjs/validate": "^3.10.7",
|
||||||
"@midwayjs/view-ejs": "^3.10.7",
|
"@midwayjs/view-ejs": "^3.10.7",
|
||||||
"axios": "^1.3.5",
|
"axios": "^1.3.5",
|
||||||
"@alicloud/pop-core": "^1.7.12",
|
|
||||||
"cache-manager-fs-hash": "^1.0.0",
|
"cache-manager-fs-hash": "^1.0.0",
|
||||||
"ipip-ipdb": "^0.6.0",
|
"ipip-ipdb": "^0.6.0",
|
||||||
"jsonwebtoken": "^9.0.0",
|
"jsonwebtoken": "^9.0.0",
|
||||||
@ -35,6 +35,7 @@
|
|||||||
"moment": "^2.29.4",
|
"moment": "^2.29.4",
|
||||||
"mysql2": "^3.1.2",
|
"mysql2": "^3.1.2",
|
||||||
"svg-captcha": "^1.4.0",
|
"svg-captcha": "^1.4.0",
|
||||||
|
"svg2png-wasm": "^1.3.4",
|
||||||
"typeorm": "^0.3.12",
|
"typeorm": "^0.3.12",
|
||||||
"uuid": "^9.0.0"
|
"uuid": "^9.0.0"
|
||||||
},
|
},
|
||||||
|
|||||||
@ -15,6 +15,9 @@ import * as jwt from 'jsonwebtoken';
|
|||||||
import * as svgToDataURL from 'mini-svg-data-uri';
|
import * as svgToDataURL from 'mini-svg-data-uri';
|
||||||
import { Context } from '@midwayjs/koa';
|
import { Context } from '@midwayjs/koa';
|
||||||
import { CacheManager } from '@midwayjs/cache';
|
import { CacheManager } from '@midwayjs/cache';
|
||||||
|
import { readFileSync } from 'fs';
|
||||||
|
const { svg2png, initialize } = require('svg2png-wasm');
|
||||||
|
initialize(readFileSync('./node_modules/svg2png-wasm/svg2png_wasm_bg.wasm'));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 登录
|
* 登录
|
||||||
@ -107,7 +110,7 @@ export class BaseSysLoginService extends BaseService {
|
|||||||
* @param width 宽
|
* @param width 宽
|
||||||
* @param height 高
|
* @param height 高
|
||||||
*/
|
*/
|
||||||
async captcha(type: string, width = 150, height = 50) {
|
async captcha(type: string, width = 150, height = 50, color = '#fff') {
|
||||||
const svg = svgCaptcha.create({
|
const svg = svgCaptcha.create({
|
||||||
ignoreChars: 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM',
|
ignoreChars: 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM',
|
||||||
width,
|
width,
|
||||||
@ -130,11 +133,22 @@ export class BaseSysLoginService extends BaseService {
|
|||||||
'#999',
|
'#999',
|
||||||
];
|
];
|
||||||
rpList.forEach(rp => {
|
rpList.forEach(rp => {
|
||||||
result.data = result.data['replaceAll'](rp, '#fff');
|
result.data = result.data['replaceAll'](rp, color);
|
||||||
});
|
});
|
||||||
if (type === 'base64') {
|
if (type === 'base64') {
|
||||||
result.data = svgToDataURL(result.data);
|
result.data = svgToDataURL(result.data);
|
||||||
}
|
}
|
||||||
|
if (type === 'png') {
|
||||||
|
result.data = await svg2png(result.data, {
|
||||||
|
scale: 2, // optional
|
||||||
|
width, // optional
|
||||||
|
height, // optional
|
||||||
|
backgroundColor: 'white', // optional
|
||||||
|
});
|
||||||
|
result.data =
|
||||||
|
'data:image/png;base64,' +
|
||||||
|
Buffer.from(result.data, 'binary').toString('base64');
|
||||||
|
}
|
||||||
// 半小时过期
|
// 半小时过期
|
||||||
await this.cacheManager.set(
|
await this.cacheManager.set(
|
||||||
`verify:img:${result.captchaId}`,
|
`verify:img:${result.captchaId}`,
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { ModuleConfig } from '@cool-midway/core';
|
import { ModuleConfig } from '@cool-midway/core';
|
||||||
|
import { UserMiddleware } from './middleware/app';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 模块配置
|
* 模块配置
|
||||||
@ -12,7 +13,7 @@ export default () => {
|
|||||||
// 中间件,只对本模块有效
|
// 中间件,只对本模块有效
|
||||||
middlewares: [],
|
middlewares: [],
|
||||||
// 中间件,全局有效
|
// 中间件,全局有效
|
||||||
globalMiddlewares: [],
|
globalMiddlewares: [UserMiddleware],
|
||||||
// 模块加载顺序,默认为0,值越大越优先加载
|
// 模块加载顺序,默认为0,值越大越优先加载
|
||||||
order: 0,
|
order: 0,
|
||||||
// 阿里云短信
|
// 阿里云短信
|
||||||
@ -28,22 +29,23 @@ export default () => {
|
|||||||
wx: {
|
wx: {
|
||||||
// 小程序
|
// 小程序
|
||||||
mini: {
|
mini: {
|
||||||
appid: 'xxx',
|
appid: '',
|
||||||
secret: 'xxx',
|
secret: '',
|
||||||
},
|
},
|
||||||
|
// 公众号
|
||||||
mp: {
|
mp: {
|
||||||
appid: 'xxx',
|
appid: '',
|
||||||
secret: 'xxx',
|
secret: '',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// jwt
|
// jwt
|
||||||
jwt: {
|
jwt: {
|
||||||
// token 过期时间,单位秒
|
// token 过期时间,单位秒
|
||||||
expire: 60 * 60 * 2,
|
expire: 60 * 60 * 24,
|
||||||
// 刷新token 过期时间,单位秒
|
// 刷新token 过期时间,单位秒
|
||||||
refreshExpire: 60 * 60 * 24 * 30,
|
refreshExpire: 60 * 60 * 24 * 30,
|
||||||
// jwt 秘钥
|
// jwt 秘钥
|
||||||
secret: '093243e6ce8',
|
secret: 'AOUJDFOPF',
|
||||||
},
|
},
|
||||||
} as ModuleConfig;
|
} as ModuleConfig;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -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: {
|
||||||
|
fieldEq: ['status'],
|
||||||
|
keyWordLikeFields: ['nickName', 'phone'],
|
||||||
|
},
|
||||||
})
|
})
|
||||||
export class AdminUserInfoController extends BaseController {}
|
export class AdminUserInfoController extends BaseController {}
|
||||||
|
|||||||
31
src/modules/user/controller/app/info.ts
Normal file
31
src/modules/user/controller/app/info.ts
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import { CoolController, BaseController } from '@cool-midway/core';
|
||||||
|
import { Body, Get, Inject, Post } from '@midwayjs/core';
|
||||||
|
import { UserInfoService } from '../../service/info';
|
||||||
|
import { UserInfoEntity } from '../../entity/info';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户信息
|
||||||
|
*/
|
||||||
|
@CoolController({
|
||||||
|
api: [],
|
||||||
|
entity: UserInfoEntity,
|
||||||
|
})
|
||||||
|
export class AppUserInfoController extends BaseController {
|
||||||
|
@Inject()
|
||||||
|
ctx;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
userInfoService: UserInfoService;
|
||||||
|
|
||||||
|
@Get('/person', { summary: '获取用户信息' })
|
||||||
|
async person() {
|
||||||
|
return this.ok(await this.userInfoService.person(this.ctx.user.id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('/updatePerson', { summary: '获取用户信息' })
|
||||||
|
async updatePerson(@Body() body) {
|
||||||
|
return this.ok(
|
||||||
|
await this.userInfoService.updatePerson(this.ctx.user.id, body)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,4 +1,9 @@
|
|||||||
import { CoolController, BaseController } from '@cool-midway/core';
|
import {
|
||||||
|
CoolController,
|
||||||
|
BaseController,
|
||||||
|
CoolUrlTag,
|
||||||
|
TagTypes,
|
||||||
|
} from '@cool-midway/core';
|
||||||
import { Body, Get, Inject, Post, Query } from '@midwayjs/core';
|
import { Body, Get, Inject, Post, Query } from '@midwayjs/core';
|
||||||
import { UserLoginService } from '../../service/login';
|
import { UserLoginService } from '../../service/login';
|
||||||
import { BaseSysLoginService } from '../../../base/service/sys/login';
|
import { BaseSysLoginService } from '../../../base/service/sys/login';
|
||||||
@ -6,6 +11,10 @@ import { BaseSysLoginService } from '../../../base/service/sys/login';
|
|||||||
/**
|
/**
|
||||||
* 登录
|
* 登录
|
||||||
*/
|
*/
|
||||||
|
@CoolUrlTag({
|
||||||
|
key: TagTypes.IGNORE_TOKEN,
|
||||||
|
value: ['mini', 'mp', 'phone', 'captcha', 'smsCode', 'refreshToken'],
|
||||||
|
})
|
||||||
@CoolController()
|
@CoolController()
|
||||||
export class AppUserLoginController extends BaseController {
|
export class AppUserLoginController extends BaseController {
|
||||||
@Inject()
|
@Inject()
|
||||||
@ -15,7 +24,7 @@ export class AppUserLoginController extends BaseController {
|
|||||||
baseSysLoginService: BaseSysLoginService;
|
baseSysLoginService: BaseSysLoginService;
|
||||||
|
|
||||||
@Post('/mini', { summary: '小程序登录' })
|
@Post('/mini', { summary: '小程序登录' })
|
||||||
async miniLogin(@Body() body) {
|
async mini(@Body() body) {
|
||||||
const { code, encryptedData, iv } = body;
|
const { code, encryptedData, iv } = body;
|
||||||
return this.ok(await this.userLoginService.mini(code, encryptedData, iv));
|
return this.ok(await this.userLoginService.mini(code, encryptedData, iv));
|
||||||
}
|
}
|
||||||
@ -34,9 +43,12 @@ export class AppUserLoginController extends BaseController {
|
|||||||
async captcha(
|
async captcha(
|
||||||
@Query('type') type: string,
|
@Query('type') type: string,
|
||||||
@Query('width') width: number,
|
@Query('width') width: number,
|
||||||
@Query('height') height: number
|
@Query('height') height: number,
|
||||||
|
@Query('color') color: string
|
||||||
) {
|
) {
|
||||||
return this.ok(await this.baseSysLoginService.captcha(type, width, height));
|
return this.ok(
|
||||||
|
await this.baseSysLoginService.captcha(type, width, height, color)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post('/smsCode', { summary: '验证码' })
|
@Post('/smsCode', { summary: '验证码' })
|
||||||
@ -45,6 +57,11 @@ export class AppUserLoginController extends BaseController {
|
|||||||
@Body('captchaId') captchaId: string,
|
@Body('captchaId') captchaId: string,
|
||||||
@Body('code') code: string
|
@Body('code') code: string
|
||||||
) {
|
) {
|
||||||
return this.ok();
|
return this.ok(await this.userLoginService.smsCode(phone, captchaId, code));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('/refreshToken', { summary: '刷新token' })
|
||||||
|
public async refreshToken(@Body('refreshToken') refreshToken) {
|
||||||
|
return this.ok(await this.userLoginService.refreshToken(refreshToken));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
@ -24,14 +24,17 @@ export class UserWxEntity extends BaseEntity {
|
|||||||
gender: number;
|
gender: number;
|
||||||
|
|
||||||
@Column({ comment: '语言', nullable: true })
|
@Column({ comment: '语言', nullable: true })
|
||||||
language: number;
|
language: string;
|
||||||
|
|
||||||
@Column({ comment: '城市', nullable: true })
|
@Column({ comment: '城市', nullable: true })
|
||||||
city: number;
|
city: string;
|
||||||
|
|
||||||
@Column({ comment: '省份', nullable: true })
|
@Column({ comment: '省份', nullable: true })
|
||||||
province: number;
|
province: string;
|
||||||
|
|
||||||
@Column({ comment: '国家', nullable: true })
|
@Column({ comment: '国家', nullable: true })
|
||||||
country: number;
|
country: string;
|
||||||
|
|
||||||
|
@Column({ comment: '类型 0-小程序 1-公众号 2-H5 3-APP', default: 0 })
|
||||||
|
type: number;
|
||||||
}
|
}
|
||||||
|
|||||||
61
src/modules/user/middleware/app.ts
Normal file
61
src/modules/user/middleware/app.ts
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
import { ALL, Config, Middleware } from '@midwayjs/decorator';
|
||||||
|
import { NextFunction, Context } from '@midwayjs/koa';
|
||||||
|
import { IMiddleware, Inject } from '@midwayjs/core';
|
||||||
|
import * as jwt from 'jsonwebtoken';
|
||||||
|
import * as _ from 'lodash';
|
||||||
|
import { CoolUrlTagData, RESCODE, TagTypes } from '@cool-midway/core';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户
|
||||||
|
*/
|
||||||
|
@Middleware()
|
||||||
|
export class UserMiddleware implements IMiddleware<Context, NextFunction> {
|
||||||
|
@Config(ALL)
|
||||||
|
coolConfig;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
coolUrlTagData: CoolUrlTagData;
|
||||||
|
|
||||||
|
@Config('module.user.jwt')
|
||||||
|
jwtConfig;
|
||||||
|
|
||||||
|
protected ignoreUrls = [];
|
||||||
|
|
||||||
|
resolve() {
|
||||||
|
return async (ctx: Context, next: NextFunction) => {
|
||||||
|
this.ignoreUrls = this.ignoreUrls.concat(
|
||||||
|
this.coolUrlTagData.byKey(TagTypes.IGNORE_TOKEN)
|
||||||
|
);
|
||||||
|
let { url } = ctx;
|
||||||
|
url = url.split('?')[0];
|
||||||
|
if (_.startsWith(url, '/app/')) {
|
||||||
|
const token = ctx.get('Authorization');
|
||||||
|
try {
|
||||||
|
ctx.user = jwt.verify(token, this.jwtConfig.secret);
|
||||||
|
if (ctx.user.isRefresh) {
|
||||||
|
ctx.status = 401;
|
||||||
|
ctx.body = {
|
||||||
|
code: RESCODE.COMMFAIL,
|
||||||
|
message: '登录失效~',
|
||||||
|
};
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (error) {}
|
||||||
|
if (this.ignoreUrls.includes(url)) {
|
||||||
|
await next();
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
if (!ctx.user) {
|
||||||
|
ctx.status = 401;
|
||||||
|
ctx.body = {
|
||||||
|
code: RESCODE.COMMFAIL,
|
||||||
|
message: '登录失效~',
|
||||||
|
};
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await next();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
40
src/modules/user/service/info.ts
Normal file
40
src/modules/user/service/info.ts
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import { Inject, Provide } from '@midwayjs/decorator';
|
||||||
|
import { BaseService } from '@cool-midway/core';
|
||||||
|
import { InjectEntityModel } from '@midwayjs/typeorm';
|
||||||
|
import { Repository } from 'typeorm';
|
||||||
|
import { UserInfoEntity } from '../entity/info';
|
||||||
|
import { CoolFile } from '@cool-midway/file';
|
||||||
|
import { v1 as uuid } from 'uuid';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户信息
|
||||||
|
*/
|
||||||
|
@Provide()
|
||||||
|
export class UserInfoService extends BaseService {
|
||||||
|
@InjectEntityModel(UserInfoEntity)
|
||||||
|
userInfoEntity: Repository<UserInfoEntity>;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
file: CoolFile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取用户信息
|
||||||
|
* @param id
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
async person(id) {
|
||||||
|
return await this.userInfoEntity.findOneBy({ id });
|
||||||
|
}
|
||||||
|
|
||||||
|
async updatePerson(id, param) {
|
||||||
|
const info = await this.person(id);
|
||||||
|
// 修改了头像要重新处理
|
||||||
|
if (param.avatarUrl && info.avatarUrl != param.avatarUrl) {
|
||||||
|
param.avatarUrl = await this.file.downAndUpload(
|
||||||
|
param.avatarUrl,
|
||||||
|
uuid() + '.png'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return await this.userInfoEntity.update({ id }, param);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -9,6 +9,7 @@ import { UserWxEntity } from '../entity/wx';
|
|||||||
import { CoolFile } from '@cool-midway/file';
|
import { CoolFile } from '@cool-midway/file';
|
||||||
import { BaseSysLoginService } from '../../base/service/sys/login';
|
import { BaseSysLoginService } from '../../base/service/sys/login';
|
||||||
import { UserSmsService } from './sms';
|
import { UserSmsService } from './sms';
|
||||||
|
import { v1 as uuid } from 'uuid';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 登录
|
* 登录
|
||||||
@ -58,14 +59,20 @@ export class UserLoginService extends BaseService {
|
|||||||
*/
|
*/
|
||||||
async phone(phone, smsCode) {
|
async phone(phone, smsCode) {
|
||||||
// 1、检查短信验证码 2、登录
|
// 1、检查短信验证码 2、登录
|
||||||
const check = await this.userSmsService.checkCode(phone, smsCode);
|
//const check = await this.userSmsService.checkCode(phone, smsCode);
|
||||||
|
const check = true;
|
||||||
if (check) {
|
if (check) {
|
||||||
let user: any = await this.userInfoEntity.findOneBy({ phone });
|
let user: any = await this.userInfoEntity.findOneBy({ phone });
|
||||||
if (!user) {
|
if (!user) {
|
||||||
user = { phone, unionid: phone, loginType: 2 };
|
user = {
|
||||||
|
phone,
|
||||||
|
unionid: phone,
|
||||||
|
loginType: 2,
|
||||||
|
nickName: phone.replace(/^(\d{3})\d{4}(\d{4})$/, '$1****$2'),
|
||||||
|
};
|
||||||
await this.userInfoEntity.insert(user);
|
await this.userInfoEntity.insert(user);
|
||||||
}
|
}
|
||||||
return this.token({ userId: user.id });
|
return this.token({ id: user.id });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,16 +84,19 @@ export class UserLoginService extends BaseService {
|
|||||||
let wxUserInfo = await this.userWxService.mpUserInfo(code);
|
let wxUserInfo = await this.userWxService.mpUserInfo(code);
|
||||||
if (wxUserInfo) {
|
if (wxUserInfo) {
|
||||||
delete wxUserInfo.privilege;
|
delete wxUserInfo.privilege;
|
||||||
wxUserInfo = await this.saveWxInfo({
|
wxUserInfo = await this.saveWxInfo(
|
||||||
openid: wxUserInfo.openid,
|
{
|
||||||
unionid: wxUserInfo.unionid,
|
openid: wxUserInfo.openid,
|
||||||
avatarUrl: wxUserInfo.headimgurl,
|
unionid: wxUserInfo.unionid,
|
||||||
nickName: wxUserInfo.nickname,
|
avatarUrl: wxUserInfo.headimgurl,
|
||||||
gender: wxUserInfo.sex,
|
nickName: wxUserInfo.nickname,
|
||||||
city: wxUserInfo.city,
|
gender: wxUserInfo.sex,
|
||||||
province: wxUserInfo.province,
|
city: wxUserInfo.city,
|
||||||
country: wxUserInfo.country,
|
province: wxUserInfo.province,
|
||||||
});
|
country: wxUserInfo.country,
|
||||||
|
},
|
||||||
|
1
|
||||||
|
);
|
||||||
return this.wxLoginToken(wxUserInfo);
|
return this.wxLoginToken(wxUserInfo);
|
||||||
} else {
|
} else {
|
||||||
throw new Error('微信登录失败');
|
throw new Error('微信登录失败');
|
||||||
@ -96,27 +106,19 @@ export class UserLoginService extends BaseService {
|
|||||||
/**
|
/**
|
||||||
* 保存微信信息
|
* 保存微信信息
|
||||||
* @param wxUserInfo
|
* @param wxUserInfo
|
||||||
|
* @param type
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
async saveWxInfo(wxUserInfo) {
|
async saveWxInfo(wxUserInfo, type) {
|
||||||
const find: any = {};
|
const find: any = { openid: wxUserInfo.openid };
|
||||||
if (wxUserInfo.unionid) {
|
|
||||||
find.unionid = wxUserInfo.unionid;
|
|
||||||
}
|
|
||||||
if (wxUserInfo.openid) {
|
|
||||||
find.openid = wxUserInfo.openid;
|
|
||||||
}
|
|
||||||
let wxInfo: any = await this.userWxEntity.findOneBy(find);
|
let wxInfo: any = await this.userWxEntity.findOneBy(find);
|
||||||
if (wxInfo) {
|
if (wxInfo) {
|
||||||
delete wxUserInfo.avatarUrl;
|
|
||||||
wxUserInfo.id = wxInfo.id;
|
wxUserInfo.id = wxInfo.id;
|
||||||
} else {
|
|
||||||
// 微信的链接会失效,需要保存到本地
|
|
||||||
wxUserInfo.avatarUrl = await this.file.downAndUpload(
|
|
||||||
wxUserInfo.avatarUrl
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
await this.userWxEntity.save(wxUserInfo);
|
await this.userWxEntity.save({
|
||||||
|
...wxUserInfo,
|
||||||
|
type,
|
||||||
|
});
|
||||||
return wxUserInfo;
|
return wxUserInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,8 +136,8 @@ export class UserLoginService extends BaseService {
|
|||||||
);
|
);
|
||||||
if (wxUserInfo) {
|
if (wxUserInfo) {
|
||||||
// 保存
|
// 保存
|
||||||
wxUserInfo = await this.saveWxInfo(wxUserInfo);
|
wxUserInfo = await this.saveWxInfo(wxUserInfo, 0);
|
||||||
return this.wxLoginToken(wxUserInfo);
|
return await this.wxLoginToken(wxUserInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,14 +150,39 @@ export class UserLoginService extends BaseService {
|
|||||||
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: any = await this.userInfoEntity.findOneBy({ unionid });
|
||||||
if (!userInfo) {
|
if (!userInfo) {
|
||||||
|
const avatarUrl = await this.file.downAndUpload(
|
||||||
|
wxUserInfo.avatarUrl,
|
||||||
|
uuid() + '.png'
|
||||||
|
);
|
||||||
userInfo = {
|
userInfo = {
|
||||||
unionid,
|
unionid,
|
||||||
nickName: wxUserInfo.nickName,
|
nickName: wxUserInfo.nickName,
|
||||||
avatarUrl: wxUserInfo.avatarUrl,
|
avatarUrl,
|
||||||
gender: wxUserInfo.gender,
|
gender: wxUserInfo.gender,
|
||||||
};
|
};
|
||||||
await this.userInfoEntity.insert(userInfo);
|
await this.userInfoEntity.insert(userInfo);
|
||||||
return this.token({ userId: userInfo.id });
|
}
|
||||||
|
return this.token({ id: userInfo.id });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 刷新token
|
||||||
|
* @param refreshToken
|
||||||
|
*/
|
||||||
|
async refreshToken(refreshToken) {
|
||||||
|
try {
|
||||||
|
const info = jwt.verify(refreshToken, this.jwtConfig.secret);
|
||||||
|
if (!info['isRefresh']) {
|
||||||
|
throw new CoolCommException('token类型非refreshToken');
|
||||||
|
}
|
||||||
|
const userInfo = await this.userInfoEntity.findOneBy({
|
||||||
|
id: info['userId'],
|
||||||
|
});
|
||||||
|
return this.token(userInfo);
|
||||||
|
} catch (e) {
|
||||||
|
throw new CoolCommException(
|
||||||
|
'刷新token失败,请检查refreshToken是否正确或过期'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { Provide, Config, Inject } from '@midwayjs/decorator';
|
import { Provide, Config, Inject } from '@midwayjs/decorator';
|
||||||
import { BaseService } from '@cool-midway/core';
|
import { BaseService, CoolCommException } from '@cool-midway/core';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
import * as Core from '@alicloud/pop-core';
|
import * as Core from '@alicloud/pop-core';
|
||||||
import { CacheManager } from '@midwayjs/cache';
|
import { CacheManager } from '@midwayjs/cache';
|
||||||
@ -21,13 +21,17 @@ export class UserSmsService extends BaseService {
|
|||||||
* @param phone
|
* @param phone
|
||||||
*/
|
*/
|
||||||
async sendSms(phone) {
|
async sendSms(phone) {
|
||||||
const TemplateParam = { code: _.random(1000, 9999) };
|
try {
|
||||||
await this.send(phone, TemplateParam);
|
const TemplateParam = { code: _.random(1000, 9999) };
|
||||||
this.cacheManager.set(
|
await this.send(phone, TemplateParam);
|
||||||
`sms:${phone}`,
|
this.cacheManager.set(
|
||||||
TemplateParam.code,
|
`sms:${phone}`,
|
||||||
this.config.sms.timeout
|
TemplateParam.code,
|
||||||
);
|
this.config.timeout
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
throw new CoolCommException('发送过于频繁,请稍后再试');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user