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.

292 lines
6.2 KiB

8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
  1. <template>
  2. <van-list v-if="technicianList.length > 0" v-model:loading="loading" :finished="finished" finished-text="没有更多了" @load="onLoad">
  3. <view v-for="item in list" :key="item.id" class="technician-item"
  4. @click="clickItem(item)">
  5. <view class="technician-img-and-status">
  6. <view class="img-box">
  7. <image :src="item.image" mode="widthFix"></image>
  8. </view>
  9. <view v-if="item.bookable == 'Y'" class="technician-status">
  10. 可服务
  11. </view>
  12. </view>
  13. <view class="technician-server-info">
  14. <view class="technician-server-top">
  15. <view class="technician-name">
  16. <text class="name">{{ item.title }}</text>
  17. <text class="btn">更多照片</text>
  18. </view>
  19. <view class="appointed-time">
  20. <view class="capsule">
  21. <view class="earliest-reducible">最早可约</view>
  22. <view class="today">今天{{ item.useTime}}</view>
  23. </view>
  24. </view>
  25. </view>
  26. <view class="technician-server-center">
  27. <view class="server-num">
  28. 已服务{{ item.isFw }}
  29. </view>
  30. <view class="position">
  31. <view class="position-icon">
  32. <image src="@/static/technician/position.png" mode="aspectFill"></image>
  33. </view>
  34. <view class="distance">
  35. {{ item.setKmOpen == 'Y' ? item.setKm || 0 : item.km || 0 }}km
  36. </view>
  37. </view>
  38. </view>
  39. <view class="technician-server-bottom">
  40. <view class="evaluate">
  41. <view class="evaluate-icon">
  42. <image src="@/static/technician/evaluate-icon.png"></image>
  43. </view>
  44. <view class="evaluate-title">
  45. 评价
  46. </view>
  47. </view>
  48. <view class="book-now" :class="{ notAvailable : item.bookable != 'Y'}">
  49. {{ item.bookable != 'Y' ? '不可预约' : '立即预约' }}
  50. </view>
  51. </view>
  52. </view>
  53. </view>
  54. </van-list>
  55. <van-empty v-else image="/static/empty/data.png" image-size="400rpx" description="此项目暂无技师服务" />
  56. </template>
  57. <script>
  58. import Position from '@/utils/position.js'
  59. export default {
  60. name: "selectTechnicianCompoents",
  61. props: ['technicianList', "select"],
  62. data() {
  63. return {
  64. loading : false,
  65. finished : false,
  66. list : [],
  67. queryParams : {
  68. pageNo : 0,
  69. pageSize : 10
  70. },
  71. position : null
  72. }
  73. },
  74. created() {
  75. this.paging()
  76. },
  77. methods: {
  78. catch(index) { //缓存用户位置
  79. if(this.position,index){
  80. this.calculatedDistance(this.position,index)
  81. }else{
  82. Position.getLocation(result => {
  83. this.position = result
  84. this.calculatedDistance(result,index)
  85. })
  86. }
  87. },
  88. clickItem(item){
  89. if (item.bookable != 'Y') {
  90. return uni.showToast({
  91. title: '技师未开启接单',
  92. icon: 'none'
  93. })
  94. }
  95. this.select(item)
  96. },
  97. //计算距离
  98. calculatedDistance(result,index){
  99. console.log(index);
  100. for(let i = index || 0 ; i < this.list.length ; i++){
  101. let distance = Position.calculateDistance(result.latitude, result.longitude, this.list[i]
  102. .latitude, this.list[i].longitude)
  103. this.list[i].km = distance;
  104. }
  105. },
  106. //滑动到屏幕底部触发
  107. onLoad(){
  108. this.queryParams.pageNo += 1
  109. this.paging()
  110. },
  111. //分页
  112. paging(){
  113. this.loading = true
  114. let { pageNo , pageSize } = this.queryParams
  115. let startPostion = pageNo * pageSize
  116. this.list.push(...this.technicianList.slice( startPostion , startPostion + pageSize))
  117. this.catch(startPostion)
  118. if(this.list.length >= this.technicianList.length){
  119. this.finished = true
  120. }
  121. this.loading = false
  122. }
  123. }
  124. }
  125. </script>
  126. <style scoped lang="scss">
  127. .technician-item {
  128. display: flex;
  129. background: white;
  130. padding: 20rpx;
  131. margin-bottom: 20rpx;
  132. .technician-img-and-status {
  133. position: relative;
  134. height: 150rpx;
  135. display: flex;
  136. flex-direction: column;
  137. justify-content: space-between;
  138. .img-box {
  139. width: 150rpx;
  140. height: 150rpx;
  141. background: #ccc;
  142. border-radius: 10rpx;
  143. overflow: hidden;
  144. image {
  145. width: 150rpx;
  146. }
  147. }
  148. .technician-status {
  149. display: flex;
  150. justify-content: center;
  151. align-items: center;
  152. position: absolute;
  153. left: 10%;
  154. bottom: -15rpx;
  155. background: #55CCA7;
  156. width: 80%;
  157. color: white;
  158. font-size: 22rpx;
  159. height: 35rpx;
  160. border-radius: 5rpx;
  161. }
  162. }
  163. .technician-server-info {
  164. display: flex;
  165. width: calc(100% - 150rpx);
  166. padding: 0rpx 20rpx;
  167. flex-direction: column;
  168. justify-content: space-between;
  169. .technician-server-top {
  170. display: flex;
  171. justify-content: space-between;
  172. align-items: center;
  173. font-size: 26rpx;
  174. .technician-name {
  175. .name {
  176. font-weight: 600;
  177. margin-right: 10rpx;
  178. }
  179. .btn {
  180. border: 1px solid #55CCA7;
  181. color: #55CCA7;
  182. font-size: 20rpx;
  183. padding: 5rpx;
  184. border-radius: 5rpx;
  185. }
  186. }
  187. .appointed-time {
  188. width: 40%;
  189. background: #E7FDF7;
  190. height: 40rpx;
  191. border-radius: 22.5rpx;
  192. font-size: 20rpx;
  193. color: #5DB9A3;
  194. .capsule {
  195. display: flex;
  196. height: 100%;
  197. align-items: center;
  198. .earliest-reducible {
  199. display: flex;
  200. align-items: center;
  201. justify-content: center;
  202. width: 50%;
  203. height: 100%;
  204. color: white;
  205. border-radius: 20rpx;
  206. background: #52CFB0;
  207. }
  208. .today {
  209. width: 50%;
  210. text-align: center;
  211. }
  212. }
  213. }
  214. }
  215. .technician-server-center {
  216. display: flex;
  217. align-items: center;
  218. font-size: 26rpx;
  219. color: #888;
  220. .position {
  221. display: flex;
  222. margin-left: 10rpx;
  223. }
  224. image {
  225. width: 25rpx;
  226. height: 25rpx;
  227. }
  228. }
  229. .technician-server-bottom {
  230. display: flex;
  231. justify-content: space-between;
  232. .evaluate {
  233. display: flex;
  234. align-items: center;
  235. color: #333;
  236. font-size: 20rpx;
  237. .evaluate-icon {
  238. margin-right: 10rpx;
  239. }
  240. }
  241. .book-now {
  242. display: flex;
  243. align-items: center;
  244. justify-content: center;
  245. height: 50rpx;
  246. width: 160rpx;
  247. border-radius: 40rpx;
  248. color: white;
  249. background: linear-gradient(170deg, #53CEAC, #5AC796);
  250. font-size: 24rpx;
  251. }
  252. .notAvailable {
  253. background: #ccc;
  254. }
  255. image {
  256. width: 25rpx;
  257. height: 25rpx;
  258. }
  259. }
  260. }
  261. }
  262. </style>