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