consumer模块完成度95%,能编译在安卓端运行,在解决数据获取和页面布局问题
This commit is contained in:
@@ -83,21 +83,44 @@
|
||||
<text class="section-desc">快速定位</text>
|
||||
</view>
|
||||
<view class="category-grid" v-if="categoryTab === 'category'">
|
||||
<!-- 一级分类 -->
|
||||
<view
|
||||
v-for="category in categories"
|
||||
v-for="category in parentCategories"
|
||||
:key="category.id"
|
||||
class="category-card"
|
||||
@click="switchCategory(category)"
|
||||
@click="onParentCategoryClick(category)"
|
||||
:style="{ '--card-color': category.color }"
|
||||
>
|
||||
<view class="card-icon">
|
||||
<text class="card-icon-text">{{ category.icon }}</text>
|
||||
</view>
|
||||
<text class="card-name">{{ category.name }}</text>
|
||||
<text class="card-desc">{{ category.description }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="category-grid" v-else>
|
||||
|
||||
<!-- 二级分类 -->
|
||||
<view v-if="categoryTab === 'category' && showSubCategories && subCategories.length > 0" class="sub-category-grid">
|
||||
<view class="sub-category-header">
|
||||
<text class="sub-category-title">{{ selectedParentCategory?.name }}分类</text>
|
||||
<text class="sub-category-close" @click="showSubCategories = false">✕</text>
|
||||
</view>
|
||||
<view class="sub-category-wrapper">
|
||||
<view
|
||||
v-for="subCat in subCategories"
|
||||
:key="subCat.id"
|
||||
class="sub-category-card"
|
||||
@click="onSubCategoryClick(subCat)"
|
||||
>
|
||||
<view class="card-icon">
|
||||
<text class="card-icon-text">{{ subCat.icon }}</text>
|
||||
</view>
|
||||
<text class="card-name">{{ subCat.name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 品牌列表 -->
|
||||
<view class="category-grid" v-if="categoryTab === 'brand'">
|
||||
<view
|
||||
v-for="brand in brands"
|
||||
:key="brand.id"
|
||||
@@ -304,6 +327,12 @@ const categoryTab = ref<string>('category')
|
||||
const categories = ref<Category[]>([])
|
||||
const brands = ref<Brand[]>([])
|
||||
|
||||
// 一级分类和二级分类
|
||||
const parentCategories = ref<Category[]>([])
|
||||
const subCategories = ref<Category[]>([])
|
||||
const selectedParentCategory = ref<Category | null>(null)
|
||||
const showSubCategories = ref(false)
|
||||
|
||||
// 排序标签类型
|
||||
type SortTab = {
|
||||
id: string
|
||||
@@ -342,38 +371,60 @@ const healthNews = [
|
||||
}
|
||||
]
|
||||
|
||||
// 获取分类数据
|
||||
// 获取一级分类数据
|
||||
const loadCategories = async (): Promise<void> => {
|
||||
try {
|
||||
const categoriesData = await supabaseService.getCategories()
|
||||
// 映射字段:根据ml_categories表结构映射
|
||||
const mappedCategories: Category[] = []
|
||||
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') ?? ''
|
||||
// 过滤掉医药健康相关分类
|
||||
if (name.includes('医药') || name.includes('健康')) {
|
||||
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'
|
||||
// 使用 JSON.parse 创建对象,避免接口实例化问题
|
||||
const categoryItem = JSON.parse(`{"id":"${id}","name":"${name}","icon":"${icon}","description":"${description}","color":"${color}"}`) as Category
|
||||
mappedCategories.push(categoryItem)
|
||||
}
|
||||
// 保持原始顺序或按ID排序,移除随机打乱
|
||||
categories.value = mappedCategories
|
||||
const categoriesData = await supabaseService.getParentCategories()
|
||||
parentCategories.value = categoriesData
|
||||
// 兼容其他使用 categories 的地方
|
||||
categories.value = categoriesData
|
||||
} catch (error) {
|
||||
console.error('加载分类数据失败:', error)
|
||||
// 如果加载失败,使用默认分类作为后备
|
||||
parentCategories.value = []
|
||||
categories.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取二级分类数据
|
||||
const loadSubCategories = async (parentId: string): Promise<void> => {
|
||||
try {
|
||||
const subData = await supabaseService.getSubCategories(parentId)
|
||||
subCategories.value = subData
|
||||
} catch (error) {
|
||||
console.error('加载子分类数据失败:', error)
|
||||
subCategories.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 点击一级分类
|
||||
const onParentCategoryClick = async (category: Category): Promise<void> => {
|
||||
// 如果已经选中,则切换显示/隐藏二级分类
|
||||
if (selectedParentCategory.value != null && selectedParentCategory.value.id === category.id) {
|
||||
showSubCategories.value = !showSubCategories.value
|
||||
return
|
||||
}
|
||||
|
||||
// 选中新的分类
|
||||
selectedParentCategory.value = category
|
||||
showSubCategories.value = true
|
||||
|
||||
// 加载二级分类
|
||||
await loadSubCategories(category.id)
|
||||
}
|
||||
|
||||
// 点击二级分类
|
||||
const onSubCategoryClick = (category: Category): void => {
|
||||
// 跳转到分类页面
|
||||
uni.setStorageSync('selectedCategory', category.id)
|
||||
const timestamp = Date.now()
|
||||
const randomParam = Math.random().toString(36).substring(2, 8)
|
||||
const url = `/pages/mall/consumer/category?categoryId=${category.id}&name=${encodeURIComponent(category.name)}×tamp=${timestamp}&random=${randomParam}`
|
||||
|
||||
uni.switchTab({
|
||||
url: '/pages/mall/consumer/category'
|
||||
})
|
||||
}
|
||||
|
||||
// 获取品牌数据
|
||||
const loadBrands = async () => {
|
||||
try {
|
||||
@@ -1138,7 +1189,7 @@ const navigateToReminders = () => uni.navigateTo({ url: '/pages/user/reminders'
|
||||
}
|
||||
|
||||
.category-card {
|
||||
width: 47%; /* 50 - 3 */
|
||||
width: 23%; /* 一行4个 */
|
||||
margin: 0 1.5% 16px 1.5%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -1187,6 +1238,78 @@ const navigateToReminders = () => uni.navigateTo({ url: '/pages/user/reminders'
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* 二级分类样式 */
|
||||
.sub-category-grid {
|
||||
background: #f8f9fa;
|
||||
border-radius: 12px;
|
||||
padding: 16px;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.sub-category-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 12px;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
}
|
||||
|
||||
.sub-category-title {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.sub-category-close {
|
||||
font-size: 16px;
|
||||
color: #999;
|
||||
padding: 4px 8px;
|
||||
}
|
||||
|
||||
.sub-category-wrapper {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.sub-category-card {
|
||||
width: 23%;
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
padding: 10px 4px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 1px solid #eee;
|
||||
margin-right: 2%;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.sub-category-card .card-icon {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border-radius: 18px;
|
||||
margin-bottom: 6px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.sub-category-card .card-icon-text {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.sub-category-card .card-name {
|
||||
font-size: 11px;
|
||||
color: #333;
|
||||
text-align: center;
|
||||
lines: 1;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
/* 健康资讯 */
|
||||
.health-news {
|
||||
background: white;
|
||||
|
||||
Reference in New Issue
Block a user