index.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654
  1. <template>
  2. <div class="Appindex">
  3. <!-- 顶部 -->
  4. <view class="head">
  5. <!-- 轮播图 -->
  6. <swiper-banner :radius="1" imgScale="5:2" :imgArr="BannerImg" :duration="1000" :interval="5000" :circular="true" :autoplay="true" @goList="goList" :indicator-dots="true" indicator-active-color="#12B280" indicator-color="rgba(255, 255, 255, .82)"></swiper-banner>
  7. <!-- 轮播图-end -->
  8. <!-- 公告 -->
  9. <view class="head_notice clearfix">
  10. <view class="notice_title" @click="goNoticeList">
  11. <image class="gg_img" src="@/static/img/gg.png"></image>
  12. </view>
  13. <swiper class="notice_swiper" vertical autoplay circular :interval="5000" :duration="1000">
  14. <swiper-item v-for="(item, index) in not_list" :key="index" @click="toDetail(item.article_id)">
  15. <text class="not_list ellipsis">{{ item.title }}</text>
  16. <text class="not_ico iconfont">&#xe62e;</text>
  17. </swiper-item>
  18. </swiper>
  19. </view>
  20. <!-- 公告-end -->
  21. <!-- 专区入口 -->
  22. <div class="l_tabBar flex_r flex_jb">
  23. <div class="search-box flex_r flex_jb flex_ac">
  24. <div class="district" @click="showAddress = !showAddress">
  25. <span>{{ LocationCity }}</span>
  26. <span class="iconfont">&#xe62f;</span>
  27. </div>
  28. <div class="search flex_r flex_jb flex_ac">
  29. <span class="iconfont">&#xe661;</span>
  30. <input v-model="searchKey" @confirm="toSearch" class="inp" placeholder="搜索你要的内容">
  31. <span class="search_btn" @click="toSearch">搜索</span>
  32. </div>
  33. <!-- <div class="scan-ico iconfont">&#xe8cf;</div> -->
  34. </div>
  35. <div class="item" v-for="(i,s) in tabs" :key="s" @click="goto(i.url)">
  36. <img :src="i.ico" alt="" class="ico">
  37. <!-- <div class="tit">{{ i.tit }}</div> -->
  38. </div>
  39. </div>
  40. <!-- 专区-end -->
  41. <!-- 活动 -->
  42. <view class="activity" v-if="homeImg.length">
  43. <image class="act_img act_one_img" :src="homeImg[0].image" @click="toConsumerGold" mode=""></image>
  44. <view class="act_other">
  45. <image class="act_img act_two_img" :src="homeImg[1].image" @click="goto('/pages/product/productTeaBaby?type=5')" mode=""></image>
  46. <image class="act_img act_two_img" :src="homeImg[2].image" mode="" @click="goVipGift"></image>
  47. </view>
  48. </view>
  49. <!-- 活动-end -->
  50. </view>
  51. <view class="bou_head flex_r flex_ac flex_jc">
  52. <image class="bou_img" src="/static/sgin/left.png" mode=""></image>
  53. <view class="bou_title">今日推荐</view>
  54. <image class="bou_img" src="/static/sgin/right.png" mode=""></image>
  55. </view>
  56. <view class="list_bar">
  57. <view class="product-list">
  58. <view class="product" v-for="(i, s) in productList" :key="s" @click="NavToGoodsDetail(i.id, i.type)">
  59. <view class="image-view">
  60. <image class="product-image" :src="i.original_img"></image>
  61. </view>
  62. <view class="content-view">
  63. <view :class="['product-title', 'ellipsis']">{{ i.goods_name }}</view>
  64. <view class="product-price">
  65. <template v-if="i.type == 1">
  66. <text class="product-price-original">{{ i.total_amount }}</text>
  67. <text class="product-price-msg">(含服务费{{$h.Mul(i.service,2)}}元)</text>
  68. </template>
  69. <text class="product-price-original" v-else>{{ i.price }}</text>
  70. <text class="product-text" v-if="[3,4].includes(i.type)">赠<text class="corFE2C15">{{ i.give_cha_bao }}</text>茶宝</text>
  71. </view>
  72. <view class="product-txt" v-if="i.type == 4">
  73. <text class="product-price-favour">{{i.market_price}}</text>
  74. <text class="product-text">消费金抵</text>
  75. <span class="corFE2C15">¥{{ Number(i.consume) }}</span>
  76. </view>
  77. <!-- <view class="product-txt" v-if="i.type == 1">赠送{{ i.give_integral + "批发券" }}</view> -->
  78. <view class="product-txt" v-if="[3,4].includes(i.type)">限时赠送<text class="corFE2C15">{{ i.teac }}</text>TeaC</view>
  79. <view class="product-txt fenxiang" v-if="[3,4].includes(i.type)">
  80. <text class="iconfont red">&#xe62b;</text>
  81. <text class="red">分享约获得 {{ i.first_teac }} {{i.type==3?'TeaC':'现金'}}</text>
  82. </view>
  83. </view>
  84. </view>
  85. </view>
  86. </view>
  87. <view class="fz_w_text">让数字经济赋能美好生活!</view>
  88. <!-- 城市选择 -->
  89. <h-address @select="selectaddress" :visible.sync="showAddress" />
  90. <!-- 隐私指引 -->
  91. <!-- <xh-privacy title="隐私保护指引" color="#18bb88"></xh-privacy> -->
  92. <!-- #ifdef APP-PLUS -->
  93. <uni-popup ref="popup">
  94. <view class="progressBox">
  95. <icon type="loading" size="26"/>
  96. <text class="words">下载中 请勿退出 {{ totalBytesWritten + " / " + totalBytesExpectedToWrite }}</text>
  97. </view>
  98. </uni-popup>
  99. <!-- #endif -->
  100. </div>
  101. </template>
  102. <script>
  103. // import xhPrivacy from "@/components/xh-privacy/xh-privacy.vue"; //隐私保护指引
  104. import swiperBanner from "@/components/swiperBanner/index.vue"; //轮播
  105. import hAddress from "@/components/h-address/address.vue"; //城市选择
  106. import tabs from '@/static/js/tabs' //专区入口
  107. import { post } from "@/request/api.js";
  108. import { formatBytes } from "@/utils/index";
  109. export default {
  110. name: "Appindex",
  111. components: {
  112. swiperBanner, //轮播
  113. hAddress
  114. // xhPrivacy,
  115. },
  116. data() {
  117. return {
  118. BannerImg: [], // 轮播图列表
  119. not_list: [], // 公告列表
  120. homeImg: "", //活动列表
  121. productList: [], //商品数据
  122. searchKey: "", //搜索关键词
  123. LocationCity: "深圳",
  124. showAddress: false,
  125. tabs,
  126. totalBytesWritten: "0B", // 已经下载的数据长度
  127. totalBytesExpectedToWrite: "0B", // 预期需要下载的数据总长度
  128. filePath:"",
  129. percentVal:0,
  130. newAppInfo:{}
  131. };
  132. },
  133. onLoad(option) {
  134. this.getToCity()
  135. this.loadData()
  136. // uni.Luserfun()
  137. // #ifdef APP-PLUS
  138. this.getNewVersion()
  139. // #endif
  140. },
  141. onShow() {
  142. this.getBanner(); //获取轮播图
  143. this.getAnnounce(); //获取公告列表
  144. this.gethomeImg(); //活动列表
  145. },
  146. onHide() {},
  147. methods: {
  148. loadData() {
  149. post("v1/goods/indexGoods").then((res) => {
  150. if (res.code === 0) {
  151. this.productList = res.data.data;
  152. }
  153. });
  154. },
  155. getNewVersion(){
  156. post("v1/getAppVersion").then((res) => {
  157. if (res.code === 0) {
  158. console.log(res.data.data);
  159. if(plus.os.name == "Android"){
  160. this.filePath = res.data.data.android.url
  161. this.newAppInfo = res.data.data.android
  162. // 获取当前版本
  163. plus.runtime.getProperty(plus.runtime.appid, (wgtinfo) => {
  164. console.log();
  165. if(wgtinfo.versionCode < this.newAppInfo.version){
  166. this.update()
  167. }
  168. });
  169. }
  170. }
  171. });
  172. },
  173. // 跳转到商品详情页
  174. NavToGoodsDetail(id, type) {
  175. this.goto("/pages/product/p_details", { id, type });
  176. },
  177. // 获取轮播图
  178. getBanner() {
  179. post("v1/banner").then((res) => {
  180. if (res.code === 0) {
  181. this.BannerImg = [];
  182. res.data.data.forEach((e) => {
  183. if (e.image) this.BannerImg.push(e.image);
  184. });
  185. }
  186. });
  187. },
  188. // 活动列表
  189. gethomeImg() {
  190. post("v1/homeImg").then((res) => {
  191. if (res.code === 0) {
  192. this.homeImg = res.data.data
  193. }
  194. });
  195. },
  196. // 跳转公告列表页
  197. goNoticeList() {
  198. this.goto("/pages/consultation-list/index");
  199. },
  200. // 获取公告列表
  201. getAnnounce() {
  202. post("v1/notice", { is_index: 1 }).then((res) => {
  203. if (res.code === 0) {
  204. this.not_list = res.data.data;
  205. }
  206. });
  207. },
  208. //跳转公告详情
  209. toDetail(id) {
  210. this.goto("/pages/notice/detail", { id });
  211. },
  212. // 轮播图跳转
  213. goList(e) {},
  214. // 金刚区跳转
  215. setPageUrl(item) {
  216. if ([1, 3, 4, 6].includes(item.type)) {
  217. this.goto("/pages/product/productRetail", { type: item.type });
  218. } else if (item.type == 2) {
  219. this.goto("/pages/product/productWholesale", { type: 2 });
  220. } else if (item.type == 5) {
  221. this.goto("/pages/product/productTeaBaby", { type: item.type });
  222. } else {
  223. appEv.errTips("此功能暂未开放!");
  224. return false;
  225. }
  226. },
  227. toConsumerGold(){
  228. uni.switchTab({
  229. url: "/pages/consumerGold/index"
  230. })
  231. },
  232. goVipGift() {
  233. this.goto("/pages/product/productRetail", { type: 4, is_vip: 1 });
  234. },
  235. // 搜索
  236. toSearch() {
  237. this.goto("/pagesC/settledMerchant/index", { key: this.searchKey });
  238. },
  239. // 获取当前城市
  240. async getToCity() {
  241. let { lat, lng } = await uni.Location();
  242. post("local/hotel/city", { longitude: lng, latitude: lat }).then(res => {
  243. if (res.code == 0) {
  244. let da = res.data
  245. this.LocationCity = da.cityName;
  246. }
  247. })
  248. },
  249. // 选择城市
  250. selectaddress(da) {
  251. this.LocationCity = da.cityName;
  252. this.showAddress = false;
  253. },
  254. update(){
  255. const _this = this;
  256. uni.showModal({
  257. title: "版本更新",
  258. content: "APP有新版本发布,点击 立即更新 进行最新版本下载。",
  259. showCancel: this.newAppInfo.is_mast == 1 ? true: false,
  260. confirmText: "立即更新",
  261. cancelText: "稍后进行",
  262. success: function (res) {
  263. if (res.confirm) {
  264. _this.$refs.popup.open()
  265. // _this.show = true; // show变量控制一个下载进度弹框(这个UI样式自己写即可)
  266. // 创建一个下载任务,并根据后端返回的apk静态资源地址filePath进行下载
  267. let downloadTask = uni.downloadFile({
  268. url: _this.filePath,
  269. success: (res) => {
  270. console.log(res, "下载成功");
  271. this.updateProgressShow = false;
  272. if (res.statusCode === 200) {
  273. _this.$refs.popup.close()
  274. plus.runtime.install(
  275. res.tempFilePath,
  276. {},
  277. function () {
  278. console.log("install success...");
  279. plus.runtime.restart();
  280. // uni.hideLoading();
  281. uni.setStorageSync("wgtinfo", null);
  282. },
  283. function (e) {
  284. uni.showToast({
  285. icon: "error",
  286. title: "更新失败",
  287. duration: 1500,
  288. });
  289. }
  290. );
  291. } else {
  292. _this.$refs.popup.close()
  293. uni.showToast({
  294. icon: "error",
  295. title: "更新失败",
  296. duration: 1500,
  297. });
  298. }
  299. },
  300. fail: (err) => {
  301. _this.$refs.popup.close()
  302. uni.showToast({
  303. icon: "error",
  304. title: "更新失败",
  305. duration: 1500,
  306. });
  307. },
  308. });
  309. downloadTask.onProgressUpdate((res) => {
  310. // console.log(res, "进度");
  311. // console.log("下载进度" + res.progress);
  312. // console.log("已经下载的数据长度" + res.totalBytesWritten);
  313. // console.log(
  314. // "预期需要下载的数据总长度" + res.totalBytesExpectedToWrite
  315. // );
  316. let totalBytesWritten = formatBytes(res.totalBytesWritten);
  317. let totalBytesExpectedToWrite = formatBytes(
  318. res.totalBytesExpectedToWrite
  319. );
  320. let num1 = totalBytesWritten.fileSize.split(
  321. totalBytesWritten.matchUnit.unitName
  322. );
  323. let num2 = totalBytesExpectedToWrite.fileSize.split(
  324. totalBytesExpectedToWrite.matchUnit.unitName
  325. );
  326. _this.totalBytesWritten =
  327. Math.floor(num1[0] * 100) / 100 +
  328. totalBytesWritten.matchUnit.unitName;
  329. _this.totalBytesExpectedToWrite =
  330. Math.floor(num2[0] * 100) / 100 +
  331. totalBytesExpectedToWrite.matchUnit.unitName;
  332. _this.percentVal = res.progress;
  333. });
  334. } else if (res.cancel) {
  335. console.log("稍后更新");
  336. }
  337. },
  338. });
  339. }
  340. },
  341. computed: {},
  342. watch: {},
  343. };
  344. </script>
  345. <style scoped lang='scss'>
  346. .head {
  347. padding: 12rpx 28rpx;
  348. }
  349. .head_search {
  350. width: 100%;
  351. height: 64rpx;
  352. line-height: 64rpx;
  353. background: #f3f5f7;
  354. border-radius: 32rpx;
  355. text-align: center;
  356. font-size: 28rpx;
  357. color: #bbbbbb;
  358. margin-bottom: 26rpx;
  359. .search_text {
  360. margin-left: 14rpx;
  361. }
  362. }
  363. .head_notice {
  364. margin: 30rpx 0;
  365. .notice_title {
  366. width: 130rpx;
  367. height: 40rpx;
  368. float: left;
  369. .gg_img {
  370. width: 100%;
  371. height: 40rpx;
  372. }
  373. }
  374. .notice_swiper {
  375. height: 40rpx;
  376. padding-left: 20rpx;
  377. font-size: 28rpx;
  378. float: left;
  379. box-sizing: border-box;
  380. width: calc(100% - 130rpx);
  381. .not_list {
  382. width: calc(100% - 50rpx);
  383. }
  384. .not_ico {
  385. width: 30rpx;
  386. font-size: 28rpx;
  387. color: #999;
  388. }
  389. .not_list,
  390. .not_ico {
  391. display: inline-block;
  392. vertical-align: middle;
  393. height: 40rpx;
  394. line-height: 40rpx;
  395. }
  396. }
  397. }
  398. .l_tabBar {
  399. margin: 32rpx 0;
  400. background-color: #fff;
  401. padding: 10rpx 20rpx;
  402. border-radius: 10rpx;
  403. box-shadow: 4rpx 4rpx 8rpx 4rpx rgba(0, 0, 0, 0.12);
  404. flex-wrap: wrap;
  405. .search-box {
  406. width: 100%;
  407. padding: 10rpx;
  408. margin-bottom: 12rpx;
  409. .district {
  410. font-size: 32rpx;
  411. font-weight: 600;
  412. color: #333;
  413. .iconfont {
  414. font-size: 20rpx;
  415. margin-left: 12rpx;
  416. }
  417. }
  418. .search {
  419. border: 1px solid #D78C2E;
  420. height: 60rpx;
  421. line-height: 60rpx;
  422. padding-left: 20rpx;
  423. border-radius: 31rpx;
  424. .iconfont {
  425. font-size: 30rpx;
  426. }
  427. .inp {
  428. font-size: 25rpx;
  429. padding: 0 8rpx;
  430. width: 300rpx;
  431. }
  432. .search_btn {
  433. background-color: #D78C2E;
  434. height: 100%;
  435. color: #fff;
  436. border-radius: 31rpx;
  437. font-size: 28rpx;
  438. padding: 0 28rpx;
  439. }
  440. }
  441. .scan-ico {
  442. font-size: 55rpx;
  443. }
  444. }
  445. .item {
  446. width: 105rpx;
  447. margin: 10rpx 10rpx;
  448. }
  449. .ico {
  450. width: 100%;
  451. height: 138rpx;
  452. }
  453. // .tit{
  454. // font-size: 26rpx;
  455. // text-align: center;
  456. // }
  457. }
  458. .bou_head {
  459. width: 100%;
  460. height: 114rpx;
  461. // margin-top: 50rpx;
  462. .bou_img {
  463. width: 92rpx;
  464. height: 30rpx;
  465. }
  466. .bou_title {
  467. height: 30rpx;
  468. line-height: 30rpx;
  469. font-size: 36rpx;
  470. color: #121212;
  471. font-weight: bold;
  472. margin: 0 36rpx;
  473. }
  474. }
  475. // 活动
  476. .activity {
  477. .act_one_img {
  478. display: inline-block;
  479. width: 300rpx;
  480. height: 378rpx;
  481. margin-right: 10rpx;
  482. }
  483. .act_other {
  484. display: inline-block;
  485. width: calc(100% - 300rpx - 10rpx);
  486. }
  487. .act_two_img {
  488. width: 100%;
  489. height: 185rpx;
  490. }
  491. .act_img {
  492. border-radius: 10rpx;
  493. }
  494. }
  495. // 活动-end
  496. // 商品列表
  497. .list_bar {
  498. .tit {
  499. text-align: center;
  500. font-size: 36rpx;
  501. color: #121212;
  502. padding: 40rpx 0 20rpx;
  503. font-weight: bold;
  504. }
  505. }
  506. .product-list {
  507. width: 100%;
  508. display: flex;
  509. flex-wrap: wrap;
  510. flex-direction: row;
  511. padding: 0 30rpx;
  512. .product {
  513. width: 48.5%;
  514. margin-bottom: 20rpx;
  515. padding-bottom: 12rpx;
  516. border-radius: 10rpx;
  517. box-shadow: 4rpx 4rpx 8rpx 4rpx rgba(0, 0, 0, 0.12);
  518. &:nth-child(2n) {
  519. margin-left: 3%;
  520. }
  521. }
  522. .product-image {
  523. border-radius: 10rpx 10rpx 0 0;
  524. width: 100%;
  525. height: 42.3vw;
  526. object-fit: cover;
  527. }
  528. .content-view {
  529. padding: 0 16rpx;
  530. }
  531. .product-title {
  532. width: 100%;
  533. overflow: hidden;
  534. line-height: 1.5;
  535. font-size: 28rpx;
  536. color: #121212;
  537. }
  538. .product-price {
  539. color: #121212;
  540. font-size: 28rpx;
  541. position: relative;
  542. }
  543. .product-price-original {
  544. color: #18bb88;
  545. font-size: 32rpx;
  546. font-weight: bold;
  547. &:before {
  548. content: "¥";
  549. font-size: 20rpx;
  550. }
  551. }
  552. .product-price-favour {
  553. color: #888888;
  554. text-decoration: line-through;
  555. margin-left: 20rpx;
  556. }
  557. .product-tip {
  558. position: absolute;
  559. right: 20rpx;
  560. background-color: #ff3333;
  561. color: #ffffff;
  562. padding: 0 20rpx;
  563. border-radius: 10rpx;
  564. }
  565. .product-unit {
  566. font-size: 24rpx;
  567. color: #18bb88;
  568. }
  569. .product-txt,
  570. .product-text {
  571. font-size: 22rpx;
  572. color: #787878;
  573. .iconfont {
  574. margin-right: 6rpx;
  575. }
  576. }
  577. .product-price-msg {
  578. font-size: 20rpx;
  579. color: #ff6d44;
  580. }
  581. .product-text {
  582. margin-left: 16rpx;
  583. }
  584. .red {
  585. color: #FA2E18;
  586. }
  587. .fenxiang {
  588. font-size: 20rpx;
  589. background: rgba(250, 46, 24, 0.08);
  590. display: inline-block;
  591. border-radius: 6rpx;
  592. padding: 0 16rpx;
  593. }
  594. }
  595. .progressBox{
  596. padding: 40rpx;
  597. border-radius: 4rpx;
  598. background-color: #fff;
  599. }
  600. </style>