增加网络波动加载中,增加会员信息扫码充值

This commit is contained in:
wwz 2025-03-26 17:58:52 +08:00
parent 3a6fa55234
commit 98ce8b5544
18 changed files with 1018 additions and 128 deletions

36
App.vue
View File

@ -31,6 +31,42 @@
// },
onShow(async () => {
try {
// #ifdef MP-WEIXIN
// res: {hasUpdate: true, version: 1.0.0}
const updateManager = uni.getUpdateManager();
updateManager.onCheckForUpdate((res) => {
if (res.hasUpdate) { //
uni.showLoading({
title: '更新中...'
}); // Loading
}
});
//
updateManager.onUpdateReady(() => {
uni.hideLoading(); // Loading
uni.showModal({ //
title: '更新提示',
content: '更新完毕,是否重启?',
success: function(res) {
if (res.confirm) {
updateManager.applyUpdate(); // 使
}
}
})
});
//
updateManager.onUpdateFailed(() => {
uni.hideLoading(); // Loading
uni.showToast({
title: '更新失败,稍后再试...',
icon: "error"
});
});
// #endif
} catch (error) {
//TODO handle the exception
}
// #ifndef H5
// try {
const storelogin = Storelogin();

View File

@ -94,12 +94,13 @@ const useWebSocket = (options = {}) => {
socketTask.value.onMessage((res) => {
receivedMessages.value = JSON.parse(res.data)
// receivedMessages.value.push(list);
if (receivedMessages.value == 'ok') {
console.log('心跳响应正常');
// 心跳正常,重置重连尝试次数
reconnectAttempts.value = 0;
if (receivedMessages.value == 'ok' || receivedMessages.value.operate_type == 'init') {
console.log('初始化正常,心跳响应正常');
// 清除重连定时器
clearTimeout(reconnectTimer.value);
reconnectTimer.value = null;
}
});
socketTask.value.onClose((res) => {
@ -109,13 +110,13 @@ const useWebSocket = (options = {}) => {
clearTimeout(reconnectTimer.value); // 清除重连定时器
if (res.code == '1006') {
uni.showToast({
title: '操作异常,请重新扫码',
title: '网络异常,请重新扫码',
icon: 'none'
});
autoReconnect.value = false;
setTimeout(() => {
uni.pro.switchTab('index/index');
}, 1500)
}, 1000)
return false;
}
if (autoReconnect.value && !isManuallyClosed.value) {
@ -179,7 +180,9 @@ const useWebSocket = (options = {}) => {
const handlePong = (res) => {
try {
let data = JSON.parse(res.data);
if (data.msg === 'ok' && data.msg_id == 'ping_interval') {
if (data.operate_type == "init" || (data.msg === 'ok' &&
data.msg_id ==
'ping_interval')) {
isPongReceived.value = true;
console.log('收到心跳响应,清除超时定时器');
clearTimeout(pongTimer);
@ -252,9 +255,7 @@ const useWebSocket = (options = {}) => {
mask: true
})
console.log(`尝试第 ${reconnectAttempts.value} 次重连,重连间隔: ${randomizedInterval}ms...`);
setTimeout(() => {
uni.hideLoading();
}, 1000)
reconnectTimer.value = setTimeout(() => {
connect();
}, randomizedInterval);
@ -266,7 +267,10 @@ const useWebSocket = (options = {}) => {
});
clearInterval(heartbeatTimer.value);
autoReconnect.value = false;
setTimeout(() => {
uni.hideLoading();
uni.pro.switchTab('index/index');
}, 1000)
}
};

83
components/Loading.vue Normal file
View File

@ -0,0 +1,83 @@
<template>
<view class="full-screen-loading" v-if="isLoading">
<view class="loading-content">
<view class="loading-spinner"></view>
<view class="loading-text">努力加载中...</view>
</view>
</view>
</template>
<script setup>
import {
ref,
defineProps
} from 'vue';
const props = defineProps({
isLoading: {
type: Boolean,
default: true
}
});
</script>
<style lang="scss" scoped>
/* 全屏遮罩 */
.full-screen-loading {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
// background: rgba(0, 0, 0, 0.7);
background:#fff;
/* 半透明背景 */
z-index: 9999;
display: flex;
justify-content: center;
align-items: center;
/* 加载内容容器 */
.loading-content {
background: #fff;
padding: 2rem;
border-radius: 8px;
text-align: center;
/* 旋转加载动画 */
.loading-spinner {
margin: 0 auto;
width: 40px;
height: 40px;
border: 4px solid #f3f3f3;
border-top: 4px solid #3498db;
/* 蓝色动画部分 */
border-radius: 50%;
animation: spin 1s linear infinite;
margin-bottom: 1rem;
/* 加载文字 */
.loading-text {
color: #333;
font-size: 14px;
}
/* 定义旋转动画 */
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
}
}
}
</style>

View File

@ -1,5 +1,5 @@
<template>
<view class="therecontent flex-between" >
<view class="therecontent flex-between">
<view class="therecontent_box_item">
<view class="therecontent_box_imge flex-between" @click="jrtoday(0)">
<view class="therecontent_box_imge_text">
@ -42,7 +42,7 @@
style="background: url(https://czg-qr-order.oss-cn-beijing.aliyuncs.com/index/towcontent_box2.png) no-repeat; background-size: cover;"
@click="jrtoday(1)">
<view class="therecontent_box_imge_text">
{{salesList.name}}
{{salesList.name || ''}}
</view>
<view class="therecontent_box_imge_right flex-start">
<view>
@ -82,13 +82,20 @@
defineProps
} from 'vue';
const props = defineProps({
salesList: Object,
salesList: {
type: Object,
default: {
name: '',
date: '',
hotList: [],
}
},
todayList: {
type: Object,
default: () => ({
name:'',
date:'',
hotList:[]
name: '',
date: '',
hotList: []
}) //
},
});

View File

@ -127,7 +127,7 @@
<up-loadmore :status="formhomelist.status" fontSize="14" color="#999" iconSize="14" />
</view>
</view>
<indexs v-if="showindex == 'shopIndex'"></indexs>
<indexs v-if="showindex == 'shopIndex'" :shopExtend='orderVIP.shopExtendList'></indexs>
</view>
</template>
@ -139,7 +139,8 @@
reactive,
onBeforeUnmount,
watch,
getCurrentInstance
getCurrentInstance,
nextTick
} from "vue";
import {
onLoad,
@ -235,7 +236,7 @@
size: 10, //
status: 'loadmore',
name: '1',
list:[]
list: []
})
// 使 reactive
const timeData = ref({});
@ -307,6 +308,10 @@
onLoadhome()
}
const orderVIP = ref({
shopExtendList:''
})
//
const showproductlist = ref(false);
//
@ -393,7 +398,9 @@
await proxy.$onLaunched;
if (uni.cache.get('shopId')) {
showindex.value = 'shopIndex'
await storeuser.actionsAPIuser()
await storeuser.actionsproductqueryProduct()
await nextTick()
orderVIP.value = uni.cache.get('orderVIP')
} else {
showindex.value = 'index'
hometop()

View File

@ -1,7 +1,7 @@
<template>
<view class="content">
<view class="contentbox"
:style="'background:url('+(shopExtend[0]?shopExtend[0].value:'https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png')+') no-repeat center center / cover' ">
:style="'background:url('+(shopExtend?shopExtend[0].value:'https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png')+') no-repeat center center / cover' ">
<view class="contentboxitem flex-between">
<view class="contentboxitemleft flex-colum" @click="scanCodehandle(0)">
<image src="https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/Xdiancan.png" mode="aspectFill">
@ -36,13 +36,23 @@
<script setup>
import {
ref,
onMounted,
reactive,
} from "vue";
defineProps,
defineEmits
} from 'vue';
//
const props = defineProps({
shopExtend: {
type: Array,
default: []
}
});
import {
productStore
} from '@/stores/user.js';
const shopExtend = uni.cache.get('shopUserInfo').shopExtendList ? uni.cache.get('shopUserInfo').shopExtendList : 'https://czg-qr-order.oss-cn-beijing.aliyuncs.com/indexs/shuangbackground.png'
const scanCodehandle = async (i) => {
const store = productStore();
await store.scanCodeactions()
@ -63,7 +73,6 @@
}
return null;
}
onMounted(() => {})
</script>
<style scoped lang="scss">

View File

@ -419,9 +419,14 @@
// *
const getCalcUsablePoints = async (data) => {
Object.assign(calcUsablePointsData, data);
try {
calcUsablePointsData.minIntegral = data.minDeductionPoints
calcUsablePointsData.maxIntegral = data.maxUsablePoints
calcUsablePointsData.instructionText = `请输入 ${ data.minDeductionPoints} - ${data.maxUsablePoints} 之间的积分`
calcUsablePointsData.instructionText =
`请输入 ${ data.minDeductionPoints} - ${data.maxUsablePoints} 之间的积分`
} catch (error) {
//TODO handle the exception
}
}

View File

@ -77,7 +77,8 @@
reactive,
onMounted,
onUnmounted,
watchEffect
watchEffect,
nextTick
} from 'vue';
import {
@ -211,13 +212,11 @@
//
watchEffect(async () => {
if (listinfo.combinedArray.length > 0) {
//
// console.log(listinfo.combinedArray, listinfo.packFeess, listinfo.totalPrices, listinfo.Seatcharge,
// listinfo.Productroll, listinfo.coupondiscountAmount)
// packFeess totalPrices Seatcharge
try {
let sum = (is_type.value != 0 ? listinfo.packFeess : 0) + listinfo.totalPrices + (is_type
.value == 0 ? listinfo.Seatcharge : 0);
console.log(listinfo.totalPrices,11)
listinfo.originAmount = Math.round(sum * 100) / 100;
// packFeess totalPrices Seatcharge Productroll coupondiscountAmount listinfo.pointsDiscountAmount
@ -226,10 +225,12 @@
0 ? listinfo.Seatcharge : 0) - (listinfo.Productroll || 0) - (listinfo
.coupondiscountAmount || 0) - (listinfo.pointsDiscountAmount || 0);
listinfo.totalCost = Math.round(sums * 100) / 100;
//
console.log(listinfo.combinedArray, listinfo.packFeess, listinfo.totalPrices, listinfo
.Seatcharge, listinfo.Productroll, listinfo.coupondiscountAmount, sums)
//
try {
console.log(orderVIP.value.freeDineConfig.enable, changeFreeenable.value)
// console.log(orderVIP.value.freeDineConfig.enable, changeFreeenable.value)
if (orderVIP.value.freeDineConfig.enable && changeFreeenable.value) {
listinfo.totalCost = (parseFloat(listinfo.totalCost) * parseFloat(orderVIP.value
.freeDineConfig
@ -239,7 +240,7 @@
//TODO handle the exception
}
//
if (listinfo.totalCost && listinfo.status == 'unpaid') {
if (listinfo.totalCost && listinfo.status == 'unpaid' && orderVIP.value.id) {
uni.$u.debounce(memberPointscalcUsablePoints, 500)
}
@ -259,7 +260,6 @@
listinfo.coupondiscountAmount = 0 //
listinfo.pointsNum = 0 //
let res = cartStore.getTotalTotalPrices(listinfo.combinedArray, 1)
console.log(res)
//
// #ifdef MP-WEIXIN
paymentMethodref.value.groupChanges(2)
@ -347,7 +347,6 @@
const learcoupons = (data) => {
if (data == 'product') {
console.log(listinfo)
uniqueIds.value = [] // id
listinfo.coupondiscountAmount = 0 //
listinfo.Productroll = 0 //
@ -549,6 +548,7 @@
try {
//
if (orderVIP.value) {
console.log(uni.cache.get('orderVIP'))
orderVIP.value = uni.cache.get('orderVIP')
ordershopUserInfo.value = orderVIP.value.shopInfo
paymentMethodref.value.orderVIPfun(uni.cache.get('orderVIP'))
@ -572,12 +572,12 @@
uni.cache.set('shopId', options.shopId, 30)
uni.$on('returnData', handleReturnData);
}
try {
// *
await storeuser.actionsproductqueryProduct()
} catch (error) {
//TODO handle the exception
}
await nextTick()
orderVIP.value = uni.cache.get('orderVIP')
//
orderorderInfo()
})
</script>

View File

@ -12,10 +12,13 @@
<view class="item" @click="tabCut(index)" v-for="(item,index) in 9" :key="index">
<view class="num_item" :class="{'active':numIndex==index }">{{index+1}}</view>
</view>
<view class="item">
<up--input class="num_item" v-model="otherNum" :class="{'active':numIndex==-1 }"
@input="isOtherNum" @focus="tabCut(-1)" @blur="blur()" border="none" type="nubmer"
maxlength="3" placeholder='请输入..'></up--input>
<view class="item" @click="tabCut(-1)">
<view class="num_item" :style="numIndex==-1?'background-color: #E8AD7B;':'' ">
<up--input v-model="otherNum" @input="isOtherNum" @blur="blur()"
border="none" type="nubmer" maxlength="3" placeholder='请输入..'></up--input>
</view>
</view>
<!-- <view class="num_item" v-else :class="{'active':numIndex==-1 }"></view> -->
</view>
@ -66,6 +69,7 @@
//
const tabCut = (index) => {
console.log(index)
numIndex.value = index;
if (index != -1) {
dinersNum.value = index + 1;
@ -112,7 +116,6 @@
const options = currentPage.options;
// #ifdef MP-WEIXIN
if (options.q) {
console.log(options.q)
const store = productStore();
await store.scanCodeactions(options.q)
}
@ -219,7 +222,7 @@
font-size: 28rpx !important;
color: #333333 !important;
text-align: center !important;
background-color: #FEF4EB !important;
background-color: #FEF4EB;
}
.active {

View File

@ -305,13 +305,13 @@
shop_id: uni.cache.get('shopId'),
operate_type: 'cleanup',
})
uni.pro.redirectTo('order/detail', {
orderId: res.id,
shopId: uni.cache.get('shopId')
})
// uni.redirectTo({
// url: '/pages/index/index?orderId=' + res.id + '&shopId=' + uni.cache.get('shopId')
// uni.pro.redirectTo('order/detail', {
// orderId: res.id,
// shopId: uni.cache.get('shopId')
// })
uni.reLaunch({
url: '/pages/order/detail?orderId=' + res.id + '&shopId=' + uni.cache.get('shopId')
})
// uni.pro.navigateTo('order/detail', {
// orderId: res.id,
// shopId: uni.cache.get('shopId')

View File

@ -37,8 +37,15 @@
<view class="price">
<text class="i"></text>
<!-- 会员价与价格 -->
<text
class="price">{{shopInfo.isVip ==1 && shopInfo.isMemberPrice==1?(item.memberPrice || item.salePrice):item.salePrice}}</text>
<text class="price" v-if="item.type == 'sku'">
<text v-for="i in item.skuList" :key="i.id">
<!-- -->
{{item.cartListinfo.sku_id == i.id?(shopInfo.isVip ==1 && shopInfo.isMemberPrice==1?(i.memberPrice || i.salePrice):i.salePrice):''}}
</text>
</text>
<text class="price" v-else>
{{shopInfo.isVip ==1 && shopInfo.isMemberPrice==1?(item.memberPrice || item.salePrice):item.salePrice}}
</text>
<!-- <text class="originalprice"
v-if="item.originPrice">¥{{item.originPrice}}</text>
<text class="unit" v-if="item.unitName">/{{item.unitName}}</text> -->
@ -102,7 +109,6 @@
type: Boolean
},
});
const shopInfo = uni.cache.get('shopInfo')
// ifcartNumber

View File

@ -10,12 +10,14 @@
<view class="panelone">
{{ shopInfo.shopName }}
</view>
<view class="paneltow">
<view class="paneltow" v-if="distance">
距离您{{ distance }}
</view>
<view class="panelthere flex-between">
<view class="paneltheretext">
营业时间{{ (shopInfo.businessStartDay || '--') +' 至 '+ (shopInfo.businessEndDay || '--') +' '+ (shopInfo.businessTime || '')}}
营业时间{{ (shopInfo.businessStartDay || '--') +' 至 '+ (shopInfo.businessEndDay || '--')}}
{{endTimeref.startTime}} -
{{endTimeref.endTime < '05'?` 凌晨${endTimeref.endTime}`:endTimeref.endTime}}
</view>
<view class="flex-start" @click="callChildMethod">
<view style="margin-right: 14rpx;">查看</view>
@ -103,8 +105,8 @@
</view>
</view>
<text class="num"> {{ ifcartNumber(item) }} </text>
<text class="dot num"
v-if="item.suitNum>1">{{item.suitNum<99?item.suitNum:'99+'}}</text>
<!-- <text class="dot num"
v-if="item.suitNum>1">{{item.suitNum<99?item.suitNum:'99+'}}</text> -->
<view class="btn">
<up-icon name="plus-circle-fill" color="#E9AB7A" size="25"></up-icon>
<view class="btnClick"
@ -304,7 +306,8 @@
:key="goodsid" @click="goodsidClick(setmenuindex, option, goodsid)"
:class="{ shop_sku_box_item_selected: isOptionSelected(setmenuindex, option)}"
:disabled="isMaxSelected(setmenuindex) &&!isOptionSelected(setmenuindex, option)">
{{option.proName}}/{{option.unitName}}
{{option.proName}}
<text v-if="option.unitName">/{{option.unitName}}</text>
<view class="shop_sku_box_item_tip" v-if="specifications.item.isPauseSale == 1">
<view>售罄</view>
</view>
@ -316,12 +319,21 @@
</scroll-view>
<view class="shop_bottom">
<view class="flex-between">
<view class="price">
<view class="price" v-if="specifications.item.type != 'package' && specifications.item.result">
<text class="i"></text>
<text
class="num">{{shopInfo.isVip ==1 && shopInfo.isMemberPrice==1? (specifications.item.result.memberPrice||specifications.item.result.salePrice):specifications.item.result.salePrice}}</text>
<text class="i" v-if="specifications.item.unitName">/{{specifications.item.unitName}}</text>
</view>
<view class="price" v-else>
<text class="i"></text>
<text
class="num">{{shopInfo.isVip ==1 && shopInfo.isMemberPrice==1? (specifications.item.memberPrice||specifications.item.salePrice):specifications.item.salePrice}}</text>
<text class="i">/{{specifications.item.unitName}}</text>
<text class="i" v-if="specifications.item.unitName">/{{specifications.item.unitName}}</text>
</view>
<view class="operation-wrap">
<view class="btn">
<up-icon name="minus-circle-fill" color="#E9AB7A" size="25"
@ -351,6 +363,8 @@
</view>
</view>
</up-popup>
<Loading :isLoading="isLoading" />
</view>
</template>
@ -378,6 +392,7 @@
import shopindex from './components/shopindex.vue'
import shoppingCartes from './components/shoppingCartes.vue'
import confirmorder from './components/confirmorder.vue'
import Loading from '@/components/Loading.vue';
//
const {
proxy
@ -441,6 +456,9 @@
//
const showShopInfoRef = ref(null)
//
const isLoading = ref(true);
//shop
const callChildMethod = () => {
if (showShopInfoRef.value) {
@ -639,13 +657,13 @@
specInfo: selectedSpecsStr.value,
id: specifications.item.id
});
console.log(result)
// console.log(result)
if (result != true) {
specifications.sku_id = result.id
specifications.product_id = result.productId
//
specifications.item.result = result
console.log(specifications.item)
// console.log(specifications.item)
if (result.isPauseSale == 0) {
canSubmit.value = true;
} else {
@ -811,8 +829,10 @@
//
return result;
} else if (specifications.item.type == 'sku') {
// console.log(product,data, 'product,data')
//
return product.skuId == data.id && product.id == data.productId
return product.cartListinfo.sku_id == data.id && product.cartListinfo.product_id == data
.productId
} else {
//
return product.skuId == data.skuId && product.id == data.id
@ -845,6 +865,7 @@
}
res = await matchingProduct(specifications.item.result)
}
console.log(res, 'res')
if (res) {
await calculateValue(res.cartNumber, '+', shopCartNumber.value)
}
@ -852,6 +873,7 @@
if (specifications.item.type != "package") {
selectedGroupSnap.value = []
}
websocketsendMessage({
id: res ? res.cartListId : '',
type: 'shopping',
@ -1044,6 +1066,9 @@
//
if (Message.operate_type == "init") {
cartList.value = Message.data
setTimeout(()=>{
isLoading.value = false;
},1000)
}
//
@ -1160,6 +1185,14 @@
if (matchedProducts.value.length > 0) {
//
let cart = matchedProducts.value.reduce((total, item) => {
if (item.type == 'sku') {
item.skuList.forEach((i, t) => {
if (item.cartListinfo.sku_id == i.id) {
item.memberPrice = i.memberPrice
item.salePrice = i.salePrice
}
})
}
// 01
if (shopInfo.isVip == 1 && shopInfo.isMemberPrice == 1) {
// memberPrice
@ -1170,7 +1203,6 @@
return total + parseFloat(item.salePrice || 0) * parseFloat(item.cartNumber);
}
}, 0);
//
return parseFloat(cart.toFixed(2));
} else {
return 0
@ -1279,6 +1311,11 @@
// return isInDayRange && isInTimeRange;
// });
const endTimeref = reactive({
startTime: '',
endTime: ''
})
//
const getCurrentTime = () => {
const now = new Date();
@ -1294,6 +1331,12 @@
}
const currentTime = getCurrentTime();
const [startTime, endTime] = shopInfo.businessTime.split('-');
endTimeref.startTime = startTime
endTimeref.endTime = endTime
//
if (startTime > endTime) {
return currentTime >= startTime || currentTime <= endTime;
}
return currentTime >= startTime && currentTime <= endTime;
});
@ -1303,7 +1346,15 @@
try {
shopProductList.hots = await productminiApphotsquery()
shopProductList.productInfo = await APIgroupquery()
} catch (error) {}
} catch (error) {
uni.showToast({
title: '网络不稳定,请重新扫码进入',
icon: 'none'
})
setTimeout(() => {
uni.pro.switchTab('index/index')
}, 1000)
}
if (shopProductList.productInfo.length > 0 || shopProductList.hots.length > 0) {
//TODO handle the exception
// cartNumber 0

696
pages/subscribeto/index.vue Normal file
View File

@ -0,0 +1,696 @@
<template>
<view class="container">
<block v-if="!dataform.queueInfo">
<image class="top_bg" src="https://czg-qr-order.oss-cn-beijing.aliyuncs.com/queueUp/queueUp_bg.png"
mode="aspectFill"></image>
<view class="content">
<image class="top_img" src="https://czg-qr-order.oss-cn-beijing.aliyuncs.com/queueUp/queueUp_img.png"
mode="aspectFill"></image>
<view class="head">
<image class="avatar" :src="dataform.shopInfo.logo" mode="aspectFill"></image>
<view class="head_text">
<text class="shopName">{{shopInfo.shopName}}</text>
<text class="tip">{{dataform.shopInfo.status == 1 ? '营业中' : '休息中'}}</text>
</view>
</view>
<view class="center">
<view class="center_head">
<text>餐桌类型</text>
<text>等待桌数</text>
<text>预计等待</text>
</view>
<view class="center_list" v-for="(item,index) in tableList" :key="index">
<view class="w center_list_item">
<text>{{item.name||''}}</text>
<text>{{item.note||''}}</text>
</view>
<view class="w center_list_item">
<text>{{item.waitingCount}}</text>
<text></text>
</view>
<view class="w time">{{item.waitTime}}分钟</view>
</view>
</view>
</view>
<view class="addBtn" @click="dataform.show = true" v-if="dataform.shopInfo.status == 1">
立即排队
</view>
</block>
<block v-else>
<view class="result"
style="background: url('https://czg-qr-order.oss-cn-beijing.aliyuncs.com/queueUp/queueUp_su_bg.png') no-repeat center 26rpx / 96%;">
<view class="head">
<u-icon name="checkmark-circle-fill" color="#fff" size="40"></u-icon>
<view class="title">排队成功</view>
</view>
<view class="center">
<view class="center_top">
<view class="shopName">{{dataform.shopInfo.shopName}}</view>
<view class="tip">当前门店</view>
</view>
<view class="sort">{{dataform.queueInfo.callNum}}</view>
<view class="note">{{dataform.queueInfo.tableName}}{{dataform.queueInfo.tableNote||''}}</view>
</view>
<view class="footer">
<view class="footer_item">
<view class="footer_item_top"><text>{{dataform.queueInfo.waitingCount}}</text><text></text></view>
<view class="footer_item_bom">前方等待桌数</view>
</view>
<view class="footer_item">
<view class="footer_item_top"><text>{{dataform.queueInfo.waitTime||''}}</text><text>分钟</text></view>
<view class="footer_item_bom">预计等待时长</view>
</view>
</view>
<view class="result_btn">
<view class="subscribe" @click="subscribe">
订阅通知
</view>
<view class="cancelBtn" @click="cancelTakeNumber">
取消排队
</view>
</view>
</view>
</block>
<!-- 立即排队 -->
<up-popup :show="dataform.show" mode="center" @close="close" round="18" :safeAreaInsetBottom="false">
<view class="add_content">
<view class="head">
<view></view>
<view class="title">取号</view>
<u-icon name="close-circle-fill" color="#666" size="30" @click="close"></u-icon>
</view>
<view class="center">
<view>
<view class="title">选择桌型</view>
<view class="tablelist">
<view class="tablelist_item" :class="{'active': item.id == dataform.callTableId }"
v-for="(item,index) in tableList" :key="index" @click="tableCut(item)">
<view>{{item.name||''}}</view>
<view>{{item.note||''}}</view>
</view>
</view>
</view>
<view>
<view class="title">手机号码</view>
<u--input type="number" placeholder="填写号码" border="surround" v-model="dataform.phone"></u--input>
</view>
</view>
<view class="footer">
<view @click="close">取消</view>
<view @click="getTakeNumber">确认取号</view>
</view>
</view>
</up-popup>
</view>
</template>
<script setup>
import {
reactive,
ref
} from 'vue';
const queueUpList = ref([])
const tableList = ref([])
const dataform = reactive({
show: false,
phone: "",
callTableId: "",
shopInfo: null,
queueInfo: null,
shopId: "",
queueId: "",
})
export default {
onLoad(options) {
// #ifdef MP-WEIXIN
if (options.q) {
this.shopId = this.getQueryString(decodeURIComponent(options.q), 'shopId')
this.queueId = this.getQueryString(decodeURIComponent(options.q), 'queueId')
}
// #endif
// #ifdef MP-ALIPAY
if (getApp().globalData.shopId) {
this.shopId = getApp().globalData.shopId
}
if (getApp().globalData.queueId) {
this.queueId = getApp().globalData.queueId
}
// #endif
},
onShow() {
this.getQueueUpState();
this.getQueueUpTablList();
},
methods: {
/**
* 解码
* @param {Object} url
* @param {Object} name
*/
getQueryString(url, name) {
var reg = new RegExp('(^|&|/?)' + name + '=([^&|/?]*)(&|/?|$)', 'i')
var r = url.substr(1).match(reg)
if (r != null) {
return r[2]
}
return null;
},
/**
* 获取排号状态
*/
async getQueueUpState() {
let params = {
openId: uni.cache.get('miniAppOpenId'),
shopId: this.shopId,
}
if (this.queueId) {
params.queueId = this.queueId;
}
let res = await this.api.getQueueUpState(params)
if (res.code == 0) {
dataform.shopInfo = res.data.shopInfo;
dataform.queueInfo = res.data.queueInfo;
dataform.queueId = dataform.queueInfo.id;
}
},
/**
* 获取排号数据
*/
async getQueueUpList() {
let res = await this.api.getQueueUpList({
openId: uni.cache.get('miniAppOpenId'),
shopId: this.shopId,
})
if (res.code == 0 && res.data.length > 0) {
queueUpList.value = res.data;
}
},
/**
* 获取桌型数据
*/
async getQueueUpTablList() {
let res = await this.api.getQueueUpTablList({
shopId: this.shopId,
})
if (res.code == 0 && res.data.length > 0) {
tableList.value = res.data;
dataform.callTableId = res.data[0].id;
}
},
/**
* 订阅通知
*/
async subscribe() {
let res = await this.api.setSubMsg({
openId: uni.cache.get('miniAppOpenId'),
shopId: this.shopId,
queueId: this.queueId,
})
if (res.code == 0) {
uni.showToast({
title: '订阅成功',
icon: 'none'
});
uni.requestSubscribeMessage({
tmplIds: ["qUhvEfvCtIcBA3DOn3QMqsGOolrEpyr0YBh99i-AUqw",
"yxOjWK-KjMEZ_BaHWqDJJpHiUPXN6JWqr7u9y65RIWM",
"3BgFazRpVlvreh5z9u4cNP_VeclXKSQfh-r3x2_bYx4"
],
complete() {
},
})
}
},
/**
* 取号
*/
async getTakeNumber() {
if (dataform.phone == "" || dataform.phone == null) {
uni.showToast({
title: '请填写手机号',
icon: 'none'
});
return;
}
let res = await this.api.getTakeNumber({
openId: uni.cache.get('miniAppOpenId'),
shopId: dataform.shopId,
phone: dataform.phone,
callTableId: dataform.callTableId,
})
if (res.code == 0) {
dataform.phone = "";
dataform.queueId = res.data.id;
this.getQueueUpState();
dataform.show = false;
uni.requestSubscribeMessage({
tmplIds: ["qUhvEfvCtIcBA3DOn3QMqsGOolrEpyr0YBh99i-AUqw",
"yxOjWK-KjMEZ_BaHWqDJJpHiUPXN6JWqr7u9y65RIWM",
"3BgFazRpVlvreh5z9u4cNP_VeclXKSQfh-r3x2_bYx4"
],
complete() {
},
})
}
},
/**
* 取消排队
*/
async cancelTakeNumber() {
let res = await this.api.cancelTakeNumber({
queueId: dataform.queueInfo.id,
shopId: this.shopId,
})
if (res.code == 0) {
this.getQueueUpTablList();
this.getQueueUpState();
}
},
/**
* 切换桌型
*/
tableCut(item) {
dataform.callTableId = item.id;
},
/**
* 弹窗关闭监听
*/
close() {
this.phone = "";
if (tableList.value.length > 0) {
dataform.callTableId = tableList.value[0].id;
}
dataform.show = false;
},
}
};
</script>
<style scoped lang="scss">
page {
// background: #f6f6f6;
}
.top_bg {
width: 100%;
height: 320rpx;
position: absolute;
z-index: 1;
top: 0;
}
.content {
position: relative;
z-index: 2;
display: flex;
flex-direction: column;
padding: 48rpx 32rpx;
.top_img {
width: 282rpx;
height: 222rpx;
position: absolute;
top: 20rpx;
right: 26rpx;
}
.head {
display: flex;
align-items: center;
.avatar {
width: 96rpx;
height: 96rpx;
margin-right: 16rpx;
border-radius: 50%;
}
.head_text {
display: flex;
flex-direction: column;
.shopName {
font-weight: 500;
font-size: 32rpx;
color: #FFFFFF;
margin-bottom: 10rpx;
}
.tip {
background: #F6FAFF;
border-radius: 4rpx;
font-weight: 400;
font-size: 20rpx;
color: #318AFE;
padding: 4rpx 10rpx;
align-self: flex-start;
}
}
}
.center {
background-color: #fff;
border-radius: 18rpx;
display: flex;
flex-direction: column;
margin-top: 48rpx;
.center_head {
height: 104rpx;
display: flex;
align-items: center;
justify-content: space-between;
background-color: #FAFAFA;
border-radius: 18rpx 18rpx 0rpx 0rpx;
text {
width: 100%;
text-align: center;
font-weight: 400;
font-size: 28rpx;
color: #333333;
}
}
.center_list {
display: flex;
align-items: center;
padding: 32rpx 0;
.w {
width: 33.333%;
text-align: center;
}
.center_list_item {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text {}
text:nth-child(1) {
font-weight: bold;
font-size: 32rpx;
color: #333333;
margin-bottom: 12rpx;
}
text:nth-child(2) {
font-weight: 400;
font-size: 24rpx;
color: #666666;
}
}
.time {
font-weight: bold;
font-size: 32rpx;
color: #333333;
}
}
}
}
.addBtn {
width: 530rpx;
height: 80rpx;
line-height: 80rpx;
text-align: center;
background: #000000;
border-radius: 56rpx 56rpx 56rpx 56rpx;
font-weight: 500;
font-size: 32rpx;
color: #FFFFFF;
margin: 16rpx auto 64rpx auto;
}
.add_content {
width: 594rpx;
display: flex;
flex-direction: column;
justify-content: space-between;
.head {
display: flex;
justify-content: space-between;
align-items: center;
padding: 32rpx;
.title {
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: bold;
font-size: 32rpx;
color: #333333;
}
}
.center {
display: flex;
flex-direction: column;
padding: 32rpx;
.title {
font-weight: bold;
font-size: 28rpx;
color: #333333;
margin-bottom: 24rpx;
}
.tablelist {
display: flex;
flex-wrap: wrap;
.tablelist_item {
min-width: 200rpx;
border-radius: 8rpx 8rpx 8rpx 8rpx;
border: 2rpx solid #E5E5E5;
margin-right: 32rpx;
margin-bottom: 32rpx;
view:nth-child(1) {
text-align: center;
font-weight: 400;
font-size: 28rpx;
color: #333333;
padding: 24rpx 0 16rpx 0;
border-bottom: 1rpx dashed #E5E5E5;
}
view:nth-child(2) {
text-align: center;
font-weight: 400;
font-size: 24rpx;
color: #999999;
padding: 16rpx 0 24rpx 0;
}
}
.active {
border: 2rpx solid #FFB562;
}
}
}
.footer {
display: flex;
view {
width: 50%;
height: 94rpx;
line-height: 94rpx;
text-align: center;
border-top: 1rpx solid #E5E5E5;
font-weight: bold;
font-size: 32rpx;
color: #333;
}
view:nth-child(1) {
color: #999999;
border-right: 1rpx solid #E5E5E5;
}
}
}
.result {
padding: 32rpx 20rpx 32rpx 20rpx;
display: flex;
flex-direction: column;
.result_bg {
padding: 0 12rpx;
}
.head {
height: 192rpx;
display: flex;
align-items: center;
justify-content: center;
.title {
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: bold;
font-size: 44rpx;
color: #333333;
margin-left: 16rpx;
}
}
.center {
display: flex;
flex-direction: column;
align-items: center;
.center_top {
display: flex;
align-items: center;
margin-top: 74rpx;
.shopName {
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 500;
font-size: 32rpx;
color: #333333;
margin-right: 16rpx;
}
.tip {
padding: 4rpx 10rpx;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
font-size: 18rpx;
color: #333333;
background-color: #E1E1E1;
border-radius: 4rpx
}
}
.sort {
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 500;
font-size: 80rpx;
color: #333333;
margin-top: 104rpx;
}
.note {
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 500;
font-size: 32rpx;
color: #999999;
margin-top: 44rpx;
margin-bottom: 84rpx;
}
}
.footer {
border-top: 1rpx dashed #E5E5E5;
padding-top: 70rpx;
display: flex;
margin-bottom: 64rpx;
.footer_item {
width: 50%;
display: flex;
flex-direction: column;
align-items: center;
.footer_item_top {
width: 100%;
display: flex;
align-items: flex-end;
justify-content: center;
text:nth-child(1) {
font-weight: bold;
font-size: 64rpx;
color: #FFB562;
}
text:nth-child(2) {
font-weight: 400;
font-size: 28rpx;
color: #666666;
margin-bottom: 12rpx;
}
}
.footer_item_bom {
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
font-size: 28rpx;
color: #666666;
margin-top: 16rpx;
}
}
.footer_item:nth-child(1) .footer_item_top {
border-right: 1rpx solid #E5E5E5;
}
}
.result_btn {
display: flex;
align-items: center;
view {
height: 80rpx;
line-height: 80rpx;
text-align: center;
border-radius: 56rpx;
border: 2rpx solid #333333;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: bold;
font-size: 32rpx;
color: #333333;
}
.subscribe {
width: 336rpx;
margin: 64rpx auto;
}
.cancelBtn {
width: 336rpx;
margin: 64rpx auto;
}
}
}
</style>

View File

@ -113,6 +113,9 @@
},
});
//
const emits = defineEmits(['emitsmemberOpen']);
//
const formInfo = reactive({
@ -304,7 +307,6 @@
const registerMember = async () => {
if (formInfo.nickName == "" || formInfo.nickName == null) {
uni.showToast({
title: '请输入会员昵称',
@ -345,9 +347,10 @@
icon: 'none'
})
//
setTimeout(() => {
uni.navigateBack()
}, 1500)
// setTimeout(() => {
// uni.navigateBack()
// }, 1500)
emits('emitsmemberOpen');
}
</script>

View File

@ -94,7 +94,8 @@
</view>
<view class="recharge" @tap="$u.debounce(userbalancerechangesub, 500)">立即充值</view>
</view>
<registermember :memberOpen="infoForn.show" :shopUserInfo="infoForn.shopUserInfo" :detailtype='detailtype'>
<registermember :memberOpen="infoForn.show" :shopUserInfo="infoForn.shopUserInfo" :detailtype='detailtype'
@emitsmemberOpen="emitsmemberOpen">
</registermember>
</view>
@ -104,7 +105,8 @@
import {
ref,
reactive,
onMounted
onMounted,
getCurrentInstance
} from 'vue';
import registermember from './components/registermember.vue'
@ -113,6 +115,11 @@
APIshopUserInfo
} from '@/common/api/member.js'
//
const {
proxy
} = getCurrentInstance();
//
import {
Memberpay
@ -194,6 +201,12 @@
});
}
const emitsmemberOpen = async () => {
asyncshopUserInfo()
await paygetActive()
// infoForn.show = false
}
//
const amountChange = () => {
let item = infoForn.listdata.filter(item => infoForn.amount == item.amount)
@ -212,36 +225,6 @@
}
const shopInfo = async () => {
let res = await this.api.shopUserInfo({
shopId: this.shopId,
userId: uni.cache.get('userInfo').id,
})
if (res.code == 0) {
infoForn.shopUserInfo = res.data;
uni.cache.remove('memberOpen', this.memberOpen)
if (infoForn.shopUserInfo.isVip == 0) {
this.memberOpen = true;
uni.cache.set('memberOpen', this.memberOpen)
}
} else {
let pages = getCurrentPages()
if (pages.length > 1) {
uni.navigateBack()
} else {
setTimeout(res => {
uni.exitMiniProgram({
success: function() {
console.log('退出小程序成功');
},
fail: function(err) {
console.log('退出小程序失败', err);
}
})
}, 500)
}
}
}
// * \
const handleClick = (item) => {
@ -268,12 +251,6 @@
complete: () => {}
})
}
//
const getRegisterMember = (e) => {
infoForn.memberOpen = e;
this.shopInfo();
this.paygetActive()
}
//
const getQueryString = (url, name) => {
@ -347,6 +324,7 @@
onMounted(async () => {
await proxy.$onLaunched;
//
const pages = getCurrentPages();
//

View File

@ -196,7 +196,6 @@
}
}
onShow(() => {
console.log(111)
store.actionsAPIuser()
if (uni.cache.get('shopId')) {
Object.assign(userInfo, uni.cache.get('orderVIP'))

View File

@ -32,7 +32,7 @@ export const useCartStore = defineStore('cart', () => {
};
// 计算购物车商品总价格
const getTotalTotalPrices = (matchedProducts, bwc = 2) => computed(() => {
const getTotalTotalPrices = (matchedProducts) => computed(() => {
if (!matchedProducts || !Array.isArray(matchedProducts)) {
return 0;
}
@ -42,7 +42,7 @@ export const useCartStore = defineStore('cart', () => {
let cart = matchedProducts.reduce((total, item) => {
// 是否启用会员价 0否1是
if (uni.cache.get('orderVIP').isVip == 1 && uni.cache.get('ordershopUserInfo')
.isMemberPrice == 1 && bwc == 2) {
.isMemberPrice == 1) {
// memberPrice会员价
return total + (parseFloat(item.memberPrice || item.price) * parseFloat(item
.num - item
@ -52,9 +52,10 @@ export const useCartStore = defineStore('cart', () => {
return total + (parseFloat(item.price) * parseFloat(item.num - item.returnNum));
}
}, 0);
cart.toFixed(2)
// 向上取整并保留两位小数
let result = roundUpToTwoDecimals(cart, 'upward')
return result;
// let result = roundUpToTwoDecimals(cart, 'upward')
return cart;
});
// 计算商品卷所选择的总价格

View File

@ -150,10 +150,9 @@ export const productStore = defineStore('product', {
if (uni.cache.get('shopInfo').isTableFee == 0) {
uni.pro.navigateTo('product/choosetable')
} else {
uni.pro.navigateTo(
'product/index', {
tableCode: tableCode,
})
uni.reLaunch({
url: '/pages/product/index'
});
}
}
@ -188,9 +187,12 @@ export const productStore = defineStore('product', {
if (uni.cache.get('shopInfo').isTableFee == 0) {
uni.pro.navigateTo('product/choosetable')
} else {
uni.pro.navigateTo('product/index', {
tableCode: uni.cache.get('tableCode'),
})
uni.reLaunch({
url: '/pages/product/index'
});
// uni.pro.navigateTo('product/index', {
// tableCode: uni.cache.get('tableCode'),
// })
}
}