ChainNearby.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. <template><page-meta :root-font-size="fontSize+'px'"></page-meta>
  2. <home-base :show="false" style="position: absolute;top:0;right:0;left:0;bottom:0"><view style="height:100%" class="scroll-view-wrapper div container">
  3. <view class="div home-top">
  4. <view class="div header">
  5. <view class="div location" @click="goMap()">
  6. <text class="i icon-local iconfont">&#xe6ed;</text><text class="span location-content">{{locationName}}</text><text class="i icon-down iconfont">&#xe652;</text>
  7. </view>
  8. <view class="div search-ipt">
  9. <view class="div search-icon iconfont">&#xe67e;</view><input class="search-input" v-model="keyword" @confirm="reload()" placeholder="搜索附近门店" />
  10. </view>
  11. </view>
  12. <index-banner :full="true" v-if="banners && banners.length > 0" :items="banners"></index-banner>
  13. </view>
  14. <view class="scroll-view div index-con-shop" style="position:relative">
  15. <!-- 无限加载滚动列表 -->
  16. <scroll-view style="position: absolute;top:0;right:0;left:0;bottom:0" class="div" @scrolltolower="loadMore" scroll-y="true">
  17. <view class="div title"><text class="span">附近的门店</text></view>
  18. <view class="div" v-if="chainList">
  19. <view class="div" v-for='(item, index) in chainList'
  20. v-bind:key='index'
  21. @click="goDetail(item)"
  22. >
  23. <view class="div">
  24. <view class="div dp">
  25. <view class="div dp-box">
  26. <view class="div dp-inner">
  27. <view class="div dp-link">
  28. <text class="span clearfix a8o">
  29. <image mode="aspectFit" class="img d9" :src="item.chain_avatar">
  30. </text>
  31. </view>
  32. <view class="div dp-link-rt">
  33. <view class="div dp-link-rt-a1">
  34. <view class="div dp-title clearfix">
  35. <text class="h2 ">{{item.chain_addressname}}</text>
  36. </view>
  37. <text class="span dp-txt2">
  38. 距您{{item.distance}}km
  39. </text>
  40. </view>
  41. <view class="div dp-link-rtlist">
  42. </view>
  43. <view class="div dp-list-box">
  44. <view class="div dp-a" v-for="(goods,i) in item.goods_list" :key="i">
  45. <text class="span dp-sapn">
  46. <image mode="aspectFit" class="img" :src="goods.goods_image_url">
  47. </text>
  48. <text class="span dp-sapn-price">¥{{goods.goods_price}}</text>
  49. </view>
  50. </view>
  51. </view>
  52. </view>
  53. </view>
  54. </view>
  55. </view>
  56. </view>
  57. <view class="div loading-wrapper" v-if="chainList.length > 0">
  58. <view class="p common-no-more" v-if='!isMore'>没有更多了</view>
  59. <uni-load-more status="loading" color='#e93b3d' v-if='isMore'></uni-load-more>
  60. </view>
  61. <empty-record v-if='chainList.length <= 0 && !isMore'></empty-record>
  62. </view>
  63. </scroll-view>
  64. </view>
  65. </view>
  66. <uni-popup background-color="#fff" ref="confirm" type="dialog">
  67. <uni-popup-dialog :mode="dialog.mode" :title="dialog.title" :content="dialog.content" :placeholder="dialog.content" @confirm="confirmDialog" @close="closeDialog"></uni-popup-dialog>
  68. </uni-popup>
  69. </home-base>
  70. </template>
  71. <script>
  72. import {getFontSize} from '@/util/common'
  73. import { urlencode } from '@/util/common'
  74. import HomeBase from '../HomeBase'
  75. import { mapState, mapMutations } from 'vuex'
  76. import EmptyRecord from '../../EmptyRecord'
  77. import IndexBanner from '../../home/index/IndexBanner'
  78. import { getAddressByPoint, getPosition, getPointByIp } from '../../../util/bmap'
  79. import { getChainList } from '../../../api/homesearch'
  80. import { getAppadList } from '../../../api/homeindex'
  81. export default {
  82. name: 'ChainList',
  83. components:{
  84. HomeBase,
  85. EmptyRecord,
  86. IndexBanner
  87. },
  88. data(){
  89. return {
  90. dialog:{},
  91. lng:0,
  92. lat:0,
  93. locationName: '请选择...',
  94. keyword:'',
  95. banners:false,
  96. chainList: false,
  97. params: { 'page': 0, 'per_page': 10 },
  98. loading: false, // 是否加载更多
  99. isMore: true, // 是否有更多
  100. }
  101. },
  102. computed:{
  103. fontSize(){
  104. return getFontSize()
  105. },
  106. ...mapState({
  107. member_point: state => state.member.point
  108. })
  109. },
  110. created: function () {
  111. if (!this.member_point.lng || !this.member_point.lat || !this.member_point.address) {
  112. // uni.navigateTo({ url: '/pages/home/map/Map' })
  113. let _this = this
  114. getPosition(function (res) {
  115. if (res.code === 10000) {
  116. _this.lat = res.result.lat
  117. _this.lng = res.result.lng
  118. _this.getAddressByPoint()
  119. } else {
  120. // uni.showToast({icon:'none',title: res.message})
  121. // 使用ip定位
  122. getPointByIp().then(res => {
  123. if (res.status == 0) {
  124. _this.lat = res.content.point.y
  125. _this.lng = res.content.point.x
  126. _this.getAddressByPoint()
  127. } else {
  128. uni.showToast({icon:'none',title: res.message})
  129. }
  130. }).catch(function (error) {
  131. uni.showToast({icon:'none',title: error.message})
  132. })
  133. }
  134. }, true)
  135. } else {
  136. this.locationName = this.member_point.address
  137. this.lat = this.member_point.lat
  138. this.lng = this.member_point.lng
  139. }
  140. getAppadList(1).then(res=>{
  141. this.banners=res.result.ad_list
  142. })
  143. this.loadMore()
  144. },
  145. methods:{
  146. closeDialog(){
  147. uni.navigateTo({ url: '/pages/home/map/Map' })
  148. },
  149. confirmDialog(value){
  150. this.reload()
  151. },
  152. ...mapMutations({
  153. memberPoint: 'memberPoint'
  154. }),
  155. getAddressByPoint () {
  156. let _this = this
  157. getAddressByPoint(this.lat + ',' + this.lng).then(res => {
  158. if (res.status == 0) {
  159. this.memberPoint({ point: { lng: this.lng, lat: this.lat, address: res.result.formatted_address, cityCode: res.result.cityCode } })
  160. this.locationName = res.result.formatted_address
  161. this.dialog={content:'我们为您定位到' + res.result.formatted_address + ',是否使用该地址?',cancelButtonText: '不,我想选择其他地址', confirmButtonText: '使用该地址'}
  162. this.$refs.confirm.open()
  163. } else {
  164. uni.showToast({icon:'none',title: res.message})
  165. }
  166. }).catch(function (error) {
  167. uni.showToast({icon:'none',title: error.message})
  168. })
  169. },
  170. goMap () {
  171. uni.navigateTo({ url: '/pages/home/map/Map' })
  172. },
  173. loadMore () {
  174. if (this.loading) {
  175. return
  176. }
  177. this.params.page = ++this.params.page
  178. if (this.isMore) {
  179. this.getChainList(true)
  180. }
  181. },
  182. reload () {
  183. // 重新加载数据
  184. this.params.page = 0
  185. this.isMore = true
  186. this.loading = false
  187. this.chainList = false
  188. this.loadMore()
  189. },
  190. getChainList () {
  191. this.loading = true
  192. getChainList({keyword:this.keyword,longitude:this.lng,latitude:this.lat},this.params).then(res => {
  193. if (res.result.hasmore) {
  194. this.isMore = true
  195. } else {
  196. this.isMore = false
  197. }
  198. if (this.chainList) {
  199. this.chainList = this.chainList.concat(res.result.chain_list)
  200. } else {
  201. this.chainList = res.result.chain_list
  202. }
  203. this.loading = false
  204. }).catch(function (error) {
  205. uni.hideLoading()
  206. uni.showToast({icon:'none',title: error.message})
  207. this.loading = false
  208. })
  209. },
  210. goDetail (item) {
  211. uni.navigateTo({ url: '/pages/home/storedetail/Storedetail'+'?'+urlencode( { 'id': item.store_id } )})
  212. },
  213. }
  214. }
  215. </script>
  216. <style scoped lang='scss'>
  217. .scroll-view-wrapper{display: flex;flex-direction: column;}
  218. .scroll-view{flex:1}
  219. .home-top {background-color: #ffffff;display: block;min-height: 2.2rem;overflow: hidden;position: relative;z-index: 2;}
  220. .header{ border-bottom: 0; position:absolute;z-index:2;height: 56px;display: flex;display: -webkit-flex;display: -moz-flex;display: -o-flex;left:0;right:0;}
  221. .header .icon-local{font-size:$h2;}
  222. .location {width: 150px;vertical-align: top;height: 24px;border-radius: 23px;line-height: 24px;font-size:$subFontSize;color: #fff;margin-top: 10px;left: 0;text-align: left;padding-left:10px;display: flex}
  223. .location .location-content {overflow: hidden;text-overflow: ellipsis;white-space: nowrap;display: inline-block;vertical-align: top;flex:1;margin-right:5px;}
  224. .location .icon-down{ display: inline-block; width: 10px;height: 30px; font-size:$fontSize;margin-right:10px;}
  225. .search-ipt{background: rgba(255,255,255,0.35);height: 30px;top: 7px;margin-right: 10px;position: relative;border-radius: 20px;color: #fff;font-size:$subFontSize;display: flex;
  226. line-height: 30px;text-align: left;white-space: nowrap;flex:1}
  227. .search-ipt .search-icon {width:30px;text-align: center}
  228. .search-ipt .search-input{background: none;border: 0;color:#fff;width:100%;}
  229. .search-ipt .search-input::-webkit-input-placeholder {color: #fff;}
  230. .index-con-wrap{display: block;max-width: 640px;margin: 0 auto;position: relative;z-index: 0;}
  231. .index-con-shop .title{font-size:$subFontSize;line-height: 50px;height: 50px;text-overflow: ellipsis;white-space: nowrap;color: #70704e;text-align: center;
  232. position: relative;background-color: #FFF;}
  233. .index-con-shop .title:before {content: '';height: 1px;border-top: 1px solid #333;width: 228px;position: absolute;top: 50%;margin-top: -1px;left: 50%;transform: scaleY(0.5) translate(-50%, 0);
  234. -webkit-transform: scaleY(0.5) translate(-50%, 0);}
  235. .index-con-shop .title .span {position: relative;padding: 0 5px;background-color: #FFF;display: inline-block; height: 50px;line-height: 48px;font-size:$h1;font-weight: bold;color: #333;}
  236. .index-shop-ul .dp {position: relative;padding: 15px 10px;min-height: 70px;border-top: 1px solid #e7e9e4;background: #FFF; padding-bottom:20px;}
  237. .dp-box {position: relative;font-size: 0;min-height: 55px;background: #fff;padding:10px;}
  238. .dp-inner{ position: relative;}
  239. .dp-inner .dp-link { position: absolute;left: 0;top: 0;bottom: 0;float: none;}
  240. .dp-inner .dp-link .span{position: relative;display: block; }
  241. .dp-inner .dp-link .span .img {float: left;width: 64px;height: 64px;border-radius: 4px;display: inline-block; margin-right: 8px;}
  242. .dp-link-rt{font-size:$fontSize;color: #999;margin-left: 76px;}
  243. .dp-link-rt .a.dp-link-rt-a1 {display: block;min-height: 66px;}
  244. .dp-title{ height: $h2;line-height: $h2;overflow: hidden;display: -webkit-box;display: -moz-box;display: -ms-box;display: flex;-moz-flex: 1;-webkit-flex: 1;-ms-flex: 1;flex: 1;-webpack-box-orient:horizontal;
  245. -moz-box-orient:horizontal;-ms-box-orient:horizontal;box-orient:horizontal;}
  246. .dp-title .h2 { font-size:$h2;color: #333;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;display: inline-block;margin-top: 0;font-weight: bold;
  247. -webkit-flex: 1;-moz-flex: 1;-ms-flex: 1;flex: 1}
  248. .dp-link-rt .dp-txt1{font-size: 0;padding-top: 10px;overflow: hidden;}
  249. .dp-txt1-st{display: inline-block; border: 1px solid #16A9ff;font-size: 0;border-radius: 2px;color: #16a9ff;line-height: 0;height: 15px; overflow: hidden; font-weight: normal;}
  250. .dp-txt1-st2 { display: inline-block;border: 1px solid #b6b6b6;border-radius: 2px;color: #999;height: 15px;overflow: hidden;font-weight: normal;}
  251. .dp-link-rt .dp-txt1 .dp-txt1-sp{display: inline-block;line-height: 1;padding: 2px;font-size:$h6;}
  252. .dp-link-rt .dp-txt1 .dp-txt1-sp2{line-height: 1;font-size:$h6;}
  253. .dp-link-rt .dp-txt1 .dp-txt1-sp3{display: inline-block;padding: 2px;line-height: 1;font-size:$h6;}
  254. .dp-link-rt .dp-txt2{display: block;margin-top: 8px;font-size:$fontSize;color: #999999;overflow: hidden;white-space: nowrap;text-overflow: ellipsis;}
  255. .dp-star {height: 14px; margin-top: 8px;overflow: hidden;font-size: 0;}
  256. .dp-star .dp-star-p1{height: 12px; padding-top: 2px;overflow: hidden;display: inline-block;position: relative;}
  257. .dp-star .dp-star-p2{font-size:$fontSize;line-height: 14px;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;color: #999;display: inline-block;}
  258. .dp-star .dp-star-sp { display: inline-block;font-size: 0;}
  259. .dp-line{display: inline-block;width: 8px;height: 10px;}
  260. .tx {position: absolute;font-size:$h6;background-color: #ff5757;color: #fff;top: -7px;right: 1px;min-width: 18px;height: 18px;border-radius: 18px;line-height: 18px;text-align: center;border: 2px solid #ffffff;}
  261. .dp-list-box{font-size: 0;vertical-align: top;white-space: nowrap;padding-top: 12px;}
  262. .dp-list-box .dp-a{position: relative;display: inline-block;overflow: hidden;width: 25%;text-align: center;font-size: 0;vertical-align: top; max-height: 105px;}
  263. .dp-list-box .dp-a .dp-sapn{position: relative;display: block;width: 60px;height: 60px;border: 1px solid #f7f7f7;border-radius: 3px;}
  264. .dp-list-box .dp-a .dp-sapn .img {display: inline-block;width: 100%;border-radius:4px;}
  265. .dp-list-box .dp-a .dp-sapn .dp-sapn-txt{ position: absolute;left: 0;top: 0;padding: 1px 2px;font-size:$h6;color: #FFF;background-color: #fc2c50;}
  266. .dp-list-box .dp-sapn-price{ }
  267. .dp-sapn-price {color: #ff5757;margin-top: 3px;}
  268. .dp-sapn-price {font-size:$fontSize;color: #ff5757;height: 17px;line-height: 17px;vertical-align: top;display: block;width: 62px;overflow: hidden; white-space: nowrap;text-overflow: ellipsis;}
  269. </style>