Commit 6b1a4d8bf491d60b1c0c89ae6ab53b7de91e1f3b

Authored by 王强
1 parent 294416b4

“新春特惠送福利”页面完成~

src/pages/discountList2/discountList2.less 0 → 100644
  1 +@charset "UTF-8";
  2 +
  3 +.discount-list-page {
  4 + background-color: #ffffff;
  5 + min-height: 100vh;
  6 + .nav-box {
  7 + position: fixed;
  8 + top: 0;
  9 + z-index: 100;
  10 + background-color: #ffffff;
  11 + width: 100%;
  12 + height: auto;
  13 + .call-app-box {
  14 + width: 100%;
  15 + }
  16 + .back-box {
  17 + background-color: #ffffff;
  18 + width: 100%;
  19 + }
  20 + .tabs-box {
  21 + background-color: #ffffff;
  22 + width: 100%;
  23 + border: 1px solid #E5E5E5;
  24 + &.is-open-app {
  25 + top: 122px;
  26 + }
  27 + &.is-cnlive {
  28 + top: 93px;
  29 + }
  30 + &.is-hide {
  31 + top: 0;
  32 + }
  33 + }
  34 + }
  35 + .pl {
  36 + background-color: transparent;
  37 + width: 100%;
  38 + &.is-open-app {
  39 + height: 212px;
  40 + }
  41 + &.is-cnlive {
  42 + height: 183px;
  43 + }
  44 + &.is-hide {
  45 + height: 90px;
  46 + }
  47 + }
  48 + .main-box {
  49 + .header-box {
  50 + width: 100%;
  51 + height: auto;
  52 + .header-img {
  53 + display: block;
  54 + width: 100%;
  55 + height: auto;
  56 + }
  57 + }
  58 + .count-down-box {
  59 + display: flex;
  60 + justify-content: flex-start;
  61 + align-items: center;
  62 + margin: 0 auto;
  63 + width: 630px;
  64 + height: auto;
  65 + .state {
  66 + display: flex;
  67 + justify-content: flex-start;
  68 + align-items: center;
  69 + .icon-tips-img {
  70 + display: block;
  71 + width: 22px;
  72 + height: 22px;
  73 + & + .text {
  74 + margin-left: 13px;
  75 + }
  76 + }
  77 + .text {
  78 + color: #633531;
  79 + font-size: 24px;
  80 + font-weight: 400;
  81 + }
  82 + }
  83 + & + .section {
  84 + margin-top: 40px;
  85 + }
  86 + }
  87 + .column-list-container {
  88 + .section {
  89 + background-color: #ffffff;
  90 + margin: 0 auto 40px auto;
  91 + width: 690px;
  92 + height: auto;
  93 + border-radius: 24px;
  94 + overflow: hidden;
  95 + &:last-child {
  96 + margin-bottom: 0;
  97 + }
  98 + &.goods-list {
  99 + /deep/ .goods-item-8-box {
  100 + .main-box {
  101 + border-bottom: 1px solid #EAEAEA;
  102 + }
  103 + }
  104 + /deep/ .goods-item-8-box:last-child {
  105 + .main-box {
  106 + border-bottom: none;
  107 + }
  108 + }
  109 + .discount-flag {
  110 + position: absolute;
  111 + top: 10px;
  112 + left: 10px;
  113 + z-index: 1;
  114 + background: linear-gradient(90deg, #F9EE7A 0%, #FAD844 100%);
  115 + padding: 1px 8px;
  116 + color: #945A08;
  117 + font-size: 20px;
  118 + font-weight: 400;
  119 + border-radius: 6px;
  120 + }
  121 + }
  122 + }
  123 + /deep/ .van-list__loading {
  124 + .van-loading {
  125 + .van-loading__spinner {
  126 + width: 28px !important;
  127 + height: 28px !important;
  128 + }
  129 + .van-list__loading-text {
  130 + margin-bottom: 30px;
  131 + color: #333333;
  132 + font-size: 28px;
  133 + font-weight: 400;
  134 + }
  135 + }
  136 + }
  137 + /deep/ .van-list__finished-text {
  138 + margin-bottom: 30px;
  139 + color: #333333;
  140 + font-size: 28px;
  141 + font-weight: 400;
  142 + }
  143 + }
  144 + .bottom-pl {
  145 + background-color: transparent;
  146 + width: 100%;
  147 + // height: 100px;
  148 + height: 1px;
  149 + }
  150 + .tips-box {
  151 + position: fixed;
  152 + bottom: 0;
  153 + z-index: 1;
  154 + background-color: #FFF6E5;
  155 + padding: 30px 0;
  156 + width: 100%;
  157 + height: auto;
  158 + .tips {
  159 + display: flex;
  160 + justify-content: flex-start;
  161 + align-items: center;
  162 + margin: 0 auto;
  163 + width: 690px;
  164 + height: 100%;
  165 + .tips-img {
  166 + display: block;
  167 + width: 26px;
  168 + height: 26px;
  169 + & + .text {
  170 + margin-left: 14px;
  171 + }
  172 + }
  173 + .text {
  174 + color: #FEA835;
  175 + font-size: 24px;
  176 + font-weight: 400;
  177 + }
  178 + }
  179 + }
  180 + }
  181 +}
src/pages/discountList2/discountList2.vue 0 → 100644
  1 +<template>
  2 + <div class="discount-list-page" :style="{'backgroundColor': tabs.list[tabs.active].color ? tabs.list[tabs.active].color : ''}" v-if="tabs.list[tabs.active]">
  3 +
  4 + <!-- 导航区域 -->
  5 + <div class="nav-box" :style="'padding-top: ' + $parent.top.value + 'px'">
  6 +
  7 + <!-- H5唤起App组件 -->
  8 + <call-app-box class="call-app-box" ref="callApp" v-if="!isCNLive.value && $parent.isOpenApp.value"
  9 + :callApps="$parent.callApps">
  10 + </call-app-box>
  11 +
  12 + <!-- 后退导航 -->
  13 + <back-box class="back-box" :class="{'hide': $route.query.hideBack == true}" v-if="isCNLive.value" @back="back"
  14 + :backs="backs">
  15 + </back-box>
  16 +
  17 + <!-- tab导航 -->
  18 + <div class="tabs-box" :class="{'is-cnlive': isCNLive.value, 'is-open-app': $parent.isOpenApp.value, 'is-hide': $route.query.hideBack == true}">
  19 +
  20 + <!-- 横向滑动tabs导航组件 -->
  21 + <horiz-list v-if="tabs.list && tabs.list.length" @change="change"
  22 + :lists="tabs.list"
  23 + com="tab2"
  24 + :pid="tabs.active">
  25 + </horiz-list>
  26 + </div>
  27 + </div>
  28 +
  29 + <!-- pl -->
  30 + <div class="pl" :class="{'is-cnlive': isCNLive.value, 'is-open-app': $parent.isOpenApp.value, 'is-hide': $route.query.hideBack == true}" :style="'padding-top: ' + $parent.top.value + 'px'"></div>
  31 +
  32 + <!-- 主区域 -->
  33 + <div class="main-box">
  34 +
  35 + <!-- 头图 -->
  36 + <div class="header-box" v-if="tabs.list[tabs.active].img">
  37 + <img :src="tabs.list[tabs.active].img + SIGN.BIG" class="header-img" />
  38 + </div>
  39 +
  40 + <!-- 上拉加载 -->
  41 + <van-list class="column-list-container" v-model="tabs.list[tabs.active].loading" :finished="tabs.list[tabs.active].finished" finished-text="~没有更多了~" @load="loadMore">
  42 +
  43 + <!-- 商品列表 -->
  44 + <div class="section goods-list" v-if="lists[tabs.active] && lists[tabs.active].length">
  45 +
  46 + <!-- 商品列表 -->
  47 + <goods-item-8 v-for="(item, index) in lists[tabs.active]" :key="index" @jump="toDetail" @primary="primary"
  48 + :item="item"
  49 + sty="1"
  50 + :discountType="tabs.list[tabs.active].discountType">
  51 + </goods-item-8>
  52 + </div>
  53 + </van-list>
  54 +
  55 + <div class="bottom-pl"></div>
  56 + </div>
  57 +
  58 + <!-- 回到顶部按钮 -->
  59 + <goto-top
  60 + :top="parseInt(150)">
  61 + </goto-top>
  62 + </div>
  63 +</template>
  64 +
  65 +<script>
  66 +
  67 + // 引入组件
  68 + import Vue from "vue";
  69 + import { Toast, Indicator } from "mint-ui";
  70 + import { List } from "vant";
  71 + import callAppBox from "@/components/callAppBox/callAppBox";
  72 + import backBox from "@/components/backBox/backBox";
  73 + import horizList from "@/components/horizList/horizList";
  74 + import goodsItem8 from "@/components/goodsItem_8/goodsItem_8";
  75 + import gotoTop from "@/components/gotoTop/gotoTop";
  76 +
  77 + Vue.use(List);
  78 +
  79 + export default {
  80 + name: 'discountListPage',
  81 + data () {
  82 + return {
  83 + title: "", // 标题
  84 + backs: null, // 后退按钮组
  85 + CALL_STATUS: {
  86 + INIT: "init", // 初始化页面
  87 + LOAD_MORE: "loadMore" // 加载更多
  88 + },
  89 + tabs: { // tabs设置
  90 + active: 0,
  91 + list: []
  92 + },
  93 + lists: [] // 列表数据
  94 + }
  95 + },
  96 + components: {
  97 + callAppBox,
  98 + backBox,
  99 + horizList,
  100 + goodsItem8,
  101 + gotoTop
  102 + },
  103 + created() {
  104 +
  105 + // 设置标题
  106 + this.$set(this, 'title', '新春特惠送福利');
  107 +
  108 + // 判断是否在App内
  109 + if (this.isCNLive.value) {
  110 +
  111 + // 添加后退按钮组“后退”和“分享”按钮
  112 + this.$set(this, 'backs', {
  113 + title: this.title,
  114 + funcs: {
  115 + back: {
  116 + icon: "static/img/icon_back.png"
  117 + },
  118 + funcArray: [
  119 + {
  120 + icon: "static/img/icon_share.png",
  121 + func: this.toShare
  122 + }
  123 + ]
  124 + }
  125 + });
  126 + }
  127 +
  128 + // 获取tabs列表
  129 + this.discountGoods2();
  130 + },
  131 + methods: {
  132 +
  133 + /**
  134 + * 加载更多
  135 + */
  136 + loadMore() {
  137 +
  138 + // 判断是否可加载
  139 + if (this.tabs.list[this.tabs.active].loadingNow === false || this.tabs.list[this.tabs.active].loadingNow === undefined) {
  140 +
  141 + // 设置加载中状态
  142 + this.$set(this.tabs.list[this.tabs.active], 'loadingNow', true);
  143 +
  144 + if (this.tabs.list[this.tabs.active].page == '1' || this.tabs.list[this.tabs.active].page === undefined) {
  145 +
  146 + // 设置初始化页码
  147 + this.$set(this.tabs.list[this.tabs.active], 'page', 1);
  148 +
  149 + // 获取店铺首页推荐商品列表
  150 + this.getShopRecommendGoods(this.CALL_STATUS.INIT);
  151 + } else {
  152 +
  153 + // 判断页面是数字再执行
  154 + if (!isNaN(parseInt(this.tabs.list[this.tabs.active].page))) {
  155 +
  156 + // 获取店铺首页推荐商品列表
  157 + this.getShopRecommendGoods(this.CALL_STATUS.LOAD_MORE);
  158 + }
  159 + }
  160 + }
  161 + },
  162 +
  163 + /**
  164 + * 切换tab
  165 + * @param {Object} item [对象数据]
  166 + * @param {Number} index [索引]
  167 + */
  168 + change(item, index) {
  169 +
  170 + // 切换tab
  171 + this.$set(this.tabs, 'active', index);
  172 +
  173 + // 根据参数判断请求哪个接口,获取哪个列表
  174 + if (this.tabs.list[this.tabs.active].type == '1' && (!this.tabs.list[this.tabs.active].page || this.tabs.list[this.tabs.active].page == 1)) {
  175 +
  176 + // 获取店铺首页推荐商品列表(初始化)
  177 + this.getShopRecommendGoods(this.CALL_STATUS.INIT);
  178 + }
  179 + },
  180 +
  181 + /**
  182 + * 获取tabs列表
  183 + */
  184 + discountGoods2() {
  185 +
  186 + // 加载中提示
  187 + Indicator.open("加载中...");
  188 +
  189 + // 获取证书请求接口
  190 + this.http("/Api/" + (this.getApiVersion().good) + "/discountGoods2", {
  191 + uid: this.getStore("uid") || 0
  192 + }, this.discountGoods2Callback, {
  193 + method: "POST"
  194 + });
  195 + },
  196 +
  197 + /**
  198 + * 获取tabs列表回调
  199 + * @param {Object} res [服务器返回数据]
  200 + * @param {Object} ext [扩展参数]
  201 + */
  202 + discountGoods2Callback(res, ext) {
  203 +
  204 + // 加载完成
  205 + Indicator.close();
  206 +
  207 + // 返回处理
  208 + if (res.code == 200) {
  209 +
  210 + // 解构数据
  211 + let { data: datas } = res;
  212 +
  213 + /* 获取tabs数据 开始 */
  214 +
  215 + if (datas.nav && datas.nav.length) {
  216 +
  217 + // 合并数组
  218 + this.$set(this.tabs, 'list', [...this.tabs.list, ...datas.nav]);
  219 +
  220 + // 单独设置标题颜色/起始页码/加载中控制
  221 + for (let i = 0; i < this.tabs.list.length; i++) {
  222 + this.$set(this.tabs.list[i], 'titleColor', this.tabs.list[i].color);
  223 + this.$set(this.tabs.list[i], 'page', 1);
  224 + this.$set(this.tabs.list[i], 'loading', false);
  225 + this.$set(this.tabs.list[i], 'loadingNow', false);
  226 + this.$set(this.tabs.list[i], 'finished', false);
  227 + }
  228 + }
  229 +
  230 + /* 获取tabs数据 结束 */
  231 +
  232 + } else if (res.code == 400) {
  233 +
  234 + // 获取分类失败
  235 + Toast(res.message);
  236 + } else {
  237 +
  238 + // 获取分类失败
  239 + Toast("获取分类失败");
  240 + }
  241 + },
  242 +
  243 + /**
  244 + * 获取店铺首页推荐商品列表
  245 + * @param {object} CALL_STATUS [何处触发请求]
  246 + */
  247 + getShopRecommendGoods(CALL_STATUS = this.CALL_STATUS.LOAD_MORE) {
  248 +
  249 + // 判断必要参数
  250 + if (this.tabs.list[this.tabs.active].shop_id) {
  251 +
  252 + // 设置开始加载
  253 + this.$set(this.tabs.list[this.tabs.active], "loading", true);
  254 +
  255 + // 加载中提示
  256 + Indicator.open('加载中...');
  257 +
  258 + // 请求接口
  259 + this.http("/Api/" + (this.getApiVersion().index) + "/shopRecommendGoods", {
  260 + shop_id: this.tabs.list[this.tabs.active].shop_id,
  261 + page: this.tabs.list[this.tabs.active].page
  262 + }, this.getShopRecommendGoodsCallback, {
  263 + method: "POST",
  264 + CALL_STATUS
  265 + });
  266 + }
  267 + },
  268 +
  269 + /**
  270 + * 获取店铺首页推荐商品列表回调
  271 + * param {res} [服务器返回数据]
  272 + * param {ext} [扩展参数]
  273 + */
  274 + getShopRecommendGoodsCallback(res, ext) {
  275 +
  276 + // 加载完成
  277 + Indicator.close();
  278 +
  279 + // 返回处理
  280 + if (res.code == 200) {
  281 +
  282 + // 解构数据
  283 + let {data: datas} = res;
  284 +
  285 + // 判断如果有数据
  286 + if (datas.list && datas.list.length) {
  287 +
  288 + /* 设置列表数据 开始 */
  289 + switch (ext.CALL_STATUS) {
  290 + case this.CALL_STATUS.INIT:
  291 +
  292 + // 设置推荐商品列表
  293 + this.$set(this.lists, this.tabs.active, datas.list);
  294 + break;
  295 + case this.CALL_STATUS.LOAD_MORE:
  296 +
  297 + // 添加数据到数组
  298 + this.$set(this.lists, this.tabs.active, [...this.lists[this.tabs.active], ...datas.list]);
  299 + break;
  300 + }
  301 +
  302 + // 设置页码
  303 + this.$set(this.tabs.list[this.tabs.active], 'page', ++this.tabs.list[this.tabs.active].page);
  304 +
  305 + // 取消Loading中状态,恢复LoadingMore功能
  306 + this.$set(this.tabs.list[this.tabs.active], 'loading', false);
  307 + this.$set(this.tabs.list[this.tabs.active], 'loadingNow', false);
  308 + this.$set(this.tabs.list[this.tabs.active], 'finished', false);
  309 + } else {
  310 +
  311 + // 取消Loading中状态,恢复LoadingMore功能
  312 + this.$set(this.tabs.list[this.tabs.active], 'loading', false);
  313 + this.$set(this.tabs.list[this.tabs.active], 'loadingNow', false);
  314 + this.$set(this.tabs.list[this.tabs.active], 'finished', true);
  315 + }
  316 +
  317 + /* 设置列表数据 结束 */
  318 +
  319 + } else if (res.code == 400) {
  320 +
  321 + // 获取商品出错
  322 + Toast(res.message);
  323 + } else {
  324 +
  325 + // 获取商品出错
  326 + Toast("获取商品出错");
  327 + }
  328 + },
  329 +
  330 + /**
  331 + * 跳转商品详情
  332 + * @param {Object} item [数据对象]
  333 + */
  334 + toDetail(item) {
  335 +
  336 + // 判断App内
  337 + if (this.isCNLive.value) {
  338 +
  339 + // 判断是活动未开始状态,弹窗提示活动未开始
  340 + if (this.tabs.list[this.tabs.active].type == '0' && this.tabs.list[this.tabs.active].discountType == '0') {
  341 +
  342 + // 通用弹窗提示
  343 + this.showModal();
  344 + return false;
  345 + }
  346 +
  347 + // 已结束,不跳转
  348 + if (this.tabs.list[this.tabs.active].type == '0' && this.tabs.list[this.tabs.active].discountType == '2') {
  349 + return false;
  350 + }
  351 +
  352 + // 已抢光,不跳转
  353 + if (this.tabs.list[this.tabs.active].type == '0' && (item.num == '2' || (item.num == '1' && item.stock == '0'))) {
  354 + return false;
  355 + }
  356 +
  357 + // 判断通用跳转函数是否存在
  358 + if (typeof this.$parent.gotoDetail === 'function') {
  359 +
  360 + // 跳转参数
  361 + let params = {
  362 + type: '2',
  363 + to: item.id,
  364 + shop_type: item.shop_type
  365 + };
  366 +
  367 + // 通用跳转
  368 + this.$parent.gotoDetail(params);
  369 + }
  370 + } else {
  371 +
  372 + // App外,唤起App
  373 + this.openApp();
  374 + }
  375 + },
  376 +
  377 + /**
  378 + * 项目按钮事件
  379 + * @param {Object} item [数据对象]
  380 + */
  381 + primary(item) {
  382 +
  383 + // 跳转商品详情
  384 + this.toDetail(item);
  385 + },
  386 +
  387 + showModal() {
  388 +
  389 + // 判断通用弹窗是否存在
  390 + if (typeof this.$parent.showModal === 'function') {
  391 +
  392 + // 设置通用弹窗参数
  393 + let options = {
  394 + title: "提示",
  395 + message: "当前活动未开始,请耐心等待",
  396 + confirmButtonText: "我知道了",
  397 + closeOnClickModal: true
  398 + };
  399 +
  400 + // 调用函数,显示通用弹窗
  401 + this.$parent.showModal(options);
  402 + }
  403 + },
  404 +
  405 + /**
  406 + * 唤起App封装
  407 + */
  408 + openApp() {
  409 +
  410 + this.$nextTick(() => {
  411 +
  412 + // 唤起App
  413 + if (typeof this.$parent.callAppModal === 'function' && typeof this.$refs.callApp === 'object') {
  414 +
  415 + // 设置唤起参数
  416 + let options = {
  417 + success: this.$refs.callApp.callApp
  418 + }
  419 +
  420 + // 唤起App
  421 + this.$parent.callAppModal(options);
  422 + }
  423 + });
  424 + },
  425 +
  426 + /**
  427 + * 分享
  428 + */
  429 + toShare() {
  430 +
  431 + // 判断分享
  432 + if (typeof this.$parent.toShare === 'function') {
  433 + this.$parent.toShare(49, this.$route.query.id || 1);
  434 + }
  435 + },
  436 +
  437 + /**
  438 + * 后退
  439 + */
  440 + back() {
  441 +
  442 + // 判断是否有处理函数
  443 + if (typeof this.$parent.back === 'function') {
  444 +
  445 + // 后退
  446 + this.$parent.back();
  447 + } else {
  448 +
  449 + // 后退
  450 + window.history.go(-1);
  451 + }
  452 + }
  453 + },
  454 + head: {
  455 + title () {
  456 + return {
  457 + inner: this.title
  458 + }
  459 + }
  460 + },
  461 + watch: {
  462 +
  463 + // 设置页面标题
  464 + title(newVal) {
  465 + if (this.$store.state.browser.toLowerCase() == "qq" && this.$store.state.deviceType.toLowerCase() == "iphone") {
  466 + this.$iFrame.insertIFrame(newVal);
  467 + } else {
  468 + this.$emit("updateHead");
  469 + }
  470 + }
  471 + },
  472 + mounted() {
  473 +
  474 + // 如果是App外,设置唤起App和微信内分享参数
  475 + if (!this.isCNLive.value) {
  476 +
  477 + // 唤起详情页
  478 + if (typeof this.$parent.getOpenApp === "function") {
  479 + this.$parent.getOpenApp({
  480 + type: 49,
  481 + id: this.$route.query.id || 1,
  482 + url: ""
  483 + });
  484 + }
  485 +
  486 + // 分享详情页
  487 + if (typeof this.$parent.getShareData === "function") {
  488 + this.$parent.getShareData({
  489 + type: 49,
  490 + id: this.$route.query.id || 1,
  491 + url: ""
  492 + });
  493 + }
  494 + }
  495 +
  496 + // 页面切换可见状态监听
  497 + document.addEventListener('visibilitychange', () => {
  498 +
  499 + // 页面显示出来了
  500 + if (document.hidden === false && this.$route.name == 'discountList') {
  501 +
  502 + // 只有折扣专区的刷新页面
  503 + if (this.tabs.list[this.tabs.active].type == '0') {
  504 +
  505 + // 请求接口封装
  506 + this.request(this.tabs.active);
  507 + }
  508 + }
  509 + });
  510 + }
  511 + }
  512 +</script>
  513 +
  514 +<!-- Add "scoped" attribute to limit CSS to this component only -->
  515 +<style rel="stylesheet/less" lang='less' scoped>
  516 + @import "discountList2";
  517 +</style>
src/router/index.js
@@ -202,6 +202,17 @@ const router = new Router({ @@ -202,6 +202,17 @@ const router = new Router({
202 } 202 }
203 }, 203 },
204 { 204 {
  205 + // 新版优选库“优选折扣列表”页面(单独处理,不带折扣专区)
  206 + path: "/discountList2",
  207 + name: "discountList2",
  208 + component: resolve => {
  209 + require(["@/pages/discountList2/discountList2"], resolve);
  210 + },
  211 + meta: {
  212 + requireAuth: false
  213 + }
  214 + },
  215 + {
205 // 新版优选库“优选热销排行列表”页面 216 // 新版优选库“优选热销排行列表”页面
206 path: "/hotSaleList", 217 path: "/hotSaleList",
207 name: "hotSaleList", 218 name: "hotSaleList",