普兆健康管家前端代码仓库
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.

327 lines
7.6 KiB

  1. <template>
  2. <view class="card" @click="jumpToProductDetail">
  3. <view class="flex top">
  4. <view class="title">{{ data.title }}</view>
  5. <view :class="['flex', 'status', `status-${flag}`]">{{ flagDesc }}</view>
  6. </view>
  7. <view class="flex main">
  8. <image class="img" :src="coverImg" mode="scaleToFill"></image>
  9. <view class="info">
  10. <view class="flex row">
  11. <view class="row-label">客户姓名</view>
  12. <view class="row-content">{{ data.name }}</view>
  13. </view>
  14. <template v-if="data.status == 0">
  15. <view class="flex row">
  16. <view class="row-label">下单时间</view>
  17. <!-- todo: check key -->
  18. <view class="row-content">{{ data.createTime }}</view>
  19. </view>
  20. </template>
  21. <template v-else>
  22. <view class="flex row">
  23. <view class="row-label">检测类型</view>
  24. <view class="row-content">{{ subscribeTypeDesc }}</view>
  25. </view>
  26. <view class="flex row">
  27. <view class="row-label">预约时间</view>
  28. <view class="row-content">{{ timeDesc }}</view>
  29. </view>
  30. </template>
  31. <view class="flex row">
  32. <view class="row-label">联系电话</view>
  33. <view class="row-content">{{ data.phone }}</view>
  34. </view>
  35. </view>
  36. </view>
  37. <view class="flex bottom">
  38. <view class="flex price">
  39. <text class="price-label">总价格</text>
  40. <text class="price-unit">¥</text><text class="price-value">{{ data.price }}</text>
  41. </view>
  42. <view class="flex btns">
  43. <!-- 待预约 -->
  44. <template v-if="data.status == '0'">
  45. <button class="btn" @click.stop="onBook">检测预约</button>
  46. </template>
  47. <!-- 待检测 -->
  48. <template v-else-if="data.status == '1'">
  49. <!-- 自采 -->
  50. <template v-if="data.subscribeType == '0'">
  51. <button class="btn" @click.stop="onSendBackOnline">线上回寄试剂盒</button>
  52. </template>
  53. </template>
  54. </view>
  55. </view>
  56. </view>
  57. </template>
  58. <script>
  59. // 状态 0待预约 1待检测 2已完成 3已取消
  60. const STATUS_AND_DESC_MAPPING = {
  61. 0: '待预约',
  62. 1: '待检测',
  63. 2: '已完成',
  64. 3: '已取消',
  65. // todo: check 预约失败
  66. // 0: '待预约',
  67. // 1: '自采',
  68. // 2: '上门',
  69. // 3: '到店',
  70. // 4: '已完成',
  71. // 5: '已取消',
  72. // 6: '预约失败',
  73. }
  74. const FLAG_AND_DESC_MAPPING = {
  75. 0: '待预约',
  76. 1: '自采',
  77. 2: '上门',
  78. 3: '到店',
  79. 4: '已完成',
  80. 5: '已取消',
  81. 6: '预约失败',
  82. }
  83. // 可选预约类型 0自采,1上门,2到店,3已取消
  84. const SUBSCRIBE_TYPE_AND_DESC_MAPPING = {
  85. 0: '自采',
  86. 1: '上门',
  87. 2: '到店',
  88. 3: '已取消',
  89. }
  90. export default {
  91. props: {
  92. data: {
  93. type: Object,
  94. default() {
  95. return {}
  96. }
  97. }
  98. },
  99. computed: {
  100. coverImg() {
  101. const { orderProduct } = this.data || {}
  102. const { image } = orderProduct || {}
  103. return image?.split?.(',')?.[0]
  104. },
  105. subscribeTypeDesc() {
  106. const { subscribeType } = this.data
  107. return SUBSCRIBE_TYPE_AND_DESC_MAPPING[subscribeType]
  108. },
  109. flag() {
  110. const { status, subscribeType } = this.data
  111. // 0: '待预约',
  112. // 1: '自采',
  113. // 2: '上门',
  114. // 3: '到店',
  115. // 4: '已完成',
  116. // 5: '已取消',
  117. // todo: check 预约失败
  118. // 6: '预约失败',
  119. // status 状态 0待预约 1待检测 2已完成 3已取消
  120. if (status == '0') { // 待预约
  121. return 0 // 待预约
  122. }
  123. if (status == '1') { // 待检测
  124. // subscribeType 可选预约类型 0自采,1上门,2到店,3已取消
  125. if (subscribeType == '0') {
  126. return 1 // 自采
  127. } else if (subscribeType == '1') {
  128. return 2 // 上门
  129. } else if (subscribeType == '2') {
  130. return 3 // 到店
  131. }
  132. return
  133. }
  134. if (status == '2') { // 已完成
  135. return 4 // 已完成
  136. }
  137. if (status == '3') { // 已取消
  138. return 5 // 已取消
  139. }
  140. },
  141. flagDesc() {
  142. return FLAG_AND_DESC_MAPPING[this.flag]
  143. },
  144. timeDesc() {
  145. const { subscribeDate, subscribeTime } = this.data || {}
  146. if (!subscribeTime) {
  147. return '--'
  148. }
  149. const timeRange = JSON.parse(subscribeTime).join('~')
  150. return `${subscribeDate} ${timeRange}`
  151. },
  152. },
  153. methods: {
  154. onBook() {
  155. this.$utils.navigateTo(`/pages_order/checkup/checkupBook/apply?id=${this.data.id}&type=${this.data.type}`)
  156. },
  157. onSendBackOnline() {
  158. this.$emit('sendBack')
  159. },
  160. jumpToProductDetail() {
  161. console.log(this.data.id, 'jumpToProductDetail')
  162. // this.$utils.navigateTo(`/pages_order/checkup/checkupBook/detail?id=${this.data.id}`)
  163. // todo: check
  164. if (this.data.status == '0') { // 0-待预约
  165. // this.$utils.navigateTo(`/pages_order/order/orderDetail/index?id=${this.data.id}`)
  166. } else {
  167. this.$utils.navigateTo(`/pages_order/checkup/checkupBook/detail?id=${this.data.id}`)
  168. }
  169. },
  170. },
  171. }
  172. </script>
  173. <style scoped lang="scss">
  174. .card {
  175. width: 100%;
  176. padding: 32rpx;
  177. box-sizing: border-box;
  178. background: #FAFAFF;
  179. border: 2rpx solid #FFFFFF;
  180. border-radius: 32rpx;
  181. }
  182. .top {
  183. justify-content: space-between;
  184. .title {
  185. font-family: PingFang SC;
  186. font-weight: 500;
  187. font-size: 36rpx;
  188. line-height: 1.4;
  189. color: #252545;
  190. }
  191. .status {
  192. display: inline-flex;
  193. min-width: 120rpx;
  194. padding: 6rpx 0;
  195. box-sizing: border-box;
  196. font-family: PingFang SC;
  197. font-weight: 400;
  198. font-size: 24rpx;
  199. line-height: 1.4;
  200. color: #252545;
  201. background: #F3F3F3;
  202. border-radius: 12rpx;
  203. &-0 {
  204. color: #7D27E0;
  205. background: #F5EEFD;
  206. }
  207. &-1 {
  208. color: #2799E0;
  209. background: #EEF7FD;
  210. }
  211. &-2 {
  212. color: #E53C29;
  213. background: #FDE7E5;
  214. }
  215. &-3 {
  216. color: #10A934;
  217. background: #E2FDE9;
  218. }
  219. }
  220. }
  221. .main {
  222. margin: 24rpx 0;
  223. column-gap: 24rpx;
  224. .img {
  225. flex: none;
  226. width: 120rpx;
  227. height: 120rpx;
  228. }
  229. .info {
  230. flex: 1;
  231. padding: 24rpx;
  232. background: #FFFFFF;
  233. border-radius: 32rpx;
  234. }
  235. .row {
  236. align-items: flex-start;
  237. justify-content: flex-start;
  238. column-gap: 4rpx;
  239. font-family: PingFang SC;
  240. font-weight: 400;
  241. font-size: 28rpx;
  242. line-height: 1.4;
  243. &-label {
  244. flex: none;
  245. color: #8B8B8B;
  246. }
  247. &-content {
  248. color: #393939;
  249. }
  250. }
  251. .row + .row {
  252. margin-top: 16rpx;
  253. }
  254. }
  255. .bottom {
  256. justify-content: space-between;
  257. .price {
  258. column-gap: 8rpx;
  259. font-family: PingFang SC;
  260. font-weight: 500;
  261. line-height: 1.4;
  262. &-label {
  263. font-weight: 400;
  264. font-size: 26rpx;
  265. color: #8B8B8B;
  266. }
  267. &-unit {
  268. font-size: 24rpx;
  269. color: #7451DE;
  270. }
  271. &-value {
  272. font-size: 32rpx;
  273. color: #7451DE;
  274. }
  275. }
  276. .btns {
  277. flex: 1;
  278. justify-content: flex-end;
  279. column-gap: 16rpx;
  280. }
  281. .btn {
  282. padding: 10rpx 22rpx;
  283. font-family: PingFang SC;
  284. font-weight: 400;
  285. font-size: 28rpx;
  286. line-height: 1.4;
  287. color: #393939;
  288. border: 2rpx solid #252545;
  289. border-radius: 32rpx;
  290. }
  291. }
  292. </style>