consumer模块完成度95%,安卓端大部分页面能正常获取数据,页面样式显示基本正常,逐渐完善;消费者端的积分、余额、评价、优惠券等小模块正在完善
This commit is contained in:
@@ -25,19 +25,24 @@
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 导航栏占位 - 修复:只使用44px高度,因为search-bar的paddingTop已处理statusBarHeight -->
|
||||
<view class="navbar-placeholder" :style="{ height: '44px' }"></view>
|
||||
<!-- 导航栏占位 - 需要包含statusBarHeight + 搜索框高度44px -->
|
||||
<view class="navbar-placeholder" :style="{ height: (statusBarHeight + 44) + 'px' }"></view>
|
||||
|
||||
<!-- 分类内容区 -->
|
||||
<view class="category-content">
|
||||
<!-- 左侧一级分类 -->
|
||||
<scroll-view scroll-y class="primary-category">
|
||||
<scroll-view
|
||||
:scroll-y="true"
|
||||
class="primary-category"
|
||||
:scroll-top="scrollTop"
|
||||
:scroll-with-animation="true"
|
||||
>
|
||||
<view
|
||||
v-for="item in primaryCategories"
|
||||
:key="item.id"
|
||||
:class="['primary-item', { active: activePrimary === item.id }]"
|
||||
:class="['primary-item', { active: isPrimaryActive(item.id) }]"
|
||||
@click="selectPrimaryCategory(item.id)"
|
||||
:style="{ backgroundColor: activePrimary === item.id ? item.color : 'transparent' }"
|
||||
:style="{ backgroundColor: getPrimaryItemBgColor(item) }"
|
||||
>
|
||||
<text class="primary-icon">{{ item.icon }}</text>
|
||||
<text class="primary-name">{{ item.name }}</text>
|
||||
@@ -46,7 +51,7 @@
|
||||
|
||||
<!-- 右侧商品列表 -->
|
||||
<scroll-view
|
||||
scroll-y
|
||||
:scroll-y="true"
|
||||
class="product-content"
|
||||
@scrolltolower="loadMore"
|
||||
:lower-threshold="50"
|
||||
@@ -57,6 +62,21 @@
|
||||
<text class="category-desc">{{ currentCategoryDesc }}</text>
|
||||
</view>
|
||||
|
||||
<!-- 二级分类 -->
|
||||
<view v-if="subCategories.length > 0" class="sub-category-section">
|
||||
<view class="sub-category-list">
|
||||
<view
|
||||
v-for="sub in subCategories"
|
||||
:key="sub.id"
|
||||
:class="['sub-category-item', { active: isSubActive(sub.id) }]"
|
||||
@click="selectSubCategory(sub.id)"
|
||||
>
|
||||
<text class="sub-category-icon">{{ sub.icon }}</text>
|
||||
<text class="sub-category-name">{{ sub.name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 商品网格 -->
|
||||
<view v-if="productList.length > 0" class="product-grid">
|
||||
<view
|
||||
@@ -98,6 +118,7 @@
|
||||
|
||||
<script setup lang="uts">
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { onLoad, onShow } from '@dcloudio/uni-app'
|
||||
import supabaseService from '@/utils/supabaseService.uts'
|
||||
import type { Product } from '@/utils/supabaseService.uts'
|
||||
|
||||
@@ -111,15 +132,20 @@ type LocalCategory = {
|
||||
|
||||
// 响应式数据
|
||||
const statusBarHeight = ref(0)
|
||||
const headerHeight = ref(44) // 默认头部高度
|
||||
const headerHeight = ref(44)
|
||||
const primaryCategories = ref<LocalCategory[]>([])
|
||||
const subCategories = ref<LocalCategory[]>([]) // 二级分类列表
|
||||
const productList = ref<Product[]>([])
|
||||
const activePrimary = ref<string>('')
|
||||
const activeSubCategory = ref<string>('') // 当前选中的二级分类
|
||||
const selectedParentId = ref<string>('') // 当前选中的一级分类ID(用于高亮显示)
|
||||
const cartCount = ref(3)
|
||||
const hasMore = ref(true)
|
||||
const hasLoadedFromParams = ref(false) // 标记是否已通过参数加载
|
||||
const hasLoadedFromParams = ref(false)
|
||||
const currentPage = ref(1)
|
||||
const loading = ref(false)
|
||||
const scrollTop = ref(0)
|
||||
const pendingCategoryId = ref('') // 待处理的分类ID(从其他页面跳转过来时暂存)
|
||||
|
||||
// 获取当前分类信息
|
||||
const currentCategoryName = ref('')
|
||||
@@ -147,7 +173,7 @@ async function loadProducts(): Promise<void> {
|
||||
page: currentPage.value
|
||||
})
|
||||
|
||||
if (currentPage.value === 1) {
|
||||
if (currentPage.value == 1) {
|
||||
productList.value = response.data
|
||||
} else {
|
||||
productList.value.push(...response.data)
|
||||
@@ -155,75 +181,303 @@ async function loadProducts(): Promise<void> {
|
||||
|
||||
hasMore.value = response.hasmore
|
||||
|
||||
// 更新当前分类信息
|
||||
const category = primaryCategories.value.find((cat: LocalCategory): boolean => cat.id === activePrimary.value)
|
||||
if (category != null) {
|
||||
currentCategoryName.value = category.name
|
||||
currentCategoryDesc.value = category.description
|
||||
// 更新当前分类信息 - 先在一级分类中查找,再在二级分类中查找
|
||||
let foundCat: LocalCategory | null = null
|
||||
for (let i = 0; i < primaryCategories.value.length; i++) {
|
||||
if (primaryCategories.value[i].id == activePrimary.value) {
|
||||
foundCat = primaryCategories.value[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
if (foundCat == null) {
|
||||
for (let i = 0; i < subCategories.value.length; i++) {
|
||||
if (subCategories.value[i].id == activePrimary.value) {
|
||||
foundCat = subCategories.value[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if (foundCat != null) {
|
||||
currentCategoryName.value = foundCat.name
|
||||
currentCategoryDesc.value = foundCat.description
|
||||
}
|
||||
|
||||
console.log('商品列表加载完成,当前总数量:', productList.value.length)
|
||||
} catch (error) {
|
||||
console.error('加载商品数据失败:', error)
|
||||
if (currentPage.value === 1) {
|
||||
if (currentPage.value == 1) {
|
||||
productList.value = []
|
||||
}
|
||||
} finally {
|
||||
loading.value = false
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 加载二级分类
|
||||
async function loadSubCategories(parentId: string): Promise<void> {
|
||||
console.log('加载二级分类,父级ID:', parentId)
|
||||
try {
|
||||
const subCats = await supabaseService.getSubCategories(parentId)
|
||||
console.log('获取到二级分类数量:', subCats.length)
|
||||
|
||||
const categories: LocalCategory[] = []
|
||||
for (let i = 0; i < subCats.length; i++) {
|
||||
const cat = subCats[i]
|
||||
categories.push({
|
||||
id: cat.id,
|
||||
name: cat.name,
|
||||
icon: cat.icon,
|
||||
description: cat.description,
|
||||
color: cat.color
|
||||
})
|
||||
}
|
||||
subCategories.value = categories
|
||||
} catch (e) {
|
||||
console.error('加载二级分类失败:', e)
|
||||
subCategories.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 判断一级分类是否选中
|
||||
function isPrimaryActive(categoryId: string): boolean {
|
||||
return selectedParentId.value == categoryId
|
||||
}
|
||||
|
||||
// 判断二级分类是否选中
|
||||
function isSubActive(subCategoryId: string): boolean {
|
||||
return activeSubCategory.value == subCategoryId || activePrimary.value == subCategoryId
|
||||
}
|
||||
|
||||
// 获取一级分类的背景色
|
||||
function getPrimaryItemBgColor(item: LocalCategory): string {
|
||||
if (isPrimaryActive(item.id)) {
|
||||
return item.color
|
||||
}
|
||||
return 'transparent'
|
||||
}
|
||||
|
||||
// 选择二级分类
|
||||
async function selectSubCategory(subCategoryId: string): Promise<void> {
|
||||
console.log('选择二级分类:', subCategoryId)
|
||||
activeSubCategory.value = subCategoryId
|
||||
|
||||
// 使用二级分类ID加载商品
|
||||
currentPage.value = 1
|
||||
hasMore.value = true
|
||||
activePrimary.value = subCategoryId // 临时设置为二级分类ID用于加载商品
|
||||
await loadProducts()
|
||||
}
|
||||
|
||||
// 选择一级分类 - 必须在 loadCategories 之前定义
|
||||
// originalCategoryId: 可能是一级分类ID,也可能是二级分类ID
|
||||
async function selectPrimaryCategory(originalCategoryId: string): Promise<void> {
|
||||
console.log('=== selectPrimaryCategory函数开始执行 ===')
|
||||
console.log('传入的categoryId:', originalCategoryId)
|
||||
|
||||
if (originalCategoryId == '') {
|
||||
console.error('categoryId为空,尝试使用第一个分类')
|
||||
if (primaryCategories.value.length > 0) {
|
||||
originalCategoryId = primaryCategories.value[0].id
|
||||
} else {
|
||||
console.error('没有可用的分类')
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 检查传入的是否是一级分类ID
|
||||
let targetParentId = originalCategoryId
|
||||
let targetSubId = ''
|
||||
console.log('当前一级分类列表长度:', primaryCategories.value.length)
|
||||
let foundInPrimary: LocalCategory | null = null
|
||||
for (let i = 0; i < primaryCategories.value.length; i++) {
|
||||
if (primaryCategories.value[i].id == originalCategoryId) {
|
||||
foundInPrimary = primaryCategories.value[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
console.log('在一级分类中查找结果:', foundInPrimary != null)
|
||||
|
||||
if (foundInPrimary == null) {
|
||||
// 传入的可能是二级分类ID,需要查找其父级分类
|
||||
console.log('传入的ID不在一级分类中,可能是二级分类ID,尝试查找父级分类')
|
||||
|
||||
// 从服务器获取分类信息以确定父级
|
||||
try {
|
||||
const categoryInfo = await supabaseService.getCategoryById(originalCategoryId)
|
||||
if (categoryInfo != null && categoryInfo.parent_id != null && categoryInfo.parent_id != '') {
|
||||
console.log('找到父级分类ID:', categoryInfo.parent_id)
|
||||
|
||||
// 检查父级分类ID是否在一级分类列表中
|
||||
console.log('查找父级分类ID:', categoryInfo.parent_id)
|
||||
let parentInPrimary: LocalCategory | null = null
|
||||
for (let i = 0; i < primaryCategories.value.length; i++) {
|
||||
if (primaryCategories.value[i].id == categoryInfo.parent_id) {
|
||||
parentInPrimary = primaryCategories.value[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
console.log('父级分类查找结果:', parentInPrimary != null)
|
||||
if (parentInPrimary != null) {
|
||||
console.log('父级分类在列表中找到:', parentInPrimary.name)
|
||||
targetParentId = categoryInfo.parent_id!
|
||||
targetSubId = originalCategoryId // 记住要选中的二级分类
|
||||
} else {
|
||||
console.log('父级分类不在列表中,使用第一个分类')
|
||||
// 打印当前列表中的所有分类ID
|
||||
for (let i = 0; i < primaryCategories.value.length; i++) {
|
||||
console.log('列表中的分类:', primaryCategories.value[i].id, primaryCategories.value[i].name)
|
||||
}
|
||||
if (primaryCategories.value.length > 0) {
|
||||
targetParentId = primaryCategories.value[0].id
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.log('未找到父级分类,使用第一个分类')
|
||||
if (primaryCategories.value.length > 0) {
|
||||
targetParentId = primaryCategories.value[0].id
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('获取分类信息失败:', e)
|
||||
if (primaryCategories.value.length > 0) {
|
||||
targetParentId = primaryCategories.value[0].id
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log('最终选中的一级分类ID:', targetParentId)
|
||||
console.log('需要选中的二级分类ID:', targetSubId)
|
||||
|
||||
// 设置一级分类高亮
|
||||
selectedParentId.value = targetParentId
|
||||
activePrimary.value = targetParentId
|
||||
|
||||
// 加载二级分类
|
||||
await loadSubCategories(targetParentId)
|
||||
|
||||
// 如果有要选中的二级分类
|
||||
if (targetSubId != '') {
|
||||
activeSubCategory.value = targetSubId
|
||||
} else {
|
||||
// 如果没有指定二级分类,但有二级分类列表,默认选中第一个
|
||||
if (subCategories.value.length > 0) {
|
||||
activeSubCategory.value = subCategories.value[0].id
|
||||
targetSubId = subCategories.value[0].id
|
||||
console.log('默认选中第一个二级分类:', subCategories.value[0].name)
|
||||
} else {
|
||||
activeSubCategory.value = ''
|
||||
}
|
||||
}
|
||||
|
||||
// 自动滚动到选中位置
|
||||
let foundIndex = -1
|
||||
for (let i = 0; i < primaryCategories.value.length; i++) {
|
||||
if (primaryCategories.value[i].id == targetParentId) {
|
||||
foundIndex = i
|
||||
break
|
||||
}
|
||||
}
|
||||
if (foundIndex != -1) {
|
||||
// 获取系统信息
|
||||
const systemInfo = uni.getSystemInfoSync()
|
||||
|
||||
let itemHeight = 70
|
||||
if (systemInfo.windowWidth > 1025) {
|
||||
itemHeight = 80
|
||||
}
|
||||
|
||||
const scrollViewHeight = systemInfo.windowHeight - systemInfo.statusBarHeight - 44
|
||||
const targetScrollTop = (foundIndex * itemHeight) - (scrollViewHeight / 2) + (itemHeight / 2)
|
||||
scrollTop.value = Math.max(0, targetScrollTop)
|
||||
console.log(`滚动左侧菜单: index=${foundIndex}, target=${scrollTop.value}`)
|
||||
}
|
||||
|
||||
// 查找分类信息
|
||||
let foundCategory: LocalCategory | null = null
|
||||
for (let i = 0; i < primaryCategories.value.length; i++) {
|
||||
if (primaryCategories.value[i].id == targetParentId) {
|
||||
foundCategory = primaryCategories.value[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
if (foundCategory != null) {
|
||||
currentCategoryName.value = foundCategory.name
|
||||
currentCategoryDesc.value = foundCategory.description
|
||||
} else {
|
||||
console.log('分类信息未找到,使用第一个分类的信息')
|
||||
if (primaryCategories.value.length > 0) {
|
||||
const firstCategory = primaryCategories.value[0]
|
||||
currentCategoryName.value = firstCategory.name
|
||||
currentCategoryDesc.value = firstCategory.description
|
||||
}
|
||||
}
|
||||
|
||||
currentPage.value = 1
|
||||
hasMore.value = true
|
||||
|
||||
// 如果有选中的二级分类,使用二级分类ID加载商品;否则使用一级分类ID
|
||||
const categoryIdForProducts = (targetSubId != '') ? targetSubId : targetParentId
|
||||
activePrimary.value = categoryIdForProducts // 临时设置为要加载的分类ID
|
||||
await loadProducts()
|
||||
}
|
||||
|
||||
async function loadCategories(): Promise<void> {
|
||||
try {
|
||||
const categoriesData = await supabaseService.getCategories()
|
||||
console.log('加载分类数据成功,数量:', categoriesData.length)
|
||||
// 只获取一级分类(parent_id 为 null 的分类)
|
||||
const categoriesData = await supabaseService.getParentCategories()
|
||||
console.log('加载一级分类数据成功,数量:', categoriesData.length)
|
||||
|
||||
// 映射数据并添加默认颜色,防止选中时背景透明导致文字看不清
|
||||
// 过滤掉医药健康相关分类
|
||||
const categories: LocalCategory[] = []
|
||||
const rawList = categoriesData as any[]
|
||||
for (let i = 0; i < rawList.length; i++) {
|
||||
const raw = rawList[i]
|
||||
const catObj = (raw instanceof UTSJSONObject) ? (raw as UTSJSONObject) : (JSON.parse(JSON.stringify(raw)) as UTSJSONObject)
|
||||
const name = catObj.getString('name') ?? ''
|
||||
for (let i = 0; i < categoriesData.length; i++) {
|
||||
const cat = categoriesData[i]
|
||||
const name = cat.name
|
||||
console.log('一级分类:', cat.id, name)
|
||||
if (name.includes('医药') || name.includes('健康')) {
|
||||
console.log('过滤掉分类:', name)
|
||||
continue
|
||||
}
|
||||
const id = catObj.getString('id') ?? ''
|
||||
const description = catObj.getString('description') ?? ''
|
||||
const icon = catObj.getString('icon') ?? catObj.getString('icon_url') ?? '📦'
|
||||
const color = catObj.getString('color') ?? '#4CAF50'
|
||||
categories.push({
|
||||
id,
|
||||
name,
|
||||
icon,
|
||||
description,
|
||||
color
|
||||
id: cat.id,
|
||||
name: cat.name,
|
||||
icon: cat.icon,
|
||||
description: cat.description,
|
||||
color: cat.color
|
||||
})
|
||||
}
|
||||
|
||||
console.log('最终一级分类列表数量:', categories.length)
|
||||
|
||||
if (categories.length > 0) {
|
||||
primaryCategories.value = categories
|
||||
// 如果没有通过参数设置分类,则设置默认选中一个分类
|
||||
if (activePrimary.value == '') {
|
||||
// 优先查找"厨具"相关的分类作为默认
|
||||
const defaultCategory = categories.find((c: LocalCategory): boolean => c.name.includes('厨具')) ?? categories[0]
|
||||
|
||||
activePrimary.value = defaultCategory.id
|
||||
console.log('设置默认分类为:', defaultCategory.name, 'ID:', defaultCategory.id)
|
||||
currentCategoryName.value = defaultCategory.name
|
||||
currentCategoryDesc.value = defaultCategory.description
|
||||
} else {
|
||||
// 如果已经选中了分类(可能来自Storage),更新显示信息
|
||||
const current = categories.find((c: LocalCategory): boolean => c.id == activePrimary.value)
|
||||
if (current != null) {
|
||||
currentCategoryName.value = current.name
|
||||
currentCategoryDesc.value = current.description
|
||||
// 如果此时没有商品列表(且没有正在加载),可能需要加载
|
||||
if (productList.value.length === 0 && !loading.value) {
|
||||
loadProducts()
|
||||
}
|
||||
}
|
||||
|
||||
// 检查是否有待处理的分类ID(从其他页面跳转过来时暂存)
|
||||
if (pendingCategoryId.value != '') {
|
||||
console.log('发现待处理的分类ID:', pendingCategoryId.value)
|
||||
// 直接调用 selectPrimaryCategory,它会处理一级或二级分类ID
|
||||
const idToSelect = pendingCategoryId.value
|
||||
pendingCategoryId.value = '' // 清除暂存
|
||||
selectPrimaryCategory(idToSelect)
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否有预设的分类ID
|
||||
if (activePrimary.value != '') {
|
||||
console.log('有预设的分类ID:', activePrimary.value)
|
||||
const target = categories.find((c: LocalCategory): boolean => c.id == activePrimary.value)
|
||||
if (target != null) {
|
||||
console.log('找到目标分类,执行选中:', target.name)
|
||||
selectPrimaryCategory(activePrimary.value)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 默认选中第一个分类或"厨具"分类
|
||||
const defaultCategory = categories.find((c: LocalCategory): boolean => c.name.includes('厨具')) ?? categories[0]
|
||||
if (defaultCategory != null) {
|
||||
console.log('设置默认分类:', defaultCategory.name)
|
||||
selectPrimaryCategory(defaultCategory.id)
|
||||
}
|
||||
} else {
|
||||
console.warn('从Supabase获取的分类数据为空')
|
||||
@@ -241,71 +495,6 @@ function loadMore(): void {
|
||||
}
|
||||
}
|
||||
|
||||
// 选择一级分类
|
||||
async function selectPrimaryCategory(categoryId: string): Promise<void> {
|
||||
console.log('=== selectPrimaryCategory函数开始执行 ===')
|
||||
console.log('传入的categoryId:', categoryId)
|
||||
console.log('当前时间:', Date.now())
|
||||
|
||||
// 验证categoryId是否有效
|
||||
if (categoryId == '') {
|
||||
console.error('categoryId为空,尝试使用第一个分类')
|
||||
if (primaryCategories.value.length > 0) {
|
||||
categoryId = primaryCategories.value[0].id
|
||||
} else {
|
||||
console.error('没有可用的分类')
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
console.log('验证后的categoryId:', categoryId)
|
||||
console.log('当前activePrimary的值:', activePrimary.value)
|
||||
|
||||
// 更新活动分类
|
||||
activePrimary.value = categoryId
|
||||
console.log('更新后的activePrimary:', activePrimary.value)
|
||||
|
||||
// 更新当前分类信息
|
||||
const category = primaryCategories.value.find((cat: LocalCategory): boolean => cat.id === categoryId)
|
||||
if (category != null) {
|
||||
currentCategoryName.value = category.name
|
||||
currentCategoryDesc.value = category.description
|
||||
console.log('✅ 找到分类:', category.name, '描述:', category.description)
|
||||
} else {
|
||||
console.error('❌ 未找到分类ID:', categoryId, ',使用第一个分类')
|
||||
// 如果找不到对应的分类,使用第一个分类
|
||||
if (primaryCategories.value.length > 0) {
|
||||
const firstCategory = primaryCategories.value[0]
|
||||
currentCategoryName.value = firstCategory.name
|
||||
currentCategoryDesc.value = firstCategory.description
|
||||
activePrimary.value = firstCategory.id
|
||||
categoryId = firstCategory.id
|
||||
console.log('使用默认分类:', firstCategory.name)
|
||||
}
|
||||
}
|
||||
|
||||
console.log('准备加载商品数据...')
|
||||
|
||||
// 重置分页并加载
|
||||
currentPage.value = 1
|
||||
hasMore.value = true
|
||||
await loadProducts()
|
||||
|
||||
console.log('✅ 加载商品数据成功')
|
||||
console.log('分类:', categoryId)
|
||||
console.log('商品数量:', productList.value.length)
|
||||
console.log('商品列表:', productList.value)
|
||||
|
||||
// 验证数据是否已正确更新
|
||||
console.log('数据更新验证:')
|
||||
console.log('activePrimary:', activePrimary.value)
|
||||
console.log('currentCategoryName:', currentCategoryName.value)
|
||||
console.log('currentCategoryDesc:', currentCategoryDesc.value)
|
||||
console.log('productList长度:', productList.value.length)
|
||||
|
||||
console.log('=== selectPrimaryCategory函数执行完成 ===')
|
||||
}
|
||||
|
||||
// 生命周期
|
||||
onMounted(() => {
|
||||
loadCategories().then(() => {
|
||||
@@ -317,12 +506,42 @@ onMounted(() => {
|
||||
})
|
||||
})
|
||||
|
||||
// 页面加载时处理参数 - 这是处理分类切换的主要入口
|
||||
// 页面显示时检查是否有参数传递过来
|
||||
onShow(() => {
|
||||
console.log('=== category页面onShow被调用 ===')
|
||||
|
||||
// 检查是否有存储的分类选择
|
||||
const savedCategoryId = uni.getStorageSync('selectedCategory')
|
||||
console.log('onShow检查Storage:', savedCategoryId)
|
||||
|
||||
if (savedCategoryId != null && savedCategoryId != '') {
|
||||
const targetId = savedCategoryId as string
|
||||
console.log('onShow发现存储的分类ID:', targetId)
|
||||
|
||||
// 清除存储,避免下次进入默认选中
|
||||
uni.removeStorageSync('selectedCategory')
|
||||
|
||||
// 确保分类数据已加载
|
||||
if (primaryCategories.value.length > 0) {
|
||||
// 如果当前未选中或选中的不是目标分类,则切换
|
||||
if (activePrimary.value != targetId) {
|
||||
console.log('onShow执行切换分类:', targetId)
|
||||
selectPrimaryCategory(targetId)
|
||||
} else {
|
||||
console.log('当前已是目标分类:', targetId)
|
||||
}
|
||||
} else {
|
||||
// 如果分类数据未加载,暂存ID,等待loadCategories完成后处理
|
||||
console.log('分类数据尚未加载,暂存ID等待加载')
|
||||
pendingCategoryId.value = targetId
|
||||
}
|
||||
}
|
||||
})
|
||||
// 页面加载时处理参数 - 这是处理分类切换的主要入口
|
||||
onLoad((options: any) => {
|
||||
console.log('=== category页面onLoad被调用 ===')
|
||||
console.log('页面加载时间:', Date.now())
|
||||
console.log('传入的options参数:', options)
|
||||
console.log('当前活动分类:', activePrimary.value)
|
||||
const systemInfo = uni.getSystemInfoSync()
|
||||
statusBarHeight.value = systemInfo.statusBarHeight
|
||||
console.log('=== category页面onLoad被调用 ===')
|
||||
|
||||
let categoryId = ''
|
||||
let categoryName = ''
|
||||
@@ -381,72 +600,6 @@ onLoad((options: any) => {
|
||||
console.log('=== category页面onLoad执行完成 ===')
|
||||
})
|
||||
|
||||
// 页面显示时也检查参数,确保从其他页面返回时能正确显示
|
||||
onShow(() => {
|
||||
console.log('=== category页面onShow被调用 ===')
|
||||
console.log('页面显示时间:', Date.now())
|
||||
console.log('当前活动分类:', activePrimary.value)
|
||||
|
||||
// 1. 优先检查 Storage 中的参数 (由首页传入)
|
||||
const storageCategoryId = (uni.getStorageSync('selectedCategory') as string) ?? ''
|
||||
if (storageCategoryId !== '') {
|
||||
console.log('✅ onShow中找到Storage分类参数:', storageCategoryId)
|
||||
hasLoadedFromParams.value = true
|
||||
// 清除Storage,防止下次误读
|
||||
uni.removeStorageSync('selectedCategory')
|
||||
|
||||
if (activePrimary.value !== storageCategoryId) {
|
||||
selectPrimaryCategory(storageCategoryId)
|
||||
}
|
||||
// 如果分类还没加载完,这里设置了ID,等loadCategories完成后会自动匹配信息
|
||||
return
|
||||
}
|
||||
|
||||
// 在onShow中,我们也需要检查是否有新的参数
|
||||
// 因为当从主页再次点击分类跳转过来时,可能不会触发onLoad
|
||||
// 而是触发onShow
|
||||
|
||||
// 获取当前页面实例和参数
|
||||
const pages = getCurrentPages()
|
||||
if (pages.length > 0) {
|
||||
const currentPage = pages[pages.length - 1]
|
||||
const rawPageOptions = currentPage.options ?? {}
|
||||
console.log('onShow中获取参数:', rawPageOptions)
|
||||
const pageOptObj = (rawPageOptions instanceof UTSJSONObject) ? (rawPageOptions as UTSJSONObject) : (JSON.parse(JSON.stringify(rawPageOptions)) as UTSJSONObject)
|
||||
|
||||
// 检查是否有分类参数
|
||||
const pageCategoryId = pageOptObj.getString('categoryId') ?? ''
|
||||
if (pageCategoryId !== '') {
|
||||
hasLoadedFromParams.value = true
|
||||
const categoryId = pageCategoryId
|
||||
const categoryName = pageOptObj.getString('name') ?? ''
|
||||
|
||||
console.log('✅ onShow中找到分类参数:', categoryId, categoryName)
|
||||
console.log('URL中的时间戳参数:', pageOptObj.getString('timestamp') ?? '')
|
||||
console.log('URL中的随机参数:', pageOptObj.getString('random') ?? '')
|
||||
|
||||
// 检查是否需要更新分类
|
||||
if (activePrimary.value !== categoryId) {
|
||||
console.log('当前分类:', activePrimary.value, '与目标分类:', categoryId, '不同,需要更新')
|
||||
console.log('准备调用selectPrimaryCategory函数...')
|
||||
selectPrimaryCategory(categoryId)
|
||||
} else {
|
||||
console.log('当前分类已经是目标分类,但可能用户想要刷新页面')
|
||||
console.log('当前分类:', activePrimary.value, '目标分类:', categoryId)
|
||||
// 即使分类相同,也重新加载数据,确保数据是最新的
|
||||
// 添加一个小的延迟,确保页面完全显示后再更新数据
|
||||
setTimeout(() => {
|
||||
selectPrimaryCategory(categoryId)
|
||||
}, 100)
|
||||
}
|
||||
} else {
|
||||
console.log('⚠️ onShow中未找到分类参数')
|
||||
}
|
||||
}
|
||||
|
||||
console.log('=== category页面onShow执行完成 ===')
|
||||
})
|
||||
|
||||
|
||||
// 添加到购物车
|
||||
async function addToCart(product: Product): Promise<void> {
|
||||
@@ -574,7 +727,7 @@ function onScan(): void {
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: linear-gradient(135deg, #4CAF50 0%, #2E7D32 100%);
|
||||
background-color: #4CAF50;
|
||||
z-index: 1000;
|
||||
box-shadow: 0 2px 12px rgba(76, 175, 80, 0.15);
|
||||
}
|
||||
@@ -714,32 +867,31 @@ function onScan(): void {
|
||||
|
||||
/* 左侧一级分类 */
|
||||
.primary-category {
|
||||
width: 120px;
|
||||
height: 100%; /* 占满父容器高度 */
|
||||
margin-right: 20px; /* gap replacement */
|
||||
width: 63px;
|
||||
height: 100%;
|
||||
margin-right: 6px;
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
padding: 12px 0;
|
||||
border-radius: 8px;
|
||||
padding: 6px 0;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.primary-item {
|
||||
display: flex;
|
||||
flex-direction: column; /* 图标和文字垂直排列 */
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 12px 8px;
|
||||
margin: 4px 8px;
|
||||
padding: 12px 4px;
|
||||
margin: 4px 6px;
|
||||
border-radius: 8px;
|
||||
/* cursor: pointer; removed for uniapp-x support */
|
||||
transition: all 0.2s ease;
|
||||
color: #666;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.primary-item:hover {
|
||||
transform: translateY(-2px); /* 悬停时向上浮动 */
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.primary-item.active {
|
||||
@@ -748,24 +900,22 @@ function onScan(): void {
|
||||
}
|
||||
|
||||
.primary-icon {
|
||||
font-size: 24px;
|
||||
margin-bottom: 6px;
|
||||
margin-right: 0; /* 移除右边距 */
|
||||
font-size: 20px;
|
||||
margin-bottom: 4px;
|
||||
margin-right: 0;
|
||||
text-align: center;
|
||||
/* display: block; removed for uniapp-x support */
|
||||
}
|
||||
|
||||
.primary-name {
|
||||
font-size: 13px;
|
||||
line-height: 1.4;
|
||||
/* display: block; removed for uniapp-x support */
|
||||
font-size: 11px;
|
||||
line-height: 1.25;
|
||||
}
|
||||
|
||||
/* 右侧内容区 */
|
||||
.product-content {
|
||||
flex: 1;
|
||||
height: 100%; /* 占满父容器高度 */
|
||||
padding: 0; /* 移除内边距,交给内部元素 */
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.category-header {
|
||||
@@ -789,6 +939,56 @@ function onScan(): void {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
/* 二级分类 */
|
||||
.sub-category-section {
|
||||
padding: 8px 8px;
|
||||
background: white;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.sub-category-list {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
width: 100%;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.sub-category-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 8px 4px;
|
||||
background: #f5f5f5;
|
||||
border-radius: 8px;
|
||||
flex: 1;
|
||||
min-width: 50px;
|
||||
}
|
||||
|
||||
.sub-category-item.active {
|
||||
background: #4CAF50;
|
||||
}
|
||||
|
||||
.sub-category-item.active .sub-category-name {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.sub-category-icon {
|
||||
font-size: 16px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.sub-category-name {
|
||||
font-size: 11px;
|
||||
color: #333;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* 商品网格 */
|
||||
.product-grid {
|
||||
display: flex;
|
||||
@@ -954,52 +1154,47 @@ function onScan(): void {
|
||||
}
|
||||
|
||||
.category-content {
|
||||
padding: 0 8px;
|
||||
padding: 0 4px;
|
||||
}
|
||||
|
||||
.primary-category {
|
||||
width: 80px; /* 减小宽度 */
|
||||
/* display: flex; 移除flex布局,保持默认 */
|
||||
/* flex-wrap: wrap; 移除换行 */
|
||||
padding: 8px 0;
|
||||
margin-right: 10px; /* Gap replacement */
|
||||
width: 56px;
|
||||
padding: 4px 0;
|
||||
margin-right: 4px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.primary-item {
|
||||
/* width: calc(25% - 8px); 移除百分比宽度 */
|
||||
width: auto; /* 恢复自动宽度 */
|
||||
margin: 4px;
|
||||
padding: 8px 4px;
|
||||
/* text-align: center; 已经在通用样式中设置 */
|
||||
margin: 2px 2px;
|
||||
padding: 4px 2px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.primary-icon {
|
||||
margin-right: 0;
|
||||
margin-bottom: 4px;
|
||||
font-size: 20px;
|
||||
margin-bottom: 2px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.primary-name {
|
||||
font-size: 11px;
|
||||
font-size: 9px;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
.product-grid {
|
||||
/* grid-template-columns: repeat(2, 1fr); REMOVED */
|
||||
/* gap: 8px; REMOVED */
|
||||
padding: 0 4px 20px 4px; /* 增加底部内边距 */
|
||||
padding: 0 4px 20px 4px;
|
||||
}
|
||||
|
||||
.product-card {
|
||||
width: 48%; /* 2 columns for mobile */
|
||||
width: 48%;
|
||||
margin: 1%;
|
||||
}
|
||||
|
||||
/* 手机端商品卡片极简模式 - 仿照主页样式 */
|
||||
.product-spec,
|
||||
.manufacturer,
|
||||
.original-price,
|
||||
.sales-info,
|
||||
.product-badge { /* 分类页也隐藏角标,保持整洁 */
|
||||
.product-badge {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@@ -1008,7 +1203,7 @@ function onScan(): void {
|
||||
}
|
||||
|
||||
.product-image {
|
||||
height: 100px; /* 由于分类页右侧空间更窄,图片高度设得更小一点 */
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.product-name {
|
||||
@@ -1018,10 +1213,7 @@ function onScan(): void {
|
||||
margin-bottom: 2px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
/* display: -webkit-box; REMOVED for support */
|
||||
/* -webkit-line-clamp: 2; REMOVED for support */
|
||||
/* -webkit-box-orient: vertical; REMOVED for support */
|
||||
lines: 2; /* UTS text truncation */
|
||||
lines: 2;
|
||||
}
|
||||
|
||||
.price-section {
|
||||
@@ -1040,30 +1232,52 @@ function onScan(): void {
|
||||
}
|
||||
|
||||
.product-meta {
|
||||
display: none; /* 隐藏整个元数据行 */
|
||||
}
|
||||
|
||||
.search-container {
|
||||
padding: 0 12px;
|
||||
height: 44px;
|
||||
}
|
||||
|
||||
.search-box {
|
||||
padding: 8px 16px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.category-header {
|
||||
padding: 12px 4px 0 4px;
|
||||
padding: 8px 4px 0 4px;
|
||||
}
|
||||
|
||||
.category-title {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.category-desc {
|
||||
font-size: 11px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 中屏手机/小平板 (415px-768px) */
|
||||
/* 中屏手机 (415px-768px) */
|
||||
@media screen and (min-width: 415px) and (max-width: 768px) {
|
||||
.search-container {
|
||||
padding: 0 16px;
|
||||
height: 44px;
|
||||
}
|
||||
|
||||
.primary-category {
|
||||
width: 62px;
|
||||
padding: 6px 0;
|
||||
margin-right: 6px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.primary-item {
|
||||
margin: 2px 2px;
|
||||
padding: 5px 2px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.primary-icon {
|
||||
font-size: 18px;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
||||
.primary-name {
|
||||
font-size: 10px;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
.product-card {
|
||||
width: 46%;
|
||||
margin: 2%;
|
||||
@@ -1077,6 +1291,26 @@ function onScan(): void {
|
||||
height: 44px;
|
||||
}
|
||||
|
||||
.primary-category {
|
||||
width: 100px;
|
||||
padding: 10px 0;
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
.primary-item {
|
||||
margin: 4px 4px;
|
||||
padding: 10px 6px;
|
||||
}
|
||||
|
||||
.primary-icon {
|
||||
font-size: 22px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.primary-name {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.product-card {
|
||||
width: 30%;
|
||||
margin: 1.5%;
|
||||
@@ -1097,7 +1331,7 @@ function onScan(): void {
|
||||
.primary-category {
|
||||
width: 160px;
|
||||
padding: 16px 0;
|
||||
margin-right: 30px; /* Gap replacement */
|
||||
margin-right: 30px;
|
||||
}
|
||||
|
||||
.primary-item {
|
||||
@@ -1132,14 +1366,9 @@ function onScan(): void {
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.product-grid {
|
||||
/* grid-template-columns: repeat(4, 1fr); REMOVED */
|
||||
/* gap: 24px; REMOVED */
|
||||
}
|
||||
|
||||
.product-card {
|
||||
border-radius: 14px;
|
||||
width: 22%; /* 4 columns */
|
||||
width: 22%;
|
||||
margin: 1.5%;
|
||||
}
|
||||
|
||||
@@ -1164,12 +1393,11 @@ function onScan(): void {
|
||||
@media screen and (min-width: 1400px) {
|
||||
.category-content {
|
||||
max-width: 1600px;
|
||||
/* gap: 40px; REMOVED */
|
||||
padding: 0 32px;
|
||||
}
|
||||
|
||||
.primary-category {
|
||||
margin-right: 40px; /* Gap replacement */
|
||||
margin-right: 40px;
|
||||
}
|
||||
|
||||
.primary-category {
|
||||
@@ -1209,14 +1437,9 @@ function onScan(): void {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.product-grid {
|
||||
/* grid-template-columns: repeat(5, 1fr); REMOVED */
|
||||
/* gap: 28px; REMOVED */
|
||||
}
|
||||
|
||||
.product-card {
|
||||
border-radius: 16px;
|
||||
width: 17%; /* 5 columns */
|
||||
width: 17%;
|
||||
margin: 1.5%;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user