修正了 pages 名为拼音的问题
This commit is contained in:
331
pages/category/category.js
Normal file
331
pages/category/category.js
Normal file
@@ -0,0 +1,331 @@
|
||||
// pages/category/category.js
|
||||
const app = getApp()
|
||||
|
||||
Page({
|
||||
data: {
|
||||
ossImageUrl: '',
|
||||
searchText: '',
|
||||
showSearchResult: false,
|
||||
searchResults: [],
|
||||
isSearching: false,
|
||||
shangpinleixing: [],
|
||||
shangpinzhuanqu: [],
|
||||
shangpinliebiao: [],
|
||||
selectedLeixingId: null,
|
||||
selectedZhuanquId: null,
|
||||
filteredZhuanquList: [],
|
||||
filteredShangpinList: [],
|
||||
zhuanquByLeixing: {},
|
||||
shangpinByZhuanqu: {},
|
||||
zhuanquGoodsCount: {},
|
||||
isLoading: false,
|
||||
hasInitialized: false
|
||||
},
|
||||
|
||||
onLoad(options) {
|
||||
this.setData({
|
||||
ossImageUrl: app.globalData.ossImageUrl
|
||||
})
|
||||
this.initPageData()
|
||||
},
|
||||
|
||||
onShow() {
|
||||
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()
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
initPageData() {
|
||||
const that = this
|
||||
this.setData({ isLoading: true })
|
||||
if (app.globalData.shangpinleixing && app.globalData.shangpinleixing.length > 0) {
|
||||
this.initFromGlobalData()
|
||||
} else {
|
||||
this.loadAllShangpinData()
|
||||
}
|
||||
},
|
||||
|
||||
initFromGlobalData() {
|
||||
const leixingList = app.globalData.shangpinleixing || []
|
||||
const zhuanquList = app.globalData.shangpinzhuanqu || []
|
||||
const shangpinList = app.globalData.shangpinliebiao || []
|
||||
|
||||
const zhuanquByLeixing = {}
|
||||
const shangpinByZhuanqu = {}
|
||||
const zhuanquGoodsCount = {}
|
||||
|
||||
zhuanquList.forEach(zhuanqu => {
|
||||
const leixingId = zhuanqu.leixing_id
|
||||
if (!zhuanquByLeixing[leixingId]) {
|
||||
zhuanquByLeixing[leixingId] = []
|
||||
}
|
||||
zhuanquByLeixing[leixingId].push(zhuanqu)
|
||||
})
|
||||
|
||||
shangpinList.forEach(shangpin => {
|
||||
const zhuanquId = shangpin.zhuanqu_id
|
||||
if (zhuanquId) {
|
||||
if (!shangpinByZhuanqu[zhuanquId]) {
|
||||
shangpinByZhuanqu[zhuanquId] = []
|
||||
zhuanquGoodsCount[zhuanquId] = 0
|
||||
}
|
||||
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[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
|
||||
})
|
||||
zhuanquGoodsCount[zhuanquId] += 1
|
||||
}
|
||||
})
|
||||
|
||||
const firstLeixing = leixingList[0]
|
||||
let firstZhuanquId = null
|
||||
if (firstLeixing && zhuanquByLeixing[firstLeixing.id]) {
|
||||
firstZhuanquId = zhuanquByLeixing[firstLeixing.id][0]?.id || null
|
||||
}
|
||||
|
||||
this.setData({
|
||||
shangpinleixing: leixingList,
|
||||
shangpinzhuanqu: zhuanquList,
|
||||
shangpinliebiao: shangpinList,
|
||||
zhuanquByLeixing: zhuanquByLeixing,
|
||||
shangpinByZhuanqu: shangpinByZhuanqu,
|
||||
zhuanquGoodsCount: zhuanquGoodsCount,
|
||||
selectedLeixingId: firstLeixing?.id || null,
|
||||
selectedZhuanquId: firstZhuanquId
|
||||
}, () => {
|
||||
this.filterData()
|
||||
this.setData({ isLoading: false, hasInitialized: true })
|
||||
})
|
||||
},
|
||||
|
||||
loadAllShangpinData() {
|
||||
const that = this
|
||||
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
|
||||
app.globalData.shangpinleixing = data.shangpinleixing || []
|
||||
app.globalData.shangpinzhuanqu = data.shangpinzhuanqu || []
|
||||
app.globalData.shangpinliebiao = data.shangpinliebiao || []
|
||||
that.initFromGlobalData()
|
||||
} else {
|
||||
that.handleLoadError()
|
||||
}
|
||||
},
|
||||
fail(error) {
|
||||
console.error('加载商品数据失败:', error)
|
||||
that.handleLoadError()
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
handleLoadError() {
|
||||
wx.showToast({
|
||||
title: '加载失败,请重试',
|
||||
icon: 'none'
|
||||
})
|
||||
this.setData({ isLoading: false })
|
||||
},
|
||||
|
||||
filterData() {
|
||||
const { selectedLeixingId, selectedZhuanquId, zhuanquByLeixing, shangpinByZhuanqu } = this.data
|
||||
const filteredZhuanquList = zhuanquByLeixing[selectedLeixingId] || []
|
||||
let filteredShangpinList = []
|
||||
if (selectedZhuanquId) {
|
||||
filteredShangpinList = shangpinByZhuanqu[selectedZhuanquId] || []
|
||||
} else if (filteredZhuanquList.length > 0) {
|
||||
const firstZhuanquId = filteredZhuanquList[0].id
|
||||
filteredShangpinList = shangpinByZhuanqu[firstZhuanquId] || []
|
||||
this.setData({ selectedZhuanquId: firstZhuanquId })
|
||||
}
|
||||
this.setData({
|
||||
filteredZhuanquList: filteredZhuanquList,
|
||||
filteredShangpinList: filteredShangpinList
|
||||
})
|
||||
},
|
||||
|
||||
selectLeixing(e) {
|
||||
const leixingId = e.currentTarget.dataset.id
|
||||
if (this.data.selectedLeixingId === leixingId) {
|
||||
return
|
||||
}
|
||||
const zhuanquList = this.data.zhuanquByLeixing[leixingId] || []
|
||||
const firstZhuanquId = zhuanquList.length > 0 ? zhuanquList[0].id : null
|
||||
this.setData({
|
||||
selectedLeixingId: leixingId,
|
||||
selectedZhuanquId: firstZhuanquId
|
||||
}, () => {
|
||||
this.filterData()
|
||||
})
|
||||
},
|
||||
|
||||
selectZhuanqu(e) {
|
||||
const zhuanquId = e.currentTarget.dataset.id
|
||||
if (this.data.selectedZhuanquId === zhuanquId) {
|
||||
return
|
||||
}
|
||||
this.setData({
|
||||
selectedZhuanquId: zhuanquId
|
||||
}, () => {
|
||||
const filteredShangpinList = this.data.shangpinByZhuanqu[zhuanquId] || []
|
||||
this.setData({
|
||||
filteredShangpinList: filteredShangpinList
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
onSearchInput(e) {
|
||||
this.setData({
|
||||
searchText: e.detail.value
|
||||
})
|
||||
},
|
||||
|
||||
onSearchTap() {
|
||||
const searchText = this.data.searchText.trim()
|
||||
if (!searchText) {
|
||||
wx.showToast({
|
||||
title: '请输入搜索内容',
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
this.startSearch(searchText)
|
||||
},
|
||||
|
||||
onSearchConfirm(e) {
|
||||
const searchText = e.detail.value.trim()
|
||||
if (!searchText) {
|
||||
wx.showToast({
|
||||
title: '请输入搜索内容',
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
this.setData({
|
||||
searchText: searchText
|
||||
})
|
||||
this.startSearch(searchText)
|
||||
},
|
||||
|
||||
startSearch(searchText) {
|
||||
this.setData({
|
||||
isSearching: true,
|
||||
showSearchResult: true
|
||||
})
|
||||
const allShangpin = this.data.shangpinliebiao
|
||||
const results = []
|
||||
for (const item of allShangpin) {
|
||||
if (item.biaoqian && item.biaoqian.toLowerCase().includes(searchText.toLowerCase())) {
|
||||
const jiage = parseFloat(item.jiage) || 0
|
||||
const priceInteger = Math.floor(jiage)
|
||||
let priceDecimal = '00'
|
||||
const decimalPart = (jiage - priceInteger).toFixed(2)
|
||||
if (decimalPart > 0) {
|
||||
priceDecimal = decimalPart.toString().split('.')[1]
|
||||
}
|
||||
results.push({
|
||||
id: item.id,
|
||||
biaoqian: item.biaoqian,
|
||||
jiage: jiage,
|
||||
priceInteger: priceInteger,
|
||||
priceDecimal: priceDecimal,
|
||||
tupian_url: item.tupian_url,
|
||||
leixing_name: this.getLeixingName(item.leixing_id),
|
||||
zhuanqu_name: this.getZhuanquName(item.zhuanqu_id)
|
||||
})
|
||||
}
|
||||
}
|
||||
this.setData({
|
||||
searchResults: results,
|
||||
isSearching: false
|
||||
})
|
||||
},
|
||||
|
||||
onClearSearch() {
|
||||
this.setData({
|
||||
searchText: '',
|
||||
showSearchResult: false,
|
||||
searchResults: []
|
||||
})
|
||||
},
|
||||
|
||||
getLeixingName(leixingId) {
|
||||
const leixingList = this.data.shangpinleixing
|
||||
for (const item of leixingList) {
|
||||
if (item.id === leixingId) {
|
||||
return item.jieshao
|
||||
}
|
||||
}
|
||||
return ''
|
||||
},
|
||||
|
||||
getZhuanquName(zhuanquId) {
|
||||
const zhuanquList = this.data.shangpinzhuanqu
|
||||
for (const item of zhuanquList) {
|
||||
if (item.id === zhuanquId) {
|
||||
return item.mingzi
|
||||
}
|
||||
}
|
||||
return ''
|
||||
},
|
||||
|
||||
goToDetail(e) {
|
||||
const shangpinId = e.currentTarget.dataset.id
|
||||
if (!shangpinId) return
|
||||
wx.navigateTo({
|
||||
url: `/pages/product-detail/product-detail?id=${shangpinId}`
|
||||
})
|
||||
},
|
||||
|
||||
onRefresh() {
|
||||
wx.showLoading({
|
||||
title: '刷新中...',
|
||||
mask: true
|
||||
})
|
||||
app.globalData.shangpinleixing = []
|
||||
app.globalData.shangpinzhuanqu = []
|
||||
app.globalData.shangpinliebiao = []
|
||||
this.loadAllShangpinData()
|
||||
setTimeout(() => {
|
||||
wx.hideLoading()
|
||||
wx.showToast({
|
||||
title: '刷新成功',
|
||||
icon: 'success',
|
||||
duration: 1500
|
||||
})
|
||||
}, 1000)
|
||||
},
|
||||
|
||||
onShareAppMessage() {
|
||||
return {
|
||||
title: '阿龙电竞 - 商品分类',
|
||||
path: '/pages/category/category'
|
||||
}
|
||||
}
|
||||
})
|
||||
6
pages/category/category.json
Normal file
6
pages/category/category.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"usingComponents": {
|
||||
"global-notification": "/components/global-notification/global-notification",
|
||||
"custom-tab-bar": "/custom-tab-bar/index"
|
||||
}
|
||||
}
|
||||
217
pages/category/category.wxml
Normal file
217
pages/category/category.wxml
Normal file
@@ -0,0 +1,217 @@
|
||||
<!-- pages/category/category.wxml -->
|
||||
<view class="fenlei-page">
|
||||
<!-- 1. 毛玻璃搜索框区域(固定) -->
|
||||
<view class="search-container">
|
||||
<view class="search-box search-box--glass">
|
||||
<image src="/images/sousuo.png" class="search-icon" />
|
||||
<input
|
||||
type="text"
|
||||
class="search-input"
|
||||
placeholder="输入商品名称搜索"
|
||||
placeholder-class="search-placeholder"
|
||||
value="{{searchText}}"
|
||||
bindinput="onSearchInput"
|
||||
bindconfirm="onSearchConfirm"
|
||||
confirm-type="search"
|
||||
/>
|
||||
<!-- 清空按钮 -->
|
||||
<view wx:if="{{searchText}}" class="search-clear" bindtap="onClearSearch">
|
||||
<image src="/images/clear.png" class="clear-icon" />
|
||||
</view>
|
||||
<!-- 搜索按钮 -->
|
||||
<view class="search-btn btn btn-sm btn-sm--gold" bindtap="onSearchTap">
|
||||
<text class="search-btn-text">搜索</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 2. 商品类型选择区域 -->
|
||||
<view class="leixing-container" wx:if="{{!showSearchResult}}">
|
||||
<scroll-view
|
||||
class="leixing-scroll"
|
||||
scroll-x
|
||||
scroll-with-animation
|
||||
show-scrollbar="{{false}}"
|
||||
>
|
||||
<view class="leixing-list">
|
||||
<block wx:for="{{shangpinleixing}}" wx:key="id" wx:for-index="idx">
|
||||
<view
|
||||
class="leixing-item {{selectedLeixingId === item.id ? 'leixing-active' : ''}}"
|
||||
bindtap="selectLeixing"
|
||||
data-id="{{item.id}}"
|
||||
data-index="{{idx}}"
|
||||
>
|
||||
<view class="leixing-image-box">
|
||||
<image
|
||||
src="{{ossImageUrl}}{{item.tupian_url}}"
|
||||
mode="aspectFill"
|
||||
class="leixing-image"
|
||||
/>
|
||||
<view class="leixing-glow {{selectedLeixingId === item.id ? 'leixing-glow-active' : ''}}"></view>
|
||||
</view>
|
||||
<text class="leixing-text">{{item.jieshao}}</text>
|
||||
<view class="leixing-active-bar {{selectedLeixingId === item.id ? 'leixing-active-bar-show' : ''}}"></view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
|
||||
<!-- 3. 左右分栏布局 -->
|
||||
<view class="main-container" wx:if="{{!showSearchResult}}">
|
||||
<!-- 左边:商品专区列表 -->
|
||||
<scroll-view
|
||||
class="zhuanqu-left"
|
||||
scroll-y
|
||||
enhanced="{{true}}"
|
||||
show-scrollbar="{{false}}"
|
||||
scroll-into-view="{{'zhuanqu-' + selectedZhuanquId}}"
|
||||
>
|
||||
<view class="zhuanqu-list">
|
||||
<block wx:for="{{filteredZhuanquList}}" wx:key="id">
|
||||
<view
|
||||
id="zhuanqu-{{item.id}}"
|
||||
class="zhuanqu-item {{selectedZhuanquId === item.id ? 'zhuanqu-active' : ''}}"
|
||||
bindtap="selectZhuanqu"
|
||||
data-id="{{item.id}}"
|
||||
>
|
||||
<view class="zhuanqu-item-content">
|
||||
<text class="zhuanqu-name">{{item.mingzi}}</text>
|
||||
<text class="zhuanqu-count">({{zhuanquGoodsCount[item.id] || 0}})</text>
|
||||
</view>
|
||||
<view class="zhuanqu-active-indicator {{selectedZhuanquId === item.id ? 'zhuanqu-indicator-glow' : ''}}"></view>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<view wx:if="{{filteredZhuanquList.length === 0}}" class="zhuanqu-empty">
|
||||
<image src="/images/empty-box.png" class="zhuanqu-empty-icon" />
|
||||
<text class="zhuanqu-empty-text">暂无专区</text>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<!-- 右边:商品列表 -->
|
||||
<scroll-view
|
||||
class="shangpin-right"
|
||||
scroll-y
|
||||
enhanced="{{true}}"
|
||||
show-scrollbar="{{false}}"
|
||||
>
|
||||
<view class="shangpin-list">
|
||||
<block wx:for="{{filteredShangpinList}}" wx:key="id">
|
||||
<view
|
||||
class="shangpin-item"
|
||||
bindtap="goToDetail"
|
||||
data-id="{{item.id}}"
|
||||
>
|
||||
<view class="shangpin-image-box">
|
||||
<image
|
||||
src="{{ossImageUrl}}{{item.tupian_url}}"
|
||||
mode="aspectFill"
|
||||
class="shangpin-image"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<view class="shangpin-info">
|
||||
<view class="shangpin-title">
|
||||
<text class="shangpin-title-text">{{item.biaoqian}}</text>
|
||||
</view>
|
||||
|
||||
<view class="shangpin-footer">
|
||||
<view class="shangpin-price">
|
||||
<text class="price-icon">¥</text>
|
||||
<text class="price-integer">{{item.priceInteger}}</text>
|
||||
<text class="price-decimal">.{{item.priceDecimal}}</text>
|
||||
</view>
|
||||
<view class="detail-btn">
|
||||
<text class="detail-btn-text">了解详情</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="item-divider" wx:if="{{index !== filteredShangpinList.length - 1}}"></view>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<view wx:if="{{filteredShangpinList.length === 0 && !isLoading}}" class="shangpin-empty">
|
||||
<image src="/images/empty-goods.png" class="shangpin-empty-icon" />
|
||||
<text class="shangpin-empty-text">该专区暂无商品</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="load-more" wx:if="{{filteredShangpinList.length > 0}}">
|
||||
<text class="load-more-text">— 已加载全部商品 —</text>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
|
||||
<!-- 搜索结果弹窗 -->
|
||||
<view class="search-results-container" wx:if="{{showSearchResult}}">
|
||||
<view class="search-mask" bindtap="onClearSearch"></view>
|
||||
<view class="search-results-content">
|
||||
<view class="search-results-header">
|
||||
<view class="search-header-left">
|
||||
<text class="search-results-title">搜索结果</text>
|
||||
<text class="search-results-count">({{searchResults.length}}个)</text>
|
||||
</view>
|
||||
<view class="search-close" bindtap="onClearSearch">
|
||||
<image src="/images/close.png" class="close-icon" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<scroll-view class="search-results-list" scroll-y>
|
||||
<block wx:for="{{searchResults}}" wx:key="id">
|
||||
<view class="search-result-item" bindtap="goToDetail" data-id="{{item.id}}">
|
||||
<view class="search-result-left">
|
||||
<image
|
||||
src="{{ossImageUrl}}{{item.tupian_url}}"
|
||||
mode="aspectFill"
|
||||
class="search-result-image"
|
||||
/>
|
||||
</view>
|
||||
<view class="search-result-right">
|
||||
<view class="search-result-title">{{item.biaoqian}}</view>
|
||||
<view class="search-result-info">
|
||||
<text class="search-result-category">{{item.leixing_name}}</text>
|
||||
<text class="search-result-separator">·</text>
|
||||
<text class="search-result-zhuanqu">{{item.zhuanqu_name}}</text>
|
||||
</view>
|
||||
<view class="search-result-price">
|
||||
<text class="price-icon">¥</text>
|
||||
<text class="price-integer">{{item.priceInteger}}</text>
|
||||
<text class="price-decimal">.{{item.priceDecimal}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<view wx:if="{{searchResults.length === 0 && !isSearching}}" class="search-empty">
|
||||
<image src="/images/search-empty.png" class="search-empty-icon" />
|
||||
<text class="search-empty-text">未找到相关商品</text>
|
||||
</view>
|
||||
|
||||
<view wx:if="{{isSearching}}" class="search-loading">
|
||||
<view class="search-spinner">
|
||||
<view class="spinner-circle"></view>
|
||||
</view>
|
||||
<text class="search-loading-text">搜索中...</text>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 全局加载状态 -->
|
||||
<view class="loading-toast loading-mask loading-mask--dark" wx:if="{{isLoading}}">
|
||||
<view class="loading-content">
|
||||
<view class="loading-spinner">
|
||||
<view class="spinner-ring"></view>
|
||||
<view class="spinner-dot"></view>
|
||||
</view>
|
||||
<text class="loading-text">加载中...</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 底部自定义TabBar -->
|
||||
<custom-tab-bar />
|
||||
<global-notification id="global-notification" />
|
||||
1175
pages/category/category.wxss
Normal file
1175
pages/category/category.wxss
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user