974 lines
27 KiB
Vue
974 lines
27 KiB
Vue
<template>
|
||
<view class="sort_warp" :class="platformType ? '' : 'iosplatformType'">
|
||
<!-- #ifndef MP-WEIXIN -->
|
||
<TopSafe v-if="!isMP" bgColor="#F2EBFF"></TopSafe>
|
||
<!-- #endif -->
|
||
|
||
<!-- 顶部固定区域:搜索 + 分类区域 -->
|
||
<view class="top_fixed_header" :class="{ is_expanded: showAllCategories }">
|
||
<!-- 搜索框容器 -->
|
||
<view class="search_bar_container" :style="mpHeaderStyle">
|
||
<view class="search_bar" :style="mpSearchStyle" @click="jumpSearch">
|
||
<u-icon name="search" size="18" color="#999"></u-icon>
|
||
<text class="search_placeholder">搜索</text>
|
||
</view>
|
||
</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 subCategoryList" :key="item.id || index"
|
||
:class="{ active: currentSubCategoryIndex === index }" @click="selectSubCategory(index)">
|
||
<text class="sidebar_name">{{ item.name }}</text>
|
||
</view>
|
||
</scroll-view>
|
||
|
||
<!-- 右侧商品列表区 -->
|
||
<view class="right_content_area">
|
||
<!-- 排序栏 -->
|
||
<view class="sort_option_bar">
|
||
<view></view>
|
||
<!-- <view class="cat_title_text">{{ currentCategory ? currentCategory.name : '' }}</view> -->
|
||
<view class="sort_actions">
|
||
<view class="sort_item" :class="{ active: sortBy === 'relevance' }" @click="setSort('relevance')">
|
||
<text>综合</text>
|
||
<view class="sort_icon_box">
|
||
<u-icon name="arrow-up-fill" size="10rpx"
|
||
:color="sortBy === 'relevance' && sortOrder === 'asc' ? '#7a35f6' : '#cccccc'"
|
||
class="icon_up"></u-icon>
|
||
<u-icon name="arrow-down-fill" size="10rpx"
|
||
:color="sortBy === 'relevance' && sortOrder === 'desc' ? '#7a35f6' : '#cccccc'"
|
||
class="icon_down"></u-icon>
|
||
</view>
|
||
</view>
|
||
<view class="sort_item" :class="{ active: sortBy === 'sales' }" @click="setSort('sales')">
|
||
<text>销量</text>
|
||
<view class="sort_icon_box">
|
||
<u-icon name="arrow-up-fill" size="10rpx"
|
||
:color="sortBy === 'sales' && sortOrder === 'asc' ? '#7a35f6' : '#cccccc'" class="icon_up"></u-icon>
|
||
<u-icon name="arrow-down-fill" size="10rpx"
|
||
:color="sortBy === 'sales' && sortOrder === 'desc' ? '#7a35f6' : '#cccccc'"
|
||
class="icon_down"></u-icon>
|
||
</view>
|
||
</view>
|
||
<view class="sort_item" :class="{ active: sortBy === 'price' }" @click="setSort('price')">
|
||
<text>价格</text>
|
||
<view class="sort_icon_box">
|
||
<u-icon name="arrow-up-fill" size="10rpx"
|
||
:color="sortBy === 'price' && sortOrder === 'asc' ? '#7a35f6' : '#cccccc'" class="icon_up"></u-icon>
|
||
<u-icon name="arrow-down-fill" size="10rpx"
|
||
:color="sortBy === 'price' && sortOrder === 'desc' ? '#7a35f6' : '#cccccc'"
|
||
class="icon_down"></u-icon>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 商品列表 -->
|
||
<scroll-view class="product_list_scroll" scroll-y @scrolltolower="onReachBottomGoods" :lower-threshold="50">
|
||
<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.url || 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"
|
||
v-if="item.sellingPoint && getSellingPointTags(item.sellingPoint).length > 0">
|
||
<text class="tag_item tag_green" v-for="(tag, tIndex) in getSellingPointTags(item.sellingPoint)"
|
||
:key="tIndex">{{ tag }}</text>
|
||
</view>
|
||
|
||
<view class="product_price_row">
|
||
<view class="price_box">
|
||
<text class="price_symbol">¥</text>
|
||
<text class="price_val">{{ item.couponPrice || item.price }}</text>
|
||
</view>
|
||
<text class="sales_val">全网销量{{ limit999(item.sales) }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 加载更多与无数据状态提示 -->
|
||
<view class="load_more_tips" v-if="loadingMore">加载中...</view>
|
||
<view class="load_more_tips" v-else-if="noMore && displayProducts.length > 0">没有更多了</view>
|
||
</view>
|
||
<view class="empty_box" v-else-if="!loading">
|
||
<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 -->
|
||
<qiaobao-assistant page-key="pages/sort/sort" title="商品分类" />
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import { getCascadeCategory } from "@/api/common.js";
|
||
import { searchList } from "@/api/product.js";
|
||
import CustomTabBar from "@/components/custom-tab-bar.vue";
|
||
import TopSafe from "@/components/common/top-safe.nvue";
|
||
|
||
export default {
|
||
components: { CustomTabBar, TopSafe },
|
||
data() {
|
||
return {
|
||
platformType: true,
|
||
isMP: false,
|
||
mpHeaderStyle: {},
|
||
mpSearchStyle: {},
|
||
categoryList: [], // 一级分类列表 (parentId = 0)
|
||
currentCategoryIndex: 0, // 当前选中的一级分类索引
|
||
subCategoryList: [], // 二级分类列表 (parentId = 一级ID)
|
||
currentSubCategoryIndex: 0, // 当前选中的二级分类索引
|
||
displayProducts: [], // 三级商品列表 (goods/searchList)
|
||
showAllCategories: false,
|
||
sortBy: 'relevance', // 'relevance' | 'sales' | 'price'
|
||
sortOrder: 'asc', // 'asc' | 'desc'
|
||
defaultIcon: 'https://static.tbmall.xin/static/new-home/xinren.png',
|
||
defaultProductImg: 'https://static.tbmall.xin/static/new-home/nangua.png',
|
||
isFromSortShop: false,
|
||
loading: false,
|
||
loadingMore: false,
|
||
noMore: false,
|
||
page: 1,
|
||
pageSize: 10
|
||
};
|
||
},
|
||
computed: {
|
||
currentCategory() {
|
||
return this.categoryList[this.currentCategoryIndex] || null;
|
||
},
|
||
currentSubCategory() {
|
||
return this.subCategoryList[this.currentSubCategoryIndex] || null;
|
||
}
|
||
},
|
||
onLoad() {
|
||
// #ifdef MP-WEIXIN || MP
|
||
this.isMP = true;
|
||
this.initMPHeader();
|
||
// #endif
|
||
},
|
||
onShow() {
|
||
/*#ifdef APP-PLUS*/
|
||
uni.hideTabBar({ animation: false });
|
||
const appUpdate = uni.getStorageSync("platform");
|
||
this.platformType = appUpdate == "android" ? "ANDROID" : "IOS";
|
||
/*#endif*/
|
||
|
||
// #ifdef MP-WEIXIN || MP
|
||
this.isMP = true;
|
||
this.initMPHeader();
|
||
// #endif
|
||
|
||
const isBackFromSortShop = this.isFromSortShop;
|
||
this.isFromSortShop = false;
|
||
|
||
this.fetchCategories(isBackFromSortShop);
|
||
},
|
||
methods: {
|
||
initMPHeader() {
|
||
// #ifdef MP-WEIXIN || MP
|
||
try {
|
||
const menuButton = uni.getMenuButtonBoundingClientRect();
|
||
const systemInfo = uni.getSystemInfoSync();
|
||
|
||
if (menuButton && menuButton.top && menuButton.top > 0) {
|
||
const menuButtonHeight = menuButton.height || 32;
|
||
const menuButtonTop = menuButton.top;
|
||
const menuButtonLeft = menuButton.left;
|
||
const windowWidth = systemInfo.windowWidth;
|
||
|
||
const rightPadding = windowWidth - menuButtonLeft + 12;
|
||
|
||
this.mpHeaderStyle = {
|
||
paddingTop: `${menuButtonTop}px`,
|
||
paddingRight: `${rightPadding}px`,
|
||
paddingLeft: '12px',
|
||
paddingBottom: '8px',
|
||
height: `${menuButtonTop + menuButtonHeight + 8}px`,
|
||
boxSizing: 'border-box',
|
||
display: 'flex',
|
||
alignItems: 'center'
|
||
};
|
||
|
||
this.mpSearchStyle = {
|
||
height: `${menuButtonHeight}px`,
|
||
borderRadius: `${menuButtonHeight / 2}px`,
|
||
boxSizing: 'border-box'
|
||
};
|
||
}
|
||
} catch (e) {
|
||
console.error("initMPHeader error:", e);
|
||
}
|
||
// #endif
|
||
},
|
||
getSellingPointTags(sellingPoint) {
|
||
if (!sellingPoint || typeof sellingPoint !== 'string') return [];
|
||
return sellingPoint
|
||
.split(/[,,]/)
|
||
.map(t => t.trim())
|
||
.filter(Boolean);
|
||
},
|
||
// 异步查询级联分类接口 (common/getCascadeCategory)
|
||
async getCategoryApi(pId) {
|
||
try {
|
||
const resp = await getCascadeCategory({ parentId: pId });
|
||
if (resp && resp.bizcode === 100 && Array.isArray(resp.data)) {
|
||
return resp.data;
|
||
}
|
||
} catch (e) {
|
||
console.error("getCascadeCategory error:", e);
|
||
}
|
||
return [];
|
||
},
|
||
|
||
// 1. 刚进来获取一级分类 (parentId = 0)
|
||
async fetchCategories(isBack = false) {
|
||
try {
|
||
const topList = await this.getCategoryApi(0);
|
||
this.categoryList = topList || [];
|
||
} catch (e) {
|
||
console.error("获取一级分类失败:", e);
|
||
this.categoryList = [];
|
||
}
|
||
|
||
if (this.categoryList.length === 0) {
|
||
this.subCategoryList = [];
|
||
this.displayProducts = [];
|
||
return;
|
||
}
|
||
|
||
let targetIndex = 0;
|
||
if (isBack) {
|
||
const sortId = uni.getStorageSync("sortId");
|
||
if (sortId) {
|
||
let idx = this.categoryList.findIndex(item => item.id === sortId);
|
||
if (idx !== -1) targetIndex = idx;
|
||
else if (this.currentCategoryIndex >= 0 && this.currentCategoryIndex < this.categoryList.length) {
|
||
targetIndex = this.currentCategoryIndex;
|
||
}
|
||
}
|
||
} else {
|
||
uni.removeStorageSync("sortId");
|
||
uni.removeStorageSync("subSortId");
|
||
targetIndex = 0;
|
||
}
|
||
|
||
this.selectCategory(targetIndex, false, isBack);
|
||
},
|
||
|
||
// 2. 选择一级分类,根据其 id 获取二级分类 (parentId = 该一级id)
|
||
async selectCategory(index, closePopup = false, isBack = false) {
|
||
this.currentCategoryIndex = index;
|
||
if (closePopup) {
|
||
this.showAllCategories = false;
|
||
}
|
||
|
||
const category = this.categoryList[index];
|
||
if (!category || !category.id) {
|
||
this.subCategoryList = [];
|
||
this.displayProducts = [];
|
||
return;
|
||
}
|
||
|
||
uni.setStorageSync("sortId", category.id);
|
||
|
||
this.loading = true;
|
||
try {
|
||
const subList = await this.getCategoryApi(category.id);
|
||
this.subCategoryList = subList || [];
|
||
|
||
if (this.subCategoryList.length === 0) {
|
||
this.displayProducts = [];
|
||
this.loading = false;
|
||
return;
|
||
}
|
||
|
||
let targetSubIndex = 0;
|
||
if (isBack) {
|
||
const subSortId = uni.getStorageSync("subSortId");
|
||
if (subSortId) {
|
||
let sIdx = this.subCategoryList.findIndex(item => item.id === subSortId);
|
||
if (sIdx !== -1) targetSubIndex = sIdx;
|
||
}
|
||
}
|
||
|
||
this.selectSubCategory(targetSubIndex);
|
||
} catch (e) {
|
||
console.error("获取二级分类失败:", e);
|
||
this.subCategoryList = [];
|
||
this.displayProducts = [];
|
||
this.loading = false;
|
||
}
|
||
},
|
||
|
||
// 3. 选择二级分类,更新当前二级分类并调用 goods/searchList 获取商品列表
|
||
selectSubCategory(subIndex) {
|
||
this.currentSubCategoryIndex = subIndex;
|
||
const subCat = this.subCategoryList[subIndex];
|
||
if (subCat && subCat.id) {
|
||
uni.setStorageSync("subSortId", subCat.id);
|
||
}
|
||
|
||
this.fetchGoodsList(false);
|
||
},
|
||
|
||
// 4. 调用 /goods/searchList 接口获取商品列表 (支持分页与排序)
|
||
async fetchGoodsList(isLoadMore = false) {
|
||
const currentSubCat = this.subCategoryList[this.currentSubCategoryIndex];
|
||
if (!currentSubCat || !currentSubCat.id) {
|
||
this.displayProducts = [];
|
||
this.loading = false;
|
||
this.loadingMore = false;
|
||
return;
|
||
}
|
||
|
||
if (isLoadMore) {
|
||
if (this.loadingMore || this.noMore) return;
|
||
this.loadingMore = true;
|
||
this.page++;
|
||
} else {
|
||
this.loading = true;
|
||
this.page = 1;
|
||
this.noMore = false;
|
||
}
|
||
|
||
const params = {
|
||
categoryId: currentSubCat.id,
|
||
page: this.page,
|
||
pageSize: this.pageSize,
|
||
sortBy: this.sortBy,
|
||
sortOrder: this.sortOrder
|
||
};
|
||
|
||
try {
|
||
const resp = await searchList(params);
|
||
if (resp && resp.bizcode === 100) {
|
||
let list = [];
|
||
if (Array.isArray(resp.data)) {
|
||
list = resp.data;
|
||
} else if (resp.data && Array.isArray(resp.data.entitys)) {
|
||
list = resp.data.entitys;
|
||
} else if (resp.data && Array.isArray(resp.data.list)) {
|
||
list = resp.data.list;
|
||
}
|
||
|
||
if (isLoadMore) {
|
||
this.displayProducts = [...this.displayProducts, ...list];
|
||
} else {
|
||
this.displayProducts = list;
|
||
}
|
||
|
||
if (list.length < this.pageSize) {
|
||
this.noMore = true;
|
||
}
|
||
} else {
|
||
if (!isLoadMore) {
|
||
this.displayProducts = [];
|
||
}
|
||
this.noMore = true;
|
||
}
|
||
} catch (e) {
|
||
console.error("searchList error:", e);
|
||
if (!isLoadMore) {
|
||
this.displayProducts = [];
|
||
}
|
||
} finally {
|
||
this.loading = false;
|
||
this.loadingMore = false;
|
||
}
|
||
},
|
||
|
||
// 5. 右侧商品列表触底触发分页加载
|
||
onReachBottomGoods() {
|
||
if (!this.noMore && !this.loadingMore && !this.loading) {
|
||
this.fetchGoodsList(true);
|
||
}
|
||
},
|
||
|
||
toggleAllCategories() {
|
||
this.showAllCategories = !this.showAllCategories;
|
||
},
|
||
|
||
// 6. 排序作用于 goods/searchList 接口
|
||
setSort(type) {
|
||
if (this.sortBy === type) {
|
||
this.sortOrder = this.sortOrder === 'asc' ? 'desc' : 'asc';
|
||
} else {
|
||
this.sortBy = type;
|
||
this.sortOrder = 'asc';
|
||
}
|
||
this.fetchGoodsList(false);
|
||
},
|
||
|
||
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) {
|
||
this.isFromSortShop = true;
|
||
uni.navigateTo({
|
||
url: '/pages/other_package/productInfo/productInfo?id=' + item.id,
|
||
})
|
||
}
|
||
}
|
||
};
|
||
</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: linear-gradient(180deg, #F2EBFF 0%, #FFFFFF 100%);
|
||
border-bottom-left-radius: 36rpx;
|
||
border-bottom-right-radius: 36rpx;
|
||
overflow: hidden;
|
||
flex-shrink: 0;
|
||
box-shadow: none;
|
||
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_container {
|
||
width: 100%;
|
||
padding: 16rpx 24rpx 12rpx;
|
||
box-sizing: border-box;
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
/* 搜索框 */
|
||
.search_bar {
|
||
width: 100%;
|
||
height: 72rpx;
|
||
background-color: #ffffff;
|
||
border-radius: 36rpx;
|
||
padding: 0 28rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
box-sizing: border-box;
|
||
|
||
.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: 160rpx;
|
||
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: none;
|
||
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;
|
||
cursor: pointer;
|
||
|
||
&.active {
|
||
color: #7a35f6;
|
||
font-weight: bold;
|
||
}
|
||
|
||
.sort_icon_box {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
margin-left: 6rpx;
|
||
line-height: 1;
|
||
|
||
.icon_up {
|
||
margin-bottom: 2rpx;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 商品列表 */
|
||
.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;
|
||
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;
|
||
flex-wrap: wrap;
|
||
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: 36rpx;
|
||
font-weight: normal;
|
||
}
|
||
}
|
||
|
||
.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;
|
||
}
|
||
}
|
||
|
||
.load_more_tips {
|
||
text-align: center;
|
||
font-size: 24rpx;
|
||
color: #999999;
|
||
padding: 24rpx 0;
|
||
}
|
||
}
|
||
</style>
|