修复转桌问题,餐位费问题,台桌增加显示更多信息,修复添加耗材第二单位

This commit is contained in:
2026-04-01 10:13:01 +08:00
parent c4283f0d1b
commit 4aea9740a1
8 changed files with 222 additions and 155 deletions

View File

@@ -1,6 +1,6 @@
<template>
<view>
<up-popup :show="show" mode="center">
<up-popup :show="show" mode="center" @close="close">
<view class="bg-fff u-p-30 box">
<scroll-view direction="vertical" scroll-y style="max-height: 80vh;">
@@ -20,18 +20,20 @@
<template v-if="form.type==1">
<view class=" u-m-t-32 ">
<view class="u-m-b-24">购物车商品</view>
<!-- <goodsTable :data="nowCartData" :columns="columnsCheck1" row-key="id"
@selection-change="handleSelectionChange($event,'now')"></goodsTable> -->
<u-table2 :data="nowCartData" :columns="columnsCheck1" row-key="id"
@selection-change="handleSelectionChange($event,'now')" />
<goodsTable :data="nowCartData" :columns="columnsCheck1" row-key="id"
@selection-change="handleSelectionChange($event,'now')"></goodsTable>
<!-- <u-table2 :data="nowCartData" :columns="columnsCheck1" row-key="id"
@selection-change="handleSelectionChange($event,'now')" /> -->
</view>
<view class=" u-m-t-50 ">
<view class="u-m-b-24">历史订单商品</view>
<view v-for="(order,orderIndex) in goodsList" class="u-m-t-32" :key="index">
<view>{{ orderIndex }}次下单</view>
<u-table2 :data="order" :columns="columnsCheck" row-key="id"
<goodsTable :data="order" :columns="columnsCheck" row-key="id"
@selection-change="handleSelectionChange($event,'old')" />
<!-- <u-table2 :data="order" :columns="columnsCheck" row-key="id"
@selection-change="handleSelectionChange($event,'old')" /> -->
</view>
@@ -84,6 +86,8 @@
})
function close() {
console.log('close');
form.mewTable = {id: ''}
show.value = false
}
const form = reactive({
@@ -131,6 +135,7 @@
const handleSelectionChange = (selection, key) => {
console.log('handleSelectionChange', selection);
if (key === 'old') {
form.old = selection
}
@@ -171,12 +176,11 @@
title: '转桌成功',
icon: 'none'
})
close()
emits('update', 1)
close()
})
} else {
close()
emits('confirm', {
targetTableCode: form.mewTable.tableCode,
old: {
@@ -193,6 +197,7 @@
cart_id: props.nowCartData.map(v => v.id)
}
})
close()
}
return
@@ -215,12 +220,10 @@
title: '转桌成功',
icon: 'none'
})
close()
emits('update', allMerge)
close()
})
} else {
close()
emits('confirm', {
targetTableCode: form.mewTable.tableCode,
old: {
@@ -234,6 +237,7 @@
cart_id: form.now.map(v => v.id)
}
})
close()
}
}

View File

