|
|
@@ -2,6 +2,7 @@
|
|
|
// var app = getApp()
|
|
|
// const { wxLogin } = require('./utils/login')
|
|
|
const CONFIG = require("config.js");
|
|
|
+const login = require("./utils/login");
|
|
|
let config = {
|
|
|
appid: CONFIG.default.appid,
|
|
|
company: CONFIG.default.company,
|
|
|
@@ -96,6 +97,13 @@ Page({
|
|
|
str = str.replace(/&/g, '&');
|
|
|
}
|
|
|
try { wx.setStorageSync('scan_raw_url', str); } catch (e) {}
|
|
|
+
|
|
|
+ if (!str.includes('?') && str.includes('=') && (str.includes('storeId=') || str.includes('storeid='))) {
|
|
|
+ try {
|
|
|
+ const obj = this.setObject(str);
|
|
|
+ obj && Object.keys(obj).forEach((key) => options[key] = obj[key]);
|
|
|
+ } catch (e) {}
|
|
|
+ }
|
|
|
|
|
|
// 检查是否是员工邀请链接(app.fmode.cn/dev/pobingfeng/manager/staff?invite=xxx)
|
|
|
if (str.includes('app.fmode.cn/dev/pobingfeng/manager/staff')) {
|
|
|
@@ -136,16 +144,24 @@ Page({
|
|
|
// 兼容从编译参数或页面直达传入的 storeId
|
|
|
if (options && options.scene && !options.storeId) {
|
|
|
try {
|
|
|
- const sceneStr = decodeURIComponent(options.scene)
|
|
|
- if (sceneStr) {
|
|
|
- const pairs = sceneStr.split('&')
|
|
|
+ let sceneStr = decodeURIComponent(options.scene);
|
|
|
+ if (sceneStr && sceneStr.indexOf('&') !== -1) {
|
|
|
+ sceneStr = sceneStr.replace(/&/g, '&');
|
|
|
+ }
|
|
|
+
|
|
|
+ if (sceneStr && sceneStr.includes('=')) {
|
|
|
+ const pairs = sceneStr.split('&');
|
|
|
for (const p of pairs) {
|
|
|
- const [k, v] = p.split('=')
|
|
|
- if (k === 'storeId' && v) {
|
|
|
- options.storeId = v
|
|
|
- break
|
|
|
- }
|
|
|
+ if (!p) continue;
|
|
|
+ const idx = p.indexOf('=');
|
|
|
+ if (idx === -1) continue;
|
|
|
+ const k = p.slice(0, idx);
|
|
|
+ const rawV = p.slice(idx + 1);
|
|
|
+ const v = rawV ? decodeURIComponent(rawV) : rawV;
|
|
|
+ if (k) options[k] = v;
|
|
|
}
|
|
|
+ } else if (sceneStr && /^[A-Za-z0-9]{8,20}$/.test(sceneStr)) {
|
|
|
+ options.storeId = sceneStr;
|
|
|
}
|
|
|
} catch (e) {
|
|
|
console.warn('解析 scene 失败:', e)
|
|
|
@@ -241,14 +257,24 @@ Page({
|
|
|
}
|
|
|
|
|
|
let currentUser = Parse.User.current()
|
|
|
+ const userLogin = wx.getStorageSync('userLogin');
|
|
|
+ const hasMobile = currentUser?.get('mobile');
|
|
|
+ const isFullyLoggedIn = !!(currentUser && hasMobile && userLogin);
|
|
|
+ const isEntryFromScan =
|
|
|
+ !!(options && (options.q || options.scene)) ||
|
|
|
+ wx.getStorageSync('storeId_from_scan') === true ||
|
|
|
+ wx.getStorageSync('need_scan_redirect') === true ||
|
|
|
+ wx.getStorageSync('need_activity_redirect') === true;
|
|
|
console.log('===========================================');
|
|
|
console.log('======= index.js review 方法 =======');
|
|
|
console.log('当前用户:', currentUser ? currentUser.id : '无');
|
|
|
console.log('用户手机号:', currentUser?.get('mobile') || '无');
|
|
|
console.log('用户名:', currentUser?.get('username') || '无');
|
|
|
console.log('Session Token:', currentUser?.getSessionToken()?.substring(0, 20) || '无');
|
|
|
- console.log('userLogin 存储:', wx.getStorageSync('userLogin') || '无');
|
|
|
+ console.log('userLogin 存储:', userLogin || '无');
|
|
|
console.log('force 参数:', force);
|
|
|
+ console.log('是否完整登录:', isFullyLoggedIn);
|
|
|
+ console.log('是否扫码/海报入口:', isEntryFromScan);
|
|
|
console.log('===========================================');
|
|
|
|
|
|
// 查询 Company 的 isPublishing 字段
|
|
|
@@ -284,11 +310,10 @@ Page({
|
|
|
}
|
|
|
|
|
|
// 根据 isPublishing 决定是否强制登录
|
|
|
- if (!currentUser || force) {
|
|
|
+ if (!isFullyLoggedIn || force) {
|
|
|
console.log('🔄 开始调用 checkAuth...');
|
|
|
|
|
|
- // isPublishing == true 时不强制授权,否则强制授权
|
|
|
- const forceAuth = !isPublishing;
|
|
|
+ const forceAuth = isEntryFromScan ? true : !isPublishing;
|
|
|
console.log('🔐 是否强制登录:', forceAuth);
|
|
|
|
|
|
let r = await checkAuth(forceAuth);
|
|
|
@@ -309,6 +334,16 @@ Page({
|
|
|
console.log('❌ 强制登录模式,用户未登录,停止访问');
|
|
|
return;
|
|
|
}
|
|
|
+
|
|
|
+ if (forceAuth) {
|
|
|
+ const mobile = currentUser?.get('mobile');
|
|
|
+ const afterLoginUserLogin = wx.getStorageSync('userLogin');
|
|
|
+ if (!currentUser || !mobile || !afterLoginUserLogin) {
|
|
|
+ wx.removeStorageSync('userLogin');
|
|
|
+ login.loginNow();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
// 即使登录失败,也允许继续访问(仅在非强制登录模式下)
|
|
|
if(!r) {
|
|
|
@@ -452,7 +487,32 @@ Page({
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- // 如果出错,尝试继续跳转到主页(游客模式)
|
|
|
+ const isEntryFromScan =
|
|
|
+ !!(this.data.options && (this.data.options.q || this.data.options.scene)) ||
|
|
|
+ wx.getStorageSync('storeId_from_scan') === true ||
|
|
|
+ wx.getStorageSync('need_scan_redirect') === true ||
|
|
|
+ wx.getStorageSync('need_activity_redirect') === true;
|
|
|
+ if (isEntryFromScan) {
|
|
|
+ this.setData({ loading: false });
|
|
|
+ wx.showModal({
|
|
|
+ title: '需要登录',
|
|
|
+ content: '扫码进入需要先完成登录授权后才能继续',
|
|
|
+ showCancel: true,
|
|
|
+ cancelText: '退出',
|
|
|
+ confirmText: '去登录',
|
|
|
+ success: async (result) => {
|
|
|
+ if (result.confirm) {
|
|
|
+ try {
|
|
|
+ await checkAuth(true);
|
|
|
+ } catch (e) {}
|
|
|
+ } else {
|
|
|
+ wx.exitMiniProgram();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
console.log('⚠️ 登录出错,尝试游客模式访问');
|
|
|
|
|
|
let url = getApp().globalData.rootPage || getApp().globalData.defaultTabBar.list[0].pagePath;
|
|
|
@@ -508,7 +568,8 @@ Page({
|
|
|
const pendingScan = wx.getStorageSync('pending_scan_record');
|
|
|
|
|
|
if (!pendingScan) {
|
|
|
- return;
|
|
|
+ console.log('ℹ️ [ScanRecord] 未发现 pending_scan_record,无需补记');
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
console.log('===========================================');
|
|
|
@@ -531,7 +592,7 @@ Page({
|
|
|
await this.recordUserSource(pendingScan);
|
|
|
|
|
|
// 记录扫码统计
|
|
|
- await this.recordScanStatistics({
|
|
|
+ const recordOk = await this.recordScanStatistics({
|
|
|
storeId: pendingScan.storeId,
|
|
|
sourceType: pendingScan.sourceType,
|
|
|
sourceId: pendingScan.sourceId,
|
|
|
@@ -544,12 +605,17 @@ Page({
|
|
|
scanTimestamp: pendingScan.timestamp
|
|
|
});
|
|
|
|
|
|
- // 清除待记录的扫码信息
|
|
|
- wx.removeStorageSync('pending_scan_record');
|
|
|
- console.log('✅ 扫码统计已记录并清除');
|
|
|
+ if (recordOk) {
|
|
|
+ wx.removeStorageSync('pending_scan_record');
|
|
|
+ console.log('✅ 扫码统计已记录并清除');
|
|
|
+ } else {
|
|
|
+ console.log('⏳ 扫码统计未完成写入,保留 pending_scan_record 等待后续重试');
|
|
|
+ }
|
|
|
+ return recordOk;
|
|
|
|
|
|
} catch (error) {
|
|
|
console.error('❌ 记录待处理扫码信息失败:', error);
|
|
|
+ return false;
|
|
|
}
|
|
|
},
|
|
|
|
|
|
@@ -603,6 +669,20 @@ Page({
|
|
|
} catch (e) {}
|
|
|
return;
|
|
|
}
|
|
|
+
|
|
|
+ try {
|
|
|
+ const now = Date.now();
|
|
|
+ const lastTry = wx.getStorageSync('pending_scan_record_try_by_traffic') || 0;
|
|
|
+ if (!lastTry || now - lastTry > 2000) {
|
|
|
+ wx.setStorageSync('pending_scan_record_try_by_traffic', now);
|
|
|
+ if (typeof getApp().checkAndRecordPendingScan === 'function') {
|
|
|
+ console.log('🧾 [ScanRecord] 借助 traffic 复判触发补记');
|
|
|
+ const ok = await getApp().checkAndRecordPendingScan();
|
|
|
+ console.log('🧾 [ScanRecord] traffic 复判触发补记结果:', ok ? 'success' : 'not_written');
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (e) {}
|
|
|
+
|
|
|
const storeId = pending && pending.storeId ? pending.storeId : null;
|
|
|
if (!storeId) {
|
|
|
console.warn('🚦 [traffic] 暂缓扣减任务缺少 storeId,清除任务');
|
|
|
@@ -1035,9 +1115,16 @@ Page({
|
|
|
className: "_User",
|
|
|
objectId: invite
|
|
|
})
|
|
|
- await Parse.Cloud.run('user_save', {
|
|
|
- userJson: user.toJSON()
|
|
|
- })
|
|
|
+ try {
|
|
|
+ await user.save()
|
|
|
+ } catch (e) {
|
|
|
+ try {
|
|
|
+ await user.fetch()
|
|
|
+ } catch (e2) {}
|
|
|
+ await Parse.Cloud.run('user_save', {
|
|
|
+ userJson: user.toJSON()
|
|
|
+ })
|
|
|
+ }
|
|
|
}
|
|
|
} catch (error) {
|
|
|
console.error('❌ updateUser 失败:', error.message);
|
|
|
@@ -1214,8 +1301,10 @@ Page({
|
|
|
console.log('📢 推广员ID (userId):', userId);
|
|
|
} else {
|
|
|
// 其他情况(产品码、案例码、店铺分享等)
|
|
|
- sourceType = 'scan';
|
|
|
- console.log('🏬 [来源识别] 来源类型: 通用扫码 (scan)');
|
|
|
+ sourceType = 'store';
|
|
|
+ sourceId = storeId;
|
|
|
+ console.log('🏬 [来源识别] 来源类型: 门店扫码 (store)');
|
|
|
+ console.log('🏬 门店ID (storeId):', storeId);
|
|
|
}
|
|
|
|
|
|
if (productId) {
|
|
|
@@ -1765,25 +1854,42 @@ Page({
|
|
|
console.log(' - userId:', userId || '无');
|
|
|
console.log(' - productId:', productId || '无');
|
|
|
console.log(' - scanCount:', scanCount || '0');
|
|
|
+ console.log('🧾 [ScanRecord] 即将尝试写入 ScanRecord 表');
|
|
|
|
|
|
// 检查用户是否已登录
|
|
|
const currentUser = Parse.User.current();
|
|
|
if (!currentUser) {
|
|
|
- console.log('⚠️ [未登录] 用户未登录,不记录扫码统计');
|
|
|
- return;
|
|
|
+ console.log('⚠️ [ScanRecord] 未写入(原因:用户未登录)');
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
console.log('👤 [用户信息] 当前登录用户:');
|
|
|
console.log(' - 用户ID:', currentUser.id);
|
|
|
- console.log(' - 手机号:', currentUser.get('mobile') || '无');
|
|
|
+ let storageMobile = '';
|
|
|
+ try { storageMobile = wx.getStorageSync('user_mobile') || ''; } catch (e) {}
|
|
|
+ let userMobile = currentUser.get('mobile') || '';
|
|
|
+ let userPhone = currentUser.get('phone') || '';
|
|
|
+ try {
|
|
|
+ const sessionToken = typeof currentUser.getSessionToken === 'function' ? currentUser.getSessionToken() : null;
|
|
|
+ const q = new Parse.Query('_User');
|
|
|
+ q.select('mobile', 'phone');
|
|
|
+ const freshUser = await q.get(currentUser.id, sessionToken ? { sessionToken } : undefined);
|
|
|
+ if (freshUser) {
|
|
|
+ userMobile = freshUser.get('mobile') || userMobile;
|
|
|
+ userPhone = freshUser.get('phone') || userPhone;
|
|
|
+ }
|
|
|
+ } catch (e) {}
|
|
|
+ console.log(' - mobile:', userMobile || '无');
|
|
|
+ console.log(' - phone:', userPhone || '无');
|
|
|
+ console.log(' - storage(user_mobile):', storageMobile || '无');
|
|
|
|
|
|
// 如果没有来源信息,不记录统计
|
|
|
if (!sourceId && !ownerId && !employeeId && !partnerId && !userId) {
|
|
|
- console.log('ℹ️ [跳过] 无来源信息,跳过统计记录');
|
|
|
- return;
|
|
|
+ console.log('ℹ️ [ScanRecord] 未写入(原因:无来源信息)');
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
- const hasMobile = !!currentUser.get('mobile');
|
|
|
+ const hasMobile = !!normalizeCnMobile(userMobile || userPhone || storageMobile);
|
|
|
const scanTs = typeof scanTimestamp === 'number' && scanTimestamp > 0 ? scanTimestamp : Date.now();
|
|
|
|
|
|
if (partnerId && !hasMobile) {
|
|
|
@@ -1809,8 +1915,8 @@ Page({
|
|
|
wx.setStorageSync('pending_scan_record', pendingData);
|
|
|
} catch (e2) {}
|
|
|
}
|
|
|
- console.log('⏳ [异业扫码] 用户未绑定手机号,延后到注册登录后再统计');
|
|
|
- return;
|
|
|
+ console.log('⏳ [ScanRecord] 未写入(原因:异业扫码且未绑定手机号,已暂存 pending_scan_record)');
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
console.log('✅ [开始记录] 用户已登录且有来源信息,开始记录');
|
|
|
@@ -1837,10 +1943,6 @@ Page({
|
|
|
console.log(' - scanTime:', new Date().toISOString());
|
|
|
|
|
|
// 根据来源类型设置对应的ID
|
|
|
- if (ownerId) {
|
|
|
- record.set('ownerId', ownerId);
|
|
|
- console.log(' - ownerId:', ownerId);
|
|
|
- }
|
|
|
if (employeeId) {
|
|
|
record.set('employeeId', employeeId);
|
|
|
console.log(' - employeeId:', employeeId);
|
|
|
@@ -1864,11 +1966,16 @@ Page({
|
|
|
className: '_User',
|
|
|
objectId: currentUser.id
|
|
|
});
|
|
|
+ record.set('userid', currentUser.id);
|
|
|
console.log(' - user:', currentUser.id);
|
|
|
|
|
|
await record.save();
|
|
|
- console.log('✅ [保存成功] 扫码记录已保存到数据库');
|
|
|
- console.log(' - 记录ID:', record.id);
|
|
|
+ console.log('✅ [ScanRecord] 保存成功');
|
|
|
+ console.log(' - recordId:', record.id);
|
|
|
+ console.log(' - userId:', currentUser.id);
|
|
|
+ console.log(' - storeId:', storeId);
|
|
|
+ console.log(' - sourceType:', sourceType || 'unknown');
|
|
|
+ console.log(' - sourceId:', sourceId || '无');
|
|
|
|
|
|
// 如果存在异业合作伙伴ID,处理异业绑定和扫码次数
|
|
|
if (partnerId) {
|
|
|
@@ -1892,7 +1999,7 @@ Page({
|
|
|
console.log(' - 已绑定异业:', userBoundPartnerId);
|
|
|
console.log(' - 当前扫码异业:', partnerId);
|
|
|
console.log('🤝 ===========================================');
|
|
|
- return;
|
|
|
+ return true;
|
|
|
}
|
|
|
|
|
|
// 规则2:检查该用户在该门店是否已经扫过该异业的码
|
|
|
@@ -1915,7 +2022,7 @@ Page({
|
|
|
console.log(' - 计入时间:', existingScan.get('scanTime'));
|
|
|
console.log(' - 记录ID:', existingScan.id);
|
|
|
console.log('🤝 ===========================================');
|
|
|
- return;
|
|
|
+ return true;
|
|
|
}
|
|
|
|
|
|
let partnerNewUserQualified = false;
|
|
|
@@ -1930,7 +2037,7 @@ Page({
|
|
|
if (!partnerNewUserQualified) {
|
|
|
console.log('ℹ️ [规则2] 非“扫码注册登录的新用户”,不计入异业扫码次数');
|
|
|
console.log('🤝 ===========================================');
|
|
|
- return;
|
|
|
+ return true;
|
|
|
}
|
|
|
|
|
|
record.set('partnerNewUserCounted', true);
|
|
|
@@ -1998,9 +2105,18 @@ Page({
|
|
|
console.log('🤝 ===========================================');
|
|
|
}
|
|
|
}
|
|
|
+ return true;
|
|
|
} catch (error) {
|
|
|
- console.warn('⚠️ 保存扫码记录失败:', error);
|
|
|
+ console.error('❌ [ScanRecord] 保存失败');
|
|
|
+ console.error(' - message:', error?.message || error);
|
|
|
+ if (error && typeof error === 'object') {
|
|
|
+ try {
|
|
|
+ console.error(' - code:', error.code);
|
|
|
+ console.error(' - details:', error.details);
|
|
|
+ } catch (e) {}
|
|
|
+ }
|
|
|
// 不影响主流程
|
|
|
+ return false;
|
|
|
}
|
|
|
}
|
|
|
});
|