|
@@ -0,0 +1,350 @@
|
|
|
|
+<template>
|
|
|
|
+ <view class="">
|
|
|
|
+ <!-- <view class="" :style="{height: navHeight+'px' }"></view> -->
|
|
|
|
+ <u-navbar
|
|
|
|
+ :placeholder="true"
|
|
|
|
+ title="品牌导览"
|
|
|
|
+ :autoBack="true"
|
|
|
|
+ :safeAreaInsetTop="true"
|
|
|
|
+ >
|
|
|
|
+ </u-navbar>
|
|
|
|
+ <view class="search-wrap">
|
|
|
|
+ <u-search
|
|
|
|
+ placeholder="请输入搜索的商品"
|
|
|
|
+ :clearabled="true"
|
|
|
|
+ :showAction="false"
|
|
|
|
+ height="80rpx"
|
|
|
|
+ @search="search"
|
|
|
|
+ @custom="search"
|
|
|
|
+ @clear="reloadList"
|
|
|
|
+ bgColor="#fff"
|
|
|
|
+ borderColor="#00A447"
|
|
|
|
+ v-model="params.goodsName">
|
|
|
|
+ </u-search>
|
|
|
|
+ </view>
|
|
|
|
+ <view class="out-wrap u-flex u-col-top">
|
|
|
|
+ <view class="types">
|
|
|
|
+ <view class="type"
|
|
|
|
+ :class="{active:index==typesIndex}"
|
|
|
|
+ @click="typesClick(index)"
|
|
|
|
+ v-for="(item,index) in goodsTypeTree" :key="item.parentId+index">
|
|
|
|
+ {{item.name}}
|
|
|
|
+ </view>
|
|
|
|
+ </view>
|
|
|
|
+ <view class="right">
|
|
|
|
+ <view class="second-types">
|
|
|
|
+ <view class="u-flex u-row-between u-col-top u-border-bottom">
|
|
|
|
+ <view class="u-flex u-flex-wrap">
|
|
|
|
+ <view class="type"
|
|
|
|
+ :class="{active:index==secondTypesIndex}"
|
|
|
|
+ @click="secondTypesClick(index)"
|
|
|
|
+ v-for="(item,index) in subTypeList" :key="item.id">
|
|
|
|
+ {{item.name}}
|
|
|
|
+ </view>
|
|
|
|
+ </view>
|
|
|
|
+ <u-icon
|
|
|
|
+ @click="showMoreSecondTypes"
|
|
|
|
+ v-if="subTypeListMore.length>0"
|
|
|
|
+ size="24px"
|
|
|
|
+ :name="showMoreSecondTypesIcon"></u-icon>
|
|
|
|
+ </view>
|
|
|
|
+ <view class="more-second-types u-flex" v-if="moreSecondTypes">
|
|
|
|
+ <view class="type"
|
|
|
|
+ :class="{active:index==moreSecondTypesIndex}"
|
|
|
|
+ @click="moreSecondTypesClick(index)"
|
|
|
|
+ v-for="(item,index) in subTypeListMore" :key="item.id">
|
|
|
|
+ {{item.name}}
|
|
|
|
+ </view>
|
|
|
|
+ </view>
|
|
|
|
+ </view>
|
|
|
|
+ <mescroll-body class="mescroll-body" ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback" :down="downOption" :up="upOption">
|
|
|
|
+ <view class="page-wrap" @click="$u.route('/brand/branddetails',{id:item.id})" v-for="item in dataList" :key="item.id">
|
|
|
|
+ <view class="hot">
|
|
|
|
+ <view class="product small-product u-flex">
|
|
|
|
+ <u--image :showLoading="true" :src="item.mainImg" width="160rpx" height="160rpx"></u--image>
|
|
|
|
+ <view class="text">
|
|
|
|
+ <view class="name ellipsis-2">{{item.goodsName}}</view>
|
|
|
|
+ <view class="u-flex u-row-between">
|
|
|
|
+ <view class="left">
|
|
|
|
+ <view class="up">
|
|
|
|
+ <view class="u-flex">
|
|
|
|
+ <text class="price">¥ <text class="price-num">{{item.vipPrice}}</text></text>
|
|
|
|
+ <!-- <text class="vip-icon">VIP</text> -->
|
|
|
|
+ <text class="price-type">会员价</text>
|
|
|
|
+ </view>
|
|
|
|
+ <!-- <view class="" v-else>
|
|
|
|
+ <text class="price">¥ <text class="price-num">{{item.salePrice}}</text></text>
|
|
|
|
+ </view> -->
|
|
|
|
+ </view>
|
|
|
|
+ <view class="down">
|
|
|
|
+ <!-- <text class="discount">8.8折</text> -->
|
|
|
|
+ <text class="original-price gray line-through">¥ {{item.salePrice}}</text>
|
|
|
|
+ <!-- <text class="sales gray">销量 {{item.saleCount}}</text> -->
|
|
|
|
+ </view>
|
|
|
|
+ </view>
|
|
|
|
+ <u--image :showLoading="false" @click.native.stop="addCart(item.id)" :src="staticUrl+'/img/add.png'" width="48rpx" height="48rpx"></u--image>
|
|
|
|
+ </view>
|
|
|
|
+ </view>
|
|
|
|
+ </view>
|
|
|
|
+ </view>
|
|
|
|
+ </view>
|
|
|
|
+ </mescroll-body>
|
|
|
|
+ </view>
|
|
|
|
+ </view>
|
|
|
|
+ <!-- <tabbar :tabbarIndexProps="Number(1)" /> -->
|
|
|
|
+ <u-toast ref="uToast"></u-toast>
|
|
|
|
+ </view>
|
|
|
|
+</template>
|
|
|
|
+
|
|
|
|
+<script>
|
|
|
|
+ import { systemInfo } from "@/mixin.js";
|
|
|
|
+ // 引入mescroll-mixins.js
|
|
|
|
+ import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
|
|
|
|
+ import tabbar from "../components/tabbar.vue";
|
|
|
|
+ export default {
|
|
|
|
+ mixins: [MescrollMixin,systemInfo], // 使用mixin
|
|
|
|
+ components: {
|
|
|
|
+ tabbar
|
|
|
|
+ },
|
|
|
|
+ data() {
|
|
|
|
+ return {
|
|
|
|
+ staticUrl:this.$commonConfig.staticUrl,
|
|
|
|
+ typesIndex:0,
|
|
|
|
+ secondTypesIndex:0,
|
|
|
|
+ moreSecondTypesIndex:null,
|
|
|
|
+ moreSecondTypes:false,
|
|
|
|
+ showMoreSecondTypesIcon:'list',
|
|
|
|
+ downOption: {},
|
|
|
|
+ // 上拉加载的配置(可选, 绝大部分情况无需配置)
|
|
|
|
+ upOption: {
|
|
|
|
+ page: {
|
|
|
|
+ size: 10 // 每页数据的数量,默认10
|
|
|
|
+ },
|
|
|
|
+ noMoreSize: 5, // 配置列表的总数量要大于等于5条才显示'-- END --'的提示
|
|
|
|
+ empty: {
|
|
|
|
+ tip: '暂无相关数据'
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ //菜单
|
|
|
|
+ goodsTypeTree:[],
|
|
|
|
+ //子菜单
|
|
|
|
+ subTypeList:[],
|
|
|
|
+ subTypeListMore:[],
|
|
|
|
+ // 列表数据
|
|
|
|
+ dataList: [],
|
|
|
|
+ params:{
|
|
|
|
+ typeId:null,
|
|
|
|
+ goodsName:'',
|
|
|
|
+ // isExplode:0,//是否爆款 0不是,1是
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ watch:{
|
|
|
|
+ typesIndex:{
|
|
|
|
+ handler(val){
|
|
|
|
+ console.log('typesIndex',val);
|
|
|
|
+ this.params.goodsName = '' ;
|
|
|
|
+ let data = uni.$u.deepClone(this.goodsTypeTree[val]);
|
|
|
|
+ this.subTypeList = data.child.splice(0,3);
|
|
|
|
+ this.subTypeListMore= data.child;
|
|
|
|
+ this.secondTypesIndex = 0;
|
|
|
|
+ this.moreSecondTypesIndex = null;
|
|
|
|
+ this.mescroll.resetUpScroll();
|
|
|
|
+ },
|
|
|
|
+ immediate:false
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ onLoad() {
|
|
|
|
+ this.getSystemInfo();
|
|
|
|
+ },
|
|
|
|
+ onShow() {
|
|
|
|
+ this.getgoodsTypeTree();
|
|
|
|
+ },
|
|
|
|
+ methods: {
|
|
|
|
+ /*下拉刷新的回调, 重置列表为第一页 (此处可删,mixins已默认)
|
|
|
|
+ downCallback(){
|
|
|
|
+ this.mescroll.resetUpScroll();
|
|
|
|
+ },
|
|
|
|
+ /*上拉加载的回调*/
|
|
|
|
+ upCallback(page) {
|
|
|
|
+ // 此处可以继续请求其他接口
|
|
|
|
+ // if(page.num == 1){
|
|
|
|
+ // // 请求其他接口...
|
|
|
|
+ // }
|
|
|
|
+ if(this.moreSecondTypesIndex||this.moreSecondTypesIndex==0){
|
|
|
|
+ this.params.typeId = this.subTypeListMore[this.moreSecondTypesIndex]?.id
|
|
|
|
+ }else{
|
|
|
|
+ this.params.typeId = this.subTypeList[this.secondTypesIndex]?.id
|
|
|
|
+ }
|
|
|
|
+ // 如果希望先请求其他接口,再触发upCallback,可参考以下写法
|
|
|
|
+ if(!this.params.typeId){
|
|
|
|
+ // this.getgoodsTypeTree();
|
|
|
|
+ return // 此处return,先获取xx
|
|
|
|
+ }
|
|
|
|
+ console.log('this.params.typeId',this.params.typeId);
|
|
|
|
+
|
|
|
|
+ let pageNum = page.num; // 页码, 默认从1开始
|
|
|
|
+ let pageSize = page.size; // 页长, 默认每页10条
|
|
|
|
+ this.params = Object.assign(this.params,{pageNum:pageNum,pageSize:pageSize});
|
|
|
|
+ this.$u.api.memberGoodList(this.params).then(data => {
|
|
|
|
+ console.log('data',JSON.parse(JSON.stringify(data)));
|
|
|
|
+ // 接口返回的当前页数据列表 (数组)
|
|
|
|
+ let curPageData = data.data.rows;
|
|
|
|
+ console.log('curPageData',JSON.parse(JSON.stringify(curPageData)));
|
|
|
|
+ // 接口返回的当前页数据长度 (如列表有26个数据,当前页返回8个,则curPageLen=8)
|
|
|
|
+ let curPageLen = curPageData.length;
|
|
|
|
+ // 接口返回的总页数 (如列表有26个数据,每页10条,共3页; 则totalPage=3)
|
|
|
|
+ // let totalPage = data.data.data.totalPage;
|
|
|
|
+ // 接口返回的总数据量(如列表有26个数据,每页10条,共3页; 则totalSize=26)
|
|
|
|
+ let totalSize = data.data.total;
|
|
|
|
+ // 接口返回的是否有下一页 (true/false)
|
|
|
|
+ // let hasNext = data.xxx;
|
|
|
|
+ // console.log('totalPage',totalPage,'curPageLen',curPageLen);
|
|
|
|
+ //设置列表数据
|
|
|
|
+ if(page.num == 1) this.dataList = []; //如果是第一页需手动置空列表
|
|
|
|
+ this.dataList = this.dataList.concat(curPageData); //追加新数据
|
|
|
|
+ // 请求成功,隐藏加载状态
|
|
|
|
+ //方法一(推荐): 后台接口有返回列表的总页数 totalPage
|
|
|
|
+ // this.mescroll.endByPage(curPageLen, totalPage);
|
|
|
|
+ //方法二(推荐): 后台接口有返回列表的总数据量 totalSize
|
|
|
|
+ this.mescroll.endBySize(curPageLen, totalSize);
|
|
|
|
+ }).catch(err => {
|
|
|
|
+ this.mescroll.endErr()
|
|
|
|
+ console.log(err)
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ },
|
|
|
|
+ /*若希望重新加载列表,只需调用此方法即可(内部会自动page.num=1,再主动触发up.callback)*/
|
|
|
|
+ reloadList() {
|
|
|
|
+ this.mescroll.resetUpScroll();
|
|
|
|
+ },
|
|
|
|
+ search(e){
|
|
|
|
+ this.reloadList();
|
|
|
|
+ },
|
|
|
|
+ getgoodsTypeTree(){
|
|
|
|
+ this.$u.api.goodsTypeTree().then(res=>{
|
|
|
|
+ this.goodsTypeTree = res.data.filter(item=> item.child.length>0);
|
|
|
|
+ console.log('this.goodsTypeTree',this.goodsTypeTree);
|
|
|
|
+ let data = uni.$u.deepClone(this.goodsTypeTree[this.typesIndex]);
|
|
|
|
+ // console.log('this.goodsTypeTree',this.goodsTypeTree);
|
|
|
|
+ // console.log('data',data);
|
|
|
|
+ this.subTypeList = data.child.splice(0,3);
|
|
|
|
+ this.subTypeListMore= data.child;
|
|
|
|
+ this.mescroll.resetUpScroll();
|
|
|
|
+ }).catch(err=>{
|
|
|
|
+ this.mescroll.endErr()
|
|
|
|
+ console.log('getgoodsTypeTree',err);
|
|
|
|
+ })
|
|
|
|
+ },
|
|
|
|
+ typesClick(index){
|
|
|
|
+ this.typesIndex = index;
|
|
|
|
+
|
|
|
|
+ },
|
|
|
|
+ secondTypesClick(index){
|
|
|
|
+ this.secondTypesIndex = index;
|
|
|
|
+ this.moreSecondTypesIndex = null;
|
|
|
|
+ this.mescroll.resetUpScroll();
|
|
|
|
+
|
|
|
|
+ },
|
|
|
|
+ moreSecondTypesClick(index){
|
|
|
|
+ this.moreSecondTypesIndex = index;
|
|
|
|
+ this.secondTypesIndex = null;
|
|
|
|
+ this.mescroll.resetUpScroll();
|
|
|
|
+ },
|
|
|
|
+ showMoreSecondTypes(){
|
|
|
|
+ // this.moreSecondTypes = !this.moreSecondTypes;
|
|
|
|
+ if(this.showMoreSecondTypesIcon=='list'){
|
|
|
|
+ this.showMoreSecondTypesIcon = 'close'
|
|
|
|
+ this.subTypeList = this.subTypeList.concat(this.subTypeListMore)
|
|
|
|
+ }else{
|
|
|
|
+ this.showMoreSecondTypesIcon = 'list'
|
|
|
|
+ this.subTypeList =this.subTypeList.splice(0,3);
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ addCart(id){
|
|
|
|
+ // console.log('addCart',id);
|
|
|
|
+ this.$u.api.addCart({goodsId:id}).then(res=>{
|
|
|
|
+ this.$refs.cartfixed.getCartList('isAdd');
|
|
|
|
+ console.log('res',res.data);
|
|
|
|
+ }).catch(err=>{
|
|
|
|
+ console.log('addCart',err);
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+</script>
|
|
|
|
+<style>
|
|
|
|
+page{
|
|
|
|
+ /* padding-top: 0; */
|
|
|
|
+}
|
|
|
|
+</style>
|
|
|
|
+<style lang="scss" scoped>
|
|
|
|
+.out-wrap{
|
|
|
|
+ background-color: #F5F5F5;
|
|
|
|
+ .right{
|
|
|
|
+ background-color: #fff;
|
|
|
|
+ flex: 1;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+.types{
|
|
|
|
+ width: 200rpx;
|
|
|
|
+ font-size: 26rpx;
|
|
|
|
+ text-align: center;
|
|
|
|
+ font-weight: 600;
|
|
|
|
+ .type{
|
|
|
|
+ position: relative;
|
|
|
|
+ padding: 25rpx 0;
|
|
|
|
+ &.active{
|
|
|
|
+ background-color: #fff;
|
|
|
|
+ &:before{
|
|
|
|
+ content: '';
|
|
|
|
+ width: 4rpx;
|
|
|
|
+ height: 1.6em;
|
|
|
|
+ background-color: #00A447;
|
|
|
|
+ position: absolute;
|
|
|
|
+ left: 0;
|
|
|
|
+ top: 50%;
|
|
|
|
+ transform: translateY(-0.8em);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+.second-types{
|
|
|
|
+ position: relative;
|
|
|
|
+ font-size: 22rpx;
|
|
|
|
+ padding: 20rpx 20rpx 0;
|
|
|
|
+ background-color: #fff;
|
|
|
|
+ .type{
|
|
|
|
+ padding: 7rpx 22rpx;
|
|
|
|
+ background-color: #F5F5F5;
|
|
|
|
+ border-radius: 22rpx;
|
|
|
|
+ margin-right: 20rpx;
|
|
|
|
+ margin-bottom: 20rpx;
|
|
|
|
+ &.active{
|
|
|
|
+ background-color: #E5F6EC;
|
|
|
|
+ color: #00A447;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // .type + .type{
|
|
|
|
+ // margin-left: 20rpx;
|
|
|
|
+ // }
|
|
|
|
+ .more-second-types{
|
|
|
|
+ position: absolute;
|
|
|
|
+ left: 0;
|
|
|
|
+ right: 0;
|
|
|
|
+ bottom: -120rpx;
|
|
|
|
+ padding: 24px 20rpx;
|
|
|
|
+ z-index: 99;
|
|
|
|
+ background-color: #fff;
|
|
|
|
+ box-shadow:
|
|
|
|
+ 0px 4.5px 3.6px rgba(0, 0, 0, 0.024),
|
|
|
|
+ 0px 12.5px 10px rgba(0, 0, 0, 0.035),
|
|
|
|
+ 0px 30.1px 24.1px rgba(0, 0, 0, 0.046),
|
|
|
|
+ 0px 100px 80px rgba(0, 0, 0, 0.07)
|
|
|
|
+ ;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+.mescroll-body{
|
|
|
|
+ background-color: #fff;
|
|
|
|
+}
|
|
|
|
+</style>
|