Files
frontend-app/pages/sort/sort.vue
T
2026-07-25 09:12:36 +08:00

455 lines
12 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="sort_warp" :class="platformType ? '' : 'iosplatformType'">
<TopSafe></TopSafe>
<view class="sort_header">
<!-- 分类切换 -->
<view class="sort_category_header">
<view :class="selCategory === 1
? 'category_item category_item_sel'
: 'category_item'
" @click="checkCategory(1)">
<view>分类</view>
<view v-if="selCategory === 1" class="category_item_sel_but"></view>
</view>
<!-- <view :class="selCategory === 2 ? 'category_item category_item_sel':'category_item'" @click="checkCategory(2)">
<view>品牌</view>
<view v-if="selCategory === 2" class="category_item_sel_but"></view>
</view> -->
</view>
<!-- 搜索 -->
<view style="width: 200rpx" @click="jumpSearch" class="jump-search">
<up-search shape="square" bgColor="#EEEEEEFF" color="#666666FF" :showAction="false"
placeholder="搜索"></up-search>
</view>
</view>
<view class="u-menu-wrap">
<!-- 左侧类别 -->
<scroll-view scroll-y scroll-with-animation class="u-tab-view menu-scroll-view" :scroll-top="scrollTop">
<view v-for="(item, index) in tabbarList" :key="index" class="u-tab-item"
:class="[current == index ? 'u-tab-item-active' : '']" :data-current="index"
@tap.stop="swichMenu(item, index)">
<text class="u-line-1">{{ item.name }}</text>
</view>
</scroll-view>
<!-- 商品类别数据 -->
<scroll-view scroll-y class="right-box" :scroll-top="rightScrollTop">
<!-- banner图 -->
<view style="padding: 0rpx 20rpx" v-if="bannerList && bannerList.length > 0">
<up-swiper :list="bannerList" height="80px"></up-swiper>
</view>
<view class="page-view">
<!-- 这里还有一层循环 -->
<up-loading-page :loading="tabbarContentLoading"></up-loading-page>
<view class="class-item" v-for="(item, index) in tabbarContentList" :key="index">
<view class="item-title">
<text>{{ item.name }}</text>
</view>
<view class="item-container" v-if="item.foods && item.foods.length !== 0">
<view class="thumb-box" v-for="(item1, index1) in item.foods" :key="item1.id || index1" @click="jumpInfo(item1)">
<image class="item-menu-image" :src="item1.icon ? item1.icon : '/static/common/def_img.jpg'"
mode="aspectFill" lazy-load>
</image>
<view class="item-menu-name">{{ item1.name }}</view>
</view>
</view>
<view v-else class="not_order_warp">
<view class="not_order_warp_img"><up-image src="https://static.tbmall.xin/static/not_shopping.png"
width="100" height="100" bgColor="#f1f6ff00"></up-image></view>
<view class="not_order_msg_warp">暂无分类,快去添加吧~</view>
</view>
</view>
</view>
</scroll-view>
</view>
<!-- #ifndef H5 || MP-WEIXIN-->
<CustomTabBar :tabIndex="1" />
<!-- #endif -->
</view>
</template>
<script>
import { getCascadeCategory, getCarouselImage } from "@/api/common.js";
import CustomTabBar from "@/components/custom-tab-bar.vue";
import { APP_PAGE_TYPE } from "@/utils/enumUtils.js";
import TopSafe from '@/components/common/top-safe.nvue';
export default {
components: { CustomTabBar, TopSafe },
data() {
return {
selCategory: 1,
scrollTop: 0, //tab标题的滚动条位置
rightScrollTop: 0, // 右侧内容的滚动条位置
current: null, // 预设当前项的值
menuHeight: 0, // 左边菜单的高度
menuItemHeight: 0, // 左边菜单item的高度
bannerList: [],
tabbarList: [], // 左侧的主分类
tabbarContentList: [], // 右侧内容的分类
tabbarContentLoading: false,
platformType: true,
isFromSortShop: false,
};
},
onShow() {
/*#ifdef APP-PLUS*/
uni.hideTabBar({
animation: false,
});
const appUpdate = uni.getStorageSync("platform");
this.platformType = appUpdate == "android" ? "ANDROID" : "IOS";
/*#endif*/
const isBackFromSortShop = this.isFromSortShop;
this.isFromSortShop = false;
this.getSort(0).then((resp) => {
if (resp && resp.length !== 0) {
this.tabbarList = resp;
let targetIndex = 0;
let fData = resp[0];
if (isBackFromSortShop) {
const sortId = uni.getStorageSync("sortId");
if (sortId && sortId !== 0) {
resp.forEach((item, index) => {
if (item.id === sortId) {
fData = item;
targetIndex = index;
}
});
} else if (this.current !== null && this.current >= 0 && this.current < resp.length) {
targetIndex = this.current;
fData = resp[targetIndex];
}
} else {
uni.removeStorageSync("sortId");
this.current = 0;
this.scrollTop = 0;
targetIndex = 0;
fData = resp[0];
}
this.swichMenu(fData, targetIndex, true);
}
});
this.getCarouselImage();
},
methods: {
checkCategory(val) {
this.selCategory = val;
},
// 查询轮播图
async getCarouselImage() {
const params = {
pageUi: APP_PAGE_TYPE.SORT,
};
const resp = await getCarouselImage(params);
if (resp && resp.bizcode === 100) {
const data = resp.data || [];
this.bannerList =
data.length !== 0 ? data.map((obj) => obj.carouselImage) : [];
}
},
jumpSearch(item) {
uni.navigateTo({
url: "/pages/rwa_package/insights/search",
});
},
jumpInfo(item) {
console.log(item, "item");
this.isFromSortShop = true;
// uni.navigateTo({
// url: `/pages/other_package/productInfo/productInfo?id=${item.id}`,
// })
uni.navigateTo({
url: `/pages/rwa_package/shop/sort-shop?id=${item.id}&name=${item.name}`,
});
},
// 查询分类
async getSort(pId) {
const params = {
parentId: pId,
};
console.log('查询分类', params, pId);
const resp = await getCascadeCategory(params);
if (resp && resp.bizcode === 100) {
return resp.data;
}
return [];
},
getImg() {
return Math.floor(Math.random() * 35);
},
// 点击左边的栏目切换
async swichMenu(item, index, force = false) {
console.log('点击左边的栏目切换', item, index, "item, index");
if (!force && index == this.current && this.tabbarContentList.length > 0) return;
if (item && item.id) {
uni.setStorageSync("sortId", item.id);
}
this.rightScrollTop = 0;
this.tabbarContentLoading = true;
const firstData = await this.getSort(item.id);
for (let fItem of firstData) {
const twoData = await this.getSort(fItem.id);
fItem.foods = twoData;
}
this.tabbarContentList = firstData;
this.current = index;
// 如果为0,意味着尚未初始化
if (this.menuHeight == 0 || this.menuItemHeight == 0) {
await this.getElRect("menu-scroll-view", "menuHeight");
await this.getElRect("u-tab-item", "menuItemHeight");
}
// 将菜单活动item垂直居中
this.scrollTop =
index * this.menuItemHeight +
this.menuItemHeight / 2 -
this.menuHeight / 2;
this.tabbarContentLoading = false;
},
// 获取一个目标元素的高度
getElRect(elClass, dataVal) {
return new Promise((resolve) => {
const query = uni.createSelectorQuery().in(this);
query
.select("." + elClass)
.fields({ size: true }, (res) => {
if (!res) {
setTimeout(() => {
this.getElRect(elClass, dataVal).then(resolve);
}, 10);
return;
}
this[dataVal] = res.height;
resolve(res);
})
.exec();
});
},
// 分享给朋友
onShareAppMessage() {
return {
title: 'TB聚合商城', // 分享标题
path: '/pages/sort/sort' // 分享路径
}
},
// 分享到朋友圈
onShareTimeline() {
return {
title: 'TB聚合商城',
query: ''
}
},
},
};
</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: #fff;
}
.sort_header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20rpx 30rpx 10rpx;
flex-shrink: 0;
background-color: #fff;
z-index: 10;
/* #ifdef MP-WEIXIN */
margin-top: 80rpx;
/* #endif */
.sort_category_header {
display: flex;
align-items: center;
}
.jump-search {
display: flex;
}
.category_item {
width: 140rpx;
font-weight: bold;
font-size: 36rpx;
color: #999999;
}
.category_item_sel {
font-size: 44rpx;
color: #1a1a1a;
}
.category_item_sel_but {
height: 8rpx;
width: 50rpx;
background: $app-bt-bj;
margin-top: 4rpx;
margin-left: 12%;
border-radius: 20rpx;
}
}
.sort_content {}
.u-menu-wrap {
flex: 1;
min-height: 0;
width: 100%;
display: flex;
flex-direction: row;
overflow: hidden;
margin-top: 10rpx;
}
.u-search-inner {
background-color: rgb(234, 234, 234);
border-radius: 100rpx;
display: flex;
align-items: center;
padding: 10rpx 16rpx;
}
.u-search-text {
font-size: 26rpx;
color: $u-tips-color;
margin-left: 10rpx;
}
.u-tab-view {
width: 200rpx;
height: 100%;
flex-shrink: 0;
background: #f6f6f6;
overflow-y: auto;
box-sizing: border-box;
-webkit-overflow-scrolling: touch;
/* #ifdef APP-PLUS */
padding-bottom: calc(110rpx + env(safe-area-inset-bottom));
/* #endif */
/* #ifndef APP-PLUS */
padding-bottom: 0rpx;
/* #endif */
}
.u-tab-item {
height: 110rpx;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
font-size: 26rpx;
color: #444;
font-weight: 400;
line-height: 1;
padding: 0 10rpx;
text-align: center;
}
.u-tab-item-active {
position: relative;
color: #000;
font-size: 30rpx;
font-weight: 600;
background: #fff;
}
.u-tab-item-active::before {
content: "";
position: absolute;
border-left: 4px solid $app-bt-bj;
height: 32rpx;
left: 0;
top: 39rpx;
}
.right-box {
flex: 1;
min-width: 0;
height: 100%;
overflow-y: auto;
background-color: rgb(250, 250, 250);
box-sizing: border-box;
-webkit-overflow-scrolling: touch;
/* #ifdef APP-PLUS */
padding-bottom: calc(110rpx + env(safe-area-inset-bottom));
/* #endif */
/* #ifndef APP-PLUS */
padding-bottom: 0rpx;
/* #endif */
}
.page-view {
padding: 16rpx;
}
.class-item {
margin-bottom: 30rpx;
background-color: #fff;
padding: 16rpx;
border-radius: 8rpx;
&:last-child {
margin-bottom: 0;
}
}
.item-title {
font-size: 26rpx;
color: $u-main-color;
font-weight: bold;
}
.item-menu-name {
font-weight: normal;
font-size: 24rpx;
color: $u-main-color;
margin-top: 10rpx;
text-align: center;
word-break: break-all;
}
.item-container {
display: flex;
flex-wrap: wrap;
}
.thumb-box {
width: 33.333333%;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
margin-top: 20rpx;
}
.item-menu-image {
width: 110rpx;
height: 110rpx;
border-radius: 8rpx;
}
</style>