فهرست منبع

✨ feat(auth): 实现用户头像自动下载保存功能

- 添加 file-module 依赖以支持文件处理功能
- 引入 FileService 并实例化
- 取消头像下载保存相关代码注释,实现小程序头像自动下载保存功能
- 完善头像下载失败错误处理逻辑,不影响主要登录流程
yourname 4 هفته پیش
والد
کامیت
171f94862e
3فایلهای تغییر یافته به همراه36 افزوده شده و 33 حذف شده
  1. 1 0
      packages/auth-module/package.json
  2. 32 33
      packages/auth-module/src/services/mini-auth.service.ts
  3. 3 0
      pnpm-lock.yaml

+ 1 - 0
packages/auth-module/package.json

@@ -46,6 +46,7 @@
     "@d8d/shared-types": "workspace:*",
     "@d8d/shared-utils": "workspace:*",
     "@d8d/user-module": "workspace:*",
+    "@d8d/file-module": "workspace:*",
     "@hono/zod-openapi": "1.0.2",
     "axios": "^1.12.2",
     "debug": "^4.4.3",

+ 32 - 33
packages/auth-module/src/services/mini-auth.service.ts

@@ -1,17 +1,17 @@
 import { DataSource, Repository } from 'typeorm';
 import { UserEntity } from '@d8d/user-module';
-// import { FileService } from '@d8d/file-module';
+import { FileService } from '@d8d/file-module';
 import { JWTUtil } from '@d8d/shared-utils';
 import axios from 'axios';
 import process from 'node:process'
 
 export class MiniAuthService {
   private userRepository: Repository<UserEntity>;
-  // private fileService: FileService;
+  private fileService: FileService;
 
   constructor(dataSource: DataSource) {
     this.userRepository = dataSource.getRepository(UserEntity);
-    // this.fileService = new FileService(dataSource);
+    this.fileService = new FileService(dataSource);
   }
 
   async miniLogin(code: string): Promise<{ token: string; user: UserEntity; isNewUser: boolean }> {
@@ -48,18 +48,17 @@ export class MiniAuthService {
     if (profile.nickname) user.nickname = profile.nickname;
 
     // 处理头像:如果用户没有头像且提供了小程序头像URL,则下载保存
-    // 暂时注释掉文件服务相关功能,因为 file-module 尚未创建
-    // if (profile.avatarUrl && !user.avatarFileId) {
-    //   try {
-    //     const avatarFileId = await this.downloadAndSaveAvatar(profile.avatarUrl, userId);
-    //     if (avatarFileId) {
-    //       user.avatarFileId = avatarFileId;
-    //     }
-    //   } catch (error) {
-    //     // 头像下载失败不影响主要功能
-    //     console.error('头像下载失败:', error);
-    //   }
-    // }
+    if (profile.avatarUrl && !user.avatarFileId) {
+      try {
+        const avatarFileId = await this.downloadAndSaveAvatar(profile.avatarUrl, userId);
+        if (avatarFileId) {
+          user.avatarFileId = avatarFileId;
+        }
+      } catch (error) {
+        // 头像下载失败不影响主要功能
+        console.error('头像下载失败:', error);
+      }
+    }
 
     return await this.userRepository.save(user);
   }
@@ -109,24 +108,24 @@ export class MiniAuthService {
     return await this.userRepository.save(user);
   }
 
-  // private async downloadAndSaveAvatar(avatarUrl: string, userId: number): Promise<number | null> {
-  //   try {
-  //     const result = await this.fileService.downloadAndSaveFromUrl(
-  //       avatarUrl,
-  //       {
-  //         uploadUserId: userId,
-  //         customPath: `avatars/`,
-  //         mimeType: 'image/jpeg'
-  //       },
-  //       { timeout: 10000 }
-  //     );
-
-  //     return result.file.id;
-  //   } catch (error) {
-  //     console.error('下载保存头像失败:', error);
-  //     return null;
-  //   }
-  // }
+  private async downloadAndSaveAvatar(avatarUrl: string, userId: number): Promise<number | null> {
+    try {
+      const result = await this.fileService.downloadAndSaveFromUrl(
+        avatarUrl,
+        {
+          uploadUserId: userId,
+          customPath: `avatars/`,
+          mimeType: 'image/jpeg'
+        },
+        { timeout: 10000 }
+      );
+
+      return result.file.id;
+    } catch (error) {
+      console.error('下载保存头像失败:', error);
+      return null;
+    }
+  }
 
   private generateToken(user: UserEntity): string {
     return JWTUtil.generateToken(user);

+ 3 - 0
pnpm-lock.yaml

@@ -231,6 +231,9 @@ importers:
 
   packages/auth-module:
     dependencies:
+      '@d8d/file-module':
+        specifier: workspace:*
+        version: link:../file-module
       '@d8d/shared-types':
         specifier: workspace:*
         version: link:../shared-types