Files
xingque/pages/index/index.js

386 lines
11 KiB
JavaScript

// 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';
import { createPage } from '../../utils/base-page.js';
// 扫码场景参数名
const SCENE_PARAM = 'scene';
Page(createPage({
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) {
// 解析二维码参数
if (options[SCENE_PARAM]) {
try {
const scene = decodeURIComponent(options[SCENE_PARAM]);
this.shopId = scene;
} catch (e) {
console.error('scene解码失败', e);
}
}
// 等待全局配置加载完成
this.waitForConfigAndInit();
// 已登录时才检查弹窗
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();
}
}
},
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. 扫码进入时绑定店铺
if (this.shopId) {
await bindShop(this.shopId);
}
// 3. 并行加载公告轮播图和商品数据
const [gonggaoResult, shopData] = await Promise.all([
this.loadGonggaoAndLunbo(),
fetchShopGoods()
]);
// 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 });
}
},
/**
* 加载公告和轮播图
*/
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,
_modalLeaving: false,
gonggaoAnim: false,
currentTime: this.getCurrentTime()
});
},
hideGonggaoDetail() {
this.setData({
showGonggaoModal: false,
_modalLeaving: true,
gonggaoAnim: true
});
setTimeout(() => this.setData({ _modalLeaving: false }), 300);
},
/**
* 刷新所有数据
* 只刷新商品数据
*/
async refreshAllData() {
if (this.data.isRefreshing) return;
this.setData({ isRefreshing: true });
wx.showLoading({ title: '刷新中...', mask: true });
try {
// 重新获取商品数据
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/product-detail/product-detail?id=${shangpinId}`
});
},
onReachBottom() {},
onShareAppMessage() {
return {
title: '阿龙电竞',
path: '/pages/shangpin/shangpin'
};
},
onUnload() {
this.setData({ gonggaoAnim: false });
}
}))