2026-08-06 18:50:25 +08:00
|
|
|
|
<template>
|
|
|
|
|
|
<view class="sort_warp" :class="platformType ? '' : 'iosplatformType'">
|
|
|
|
|
|
<!-- #ifndef MP-WEIXIN -->
|
|
|
|
|
|
<TopSafe></TopSafe>
|
|
|
|
|
|
<!-- #endif -->
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 顶部固定区域:搜索 + 分类区域 -->
|
|
|
|
|
|
<view class="top_fixed_header" :class="{ is_expanded: showAllCategories }" :style="mpHeaderStyle">
|
|
|
|
|
|
<!-- 搜索框 -->
|
|
|
|
|
|
<view class="search_bar" @click="jumpSearch">
|
|
|
|
|
|
<u-icon name="search" size="18" color="#999"></u-icon>
|
|
|
|
|
|
<text class="search_placeholder">搜索</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 1. 未展开时:顶部分类横向滚动条 -->
|
|
|
|
|
|
<view class="top_category_row" v-if="!showAllCategories">
|
|
|
|
|
|
<scroll-view class="top_category_scroll" scroll-x :show-scrollbar="false">
|
|
|
|
|
|
<view class="top_cat_list">
|
|
|
|
|
|
<view class="top_cat_item" v-for="(item, index) in categoryList" :key="item.id || index"
|
|
|
|
|
|
@click="selectCategory(index)">
|
|
|
|
|
|
<view class="top_cat_img_box" :class="{ active_img: currentCategoryIndex === index }">
|
|
|
|
|
|
<image class="top_cat_img" :src="item.icon || defaultIcon" mode="aspectFill" />
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view class="top_cat_name_badge" :class="{ active_badge: currentCategoryIndex === index }">
|
|
|
|
|
|
{{ item.name }}
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</scroll-view>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 右侧全部按钮 -->
|
|
|
|
|
|
<view class="expand_all_btn" @click="toggleAllCategories">
|
|
|
|
|
|
<text class="expand_text">全部</text>
|
|
|
|
|
|
<u-icon name="arrow-down-fill" size="10" color="#666"></u-icon>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 2. 点开全部时:展开所有分类网格面板 -->
|
|
|
|
|
|
<view class="all_categories_panel" v-else>
|
|
|
|
|
|
<view class="panel_header">
|
|
|
|
|
|
<text class="panel_title">所有分类</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<scroll-view class="panel_grid_scroll" scroll-y :show-scrollbar="false">
|
|
|
|
|
|
<view class="panel_grid">
|
|
|
|
|
|
<view class="top_cat_item panel_cat_item" v-for="(item, index) in categoryList" :key="item.id || index"
|
|
|
|
|
|
@click="selectCategory(index, true)">
|
|
|
|
|
|
<view class="top_cat_img_box" :class="{ active_img: currentCategoryIndex === index }">
|
|
|
|
|
|
<image class="top_cat_img" :src="item.icon || defaultIcon" mode="aspectFill" />
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view class="top_cat_name_badge" :class="{ active_badge: currentCategoryIndex === index }">
|
|
|
|
|
|
{{ item.name }}
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</scroll-view>
|
|
|
|
|
|
<view class="collapse_btn" @click="toggleAllCategories">
|
|
|
|
|
|
<text style="margin-right: 6rpx;">全部收起</text>
|
|
|
|
|
|
<u-icon name="arrow-up" size="12" color="#666"></u-icon>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 主体区域:左侧边栏 + 右侧商品列表 -->
|
|
|
|
|
|
<view class="main_container">
|
|
|
|
|
|
<!-- 展开所有分类时的半透明遮罩 -->
|
|
|
|
|
|
<view class="mask_overlay" v-if="showAllCategories" @click="showAllCategories = false"></view>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 左侧分类侧边栏 -->
|
|
|
|
|
|
<scroll-view class="left_sidebar_scroll" scroll-y>
|
|
|
|
|
|
<view class="sidebar_item" v-for="(item, index) in categoryList" :key="item.id || index"
|
|
|
|
|
|
:class="{ active: currentCategoryIndex === index }" @click="selectCategory(index)">
|
|
|
|
|
|
<text class="sidebar_name">{{ item.name }}</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</scroll-view>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 右侧商品列表区 -->
|
|
|
|
|
|
<view class="right_content_area">
|
|
|
|
|
|
<!-- 排序栏 -->
|
|
|
|
|
|
<view class="sort_option_bar">
|
|
|
|
|
|
<view class="cat_title_text">{{ currentCategory ? currentCategory.name : '' }}</view>
|
|
|
|
|
|
<view class="sort_actions">
|
|
|
|
|
|
<view class="sort_item" :class="{ active: sortType === 'default' }" @click="setSort('default')">
|
|
|
|
|
|
综合 <text class="sort_arrow">⇅</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view class="sort_item" :class="{ active: sortType === 'sales' }" @click="setSort('sales')">
|
|
|
|
|
|
销量 <text class="sort_arrow">⇅</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view class="sort_item" :class="{ active: sortType === 'price' }" @click="setSort('price')">
|
|
|
|
|
|
价格 <text class="sort_arrow">⇅</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 商品列表 -->
|
|
|
|
|
|
<scroll-view class="product_list_scroll" scroll-y>
|
|
|
|
|
|
<view class="product_list_box" v-if="displayProducts && displayProducts.length > 0">
|
|
|
|
|
|
<view class="product_row_card" v-for="(item, index) in displayProducts" :key="item.id || index"
|
|
|
|
|
|
@click="jumpInfo(item)">
|
|
|
|
|
|
<view class="product_img_box">
|
|
|
|
|
|
<image class="product_img" :src="item.image || item.icon || defaultProductImg" mode="aspectFill"
|
|
|
|
|
|
lazy-load />
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view class="product_info_box">
|
|
|
|
|
|
<view class="product_title">{{ item.name || item.title }}</view>
|
|
|
|
|
|
|
|
|
|
|
|
<view class="product_tags_row">
|
|
|
|
|
|
<text class="tag_item tag_blue" v-if="item.tags && item.tags[0]">{{ item.tags[0] }}</text>
|
|
|
|
|
|
<text class="tag_item tag_green" v-if="item.tags && item.tags[1]">{{ item.tags[1] }}</text>
|
|
|
|
|
|
<text class="tag_item tag_blue" v-if="!item.tags">专业检测</text>
|
|
|
|
|
|
<text class="tag_item tag_green" v-if="!item.tags">生态有机</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
<view class="product_price_row">
|
|
|
|
|
|
<view class="price_box">
|
|
|
|
|
|
<text class="price_symbol">¥</text>
|
|
|
|
|
|
<text class="price_val">{{ item.price }}</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<text class="sales_val">全网销量{{ limit999(item.sales) }}</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view class="empty_box" v-else>
|
|
|
|
|
|
<image src="https://static.tbmall.xin/static/not_shopping.png" class="empty_img" />
|
|
|
|
|
|
<text class="empty_text">暂无商品数据</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</scroll-view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- #ifndef H5 || MP-WEIXIN-->
|
|
|
|
|
|
<CustomTabBar :tabIndex="1" />
|
|
|
|
|
|
<!-- #endif -->
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
|
import { getCascadeCategory } from "@/api/common.js";
|
|
|
|
|
|
import CustomTabBar from "@/components/custom-tab-bar.vue";
|
|
|
|
|
|
import TopSafe from "@/components/common/top-safe.nvue";
|
|
|
|
|
|
|
|
|
|
|
|
// 假数据列表:当后端接口未就绪时自动提供高保真模拟数据
|
|
|
|
|
|
const MOCK_CATEGORIES = [
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 101,
|
|
|
|
|
|
name: '有机食品',
|
|
|
|
|
|
icon: 'https://static.tbmall.xin/static/new-home/xinren.png',
|
|
|
|
|
|
foods: [
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 1001,
|
|
|
|
|
|
name: '鲜8有机贝贝南瓜2500g粉糯板栗味自然生长不催熟',
|
|
|
|
|
|
title: '鲜8有机贝贝南瓜2500g粉糯板栗味自然生长不催熟',
|
|
|
|
|
|
price: '39.00',
|
|
|
|
|
|
sales: 888,
|
|
|
|
|
|
tags: ['专业检测', '生态有机'],
|
|
|
|
|
|
image: 'https://static.tbmall.xin/static/new-home/nangua.png'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 1002,
|
|
|
|
|
|
name: '采缇国产车厘子5kg4j大连美早樱桃生鲜次日达樱桃',
|
|
|
|
|
|
title: '采缇国产车厘子5kg4j大连美早樱桃生鲜次日达樱桃',
|
|
|
|
|
|
price: '26.99',
|
|
|
|
|
|
sales: 888,
|
|
|
|
|
|
tags: ['专业检测', '生态有机'],
|
|
|
|
|
|
image: 'https://static.tbmall.xin/static/new-home/baokuan.png'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 1003,
|
|
|
|
|
|
name: '江苏白凤水蜜桃 应季水果 &新鲜礼盒装',
|
|
|
|
|
|
title: '江苏白凤水蜜桃 应季水果 &新鲜礼盒装',
|
|
|
|
|
|
price: '34.88',
|
|
|
|
|
|
sales: 888,
|
|
|
|
|
|
tags: ['专业检测', '生态有机'],
|
|
|
|
|
|
image: 'https://static.tbmall.xin/static/new-home/cart.png'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 1004,
|
|
|
|
|
|
name: '季新鲜 &进口山竹时令 &老树麻竹整箱送礼',
|
|
|
|
|
|
title: '季新鲜 &进口山竹时令 &老树麻竹整箱送礼',
|
|
|
|
|
|
price: '52.00',
|
|
|
|
|
|
sales: 888,
|
|
|
|
|
|
tags: ['专业检测', '生态有机'],
|
|
|
|
|
|
image: 'https://static.tbmall.xin/static/new-home/huiyuan.png'
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 102,
|
|
|
|
|
|
name: '生鲜食材',
|
|
|
|
|
|
icon: 'https://static.tbmall.xin/static/new-home/baokuan.png',
|
|
|
|
|
|
foods: [
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 1005,
|
|
|
|
|
|
name: '精选新鲜三文鱼中段切片 200g刺身级',
|
|
|
|
|
|
title: '精选新鲜三文鱼中段切片 200g刺身级',
|
|
|
|
|
|
price: '59.90',
|
|
|
|
|
|
sales: 1200,
|
|
|
|
|
|
tags: ['冷链速达', '产地直供'],
|
|
|
|
|
|
image: 'https://static.tbmall.xin/static/new-home/baokuan.png'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 1006,
|
|
|
|
|
|
name: '澳洲进口谷饲安格斯原切雪花牛肉卷 500g',
|
|
|
|
|
|
title: '澳洲进口谷饲安格斯原切雪花牛肉卷 500g',
|
|
|
|
|
|
price: '89.00',
|
|
|
|
|
|
sales: 650,
|
|
|
|
|
|
tags: ['原切牛肉', '品质严选'],
|
|
|
|
|
|
image: 'https://static.tbmall.xin/static/new-home/cart.png'
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 103,
|
|
|
|
|
|
name: '米面粮油',
|
|
|
|
|
|
icon: 'https://static.tbmall.xin/static/new-home/cart.png',
|
|
|
|
|
|
foods: [
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 1007,
|
|
|
|
|
|
name: '五常大米 优质长粒香米 5kg真空包装',
|
|
|
|
|
|
title: '五常大米 优质长粒香米 5kg真空包装',
|
|
|
|
|
|
price: '49.90',
|
|
|
|
|
|
sales: 3400,
|
|
|
|
|
|
tags: ['核心产区', '自然醇香'],
|
|
|
|
|
|
image: 'https://static.tbmall.xin/static/new-home/xinren.png'
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 104,
|
|
|
|
|
|
name: '零食饮料',
|
|
|
|
|
|
icon: 'https://static.tbmall.xin/static/new-home/huiyuan.png',
|
|
|
|
|
|
foods: [
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 1008,
|
|
|
|
|
|
name: '花生造黑松露黑麦苏打饼干 590g*2盒',
|
|
|
|
|
|
title: '花生造黑松露黑麦苏打饼干 590g*2盒',
|
|
|
|
|
|
price: '29.90',
|
|
|
|
|
|
sales: 2300,
|
|
|
|
|
|
tags: ['零反式脂肪酸', '拒绝油炸'],
|
|
|
|
|
|
image: 'https://static.tbmall.xin/static/new-home/huiyuan.png'
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 105,
|
|
|
|
|
|
name: '滋补养生',
|
|
|
|
|
|
icon: 'https://static.tbmall.xin/static/new-home/xinren.png',
|
|
|
|
|
|
foods: [
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 1009,
|
|
|
|
|
|
name: '青海野生黑枸杞干果 250g特级罐装',
|
|
|
|
|
|
title: '青海野生黑枸杞干果 250g特级罐装',
|
|
|
|
|
|
price: '78.00',
|
|
|
|
|
|
sales: 510,
|
|
|
|
|
|
tags: ['正宗原产', '花青素丰富'],
|
|
|
|
|
|
image: 'https://static.tbmall.xin/static/new-home/nangua.png'
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 106,
|
|
|
|
|
|
name: '非遗传承',
|
|
|
|
|
|
icon: 'https://static.tbmall.xin/static/new-home/baokuan.png',
|
|
|
|
|
|
foods: []
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 107,
|
|
|
|
|
|
name: '家居百货',
|
|
|
|
|
|
icon: 'https://static.tbmall.xin/static/new-home/cart.png',
|
|
|
|
|
|
foods: []
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 108,
|
|
|
|
|
|
name: '美妆护肤',
|
|
|
|
|
|
icon: 'https://static.tbmall.xin/static/new-home/huiyuan.png',
|
|
|
|
|
|
foods: []
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: 109,
|
|
|
|
|
|
name: '其他特色',
|
|
|
|
|
|
icon: 'https://static.tbmall.xin/static/new-home/xinren.png',
|
|
|
|
|
|
foods: []
|
|
|
|
|
|
}
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
export default {
|
|
|
|
|
|
components: { CustomTabBar, TopSafe },
|
|
|
|
|
|
data() {
|
|
|
|
|
|
return {
|
|
|
|
|
|
platformType: true,
|
|
|
|
|
|
currentCategoryIndex: 0,
|
|
|
|
|
|
showAllCategories: false,
|
|
|
|
|
|
sortType: 'default', // default | sales | price
|
|
|
|
|
|
sortAsc: true,
|
|
|
|
|
|
categoryList: [],
|
|
|
|
|
|
capsuleTop: 0,
|
|
|
|
|
|
defaultIcon: 'https://static.tbmall.xin/static/new-home/xinren.png',
|
|
|
|
|
|
defaultProductImg: 'https://static.tbmall.xin/static/new-home/nangua.png'
|
|
|
|
|
|
};
|
|
|
|
|
|
},
|
|
|
|
|
|
computed: {
|
|
|
|
|
|
mpHeaderStyle() {
|
|
|
|
|
|
/*#ifdef MP-WEIXIN*/
|
|
|
|
|
|
if (this.capsuleTop) {
|
|
|
|
|
|
return { paddingTop: this.capsuleTop + 'px' };
|
|
|
|
|
|
}
|
|
|
|
|
|
return { paddingTop: '80rpx' };
|
|
|
|
|
|
/*#endif*/
|
|
|
|
|
|
return {};
|
|
|
|
|
|
},
|
|
|
|
|
|
currentCategory() {
|
|
|
|
|
|
return this.categoryList[this.currentCategoryIndex] || null;
|
|
|
|
|
|
},
|
|
|
|
|
|
displayProducts() {
|
|
|
|
|
|
if (!this.currentCategory) return [];
|
|
|
|
|
|
let list = this.currentCategory.foods || this.currentCategory.productList || [];
|
|
|
|
|
|
if (!list || list.length === 0) return [];
|
|
|
|
|
|
list = [...list];
|
|
|
|
|
|
|
|
|
|
|
|
if (this.sortType === 'sales') {
|
|
|
|
|
|
list.sort((a, b) => (Number(b.sales) || 0) - (Number(a.sales) || 0));
|
|
|
|
|
|
} else if (this.sortType === 'price') {
|
|
|
|
|
|
if (this.sortAsc) {
|
|
|
|
|
|
list.sort((a, b) => (Number(a.price) || 0) - (Number(b.price) || 0));
|
|
|
|
|
|
} else {
|
|
|
|
|
|
list.sort((a, b) => (Number(b.price) || 0) - (Number(a.price) || 0));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return list;
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
onShow() {
|
|
|
|
|
|
/*#ifdef APP-PLUS*/
|
|
|
|
|
|
uni.hideTabBar({ animation: false });
|
|
|
|
|
|
const appUpdate = uni.getStorageSync("platform");
|
|
|
|
|
|
this.platformType = appUpdate == "android" ? "ANDROID" : "IOS";
|
|
|
|
|
|
/*#endif*/
|
|
|
|
|
|
|
|
|
|
|
|
/*#ifdef MP-WEIXIN*/
|
|
|
|
|
|
try {
|
|
|
|
|
|
const menu = uni.getMenuButtonBoundingClientRect();
|
|
|
|
|
|
if (menu && menu.bottom) {
|
|
|
|
|
|
this.capsuleTop = menu.bottom + 6;
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (e) {}
|
|
|
|
|
|
/*#endif*/
|
|
|
|
|
|
|
|
|
|
|
|
this.fetchCategories();
|
|
|
|
|
|
},
|
|
|
|
|
|
methods: {
|
|
|
|
|
|
async fetchCategories() {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const resp = await getCascadeCategory({ parentId: 0 });
|
|
|
|
|
|
if (resp && resp.bizcode === 100 && resp.data && resp.data.length > 0) {
|
|
|
|
|
|
this.categoryList = resp.data;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
this.categoryList = MOCK_CATEGORIES;
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
console.log("使用模拟分类数据", e);
|
|
|
|
|
|
this.categoryList = MOCK_CATEGORIES;
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
selectCategory(index, closePopup = false) {
|
|
|
|
|
|
this.currentCategoryIndex = index;
|
|
|
|
|
|
if (closePopup) {
|
|
|
|
|
|
this.showAllCategories = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
toggleAllCategories() {
|
|
|
|
|
|
this.showAllCategories = !this.showAllCategories;
|
|
|
|
|
|
},
|
|
|
|
|
|
setSort(type) {
|
|
|
|
|
|
if (this.sortType === type && type === 'price') {
|
|
|
|
|
|
this.sortAsc = !this.sortAsc;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
this.sortType = type;
|
|
|
|
|
|
this.sortAsc = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
limit999(n) {
|
|
|
|
|
|
const num = Number(n);
|
|
|
|
|
|
if (isNaN(num) || num < 10000) {
|
|
|
|
|
|
return n != null && n !== '' ? String(n) : '0';
|
|
|
|
|
|
}
|
|
|
|
|
|
return `${Math.floor(num / 10000)}万+`;
|
|
|
|
|
|
},
|
|
|
|
|
|
jumpSearch() {
|
|
|
|
|
|
uni.navigateTo({
|
|
|
|
|
|
url: "/pages/rwa_package/insights/search",
|
|
|
|
|
|
});
|
|
|
|
|
|
},
|
|
|
|
|
|
jumpInfo(item) {
|
|
|
|
|
|
uni.navigateTo({
|
|
|
|
|
|
url: `/pages/rwa_package/shop/sort-shop?id=${item.id}&name=${encodeURIComponent(item.name || item.title || '')}`,
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
|
|
page {
|
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.sort_warp {
|
|
|
|
|
|
height: 100vh;
|
|
|
|
|
|
/* #ifdef H5 */
|
|
|
|
|
|
height: calc(100vh - var(--window-top, 0px) - var(--window-bottom, 0px));
|
|
|
|
|
|
/* #endif */
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
background-color: #ffffff;
|
|
|
|
|
|
position: relative;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 顶部固定区域 */
|
|
|
|
|
|
.top_fixed_header {
|
|
|
|
|
|
position: relative;
|
|
|
|
|
|
z-index: 100;
|
|
|
|
|
|
background: #ffffff;
|
|
|
|
|
|
flex-shrink: 0;
|
|
|
|
|
|
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.03);
|
|
|
|
|
|
transition: all 0.2s;
|
|
|
|
|
|
|
|
|
|
|
|
&.is_expanded {
|
|
|
|
|
|
background: linear-gradient(180deg, #F2EBFF 0%, #FFFFFF 100%, #FFFFFF 100%) !important;
|
|
|
|
|
|
border-bottom-left-radius: 36rpx !important;
|
|
|
|
|
|
border-bottom-right-radius: 36rpx !important;
|
|
|
|
|
|
box-shadow: 0 12rpx 32rpx rgba(122, 53, 246, 0.12) !important;
|
|
|
|
|
|
overflow: hidden !important;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 搜索框 */
|
|
|
|
|
|
.search_bar {
|
|
|
|
|
|
margin: 16rpx 24rpx 12rpx;
|
|
|
|
|
|
height: 72rpx;
|
|
|
|
|
|
background-color: #ffffff;
|
|
|
|
|
|
border-radius: 36rpx;
|
|
|
|
|
|
padding: 0 28rpx;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
|
|
|
|
|
|
.search_placeholder {
|
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
|
color: #999999;
|
|
|
|
|
|
margin-left: 12rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 顶部分类横划栏 */
|
|
|
|
|
|
.top_category_row {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
padding: 10rpx 0 16rpx 20rpx;
|
|
|
|
|
|
|
|
|
|
|
|
.top_category_scroll {
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
overflow-x: auto;
|
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
|
min-width: 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.top_cat_list {
|
|
|
|
|
|
display: inline-flex;
|
|
|
|
|
|
align-items: flex-start;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.expand_all_btn {
|
|
|
|
|
|
width: 90rpx;
|
|
|
|
|
|
flex-shrink: 0;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
font-size: 22rpx;
|
|
|
|
|
|
color: #666666;
|
|
|
|
|
|
padding: 0 12rpx;
|
|
|
|
|
|
|
|
|
|
|
|
.expand_text {
|
|
|
|
|
|
font-size: 22rpx;
|
|
|
|
|
|
color: #666666;
|
|
|
|
|
|
margin-bottom: 4rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 分类 Icon 与 Badge 通用样式(同时作用于横滑栏与展开网格) */
|
|
|
|
|
|
.top_cat_item {
|
|
|
|
|
|
display: inline-flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
margin-right: 32rpx;
|
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
|
|
|
|
|
|
&.panel_cat_item {
|
|
|
|
|
|
width: 20% !important;
|
|
|
|
|
|
max-width: 20% !important;
|
|
|
|
|
|
margin-right: 0 !important;
|
|
|
|
|
|
margin-bottom: 24rpx !important;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.top_cat_img_box {
|
|
|
|
|
|
width: 96rpx !important;
|
|
|
|
|
|
height: 96rpx !important;
|
|
|
|
|
|
min-width: 96rpx !important;
|
|
|
|
|
|
max-width: 96rpx !important;
|
|
|
|
|
|
min-height: 96rpx !important;
|
|
|
|
|
|
max-height: 96rpx !important;
|
|
|
|
|
|
border-radius: 50% !important;
|
|
|
|
|
|
overflow: hidden !important;
|
|
|
|
|
|
background: #f7f7f7;
|
|
|
|
|
|
display: flex !important;
|
|
|
|
|
|
align-items: center !important;
|
|
|
|
|
|
justify-content: center !important;
|
|
|
|
|
|
box-sizing: border-box !important;
|
|
|
|
|
|
border: 4rpx solid transparent;
|
|
|
|
|
|
transition: all 0.2s;
|
|
|
|
|
|
flex-shrink: 0 !important;
|
|
|
|
|
|
|
|
|
|
|
|
&.active_img {
|
|
|
|
|
|
border-color: #7a35f6 !important;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.top_cat_img {
|
|
|
|
|
|
width: 88rpx !important;
|
|
|
|
|
|
height: 88rpx !important;
|
|
|
|
|
|
min-width: 88rpx !important;
|
|
|
|
|
|
max-width: 88rpx !important;
|
|
|
|
|
|
min-height: 88rpx !important;
|
|
|
|
|
|
max-height: 88rpx !important;
|
|
|
|
|
|
border-radius: 50% !important;
|
|
|
|
|
|
display: block !important;
|
|
|
|
|
|
flex-shrink: 0 !important;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.top_cat_name_badge {
|
|
|
|
|
|
font-size: 22rpx !important;
|
|
|
|
|
|
color: #666666 !important;
|
|
|
|
|
|
margin-top: 10rpx !important;
|
|
|
|
|
|
padding: 2rpx 12rpx !important;
|
|
|
|
|
|
border-radius: 16rpx !important;
|
|
|
|
|
|
line-height: 32rpx !important;
|
|
|
|
|
|
white-space: nowrap !important;
|
|
|
|
|
|
transition: all 0.2s;
|
|
|
|
|
|
|
|
|
|
|
|
&.active_badge {
|
|
|
|
|
|
background-color: #7a35f6 !important;
|
|
|
|
|
|
color: #ffffff !important;
|
|
|
|
|
|
font-weight: bold !important;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 点开全部时的网格面板 */
|
|
|
|
|
|
.all_categories_panel {
|
|
|
|
|
|
background: transparent;
|
|
|
|
|
|
padding: 16rpx 24rpx 0;
|
|
|
|
|
|
border-bottom-left-radius: 36rpx !important;
|
|
|
|
|
|
border-bottom-right-radius: 36rpx !important;
|
|
|
|
|
|
overflow: hidden !important;
|
|
|
|
|
|
|
|
|
|
|
|
.panel_header {
|
|
|
|
|
|
margin-bottom: 20rpx;
|
|
|
|
|
|
padding-left: 8rpx;
|
|
|
|
|
|
|
|
|
|
|
|
.panel_title {
|
|
|
|
|
|
font-size: 30rpx;
|
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
|
color: #1a1a1a;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.panel_grid_scroll {
|
|
|
|
|
|
max-height: 55vh;
|
|
|
|
|
|
overflow-y: auto;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.panel_grid {
|
|
|
|
|
|
display: flex !important;
|
|
|
|
|
|
flex-wrap: wrap !important;
|
|
|
|
|
|
width: 100% !important;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.collapse_btn {
|
|
|
|
|
|
display: flex !important;
|
|
|
|
|
|
align-items: center !important;
|
|
|
|
|
|
justify-content: center !important;
|
|
|
|
|
|
font-size: 24rpx !important;
|
|
|
|
|
|
color: #666666 !important;
|
|
|
|
|
|
height: 80rpx !important;
|
|
|
|
|
|
background-color: #ffffff !important;
|
|
|
|
|
|
border-top: 1rpx solid #eeeeee !important;
|
|
|
|
|
|
margin-top: 16rpx !important;
|
|
|
|
|
|
margin-left: -24rpx !important;
|
|
|
|
|
|
margin-right: -24rpx !important;
|
|
|
|
|
|
border-bottom-left-radius: 36rpx !important;
|
|
|
|
|
|
border-bottom-right-radius: 36rpx !important;
|
|
|
|
|
|
overflow: hidden !important;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 主内容区 */
|
|
|
|
|
|
.main_container {
|
|
|
|
|
|
position: relative;
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: row;
|
|
|
|
|
|
min-height: 0;
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
background-color: #f7f7f7;
|
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
|
|
|
|
|
|
/* 展开所有分类时的半透明遮罩 */
|
|
|
|
|
|
.mask_overlay {
|
|
|
|
|
|
position: fixed !important;
|
|
|
|
|
|
top: 0 !important;
|
|
|
|
|
|
left: 0 !important;
|
|
|
|
|
|
right: 0 !important;
|
|
|
|
|
|
bottom: 0 !important;
|
|
|
|
|
|
width: 100vw !important;
|
|
|
|
|
|
height: 100vh !important;
|
|
|
|
|
|
background-color: rgba(0, 0, 0, 0.45) !important;
|
|
|
|
|
|
z-index: 90 !important;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 左侧边栏 */
|
|
|
|
|
|
.left_sidebar_scroll {
|
|
|
|
|
|
width: 180rpx;
|
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
flex-shrink: 0;
|
|
|
|
|
|
background-color: #f7f7f7;
|
|
|
|
|
|
overflow-y: auto;
|
|
|
|
|
|
|
|
|
|
|
|
/* #ifdef APP-PLUS */
|
|
|
|
|
|
padding-bottom: calc(110rpx + env(safe-area-inset-bottom));
|
|
|
|
|
|
/* #endif */
|
|
|
|
|
|
|
|
|
|
|
|
.sidebar_item {
|
|
|
|
|
|
height: 104rpx;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
font-size: 26rpx;
|
|
|
|
|
|
color: #555555;
|
|
|
|
|
|
padding: 0 12rpx;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
position: relative;
|
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
|
|
|
|
|
|
&.active {
|
|
|
|
|
|
background-color: #ffffff;
|
|
|
|
|
|
color: #7a35f6;
|
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
|
|
|
|
|
|
|
&::before {
|
|
|
|
|
|
content: "";
|
|
|
|
|
|
position: absolute;
|
|
|
|
|
|
left: 0;
|
|
|
|
|
|
top: 34rpx;
|
|
|
|
|
|
width: 6rpx;
|
|
|
|
|
|
height: 36rpx;
|
|
|
|
|
|
background-color: #7a35f6;
|
|
|
|
|
|
border-radius: 0 4rpx 4rpx 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 右侧内容区域 */
|
|
|
|
|
|
.right_content_area {
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
background-color: #ffffff;
|
|
|
|
|
|
min-width: 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 右侧排序栏 */
|
|
|
|
|
|
.sort_option_bar {
|
|
|
|
|
|
height: 80rpx;
|
|
|
|
|
|
padding: 0 24rpx;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
border-bottom: 1rpx solid #f5f5f5;
|
|
|
|
|
|
flex-shrink: 0;
|
|
|
|
|
|
|
|
|
|
|
|
.cat_title_text {
|
|
|
|
|
|
font-size: 30rpx;
|
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
|
color: #7a35f6;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.sort_actions {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
gap: 32rpx;
|
|
|
|
|
|
|
|
|
|
|
|
.sort_item {
|
|
|
|
|
|
font-size: 26rpx;
|
|
|
|
|
|
color: #999999;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
|
|
|
|
|
|
&.active {
|
|
|
|
|
|
color: #7a35f6;
|
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.sort_arrow {
|
|
|
|
|
|
font-size: 20rpx;
|
|
|
|
|
|
margin-left: 4rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 商品列表 */
|
|
|
|
|
|
.product_list_scroll {
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
overflow-y: auto;
|
|
|
|
|
|
|
|
|
|
|
|
/* #ifdef APP-PLUS */
|
|
|
|
|
|
padding-bottom: calc(110rpx + env(safe-area-inset-bottom));
|
|
|
|
|
|
/* #endif */
|
|
|
|
|
|
|
|
|
|
|
|
.product_list_box {
|
|
|
|
|
|
padding: 0 24rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.product_row_card {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: row;
|
|
|
|
|
|
padding: 24rpx 0;
|
|
|
|
|
|
border-bottom: 1rpx solid #f7f7f7;
|
|
|
|
|
|
background: #ffffff;
|
|
|
|
|
|
|
|
|
|
|
|
.product_img_box {
|
|
|
|
|
|
width: 200rpx;
|
|
|
|
|
|
height: 200rpx;
|
|
|
|
|
|
border-radius: 16rpx;
|
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
flex-shrink: 0;
|
|
|
|
|
|
margin-right: 20rpx;
|
|
|
|
|
|
background: #f9f9f9;
|
|
|
|
|
|
|
|
|
|
|
|
.product_img {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.product_info_box {
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
min-width: 0;
|
|
|
|
|
|
|
|
|
|
|
|
.product_title {
|
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
|
color: #1a1a1a;
|
|
|
|
|
|
line-height: 38rpx;
|
|
|
|
|
|
max-height: 76rpx;
|
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
|
|
display: -webkit-box;
|
|
|
|
|
|
-webkit-line-clamp: 2;
|
|
|
|
|
|
-webkit-box-orient: vertical;
|
|
|
|
|
|
word-break: break-all;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.product_tags_row {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
gap: 12rpx;
|
|
|
|
|
|
margin-top: 8rpx;
|
|
|
|
|
|
|
|
|
|
|
|
.tag_item {
|
|
|
|
|
|
font-size: 20rpx;
|
|
|
|
|
|
padding: 2rpx 10rpx;
|
|
|
|
|
|
border-radius: 6rpx;
|
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
|
|
|
|
|
|
|
&.tag_blue {
|
|
|
|
|
|
color: #2979ff;
|
|
|
|
|
|
border: 1rpx solid #2979ff;
|
|
|
|
|
|
background-color: rgba(41, 121, 255, 0.05);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
&.tag_green {
|
|
|
|
|
|
color: #19be6b;
|
|
|
|
|
|
border: 1rpx solid #19be6b;
|
|
|
|
|
|
background-color: rgba(25, 190, 107, 0.05);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.product_price_row {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
align-items: baseline;
|
|
|
|
|
|
margin-top: 12rpx;
|
|
|
|
|
|
|
|
|
|
|
|
.price_box {
|
|
|
|
|
|
color: #ff2a2a;
|
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
|
|
|
|
|
|
|
.price_symbol {
|
|
|
|
|
|
font-size: 24rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.price_val {
|
|
|
|
|
|
font-size: 38rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.sales_val {
|
|
|
|
|
|
font-size: 24rpx;
|
|
|
|
|
|
color: #999999;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.empty_box {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
padding-top: 120rpx;
|
|
|
|
|
|
|
|
|
|
|
|
.empty_img {
|
|
|
|
|
|
width: 160rpx;
|
|
|
|
|
|
height: 160rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.empty_text {
|
|
|
|
|
|
font-size: 26rpx;
|
|
|
|
|
|
color: #999999;
|
|
|
|
|
|
margin-top: 20rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
</style>
|