TimelineItem.vue 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. <template>
  2. <view class="timeline-item">
  3. <!-- 左侧时间线 -->
  4. <view class="timeline-left">
  5. <view class="timeline">
  6. <view class="dot" :class="{'dot-choose-bg': showDotBg}">
  7. <view class="timeline-dot" :class="{
  8. 'dot-active': isActive,
  9. 'dot-passed': !isActive
  10. }"></view>
  11. </view>
  12. <view
  13. v-if="showLine"
  14. class="timeline-line "
  15. :class="{
  16. 'line-active': isActive,
  17. 'line-passed': !isActive
  18. }"
  19. ></view>
  20. </view>
  21. </view>
  22. <!-- 右侧状态内容 -->
  23. <view class="status-section">
  24. <!-- 状态标签 -->
  25. <view
  26. v-if="title"
  27. class="status-badge"
  28. :class="{
  29. 'status-collected': title === '已代收',
  30. 'status-title-active': isActive
  31. }"
  32. >
  33. {{ title }}
  34. </view>
  35. <!-- 状态详情 -->
  36. <view v-if="desc" class="status-detail">
  37. {{ desc }}
  38. </view>
  39. <!-- 状态时间 -->
  40. <view v-if="time" class="status-time">
  41. {{ time }}
  42. </view>
  43. </view>
  44. </view>
  45. </template>
  46. <script setup>
  47. defineProps({
  48. // 是否激活状态(即当前状态)
  49. isActive: {
  50. type: Boolean,
  51. default: false
  52. },
  53. // 标题,例如:已代收、派送中
  54. title: {
  55. type: String,
  56. default: ''
  57. },
  58. // 状态描述
  59. desc: {
  60. type: String,
  61. default: ''
  62. },
  63. // 时间
  64. time: {
  65. type: String,
  66. default: ''
  67. },
  68. // 是否显示连接线(最后一个节点不显示)
  69. showLine: {
  70. type: Boolean,
  71. default: true
  72. },
  73. // 是否显示连接线(第一个节点显示 后边不显示)
  74. showDotBg: {
  75. type: Boolean,
  76. default: true
  77. }
  78. })
  79. </script>
  80. <style scoped lang="less">
  81. .timeline-item {
  82. display: flex;
  83. // background-color: #F5F7FA;
  84. // border-radius: 16rpx;
  85. min-height: 120rpx; /* 确保最小高度 */
  86. &:last-child {
  87. margin-bottom: 0;
  88. }
  89. .timeline-left {
  90. display: flex;
  91. flex-direction: column;
  92. align-items: center;
  93. width: 54rpx; /* 增加宽度确保有足够空间 */
  94. margin-right: 20rpx;
  95. flex-shrink: 0;
  96. }
  97. .timeline {
  98. display: flex;
  99. flex-direction: column;
  100. align-items: center;
  101. height: 100%; /* 确保时间线占满整个高度 */
  102. /* 修复 dot 样式 */
  103. .dot {
  104. width: 34rpx;
  105. height: 34rpx;
  106. border-radius: 50%;
  107. display: flex;
  108. justify-content: center;
  109. align-items: center;
  110. flex-shrink: 0;
  111. position: relative;
  112. z-index: 2; /* 确保圆点在最上层 */
  113. &.dot-choose-bg {
  114. background-color: #C1D5FF;
  115. }
  116. }
  117. .timeline-dot {
  118. width: 18rpx;
  119. height: 18rpx;
  120. border-radius: 50%;
  121. position: relative;
  122. z-index: 3;
  123. &.dot-active {
  124. background-color: #1B64F0;
  125. }
  126. &.dot-passed {
  127. background-color: #CCCCCC;
  128. }
  129. }
  130. .timeline-line {
  131. flex: 1; /* 关键:使用flex:1让连接线自适应高度 */
  132. width: 4rpx;
  133. min-height: 40rpx; /* 确保最小高度 */
  134. margin-top: 10rpx;
  135. &.line-active {
  136. border-left: 4rpx dashed #1B64F0;
  137. }
  138. &.line-passed {
  139. border-left: 4rpx dashed #CCCCCC;
  140. }
  141. }
  142. }
  143. .status-section {
  144. flex: 1;
  145. min-width: 0;
  146. display: flex;
  147. margin-bottom: 20rpx;
  148. flex-direction: column;
  149. justify-content: center; /* 垂直居中内容 */
  150. .status-badge {
  151. margin-bottom: 8rpx;
  152. height: 48rpx;
  153. font-weight: 400;
  154. font-size: 32rpx;
  155. line-height: 48rpx;
  156. overflow: hidden;
  157. text-overflow: ellipsis;
  158. white-space: nowrap;
  159. &.status-collected {
  160. color: #333333;
  161. }
  162. &.status-title-active {
  163. color: #1B64F0;
  164. font-weight: 600;
  165. }
  166. /* 默认颜色 */
  167. &:not(.status-title-active) {
  168. color: #333333;
  169. }
  170. }
  171. .status-detail {
  172. font-weight: 400;
  173. font-size: 28rpx;
  174. color: #333333;
  175. line-height: 44rpx;
  176. margin-top: 8rpx;
  177. word-break: break-all;
  178. display: -webkit-box;
  179. // -webkit-line-clamp: 4; /* 限制最多显示2行 */
  180. // -webkit-box-orient: vertical;
  181. overflow: hidden;
  182. }
  183. .status-time {
  184. margin-top: 8rpx;
  185. height: 40rpx;
  186. font-weight: 400;
  187. font-size: 24rpx;
  188. color: #999999;
  189. line-height: 40rpx;
  190. overflow: hidden;
  191. text-overflow: ellipsis;
  192. white-space: nowrap;
  193. }
  194. }
  195. }
  196. </style>