|
|
@@ -11,27 +11,9 @@
|
|
|
<view class="info-item-label">就餐桌号</view>
|
|
|
<view class="info-item-value">{{ orderInfo.tableNumber || orderInfo.tableId || '—' }}</view>
|
|
|
</view>
|
|
|
- <view class="info-item info-item--diners">
|
|
|
+ <view class="info-item">
|
|
|
<view class="info-item-label">用餐人数</view>
|
|
|
- <view class="diner-stepper">
|
|
|
- <view
|
|
|
- class="diner-stepper__btn"
|
|
|
- :class="{ 'diner-stepper__btn--disabled': dinerCount <= 1 }"
|
|
|
- hover-class="diner-stepper__btn--active"
|
|
|
- @tap.stop="adjustDiners(-1)"
|
|
|
- >
|
|
|
- <view class="diner-stepper__icon diner-stepper__icon--minus" />
|
|
|
- </view>
|
|
|
- <text class="diner-stepper__value">{{ dinerCount }}</text>
|
|
|
- <view
|
|
|
- class="diner-stepper__btn"
|
|
|
- :class="{ 'diner-stepper__btn--disabled': dinerCount >= MAX_DINERS }"
|
|
|
- hover-class="diner-stepper__btn--active"
|
|
|
- @tap.stop="adjustDiners(1)"
|
|
|
- >
|
|
|
- <view class="diner-stepper__icon diner-stepper__icon--plus" />
|
|
|
- </view>
|
|
|
- </view>
|
|
|
+ <view class="info-item-value">{{ dinerCount }}人</view>
|
|
|
</view>
|
|
|
<view class="info-item">
|
|
|
<view class="info-item-label">联系电话</view>
|
|
|
@@ -39,7 +21,7 @@
|
|
|
</view>
|
|
|
<view class="info-item">
|
|
|
<view class="info-item-label">备注信息</view>
|
|
|
- <view class="info-item-value remark-text">{{ orderInfo.remark || '—' }}</view>
|
|
|
+ <view class="info-item-value remark-text">{{ (orderInfo.remark || '').trim() || '无' }}</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
@@ -91,7 +73,7 @@
|
|
|
<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="(orderInfo.discountAmount ?? 0) > 0" class="coupon-amount">{{ couponDisplayText }}</text>
|
|
|
+ <text v-if="hasCheckoutCouponChosen" class="coupon-amount">{{ couponRowDisplayName }}</text>
|
|
|
<text v-else class="coupon-placeholder">请选择</text>
|
|
|
<text class="coupon-arrow">›</text>
|
|
|
</view>
|
|
|
@@ -120,6 +102,7 @@
|
|
|
:coupon-list="couponList"
|
|
|
:selected-coupon-id="selectedCouponId"
|
|
|
:view-only="false"
|
|
|
+ :dish-amount="foodSubtotalForDisplay"
|
|
|
:list-loading="checkoutCouponLoading"
|
|
|
:list-has-more="checkoutCouponHasMore"
|
|
|
@load-more="handleCheckoutCouponLoadMore"
|
|
|
@@ -137,13 +120,15 @@ 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 { normalizeUserCouponListItem, parseCouponListPage, mergeCouponListById } from '@/utils/couponNormalize.js';
|
|
|
+import { normalizeUserCouponListItem, parseCouponListPage, getCouponMinSpendThreshold } from '@/utils/couponNormalize.js';
|
|
|
import SelectCouponModal from '@/pages/orderFood/components/SelectCouponModal.vue';
|
|
|
|
|
|
const orderId = ref('');
|
|
|
/** 用餐人数上限(与选人数页「查看更多」一致) */
|
|
|
const MAX_DINERS = 16;
|
|
|
const MIN_DINERS = 1;
|
|
|
+/** 应付金额下限(元),算出低于此值时按 0.01 展示并支付 */
|
|
|
+const MIN_CHECKOUT_PAY_YUAN = 0.01;
|
|
|
|
|
|
const orderInfo = ref({
|
|
|
orderNo: '',
|
|
|
@@ -175,10 +160,8 @@ const couponModalOpen = ref(false);
|
|
|
const couponList = ref([]);
|
|
|
const selectedCouponId = ref(null);
|
|
|
|
|
|
-const CHECKOUT_COUPON_PAGE_SIZE = 10;
|
|
|
const checkoutCouponLoading = ref(false);
|
|
|
-const checkoutCouponHasMore = ref(true);
|
|
|
-const checkoutCouponLastPage = ref(0);
|
|
|
+const checkoutCouponHasMore = ref(false);
|
|
|
|
|
|
// 菜品清单展示(排除特殊占位 id=-1)
|
|
|
const displayFoodList = computed(() =>
|
|
|
@@ -191,21 +174,9 @@ function parseDinerCount(val) {
|
|
|
return Math.min(MAX_DINERS, Math.floor(n));
|
|
|
}
|
|
|
|
|
|
-/** 当前用餐人数(数字,用于步进器展示) */
|
|
|
+/** 当前用餐人数(数字,结算页只读展示) */
|
|
|
const dinerCount = computed(() => parseDinerCount(orderInfo.value.diners));
|
|
|
|
|
|
-function adjustDiners(delta) {
|
|
|
- const cur = parseDinerCount(orderInfo.value.diners);
|
|
|
- const next = cur + delta;
|
|
|
- if (next < MIN_DINERS || next > MAX_DINERS) return;
|
|
|
- orderInfo.value.diners = String(next);
|
|
|
- uni.setStorageSync('currentDiners', String(next));
|
|
|
- // 本版本不参与服务费(恢复按人数重算时取消注释)
|
|
|
- // if (Number(estimateFeeType.value) === 1) {
|
|
|
- // fetchServiceFeeEstimate().catch((err) => console.warn('按人数重算服务费失败:', err));
|
|
|
- // }
|
|
|
-}
|
|
|
-
|
|
|
// 展示用菜品小计:有明细时与行成交价一致;否则用接口 dishTotal 或 totalAmount − 服务费
|
|
|
const foodSubtotalForDisplay = computed(() => {
|
|
|
const list = displayFoodList.value;
|
|
|
@@ -223,91 +194,80 @@ const foodSubtotalForDisplay = computed(() => {
|
|
|
return Math.max(0, total - fee);
|
|
|
});
|
|
|
|
|
|
-// 优惠券展示:满减券显示 nominalValue+元,折扣券显示 discountRate+折,否则显示 couponName 或 已使用优惠券
|
|
|
-const couponDisplayText = computed(() => {
|
|
|
+/** 是否已在结算页选定优惠券(含订单带入) */
|
|
|
+const hasCheckoutCouponChosen = computed(() => {
|
|
|
const o = orderInfo.value;
|
|
|
- if ((o.discountAmount ?? 0) <= 0) return '';
|
|
|
+ if ((o.discountAmount ?? 0) > 0) return true;
|
|
|
+ if (o.couponId != null && String(o.couponId).trim() !== '') return true;
|
|
|
+ if (selectedCouponId.value != null && String(selectedCouponId.value).trim() !== '') return true;
|
|
|
+ return false;
|
|
|
+});
|
|
|
+
|
|
|
+/** 优惠券行文案:优先展示券名称,缺省时再展示面值/折扣简短文案 */
|
|
|
+const couponRowDisplayName = computed(() => {
|
|
|
+ const o = orderInfo.value;
|
|
|
+ const name = String(o.couponName ?? '').trim();
|
|
|
+ if (name) return name;
|
|
|
const type = Number(o.couponType);
|
|
|
- if (type === 1 && (o.nominalValue != null && o.nominalValue !== '')) {
|
|
|
+ if (type === 1 && o.nominalValue != null && o.nominalValue !== '') {
|
|
|
const val = Number(o.nominalValue);
|
|
|
- return Number.isNaN(val) ? (o.couponName || '已使用优惠券') : val + '元';
|
|
|
+ return Number.isNaN(val) ? '已选优惠券' : `${val}元`;
|
|
|
}
|
|
|
- if (type === 2 && (o.discountRate != null && o.discountRate !== '')) {
|
|
|
+ if (type === 2 && o.discountRate != null && o.discountRate !== '') {
|
|
|
const rate = Number(o.discountRate);
|
|
|
- return Number.isNaN(rate) ? (o.couponName || '已使用优惠券') : rate + '折';
|
|
|
+ return Number.isNaN(rate) ? '已选优惠券' : `${rate}折`;
|
|
|
}
|
|
|
- return o.couponName || '已使用优惠券';
|
|
|
+ return '已选优惠券';
|
|
|
});
|
|
|
|
|
|
-// 点击优惠券行:打开选择弹窗
|
|
|
+// 点击优惠券行:打开选择弹窗(列表已在进入页面时拉取,不再请求接口)
|
|
|
const onCouponRowClick = () => {
|
|
|
- openCouponModal();
|
|
|
+ couponModalOpen.value = true;
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
- * 拉取结算页可用优惠券(分页,每页 CHECKOUT_COUPON_PAGE_SIZE)
|
|
|
- * @param {{ reset?: boolean }} options
|
|
|
+ * 拉取结算页用户持有优惠券(GET /dining/coupon/userOwned,一次性返回)
|
|
|
+ * @param {{ reset?: boolean; silentNoStore?: boolean }} options
|
|
|
+ * silentNoStore:无门店时不 toast(用于进入页面预拉取)
|
|
|
*/
|
|
|
async function fetchCheckoutCouponList(options = { reset: true }) {
|
|
|
- const { reset = true } = options;
|
|
|
+ const { reset = true, silentNoStore = false } = options;
|
|
|
const storeId = orderInfo.value.storeId || uni.getStorageSync('currentStoreId') || '';
|
|
|
if (!storeId) {
|
|
|
- uni.showToast({ title: '暂无门店信息', icon: 'none' });
|
|
|
+ if (!silentNoStore) {
|
|
|
+ uni.showToast({ title: '暂无门店信息', icon: 'none' });
|
|
|
+ }
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
- if (reset) {
|
|
|
- if (checkoutCouponLoading.value) return false;
|
|
|
- checkoutCouponLoading.value = true;
|
|
|
- } else {
|
|
|
- if (
|
|
|
- checkoutCouponLoading.value ||
|
|
|
- !checkoutCouponHasMore.value
|
|
|
- ) {
|
|
|
- return true;
|
|
|
- }
|
|
|
- checkoutCouponLoading.value = true;
|
|
|
+ if (!reset) {
|
|
|
+ return true;
|
|
|
}
|
|
|
|
|
|
- const page = reset ? 1 : checkoutCouponLastPage.value + 1;
|
|
|
+ if (checkoutCouponLoading.value) return false;
|
|
|
+ checkoutCouponLoading.value = true;
|
|
|
|
|
|
try {
|
|
|
- const res = await diningApi.GetUserCouponList({
|
|
|
- storeId,
|
|
|
- tabType: 0,
|
|
|
- page,
|
|
|
- size: CHECKOUT_COUPON_PAGE_SIZE
|
|
|
- });
|
|
|
- const { list: rawList, total } = parseCouponListPage(res);
|
|
|
+ const amount = Math.max(0, Math.round((Number(foodSubtotalForDisplay.value) || 0) * 100) / 100);
|
|
|
+ const res = await diningApi.GetUserCouponUserOwned({ storeId, amount });
|
|
|
+ const { list: rawList } = parseCouponListPage(res);
|
|
|
const arr = Array.isArray(rawList) ? rawList : [];
|
|
|
const normalized = arr
|
|
|
.map((item) => normalizeUserCouponListItem(item, 0))
|
|
|
.filter(Boolean);
|
|
|
|
|
|
- if (reset) {
|
|
|
- couponList.value = normalized;
|
|
|
- } else {
|
|
|
- couponList.value = mergeCouponListById(couponList.value, normalized);
|
|
|
- }
|
|
|
- checkoutCouponLastPage.value = page;
|
|
|
+ couponList.value = normalized;
|
|
|
+ checkoutCouponHasMore.value = false;
|
|
|
|
|
|
- const mergedLen = couponList.value.length;
|
|
|
- if (total > 0) {
|
|
|
- checkoutCouponHasMore.value = mergedLen < total;
|
|
|
- } else {
|
|
|
- checkoutCouponHasMore.value = normalized.length >= CHECKOUT_COUPON_PAGE_SIZE;
|
|
|
- }
|
|
|
+ syncCheckoutSelectedCouponId();
|
|
|
|
|
|
return true;
|
|
|
} catch (err) {
|
|
|
console.error('获取优惠券失败:', err);
|
|
|
- if (reset) {
|
|
|
- uni.showToast({ title: '获取优惠券失败', icon: 'none' });
|
|
|
- couponList.value = [];
|
|
|
- checkoutCouponHasMore.value = false;
|
|
|
- } else {
|
|
|
- uni.showToast({ title: '加载更多失败', icon: 'none' });
|
|
|
- }
|
|
|
+ uni.showToast({ title: '获取优惠券失败', icon: 'none' });
|
|
|
+ couponList.value = [];
|
|
|
+ checkoutCouponHasMore.value = false;
|
|
|
+ syncCheckoutSelectedCouponId();
|
|
|
return false;
|
|
|
} finally {
|
|
|
checkoutCouponLoading.value = false;
|
|
|
@@ -320,15 +280,6 @@ function handleCheckoutCouponLoadMore() {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-// 打开优惠券弹窗并拉取用户可用券
|
|
|
-const openCouponModal = async () => {
|
|
|
- couponModalOpen.value = false;
|
|
|
- const ok = await fetchCheckoutCouponList({ reset: true });
|
|
|
- if (ok) {
|
|
|
- couponModalOpen.value = true;
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
// 选择优惠券后更新订单优惠与应付金额
|
|
|
const handleCouponSelect = ({ coupon, selectedId }) => {
|
|
|
const hasSelected = selectedId != null && selectedId !== '';
|
|
|
@@ -353,16 +304,16 @@ const handleCouponSelect = ({ coupon, selectedId }) => {
|
|
|
|
|
|
const couponType = Number(coupon.couponType) || 0;
|
|
|
const foodSubtotal = Number(foodSubtotalForDisplay.value) || 0;
|
|
|
- const threshold = Number(coupon.minAmount) || 0;
|
|
|
- // 满减券(couponType=1)且有门槛:菜品总价须 ≥ 门槛,否则不可选
|
|
|
- if (couponType === 1 && threshold > 0 && foodSubtotal < threshold) {
|
|
|
- uni.showToast({ title: '未到满减此券不可用', icon: 'none' });
|
|
|
+ const threshold = getCouponMinSpendThreshold(coupon);
|
|
|
+ // 有门槛(minimumSpendingAmount/minAmount > 0):菜品总价须 ≥ 门槛
|
|
|
+ if (threshold > 0 && foodSubtotal < threshold) {
|
|
|
+ uni.showToast({ title: '未达到优惠券使用门槛', icon: 'none' });
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
selectedCouponId.value = String(selectedId);
|
|
|
orderInfo.value.couponId = coupon?.couponId ?? coupon?.id ?? String(selectedId) ?? null;
|
|
|
- orderInfo.value.couponName = coupon.name ?? '';
|
|
|
+ orderInfo.value.couponName = String(coupon.name ?? coupon.title ?? coupon.couponName ?? '').trim();
|
|
|
orderInfo.value.couponType = couponType || null;
|
|
|
orderInfo.value.discountRate = coupon.discountRate != null ? coupon.discountRate : null;
|
|
|
const nvRaw = coupon.nominalValue;
|
|
|
@@ -388,12 +339,16 @@ const handleCouponSelect = ({ coupon, selectedId }) => {
|
|
|
couponModalOpen.value = false;
|
|
|
};
|
|
|
|
|
|
-// 应付金额 = 菜品总价 + 服务费 − 优惠金额
|
|
|
+// 应付金额 = 菜品总价 + 服务费 − 优惠金额(不低于 0.01 元)
|
|
|
const updateCheckoutPayAmount = () => {
|
|
|
const food = Number(foodSubtotalForDisplay.value) || 0;
|
|
|
const fee = Number(orderInfo.value.serviceFee) || 0;
|
|
|
const discount = Number(orderInfo.value.discountAmount) || 0;
|
|
|
- orderInfo.value.payAmount = Math.max(0, Math.round((food + fee - discount) * 100) / 100);
|
|
|
+ let raw = Math.round((food + fee - discount) * 100) / 100;
|
|
|
+ if (!Number.isFinite(raw) || raw < MIN_CHECKOUT_PAY_YUAN) {
|
|
|
+ raw = MIN_CHECKOUT_PAY_YUAN;
|
|
|
+ }
|
|
|
+ orderInfo.value.payAmount = raw;
|
|
|
};
|
|
|
|
|
|
/** 服务费变化后:折扣券(按菜品+服务费为基数)需重算优惠金额 */
|
|
|
@@ -551,6 +506,58 @@ function getTableIdForServiceFeeEstimate() {
|
|
|
return String(uni.getStorageSync('currentTableId') || '').trim();
|
|
|
}
|
|
|
|
|
|
+/** 根据 orderInfo.couponId 与券列表对齐选中态(弹窗单选 id 为 userCoupon 实例 id) */
|
|
|
+function syncCheckoutSelectedCouponId() {
|
|
|
+ const cid = orderInfo.value.couponId;
|
|
|
+ if (cid == null || String(cid).trim() === '') {
|
|
|
+ selectedCouponId.value = null;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const s = String(cid).trim();
|
|
|
+ const list = couponList.value ?? [];
|
|
|
+ const hit = list.find(
|
|
|
+ (c) =>
|
|
|
+ String(c?.couponId ?? '') === s ||
|
|
|
+ String(c?.id ?? '') === s ||
|
|
|
+ String(c?.userCouponId ?? '') === s
|
|
|
+ );
|
|
|
+ selectedCouponId.value = hit ? String(hit.id) : null;
|
|
|
+}
|
|
|
+
|
|
|
+/** 从订单详情接口回显优惠券(与下单/锁单时服务端数据一致) */
|
|
|
+function applyCheckoutCouponFromOrderRaw(raw) {
|
|
|
+ const cid = raw?.couponId ?? raw?.userCouponId ?? raw?.memberCouponId ?? null;
|
|
|
+ const discountAmt =
|
|
|
+ Number(raw?.discountAmount ?? raw?.couponAmount ?? raw?.couponDiscount ?? 0) || 0;
|
|
|
+ const hasCoupon =
|
|
|
+ (cid != null && String(cid).trim() !== '') ||
|
|
|
+ discountAmt > 0 ||
|
|
|
+ (String(raw?.couponName ?? '').trim() !== '');
|
|
|
+
|
|
|
+ if (!hasCoupon) {
|
|
|
+ orderInfo.value.couponId = null;
|
|
|
+ orderInfo.value.couponName = '';
|
|
|
+ orderInfo.value.couponType = null;
|
|
|
+ orderInfo.value.discountRate = null;
|
|
|
+ orderInfo.value.nominalValue = null;
|
|
|
+ orderInfo.value.discountAmount = 0;
|
|
|
+ selectedCouponId.value = null;
|
|
|
+ updateCheckoutPayAmount();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ orderInfo.value.couponId = cid != null && String(cid).trim() !== '' ? String(cid).trim() : null;
|
|
|
+ orderInfo.value.couponName = String(raw?.couponName ?? '').trim();
|
|
|
+ orderInfo.value.couponType = raw?.couponType ?? null;
|
|
|
+ const rawRate = raw?.discountRate;
|
|
|
+ orderInfo.value.discountRate =
|
|
|
+ rawRate != null && rawRate !== '' ? (Number(rawRate) || 0) / 10 : null;
|
|
|
+ orderInfo.value.nominalValue = raw?.nominalValue ?? null;
|
|
|
+ orderInfo.value.discountAmount = discountAmt;
|
|
|
+ recalcDiscountAfterServiceFeeChange();
|
|
|
+ updateCheckoutPayAmount();
|
|
|
+}
|
|
|
+
|
|
|
const fetchOrderDetail = async () => {
|
|
|
const id = orderId.value || '';
|
|
|
if (!id) return;
|
|
|
@@ -575,22 +582,11 @@ const fetchOrderDetail = async () => {
|
|
|
const total = Number(raw?.totalAmount ?? raw?.orderAmount ?? raw?.foodAmount ?? 0) || 0;
|
|
|
orderInfo.value.totalAmount = total;
|
|
|
orderInfo.value.dishTotal = raw?.dishTotal != null ? Number(raw.dishTotal) : null;
|
|
|
- orderInfo.value.couponId = raw?.couponId ?? null;
|
|
|
- orderInfo.value.couponName = raw?.couponName ?? '';
|
|
|
- orderInfo.value.couponType = raw?.couponType ?? null;
|
|
|
- const rawRate = raw?.discountRate;
|
|
|
- orderInfo.value.discountRate = rawRate != null && rawRate !== '' ? (Number(rawRate) || 0) / 10 : null;
|
|
|
- orderInfo.value.nominalValue = raw?.nominalValue ?? null;
|
|
|
- orderInfo.value.discountAmount = Number(raw?.discountAmount ?? raw?.couponAmount ?? raw?.couponDiscount ?? 0) || 0;
|
|
|
- orderInfo.value.payAmount = Number(raw?.payAmount ?? raw?.totalAmount ?? raw?.totalPrice ?? 0) || 0;
|
|
|
// 本版本不参与服务费:不从订单拉取服务费
|
|
|
- // orderInfo.value.serviceFee =
|
|
|
- // Number(raw?.serviceFee ?? raw?.serviceCharge ?? raw?.tablewareFee ?? 0) || 0;
|
|
|
orderInfo.value.serviceFee = 0;
|
|
|
const list = raw?.orderItemList ?? raw?.orderItems ?? raw?.items ?? raw?.detailList ?? [];
|
|
|
foodList.value = (Array.isArray(list) ? list : []).map(normalizeOrderItem);
|
|
|
- selectedCouponId.value = orderInfo.value.couponId != null && orderInfo.value.couponId !== '' ? String(orderInfo.value.couponId) : null;
|
|
|
- updateCheckoutPayAmount();
|
|
|
+ applyCheckoutCouponFromOrderRaw(raw);
|
|
|
await fetchServiceFeeEstimate(); // 本版为 no-op(不参与服务费)
|
|
|
} catch (err) {
|
|
|
console.error('获取订单详情失败:', err);
|
|
|
@@ -611,7 +607,7 @@ const handleConfirmPay = async () => {
|
|
|
return;
|
|
|
}
|
|
|
const payAmountVal = Math.round((Number(orderInfo.value.payAmount ?? 0) || 0) * 100) / 100;
|
|
|
- if (payAmountVal <= 0) {
|
|
|
+ if (payAmountVal < MIN_CHECKOUT_PAY_YUAN) {
|
|
|
uni.showToast({ title: '订单金额异常', icon: 'none' });
|
|
|
return;
|
|
|
}
|
|
|
@@ -699,11 +695,13 @@ onLoad(async (options) => {
|
|
|
}
|
|
|
if (options?.remark != null && options?.remark !== '') orderInfo.value.remark = decodeURIComponent(options.remark);
|
|
|
if (options?.totalAmount != null && options?.totalAmount !== '') {
|
|
|
- orderInfo.value.payAmount = Number(options.totalAmount) || 0;
|
|
|
+ const p = Math.round((Number(options.totalAmount) || 0) * 100) / 100;
|
|
|
+ orderInfo.value.payAmount = p < MIN_CHECKOUT_PAY_YUAN ? MIN_CHECKOUT_PAY_YUAN : p;
|
|
|
}
|
|
|
if (id) {
|
|
|
await fetchOrderDetail();
|
|
|
}
|
|
|
+ await fetchCheckoutCouponList({ reset: true, silentNoStore: true });
|
|
|
});
|
|
|
|
|
|
onShow(() => {
|
|
|
@@ -796,89 +794,6 @@ onUnload(() => {
|
|
|
&--clickable {
|
|
|
cursor: pointer;
|
|
|
}
|
|
|
-
|
|
|
- &--diners {
|
|
|
- align-items: center;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /* 用餐人数:胶囊步进器(与设计稿一致) */
|
|
|
- .diner-stepper {
|
|
|
- display: flex;
|
|
|
- flex-direction: row;
|
|
|
- align-items: center;
|
|
|
- justify-content: space-between;
|
|
|
- background: #f2f3f5;
|
|
|
- border-radius: 999rpx;
|
|
|
- padding: 3rpx 6rpx;
|
|
|
- min-width: 196rpx;
|
|
|
- box-sizing: border-box;
|
|
|
- }
|
|
|
-
|
|
|
- .diner-stepper__btn {
|
|
|
- width: 44rpx;
|
|
|
- height: 44rpx;
|
|
|
- border-radius: 50%;
|
|
|
- background: #ffffff;
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: center;
|
|
|
- flex-shrink: 0;
|
|
|
- box-shadow: 0 1rpx 6rpx rgba(0, 0, 0, 0.06);
|
|
|
- }
|
|
|
-
|
|
|
- .diner-stepper__btn--active:active {
|
|
|
- opacity: 0.88;
|
|
|
- }
|
|
|
-
|
|
|
- .diner-stepper__btn--disabled {
|
|
|
- opacity: 0.35;
|
|
|
- pointer-events: none;
|
|
|
- }
|
|
|
-
|
|
|
- .diner-stepper__value {
|
|
|
- flex: 1;
|
|
|
- text-align: center;
|
|
|
- font-size: 26rpx;
|
|
|
- font-weight: 500;
|
|
|
- color: #151515;
|
|
|
- line-height: 44rpx;
|
|
|
- min-width: 36rpx;
|
|
|
- }
|
|
|
-
|
|
|
- .diner-stepper__icon--minus {
|
|
|
- width: 20rpx;
|
|
|
- height: 2rpx;
|
|
|
- background: #c8c8c8;
|
|
|
- border-radius: 2rpx;
|
|
|
- }
|
|
|
-
|
|
|
- .diner-stepper__icon--plus {
|
|
|
- position: relative;
|
|
|
- width: 18rpx;
|
|
|
- height: 18rpx;
|
|
|
- }
|
|
|
-
|
|
|
- .diner-stepper__icon--plus::before,
|
|
|
- .diner-stepper__icon--plus::after {
|
|
|
- content: '';
|
|
|
- position: absolute;
|
|
|
- left: 50%;
|
|
|
- top: 50%;
|
|
|
- background: #fc743d;
|
|
|
- border-radius: 2rpx;
|
|
|
- }
|
|
|
-
|
|
|
- .diner-stepper__icon--plus::before {
|
|
|
- width: 18rpx;
|
|
|
- height: 2rpx;
|
|
|
- transform: translate(-50%, -50%);
|
|
|
- }
|
|
|
-
|
|
|
- .diner-stepper__icon--plus::after {
|
|
|
- width: 2rpx;
|
|
|
- height: 18rpx;
|
|
|
- transform: translate(-50%, -50%);
|
|
|
}
|
|
|
|
|
|
.price-line {
|