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.

651 lines
14 KiB

10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
  1. <template>
  2. <view class="technician-Detail">
  3. <van-nav-bar class="technician-Detail-Top" title="技师详情" left-arrow @click-left="back" safe-area-inset-top />
  4. <view class="technician-Detail-img">
  5. <van-swipe class="my-swipe" :autoplay="3000" indicator-color="white">
  6. <van-swipe-item v-for="(item,index) in technicianImages" :key="index">
  7. <image :src="item" style="width: 100%;" mode="widthFix"></image>
  8. </van-swipe-item>
  9. <template #indicator="{ active, total }">
  10. <!-- <div class="custom-indicator">{{ active + 1 }}/{{ total }}</div> -->
  11. </template>
  12. </van-swipe>
  13. <view class="technician-Detail-img-text">下单付款后商家会在10分钟内联系你哦~</view>
  14. </view>
  15. <view class="techni-content">
  16. <view class="userInfo">
  17. <view class="img-box">
  18. <image @click="showImage(technicianDetail.image)" :src="technicianDetail.image" mode="aspectFill"></image>
  19. </view>
  20. <view class="base-info">
  21. <view class="username-tag">
  22. <view class="username">{{ technicianDetail.title }}</view>
  23. <view v-if="technicianDetail.isVip" class="tag">
  24. <image src="@/static/order/s.png" mode="aspectFit"></image>
  25. <view class="auth">官方认证</view>
  26. </view>
  27. </view>
  28. <view class="build">
  29. <view class="sex">
  30. <image src="../../static/technician/sex.png" mode="aspectFit"></image>
  31. </view>
  32. <view class="address">
  33. {{ technicianDetail.area }}
  34. </view>
  35. <view class="cm">
  36. {{ technicianDetail.cm }}
  37. </view>
  38. <view class="weight">
  39. {{ technicianDetail.kg /2 }}kg
  40. </view>
  41. <view class="real-name">
  42. <image src="../../static/technician/real-name.png" mode="aspectFit"></image>
  43. <view class="desc">实名</view>
  44. </view>
  45. </view>
  46. <view class="service-experience">
  47. <view class="experience">
  48. {{ technicianDetail.experience }}年经验
  49. </view>
  50. <view class="service-num">
  51. 近期服务过{{ technicianDetail.isFw }}
  52. </view>
  53. </view>
  54. </view>
  55. </view>
  56. <view class="view">
  57. <view class="service-description">
  58. <div v-for="item in serviceDescList" class="sesc-item">
  59. <image src="../../static/technician/desc.png" mode="aspectFit"></image>
  60. <view>{{ item }}</view>
  61. </div>
  62. </view>
  63. </view>
  64. <view class="line">
  65. <view></view>
  66. </view>
  67. <view class="text">
  68. <div class="colleact-info">
  69. <view style="color: #454545;">个人介绍</view>
  70. <!-- <view v-if="collect == 0" class="selective-technician">
  71. <view @click.stop="addCollect(technicianDetail.id)" class="btn">
  72. 立即收藏
  73. </view>
  74. </view> -->
  75. </div>
  76. <view style="color: #A1A1A1; margin-top: 5px;">
  77. {{ technicianDetail.notes }}
  78. </view>
  79. </view>
  80. <!-- <view class="ServicesAvailable">
  81. <view>服务项目</view>
  82. </view> -->
  83. <van-tabs class="tabs" v-model:active="activeTag" color="#EF8C94">
  84. <van-tab title="服务项目">
  85. <van-empty v-if="projectList.length <= 0" image="/static/empty/message-list.png" image-size="400rpx" description="暂无服务"/>
  86. <view v-else class="server-list">
  87. <view v-for="item in projectList" class="server-item" @click="toPayOrder(item)">
  88. <view class="img-box">
  89. <image :src="item.image" mode="aspectFill"></image>
  90. </view>
  91. <view class="server-info">
  92. <view class="server-title">{{ item.title }}</view>
  93. <view class="time-coupon">
  94. <image src="@/static/home/time-icon.png"></image>
  95. <view class="time">{{ item.times }}分钟</view>
  96. <!-- <view class="coupon">{{ item.subTitle }}</view> -->
  97. </view>
  98. <view class="price">
  99. <view class="current-price">
  100. <text class="unit"></text>{{ item.price }}
  101. </view>
  102. <view class="original-price">
  103. <text class="unit"></text>{{ item.oldPrice }}
  104. </view>
  105. </view>
  106. <view class="sales-volume">
  107. <image src="@/static/icons/icon1.png"></image>
  108. <view class="desc">已售出{{ item.payNum }}+</view>
  109. </view>
  110. </view>
  111. <view class="selective-technician">
  112. <view @click.stop="toPayOrder(item)" :class="{ notAvailable : technicianDetail.bookable != 'Y' }" class="btn">
  113. {{ technicianDetail.bookable == 'Y' ? '立即预约' : '不可预约' }}
  114. </view>
  115. </view>
  116. </view>
  117. </view>
  118. </van-tab>
  119. <van-tab title="健康证">
  120. <view class="health-certificate">
  121. <van-empty v-if="false" image="/static/empty/order.png" image-size="400rpx" description="技师暂未上传健康证"/>
  122. <view v-else class="health-certificate-main">
  123. <image @click="showImage('../../static/ms/w.png')" src="../../static/ms/w.png" mode="widthFix" style="width: 100%;"></image>
  124. </view>
  125. </view>
  126. </van-tab>
  127. <van-tab title="营业证">
  128. <view class="health-certificate">
  129. <van-empty v-if="false" image="/static/empty/order.png" image-size="400rpx" description="技师暂未上传健康证"/>
  130. <view v-else class="health-certificate-main">
  131. <image @click="showImage('../../static/ms/w.png')" src="../../static/ms/w.png" mode="widthFix" style="width: 100%;"></image>
  132. </view>
  133. </view>
  134. </van-tab>
  135. </van-tabs>
  136. </view>
  137. <van-floating-bubble
  138. v-if="collect == 0"
  139. axis="xy"
  140. icon="/static/technician/collect-icon.png"
  141. magnetic="x"
  142. @click="addCollect(technicianDetail.id)"
  143. />
  144. </view>
  145. </template>
  146. <script>
  147. import { showImagePreview } from 'vant';
  148. export default {
  149. data() {
  150. return {
  151. searchKeyword: '',
  152. technicianDetail: {},
  153. projectList: [],
  154. queryParams: {
  155. pageNo: 1,
  156. pageSize: 100
  157. },
  158. loading: false,
  159. finished: false,
  160. serviceDescList : ['实名认证','头像认证','健康证','按摩师证'],
  161. collect : 0,
  162. technicianImages : [],
  163. activeTag : 0
  164. }
  165. },
  166. onShow() {
  167. this.getTechnicianDetail()
  168. },
  169. methods: {
  170. //获取技师详情
  171. getTechnicianDetail() {
  172. this.$api('getTechnicianDetail', {
  173. id: this.$route.query.id
  174. }, res => {
  175. if (res.code == 200) {
  176. this.collect = res.result.collect
  177. this.technicianDetail = res.result.msgTechnician
  178. if(res.result.msgTechnician.images == ''){ //如果用户没有上传个人相册,那么这里给个默认值
  179. this.technicianImages = ['/static/technician/album.png']
  180. }else{
  181. this.technicianImages = res.result.msgTechnician.images.split(',')
  182. }
  183. this.projectList = res.result.list
  184. }
  185. })
  186. },
  187. back() {
  188. uni.switchTab({
  189. url: '/pages/index/technician'
  190. })
  191. },
  192. toPayOrder(item) {
  193. if (this.technicianDetail.bookable != 'Y') {
  194. return uni.showToast({
  195. title: '技师未开启接单',
  196. icon: 'none'
  197. })
  198. }
  199. this.$api('createVipOrder', {
  200. projectId: item.id,
  201. technicianId: this.$route.query.id
  202. }, res => {
  203. if (res.code == 200) {
  204. if (res.code == 200) {
  205. let {
  206. distance,
  207. id,
  208. setKmOpen
  209. } = this.$route.query
  210. uni.navigateTo({ //setKmOpen 是否开启假距离 distance 距离信息
  211. url: `/pages/order/payOrder?orderId=${res.result.id}&distance=${distance}&id=${id}&current=technicianDetail&setKmOpen=${setKmOpen}`
  212. })
  213. }
  214. }
  215. })
  216. },
  217. addCollect(tenId) { //新增收藏
  218. this.$api('addCollect', {
  219. tenId
  220. }, res => {
  221. if (res.code == 200) {
  222. uni.showToast({
  223. title: '收藏成功',
  224. icon: 'none'
  225. })
  226. this.getTechnicianDetail()
  227. }
  228. })
  229. },
  230. //放大显示图片
  231. showImage(imgUrl){
  232. showImagePreview({
  233. images: [imgUrl],
  234. closeable: true,
  235. });
  236. }
  237. }
  238. }
  239. </script>
  240. <style scoped lang="scss">
  241. .technician-Detail {
  242. width: 750rpx;
  243. background: #F5F5F5;
  244. margin: 0 auto;
  245. .technician-Detail-Top {
  246. background-color: #EF8C94;
  247. ::v-deep .van-nav-bar__title {
  248. color: #fff;
  249. }
  250. ::v-deep i {
  251. color: #fff;
  252. }
  253. }
  254. .technician-Detail-img {
  255. position: relative;
  256. max-height: 900rpx;
  257. overflow: hidden;
  258. .my-swipe .van-swipe-item {
  259. color: #fff;
  260. font-size: 20px;
  261. line-height: 150px;
  262. text-align: center;
  263. }
  264. .custom-indicator {
  265. position: absolute;
  266. right: 15rpx;
  267. bottom: 80rpx;
  268. padding: 5rpx 10rpx;
  269. font-size: 20rpx;
  270. background: rgba(0, 0, 0, 0.1);
  271. }
  272. .technician-Detail-img-text {
  273. display: flex;
  274. align-items: center;
  275. justify-content: center;
  276. position: absolute;
  277. left: 0;
  278. bottom: 0;
  279. width: 100%;
  280. height: 80rpx;
  281. background: rgba(255, 255, 255, .6);
  282. color: #4E4E50;
  283. }
  284. }
  285. .techni-content {
  286. width: calc(100% - 40rpx);
  287. margin: 10rpx 20rpx 0rpx 20rpx;
  288. .userInfo {
  289. display: flex;
  290. background: white;
  291. border-radius: 10rpx;
  292. box-sizing: border-box;
  293. padding: 20rpx 10rpx 0rpx 10rpx;
  294. color: #666666;
  295. .img-box {
  296. width: 120rpx;
  297. height: 120rpx;
  298. overflow: hidden;
  299. border-radius: 50%;
  300. &::v-deep div{
  301. background-position: center top !important;
  302. background-size: 100% !important;
  303. }
  304. image {
  305. width: 120rpx;
  306. height: 120rpx;
  307. }
  308. }
  309. .base-info {
  310. display: flex;
  311. flex-direction: column;
  312. justify-content: space-between;
  313. box-sizing: border-box;
  314. padding-left: 15rpx;
  315. width: calc(100% - 120rpx);
  316. .username-tag {
  317. display: flex;
  318. align-items: center;
  319. .username {
  320. margin-right: 5rpx;
  321. color: #333333;
  322. font-size: 26rpx;
  323. }
  324. .tag {
  325. position: relative;
  326. display: flex;
  327. align-items: center;
  328. image {
  329. height: 45rpx;
  330. width: 90rpx;
  331. vertical-align: middle;
  332. }
  333. .auth {
  334. position: absolute;
  335. white-space: nowrap;
  336. color: #FF6200;
  337. left: 23rpx;
  338. font-size: 17rpx;
  339. }
  340. }
  341. }
  342. .build {
  343. display: flex;
  344. align-items: center;
  345. .sex {
  346. width: 25rpx;
  347. height: 25rpx;
  348. image {
  349. width: 100%;
  350. height: 100%;
  351. }
  352. }
  353. .real-name {
  354. display: flex;
  355. align-items: center;
  356. padding: 0rpx 3rpx;
  357. border: 1px solid #3484E8;
  358. color: #3484E8;
  359. font-size: 22rpx;
  360. image {
  361. width: 18rpx;
  362. height: 18rpx;
  363. }
  364. }
  365. > view{
  366. border-right: 1px solid #ccc;
  367. padding: 0rpx 8rpx;
  368. &:nth-child(1){
  369. padding-left: 0;
  370. }
  371. &:nth-last-child(2){
  372. border-right: none;
  373. }
  374. }
  375. }
  376. .service-experience{
  377. display: flex;
  378. .experience{
  379. color: #ED9044;
  380. margin-right: 20rpx;
  381. }
  382. .service-num{
  383. }
  384. }
  385. }
  386. }
  387. .service-description {
  388. display: flex;
  389. background: white;
  390. justify-content: space-between;
  391. padding: 30rpx 10rpx;
  392. .sesc-item {
  393. display: flex;
  394. color: #FFD777;
  395. image {
  396. width: 30rpx;
  397. height: 30rpx;
  398. }
  399. }
  400. }
  401. .line{
  402. padding: 0rpx 10rpx;
  403. background: white;
  404. view{
  405. border-bottom: 2px dashed #EBE7E7;
  406. }
  407. }
  408. .text{
  409. background: white;
  410. box-sizing: border-box;
  411. padding: 10rpx 10rpx 30rpx 10rpx;
  412. border-bottom-left-radius: 10rpx;
  413. border-bottom-right-radius: 10rpx;
  414. }
  415. }
  416. .ServicesAvailable {
  417. margin-top: 10px;
  418. border-radius: 5px;
  419. background-color: #fff;
  420. padding: 10px 0px;
  421. font-size: 16px;
  422. view {
  423. border-left: 4px outset #55B16E;
  424. margin-left: 10px;
  425. padding-left: 10px;
  426. }
  427. }
  428. .tabs {
  429. margin-top: 20rpx;
  430. &::v-deep .van-tabs__wrap{
  431. border-radius: 10rpx;
  432. }
  433. }
  434. .server-list {
  435. padding-bottom: 80rpx;
  436. .server-item {
  437. display: flex;
  438. flex-wrap: wrap;
  439. justify-content: space-between;
  440. background: white;
  441. border-radius: 15rpx;
  442. box-sizing: border-box;
  443. padding: 15rpx;
  444. margin: 20rpx 0rpx;
  445. .img-box {
  446. width: 150rpx;
  447. height: 150rpx;
  448. border-radius: 10rpx;
  449. overflow: hidden;
  450. image {
  451. width: 100%;
  452. height: 100%;
  453. }
  454. }
  455. .server-info {
  456. display: flex;
  457. flex-direction: column;
  458. justify-content: space-around;
  459. width: calc(100% - 330rpx);
  460. box-sizing: border-box;
  461. padding: 0 10rpx;
  462. .server-title {}
  463. .time-coupon,
  464. .price {
  465. display: flex;
  466. flex-wrap: wrap;
  467. align-items: center;
  468. }
  469. .time-coupon {
  470. font-size: 26rpx;
  471. image {
  472. width: 22rpx;
  473. height: 22rpx;
  474. }
  475. .time {
  476. color: #B8B8B8;
  477. margin-left: 6rpx;
  478. }
  479. .coupon {
  480. display: flex;
  481. justify-content: center;
  482. align-items: center;
  483. background: #F29E45;
  484. color: white;
  485. width: 140rpx;
  486. height: 45rpx;
  487. border-radius: 10rpx;
  488. margin-left: 10rpx;
  489. }
  490. }
  491. .price {
  492. display: flex;
  493. align-items: center;
  494. color: #B8B8B8;
  495. .current-price {
  496. font-size: 30rpx;
  497. font-weight: 600;
  498. color: #D34430;
  499. margin-right: 5rpx;
  500. }
  501. .unit {
  502. font-size: 20rpx;
  503. }
  504. }
  505. .sales-volume {
  506. display: flex;
  507. align-items: center;
  508. color: #B8B8B8;
  509. font-size: 26rpx;
  510. image {
  511. width: 23rpx;
  512. height: 23rpx;
  513. }
  514. }
  515. }
  516. .selective-technician {
  517. display: flex;
  518. flex-wrap: wrap;
  519. align-items: center;
  520. width: 170rpx;
  521. .btn {
  522. display: flex;
  523. align-items: center;
  524. justify-content: center;
  525. height: 60rpx;
  526. width: 170rpx;
  527. border-radius: 40rpx;
  528. color: white;
  529. background: #EF8C94;
  530. }
  531. .notAvailable {
  532. background: #ccc;
  533. }
  534. }
  535. }
  536. }
  537. .health-certificate{
  538. padding-bottom: 80rpx;
  539. .health-certificate-main{
  540. margin: 15rpx 0rpx 30rpx 0rpx;
  541. background: white;
  542. min-height: 30vh;
  543. border-radius: 10rpx;
  544. box-sizing: border-box;
  545. padding: 15rpx;
  546. }
  547. }
  548. .colleact-info {
  549. display: flex;
  550. justify-content: space-between;
  551. font-size: 28rpx;
  552. align-items: center;
  553. height: 60rpx;
  554. .selective-technician {
  555. display: flex;
  556. flex-wrap: wrap;
  557. align-items: center;
  558. .btn {
  559. display: flex;
  560. align-items: center;
  561. justify-content: center;
  562. height: 50rpx;
  563. width: 170rpx;
  564. border-radius: 40rpx;
  565. color: white;
  566. background: #EF8C94;
  567. }
  568. }
  569. }
  570. }
  571. </style>