0235699曾露 2 days ago
parent
commit
aad84f85c6
6 changed files with 303 additions and 134 deletions
  1. 3 2
      app.json
  2. 97 5
      common-page/pages/web-view/index.js
  3. 55 108
      components/app-auth/index.js
  4. 1 8
      components/app-auth/index.wxml
  5. 0 0
      components/app-auth/index.wxss
  6. 147 11
      index.js

+ 3 - 2
app.json

@@ -1,6 +1,7 @@
 {
   "pages": [
-    "index"
+    "index",
+    "components/app-auth/index"
   ],
   "subpackages": [
     {
@@ -62,4 +63,4 @@
       }
     }
   }
-}
+}

+ 97 - 5
common-page/pages/web-view/index.js

@@ -31,12 +31,86 @@ Page({
         
         console.log('✅ 用户已登录且有手机号,继续加载 web-view');
         
+        const postAuthModal = wx.getStorageSync('post_auth_modal');
+        if (postAuthModal && (postAuthModal.title || postAuthModal.content)) {
+            wx.removeStorageSync('post_auth_modal');
+            await new Promise((resolve) => {
+                wx.showModal({
+                    title: postAuthModal.title || '温馨提示',
+                    content: postAuthModal.content || '',
+                    showCancel: false,
+                    success: () => resolve(),
+                    fail: () => resolve(),
+                    complete: () => resolve(),
+                });
+            });
+        }
+
+        const upsertQueryParam = (url, key, value) => {
+            if (!url || !key) return url;
+            const safeValue = value === undefined || value === null ? '' : String(value);
+            const [base, hash] = url.split('#');
+            const [pathPart, queryString] = base.split('?');
+            const pairs = (queryString || '')
+                .split('&')
+                .filter(Boolean)
+                .map((p) => {
+                    const idx = p.indexOf('=');
+                    if (idx === -1) return [p, ''];
+                    return [p.slice(0, idx), p.slice(idx + 1)];
+                });
+            let found = false;
+            const nextPairs = pairs.map(([k, v]) => {
+                if (k === key) {
+                    found = true;
+                    return [k, encodeURIComponent(safeValue)];
+                }
+                return [k, v];
+            });
+            if (!found) nextPairs.push([key, encodeURIComponent(safeValue)]);
+            const nextQuery = nextPairs.length ? nextPairs.map(([k, v]) => `${k}=${v}`).join('&') : '';
+            const nextBase = nextQuery ? `${pathPart}?${nextQuery}` : pathPart;
+            return hash !== undefined ? `${nextBase}#${hash}` : nextBase;
+        };
+
+        const removeQueryParam = (url, key) => {
+            if (!url || !key) return url;
+            const [base, hash] = url.split('#');
+            const [pathPart, queryString] = base.split('?');
+            if (!queryString) return url;
+            const nextPairs = queryString
+                .split('&')
+                .filter(Boolean)
+                .map((p) => {
+                    const idx = p.indexOf('=');
+                    if (idx === -1) return [p, ''];
+                    return [p.slice(0, idx), p.slice(idx + 1)];
+                })
+                .filter(([k]) => k !== key);
+            const nextQuery = nextPairs.length ? nextPairs.map(([k, v]) => `${k}=${v}`).join('&') : '';
+            const nextBase = nextQuery ? `${pathPart}?${nextQuery}` : pathPart;
+            return hash !== undefined ? `${nextBase}#${hash}` : nextBase;
+        };
+
         // 2. 解码 URL
         let path = decodeURIComponent(options.path || '');
 
         console.log('原始 options.path:', options.path);
         console.log('解码后的 path:', path);
 
+        const currentUser = Parse.User.current();
+        const sessionToken = currentUser?.getSessionToken ? currentUser.getSessionToken() : null;
+        if (sessionToken) {
+            path = upsertQueryParam(path, 'token', sessionToken);
+            path = removeQueryParam(path, 'guestMode');
+        } else {
+            const hasToken = path.includes('token=');
+            const hasGuestMode = path.includes('guestMode=');
+            if (!hasToken && !hasGuestMode) {
+                path = upsertQueryParam(path, 'guestMode', 'true');
+            }
+        }
+
         // 拼接额外参数(避免重复添加已存在的参数)
         let hasQuery = path.indexOf('?') !== -1;
         let parsm = hasQuery ? '&' : '?';
@@ -139,14 +213,28 @@ Page({
             
             // 构建返回 URL(登录成功后返回当前页面)
             const currentPath = options.path || '';
-            const returnUrl = encodeURIComponent(currentPath);
+            const returnUrl = currentPath;
+            const storeId = options.storeId ? String(options.storeId) : '';
+            const storeName = options.storeName ? String(options.storeName) : '';
             
             console.log('🔗 returnUrl:', returnUrl);
             console.log('===========================================');
             
+            wx.setStorageSync('post_auth_modal', {
+                title: '授权成功',
+                content: '已完成授权,正在为你打开分享内容。'
+            });
+            
             // 跳转到授权页面,并传递 returnUrl
+            let authPageUrl = `/components/app-auth/index?returnUrl=${returnUrl}`;
+            if (storeId) {
+                authPageUrl += `&storeId=${storeId}`;
+            }
+            if (storeName) {
+                authPageUrl += `&storeName=${storeName}`;
+            }
             wx.redirectTo({
-                url: `/components/app-auth/index?returnUrl=${returnUrl}`,
+                url: authPageUrl,
                 success: () => {
                     console.log('✅ redirectTo 到授权页面成功');
                 },
@@ -155,7 +243,7 @@ Page({
                     
                     // 降级:使用 navigateTo
                     wx.navigateTo({
-                        url: `/components/app-auth/index?returnUrl=${returnUrl}`,
+                        url: authPageUrl,
                         success: () => {
                             console.log('✅ navigateTo 到授权页面成功');
                         },
@@ -164,7 +252,7 @@ Page({
                             
                             // 最后降级:使用 reLaunch
                             wx.reLaunch({
-                                url: `/components/app-auth/index?returnUrl=${returnUrl}`,
+                                url: authPageUrl,
                                 success: () => {
                                     console.log('✅ reLaunch 到授权页面成功');
                                 },
@@ -184,7 +272,11 @@ Page({
             console.log('===========================================');
             
             // 出错时也跳转到授权页面
-            const returnUrl = options.path ? encodeURIComponent(options.path) : '';
+            const returnUrl = options.path || '';
+            wx.setStorageSync('post_auth_modal', {
+                title: '授权成功',
+                content: '已完成授权,正在为你打开分享内容。'
+            });
             wx.redirectTo({
                 url: `/components/app-auth/index?returnUrl=${returnUrl}`,
                 fail: () => {

+ 55 - 108
components/app-auth/index.js

@@ -277,6 +277,11 @@ Page({
           } catch (e) {
             console.warn('🚦 [traffic] 暂缓扣减复判触发失败:', e?.message || e);
           }
+          try {
+            if (typeof getApp().checkAndRecordPendingScan === 'function') {
+              await getApp().checkAndRecordPendingScan();
+            }
+          } catch (e) {}
           if (!user.get('avatar') || user.get('nickname') == '微信用户' || !user.get('nickname')) {
             this.setData({
               phoneModal: false,
@@ -346,6 +351,11 @@ Page({
     } catch (e) {
       console.warn('🚦 [traffic] 暂缓扣减复判触发失败:', e?.message || e);
     }
+    try {
+      if (typeof getApp().checkAndRecordPendingScan === 'function') {
+        await getApp().checkAndRecordPendingScan();
+      }
+    } catch (e) {}
     if (!currentUser.get('avatar') || currentUser.get('nickname') == '微信用户' || !currentUser.get('nickname')) {
       this.setData({
         phoneModal: false,
@@ -616,9 +626,19 @@ Page({
       // 如果是 web-view 页面,跳转回去
       const decodedUrl = decodeURIComponent(returnUrl);
       console.log('🔙 准备跳转回 H5 页面:', decodedUrl);
-      
+
+      let nextUrl = `/common-page/pages/web-view/index?path=${encodeURIComponent(decodedUrl)}`;
+      const storeId = currentPage?.options?.storeId;
+      const storeName = currentPage?.options?.storeName;
+      if (storeId) {
+        nextUrl += `&storeId=${storeId}`;
+      }
+      if (storeName) {
+        nextUrl += `&storeName=${storeName}`;
+      }
+
       wx.navigateTo({
-        url: `/common-page/pages/web-view/index?path=${encodeURIComponent(decodedUrl)}`,
+        url: nextUrl,
         success: () => {
           console.log('✅ 跳转回 H5 页面成功');
           console.log('===========================================');
@@ -771,9 +791,8 @@ Page({
     } else {
       console.error('❌ 未获取到头像URL');
       
-      // 在开发环境下,如果获取失败,提示用户可以跳过
       wx.showToast({
-        title: '开发工具不支持,请真机测试或跳过',
+        title: '开发工具不支持,请真机测试',
         icon: 'none',
         duration: 2000
       });
@@ -799,6 +818,7 @@ Page({
       nickname,
       avatarUrl
     } = this.data
+    const finalNickname = (nickname || '').toString().trim();
     
     console.log('昵称:', nickname);
     console.log('头像URL:', avatarUrl);
@@ -815,6 +835,14 @@ Page({
     }
     
     console.log('当前用户ID:', user.id);
+
+    if (!finalNickname) {
+      wx.showToast({
+        title: '请输入微信昵称',
+        icon: 'none'
+      });
+      return;
+    }
     
     // 显示加载提示
     wx.showLoading({
@@ -823,42 +851,22 @@ Page({
     });
     
     try {
-      // 如果用户填写了信息,则更新
-      if (nickname || avatarUrl) {
-        console.log('ℹ️ 用户填写了信息,开始更新');
-        
-        // 如果有头像,上传头像
-        if (avatarUrl) {
-          console.log('📤 开始上传头像...');
-          let avatar = await this.updataAvatar(avatarUrl);
-          if (avatar) {
-            user.set("avatar", avatar);
-            console.log('✅ 头像上传成功:', avatar);
-          } else {
-            console.warn('⚠️ 头像上传失败');
-          }
-        }
-        
-        // 如果有昵称,更新昵称
-        if (nickname) {
-          user.set("nickname", nickname);
-          console.log('✅ 昵称已设置:', nickname);
-        }
-        
-        await user.save();
-        console.log('✅ 用户信息保存成功');
-      } else {
-        // 用户没有填写任何信息,使用默认值
-        console.log('ℹ️ 用户跳过头像昵称设置,使用默认值');
-        
-        // 如果用户没有昵称,设置默认昵称
-        if (!user.get('nickname') || user.get('nickname') === '微信用户') {
-          const defaultNickname = '用户' + user.id.substring(0, 6);
-          user.set('nickname', defaultNickname);
-          await user.save();
-          console.log('✅ 已设置默认昵称:', defaultNickname);
+      if (avatarUrl) {
+        console.log('📤 开始上传头像...');
+        let avatar = await this.updataAvatar(avatarUrl);
+        if (avatar) {
+          user.set("avatar", avatar);
+          console.log('✅ 头像上传成功:', avatar);
+        } else {
+          console.warn('⚠️ 头像上传失败');
         }
       }
+
+      user.set("nickname", finalNickname);
+      console.log('✅ 昵称已设置:', finalNickname);
+      
+      await user.save();
+      console.log('✅ 用户信息保存成功');
       
       wx.hideLoading();
       
@@ -868,6 +876,12 @@ Page({
       // 延迟一下再跳转,确保弹窗关闭动画完成
       setTimeout(() => {
         console.log('🚀 准备跳转...');
+        try {
+          const u = Parse.User.current();
+          if (u && u.id) {
+            wx.setStorageSync('userLogin', u.id);
+          }
+        } catch (e) {}
         this.backLoad();
       }, 300);
       
@@ -877,79 +891,12 @@ Page({
       
       wx.showModal({
         title: '提示',
-        content: '保存失败,是否继续?',
-        showCancel: true,
-        cancelText: '重试',
-        confirmText: '继续',
-        success: (result) => {
-          if (result.confirm) {
-            // 用户选择继续,直接跳转
-            this.onClose();
-            setTimeout(() => {
-              this.backLoad();
-            }, 300);
-          }
-          // 用户选择重试,留在当前页面
-        }
+        content: '保存失败,请重试',
+        showCancel: false,
+        confirmText: '重试'
       });
     }
   },
-  
-  //跳过头像昵称设置
-  async onSkip() {
-    console.log('=== onSkip 方法被调用 ===');
-    
-    let user = Parse.User.current();
-    
-    if (!user) {
-      console.error('❌ 用户未登录');
-      wx.showToast({
-        title: '用户未登录',
-        icon: 'none'
-      });
-      return;
-    }
-    
-    console.log('当前用户ID:', user.id);
-    
-    wx.showLoading({
-      title: '处理中...',
-      mask: true
-    });
-    
-    try {
-      // 设置默认昵称(如果没有)
-      if (!user.get('nickname') || user.get('nickname') === '微信用户') {
-        const defaultNickname = '用户' + user.id.substring(0, 6);
-        user.set('nickname', defaultNickname);
-        await user.save();
-        console.log('✅ 已设置默认昵称:', defaultNickname);
-      } else {
-        console.log('ℹ️ 用户已有昵称:', user.get('nickname'));
-      }
-      
-      wx.hideLoading();
-      
-      // 关闭弹窗
-      this.onClose();
-      
-      // 延迟一下再跳转
-      setTimeout(() => {
-        console.log('🚀 准备跳转...');
-        this.backLoad();
-      }, 300);
-      
-    } catch (err) {
-      wx.hideLoading();
-      console.error('❌ 设置默认昵称失败:', err);
-      
-      // 即使失败也允许继续
-      this.onClose();
-      setTimeout(() => {
-        this.backLoad();
-      }, 300);
-    }
-  },
   //关闭头像昵称填写弹窗
   onClose() {
     this.setData({

+ 1 - 8
components/app-auth/index.wxml

@@ -81,19 +81,13 @@
 
 <view class="model" wx:if="{{wxModel}}">
 	<view class="model_box">
-		<van-icon
-		 name="cross"
-		 class="post_flex"
-		 size="40rpx"
-		 bind:tap="onSkip"
-		/>
 		<view class="model_top">
 			<view class="company_cover">
 				<van-icon size="50rpx" name="{{logo}}" />
 				<view class="title">请填写您的微信头像、昵称</view>
 			</view>
 		</view>
-		<view class="desc">完善个人信息,获得更好的服务体验(可选)</view>
+		<view class="desc">完善个人信息,获得更好的服务体验</view>
 		<view class="cell">
 			<view class="label">微信头像</view>
 			<view class="cont">
@@ -117,7 +111,6 @@
 			</view>
 		</view>
 		<view class="btn" bind:tap="onComplete">确定</view>
-		<view class="btn-skip" bind:tap="onSkip">暂时跳过</view>
 	</view>
 </view>
 

File diff suppressed because it is too large
+ 0 - 0
components/app-auth/index.wxss


+ 147 - 11
index.js

@@ -90,12 +90,12 @@ Page({
     // 处理扫码链接(options.q 包含完整的URL或activityId)
     if (options.q) {
       let str = decodeURIComponent(options.q); // 扫描二维码获得的跳转链接
-
       // 兼容一些环境中把 & 编码成 &amp; 的情况,防止参数解析错误(如 scanCount=0&amp;storeId=...)
       if (str.indexOf('&amp;') !== -1) {
         console.log('🔧 检测到 URL 中包含 &amp;,自动还原为 &');
         str = str.replace(/&amp;/g, '&');
       }
+      try { wx.setStorageSync('scan_raw_url', str); } catch (e) {}
       
       // 检查是否是员工邀请链接(app.fmode.cn/dev/pobingfeng/manager/staff?invite=xxx)
       if (str.includes('app.fmode.cn/dev/pobingfeng/manager/staff')) {
@@ -194,6 +194,10 @@ Page({
     } catch (e) {
       console.warn('🚦 [traffic] 注册全局复判方法失败:', e?.message || e);
     }
+
+    try {
+      getApp().checkAndRecordPendingScan = this.checkAndRecordPendingScan.bind(this);
+    } catch (e) {}
   },
 
   /**
@@ -536,7 +540,8 @@ Page({
         partnerId: pendingScan.partnerId,
         userId: pendingScan.userId,
         productId: pendingScan.productId,
-        scanCount: pendingScan.scanCount
+        scanCount: pendingScan.scanCount,
+        scanTimestamp: pendingScan.timestamp
       });
       
       // 清除待记录的扫码信息
@@ -690,8 +695,76 @@ Page({
       console.log('📌 [扣减前置] trafficDeducted:', currentUser.get('trafficDeducted') === true ? 'true' : 'false');
       console.log('📌 [扣减前置] trafficDeductedStoreId:', currentUser.get('trafficDeductedStoreId') || '无');
       console.log('📌 [扣减前置] trafficDeductedAt:', currentUser.get('trafficDeductedAt') || '无');
+      try {
+        const scanSnapshot = {
+          storeId: wx.getStorageSync('scan_storeId') || null,
+          sourceType: wx.getStorageSync('scan_sourceType') || null,
+          sourceId: wx.getStorageSync('scan_sourceId') || null,
+          ownerId: wx.getStorageSync('scan_ownerId') || null,
+          employeeId: wx.getStorageSync('scan_employeeId') || null,
+          partnerId: wx.getStorageSync('scan_partnerId') || null,
+          userId: wx.getStorageSync('scan_userId') || null,
+          productId: wx.getStorageSync('scan_productId') || null,
+          caseId: wx.getStorageSync('scan_caseId') || null,
+          planId: wx.getStorageSync('scan_planId') || null,
+          shareUserId: wx.getStorageSync('scan_shareUserId') || null,
+          scanCount: wx.getStorageSync('scan_scanCount') || null,
+          rawUrl: wx.getStorageSync('scan_raw_url') || null
+        };
+        console.log('🔗 [扫码参数快照] scanInfo:', scanInfo);
+        console.log('🔗 [扫码参数快照] storage:', scanSnapshot);
+      } catch (e) {
+        console.warn('⚠️ 读取扫码参数快照失败:', e?.message || e);
+      }
+      
+      // 员工推荐判定与日志
+      try {
+        let staffJudge = { isStaff: false, reason: 'no_staff_params' };
+        if (employeeId) {
+          staffJudge = { isStaff: true, reason: 'employeeId_param', staffId: employeeId };
+        } else if (ownerId) {
+          staffJudge = { isStaff: true, reason: 'ownerId_param', staffId: ownerId };
+        } else if (userId) {
+          try {
+            const uq = new Parse.Query('_User');
+            const u = await uq.get(userId);
+            const roles = Array.isArray(u.get('roles')) ? u.get('roles').map(r => String(r).toLowerCase()) : [];
+            const isStaff = roles.includes('staff') || roles.includes('userstaff') || roles.includes('employee') || roles.includes('sales');
+            staffJudge = { isStaff, reason: isStaff ? 'user_role_staff' : 'user_role_non_staff', staffId: userId, roles };
+          } catch (e) {
+            staffJudge = { isStaff: false, reason: 'user_lookup_failed', error: e?.message || e };
+          }
+        }
+        console.log('👥 [员工推荐判定] 结果:', staffJudge);
+      } catch (e) {
+        console.warn('⚠️ [员工推荐判定] 失败:', e?.message || e);
+      }
+      
+      // 来源优先级判定与升级覆盖
+      const pickType = () => {
+        if (partnerId && employeeId) return 'channel_partner_employee';
+        if (partnerId) return 'channel_partner';
+        if (employeeId) return 'employee';
+        if (ownerId) return 'owner';
+        if (userId) return 'promoter';
+        return 'self_entry';
+      };
+      const prio = (t) => {
+        if (t === 'channel_partner_employee') return 4;
+        if (t === 'owner' || t === 'employee') return 3;
+        if (t === 'channel_partner') return 2;
+        if (t === 'promoter') return 1;
+        return 0;
+      };
+      const newType = pickType();
+      const oldType = existingSource && existingSource.type ? String(existingSource.type) : 'self_entry';
+      const shouldOverride = prio(newType) > prio(oldType);
+      console.log('🔀 [来源优先级] oldType:', oldType, 'newType:', newType, 'override:', shouldOverride ? 'YES' : 'NO');
 
-      if (!existingSource) {
+      if (!existingSource || shouldOverride) {
+        if (existingSource && shouldOverride) {
+          console.log('🔁 [来源升级] 触发覆盖: 从', oldType, '→', newType);
+        }
         let sourceInfo = {
           type: 'self_entry',
           label: '自主进入',
@@ -757,9 +830,19 @@ Page({
           console.log('🔍 [来源类型] 员工');
           
           try {
-            const employeeQuery = new Parse.Query('Employee');
-            const employee = await employeeQuery.get(employeeId);
-            const employeeName = employee.get('name') || '未知员工';
+            // 兼容管理员端员工表 UserStaff
+            let employeeName = '未知员工';
+            try {
+              const staffQuery = new Parse.Query('UserStaff');
+              const staff = await staffQuery.get(employeeId);
+              employeeName = staff.get('name') || staff.get('nickname') || staff.get('mobile') || '管理员端员工';
+            } catch (e1) {
+              try {
+                const employeeQuery = new Parse.Query('Employee');
+                const employee = await employeeQuery.get(employeeId);
+                employeeName = employee.get('name') || '未知员工';
+              } catch (e2) {}
+            }
             
             sourceInfo = {
               type: 'employee',
@@ -1301,7 +1384,8 @@ Page({
           partnerId,
           userId,
           productId,
-          scanCount
+          scanCount,
+          scanTimestamp: Date.now()
         });
       } else {
         // 用户未登录,保存扫码信息,等登录后再记录
@@ -1667,7 +1751,8 @@ Page({
         partnerId,
         userId,
         productId,
-        scanCount
+        scanCount,
+        scanTimestamp
       } = params;
       
       console.log('📋 [统计参数] 接收到的参数:');
@@ -1697,6 +1782,36 @@ Page({
         console.log('ℹ️ [跳过] 无来源信息,跳过统计记录');
         return;
       }
+
+      const hasMobile = !!currentUser.get('mobile');
+      const scanTs = typeof scanTimestamp === 'number' && scanTimestamp > 0 ? scanTimestamp : Date.now();
+
+      if (partnerId && !hasMobile) {
+        const pendingData = {
+          storeId,
+          sourceType,
+          sourceId,
+          ownerId,
+          employeeId,
+          partnerId,
+          userId,
+          productId,
+          scanCount,
+          timestamp: scanTs
+        };
+        try {
+          const existingPending = wx.getStorageSync('pending_scan_record');
+          if (!existingPending || existingPending.partnerId !== partnerId || existingPending.storeId !== storeId) {
+            wx.setStorageSync('pending_scan_record', pendingData);
+          }
+        } catch (e) {
+          try {
+            wx.setStorageSync('pending_scan_record', pendingData);
+          } catch (e2) {}
+        }
+        console.log('⏳ [异业扫码] 用户未绑定手机号,延后到注册登录后再统计');
+        return;
+      }
       
       console.log('✅ [开始记录] 用户已登录且有来源信息,开始记录');
       
@@ -1791,18 +1906,35 @@ Page({
           });
           scanQuery.equalTo('partnerId', partnerId);
           scanQuery.equalTo('storeId', storeId);
+          scanQuery.equalTo('partnerNewUserCounted', true);
           
           const existingScan = await scanQuery.first();
           
           if (existingScan) {
-            console.log('⚠️ [规则2] 该用户在该门店已扫过该异业的码,不重复计数');
-            console.log('   - 首次扫码时间:', existingScan.get('scanTime'));
+            console.log('⚠️ [规则2] 该用户在该门店已计入“异业新用户扫码”,不重复计数');
+            console.log('   - 计入时间:', existingScan.get('scanTime'));
             console.log('   - 记录ID:', existingScan.id);
             console.log('🤝 ===========================================');
             return;
           }
           
-          console.log('✅ [首次扫码] 该用户在该门店首次扫该异业码');
+          let partnerNewUserQualified = false;
+          try {
+            const createdAtMs = currentUser.createdAt instanceof Date ? currentUser.createdAt.getTime() : 0;
+            const diffMs = createdAtMs ? Math.abs(scanTs - createdAtMs) : Number.MAX_SAFE_INTEGER;
+            partnerNewUserQualified = diffMs <= 10 * 60 * 1000;
+          } catch (e) {
+            partnerNewUserQualified = false;
+          }
+
+          if (!partnerNewUserQualified) {
+            console.log('ℹ️ [规则2] 非“扫码注册登录的新用户”,不计入异业扫码次数');
+            console.log('🤝 ===========================================');
+            return;
+          }
+
+          record.set('partnerNewUserCounted', true);
+          console.log('✅ [首次计入] 该用户在该门店首次计入“异业新用户扫码”');
           
           // 规则3:如果用户还没有绑定异业,绑定当前异业
           if (!userBoundPartnerId) {
@@ -1853,6 +1985,10 @@ Page({
           } else {
             console.error('❌ [错误] 未找到异业合作伙伴记录');
           }
+
+          if (record && record.get && record.get('partnerNewUserCounted') === true) {
+            await record.save();
+          }
           
           console.log('🤝 ===========================================');
         } catch (e) {

Some files were not shown because too many files changed in this diff