订单结算更新

This commit is contained in:
2025-11-12 13:43:35 +08:00
parent 378cddb582
commit d0cee95145
6 changed files with 395 additions and 429 deletions

View File

@@ -1,305 +1,319 @@
<template>
<view class="page-gray">
<view class="bg-fff">
<view class="search bg-fff u-flex u-col-center ">
<view class="u-flex-1">
<uni-search-bar bgColor="#F9F9F9" cancelButton="none" placeholder="输入桌号" @confirm="search"
v-model="searchValue">
</uni-search-bar>
</view>
<!-- <view class="u-flex">
<view class="page-gray">
<view class="bg-fff">
<view class="search bg-fff u-flex u-col-center">
<view class="u-flex-1">
<uni-search-bar
bgColor="#F9F9F9"
cancelButton="none"
placeholder="输入桌号"
@confirm="search"
v-model="searchValue"
>
</uni-search-bar>
</view>
<!-- <view class="u-flex">
<image src="/pagesCreateOrder/static/images/icon-saoma.svg" class="icon-saoma" mode=""></image>
</view> -->
</view>
<view>
<picker @change="areaChange" range-key="name" :value="area.defaultCateIndex" :range="area.list">
<view class="u-flex u-row-between area">
<view class="color-333">桌台类型<text v-if="area.sel">{{area.sel.name}}</text> <text
v-else>全部</text> </view>
<uni-icons type="right"></uni-icons>
</view>
</picker>
</view>
</view>
</view>
<view>
<picker
@change="areaChange"
range-key="name"
:value="area.defaultCateIndex"
:range="area.list"
>
<view class="u-flex u-row-between area">
<view class="color-333"
>桌台类型<text v-if="area.sel">{{ area.sel.name }}</text>
<text v-else>全部</text>
</view>
<uni-icons type="right"></uni-icons>
</view>
</picker>
</view>
</view>
<view class="list ">
<view class="">
<template v-if="tables.list.length">
<view class=" bg-fff box bg-fff">
<view class="" v-for="(item,index) in tables.list" :key="index" @tap="chooseTable(index,item)">
<template v-if="item.status=='idle'">
<view class="u-flex item u-row-between" style="border-bottom: 1px solid #E5E5E5;">
<view class="u-flex">
<view class="">
<view class="u-flex">
<view>{{item.name}}</view>
<view class="line"></view>
<view>{{''}}</view>
</view>
<view class="color-999 u-font-24 u-m-t-12">
<text
:style="{color:returnStutasColor(item.status)}">{{returnStutasText(item.status)}}</text>
</view>
</view>
</view>
<view class="my-radio u-font-28 u-flex color-333">
<view class="circle u-flex u-row-center"
:class="{active:index==tables.selIndex}">
<uni-icons type="checkmarkempty" :size="16" color="#fff"></uni-icons>
</view>
</view>
</view>
</template>
</view>
</view>
<view class="u-m-t-32">
<my-pagination :page="query.page" :totalElements="query.totalElements" :size="query.size"
@change="pageChange"></my-pagination>
</view>
<view class="list">
<view class="">
<template v-if="tables.list.length">
<view class="bg-fff box bg-fff">
<view
class=""
v-for="(item, index) in tables.list"
:key="index"
@tap="chooseTable(index, item)"
>
<template v-if="item.status == 'idle'">
<view
class="u-flex item u-row-between"
style="border-bottom: 1px solid #e5e5e5"
>
<view class="u-flex">
<view class="">
<view class="u-flex">
<view>{{ item.name }}</view>
<view class="line"></view>
<view>{{ "" }}</view>
</view>
<view class="color-999 u-font-24 u-m-t-12">
<text
:style="{ color: returnStutasColor(item.status) }"
>{{ returnStutasText(item.status) }}</text
>
</view>
</view>
</view>
<view class="my-radio u-font-28 u-flex color-333">
<view
class="circle u-flex u-row-center"
:class="{ active: index == tables.selIndex }"
>
<uni-icons
type="checkmarkempty"
:size="16"
color="#fff"
></uni-icons>
</view>
</view>
</view>
</template>
</view>
</view>
<view class="u-m-t-32">
<my-pagination
:page="query.page"
:totalElements="query.totalElements"
:size="query.size"
@change="pageChange"
></my-pagination>
</view>
</template>
</template>
<template v-if="tables.list.length<=0">
<my-img-empty tips="未找到相关的桌台"></my-img-empty>
</template>
</view>
</view>
</view>
<template v-if="tables.list.length <= 0">
<my-img-empty tips="未找到相关的桌台"></my-img-empty>
</template>
</view>
</view>
</view>
</template>
<script setup>
import {
$table,
$tableArea
} from '@/http/yskApi/table.js'
import {
reactive,
ref,
watch
} from 'vue';
import {
$status
} from '@/commons/table-status.js'
import {
onLoad
} from '@dcloudio/uni-app'
let nouser = ref(false)
import { $table, $tableArea } from "@/http/yskApi/table.js";
import { reactive, ref, watch } from "vue";
import { $status } from "@/commons/table-status.js";
import { onLoad } from "@dcloudio/uni-app";
let nouser = ref(false);
function returnStutasText(key) {
const item = $status[key]
return item ? item.label : ''
}
function returnStutasText(key) {
const item = $status[key];
return item ? item.label : "";
}
function returnStutasColor(key) {
// if(key=='using'){
// return 'rgb(250,85,85)'
// }else{
// return ''
// }
const item = $status[key]
return item ? item.type : ''
}
function returnStutasColor(key) {
// if(key=='using'){
// return 'rgb(250,85,85)'
// }else{
// return ''
// }
const item = $status[key];
return item ? item.type : "";
}
function emitChooeTable(data) {
uni.$emit('choose-table', data)
setTimeout(() => {
uni.navigateBack()
}, 100)
}
let searchValue = ref('')
function emitChooeTable(data) {
uni.$emit("choose-table", data);
setTimeout(() => {
uni.navigateBack();
}, 100);
}
let searchValue = ref("");
function search() {
query.page = 1
getTable()
}
function search() {
query.page = 1;
getTable();
}
function chooseTable(index, item) {
if (item.status == 'closed') {
return uni.showToast({
title: '该桌台已关闭!',
icon: 'none'
})
}
if (index === undefined || item === undefined) {
nouser.value = true
return emitChooeTable()
} else {
tables.selIndex = index
emitChooeTable(item)
}
}
function chooseTable(index, item) {
if (item.status == "closed") {
return uni.showToast({
title: "该桌台已关闭!",
icon: "none",
});
}
if (index === undefined || item === undefined) {
nouser.value = true;
return emitChooeTable();
} else {
tables.selIndex = index;
emitChooeTable(item);
}
}
//分类
const area = reactive({
list: [
{
name: "全部",
},
],
defaultCateIndex: 0,
sel: "",
});
function areaChange(e) {
area.defaultCateIndex = e.detail.value;
area.sel = area.list[e.detail.value];
query.page = 1;
getTable();
}
const query = {
page: 1,
size: 10,
areaId: 0,
totalElements: 0,
};
// 页数改变事件
function pageChange(page) {
console.log(page);
query.page = page;
getTable();
}
const tables = reactive({
hasAjax: false,
selIndex: -1,
originList: [],
list: [],
});
async function getTable() {
// let state=status.list[status.active].key
// state=state?(state=='all'?'':state):''
const areaId = area.list[area.defaultCateIndex].id || "";
let { data } = await $table.get({
...query,
areaId,
name: searchValue.value,
state: "idle",
});
query.totalElements = data.totalRow || 0;
tables.hasAjax = true;
tables.list = data.records;
tables.selIndex = data.records.findIndex(
(v) => v.tableCode == option.tableCode
);
tables.originList = data.records;
}
async function getArea() {
const { data } = await $tableArea.get({
page: 0,
size: 300,
});
data.records.unshift({
name: "全部",
});
area.list = data.records.map((v) => {
return {
...v,
};
});
}
//分类
const area = reactive({
list: [{
name: '全部'
}],
defaultCateIndex: 0,
sel: ''
})
function areaChange(e) {
area.defaultCateIndex = e.detail.value
area.sel = area.list[e.detail.value]
query.page = 1
getTable()
}
const query = {
page: 1,
size: 10,
areaId: 0,
totalElements: 0
}
// 页数改变事件
function pageChange(page) {
console.log(page);
query.page = page
getTable()
}
const tables = reactive({
hasAjax: false,
selIndex: -1,
originList: [],
list: []
})
async function getTable() {
// let state=status.list[status.active].key
// state=state?(state=='all'?'':state):''
const areaId = area.list[area.defaultCateIndex].id || ''
let {
data
} = await $table.get({
...query,
areaId,
name: searchValue.value,
state: 'idle'
})
query.totalElements = data.totalRow || 0;
tables.hasAjax = true;
tables.list = data.records
tables.selIndex = data.records.findIndex(v => v.tableCode == option.tableCode)
tables.originList = data.records
}
async function getArea() {
const {
data
} = await $tableArea.get({
page: 0,
size: 300
})
data.records.unshift({
name: '全部'
})
area.list = data.records.map(v => {
return {
...v,
}
})
}
watch(() => area.sel, (newval) => {
getTable()
})
let option = {}
onLoad(opt => {
Object.assign(option, opt)
console.log(option);
getTable()
getArea()
})
watch(
() => area.sel,
(newval) => {
getTable();
}
);
let option = {};
onLoad((opt) => {
Object.assign(option, opt);
console.log(option);
getTable();
getArea();
});
</script>
<style lang="scss" scoped>
.line {
width: 1px;
height: 20rpx;
background-color: #E5E5E5;
margin-left: 8rpx;
margin-right: 16rpx;
}
.line {
width: 1px;
height: 20rpx;
background-color: #e5e5e5;
margin-left: 8rpx;
margin-right: 16rpx;
}
.my-radio {
.my-radio {
.circle {
background: #ffffff;
width: 18px;
height: 18px;
.circle {
background: #FFFFFF;
width: 18px;
height: 18px;
&.active {
background-color: $my-main-color;
border-color: $my-main-color;
}
&.active {
background-color: $my-main-color;
border-color: $my-main-color;
}
border: 1px solid #707070;
border-radius: 50%;
overflow: hidden;
border: 1px solid #707070;
border-radius: 50%;
overflow: hidden;
&.square {
border-radius: 8rpx;
}
}
}
&.square {
border-radius: 8rpx;
}
}
.area {
padding: 2px 28rpx 24rpx 28rpx;
}
}
.scale7 {
transform: scale(0.7);
}
.area {
padding: 2px 28rpx 24rpx 28rpx;
}
::v-deep .uni-searchbar {
padding: 0 !important;
}
.scale7 {
transform: scale(0.7);
}
.search {
padding: 20rpx 28rpx 20rpx 28rpx;
::v-deep .uni-searchbar {
padding: 0 !important;
}
.icon-saoma {
margin-left: 20rpx;
width: 34rpx;
height: 32rpx;
}
}
.search {
padding: 20rpx 28rpx 20rpx 28rpx;
.list {
padding: 32rpx 24rpx;
.icon-saoma {
margin-left: 20rpx;
width: 34rpx;
height: 32rpx;
}
}
.no-choose {
padding: 36rpx 30rpx 36rpx 24rpx;
}
.list {
padding: 32rpx 24rpx;
.box {
padding: 32rpx 30rpx 32rpx 24rpx;
.no-choose {
padding: 36rpx 30rpx 36rpx 24rpx;
}
.item {
padding: 24rpx 0;
.box {
padding: 32rpx 30rpx 32rpx 24rpx;
.headimg {
border-radius: 12rpx 12rpx 12rpx 12rpx;
overflow: hidden;
font-size: 0;
width: 84rpx;
height: 84rpx;
.item {
padding: 24rpx 0;
.img {
width: 84rpx;
height: 84rpx;
}
}
}
.headimg {
border-radius: 12rpx 12rpx 12rpx 12rpx;
overflow: hidden;
font-size: 0;
width: 84rpx;
height: 84rpx;
.img {
width: 84rpx;
height: 84rpx;
}
}
}
.item:not(:first-child) {
border-top: 1px solid #E5E5E5;
}
}
}
.item:not(:first-child) {
border-top: 1px solid #e5e5e5;
}
}
}
</style>

