food.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646
  1. <template>
  2. <view class="content">
  3. <u-navbar title="美食推荐" :safeAreaInsetTop="true" placeholder='true' fixed>
  4. <view class="u-nav-slot" slot="left" @click='leftClick'>
  5. <view class="iconfont applet-colors-ditu"></view>
  6. </view>
  7. </u-navbar>
  8. <mescroll-uni :up="upOption" :down="downOption" ref="mescrollRef" @init="mescrollInit"
  9. @up="upCallback" @down="downCallback" :top="150">
  10. <view class="flex content1">
  11. <view @click='placeSelect' class='address flex'>
  12. <view class='detailedAddress'>{{detailedAddress1}}</view>
  13. <view class='iconfont applet-xiala'></view>
  14. </view>
  15. <view class="search-wrap">
  16. <view class="search flex justify-space-between align-item-center flex-between" @click="search">
  17. <view class="left flex">
  18. <image class="dSLComVueTopLeftImg" style="width: 40rpx;height: 40rpx"
  19. src="@/static/image/card/search.png"></image>
  20. <text class="search-val"> {{searchVal?searchVal:'搜索美食'}}</text>
  21. </view>
  22. <view class="right">
  23. <image style='width:32rpx;height:32rpx;' v-if="searchVal" @click.stop="delSearchVal"
  24. src="@/static/image/card/searchdel.png" mode="widthFix"></image>
  25. </view>
  26. </view>
  27. </view>
  28. </view>
  29. <view class="tag-type head">
  30. <view v-for='item in jobs' @click="change(item)" class="item" :class="item.checked?'item-active':''">
  31. {{item.iname}}
  32. </view>
  33. </view>
  34. <scroll-view scroll-x="true" scroll-with-animation="true" class='list-type'>
  35. <view v-for='item in searchTypes' @click='changetype(item)'
  36. :class='searchType==item.value?"Semibold active":"Regular"' class="typeitem">{{item.name}}</view>
  37. </scroll-view>
  38. <view class='findItem' v-for='item in findList' @click="toShop(item)" v-if="item.foodDishesInfoList&&item.foodDishesInfoList.length!=0">
  39. <view style='align-items: flex-start;' class='flex' >
  40. <view style='width:100vw;' class="left flex">
  41. <!-- @click.stop='previewImg(item1)' -->
  42. <view v-for='item1 in item.foodDishesInfoList' class="img">
  43. <u--image radius='4' :showLoading="true" :src="item1.dishImage" width="150rpx"
  44. height="150rpx" ></u--image>
  45. </view>
  46. </view>
  47. </view>
  48. <view class='flex row2'>
  49. <view v-if='item.mainBody=="商铺"' class='iconfont applet-dianpu1'></view>
  50. <u--image v-if='item.mainBody=="个人"' :showLoading="true" src="/static/image/find/geren.png"
  51. width="20px" height="20px"></u--image>
  52. <view class='name'>{{item.shopNames}}</view>
  53. </view>
  54. <view class="tag-type flex">
  55. <text class="text" v-for='item1 in item.labels'> {{item1}}</text>
  56. </view>
  57. <view class='address flex justify-space-between'>
  58. <view style='width:60vw;' class='flex'>
  59. <view class='iconfont applet-dizhi'></view>
  60. <view class="detailedAddress" @click.stop="toShopDetail(item)">
  61. {{item.detailedAddress}}
  62. </view>
  63. <!-- <view>{{item.province}}{{item.city}}{{item.area}}</view> -->
  64. </view>
  65. <view style="color: #999;width:40vw;text-align:right;">
  66. 距离{{item.distance1>1000?item.distance:item.distance1}} {{item.distance1>1000?'km':'m'}}
  67. </view>
  68. </view>
  69. </view>
  70. </mescroll-uni>
  71. <!-- <mescroll-body ref="mescrollRef" :up="upOption" :down="downOption" @init="mescrollInit" @up="upCallback" @down="downCallback"></mescroll-body> -->
  72. <!-- <view class='group' @click='group'>
  73. <button class="tuan">团</button>
  74. </view> -->
  75. </view>
  76. </template>
  77. <script>
  78. var that;
  79. var GDMapWX = require('@/js_sdk/js-amap/amap-wx.130.js');
  80. import uniTag from '@/uni_modules/uni-tag/components/uni-tag/uni-tag.vue';
  81. import MoteLinesDivide from "@/components/text-over-flow/text-over-flow.vue"
  82. import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
  83. import {
  84. authorizedLocation
  85. } from '@/util/util.js'
  86. export default {
  87. components: {
  88. MoteLinesDivide,
  89. uniTag
  90. },
  91. mixins: [MescrollMixin],
  92. data() {
  93. return {
  94. place: '',
  95. searchVal: "",
  96. current: 0,
  97. mescroll: null,
  98. findList: [],
  99. inverted: true,
  100. handleList: [],
  101. labels: [],
  102. searchType: '1',
  103. label: '',
  104. longitude: '',
  105. latitude: '',
  106. curPageLen: 0,
  107. totalPage: 0,
  108. detailedAddress: '正在定位...',
  109. detailedAddress1: '',
  110. downOption: {
  111. auto: false,
  112. textColor: '#bbb'
  113. },
  114. searchTypes: [{
  115. name: '默认排序',
  116. value: '1'
  117. }, {
  118. name: '距离最近',
  119. value: '2'
  120. },
  121. // {
  122. // name: '最多点赞',
  123. // value: '3'
  124. // }, {
  125. // name: '我的收藏',
  126. // value: '4'
  127. // },
  128. ],
  129. jobs: [{
  130. id: 1,
  131. iname: '海鲜',
  132. checked: false
  133. },
  134. {
  135. id: 2,
  136. iname: '自助',
  137. checked: false
  138. }, {
  139. id: 3,
  140. iname: '烧烤',
  141. checked: false
  142. },
  143. {
  144. id: 4,
  145. iname: '火锅',
  146. checked: false
  147. },
  148. {
  149. id: 5,
  150. iname: '家常菜',
  151. checked: false
  152. },
  153. {
  154. id: 6,
  155. iname: '面食',
  156. checked: false
  157. },
  158. {
  159. id: 7,
  160. iname: '小龙虾',
  161. checked: false
  162. },
  163. {
  164. id: 8,
  165. iname: '早餐',
  166. checked: false
  167. }
  168. ],
  169. upOption: {
  170. page: {
  171. size: 10 // 每页数据的数量,默认10
  172. },
  173. auto: false,
  174. noMoreSize: 1,
  175. textNoMore: '没有更多了~',
  176. textColor: '#bbb'
  177. },
  178. };
  179. },
  180. onLoad() {
  181. that = this
  182. // this.getList()
  183. // this.getLocation()
  184. // this.mescroll.resetUpScroll();
  185. },
  186. onShow() {
  187. //判断是否有定位权限
  188. this.searchVal = uni.getStorageSync("search_food_val")
  189. if (this.detailedAddress == '正在定位...') {
  190. this.isdingwei()
  191. }
  192. },
  193. methods: {
  194. toShopDetail(val){
  195. console.log(val)
  196. uni.navigateTo({
  197. url: "/pageA/food/detailMap?val="+JSON.stringify(val)
  198. })
  199. },
  200. leftClick() {
  201. uni.navigateTo({
  202. url: "/pageA/food/fondMap"
  203. })
  204. },
  205. previewImg(item) {
  206. uni.previewImage({
  207. current: 0,
  208. urls: [item.dishImage],
  209. loop: true,
  210. })
  211. },
  212. toShop(val) {
  213. uni.navigateTo({
  214. url: "/pageA/food/menu?val=" + JSON.stringify(val)
  215. })
  216. },
  217. delSearchVal() {
  218. this.searchVal = ''
  219. uni.removetorageSync("search_food_val")
  220. that.mescroll.resetUpScroll()
  221. },
  222. isdingwei() {
  223. authorizedLocation().then(res => {
  224. let _obj = {}
  225. if (res == '取消授权') {
  226. //获取上一次,无上一次山海广场
  227. let _place = uni.getStorageSync("LocationPlace")
  228. if (_place && _place.latitude) {
  229. _obj = {
  230. latitude: _place.latitude,
  231. longitude: _place.longitude
  232. }
  233. } else {
  234. _obj = {
  235. latitude: 40.22086204872,
  236. longitude: 122.08338497727
  237. }
  238. }
  239. } else {
  240. _obj = {
  241. latitude: res.latitude,
  242. longitude: res.longitude
  243. }
  244. }
  245. this.longitude = _obj.longitude
  246. this.latitude = _obj.latitude
  247. var amapPluginInstance = new GDMapWX.AMapWX({
  248. key: '6bafe91754a563ff2b7c02542c1ef4e8'
  249. });
  250. amapPluginInstance.getRegeo({
  251. success: function(res) {
  252. console.log(res)
  253. that.detailedAddress = res[0].desc
  254. that.detailedAddress1 = that.detailedAddress.length>4 ? that.detailedAddress.slice(0,4)+'...' : that.detailedAddress
  255. that.mescroll.resetUpScroll()
  256. //成功回调
  257. },
  258. fail: function(info) {
  259. //失败回调
  260. console.log(info)
  261. }
  262. })
  263. })
  264. },
  265. search() {
  266. uni.navigateTo({
  267. url: "/pageA/food/search"
  268. })
  269. },
  270. change(item) {
  271. this.searchVal = item.iname
  272. this.mescroll.resetUpScroll()
  273. // if (this.label == item.iname) {
  274. // this.label = ''
  275. // } else {
  276. // this.label = item.iname
  277. // }
  278. // this.inverted = !this.inverted;
  279. // that.upCallback({
  280. // num: 1,
  281. // size: 10
  282. // })
  283. },
  284. changetype(item) {
  285. this.searchType = item.value
  286. that.upCallback({
  287. num: 1,
  288. size: 10
  289. })
  290. },
  291. placeSelect() {
  292. uni.chooseLocation({
  293. success: function(res) {
  294. console.log(res);
  295. that.latitude = res.latitude
  296. that.longitude = res.longitude
  297. uni.setStorageSync("findlatitude", res.latitude)
  298. uni.setStorageSync("findlongitude", res.longitude)
  299. // let _address = that.$helper.formatLocation(res.address)
  300. that.detailedAddress = res.name
  301. that.detailedAddress1 = that.detailedAddress.length>4 ? that.detailedAddress.slice(0,4)+'...' : that.detailedAddress
  302. uni.setStorageSync("detailedAddress", res.name)
  303. that.$forceUpdate()
  304. that.upCallback({
  305. num: 1,
  306. size: 10
  307. })
  308. }
  309. });
  310. },
  311. mescrollInit(mescroll) {
  312. this.mescroll = mescroll;
  313. },
  314. downCallback() {
  315. this.mescroll.resetUpScroll()
  316. // if (uni.getStorageSync("userInfo").phone) {
  317. // this.mescroll.resetUpScroll()
  318. // } else {
  319. // that.mescroll.endBySize(0, 0)
  320. // this.showAuthorizePhone = true
  321. // }
  322. },
  323. getDistance(latitude, longitude) {
  324. console.log(latitude, longitude, that.latitude, that.longitude)
  325. return new Promise((resolve, reject) => {
  326. qqmapsdk.direction({
  327. mode: 'driving', //可选值:'driving'(驾车) trucking 货车
  328. //from参数不填默认当前地址
  329. // latitude纬度 longitude 经度
  330. from: {
  331. latitude: that.latitude,
  332. longitude: that.longitude
  333. },
  334. to: {
  335. latitude: latitude,
  336. longitude: longitude
  337. },
  338. size: 4, // 车型 1: 微型车 2: 轻型车 3: 中型车 4: 重型车
  339. policy: 'LEAST_TIME', //'9', //参考实时路况,高速优先,尽量躲避拥堵
  340. height: 4,
  341. width: 2.5,
  342. length: 13,
  343. weight: 6.8,
  344. axle_weight: 34,
  345. axle_count: 6,
  346. is_trailer: 1,
  347. success: function(res1, data) {
  348. console.log(res1, data[0].distance, data)
  349. resolve(data[0])
  350. }
  351. })
  352. })
  353. },
  354. async upCallback(page) {
  355. uni.showLoading({
  356. title: '数据加载中'
  357. })
  358. await that.$request.baseRequest('admin.tourism.foodInfo', 'foodList', {
  359. page: page.num,
  360. limit: page.size,
  361. searchType: this.searchType,
  362. searchKeyWord: this.searchVal,
  363. place: this.detailedAddress,
  364. userLongitude: this.longitude,
  365. userLatitude: this.latitude,
  366. }, failres => {
  367. uni.showToast({
  368. icon: "none",
  369. title: failres.errmsg,
  370. duration: 3000
  371. });
  372. }).then(res => {
  373. uni.hideLoading()
  374. if (page.num == 1) that.findList = [], that.handleList = [];
  375. that.curPageLen = res.data.items.length;
  376. that.handleList = res.data.items
  377. that.totalPage = res.data.total;
  378. })
  379. if (that.handleList.length > 0) {
  380. for (var i = 0; i < that.handleList.length; i++) {
  381. that.handleList[i].latitude = that.handleList[i].location.split(',')[0]
  382. that.handleList[i].longitude = that.handleList[i].location.split(',')[1]
  383. // var data = await that.getDistance(that.handleList[i].latitude, that.handleList[i].longitude)
  384. that.handleList[i].distance1 = JSON.parse(JSON.stringify(that.handleList[i].distance))
  385. that.handleList[i].distance = (that.handleList[i].distance / 1000).toFixed(1)
  386. if (that.handleList[i].label) {
  387. that.handleList[i].labels = that.handleList[i].label.split(",")
  388. }
  389. if (that.handleList[i].foodDishesInfoList) {
  390. that.handleList[i].foodDishesInfoList = that.handleList[i].foodDishesInfoList.splice(0, 4)
  391. }
  392. }
  393. that.findList = that.handleList
  394. } else {
  395. uni.hideLoading()
  396. }
  397. that.$nextTick(() => {
  398. that.mescroll.endBySize(that.curPageLen, that.totalPage)
  399. });
  400. },
  401. group() {
  402. uni.navigateTo({
  403. url: '/pageA/food/groupBuying'
  404. })
  405. },
  406. }
  407. }
  408. </script>
  409. <style lang="scss" scoped>
  410. .content {}
  411. .content1 {
  412. padding: 20rpx;
  413. background-color: #fff;
  414. .search {
  415. // color: #9199af;
  416. // background: #f9d27d;
  417. border-radius: 50rpx;
  418. padding: 15rpx 0 15rpx 30rpx;
  419. box-sizing: border-box;
  420. margin-right: 20rpx;
  421. }
  422. .left {
  423. width: 80%;
  424. text {
  425. white-space: nowrap;
  426. overflow: scroll;
  427. position: relative;
  428. margin-left: 20rpx;
  429. color: #BBBBBB;
  430. display: flex;
  431. align-items: center;
  432. }
  433. }
  434. .right {
  435. // width:14%;
  436. // margin-right: 20rpx
  437. display: flex;
  438. }
  439. }
  440. .search-wrap {
  441. width: 70%;
  442. background: rgb(249, 249, 249);
  443. // border: 1px solid #f9d27d;
  444. border-radius: 50rpx;
  445. .left{
  446. align-items: center;
  447. }
  448. .search-val{
  449. color:#BBBBBB;
  450. }
  451. }
  452. .address {
  453. width: 30%;
  454. }
  455. .findItem {
  456. background: #fff;
  457. margin: 20rpx;
  458. border-radius: 20rpx;
  459. padding: 20rpx;
  460. font-size: 32rpx;
  461. .row2 {
  462. margin: 20rpx 0;
  463. }
  464. .left {
  465. // background: red;
  466. }
  467. .name {
  468. color: #333;
  469. margin-left: 10rpx;
  470. font-weight: 700;
  471. font-size: 36rpx;
  472. }
  473. .description {
  474. color: #666;
  475. margin-top: 10rpx;
  476. }
  477. .address {
  478. margin-top: 30rpx;
  479. width: 100%;
  480. color: #393733;
  481. }
  482. .img{
  483. margin: 10rpx;
  484. }
  485. }
  486. .applet-dianpu1 {
  487. color: #393733;
  488. font-size: 50rpx;
  489. }
  490. .applet-dizhi {
  491. color: #393733;
  492. font-size: 40rpx;
  493. position: relative;
  494. top: -2rpx;
  495. }
  496. .group {
  497. position: fixed;
  498. // margin-left: 350px;
  499. bottom: 40rpx;
  500. right: 40rpx;
  501. z-index: 999;
  502. }
  503. .tuan {
  504. background: #eaad1a;
  505. border-radius: 50px;
  506. color: #fff;
  507. }
  508. .applet-colors-tianjia2 {}
  509. // .text {
  510. // font-size: 26rpx;
  511. // font-weight: 500;
  512. // color: #eaad1a;
  513. // opacity: 0.5;
  514. // margin-right: 56rpx;
  515. // }
  516. .head {
  517. white-space: nowrap;
  518. overflow-x: scroll;
  519. padding-left: 20rpx;
  520. width: calc(100vw);
  521. box-sizing: border-box;
  522. .item {
  523. display: inline-block;
  524. background: #F0F0F0;
  525. color: #999;
  526. padding: 10rpx 26rpx;
  527. margin-right: 20rpx;
  528. border-radius: 50rpx;
  529. font-size: 24rpx;
  530. }
  531. }
  532. .tag-type {
  533. .text {
  534. border-radius: 4px;
  535. background-color: #FDF2E5;
  536. color: #E95700;
  537. margin-right: 30rpx;
  538. padding: 10rpx 26rpx;
  539. font-size: 24rpx;
  540. }
  541. }
  542. .list-type {
  543. background: #fff;
  544. width: 100vw;
  545. padding-top: 5px;
  546. height: 88rpx;
  547. overflow-x: scroll;
  548. white-space: nowrap;
  549. }
  550. .typeitem {
  551. margin: 20rpx 20rpx 0 20rpx;
  552. position: relative;
  553. display: inline-block;
  554. padding-bottom: 10px;
  555. font-size: 28rpx;
  556. color: #888;
  557. }
  558. .typeitem.active {
  559. color: #eaad1a;
  560. font-size: 32rpx;
  561. }
  562. .typeitem.active:after {
  563. content: '';
  564. display: block;
  565. position: absolute;
  566. height: 3px;
  567. bottom: 0;
  568. background: #eaad1a;
  569. width: 44rpx;
  570. left: 50%;
  571. transform: translateX(-50%);
  572. }
  573. .detailedAddress {
  574. width: 70vw;
  575. overflow: hidden;
  576. text-overflow: ellipsis;
  577. white-space: nowrap;
  578. color:#999 ;
  579. line-height: 40rpx;
  580. }
  581. .tag-type {
  582. background: #fff;
  583. uni-tag {
  584. margin-left: 20rpx !important;
  585. }
  586. }
  587. .applet-colors-ditu {
  588. font-size: 40rpx;
  589. }
  590. /deep/.mescroll-upwarp {
  591. padding: 30rpx 0;
  592. }
  593. .applet-xiala{
  594. margin: 0 16rpx 0 -4px;
  595. }
  596. </style>