Commit b94ceba3d30f8f4a0ca89a8492e81a6c4f864dff

Authored by zhiyangdu
1 parent fdc6447e

新增爱心屋项目

src/components/columnCommodityListBox/columnCommodityListBox.less 0 → 100644
  1 +@charset "UTF-8";
  2 +
  3 +.column-list-box {
  4 + .title-box {
  5 + & + .box {
  6 + margin-top: 30px;
  7 + }
  8 + }
  9 + .box {
  10 + // display: flex;
  11 + // flex-direction: row;
  12 + // justify-content: space-between;
  13 + // align-items: flex-start;
  14 + // flex-wrap: wrap;
  15 + column-count: 2;
  16 + column-width: 336px;
  17 + column-gap: 18px;
  18 + margin: 0 auto;
  19 + padding-bottom: 18px;
  20 + width: 690px;
  21 + .left-box {
  22 + .item-box {
  23 + &:last-child {
  24 + margin-bottom: 0;
  25 + }
  26 + }
  27 + }
  28 + .right-box {
  29 + .item-box {
  30 + &:last-child {
  31 + // margin-bottom: 0;
  32 + }
  33 + }
  34 + }
  35 + .item-box {
  36 + background-color: #ffffff;
  37 + margin-bottom: 18px;
  38 + width: 336px;
  39 + height: auto;
  40 + break-inside: avoid;
  41 + border-radius: 16px;
  42 + overflow: hidden;
  43 + .item {
  44 + width: 100%;
  45 + height: auto;
  46 + .img-box {
  47 + display: flex;
  48 + justify-content: center;
  49 + align-items: center;
  50 + width: 100%;
  51 + height: 336px;
  52 + // height: 100%;
  53 + overflow: hidden;
  54 + .img {
  55 + display: block;
  56 + width: 100%;
  57 + height: auto;
  58 + }
  59 + }
  60 + .content-box {
  61 + margin: 0 auto;
  62 + width: 286px;
  63 + .title {
  64 + display: -webkit-box;
  65 + margin-top: 20px;
  66 + color: #333333;
  67 + font-size: 26px;
  68 + width: 100%;
  69 + height: auto;
  70 + line-height: 40px;
  71 + -webkit-line-clamp: 2;
  72 + -webkit-box-orient: vertical;
  73 + text-overflow: ellipsis;
  74 + overflow: hidden;
  75 + }
  76 + .coupon-box {
  77 + display: inline;
  78 + margin-top: 8px;
  79 + padding: 1px 6px;
  80 + color: #FC1541;
  81 + font-size: 18px;
  82 + border: 1px solid #FC1541;
  83 + border-radius: 4px;
  84 + }
  85 + .price-box {
  86 + display: flex;
  87 + justify-content: space-between;
  88 + align-items: center;
  89 + margin-top: 25px;
  90 + margin-bottom: 20px;
  91 + .left {
  92 + display: flex;
  93 + justify-content: flex-start;
  94 + align-items: baseline;
  95 + color: #FC1541;
  96 + .y {
  97 + font-size: 24px;
  98 + }
  99 + .integer {
  100 + font-size: 38px;
  101 + }
  102 + .decimal {
  103 + font-size: 24px;
  104 + }
  105 +
  106 + }
  107 + .right {
  108 + display: flex;
  109 + justify-content: flex-end;
  110 + align-items: baseline;
  111 + .icon-add {
  112 + display: block;
  113 + width: 48px;
  114 + height: 48px;
  115 + }
  116 + }
  117 + }
  118 + }
  119 + }
  120 + }
  121 + }
  122 +}
