time-select.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705
  1. <template>
  2. <view>
  3. <view class="popup-wrapper popup-wrapper-special">
  4. <!-- 标题 -->
  5. <view class="popup-title popup-title-special popup-title-new">
  6. <view>请选择服务开始时间</view>
  7. <view v-if="selectTimeValue >= 17" class="fee-tips">您选的时间段可能会加收夜间服务费,具体以与商家的沟通为准</view>
  8. <!-- 选择服务者上门时段(具体服务时长以实际服务为准) -->
  9. </view>
  10. <block>
  11. <view class="popup-content popup-content-special">
  12. <view class="time-select-top" style="display: flex;">
  13. <scroll-view class="scroll-view_H" scroll-x="true" scroll-left="0">
  14. <view class="time-select-left-item" @tap="dateCheck" :data-index="index"
  15. :data-week="item.week" :data-date="item.date" :data-isbook="item.isBook"
  16. v-for="(item, index) in dateList" :key="index" style="display: inline-block;">
  17. <view class="date-line-wrapper">
  18. <view :class="[
  19. 'date-msg',
  20. dateIndex == index ? 'current-date' : '',
  21. item.dateMsg != '' ? 'avail-date' : ''
  22. ]">
  23. {{item.weekOfDay}}
  24. </view>
  25. <view :class="[
  26. 'date-msg1',
  27. dateIndex == index ? 'current-date' : '',
  28. item.dateMsg != '' ? 'avail-date' : ''
  29. ]"> {{ item.bookdate | formatDate }}</view>
  30. <view :class="[
  31. dateIndex == index ? 'current-line' : '',
  32. item.dateMsg != '' ? 'current-line0' : ''
  33. ]"></view>
  34. </view>
  35. </view>
  36. </scroll-view>
  37. </view>
  38. <view class="time-select-middle">
  39. <view class="noon-select">
  40. <view :class="'noon-item' + (noonType == '1' ? 'active-noon' : '')" data-noon="1"
  41. @tap="noonTab">上午</view>
  42. <view class="divider"></view>
  43. <view :class="'noon-item' + (noonType == '2' ? 'active-noon' : '')" data-noon="2"
  44. @tap="noonTab">下午</view>
  45. </view>
  46. <view class="time-item-wrapper">
  47. <view @tap="timeCheck" :data-stock="item.stock" :data-index="index" :data-msg="item.timeMsg"
  48. :data-toastmsg="item.toastMsg" :class="[
  49. 'time-msg',
  50. timeIndex == index ? 'current-time' : '',
  51. item.toastMsg != null ? 'avail-time' : ''
  52. ]" v-for="(item, index) in timeList" :key="index">
  53. <view :class="timeIndex === index ? 'current-time' : ''">{{ item.begin }}</view>
  54. </view>
  55. </view>
  56. <view class="appointment-tips">
  57. <view> <span></span>
  58. <text>可预约</text>
  59. </view>
  60. <view> <span class="selected"></span>
  61. <text>已选择</text>
  62. </view>
  63. <view> <span class="no-appointment"></span>
  64. <text>不可约</text>
  65. </view>
  66. </view>
  67. <view class="time-select-bottom" v-if="date!==''&week!==''&time!==''">
  68. <span>当前选择:</span>{{date}}({{week}}){{time}}
  69. </view>
  70. </view>
  71. </view>
  72. </block>
  73. <!-- 确认按钮 -->
  74. <view class="popup-btn-wrapper">
  75. <view @tap="confirmTime" class="confirm-btn">确定</view>
  76. </view>
  77. </view>
  78. <!-- 不可预约提示弹框 -->
  79. <van-overlay :show="showNoappointment" z-index=99999 @tap="onClickHide">
  80. <view class="overlay-wrapper">
  81. <view class="fail-wrapper" style="height: 900rpx;">
  82. <image src="https://mall.zhaijieshi.cc/file/wx-huawang/bj3.png" class="bgimg"></image>
  83. <image src="https://mall.zhaijieshi.cc/file/wx-huawang/cc.png" class="ccimg"></image>
  84. <view class="fail-top">
  85. <view class="fail-text">暂不可约</view>
  86. <view class="sub-color">服务可约时间遇到困难</view>
  87. </view>
  88. <view class="er-code">
  89. <view class="image">
  90. <image src="https://mall.zhaijieshi.cc/file/wx-huawang/er-code.png"
  91. :show-menu-by-longpress="true" @tap="previewImage"></image>
  92. </view>
  93. <view class="addwx ">
  94. 长按识别添加
  95. </view>
  96. <view class="addwx">
  97. 您的专属花王管家
  98. <image src="https://mall.zhaijieshi.cc/file/wx-huawang/tipcontent.png" class="tipcontent">
  99. </image>
  100. </view>
  101. </view>
  102. <view class="fail-bottom">
  103. <view class="btn" @tap="onClickHide">
  104. 我知道了
  105. </view>
  106. </view>
  107. </view>
  108. </view>
  109. </van-overlay>
  110. </view>
  111. </template>
  112. <script>
  113. import {
  114. setData
  115. } from '../uni_modules/zp-mixins/methods/setData';
  116. var util = require('@/utils/util.js');
  117. var api = require('@/config/api.js');
  118. var check = require('@/utils/check.js');
  119. export default {
  120. name: "time-select",
  121. props: {
  122. timeParams: Object
  123. },
  124. created() {
  125. console.log("传过来的参数", this.timeParams);
  126. let addressId = this.timeParams.addressId;
  127. if (!addressId || addressId === 'null' || addressId === 'undefined') {
  128. delete this.timeParams.addressId
  129. }
  130. this.getDayTime(this.timeParams)
  131. },
  132. onShow() {
  133. },
  134. filters: {
  135. formatDate: function(value, format) {
  136. // 这里可以根据format来格式化日期
  137. if (value) {
  138. return value.substring(0, 10).split('-').slice(1).join('-');
  139. }
  140. }
  141. },
  142. data() {
  143. return {
  144. noonType: 1,
  145. selectTimeValue: '',
  146. timeList: [],
  147. dateList: [],
  148. timeIndex: '',
  149. //选中的时间段
  150. dateIndex: 0,
  151. //选中的日期
  152. appointDate: '',
  153. futureDays: '',
  154. time: '',
  155. week: '',
  156. date: '',
  157. showNoappointment: false,
  158. toastMsg: ''
  159. };
  160. },
  161. methods: {
  162. getDayTime(params) {
  163. uni.showLoading({
  164. title: '加载中'
  165. });
  166. util.request(api.everyDayTime, params, 'GET')
  167. .then((res) => {
  168. uni.hideLoading();
  169. if (res.errno == 0) {
  170. console.log("时间", res.data);
  171. this.setData({
  172. dateList: res.data,
  173. dateIndex: 0,
  174. timeIndex: -1,
  175. noonType: 1
  176. });
  177. let period = res.data[0].period;
  178. let list = period.filter((item) => {
  179. return item.ofTime == '上午';
  180. });
  181. this.setData({
  182. timeList: list
  183. });
  184. } else {
  185. uni.showToast({
  186. title: res.errmsg,
  187. icon: 'none',
  188. duration: 2000
  189. });
  190. this.setData({
  191. timeList: [],
  192. timeIndex: ''
  193. });
  194. }
  195. })
  196. .catch((err) => {
  197. console.log(err);
  198. uni.hideLoading();
  199. uni.showToast({
  200. title: err.errMsg,
  201. icon: 'none'
  202. });
  203. this.setData({
  204. timeList: [],
  205. timeIndex: ''
  206. });
  207. });
  208. },
  209. noonTab(e) {
  210. let noon = e.currentTarget.dataset.noon;
  211. console.log("noon", noon);
  212. this.setData({
  213. timeIndex: -1,
  214. noonType: noon,
  215. selectTimeValue: ''
  216. });
  217. console.log("noon1", noon);
  218. let period = this.dateList[this.dateIndex].period;
  219. let current = this.noonType == 1 ? '上午' : '下午';
  220. let list = period.filter((item) => {
  221. return item.ofTime == current;
  222. });
  223. this.setData({
  224. timeList: list
  225. });
  226. },
  227. dateCheck(e) {
  228. let index = e.currentTarget.dataset.index;
  229. let date = e.currentTarget.dataset.date;
  230. let week = e.currentTarget.dataset.week;
  231. let isbook = e.currentTarget.dataset.isbook;
  232. this.setData({
  233. dateIndex: index
  234. });
  235. let period = this.dateList[this.dateIndex].period;
  236. let current = this.noonType == 1 ? '上午' : '下午';
  237. let list = period.filter((item) => {
  238. return item.ofTime == current;
  239. });
  240. let bookdate = this.dateList[this.dateIndex].bookdate
  241. let weekOfDay = this.dateList[this.dateIndex].weekOfDay
  242. this.setData({
  243. timeList: list,
  244. date: bookdate,
  245. week: weekOfDay
  246. });
  247. let isNoTime = list.every((item) => {
  248. return item.timeMsg && item.timeMsg != null;
  249. });
  250. if (isNoTime) {
  251. this.setData({
  252. timeIndex: -1,
  253. selectTimeValue: ''
  254. });
  255. }
  256. },
  257. timeCheck(e) {
  258. console.log(e.currentTarget);
  259. let index = e.currentTarget.dataset.index;
  260. let msg = e.currentTarget.dataset.msg;
  261. let toastMsg = e.currentTarget.dataset.toastmsg;
  262. if (toastMsg == null || toastMsg == '') {
  263. let time = this.timeList[index].begin.split(':')[0];
  264. let bookTime = this.timeList[index].begin + '-' + this.timeList[index].end
  265. this.setData({
  266. timeIndex: index,
  267. selectTimeValue: Number(time),
  268. time: bookTime
  269. });
  270. } else {
  271. this.setData({
  272. toastMsg: toastMsg,
  273. showNoappointment: true
  274. })
  275. }
  276. },
  277. confirmTime() {
  278. if (this.timeIndex === '' || this.timeIndex < 0) {
  279. util.showErrorToast('请选择服务时间');
  280. return false;
  281. }
  282. let date = this.dateList[this.dateIndex].bookdate;
  283. let week = this.dateList[this.dateIndex].weekOfDay;
  284. let time = this.timeList[this.timeIndex].begin + '-' + this.timeList[this.timeIndex].end;
  285. let futureDays = (((new Date(date)).getTime() - (new Date()).getTime()) / (1000 * 24 * 3600));
  286. futureDays = Math.ceil(futureDays);
  287. this.setData({
  288. choosePopup: false,
  289. appointDate: date + ' ' + week + ' ' + time,
  290. futureDays: futureDays,
  291. });
  292. this.$emit('timeShow', {
  293. appointDate: this.appointDate,
  294. futureDays: this.futureDays,
  295. Time: {
  296. date,
  297. week,
  298. time
  299. }
  300. });
  301. },
  302. onClickHide() {
  303. this.setData({
  304. showNoappointment: false
  305. })
  306. },
  307. previewImage(e) {
  308. uni.previewImage({
  309. // 需要预览的图片链接列表
  310. urls: [],
  311. // 为当前显示图片的链接/索引值
  312. current: 'https://mall.zhaijieshi.cc/file/wx-huawang/er-code.png',
  313. // 图片指示器样式
  314. indicator: 'default',
  315. // 是否可循环预览
  316. loop: false,
  317. // 长按图片显示操作菜单,如不填默认为保存相册
  318. // longPressActions:{
  319. // itemList:[this.l('发送给朋友'),this.l]
  320. // },
  321. success: res => {
  322. console.log('res', res);
  323. },
  324. fail: err => {
  325. console.log('err', err);
  326. }
  327. })
  328. }
  329. },
  330. }
  331. </script>
  332. <style>
  333. .popup-wrapper view {
  334. color: #888;
  335. font-size: 30rpx;
  336. }
  337. .popup-content {
  338. flex: 1;
  339. }
  340. .appointment-tips {
  341. display: flex;
  342. justify-content: space-between;
  343. width: 178px;
  344. position: absolute;
  345. bottom: 72rpx;
  346. left: calc(50% - 89px);
  347. }
  348. .appointment-tips view span {
  349. width: 20rpx;
  350. height: 20rpx;
  351. border-radius: 20rpx;
  352. background-color: #feebd7;
  353. display: inline-block;
  354. margin-right: 10rpx;
  355. }
  356. .appointment-tips view .selected {
  357. background-color: #d77958;
  358. }
  359. .appointment-tips view .no-appointment {
  360. background-color: #ccc;
  361. }
  362. .appointment-tips view text {
  363. color: #d77958;
  364. font-size: 24rpx;
  365. }
  366. .time-select-bottom {
  367. width: 100vw;
  368. background-color: #feebd7;
  369. height: 54rpx;
  370. font-size: 22rpx !important;
  371. line-height: 54rpx;
  372. padding-left: 30rpx;
  373. position: absolute;
  374. bottom: 0;
  375. }
  376. .time-select-left {
  377. border-right: 1rpx solid #ddd;
  378. padding: 0 8rpx 0 20rpx;
  379. width: 370rpx;
  380. }
  381. .time-select-right {
  382. flex: 1;
  383. height: 900rpx;
  384. overflow-y: hidden;
  385. }
  386. .scroll-view_H {
  387. white-space: nowrap;
  388. overflow-x: scroll;
  389. }
  390. .time-select-left-item {
  391. height: 108rpx;
  392. display: flex;
  393. flex-direction: column;
  394. padding: 4rpx 0;
  395. width: 20vw;
  396. }
  397. .date-line-wrapper {
  398. display: flex;
  399. flex-direction: column;
  400. align-items: center;
  401. }
  402. .time-select-left-item .date-msg {
  403. height: 36rpx;
  404. line-height: 36rpx;
  405. color: #292929;
  406. font-size: 36rpx;
  407. font-weight: bold;
  408. }
  409. .time-select-left-item .date-msg1 {
  410. height: 36rpx;
  411. line-height: 36rpx;
  412. color: #292929;
  413. font-size: 22rpx;
  414. margin-top: 10rpx;
  415. }
  416. .time-select-left-item .date-msg.avail-date {
  417. color: #999 !important;
  418. font-weight: bold;
  419. }
  420. .time-select-left-item .date-msg1.avail-date {
  421. color: #999 !important;
  422. font-weight: bold;
  423. }
  424. .popup-wrapper .popup-content .current-date {
  425. color: #d77958;
  426. font-weight: bold;
  427. }
  428. view.popup-btn-wrapper {
  429. margin: 10rpx auto;
  430. padding: 24rpx;
  431. background-color: #d77958;
  432. text-align: center;
  433. width: 682rpx;
  434. border-radius: 16rpx;
  435. }
  436. view.popup-btn-wrapper view {
  437. color: #fff;
  438. }
  439. .time-select-middle {
  440. background-color: #FCFCFC;
  441. padding: 10rpx 0rpx;
  442. height: 800rpx;
  443. position: relative;
  444. }
  445. .noon-select {
  446. width: 100%;
  447. display: flex;
  448. justify-content: center;
  449. margin: 30rpx auto;
  450. }
  451. .noon-select .divider {
  452. height: 40rpx;
  453. width: 2rpx;
  454. background-color: #e5e5e5;
  455. }
  456. .noon-select .noon-item {
  457. text-align: center;
  458. color: #979797;
  459. font-size: 36rpx;
  460. width: 49%;
  461. }
  462. .noon-itemactive-noon {
  463. text-align: center;
  464. color: #d77958 !important;
  465. font-size: 36rpx !important;
  466. width: 49%;
  467. }
  468. .popup-title-new.popup-title {
  469. display: flex;
  470. flex-direction: column;
  471. font-size: 20px;
  472. font-weight: bold;
  473. text-align: left;
  474. padding: 30rpx;
  475. }
  476. .popup-title-new view {
  477. color: #000;
  478. font-size: 40rpx;
  479. font-weight: bold;
  480. }
  481. .popup-title-new view.fee-tips {
  482. color: #d77958;
  483. font-size: 22rpx;
  484. }
  485. .current-line {
  486. width: 38rpx;
  487. height: 6rpx;
  488. background: #d77958;
  489. border-radius: 3rpx;
  490. margin: auto;
  491. opacity: 1;
  492. }
  493. .current-line0 {
  494. width: 38rpx;
  495. height: 6rpx;
  496. background: #d77958;
  497. border-radius: 3rpx;
  498. margin: auto;
  499. opacity: 0 !important;
  500. }
  501. .current-time {
  502. color: #fff !important;
  503. font-family: AlibabaPuHuiTi_2_65_Medium;
  504. line-height: 70rpx;
  505. height: 70rpx;
  506. background-color: #d77958;
  507. border-radius: 8px;
  508. font-size: 36rpx;
  509. }
  510. .time-item-wrapper {
  511. display: flex;
  512. width: 90vw;
  513. justify-content: flex-start;
  514. flex-wrap: wrap;
  515. text-align: center;
  516. gap: 20px;
  517. margin: 10px auto;
  518. }
  519. .time-item-wrapper .time-msg {
  520. width: 20%;
  521. line-height: 70rpx;
  522. height: 70rpx;
  523. background-color: #feebd7;
  524. border-radius: 8px;
  525. font-size: 36rpx;
  526. font-weight: bold;
  527. }
  528. .time-item-wrapper .avail-time {
  529. width: 20%;
  530. line-height: 70rpx;
  531. height: 70rpx;
  532. background-color: #CCCCCC;
  533. border-radius: 8px;
  534. font-size: 36rpx;
  535. font-weight: bold;
  536. }
  537. /* 不可预约弹框 */
  538. .overlay-wrapper {
  539. display: flex;
  540. align-items: center;
  541. justify-content: center;
  542. height: 100%;
  543. }
  544. .fail-wrapper {
  545. width: 652rpx;
  546. height: 580rpx;
  547. border-radius: 22rpx;
  548. background-color: #fff;
  549. background-size: 100% 40%;
  550. position: relative;
  551. font-size: 24rpx;
  552. display: flex;
  553. flex-direction: column;
  554. justify-content: space-between;
  555. }
  556. .fail-wrapper .bgimg {
  557. width: 100%;
  558. height: 260rpx;
  559. display: block;
  560. }
  561. .fail-wrapper .ccimg {
  562. position: absolute;
  563. top: 50rpx;
  564. left: 248rpx;
  565. width: 161rpx;
  566. height: 161rpx;
  567. }
  568. .fail-top {
  569. display: flex;
  570. flex-direction: column;
  571. align-items: center;
  572. }
  573. .er-code {
  574. width: 240rpx;
  575. height: 280rpx;
  576. margin: 20rpx auto;
  577. }
  578. .er-code .image {
  579. width: 220rpx;
  580. height: 220rpx;
  581. margin: auto;
  582. }
  583. .er-code .image image {
  584. width: 100%;
  585. height: 100%;
  586. }
  587. .er-code .addwx {
  588. width: 240rpx;
  589. color: #c2c2c2;
  590. margin: 14rpx auto;
  591. height: 30rpx;
  592. line-height: 30rpx;
  593. font-size: 28rpx;
  594. text-align: center;
  595. }
  596. .er-code .addwx .tipcontent {
  597. width: 96rpx;
  598. height: 32rpx;
  599. position: absolute;
  600. top: 700rpx;
  601. }
  602. .fail-text {
  603. font-size: 34rpx;
  604. font-weight: bold;
  605. margin: 4rpx 0 40rpx;
  606. height: 34rpx;
  607. }
  608. .fail-bottom {
  609. height: 132rpx;
  610. display: flex;
  611. justify-content: space-around;
  612. align-items: center;
  613. }
  614. .fail-bottom .btn {
  615. border: #C2C2C2 2rpx solid;
  616. border-radius: 48rpx;
  617. color: #C2C2C2;
  618. width: 240rpx;
  619. height: 80rpx;
  620. text-align: center;
  621. font-size: 28rpx;
  622. line-height: 80rpx;
  623. }
  624. </style>