|
|
@@ -82,20 +82,7 @@
|
|
|
<view class="info-item-label">餐具费</view>
|
|
|
<view class="info-item-value">¥{{ formatPrice(orderInfo.utensilFee ?? 0) }}</view>
|
|
|
</view>
|
|
|
- <view class="info-item info-item--coupon info-item--clickable" @click="onCouponRowClick">
|
|
|
- <view class="info-item-label">优惠券</view>
|
|
|
- <view class="info-item-value coupon-value">
|
|
|
- <text v-if="selectedCouponDisplay" class="coupon-amount">{{ selectedCouponDisplay }}</text>
|
|
|
- <text v-else class="coupon-placeholder">请选择</text>
|
|
|
- <text class="coupon-arrow">›</text>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
- <view v-if="(orderInfo.discountAmount ?? 0) > 0" class="info-item info-item--coupon">
|
|
|
- <view class="info-item-label">优惠金额</view>
|
|
|
- <view class="info-item-value coupon-value">
|
|
|
- <text class="coupon-amount">-¥{{ formatPrice(orderInfo.discountAmount) }}</text>
|
|
|
- </view>
|
|
|
- </view>
|
|
|
+
|
|
|
<view class="price-line">
|
|
|
<view class="price-line-label">应付金额</view>
|
|
|
<view class="price-line-value">¥{{ formatPrice(orderInfo.payAmount ?? orderInfo.totalAmount) }}</view>
|
|
|
@@ -108,17 +95,6 @@
|
|
|
<view class="bottom-button-text" hover-class="hover-active" @click="handleConfirmOrder">确认下单</view>
|
|
|
</view>
|
|
|
|
|
|
- <!-- 选择优惠券弹窗(需盖住底部确认订单按钮) -->
|
|
|
- <view class="coupon-modal-wrapper">
|
|
|
- <SelectCouponModal
|
|
|
- v-model:open="couponModalOpen"
|
|
|
- :coupon-list="couponList"
|
|
|
- :selected-coupon-id="selectedCouponId"
|
|
|
- :view-only="false"
|
|
|
- @select="handleCouponSelect"
|
|
|
- @close="couponModalOpen = false"
|
|
|
- />
|
|
|
- </view>
|
|
|
</view>
|
|
|
</template>
|
|
|
|
|
|
@@ -129,7 +105,6 @@ import { go } from "@/utils/utils.js";
|
|
|
import { getFileUrl } from "@/utils/file.js";
|
|
|
import { useUserStore } from "@/store/user.js";
|
|
|
import * as diningApi from "@/api/dining.js";
|
|
|
-import SelectCouponModal from "@/pages/orderFood/components/SelectCouponModal.vue";
|
|
|
|
|
|
// 订单信息(从购物车带过来或 URL 参数)
|
|
|
const orderInfo = ref({
|
|
|
@@ -147,13 +122,6 @@ const orderInfo = ref({
|
|
|
couponId: null
|
|
|
});
|
|
|
|
|
|
-// 优惠券选择
|
|
|
-const couponModalOpen = ref(false);
|
|
|
-const selectedCouponId = ref(null);
|
|
|
-const couponList = ref([]);
|
|
|
-/** 选中券的展示文案(如 "5.5折"、"10元"),用于价格明细展示 */
|
|
|
-const selectedCouponDisplay = ref('');
|
|
|
-
|
|
|
// 菜品列表(从购物车带过来)
|
|
|
const foodList = ref([]);
|
|
|
|
|
|
@@ -193,81 +161,11 @@ function formatPrice(price) {
|
|
|
return Number.isNaN(num) ? '0.00' : num.toFixed(2);
|
|
|
}
|
|
|
|
|
|
-// 规范化优惠券项(与 orderFood 的 normalizeCouponItem 一致,供 SelectCouponModal 使用)
|
|
|
-function normalizeCouponItem(item) {
|
|
|
- if (!item || typeof item !== 'object') return null;
|
|
|
- const raw = item;
|
|
|
- const couponType = Number(raw.couponType) || 0;
|
|
|
- const nominalValue = Number(raw.nominalValue ?? raw.amount ?? 0) || 0;
|
|
|
- const discountRate = ((Number(raw.discountRate) || 0) / 10) || 0;
|
|
|
- const minAmount = Number(raw.minimumSpendingAmount ?? raw.minAmount ?? 0) || 0;
|
|
|
- let amountDisplay = nominalValue + '元';
|
|
|
- if (couponType === 1) amountDisplay = nominalValue + '元';
|
|
|
- else if (couponType === 2 && discountRate > 0) amountDisplay = (discountRate % 1 === 0 ? discountRate : discountRate.toFixed(1)) + '折';
|
|
|
- return {
|
|
|
- id: raw.userCouponId ?? raw.id ?? raw.couponId ?? '',
|
|
|
- couponId: raw.couponId ?? raw.id ?? raw.userCouponId ?? '',
|
|
|
- amount: nominalValue,
|
|
|
- minAmount,
|
|
|
- name: raw.name ?? raw.title ?? raw.couponName ?? '',
|
|
|
- expireDate: raw.expirationTime ?? raw.endGetDate ?? raw.expireDate ?? '',
|
|
|
- couponType,
|
|
|
- discountRate,
|
|
|
- amountDisplay
|
|
|
- };
|
|
|
-}
|
|
|
-
|
|
|
-// 点击优惠券行:打开选择弹窗
|
|
|
-const onCouponRowClick = () => {
|
|
|
- openCouponModal();
|
|
|
-};
|
|
|
-
|
|
|
-// 打开优惠券弹窗并拉取用户可用券
|
|
|
-const openCouponModal = async () => {
|
|
|
- const storeId = uni.getStorageSync('currentStoreId') || '';
|
|
|
- couponModalOpen.value = false;
|
|
|
- try {
|
|
|
- const res = await diningApi.GetUserOwnedCouponList({ storeId });
|
|
|
- const list = Array.isArray(res) ? res : (res?.data ?? res?.records ?? res?.list ?? []);
|
|
|
- const normalized = (Array.isArray(list) ? list : []).map(normalizeCouponItem).filter(Boolean);
|
|
|
- couponList.value = normalized;
|
|
|
- couponModalOpen.value = true;
|
|
|
- } catch (err) {
|
|
|
- console.error('获取优惠券失败:', err);
|
|
|
- uni.showToast({ title: '获取优惠券失败', icon: 'none' });
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
-// 选择优惠券后更新订单优惠与应付金额(折扣券按折扣率计算优惠金额);取消选中时 selectedId 为空,需清空展示
|
|
|
-const handleCouponSelect = ({ coupon, selectedId }) => {
|
|
|
- const hasSelected = selectedId != null && selectedId !== '';
|
|
|
- selectedCouponId.value = hasSelected ? String(selectedId) : null;
|
|
|
- orderInfo.value.couponId = hasSelected ? (coupon?.couponId ?? coupon?.id ?? selectedCouponId.value) : null;
|
|
|
- if (!hasSelected) {
|
|
|
- selectedCouponDisplay.value = '';
|
|
|
- orderInfo.value.discountAmount = 0;
|
|
|
- } else if (coupon) {
|
|
|
- selectedCouponDisplay.value = coupon.amountDisplay || (coupon.amount ? coupon.amount + '元' : '');
|
|
|
- const total = dishTotal.value;
|
|
|
- const couponType = Number(coupon.couponType) || 0;
|
|
|
- if (couponType === 2 && coupon.discountRate != null && total > 0) {
|
|
|
- // 折扣券:优惠金额 = 菜品总价 × (1 - 折数/10),如 5.5折 即 优惠 = 总价 × 0.45
|
|
|
- const rate = Number(coupon.discountRate) || 0;
|
|
|
- orderInfo.value.discountAmount = Math.round(total * (1 - rate / 10) * 100) / 100;
|
|
|
- } else {
|
|
|
- orderInfo.value.discountAmount = Number(coupon.amount) || 0;
|
|
|
- }
|
|
|
- }
|
|
|
- updatePayAmount();
|
|
|
- couponModalOpen.value = false;
|
|
|
-};
|
|
|
-
|
|
|
-// 根据菜品总价(不含餐具)、餐具费、优惠额计算应付金额
|
|
|
+// 根据菜品总价(不含餐具)、餐具费计算应付金额(优惠券在结算页选择,确认订单页不选券)
|
|
|
const updatePayAmount = () => {
|
|
|
const dish = dishTotal.value;
|
|
|
const utensil = Number(orderInfo.value.utensilFee) || 0;
|
|
|
- const discount = Number(orderInfo.value.discountAmount) || 0;
|
|
|
- orderInfo.value.payAmount = Math.max(0, dish + utensil - discount);
|
|
|
+ orderInfo.value.payAmount = Math.max(0, dish + utensil);
|
|
|
};
|
|
|
|
|
|
// 将 tags 统一为 [{ text, type }] 格式
|
|
|
@@ -325,15 +223,10 @@ const handleConfirmOrder = async () => {
|
|
|
const tablewareFee = Number(orderInfo.value.utensilFee) || 0;
|
|
|
const payAmount = Number((Number(orderInfo.value.payAmount) ?? 0).toFixed(2));
|
|
|
const totalAmount = Number((Number(dishTotal.value) ?? 0).toFixed(2));
|
|
|
- const couponIdVal = orderInfo.value.couponId ?? selectedCouponId.value;
|
|
|
- const couponIdToSend = (couponIdVal != null && couponIdVal !== '') ? String(couponIdVal) : null;
|
|
|
const createParams = {
|
|
|
tableId,
|
|
|
contactPhone,
|
|
|
totalAmount,
|
|
|
- couponId: couponIdToSend,
|
|
|
- userCouponId: couponIdToSend,
|
|
|
- discountAmount: orderInfo.value.discountAmount ?? 0,
|
|
|
tablewareFee,
|
|
|
payAmount,
|
|
|
dinerCount: dinerCount || undefined,
|
|
|
@@ -390,11 +283,6 @@ onLoad((options) => {
|
|
|
if (data.dishTotal != null && data.dishTotal !== '') orderInfo.value.dishTotal = Number(data.dishTotal) || 0;
|
|
|
const fee = data.utensilFee ?? data.tablewareFee;
|
|
|
if (fee != null && fee !== '') orderInfo.value.utensilFee = Number(fee) || 0;
|
|
|
- if (data.discountAmount != null) orderInfo.value.discountAmount = data.discountAmount;
|
|
|
- if (data.couponId != null) {
|
|
|
- selectedCouponId.value = data.couponId;
|
|
|
- orderInfo.value.couponId = data.couponId;
|
|
|
- }
|
|
|
updatePayAmount();
|
|
|
} catch (e) {
|
|
|
console.error('解析购物车数据失败:', e);
|
|
|
@@ -606,28 +494,6 @@ onUnload(() => {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-/* 优惠券弹窗层级:需盖住底部确认订单按钮(z-index:999);确认订单页减小底部留白 */
|
|
|
-.coupon-modal-wrapper {
|
|
|
- position: relative;
|
|
|
- z-index: 99999;
|
|
|
- :deep(.uni-popup) {
|
|
|
- z-index: 99999 !important;
|
|
|
- top: 0 !important;
|
|
|
- left: 0 !important;
|
|
|
- right: 0 !important;
|
|
|
- bottom: 0 !important;
|
|
|
- }
|
|
|
- :deep(.uni-popup__wrapper) {
|
|
|
- z-index: 99999 !important;
|
|
|
- }
|
|
|
- :deep(.select-coupon-modal__list) {
|
|
|
- padding-bottom: calc( env(safe-area-inset-bottom));
|
|
|
- }
|
|
|
- :deep(.select-coupon-modal__empty) {
|
|
|
- margin-bottom: 60rpx;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
.bottom-button {
|
|
|
width: 100%;
|
|
|
background-color: #fff;
|