Kaynağa Gözat

fix: 优化用户 openid 绑定逻辑

- 首次注册用户时绑定 openid
- 老用户登录时如无 openid 则自动绑定
- 优化邀请码处理逻辑

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
MyFramework User 3 ay önce
ebeveyn
işleme
70ab813a52

+ 8 - 1
my-uniapp-vue3/src/store/user.ts

@@ -32,11 +32,13 @@ export const useUserStore = defineStore('user', () => {
   // 登录
   async function login(phone: string, code: string) {
     const inviteCode = uni.getStorageSync('invite_code') || '';
+    // 读取微信 openid(从公众号进入时已存储在 localStorage)
+    const wxOpenid = (typeof localStorage !== 'undefined' && localStorage.getItem('wx_openid')) || '';
 
     const result = await post<{
       token: string;
       user: UserInfo;
-    }>('/auth/login', { phone, code, inviteCode });
+    }>('/auth/login', { phone, code, inviteCode, openid: wxOpenid });
 
     token.value = result.token;
     userInfo.value = result.user;
@@ -48,6 +50,11 @@ export const useUserStore = defineStore('user', () => {
       uni.removeStorageSync('invite_code');
     }
 
+    // 绑定成功后清除 localStorage 中的 openid(避免后续登录重复携带)
+    if (wxOpenid && typeof localStorage !== 'undefined') {
+      localStorage.removeItem('wx_openid');
+    }
+
     await fetchMemberStatus();
     return result;
   }

+ 2 - 2
server/src/modules/auth/auth.controller.ts

@@ -32,7 +32,7 @@ router.post('/send-code', async (ctx: Context) => {
 
 // 手机号登录
 router.post('/login', async (ctx: Context) => {
-  const { phone, code, inviteCode } = ctx.request.body as { phone: string; code?: string; inviteCode?: string };
+  const { phone, code, inviteCode, openid } = ctx.request.body as { phone: string; code?: string; inviteCode?: string; openid?: string };
 
   if (!phone || !/^1[3-9]\d{9}$/.test(phone)) {
     throw new BadRequestError('请输入正确的手机号');
@@ -43,7 +43,7 @@ router.post('/login', async (ctx: Context) => {
     // 跳过验证码检查,直接登录
   }
 
-  const result = await AuthService.loginWithPhone(phone, code, inviteCode);
+  const result = await AuthService.loginWithPhone(phone, code, inviteCode, openid);
 
   ctx.body = {
     code: 0,

+ 8 - 1
server/src/modules/auth/auth.service.ts

@@ -42,7 +42,7 @@ export function generateToken(userId: string, phone?: string): string {
 }
 
 // 手机号登录/注册
-export async function loginWithPhone(phone: string, code?: string, inviteCode?: string): Promise<{
+export async function loginWithPhone(phone: string, code?: string, inviteCode?: string, openid?: string): Promise<{
   token: string;
   user: {
     id: string;
@@ -72,6 +72,7 @@ export async function loginWithPhone(phone: string, code?: string, inviteCode?:
     user = await prisma.user.create({
       data: {
         phone,
+        openid: openid || null, // 首次注册时绑定 openid
         nickname: `用户${phone.slice(-4)}`,
         avatar: `https://api.dicebear.com/7.x/avataaars/svg?seed=${phone}`,
         memberLevel: 0,
@@ -90,6 +91,12 @@ export async function loginWithPhone(phone: string, code?: string, inviteCode?:
         await handleInvite(shareRecord.userId, user.id, inviteCode);
       }
     }
+  } else if (openid && !user.openid) {
+    // 老用户登录时,如果之前没有 openid,则绑定
+    user = await prisma.user.update({
+      where: { id: user.id },
+      data: { openid },
+    });
   }
 
   const token = generateToken(user.id.toString(), phone);