ソースを参照

增加品牌内容,未完成

gcz 1 年間 前
コミット
7930ed7e17
5 ファイル変更436 行追加8 行削除
  1. 350 0
      brand/brand.vue
  2. 55 0
      brand/branddetails.vue
  3. 19 0
      pages.json
  4. 1 1
      pages/index/index.vue
  5. 11 7
      shopping/producTypetList.vue

+ 350 - 0
brand/brand.vue

@@ -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>

+ 55 - 0
brand/branddetails.vue

@@ -0,0 +1,55 @@
+<template>
+	<view class="pages">
+		<u-navbar
+			title="品牌详情"
+			:placeholder="true"
+			:autoBack="false"
+			@leftClick="leftClick"
+			 :safeAreaInsetTop="true"
+		>
+		</u-navbar>
+		<u-loading-page :loading="loadingPage" bgColor="#f1f1f1"></u-loading-page>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				staticUrl:this.$commonConfig.staticUrl,
+				id:'',
+				loadingPage:true,
+				details:{}
+			}
+		},
+		onShow() {
+		},
+		onLoad(page) {
+			this.id = page.id;
+			this.getDetails(this.id);
+		},
+		methods: {
+			leftClick(e){
+				let pages = getCurrentPages();
+				if(pages.length==1){
+					uni.$u.route('/pages/index/index')
+				}else{
+					uni.navigateBack()
+				};
+			},
+			getDetails(id){
+				this.$u.api.memberGoodDetails({id:id}).then(res=>{
+					this.loadingPage = false;
+					// console.log('res',res.data);
+					this.details = res.data;
+				}).catch(err=>{
+					console.log('getDetails',err.data);
+				})
+			},
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 19 - 0
pages.json

@@ -344,6 +344,25 @@
 					}
 				}
 			]
+		},
+		{
+			"root": "brand",
+			"pages": [
+				{
+					"path": "brand",
+					"style": {
+						"navigationBarTitleText": "品牌导览",
+						"navigationStyle": "custom"
+					}
+				},
+				{
+					"path": "branddetails",
+					"style": {
+						"navigationBarTitleText": "品牌详情",
+						"navigationStyle": "custom"
+					}
+				}
+			]
 		}
 	],
 	"preloadRule": {

+ 1 - 1
pages/index/index.vue

@@ -181,7 +181,7 @@
 				memberInfo:{},
 				avatar:'',
 				iconNavList:[
-					{name:'品牌导览',icon:`${this.$commonConfig.staticUrl}/img/index-nav-icon-1.png`,url:''},
+					{name:'品牌导览',icon:`${this.$commonConfig.staticUrl}/img/index-nav-icon-1.png`,url:'brand/brand'},
 					{name:'会员权益',icon:`${this.$commonConfig.staticUrl}/img/index-nav-icon-2.png`,url:'center/privilege'},
 					{name:'线上商城',icon:`${this.$commonConfig.staticUrl}/img/index-nav-icon-3.png`,url:'/shopping/producTypetList'},
 					{name:'积分兑换',icon:`${this.$commonConfig.staticUrl}/img/index-nav-icon-4.png`,url:'/credits/credits'},

+ 11 - 7
shopping/producTypetList.vue

@@ -33,8 +33,8 @@
 			</view>
 			<view class="right">
 				<view class="second-types">
-					<view class="u-flex u-row-between">
-						<view class="u-flex">
+					<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)" 
@@ -256,11 +256,13 @@
 				this.mescroll.resetUpScroll();
 			},
 			showMoreSecondTypes(){
-				this.moreSecondTypes = !this.moreSecondTypes;
+				// 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){
@@ -314,20 +316,22 @@ page{
 .second-types{
 	position: relative;
 	font-size: 22rpx;
-	padding: 20rpx;
+	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;
-	}
+	// .type + .type{
+	// 	margin-left: 20rpx;
+	// }
 	.more-second-types{
 		position: absolute;
 		left: 0;