494 lines
13 KiB
JavaScript
494 lines
13 KiB
JavaScript
// pages/shangpin/shangpin.js
|
||
const app = getApp()
|
||
|
||
Page({
|
||
/**
|
||
* 页面的初始数据
|
||
*/
|
||
data: {
|
||
// 全局变量引用
|
||
ossImageUrl: '',
|
||
lunbozhanwei: '',
|
||
|
||
// 页面数据
|
||
shangpingonggao: '',
|
||
lunboList: [],
|
||
shangpinleixing: [],
|
||
shangpinzhuanqu: [],
|
||
shangpinliebiao: [],
|
||
|
||
// 状态控制
|
||
selectedLeixingId: null,
|
||
filteredData: [],
|
||
showGonggaoModal: false,
|
||
gonggaoAnim: true,
|
||
isLoading: false,
|
||
isRefreshing: false,
|
||
hasInitialized: false,
|
||
|
||
// 🔴【新增】当前时间(用于弹窗显示)
|
||
currentTime: ''
|
||
},
|
||
|
||
/**
|
||
* 生命周期函数--监听页面加载
|
||
*/
|
||
onLoad(options) {
|
||
// 🔥 等待全局配置加载完成
|
||
this.waitForConfigAndInit();
|
||
// 🆕 修改:仅在已登录时检查弹窗,避免未登录时发起请求导致 401 弹窗
|
||
const token = wx.getStorageSync('token');
|
||
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 {
|
||
// 配置未就绪,延迟重试(最多等待3秒,每100ms检查一次)
|
||
|
||
setTimeout(() => this.waitForConfigAndInit(), 100);
|
||
}
|
||
},
|
||
|
||
/**
|
||
* 生命周期函数--监听页面显示
|
||
*/
|
||
onShow() {
|
||
// 如果已经初始化过,只更新时间;否则等待配置
|
||
if (this.data.ossImageUrl) {
|
||
this.setData({
|
||
gonggaoAnim: true,
|
||
currentTime: this.getCurrentTime()
|
||
});
|
||
}
|
||
this.registerNotificationComponent();
|
||
},
|
||
|
||
// 注册通知组件
|
||
registerNotificationComponent() {
|
||
const app = getApp();
|
||
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}`;
|
||
},
|
||
|
||
/**
|
||
* 🔴【新增】按paixu字段排序函数
|
||
* 规则:1. paixu大的在前 2. paixu相同时id小的在前 3. 没有paixu的按id排序
|
||
*/
|
||
sortByPaixu(list) {
|
||
if (!list || !Array.isArray(list)) return []
|
||
|
||
return [...list].sort((a, b) => {
|
||
// 获取paixu值,如果没有则默认为0
|
||
const paixuA = a.paixu || 0
|
||
const paixuB = b.paixu || 0
|
||
|
||
// 1. 先按paixu降序(大的在前)
|
||
if (paixuB !== paixuA) {
|
||
return paixuB - paixuA
|
||
}
|
||
|
||
// 2. paixu相同时,按id升序(小的在前)
|
||
return a.id - b.id
|
||
})
|
||
},
|
||
|
||
/**
|
||
* 初始化页面数据
|
||
*/
|
||
initPageData() {
|
||
const that = this
|
||
this.setData({ isLoading: true })
|
||
|
||
const needLoad = []
|
||
|
||
// 1. 检查公告和轮播图
|
||
if (!app.globalData.shangpingonggao || app.globalData.shangpinlunbo.length === 0) {
|
||
needLoad.push(this.loadGonggaoAndLunbo())
|
||
} else {
|
||
this.setData({
|
||
shangpingonggao: app.globalData.shangpingonggao,
|
||
lunboList: this.processImageUrls(app.globalData.shangpinlunbo)
|
||
})
|
||
}
|
||
|
||
// 2. 检查商品数据
|
||
if (app.globalData.shangpinleixing.length === 0) {
|
||
needLoad.push(this.loadAllShangpinData())
|
||
} else {
|
||
const leixingList = app.globalData.shangpinleixing
|
||
|
||
// 🔴【修改】对商品类型进行排序
|
||
const sortedLeixing = this.sortByPaixu(leixingList)
|
||
|
||
this.setData({
|
||
shangpinleixing: leixingList,
|
||
shangpinzhuanqu: app.globalData.shangpinzhuanqu || [],
|
||
shangpinliebiao: app.globalData.shangpinliebiao || [],
|
||
selectedLeixingId: sortedLeixing[0]?.id || null
|
||
}, () => {
|
||
this.filterShangpinData()
|
||
})
|
||
}
|
||
|
||
if (needLoad.length > 0) {
|
||
Promise.all(needLoad)
|
||
.then(() => {
|
||
that.setData({ isLoading: false })
|
||
})
|
||
.catch(error => {
|
||
console.error('数据加载失败:', error)
|
||
that.setData({ isLoading: false })
|
||
wx.showToast({
|
||
title: '加载失败,请重试',
|
||
icon: 'none'
|
||
})
|
||
})
|
||
} else {
|
||
this.setData({ isLoading: false })
|
||
}
|
||
},
|
||
|
||
/**
|
||
* 加载公告和轮播图数据
|
||
*/
|
||
loadGonggaoAndLunbo() {
|
||
const that = this
|
||
return new Promise((resolve, reject) => {
|
||
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 || []
|
||
|
||
that.setData({
|
||
shangpingonggao: app.globalData.shangpingonggao,
|
||
lunboList: that.processImageUrls(app.globalData.shangpinlunbo)
|
||
})
|
||
|
||
resolve()
|
||
} else {
|
||
reject(new Error('请求失败'))
|
||
}
|
||
},
|
||
fail(error) {
|
||
console.error('加载公告失败:', error)
|
||
reject(error)
|
||
}
|
||
})
|
||
})
|
||
},
|
||
|
||
/**
|
||
* 加载所有商品数据
|
||
*/
|
||
loadAllShangpinData() {
|
||
const that = this
|
||
return new Promise((resolve, reject) => {
|
||
wx.request({
|
||
url: app.globalData.apiBaseUrl + '/shangpin/shangpinhuoqu/',
|
||
method: 'POST',
|
||
header: {
|
||
'content-type': 'application/json'
|
||
},
|
||
success(res) {
|
||
if (res.statusCode === 200 && res.data) {
|
||
const data = res.data
|
||
|
||
// 🔴【修改】对返回的数据进行排序
|
||
const sortedLeixing = that.sortByPaixu(data.shangpinleixing || [])
|
||
const sortedZhuanqu = that.sortByPaixu(data.shangpinzhuanqu || [])
|
||
const sortedShangpin = that.sortByPaixu(data.shangpinliebiao || [])
|
||
|
||
app.globalData.shangpinleixing = sortedLeixing
|
||
app.globalData.shangpinzhuanqu = sortedZhuanqu
|
||
app.globalData.shangpinliebiao = sortedShangpin
|
||
|
||
that.setData({
|
||
shangpinleixing: sortedLeixing,
|
||
shangpinzhuanqu: sortedZhuanqu,
|
||
shangpinliebiao: sortedShangpin,
|
||
selectedLeixingId: sortedLeixing[0]?.id || null
|
||
}, () => {
|
||
that.filterShangpinData()
|
||
resolve()
|
||
})
|
||
} else {
|
||
reject(new Error('请求失败'))
|
||
}
|
||
},
|
||
fail(error) {
|
||
console.error('加载商品数据失败:', error)
|
||
reject(error)
|
||
}
|
||
})
|
||
})
|
||
},
|
||
|
||
/**
|
||
* 处理图片URL(拼接OSS域名)
|
||
*/
|
||
processImageUrls(urlList) {
|
||
if (!urlList || !Array.isArray(urlList)) return []
|
||
|
||
return urlList.map(url => {
|
||
if (url.startsWith('http')) {
|
||
return url
|
||
} else {
|
||
return this.data.ossImageUrl + url
|
||
}
|
||
})
|
||
},
|
||
|
||
/**
|
||
* 筛选商品数据
|
||
*/
|
||
filterShangpinData() {
|
||
const { selectedLeixingId, shangpinzhuanqu, shangpinliebiao } = this.data
|
||
|
||
if (!selectedLeixingId || !shangpinzhuanqu || !shangpinliebiao) {
|
||
this.setData({ filteredData: [] })
|
||
return
|
||
}
|
||
|
||
// 1. 构建专区Map(按类型分组,但只处理当前选中的类型)
|
||
const zhuanquByLeixing = new Map()
|
||
|
||
shangpinzhuanqu.forEach(zhuanqu => {
|
||
if (zhuanqu.leixing_id === selectedLeixingId) {
|
||
if (!zhuanquByLeixing.has(selectedLeixingId)) {
|
||
zhuanquByLeixing.set(selectedLeixingId, [])
|
||
}
|
||
zhuanquByLeixing.get(selectedLeixingId).push(zhuanqu)
|
||
}
|
||
})
|
||
|
||
// 2. 构建商品Map(按专区分组)
|
||
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 // 🔴 保留排序字段
|
||
})
|
||
}
|
||
})
|
||
|
||
// 3. 构建最终数据结构
|
||
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) => {
|
||
// 按专区paixu降序
|
||
const paixuA = a.zhuanqu.paixu || 0
|
||
const paixuB = b.zhuanqu.paixu || 0
|
||
if (paixuB !== paixuA) return paixuB - paixuA
|
||
// paixu相同时按专区id升序
|
||
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
|
||
})
|
||
},
|
||
|
||
/**
|
||
* 刷新所有数据
|
||
*/
|
||
refreshAllData() {
|
||
const that = this
|
||
this.setData({ isRefreshing: true })
|
||
|
||
wx.showLoading({
|
||
title: '刷新中...',
|
||
mask: true
|
||
})
|
||
|
||
// 清空全局变量
|
||
app.globalData.shangpingonggao = ''
|
||
app.globalData.shangpinlunbo = []
|
||
app.globalData.shangpinleixing = []
|
||
app.globalData.shangpinzhuanqu = []
|
||
app.globalData.shangpinliebiao = []
|
||
|
||
Promise.all([
|
||
that.loadGonggaoAndLunbo(),
|
||
that.loadAllShangpinData()
|
||
])
|
||
.then(() => {
|
||
wx.hideLoading()
|
||
that.setData({ isRefreshing: false })
|
||
wx.showToast({
|
||
title: '刷新成功',
|
||
icon: 'success',
|
||
duration: 1500
|
||
})
|
||
})
|
||
.catch(error => {
|
||
console.error('刷新失败:', error)
|
||
wx.hideLoading()
|
||
that.setData({ isRefreshing: false })
|
||
wx.showToast({
|
||
title: '刷新失败',
|
||
icon: 'none'
|
||
})
|
||
})
|
||
},
|
||
|
||
/**
|
||
* 跳转到商品详情页
|
||
*/
|
||
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 })
|
||
}
|
||
}) |