344 lines
9.9 KiB
Vue

<template>
<view class="page flex flex-col">
<!-- 固定搜索框 -->
<view class="fixed-search-bar">
<SearchBar :placeholders="'搜索酒款/品牌'" :bgcolor="'#19367A'" :borderRs="'0px 0px 24rpx 24rpx'"/>
</view>
<!-- 热门厂牌和我的关注 -->
<view class="hot-header" v-if="hotflag">
<view class="flex align-center hot-center">
<view class="" style="margin-left: 24rpx;" @click="hotClick('1')" :class="hotActives=='1'?'hot-actives':''">
<view class="">热门厂牌</view>
</view>
<view class="" style="color: #E0E0E0;margin-left: 20rpx;">|</view>
<view style="margin-left: 24rpx;" @click="hotClick('2')" :class="hotActives=='2'?'hot-actives':''">
<view class="">我的关注</view>
</view>
</view>
</view>
<!-- 热门厂牌列表 -->
<!-- <view class="hot-bom flex align-center justify-between flex-wrap" v-if="hotflag">
<view class="" v-for="it in 8" style="width: 25%;text-align: center;">
<view class="">
<image src="@/static/fengwei.png" mode="" style="width: 88rpx;height: 88rpx;"></image>
</view>
<view class="" style="font-size: 28rpx;margin: 16rpx 0 12rpx 0;">风味屋</view>
</view>
</view> -->
<!-- 联系人列表和索引栏 -->
<view class="container" :style="{ height: containerHeight + 'px',}" :class="hotflag?'':'hot-act'">
<scroll-view scroll-y :scroll-into-view="scrollIntoView" class="list" @scroll="handleScroll">
<view class="hot-bom flex align-center justify-between flex-wrap" v-if="hotflag">
<view class="" v-for="it in 8" style="width: 25%;text-align: center;">
<view class="">
<image src="@/static/bg/fengwei.png" mode="" style="width: 88rpx;height: 88rpx;"></image>
</view>
<view class="" style="font-size: 28rpx;margin: 16rpx 0 12rpx 0;">风味屋</view>
</view>
</view>
<view v-for="(group, letter) in groupedData" :key="letter" :id="letter">
<view class="group-title">
{{ letter }}
<!-- 自定义 switch -->
<view class="flex align-center" v-if="currentVisibleLetter === letter">
<view class="" style="font-size: 24rpx;color: #606060;margin-right: 15rpx;">只看在售</view>
<!-- :class="{ 'switch-on': isOnSaleFilter[letter], 'switch-off': !isOnSaleFilter[letter] }"
@click="toggleFilter(letter)" -->
<view
class="custom-switch"
:class="{ 'switch-on': isOnSaleFilter, 'switch-off': !isOnSaleFilter }"
@click="toggleGlobalFilter"
>
<view class="switch-thumb"></view>
</view>
</view>
</view>
<view v-for="(item, index) in group" :key="index" class="contact-item">
<view class="">
<image src="@/static/logouts.png" style="width:88rpx;height: 88rpx;" mode=""></image>
</view>
<text style="margin-left: 52rpx;font-size: 28rpx;">{{ item.name }}</text>
</view>
</view>
</scroll-view>
<!-- 字母索引栏 -->
<view class="index-bar">
<view v-for="letter in indexLetters" :key="letter" @tap="scrollToGroup(letter)"
:class="{ 'active-letter': activeLetter === letter }">
{{ letter }}
</view>
</view>
</view>
</view>
</template>
<script>
import { getLastSixMonth, getNewBeerListByMonth, popularStyle } from "@/api/platform.js";
import CustomNavBar from '@/components/CustomNavBar.vue';
import SearchBar from '@/components/SearchBar.vue';
export default {
components: {
CustomNavBar,
SearchBar
},
data() {
return {
dataList: [],
currentMonth: [],
currentMonthIndex: 0,
popularStyleList: [],
queryForm: {
num: null,
},
bgcolor: '#19367A',
containerHeight: 0, // 动态计算的容器高度
rawGroupedData: [
{ name: "Alice", phone: "123456789", group: "A", isOnSale: true },
{ name: "Alice1", phone: "123456789", group: "A", isOnSale: false },
{ name: "Bob", phone: "987654321", group: "B", isOnSale: true },
{ name: "Bob1", phone: "987654321", group: "B", isOnSale: false },
{ name: "Charlie", phone: "555555555", group: "C", isOnSale: true },
{ name: "David", phone: "111111111", group: "D", isOnSale: true },
{ name: "Eve", phone: "222222222", group: "E", isOnSale: true },
{ name: "Frank", phone: "333333333", group: "F", isOnSale: true },
{ name: "Grace", phone: "444444444", group: "G", isOnSale: true },
{ name: "Hank", phone: "555555555", group: "H", isOnSale: true },
{ name: "Ivy", phone: "666666666", group: "I", isOnSale: true },
{ name: "Jack", phone: "777777777", group: "J", isOnSale: true },
],
scrollIntoView: "", // 当前滚动到的分组
isOnSaleFilter: {},
originalGroupedData: {},
activeLetter: "", // 当前选中的字母
hotActives: '1',
hotflag:true,
currentVisibleLetter: null,
isOnSaleFilter: false,
};
},
computed: {
// 按字母分组
groupedData() {
const grouped = this.rawGroupedData.reduce((acc, item) => {
const group = item.group;
if (!acc[group]) acc[group] = [];
acc[group].push(item);
return acc;
}, {});
// // 应用过滤条件
// Object.keys(grouped).forEach((letter) => {
// if (this.isOnSaleFilter[letter]) {
// grouped[letter] = grouped[letter].filter((item) => item.isOnSale);
// }
// });
// 如果全局过滤开关开启,过滤全部数据
if (this.isOnSaleFilter) {
Object.keys(grouped).forEach((letter) => {
grouped[letter] = grouped[letter].filter((item) => item.isOnSale);
});
}
return grouped;
},
// 字母索引
indexLetters() {
return Object.keys(this.groupedData).sort();
},
},
methods: {
hotClick(ind) {
this.hotActives = ind;
},
toggleGlobalFilter() {
this.isOnSaleFilter = !this.isOnSaleFilter;
},
handleScroll(e) {
const scrollTop = e.detail.scrollTop;
if (scrollTop < 2) {
this.hotflag = true; // 滚动到顶部时显示热门厂牌内容
}
},
// 获取热门风格
// getPopularStyle() {
// popularStyle().then((res) => {
// console.log(res);
// this.popularStyleList = res.data;
// });
// },
// getLastSixMonthFun() {
// getLastSixMonth().then((res) => {
// console.log(res);
// this.dataList = res.data;
// this.queryForm.num = 0;
// this.getNewBeerListByMonthFun();
// });
// },
// 点击字母滚动到对应分组
scrollToGroup(letter) {
this.scrollIntoView = letter;
this.activeLetter = letter;
this.hotflag = false
this.currentVisibleLetter = letter; // 更新当前显示“只看在售”的字母
},
// 动态计算容器高度
calculateContainerHeight() {
const systemInfo = uni.getSystemInfoSync();
const searchBarHeight = 120; // 搜索框高度
const hotHeaderHeight = 90; // 热门厂牌和我的关注高度
const hotBomHeight = 200; // 热门厂牌列表高度(根据实际内容调整)
this.containerHeight = systemInfo.windowHeight - searchBarHeight - hotHeaderHeight - hotBomHeight;
},
// 切换开关状态
toggleFilter(letter) {
this.$set(this.isOnSaleFilter, letter, !this.isOnSaleFilter[letter]);
},
},
mounted() {
// 初始化原始数据副本
this.originalGroupedData = JSON.parse(JSON.stringify(this.groupedData));
this.calculateContainerHeight();
this.currentVisibleLetter = this.indexLetters[0];
},
};
</script>
<style scoped lang="scss">
.page {
display: flex;
flex-direction: column;
height: 100vh;
font-family: Roboto;
}
.fixed-search-bar {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 1000;
background-color: #fff; // 根据需要设置背景色
}
.hot-header {
margin-top: 120rpx; // 搜索框高度
}
.hot-center {
height: 90rpx;
color: #606060;
font-size: 24rpx;
background: #FFFFFF;
}
.hot-actives {
font-size: 28rpx;
font-weight: 600;
color: #030303;
}
.hot-bom {
padding: 0 24rpx;
background: #FFFFFF;
}
.container {
flex: 1;
display: flex;
}
.list {
flex: 1;
height: 100%;
}
.group-title {
padding: 10px;
background-color: #f9f9f9;
font-weight: bold;
display: flex;
align-items: center;
justify-content: space-between;
}
.contact-item {
background: #FFFFFF;
padding: 10px;
border-bottom: 1px solid #eee;
display: flex;
align-items: center;
}
.index-bar {
width: 20px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: #f8f8f8;
}
.index-bar view {
padding: 2px 0;
font-size: 12px;
cursor: pointer;
border-radius: 50%; /* 圆形背景 */
width: 20px;
height: 20px;
display: flex;
align-items: center;
justify-content: center;
transition: background-color 0.3s;
}
.index-bar view.active-letter {
background-color: #D42E78; /* 选中字母的背景色 */
color: white; /* 选中字母的文字颜色 */
}
/* 自定义 switch 样式 */
.custom-switch {
width: 50rpx;
height: 28rpx;
border-radius: 14rpx;
position: relative;
cursor: pointer;
transition: background-color 0.3s;
-webkit-tap-highlight-color: transparent; /* 移除点击高亮 */
user-select: none; /* 禁止文本选择 */
}
.switch-on {
background-color: #D42E78; /* 开启状态颜色(蓝色) */
}
.switch-off {
background-color: #e5e5e5; /* 关闭状态颜色 */
}
.switch-thumb {
width: 24rpx;
height: 24rpx;
background-color: white;
border-radius: 12rpx;
position: absolute;
top: 2rpx;
transition: left 0.3s;
}
.switch-on .switch-thumb {
left: 24rpx; /* 开启状态滑块位置 */
}
.switch-off .switch-thumb {
left: 2rpx; /* 关闭状态滑块位置 */
}
.hot-act{
padding-top: 120rpx;
}
</style>