index.vue 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. <template>
  2. <view class="scenic">
  3. <zs-skeleton type="scenic" :loading="loading"></zs-skeleton>
  4. <zs-header :background="background" title="景区门票"></zs-header>
  5. <view class="bg-box">
  6. <image class="bg" src="https://hyxhsh.oss-cn-chengdu.aliyuncs.com/63b7c68b71a69169d1b33f92/store/bdb/user/avatar/AHQWEtDgezfk6e611290c7c9ba152e04c5fe7c339cca.jpg/1.jpg" mode=""></image>
  7. <view class="fixed-box">
  8. <view class="search-box" @click="handleSearch">
  9. <view class="city-box">
  10. <image class="icon" src="@/static/blue-position.png" mode=""></image>
  11. <view class="city">
  12. {{city}}
  13. </view>
  14. </view>
  15. <input class="search" disabled v-model="value" type="text" placeholder="景点名称" />
  16. </view>
  17. </view>
  18. </view>
  19. <view class="more-box">
  20. <view class="title">
  21. 猜你喜欢
  22. </view>
  23. <!-- <view class="btn-box">
  24. 更多 <image class="btn" src="@/static/right.png" mode=""></image>
  25. </view> -->
  26. </view>
  27. <zs-list class="list" mt="20rpx" @load="loadMore" :status="status">
  28. <view class="left">
  29. <view class="item" v-for="item in list" :key="item.tripartiteJson.scenicId" @click="goDetail(item)">
  30. <zs-img :src="item.logoPath" width="340rpx" height="340rpx" mode="widthFix"></zs-img>
  31. <view class="info">
  32. <view class="title">
  33. {{item.tripartiteJson.scenicName}}
  34. </view>
  35. <view class="address-box">
  36. <view class="price-box">
  37. <view class="unit">
  38. </view>
  39. <view class="price">
  40. <!-- {{item.tripartiteJson.ticketList.length?item.tripartiteJson.ticketList[0].salePrice:0}} -->
  41. {{item.tripartiteJson.ticketList | filterMinPrice}}
  42. </view>
  43. <view class="text">
  44. </view>
  45. </view>
  46. <!-- <view class="address">
  47. </view> -->
  48. <view class="distance">
  49. {{(item.shopVo.distance/1000).toFixed(2)}} KM
  50. </view>
  51. </view>
  52. </view>
  53. </view>
  54. </view>
  55. <view class="right">
  56. <view class="item" v-for="item in list1" :key="item.tripartiteJson.scenicId" @click="goDetail(item)">
  57. <zs-img :src="item.logoPath" width="340rpx" height="340rpx" mode="widthFix"></zs-img>
  58. <view class="info">
  59. <view class="title">
  60. {{item.tripartiteJson.scenicName}}
  61. </view>
  62. <view class="address-box">
  63. <view class="price-box">
  64. <view class="unit">
  65. </view>
  66. <view class="price">
  67. <!-- {{item.tripartiteJson.ticketList.length?item.tripartiteJson.ticketList[0].salePrice:0}} -->
  68. {{item.tripartiteJson.ticketList | filterMinPrice}}
  69. </view>
  70. <view class="text">
  71. </view>
  72. </view>
  73. <!-- <view class="address">
  74. </view> -->
  75. <view class="distance">
  76. {{(item.shopVo.distance/1000).toFixed(2)}} KM
  77. </view>
  78. </view>
  79. </view>
  80. </view>
  81. </view>
  82. </zs-list>
  83. </view>
  84. </template>
  85. <script>
  86. import {getScenicList} from '@/api/scenic.js'
  87. import { search } from '@/api/shop.js';
  88. export default {
  89. data() {
  90. return {
  91. background:false,
  92. city: uni.getStorageSync('city'),
  93. value:'',
  94. status:'more',
  95. // query:{
  96. // key: '黄山风景区',
  97. // page: 1,
  98. // pageSize: 20
  99. // },
  100. query:{
  101. queryName:'',
  102. menuId: 1,
  103. 'location.lat':0,
  104. 'location.lon':0,
  105. pageCurrent:1,
  106. pageSize:10
  107. },
  108. list:[],
  109. list1:[],
  110. loading:false,
  111. }
  112. },
  113. filters: {
  114. filterDistance: function(item) {
  115. let blocation = item.blocation.split(',')
  116. let location = JSON.parse(uni.getStorageSync('location'))
  117. /*参数:两地的经纬度数值*/
  118. var radLat1 = location.latitude * Math.PI / 180.0;
  119. var radLat2 = location.longitude* Math.PI / 180.0;
  120. var a = radLat1 - radLat2;
  121. var b = location.longitude* Math.PI / 180.0 - blocation[0]* Math.PI / 180.0;
  122. var s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
  123. Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
  124. s = s * 6378137.0;//地球半径 单位米;
  125. s = Math.round(s * 10000) / 10000 /1000 //输出为千米
  126. s = s.toFixed(0)
  127. return s
  128. },
  129. filterMinPrice(list){
  130. if(list.length){
  131. let arr = JSON.parse(JSON.stringify(list))
  132. arr.sort(function(a,b){ return a.salePrice - b.salePrice})
  133. return arr[0].salePrice
  134. console.log(arr);
  135. }else{
  136. return 0
  137. }
  138. }
  139. },
  140. methods: {
  141. handleSearch() {
  142. uni.navigateTo({
  143. url:'/scenic/search'
  144. })
  145. },
  146. goDetail(item){
  147. uni.navigateTo({
  148. url:`/scenic/detail?id=${item.tripartiteJson.scenicId}&epId=${item.shopVo.shopId}`
  149. })
  150. },
  151. loadMore(){
  152. // this.getScenicList()
  153. this.search()
  154. },
  155. getScenicList(){
  156. this.status = 'loading'
  157. getScenicList(this.query).then(res=>{
  158. this.loading = false
  159. if(res.state == 'Success'){
  160. let list = []
  161. let list1 = []
  162. res.content.data.rows.map((item,index)=>{
  163. if(index%2 == 0){
  164. list.push(item)
  165. }else{
  166. list1.push(item)
  167. }
  168. })
  169. this.list = this.list.concat(list)
  170. this.list1 = this.list1.concat(list1)
  171. console.log(this.list,this.list1);
  172. if((this.list.length + this.list1.length)>= res.content.data.totalCount){
  173. this.status = 'noMore'
  174. }else{
  175. this.status = 'more'
  176. this.query.page++
  177. }
  178. }
  179. })
  180. },
  181. search() {
  182. if(this.status == 'noMore' || this.status == 'loading' || !this.query['location.lat']) return
  183. this.status = 'loading'
  184. search(this.query).then(res=>{
  185. if(res.state == 'Success'){
  186. this.loading = false
  187. let list = []
  188. let list1 = []
  189. let data = res.content.records
  190. data.map((item,index)=>{
  191. item.tripartiteJson = JSON.parse(item.tripartiteJson)
  192. if(index%2 == 0){
  193. list.push(item)
  194. }else{
  195. list1.push(item)
  196. }
  197. })
  198. // 存储原始数据
  199. this.list = this.list.concat(list)
  200. this.list1 = this.list1.concat(list1)
  201. console.log('加载数据',this.status,this.list,this.list1,this.query.pageCurrent);
  202. if(this.query.pageCurrent == res.content.pages){
  203. this.status = 'noMore'
  204. }else{
  205. this.status = 'more'
  206. this.query.pageCurrent++
  207. }
  208. }
  209. })
  210. }
  211. },
  212. onPageScroll(e) {
  213. if (e.scrollTop >= 50) {
  214. this.background = true
  215. } else {
  216. this.background = false
  217. }
  218. },
  219. onLoad() {
  220. this.loading = true
  221. uni.getLocation({
  222. type: 'gcj02',
  223. success: (res) => {
  224. // 解析地址
  225. this.query['location.lat'] = res.latitude
  226. this.query['location.lon'] = res.longitude
  227. console.log(this);
  228. // 存储经纬度
  229. uni.setStorageSync('location',JSON.stringify({latitude:res.latitude,longitude:res.longitude}))
  230. this.search()
  231. }
  232. })
  233. }
  234. }
  235. </script>
  236. <style lang="scss" >
  237. .scenic{
  238. background: #F9F9F9;
  239. min-height: 100vh;
  240. // padding: 0 24rpx ;
  241. .bg-box{
  242. width: 100%;
  243. height: 624rpx;
  244. position: relative;
  245. .bg{
  246. width: 100%;
  247. height: 624rpx;
  248. }
  249. .fixed-box{
  250. position: absolute;
  251. top: 150rpx;
  252. left: 0;
  253. padding: 20rpx 24rpx;
  254. z-index: 9;
  255. // background: #F9F9F9;
  256. .search-box{
  257. width: 702rpx;
  258. height: 72rpx;
  259. // padding: 16rpx;
  260. box-sizing: border-box;
  261. position: relative;
  262. z-index: 9;
  263. .city-box{
  264. position: absolute;
  265. left: 0;
  266. top: 50%;
  267. transform: translateY(-50%);
  268. display: flex;
  269. align-items: center;
  270. padding: 0 28rpx;
  271. border-right: 1rpx solid #F0F0F0;
  272. .icon{
  273. width: 30rpx;
  274. height: 30rpx;
  275. }
  276. .city{
  277. font-weight: 600;
  278. font-size: 28rpx;
  279. color: #222222;
  280. margin-left: 6rpx;
  281. }
  282. }
  283. .search{
  284. width: 702rpx;
  285. height: 72rpx;
  286. background: #FFFFFF;
  287. border-radius: 40rpx 40rpx 40rpx 40rpx;
  288. padding-left: 230rpx;
  289. padding-right: 100rpx;
  290. box-sizing: border-box;
  291. }
  292. }
  293. }
  294. }
  295. .more-box{
  296. display: flex;
  297. align-items: center;
  298. justify-content: space-between;
  299. margin-top: 20rpx;
  300. padding: 0 24rpx;
  301. .title{
  302. font-weight: 600;
  303. font-size: 32rpx;
  304. color: #222222;
  305. }
  306. .btn-box{
  307. display: flex;
  308. align-items: center;
  309. font-weight: 300;
  310. font-size: 24rpx;
  311. color: #AAAAAA;
  312. .btn{
  313. width: 48rpx;
  314. height: 48rpx;
  315. }
  316. }
  317. }
  318. .zs-list{
  319. display: flex;
  320. flex-wrap: wrap;
  321. justify-content: space-between;
  322. margin: 0 24rpx;
  323. .item{
  324. background: #FFFFFF;
  325. border-radius: 16rpx;
  326. margin-bottom: 20rpx;
  327. .info{
  328. padding: 16rpx 16rpx 20rpx;
  329. width: 100%;
  330. box-sizing: border-box;
  331. .title{
  332. font-weight: 400;
  333. font-size: 24rpx;
  334. color: #222222;
  335. width: 300rpx;
  336. white-space: nowrap;
  337. overflow: hidden;
  338. text-overflow: ellipsis;
  339. }
  340. .price-box{
  341. display: flex;
  342. align-items: flex-end;
  343. margin-top: 12rpx;
  344. .unit{
  345. font-weight: 600;
  346. font-size: 20rpx;
  347. color: $uni-color-primary;
  348. }
  349. .price{
  350. font-weight: 600;
  351. font-size: 36rpx;
  352. color: $uni-color-primary;
  353. }
  354. .text{
  355. font-weight: 300;
  356. font-size: 24rpx;
  357. color: #AAAAAA;
  358. margin-left: 6rpx;
  359. }
  360. }
  361. .address-box{
  362. display: flex;
  363. align-items: flex-end;
  364. justify-content: space-between;
  365. font-weight: 300;
  366. font-size: 20rpx;
  367. color: #AAAAAA;
  368. margin-top: 12rpx;
  369. }
  370. }
  371. }
  372. }
  373. }
  374. </style>