Files
xingque/pages/index/index.js

400 lines
12 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// pages/shangpin/shangpin.js
const app = getApp();
import { ensureLogin } from '../../utils/login';
import { fetchShopGoods, bindShop } from '../../utils/shop';
import { backfillUserProfileCache, getSessionToken } from '../../utils/role-tab-bar';
import PopupService from '../../services/popupService.js';
// 🔥 固定参数:扫码时从 scene 中获取店铺ID的字段名可在此处集中修改
const SCENE_PARAM = 'scene'; // 二维码参数统一使用 scene解码后即为店铺ID
Page({
data: {
// 全局变量引用
ossImageUrl: '',
lunbozhanwei: '',
// 页面数据
shangpingonggao: '',
lunboList: [],
shangpinleixing: [],
shangpinzhuanqu: [],
shangpinliebiao: [],
// 状态控制
selectedLeixingId: null,
filteredData: [],
showGonggaoModal: false,
gonggaoAnim: true,
isLoading: false,
isRefreshing: false,
hasInitialized: false,
currentTime: ''
},
// 从二维码解析出的店铺ID仅在扫码时存在
shopId: null,
onLoad(options) {
// 🔥 解析二维码参数scene
if (options[SCENE_PARAM]) {
try {
// 微信会对 scene 进行编码,需要解码
const scene = decodeURIComponent(options[SCENE_PARAM]);
this.shopId = scene; // 例如dianpu_123
} catch (e) {
console.error('scene解码失败', e);
}
}
// 等待全局配置加载完成
this.waitForConfigAndInit();
// 🆕 修改:仅在已登录时检查弹窗,避免未登录时发起请求导致 401 弹窗
const token = getSessionToken(app);
if (token) {
PopupService.checkAndShow(this, 'index');
}
},
// 🆕 页面隐藏时清理弹窗视图
onHide: function () {
const popupComp = this.selectComponent('#popupNotice');
if (popupComp && popupComp.cleanup) {
popupComp.cleanup();
}
},
waitForConfigAndInit() {
if (app.globalData.ossImageUrl) {
this.setData({
ossImageUrl: app.globalData.ossImageUrl,
lunbozhanwei: app.globalData.lunbozhanwei,
currentTime: this.getCurrentTime()
});
this.initPageData();
} else {
setTimeout(() => this.waitForConfigAndInit(), 100);
}
},
onShow() {
backfillUserProfileCache(app);
if (this.data.ossImageUrl) {
this.setData({
gonggaoAnim: true,
currentTime: this.getCurrentTime(),
});
}
this.registerNotificationComponent();
if (!getSessionToken(app)) {
this.setData({
hasInitialized: false,
filteredData: [],
shangpinleixing: [],
shangpinzhuanqu: [],
shangpinliebiao: [],
});
return;
}
// 已登录时加载/刷新商品;未登录不自动登录、不跳转
if (!this.data.isLoading) {
const needLoad = !this.data.hasInitialized
|| !this.data.filteredData
|| this.data.filteredData.length === 0;
if (needLoad) {
this.initPageData();
}
}
},
registerNotificationComponent() {
const notificationComp = this.selectComponent('#global-notification');
if (notificationComp && notificationComp.showNotification) {
app.globalData.globalNotification = {
show: (data) => notificationComp.showNotification(data),
hide: () => notificationComp.hideNotification()
};
}
},
getCurrentTime() {
const now = new Date();
const year = now.getFullYear();
const month = (now.getMonth() + 1).toString().padStart(2, '0');
const day = now.getDate().toString().padStart(2, '0');
const hour = now.getHours().toString().padStart(2, '0');
const minute = now.getMinutes().toString().padStart(2, '0');
return `${year}-${month}-${day} ${hour}:${minute}`;
},
sortByPaixu(list) {
if (!list || !Array.isArray(list)) return [];
return [...list].sort((a, b) => {
const paixuA = a.paixu || 0;
const paixuB = b.paixu || 0;
if (paixuB !== paixuA) return paixuB - paixuA;
return a.id - b.id;
});
},
/**
* 初始化页面数据(重构后)
* 流程:确保登录 → 如有扫码ID则绑定店铺 → 并行加载公告轮播图和商品数据
*/
async initPageData() {
this.setData({ isLoading: true });
try {
// 1. 确保登录(静默,不跳转)
await ensureLogin({ page: this });
// 2. 🔥 关键仅当通过扫码进入且携带了有效的店铺ID时才执行绑定
if (this.shopId) {
await bindShop(this.shopId);
}
// 3. 并行加载公告轮播图(复用原接口,独立请求)和店铺商品(新接口)
const [gonggaoResult, shopData] = await Promise.all([
this.loadGonggaoAndLunbo(), // 公告轮播图使用原有的 wx.request 方式,不受影响
fetchShopGoods() // 商品数据通过封装的 request 获取
]);
// 4. 处理商品数据
const sortedLeixing = this.sortByPaixu(shopData.shangpinleixing || []);
const sortedZhuanqu = this.sortByPaixu(shopData.shangpinzhuanqu || []);
const sortedShangpin = this.sortByPaixu(shopData.shangpinliebiao || []);
// 更新全局缓存(可选,用于其他页面复用)
app.globalData.shangpinleixing = sortedLeixing;
app.globalData.shangpinzhuanqu = sortedZhuanqu;
app.globalData.shangpinliebiao = sortedShangpin;
this.setData({
shangpinleixing: sortedLeixing,
shangpinzhuanqu: sortedZhuanqu,
shangpinliebiao: sortedShangpin,
selectedLeixingId: sortedLeixing[0]?.id || null,
isLoading: false,
hasInitialized: true,
}, () => {
this.filterShangpinData();
});
} catch (error) {
console.error('初始化失败:', error);
this.setData({ isLoading: false });
// 错误提示已在各函数内部处理,此处仅做兜底
}
},
/**
* 加载公告和轮播图(完全复用原逻辑,使用 wx.request不使用封装 request
*/
loadGonggaoAndLunbo() {
return new Promise((resolve, reject) => {
// 如果全局已有数据,直接使用
if (app.globalData.shangpingonggao && app.globalData.shangpinlunbo.length > 0) {
this.setData({
shangpingonggao: app.globalData.shangpingonggao,
lunboList: this.processImageUrls(app.globalData.shangpinlunbo)
});
resolve();
return;
}
wx.request({
url: app.globalData.apiBaseUrl + '/peizhi/shangpingonggao/',
method: 'POST',
header: { 'content-type': 'application/json' },
success: (res) => {
if (res.statusCode === 200 && res.data) {
const data = res.data;
app.globalData.shangpingonggao = data.shangpingonggao || '';
app.globalData.shangpinlunbo = data.shangpinlunbo || [];
this.setData({
shangpingonggao: app.globalData.shangpingonggao,
lunboList: this.processImageUrls(app.globalData.shangpinlunbo)
});
resolve();
} else {
reject(new Error('请求失败'));
}
},
fail: reject
});
});
},
processImageUrls(urlList) {
if (!urlList || !Array.isArray(urlList)) return [];
return urlList.map(url => url.startsWith('http') ? url : this.data.ossImageUrl + url);
},
/**
* 筛选商品数据(完全复用原有逻辑,不做任何改动)
*/
filterShangpinData() {
const { selectedLeixingId, shangpinzhuanqu, shangpinliebiao } = this.data;
if (!selectedLeixingId || !shangpinzhuanqu || !shangpinliebiao) {
this.setData({ filteredData: [] });
return;
}
const zhuanquByLeixing = new Map();
shangpinzhuanqu.forEach(zhuanqu => {
if (zhuanqu.leixing_id === selectedLeixingId) {
if (!zhuanquByLeixing.has(selectedLeixingId)) {
zhuanquByLeixing.set(selectedLeixingId, []);
}
zhuanquByLeixing.get(selectedLeixingId).push(zhuanqu);
}
});
const shangpinByZhuanqu = new Map();
shangpinliebiao.forEach(shangpin => {
if (shangpin.leixing_id === selectedLeixingId && shangpin.zhuanqu_id) {
const zhuanquId = shangpin.zhuanqu_id;
if (!shangpinByZhuanqu.has(zhuanquId)) {
shangpinByZhuanqu.set(zhuanquId, []);
}
const jiage = parseFloat(shangpin.jiage) || 0;
const priceInteger = Math.floor(jiage);
let priceDecimal = '00';
const decimalPart = (jiage - priceInteger).toFixed(2);
if (decimalPart > 0) {
priceDecimal = decimalPart.toString().split('.')[1];
}
shangpinByZhuanqu.get(zhuanquId).push({
id: shangpin.id,
biaoqian: shangpin.biaoqian,
jiage: jiage,
priceInteger: priceInteger,
priceDecimal: priceDecimal,
tupian_url: shangpin.tupian_url,
duiwai_xiaoliang: shangpin.duiwai_xiaoliang || 0,
paixu: shangpin.paixu || 0
});
}
});
const filteredData = [];
const currentZhuanquList = zhuanquByLeixing.get(selectedLeixingId) || [];
currentZhuanquList.forEach(zhuanqu => {
const shangpinList = shangpinByZhuanqu.get(zhuanqu.id) || [];
if (shangpinList.length > 0) {
filteredData.push({
zhuanqu: {
id: zhuanqu.id,
mingzi: zhuanqu.mingzi,
paixu: zhuanqu.paixu || 0
},
shangpinList: shangpinList
});
}
});
const sortedFilteredData = filteredData.sort((a, b) => {
const paixuA = a.zhuanqu.paixu || 0;
const paixuB = b.zhuanqu.paixu || 0;
if (paixuB !== paixuA) return paixuB - paixuA;
return a.zhuanqu.id - b.zhuanqu.id;
});
this.setData({ filteredData: sortedFilteredData });
},
selectLeixing(e) {
const leixingId = e.currentTarget.dataset.id;
if (this.data.selectedLeixingId === leixingId) return;
this.setData({ selectedLeixingId: leixingId }, () => {
this.filterShangpinData();
});
},
showGonggaoDetail() {
this.setData({
showGonggaoModal: true,
gonggaoAnim: false,
currentTime: this.getCurrentTime()
});
},
hideGonggaoDetail() {
this.setData({
showGonggaoModal: false,
gonggaoAnim: true
});
},
/**
* 刷新所有数据(点击刷新按钮)
* 只刷新商品数据,公告轮播图保持不变(若需刷新可清空全局缓存后调用 loadGonggaoAndLunbo
*/
async refreshAllData() {
if (this.data.isRefreshing) return;
this.setData({ isRefreshing: true });
wx.showLoading({ title: '刷新中...', mask: true });
try {
// 重新获取商品数据(登录状态由 fetchShopGoods 内部确保)
const shopData = await fetchShopGoods();
// 公告轮播图通常不需要随刷新按钮更新,保持原样
const sortedLeixing = this.sortByPaixu(shopData.shangpinleixing || []);
const sortedZhuanqu = this.sortByPaixu(shopData.shangpinzhuanqu || []);
const sortedShangpin = this.sortByPaixu(shopData.shangpinliebiao || []);
app.globalData.shangpinleixing = sortedLeixing;
app.globalData.shangpinzhuanqu = sortedZhuanqu;
app.globalData.shangpinliebiao = sortedShangpin;
this.setData({
shangpinleixing: sortedLeixing,
shangpinzhuanqu: sortedZhuanqu,
shangpinliebiao: sortedShangpin,
selectedLeixingId: sortedLeixing[0]?.id || null,
isRefreshing: false
}, () => {
this.filterShangpinData();
});
wx.hideLoading();
wx.showToast({ title: '刷新成功', icon: 'success', duration: 1500 });
} catch (error) {
wx.hideLoading();
this.setData({ isRefreshing: false });
}
},
goToDetail(e) {
const shangpinId = e.currentTarget.dataset.id;
if (!shangpinId) return;
wx.navigateTo({
url: `/pages/shangpinxiangqing/shangpinxiangqing?id=${shangpinId}`
});
},
onReachBottom() {},
onShareAppMessage() {
return {
title: '阿龙电竞',
path: '/pages/shangpin/shangpin'
};
},
onUnload() {
this.setData({ gonggaoAnim: false });
}
});