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

1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year 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>