| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- <template>
- <view class="price-card" v-if="hasAnyPrice">
- <view class="card-header">
- <view class="header-row">
- <view class="header-dot"></view>
- <text class="header-title">收费标准<text class="header-tip">(以场地设备实际功能为准)</text></text>
- <view class="header-close" @click="emit('close')">
- <text class="close-icon">✕</text>
- </view>
- </view>
- </view>
- <view class="price-grid">
- <view class="price-item" v-for="item in priceItems" :key="item.label">
- <text class="price-label">{{ item.label }}</text>
- <text class="price-value">{{ fmtYuanPerMin(item.value) }}</text>
- </view>
- </view>
- <view class="price-footer" v-if="amountMinLimit != null || prepayMoney != null">
- <view class="footer-item" v-if="amountMinLimit != null && amountMinLimit > 0">
- <text class="footer-label">最低消费</text>
- <text class="footer-value">¥{{ (amountMinLimit / 100).toFixed(2) }}</text>
- </view>
- <view class="footer-item" v-if="prepayMoney != null && prepayMoney > 0">
- <text class="footer-label">单次上限</text>
- <text class="footer-value">¥{{ (prepayMoney / 100).toFixed(2) }}</text>
- </view>
- </view>
- </view>
- </template>
- <script setup lang="ts" name="PriceTable">
- import { computed } from "vue";
- const PRICE_LABELS: Record<string, string> = {
- priceSpace: "场地费",
- priceWater: "清水",
- priceFoam: "泡沫",
- priceCleaner: "吸尘",
- priceTap: "洗手",
- priceUserExt: "扩展项目",
- priceCoat: "镀膜",
- priceBlow: "吹气",
- };
- const props = defineProps({
- price: {
- type: Object,
- default: null,
- },
- });
- const emit = defineEmits(["close"]);
- const amountMinLimit = computed(() => props.price?.amountMinLimit);
- const prepayMoney = computed(() => props.price?.prepayMoney);
- const hasAnyPrice = computed(() => {
- if (!props.price) return false;
- return Object.keys(PRICE_LABELS).some((key) => props.price[key] != null);
- });
- const priceItems = computed(() => {
- if (!props.price) return [];
- return Object.entries(PRICE_LABELS)
- .filter(([key]) => props.price[key] != null)
- .map(([key, label]) => ({ label, value: props.price[key] }));
- });
- const fmtYuanPerMin = (fen: number) => {
- if (fen == null) return "";
- const yuan = fen / 100;
- return yuan % 1 === 0 ? `¥${yuan}/分钟` : `¥${yuan.toFixed(2)}/分钟`;
- };
- </script>
- <style lang="scss" scoped>
- .price-card {
- width: 580rpx;
- max-height: 80vh;
- background: $uni-bg-color-card;
- border-radius: 24rpx;
- overflow: hidden;
- display: flex;
- flex-direction: column;
- .card-header {
- padding: 32rpx 32rpx 0;
- .header-row {
- display: flex;
- align-items: center;
- gap: 12rpx;
- }
- .header-dot {
- width: 10rpx;
- height: 10rpx;
- background: $uni-color-primary;
- border-radius: 50%;
- flex-shrink: 0;
- }
- .header-title {
- font-size: 30rpx;
- font-weight: $uni-font-weight-semibold;
- color: $uni-text-color-dark;
- flex: 1;
- }
- .header-close {
- width: 48rpx;
- height: 48rpx;
- border-radius: 50%;
- background: $uni-bg-color-page;
- display: flex;
- align-items: center;
- justify-content: center;
- flex-shrink: 0;
- .close-icon {
- font-size: 24rpx;
- color: $uni-text-color-tertiary;
- }
- }
- .header-tip {
- font-size: 22rpx;
- color: $uni-text-color-tertiary;
- font-weight: $uni-font-weight-normal;
- }
- }
- .price-grid {
- display: flex;
- flex-wrap: wrap;
- padding: 24rpx 32rpx 12rpx;
- overflow-y: auto;
- .price-item {
- width: 50%;
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 14rpx 0;
- box-sizing: border-box;
- &:nth-child(odd) {
- padding-right: 20rpx;
- }
- &:nth-child(even) {
- padding-left: 20rpx;
- }
- .price-label {
- font-size: 26rpx;
- color: $uni-text-color-hint;
- }
- .price-value {
- font-size: 26rpx;
- color: $uni-color-primary;
- font-weight: $uni-font-weight-semibold;
- }
- }
- }
- .price-footer {
- display: flex;
- gap: 32rpx;
- padding: 16rpx 32rpx 32rpx;
- border-top: 1rpx solid $uni-border-color-light;
- .footer-item {
- display: flex;
- align-items: center;
- gap: 8rpx;
- .footer-label {
- font-size: 24rpx;
- color: $uni-text-color-tertiary;
- }
- .footer-value {
- font-size: 24rpx;
- color: $uni-text-color-dark;
- font-weight: $uni-font-weight-medium;
- }
- }
- }
- }
- </style>
|