You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

659 lines
16 KiB

<template>
<view class="content">
<!-- <slot>加载中请稍后...</slot> -->
<scroll-view scroll-y class="left-aside">
<view v-for="item in flist" :key="item.id" class="f-item" :class="{ active: item.id === currentId }" @click="tabtap(item)">{{ item.name }}</view>
</scroll-view>
<scroll-view scroll-with-animation scroll-y class="right-aside" @scroll="asideScroll" :scroll-top="tabScrollTop">
<view v-for="item in slist" :key="item.id" class="s-list" :id="'main-' + item.id">
<text class="s-item">{{ item.catename }}</text>
<view class="t-list">
<view @click="navToList(item.id, titem)" v-if="titem.pid === item.id" class="t-item" v-for="(titem, index) in tlist" :key="titem.id">
<view style="flex: 3;position: relative;overflow: hidden;"><image :src="titem.thumb" mode="aspectFill" style="width: 150upx; height: 150upx; border-radius: 10upx;"></image>
<view class="f-w viptag iconfont icon-choicenessfill" v-if="titem.vipstatus == '2'">
</view>
</view>
<view style="flex: 7;padding-left: 20upx;">
<view class="f-32 f-w" style="color: #333333;width: 10em;overflow: hidden;white-space: nowrap;text-overflow: ellipsis;">{{ titem.name }}</view>
<view style="color: #999999;padding: 16upx 0;">已售{{titem.salenum}}
<view class="dis-flex flex-y-center member-coupon-view" v-if="titem.vipstatus == '1'">
<view class="member-price-label f-22">会员</view>
<view class="f-22 col-f onelist-hidden b-0 coupon-price-2">-<text class="member-coupon-price">{{titem.vipdiscount}}</text>元</view>
</view>
<view class="member-coupon-view f-22" style="background-color: #efd68f;border-radius: 7upx;padding: 5upx 10upx;color: #333333;" v-if="titem.vipstatus == '2'">
会员专享
</view>
</view>
<view class="dis-flex">
<view class="flex-box">
<text class="f-26" style="color: #F44F44;">¥{{ titem.price }}</text>
<text class="f-20" style="text-decoration:line-through;color: #999999;padding-left: 10upx;" v-if=" Number(titem.oldprice) > 0">¥{{ titem.oldprice }}</text>
</view>
<view class="flex-box">
<view style="float: right;">
<view :animation="animationData" v-if="false" style="width: 100upx;height: 100upx;background-color: #33ff55;"></view>
<jumpBall ref="jumpBall" @msg="jbMsg" />
<tui-numberbox
:class="'admin' + index"
:value="tlist[index].num"
v-if="!titem.optionarray.length && titem.saleoverflag !== 1"
@change="change($event, titem, 'admin' + index, index)"
:width="40"
:min="0"
@click.stop=""
></tui-numberbox>
<view
v-else-if="!!titem.optionarray.length && titem.saleoverflag !== 1"
style="padding: 10upx 20upx;border-radius: 10upx;background-color: #FF4444;color: #FFFFFF;"
@click.stop="popupOpen(titem)"
>
选规格
</view>
<view
v-else-if="titem.saleoverflag == 1"
style="padding: 10upx 20upx;border-radius: 10upx;background-color: #999999;color: #FFFFFF;"
@click.stop="sellout"
>
已售罄
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</scroll-view>
<!-- 购物车 -->
<view class="foot"><view class="cart"></view></view>
<!-- 选规格弹窗 -->
<popup-view :show="showBuyMenu" type="center" @clickmask="onToggleTrade">
<view style="background-color: #FFFFFF;border-radius: 15upx;">
<view class="footName f-28" style="padding: 20upx 20upx 0;">{{ selectSpecification.name }}</view>
<view class="p-top-40 f-24" style="color: #999999;padding: 40upx 20upx 0upx;">规格</view>
<view class="dis-flex" style="padding: 0 20upx 30upx;flex-wrap: wrap;overflow: auto;max-height: 40vh;">
<view :class="item.checked ? 'checked' : 'noChecked'"
style="flex: 0.01;padding: 10upx 30upx;margin: 20upx 10upx 20upx 0;text-align: center;width: 100upx;min-width: 100upx;"
v-for="(item, index) in selectSpecification.optionarray"
:key="index"
@click="checkedLabel(item)">{{ item.name }}</view>
</view>
<view style="background-color: #F8F8F8;padding: 10upx 20upx;">
<text class="f-26" style="color: #999999;">已选规格:</text>
<text class="f-26">({{ numberPeople.name }})</text>
</view>
<view class="dis-flex" style="padding: 0 20upx;">
<view style="flex: 7;padding: 30upx 0;">
<text class="f-30 f-w" style="color: #FF4444;">¥{{ numberPeople.price }}</text>
<text class="f-24" style="text-decoration: line-through;color: #999999;padding-left: 10upx;">¥{{ numberPeople.oldprice }}</text>
</view>
<view style="flex: 3;padding-top: 30upx;">
<button type="warn" size="mini" v-if="numberPeople.num == 0" style="font-size: 20upx;" @click="addShoping">加入购物车</button>
<tui-numberbox @click.stop="" :value="numberPeople.num" v-if="numberPeople.num > 0" @change="changes($event, numberPeople)" :width="60" :min="0"></tui-numberbox>
</view>
</view>
</view>
</popup-view>
</view>
</template>
<script>
import App from '@/common/js/app.js';
import PopupView from '@/components/template/PopManager.vue';
import tuiNumberbox from '@/components/template/numberbox.vue';
import jumpBall from '@/components/hx-jump-ball/hx-jump-ball.vue';
export default {
components: {
tuiNumberbox,
PopupView,
jumpBall
},
data() {
return {
nums: 1,
element: [],
animation: '',
animationData: {},
off: false,
selectSpecification: {},
showBuyMenu: false,
sizeCalcState: false,
tabScrollTop: 0,
currentId: 1,
flist: [],
slist: [],
tlist: [],
value: 0,
numberPeople: {
},
goodid: 0,
num: 0,
record:true,
onepoc:true
};
},
mounted() {
let _this = this;
var animation = uni.createAnimation({
duration: 1000,
timingFunction: 'ease'
});
this.animation = animation;
// let q = uni.createSelectorQuery();
// setTimeout(function() {
// q.select('#cart')
// .boundingClientRect(data => {
// _this.setData({
// cartBasketRect: data,
// })
// // this.cartBasketRect = data;
// // console.log(data);
// // console.log(this.$refs.inCart);
// })
// .exec();
// }, 100);
// uni.$on('addShopings',function(data){
// console.log(data);
// this.addShopingas(data);
// })
// this.loadData();
},
props: {
storeFoodList: {
type: Object,
default: null
},
topshow:{
type:Boolean,
default:null
},
height:{
type:String,
default:'45vh'
},
width:{
type:String,
default:'100vw'
}
},
watch: {
storeFoodList: {
handler(newData, oldData) {
let foodList = [];
this.tlist = [];
this.flist = [];
this.slist = [];
this.flist = newData.cartinfo.catelist;
this.slist = newData.cartinfo.goodslist;
this.slist.map(item => {
// this.tlist.push(...item.categoods);
this.tlist.push.apply(this.tlist, item.categoods);
this.tlist.map(items => {
items.optionarray.forEach((i, index) => {
i.checked = false;
items.optionarray[0].checked = true;
if(this.num > 0){
this.checkedLabel(this.numberPeople);
}
});
});
});
console.log(newData.flag);
if(newData.num !== 1 && newData.num>1){
this.calcSize();
return
}
// this.tabtap(this.flist[0]);
this.currentId = this.flist[0].id;
},
deep: true
},
topshow:{
handler(newdata){
this.calcSize();
this.sizeCalcState = false;
},
deep:true
}
},
mounted() {
this.calcSize();
},
onShow() {
if(this.onepic){
this.onepoc = false;
};
this.calcSize();
},
methods: {
changes(e,item){
App._post_form(
`&p=citydelivery&do=addShopCart&goodid=${this.selectSpecification.id}&specid=${this.numberPeople.id}&addtype=${e.type == 'plus' ? 1 : 0}`,
{},
res => {
if(res.errno !== 0){
return
}
let storePrice = res.data;
this.num++;
storePrice.changenum = this.num;
storePrice.changemoney = storePrice.changemoney * this.num;
storePrice.id = this.selectSpecification.id;
// this.$emit('getshopPrice',storePrice);
// this.$store.commit('STOREPRICES',storePrice);
uni.$emit('STOREPRICES', storePrice);
this.numberPeople.num = e.value;
},
false,
() => {
// _this.loadlogo = true
}
);
},
jbMsg() {},
// 定义动画内容
rotateAndScale() { //手动动画方法废弃无用
// 定义动画内容
this.animation
.rotate(45)
.scale(2, 2)
.step();
// 导出动画数据传递给data层
this.animationData = this.animation.export();
},
norotateAndScale() {
this.animation
.rotate(0)
.scale(1, 1)
.step();
this.animationData = this.animation.export();
},
addShoping() {
App._post_form(
`&p=citydelivery&do=addShopCart&goodid=${this.selectSpecification.id}&specid=${this.numberPeople.id}&addtype=${1}`,
{},
res => {
if(res.errno !== 0){
return
}
let storePrice = res.data;
this.num++;
this.numberPeople.num = 1;
storePrice.changenum = this.num;
storePrice.changemoney = storePrice.changemoney * this.num;
storePrice.id = this.selectSpecification.id;
uni.$emit('STOREPRICES', storePrice);
},
fail=>{
console.log(fail,123321)
}
,
false,
() => {
// _this.loadlogo = true
}
);
},
change: function(e, titem, classis, index) {
let _this = this;
let views; //点击的坐标
let viewss; //购物车坐标
_this.element = [];
// this.element = ['.' + classis,'.cart'];
// this.nums ++;
// this.$refs.jumpBall[0].start = this.nums
App._post_form(
`&p=citydelivery&do=addShopCart&goodid=${titem.id}&specid=${0}&addtype=${e.type == 'plus' ? 1 : 0}`,
{},
res => {
if(res.errno != 0){
return
}
let storePrice = res.data;
storePrice.changenum = e.value;
storePrice.changemoney = storePrice.changemoney * e.value;
storePrice.id = titem.id;
this.tlist.map((items, index) => {
if (items.id == titem.id) {
this.tlist[index].num = e.value;
}
});
setTimeout(() => {
let view = uni
.createSelectorQuery()
.in(_this)
.select('.' + classis);
view.fields(
{
size: true,
rect: true,
scrollOffset: true
},
data => {
_this.element.push(data);
views = data;
// item.top = h;
// h += data.height;
// item.bottom = h;
let viewis = uni
.createSelectorQuery()
.in(_this)
.select('.cart');
viewis
.fields(
{
size: true,
rect: true,
scrollOffset: true
},
datas => {
_this.element.push(datas);
viewss = datas;
// item.top = h;
// h += data.height;
// item.bottom = h;
if (e.type == 'plus') {
// _this.setData({
// nums:this.nums+1
// });
_this.$refs.jumpBall[index].$emit('childMethod', _this.element);
}
}
)
.exec();
}
).exec();
}, 100);
// this.$emit('getshopPrice',storePrice);
// this.$store.commit('STOREPRICES',storePrice);
uni.$emit('STOREPRICES', storePrice);
},
fail=>{
console.log(fail,102210)
}
,
false,
() => {
// _this.loadlogo = true
}
);
//
},
//一级分类点击
tabtap(item) {
// if (!this.sizeCalcState) {
this.calcSize();
// }
setTimeout(()=>{
this.record = false;
this.currentId = item.id;
let index = this.slist.findIndex(sitem => sitem.pid === item.id);
this.tabScrollTop = this.slist[index].top;
})
},
//右侧栏滚动
asideScroll(e) {
if(!this.record){
this.record = true;
return
}
// if (!this.sizeCalcState) {
this.calcSize();
// }
setTimeout(()=>{
let scrollTop = e.detail.scrollTop;
let tabs = this.slist.filter(item => item.top <= scrollTop).reverse();
if (tabs.length > 0) {
this.currentId = tabs[0].pid;
}
})
},
//计算右侧栏每个tab的高度等信息
calcSize() {
let _this = this;
let h = 0;
this.slist.forEach(item => {
let view = uni
.createSelectorQuery()
.in(_this)
.select('#main-' + item.id);
view.fields(
{
size: true,
rect: true,
scrollOffset: true
},
data => {
item.top = h;
h += data.height;
item.bottom = h;
}
).exec();
});
this.sizeCalcState = true;
},
navToList(sid, item) {
App.navigationTo({
url: 'pages/subPages2/businessCenter/foodIntroduced/foodIntroduced?id=' + item.id + '&num=' + item.num + '&width=' + this.width + '&height=' + this.height
});
},
// 选择规格商品
popupOpen(item) {
this.showBuyMenu = true;
this.selectSpecification = item;
console.log(item);
item.optionarray.forEach(items=>{
if(items.checked){
this.numberPeople = items;
}
})
},
sellout(){
},
// 规格弹窗开关
onToggleTrade() {
//关闭后重置规格数据
this.showBuyMenu = !this.showBuyMenu;
},
// 选中某规格
checkedLabel(item) {
this.numberPeople = item;
this.selectSpecification.optionarray.forEach(items => {
items.checked = false;
if (items.id == item.id) {
items.checked = true;
}
});
// this.selectSpecification.map((items,index)=>{
// })
}
}
};
</script>
<style lang="scss" scoped>
page,
.content {
height:100%;
background-color: #ffffff;
}
.viptag{
position: absolute;
right: 0;
color: #FFFFFF;
top: 0;
background: linear-gradient(580deg, #31b968 50%, transparent 50%);
font-size: 24upx;
text-align: right;
width: 50upx;
height: 50upx;
}
.foot {
position: fixed;
bottom: 60upx;
height: 90upx;
left: 10upx;
width: 100%;
}
.foot .cart {
width: 180upx;
height: 90upx;
line-height: 90upx;
text-align: center;
}
.content {
display: flex;
}
.left-aside {
flex-shrink: 0;
width: 200upx;
height: 100%;
background-color: #f8f8f8;
}
.f-item {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100upx;
font-size: 28upx;
color: #888888;
position: relative;
&.active {
color: #3a3a3a;
background: #ffffff;
&:before {
content: '';
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
height: 36upx;
width: 8upx;
background-color: red;
border-radius: 0 4px 4px 0;
opacity: 0.8;
}
}
}
.f-item:last-child{
margin-bottom: 110upx;
}
.right-aside {
flex: 1;
overflow: hidden;
padding-left: 20upx;
// padding-bottom: 100upx;
}
.s-list:last-child{
// flex: 1;
// overflow: hidden;
// padding-left: 20upx;
padding-bottom: 200upx;
}
.s-item {
display: flex;
align-items: center;
height: 70upx;
padding-top: 8upx;
font-size: 28upx;
color: #ff4444;
}
.t-list .t-item:last-child {
border: none;
}
.t-list {
/* display: flex; */
flex-wrap: wrap;
width: 100%;
background: #fff;
padding-top: 12upx;
&:after {
content: '';
flex: 99;
height: 0;
}
}
.t-item {
/* flex-shrink: 0; */
display: flex;
/* justify-content: center;
align-items: center;
flex-direction: column; */
/* width: 176upx; */
font-size: 26upx;
color: #666;
padding-bottom: 10upx;
width: 95%;
border-bottom: 1upx solid #f1f1f1;
padding-top: 10upx;
image {
width: 140upx;
height: 140upx;
}
}
.footName {
width: 70vw;
overflow: hidden; /*超出部分隐藏*/
white-space: nowrap; /*不换行*/
text-overflow: ellipsis; /*超出部分文字以...显示*/
font-weight: 600;
}
.checked {
background-color: #fff5f5;
border: 1upx solid #ff4444;
border-radius: 10upx;
font-size: 24upx;
color: #ff4444;
}
.noChecked {
background-color: #ffffff;
border: 1upx solid #999999;
border-radius: 10upx;
font-size: 24upx;
}
.member-coupon-view {
float: right;
}
.member-price-label {
color: #333333;
height: 0;
line-height: 30upx;
border-width: 0upx 10upx 30upx 0;
border-style: none solid solid;
border-color: transparent #000 #efd68f;
position: relative;
left: 10upx;
padding-left: 6upx;
border-radius: 4upx 0 0 4upx;
margin-left: -10upx;
}
.coupon-price-2 {
padding: 0 10upx;
height: 30upx;
line-height: 30upx;
border-radius: 0 4upx 4upx 0;
}
.member-coupon-price {
color: #efd68f;
}
</style>