修复bug
This commit is contained in:
@@ -14,6 +14,14 @@ const storeBusinessHours = ref('');
|
||||
// 是否仅选择日期(当进入页面传递了 storeBusinessHours 时开启)
|
||||
const onlySelectDay = ref(false);
|
||||
|
||||
// 业务规则:只能预约周一 / 周四 / 周五
|
||||
// JS 中:0-周日 1-周一 ... 4-周四 5-周五
|
||||
const allowedWeekdays = [1, 4, 5];
|
||||
const isAllowedDay = (date: Date): boolean => {
|
||||
const dayIndex = date.getDay();
|
||||
return allowedWeekdays.includes(dayIndex);
|
||||
};
|
||||
|
||||
// 解析商家营业时间的接口
|
||||
interface BusinessHours {
|
||||
days: string[]; // 营业的星期几
|
||||
@@ -112,6 +120,11 @@ const isDateOpen = (date: Date): boolean => {
|
||||
* @returns 是否可选择
|
||||
*/
|
||||
const isDateSelectable = (date: Date): boolean => {
|
||||
// 新增:限制只能预约周一 / 周四 / 周五
|
||||
if (!isAllowedDay(date)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 如果只选日期模式,营业即可选择
|
||||
if (onlySelectDay.value) {
|
||||
if (!storeBusinessHours.value) return true;
|
||||
@@ -227,9 +240,12 @@ const hasAvailableTimeSlots = (date: Date): boolean => {
|
||||
// 初始化选中日期为第一个有可用时间段的营业日期
|
||||
const initializeSelectedDate = () => {
|
||||
if (onlySelectDay.value) {
|
||||
// 仅选日期模式:选择第一个营业日期(或第一个日期)
|
||||
const firstOpen = dateOptions.value.find((d) => isDateOpen(d));
|
||||
selectedDate.value = firstOpen || dateOptions.value[0];
|
||||
// 仅选日期模式:选择第一个“允许预约且营业”的日期(或第一个允许的日期)
|
||||
const firstOpen = dateOptions.value.find(
|
||||
(d) => isAllowedDay(d) && isDateOpen(d)
|
||||
);
|
||||
const firstAllowed = firstOpen || dateOptions.value.find((d) => isAllowedDay(d));
|
||||
selectedDate.value = firstAllowed || dateOptions.value[0];
|
||||
nextTick(() => updateScrollPosition());
|
||||
return;
|
||||
}
|
||||
@@ -487,7 +503,12 @@ const findNextBusinessDate = (currentDate: Date): Date | null => {
|
||||
dayjs(date).isSame(dayjs(nextDate), "day")
|
||||
);
|
||||
|
||||
if (isInRange && isDateOpen(nextDate) && hasAvailableTimeSlots(nextDate)) {
|
||||
if (
|
||||
isInRange &&
|
||||
isAllowedDay(nextDate) &&
|
||||
isDateOpen(nextDate) &&
|
||||
hasAvailableTimeSlots(nextDate)
|
||||
) {
|
||||
return nextDate;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,8 +60,8 @@
|
||||
class="category-item"
|
||||
@click="handleItemClick(item)"
|
||||
>
|
||||
<image :src="item.logoUrl" class="category-icon" mode="aspectFit" />
|
||||
<text class="category-text">{{ item.categoryName }}</text>
|
||||
<image v-if="item.categoryImage || item.logoUrl" :src="item.categoryImage || item.logoUrl" class="category-icon" mode="aspectFit" />
|
||||
<text class="category-text">{{ item.categoryName || item.name }}</text>
|
||||
</view>
|
||||
<view
|
||||
v-for="(item, idx) in categoriesReversed"
|
||||
@@ -69,8 +69,8 @@
|
||||
class="category-item"
|
||||
@click="handleItemClick(item)"
|
||||
>
|
||||
<image :src="item.categoryImage" class="category-icon" mode="aspectFit" />
|
||||
<text class="category-text">{{ item.categoryName }}</text>
|
||||
<image v-if="item.categoryImage || item.logoUrl" :src="item.categoryImage || item.logoUrl" class="category-icon" mode="aspectFit" />
|
||||
<text class="category-text">{{ item.categoryName || item.name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
<!--
|
||||
* @Author: ISFP_T 68358856@qq.com
|
||||
* @Date: 2026-02-25 10:02:44
|
||||
* @LastEditors: ISFP_T 68358856@qq.com
|
||||
* @LastEditTime: 2026-03-04 10:22:25
|
||||
* @FilePath: \chef-link-uniapp\src\pages\home\components\tabbar-home\components\food-box\index.vue
|
||||
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||
-->
|
||||
<script setup lang="ts">
|
||||
import Collection from "@/components/collection/index.vue";
|
||||
import {appCollectCollectPost} from "@/service";
|
||||
@@ -11,10 +19,18 @@ function handleClickFood() {
|
||||
// uni.navigateTo({
|
||||
// url: '/pages-store/pages/store/index?id=' + props.item.id
|
||||
// })
|
||||
|
||||
let merchantId = ''
|
||||
if(props.item.merchantId){
|
||||
merchantId = props.item.merchantId
|
||||
uni.navigateTo({
|
||||
url: '/pages-store/pages/store/dishes?id=' +props.item.id + '&storeId=' + props.item.merchantId,
|
||||
})
|
||||
}else{
|
||||
uni.navigateTo({
|
||||
url: '/pages-store/pages/store/index?id=' + props.item.id
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function handleCollectionChange(value: boolean) {
|
||||
@@ -33,23 +49,23 @@ function handleCollectionChange(value: boolean) {
|
||||
<template>
|
||||
<view @click="handleClickFood" class="mb-52rpx">
|
||||
<image
|
||||
:src="item?.dishImage?.split(',')[0]"
|
||||
:src="item?.dishImage?.split(',')[0]||item?.logo"
|
||||
mode="aspectFill"
|
||||
class="w-100% h-400rpx rounded-24rpx bg-common"
|
||||
></image>
|
||||
<view class="flex justify-between items-start mt-14rpx">
|
||||
<view>
|
||||
<text class="text-30rpx lh-30rpx text-#333 font-500 line-clamp-1"
|
||||
>{{ item.dishName }}</text
|
||||
>{{ item?.dishName||item?.merchantName }}</text
|
||||
>
|
||||
<!-- <view v-if="+item.deliveryService === 1" class="text-#CE7138 text-24rpx lh-24rpx mt-12rpx">${{ item.deliveryFee }} {{ t('pages.home.deliveryFee') }}</view> -->
|
||||
<view class="text-24rpx lh-24rpx flex items-center mt-12rpx">
|
||||
<view class="text-24rpx lh-24rpx flex items-center mt-12rpx" v-if="item?.originalPrice">
|
||||
|
||||
<image
|
||||
src="@img/chef/124.png"
|
||||
class="w-24rpx h-24rpx mx-4rpx mt-2rpx"
|
||||
></image>
|
||||
<text class="text-#333 font-500">$US{{ item.originalPrice }}</text>
|
||||
<text class="text-#333 font-500">$US{{ item?.originalPrice }}</text>
|
||||
<!-- <text class="text-#7D7D7D">({{ item.commentCount }}) • {{ item.deliveryTime }}{{ t('common.minutes') }}</text> -->
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@@ -392,7 +392,7 @@ const debouncedEmit = debounce(1300, (isCollected: boolean, id: string, type: Co
|
||||
<view class="flex-center-sb mt-12rpx">
|
||||
<view class="text-28rpx text-#999">
|
||||
<view class="line-through">US${{ item?.originalPrice }}</view>
|
||||
<view>{{ t('pages-store.store.sales') }}:{{ item?.salesCount }}</view>
|
||||
<!-- <view>{{ t('pages-store.store.sales') }}:{{ item?.salesCount }}</view> -->
|
||||
</view>
|
||||
|
||||
<view class="center w-64rpx h-64rpx rounded-50% bg-white shadow-lg">
|
||||
@@ -418,7 +418,7 @@ const debouncedEmit = debounce(1300, (isCollected: boolean, id: string, type: Co
|
||||
</view>
|
||||
|
||||
<!-- 回到顶部按钮 -->
|
||||
<view v-if="showBackToTop" @click="scrollToTop" class="back-to-top-btn">
|
||||
<view v-if="showBackToTop" @click="scrollToTop" class="fixed bottom-148rpx left-30rpx w-88rpx h-88rpx bg-#14181B rounded-50% center shadow-lg">
|
||||
<image src="@img/chef/119.png" class="w-40rpx h-40rpx shrink-0 rotate-180"></image>
|
||||
</view>
|
||||
</view>
|
||||
@@ -445,19 +445,4 @@ const debouncedEmit = debounce(1300, (isCollected: boolean, id: string, type: Co
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.back-to-top-btn {
|
||||
position: fixed;
|
||||
bottom: 148rpx;
|
||||
left: 30rpx;
|
||||
width: 88rpx;
|
||||
height: 88rpx;
|
||||
background-color: #14181B;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.15);
|
||||
z-index: 998;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -6,7 +6,7 @@ import AnimatedButton from "../animated-button/animated-button.vue";
|
||||
import Collection from "@/components/collection/index.vue";
|
||||
import FoodSkeleton from "@/pages/search/components/food-skeleton.vue";
|
||||
import RecipeSkeleton from "@/pages/search/components/recipe-skeleton.vue";
|
||||
import {appRecipeCategoryListGet, appSearchMerchantByDishPost, appSearchSearchRecipePost, appCollectCollectPost} from "@/service";
|
||||
import {getDishListByCategoryId,appRecipeCategoryListGet, appSearchMerchantByDishPost, appSearchSearchRecipePost, appCollectCollectPost} from "@/service";
|
||||
import {formatTimestamp} from "@/utils/utils";
|
||||
import {useUserStore} from "@/store";
|
||||
import { debounce } from 'throttle-debounce'
|
||||
@@ -43,22 +43,22 @@ const { paging, dataList, loading, queryList, firstLoaded } = usePage((pageNum,
|
||||
if(props.activeTab === 0) {
|
||||
// 搜索美食
|
||||
return new Promise(resolve => {
|
||||
appSearchMerchantByDishPost({
|
||||
getDishListByCategoryId({
|
||||
body: {
|
||||
keyword: props.keyword || '', // 搜索关键词
|
||||
pageNum: pageNum,
|
||||
pageSize: pageSize,
|
||||
selfPickup: selfPickup.value, // 是否自提
|
||||
discount: discount.value, // 是否有折扣 1是 2 否
|
||||
scoreRange: props.scoreRange || null, // 评分范围 比如 3-4
|
||||
priceRange: props.price || null, // 价格范围 比如 10-30
|
||||
selfPickup: selfPickup.value || undefined, // 是否自提
|
||||
discount: discount.value || undefined, // 是否有折扣 1是 2 否
|
||||
scoreRange: props.scoreRange || undefined, // 评分范围 比如 3-4
|
||||
priceRange: props.price || undefined, // 价格范围 比如 10-30
|
||||
sortType: 1, // 1系统推荐(按照喜好) 2 距离排序 3 评分排序
|
||||
lat: userStore.userLocation.latitude,
|
||||
lng: userStore.userLocation.longitude,
|
||||
}
|
||||
lat: userStore.userLocation.latitude || undefined,
|
||||
lng: userStore.userLocation.longitude || undefined,
|
||||
},
|
||||
}).then(res => {
|
||||
foodTotal.value = res.total; // 更新美食数据总条数
|
||||
resolve({rows: res.rows})
|
||||
foodTotal.value = res.total||res.data?.total||0; // 更新美食数据总条数
|
||||
resolve({rows: res.rows||res.data.rows})
|
||||
})
|
||||
})
|
||||
} else {
|
||||
@@ -177,18 +177,18 @@ defineExpose({
|
||||
bg-color="#ffffff"
|
||||
>
|
||||
<template v-if="activeTab === 0">
|
||||
<view
|
||||
<!-- <view
|
||||
class="animate-in fade-in animate-ease-out animate-duration-300"
|
||||
v-show="loadingFoodState"
|
||||
>
|
||||
<food-skeleton />
|
||||
</view>
|
||||
</view> -->
|
||||
<view
|
||||
class="animate-in fade-in animate-ease-in animate-duration-300"
|
||||
v-show="!loadingFoodState"
|
||||
>
|
||||
<!-- 筛选工具 -->
|
||||
<filtrate-tool class="my-36rpx" @togglePickup="togglePickup" @toggleDiscount="toggleDiscount" @toggleScore="emit('toggleScore')" @togglePrice="emit('togglePrice')" />
|
||||
<!-- <filtrate-tool class="my-36rpx" @togglePickup="togglePickup" @toggleDiscount="toggleDiscount" @toggleScore="emit('toggleScore')" @togglePrice="emit('togglePrice')" /> -->
|
||||
<view
|
||||
class="pl-30rpx pb-36rpx text-36rpx lh-36rpx text-#333 font-500 tracking-[.04em]"
|
||||
>{{ foodTotal }} {{ t('pages.search.result.result') }}</view
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import SearchHistory from './components/search-history/index.vue'
|
||||
import SearchSkeleton from './components/search-skeleton.vue'
|
||||
import {useSearchStore} from '@/store'
|
||||
import {appSearchListPost} from '@/service'
|
||||
import {appSearchListPost,appRecipeCategoryListGet} from '@/service'
|
||||
|
||||
const {t} = useI18n()
|
||||
const searchStore = useSearchStore()
|
||||
@@ -23,9 +23,9 @@ function handleSearch() {
|
||||
|
||||
function handleHotSearch(item: any) {
|
||||
nextTick(() => {
|
||||
searchStore.setHistoryList(item.name)
|
||||
searchStore.setHistoryList(item.categoryName)
|
||||
uni.navigateTo({
|
||||
url: `/pages/search/result?keyword=${item.name}`,
|
||||
url: `/pages/search/result?keyword=${item.categoryName}`,
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -39,7 +39,7 @@ onMounted(() => {
|
||||
|
||||
const hotSearchList = ref([])
|
||||
function getHotSearchList() {
|
||||
appSearchListPost({}).then(res=> {
|
||||
appRecipeCategoryListGet({}).then(res=> {
|
||||
console.log('热门搜索词列表', res)
|
||||
hotSearchList.value = res.data
|
||||
}).finally(() => {
|
||||
@@ -68,9 +68,9 @@ function getHotSearchList() {
|
||||
</view>
|
||||
<template v-for="item in hotSearchList">
|
||||
<view @click="handleHotSearch(item)" class="w-full h-144rpx flex items-center">
|
||||
<image :src="item.logoUrl" class="w-64rpx h-64rpx mr-28rpx rounded-50%" mode="aspectFill"></image>
|
||||
<image :src="item?.categoryImage" class="w-64rpx h-64rpx mr-28rpx rounded-50%" mode="aspectFill"></image>
|
||||
<view class="flex-1 border-b-solid border-b-1rpx border-b-#DFDFDF h-full flex items-center text-30rpx text-primary font-500 tracking-[.06em]">
|
||||
{{ item.name }}
|
||||
{{ item?.categoryName }}
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@@ -107,11 +107,11 @@ onMounted(()=> {
|
||||
v-model="keyword"
|
||||
@search="handleSearch"
|
||||
/>
|
||||
<tab-switcher
|
||||
<!-- <tab-switcher
|
||||
v-model="activeTab"
|
||||
:tabs="tabs"
|
||||
@change="handleTabChange"
|
||||
/>
|
||||
/> -->
|
||||
</template>
|
||||
<swiper
|
||||
class="h-full"
|
||||
|
||||
Reference in New Issue
Block a user