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.

643 lines
14 KiB

8 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">
  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. </view>
  138. </template>
  139. <script>
  140. import { showImagePreview } from 'vant';
  141. export default {
  142. data() {
  143. return {
  144. searchKeyword: '',
  145. technicianDetail: {},
  146. projectList: [],
  147. queryParams: {
  148. pageNo: 1,
  149. pageSize: 100
  150. },
  151. loading: false,
  152. finished: false,
  153. serviceDescList : ['实名认证','头像认证','健康证','按摩师证'],
  154. collect : 0,
  155. technicianImages : [],
  156. activeTag : 0
  157. }
  158. },
  159. onShow() {
  160. this.getTechnicianDetail()
  161. },
  162. methods: {
  163. //获取技师详情
  164. getTechnicianDetail() {
  165. this.$api('getTechnicianDetail', {
  166. id: this.$route.query.id
  167. }, res => {
  168. if (res.code == 200) {
  169. this.collect = res.result.collect
  170. this.technicianDetail = res.result.msgTechnician
  171. if(res.result.msgTechnician.images == ''){ //如果用户没有上传个人相册,那么这里给个默认值
  172. this.technicianImages = ['/static/technician/album.png']
  173. }else{
  174. this.technicianImages = res.result.msgTechnician.images.split(',')
  175. }
  176. this.projectList = res.result.list
  177. }
  178. })
  179. },
  180. back() {
  181. uni.switchTab({
  182. url: '/pages/index/technician'
  183. })
  184. },
  185. toPayOrder(item) {
  186. if (this.technicianDetail.bookable != 'Y') {
  187. return uni.showToast({
  188. title: '技师未开启接单',
  189. icon: 'none'
  190. })
  191. }
  192. this.$api('createVipOrder', {
  193. projectId: item.id,
  194. technicianId: this.$route.query.id
  195. }, res => {
  196. if (res.code == 200) {
  197. if (res.code == 200) {
  198. let {
  199. distance,
  200. id,
  201. setKmOpen
  202. } = this.$route.query
  203. uni.navigateTo({ //setKmOpen 是否开启假距离 distance 距离信息
  204. url: `/pages/order/payOrder?orderId=${res.result.id}&distance=${distance}&id=${id}&current=technicianDetail&setKmOpen=${setKmOpen}`
  205. })
  206. }
  207. }
  208. })
  209. },
  210. addCollect(tenId) { //新增收藏
  211. this.$api('addCollect', {
  212. tenId
  213. }, res => {
  214. if (res.code == 200) {
  215. uni.showToast({
  216. title: '收藏成功',
  217. icon: 'none'
  218. })
  219. this.getTechnicianDetail()
  220. }
  221. })
  222. },
  223. //放大显示图片
  224. showImage(imgUrl){
  225. showImagePreview({
  226. images: [imgUrl],
  227. closeable: true,
  228. });
  229. }
  230. }
  231. }
  232. </script>
  233. <style scoped lang="scss">
  234. .technician-Detail {
  235. width: 750rpx;
  236. background: #F5F5F5;
  237. margin: 0 auto;
  238. .technician-Detail-Top {
  239. background-color: var(--van-primary-color);
  240. ::v-deep .van-nav-bar__title {
  241. color: #fff;
  242. }
  243. ::v-deep i {
  244. color: #fff;
  245. }
  246. }
  247. .technician-Detail-img {
  248. position: relative;
  249. max-height: 900rpx;
  250. overflow: hidden;
  251. .my-swipe .van-swipe-item {
  252. color: #fff;
  253. font-size: 20px;
  254. line-height: 150px;
  255. text-align: center;
  256. }
  257. .custom-indicator {
  258. position: absolute;
  259. right: 15rpx;
  260. bottom: 80rpx;
  261. padding: 5rpx 10rpx;
  262. font-size: 20rpx;
  263. background: rgba(0, 0, 0, 0.1);
  264. }
  265. .technician-Detail-img-text {
  266. display: flex;
  267. align-items: center;
  268. justify-content: center;
  269. position: absolute;
  270. left: 0;
  271. bottom: 0;
  272. width: 100%;
  273. height: 80rpx;
  274. background: rgba(255, 255, 255, .6);
  275. color: #4E4E50;
  276. }
  277. }
  278. .techni-content {
  279. width: calc(100% - 40rpx);
  280. margin: 10rpx 20rpx 0rpx 20rpx;
  281. .userInfo {
  282. display: flex;
  283. background: white;
  284. border-radius: 10rpx;
  285. box-sizing: border-box;
  286. padding: 20rpx 10rpx 0rpx 10rpx;
  287. color: #666666;
  288. .img-box {
  289. width: 120rpx;
  290. height: 120rpx;
  291. overflow: hidden;
  292. border-radius: 50%;
  293. &::v-deep div{
  294. background-position: center top !important;
  295. background-size: 100% !important;
  296. }
  297. image {
  298. width: 120rpx;
  299. height: 120rpx;
  300. }
  301. }
  302. .base-info {
  303. display: flex;
  304. flex-direction: column;
  305. justify-content: space-between;
  306. box-sizing: border-box;
  307. padding-left: 15rpx;
  308. width: calc(100% - 120rpx);
  309. .username-tag {
  310. display: flex;
  311. align-items: center;
  312. .username {
  313. margin-right: 5rpx;
  314. color: #333333;
  315. font-size: 26rpx;
  316. }
  317. .tag {
  318. position: relative;
  319. display: flex;
  320. align-items: center;
  321. image {
  322. height: 45rpx;
  323. width: 90rpx;
  324. vertical-align: middle;
  325. }
  326. .auth {
  327. position: absolute;
  328. white-space: nowrap;
  329. color: #FF6200;
  330. left: 23rpx;
  331. font-size: 17rpx;
  332. }
  333. }
  334. }
  335. .build {
  336. display: flex;
  337. align-items: center;
  338. .sex {
  339. width: 25rpx;
  340. height: 25rpx;
  341. image {
  342. width: 100%;
  343. height: 100%;
  344. }
  345. }
  346. .real-name {
  347. display: flex;
  348. align-items: center;
  349. padding: 0rpx 3rpx;
  350. border: 1px solid #3484E8;
  351. color: #3484E8;
  352. font-size: 22rpx;
  353. image {
  354. width: 18rpx;
  355. height: 18rpx;
  356. }
  357. }
  358. > view{
  359. border-right: 1px solid #ccc;
  360. padding: 0rpx 8rpx;
  361. &:nth-child(1){
  362. padding-left: 0;
  363. }
  364. &:nth-last-child(2){
  365. border-right: none;
  366. }
  367. }
  368. }
  369. .service-experience{
  370. display: flex;
  371. .experience{
  372. color: #ED9044;
  373. margin-right: 20rpx;
  374. }
  375. .service-num{
  376. }
  377. }
  378. }
  379. }
  380. .service-description {
  381. display: flex;
  382. background: white;
  383. justify-content: space-between;
  384. padding: 30rpx 10rpx;
  385. .sesc-item {
  386. display: flex;
  387. color: #FFD777;
  388. image {
  389. width: 30rpx;
  390. height: 30rpx;
  391. }
  392. }
  393. }
  394. .line{
  395. padding: 0rpx 10rpx;
  396. background: white;
  397. view{
  398. border-bottom: 2px dashed #EBE7E7;
  399. }
  400. }
  401. .text{
  402. background: white;
  403. box-sizing: border-box;
  404. padding: 10rpx 10rpx 30rpx 10rpx;
  405. border-bottom-left-radius: 10rpx;
  406. border-bottom-right-radius: 10rpx;
  407. }
  408. }
  409. .ServicesAvailable {
  410. margin-top: 10px;
  411. border-radius: 5px;
  412. background-color: #fff;
  413. padding: 10px 0px;
  414. font-size: 16px;
  415. view {
  416. border-left: 4px outset #55B16E;
  417. margin-left: 10px;
  418. padding-left: 10px;
  419. }
  420. }
  421. .tabs {
  422. margin-top: 20rpx;
  423. &::v-deep .van-tabs__wrap{
  424. border-radius: 10rpx;
  425. }
  426. }
  427. .server-list {
  428. padding-bottom: 80rpx;
  429. .server-item {
  430. display: flex;
  431. flex-wrap: wrap;
  432. justify-content: space-between;
  433. background: white;
  434. border-radius: 15rpx;
  435. box-sizing: border-box;
  436. padding: 15rpx;
  437. margin: 20rpx 0rpx;
  438. .img-box {
  439. width: 150rpx;
  440. height: 150rpx;
  441. border-radius: 10rpx;
  442. overflow: hidden;
  443. image {
  444. width: 100%;
  445. height: 100%;
  446. }
  447. }
  448. .server-info {
  449. display: flex;
  450. flex-direction: column;
  451. justify-content: space-around;
  452. width: calc(100% - 330rpx);
  453. box-sizing: border-box;
  454. padding: 0 10rpx;
  455. .server-title {}
  456. .time-coupon,
  457. .price {
  458. display: flex;
  459. flex-wrap: wrap;
  460. align-items: center;
  461. }
  462. .time-coupon {
  463. font-size: 26rpx;
  464. image {
  465. width: 22rpx;
  466. height: 22rpx;
  467. }
  468. .time {
  469. color: #B8B8B8;
  470. margin-left: 6rpx;
  471. }
  472. .coupon {
  473. display: flex;
  474. justify-content: center;
  475. align-items: center;
  476. background: #F29E45;
  477. color: white;
  478. width: 140rpx;
  479. height: 45rpx;
  480. border-radius: 10rpx;
  481. margin-left: 10rpx;
  482. }
  483. }
  484. .price {
  485. display: flex;
  486. align-items: center;
  487. color: #B8B8B8;
  488. .current-price {
  489. font-size: 30rpx;
  490. font-weight: 600;
  491. color: #D34430;
  492. margin-right: 5rpx;
  493. }
  494. .unit {
  495. font-size: 20rpx;
  496. }
  497. }
  498. .sales-volume {
  499. display: flex;
  500. align-items: center;
  501. color: #B8B8B8;
  502. font-size: 26rpx;
  503. image {
  504. width: 23rpx;
  505. height: 23rpx;
  506. }
  507. }
  508. }
  509. .selective-technician {
  510. display: flex;
  511. flex-wrap: wrap;
  512. align-items: center;
  513. width: 170rpx;
  514. .btn {
  515. display: flex;
  516. align-items: center;
  517. justify-content: center;
  518. height: 60rpx;
  519. width: 170rpx;
  520. border-radius: 40rpx;
  521. color: white;
  522. background: linear-gradient(170deg, #53CEAC, #5AC796);
  523. }
  524. .notAvailable {
  525. background: #ccc;
  526. }
  527. }
  528. }
  529. }
  530. .health-certificate{
  531. padding-bottom: 80rpx;
  532. .health-certificate-main{
  533. margin: 15rpx 0rpx 30rpx 0rpx;
  534. background: white;
  535. min-height: 30vh;
  536. border-radius: 10rpx;
  537. box-sizing: border-box;
  538. padding: 15rpx;
  539. }
  540. }
  541. .colleact-info {
  542. display: flex;
  543. justify-content: space-between;
  544. font-size: 28rpx;
  545. align-items: center;
  546. height: 60rpx;
  547. .selective-technician {
  548. display: flex;
  549. flex-wrap: wrap;
  550. align-items: center;
  551. .btn {
  552. display: flex;
  553. align-items: center;
  554. justify-content: center;
  555. height: 50rpx;
  556. width: 170rpx;
  557. border-radius: 40rpx;
  558. color: white;
  559. background: linear-gradient(170deg, #53CEAC, #5AC796);
  560. }
  561. }
  562. }
  563. }
  564. </style>