You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

511 lines
11 KiB

2 weeks ago
  1. <template>
  2. <div class="wrapper" :style="'top:'+statusBarHeight+'px'">
  3. <div class="header">
  4. <!-- <view class="back_div">
  5. <image class="back_img" @click="back_city()" src="@/static/images/back_img.png" mode=""></image>
  6. </view> -->
  7. <input class="input" @input="onInput" placeholder="搜索 中文/拼音/首字母" v-model="searchValue" />
  8. </div>
  9. <scroll-view class="calendar-list" scroll-y="true" :scroll-into-view="scrollIntoId">
  10. <view v-if="disdingwei" id="hot">
  11. <!-- 定位模块 -->
  12. <view class="dingwei">
  13. <view class="dingwei_Tips">
  14. 当前定位
  15. </view>
  16. <view class="dingwei_city">
  17. <view class="dingwei_city_one" @click="back_city(currentCity)">
  18. {{currentCity.cityName}}
  19. </view>
  20. <view class="dingweis_div" @click="getWarpweft">
  21. <image class="dingweis" src="@/static/images/dingweis.png" mode=""></image>
  22. <text>{{po_tips}}</text>
  23. </view>
  24. </view>
  25. </view>
  26. <!-- 最近模块 -->
  27. <view class="dingwei">
  28. <view class="dingwei_Tips">
  29. 热门城市
  30. </view>
  31. <view class="dingwei_city dingwei_city_zuijin">
  32. <view class="dingwei_city_one toright" v-for="(item,index) in hotCity" @click="back_city(item)">
  33. {{item.cityName}}
  34. </view>
  35. </view>
  36. </view>
  37. </view>
  38. <!-- 城市列表 -->
  39. <view v-if="searchValue == ''" v-for="(item, index) in list" :id="getId(index)" :key="index">
  40. <view class="letter-header">{{ getId(index) }}</view>
  41. <view class="city-div" v-for="(city, i) in item" :key="i" @click="back_city(city)">
  42. <text class="city">{{ city.cityName }}</text>
  43. </view>
  44. </view>
  45. <!-- 搜索结果 -->
  46. <view class="city-div" v-for="(item, index) in searchList" @click="back_city(item)">
  47. <text class="city">{{ item.cityName }}</text>
  48. </view>
  49. </scroll-view>
  50. <!-- 右侧字母 -->
  51. <view class="letters" v-if="searchValue == ''">
  52. <view class="letters-item" @click="scrollTo('hot')">最近</view>
  53. <view class="letters-item" v-for="item in letter" :key="item" @click="scrollTo(item)">{{ item }}</view>
  54. </view>
  55. <!-- 选中之后字母 -->
  56. <view class="mask" v-if="showMask">
  57. <view class="mask-r">{{selectLetter}}</view>
  58. </view>
  59. </div>
  60. </template>
  61. <script>
  62. import Citys from './city.js';
  63. import allCity from './allCity.js'
  64. import HotCity from './HotCity.js'
  65. import carStore from '@/store/modules/car.js'
  66. let usecarStore = carStore()
  67. import {
  68. jsonp
  69. } from 'vue-jsonp'
  70. export default {
  71. data() {
  72. return {
  73. statusBarHeight: this.statusBarHeight,
  74. ImgUrl: this.ImgUrl,
  75. letter: [],
  76. selectLetter: '',
  77. searchValue: '',
  78. scrollIntoId: '',
  79. list: [],
  80. tId: null,
  81. searchList: [],
  82. showMask: false,
  83. disdingwei: true,
  84. Visit: [], //最近访问
  85. currentCity: ' ',
  86. longitude: '', //经度
  87. latitude: '', //纬度
  88. seconds: 3,
  89. po_tips: '重新定位',
  90. citys: [],
  91. hotCity: HotCity
  92. }
  93. },
  94. created() {
  95. console.log(usecarStore)
  96. //获取存储的最近访问
  97. this.initcity()
  98. var that = this
  99. uni.getStorage({
  100. key: 'Visit_key',
  101. success: function(res) {
  102. that.Visit = res.data
  103. }
  104. });
  105. //获取定位 经度纬度
  106. that.getWarpweft()
  107. //获取city.js 的程序字母
  108. var mu = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'q', 'r', 's', 't', 'w', 'x',
  109. 'y',
  110. 'z'
  111. ];
  112. var tmp = [];
  113. for (var i = 0; i < mu.length; i++) {
  114. var item = mu[i];
  115. for (var j = 0; j < this.citys.length; j++) {
  116. var py = this.citys[j].py;
  117. if (py.substring(0, 1) == item) {
  118. if (tmp.indexOf(item) == -1) {
  119. this.list[i] = [this.citys[j]];
  120. tmp.push(item);
  121. this.letter.push(item.toUpperCase());
  122. } else {
  123. this.list[i].push(this.citys[j]);
  124. }
  125. }
  126. }
  127. }
  128. },
  129. methods: {
  130. initcity() {
  131. let cityArr = allCity.map(arr => {
  132. return arr.cityInfoList.map(item => {
  133. let obj = {
  134. cityName: item.cityName,
  135. pinYin: item.cityPinyin,
  136. py: item.cityAcronym.toLocaleLowerCase(),
  137. code: item.cityCode,
  138. cityInitial: item.cityInitial
  139. }
  140. return obj
  141. })
  142. })
  143. this.citys = cityArr.flat()
  144. console.log(this.citys)
  145. },
  146. getId(index) {
  147. return this.letter[index];
  148. },
  149. scrollTo(letter) {
  150. this.showMask = true
  151. this.selectLetter = letter == 'hot' ? '最' : letter
  152. setTimeout(() => {
  153. this.showMask = false
  154. }, 300);
  155. this.scrollIntoId = letter;
  156. },
  157. query(source, text) {
  158. console.log(source, text)
  159. let res = [];
  160. var self = this;
  161. res = source.filter(item => {
  162. const arr = [];
  163. let isHave = false;
  164. Object.keys(item).forEach(prop => {
  165. const itemStr = item[prop];
  166. self.isString(itemStr) &&
  167. itemStr.split(',').forEach(val => {
  168. arr.push(val);
  169. });
  170. });
  171. arr.some(val => {
  172. isHave = new RegExp('^' + text).test(val);
  173. return isHave;
  174. });
  175. return isHave;
  176. });
  177. console.log(JSON.stringify(res));
  178. return res;
  179. },
  180. isString(obj) {
  181. return typeof obj === 'string';
  182. },
  183. onInput(e) {
  184. const value = e.detail.value;
  185. console.log(value);
  186. if (value !== '' && this.citys && this.citys.length > 0) {
  187. const queryData = this.query(this.citys, String(value).trim());
  188. this.searchList = queryData;
  189. this.disdingwei = false
  190. } else {
  191. this.searchList = [];
  192. this.disdingwei = true
  193. }
  194. },
  195. back_city(item) {
  196. if (item) {
  197. console.log(item)
  198. usecarStore.setCar('city', item.code)
  199. usecarStore.setCar('cityName', item.cityName)
  200. uni.navigateBack()
  201. return
  202. this.$emit('back_city', item);
  203. //unshift 把数据插入到首位,与push相反
  204. this.Visit.unshift(item)
  205. this.searchValue = "";
  206. this.disdingwei = true
  207. var arr = this.Visit
  208. //数组去重
  209. function distinct(arr) {
  210. let newArr = []
  211. for (let i = 0; i < arr.length; i++) {
  212. if (newArr.indexOf(arr[i]) < 0) {
  213. newArr.push(arr[i])
  214. }
  215. }
  216. return newArr
  217. }
  218. this.Visit = distinct(arr)
  219. console.log(this.Visit, "---最近访问")
  220. uni.setStorage({
  221. key: 'Visit_key',
  222. data: this.Visit
  223. });
  224. } else {
  225. this.$emit('back_city', 'no');
  226. }
  227. },
  228. // IDZBZ-L5GCZ-EQXXA-ZR5K4-JTSXH-IQBLO
  229. getWarpweft() {
  230. var that = this
  231. that.po_tips = '定位中...'
  232. // let key = 'NRWBZ-TKRWV-CSAPH-5PFDS-J4HT6-IWF4O'
  233. let key = 'IDZBZ-L5GCZ-EQXXA-ZR5K4-JTSXH-IQBLO'
  234. let countdown = setInterval(() => {
  235. that.seconds--;
  236. uni.getLocation({
  237. type: 'wgs84',
  238. success: function(res) {
  239. console.log('当前位置的经度:' + res.longitude);
  240. console.log('当前位置的纬度:' + res.latitude);
  241. that.longitude = res.longitude
  242. that.latitude = res.latitude
  243. let url = 'https://apis.map.qq.com/ws/geocoder/v1/'
  244. jsonp(url, {
  245. key: key,
  246. location: res.latitude + ',' + res.longitude,
  247. output: 'jsonp'
  248. }).then(res => {
  249. console.log('jsonp', res.result.address_component);
  250. let {
  251. province,
  252. city,
  253. district
  254. } = res.result.address_component;
  255. that.province = province;
  256. that.city = city;
  257. that.area = district;
  258. console.log(province, city, district);
  259. that.currentCity = that.citys.find(item=>item.cityName==city)
  260. if(!that.currentCity) {
  261. uni.$u.toast('获取定位失败,请手动选择城市')
  262. }
  263. console.log(that.currentCity, '当前城市')
  264. }).catch(()=>{
  265. uni.$u.toast('获取定位失败,请手动选择城市')
  266. })
  267. },
  268. fail() {
  269. uni.$u.toast('获取定位失败,请手动选择城市')
  270. }
  271. })
  272. if (that.seconds <= 0) {
  273. that.seconds = 3
  274. that.po_tips = '重新定位'
  275. clearInterval(countdown);
  276. }
  277. },
  278. 1000);
  279. }
  280. }
  281. };
  282. </script>
  283. <style scoped>
  284. .wrapper {
  285. /* position: fixed;
  286. z-index: 999999;
  287. background: #ffffff;
  288. height: 100%;
  289. width: 100%;
  290. top: 0px;
  291. left: 0px; */
  292. }
  293. .mask {
  294. position: absolute;
  295. bottom: 0rpx;
  296. top: 83rpx;
  297. left: 0rpx;
  298. right: 0rpx;
  299. width: 750rpx;
  300. display: flex;
  301. justify-content: center;
  302. align-items: center;
  303. background: rgba(0, 0, 0, 0);
  304. }
  305. .mask-r {
  306. height: 120rpx;
  307. width: 120rpx;
  308. border-radius: 60rpx;
  309. display: flex;
  310. background: rgba(0, 0, 0, 0.5);
  311. justify-content: center;
  312. align-items: center;
  313. font-size: 40rpx;
  314. color: #FFFFFF
  315. }
  316. .content {
  317. height: 100%;
  318. width: 100%;
  319. background-color: #ffffff;
  320. }
  321. .header {
  322. height: 100rpx;
  323. display: flex;
  324. justify-content: center;
  325. align-items: center;
  326. }
  327. .back_div {
  328. width: 65rpx;
  329. height: 100%;
  330. display: flex;
  331. justify-content: center;
  332. align-items: center;
  333. }
  334. .back_img {
  335. width: 35rpx;
  336. height: 35rpx;
  337. }
  338. .input {
  339. font-size: 28rpx;
  340. width: 620rpx;
  341. height: 70rpx;
  342. border-radius: 40rpx;
  343. background-color: #F5F5F5;
  344. padding-left: 20rpx;
  345. padding-right: 20rpx;
  346. box-sizing: border-box;
  347. }
  348. .title {
  349. font-size: 30rpx;
  350. color: white;
  351. }
  352. .show {
  353. left: 0;
  354. width: 100%;
  355. transition: left 0.3s ease;
  356. }
  357. .hide {
  358. left: 100%;
  359. width: 100%;
  360. transition: left 0.3s ease;
  361. }
  362. .title {
  363. font-size: 30rpx;
  364. color: white;
  365. }
  366. .calendar-list {
  367. position: absolute;
  368. top: 83rpx;
  369. bottom: 0rpx;
  370. width: 100%;
  371. background-color: #FFFFFF;
  372. }
  373. .letters {
  374. position: absolute;
  375. right: 30rpx;
  376. bottom: 0px;
  377. width: 50rpx;
  378. top: 260rpx;
  379. color: #2f9bfe;
  380. text-align: center;
  381. font-size: 24rpx;
  382. }
  383. .letters-item {
  384. margin-bottom: 5rpx;
  385. }
  386. .letter-header {
  387. height: 45rpx;
  388. font-size: 22rpx;
  389. color: #333333;
  390. padding-left: 24rpx;
  391. box-sizing: border-box;
  392. display: flex;
  393. align-items: center;
  394. background-color: #ebedef;
  395. }
  396. .city-div {
  397. width: 660rpx;
  398. height: 85rpx;
  399. margin-left: 24rpx;
  400. border-bottom-width: 0.5rpx;
  401. border-bottom-color: #ebedef;
  402. border-bottom-style: solid;
  403. display: flex;
  404. align-items: center;
  405. margin-right: 35rpx;
  406. }
  407. .city {
  408. font-size: 28rpx;
  409. color: #000000;
  410. padding-left: 30rpx;
  411. }
  412. .dingwei {
  413. width: 100%;
  414. padding-top: 25rpx;
  415. box-sizing: border-box;
  416. margin-bottom: 26rpx;
  417. }
  418. .dingwei_Tips {
  419. margin-left: 24rpx;
  420. margin-bottom: 24rpx;
  421. font-size: 24rpx;
  422. color: #A5A5A5;
  423. }
  424. .dingwei_city {
  425. width: 100%;
  426. height: 60rpx;
  427. padding-left: 55rpx;
  428. padding-right: 70rpx;
  429. box-sizing: border-box;
  430. display: flex;
  431. justify-content: space-between;
  432. }
  433. .dingwei_city_one {
  434. width: 185rpx;
  435. height: 60rpx;
  436. background-color: #F5F5F5;
  437. border-radius: 10rpx;
  438. font-size: 32rpx;
  439. color: #333333;
  440. display: flex;
  441. justify-content: center;
  442. align-items: center;
  443. }
  444. .dingweis_div {
  445. display: flex;
  446. align-content: flex-end;
  447. align-items: center;
  448. font-size: 24rpx;
  449. color: #FD5745;
  450. }
  451. .dingweis {
  452. width: 32rpx;
  453. height: 32rpx;
  454. }
  455. .dingwei_city_zuijin {
  456. display: flex;
  457. justify-content: flex-start;
  458. }
  459. .toright {
  460. margin-right: 25rpx;
  461. }
  462. </style>