Commit accfd722a8e910335c2d57a534f186f37b428c4e

Authored by 王强
1 parent 8472b787

工会商品首页框架完成~

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