index.vue 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. <template>
  2. <view class="car-card" :class="statusClass" @click="handleCardClick">
  3. <!-- 第一行:车辆名称 -->
  4. <view class="car-title">
  5. {{ carData.name || '别克GL8' }}
  6. </view>
  7. <!-- {{ carData }} -->
  8. <!-- 第二行:左右结构 -->
  9. <view class="car-info">
  10. <!-- 左边:车辆图片 -->
  11. <view class="car-image-container">
  12. <image class="car-image" :src="getImageUrl(carData.image)" mode="aspectFill" />
  13. </view>
  14. <!-- 右边:车辆信息 -->
  15. <view class="car-details">
  16. <view class="detail-item car-name">
  17. {{ carData.wph }}
  18. </view>
  19. <view class="detail-item seats" v-for="wp in carData.wpcsList">
  20. {{ wp.mc }} : {{ wp.sz || wp.zf }}
  21. </view>
  22. <!-- <view class="detail-item car-color">
  23. {{ carData.color || '白色' }}
  24. </view>-->
  25. <view class="detail-item car-type">
  26. {{ carData.type || '商务车' }}
  27. </view>
  28. </view>
  29. </view>
  30. </view>
  31. </template>
  32. <script setup>
  33. import { computed } from 'vue'
  34. import { getImageUrl } from '@/utils/util'
  35. // Props
  36. const props = defineProps({
  37. // 车辆数据
  38. carData: {
  39. type: Object,
  40. default: () => ({})
  41. },
  42. // 车辆状态:'available' | 'reserved' | 'disabled'
  43. status: {
  44. type: String,
  45. default: 'available',
  46. validator: (value) => ['available', 'reserved', 'disabled'].includes(value)
  47. }
  48. })
  49. // Emits
  50. const emit = defineEmits(['click', 'select'])
  51. // 计算状态样式类
  52. const statusClass = computed(() => {
  53. return `status-${props.status}`
  54. })
  55. // 处理卡片点击
  56. const handleCardClick = () => {
  57. if (props.status === 'disabled') {
  58. return // 禁用状态和已预约状态不响应点击
  59. }
  60. emit('click', props.carData)
  61. emit('select', props.carData)
  62. }
  63. // 移除 onMounted 中的异步获取逻辑,现在在父组件中处理
  64. // onMounted(async () => {
  65. // // 更新物品类型
  66. // const result = await commonApi.getDictByCbNameAndValue('wplb', props.carData.wplbm)
  67. // props.carData.type = result.data.result[props.carData.wplbm]
  68. // })
  69. </script>
  70. <style lang="scss" scoped>
  71. .car-card {
  72. background: #FFFFFF;
  73. border-radius: 8rpx;
  74. overflow: visible;
  75. padding: 34rpx;
  76. margin-bottom: 34rpx;
  77. box-shadow: 2rpx 6rpx 6rpx rgba(4, 0, 0, 0.15);
  78. box-sizing: border-box;
  79. position: relative;
  80. z-index: 1;
  81. transition: all 0.3s ease;
  82. // 可预约状态 - 绿色
  83. &.status-available {
  84. background-color: #c7ffe0;
  85. }
  86. // 已被预约状态 - 橙色(不可更改)
  87. &.status-reserved {
  88. background-color: #ffb882;
  89. }
  90. // 禁用状态 - 灰色
  91. &.status-disabled {
  92. background-color: #f5f5f5;
  93. opacity: 0.6;
  94. }
  95. }
  96. .car-title {
  97. font-size: 34rpx;
  98. font-weight: bold;
  99. color: #000000;
  100. margin-bottom: 17rpx;
  101. text-align: left;
  102. }
  103. .car-info {
  104. display: flex;
  105. align-items: flex-start;
  106. gap: 45rpx;
  107. }
  108. .car-image-container {
  109. flex-shrink: 0;
  110. width: 380rpx;
  111. height: 212rpx;
  112. border-radius: 8rpx;
  113. overflow: hidden;
  114. background-color: #f8f8f8;
  115. }
  116. .car-image {
  117. width: 100%;
  118. height: 100%;
  119. object-fit: cover;
  120. }
  121. .car-details {
  122. flex: 1;
  123. display: flex;
  124. flex-direction: column;
  125. gap: 8rpx;
  126. min-width: 0;
  127. }
  128. .detail-item {
  129. font-size: 34rpx;
  130. color: #333;
  131. line-height: 48rpx;
  132. }
  133. // 禁用状态下的文字颜色
  134. .status-disabled {
  135. .car-title,
  136. .detail-item {
  137. color: #999 !important;
  138. }
  139. .detail-item.seats {
  140. color: #bbb !important;
  141. }
  142. }
  143. // 响应式适配
  144. @media (max-width: 750rpx) {
  145. .car-card-content {
  146. padding: 20rpx;
  147. }
  148. .car-image-container {
  149. width: 160rpx;
  150. height: 100rpx;
  151. }
  152. .car-title {
  153. font-size: 32rpx;
  154. }
  155. .detail-item {
  156. font-size: 26rpx;
  157. &.seats {
  158. font-size: 28rpx;
  159. }
  160. &.car-name {
  161. font-size: 28rpx;
  162. }
  163. }
  164. }
  165. </style>