View File

@@ -384,20 +384,20 @@
</view>
</view>
<view class="border-bottom">
<template v-if="$seatFee && $seatFee.totalAmount">
<template v-if="orderCostSummary.seatFee > 0">
<view class="u-flex u-row-between u-m-t-18 u-p-b-34">
<view>
<text>桌位费</text>
</view>
<view>¥{{ $seatFee.totalAmount.toFixed(2) || "0.00" }}</view>
<view>¥{{ orderCostSummary.seatFee }}</view>
</view>
</template>
<template v-if="$packFee > 0">
<template v-if="orderCostSummary.packFee > 0">
<view class="u-flex u-row-between u-m-t-18 u-p-b-34">
<view>
<text>打包费</text>
</view>
<view>¥{{ $packFee || "0.00" }}</view>
<view>¥{{ orderCostSummary.packFee }}</view>
</view>
</template>
</view>
@@ -412,7 +412,9 @@
<view class="u-flex price u-m-l-32">
<view class="">实收金额</view>
<view class="font-bold u-font-32">¥{{ orderCostSummary.finalPayAmount }}</view>
<view class="font-bold u-font-32"
>¥{{ orderCostSummary.finalPayAmount }}</view
>
</view>
</view>
</view>
@@ -479,7 +481,6 @@ import { getSafeBottomHeight } from "@/commons/utils/safe-bottom.js";
import go from "@/commons/utils/go.js";
import { hasPermission } from "@/commons/utils/hasPermission.js";
import { getNowCart } from "@/pagesCreateOrder/util.js";
import { number } from "uview-plus/libs/function/test";
import { getShopTableDetail } from "@/http/api/table.js";
import { getShopInfo } from "@/http/api/shop.js";
@@ -622,7 +623,6 @@ const $seatFee = reactive({
* 打包费
*/
const $packFee = computed(() => {
let packAmount = 0;
return goods.list
.reduce((prve, cur) => {
return prve + (cur.packFee || 0) * parseFloat(cur.pack_number).toFixed(2);
@@ -630,15 +630,6 @@ const $packFee = computed(() => {
.toFixed(2);
});
/**
* 菜品数量
*/
const goodsNumber = computed(() => {
const result = goods.list.reduce((prve, cur) => {
return prve + cur.number;
}, 0);
return result;
});
/**
* 判断是否是会员
@@ -652,57 +643,13 @@ const isVip = computed(() => {
);
});
const discount_sale_amount = computed(() => {
return goods.list
.filter((v) => v.discount_sale_amount && v.discount_sale_amount > 0)
.reduce((a, b) => {
const lowMemberPrice = b.lowMemberPrice ? b.lowMemberPrice : b.lowPrice;
const tPrice = isVip.value ? lowMemberPrice : b.lowPrice;
return a + b.number * (tPrice - b.discount_sale_amount);
}, 0);
});
function returnLimitPrice(data) {
const price = yskUtils.limitUtils.returnPrice({
goods: data,
shopInfo: shopInfo,
limitTimeDiscountRes: pageData.limitTimeDiscount,
shopUserInfo: null,
idKey: "id",
});
return price;
}
const goodsPrice = computed(() => {
const goodsTotalPrice = goods.list.reduce((prve, cur) => {
const lowMemberPrice = cur.lowMemberPrice
? cur.lowMemberPrice
: cur.lowPrice;
let price = isVip.value ? lowMemberPrice : cur.lowPrice;
if (cur.is_time_discount) {
price = returnLimitPrice(cur);
}
const tPrice = Math.floor(price * cur.number * 100) / 100;
return prve + (cur.is_gift ? 0 : tPrice);
}, 0);
const tpackFee = $packFee.value > 0 ? $packFee.value * 1 : 0;
return (goodsTotalPrice - discount_sale_amount.value + tpackFee || 0).toFixed(
2
);
});
/**
* 实收金额
*/
const allPrice = computed(() => {
const n = goodsPrice.value * 1 + $seatFee.totalAmount;
return n.toFixed(2);
});
/**
* 计算优惠金额
*/
const youhui = computed(() => {
return 0
return 0;
});
function toFixed(price, item) {
@@ -752,16 +699,17 @@ function onMessage() {
switch (msg.operate_type) {
case "pad_init":
goods.list = [];
console.log(msg.data);
msg.data.map((item) => {
cartItem = getNowCart(item, $goods, pageData.user);
console.log(cartItem);
if (cartItem.isGrounding || cartItem.is_temporary == 1) {
cartControls(cartItem, "add");
} else {
delCart(cartItem.id);
}
});
if (pageData.eatTypes.isShow) {
if (pageData.eatTypes.active == "take-out") {
cartItem.pack_number = cartItem.number;
@@ -811,6 +759,9 @@ function onMessage() {
case "product_update":
init();
break;
case "pad_batch":
init();
break;
}
});
}
@@ -838,22 +789,28 @@ function cartControls(cartItem, type) {
pageData.table.tableCode = cartItem.table_code;
}
let cartIndex = 0;
goods.list.map((item, index) => {
if (item.id == cartItem.id) {
cartIndex = index;
}
});
if (type == "del") {
goods.list.splice(cartIndex, 1);
return;
}
if (type == "add") {
goods.list.push(cartItem);
goods.list.push({...cartItem,packNumber:cartItem.pack_number});
}
if (type == "edit") {
goods.list[cartIndex].number = cartItem.number;
goods.list[cartIndex].pack_number = cartItem.pack_number;
goods.list[cartIndex].packNumber = cartItem.pack_number;
}
}
/**
@@ -880,6 +837,7 @@ async function getTbShopInfo() {
id: uni.getStorageSync("shopId"),
});
pageData.shopInfo = res.data;
seatFeeConfig.pricePerPerson = res.data.tableFee || 0;
uni.setStorageSync("shopInfo", res.data);
}
@@ -922,7 +880,18 @@ async function changeUseType() {
if (!goods.list.length) {
return;
}
getCart();
websocketUtil.send(
JSON.stringify({
type: "pad",
is_pack: pageData.eatTypes.active == "take-out" ? 1 : 0,
account: uni.getStorageSync("shopInfo").id,
shop_id: uni.getStorageSync("shopInfo").id,
operate_type: "batch",
table_code: pageData.table.tableCode,
})
);
// getCart();
}
/**
@@ -1160,7 +1129,6 @@ async function createAnOrder() {
let vipPrice = isVip.value ? 1 : 0;
let placeNum = pageData.orderInfo ? pageData.orderInfo.placeNum + 1 : 1;
let originAmount = goodsPrice.value * 1 + youhui.value * 1;
let par = {
shopId: pageData.shopInfo.id, //店铺Id
userId: pageData.user.userId, //用户Id
@@ -1168,12 +1136,12 @@ async function createAnOrder() {
dineMode: pageData.eatTypes.active, //用餐模式 堂食 dine-in 外带 take-out 外卖 take-away
remark: pageData.form.note, //备注
seatNum: 0, //用餐人数
packFee: $packFee.value, //打包费
originAmount: originAmount, //订单原金额(包含打包费+餐位费) 不含折扣价格
packFee:pageData.eatTypes.active=='dine-in'?seatFeeConfig.personCount : 0, //打包费
originAmount: orderCostSummary.value.goodsRealAmount, //订单原金额(包含打包费+餐位费)
placeNum: placeNum, //当前订单下单次数
waitCall: 0, //是否等叫 0 否 1 等叫
vipPrice: vipPrice, //是否使用会员价
limitRate:pageData.limitTimeDiscount
limitRate: pageData.limitTimeDiscount,
};
if (!pageData.shopInfo.isTableFee && pageData.table && pageData.table.id) {
par.seatNum = userNumbers.defaultCateIndex * 1 + 1;
@@ -1186,7 +1154,7 @@ async function createAnOrder() {
console.log(res, "创建订单");
if (res.code != 200) {
uni.showToast({
title: res.msg||'创建订单失败!',
title: res.msg || "创建订单失败!",
icon: "none",
});
return;
@@ -1223,7 +1191,7 @@ async function createAnOrder() {
"PAGES_ORDER_DETAIL",
{
id: res.data.id,
dinnerType: pageData.eatTypes.active,
dinnerType: pageData.eatTypes.active,
},
"redirect"
);
@@ -1239,9 +1207,6 @@ async function createAnOrder() {
});
}
//选择的优惠券
const selCoupon = ref([]);
//活动列表
@@ -1303,6 +1268,7 @@ const orderExtraConfig = computed(() => {
});
// 订单费用汇总
const orderCostSummary = computed(() => {
console.log(goods.list, "购物车数据");
const costSummary = yskUtils.OrderPriceCalculator.calculateOrderCostSummary(
goods.list,
pageData.eatTypes.active,
@@ -1315,7 +1281,15 @@ const orderCostSummary = computed(() => {
console.log(" 订单费用汇总", costSummary);
return costSummary;
});
watch(
() => $seatFee.totalNumber,
(newVal, oldVal) => {
seatFeeConfig.personCount = newVal;
},
{
immediate: true,
}
);
</script>
<style lang="scss" scoped>

View File

@@ -35,7 +35,6 @@ export function getNowCart(carItem,goodsList,user) {
})
} else {
// 临时菜
console.log(carItem,'salePrice1111111111')
carItem.number = parseFloat(carItem.number)
carItem.name = carItem.product_name
carItem.lowPrice = carItem.discount_sale_amount