timeLine.vue 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. <template>
  2. <div class="swiper-container">
  3. <swiper ref="mySwiper" class="swiper-wrapper timeline" :options="options">
  4. <swiper-slide v-for="(item,index) in steps" :key="index" class="swiper-slide">
  5. <div class="line" />
  6. <div
  7. class="center circle"
  8. :class="{
  9. 'circle2': item.createTime !== null && item.statusName !== null,
  10. 'circle3': item.createTime === '今天' && item.statusName === null && item.statusName !== 'HOLD' && item.statusName !== '解除HOLD',
  11. 'circle4': item.createTime === null,
  12. 'circle5': item.statusName === 'HOLD' || item.statusName === '解除HOLD'
  13. }"
  14. >
  15. <el-tooltip v-if="item.id === -2 " class="item" effect="dark" :content="'Hold原因:' + item.remark" placement="top">
  16. <div
  17. :class="{
  18. 'circle-in': item.createTime !== null && item.statusName !== null ,
  19. 'circle-is': item.createTime === '今天' && item.statusName === null,
  20. 'circle-iq': item.createTime === null,
  21. 'circle-ia': item.statusName === 'HOLD' || item.statusName === '解除HOLD'
  22. }"
  23. class="circle-of center"
  24. />
  25. </el-tooltip>
  26. <div
  27. v-else
  28. :class="{
  29. 'circle-in': item.createTime !== null && item.statusName !== null ,
  30. 'circle-is': item.createTime === '今天' && item.statusName === null,
  31. 'circle-iq': item.createTime === null,
  32. 'circle-ia': item.statusName === 'HOLD' || item.statusName === '解除HOLD'
  33. }"
  34. class="circle-of center"
  35. />
  36. </div>
  37. <div :class="[index%2==0?'point1':'point2']" />
  38. <div class="content3" :class="{'start-time': item.timeSpan === '0天'}">
  39. {{ item.timeSpan }}
  40. </div>
  41. <div class="content1">
  42. {{ item.createTime }}
  43. </div>
  44. <div class="content2">
  45. {{ item.statusName }}
  46. </div>
  47. </swiper-slide>
  48. </swiper>
  49. </div>
  50. </template>
  51. <script>
  52. import { Swiper, SwiperSlide, directive } from 'vue-awesome-swiper'
  53. import 'swiper/css/swiper.css'
  54. import { taskGetWorkFlow } from '@/api/taskIndex'
  55. import { requirementGetWorkFlow } from '@/api/requirement.js'
  56. export default {
  57. components: {
  58. Swiper,
  59. SwiperSlide
  60. },
  61. directives: {
  62. swiper: directive
  63. },
  64. props: {
  65. id: { type: [Number, String], default: null },
  66. name: { type: String, default: null }
  67. },
  68. data() {
  69. return {
  70. steps: [],
  71. options: {
  72. pagination: {
  73. el: '.swiper-pagination'
  74. },
  75. slidesPerView: 5,
  76. grabCursor: true
  77. }
  78. }
  79. },
  80. computed: {
  81. swiper() {
  82. return this.$refs.mySwiper.$swiper
  83. }
  84. },
  85. created() {
  86. this.taskGetWorkFlow()
  87. },
  88. methods: {
  89. async taskGetWorkFlow() {
  90. if (this.name === '任务') {
  91. const res = await taskGetWorkFlow(this.id)
  92. this.steps = res.data.workFlowNodeList
  93. }
  94. if (this.name === '需求') {
  95. const res = await requirementGetWorkFlow(this.id)
  96. this.steps = res.data.workFlowNodeList
  97. }
  98. }
  99. }
  100. }
  101. </script>
  102. <style scoped lang="scss">
  103. .swiper-container {
  104. padding-bottom: 20px;
  105. position: relative;
  106. }
  107. .timeline {
  108. width: calc(100% - 60px);
  109. list-style-type: none;
  110. display: flex;
  111. padding: 0;
  112. text-align: center;
  113. }
  114. .swiper-slide {
  115. height: 150px;
  116. width: 120px !important;
  117. display: flex;
  118. align-items: center;
  119. font-size: 18px;
  120. position: relative;
  121. .line{
  122. width: 100%;
  123. height:0px;
  124. border: 1px solid rgba(217,217,217,1);
  125. }
  126. .center {
  127. left: 50%;
  128. top: 50%;
  129. transform: translate(-50%,-50%);
  130. }
  131. .circle {
  132. position: absolute;
  133. }
  134. .circle2::after{
  135. content: '';
  136. position: absolute;
  137. height: 50px;
  138. border: 1px solid rgba(24,144,255,1);
  139. left: 50%;
  140. bottom: -16px;
  141. transform: translate(-50%,33px);
  142. }
  143. .circle3::after{
  144. content: '';
  145. display:none;
  146. position: absolute;
  147. height: 50px;
  148. border: 1px solid rgba(126,211,33,1);
  149. left: 50%;
  150. bottom: -16px;
  151. transform: translate(-50%,33px);
  152. }
  153. .circle4::after{
  154. content: '';
  155. position: absolute;
  156. height: 50px;
  157. border:1px solid rgba(153,153,153,1);
  158. left: 50%;
  159. bottom: -16px;
  160. transform: translate(-50%,33px);
  161. }
  162. .circle5::after{
  163. content: '';
  164. position: absolute;
  165. height: 50px;
  166. border:1px solid rgba(245,108,108,1);
  167. left: 50%;
  168. bottom: -16px;
  169. transform: translate(-50%,33px);
  170. }
  171. .circle-of {
  172. position: absolute;
  173. border-radius: 50%;
  174. width: 11px;
  175. height: 11px;
  176. z-index: 99;
  177. }
  178. .circle-in {
  179. background: rgba(24,144,255,1);
  180. }
  181. .circle-is {
  182. background:rgba(126,211,33,1);
  183. }
  184. .circle-iq {
  185. background:rgba(153,153,153,1);
  186. }
  187. .circle-ia {
  188. background:rgba(245,108,108,1);
  189. }
  190. .content1,.content2 {
  191. width: 100%;
  192. font-size: 12px;
  193. color: rgba(51,51,51,1);
  194. position: absolute;
  195. left: 50%;
  196. transform: translateX(-50%);
  197. }
  198. .content3 {
  199. width: 100%;
  200. font-size: 10px;
  201. color: rgba(97,175,255,1);
  202. position: absolute;
  203. left: 0%;
  204. top: 58px;
  205. transform: translateX(-50%);
  206. }
  207. .content2 {
  208. bottom:5px;
  209. font-weight:500;
  210. }
  211. .content1 {
  212. top: 45px;
  213. }
  214. .start-time {
  215. color: rgba(153,153,153,1);
  216. }
  217. }
  218. .swiper-slide {
  219. margin-top: -30px;
  220. }
  221. .swiper-slide:nth-child(2n) {
  222. width: 40%;
  223. }
  224. .swiper-slide:nth-child(3n) {
  225. width: 20%;
  226. }
  227. </style>