Files
2026-03-31 21:59:42 +08:00

323 lines
13 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.

<!-- 使用 type="home" 属性设置首页其他页面不需要设置默认为page -->
<route lang="jsonc" type="page">{
"needLogin": true,
"layout": "tabbar",
"style": {
"navigationStyle": "custom"
}
}</route>
<template>
<view class="home-bg">
<view class="home-bg w-[100%] sticky top-0 left-0 z-100">
<wd-navbar safeAreaInsetTop :bordered="false" custom-style="background-color: #fff !important;">
<template #left>
<view class="flex items-center" @click="List.handleBack">
<view class="mt-4rpx">
<wd-icon name="thin-arrow-left" size="30rpx" color="#121212"></wd-icon>
</view>
<view class="text-[#303133] text-36rpx ml-24rpx leading-48rpx">预约茶艺师</view>
</view>
</template>
</wd-navbar>
<view class="search-box px-30rpx pb-10rpx pt-20rpx bg-[#fff]">
<view class="w-full h-72rpx bg-[#F6F7F8] rounded-36rpx flex items-center pl-30rpx pr-6rpx">
<wd-icon name="search" size="32rpx" color="#C0C4CC"></wd-icon>
<input type="text" class="flex-1 ml-16rpx text-28rpx h-full bg-transparent" placeholder="茶艺师名称"
placeholder-style="color: #C0C4CC" v-model="keywords" @confirm="List.handleSearch"
confirm-type="search" />
<view
class="w-142rpx h-60rpx flex justify-center items-center rounded-30rpx bg-[#4C9F44] text-[#fff] text-28rpx"
@click="List.handleSearch">
搜索
</view>
</view>
</view>
</view>
<!-- 团体茶艺师预购 -->
<view class="flex items-center justify-center pt-20rpx bg-[#fff] pb-28rpx"
@click="router.navigateTo('/bundle/reserve-group/reserve-group')">
<wd-img :src="`${OSS}images/teaspecialist/image1.png`" width="690rpx" height="320rpx"></wd-img>
</view>
<!-- 茶艺师列表 -->
<view class="level-bg pt-28rpx">
<!-- 茶艺师等级筛选 -->
<view
class="flex items-center text-#303133 overflow-x-auto whitespace-nowrap ml-30rpx mb-30rpx tea-level-scrollbar">
<view v-for="(item, index) in TeaSpecialistLevels" :key="index"
class="h-64rpx rounded-12rpx px-24rpx py-12rpx flex items-center justify-center font-400 text-28rpx mr-20rpx"
:class="selectedLevel.includes(item.level) ? 'border-2rpx border-solid border-[#4C9F44] text-[#4C9F44] bg-[#fff]' : 'bg-[#FFF] text-[#606266]'"
@click="List.handleToggleTeaSpecialistLevel(item.level)">
{{ item.label }}
</view>
</view>
<mescroll-body @init="mescrollInit" @down="downCallback" :down="downOption" @up="List.upCallback"
:up="upOption" fixed>
<view class="flex items-center bg-white p-20rpx rounded-10rpx mx-30rpx mb-20rpx relative"
v-for="(item, index) in list" :key="index">
<view
class="tea-specialist-time absolute z-3 top-6rpx left-0 bg-[#4C9F44] text-[#fff] font-400 text-18rpx flex items-center justify-center">
<text v-if="item.state == 0">可约</text>
<text v-if="item.state == 1">工作中</text>
<text v-if="item.state == 2">不可约</text>
</view>
<view class="mr-28rpx relative z-2" @click="List.handlePreviewImage(item.image)">
<wd-img width="200rpx" height="200rpx" :src="item.image" mode="aspectFill"></wd-img>
</view>
<view class="flex-1" @click="List.handleReserveTeaSpecialist(item.team_user_id, item.state)">
<view class="flex items-center">
<view class="font-bold text-[#303133] text-30rpx leading-42rpx mr-14rpx">
{{ item.name }}
</view>
<view class="flex items-center">
<wd-icon name="star-on" size="22rpx" color="#FF5951"></wd-icon>
<view class="font-400 text-24rpx text-[#FF5951] leading-34rpx ml-6rpx">5.0</view>
<!-- <tea-specialist-level :level="item.level"></tea-specialist-level> -->
</view>
</view>
<view class="flex items-center">
<!-- 到店服务标签 -->
<view class="mr-12rpx" v-if="item.server_type == 1 || item.server_type == 3">
<wd-tag color="#F55726" bg-color="#F55726" plain
custom-class="!rounded-4rpx">到店服务</wd-tag>
</view>
<!-- 上门服务标签 -->
<view class="mr-12rpx" v-if="item.server_type == 2 || item.server_type == 3">
<wd-tag color="#40AE36" bg-color="#40AE36" plain
custom-class="!rounded-4rpx">上门服务</wd-tag>
</view>
<view class="mr-12rpx">
<wd-tag color="#818CA9" bg-color="#F3F3F3">{{ item.both }}岁</wd-tag>
</view>
<view class="flex items-center mt-8rpx">
<wd-img :src="item.sex == 1 ? `${OSS}icon/icon_man.png` : `${OSS}icon/icon_woman.png`"
width="28rpx" height="28rpx"></wd-img>
</view>
</view>
<view class="flex flex-wrap items-center mt-14rpx">
<view
class="mr-8rpx bg-[#4C9F44] text-[#fff] px-10rpx leading-34rpx font-400 text-24rpx rounded-4rpx"
v-for="(label, index) in item.label" :key="index">
{{ label.label_name }}
</view>
</view>
<view class="flex items-center justify-between mt-18rpx">
<view class="mr-20rpx w-200rpx">
<view class="flex items-center">
<view class="flex items-center">
<wd-img :src="`${OSS}icon/icon_store_cert.png`" width="36rpx"
height="36rpx"></wd-img>
</view>
<text class="ml-8rpx font-400 text-24rpx leading-4rpx text-#303133">商家认证</text>
</view>
</view>
<view class="flex items-center font-400 text-24rpx leading-34rpx text-#92928C">距您{{
item.distance
}}km</view>
</view>
<view
class="font-400 text-[#FF5951] text-26rpx leading-40rpx flex items-center justify-between mt-4rpx">
<view class="">
<text class="text-32rpx">{{ item.price }}</text>
<text class="text-24rpx">/小时</text>
</view>
<view class="font-400 text-22rpx leading-32rpx text-#92928C">{{ item.is_time }}</view>
</view>
</view>
</view>
</mescroll-body>
</view>
</view>
</template>
<script lang="ts" setup>
import { useToast } from 'wot-design-uni'
import { onPageScroll, onReachBottom } from '@dcloudio/uni-app'
import useMescroll from "@/uni_modules/mescroll-uni/hooks/useMescroll.js"
import { router, previewImage } from '@/utils/tools'
import { getTeaSpecialist } from '@/api/tea-specialist'
import TeaSpecialistLevel from '@/components/TeaSpecialistLevel.vue'
import type { ITeaSpecialistResult } from '@/api/types/tea-specialist'
import { TeaSpecialistLevelValue, TeaSpecialistLevels } from '@/utils/teaSpecialist'
const OSS = inject('OSS')
const navbarHeight = inject('navbarHeight')
const toast = useToast()
// 茶艺师等级
const selectedLevel = ref<Array<any>>([]) // 选择茶艺师的点击等级
// mescroll
const { mescrollInit, downCallback, getMescroll } = useMescroll(onPageScroll, onReachBottom) // 调用mescroll的hook
const downOption = {
auto: true
}
const upOption = {
empty: {
icon: OSS + 'icon/icon_reserver_empty.png',
tip: '暂无预约信息',
},
auto: true,
textNoMore: '~ 已经到底啦 ~', //无更多数据的提示
}
const orderStatus = ref<string>('')
const list = ref<Array<any>>([]) // 茶室列表
const keywords = ref<string>('') // 搜索关键词
onLoad(async () => {
uni.$on('refreshTeaSpecialist', () => {
list.value = []
getMescroll().resetUpScroll()
})
})
onUnload(() => {
uni.$off('refreshTeaSpecialist')
})
// 茶室分享(仅页面右上角分享,无需按钮分享)
onShareAppMessage(() => {
return {
title: '茶艺师列表',
path: `/bundle_b/pages/tea-specialist/list`,
}
})
const List = {
/**
* 筛选表
*/
upCallback: (mescroll) => {
const filter = {
level: selectedLevel.value.join(',') || '',
page: mescroll.num,
size: mescroll.size,
latitude: uni.getStorageSync('latitude') || import.meta.env.VITE_DEFAULT_LATITUDE,
longitude: uni.getStorageSync('longitude') || import.meta.env.VITE_DEFAULT_LONGITUDE,
search: keywords.value
}
getTeaSpecialist(filter).then((res: ITeaSpecialistResult) => {
const curPageData = res.list || [] // 当前页数据
if (mescroll.num == 1) list.value = [] // 第一页需手动制空列表
list.value = list.value.concat(curPageData) //追加新数据
mescroll.endSuccess(curPageData.length, Boolean(res.more))
}).catch(() => {
mescroll.endErr() // 请求失败, 结束加载
})
},
/**
* 预约茶艺师
* @param id
* @param state 茶艺师状态: 0可约 1工作中
*/
handleReserveTeaSpecialist: (id: number, state: number) => {
router.navigateTo(`/bundle_b/pages/tea-specialist/detail?id=${id}`)
},
/**
* 获取茶艺师等级
* @param value
*/
handleToggleTeaSpecialistLevel: (value: any) => {
const index = selectedLevel.value.indexOf(value);
if (index > -1) {
// 如果已经选择了该等级,则取消选择
selectedLevel.value.splice(index, 1);
} else {
// 如果未选择该等级,则添加选择
selectedLevel.value.push(value);
}
List.handleSearch()
},
/**
* 搜索茶艺师列表
*/
handleSearch: () => {
list.value = []
getMescroll().resetUpScroll()
},
/**
* 分享的页面没有栈所以需要switch方法跳转
*/
handleBack: () => {
router.navigateBack().catch(err => {
router.switchTab('/pages/index/index')
})
},
/**
* 预览图片
*/
handlePreviewImage: (img: any) => {
previewImage(img, [img])
}
}
</script>
<style lang="scss">
page {
background-color: $cz-page-background;
}
.home-bg {
background-color: $cz-page-background;
// background-image: url(#{$OSS}images/home/home_bg.png);
background-size: 100%;
background-repeat: no-repeat;
}
.search-box {
:deep() {
.wd-search {
background: #fff !important;
}
.wd-search__search-left-icon {
color: #999 !important;
}
}
}
.ele-center {
left: 50%;
transform: translateX(-50%);
}
// 隐藏横向滚动条
.tea-level-scrollbar {
&::-webkit-scrollbar {
display: none;
-ms-overflow-style: none;
scrollbar-width: none;
}
}
.tea-specialist-time {
border-radius: 0rpx 50rpx 50rpx 0rpx;
min-width: 80rpx;
height: 38rpx;
}
.level-bg {
background: linear-gradient(180deg, #E9FFF1 0%, #F6F7F8 100%) no-repeat;
background-size: 100% 220rpx;
border-radius: 20rpx 20rpx 0rpx 0rpx;
}
</style>