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.

513 lines
11 KiB

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