Files
cashier-ipad-new/pagesCreateOrder/table-order/components/goods-list.vue
2025-12-05 19:22:28 +08:00

309 lines
7.6 KiB
Vue

<template>
<view class="table">
<view class="header">
<text>商品</text>
<view class="u-flex" style="gap: 54rpx">
<text>数量</text>
<text>单价</text>
<text>小计</text>
</view>
</view>
<view class="list">
<view
v-for="(item, index) in cartStore.allCartList"
:key="index"
class="item transition"
@click="itemClick(item)"
:class="[isSelected(item) ? 'isSelected' : '']"
>
<view class="u-flex">
<text>{{ item.productName }}</text>
<view class="u-flex gap-20" style="margin-left: 40rpx">
<text class="status gift" v-if="item.isGift"></text>
<text class="status pack" v-if="item.packNumber > 0"
>
<view class="badge">{{ item.packNumber }}</view>
</text>
<template
v-if="
item.subStatus && cartStore.shopInfo.registerType == 'after'
"
>
<text
class="status"
:class="[
returnSubStatusText(item) == '已超时' ? 'timeout' : '',
returnStatusClass(item),
]"
>{{ returnSubStatusText(item) }}</text
>
</template>
</view>
</view>
<view class="u-flex text-center" style="gap: 54rpx; min-width: 348rpx">
<text class="u-flex-1">{{ item.num }}</text>
<view class="u-flex u-flex-1 u-relative">
<text class="limit-price" v-if="showOldPrice(item)">
{{ returnPrice(item) }}
</text>
<text
class="origin-price"
:class="[showOldPrice(item) ? 'old-price' : '']"
>{{ item.price }}</text
>
</view>
<text class="u-flex-1">{{
BigNumber(item.num).times(returnPrice(item)).toFixed(2)
}}</text>
</view>
</view>
<view class="item" v-if="cartStore.orderCostSummary.seatFee > 0">
<view class="u-flex">
<text>餐位费</text>
</view>
<view class="u-flex text-center" style="gap: 54rpx; min-width: 348rpx">
<text class="u-flex-1">{{ cartStore.personCount }}</text>
<view class="u-flex u-flex-1 u-relative">
<text class="origin-price">{{ cartStore.shopInfo.tableFee }}</text>
</view>
<text class="u-flex-1">
{{ cartStore.orderCostSummary.seatFee }}
</text>
</view>
</view>
<view class="item" v-if="cartStore.orderCostSummary.packFee > 0">
<view class="u-flex">
<text>打包费</text>
</view>
<view class="u-flex text-center" style="gap: 54rpx; min-width: 348rpx">
<text class="u-flex-1"></text>
<view class="u-flex u-flex-1 u-relative">
<text class="origin-price"></text>
</view>
<text class="u-flex-1">
{{ cartStore.orderCostSummary.packFee }}
</text>
</view>
</view>
</view>
</view>
</template>
<script setup>
import { computed, inject, ref, watch } from "vue";
import dayjs from "dayjs";
import BigNumber from "bignumber.js";
const cartStore = inject("cartStore");
const yskUtils = inject("yskUtils");
function isSelected(item) {
return selCart.value && item.id === selCart.value.id;
}
function showOldPrice(item) {
return item.isTimeDiscount || item.isGift || item.discountSaleAmount * 1 > 0;
}
const nowTime = ref(new Date().getTime());
const timer = setInterval(() => {
nowTime.value = new Date().getTime();
}, 1000);
//超时时间
const maxTime = cartStore.shopInfo.serveTime * 60 * 1000;
function returnStatusClass(item) {
if (item.subStatus == "DELIVERED") {
return "success";
}
if (
item.subStatus == "READY_TO_SERVE" &&
returnSubStatusText(item) != "已超时"
) {
return "warning";
}
if (item.subStatus == "SENT_OUT") {
return "green";
}
}
/**
* 返回商品状态文本
*/
function returnSubStatusText(item) {
let a = nowTime.value;
if (item.subStatus == "PENDING_PREP") {
return "待起菜";
}
if (item.subStatus == "READY_TO_SERVE") {
if (item.startOrderTime && cartStore.shopInfo.isServeTimeControl) {
const maxWaitTime = dayjs(item.startOrderTime).add(
maxTime,
"millisecond"
);
if (dayjs(nowTime.value).isAfter(maxWaitTime)) {
return "已超时";
}
}
return "待出菜";
}
if (item.subStatus == "SENT_OUT") {
return "已出菜";
}
if (item.subStatus == "DELIVERED") {
return "已上菜";
}
return "";
}
function returnPrice(data) {
if (data.isTimeDiscount) {
return returnLimitPrice(data);
}
if (data.discountSaleAmount * 1 > 0) {
return data.discountSaleAmount;
}
if (data.isGift) {
return 0;
}
return data.price;
}
function returnLimitPrice(data) {
const price = yskUtils.limitUtils.returnPrice({
goods: data,
shopInfo: cartStore.shopInfo,
limitTimeDiscountRes: cartStore.limitTimeDiscount,
shopUserInfo: cartStore.shopUserInfo,
idKey: "productId",
});
console.log("cartStore.shopInfo", cartStore.shopInfo);
console.log("cartStore.limitTimeDiscount", cartStore.limitTimeDiscount);
console.log("cartStore.shopUserInfo", cartStore.shopUserInfo);
return price;
}
const selCart = defineModel("selCart", {
default: null,
});
function itemClick(item) {
if (selCart.value && item.id === selCart.value.id) {
selCart.value = null;
return;
}
selCart.value = item;
console.log(item);
}
</script>
<style scoped lang="scss">
.list {
.item {
padding: 40rpx 102rpx;
display: flex;
justify-content: space-between;
background-color: #fff;
border: 1px solid transparent;
border-top-color: #e5e5e5;
font-size: 40rpx;
&:last-child {
border-top-color: transparent;
}
&.isSelected {
border-color: $my-main-color;
}
}
}
.table {
.header {
background-color: #f8f8f8;
padding: 40rpx 102rpx;
display: flex;
justify-content: space-between;
font-size: 40rpx;
}
}
.status {
padding: 10rpx 14rpx;
border-radius: 14rpx;
border: 1px solid transparent;
font-size: 28rpx;
color: #999;
border-color: #999;
background-color: rgba(153, 153, 153, 0.25);
position: relative;
&.default {
}
&.timeout {
color: #ff383c;
border-color: #ff383c;
background-color: rgba(255, 56, 60, 0.21);
}
&.success {
color: $my-main-color;
border-color: $my-main-color;
background-color: rgba(63, 158, 255, 0.25);
}
&.green {
$color: rgba(52, 199, 89, 1);
border-color: $color;
color: $color;
background-color: rgba(52, 199, 89, 0.25);
}
&.warning {
$color: #ff8d28;
border-color: $color;
color: $color;
background-color: rgba(255, 141, 40, 0.25);
}
&.gift {
$color: rgb(255, 159, 46);
color: $color;
background-color: rgb(255, 240, 223);
border-color: $color;
}
&.pack {
$color: rgb(49, 138, 254);
color: $color;
background-color: rgb(49, 138, 254, 0.25);
border-color: $color;
}
.badge {
position: absolute;
text-align: center;
$height: 32rpx;
line-height: $height;
height: $height;
top: calc(-#{$height} / 2);
right: calc(-#{$height} / 2);
width: $height;
border-radius: 50%;
font-size: 20rpx;
color: #fff;
background-color: #ff383c;
}
}
.old-price {
text-decoration: line-through;
color: #999;
font-size: 28rpx;
position: relative;
}
.limit-price,
.discount-price {
position: absolute;
bottom: 100%;
text-align: center;
left: 0;
right: 0;
}
.gap-10 {
gap: 10rpx;
}
</style>