consumer模块完成度95%,能编译在安卓端运行,在解决数据获取和页面布局问题
This commit is contained in:
@@ -51,13 +51,13 @@
|
||||
<!-- 主内容区域 -->
|
||||
<scroll-view
|
||||
v-else
|
||||
scroll-y
|
||||
direction="vertical"
|
||||
class="main-content"
|
||||
:style="{ height: scrollHeight + 'px' }"
|
||||
@scrolltolower="loadMore"
|
||||
>
|
||||
<!-- 初始状态(无搜索词) -->
|
||||
<view v-if="!searchKeyword && !showResults">
|
||||
<view v-if="searchKeyword == '' && showResults == false">
|
||||
<!-- 搜索历史 -->
|
||||
<view v-if="searchHistory.length > 0" class="search-history">
|
||||
<view class="section-header">
|
||||
@@ -92,12 +92,12 @@
|
||||
v-for="(item, index) in hotSearchList"
|
||||
:key="index"
|
||||
class="hot-tag"
|
||||
:class="{ 'hot': item.hot }"
|
||||
:class="item.hot == true ? 'hot' : ''"
|
||||
@click="searchFromHot(item.keyword)"
|
||||
>
|
||||
<text class="hot-rank" :class="{ 'top-three': index < 3 }">{{ index + 1 }}</text>
|
||||
<text class="hot-rank" :class="index < 3 ? 'top-three' : ''">{{ index + 1 }}</text>
|
||||
<text class="hot-text">{{ item.keyword }}</text>
|
||||
<text v-if="item.hot" class="hot-icon">🔥</text>
|
||||
<text v-if="item.hot == true" class="hot-icon">🔥</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -136,7 +136,7 @@
|
||||
</view>
|
||||
|
||||
<!-- 搜索建议 -->
|
||||
<view v-if="searchKeyword && !showResults" class="search-suggestions">
|
||||
<view v-if="searchKeyword != '' && showResults == false" class="search-suggestions">
|
||||
<view class="suggestions-list">
|
||||
<view
|
||||
v-for="(suggestion, index) in searchSuggestions"
|
||||
@@ -157,7 +157,7 @@
|
||||
<view class="section-top">
|
||||
<text class="result-title-sm">相关店铺</text>
|
||||
</view>
|
||||
<scroll-view scroll-x class="shop-list-scroll">
|
||||
<scroll-view direction="horizontal" class="shop-list-scroll">
|
||||
<view class="shop-list-row">
|
||||
<view
|
||||
v-for="shop in searchShopResults"
|
||||
@@ -267,110 +267,47 @@ const autoFocus = ref(true)
|
||||
const activeSort = ref('default') // 当前排序方式: default, sales, price
|
||||
const priceSortAsc = ref(false) // 价格排序是否为升序
|
||||
|
||||
// 数据定义
|
||||
const searchHistory = ref<string[]>([])
|
||||
const hotSearchList = ref<any[]>([])
|
||||
const guessList = ref<any[]>([])
|
||||
const allGuessItems = ref<any[]>([]) // 缓存所有猜你喜欢商品
|
||||
const searchResults = ref<any[]>([])
|
||||
const searchShopResults = ref<any[]>([]) // 搜索到的店铺
|
||||
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
initPage()
|
||||
})
|
||||
|
||||
|
||||
const initPage = () => {
|
||||
try {
|
||||
const systemInfo = uni.getSystemInfoSync()
|
||||
statusBarHeight.value = systemInfo.statusBarHeight ?? 0
|
||||
const windowHeight = systemInfo.windowHeight
|
||||
// 减去头部高度 (约60px + statusBarHeight)
|
||||
scrollHeight.value = windowHeight - (60 + statusBarHeight.value)
|
||||
|
||||
loadData()
|
||||
|
||||
// 检查页面参数
|
||||
const pages = getCurrentPages()
|
||||
if (pages.length > 0) {
|
||||
const currentPage = pages[pages.length - 1]
|
||||
// @ts-ignore
|
||||
const options = currentPage.options
|
||||
if (options && options['keyword']) {
|
||||
const keyword = decodeURIComponent(options['keyword'])
|
||||
searchKeyword.value = keyword
|
||||
|
||||
if (options['type'] === 'family' || options['type'] === 'brand') {
|
||||
// 如果是家庭常备药或品牌类型,直接添加到历史并搜索
|
||||
if (options['type'] === 'family') {
|
||||
addToHistory(keyword)
|
||||
}
|
||||
// 立即显示结果区域并设置为加载中
|
||||
showResults.value = true
|
||||
loading.value = true
|
||||
// 确保searchResults不为空数组导致闪烁(虽然loading=true已经拦截了empty-result,但双重保险)
|
||||
// 此时不要置空searchResults,或者给一个初始值
|
||||
|
||||
// 直接调用搜索,移除setTimeout,防止中间状态
|
||||
performSearch()
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('初始化失败', e)
|
||||
isError.value = true
|
||||
}
|
||||
type HotSearchItemType = {
|
||||
keyword: string
|
||||
hot: boolean
|
||||
}
|
||||
|
||||
// 加载基础数据
|
||||
const loadData = async () => {
|
||||
isError.value = false
|
||||
|
||||
try {
|
||||
loadSearchHistory()
|
||||
// 获取热门商品作为热门搜索推荐和猜你喜欢
|
||||
// 获取更多数据以便"换一批"
|
||||
const hotProducts = await supabaseService.getHotProducts(30)
|
||||
|
||||
hotSearchList.value = hotProducts.slice(0, 10).map((p: any) => ({
|
||||
keyword: p.name,
|
||||
hot: true
|
||||
}))
|
||||
|
||||
allGuessItems.value = hotProducts.map((p: any) => ({
|
||||
id: p.id,
|
||||
name: p.name,
|
||||
price: p.base_price,
|
||||
image: p.main_image_url ?? '/static/default.jpg',
|
||||
sales: typeof p.sale_count === 'number' ? p.sale_count : 0
|
||||
}))
|
||||
|
||||
// 初始显示随机6个
|
||||
refreshGuessListItems()
|
||||
|
||||
} catch (e) {
|
||||
console.error('Load data failed', e)
|
||||
isError.value = true
|
||||
}
|
||||
type GuessItemType = {
|
||||
id: string
|
||||
name: string
|
||||
price: number
|
||||
image: string
|
||||
sales: number
|
||||
}
|
||||
|
||||
// 点击重试
|
||||
const retryLoad = () => {
|
||||
uni.showLoading({ title: '重新加载中' })
|
||||
setTimeout(() => {
|
||||
uni.hideLoading()
|
||||
loadData()
|
||||
}, 1000)
|
||||
type SearchResultType = {
|
||||
id: string
|
||||
name: string
|
||||
image: string
|
||||
price: number
|
||||
specification: string
|
||||
tag: string
|
||||
sales: number
|
||||
}
|
||||
|
||||
// 历史记录管理
|
||||
type ShopResultType = {
|
||||
id: string
|
||||
name: string
|
||||
logo: string
|
||||
productCount: number
|
||||
}
|
||||
|
||||
const searchHistory = ref<Array<string>>([])
|
||||
const hotSearchList = ref<Array<HotSearchItemType>>([])
|
||||
const guessList = ref<Array<GuessItemType>>([])
|
||||
const allGuessItems = ref<Array<GuessItemType>>([])
|
||||
const searchResults = ref<Array<SearchResultType>>([])
|
||||
const searchShopResults = ref<Array<ShopResultType>>([])
|
||||
|
||||
const loadSearchHistory = () => {
|
||||
const history = uni.getStorageSync('searchHistory')
|
||||
if (history) {
|
||||
if (history != null) {
|
||||
try {
|
||||
// 确保是数组
|
||||
const parsed = JSON.parse(history as string)
|
||||
if (Array.isArray(parsed)) {
|
||||
searchHistory.value = parsed as string[]
|
||||
@@ -414,13 +351,258 @@ const deleteHistoryItem = (index: number) => {
|
||||
saveSearchHistory()
|
||||
}
|
||||
|
||||
// 搜索建议 - 改为实时获取
|
||||
const searchSuggestions = ref<string[]>([])
|
||||
let suggestTimer = 0
|
||||
const refreshGuessListItems = () => {
|
||||
if (allGuessItems.value.length > 0) {
|
||||
const arr: Array<GuessItemType> = []
|
||||
for (let i: number = 0; i < allGuessItems.value.length; i++) {
|
||||
arr.push(allGuessItems.value[i])
|
||||
}
|
||||
for (let i: number = arr.length - 1; i > 0; i--) {
|
||||
const j = Math.floor(Math.random() * (i + 1))
|
||||
const temp = arr[i]
|
||||
arr[i] = arr[j]
|
||||
arr[j] = temp
|
||||
}
|
||||
const result: Array<GuessItemType> = []
|
||||
const limit = arr.length < 6 ? arr.length : 6
|
||||
for (let i: number = 0; i < limit; i++) {
|
||||
result.push(arr[i])
|
||||
}
|
||||
guessList.value = result
|
||||
}
|
||||
}
|
||||
|
||||
const loadData = async (): Promise<void> => {
|
||||
isError.value = false
|
||||
|
||||
try {
|
||||
loadSearchHistory()
|
||||
const hotProducts = await supabaseService.getHotProducts(30)
|
||||
|
||||
const hotList: Array<HotSearchItemType> = []
|
||||
const limit1 = hotProducts.length < 10 ? hotProducts.length : 10
|
||||
for (let i: number = 0; i < limit1; i++) {
|
||||
const p = hotProducts[i] as UTSJSONObject
|
||||
const item: HotSearchItemType = {
|
||||
keyword: p.getString('name') ?? '',
|
||||
hot: true
|
||||
}
|
||||
hotList.push(item)
|
||||
}
|
||||
hotSearchList.value = hotList
|
||||
|
||||
const allItems: Array<GuessItemType> = []
|
||||
for (let i: number = 0; i < hotProducts.length; i++) {
|
||||
const p = hotProducts[i] as UTSJSONObject
|
||||
const saleCount = p.getNumber('sale_count')
|
||||
const item: GuessItemType = {
|
||||
id: p.getString('id') ?? '',
|
||||
name: p.getString('name') ?? '',
|
||||
price: p.getNumber('base_price') ?? 0,
|
||||
image: p.getString('main_image_url') ?? '/static/default.jpg',
|
||||
sales: saleCount != null ? saleCount : 0
|
||||
}
|
||||
allItems.push(item)
|
||||
}
|
||||
allGuessItems.value = allItems
|
||||
|
||||
refreshGuessListItems()
|
||||
|
||||
} catch (e) {
|
||||
console.error('Load data failed', e)
|
||||
isError.value = true
|
||||
}
|
||||
}
|
||||
|
||||
const retryLoad = () => {
|
||||
uni.showLoading({ title: '重新加载中' })
|
||||
setTimeout(() => {
|
||||
uni.hideLoading()
|
||||
loadData()
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
const searchSuggestions = ref<Array<string>>([])
|
||||
let suggestTimer: number = 0
|
||||
|
||||
const fetchSuggestions = async (kw: string): Promise<void> => {
|
||||
if (kw == '' || showResults.value) return
|
||||
|
||||
try {
|
||||
const res = await supabaseService.searchProducts(kw.trim(), 1, 5)
|
||||
if (res.data != null && res.data.length > 0) {
|
||||
const names: Array<string> = []
|
||||
for (let i: number = 0; i < res.data.length; i++) {
|
||||
const p = res.data[i]
|
||||
let name = ''
|
||||
if (p instanceof UTSJSONObject) {
|
||||
name = p.getString('name') ?? ''
|
||||
} else {
|
||||
const pObj = p as UTSJSONObject
|
||||
name = pObj.getString('name') ?? ''
|
||||
}
|
||||
let found = false
|
||||
for (let j: number = 0; j < names.length; j++) {
|
||||
if (names[j] === name) {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (found === false && name !== '') {
|
||||
names.push(name)
|
||||
}
|
||||
}
|
||||
searchSuggestions.value = names
|
||||
} else {
|
||||
searchSuggestions.value = []
|
||||
}
|
||||
} catch(e) {
|
||||
searchSuggestions.value = []
|
||||
}
|
||||
}
|
||||
|
||||
const currentPage = ref<number>(1)
|
||||
|
||||
const performSearch = async (): Promise<void> => {
|
||||
showResults.value = true
|
||||
loading.value = true
|
||||
currentPage.value = 1
|
||||
|
||||
const keyword = searchKeyword.value.trim()
|
||||
if (keyword == '') {
|
||||
loading.value = false
|
||||
return
|
||||
}
|
||||
|
||||
let sortBy = 'sales'
|
||||
let ascending = false
|
||||
if (activeSort.value === 'price') {
|
||||
sortBy = 'price'
|
||||
ascending = priceSortAsc.value
|
||||
} else if (activeSort.value === 'default') {
|
||||
sortBy = 'default'
|
||||
}
|
||||
|
||||
try {
|
||||
const prodResp = await supabaseService.searchProducts(keyword, currentPage.value, 20, sortBy, ascending)
|
||||
|
||||
let shopRespData: Array<any> = []
|
||||
if (currentPage.value === 1 && activeSort.value === 'default') {
|
||||
const shopResp = await supabaseService.searchShops(keyword)
|
||||
if (shopResp.data != null) {
|
||||
const rawData = shopResp.data
|
||||
for (let i: number = 0; i < rawData.length; i++) {
|
||||
shopRespData.push(rawData[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (shopRespData.length > 0) {
|
||||
const shopList: Array<ShopResultType> = []
|
||||
for (let i: number = 0; i < shopRespData.length; i++) {
|
||||
const s = shopRespData[i] as UTSJSONObject
|
||||
const shopItem: ShopResultType = {
|
||||
id: s.getString('id') ?? '',
|
||||
name: s.getString('shop_name') ?? '',
|
||||
logo: s.getString('shop_logo') ?? '/static/shop_logo_default.png',
|
||||
productCount: s.getNumber('product_count') ?? 0
|
||||
}
|
||||
shopList.push(shopItem)
|
||||
}
|
||||
searchShopResults.value = shopList
|
||||
} else {
|
||||
searchShopResults.value = []
|
||||
}
|
||||
|
||||
const prodData = prodResp.data != null ? prodResp.data : []
|
||||
const resultList: Array<SearchResultType> = []
|
||||
for (let i: number = 0; i < prodData.length; i++) {
|
||||
const p = prodData[i] as UTSJSONObject
|
||||
let tag = ''
|
||||
const tagsRaw = p.get('tags')
|
||||
if (tagsRaw != null) {
|
||||
try {
|
||||
const tagsStr = p.getString('tags')
|
||||
if (tagsStr != null) {
|
||||
const tags = JSON.parse(tagsStr)
|
||||
if (Array.isArray(tags) && tags.length > 0) {
|
||||
const firstTag = tags[0]
|
||||
tag = firstTag != null ? (firstTag as string) : ''
|
||||
}
|
||||
}
|
||||
} catch(e) {}
|
||||
}
|
||||
|
||||
const searchItem: SearchResultType = {
|
||||
id: p.getString('id') ?? '',
|
||||
name: p.getString('name') ?? '',
|
||||
image: p.getString('main_image_url') ?? '/static/default.jpg',
|
||||
price: p.getNumber('base_price') ?? 0,
|
||||
specification: p.getString('specification') ?? '标准规格',
|
||||
tag: tag,
|
||||
sales: p.getNumber('sale_count') ?? 0
|
||||
}
|
||||
resultList.push(searchItem)
|
||||
}
|
||||
searchResults.value = resultList
|
||||
|
||||
hasMore.value = prodResp.hasmore
|
||||
} catch(e) {
|
||||
console.error('Search failed', e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const initPage = () => {
|
||||
try {
|
||||
const systemInfo = uni.getSystemInfoSync()
|
||||
statusBarHeight.value = systemInfo.statusBarHeight ?? 0
|
||||
const windowHeight = systemInfo.windowHeight
|
||||
scrollHeight.value = windowHeight - (60 + statusBarHeight.value)
|
||||
|
||||
loadData()
|
||||
|
||||
const pages = getCurrentPages()
|
||||
if (pages.length > 0) {
|
||||
const currentPageObj = pages[pages.length - 1]
|
||||
// @ts-ignore
|
||||
const options = currentPageObj.options
|
||||
if (options != null) {
|
||||
const optObj = options as UTSJSONObject
|
||||
const kwRaw = optObj.getString('keyword')
|
||||
if (kwRaw != null && kwRaw !== '') {
|
||||
const decoded = decodeURIComponent(kwRaw)
|
||||
const keyword = decoded != null ? decoded : kwRaw
|
||||
searchKeyword.value = keyword
|
||||
|
||||
const typeVal = optObj.getString('type')
|
||||
if (typeVal === 'family' || typeVal === 'brand') {
|
||||
if (typeVal === 'family') {
|
||||
addToHistory(keyword)
|
||||
}
|
||||
showResults.value = true
|
||||
loading.value = true
|
||||
performSearch()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('初始化失败', e)
|
||||
isError.value = true
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
initPage()
|
||||
})
|
||||
|
||||
// 搜索逻辑
|
||||
const onInput = (e: any) => {
|
||||
const val = e.detail.value
|
||||
const eObj = e as UTSJSONObject
|
||||
const detailRaw = eObj.get('detail')
|
||||
const detail = detailRaw != null ? (detailRaw as UTSJSONObject) : (new UTSJSONObject())
|
||||
const val = detail.getString('value') ?? ''
|
||||
searchKeyword.value = val
|
||||
if (val == '') {
|
||||
showResults.value = false
|
||||
@@ -428,37 +610,12 @@ const onInput = (e: any) => {
|
||||
return
|
||||
}
|
||||
|
||||
// Debounce suggestion search
|
||||
if (suggestTimer > 0) clearTimeout(suggestTimer)
|
||||
suggestTimer = setTimeout(() => {
|
||||
fetchSuggestions(val)
|
||||
}, 300)
|
||||
}
|
||||
|
||||
const fetchSuggestions = async (kw: string) => {
|
||||
if (kw == '' || showResults.value) return
|
||||
|
||||
// 简单搜索前5个相关商品作为建议
|
||||
try {
|
||||
const res = await supabaseService.searchProducts(kw.trim(), 1, 5)
|
||||
if (Array.isArray(res.data) && res.data.length > 0) {
|
||||
// 去重
|
||||
const names = res.data.map((p:any) :string => {
|
||||
if(p instanceof UTSJSONObject){
|
||||
return p.getString('name') ?? ''
|
||||
}
|
||||
return p['name'] as string
|
||||
})
|
||||
// @ts-ignore
|
||||
searchSuggestions.value = Array.from(new Set(names))
|
||||
} else {
|
||||
searchSuggestions.value = []
|
||||
}
|
||||
} catch(e) {
|
||||
searchSuggestions.value = []
|
||||
}
|
||||
}
|
||||
|
||||
const clearSearch = () => {
|
||||
searchKeyword.value = ''
|
||||
showResults.value = false
|
||||
@@ -487,84 +644,6 @@ const selectSuggestion = (suggestion: string) => {
|
||||
performSearch()
|
||||
}
|
||||
|
||||
const currentPage = ref(1)
|
||||
|
||||
const performSearch = async () => {
|
||||
// 再次强制设置状态,确保万无一失
|
||||
showResults.value = true
|
||||
loading.value = true
|
||||
// 重置页码
|
||||
currentPage.value = 1
|
||||
|
||||
// 使用 Supabase 搜索真实数据
|
||||
const keyword = searchKeyword.value.trim()
|
||||
if (keyword == '') {
|
||||
loading.value = false
|
||||
return
|
||||
}
|
||||
|
||||
// 确定排序方式
|
||||
let sortBy = 'sales'
|
||||
let ascending = false
|
||||
if (activeSort.value === 'price') {
|
||||
sortBy = 'price'
|
||||
ascending = priceSortAsc.value
|
||||
} else if (activeSort.value === 'default') {
|
||||
sortBy = 'default'
|
||||
}
|
||||
|
||||
try {
|
||||
// 并行请求:商品搜索 + 店铺搜索
|
||||
const [prodResp, shopResp] = await Promise.all([
|
||||
supabaseService.searchProducts(keyword, currentPage.value, 20, sortBy, ascending),
|
||||
// 只有第一页搜索且非价格排序时搜索店铺,避免重复和无关搜索
|
||||
currentPage.value === 1 && activeSort.value === 'default'
|
||||
? supabaseService.searchShops(keyword)
|
||||
: Promise.resolve({ data: [], total: 0, page: 1, limit: 0, hasmore: false })
|
||||
])
|
||||
|
||||
// 处理店铺结果
|
||||
if (shopResp.data.length > 0) {
|
||||
searchShopResults.value = shopResp.data.map((s: any) => ({
|
||||
id: s.id,
|
||||
name: s.shop_name,
|
||||
logo: s.shop_logo ?? '/static/shop_logo_default.png',
|
||||
productCount: s.product_count ?? 0
|
||||
}))
|
||||
} else {
|
||||
searchShopResults.value = []
|
||||
}
|
||||
|
||||
// 处理商品结果
|
||||
searchResults.value = prodResp.data.map((p: any) => {
|
||||
let tag = ''
|
||||
if (p.tags) {
|
||||
try {
|
||||
const tags = (typeof p.tags === 'string') ? JSON.parse(p.tags) : p.tags
|
||||
if (Array.isArray(tags) && tags.length > 0) tag = String(tags[0])
|
||||
} catch(e) {}
|
||||
}
|
||||
|
||||
return {
|
||||
id: p.id,
|
||||
name: p.name,
|
||||
image: p.main_image_url ?? '/static/default.jpg',
|
||||
price: p.base_price,
|
||||
specification: p.specification ?? '标准规格',
|
||||
tag: tag,
|
||||
sales: p.sale_count ?? 0
|
||||
}
|
||||
})
|
||||
|
||||
hasMore.value = prodResp.hasmore
|
||||
} catch(e) {
|
||||
console.error('Search failed', e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 切换排序
|
||||
const switchSort = (type: string) => {
|
||||
if (type === 'price') {
|
||||
if (activeSort.value === 'price') {
|
||||
@@ -580,15 +659,13 @@ const switchSort = (type: string) => {
|
||||
performSearch()
|
||||
}
|
||||
|
||||
const loadMore = async () => {
|
||||
if (loading.value || !hasMore.value || searchKeyword.value.trim() == '') return
|
||||
const loadMore = async (): Promise<void> => {
|
||||
if (loading.value || hasMore.value == false || searchKeyword.value.trim() == '') return
|
||||
loading.value = true
|
||||
|
||||
// 增加页码
|
||||
currentPage.value++
|
||||
|
||||
const keyword = searchKeyword.value.trim()
|
||||
// 确定排序方式
|
||||
let sortBy = 'sales'
|
||||
let ascending = false
|
||||
if (activeSort.value === 'price') {
|
||||
@@ -600,26 +677,35 @@ const loadMore = async () => {
|
||||
|
||||
try {
|
||||
const response = await supabaseService.searchProducts(keyword, currentPage.value, 20, sortBy, ascending)
|
||||
const newItems = response.data.map((p: any) => {
|
||||
const respData = response.data != null ? response.data : []
|
||||
for (let i: number = 0; i < respData.length; i++) {
|
||||
const p = respData[i] as UTSJSONObject
|
||||
let tag = ''
|
||||
if (p.tags) {
|
||||
const tagsRaw = p.get('tags')
|
||||
if (tagsRaw != null) {
|
||||
try {
|
||||
const tags = (typeof p.tags === 'string') ? JSON.parse(p.tags) : p.tags
|
||||
if (Array.isArray(tags) && tags.length > 0) tag = String(tags[0])
|
||||
const tagsStr = p.getString('tags')
|
||||
if (tagsStr != null) {
|
||||
const tags = JSON.parse(tagsStr)
|
||||
if (Array.isArray(tags) && tags.length > 0) {
|
||||
const firstTag = tags[0]
|
||||
tag = firstTag != null ? (firstTag as string) : ''
|
||||
}
|
||||
}
|
||||
} catch(e) {}
|
||||
}
|
||||
|
||||
return {
|
||||
id: p.id,
|
||||
name: p.name,
|
||||
image: p.main_image_url ?? '/static/default.jpg',
|
||||
price: p.base_price,
|
||||
specification: p.specification ?? '标准规格',
|
||||
const searchItem: SearchResultType = {
|
||||
id: p.getString('id') ?? '',
|
||||
name: p.getString('name') ?? '',
|
||||
image: p.getString('main_image_url') ?? '/static/default.jpg',
|
||||
price: p.getNumber('base_price') ?? 0,
|
||||
specification: p.getString('specification') ?? '标准规格',
|
||||
tag: tag,
|
||||
sales: p.sale_count ?? 0
|
||||
sales: p.getNumber('sale_count') ?? 0
|
||||
}
|
||||
})
|
||||
searchResults.value.push(...newItems)
|
||||
searchResults.value.push(searchItem)
|
||||
}
|
||||
hasMore.value = response.hasmore
|
||||
} catch(e) {
|
||||
console.error('Load more failed', e)
|
||||
@@ -637,29 +723,22 @@ const refreshGuessList = () => {
|
||||
}, 500)
|
||||
}
|
||||
|
||||
const refreshGuessListItems = () => {
|
||||
if (allGuessItems.value.length > 0) {
|
||||
// 简单的随机乱序并取前6个
|
||||
const shuffled = [...allGuessItems.value].sort(() => Math.random() - 0.5)
|
||||
guessList.value = shuffled.slice(0, 6)
|
||||
}
|
||||
}
|
||||
|
||||
const viewProductDetail = (item: any) => {
|
||||
// 跳转详情页逻辑 - 传递必要的参数作为预加载/fallback
|
||||
const viewProductDetail = (item: SearchResultType | GuessItemType) => {
|
||||
const id = (item as GuessItemType).id
|
||||
const price = (item as GuessItemType).price
|
||||
const name = (item as GuessItemType).name
|
||||
uni.navigateTo({
|
||||
url: `/pages/mall/consumer/product-detail?productId=${item.id}&price=${item.price}&name=${encodeURIComponent(item.name)}`
|
||||
url: `/pages/mall/consumer/product-detail?productId=${id}&price=${price}&name=${encodeURIComponent(name)}`
|
||||
})
|
||||
}
|
||||
|
||||
const viewShopDetail = (shop: any) => {
|
||||
const viewShopDetail = (shop: ShopResultType) => {
|
||||
uni.navigateTo({
|
||||
url: `/pages/mall/consumer/shop-detail?id=${shop.id}`
|
||||
})
|
||||
}
|
||||
|
||||
// 添加到购物车 - 搜索列表无法选择规格,跳转详情页
|
||||
const addToCart = (product: any) => {
|
||||
const addToCart = (product: SearchResultType | GuessItemType) => {
|
||||
uni.showToast({ title: '请选择规格', icon: 'none' })
|
||||
setTimeout(() => {
|
||||
viewProductDetail(product)
|
||||
|
||||
Reference in New Issue
Block a user