BookingTime.vue 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. <script setup lang='ts'>
  2. import { sceneBookingApi } from '@/api/api/sceneBooking';
  3. import router from '@/router';
  4. import { useStore } from '@/stores';
  5. import { showToast } from 'vant';
  6. const dateArray = ref([] as any)
  7. const store = useStore()
  8. const getFutureDates = (numDays: number) => {
  9. const datesArray = [];
  10. const today = new Date();
  11. const dateFormat = 'yyyy-MM-dd 星期X'; // 新增星期格式
  12. for (let i = 0; i <= numDays; i++) {
  13. const futureDate = new Date(today.getTime());
  14. futureDate.setDate(today.getDate() + i);
  15. const formattedDate = formatDate(futureDate, dateFormat);
  16. datesArray.push({
  17. date: formattedDate,
  18. isDisabled: false
  19. });
  20. }
  21. return datesArray;
  22. }
  23. const formatDate = (date: any, format: any) => {
  24. const year = date.getFullYear();
  25. const month = String(date.getMonth() + 1).padStart(2, '0');
  26. const day = String(date.getDate()).padStart(2, '0');
  27. const weekDay = getWeekDay(date);
  28. return format.replace('yyyy', year)
  29. .replace('MM', month)
  30. .replace('dd', day)
  31. .replace('X', weekDay);
  32. }
  33. const getWeekDay = (date: any) => {
  34. const daysOfWeek = ['日', '一', '二', '三', '四', '五', '六'];
  35. return daysOfWeek[date.getDay()];
  36. }
  37. const selectDate = ref('' as string)
  38. const selectTime = ref('' as string)
  39. const bookingTimeList = ref([] as any)
  40. const disableTimeList = ref([] as any)
  41. const noticeText = ref('' as any)
  42. // 获得可预约时间段
  43. const getBookingTime = async () => {
  44. const res: any = await sceneBookingApi.getBookingTimeAPI(selectDate.value.slice(0, 10))
  45. if (res.code == 0) {
  46. bookingTimeList.value = res.data.time
  47. disableTimeList.value = res.data.stopDate
  48. noticeText.value = res.notice
  49. } else {
  50. showToast(res.msg)
  51. }
  52. }
  53. watch(selectDate, () => {
  54. // 获取time
  55. getBookingTime()
  56. })
  57. watch(disableTimeList, () => {
  58. dateArray.value = dateArray.value.map((item: any) => {
  59. return {
  60. ...item,
  61. isDisabled: disableTimeList.value.includes(item.date.slice(0, 10))
  62. }
  63. })
  64. console.log('发生变化', dateArray.value, disableTimeList.value)
  65. }, { immediate: true })
  66. const selectDateFu = (item: any) => {
  67. if (item.isDisabled) {
  68. showToast('该日期不可预约,请选择其他日期')
  69. } else {
  70. selectDate.value = item.date
  71. selectTime.value = ''
  72. }
  73. }
  74. const selectTimeFu = (item: any) => {
  75. // router.go(0)
  76. if (item.pcs === 0) {
  77. showToast('该时段预约已满,请选择其他时段进行预约')
  78. } else {
  79. selectTime.value = item.time
  80. }
  81. }
  82. const goInpitInfo = async () => {
  83. const res: any = await sceneBookingApi.getBookingTimeAPI(selectDate.value.slice(0, 10))
  84. if (res.code == 0) {
  85. const selectTimeItem = res.data.time.filter((item: any) => {
  86. return item.time === selectTime.value
  87. })
  88. if (selectTimeItem.length > 0 && selectTimeItem[0].pcs > 0) {
  89. store.selectDate = selectDate.value
  90. store.selectTime = selectTime.value
  91. router.push({ name: 'bookInputInfo'});
  92. // router.push({
  93. // name: 'bookInputInfo'
  94. // })
  95. } else {
  96. router.go(0)
  97. }
  98. } else {
  99. showToast(res.msg)
  100. }
  101. }
  102. onBeforeMount(() => {
  103. dateArray.value = getFutureDates(13)
  104. console.log(store.selectDate)
  105. if (store.selectDate != '' && store.selectTime != '') {
  106. selectDate.value = store.selectDate
  107. selectTime.value = store.selectTime
  108. } else {
  109. selectDate.value = dateArray.value[0].date
  110. }
  111. })
  112. </script>
  113. <template>
  114. <div class='time-box'>
  115. <div class="date-select-box">
  116. <div class="date-select-item" v-for="(item, index) in dateArray" :key="index"
  117. :class="{ active: item.date === selectDate, disAble: item.isDisabled }" @click="selectDateFu(item)">
  118. {{
  119. item.date.slice(5) }}</div>
  120. </div>
  121. <div class="time-select-box">
  122. <div class="time-select-item" v-for="(item, index) in bookingTimeList" :key="index"
  123. :class="{ active: item.time === selectTime }" :style="{ color: item.pcs == 0 ? '#9D4F0B' : '' }"
  124. @click="() => { selectTimeFu(item) }">
  125. <div>{{ item.time }}</div>
  126. <div>{{ item.pcs == 0 ? `预约已满` : `剩余${item.pcs}` }}</div>
  127. </div>
  128. </div>
  129. </div>
  130. <div class="online-box" v-if="selectDate != '' && selectTime != ''" @click="goInpitInfo()">发起预约</div>
  131. </template>
  132. <style lang='less' scoped>
  133. .time-box {
  134. width: 100%;
  135. height: 100%;
  136. position: absolute;
  137. z-index: 2;
  138. top: 0px;
  139. left: 0px;
  140. display: flex;
  141. justify-content: start;
  142. align-items: center;
  143. background: #F1E9D4;
  144. margin: 0;
  145. box-sizing: border-box;
  146. font-family: 'SourceHanSansCN-Regular';
  147. .date-select-box {
  148. width: 35%;
  149. height: 100%;
  150. overflow: auto;
  151. .date-select-item {
  152. width: 100%;
  153. height: 80px;
  154. display: flex;
  155. justify-content: center;
  156. align-items: center;
  157. color: #88866F;
  158. margin-bottom: 3px;
  159. background: #F7F3E8;
  160. }
  161. .active {
  162. background: #E4DCC5;
  163. color: #333333;
  164. }
  165. .disAble {
  166. background: #E4DCC5;
  167. color: rgba(51, 51, 51, 0.2);
  168. }
  169. }
  170. .time-select-box {
  171. width: 65%;
  172. height: 100%;
  173. overflow: auto;
  174. padding: 15px;
  175. box-sizing: border-box;
  176. .time-select-item {
  177. width: 100%;
  178. height: 50px;
  179. background: #F7F3E8;
  180. border-radius: 5px;
  181. color: #88866F;
  182. display: flex;
  183. justify-content: space-between;
  184. align-items: center;
  185. padding: 10px 15px;
  186. box-sizing: border-box;
  187. margin-bottom: 20px;
  188. }
  189. .active {
  190. background: #E4DCC5;
  191. color: #333333;
  192. }
  193. }
  194. }
  195. .online-box {
  196. width: 80%;
  197. height: 60px;
  198. border-radius: 50px;
  199. background: url(@/assets/images/onlineBg.png);
  200. background-size: 100% 100%;
  201. color: #F1E9D4;
  202. position: fixed;
  203. left: 50%;
  204. transform: translateX(-50%);
  205. bottom: 3vh;
  206. display: flex;
  207. justify-content: center;
  208. align-items: center;
  209. letter-spacing: 2px;
  210. font-weight: bold;
  211. z-index: 2;
  212. }
  213. </style>