@@ -78,6 +78,8 @@
})
}
modelValue.value = list.value[selIndex.value]
console.log('selIndex.value', selIndex.value );
console.log('modelValue.value ', modelValue.value );
close()
}
const query = reactive({

View File

@@ -4,7 +4,8 @@
<view class="u-flex u-row-between no-wrap title">
<!-- 全选框 -->
<view class="table-th">
<up-checkbox @change="handleSelectAll" usedAlone v-model:checked="internalAllChecked" shape="square" :size="20" />
<up-checkbox @change="handleSelectAll" usedAlone v-model:checked="internalAllChecked" shape="square"
:size="20" />
</view>
<!-- 动态列标题 -->
@@ -13,24 +14,24 @@
</view>
</view>
<!-- 格行 -->
<view @click="handleRowCheck(item)" class="u-m-t-12 u-flex u-p-24 u-row-between row"
v-for="(item, index) in internalData" :key="item.id || index" row-key="id">
<!-- 单选框 -->
<view class="table-td">
<up-checkbox
usedAlone
v-model:checked="item._checked" shape="square" :size="20" @change="handleRowCheck(item)"></up-checkbox>
</view>
<!-- 有数据 渲染列 -->
<template v-if="internalData.length > 0">
<view @click="handleRowCheck(item)" class="u-m-t-12 u-flex u-p-24 u-row-between row"
v-for="(item, index) in internalData" :key="item.id || index" row-key="id">
<view class="table-td">
<up-checkbox @change="handleRowCheck(item)" usedAlone v-model:checked="item._checked" shape="square" :size="20"></up-checkbox>
</view>
<!-- 动态列内容 -->
<view class="table-td" v-for="col in columns" :key="col.key" :style="col.style || {}">
<!-- 支持自定义渲染 / 直接取值 -->
<slot v-if="col.slot" :name="col.slot" :row="item" />
<template v-else>
{{ item[col.key] }}
</template>
<view class="table-td" v-for="col in columns" :key="col.key" :style="col.style || {}">
<slot v-if="col.slot" :name="col.slot" :row="item" />
<template v-else>{{ item[col.key] }}</template>
</view>
</view>
</template>
<!-- 无数据 显示暂无数据 -->
<view v-else class="empty-text u-p-t-40 u-p-b-40 u-text-center">
暂无数据
</view>
</view>
</template>
@@ -83,12 +84,13 @@
// 全选切换
function handleSelectAll() {
internalAllChecked.value = !internalAllChecked.value
const checked = internalAllChecked.value;
internalData.value=internalData.value.map(item=>{
internalData.value = internalData.value.map(item => {
item._checked = checked;
return item;
})
console.log('internalData.value',internalData.value);
console.log('internalData.value', internalData.value);
emitChange();
}
@@ -103,6 +105,7 @@
const selectedRows = internalData.value.filter(item => item._checked);
emits('selection-change', selectedRows);
}
// 监听所有行选中状态,自动更新全选框
watch(
@@ -143,5 +146,11 @@
.row:nth-of-type(2n + 1) {
background: #f0f0f0;
}
// 空数据样式
.empty-text {
font-size: 28rpx;
color: #999;
}
}
</style>

View File

@@ -87,7 +87,7 @@ let datas = reactive({
consGroupId: null,
conUnitTwo: '', // 第二单位
conUnitTwoConvert: '', // 第二单位转换数量
defaultUnit: 2
defaultUnit: ''
},
consGroupName: '',
typeList: []

View File

@@ -15,41 +15,48 @@
</view>
</view>
<view class="u-flex u-flex-col u-row-center u-col-center bg-fff bottom">
<template v-if="data.status != 'using'">
<view class="u-font-32" :style="{ color: returnStutasColor(data.status) }">{{ returnStutasText(data.status) }}~</view>
<template v-if="data.status != 'unsettled'">
<view class="u-font-32" :style="{ color: returnStutasColor(data.status) }">
{{ returnStutasText(data.status) }}~</view>
</template>
<view class="w-full u-p-l-16 u-p-r-16 u-p-t-16 u-font-24">
<template v-if="data.status == 'using' && data.orderId">
<template v-if="data.status == 'unsettled' && data.orderId">
<view class="color-666 u-text-left u-p-b-20 border-bottom">
<view class="">
<text>已点</text>
<text class="u-m-l-20 color-333">{{ data.productNum || 0 }}</text>
<text>就餐人数</text>
<text class="u-m-l-20 color-333">{{ data.personNum}}/{{data.maxCapacity}}</text>
</view>
<view class="u-m-t-10">
<text>金额</text>
<text class="u-m-l-20 color-333">{{ data.totalAmount || 0 }} </text>
<text class="u-m-l-20 color-333">{{ data.orderAmount || 0 }} </text>
</view>
<view class="u-m-t-10">
<!-- <view class="u-m-t-10">
<text>待结</text>
<text class="u-m-l-20 color-333">{{ data.totalAmount || 0 }} </text>
</view>
</view> -->
</view>
<view class="u-flex u-row-between u-font-20 u-p-b-20 u-p-t-20">
<text class="color-333">开台时间</text>
<text class="color-666">{{ data.useTime }}</text>
<!-- <text class="color-666">{{ data.orderCreateTime }}</text> -->
<text class="color-666">{{ formatTime(data.orderCreateTime) }}</text>
</view>
</template>
<template v-else>
<view class="u-flex u-row-center u-m-t-16">
<template v-if="data.id">
<template v-if="data.status == 'unbind'">
<my-button color="#333" :width="200" :height="56" type="default" @click="bind">绑定码牌</my-button>
<my-button color="#333" :width="200" :height="56" type="default"
@click="bind">绑定码牌</my-button>
</template>
<template v-if="data.status == 'idle' || (data.status == 'using' && !data.orderId)">
<my-button color="#333" :width="150" :height="56" type="default" @click="diancan">选择</my-button>
<template v-if="data.status == 'idle' || (data.status == 'unsettled' && !data.orderId)">
<my-button color="#333" :width="150" :height="56" type="default"
@click="diancan">选择</my-button>
</template>
<template v-if="data.status == 'cleaning'">
<my-button color="#333" :width="150" :height="56" type="default" @click="qingtai">清台</my-button>
<my-button color="#333" :width="150" :height="56" type="default"
@click="qingtai">清台</my-button>
</template>
</template>
<my-button v-else :width="150" :height="56" type="default" disabled>选择</my-button>
@@ -61,124 +68,165 @@
</template>
<script setup>
import { computed, ref } from 'vue';
import myButton from '@/components/my-components/my-button';
import go from '@/commons/utils/go.js';
import { hasPermission } from '@/commons/utils/hasPermission.js';
import { shopTableClear } from '@/http/api/table.js';
import {
computed,onUnmounted,
ref
} from 'vue';
import myButton from '@/components/my-components/my-button';
import go from '@/commons/utils/go.js';
import {
hasPermission
} from '@/commons/utils/hasPermission.js';
import {
shopTableClear
} from '@/http/api/table.js';
const emits = defineEmits(['more', 'update', 'bind']);
const props = defineProps({
data: {
type: Object,
default: () => {
return {};
const emits = defineEmits(['more', 'update', 'bind']);
const props = defineProps({
data: {
type: Object,
default: () => {
return {};
}
},
areaMap: {
type: Object,
default: () => {}
}
},
areaMap: {
type: Object,
default: () => {}
});
const computedClass = computed(() => {
return props.data.status;
});
function returnStutasText(key) {
const item = uni.$dict.tableStatus[key];
return item ? item.label : '';
}
});
const computedClass = computed(() => {
return props.data.status;
});
function returnStutasColor(key) {
const item = uni.$dict.tableStatus[key];
return item ? item.type : '';
}
const nowTime = ref(new Date().getTime());
// 定时器 ID用于销毁
let timer = null;
// 启动实时更新时间uniapp 全端稳定)
function updateTime() {
timer = setInterval(() => {
nowTime.value = new Date().getTime();
}, 1000); // 1秒刷新一次足够用
}
updateTime();
// 页面销毁时清除定时器(必须加!)
onUnmounted(() => {
if (timer) {
clearInterval(timer);
timer = null;
}
});
// 时间格式化工具(完全不变,逻辑一样)
function formatTime(str) {
if (!str) return "";
const targetTime = new Date(str).getTime();
const milliseconds = nowTime.value - targetTime;
if (milliseconds <= 0) return "已结束";
const days = Math.floor(milliseconds / (1000 * 60 * 60 * 24));
const hours = Math.floor((milliseconds % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
const minutes = Math.floor((milliseconds % (1000 * 60 * 60)) / (1000 * 60));
return `${days ? days + "天" : ""} ${hours ? hours + "时" : ""} ${minutes + "分"}`;
}
/**
* 更多
*/
function more() {
if (props.data.status == 'done') {
return uni.showToast({
icon: 'none',
title: '桌台关闭中!'
});
}
emits('more');
}
function returnStutasText(key) {
const item = uni.$dict.tableStatus[key];
return item ? item.label : '';
}
/**
* 绑定码牌
*/
function bind() {
emits('bind', props.data);
}
function returnStutasColor(key) {
const item = uni.$dict.tableStatus[key];
return item ? item.type : '';
}
/**
* 更多
*/
function more() {
if (props.data.status == 'done') {
return uni.showToast({
icon: 'none',
title: '桌台关闭中!'
/**
* 选择下单
*/
async function diancan() {
hasPermission('允许下单').then((res) => {
console.log(res);
if (res) {
const useType = props.status == 'unsettled' ? props.data.useType : undefined;
console.log(props.data);
go.to('PAGES_CREATE_ORDER', props.data);
}
});
}
emits('more');
}
/**
* 绑定码牌
*/
function bind() {
emits('bind', props.data);
}
/**
* 选择下单
*/
async function diancan() {
hasPermission('允许下单').then((res) => {
console.log(res);
if (res) {
const useType = props.status == 'using' ? props.data.useType : undefined;
console.log(props.data);
go.to('PAGES_CREATE_ORDER', props.data);
}
});
}
/**
* 清台
*/
function qingtai() {
let item = props.data;
uni.showModal({
title: '提示',
content: '确定要清台:' + item.name + '',
success(res) {
if (res.confirm) {
shopTableClear({
id: item.id
}).then((res) => {
uni.$utils.showToast('清台成功');
emits('update');
});
/**
* 清台
*/
function qingtai() {
let item = props.data;
uni.showModal({
title: '提示',
content: '确定要清台:' + item.name + '',
success(res) {
if (res.confirm) {
shopTableClear({
id: item.id
}).then((res) => {
uni.$utils.showToast('清台成功');
emits('update');
});
}
}
}
});
}
});
}
</script>
<style lang="scss" scoped>
.item {
width: 330rpx;
box-sizing: border-box;
overflow: hidden;
box-shadow: 1px 1px 0 #eee;
border-color: #eee;
.item {
width: 330rpx;
box-sizing: border-box;
overflow: hidden;
box-shadow: 1px 1px 0 #eee;
border-color: #eee;
.bottom {
min-height: 224rpx;
}
.bottom {
min-height: 224rpx;
}
.my-bg-main {
padding: 24rpx 28rpx;
.my-bg-main {
padding: 24rpx 28rpx;
.tag {
background-color: rgba(255, 255, 255, 0.7);
font-size: 24rpx;
color: $my-main-color;
border-radius: 8rpx;
padding: 2rpx 10rpx;
.tag {
background-color: rgba(255, 255, 255, 0.7);
font-size: 24rpx;
color: $my-main-color;
border-radius: 8rpx;
padding: 2rpx 10rpx;
}
}
&.unsettled {
.tag {
color: rgb(250, 85, 85);
}
}
}
&.using {
.tag {
color: rgb(250, 85, 85);
}
}
}
</style>
</style>

View File

@@ -83,7 +83,7 @@ import { getShopTable, shopTableBind, shopTableClear } from '@/http/api/table.js
import { getShopArea } from '@/http/api/area.js';
import { printOrder } from '@/http/api/order.js';
import { getHistoryOrder } from '@/http/api/order.js';
import tableStatus from './tableStatus'
const pageData = reactive({
statusShow: false,
hasAjax: false,
@@ -102,7 +102,8 @@ const pageData = reactive({
key: '',
label: '全部'
},
...uni.$utils.objToArrary(uni.$dict.tableStatus)
// ...uni.$utils.objToArrary(uni.$dict.tableStatus)
...tableStatus
]
],
statusName: '全部',
@@ -164,8 +165,9 @@ async function getArea() {
* @param {Object} e
*/
function confirmStatus(e) {
console.log('---',e);
pageData.statusShow = false;
pageData.query.status = e.value[0].key;
pageData.query.status = e.value[0].type;
pageData.statusName = e.value[0].label;
getTable();
}

View File

@@ -422,6 +422,7 @@
} from '@/http/api/order/order.js'
function changeTableConfirm(json) {
console.log('changeTableConfirm',json);
websocketUtil.send(
JSON.stringify({
type: "shopping",

View File

@@ -392,7 +392,6 @@ async function init() {
}
Object.assign(order, orderRes);
pageData.goodsList = objToArrary(orderRes.detailMap);
// console.log("order===",order)
// console.log("pageData.user===",pageData.user)
// 获取用户信息
@@ -412,6 +411,7 @@ async function init() {
}
pageData.seatNum = order.seatNum;
seatFeeConfig.personCount = order.seatNum;
console.log('seatFeeConfig',seatFeeConfig);
}
/**
@@ -464,7 +464,7 @@ const pointDeductionRule = reactive({
const seatFeeConfig = reactive({
pricePerPerson: pageData.shopInfo.tableFee || 0,
personCount: 0, //就餐人数
isEnabled: !pageData.shopInfo.isTableFee
isEnabled: !pageData.shopInfo.isTableFee,
});
//使用积分数量
const userPoints = ref(0);
@@ -517,7 +517,7 @@ const orderExtraConfig = computed(() => {
memberDiscountRate: 1,
newUserDiscount: newUserDiscount.value,
fullReductionActivities: fullReductionActivities.value,
currentDinnerType: options.dinnerType,
currentDinnerType: options.dinnerType||order.dineMode,
isFreeDine: false, //霸王餐
freeDineConfig: freeDineConfig.value,
limitTimeDiscount: order.limitRate,
@@ -528,7 +528,7 @@ const orderExtraConfig = computed(() => {
const orderCostSummary = computed(() => {
const costSummary = yskUtils.OrderPriceCalculator.calculateOrderCostSummary(
pageData.goodsList,
options.dinnerType,
(options.dinnerType||order.dineMode),
selCoupon.value,
activityList.value,
orderExtraConfig.value,
@@ -633,6 +633,7 @@ watch(
);
function getPayParam() {
const dinnerType=options.dinnerType||order.dineMode
let params = {
shopId: uni.getStorageSync('shopInfo').id || '',
orderId: order.id,
@@ -646,7 +647,7 @@ function getPayParam() {
roundAmount: 0, //抹零金额 减免多少钱
pointsDiscountAmount: orderCostSummary.value.pointDeductionAmount, //积分抵扣金额(tb_points_basic_setting表)
pointsNum: orderCostSummary.value.pointUsed, //(扣除各类折扣 enable_deduction后使用)
seatNum: options.dinnerType == 'dine-in' ? seatFeeConfig.personCount : 0, //用餐人数
seatNum: dinnerType == 'dine-in' ? seatFeeConfig.personCount : 0, //用餐人数
newCustomerDiscountAmount: orderCostSummary.value.newUserDiscount, //新客立减
newCustomerDiscountId: orderCostSummary.value.newUserDiscount > 0 ? newUserDiscountRes.value.id : '',