list.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572
  1. <template>
  2. <view class="list">
  3. <view class="search" v-if="showFrame">
  4. <div class="dist_search">
  5. <picker @change="bindPickerChange" :value="cityIndex" :range="cityArr">
  6. <view class="district">{{cityArr[cityIndex]}}</view>
  7. </picker>
  8. <view class="icon"></view>
  9. </div>
  10. <view class="separate">
  11. </view>
  12. <view class="inp">
  13. <view class="icon">
  14. </view>
  15. <input type="text" v-model="filterCityText" placeholder="请输入油站名称" />
  16. </view>
  17. </view>
  18. <view class="postion" v-if="showFrame">
  19. <view class="icon"></view>
  20. <view class="current" @click="reGetLocation">
  21. 当前位置:{{location}}
  22. </view>
  23. <view class="refresh" @click="refresh">
  24. </view>
  25. </view>
  26. <view class="distance"
  27. style="margin-top: 200rpx;text-align: center;"
  28. v-if="moreDistanceTipShow"
  29. >
  30. 您附近{{distanceShow}}公里内没有油站
  31. </view>
  32. <view class="collection">
  33. <view class="station"
  34. v-for="ele in filterDistanceArr"
  35. @click="goBuy($event, ele.stationId)"
  36. >
  37. <view class="content">
  38. <image :src="ele.stationPic" mode=""></image>
  39. <view class="detail">
  40. <view class="name">{{ ele.stationName }}</view>
  41. <view class="other">
  42. <text v-if="ele.distance!==undefined">{{ele.distance + ' '}}km | </text>
  43. {{ ' ' + ele.stationAddress }}
  44. </view>
  45. </view>
  46. </view>
  47. <view class="footer">
  48. <view class="gothere" @click.stop="goThere($event, ele.stationLatitude, ele.stationLongitude, ele.stationName, ele.stationAddress)">
  49. 去这里
  50. </view>
  51. <view class="separator">|</view>
  52. <view class="gobuy" @click.stop="goBuy($event, ele.stationId)">
  53. 去买单
  54. </view>
  55. </view>
  56. </view>
  57. </view>
  58. </view>
  59. </template>
  60. <script>
  61. import {
  62. mapState,
  63. mapMutations,
  64. mapGetters
  65. } from "vuex";
  66. import Parse from "../../util/parse.js"
  67. import settings from '@/settings.js'
  68. // import getPermission from "../../util/permission.js"
  69. export default {
  70. data() {
  71. return {
  72. // notice: '',
  73. stationList: [],
  74. filterCityText: '',
  75. res: {},
  76. // cityArr:['泰安市','济南市'],
  77. cityIndex:0,
  78. location:'正在拼命拉取中...',
  79. showFrame:false,
  80. showDistanceEmptyListTip:false,
  81. distanceShow:settings.distanceShow
  82. }
  83. },
  84. async created() {
  85. // 调试
  86. // wx.setEnableDebug({
  87. // enableDebug: true
  88. // })
  89. this.initAli()
  90. this.init()
  91. },
  92. computed: {
  93. moreDistanceTipShow(){
  94. return settings.distanceFlag && settings.distanceShow!=0 && this.filterDistanceArr.length == 0 && this.showDistanceEmptyListTip
  95. },
  96. filterCityArr(){
  97. return this.stationList.filter((ele)=>{
  98. if(this.cityArr[this.cityIndex] == '全部'){
  99. return ele.stationName.includes(this.filterCityText) || ele.stationAddress.includes(this.filterCityText)
  100. }
  101. return ele.city === this.cityArr[this.cityIndex] && (ele.stationName.includes(this.filterCityText) || ele.stationAddress.includes(this.filterCityText))
  102. })
  103. },
  104. cityArr(){
  105. const cityArrSet = new Set(['全部']);
  106. this.stationList.map((ele)=>{
  107. cityArrSet.add(ele.city)
  108. })
  109. return [...cityArrSet]
  110. },
  111. filterDistanceArr(){
  112. if(settings.distanceFlag){
  113. if(settings.distanceShow!=0){
  114. return this.filterCityArr.filter((ele)=>{
  115. return ele.distance <= settings.distanceShow
  116. })
  117. }
  118. }
  119. return this.filterCityArr
  120. }
  121. },
  122. methods: {
  123. ...mapMutations(["updateStationId","clearEmployeeId"]),
  124. test() {
  125. console.log(132)
  126. },
  127. initAli(){
  128. // #ifdef MP-ALIPAY
  129. settings.distanceFlag = true;
  130. settings.distanceShow = settings.aLiDistanceShow;
  131. // #endif
  132. },
  133. async init() {
  134. uni.showLoading({
  135. title: '加载中...',
  136. mask: true
  137. });
  138. const oldStationList = this.stationList;
  139. const oldLocation = this.location
  140. try{
  141. this.location = '正在拼命拉取中...'
  142. //#ifdef MP-WEIXIN
  143. const stationListData = await this.$Request({
  144. url: "/getStationListByAppId",
  145. method: "GET",
  146. data: {
  147. appId: this.appId
  148. }
  149. })
  150. //#endif
  151. //#ifdef MP-ALIPAY
  152. const stationListData = await this.$Request({
  153. url: "/getStationListToAliPay",
  154. method: "GET",
  155. data: {
  156. // appId: this.appId
  157. }
  158. })
  159. //#endif
  160. if(stationListData.retCode !== 0){
  161. throw new Error("初始油站信息失败")
  162. }
  163. // 单站
  164. if(stationListData.data.length === 1){
  165. this.updateStationId(stationListData.data[0].stationId)
  166. const [redirectErr, redirectData] = await uni.redirectTo({
  167. url: "/pages/index/index"
  168. })
  169. return
  170. }
  171. if(settings.distanceFlag && settings.distanceShow==0){
  172. this.stationList = []
  173. }else{
  174. this.stationList = stationListData.data;
  175. this.showFrame = true;
  176. }
  177. const locationData = await uni.getLocation()
  178. if(locationData[0] !== null && locationData[0].errMsg === 'getLocation:fail auth deny' ){
  179. // 用户拒绝位置
  180. this.location = "您拒绝了授权,点击重新获取~"
  181. this.showFrame = true;
  182. uni.hideLoading();
  183. return
  184. }else if(locationData[0] !== null && locationData[0].errMsg === 'getLocation:fail 频繁调用会增加电量损耗,可考虑使用 wx.onLocationChange 监听地理位置变化' ){
  185. // 频繁调用时兼容处理
  186. this.location = oldLocation
  187. this.stationList = oldStationList
  188. this.showFrame = true;
  189. uni.hideLoading();
  190. return
  191. }else if(locationData[0] !== null && locationData[0].errMsg === 'getLocation:fail:ERROR_NOCELL&WIFI_LOCATIONSWITCHOFF' ){
  192. this.location = "您的手机未开启定位"
  193. this.showFrame = true;
  194. uni.hideLoading();
  195. return
  196. }else if(locationData[0] !== null){
  197. this.location = "没有获取到您的位置"
  198. this.showFrame = true;
  199. uni.hideLoading();
  200. return
  201. }
  202. //#ifdef MP-WEIXIN
  203. const stationLocationData = await this.$Request({
  204. url: "/getStationInfoListNew",
  205. method: "GET",
  206. data: {
  207. stationLongitude:locationData[1].longitude,
  208. stationLatitude: locationData[1].latitude,
  209. pageNum: 1,
  210. pageSize:1000,
  211. appId: this.appId
  212. }
  213. })
  214. //#endif
  215. //#ifdef MP-ALIPAY
  216. const stationLocationData = await this.$Request({
  217. url: "/getStationInfoListNewToAliPay",
  218. method: "GET",
  219. data: {
  220. stationLongitude:locationData[1].longitude,
  221. stationLatitude: locationData[1].latitude,
  222. pageNum: 1,
  223. pageSize:1000,
  224. appId: this.appId
  225. }
  226. })
  227. //#endif
  228. if(stationLocationData.retCode !== 0){
  229. throw new Error("获取定位信息失败")
  230. }
  231. this.location = stationLocationData.data.address
  232. if(settings.distanceFlag && settings.distanceShow==0){
  233. this.goBuyReplace(stationLocationData.data.stationInfoResponseList[0].stationId)
  234. this.stationList = []
  235. }else{
  236. this.showDistanceEmptyListTip = true
  237. this.stationList = stationLocationData.data.stationInfoResponseList
  238. }
  239. // const stationLocationListData = await this.$Request({
  240. // url: "/getStationInfoList",
  241. // method: "GET",
  242. // data: {
  243. // stationLongitude:locationData[1].longitude,
  244. // stationLatitude: locationData[1].latitude,
  245. // pageNum: 1,
  246. // pageSize:1000,
  247. // appId: this.appId
  248. // }
  249. // })
  250. // if(stationLocationListData.retCode !== 0){
  251. // throw new Error("获取详细油站信息失败")
  252. // }
  253. // this.stationList = stationLocationListData.data.stationInfoResponseList
  254. uni.hideLoading();
  255. }catch(e){
  256. // uni.hideLoading();
  257. uni.showToast({
  258. title: e
  259. })
  260. }
  261. },
  262. goBuy(e, stationId) {
  263. if(!!e){
  264. e.stopPropagation()
  265. }
  266. this.updateStationId(stationId)
  267. this.clearEmployeeId()
  268. uni.navigateTo({
  269. url: "/pages/index/index"
  270. })
  271. return
  272. },
  273. goBuyReplace(stationId) {
  274. this.updateStationId(stationId)
  275. this.clearEmployeeId()
  276. uni.redirectTo({
  277. url: "/pages/index/index"
  278. })
  279. return
  280. },
  281. goThere(e, latitude, longitude, stationName, stationAddress) {
  282. e.stopPropagation()
  283. uni.openLocation({
  284. name: stationName,
  285. address: stationAddress,
  286. latitude: parseFloat(latitude),
  287. longitude: parseFloat(longitude),
  288. success: function() {
  289. console.log('success');
  290. }
  291. });
  292. },
  293. async refresh(){
  294. // uni.getSetting({
  295. // success(res) {
  296. // console.log(res.authSetting)
  297. // }
  298. // })
  299. this.init()
  300. },
  301. async reGetLocation(){
  302. const that = this
  303. // try{
  304. const getSetPro = await uni.getSetting()
  305. if(getSetPro[0] === null){
  306. if(!getSetPro[1].authSetting['scope.userLocation']){
  307. uni.openSetting({
  308. success(res) {
  309. if(res.authSetting['scope.userLocation']){
  310. that.refresh();
  311. }else{
  312. uni.showToast({
  313. icon:'error',
  314. title:'还没授权呦~',
  315. mask: true
  316. })
  317. }
  318. }
  319. })
  320. }else{
  321. that.refresh()
  322. }
  323. }else{
  324. throw new Error("")
  325. }
  326. // }catch(e){
  327. // uni.showToast({
  328. // icon:'error',
  329. // title:'授权时出错~',
  330. // duration:1200,
  331. // mask: true
  332. // })
  333. // setTimeout(()=>{
  334. // that.refresh();
  335. // },1600)
  336. // }
  337. },
  338. bindPickerChange(e){
  339. this.cityIndex = e.detail.value
  340. }
  341. }
  342. }
  343. </script>
  344. <style lang="scss">
  345. page {
  346. .list {
  347. padding: 30rpx;
  348. background: #F6F6F6;
  349. height: 100vh;
  350. .search {
  351. width: 690rpx;
  352. height: 80rpx;
  353. background: #FFFFFF;
  354. box-shadow: 0px 2rpx 9rpx 4rpx rgba(99, 99, 99, 0.1);
  355. border-radius: 40rpx;
  356. // position: relative;
  357. display:flex;
  358. flex-direction: row;
  359. justify-content:space-around;
  360. align-items: center;
  361. .dist_search {
  362. height: 80rpx;
  363. max-width: 130rpx;
  364. white-space: nowrap;
  365. display: flex;
  366. margin-left: 20rpx;
  367. .district {
  368. height: 80rpx;
  369. font-size: 28rpx;
  370. font-weight: bold;
  371. color: #111111;
  372. line-height: 80rpx;
  373. overflow: hidden;
  374. white-space: nowrap;
  375. text-overflow: ellipsis;
  376. max-width: 110rpx;
  377. }
  378. >.icon {
  379. background: url(../../static/icon/1_b01_down.2x.png) no-repeat 0px 0px;
  380. background-size: 100% 100%;
  381. width: 13rpx;
  382. height: 8rpx;
  383. line-height: 80rpx;
  384. margin-top: 38rpx;
  385. margin-left: 10rpx;
  386. }
  387. }
  388. .separate {
  389. width: 0rpx;
  390. height: 35rpx;
  391. border: 1rpx solid #CCCCCC;
  392. box-sizing: border-box;
  393. // position: absolute;
  394. // top: 20rpx;
  395. // left: 180rpx;
  396. }
  397. .inp {
  398. // position: absolute;
  399. // top: 15rpx;
  400. // left: 200rpx;
  401. width: 450rpx;
  402. height: 80rpx;
  403. // position: relative;
  404. .icon {
  405. display: inline-block;
  406. background: url(../../static/icon/1_b01_search.2x.png) no-repeat 0px 0px;
  407. background-size: 100% 100%;
  408. width: 26rpx;
  409. height: 26rpx;
  410. margin-bottom: 25rpx;
  411. // // top: 162rpx;
  412. // position: absolute;
  413. // top: 27rpx;
  414. }
  415. >input {
  416. display: inline-block;
  417. margin-left: 20rpx;
  418. width: 310rpx;
  419. height: 80rpx;
  420. line-height: 80rpx;
  421. background:none;
  422. outline:none;
  423. border:none;
  424. }
  425. }
  426. }
  427. .postion {
  428. margin: 30rpx 30rpx 0 30rpx ;
  429. .icon {
  430. background: url(../../static/icon/1_b01_location.2x.png) no-repeat 0px 0px;
  431. background-size: 100% 100%;
  432. width: 33rpx;
  433. height: 35rpx;
  434. display: inline-block;
  435. }
  436. .current {
  437. margin-left: 20rpx;
  438. display: inline-block;
  439. height: 40rpx;
  440. font-size: 28rpx;
  441. color: #868686;
  442. line-height: 40rpx;
  443. max-width: 550rpx;
  444. overflow: hidden;
  445. white-space: nowrap;
  446. text-overflow: ellipsis;
  447. }
  448. .refresh {
  449. background: url(../../static/icon/icon_shuaxin.2x.png) no-repeat 0px 0px;
  450. background-size: 100% 100%;
  451. // background-color: #868686;
  452. margin-top: 5rpx;
  453. width: 27rpx;
  454. height: 27rpx;
  455. float: right;
  456. }
  457. }
  458. .collection {
  459. margin-top: 30rpx;
  460. .station {
  461. margin-bottom: 30rpx;
  462. // padding: 30rpx;
  463. padding: 40rpx;
  464. width: 690rpx;
  465. height: 285rpx;
  466. background: #FFFFFF;
  467. box-shadow: 0px 2rpx 9rpx 4rpx rgba(99, 99, 99, 0.1);
  468. border-radius: 18rpx;
  469. box-sizing: border-box;
  470. .content {
  471. display: flex;
  472. >image {
  473. width: 155rpx;
  474. height: 155rpx;
  475. display: inline-block;
  476. }
  477. .detail {
  478. margin-left: 20rpx;
  479. width: 450rpx;
  480. height: 155rpx;
  481. display: inline-block;
  482. .name {
  483. height: 45rpx;
  484. font-size: 32rpx;
  485. font-weight: bold;
  486. color: #111111;
  487. line-height: 45rpx;
  488. overflow: hidden;
  489. white-space: nowrap;
  490. text-overflow: ellipsis;
  491. }
  492. }
  493. }
  494. .footer {
  495. margin-top: 40rpx;
  496. display: flex;
  497. justify-content: space-around;
  498. .gothere {
  499. height: 40rpx;
  500. width: 250rpx;
  501. font-size: 28rpx;
  502. font-weight: bold;
  503. color: #6c6c6c;
  504. line-height: 40rpx;
  505. text-align: center;
  506. }
  507. .separator {
  508. // width: 1px;
  509. // height: 46rpx;
  510. // border: 1px solid #CCCCCC;
  511. color: #CCCCCC;
  512. }
  513. .gobuy {
  514. height: 40rpx;
  515. font-size: 28rpx;
  516. font-weight:bold;
  517. width: 250rpx;
  518. color: #F3B235;
  519. line-height: 40rpx;
  520. text-align: center;
  521. }
  522. }
  523. }
  524. }
  525. }
  526. }
  527. </style>