zhongtuanLitterButler/pages/index/categoryChange.vue

979 lines
22 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>
<!-- tabbar="/pages/index/category" :navbarStyle="template.style?.navbar" navbar="custom"-->
<s-layout navbar="normal" title="中团小管家" tabbar="/pages/index/category" :bgStyle="{ color: '#f7f7f7' }">
<view class="container">
<view class="search-box" :style="[{ top: Number(statusBarHeight + 85) + 'rpx' }]"
@click="toPage('/packageA/search/index?tab=2')">
<uni-section style="border-radius: 192rpx;height: 70rpx;width: 690rpx;margin: 0 auto;" type="line">
<uni-search-bar style="border-radius: 192rpx;" radius="23" placeholder="搜索您需要的信息" bgColor="#f8f8f8"
clearButton="none" cancelButton="none" :readonly="true" />
</uni-section>
</view>
<view class="header">
<!-- 轮播图 -->
<view class="swiper-box" v-if="bannerShow">
<view class="swiper_SS">
<swiper class="swiper_s" :circular="true" :autoplay="true" indicator-active-color="#0DAE11"
indicator-color="#ffffff" :indicator-dots="false" :current="swiperCurrent"
@animationfinish="swiperChange">
<!-- v-for="(item, index) in swiperList" :key="index" @click="openSwiper(item)"-->
<swiper-item style="margin: 0 auto;" v-for="(item, index) in bannerList" :key="index"
@click="swiperJump(item)">
<view style="position: relative;width: 100%;height: 100%;">
<!--<view class="fnon_tit"></view>
<view class="text">{{ item.title ? item.title : '' }}</view>
@click="click(item.url)" 跳转活动链接 -->
<image class="swiper-image" :src="item.image" mode="scaleToFill" />
</view>
</swiper-item>
<!-- <swiper-item style="margin: 0 auto;">
<view style="position: relative;width: 100%;height: 100%">
<!--<view class="fnon_tit"></view>
<view class="text">{{ item.title ? item.title : '' }}</view>
@click="click(item.url)" 跳转活动链接
<image class="swiper-image" src="/static/cart-empty.png" mode="scaleToFill" />
</view>
</swiper-item> -->
</swiper>
</view>
</view>
<view class="schoolCategory">
<!-- 左侧分类 -->
<view class="left-scrop" :style="[{ top: Number(statusBarHeight + homeTopFirst) + 'rpx' }]">
<scroll-view scroll-y :style="[{ height: (pageHeight - homeHightFirst) + 'px' }]"
:show-scrollbar="false">
<view class="menu-item ss-flex" v-for="(item, index) in firstCateList" :key="item.id"
:class="[{ 'menu-item-active': index == firstIndex }]" @tap="onMenu(item,index)"
:id="'item_' + item.id">
<!-- ss-line-1 -->
<view class="menu-title">
{{ item.name }}
</view>
</view>
</scroll-view>
</view>
<!-- 右侧分类 -->
<view class="goods-list-box" v-if="secondCateList.length">
<!-- 二级分类筛选框 -->
<view class="right-scrop">
<view class="selectSecBox" @click="selectSecShow = true">
<view
style="font-size: 30rpx;line-height: 32rpx;font-weight: bold;color: #3D3D3D;margin-right: 20rpx;">
{{ selectedItem.name ? selectedItem.name:'全部分类'}}
</view>
<image style="height: 32rpx;width: 32rpx;"
src="https://mall.jiangxiaoxian.hschool.com.cn/secondImage.png" mode="" />
</view>
</view>
<view class="right-bottom">
<!-- -->
<scroll-view scroll-y class="thirdScroll" :show-scrollbar="false" scroll-with-animation
:style="[{ height: (pageHeight - homeHightTwo) + 'px'}, {'padding-bottom': twoBottom + 'rpx' }]"
@scrolltolower="handleScroll" @scrolltoupper="handleScrollTop()" :scroll-top="rightScroll">
<view v-for="(e, w) in secondCateList" :key="e.id" class="thirdListBox" :id="'content_' + e.parent_id">
<view class="title-box ss-flex ss-col-center ss-row-between ss-p-b-30">
<view class="title-text">{{ e.name }}</view>
<button class="ss-reset-button more-btn" @click="toSecondCate(e, '0')">
查看更多
<text class="cicon-forward"></text>
</button>
</view>
<view class="goods-item-box ss-flex ss-flex-wrap ss-p-b-20">
<view class="goods-item" v-if="secondCateList[w].children.length>0"
v-for="(f, q) in secondCateList[w].children" :key="f.id"
@click="toSecondCate(e, q)">
<view>
<image class="goods-img" :src="f.image" mode="aspectFill">
</image>
<view class="" style="padding: 10rpx 0rpx;">
<view class="goods-title">{{ f.name }}</view>
</view>
</view>
</view>
</view>
</view>
</scroll-view>
</view>
</view>
</view>
</view>
<!-- 固定显示
<view class="car-show" v-show="!showLine" @click="getCarList">
<image @click="toPage('/pages/index/cart')" class="cart-image"
src="https://mall.jiangxiaoxian.hschool.com.cn/car.png" mode=""></image>
</view>-->
</view>
<!-- 下拉筛选二级分类 -->
<su-popup :show="selectSecShow == true" type="top" round="10" @close="selectSecShow = false"
@open="selectSecShow = true">
<view class="popup" :style="[{ top: Number(statusBarHeight + 75) + 'rpx' }]" style="">
<view class="secPopBox">
<scroll-view scroll-y="true" class="scrollBoxSec" :show-scrollbar="true">
<view class="grid-container">
<view class="secListbox" v-for="(item,index) in secSelectCateList" :key="item.id"
@click="handleSecSelect(item,index)">
<view v-if="item.name == '全部分类'"
:class=" item.name == selectedItem.name ? 'SelectedSecItem':'secItemAll'">
{{item.name}}
</view>
<view v-else :class=" item.id == selectedItem.id ? 'SelectedSecItem':'secItem'">
{{item.name}}
</view>
</view>
</view>
</scroll-view>
<view class="secBtns">
<view class="secReset" @click="resetSelect()">重置</view>
<view class="secSure" style="margin-left: 30rpx;" @click="sureSelect()">确认</view>
</view>
</view>
</view>
</su-popup>
</s-layout>
</template>
<script setup>
import {
computed,
ref,
reactive,
nextTick
} from 'vue';
import {
onLoad,
onShow,
onPageScroll,
onPullDownRefresh,
onReachBottom,
} from '@dcloudio/uni-app';
import {
consignee,
mobile,
address,
region
} from '@/sheep/validate/form';
import rent from '../../sheep/api/rent';
import sheep from '@/sheep';
import _ from 'lodash';
import {
baseUrl
} from '@/sheep/config';
// const template = computed(() => sheep.$store('app').template?.home);
const state = reactive({
categoryList: [],
activeMenu: '0',
pagination: {
data: [],
current_page: 1,
total: 1,
last_page: 1,
},
loadStatus: '',
});
const homeHightTwo = ref(210); //用来计算二级分类部分要减的高度
const homeHightFirst = ref(175); //用来计算计算一级要减的高度
const homeTopFirst = ref(535); //用来计算一级分类的top
const twoBottom = ref(0); //二级分类的底部内边距
const rightScroll = ref(0);//二级分类的滚动条的位置
const bannerShow = ref(true);//轮播图显示
// const homeTopTwo = ref();//用来计算二级分类的top
// 滚动到底部处理函数
function handleScroll(e) {
console.log('e', e);
homeHightTwo.value = 5
homeHightFirst.value = 40
homeTopFirst.value = 225
twoBottom.value = 100
bannerShow.value = false
setTimeout(() => {
rightScroll.value = 9999
},100)
}
// 滚动到顶部处理函数
function handleScrollTop(e) {
console.log('e', e);
homeHightFirst.value = 175
homeHightTwo.value = 220
homeTopFirst.value = 535
bannerShow.value = true;
setTimeout(() => {
rightScroll.value = 0
},100)
}
const searchValue = ref(null);
const {
screenHeight,
safeAreaInsets,
screenWidth,
safeArea
} = sheep.$platform.device;
const pageHeight = computed(() => safeArea.height - 44 - 150);
const statusBarHeight = sheep.$platform.device.statusBarHeight * 2;
const firstIndex = ref(0);
const secondIndex = ref(0);
const listQuery = ref({
page: 1,
limit: 1000,
keywords: null,
root: '',
parent_id: '',
})
const goodsCateCount = ref(0);
const homrS = ref(false);
const loadStatus = ref('');
onShow(() => {
getList();
getBanner();
selectSecShow.value = false;
})
//搜索
function onSearch(e) {
state.keyword = e;
emptyList();
getList(state.currentSort, state.currentOrder, state.categoryId, e);
}
const bannerList = ref([])
async function getBanner() {
const res = await sheep.$api.home.homeBanner({});
console.log('banner', res);
if (res.code == 1) {
bannerList.value = res.data.list
console.log('bannerList', bannerList.value);
}
}
const firstCateList = ref([]);
const secondCateList = ref([]);
const thirdCateList = ref([]);
//一级分类
async function getList() {
console.log('分类列表', firstIndex.value);
const res = await sheep.$api.goods.newList({
keywords: listQuery.value.keywords,
page: listQuery.value.page,
limit: listQuery.value.limit,
tree: '1',
parent_id: listQuery.value.parent_id,
root: listQuery.value.root,
});
console.log('getList', res.data[0]);
if (res.data) {
// firstCateList.value = [...firstCateList.value, ...res.data];
firstCateList.value = res.data[0].children;
secondCateList.value = firstCateList.value[firstIndex.value].children;
goodsCateCount.value = res.data.count;
getSecSelectData();
} else {
firstCateList.value = [];
}
console.log('getList', firstCateList.value, goodsCateCount.value);
}
//选择一级分类
function onMenu(item, val) {
console.log('选择一级分类val', val);
state.activeMenu = val;
firstIndex.value = val;
secondIndex.value = 0; // 重置二级索引
console.log('选择一级分类first', firstCateList.value[firstIndex.value]);
secondCateList.value = firstCateList.value[firstIndex.value].children;
console.log('二级分类secondCateList:', secondCateList.value);
nextTick(() => {
// 延迟执行滚动操作确保DOM完全渲染
setTimeout(() => {
uni.pageScrollTo({
selector: `#content_${item.id}`,
duration: 300,
offsetTop: -150 // 可以根据需要调整偏移量
});
}, 200); // 增加延迟时间确保DOM渲染完成
});
getSecSelectData();
// getSecond(firstCateList.value[val].id);
};
const secSelectCateList = ref([]); //二级筛选框
const selectSecShow = ref(false); //下拉框的显示隐藏
const selectedItem = ref({}); //选中的分类数据
const selectSecName = ref('');//选中的名字
function getSecSelectData() {
const items = [{
name: '全部分类',
id: '',
children: []
}]
secSelectCateList.value = [...items, ...secondCateList.value]
console.log('secSelectCateList', secSelectCateList.value);
}
function handleSecSelect(item, index) {
selectedItem.value = item;
selectSecName.value = item.name
console.log('item:', selectedItem.value);
}
//确定筛选的二级分类
function sureSelect() {
selectSecShow.value = false;
// firstIndex.value = 0;
secondCateList.value = [selectedItem.value];
console.log('定筛选的二级分类', secondCateList.value.children);
if (selectedItem.value.name != '全部分类') {
sheep.$api.goods.newList({
page: listQuery.value.page,
limit: listQuery.value.limit,
tree: '1',
parent_id: selectedItem.value.parent_id,
root: selectedItem.value.id,
}).then((res) => {
if (res.code == 1) {
console.log('res', res.data);
// secondCateList.value = res.data;
secondIndex.value = 0;
secondCateList.value[secondIndex.value].children = [...res.data];
} else {}
})
console.log('getList', );
} else {
getList();
}
}
//重置筛选二级分类
function resetSelect() {
selectedItem.value = {
name: '全部分类',
id: '',
children: []
};
console.log('重置', firstIndex.value);
}
//查看更多
function toSecondCate(e, index) {
console.log('列表数据');
console.log('查看更多e:', e.id, e.name, index);
// clog
if (e.children.length != 0) {
const thirdId = e.children[index].id;
console.log('查看更多-thirdId:', thirdId);
uni.navigateTo({
url: '/pages/goods/list?categoryId=' + thirdId + '&name=' + e.name
})
} else {
uni.navigateTo({
url: '/pages/goods/list?categoryId=' + e.id + '&name=' + e.name
})
}
}
onPullDownRefresh(async () => {
firstCateList.value = [];
// firstIndex.value = 0;
// secondIndex.value = 0;
uni.showLoading({
title: '加载中...'
});
console.log('下拉刷新触发');
await getList();
setTimeout(() => {
uni.hideLoading();
uni.stopPullDownRefresh();
}, 1500)
})
const toPage = (e) => {
uni.navigateTo({
url: e,
})
}
function searchGoods() {
console.log('搜索');
}
// 隐藏原生tabBar
uni.hideTabBar({
fail: () => {},
});
</script>
<style lang="scss" scoped>
.example-body {
/* #ifndef APP-NVUE */
display: block;
/* #endif */
padding: 0px;
}
.uni-mt-10 {
margin-top: 10px;
}
.title2 {
color: #3d3d3d;
font-size: 30rpx;
font-weight: 800;
line-height: 42rpx;
}
.title3 {
font-size: 20rpx;
font-weight: 400;
color: #999999;
line-height: 22rpx;
}
.container {
width: 100%;
height: 100%;
background-color: #ffffff;
scroll-behavior: smooth;
.search-box {
// width: 690rpx;
width: 100%;
height: 70rpx;
// background-color: #fff;
// margin-left: 30rpx;
position: fixed;
// top: 0;
z-index: 100;
display: flex;
justify-content: center;
align-items: center;
// padding-top: 30rpx;
// padding-bottom: 30rpx;
padding: 30rpx 0rpx;
background: linear-gradient(to bottom, #FCC74E, #D8D8D8);
}
.search-result {
padding-top: 10px;
padding-bottom: 20px;
text-align: center;
}
.search-result-text {
text-align: center;
font-size: 14px;
color: #666;
}
.header {
position: relative;
top: 132rpx;
width: 100%;
.swiper-box {
background: linear-gradient(to bottom, #D8D8D8, #ffffff);
width: 100%;
// padding: 0 30rpx;
// display: grid;
// justify-content: center;
height: 280rpx;
// position: relative;
padding-bottom: 30rpx;
.swiper_SS {
height: 280rpx;
width: 690rpx;
margin: 0 auto;
.swiper_s {
width: 100%;
height: 100%;
// display: grid;
// justify-content: center;
.swiper-image {
width: 100%;
height: 100%;
border-radius: 36rpx;
object-fit: contain;
}
}
}
}
}
.schoolCategory {
// display: flex;
justify-content: flex-start;
align-items: flex-start;
// background-color: #ffffff;
.left-scrop {
width: 200rpx;
height: 100%;
// padding-left: 12rpx;
background-color: #f6f6f6;
position: fixed;
left: 0;
.menu-item {
width: 100%;
height: 110rpx;
position: relative;
transition: all linear 0.2s;
.menu-title {
// width: 175rpx;
// height:70rpx;
line-height: 45rpx;
font-size: 30rpx;
font-weight: 400;
color: #333;
margin-left: 18rpx;
margin-right: 15rpx;
position: relative;
z-index: 10;
overflow: hidden;
// white-space: nowrap;
// text-overflow: ellipsis;
// padding: 10rpx 0;
padding: 10rpx;
&::before {
content: '';
width: 64rpx;
height: 12rpx;
background: linear-gradient(90deg,
var(--ui-BG-Main-gradient),
var(--ui-BG-Main-light)) !important;
position: absolute;
left: -64rpx;
bottom: 0;
z-index: -1;
transition: all linear 0.2s;
}
}
&.menu-item-active {
background-color: #fff;
border-radius: 20rpx 0 0 20rpx;
&::before {
content: '';
position: absolute;
right: 0;
bottom: -20rpx;
width: 20rpx;
height: 20rpx;
// background: radial-gradient(circle at 0 100%, transparent 20rpx, #fff 0);
}
&::after {
content: '';
position: absolute;
top: -20rpx;
right: 0;
width: 20rpx;
height: 20rpx;
background: radial-gradient(circle at 0% 0%, transparent 20rpx, #fff 0);
}
.menu-title {
font-weight: 600;
&::before {
left: 0;
}
}
}
}
}
.goods-list-box {
background-color: #fff;
width: calc(100vw - 210rpx);
// height: 110rpx;
// padding: 2rpx;
margin-left: 200rpx;
position: relative;
// top: 20rpx;
.right-scrop {
width: 100%;
height: 90rpx;
overflow: hidden;
// position: fixed;
// top: 74px;
background-color: #ffffff;
z-index: 10;
padding: 5rpx 0;
border-radius: 20rpx;
display: flex;
align-items: center;
justify-content: center;
.selectSecBox {
display: flex;
align-items: center;
justify-content: center;
width: 498rpx;
height: 80rpx;
background-color: #FFFBF1;
border: 2rpx solid #FCC74E;
border-radius: 12rpx;
margin-left: 20rpx;
}
.horizontal-scroll {
width: 95%;
height: 100%;
white-space: nowrap;
padding-left: 22rpx;
overflow: hidden;
// z-index: 10;
// display: flex;
// align-items: flex-start;
// padding: 0 20rpx; // 容器内边距
}
.menu-item2 {
display: inline-block;
margin-top: 20rpx;
margin-right: 30rpx;
height: 70rpx;
width: 180rpx;
text-align: center;
flex-shrink: 0; //防止压缩
// display: flex;
// align-items: center;
// justify-content: center;
// vertical-align: center;
.menuR-title {
width: 175rpx;
height: 70rpx;
border: 1rpx solid #999999;
border-radius: 158rpx;
line-height: 70rpx;
font-size: 28rpx;
font-weight: bold;
color: #999999;
text-align: center;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
background-color: #fff;
padding: 0 10rpx;
// padding: 0 0 0 20rpx;
}
.menuRselect-title {
width: 175rpx;
height: 70rpx;
border: 1rpx solid #FCC74E;
border-radius: 158rpx;
line-height: 70rpx;
font-size: 28rpx;
font-weight: bold;
color: #3d3d3d;
text-align: center;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
background-color: #FCC74E;
padding: 0 10rpx;
// padding: 0 0 0 20rpx;
}
}
}
.right-bottom {
// padding-top: 120rpx;
width: 100%;
// height: 500rpx;
overflow: hidden;
background-color: #fff;
z-index: 10;
.thirdScroll {
width: 100%;
// height: 100%;
white-space: nowrap;
// padding-left: 30rpx;
overflow: hidden;
.thirdListBox {
margin-left: 30rpx;
.title-box {
.title-text {
font-size: 28rpx;
font-weight: bold;
color: #333333;
}
.more-btn {
font-size: 26rpx;
font-weight: 400;
color: #999999;
}
}
.goods-item {
width: calc((100% - 20px) / 2);
margin-right: 10px;
margin-bottom: 20px;
&:nth-of-type(2n) {
margin-right: 0;
}
.goods-img {
width: calc((100vw - 150px) / 2);
height: calc((100vw - 150px) / 2);
border-radius: 18rpx;
}
.goods-title {
width: calc((100vw - 150px) / 2);
font-size: 30rpx;
font-weight: 500;
color: #333333;
text-align: center;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.goods-price {
color: $red;
line-height: 40rpx;
}
}
}
}
}
}
}
.car-show {
height: 80rpx;
position: fixed;
bottom: 200rpx;
right: 0;
.car-image {
width: 165rpx;
height: 78rpx;
}
.logo-image {
width: 67rpx;
height: 67rpx;
position: absolute;
top: -50rpx;
left: 80rpx;
}
.gou-image {
width: 30rpx;
height: 30rpx;
position: absolute;
top: 49%;
left: 30rpx;
transform: translateY(-50%);
}
.cart-image {
width: 80rpx;
height: 80rpx;
position: absolute;
top: 45%;
right: 20rpx;
transform: translateY(-50%);
}
}
}
.popup {
width: 750rpx;
height: 420rpx;
background-color: #ffffff;
position: fixed;
border-radius: 0rpx 0rpx 18rpx 18rpx;
.secPopBox {
width: 690rpx;
height: 250rpx;
padding: 30rpx;
.scrollBoxSec {
width: 100%;
height: 100%;
.grid-container {
display: grid;
grid-template-columns: repeat(3, 220rpx);
grid-template-rows: auto;
gap: 10rpx;
padding: 20rpx;
justify-content: center;
}
}
.secListbox {
width: 100%;
height: 100%;
.secItem {
width: 220rpx;
border-radius: 12rpx;
height: 70rpx;
background-color: #f7f7f7;
color: #999999;
font-size: 32rpx;
line-height: 32rpx;
display: flex;
justify-content: center;
align-items: center;
}
.secItemAll {
width: 220rpx;
border-radius: 12rpx;
height: 70rpx;
background-color: #f7f7f7;
color: #3d3d3d;
font-size: 32rpx;
line-height: 32rpx;
display: flex;
justify-content: center;
align-items: center;
}
.SelectedSecItem {
width: 216rpx;
border-radius: 12rpx;
height: 66rpx;
background-color: #FFFBF1;
border: 2rpx solid #FCC74E;
color: #323232;
font-size: 32rpx;
line-height: 32rpx;
display: flex;
justify-content: center;
align-items: center;
}
}
.secBtns {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
padding-top: 30rpx;
.secReset {
width: 330rpx;
height: 80rpx;
background-color: #FFFBF1;
border-radius: 217rpx;
display: flex;
justify-content: center;
align-items: center;
}
.secSure {
width: 330rpx;
height: 80rpx;
background: linear-gradient(to right, #FCCA58 100%, #FFBD25 100%);
border-radius: 217rpx;
display: flex;
justify-content: center;
align-items: center;
}
}
}
}
</style>