import { CustomPrismaService } from 'nestjs-prisma'; import { Inject, Injectable } from '@nestjs/common'; import { OAuthProvider } from '@prisma/client'; import { ConfigService } from '@/common/config'; import { JwtService } from '@/libs/jwt/jwt.service'; import { ExtendedPrismaClient } from '@/processors/database/prisma.extension'; import { ConfigType } from 'shared'; @Injectable() export class WechatService { private wechatConfig: ConfigType['wechat']; constructor( @Inject('PrismaService') private prisma: CustomPrismaService, private jwtService: JwtService, configService: ConfigService, ) { this.wechatConfig = configService.get('wechat'); } async wechatOauth(code: string) { const { access_token: accessToken, expires_in: expiresIn, refresh_token: refreshToken, openid, }: { access_token: string; expires_in: number; refresh_token: string; openid: string; scope: string; unionid?: string; } = await fetch( 'https://api.weixin.qq.com/sns/oauth2/access_token?' + new URLSearchParams([ ['appid', this.wechatConfig.oauth.appId], ['secret', this.wechatConfig.oauth.appSecret], ['code', code], ['grant_type', 'authorization_code'], ]), ).then((res) => res.json()); const expiredAt = new Date(Date.now() + expiresIn * 1000); return { openid, accessToken, refreshToken, expiredAt, }; } async refreshAccessToken(refreshToken: string) {} async getInfo(accessToken: string, openid: string) { return (await fetch( 'https://api.weixin.qq.com/sns/userinfo?' + new URLSearchParams([ ['access_token', accessToken], ['openai', openid], ]), ).then((res) => res.json())) as { openid: string; nickname: string; sex: 1 | 2; province: string; city: string; country: string; headimgurl: string; privilege: string[]; unionid?: string; }; } async loginByWeChat(token) { const user = ( await this.prisma.client.oAuth.findUnique({ where: { provider_providerId: { provider: OAuthProvider.Wechat, providerId: token.openid, }, }, include: { user: true, }, }) )?.user; if (!user) { return false; } return this.jwtService.sign({ id: user.id, role: user.role }); } async registerByWeChat(token, userInfo) { const user = await this.prisma.client.user.create({ data: { name: `wx_${token.openid}`, oauths: { create: { provider: OAuthProvider.Wechat, providerId: token.openid, accessToken: token.accessToken, refreshToken: token.refreshToken, expiredAt: token.expiredAt, data: userInfo, }, }, }, }); return this.jwtService.sign({ id: user.id, role: user.role }); } }