0 \ No newline at end of file 123 \ No newline at end of file
src/components/columnCommodityListBox/columnCommodityListBox.vue 0 → 100644
  1 +<template>
  2 + <div class="column-list-box" v-if="columnLists && columnLists.list && columnLists.list.length">
  3 + <slot name="title"></slot>
  4 + <div class="box">
  5 +
  6 + <!-- left-box -->
  7 + <div class="left-box">
  8 +
  9 + <!-- 数组内奇数,index是偶数 -->
  10 + <div class="item-box" v-if="!(index % 2)" v-for="(item, index) in columnLists.list" :key="index" @click="toDetail(item)">
  11 + <div class="item">
  12 + <div class="img-box">
  13 + <img v-lazy="item.simg + SIGN.MIDDLE" class="img" />
  14 + </div>
  15 + <div class="content-box">
  16 + <div class="title">{{item.title}}</div>
  17 + <!-- <div class="coupon-box">
  18 + 满180减10
  19 + </div> -->
  20 + <div class="price-box">
  21 + <div class="left">
  22 + <div class="y">¥</div>
  23 + <div class="integer">{{getInteger(item.price)}}.</div>
  24 + <div class="decimal">{{getDecimal(item.price)}}</div>
  25 + </div>
  26 + <div class="right">
  27 + <img src="static/img/icon_add.png" class="icon-add" mode="widthFix" />
  28 + </div>
  29 + </div>
  30 + </div>
  31 + </div>
  32 + </div>
  33 + </div>
  34 +
  35 + <!-- right-box -->
  36 + <div class="right-box">
  37 +
  38 + <!-- 数组内偶数,index是奇数 -->
  39 + <div class="item-box" v-if="index % 2" v-for="(item, index) in columnLists.list" :key="index" @click="toDetail(item)">
  40 + <div class="item">
  41 + <div class="img-box">
  42 + <img v-lazy="item.simg + SIGN.MIDDLE" class="img" />
  43 + </div>
  44 + <div class="content-box">
  45 + <div class="title">{{item.title}}</div>
  46 + <!-- <div class="coupon-box">
  47 + 满180减10
  48 + </div> -->
  49 + <div class="price-box">
  50 + <div class="left">
  51 + <div class="y">¥</div>
  52 + <div class="integer">{{getInteger(item.price)}}.</div>
  53 + <div class="decimal">{{getDecimal(item.price)}}</div>
  54 + </div>
  55 + <div class="right">
  56 + <img src="static/img/icon_add.png" class="icon-add" mode="widthFix" />
  57 + </div>
  58 + </div>
  59 + </div>
  60 + </div>
  61 + </div>
  62 + </div>
  63 + </div>
  64 + </div>
  65 +</template>
  66 +
  67 +<script>
  68 + export default {
  69 + data() {
  70 + return {
  71 +
  72 + };
  73 + },
  74 + props: ["columnLists"],
  75 + computed: {
  76 +
  77 + /**
  78 + * 获取整数
  79 + */
  80 + getInteger() {
  81 + return (number) => {
  82 + return parseInt(number);
  83 + }
  84 + },
  85 +
  86 + /**
  87 + * 获取小数
  88 + */
  89 + getDecimal() {
  90 + return (number) => {
  91 +
  92 + // 拆分数字
  93 + let numberArr = number.toString().split(".");
  94 +
  95 + // 判断是否有效数部分
  96 + if (numberArr.length === 2) {
  97 + return numberArr[1];
  98 + } else {
  99 + return "00";
  100 + }
  101 + }
  102 + }
  103 + },
  104 + methods: {
  105 +
  106 + /**
  107 + * 跳转详情
  108 + * @param {object} item [对象]
  109 + */
  110 + toDetail(item) {
  111 + this.$emit("detail", item);
  112 + }
  113 + }
  114 + }
  115 +</script>
  116 +
  117 +<!-- Add "scoped" attribute to limit CSS to this component only -->
  118 +<style rel="stylesheet/less" lang='less' scoped>
  119 + @import './columnCommodityListBox';
  120 +</style>
0 \ No newline at end of file 121 \ No newline at end of file
src/components/htmlBox/htmlBox.less 0 → 100644
  1 +@charset "UTF-8";
  2 +
  3 +.html-box {
  4 + .box {
  5 + width: 750px;
  6 + height: auto;
  7 + .html {
  8 + background-color: #ffffff;
  9 + margin: 0 auto;
  10 + width: 690px;
  11 + height: auto;
  12 + color: #999999 !important;
  13 + font-size: 26px !important;
  14 + p {
  15 + margin-top: 20px;
  16 + margin-bottom: 20px;
  17 + margin-block-start: 20px;
  18 + margin-block-end: 20px;
  19 + margin-inline-start: 0px;
  20 + margin-inline-end: 0px;
  21 + }
  22 + img {
  23 + width: 100% !important;
  24 + height: auto !important;
  25 + }
  26 + }
  27 + }
  28 +}
0 \ No newline at end of file 29 \ No newline at end of file
src/components/htmlBox/htmlBox.vue 0 → 100644
  1 +<template>
  2 + <div class="html-box" v-if="htmls">
  3 + <div class="box">
  4 + <div class="html" v-html="htmls"></div>
  5 + </div>
  6 + </div>
  7 +</template>
  8 +
  9 +<script>
  10 + export default {
  11 + data() {
  12 + return {
  13 +
  14 + }
  15 + },
  16 + props: ["htmls"],
  17 + methods: {
  18 +
  19 + }
  20 + }
  21 +</script>
  22 +
  23 +<!-- Add "scoped" attribute to limit CSS to this component only -->
  24 +<style rel="stylesheet/less" lang="less" scoped>
  25 + @import './htmlBox';
  26 +</style>
src/components/imgListBox/imgListBox.less 0 → 100644
  1 +@charset "UTF-8";
  2 +
  3 +.img-list-box {
  4 + .box {
  5 + width: 750px;
  6 + height: auto;
  7 + .img-box {
  8 + display: flex;
  9 + justify-content: center;
  10 + align-items: center;
  11 + padding-bottom: 80px;
  12 + width: 100%;
  13 + height: 100%;
  14 + &:first-child {
  15 + padding-top: 50px;
  16 + }
  17 + .img {
  18 + display: block;
  19 + width: 100%;
  20 + }
  21 + }
  22 + }
  23 +}
