鸿宇研学生前端代码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

229 lines
5.1 KiB

  1. <template>
  2. <view>
  3. <view class="card">
  4. <view class="flex card-header" style="justify-content: space-between;">
  5. <view>订单详情</view>
  6. <view :class="['tag', `tag-${data.status}`]">
  7. {{ statusDesc }}
  8. </view>
  9. </view>
  10. <view class="flex member" v-for="item in members" :key="item.id">
  11. <view class="info">
  12. <view class="flex info-top">
  13. <view>{{ item.name }}</view>
  14. <view>{{ getTypeDesc(item.type) }}</view>
  15. <view class="light">{{ getTypeTips(item.type) }}</view>
  16. </view>
  17. <view class="info-bottom">{{ item.idNo }}</view>
  18. </view>
  19. <view class="flex price">¥<view class="highlight">{{ item.price }}</view></view>
  20. </view>
  21. <view class="row">
  22. <view class="row-label">总价格</view>
  23. <view class="row-content">
  24. <view class="flex total-price">
  25. <view>¥</view>
  26. <view class="highlight">{{ totalPrice }}</view>
  27. <view class="light" v-if="data.discount">
  28. {{ `优惠(${data.discount}` }}
  29. </view>
  30. </view>
  31. </view>
  32. </view>
  33. </view>
  34. <view class="card">
  35. <view class="card-header">联系人信息</view>
  36. <view class="row">
  37. <view class="row-label">真实姓名</view>
  38. <view class="row-content">{{ data.name }}</view>
  39. </view>
  40. <view class="row">
  41. <view class="row-label">手机号码</view>
  42. <view class="row-content">{{ data.phone }}</view>
  43. </view>
  44. </view>
  45. <view class="card order">
  46. <view class="card-header">订单信息</view>
  47. <view class="row">
  48. <view class="row-label">订单编号</view>
  49. <view class="row-content">{{ data.orderNo }}</view>
  50. </view>
  51. <view class="row">
  52. <view class="row-label">下单时间</view>
  53. <view class="row-content">{{ data.createTime }}</view>
  54. </view>
  55. </view>
  56. </view>
  57. </template>
  58. <script>
  59. const ORDER_STATUS_AND_DESC_MAPPING = {
  60. 0: '待支付',
  61. 1: '已支付',
  62. 2: '已完成',
  63. }
  64. const MEMBER_TYPE_AND_DESC_MAPPING = {
  65. 0: '成人',
  66. 1: '青少年',
  67. 2: '儿童',
  68. }
  69. const MEMBER_TYPE_AND_TIPS_MAPPING = {
  70. 0: '(18周岁以上)',
  71. 1: '(14周岁以上)',
  72. 2: '(14周岁以下)',
  73. }
  74. export default {
  75. props: {
  76. data: {
  77. type: Object,
  78. default() {
  79. return {}
  80. }
  81. },
  82. },
  83. computed: {
  84. statusDesc() {
  85. const { status } = this.data
  86. return ORDER_STATUS_AND_DESC_MAPPING[status]
  87. },
  88. productPackage() {
  89. const { time, product } = this.data
  90. const { timeOptions } = product || {}
  91. return timeOptions?.find?.(item => item.id === time) || {}
  92. },
  93. totalPrice() {
  94. const { adults, teenager, child } = this.data
  95. const { adultsPrice, teenagerPrice, childPrice } = this.productPackage
  96. let total = 0
  97. adults && (total += adults * (adultsPrice || 0))
  98. teenager && (total += teenager * (teenagerPrice || 0))
  99. child && (total += child * (childPrice || 0))
  100. return total
  101. },
  102. members() {
  103. const { members } = this.data
  104. const { adultsPrice, teenagerPrice, childPrice } = this.productPackage
  105. return members?.map?.(item => {
  106. const { type } = item
  107. let price = 0
  108. switch(type) {
  109. case 0: // 成年
  110. price = adultsPrice
  111. break
  112. case 1: // 青少年
  113. price = teenagerPrice
  114. break
  115. case 2: // 儿童
  116. price = childPrice
  117. break
  118. }
  119. return { ...item, price }
  120. })
  121. },
  122. },
  123. methods: {
  124. getTypeDesc(type) {
  125. return MEMBER_TYPE_AND_DESC_MAPPING[type]
  126. },
  127. getTypeTips(type) {
  128. return MEMBER_TYPE_AND_TIPS_MAPPING[type]
  129. },
  130. },
  131. }
  132. </script>
  133. <style scoped lang="scss">
  134. @import '../styles/style.scss';
  135. @import '../styles/tag.scss';
  136. .member {
  137. margin-top: 16rpx;
  138. justify-content: space-between;
  139. padding: 24rpx;
  140. background: #F9F9F9;
  141. border-radius: 24rpx;
  142. .info {
  143. &-top {
  144. justify-content: space-between;
  145. column-gap: 24rpx;
  146. font-size: 32rpx;
  147. color: #181818;
  148. .light {
  149. font-size: 24rpx;
  150. color: #8B8B8B;
  151. }
  152. }
  153. &-bottom {
  154. font-size: 28rpx;
  155. color: #9B9B9B;
  156. }
  157. }
  158. .price {
  159. column-gap: 4rpx;
  160. font-size: 24rpx;
  161. font-weight: 500;
  162. color: #FF4800;
  163. .highlight {
  164. font-size: 32rpx;
  165. }
  166. }
  167. }
  168. .row {
  169. margin-top: 16rpx;
  170. display: flex;
  171. align-items: center;
  172. justify-content: space-between;
  173. &-label {
  174. font-size: 26rpx;
  175. color: #8B8B8B;
  176. }
  177. &-content {
  178. font-size: 28rpx;
  179. color: #393939;
  180. }
  181. }
  182. .order {
  183. .row {
  184. margin-top: 32rpx;
  185. }
  186. }
  187. .total-price {
  188. column-gap: 8rpx;
  189. font-size: 24rpx;
  190. font-weight: 500;
  191. color: #FF4800;
  192. .highlight {
  193. font-size: 32rpx;
  194. }
  195. .light {
  196. font-size: 22rpx;
  197. font-weight: 400;
  198. }
  199. }
  200. </style>