index.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613
  1. <template>
  2. <view>
  3. <zs-skeleton type="index" :loading="loading"></zs-skeleton>
  4. <view class="navBarBox">
  5. <view
  6. class="statusBar"
  7. :style="{ paddingTop: statusBarHeight + 'px' }"
  8. ></view>
  9. <view class="navBar">
  10. <view>印象贵大文创</view>
  11. <image class="logo" mode="scaleToFill"></image>
  12. </view>
  13. </view>
  14. <view class="content">
  15. <view @click="handleSearch" class="search-box">
  16. <zs-search
  17. style="margin-top: 10px"
  18. :showBtn="false"
  19. :showPrefix="false"
  20. placeholder="请输入商品名称"
  21. height="80"
  22. bgColor="#F6F6F6"
  23. ></zs-search>
  24. </view>
  25. <view class="swiper-box">
  26. <view class="progress">
  27. {{ current + 1 + "/" + advList.length }}
  28. </view>
  29. <swiper
  30. class="swiper"
  31. @change="swiperChange"
  32. :current="current"
  33. :indicator-dots="false"
  34. circular
  35. :autoplay="true"
  36. :interval="3000"
  37. :duration="1000"
  38. >
  39. <swiper-item
  40. v-for="(item, index) in advList"
  41. :key="item.id"
  42. @click="jump(item.jumpUrl)"
  43. >
  44. <image class="swiper-item" mode="" :src="item.advertsImg"> </image>
  45. </swiper-item>
  46. </swiper>
  47. </view>
  48. <view class="discount-list">
  49. <view
  50. class="discount-item"
  51. v-for="(item, index) in discountsList"
  52. :key="index"
  53. @click="goDetail(item)"
  54. >
  55. <image class="icon" :src="item.columnImg" mode=""></image>
  56. <view class="title">{{ item.columnName }}</view>
  57. </view>
  58. </view>
  59. <view class="swiper-box" style="height: 160rpx">
  60. <swiper
  61. class="swiper"
  62. @change="swiperChange"
  63. :indicator-dots="false"
  64. circular
  65. :autoplay="false"
  66. :interval="3000"
  67. :duration="1000"
  68. >
  69. <swiper-item
  70. v-for="(item, index) in advList1"
  71. :key="item.id"
  72. @click="jump(item.jumpUrl)"
  73. >
  74. <image class="swiper-item" mode="" :src="item.advertsImg"> </image>
  75. </swiper-item>
  76. </swiper>
  77. </view>
  78. <view class="sub-title">
  79. <view>精选推荐</view>
  80. </view>
  81. <view class="goods-list">
  82. <zs-list class="store-box" mt="0" @load="loadMore" :status="status">
  83. <view class="left">
  84. <view
  85. class="store-item"
  86. v-for="(item, index) in list"
  87. :key="index"
  88. @click="goGoodsDetail(item)"
  89. >
  90. <zs-img
  91. :src="item.goodsImg"
  92. width="340rpx"
  93. height="340rpx"
  94. mode="widthFix"
  95. ></zs-img>
  96. <view class="info">
  97. <view class="title">
  98. {{ item.goodsName }}
  99. </view>
  100. <view class="goods-price">
  101. <view> ¥{{ item.realPrice }} </view>
  102. <view class="distance">
  103. 销售{{ item.saleNum.toFixed(2) }}
  104. </view>
  105. </view>
  106. </view>
  107. </view>
  108. </view>
  109. <view class="right">
  110. <view
  111. class="store-item"
  112. v-for="(item, index) in list1"
  113. :key="index"
  114. @click="goGoodsDetail(item)"
  115. >
  116. <zs-img
  117. :src="item.goodsImg"
  118. width="340rpx"
  119. height="340rpx"
  120. mode="widthFix"
  121. ></zs-img>
  122. <view class="info">
  123. <view class="title">
  124. {{ item.goodsName }}
  125. </view>
  126. <view class="goods-price">
  127. <!-- <image
  128. class="position"
  129. src="../../static/position.png"
  130. mode=""
  131. ></image> -->
  132. <view> ¥{{ item.realPrice }}</view>
  133. <view class="distance">
  134. 销售{{ item.saleNum.toFixed(2) }}
  135. </view>
  136. </view>
  137. </view>
  138. </view>
  139. </view>
  140. </zs-list>
  141. </view>
  142. <zs-tab-bar :value="0"></zs-tab-bar>
  143. </view>
  144. </view>
  145. </template>
  146. <script>
  147. import { getUserDetail, getAdv } from "@/api/common.js";
  148. import { appSearch } from "@/api/shop.js";
  149. import { searchMenu } from "@/api/study.js";
  150. // 腾讯地图
  151. var QQMapWX = require("../../libs/qqmap-wx-jssdk.min.js");
  152. var qqmapsdk = new QQMapWX({
  153. key: "KX5BZ-B64RC-RO62W-AMWAZ-VVTC3-YAFXF",
  154. });
  155. export default {
  156. data() {
  157. return {
  158. advList: [],
  159. advList1: [],
  160. discountsList: [], //菜单
  161. current: 0,
  162. loading: false,
  163. navBarHeight: 0,
  164. statusBarHeight: 0,
  165. list: [],
  166. list1: [],
  167. status: "more",
  168. query: {
  169. currentPage: 1,
  170. pageSize: 10,
  171. shopId: "",
  172. status: 3,
  173. },
  174. };
  175. },
  176. onLoad() {},
  177. created() {
  178. this.loading = true;
  179. this.navBarHeight = this.$navHight(1);
  180. this.navBarHeight = this.navBarHeight + 10 + "px";
  181. this.statusBarHeight = uni.getSystemInfoSync()["statusBarHeight"];
  182. this.query.shopId = uni.getStorageSync("gdShopId");
  183. Promise.all([
  184. this.getSearchMenu(),
  185. this.getAdv(),
  186. this.appSearch(),
  187. this.getBanner(),
  188. this.getCity(),
  189. ]).then((res) => {});
  190. },
  191. methods: {
  192. goGoodsDetail(item) {
  193. uni.setStorageSync("shopInfo", JSON.stringify(item));
  194. uni.reLaunch({
  195. url: `../../detail/goodsDetail/index?id=${item.goodsId}`,
  196. });
  197. },
  198. // 点击搜索
  199. handleSearch() {
  200. if (!uni.getStorageSync("token")) {
  201. return uni.showModal({
  202. title: "请登录",
  203. confirmText: "去登录",
  204. success(res) {
  205. console.log(res);
  206. if (res.confirm) {
  207. uni.navigateTo({
  208. url: "/login/login/login?redirect=/pages/index/index",
  209. });
  210. }
  211. },
  212. });
  213. }
  214. uni.reLaunch({
  215. url: "./search",
  216. });
  217. // if(!val) return
  218. // this.query.queryName = val
  219. // this.query.pageCurrent = 1
  220. // this.list = []
  221. // this.list1 = []
  222. // this.status = 'more'
  223. // this.search()
  224. },
  225. // swiper变动
  226. swiperChange(val) {
  227. this.current = val.target.current;
  228. },
  229. // Banner
  230. getBanner() {
  231. return new Promise((resolve, reject) => {
  232. getAdv({
  233. currentPage: 1,
  234. pageSize: 99,
  235. advertsType: 1,
  236. }).then((res) => {
  237. if (res.state == "Success") {
  238. this.advList = res.content.records;
  239. this.loading = false;
  240. resolve(2);
  241. }
  242. });
  243. });
  244. },
  245. // 广告位
  246. getAdv() {
  247. return new Promise((resolve, reject) => {
  248. getAdv({
  249. currentPage: 1,
  250. pageSize: 99,
  251. advertsType: 2,
  252. }).then((res) => {
  253. if (res.state == "Success") {
  254. this.advList1 = res.content.records;
  255. this.loading = false;
  256. resolve(2);
  257. }
  258. });
  259. });
  260. },
  261. // 金刚区
  262. getSearchMenu() {
  263. return new Promise((resolve, reject) => {
  264. searchMenu({
  265. currentPage: 1,
  266. pageSize: 4,
  267. belongType: 1,
  268. status: 1,
  269. }).then((res) => {
  270. if (res.state == "Success") {
  271. this.discountsList = res.content.records;
  272. resolve(1);
  273. }
  274. });
  275. });
  276. },
  277. // 跳转优惠详情
  278. goDetail(item) {
  279. // url = "/pages/home/detail";
  280. // uni.navigateTo({
  281. // url: `${url}`,
  282. // success(res) {
  283. // // res.eventChannel.emit("banner", banner);
  284. // },
  285. // });
  286. uni.navigateTo({
  287. url: "./searchResult?column=" + item.columnName,
  288. });
  289. console.log("item", item);
  290. },
  291. appSearch() {
  292. if (this.status == "noMore") return;
  293. this.status = "loading";
  294. appSearch(this.query).then((res) => {
  295. if (res.state == "Success") {
  296. this.loading = false;
  297. let list = [];
  298. let list1 = [];
  299. res.content.records.map((item, index) => {
  300. if (index % 2) {
  301. list1.push(item);
  302. } else {
  303. list.push(item);
  304. }
  305. });
  306. this.list = this.list.concat(list);
  307. this.list1 = this.list1.concat(list1);
  308. let total = this.list.length + this.list1.length;
  309. if (total >= res.content.total) {
  310. this.status = "noMore";
  311. } else {
  312. this.status = "more";
  313. this.query.currentPage++;
  314. }
  315. }
  316. });
  317. },
  318. loadMore() {
  319. console.log("loadMore");
  320. if (this.query["location.lat"] && this.query["location.lon"]) {
  321. this.appSearch();
  322. }
  323. },
  324. // 获取当前城市
  325. getCity() {
  326. let that = this;
  327. return new Promise((resolve, reject) => {
  328. uni.getLocation({
  329. type: "gcj02",
  330. success: (res) => {
  331. // 解析地址
  332. that.query["location.lat"] = res.latitude;
  333. that.query["location.lon"] = res.longitude;
  334. // 存储经纬度
  335. uni.setStorageSync(
  336. "location",
  337. JSON.stringify({
  338. latitude: res.latitude,
  339. longitude: res.longitude,
  340. })
  341. );
  342. qqmapsdk.reverseGeocoder({
  343. location: {
  344. latitude: res.latitude,
  345. longitude: res.longitude,
  346. },
  347. success: function (res) {
  348. // 市
  349. that.city = res.result.address_component.city;
  350. resolve();
  351. },
  352. fail: function (res) {
  353. that.city = "定位失败";
  354. },
  355. });
  356. },
  357. fail: (res) => {
  358. console.log("获取经纬度失败");
  359. },
  360. });
  361. });
  362. },
  363. },
  364. };
  365. </script>
  366. <style lang="scss">
  367. .navBarBox .navBar .logo {
  368. width: 0rpx;
  369. height: 82rpx;
  370. // margin-right: 10rpx;
  371. }
  372. .navBarBox .navBar {
  373. font-size: 35rpx;
  374. font-weight: bold;
  375. padding: 3rpx 50rpx;
  376. padding-bottom: 8rpx;
  377. display: flex;
  378. flex-direction: row;
  379. justify-content: center;
  380. align-items: center;
  381. }
  382. .content {
  383. // padding-top: 24%;
  384. display: flex;
  385. flex-direction: column;
  386. background-color: #fafafa;
  387. justify-content: center;
  388. }
  389. page {
  390. background-color: #fafafa;
  391. }
  392. .search-box {
  393. width: 100vw;
  394. }
  395. .swiper-box {
  396. position: relative;
  397. margin: 0 24rpx 10rpx;
  398. padding-top: 20rpx;
  399. width: 702rpx;
  400. height: 280rpx;
  401. border-radius: 16rpx;
  402. .progress {
  403. position: absolute;
  404. top: 38rpx;
  405. right: 20rpx;
  406. z-index: 2;
  407. color: #ffffff;
  408. font-size: 16rpx;
  409. background: rgba(255, 255, 255, 0.3);
  410. padding: 2rpx 10rpx;
  411. border-radius: 14rpx;
  412. }
  413. .swiper {
  414. position: relative;
  415. height: 100%;
  416. padding: 0 10rpx;
  417. .swiper-item {
  418. width: 100%;
  419. height: 100%;
  420. border-radius: 16rpx;
  421. object-fit: cover;
  422. }
  423. }
  424. }
  425. .discount-list {
  426. display: flex;
  427. flex-wrap: wrap;
  428. width: 100%;
  429. justify-content: space-evenly;
  430. // padding: 30rpx 0;
  431. // margin: 0 0rpx 0rpx;
  432. background: #fafafa;
  433. border-radius: 16rpx;
  434. position: relative;
  435. top: 0rpx;
  436. padding-top: 20rpx;
  437. .discount-item {
  438. width: 20%;
  439. display: flex;
  440. flex-direction: column;
  441. align-items: center;
  442. margin-top: 10rpx;
  443. margin-bottom: 10rpx;
  444. position: relative;
  445. .icon {
  446. width: 56rpx;
  447. height: 56rpx;
  448. }
  449. .title {
  450. font-size: 26rpx;
  451. margin-top: 10rpx;
  452. }
  453. .tag {
  454. position: absolute;
  455. top: -20rpx;
  456. left: 50%;
  457. background: #ff0615;
  458. box-shadow: inset 0rpx 6rpx 12rpx 2rpx rgba(255, 255, 255, 0.16);
  459. border-radius: 12rpx 14rpx 14rpx 0rpx;
  460. color: #fff;
  461. white-space: nowrap;
  462. font-size: 18rpx;
  463. line-height: -14rpx;
  464. height: 24rpx;
  465. padding: 0 10rpx;
  466. // width: fit-content;
  467. background-size: 100% 34rpx;
  468. }
  469. .desc {
  470. color: #ff0817;
  471. font-size: 16rpx;
  472. text-align: center;
  473. margin-top: 4rpx;
  474. }
  475. }
  476. }
  477. .sub-title {
  478. margin: 20rpx 0;
  479. padding-left: 40rpx;
  480. font-size: 30rpx;
  481. font-weight: bold;
  482. }
  483. .goods-list {
  484. border-radius: 16rpx 16rpx 0 0;
  485. margin-bottom: 60rpx;
  486. }
  487. .zs-list {
  488. display: flex;
  489. flex-wrap: wrap;
  490. justify-content: space-between;
  491. padding: 0 24rpx;
  492. .left {
  493. .adv-swiper {
  494. width: 340rpx;
  495. height: 444rpx;
  496. margin-bottom: 25rpx;
  497. .adv-item {
  498. width: 340rpx;
  499. height: 444rpx;
  500. }
  501. }
  502. }
  503. .right {
  504. }
  505. .store-item {
  506. width: 340rpx;
  507. margin-bottom: 25rpx;
  508. // box-shadow: 0rpx 0rpx 24rpx 2rpx rgba(0, 0, 0, 0.08);
  509. border-radius: 16rpx;
  510. background: #fff;
  511. .icon {
  512. width: 100%;
  513. height: 300rpx;
  514. border-radius: 16rpx 16rpx 0 0;
  515. }
  516. .info {
  517. padding: 20rpx;
  518. background: #fff;
  519. border-radius: 0 0 16rpx 16rpx;
  520. position: relative;
  521. .title {
  522. // font-weight: bold;
  523. width: 100%;
  524. white-space: nowrap;
  525. text-overflow: ellipsis;
  526. overflow: hidden;
  527. }
  528. .tags {
  529. display: flex;
  530. align-items: center;
  531. .tag-item {
  532. line-height: 50rpx;
  533. border-radius: 8rpx;
  534. padding: 6rpx 0;
  535. font-size: 24rpx;
  536. margin-left: 10rpx;
  537. display: flex;
  538. .label {
  539. background: #fff;
  540. color: #fe5b47;
  541. padding: 0 10rpx;
  542. border-radius: 8rpx 0 0 8rpx;
  543. }
  544. .value {
  545. color: #fff;
  546. background: rgba(255, 255, 255, 0.2);
  547. padding: 0 14rpx;
  548. border-radius: 0 8rpx 8rpx 0;
  549. }
  550. }
  551. }
  552. .goods-price {
  553. display: flex;
  554. align-items: center;
  555. margin-top: 15rpx;
  556. justify-content: space-between;
  557. color: #ff4d3a;
  558. font-weight: bold;
  559. font-size: 30rpx;
  560. .distance {
  561. font-weight: normal;
  562. font-size: 20rpx;
  563. color: #999;
  564. }
  565. .position {
  566. color: 999;
  567. width: 25rpx;
  568. height: 29rpx;
  569. margin-right: 8rpx;
  570. }
  571. }
  572. }
  573. }
  574. }
  575. </style>