index.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624
  1. <template>
  2. <view :style="colorStyle">
  3. <view class="navbar">
  4. <view :class="{ on: content.store_type === 1 }" class="item" @tap="navChange(1)">选择门店</view>
  5. <view :class="{ on: content.store_type === 2 }" class="item" @tap="navChange(2)">常用门店</view>
  6. </view>
  7. <view class="header_search" v-if="!header">
  8. <!-- <view class="title">
  9. 搜索门店
  10. </view> -->
  11. <view class="box acea-row row-center-wrapper">
  12. <input type="text" placeholder="搜索门店" class="input" focus @input="setValue" v-model="content.keyword"></input>
  13. <text class="iconfont icon-sousuo6" />
  14. </view>
  15. </view>
  16. <!-- <transition-group name="lyric" v-if="header">
  17. <map style="width: 100%; height: 668rpx;" :latitude="latitudeStore" :longitude="longitudeStore" :markers="covers" v-if="map" :key="1" />
  18. </transition-group> -->
  19. <!-- 附近门店 -->
  20. <view class="nearby" v-if="header">
  21. <view class="store acea-row row-middle">
  22. <!-- <view class="btn" :class="{'activeColor':active==1}" @click="btnFn(1)">
  23. 附近门店
  24. </view> -->
  25. <view class="area">
  26. <view class="btn" :class="{'activeColor':active==2}" @click="btnFn(2)">
  27. {{ addressInfo.length ? addressInfo[1].label : '全部门店' }}
  28. <text class="iconfont icon-xiangxia"></text>
  29. </view>
  30. </view>
  31. <view class="search" @click="searchMap()">
  32. <text class="iconfont icon-sousuo6"></text>
  33. </view>
  34. <view class="search" @click="goMap">
  35. <text class="iconfont icon-ditu1"></text>
  36. </view>
  37. <!-- <view class="put" @click="putMap()">
  38. <text class="iconfont icon-xiangshang" v-if="map==1" />
  39. <text class="iconfont icon-xiangxia" v-else />
  40. {{map==1?"收起地图":"展开地图"}}
  41. </view> -->
  42. </view>
  43. </view>
  44. <!-- 门店列表 -->
  45. <view class="content" v-if="info.length>0">
  46. <view class="list acea-row row-between-wrapper" v-for="(item,index) in info" :key="index" @click="activeFn(item)" :class="{active:sortIndex==item.id}">
  47. <text class="iconfont icon-xuanzhong6" v-if="sortIndex==item.id"></text>
  48. <view class="left">
  49. <view class="name line2">
  50. {{item.name}}
  51. </view>
  52. <view class="adress acea-row">
  53. <text class="iconfont icon-dingwei2" />
  54. <view class="con">{{item.detailed_address}}</view>
  55. </view>
  56. <view class="adress">
  57. <text class="iconfont icon-yingyeshijian2" />
  58. 营业时间:{{item.day_time}}
  59. </view>
  60. </view>
  61. <view class="right">
  62. <view class="gostore">
  63. 进店选购
  64. </view>
  65. <view class="distance">
  66. 距离{{item.range}}km
  67. </view>
  68. <view class="telephone">
  69. <view class="phone" @click.stop="callPhone(item)">
  70. <text class="iconfont icon-dianhua"></text>
  71. </view>
  72. <view class="phone" @click.stop="showMaoLocation(item)">
  73. <text class="iconfont icon-dingwei2"></text>
  74. </view>
  75. </view>
  76. </view>
  77. </view>
  78. </view>
  79. <!-- 缺省页 -->
  80. <view class="default" v-if="info.length==0">
  81. <image :src="imgHost+'/statics/images/store-default.png'" mode="" class="img"></image>
  82. <view class="text">
  83. 暂无门店信息,再去试试其他地址吧~
  84. </view>
  85. </view>
  86. <areaWindow ref="areaWindow" :display="display" :cityShow="2" :address="addressInfo" @submit="OnChangeAddress" @changeClose="changeClose"></areaWindow>
  87. </view>
  88. </template>
  89. <script>
  90. import {
  91. HTTP_REQUEST_URL
  92. } from '@/config/app';
  93. import colors from "@/mixins/color";
  94. import {
  95. getList
  96. } from '@/api/new_store.js'
  97. import {
  98. getGeocoder,
  99. getCityList
  100. } from '@/api/user.js';
  101. import areaWindow from '@/components/areaWindow';
  102. export default {
  103. components: {
  104. areaWindow
  105. },
  106. mixins: [colors],
  107. data() {
  108. return {
  109. imgHost: HTTP_REQUEST_URL,
  110. sortIndex: 0,
  111. active: 1,
  112. content: {
  113. // 自己的位置
  114. latitude: uni.getStorageSync('user_latitude'),
  115. longitude: uni.getStorageSync('user_longitude'),
  116. store_type: 1,
  117. keyword: "",
  118. // limit: 10,
  119. page: 1,
  120. province: 0,
  121. city: 0,
  122. area: 0,
  123. },
  124. info: [],
  125. map: 1,
  126. header: 1,
  127. comeType: 0,
  128. // 门店位置
  129. latitudeStore: uni.getStorageSync('user_latitude'),
  130. longitudeStore: uni.getStorageSync('user_longitude'),
  131. covers: [],
  132. display: false,
  133. addressInfo: [],
  134. };
  135. },
  136. onLoad(options) {
  137. this.comeType = options.type
  138. this.sortIndex = options.storeId
  139. this.isCollage = options.isCollage
  140. this.getlist()
  141. // try {
  142. // if (this.content.latitude && this.content.longitude && options.storeFrom == 1) {
  143. // // this.getlist()
  144. // this.selfLocation();
  145. // } else {
  146. // this.selfLocation();
  147. // }
  148. // } catch (e) {
  149. // this.getlist()
  150. // }
  151. },
  152. methods: {
  153. goMap() {
  154. uni.navigateTo({
  155. url: `/pages/store/map/index?province=${this.content.province}&city=${this.content.city}&area=${this.content.area}`
  156. })
  157. },
  158. navChange(type) {
  159. this.content.store_type = type;
  160. this.getlist();
  161. },
  162. getCityList({
  163. province,
  164. city,
  165. district
  166. }) {
  167. getCityList(`${province}/${city}/${district}`).then(({
  168. data
  169. }) => {
  170. this.addressInfo = data;
  171. this.content.province = data[0].value;
  172. this.content.city = data[1].value;
  173. this.content.area = data[2].value;
  174. this.getlist();
  175. });
  176. },
  177. getGeocoder(location) {
  178. getGeocoder(location).then(res => {
  179. const {
  180. province,
  181. city,
  182. district
  183. } = res.data.address_component;
  184. this.getCityList({
  185. province,
  186. city,
  187. district
  188. });
  189. });
  190. },
  191. selfLocation() {
  192. let self = this
  193. // #ifdef H5
  194. if (self.$wechat.isWeixin()) {
  195. self.$wechat.location().then(res => {
  196. this.content.latitude = res.latitude;
  197. this.content.longitude = res.longitude;
  198. uni.setStorageSync('user_latitude', res.latitude);
  199. uni.setStorageSync('user_longitude', res.longitude);
  200. self.getlist();
  201. }).catch(err => {
  202. self.getlist();
  203. })
  204. } else {
  205. // #endif
  206. uni.getLocation({
  207. type: 'wgs84',
  208. success: ({
  209. latitude,
  210. longitude
  211. }) => {
  212. try {
  213. // this.content.latitude = res.latitude;
  214. // this.content.longitude = res.longitude;
  215. // uni.setStorageSync('user_latitude', res.latitude);
  216. // uni.setStorageSync('user_longitude', res.longitude);
  217. this.getGeocoder({
  218. lat: latitude,
  219. long: longitude
  220. });
  221. } catch {}
  222. // self.getlist();
  223. },
  224. complete: function() {
  225. // self.getlist();
  226. }
  227. });
  228. // #ifdef H5
  229. }
  230. // #endif
  231. },
  232. // 门店列表
  233. getlist() {
  234. getList(this.content).then(res => {
  235. this.info = res.data
  236. res.data.forEach(item => {
  237. if (this.sortIndex == item.id) {
  238. this.latitudeStore = item.latitude;
  239. this.longitudeStore = item.longitude;
  240. this.covers.push({
  241. title: item.name,
  242. latitude: item.latitude,
  243. longitude: item.longitude,
  244. iconPath: item.image,
  245. width: 30,
  246. height: 30
  247. })
  248. }
  249. })
  250. })
  251. },
  252. // 输入关键字搜索门店
  253. setValue(e) {
  254. this.getlist()
  255. },
  256. // 点击高亮
  257. activeFn(row) {
  258. this.sortIndex = row.id
  259. if (this.comeType) {
  260. if (this.isCollage == 1) {
  261. uni.$emit('activeFn', row);
  262. uni.navigateBack();
  263. return;
  264. }
  265. uni.reLaunch({
  266. url: `/pages/store_cate/store_cate?mapFrom=1&id=` + row.id
  267. });
  268. }
  269. },
  270. // 搜索门店
  271. searchMap() {
  272. this.header = 0
  273. },
  274. // 收起地图
  275. putMap() {
  276. if (this.map == 1) {
  277. this.map = 0
  278. } else if (this.map == 0) {
  279. this.map = 1
  280. }
  281. },
  282. // 打电话
  283. callPhone(row) {
  284. uni.makePhoneCall({
  285. phoneNumber: row.phone //仅为示例
  286. });
  287. },
  288. btnFn(num) {
  289. // switch (num) {
  290. // case 1:
  291. // this.active = 1
  292. // this.content.store_type = 1
  293. // break;
  294. // case 2:
  295. // this.active = 2
  296. // this.content.store_type = 2
  297. // break;
  298. // }
  299. // this.getlist()
  300. this.display = true;
  301. },
  302. showMaoLocation(e) {
  303. let self = this;
  304. // #ifdef H5
  305. if (self.$wechat.isWeixin()) {
  306. return self.$wechat.seeLocation({
  307. latitude: Number(e.latitude),
  308. longitude: Number(e.longitude),
  309. name: e.name,
  310. scale: 13,
  311. address: `${e.address}-${e.detailed_address}`,
  312. }).then(res => {})
  313. }
  314. // #endif
  315. uni.openLocation({
  316. latitude: Number(e.latitude),
  317. longitude: Number(e.longitude),
  318. name: e.name,
  319. address: `${e.address}-${e.detailed_address}`,
  320. success: function() {
  321. Number
  322. }
  323. });
  324. },
  325. changeClose() {
  326. this.display = false;
  327. },
  328. OnChangeAddress(address) {
  329. this.addressInfo = address;
  330. this.content.province = address[0].value;
  331. this.content.city = address[1].value;
  332. this.content.area = address[2].value;
  333. this.getlist();
  334. }
  335. }
  336. }
  337. </script>
  338. <style lang="scss">
  339. .nearby .active,
  340. .content .active {
  341. position: relative;
  342. border: 1px solid var(--view-theme) !important;
  343. .icon-xuanzhong6 {
  344. font-size: 46rpx;
  345. position: absolute;
  346. bottom: -8rpx;
  347. right: -6rpx;
  348. color: var(--view-theme);
  349. }
  350. }
  351. .activeColor {
  352. background-color: var(--view-theme) !important;
  353. color: #fff !important;
  354. }
  355. .nearby {
  356. width: 100%;
  357. height: 132rpx;
  358. background-color: #fff;
  359. // border-radius: 40rpx 40rpx 0rpx 0rpx;
  360. // box-shadow: 0px -2px 22px 0px rgba(0, 0, 0, 0.0400);
  361. .store {
  362. height: 132rpx;
  363. padding: 0 30rpx;
  364. .btn {
  365. margin-right: 16rpx;
  366. width: 160rpx;
  367. height: 56rpx;
  368. // background: #F5F5F5;
  369. border-radius: 29rpx;
  370. text-align: center;
  371. line-height: 56rpx;
  372. font-size: 26rpx;
  373. font-weight: 400;
  374. color: #999999;
  375. }
  376. .search {
  377. display: flex;
  378. justify-content: center;
  379. align-items: center;
  380. width: 56rpx;
  381. height: 56rpx;
  382. border-radius: 50%;
  383. background-color: #F5F5F5;
  384. +.search {
  385. margin-left: 28rpx;
  386. }
  387. .iconfont {
  388. font-size: 30rpx;
  389. color: #666666;
  390. }
  391. }
  392. }
  393. }
  394. .content {
  395. width: 100%;
  396. height: 100%;
  397. padding: 0 30rpx;
  398. .list {
  399. display: flex;
  400. margin-top: 20rpx;
  401. width: 100%;
  402. background: #FFFFFF;
  403. border-radius: 12rpx;
  404. padding: 28rpx 30rpx;
  405. border: 1px solid #fff;
  406. overflow: hidden;
  407. .left {
  408. width: 450rpx;
  409. border-right: 1px solid #eee;
  410. padding-right: 20rpx;
  411. .name {
  412. font-size: 28rpx;
  413. font-weight: 500;
  414. color: #333333;
  415. }
  416. .adress {
  417. width: 400rpx;
  418. margin-top: 18rpx;
  419. word-wrap: break-word;
  420. font-size: 22rpx;
  421. font-weight: 400;
  422. color: #888888;
  423. .con {
  424. width: 360rpx;
  425. }
  426. .icon-dingwei2 {
  427. margin-right: 8rpx;
  428. font-size: 18rpx;
  429. color: #ccc;
  430. margin-top: 6rpx;
  431. }
  432. .icon-yingyeshijian2 {
  433. margin-right: 8rpx;
  434. font-size: 18rpx;
  435. color: #ccc;
  436. }
  437. }
  438. }
  439. .right {
  440. .gostore {
  441. font-size: 22rpx;
  442. font-weight: 400;
  443. color: var(--view-theme);
  444. }
  445. .distance {
  446. margin-top: 14rpx;
  447. font-size: 20rpx;
  448. font-weight: 400;
  449. color: #999999;
  450. }
  451. .telephone {
  452. margin-top: 14rpx;
  453. display: flex;
  454. .phone {
  455. position: relative;
  456. margin-right: 24rpx;
  457. width: 40rpx;
  458. height: 40rpx;
  459. background: var(--view-minorColorT);
  460. border-radius: 50%;
  461. text-align: center;
  462. line-height: 40rpx;
  463. z-index: 2;
  464. .icon-dingwei2 {
  465. font-size: 25rpx;
  466. color: var(--view-theme) !important;
  467. }
  468. .icon-dianhua {
  469. font-size: 25rpx;
  470. color: var(--view-theme) !important;
  471. }
  472. }
  473. }
  474. }
  475. }
  476. }
  477. .lyric-enter,
  478. .lyric-leave-to {
  479. opacity: 0;
  480. transform: translateY(60px);
  481. }
  482. .lyric-enter-to,
  483. .lyric-leave {
  484. opacity: 1;
  485. }
  486. .lyric-enter-active,
  487. .lyric-leave-active {
  488. transition: all 0.3s;
  489. }
  490. .header_search {
  491. .title {
  492. width: 100%;
  493. height: 86rpx;
  494. text-align: center;
  495. line-height: 86rpx;
  496. font-size: 30rpx;
  497. font-weight: 600;
  498. color: #282828;
  499. background-color: #fff;
  500. }
  501. .box {
  502. width: 100%;
  503. height: 92rpx;
  504. background: #fff;
  505. position: relative;
  506. .input {
  507. // margin-left: 30rpx;
  508. padding-right: 40rpx;
  509. padding-left: 80rpx;
  510. width: 690rpx;
  511. height: 60rpx;
  512. background: #F5F5F5;
  513. border-radius: 30rpx;
  514. font-size: 26rpx;
  515. font-weight: 400;
  516. box-sizing: border-box;
  517. // color: #CCCCCC;
  518. }
  519. .iconfont {
  520. content: "\e79b";
  521. position: absolute;
  522. left: 60rpx;
  523. top: 34rpx;
  524. font-size: 30rpx;
  525. color: #CCCCCC;
  526. }
  527. }
  528. }
  529. .default {
  530. display: flex;
  531. flex-direction: column;
  532. align-items: center;
  533. .img {
  534. width: 414rpx;
  535. height: 256rpx;
  536. }
  537. .text {
  538. margin-top: 54rpx;
  539. font-size: 26rpx;
  540. font-weight: 400;
  541. color: #999999;
  542. }
  543. }
  544. .navbar {
  545. display: flex;
  546. height: 90rpx;
  547. background-color: #FFFFFF;
  548. font-size: 30rpx;
  549. color: #999999;
  550. .item {
  551. flex: 1;
  552. position: relative;
  553. display: flex;
  554. justify-content: center;
  555. align-items: center;
  556. cursor: pointer;
  557. }
  558. .on {
  559. font-weight: 500;
  560. color: var(--view-theme);
  561. &::after {
  562. content: "";
  563. position: absolute;
  564. bottom: 0;
  565. left: 50%;
  566. width: 120rpx;
  567. height: 4rpx;
  568. background-color: var(--view-theme);
  569. transform: translateX(-50%);
  570. }
  571. }
  572. }
  573. .area {
  574. flex: 1;
  575. min-width: 0;
  576. }
  577. </style>