添加页面

This commit is contained in:
wangxiaowei
2025-12-13 17:15:30 +08:00
parent 0ab8464612
commit 775a93f766
22 changed files with 1329 additions and 432 deletions

View File

@ -9,121 +9,126 @@
}</route>
<template>
<view class="home-bg">
<view class="home-bg pb-80rpx">
<view class="home-bg w-[100%] fixed top-0 left-0 z-100">
<wd-navbar safeAreaInsetTop :bordered="false" custom-style="background-color: transparent !important;">
<template #left>
<view class="flex items-center line-1 w-130rpx" @click="Index.handleToCity">
<view class="mr-10rpx font-400 leading-44rpx text-32rpx pl-10rpx line-1">{{ city || LOCATION_DEFAULT_CITY }}</view>
<view class="flex items-center line-1 w-450rpx" @click="router.navigateTo('/bundle/account/switch')">
<view class="mr-10rpx font-400 leading-44rpx text-32rpx pl-10rpx line-1">茶址24小时智能茶室(中新店)</view>
<wd-img width="14rpx" height="9rpx" :src="`${OSS}icon/icon_arrow_down.png`" />
</view>
</template>
<template #title>
<view class="search-box flex items-center ml-26rpx" @click="Index.handleToSearch">
<wd-search placeholder="搜索茶址名称" hide-cancel disabled :placeholder-left="true"
placeholderStyle="text-align:left;padding-left: 24rpx;line-heigt: 44rpx;color: #C9C9C9; font-size: 32rpx;font-weight: normal;">
</wd-search>
</view>
</template>
</wd-navbar>
</view>
<view :style="{ paddingTop: navbarHeight + 'px' }">
<view class="mt-32rpx mx-30rpx">
<wd-swiper height="240rpx" indicatorPosition="bottom-left"
:indicator="{ type: 'dots-bar' }" :list="swiperList" v-model:current="current" mode="aspectFit"></wd-swiper>
</view>
<view class="mt-32rpx mx-30rpx relative">
<wd-img width="690rpx" height="240rpx" :src="`${OSS}images/store/home/image1.png`" mode="aspectFit" />
<view class="mt-40rpx flex items-center h-36rpx mx-30rpx">
<wd-img width="160rpx" height="36rpx" :src="`${OSS}images/home/home_image1.png`" mode="aspectFit" />
<text class="text-22rpx leading-32rpx text-[#818CA9] ml-36rpx">更多茶艺师点击预约</text>
</view>
<!-- 本月收入 -->
<view class="flex flex-col justify-center items-center absolute top-42rpx left-46rpx">
<view class="font-400 text-26rpx text-[#825F37] leading-36rpx">本月收入</view>
<view class="mt-42rpx">
<price-format color="#825F37" :first-size="36" :second-size="36" :subscript-size="24" :price="23.02"></price-format>
</view>
</view>
<view class="mt-16rpx relative w-690rpx h-180rpx mx-30rpx" @click="Index.handleToWxOfficialAccount">
<wd-img width="690rpx" height="180rpx" :src="`${OSS}images/home/home_image2.png`" mode="scaleToFill" />
<view class="h-64rpx absolute bottom-0 right-0 bg-[#4C9F44] text-[#fff] flex items-center px-26rpx rounded">
<text class="mr-8rpx">一键约</text>
<wd-img width="22rpx" height="18.06rpx" :src="`${OSS}icon/icon_arrow_right.png`" mode="aspectFit" />
<view class="absolute top-42rpx left-174rpx">
<wd-img width="6rpx" height="188rpx" :src="`${OSS}images/store/home/image2.png`" mode="aspectFit" />
</view>
<!-- 下单金额 -->
<view class="flex flex-col justify-center items-center absolute top-42rpx left-208rpx">
<view class="font-400 text-26rpx text-[#825F37] leading-36rpx">下单金额</view>
<view class="mt-26rpx">
<price-format color="#825F37" :first-size="36" :second-size="36" :subscript-size="24" :price="23.02"></price-format>
</view>
<view class="font-400 text-24rpx text-[#825F37] leading-34rpx mt-10rpx">昨日223</view>
</view>
<!-- 核销金额 -->
<view class="flex flex-col justify-center items-center absolute top-42rpx left-368rpx">
<view class="font-400 text-26rpx text-[#825F37] leading-36rpx">核销金额</view>
<view class="mt-26rpx">
<price-format color="#825F37" :first-size="36" :second-size="36" :subscript-size="24" :price="23.02"></price-format>
</view>
<view class="font-400 text-24rpx text-[#825F37] leading-34rpx mt-10rpx">昨日223</view>
</view>
</view>
<view class="relative mt-40rpx h-44rpx mx-30rpx">
<view class="absolute ele-center" >
<wd-img width="252.04rpx" height="24.43rpx" :src="`${OSS}images/home/home_image3.png`" mode="aspectFit" />
<!-- 菜单栏 -->
<view class="flex justify-between mt-40rpx">
<view class="flex flex-col justify-center items-center w-[25%]" @click="showScanMenu = true">
<wd-img width="90rpx" height="90rpx" :src="`${OSS}images/store/home/image3.png`" mode="aspectFit" />
<view class="font-400 text-24rpx text-[#303133] leading-34rpx">扫码验券</view>
</view>
<view class="flex flex-col justify-center items-center w-[25%]" @click="router.navigateTo('/bundle/finance/finance')">
<wd-img width="90rpx" height="90rpx" :src="`${OSS}images/store/home/image4.png`" mode="aspectFit" />
<view class="font-400 text-24rpx text-[#303133] leading-34rpx">财务管理</view>
</view>
<view class="flex flex-col justify-center items-center w-[25%]">
<wd-img width="90rpx" height="90rpx" :src="`${OSS}images/store/home/image5.png`" mode="aspectFit" />
<view class="font-400 text-24rpx text-[#303133] leading-34rpx">套餐管理</view>
</view>
<view class="flex flex-col justify-center items-center w-[25%]">
<wd-img width="90rpx" height="90rpx" :src="`${OSS}images/store/home/image6.png`" mode="aspectFit" />
<view class="font-400 text-24rpx text-[#303133] leading-34rpx">用户列表</view>
</view>
<view class="text-32rpx text[#303133] font-500 absolute top-0 ele-center">预约茶室</view>
</view>
<view>
<mescroll-body @init="mescrollInit" :down="downOption" @down="downCallback" :up="upOption" @up="Index.upCallback" top="28rpx"
:fixed="true">
<view class="relative p-20rp mb-24rpx" v-for="(item, index) in list" :key="index" @click="Index.handleToReserveRoom(item.id, item.operation_type)">
<view class="absolute top--28rpx left-0 z-1" v-if="item.operation_type == 1">
<wd-img width="110rpx" height="110rpx" :src="`${OSS}images/home/home_image4.png`"/>
</view>
<view class="mx-30rpx p-30rpx flex bg-white rounded-10rpx">
<wd-img width="200rpx" height="200rpx" :src="item.image" radius="10rpx" />
<view class="flex-1 ml-28rpx flex justify-between line-1 items-start relative">
<view class="line-1">
<view class="font-bold text-30rpx leading-42rpx line-1">
{{ item.name }}
</view>
<view class="flex items-center mt-12rpx leading-34rpx">
<view class="font-400 text-[#F29747] text-24rpx mr-18rpx">半年预约{{ item.half_year_nums > 10 ? item.half_year_nums + '+' : item.half_year_nums }}</view>
<view class="font-400 bg-[#F3F3F3] text-[#818CA9] text-22rpx px-8rpx rounded-4rpx">刚有人预约了</view>
</view>
<view class="flex items-center mt-12rpx leading-34rpx">
<view class="font-400 text-[#606266] text-24rpx mr-10rpx">
营业时间:{{ item.start_time }}-{{ item.end_time }}
</view>
<view class="font-400 bg-[#FFEEED] text-[#FF5951] text-22rpx px-4rpx rounded-4rpx border-[#F2E2E1]" v-if="item.shop_status == 0">
打烊了
</view>
</view>
<view class="flex items-center mt-20rpx">
<wd-img width="26rpx" height="26rpx" :src="`${OSS}icon/icon_location.png`"
mode="aspectFit" />
<view class="ml-4rpx line-1 font-400 text-22rpx text-[#606266] leading-32rpx">
{{ item.address }}
</view>
</view>
</view>
<view class="absolute bottom-0 right-0">
<view class="flex justify-end">
<view class="bg-[#4C9F44] w-72rpx h-40rpx rounded-18rpx flex items-center justify-center">
<wd-icon name="add" color="#fff" size="20rpx" custom-style="font-weight: bold;" />
</view>
</view>
<view class="text-24rpx text-[#92928C] font-400 mt-12rpx">距您{{ item.distance }}km</view>
</view>
<!-- 商家培训 -->
<view class="bg-white rounded-16rpx px-30rpx py-28rpx mx-30rpx mt-40rpx">
<view class="flex items-center justify-between">
<view class="flex items-center">
<wd-img width="48rpx" height="48rpx" :src="`${OSS}images/store/home/image7.png`" mode="aspectFit" />
<view class="flex items-center ml-10rpx">
<view class="text-32rpx text-[#303133] leading-44rpx">商家培训</view>
<view class="">
<wd-divider vertical color="#D9D9D9"></wd-divider>
</view>
<view class="font-400 text-24rpx text-[#909399] leading-34rpx">商家运营赋能</view>
</view>
</view>
</mescroll-body>
<view class="">
<text class="font-400 text-24rpx text-[#909399] leading-34rpx">更多</text>
<wd-icon name="arrow-right" size="20rpx" color="#C9C9C9" class="ml-4rpx"></wd-icon>
</view>
</view>
<view class="mt-30rpx">
<view v-for="i in 4" :key="i">
<view class="flex items-center justify-between">
<view class="mr-26rpx">
<view class="font-400 text-26rpx text-[#303133] leading-40rpx w-440rpx line-2">必备课如何做好门店评价管理客户为什么给好评</view>
<view class="font-400 text-22rpx text-[#909399] leading-32rpx">2025-08-09 17:21</view>
</view>
<view>
<wd-img width="164rpx" height="108rpx" radius="4rpx" :src="`${OSS}images/banner1.png`" mode="aspectFit" />
</view>
</view>
<view class="mt-22rpx mb-30rpx" v-if="i !== 4">
<wd-gap bg-color="#F6F7F9" height="2rpx"></wd-gap>
</view>
</view>
</view>
</view>
</view>
<!-- 扫码验券弹出框 -->
<wd-action-sheet v-model="showScanMenu" :actions="scanActions" @select="Index.handleSelectScanMenu" />
</view>
</template>
<script lang="ts" setup>
import { router } from '@/utils/tools'
import { onPageScroll, onReachBottom } from '@dcloudio/uni-app'
import useMescroll from "@/uni_modules/mescroll-uni/hooks/useMescroll.js"
import { LOCATION_DENY_TIME_KEY, handleEnsureLocationAuthHooks, LOCATION_DEFAULT_CITY, handleGetLocationCity, LOCATION_CITY_KEY } from '@/hooks/useLocation'
import { getHomeBannerList } from '@/api/home'
import { getHomeTeaStoreList } from '@/api/tea-room'
import { useUserStore } from '@/store'
const OSS = inject('OSS')
const navbarHeight = inject('navbarHeight')
/** 轮播图 **/
const swiperList = ref<string[]>([])
const current = ref<number>(0)
// 分页
const { mescrollInit, downCallback, getMescroll } = useMescroll(onPageScroll, onReachBottom) // 调用mescroll的hook
const downOption = {
auto: true
}
@ -131,171 +136,63 @@
auto: true,
textNoMore: '~ 已经到底啦 ~', //无更多数据的提示
}
const latitude = ref<number>(0)
const longitude = ref<number>(0)
const city = ref<string>('')
const keywords = ref<string>('')
const list = ref<Array<any>>([])
let lastLocation = { lat: 0, lng: 0 }
onShow(async () => {
if (uni.getStorageSync(LOCATION_DENY_TIME_KEY)) {
const location = await checkLocationAuthWithModal()
if (location) {
// 只有经纬度变化时才刷新
if (location.lat !== lastLocation.lat || location.lng !== lastLocation.lng) {
const loc = await handleGetLocationCity(location.lat, location.lng)
city.value = loc.city
latitude.value = location.lat
longitude.value = location.lng
lastLocation.lat = location.lat
lastLocation.lng = location.lng
console.log("🚀 ~ city.value:", 'xxxxx', city.value)
Index.handleResetSearch()
}
}
// 扫码验券弹出框
const showScanMenu = ref<boolean>(false)
const scanActions = ref([
{
name: '扫码验券',
},
{
name: '输入券码',
},
{
name: '验券记录',
}
})
])
onLoad(async() => {
// 初始化页面数据
Index.handleInit()
// 获取用户经纬度(带缓存和授权逻辑)
const { lat, lng } = await handleEnsureLocationAuthHooks()
latitude.value = lat
longitude.value = lng
const location = await handleGetLocationCity(lat, lng)
city.value = location.city
latitude.value = location.latitude
longitude.value = location.longitude
Index.handleResetSearch()
})
const Index = {
handleInit: async() => {
},
/**
* 茶室门店列表
* @param mescroll
* 选择扫码验券菜单
*/
upCallback: (mescroll) => {
const userStore = useUserStore()
const userId = userStore.userInfo?.id || 0
const filter = {
page: mescroll.num,
size: mescroll.size,
latitude: latitude.value,
longitude: longitude.value,
search: keywords.value,
user_id: userId
}
uni.showLoading({ title: '加载中...' })
try {
getHomeTeaStoreList(filter).then( res => {
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() // 请求失败, 结束加载
})
uni.hideLoading()
} catch (error) {
uni.hideLoading()
handleSelectScanMenu: (item: { item: { name: string }}) => {
console.log("🚀 ~ item:", item)
if (item.item.name === '扫码验券') {
Index.handleScanCode()
} else if (item.item.name === '输入券码') {
const storeName = '茶址24小时智能茶室(中新店)'
router.navigateTo(`/bundle/store/verify-code?storeName=${storeName}`)
} else if (item.item.name === '验券记录') {
router.navigateTo('/bundle/store/verify-record')
}
},
/**
* 初始化首页数据
* 扫码验券
*/
handleInit: () => {
getHomeBannerList().then(res => {
swiperList.value = res.list.map(item => item.address)
})
},
/**
* 跳转城市选择
*/
handleToCity: () => {
uni.$on('locationUpdate', params => {
console.log("🚀 ~ params:", params)
uni.$off('locationUpdate')
city.value = params.city
latitude.value = params.latitude
longitude.value = params.longitude
Index.handleResetSearch()
})
router.navigateTo(`/pages/city/city?lat=${latitude.value}&lng=${longitude.value}`)
},
/**
* 跳转茶室搜索
*/
handleToSearch: () => {
uni.$on('refreshTeaRoomList', params => {
keywords.value = params.keywords
Index.handleResetSearch()
uni.$off('refreshTeaRoomList')
})
router.navigateTo(`/pages/search/search?keywords=${keywords.value}`)
},
/**
* 跳转到预约茶室页面
*/
handleToReserveRoom: (id: number = 0, type: number = 1) => {
router.navigateTo( `/bundle/tea-room/room?id=${id}&type=${type}`)
},
/**
* 重置搜索
*/
handleResetSearch: () => {
console.log("🚀 ~ location:", 456)
list.value = []
getMescroll().resetUpScroll()
},
/**
* 跳转公众号
*/
handleToWxOfficialAccount: () => {
wx.openOfficialAccountProfile({
username: '', // 此处填写公众号的原始 ID
success: res => {
handleScanCode: () => {
uni.scanCode({
success: (res) => {
console.log('scanCode res:', res)
},
fail: res => {
fail: (err) => {
console.log('scanCode err:', err)
}
})
},
/**
* 更新定位信息
*/
handleLocationUpdate: (params: any) => {
console.log("🚀 ~ locationUpdate:")
if (
city.value !== params.city ||
latitude.value !== params.latitude ||
longitude.value !== params.longitude
) {
city.value = params.city
latitude.value = params.latitude
longitude.value = params.longitude
Index.handleResetSearch()
}
}
}
</script>
@ -311,36 +208,6 @@ page {
background-repeat: no-repeat;
}
.search-box {
display: flex;
height: 100%;
margin-right: 40px;
--wot-search-padding: 0;
--wot-search-side-padding: 0;
:deep() {
.wd-search {
background: transparent !important;
width: 100% !important;
}
.wd-search__block {
background-color: #fff !important;
}
.wd-search__input {
// #ifdef MP
padding-left: 32px !important;
padding-right: 32px !important;
// #endif
// #ifndef MP
padding-right: 0 !important;
// #endif
}
}
}
.rounded {
border-radius: 20rpx 0rpx 20rpx 0rpx;
}