|
@@ -1,17 +1,18 @@
|
|
|
import { DataSource, Repository } from 'typeorm';
|
|
import { DataSource, Repository } from 'typeorm';
|
|
|
import { UserEntity } from '@/server/modules/users/user.entity';
|
|
import { UserEntity } from '@/server/modules/users/user.entity';
|
|
|
import { File } from '@/server/modules/files/file.entity';
|
|
import { File } from '@/server/modules/files/file.entity';
|
|
|
|
|
+import { FileService } from '@/server/modules/files/file.service';
|
|
|
import jwt from 'jsonwebtoken';
|
|
import jwt from 'jsonwebtoken';
|
|
|
import axios from 'axios';
|
|
import axios from 'axios';
|
|
|
import { v4 as uuidv4 } from 'uuid';
|
|
import { v4 as uuidv4 } from 'uuid';
|
|
|
|
|
|
|
|
export class MiniAuthService {
|
|
export class MiniAuthService {
|
|
|
private userRepository: Repository<UserEntity>;
|
|
private userRepository: Repository<UserEntity>;
|
|
|
- private fileRepository: Repository<File>;
|
|
|
|
|
|
|
+ private fileService: FileService;
|
|
|
|
|
|
|
|
constructor(private dataSource: DataSource) {
|
|
constructor(private dataSource: DataSource) {
|
|
|
this.userRepository = dataSource.getRepository(UserEntity);
|
|
this.userRepository = dataSource.getRepository(UserEntity);
|
|
|
- this.fileRepository = dataSource.getRepository(File);
|
|
|
|
|
|
|
+ this.fileService = new FileService(dataSource);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
async miniLogin(code: string): Promise<{ token: string; user: UserEntity; isNewUser: boolean }> {
|
|
async miniLogin(code: string): Promise<{ token: string; user: UserEntity; isNewUser: boolean }> {
|
|
@@ -50,7 +51,7 @@ export class MiniAuthService {
|
|
|
// 处理头像:如果用户没有头像且提供了小程序头像URL,则下载保存
|
|
// 处理头像:如果用户没有头像且提供了小程序头像URL,则下载保存
|
|
|
if (profile.avatarUrl && !user.avatarFileId) {
|
|
if (profile.avatarUrl && !user.avatarFileId) {
|
|
|
try {
|
|
try {
|
|
|
- const avatarFileId = await this.downloadAndSaveAvatar(profile.avatarUrl);
|
|
|
|
|
|
|
+ const avatarFileId = await this.downloadAndSaveAvatar(profile.avatarUrl, userId);
|
|
|
if (avatarFileId) {
|
|
if (avatarFileId) {
|
|
|
user.avatarFileId = avatarFileId;
|
|
user.avatarFileId = avatarFileId;
|
|
|
}
|
|
}
|
|
@@ -108,47 +109,25 @@ export class MiniAuthService {
|
|
|
return await this.userRepository.save(user);
|
|
return await this.userRepository.save(user);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private async downloadAndSaveAvatar(avatarUrl: string): Promise<number | null> {
|
|
|
|
|
|
|
+ private async downloadAndSaveAvatar(avatarUrl: string, userId: number): Promise<number | null> {
|
|
|
try {
|
|
try {
|
|
|
- // 从URL下载头像
|
|
|
|
|
- const response = await axios.get(avatarUrl, {
|
|
|
|
|
- responseType: 'arraybuffer',
|
|
|
|
|
- timeout: 10000
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ const result = await this.fileService.downloadAndSaveFromUrl(
|
|
|
|
|
+ avatarUrl,
|
|
|
|
|
+ {
|
|
|
|
|
+ uploadUserId: userId,
|
|
|
|
|
+ customPath: `avatars/`,
|
|
|
|
|
+ mimeType: 'image/jpeg'
|
|
|
|
|
+ },
|
|
|
|
|
+ { timeout: 10000 }
|
|
|
|
|
+ );
|
|
|
|
|
|
|
|
- const buffer = Buffer.from(response.data);
|
|
|
|
|
-
|
|
|
|
|
- // 生成文件名
|
|
|
|
|
- const fileName = `avatar_${uuidv4()}.jpg`;
|
|
|
|
|
- const filePath = `avatars/${fileName}`;
|
|
|
|
|
-
|
|
|
|
|
- // 上传到文件服务(这里模拟上传到MinIO)
|
|
|
|
|
- // 实际项目中需要集成MinIO或其他文件存储服务
|
|
|
|
|
- const fileRecord = this.fileRepository.create({
|
|
|
|
|
- originalName: fileName,
|
|
|
|
|
- fileName: fileName,
|
|
|
|
|
- filePath: filePath,
|
|
|
|
|
- fileSize: buffer.length,
|
|
|
|
|
- mimeType: 'image/jpeg',
|
|
|
|
|
- fileType: 'image',
|
|
|
|
|
- extension: 'jpg',
|
|
|
|
|
- md5: this.calculateMD5(buffer),
|
|
|
|
|
- url: `${process.env.MINIO_ENDPOINT || ''}/avatars/${fileName}`
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- const savedFile = await this.fileRepository.save(fileRecord);
|
|
|
|
|
- return savedFile.id;
|
|
|
|
|
|
|
+ return result.file.id;
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
|
console.error('下载保存头像失败:', error);
|
|
console.error('下载保存头像失败:', error);
|
|
|
return null;
|
|
return null;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private calculateMD5(buffer: Buffer): string {
|
|
|
|
|
- // 简化的MD5计算,实际项目中应使用crypto模块
|
|
|
|
|
- return require('crypto').createHash('md5').update(buffer).digest('hex');
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
private generateToken(user: UserEntity): string {
|
|
private generateToken(user: UserEntity): string {
|
|
|
const payload = {
|
|
const payload = {
|
|
|
id: user.id,
|
|
id: user.id,
|