appointment.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  1. <template>
  2. <view class="app-container">
  3. <u-navbar title="预约" bgColor="#fff" :fixed="true" :autoBack="false" leftIconColor="#333333" leftIconSize="28"
  4. @leftClick="handleLeftClick">
  5. </u-navbar>
  6. <view class="app-container-item flex-column-center">
  7. <view class="top-card">
  8. <view class="title flex-between">
  9. <text style="font-weight: bold;">{{ detailInfo.title }}</text>
  10. <view class="flex">
  11. <text style="font-size: 15px;color: #636B85;margin-right: 5px">选择</text>
  12. <u-icon name="arrow-right" color="#909399" size="30"></u-icon>
  13. </view>
  14. </view>
  15. <text style="font-size: 13px;color: #B2BCCB;height: 30px;line-height: 30px">实名制预约票</text>
  16. <view class="time flex-between">
  17. <text>开园时间:{{ detailInfo.openStartTime }}-{{ detailInfo.openEndTime }}</text>
  18. <view style="color: #27C9DF">
  19. <text style="font-size: 14px;margin-right: 5px">预订须知</text>
  20. <text class="iconfont icon-icon-arrow-right" style="font-size: 10px;color: #27C9DF;"></text>
  21. </view>
  22. </view>
  23. </view>
  24. <view class="time_period-card">
  25. <view class="form_item flex-between">
  26. <view>
  27. <text style="font-size: 15px;margin-right: 10px">免票预约</text>
  28. <text style="color: #27C9DF;font-size: 18px">¥ 0.00</text>
  29. </view>
  30. <view>
  31. <u-number-box v-model="form.num" step="1" :min="0">
  32. <template #minus>
  33. <text class="iconfont icon-reduce" style="font-size: 20px;color: #2EDAF1"></text>
  34. </template>
  35. <template #input>
  36. <text style="width: 50px;text-align: center;" class="input">{{form.num}}</text>
  37. </template>
  38. <template #plus>
  39. <text class="iconfont icon-add" style="font-size: 20px;color: #2EDAF1"></text>
  40. </template>
  41. </u-number-box>
  42. </view>
  43. </view>
  44. <view class="form_item flex-between">
  45. <view>
  46. <text style="font-size: 15px;margin-right: 10px">预约时间</text>
  47. </view>
  48. <view>
  49. <uni-datetime-picker key="startTime" type="date" v-model="form.startTime" :border="false"
  50. :showClear="false" :start="startDate.min" :end="startDate.max"
  51. @change="dateConfirm('startTime', $event)"></uni-datetime-picker>
  52. </view>
  53. </view>
  54. <view>
  55. <view>
  56. <text style="font-size: 15px;margin-right: 10px">预约时间段</text>
  57. </view>
  58. <view class="time_period-content">
  59. <view class="time_period-content_item flex-between"
  60. v-for="(pItem, pIndex) in detailInfo.timePeriod" :style="[{
  61. background: timePeriodCheckIndex !=null && pIndex == timePeriodCheckIndex? '#2EDAF1' : '#F6F8FC'
  62. }]" :key="pIndex" @click="onClickTimePeriod(pItem, pIndex)">
  63. <text
  64. :style="{color: timePeriodCheckIndex !=null && pIndex == timePeriodCheckIndex?'white':getStateColor(pItem.reservationState).timeColor}">{{ pItem.startTime }}~{{ pItem.endTime }}</text>
  65. <text
  66. :style="{color: timePeriodCheckIndex !=null && pIndex == timePeriodCheckIndex?'white':getStateColor(pItem.reservationState).stateColor}">{{ pItem.reservationState | matchStateColor }}</text>
  67. </view>
  68. </view>
  69. </view>
  70. </view>
  71. <view class="time_period-card">
  72. <view class="form_item flex-between">
  73. <view>
  74. <text style="font-size: 15px;margin-right: 10px;color: #333333;font-weight: bold">游玩人</text>
  75. <text style="color: #636B85;font-size: 15px">(需填写{{form.num}}人)</text>
  76. </view>
  77. <view style="background: #2EDAF1;width: 52px;height: 25px;border-radius: 15px" class="flex"
  78. @click="addTourists">
  79. <text class="iconfont icon-plus" style="font-size: 12px;color: #fff"></text>
  80. </view>
  81. </view>
  82. <view class="id-card">
  83. <view class="id-card_item" v-for="(item,index) in touristList" :key="index">
  84. <text>{{ item.username }}</text>
  85. <text>【身份证】{{ item.idNumber }}</text>
  86. </view>
  87. </view>
  88. </view>
  89. <!-- <view style="clear: both; overflow: hidden;"></view>-->
  90. </view>
  91. <view class="app-container-btn flex-between">
  92. <text>合计:</text>
  93. <view>
  94. <u-button v-if="isSubmitEnabled" type="primary" shape="circle" class="btn" text="立即预订"
  95. @tap="toAppoint()"></u-button>
  96. <u-button text="立即预订" class="btn" v-else color="#DDE2EC"></u-button>
  97. </view>
  98. </view>
  99. </view>
  100. </template>
  101. <script>
  102. export default {
  103. components: {},
  104. data() {
  105. return {
  106. form: {
  107. startTime: this.$sun.formatTime(new Date(), '{y}-{m}-{d}'),
  108. num: 0,
  109. endTime: '',
  110. zoneDeviceRId: '22',
  111. zoneDeviceRName: '',
  112. visiteeRoom: '',
  113. },
  114. rules: {
  115. /*'visiteeRoom': [{
  116. required: true,
  117. message: '请输入房间号',
  118. trigger: ['change', 'blur']
  119. }],
  120. 'zoneDeviceRName': [{
  121. required: true,
  122. message: '请输入房间号',
  123. trigger: ['change', 'blur']
  124. }],
  125. 'startTime': [{
  126. required: true,
  127. message: '请选择开始时间',
  128. trigger: ['change', 'blur']
  129. }],
  130. 'endTime': [{
  131. required: true,
  132. message: '请选择结束时间',
  133. trigger: ['change', 'blur']
  134. },
  135. ]*/
  136. },
  137. detailInfo: {
  138. title: '兰花街1、2、3',
  139. date: '2024.06.14',
  140. openStartTime: '08:00',
  141. openEndTime: '20:00',
  142. timePeriod: [{
  143. startTime: '08:00',
  144. endTime: '10:00',
  145. reservationState: 1
  146. },
  147. {
  148. startTime: '10:00',
  149. endTime: '12:00',
  150. reservationState: 2
  151. },
  152. {
  153. startTime: '12:00',
  154. endTime: '14:00',
  155. reservationState: 3
  156. },
  157. {
  158. startTime: '14:00',
  159. endTime: '16:00',
  160. reservationState: 4
  161. },
  162. {
  163. startTime: '16:00',
  164. endTime: '18:00',
  165. reservationState: 5
  166. },
  167. {
  168. startTime: '18:00',
  169. endTime: '20:00',
  170. reservationState: 4
  171. }
  172. ]
  173. },
  174. timePeriodCheckIndex: null,
  175. touristList: [{
  176. id: 1,
  177. username: '刘琳琳', // 姓名
  178. idNumber: '430822********0465', // 身份证号
  179. IDType: '',
  180. }, {
  181. id: 2,
  182. username: '刘琳X', // 姓名
  183. idNumber: '430822********0464', // 身份证号
  184. IDType: '',
  185. }, {
  186. id: 3,
  187. username: '刘琳Y', // 姓名
  188. idNumber: '430822********0463', // 身份证号
  189. IDType: '',
  190. }]
  191. };
  192. },
  193. computed: {
  194. isSubmitEnabled() {
  195. return this.timePeriodCheckIndex != null && (this.form.startTime && this.form.startTime != '');
  196. },
  197. startDate() {
  198. return {
  199. min: this.$sun.formatTime(new Date(), '{y}-{m}-{d}'),
  200. max: this.form.endTime ? this.form.endTime : '2099-1-1 00:00:00'
  201. }
  202. },
  203. endDate() {
  204. return {
  205. min: this.form.startTime ? this.form.startTime : this.$sun.formatTime(new Date(), '{y}-{m}-{d}'),
  206. max: '2099-1-1 00:00:00'
  207. }
  208. },
  209. },
  210. filters: {
  211. matchStateColor(code) {
  212. switch (code) {
  213. case 1:
  214. return '停售';
  215. case 2:
  216. return '普通';
  217. case 3:
  218. return '拥挤';
  219. case 4:
  220. return '空闲';
  221. case 5:
  222. return '繁忙';
  223. }
  224. }
  225. },
  226. onLoad(options) {
  227. this.detailInfo = JSON.parse(options.info);
  228. console.log('onLoad', this.detailInfo)
  229. },
  230. onShow() {},
  231. methods: {
  232. /**
  233. * 添加游玩人
  234. */
  235. addTourists() {
  236. console.log('添加游玩人');
  237. uni.navigateTo({
  238. url: '/pages/tourist/index?touristIdList=' + JSON.stringify(this.touristList.map(v => v.id))
  239. });
  240. },
  241. // 日期选择-确定
  242. async dateConfirm(code, e) {
  243. console.log(code, e, '日期选择-确定')
  244. this.form.startTime = e;
  245. this.timePeriodCheckIndex = null;
  246. },
  247. /**
  248. * 选择预约时间段
  249. * @param item
  250. * @param index
  251. */
  252. onClickTimePeriod(item, index) {
  253. if (item.reservationState != 1) {
  254. this.timePeriodCheckIndex = index;
  255. }
  256. },
  257. /**
  258. * 立即预订
  259. */
  260. toAppoint() {
  261. },
  262. getStateColor(code) {
  263. let param = {};
  264. switch (code) {
  265. case 1:
  266. param = {
  267. timeColor: '#B2BCCB',
  268. stateColor: '#B2BCCB'
  269. };
  270. break;
  271. case 2:
  272. param = {
  273. timeColor: '#636B85',
  274. stateColor: '#65DBF5'
  275. };
  276. break;
  277. case 3:
  278. case 5:
  279. param = {
  280. timeColor: '#636B85',
  281. stateColor: '#FFAF51'
  282. };
  283. break;
  284. case 4:
  285. param = {
  286. timeColor: '#636B85',
  287. stateColor: '#65DBF5'
  288. };
  289. break;
  290. }
  291. return param
  292. },
  293. handleLeftClick() {
  294. //获取页面栈的长度
  295. const canNavBack = getCurrentPages()
  296. //判断是否刷新了浏览器,刷新了浏览器,页面栈只有当前一个
  297. if (canNavBack && canNavBack.length > 1) {
  298. uni.navigateBack({
  299. delta: 1
  300. })
  301. } else {
  302. history.back()
  303. }
  304. },
  305. getGuideInfo() {
  306. // this.isLogin = true;
  307. },
  308. }
  309. };
  310. </script>
  311. <style lang="scss" scoped>
  312. .app-container {
  313. width: 100vw;
  314. //background: #fff;
  315. position: relative;
  316. height: 100vh;
  317. &-item {
  318. position: absolute;
  319. top: 44px;
  320. padding: 10px 20px 100px 20px;
  321. width: calc(100%);
  322. box-sizing: border-box;
  323. .time_period-card {
  324. width: calc(100%);
  325. box-sizing: border-box;
  326. margin-top: 10px;
  327. background: #fff;
  328. border-radius: 8px;
  329. position: relative;
  330. display: flex;
  331. flex-direction: column;
  332. padding: 10px;
  333. .id-card {
  334. //height: 50px;
  335. box-sizing: border-box;
  336. padding: 10px;
  337. &_item {
  338. display: flex;
  339. flex-direction: column;
  340. padding: 10px 20px;
  341. font-size: 14px;
  342. color: #333333;
  343. background: #F8FAFD;
  344. border-radius: 8px;
  345. text {
  346. height: 26px;
  347. line-height: 26px;
  348. }
  349. &:not(:last-child) {
  350. margin-bottom: 10px;
  351. }
  352. }
  353. }
  354. .form_item {
  355. height: 48px;
  356. line-height: 48px;
  357. }
  358. .time_period-content {
  359. width: 100%;
  360. box-sizing: border-box;
  361. display: flex;
  362. flex-direction: row;
  363. flex-wrap: wrap;
  364. background: #fff;
  365. padding: 10px 0;
  366. border-radius: 8px;
  367. overflow: hidden;
  368. &_item {
  369. background: #F6F8FC;
  370. box-sizing: border-box;
  371. width: calc((100% - 16px) / 3);
  372. height: 50px;
  373. border-radius: 6px;
  374. padding: 6px;
  375. flex-direction: column;
  376. text {
  377. height: 20px;
  378. line-height: 20px;
  379. font-size: 13px;
  380. color: #636B85;
  381. }
  382. &:nth-child(n + 4) {
  383. margin-top: 8px;
  384. }
  385. &:not(:nth-child(3n)) {
  386. margin-right: 8px;
  387. }
  388. }
  389. }
  390. }
  391. .top-card {
  392. width: calc(100%);
  393. box-sizing: border-box;
  394. margin-top: 10px;
  395. background: #fff;
  396. border-radius: 8px;
  397. position: relative;
  398. display: flex;
  399. flex-direction: column;
  400. padding: 20px 10px;
  401. box-sizing: border-box;
  402. .title {
  403. width: 100%;
  404. font-size: 20px;
  405. color: #1D2633;
  406. }
  407. .time {
  408. color: #1D2633;
  409. font-size: 15px;
  410. }
  411. }
  412. }
  413. &-btn {
  414. position: fixed;
  415. bottom: 0;
  416. height: 80px;
  417. text-align: center;
  418. background: white;
  419. width: 100%;
  420. padding: 0 24px;
  421. box-sizing: border-box;
  422. .btn {
  423. width: 120px;
  424. border-top-right-radius: 25px !important;
  425. border-top-left-radius: 25px !important;
  426. border-bottom-left-radius: 25px !important;
  427. border-bottom-right-radius: 25px !important;
  428. }
  429. }
  430. }
  431. </style>