doctorRegister.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471
  1. <template>
  2. <view class="container">
  3. <view class="info">
  4. <view class="es-mt-34 u-f-ajc u-f-jsb" :style="{paddingTop: statusBarHeight+'px'}">
  5. <view class="u-f-ajc" @tap="toBack">
  6. <image class="es-icon-64" src="/static/image/black_back.png" mode=""></image>
  7. </view>
  8. <view class="u-f-ajc">
  9. <image @tap="doShare(doctor.doctorName || '')" class="es-icon-48"
  10. src="/static/image/agent/share_icom.png" mode=""></image>
  11. </view>
  12. </view>
  13. <view class="u-f-ajc u-f-jsb">
  14. <view class="es-mt-38">
  15. <view class="u-f-ajc" :style="{alignItems:'flex-end'}">
  16. <view class="es-c-22 es-fs-48 es-fw-600">{{doctor.doctorName || ''}}</view>
  17. <view class="line"></view>
  18. <view class="es-fs-24 es-c-22 es-mb-10"><text>{{department && department.deptName || ''}}</text>
  19. ·
  20. <text>{{doctor.position || ''}}</text>
  21. </view>
  22. </view>
  23. <view class="u-f es-mt-26">
  24. <view class="es-fs-20 three es-mr-12 u-f-ajc" v-if="hospital.sealUrl">
  25. {{hospital?hospital.sealUrl : ''}}
  26. </view>
  27. <view class="es-fs-28 es-c-22 es-mr-10">
  28. {{hospital?hospital.hospitalName : ''}}
  29. </view>
  30. <view class="u-f-ajc" v-if="false">
  31. <u-icon name="arrow-right" size="22rpx" color="#222222"></u-icon>
  32. </view>
  33. </view>
  34. </view>
  35. <view class="u-f-ajc">
  36. <image class="es-br-ban es-icon-128" :src="doctor.avatar ||'/static/logo.png'" mode=""></image>
  37. </view>
  38. </view>
  39. <view class="u-f-ajc u-f-jsb es-mt-32">
  40. <view class="u-f-ajc">
  41. <view class="color9B es-fs-24 es-mr-8">好评率</view>
  42. <view class="es-fw-600 es-c-22 es-fs-32">{{doctor.pingStar || 0}}分</view>
  43. </view>
  44. <view class="u-f-ajc">
  45. <view class="color9B es-fs-24 es-mr-8">接诊量</view>
  46. <view class="es-fw-600 es-c-22 es-fs-32">{{doctor.orderNumber || 0}}</view>
  47. </view>
  48. <view class="u-f-ajc">
  49. <view class="color9B es-fs-24 es-mr-8">平均响应</view>
  50. <view class="es-fw-600 es-c-22 es-fs-32">{{doctor.speed || 0}}分钟</view>
  51. </view>
  52. </view>
  53. <view class="u-f es-mt-44">
  54. <view class="u-f es-mr-10 es-mt-6">
  55. <image class="image" src="/static/image/agent/be_good_at_font.png" mode=""></image>
  56. </view>
  57. <view class="es-c-22 es-fs-24 u-f-ajc" :class="[specialityShow?'':'speciality']">
  58. <view :class="[specialityShow?'':'speciality']">
  59. {{doctor.speciality || ''}}
  60. </view>
  61. <view v-if="doctor.speciality && doctor.speciality.length>28" class=""
  62. @tap="specialityShow=!specialityShow">
  63. <u-icon v-if="specialityShow" name="arrow-up" color="#222222" size="24rpx"></u-icon>
  64. <u-icon v-else name="arrow-right" color="#222222" size="24rpx"></u-icon>
  65. </view>
  66. </view>
  67. </view>
  68. <view class="u-f es-mt-14">
  69. <view class="u-f es-mr-10 es-mt-6">
  70. <image class="image" src="/static/image/agent/introduction_icon.png" mode=""></image>
  71. </view>
  72. <view class="es-c-22 es-fs-24 u-f-ajc" :class="[introductionShow?'':'speciality']">
  73. <view :class="[introductionShow?'':'speciality']">
  74. {{doctor.introduction || ''}}
  75. </view>
  76. <view v-if="doctor.introduction && doctor.introduction.length>28" class=""
  77. @tap="introductionShow=!introductionShow">
  78. <u-icon v-if="introductionShow" name="arrow-up" color="#222222" size="24rpx"></u-icon>
  79. <u-icon v-else name="arrow-right" color="#222222" size="24rpx"></u-icon>
  80. </view>
  81. </view>
  82. </view>
  83. </view>
  84. <view class="es-c-22 es-fs-32 es-fw es-ml-24 es-mt-40 title">
  85. 预约挂号
  86. </view>
  87. <view class="listBox">
  88. <view class="es-bc-white es-mt-20 es-br-16" v-for="(item,index) in list" :key="index" @tap="detail(item)">
  89. <view class="listBox-list u-f-ajc u-f-jsb">
  90. <view class="">
  91. <view class="es=c-22 es-fs-28">
  92. <text class="es-mr-12">{{item.scheduleDate}} </text>
  93. <text class="es-mr-12">
  94. {{getDayOfWeek(item.scheduleDate)}}</text>
  95. <text class="es-mr-12">
  96. {{item.timeSlotType ==1?'上午':'下午'}}</text>
  97. <text class="es-fs-20 listBox-list-tip"
  98. v-if="getDateFun(item.scheduleDate)">{{getDateFun(item.scheduleDate)}}</text>
  99. </view>
  100. <view class="es=c-99 es-fs-24 es-mt-10">
  101. <text class="es-mr-18">专家门诊</text>
  102. <text class="es-fs-24 colorFF5C03">¥{{item.price}}</text>
  103. </view>
  104. </view>
  105. <view class="es-c-white es-fs-28 listBox-list-btn"
  106. :class="[item.totalSlotsByTime<=0?'bgC':'bgFF5C03']">
  107. {{item.totalSlotsByTime?'余号'+item.totalSlotsByTime:'约满'}}
  108. </view>
  109. </view>
  110. </view>
  111. </view>
  112. <u-popup :show="show" round="40rpx" mode="bottom" @close="show=false" @open="open">
  113. <view class="popupBox">
  114. <view class="u-f-ajc u-f-jsb">
  115. <view class="u-f-ajc es-c-22 es-fs-32 es-fw">
  116. <text class="es-mr-10">{{detailData && detailData.scheduleDate || ''}}</text>
  117. <text class="es-mr-10">{{detailData && getDayOfWeek(detailData.scheduleDate)}}</text>
  118. <text class="es-mr-10">{{detailData && detailData.timeSlotType ==1?'上午':'下午'}}</text>
  119. </view>
  120. <view class="u-f-ajc" @tap="show=false">
  121. <image class="es-icon-48" src="/static/image/agent/close.png" mode=""></image>
  122. </view>
  123. </view>
  124. <view class="line"></view>
  125. <view class="popupBox-content">
  126. <view class="popupBox-content-list u-f-ajc u-f-fc" v-for="(item,index) in detailList" :key="index"
  127. :class="[index==active?'bgFCF0E7 colorFF5C03':'bgF5F7FA es-c-22']" @tap="active=index">
  128. <view class="es-fs-28 es-fw-500">
  129. {{strSplit(item.startTime)}}-{{strSplit(item.endTime)}}
  130. </view>
  131. <view class="es-fs-24 mt-4">
  132. 余号{{item.availableSlots}}
  133. </view>
  134. </view>
  135. </view>
  136. <view class="popupBox-btn es-mt-40 u-f-ajc es-fs-30 es-fw-500 es-c-white" @tap="sure">
  137. 预约
  138. </view>
  139. </view>
  140. </u-popup>
  141. <!-- 分享弹窗 -->
  142. <u-popup :show="showShare" @close="showShare = false">
  143. <share-box :shareItem="shareItem" @closeShare='showShare = false'></share-box>
  144. </u-popup>
  145. </view>
  146. </template>
  147. <script>
  148. import {
  149. getDoctorDetails
  150. } from '@/api/doctor.js'
  151. import {
  152. queryDoctorScheduleInfoByUser,
  153. userSchedule,
  154. getAiDoctorForDetails,
  155. queryDoctorScheduleInfoByDate
  156. } from '@/api/agent.js'
  157. export default {
  158. data() {
  159. return {
  160. show: false,
  161. active: 0,
  162. doctor: {
  163. certificateCode: "",
  164. },
  165. department: {
  166. deptName: ""
  167. },
  168. hospital: {
  169. hospitalName: ""
  170. },
  171. list: [],
  172. doctorId: '',
  173. timeSlotType: '',
  174. timeSlotType: '',
  175. detailData: null,
  176. detailList: [],
  177. specialityShow: false,
  178. introductionShow: false,
  179. showShare: false,
  180. shareItem: {
  181. imageUrl: "",
  182. title: "",
  183. path: "",
  184. isMini: true
  185. },
  186. isShare: false,
  187. statusBarHeight: '',
  188. }
  189. },
  190. onLoad(options) {
  191. const systemInfo = uni.getSystemInfoSync();
  192. this.statusBarHeight = systemInfo.statusBarHeight;
  193. if (options.companyId) {
  194. this.isShare = true
  195. uni.setStorageSync('registration', options)
  196. }
  197. const registration = uni.getStorageSync('registration')
  198. if (registration && registration.companyId) {
  199. this.isShare = true
  200. }
  201. if (options.doctorId) {
  202. this.doctorId = options.doctorId
  203. this.getAiDoctorForDetailsFun()
  204. this.queryDoctorScheduleInfoByDateFun()
  205. }
  206. },
  207. computed: {
  208. },
  209. onShow() {
  210. },
  211. methods: {
  212. toBack() {
  213. uni.navigateBack()
  214. },
  215. doShare(title) {
  216. const registration = uni.getStorageSync('registration')
  217. this.shareItem.title = title;
  218. this.shareItem.imageUrl = this.doctor && this.doctor.avatar || '';
  219. this.shareItem.compressImage = 1
  220. this.shareItem.isMini = true;
  221. this.shareItem.path =
  222. `/pages_doctor/doctorRegister?doctorId=${this.doctorId}&companyId=${registration.companyId || ''}&companyUserId=${registration.companyUserId || ''}`
  223. let cdn = uni.getStorageSync('h5Path');
  224. this.shareItem.url =
  225. `${cdn}/pages_doctor/doctorRegister?doctorId=${this.doctorId}&companyId=${registration.companyId || ''}&companyUserId=${registration.companyUserId || ''}`;
  226. this.showShare = true;
  227. },
  228. strSplit(e) {
  229. let time = e.split(':')
  230. return time[0] + ':' + time[1]
  231. },
  232. getDateFun(timeData) {
  233. const now = new Date();
  234. const targetDate = new Date(timeData);
  235. const diffTime = targetDate.getTime() - now.getTime();
  236. const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
  237. if (diffDays === 0) {
  238. return '今天'
  239. } else if (diffDays === 1) {
  240. return '明天'
  241. } else if (diffDays === 2) {
  242. return '后天'
  243. } else {
  244. return ''
  245. }
  246. },
  247. schedulestatusFun(e) {
  248. let arr = ['', '余号' + e.totalSlots, '停诊', '已满']
  249. return arr[e.scheduleStatus]
  250. },
  251. getDayOfWeek(date) {
  252. const days = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
  253. const today = new Date(date);
  254. const dayIndex = today.getDay();
  255. return days[dayIndex];
  256. },
  257. async getAiDoctorForDetailsFun() {
  258. const res = await getDoctorDetails({
  259. doctorId: this.doctorId
  260. })
  261. if (res.code == 200) {
  262. this.doctor = res.data.doctor;
  263. this.department = res.data.department;
  264. this.hospital = res.data.hospital;
  265. } else {
  266. uni.showToast({
  267. icon: 'none',
  268. title: res.msg
  269. })
  270. }
  271. },
  272. async queryDoctorScheduleInfoByDateFun() {
  273. const res = await queryDoctorScheduleInfoByDate({
  274. doctorId: this.doctorId,
  275. isPrivate: this.isShare,
  276. scheduleDate: this.detailData ? this.detailData.scheduleDate : '',
  277. timeSlotType: this.detailData ? this.detailData.timeSlotType : ''
  278. })
  279. if (res.code == 200) {
  280. this.list = res.data
  281. } else {
  282. uni.showToast({
  283. icon: 'none',
  284. title: res.msg
  285. })
  286. }
  287. },
  288. async queryDoctorScheduleInfoByUserFun() {
  289. const res = await queryDoctorScheduleInfoByUser({
  290. doctorId: this.doctorId,
  291. scheduleDate: this.detailData ? this.detailData.scheduleDate : '',
  292. timeSlotType: this.detailData ? this.detailData.timeSlotType : ''
  293. })
  294. if (res.code == 200) {
  295. if (this.detailData) {
  296. this.detailList = res.data
  297. this.show = true
  298. return
  299. }
  300. // this.list = res.data
  301. } else {
  302. uni.showToast({
  303. icon: 'none',
  304. title: res.msg
  305. })
  306. }
  307. },
  308. detail(e) {
  309. if (e.totalSlotsByTime <= 0) return
  310. this.detailData = e
  311. this.queryDoctorScheduleInfoByUserFun()
  312. },
  313. async sure() {
  314. const res = await userSchedule({
  315. doctorId: this.doctorId,
  316. scheduleDate: this.detailData ? this.detailData.scheduleDate : '',
  317. startTime: this.detailList[this.active].startTime,
  318. endTime: this.detailList[this.active].endTime,
  319. })
  320. if (res.code == 200) {
  321. this.show = false
  322. uni.navigateTo({
  323. url: `/pages/store/inquiryForm1?inquiryType=1&orderType=3&doctorId=${this.doctorId}&scheduleStartTime=${this.detailData.scheduleDate+' '+this.detailList[this.active].startTime}&scheduleEndTime=${this.detailData.scheduleDate+' '+this.detailList[this.active].endTime}`
  324. })
  325. } else {
  326. uni.showToast({
  327. icon: 'none',
  328. title: res.msg
  329. })
  330. }
  331. }
  332. }
  333. }
  334. </script>
  335. <style scoped lang="scss">
  336. .container {
  337. background: #F5F7FA;
  338. }
  339. .info {
  340. padding: 24rpx;
  341. background-image: url('/static/image/agent/doctor-register-bg.png');
  342. background-repeat: no-repeat;
  343. background-size: 100% 100%;
  344. height: 588rpx;
  345. .line {
  346. display: inline-block;
  347. width: 2rpx;
  348. height: 24rpx;
  349. background: #222222;
  350. margin: 0 16rpx 10rpx;
  351. }
  352. .color9B {
  353. color: #9B9B9B;
  354. }
  355. .three {
  356. padding: 4rpx 12rpx;
  357. background: #FCF0E7;
  358. border-radius: 8rpx 8rpx 8rpx 8rpx;
  359. border: 1rpx solid #FF5030;
  360. color: #FF5030;
  361. }
  362. .image {
  363. width: 64rpx;
  364. height: 24rpx;
  365. }
  366. }
  367. .title {
  368. position: relative;
  369. &::after {
  370. content: '';
  371. width: 24rpx;
  372. height: 8rpx;
  373. background: #FF5030;
  374. border-radius: 4rpx 4rpx 4rpx 4rpx;
  375. position: absolute;
  376. left: 52rpx;
  377. bottom: -14rpx;
  378. // display: flex;
  379. // align-items: center;
  380. // justify-content: center;
  381. }
  382. }
  383. .listBox {
  384. margin: 32rpx 24rpx 0;
  385. .listBox-list {
  386. padding: 32rpx;
  387. .listBox-list-tip {
  388. padding: 4rpx 8rpx;
  389. color: #454545;
  390. background: #ECECEC;
  391. border-radius: 8rpx;
  392. }
  393. .listBox-list-btn {
  394. padding: 12rpx 52rpx;
  395. border-radius: 32rpx;
  396. }
  397. .bgC {
  398. background: #CCCCCC;
  399. }
  400. .bgFF5C03 {
  401. background: #FF5030;
  402. }
  403. }
  404. }
  405. .colorFF5C03 {
  406. color: #FF5030;
  407. }
  408. .popupBox {
  409. padding: 30rpx 24rpx;
  410. .line {
  411. height: 1rpx;
  412. background-color: #ECECEC;
  413. margin: 30rpx 0;
  414. }
  415. .bgFCF0E7 {
  416. background: #FCF0E7;
  417. }
  418. .bgF5F7FA {
  419. background: #F5F7FA;
  420. }
  421. .popupBox-content {
  422. display: grid;
  423. grid-template-columns: repeat(3, 1fr);
  424. gap: 16rpx;
  425. .popupBox-content-list {
  426. border-radius: 24rpx;
  427. height: 160rpx;
  428. }
  429. }
  430. .popupBox-btn {
  431. height: 96rpx;
  432. background: #FC581C;
  433. border-radius: 48rpx;
  434. }
  435. }
  436. .speciality {
  437. overflow: hidden;
  438. text-overflow: ellipsis;
  439. white-space: nowrap;
  440. }
  441. </style>