Переглянути джерело

refactor: 收费标准改为点击弹窗展示,避免页面信息过载

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
skyline 2 днів тому
батько
коміт
5181ada7c8

+ 33 - 11
car-wash-mp/src/components/price-table/index.vue

@@ -3,6 +3,9 @@
     <view class="card-header">
       <view class="header-dot"></view>
       <text class="header-title">收费标准</text>
+      <view class="header-close" @click="emit('close')">
+        <text class="close-icon">✕</text>
+      </view>
     </view>
 
     <view class="price-grid">
@@ -46,6 +49,8 @@ const props = defineProps({
   },
 });
 
+const emit = defineEmits(["close"]);
+
 const amountMinLimit = computed(() => props.price?.amountMinLimit);
 const prepayMoney = computed(() => props.price?.prepayMoney);
 
@@ -70,40 +75,57 @@ const fmtYuanPerMin = (fen: number) => {
 
 <style lang="scss" scoped>
 .price-card {
-  margin: 0 30rpx 24rpx;
-  @include card-interactive(24rpx);
+  width: 580rpx;
+  max-height: 80vh;
+  background: $uni-bg-color-card;
+  border-radius: 24rpx;
   overflow: hidden;
-  cursor: default;
-
-  &:active {
-    transform: none;
-    box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.06);
-  }
+  display: flex;
+  flex-direction: column;
 
   .card-header {
     display: flex;
     align-items: center;
     gap: 12rpx;
-    padding: 28rpx 28rpx 0;
+    padding: 32rpx 32rpx 0;
 
     .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;
+      }
     }
   }
 
   .price-grid {
     display: flex;
     flex-wrap: wrap;
-    padding: 24rpx 28rpx 12rpx;
+    padding: 24rpx 32rpx 12rpx;
+    overflow-y: auto;
 
     .price-item {
       width: 50%;
@@ -137,7 +159,7 @@ const fmtYuanPerMin = (fen: number) => {
   .price-footer {
     display: flex;
     gap: 32rpx;
-    padding: 16rpx 28rpx 28rpx;
+    padding: 16rpx 32rpx 32rpx;
     border-top: 1rpx solid $uni-border-color-light;
 
     .footer-item {

+ 51 - 2
car-wash-mp/src/pages-wash/device/index.vue

@@ -26,8 +26,19 @@
         </view>
       </view>
 
-      <!-- 价格公示 -->
-      <PriceTable :price="state.device?.price" />
+      <!-- 价格公示入口 -->
+      <view class="price-entry" v-if="state.device?.price" @click="pricePopupRef?.open()">
+        <view class="price-entry-left">
+          <text class="price-icon">¥</text>
+          <text class="price-text">收费标准</text>
+        </view>
+        <uv-icon name="arrow-right" size="16" color="#C0C4CC"></uv-icon>
+      </view>
+
+      <!-- 价格公示弹窗 -->
+      <uv-popup ref="pricePopupRef" mode="center" :round="0" :closeable="false" customStyle="background:transparent;">
+        <PriceTable :price="state.device?.price" @close="pricePopupRef?.close()" />
+      </uv-popup>
 
       <!-- 停车费提示 -->
       <view class="parking-notice" v-if="state.parkingFee">
@@ -148,6 +159,7 @@ const initState = () => ({
 
 const state = reactive(initState())
 const timerId = ref<ReturnType<typeof setInterval> | null>(null)
+const pricePopupRef = ref()
 
 const isDeviceOperable = computed(() => {
   const s = state.device?.state
@@ -495,6 +507,43 @@ const handleGotoRechage = () => {
   }
 }
 
+// 价格公示入口
+.price-entry {
+  margin: 0 30rpx 24rpx;
+  padding: 20rpx 28rpx;
+  background: rgba($uni-color-primary, 0.05);
+  border: 1rpx solid rgba($uni-color-primary, 0.12);
+  border-radius: 16rpx;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+
+  &-left {
+    display: flex;
+    align-items: center;
+    gap: 12rpx;
+    flex: 1;
+  }
+
+  .price-icon {
+    width: 36rpx;
+    height: 36rpx;
+    line-height: 36rpx;
+    text-align: center;
+    font-size: 20rpx;
+    font-weight: $uni-font-weight-bold;
+    color: #fff;
+    background: $uni-color-primary;
+    border-radius: 6rpx;
+    flex-shrink: 0;
+  }
+
+  .price-text {
+    font-size: 26rpx;
+    color: $uni-text-color-secondary;
+  }
+}
+
 // 停车费提示
 .parking-notice {
   margin: 0 30rpx 24rpx;

+ 51 - 2
car-wash-mp/src/pages-wash/station/index.vue

@@ -25,8 +25,19 @@
         <WashStation :item="state.station" ref="station_ref" :showPhone="true"></WashStation>
       </view>
 
-      <!-- 价格公示 -->
-      <PriceTable :price="unifiedPrice" />
+      <!-- 价格公示入口 -->
+      <view class="price-entry" v-if="unifiedPrice" @click="pricePopupRef?.open()">
+        <view class="price-entry-left">
+          <text class="price-icon">¥</text>
+          <text class="price-text">收费标准</text>
+        </view>
+        <uv-icon name="arrow-right" size="16" color="#C0C4CC"></uv-icon>
+      </view>
+
+      <!-- 价格公示弹窗 -->
+      <uv-popup ref="pricePopupRef" mode="center" :round="0" :closeable="false" customStyle="background:transparent;">
+        <PriceTable :price="unifiedPrice" @close="pricePopupRef?.close()" />
+      </uv-popup>
 
       <!-- 设备列表 -->
       <view class="device-section">
@@ -124,6 +135,7 @@ import PriceTable from "@/components/price-table/index.vue";
 
 const station_ref = ref();
 const deviceLoading = ref(false);
+const pricePopupRef = ref();
 
 const initState = () => ({
   deviceList: [] as any[],
@@ -257,6 +269,43 @@ const getDeviceStatusClass = (stateVal: string) => {
   margin: 0 30rpx 24rpx;
 }
 
+// 价格公示入口
+.price-entry {
+  margin: 0 30rpx 24rpx;
+  padding: 20rpx 28rpx;
+  background: rgba($uni-color-primary, 0.05);
+  border: 1rpx solid rgba($uni-color-primary, 0.12);
+  border-radius: 16rpx;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+
+  &-left {
+    display: flex;
+    align-items: center;
+    gap: 12rpx;
+    flex: 1;
+  }
+
+  .price-icon {
+    width: 36rpx;
+    height: 36rpx;
+    line-height: 36rpx;
+    text-align: center;
+    font-size: 20rpx;
+    font-weight: $uni-font-weight-bold;
+    color: #fff;
+    background: $uni-color-primary;
+    border-radius: 6rpx;
+    flex-shrink: 0;
+  }
+
+  .price-text {
+    font-size: 26rpx;
+    color: $uni-text-color-secondary;
+  }
+}
+
 // 设备区域
 .device-section {
   margin: 0 30rpx;