appointment.ts 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. import PageContainerBehavior from "../../../../core/behavior/page-container.behavior";
  2. import DictionariesBehavior from "../../../../core/behavior/dictionaries.behavior";
  3. import tickleBehavior from "../../../../core/behavior/tickle.behavior";
  4. import { patientOfflineTreatmentAppointmentMethod } from "../../request";
  5. // module/order/pages/appointment/appointment.ts
  6. Page({
  7. behaviors: [PageContainerBehavior, DictionariesBehavior, tickleBehavior],
  8. data: {
  9. goodsInfo: { appointmentTime: '' },
  10. dateList: [] as Array<{
  11. label: string;
  12. dateStr: string;
  13. date: string;
  14. isSelected: boolean;
  15. }>,
  16. timeSlots: [] as Array<{
  17. time: string;
  18. isSelected: boolean;
  19. isDisabled: boolean;
  20. }>,
  21. selectedDate: "",
  22. selectedTime: "",
  23. show: false,
  24. date: '',
  25. offlineId: "",
  26. },
  27. onLoad(options: any) {
  28. // 初始化日期列表(从今天开始5天)
  29. this.initDateList();
  30. if (options.goodsInfo) {
  31. const goodsInfo = JSON.parse(options.goodsInfo);
  32. this.setData({
  33. goodsInfo: goodsInfo,
  34. offlineId: goodsInfo.offlineId,
  35. });
  36. }
  37. },
  38. // 初始化日期列表
  39. initDateList(startDate?: Date) {
  40. const dateList: Array<{
  41. label: string;
  42. dateStr: string;
  43. date: string;
  44. isSelected: boolean;
  45. }> = [];
  46. const baseDate = startDate || new Date();
  47. // 设置时间为0点,避免时区问题
  48. baseDate.setHours(0, 0, 0, 0);
  49. const today = new Date();
  50. today.setHours(0, 0, 0, 0);
  51. const weekDays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
  52. for (let i = 0; i < 5; i++) {
  53. const date = new Date(baseDate);
  54. date.setDate(baseDate.getDate() + i);
  55. const month = date.getMonth() + 1;
  56. const day = date.getDate();
  57. const weekDay = weekDays[date.getDay()];
  58. // 判断相对今天的位置
  59. const diffDays = Math.floor((date.getTime() - today.getTime()) / (1000 * 60 * 60 * 24));
  60. let label = '';
  61. if (diffDays === 0) {
  62. label = '今天';
  63. } else if (diffDays === 1) {
  64. label = '明天';
  65. } else {
  66. label = weekDay;
  67. }
  68. const dateStr = `${month}月${day}日`;
  69. const dateValue = `${date.getFullYear()}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`;
  70. dateList.push({
  71. label,
  72. dateStr,
  73. date: dateValue,
  74. isSelected: i === 0, // 默认选中第一个
  75. });
  76. }
  77. this.setData({
  78. dateList,
  79. selectedDate: dateList[0].date, // 默认选中第一个日期
  80. });
  81. // 初始化时间列表,传入默认选中的日期
  82. this.initTimeSlots(dateList[0].date);
  83. },
  84. // 初始化时间列表 - 固定8:00-20:00
  85. initTimeSlots(selectedDate?: string) {
  86. const timeSlots: Array<{
  87. time: string;
  88. isSelected: boolean;
  89. isDisabled: boolean;
  90. }> = [];
  91. const now = new Date();
  92. const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
  93. const selectedDateObj = selectedDate ? new Date(selectedDate) : today;
  94. const selectedDateOnly = new Date(selectedDateObj.getFullYear(), selectedDateObj.getMonth(), selectedDateObj.getDate());
  95. // 判断选中的日期是否是今天
  96. const isToday = selectedDateOnly.getTime() === today.getTime();
  97. const currentHour = now.getHours();
  98. const currentMinute = now.getMinutes();
  99. // 从08:00到20:00,每30分钟一个时间段
  100. for (let hour = 8; hour <= 20; hour++) {
  101. for (let minute = 0; minute < 60; minute += 30) {
  102. if (timeSlots.length >= 25) break; // 限制为25个时间段
  103. const timeStr = `${String(hour).padStart(2, '0')}:${String(minute).padStart(2, '0')}`;
  104. // 如果是今天,需要判断时间是否已过去
  105. let isDisabled = false;
  106. if (isToday) {
  107. // 如果时间已过去,禁用
  108. if (hour < currentHour || (hour === currentHour && minute <= currentMinute)) {
  109. isDisabled = true;
  110. }
  111. }
  112. timeSlots.push({
  113. time: timeStr,
  114. isSelected: false,
  115. isDisabled,
  116. });
  117. }
  118. }
  119. this.setData({ timeSlots });
  120. },
  121. // 选择日期
  122. onDateSelect(e: any) {
  123. const index = e.currentTarget.dataset.index;
  124. const dateList = this.data.dateList.map((item, i) => ({
  125. ...item,
  126. isSelected: i === index,
  127. }));
  128. const selectedDate = dateList[index].date;
  129. // 重新初始化时间列表,根据选中的日期禁用已过去的时间
  130. this.initTimeSlots(selectedDate);
  131. this.setData({
  132. dateList,
  133. selectedDate,
  134. // 切换日期时清空已选时间
  135. selectedTime: "",
  136. });
  137. },
  138. // 选择时间
  139. onTimeSelect(e: any) {
  140. const index = e.currentTarget.dataset.index;
  141. const time = e.currentTarget.dataset.time;
  142. const timeSlot = this.data.timeSlots[index];
  143. // 如果时间段被禁用,不处理
  144. if (timeSlot && timeSlot.isDisabled) {
  145. return;
  146. }
  147. // 每次只能选择一个时间段,点击新的会取消之前的选择
  148. const timeSlots = this.data.timeSlots.map((item, i) => ({
  149. ...item,
  150. isSelected: i === index, // 只有当前点击的为选中状态
  151. }));
  152. this.setData({
  153. timeSlots,
  154. selectedTime: time,
  155. });
  156. },
  157. // 提交预约
  158. async onSubmit() {
  159. if (!this.data.selectedDate) {
  160. wx.showToast({
  161. title: "请选择日期",
  162. icon: "none",
  163. });
  164. return;
  165. }
  166. if (!this.data.selectedTime) {
  167. wx.showToast({
  168. title: "请选择时间",
  169. icon: "none",
  170. });
  171. return;
  172. }
  173. console.log(this.data.selectedDate, "this.data.selectedDate", this.data.selectedTime, "this.data.selectedTime", this.data.offlineId, "this.data.offlineId")
  174. const appointmentTime = `${this.data.selectedDate} ${this.data.selectedTime}`;
  175. console.log(appointmentTime, "appointmentTime");
  176. console.log(this.data.offlineId, "this.data.offlineId");
  177. this.setData({
  178. goodsInfo: {
  179. ...this.data.goodsInfo,
  180. appointmentTime: `${this.data.selectedDate} ${this.data.selectedTime}`,
  181. },
  182. });
  183. try {
  184. await patientOfflineTreatmentAppointmentMethod(this.data.offlineId, appointmentTime);
  185. wx.showToast({
  186. title: '预约成功',
  187. icon: 'success',
  188. });
  189. setTimeout(() => {
  190. wx.redirectTo({
  191. url: `/module/order/pages/appointment-success/appointment-success?goodsInfo=${JSON.stringify(this.data.goodsInfo)}`,
  192. });
  193. }, 1000);
  194. } catch (error: any) {
  195. wx.showToast({
  196. title: error.errMsg || "预约失败",
  197. icon: "none",
  198. });
  199. console.log(error, "error")
  200. }
  201. },
  202. // 打开日历弹窗
  203. onOpenCalendar() {
  204. console.log('onOpenCalendar');
  205. this.setData({ show: true });
  206. },
  207. // 关闭日历弹窗
  208. onClose() {
  209. this.setData({ show: false });
  210. },
  211. // 格式化日期
  212. formatDate(date: any) {
  213. date = new Date(date);
  214. return `${date.getMonth() + 1}/${date.getDate()}`;
  215. },
  216. // 确认选择日期
  217. onConfirm(event: any) {
  218. const selectedDate = event.detail;
  219. console.log('选择的日期:', selectedDate);
  220. if (selectedDate) {
  221. // 解析日期
  222. const dateObj = new Date(selectedDate);
  223. dateObj.setHours(0, 0, 0, 0);
  224. // 格式化日期字符串用于比较
  225. const dateValue = `${dateObj.getFullYear()}-${String(dateObj.getMonth() + 1).padStart(2, '0')}-${String(dateObj.getDate()).padStart(2, '0')}`;
  226. // 检查选择的日期是否在当前展示的5天中
  227. const existingDateIndex = this.data.dateList.findIndex(item => item.date === dateValue);
  228. if (existingDateIndex !== -1) {
  229. // 如果选择的日期在已展示的5天中,只更新选中状态
  230. const dateList = this.data.dateList.map((item, index) => ({
  231. ...item,
  232. isSelected: index === existingDateIndex,
  233. }));
  234. // 重新初始化时间列表,根据选中的日期禁用已过去的时间
  235. this.initTimeSlots(dateValue);
  236. // 清空已选时间
  237. this.setData({
  238. show: false,
  239. dateList,
  240. selectedDate: dateValue,
  241. date: this.formatDate(selectedDate),
  242. selectedTime: "",
  243. });
  244. } else {
  245. // 如果选择的日期不在已展示的5天中,重新生成日期列表
  246. this.initDateList(dateObj);
  247. // 重新初始化时间列表,根据选中的日期禁用已过去的时间
  248. this.initTimeSlots(dateValue);
  249. // 清空已选时间
  250. this.setData({
  251. show: false,
  252. date: this.formatDate(selectedDate),
  253. selectedTime: "",
  254. });
  255. }
  256. } else {
  257. this.setData({ show: false });
  258. }
  259. },
  260. });