mirror of
https://gitee.com/beijing_hongye_huicheng/lilishop-uniapp.git
synced 2026-11-13 12:28:50 +08:00
feat: 更新预约功能与礼品卡支持
- 新增礼品卡页面,支持礼品卡的选择与使用。 - 调整预约下单流程,增强预约信息展示与用户交互。 - 更新支付成功页面的导航逻辑,确保用户体验流畅。 - 优化搜索页面的历史关键词加载逻辑,提升性能。
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="main-page">
|
||||
<div class="main-page" :style="themeStyle">
|
||||
<!-- #ifdef APP-PLUS -->
|
||||
<view class="status_bar"></view>
|
||||
<!-- #endif -->
|
||||
@@ -13,8 +13,6 @@
|
||||
routerVal.goodsId
|
||||
" :thumbnail="goodsDetail.thumbnail" :goodsName="goodsDetail.goodsName" type="goods"
|
||||
@close="enableShare = false" />
|
||||
<popups v-model="popupsSwitch" @tapPopup="handleNavbarList" :popData="navbarListData" :x="navbarListX"
|
||||
:y="navbarListY" placement="top-start" />
|
||||
<view class="index">
|
||||
<!-- topBar -->
|
||||
<u-navbar
|
||||
@@ -25,17 +23,8 @@
|
||||
:bg-color="navbar.background"
|
||||
:auto-back="false"
|
||||
:class="headerFlag ? 'header' : 'header bg-none scroll-hide'"
|
||||
@leftClick="back"
|
||||
>
|
||||
<template #left>
|
||||
<view class="backs" @tap.stop>
|
||||
<view class="nav-action" @tap.stop="back()">
|
||||
<u-icon name="arrow-left" class="icon-back"></u-icon>
|
||||
</view>
|
||||
<view class="nav-action" @tap.stop="popupsSwitch = !popupsSwitch">
|
||||
<u-icon name="list" class="icon-list"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<template #center>
|
||||
<view class="headerList" :class="headerFlag ? 'tab-bar' : 'tab-bar scroll-hide'">
|
||||
<view class="headerRow headerRow--tabs">
|
||||
@@ -62,17 +51,8 @@
|
||||
class="header-only-back"
|
||||
:bg-color="navbarOnlyBack.background"
|
||||
:auto-back="false"
|
||||
@leftClick="back"
|
||||
>
|
||||
<template #left>
|
||||
<view class="bg-back" @tap.stop>
|
||||
<view class="nav-action" @tap.stop="back()">
|
||||
<u-icon size="20" name="arrow-left" class="icon-back"></u-icon>
|
||||
</view>
|
||||
<view class="nav-action" @tap.stop="popupsSwitch = !popupsSwitch">
|
||||
<u-icon size="20" name="list" class="icon-list"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</u-navbar>
|
||||
</view>
|
||||
|
||||
@@ -262,7 +242,13 @@
|
||||
<view class="detail-btn" v-if="!isGroup && !takeDownFromSale">
|
||||
<view class="to-store-car to-store-btn" v-if="showAddToCart" @click="shutMask(4)">
|
||||
加入购物车</view>
|
||||
<view class="to-buy to-store-btn" @click="shutMask(4, 'buy')">立即购买</view>
|
||||
<view
|
||||
class="to-buy to-store-btn"
|
||||
:class="{ 'to-buy-theme': isAppointmentGoodsType }"
|
||||
@click="handleBuyClick"
|
||||
>
|
||||
{{ isAppointmentGoodsType ? '立即预约' : '立即购买' }}
|
||||
</view>
|
||||
<view class="to-store-car to-store-btn" v-if="startTimer">暂未开始</view>
|
||||
</view>
|
||||
<!-- 拼团结算 -->
|
||||
@@ -325,13 +311,13 @@ import * as API_trade from '@/api/trade.js'
|
||||
import * as API_Members from '@/api/members.js'
|
||||
import * as API_store from '@/api/store.js'
|
||||
import { getIMDetail } from '@/api/common'
|
||||
import { modelNavigateTo } from '@/pages/tabbar/home/template/tpl.js'
|
||||
/************请求存储***************/
|
||||
import storage from '@/utils/storage.js'
|
||||
/************工具函数***************/
|
||||
import { useStore } from '@/store'
|
||||
import { getThemeStyle } from '@/utils/theme'
|
||||
import { unitPrice, goodsFormatPrice, isLogin, parseGoodsImageUrl, clearStrComma, talkIm } from '@/utils/filters.js'
|
||||
import { isNonPhysicalGoods } from '@/utils/goodsType.js'
|
||||
import { isNonPhysicalGoods, isAppointmentGoods } from '@/utils/goodsType.js'
|
||||
|
||||
/************组件***************/
|
||||
import PromotionLayout from './product/promotion/-promotion'
|
||||
@@ -347,36 +333,17 @@ import GoodsSwiper from './product/goods/-goods-swiper'
|
||||
import popupGoods from '@/components/m-buy/goods'
|
||||
import popupAddress from './product/popup/address'
|
||||
import shares from '@/components/m-share/index'
|
||||
import popups from '@/components/popups/popups'
|
||||
import takeDownFormSaleGoods from '@/components/m-take-down-sale-goods/index'
|
||||
import setup from './product/popup/popup'
|
||||
|
||||
const store = useStore()
|
||||
const themeStyle = computed(() => getThemeStyle(store.state.theme))
|
||||
const instance = getCurrentInstance()
|
||||
const popupGoodsRef = ref()
|
||||
const takeDownSaleRef = ref()
|
||||
|
||||
// 响应式数据
|
||||
const promotionShow = ref(false)
|
||||
let navbarListX: any
|
||||
let navbarListY: any
|
||||
// #ifdef H5
|
||||
navbarListX = ref(110)
|
||||
navbarListY = ref(80)
|
||||
// #endif
|
||||
// #ifdef MP-WEIXIN || APP-PLUS
|
||||
// #ifndef H5
|
||||
navbarListX = ref(120)
|
||||
navbarListY = ref(170)
|
||||
// #endif
|
||||
// #endif
|
||||
const navbarListData = [
|
||||
{ title: "首页", icon: "home-fill", ___type: "other" },
|
||||
{ title: "购物车", icon: "bag-fill", ___type: "other" },
|
||||
{ title: "搜索", icon: "search", ___type: "category" },
|
||||
{ title: "个人中心", icon: "account-fill", ___type: "other" },
|
||||
]
|
||||
const popupsSwitch = ref(false)
|
||||
const enableShare = ref(false)
|
||||
const selectedGoods = ref<any>("")
|
||||
const isGroup = ref(false)
|
||||
@@ -437,6 +404,7 @@ const isNonPhysicalGoodsType = computed(() => isNonPhysicalGoods(goodsDetail.val
|
||||
const showAddToCart = computed(() => {
|
||||
return !isNonPhysicalGoodsType.value
|
||||
})
|
||||
const isAppointmentGoodsType = computed(() => isAppointmentGoods(goodsDetail.value?.goodsType))
|
||||
|
||||
// watch
|
||||
watch(isGroup, (val) => {
|
||||
@@ -494,10 +462,6 @@ function share() {
|
||||
return `/pages/product/goods?id=${routerVal.value.id}&goodsId=${routerVal.value.goodsId}`
|
||||
}
|
||||
|
||||
function handleNavbarList(val: any) {
|
||||
modelNavigateTo({ url: val })
|
||||
}
|
||||
|
||||
function emptyPromotion(): boolean {
|
||||
if (PromotionList.value == "" || PromotionList.value == null || PromotionList.value == []) {
|
||||
return true
|
||||
@@ -637,13 +601,11 @@ function cartCount() {
|
||||
}
|
||||
|
||||
function back() {
|
||||
if (getCurrentPages().length == 1) {
|
||||
uni.switchTab({
|
||||
url: "/pages/tabbar/home/index",
|
||||
})
|
||||
} else {
|
||||
uni.navigateBack()
|
||||
}
|
||||
uni.navigateBack({
|
||||
fail() {
|
||||
uni.switchTab({ url: '/pages/tabbar/home/index' })
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
function getStoreBaseInfoFun(id: any) {
|
||||
@@ -724,6 +686,26 @@ function getCoupon(item: any) {
|
||||
receiveCouponsFun(item.id)
|
||||
}
|
||||
|
||||
function goAppointmentCheckout(num = 1) {
|
||||
const sku = goodsDetail.value?.id
|
||||
const gid = goodsDetail.value?.goodsId || routerVal.value.goodsId
|
||||
if (!sku || !gid) {
|
||||
uni.showToast({ title: '商品信息异常', icon: 'none' })
|
||||
return
|
||||
}
|
||||
uni.navigateTo({
|
||||
url: `/pages/order/appointment/appointmentCheckout?skuId=${sku}&goodsId=${gid}&num=${num}`,
|
||||
})
|
||||
}
|
||||
|
||||
function handleBuyClick() {
|
||||
if (isAppointmentGoodsType.value) {
|
||||
goAppointmentCheckout()
|
||||
return
|
||||
}
|
||||
shutMask(4, 'buy')
|
||||
}
|
||||
|
||||
function shutMask(flag: any, buyFlag?: any, type?: any) {
|
||||
promotionShow.value = false
|
||||
buyMask.value = false
|
||||
|
||||
@@ -46,6 +46,10 @@ page {
|
||||
> .to-buy {
|
||||
background-image: linear-gradient(135deg, #ffba0d, #ffc30d 69%, #ffcf0d);
|
||||
}
|
||||
> .to-buy-theme {
|
||||
background-image: none;
|
||||
background: var(--theme-primary, #ff3c2a);
|
||||
}
|
||||
> .to-store-car {
|
||||
background-image: linear-gradient(135deg, #f2140c, #f2270c 70%, #f24d0c);
|
||||
}
|
||||
@@ -201,7 +205,7 @@ page {
|
||||
|
||||
.header-only-back {
|
||||
background: transparent;
|
||||
z-index: 9;
|
||||
z-index: 12 !important;
|
||||
}
|
||||
.header,
|
||||
.header-only-back {
|
||||
@@ -332,26 +336,10 @@ page {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.nav-action + .nav-action {
|
||||
border-left: 2rpx solid rgb(194, 194, 194);
|
||||
}
|
||||
.backs,
|
||||
.bg-back {
|
||||
width: 150rpx;
|
||||
border: 2rpx solid #e8e8e8;
|
||||
border-radius: 100px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
padding: 8rpx 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.bg-back {
|
||||
background: rgba($color: #fff, $alpha: 0.8);
|
||||
}
|
||||
.backs {
|
||||
text-align: center;
|
||||
font-size: 42rpx;
|
||||
}
|
||||
|
||||
.headerImg {
|
||||
|
||||
@@ -234,7 +234,7 @@ import {
|
||||
getStoreIsCollect,
|
||||
} from '@/api/members.js'
|
||||
import config from '@/config/config'
|
||||
import { getGoodsList } from '@/api/goods.js'
|
||||
import { getGoodsList, getMpScene } from '@/api/goods.js'
|
||||
import { getAllCoupons } from '@/api/promotions.js'
|
||||
import { getFloorStoreData } from '@/api/home'
|
||||
import {
|
||||
@@ -349,6 +349,33 @@ function fallbackToBasePage() {
|
||||
getCategoryData()
|
||||
}
|
||||
|
||||
function applyStoreId(id) {
|
||||
storeId.value = id || ''
|
||||
goodsParams.storeId = storeId.value
|
||||
couponParams.storeId = storeId.value
|
||||
}
|
||||
|
||||
function parseStoreIdFromParams(params) {
|
||||
const text = String(params || '').trim()
|
||||
if (!text) return ''
|
||||
if (text.indexOf('id=') === 0) return text.slice(3)
|
||||
const match = /(?:^|&)id=([^&]+)/.exec(text)
|
||||
return match ? decodeURIComponent(match[1]) : ''
|
||||
}
|
||||
|
||||
async function resolveStoreIdFromScene(scene) {
|
||||
const raw = decodeURIComponent(String(scene || '')).trim()
|
||||
if (!raw) return ''
|
||||
const direct = parseStoreIdFromParams(raw)
|
||||
if (direct) return direct
|
||||
try {
|
||||
const res = await getMpScene(raw)
|
||||
return parseStoreIdFromParams(res?.data?.result)
|
||||
} catch {
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
function getStoreLicencePhoto() {
|
||||
uni.navigateTo({
|
||||
url: `/pages/product/licencePhoto?id=${storeId.value}`,
|
||||
@@ -505,11 +532,15 @@ function getCoupon(item: any) {
|
||||
}
|
||||
|
||||
onLoad((options: any) => {
|
||||
storeId.value = options.id
|
||||
console.log(storeId.value, 'this.storeId')
|
||||
|
||||
goodsParams.storeId = options.id
|
||||
couponParams.storeId = options.id
|
||||
applyStoreId(options?.id)
|
||||
if (!storeId.value && options?.scene) {
|
||||
resolveStoreIdFromScene(options.scene).then((id) => {
|
||||
if (!storeId.value && id) {
|
||||
applyStoreId(id)
|
||||
init()
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
onPageScroll((e) => {
|
||||
@@ -531,7 +562,7 @@ onMounted(() => {
|
||||
withShareTicket: true,
|
||||
})
|
||||
// #endif
|
||||
init()
|
||||
if (storeId.value) init()
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user