0 \ No newline at end of file 24 \ No newline at end of file
src/components/imgListBox/imgListBox.vue 0 → 100644
  1 +<template>
  2 + <div class="img-list-box" v-if="imgLists && imgLists.list && imgLists.list.length">
  3 + <div class="box">
  4 + <div class="img-box" v-for="(item, index) in imgLists.list" :key="index" @click="toDetail(item)">
  5 + <img v-lazy="item.simg + SIGN.BIG" class="img" mode="widthFix" />
  6 + </div>
  7 + </div>
  8 + </div>
  9 +</template>
  10 +
  11 +<script>
  12 + export default {
  13 + data() {
  14 + return {
  15 +
  16 + };
  17 + },
  18 + props: ["imgLists"],
  19 + methods: {
  20 +
  21 + /**
  22 + * 跳转详情
  23 + * @param {object} item [列表对象]
  24 + */
  25 + toDetail(item) {
  26 + this.$emit("detail", item);
  27 + }
  28 + }
  29 + }
  30 +</script>
  31 +
  32 +<!-- Add "scoped" attribute to limit CSS to this component only -->
  33 +<style rel="stylesheet/less" lang='less' scoped>
  34 + @import './imgListBox';
  35 +</style>
0 \ No newline at end of file 36 \ No newline at end of file
src/main.js
@@ -44,7 +44,7 @@ import &#39;url-search-params-polyfill&#39;; @@ -44,7 +44,7 @@ import &#39;url-search-params-polyfill&#39;;
44 Vue.config.productionTip = false; 44 Vue.config.productionTip = false;
45 45
46 // 部署模式设置(开发模式:"dev",测试模式:"test",生产模式:"prod") 46 // 部署模式设置(开发模式:"dev",测试模式:"test",生产模式:"prod")
47 -Vue.prototype.mode = "dev"; 47 +Vue.prototype.mode = "test";
48 48
49 // 微信JS-SDK对象 49 // 微信JS-SDK对象
50 Vue.prototype.jweixin = { 50 Vue.prototype.jweixin = {
src/pages/GuanAIHouse/GuanAIHouse.less 0 → 100644
  1 +@charset "UTF-8";
  2 +
  3 +.mall-box {
  4 + .nav {
  5 + position: fixed;
  6 + top: 0;
  7 + z-index: 100;
  8 + background-color: transparent;
  9 + width: 750px;
  10 + height: auto;
  11 + }
  12 + .pl-call-app {
  13 + background-color: transparent;
  14 + width: 100%;
  15 + height: 122px;
  16 + }
  17 + .pl-nav {
  18 + background-color: #FA245F;
  19 + width: 100%;
  20 + height: 93px;
  21 + }
  22 + /deep/ .van-pull-refresh {
  23 + .van-pull-refresh__track {
  24 + .van-pull-refresh__head {
  25 + font-size: 30px;
  26 + }
  27 + }
  28 + }
  29 + .header-box {
  30 + background-color: #FA245F;
  31 + width: 750px;
  32 + height: auto;
  33 + .swiper-box {
  34 + // padding-top: 93px;
  35 + padding-bottom: 30px;
  36 + }
  37 + .padding-top30{
  38 + padding-top: 30px;
  39 + }
  40 + }
  41 + .main-box {
  42 + .tabs-box {
  43 + padding-top: 30px;
  44 + padding-bottom: 30px;
  45 + width: 750px;
  46 + height: auto;
  47 + &.bg-white {
  48 + background-color: #ffffff;
  49 + }
  50 + &.bg-excessive-color {
  51 + background: linear-gradient(90deg, rgba(255, 246, 248, 1) 0%, rgba(255, 233, 239, 1) 100%);
  52 + }
  53 + .box {
  54 + display: flex;
  55 + justify-content: space-around;
  56 + align-items: center;
  57 + margin: 0 auto;
  58 + width: 690px;
  59 + height: 100%;
  60 + .tab {
  61 + color: #B4B4B4;
  62 + font-size: 32px;
  63 + .line {
  64 + background-color: transparent;
  65 + margin: 8px auto 0 auto;
  66 + width: 40px;
  67 + height: 4px;
  68 + }
  69 + &.active {
  70 + color: #333333;
  71 + .line {
  72 + background-color: #FC1541;
  73 + width: 40px;
  74 + height: 4px;
  75 + }
  76 + }
  77 + }
  78 + }
  79 + }
  80 + .tabs-swiper-box {
  81 + width: 750px;
  82 + height: auto;
  83 + .swipe {
  84 + width: 100%;
  85 + height: 100%;
  86 + .swipe-item {
  87 + width: 100%;
  88 + height: 100%;
  89 + .skeleton {
  90 + &.brief {
  91 + background-color: #ffffff;
  92 + }
  93 + &.boutique {
  94 + background: linear-gradient(90deg, rgba(255, 246, 248, 1) 0%, rgba(255, 233, 239, 1) 100%);
  95 + }
  96 + &.commodity {
  97 + background-color: #F9F9F9;
  98 + .column-commodity-excessive {
  99 + background: linear-gradient(180deg, rgba(255, 255, 255, 1) 0%, rgba(249, 249, 249, 1) 100%);
  100 + width: 750px;
  101 + height: 30px;
  102 + }
  103 + }
  104 + }
  105 + }
  106 + }
  107 + }
  108 + }
  109 +}
src/pages/GuanAIHouse/GuanAIHouse.vue 0 → 100644
  1 +<template>
  2 + <div class="mall-box" ref="mallBox">
  3 +
  4 + <!-- nav -->
  5 + <div class="nav">
  6 +
  7 + <!-- H5唤起App组件 -->
  8 + <call-app-box class="call-app-box" :style="'padding-top: ' + ($parent.top.value) + 'px'" ref="callApp" v-if="!isCNLive.value"
  9 + :callApps="$parent.callApps">
  10 + </call-app-box>
  11 +
  12 + <!-- 后退按钮组 -->
  13 + <back-box v-if="$parent.isBackBox.value" class="back-box" :style="'padding-top: ' + $parent.top.value + 'px; background-color: rgba(250, 36, 95, ' + opacity + ')'" ref="navBox" @back="back"
  14 + :backs="backs">
  15 + </back-box>
  16 + </div>
  17 +
  18 + <!-- pl callApp -->
  19 + <div class="pl-call-app" :style="'padding-top: ' + $parent.top.value + 'px'" v-if="$parent.isOpenApp.value"></div>
  20 +
  21 + <!-- pl nav -->
  22 + <div v-if="$parent.isBackBox.value" class="pl-nav" :style="'padding-top: ' + $parent.top.value + 'px'"></div>
  23 +
  24 + <!-- 头部区域 -->
  25 + <div class="header-box" ref="headerBox">
  26 +
  27 + <!-- 轮播图 -->
  28 + <swiper-box class="swiper-box" :class="{'padding-top30': !$parent.isBackBox.value}" @detail="toDetail"
  29 + :swipers="swipers">
  30 + </swiper-box>
  31 + </div>
  32 +
  33 + <!-- 主内容区域 -->
  34 + <div class="main-box">
  35 +
  36 + <!-- tabs -->
  37 + <div class="tabs-box" :class="tabs[activeTabIndex] && tabs[activeTabIndex].class ? tabs[activeTabIndex].class : ''" ref="tabsBox">
  38 + <div class="box">
  39 + <div class="tab" :class="{'active': item.active}" v-for="(item, index) in tabs" :key="index" @click="changeTab(item)">
  40 + <div class="title">{{item.title}}</div>
  41 + <div class="line"></div>
  42 + </div>
  43 + </div>
  44 + </div>
  45 +
  46 + <!-- 滑动列表区域 -->
  47 + <div class="tabs-swiper-box" :style="{height: swiperExce.offsetHeight + 'px', minHeight: 'calc(100vh - ' + ($parent.top.value + 'px') + ' - 38.1vh)'}" ref="tabsSwiperBox">
  48 + <swipe class="swipe" ref="swiperBox" :autoplay="0" :touchable="swiperTouchable.value" :show-indicators="false" :loop="false" :initial-swipe="2" @change="swiperChange">
  49 + <swipe-item class="swipe-item">
  50 +
  51 + <!-- 外部骨架 -->
  52 + <div class="skeleton brief" ref="brief">
  53 +
  54 + <!-- 领头雁简介 -->
  55 + <html-box
  56 + :htmls="briefs">
  57 + </html-box>
  58 + </div>
  59 + </swipe-item>
  60 + <swipe-item class="swipe-item">
  61 +
  62 + <!-- 外部骨架 -->
  63 + <div class="skeleton boutique" ref="boutique">
  64 +
  65 + <!-- 精品推荐 -->
  66 + <div class="boutique-list" v-infinite-scroll="loadBoutique" infinite-scroll-disabled="paging.boutique.loading" :infinite-scroll-distance="paging.distance">
  67 +
  68 + <img-list-box @detail="toDetail"
  69 + :imgLists="boutiques">
  70 + </img-list-box>
  71 + </div>
  72 + </div>
  73 + </swipe-item>
  74 + <swipe-item class="swipe-item">
  75 +
  76 + <!-- 外部骨架 -->
  77 + <div class="skeleton commodity" ref="commodity">
  78 +
  79 + <!-- 渐变过度 -->
  80 + <div class="column-commodity-excessive"></div>
  81 +
  82 + <!-- 商品推荐 -->
  83 + <div class="column-commodity-list" v-infinite-scroll="loadCommodity" infinite-scroll-disabled="paging.commodity.loading" :infinite-scroll-distance="paging.distance">
  84 +
  85 + <column-commodity-list-box @detail="toCommodityDetail"
  86 + :columnLists="commoditys">
  87 + </column-commodity-list-box>
  88 + </div>
  89 + </div>
  90 + </swipe-item>
  91 + </swipe>
  92 + </div>
  93 + </div>
  94 + </div>
  95 +</template>
  96 +
  97 +<script>
  98 +
  99 + // 引入组件
  100 + import Vue from "vue";
  101 + // import { Toast, Indicator, Swipe, SwipeItem } from "mint-ui";
  102 + import { Toast, Indicator } from "mint-ui";
  103 + import { Swipe, SwipeItem } from "vant";
  104 + import callAppBox from "@/components/callAppBox/callAppBox";
  105 + import swiperBox from "@/components/swiper/swiper";
  106 + import backBox from "@/components/backBox/backBox";
  107 + import htmlBox from "@/components/htmlBox/htmlBox";
  108 + import imgListBox from "@/components/imgListBox/imgListBox";
  109 + import columnCommodityListBox from "@/components/columnCommodityListBox/columnCommodityListBox";
  110 +
  111 + export default {
  112 + data () {
  113 + return {
  114 + title: "", // 页面标题
  115 + backs: null, // 后退按钮组
  116 + opacity: 0, // 后退按钮背景色透明度
  117 + swipers: null, // 轮播图
  118 + tabs: null, // tabs内容
  119 + activeTabIndex: -1, // 活动tab索引
  120 + swiperExce: { // swiper元素高度,最小高度
  121 + offsetHeight: 0
  122 + },
  123 + swiperTouchable: { // 是否可以通过手势滑动
  124 + value: true
  125 + },
  126 + briefs: null, // 领头雁简介
  127 + boutiques: { // 精品推荐
  128 + list: []
  129 + },
  130 + shopId: null, // 店铺id
  131 + commoditys: { // 全部推荐
  132 + list: []
  133 + },
  134 + paging: { // 分页
  135 + boutique: {
  136 + loading: true,
  137 + page: 1
  138 + },
  139 + commodity: {
  140 + loading: true,
  141 + page: 1
  142 + },
  143 + distance: 50
  144 + }
  145 + }
  146 + },
  147 + components: {
  148 + Swipe,
  149 + SwipeItem,
  150 + callAppBox,
  151 + swiperBox,
  152 + backBox,
  153 + htmlBox,
  154 + imgListBox,
  155 + columnCommodityListBox
  156 + },
  157 + created() {
  158 +
  159 + // 设置后退按钮组
  160 + this.$set(this, "backs", {
  161 + title: ""
  162 + });
  163 +
  164 + // 判断是否在App内
  165 + if (this.isCNLive.value) {
  166 +
  167 + // 添加后退按钮组“后退”和“分享”按钮
  168 + Object.assign(this.backs, {
  169 + funcs: {
  170 + back: {
  171 + icon: "static/img/icon_back_white.png"
  172 + },
  173 + funcArray: [
  174 + {
  175 + icon: "static/img/icon_share_white.png",
  176 + func: this.toShare
  177 + }
  178 + ]
  179 + }
  180 + });
  181 + }
  182 +
  183 + // tabs
  184 + this.$set(this, "tabs", [
  185 + {
  186 + title: "领头雁简介",
  187 + active: false,
  188 + class: "bg-white"
  189 + },
  190 + {
  191 + title: "精品推荐",
  192 + active: false,
  193 + class: "bg-excessive-color"
  194 + },
  195 + {
  196 + title: "全部商品",
  197 + active: false,
  198 + class: "bg-white"
  199 + }
  200 + ]);
  201 +
  202 + // 判断商品列表是否可以滑动
  203 + if (this.$route.query.swiperTouchable) {
  204 + if (typeof this.$route.query.swiperTouchable === "string" && this.$route.query.swiperTouchable === "false") {
  205 + this.$set(this.swiperTouchable, "value", false);
  206 + }
  207 + }
  208 +
  209 + // 领头雁电商活动
  210 + this.activityAdsShop();
  211 +
  212 + // 获取领头雁电商精品推荐
  213 + this.getActivityAdsGoods(this.paging.boutique.page);
  214 + },
  215 + methods: {
  216 +
  217 + /**
  218 + * 上拉加载“精品推荐”
  219 + */
  220 + loadBoutique() {
  221 +
  222 + // 判断是“精品推荐”页才加载
  223 + if (this.activeTabIndex === 1) {
  224 +
  225 + // 设置“精品推荐”页码
  226 + this.$set(this.paging.boutique, "page", ++this.paging.boutique.page);
  227 +
  228 + // 调用接口
  229 + this.getActivityAdsGoods(this.paging.boutique.page);
  230 + }
  231 + },
  232 +
  233 + /**
  234 + * 上拉加载“商品推荐”
  235 + */
  236 + loadCommodity() {
  237 +
  238 + // 判断是“精品推荐”页才加载
  239 + if (this.activeTabIndex === 2 && this.shopId) {
  240 +
  241 + // 设置“精品推荐”页码
  242 + this.$set(this.paging.commodity, "page", ++this.paging.commodity.page);
  243 +
  244 + // 调用接口
  245 + this.shopRecommendGoods(this.paging.commodity.page);
  246 + }
  247 + },
  248 +
  249 + /**
  250 + * 领头雁电商活动
  251 + */
  252 + activityAdsShop() {
  253 +
  254 + // 判断必要参数
  255 + if (this.$route.query.id) {
  256 +
  257 + // 加载中提示
  258 + Indicator.open('加载中...');
  259 +
  260 + // 请求接口
  261 + this.http("/Api/" + (this.getApiVersion().LeadGoose) + "/activityAdsShop", {
  262 + id: this.$route.query.id
  263 + }, this.activityAdsShopCallback, {
  264 + method: "POST"
  265 + });
  266 + }
  267 + },
  268 +
  269 + /**
  270 + * 领头雁电商活动回调
  271 + * @param {object} res [服务器返回数据]
  272 + * @param {object} ext [扩展参数]
  273 + */
  274 + activityAdsShopCallback(res, ext) {
  275 +
  276 + // 加载完成
  277 + Indicator.close();
  278 +
  279 + // 返回处理
  280 + if (res.code == 200) {
  281 + // 解构数据
  282 + let {data: datas} = res;
  283 +
  284 + /* 设置活动数据 开始 */
  285 +
  286 + // 设置标题
  287 + this.$set(this, "title", datas.title);
  288 +
  289 + // 设置后退按钮组标题
  290 + this.$set(this.backs, "title", datas.title);
  291 +
  292 + // 设置banner
  293 + if (datas.banner) {
  294 + this.$set(this, "swipers", {
  295 + list: datas.banner
  296 + });
  297 + }
  298 +
  299 + // 设置领头雁简介
  300 + this.$set(this, "briefs", datas.content);
  301 +
  302 + // 设置活动店铺shop_id,用于店铺推荐商品使用
  303 + if (datas.shop_id) {
  304 +
  305 + // 设置活动店铺shop_id
  306 + this.$set(this, "shopId", datas.shop_id);
  307 +
  308 + // 店铺商品推荐
  309 + this.shopRecommendGoods(this.paging.commodity.page);
  310 + }
  311 +
  312 + /* 设置活动数据 结束 */
  313 +
  314 + } else if (res.code == 400) {
  315 +
  316 + // 获取活动失败
  317 + Toast(res.message);
  318 + } else {
  319 +
  320 + // 获取活动失败
  321 + Toast("获取活动失败");
  322 + }
  323 + },
  324 +
  325 + /**
  326 + * 获取领头雁电商精品推荐
  327 + * @param {int} page [页码]
  328 + */
  329 + getActivityAdsGoods(page) {
  330 +
  331 + // 判断必要参数
  332 + if (this.$route.query.id) {
  333 +
  334 + // 加载中
  335 + this.$set(this.paging.boutique, "loading", true);
  336 +
  337 + // 加载中提示
  338 + Indicator.open('加载中...');
  339 +
  340 + // 请求接口
  341 + this.http("/Api/" + (this.getApiVersion().LeadGoose) + "/getActivityAdsGoods", {
  342 + id: this.$route.query.id,
  343 + page: page
  344 + }, this.getActivityAdsGoodsCallback, {
  345 + method: "POST"
  346 + });
  347 + }
  348 + },
  349 +
  350 + /**
  351 + * 获取领头雁电商精品推荐回调
  352 + * @param {object} res [服务器返回数据]
  353 + * @param {object} ext [扩展参数]
  354 + */
  355 + getActivityAdsGoodsCallback(res, ext) {
  356 +
  357 + // 加载完成
  358 + Indicator.close();
  359 +
  360 + // 返回处理
  361 + if (res.code == 200) {
  362 +
  363 + // 解构数据
  364 + let {data: datas} = res;
  365 +
  366 + /* 设置精品推荐数据 开始 */
  367 +
  368 + // 判断是否有数据
  369 + if (datas.list && datas.list.length) {
  370 +
  371 + // 追加列表
  372 + this.$set(this.boutiques, "list", [...this.boutiques.list, ...datas.list]);
  373 +
  374 + // 设置还有需要加载的内容
  375 + this.$set(this.paging.boutique, "loading", false);
  376 +
  377 + // 如果当前显示“精品推荐”,设置swiper高度
  378 + if (this.activeTabIndex === 1) {
  379 +
  380 + this.$nextTick(() => {
  381 +
  382 + setTimeout(() => {
  383 +
  384 + // 重新设置swiper高度
  385 + this.$set(this.swiperExce, "offsetHeight", this.$refs.boutique.offsetHeight);
  386 + }, 500);
  387 + });
  388 + }
  389 + } else {
  390 +
  391 + // 没有需要加载的内容,停止上拉加载
  392 + this.$set(this.paging.boutique, "loading", true);
  393 + }
  394 +
  395 + /* 设置精品推荐数据 结束 */
  396 +
  397 + } else if (res.code == 400) {
  398 +
  399 + // 获取精品推荐失败
  400 + Toast(res.message);
  401 + } else {
  402 +
  403 + // 获取精品推荐失败
  404 + Toast("获取精品推荐失败");
  405 + }
  406 + },
  407 +
  408 + /**
  409 + * 店铺商品推荐
  410 + * @param {int} page [页码]
  411 + */
  412 + shopRecommendGoods(page) {
  413 +
  414 + // 判断必要参数
  415 + if (this.shopId) {
  416 +
  417 + // 加载中
  418 + this.$set(this.paging.commodity, "loading", true);
  419 +
  420 + // 加载中提示
  421 + Indicator.open('加载中...');
  422 +
  423 + // 请求接口
  424 + this.http("/Api/" + (this.getApiVersion().index) + "/shopRecommendGoods", {
  425 + shop_id: this.shopId,
  426 + page: page
  427 + }, this.shopRecommendGoodsCallback, {
  428 + method: "POST"
  429 + });
  430 + }
  431 + },
  432 +
  433 + /**
  434 + * 店铺商品推荐回调
  435 + * @param {object} res [服务器返回数据]
  436 + * @param {object} ext [扩展参数]
  437 + */
  438 + shopRecommendGoodsCallback(res, ext) {
  439 +
  440 + // 加载完成
  441 + Indicator.close();
  442 +
  443 + // 返回处理
  444 + if (res.code == 200) {
  445 +
  446 + // 解构数据
  447 + let {data: datas} = res;
  448 +
  449 + /* 设置商品推荐数据 开始 */
  450 +
  451 + // 判断是否有数据
  452 + if (datas.list && datas.list.length) {
  453 +
  454 + // 追加列表
  455 + this.$set(this.commoditys, "list", [...this.commoditys.list, ...datas.list]);
  456 +
  457 + // 设置还有需要加载的内容
  458 + this.$set(this.paging.commodity, "loading", false);
  459 +
  460 + // 如果当前显示“全部商品”,设置swiper高度
  461 + if (this.activeTabIndex === 2) {
  462 +
  463 + this.$nextTick(() => {
  464 +
  465 + setTimeout(() => {
  466 +
  467 + // 重新设置swiper高度
  468 + this.$set(this.swiperExce, "offsetHeight", this.$refs.commodity.offsetHeight);
  469 + }, 500);
  470 + });
  471 + }
  472 + } else {
  473 +
  474 + // 没有需要加载的内容,停止上拉加载
  475 + this.$set(this.paging.commodity, "loading", true);
  476 + }
  477 +
  478 + /* 设置商品推荐数据 结束 */
  479 +
  480 + } else if (res.code == 400) {
  481 +
  482 + // 获取商品推荐失败
  483 + Toast(res.message);
  484 + } else {
  485 +
  486 + // 获取商品推荐失败
  487 + Toast("获取商品推荐失败");
  488 + }
  489 + },
  490 +
  491 + /**
  492 + * 调用通用跳转
  493 + * @param {object} item [通用跳转对象]
  494 + */
  495 + toDetail(item) {
  496 +
  497 + // 判断是否有通用跳转函数
  498 + if (typeof this.$parent.gotoDetail === "function") {
  499 +
  500 + // 调用通用跳转
  501 + this.$parent.gotoDetail(item);
  502 + }
  503 + },
  504 +
  505 + /**
  506 + * 特定跳转商品详情
  507 + * @param {object} item [跳转对象]
  508 + */
  509 + toCommodityDetail(item) {
  510 +
  511 + // 设置跳转参数
  512 + Object.assign(item, {
  513 + type: "2",
  514 + to: item.id
  515 + });
  516 +
  517 + // 调用通用跳转
  518 + this.toDetail(item);
  519 + },
  520 +
  521 + /**
  522 + * 切换tab
  523 + * @param {object} item [当前备切换的标签对象]
  524 + */
  525 + changeTab(item) {
  526 +
  527 + // 判断点击的是非当前活动项目
  528 + if (!item.active) {
  529 +
  530 + // 清理所有活动状态
  531 + for (let i = 0; i < this.tabs.length; i++) {
  532 + this.$set(this.tabs[i], "active", false);
  533 + }
  534 +
  535 + // 设置新的活动项目
  536 + this.$set(item, "active", true);
  537 +
  538 + // 设置新的活动索引
  539 + for (let i = 0; i < this.tabs.length; i++) {
  540 + if (item.title === this.tabs[i].title) {
  541 + this.$set(this, "activeTabIndex", i);
  542 + break;
  543 + }
  544 + }
  545 +
  546 + // 判断是否需要执行切换
  547 + if (this.$refs.swiperBox.active !== this.activeTabIndex) {
  548 +
  549 + // 切换到对应swiper
  550 + this.$refs.swiperBox.swipeTo(this.activeTabIndex);
  551 +
  552 + // 设置swiper高度
  553 + this.setSwiperHeight();
  554 + }
  555 + }
  556 + },
  557 +
  558 + /**
  559 + * swiper滑动改变
  560 + * @param {int} index [swiper索引]
  561 + */
  562 + swiperChange(index) {
  563 +
  564 + // 如果当前tabs不一致,并且不是在切换中,设置tabs联动
  565 + if (index !== this.activeTabIndex) {
  566 +
  567 + // 清理所有活动状态
  568 + for (let i = 0; i < this.tabs.length; i++) {
  569 + this.$set(this.tabs[i], "active", false);
  570 + }
  571 +
  572 + // 设置新的活动项目
  573 + this.$set(this.tabs[index], "active", true);
  574 +
  575 + // 设置新的活动索引
  576 + this.$set(this, "activeTabIndex", index);
  577 +
  578 + // 设置swiper高度
  579 + this.setSwiperHeight();
  580 + }
  581 + },
  582 +
  583 + /**
  584 + * 设置swiper高度
  585 + */
  586 + setSwiperHeight() {
  587 +
  588 + this.$nextTick(() => {
  589 +
  590 + // 设置swiper高度
  591 + switch (this.activeTabIndex) {
  592 + case 0:
  593 + this.$set(this.swiperExce, "offsetHeight", this.$refs.brief.offsetHeight);
  594 + break;
  595 + case 1:
  596 + this.$set(this.swiperExce, "offsetHeight", this.$refs.boutique.offsetHeight);
  597 + break;
  598 + case 2:
  599 + this.$set(this.swiperExce, "offsetHeight", this.$refs.commodity.offsetHeight);
  600 + break;
  601 + }
  602 + });
  603 + },
  604 +
  605 + /**
  606 + * 后退
  607 + */
  608 + back() {
  609 +
  610 + // 判断后退
  611 + if (typeof this.$parent.back === "function") {
  612 + this.$parent.back();
  613 + } else {
  614 + window.history.go(-1);
  615 + }
  616 + },
  617 +
  618 + /**
  619 + * 分享
  620 + */
  621 + toShare() {
  622 +
  623 + // 判断分享
  624 + if (typeof this.$parent.toShare === "function") {
  625 + this.$parent.toShare(37, this.$route.query.id || 0);
  626 + }
  627 + },
  628 +
  629 + /**
  630 + * 滚动条滚动/touchmove监听处理
  631 + * @param {object} e [滚动条对象]
  632 + * @param {boolean} isTimeout [是否为setTimeout方法调用]
  633 + */
  634 + onPageScrollFun(e, isTimeout = false) {
  635 +
  636 + // 获取滚动条位置,浏览器兼容处理
  637 + let scrollTop = (document.documentElement.scrollTop || document.body.scrollTop) || 0;
  638 +
  639 + // 滚动控制高度
  640 + let maxHeight = 200;
  641 +
  642 + // 动态获取百分比分配比例
  643 + if (typeof this.$refs === "object" && typeof this.$refs.navBox === "object" && typeof this.$refs.navBox.clientHeight === "number") {
  644 + maxHeight = (this.$refs.navBox.clientHeight + this.$parent.top.value) * 2;
  645 + }
  646 +
  647 + if (scrollTop >= 0 && scrollTop <= maxHeight) {
  648 + this.opacity = scrollTop / maxHeight;
  649 + } else if (scrollTop > maxHeight) {
  650 + this.opacity = 1;
  651 + } else {
  652 + this.opacity = 0;
  653 + }
  654 +
  655 + if (!isTimeout) {
  656 +
  657 + if (this.timer) {
  658 + clearTimeout(this.timer);
  659 + }
  660 +
  661 + // 倒计时校正滚动条位置
  662 + this.timer = setTimeout(function(options) {
  663 +
  664 + // 递归
  665 + options.context.onPageScrollFun(options.e, true);
  666 + }, 1000, {e, context: this});
  667 + }
  668 + }
  669 + },
  670 + head: {
  671 + title () {
  672 + return {
  673 + inner: this.title
  674 + }
  675 + }
  676 + },
  677 + watch: {
  678 +
  679 + // 设置页面标题
  680 + title(newVal) {
  681 + if (this.$store.state.browser.toLowerCase() == "qq" && this.$store.state.deviceType.toLowerCase() == "iphone") {
  682 + this.$iFrame.insertIFrame(newVal);
  683 + } else {
  684 + this.$emit("updateHead");
  685 + }
  686 + }
  687 + },
  688 + mounted() {
  689 +
  690 + // 监听滚动条,设置滚动条推动渐变颜色和图片
  691 + window.addEventListener("scroll", this.onPageScrollFun, true);
  692 +
  693 + // 获取并设置分享参数
  694 +
  695 + // 唤起详情页
  696 + if (typeof this.$parent.getOpenApp === "function") {
  697 + this.$parent.getOpenApp({
  698 + type: 37,
  699 + id: this.$route.query.id || 0,
  700 + url: ""
  701 + });
  702 + }
  703 +
  704 + // 分享详情页
  705 + if (typeof this.$parent.getShareData === "function") {
  706 + this.$parent.getShareData({
  707 + type: 37,
  708 + id: this.$route.query.id || 0,
  709 + url: ""
  710 + });
  711 + }
  712 +
  713 + // 设置初始化tab
  714 + this.$nextTick(() => {
  715 +
  716 + // 设置初始化tab
  717 + this.changeTab(this.tabs[2]);
  718 + });
  719 + }
  720 + }
  721 +</script>
  722 +
  723 +<!-- Add "scoped" attribute to limit CSS to this component only -->
  724 +<style rel="stylesheet/less" lang='less' scoped>
  725 + @import "GuanAIHouse";
  726 +</style>
src/router/index.js
@@ -81,6 +81,17 @@ const router = new Router({ @@ -81,6 +81,17 @@ const router = new Router({
81 meta: { 81 meta: {
82 requireAuth: false 82 requireAuth: false
83 } 83 }
  84 + },
  85 + {
  86 + // 优选库关爱屋
  87 + path: "/GuanAIHouse",
  88 + name: "GuanAIHouse",
  89 + component: resolve => {
  90 + require(["@/pages/GuanAIHouse/GuanAIHouse"], resolve);
  91 + },
  92 + meta: {
  93 + requireAuth: false
  94 + }
84 } 95 }
85 ] 96 ]
86 }, 97 },
static/img/icon_back_white.png 0 → 100644

288 Bytes

static/img/icon_share_white.png 0 → 100644

657 Bytes