index.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578
  1. <template>
  2. <view class="hotel">
  3. <zs-header :background="background"></zs-header>
  4. <zs-img class="banner" width="750rpx" height="556rpx" src="https://hyxhsh.oss-cn-chengdu.aliyuncs.com/63b7c68b71a69169d1b33f92/store/bdb/user/avatar/HpBk08yMov1nb3b9eeb79b10b687ce1d770e0fd3fe93.png/1.png"></zs-img>
  5. <view class="search-box">
  6. <view class="address-box">
  7. <view class="box">
  8. <view class="address" @click="jump('./cityList')">
  9. {{city||address}}
  10. </view>
  11. <image class="more" src="@/static/right.png" mode=""></image>
  12. </view>
  13. <view class="nearby" @click="refresh">
  14. 当前位置
  15. </view>
  16. <image class="position" src="@/static/rePosition.png" mode=""></image>
  17. </view>
  18. <view class="chooose-box">
  19. <view class="time-box" @click="chooseDate">
  20. <view class="start-time">
  21. {{query.checkInDate | filterDate('time')}}
  22. </view>
  23. <view class="day">
  24. {{query.checkInDate | filterDate('day')}}
  25. </view>
  26. <view class="line">
  27. </view>
  28. <view class="end-time">
  29. {{query.checkOutDate | filterDate('time')}}
  30. </view>
  31. <view class="day">
  32. {{query.checkOutDate | filterDate('day')}}
  33. </view>
  34. </view>
  35. <view class="total">
  36. 共{{day}}晚
  37. <image class="more" src="@/static/right.png" mode=""></image>
  38. </view>
  39. </view>
  40. <view class="input-box">
  41. <input class="input" type="text" v-model="query.keyword" placeholder="搜索酒店名/地名/关键词" />
  42. <image class="more" src="@/static/right.png" mode=""></image>
  43. </view>
  44. <view class="btn-box">
  45. <button class="btn" type="default" @click="handleSearch(0)">查找酒店</button>
  46. </view>
  47. </view>
  48. <!-- 列表 -->
  49. <zs-list class="store-box" mt="0" @load="loadMore" :status="status">
  50. <view class="left">
  51. <view class="hotel-item" v-for="(item,index) in list" :key="index" @click="goDetail(item.hotelId)">
  52. <view >
  53. <zs-img :src="item.picture" width="340rpx" height="322rpx" mode="widthFix"></zs-img>
  54. <view class="info">
  55. <view class="price-box">
  56. <view class="left" v-if="item.price">
  57. <view class="price">
  58. ¥{{item.price}}
  59. </view>
  60. <view class="label">
  61. </view>
  62. </view>
  63. <view class="left" v-else>
  64. <view class="label">
  65. 暂无报价
  66. </view>
  67. </view>
  68. <view class="right">
  69. <image class="star" v-for="(i,d) in getTag(item.star).num" :key="d" src="../static/star.png" mode=""></image>
  70. </view>
  71. </view>
  72. <view class="title">
  73. {{item.chineseName}}
  74. <!-- <view :class="[getTag(item.star).tag]">
  75. {{item.starName}}
  76. </view> -->
  77. </view>
  78. <!-- <view class="desc">
  79. 观山湖区
  80. </view> -->
  81. </view>
  82. </view>
  83. </view>
  84. </view>
  85. <view class="right">
  86. <view class="hotel-item" v-for="(item,index) in list1" :key="index" @click="goDetail(item.hotelId)">
  87. <view >
  88. <zs-img :src="item.picture" width="340rpx" height="322rpx" mode="widthFix"></zs-img>
  89. <view class="info">
  90. <view class="price-box">
  91. <view class="left" v-if="item.price">
  92. <view class="price">
  93. ¥{{item.price}}
  94. </view>
  95. <view class="label">
  96. </view>
  97. </view>
  98. <view class="left" v-else>
  99. <view class="label">
  100. 暂无报价
  101. </view>
  102. </view>
  103. <view class="right">
  104. <image class="star" v-for="(i,d) in getTag(item.star).num" :key="d" src="../static/star.png" mode=""></image>
  105. </view>
  106. </view>
  107. <view class="title">
  108. {{item.chineseName}}
  109. <!-- <view :class="[getTag(item.star).tag]">
  110. {{item.starName}}
  111. </view> -->
  112. </view>
  113. <!-- <view class="desc">
  114. 观山湖区
  115. </view> -->
  116. </view>
  117. </view>
  118. </view>
  119. </view>
  120. </zs-list>
  121. <u-calendar
  122. startText="住店"
  123. endText="离店"
  124. :monthNum="5"
  125. confirmDisabledText="请选择离店日期"
  126. :show="show"
  127. :mode="mode"
  128. @confirm="confirm"
  129. @close="show = false"
  130. ref="calendar"
  131. :rowHeight="100"
  132. closeOnClickOverlay
  133. color="#EE4320"
  134. >
  135. </u-calendar>
  136. </view>
  137. </template>
  138. <script>
  139. import {getHotelList} from '@/api/hotel.js'
  140. import {queryFromLocation} from '@/api/common'
  141. export default {
  142. data() {
  143. return {
  144. city:'',
  145. address:'',
  146. list:[],
  147. list1:[],
  148. status:'more',
  149. show: false,
  150. background: false,
  151. mode: 'range',
  152. query:{
  153. "checkInDate":uni.$u.timeFormat(new Date().getTime(), 'yyyy-mm-dd') ,
  154. "checkOutDate":uni.$u.timeFormat(new Date().getTime()+1000*60*60*24, 'yyyy-mm-dd'),
  155. "cityCode": 0,
  156. "cityName": uni.getStorageSync('city').replace('市',''),
  157. "filter": {},
  158. "keyword": "",
  159. "limit": 10,
  160. "returnFilter": 0,
  161. "sortKey": "",
  162. "start": 0
  163. },
  164. day:1
  165. }
  166. },
  167. filters: {
  168. filterDate: function(value,type) {
  169. let timestamp = new Date(value).getTime()
  170. if(type == 'time'){
  171. return uni.$u.timeFormat(timestamp, 'mm月dd日');
  172. }else if(type == 'day'){
  173. let arr = ['日','一','二','三','四','五','六']
  174. let num = new Date(timestamp).getDay()
  175. return `周${arr[num]}`
  176. }
  177. }
  178. },
  179. methods: {
  180. jump(url){
  181. uni.navigateTo({
  182. url
  183. })
  184. },
  185. getTag(star){
  186. if(star == 0 ||star == 1){
  187. return {tag:'tag1',num:1}
  188. }else if(star == 2 ||star == 6){
  189. return {tag:'tag2',num:2}
  190. }if(star == 3 ||star == 7){
  191. return {tag:'tag2',num:3}
  192. }if(star == 4 ||star == 8){
  193. return {tag:'tag3',num:4}
  194. }if(star == 5 ||star == 9){
  195. return {tag:'tag3',num:5}
  196. }
  197. },
  198. // 获取当前城市
  199. getCity(){
  200. let that = this
  201. that.address = '定位中...'
  202. return new Promise((resolve,reject)=>{
  203. uni.getLocation({
  204. type: 'gcj02',
  205. success: (res) => {
  206. // 解析地址
  207. // that.query['location.lat'] = res.latitude
  208. // that.query['location.lon'] = res.longitude
  209. // 存储经纬度
  210. uni.setStorageSync('location',JSON.stringify({latitude:res.latitude,longitude:res.longitude}))
  211. queryFromLocation({
  212. coordType:'gcj02ll',
  213. lat: res.latitude,
  214. lng: res.longitude
  215. }).then(res=>{
  216. if(res.state == 'Success'){
  217. that.address = res.content.formatted_address
  218. }else{
  219. that.address = '定位失败'
  220. }
  221. })
  222. },
  223. fail: () => {
  224. console.log("获取经纬度失败");
  225. },
  226. })
  227. })
  228. },
  229. refresh(){
  230. this.getCity().then(res=>{
  231. this.status = 'more'
  232. this.query.start = 0
  233. this.list = []
  234. this.list1 = []
  235. this.getHotelList()
  236. })
  237. },
  238. handleSearch(type){
  239. uni.navigateTo({
  240. url:`./search?key=${this.query.keyword}&checkInDate=${this.query.checkInDate}&checkOutDate=${this.query.checkOutDate}&day=${this.day}&isNear=${type}&cityName=${this.city}`
  241. })
  242. },
  243. confirm(e) {
  244. this.show = false
  245. if(e){
  246. this.day = e.length - 1
  247. this.query.checkInDate = e[0]
  248. this.query.checkOutDate = e[this.day]
  249. }
  250. },
  251. loadMore(){
  252. this.getHotelList()
  253. },
  254. goDetail(id) {
  255. uni.navigateTo({
  256. url:`/hotel/hotelDetail?id=${id}&checkInDate=${this.query.checkInDate}&checkOutDate=${this.query.checkOutDate}`
  257. })
  258. },
  259. chooseDate(){
  260. this.show = true
  261. },
  262. getHotelList(){
  263. this.status = 'loading'
  264. let query = JSON.parse(JSON.stringify(this.query))
  265. query.start = query.start*query.limit
  266. if(this.city){
  267. query.cityName = this.city
  268. }
  269. getHotelList(query).then(res=>{
  270. if(res.state == 'Success'){
  271. let list = []
  272. let list1 = []
  273. res.content.data.hotelList.map((item,index)=>{
  274. if(index%2){
  275. this.list1.push(item)
  276. }else{
  277. this.list.push(item)
  278. }
  279. })
  280. this.list = this.list.concat(list)
  281. this.list1 = this.list1.concat(list1)
  282. if((this.list.length+this.list1.length) >= res.content.data.count){
  283. this.status = 'noMore'
  284. }else{
  285. this.status = 'more'
  286. this.query.start++
  287. }
  288. }
  289. })
  290. }
  291. },
  292. onPageScroll(e) {
  293. if (e.scrollTop >= 50) {
  294. this.background = true
  295. } else {
  296. this.background = false
  297. }
  298. },
  299. onLoad(options) {
  300. if(options.cityName){
  301. this.city = options.cityName
  302. }else{
  303. this.getCity()
  304. }
  305. }
  306. }
  307. </script>
  308. <style lang="scss" >
  309. .hotel{
  310. background: #F9F9F9;
  311. min-height: 100vh;
  312. .banner{
  313. }
  314. .search-box{
  315. padding: 28rpx 24rpx;
  316. width: 702rpx;
  317. background: #FFFFFF;
  318. border-radius: 16rpx 16rpx 16rpx 16rpx;
  319. margin: -224rpx 24rpx 20rpx;
  320. position: relative;
  321. // top: -224rpx;
  322. box-sizing: border-box;
  323. .address-box{
  324. display: flex;
  325. align-items: center;
  326. padding-bottom: 30rpx;
  327. .box{
  328. flex: 1;
  329. display: flex;
  330. align-items: center;
  331. .address{
  332. max-width: 400rpx;
  333. font-weight: 600;
  334. font-size: 32rpx;
  335. color: #222222;
  336. white-space: nowrap;
  337. overflow: hidden;
  338. text-overflow: ellipsis;
  339. }
  340. .more{
  341. width: 48rpx;
  342. height: 48rpx;
  343. margin: 0 16rpx;
  344. }
  345. }
  346. .nearby{
  347. font-weight: 300;
  348. font-size: 24rpx;
  349. color: #222222;
  350. }
  351. .position{
  352. width: 48rpx;
  353. height: 48rpx;
  354. }
  355. }
  356. .chooose-box{
  357. padding: 78rpx 0 24rpx;
  358. display: flex;
  359. align-items: center;
  360. justify-content: space-between;
  361. border-top:1rpx solid #F0F0F0;
  362. border-bottom: 1rpx solid #F0F0F0;
  363. .time-box{
  364. display: flex;
  365. align-items: flex-end;
  366. .start-time,.end-time{
  367. font-weight: 600;
  368. font-size: 32rpx;
  369. color: #222222;
  370. position: relative;
  371. }
  372. .start-time::before{
  373. content: '入住';
  374. position: absolute;
  375. top:calc(-100% - 20rpx);
  376. left: 0;
  377. font-weight: 300;
  378. font-size: 24rpx;
  379. color: #222222;
  380. }
  381. .end-time::before{
  382. content: '离店';
  383. position: absolute;
  384. top:calc(-100% - 20rpx);
  385. left: 0;
  386. font-weight: 300;
  387. font-size: 24rpx;
  388. color: #222222;
  389. }
  390. .line{
  391. font-weight: 600;
  392. font-size: 32rpx;
  393. color: #222222;
  394. margin: 0 16rpx;
  395. }
  396. .day{
  397. font-weight: 300;
  398. font-size: 28rpx;
  399. color: #222222;
  400. margin-left: 16rpx;
  401. vertical-align: bottom;
  402. }
  403. }
  404. .total{
  405. display: flex;
  406. align-items: center;
  407. font-weight: 300;
  408. font-size: 24rpx;
  409. color: #222222;
  410. .more{
  411. width: 48rpx;
  412. height: 48rpx;
  413. }
  414. }
  415. }
  416. .input-box{
  417. position: relative;
  418. line-height: 84rpx;
  419. border-bottom: 1rpx solid #F0F0F0;
  420. .input{
  421. width: 100%;
  422. height: 84rpx;
  423. line-height: 84rpx;
  424. padding-right: 48rpx;
  425. font-size: 24rpx;
  426. color: #222222;
  427. }
  428. .more{
  429. width: 48rpx;
  430. height: 48rpx;
  431. position: absolute;
  432. top: 50%;
  433. right: 0%;
  434. transform: translateY(-50%);
  435. }
  436. }
  437. .btn-box{
  438. padding-top: 28rpx;
  439. .btn{
  440. height: 80rpx;
  441. background: #EE4320;
  442. border-radius: 40rpx;
  443. font-weight: 600;
  444. font-size: 28rpx;
  445. color: #FFFFFF;
  446. }
  447. }
  448. }
  449. .zs-list {
  450. display: flex;
  451. flex-wrap: wrap;
  452. justify-content: space-between;
  453. padding: 0 24rpx;
  454. .hotel-item.disable{
  455. filter: grayscale(1);
  456. }
  457. .hotel-item {
  458. width: 340rpx;
  459. margin-bottom: 20rpx;
  460. // box-shadow: 0rpx 0rpx 24rpx 2rpx rgba(0, 0, 0, 0.08);
  461. border-radius: 16rpx;
  462. background: #fff;
  463. .icon {
  464. width: 100%;
  465. height: 300rpx;
  466. border-radius: 16rpx 16rpx 0 0;
  467. }
  468. .info{
  469. flex: 1;
  470. padding: 16rpx;
  471. display: flex;
  472. flex-direction: column;
  473. justify-content: space-between;
  474. position: relative;
  475. .title{
  476. font-size: 28rpx;
  477. font-weight: bold;
  478. overflow: hidden;
  479. text-overflow: ellipsis;
  480. /* 弹性伸缩盒子模型显示 */
  481. display: -webkit-box;
  482. /* 限制在一个块元素显示的文本的行数 */
  483. -webkit-line-clamp: 2;
  484. /* 设置或检索伸缩盒对象的子元素的排列方式 */
  485. -webkit-box-orient: vertical;
  486. margin-top: 10rpx;
  487. }
  488. .desc{
  489. font-size: 24rpx;
  490. color: #AAAAAA;
  491. overflow: hidden;
  492. text-overflow: ellipsis;
  493. /* 弹性伸缩盒子模型显示 */
  494. display: -webkit-box;
  495. /* 限制在一个块元素显示的文本的行数 */
  496. -webkit-line-clamp: 2;
  497. /* 设置或检索伸缩盒对象的子元素的排列方式 */
  498. -webkit-box-orient: vertical;
  499. margin-top: 12rpx;
  500. }
  501. .price-box{
  502. display: flex;
  503. justify-content: space-between;
  504. align-items: center;
  505. margin-top: 12rpx;
  506. .left{
  507. display: flex;
  508. align-items: center;
  509. .label{
  510. font-size: 24rpx;
  511. color: #AAAAAA;
  512. margin-left: 6rpx;
  513. }
  514. .price{
  515. font-size: 32rpx;
  516. color: $uni-color-primary;
  517. font-weight: bold;
  518. }
  519. }
  520. .right{
  521. font-size: 24rpx;
  522. color: #AAAAAA;
  523. display: flex;
  524. align-items: center;
  525. .star{
  526. width: 21rpx;
  527. height: 17rpx;
  528. margin-left: 3rpx;
  529. }
  530. .half-star{
  531. width: 10.5rpx;
  532. height: 16.5rpx;
  533. margin-left: 3rpx;
  534. }
  535. }
  536. }
  537. }
  538. }
  539. }
  540. }
  541. </style>