new-mshop-view/pages/wine/goods_list.vue

1420 lines
47 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="page-content">
<!--主要内容-->
<view class="main-content">
<!--顶部搜索-->
<view class="search-content">
<view class="search-main">
<input class="search-input" v-model="search.store_name" type="text" placeholder="请输入商品名称...">
<view class="search-btn" @click="getGoodsList(1)">搜索</view>
</view>
</view>
<!-- 筛选 -->
<view class="screen">
<view class="block" @click="brandSelectShowOrHide">
<view class="title">{{ brand_name || '品牌' }}</view>
<text class="iconfont icon-xiangxia"></text>
</view>
<view class="block" @click="cateSelectShowOrHide">
<view class="title">{{ cate_name || '分类' }}</view>
<text class="iconfont icon-xiangxia"></text>
</view>
<view class="block" @click="merSelectShowOrHide">
<view class="title">{{ mer_name || (Number(quota_type) === 1 ? '酒道馆' : '小酒馆') }}</view>
<text class="iconfont icon-xiangxia"></text>
</view>
</view>
<!--商品列表-->
<view class="list">
<view class="item" v-for="(item,index) in Object.values(list)" :key="index">
<view class="goods">
<view class="image">
<image class="goods-image" :src="item.image"></image>
</view>
<view class="info">
<view class="top">
<view class="title">{{ item.store_name }}</view>
<view class="distance">{{ item.distance_text || '' }}</view>
</view>
<view class="price-info">
<view class="integral">{{ item.price }}积分</view>
<view class="price">¥{{ item.price }}</view>
</view>
<view class="other-info">
<view class="stock">
库存:{{ item.stock }}{{ item.unit_name }}
</view>
<view class="once_min_count" v-if="item.once_min_count > 0">
起购:{{ item.once_min_count }} {{ item.unit_name }}
</view>
</view>
</view>
</view>
<view class="buy">
<!-- 酒类型0=未知1=瓶装酒2=封坛酒-->
<view class="left">
<template v-if="Number(quota_type) === 1">
<view class="left-text wine-type-one" v-if="item.wine_type == 1">瓶装酒</view>
<view class="left-text wine-type-two" v-if="item.wine_type == 2">封坛酒</view>
</template>
<template v-else-if="Number(quota_type) === 2">
<!--小酒馆内容 暂无-->
</template>
</view>
<view class="right">
<template v-if="!buyList[item.product_id]">
<template v-if="Number(quota_type) === 1">
<!--瓶装酒-->
<template v-if="item.wine_type == 1">
<text v-if="Number(surplus_available) >= (Number(item.price) * (Number(item.once_min_count) || 1))" @click="buyFlowAddBuyNum('add', item)" class="iconfont icon-gengduozhankai1"></text>
<view v-else class="lack_available">额度不足</view>
</template>
<!--封坛酒-->
<template v-if="item.wine_type == 2">
<text v-if="Number(surplus_wine_available) >= (Number(item.price) * (Number(item.once_min_count) || 1))" @click="buyFlowAddBuyNum('add', item)" class="iconfont icon-gengduozhankai1"></text>
<view v-else class="lack_available">额度不足</view>
</template>
</template>
<template v-else-if="Number(quota_type) === 2">
<text @click="buyFlowAddBuyNum('add', item)" class="iconfont icon-gengduozhankai1"></text>
</template>
</template>
<template v-else>
<view class="buy-num">
<view class="num-change">
<text class="iconfont icon-shangpinshuliang-jian" @click="buyFlowAddBuyNum('reduce', item)"></text>
<input
:value="buyList[item.product_id] ? buyList[item.product_id].total_num : 0"
class="num-input"
type='number'
@click="buyFlowAddBuyNum('click', item)"
:disabled="Object.values(item.attrValue).length > 1"
@input="buyFlowInputBuyNum($event, item.attrValue[0], item)"
/>
<text class="iconfont icon-shangpinshuliang-jia" @click="buyFlowAddBuyNum('add', item)" ></text>
</view>
<view v-if="(batch_list[item.product_id] || 0) == 1" class="unit">
{{ item.batch_unit }} 共{{ (buyList[item.product_id].total_num || 0) * (buyList[item.product_id].batch_num || 1) }}{{ item.unit_name }}
</view>
<view v-else class="unit">{{ item.unit_name }}</view>
</view>
</template>
</view>
</view>
</view>
</view>
<!--结算按钮-->
<view class="settlement">
<view class="top">
<view class="left">
<text class="iconfont icon-gouwuche-mendian">
<text class="total-num" v-if="totalNum > 0">{{ totalNum > 99 ? '99+' : totalNum }}</text>
</text>
<view class="total">
合计:<text class="total-price">{{ totalPrice }}积分</text>
</view>
</view>
<view class="right">
<view class="settlement-btn" @click="settlementCart" v-if="Object.values(buyList).length > 0">立即结算</view>
<view class="settlement-btn not-btn" v-else>立即结算</view>
</view>
</view>
<view class="quota-info" v-if="Number(quota_type) === 1">
<view class="available-line">可用瓶装酒额度:{{ surplus_available || 0 }}</view>
<view class="available-line">可用封坛酒额度:{{ surplus_wine_available || 0 }}</view>
</view>
</view>
</view>
<!-- 授权登录 -->
<authorize @onLoadFun="onLoadFun" :isAuto="isAuto" :isShowAuth="isShowAuth" @authColse="authClose"></authorize>
<!-- 多规格商品选择弹框 -->
<uni-popup ref="moreSpecsSelect" type="bottom" :is-mask-click="false">
<view class="more-spec-content">
<!--顶部商品信息-->
<view class="goods-info">
<view class="image">
<image class="goods-image" :src="currentGoods.selected.image"></image>
</view>
<view class="info">
<view class="title">{{ currentGoods.store_name }}</view>
<view class="price-info">
<view class="integral">{{ currentGoods.selected.price || 0 }}积分</view>
<view class="price">
<text class="price-icon">¥</text>
{{ currentGoods.selected.price || '' }}
</view>
</view>
<view v-if="(batch_list[currentGoods.product_id] || 0) == 1" class="stock">
库存:{{ Math.floor((currentGoods.selected.stock || 0) / currentGoods.batch_num) }}
</view>
<view v-else class="stock">库存:{{ currentGoods.selected.stock || 0 }}</view>
</view>
<text class="iconfont icon-cha2 close-btn" @click="closeMoreSpecsSelect"></text>
</view>
<!--规格-->
<view class="goods-spec">
<view class="spec-block" v-for="(item,index) in currentGoods.attr" :key="index">
<view class="spec-title">{{ item.attr_name || '' }}</view>
<view class="spec-list">
<view
v-for="(specItem,specIndex) in item.attr_values"
:key="specIndex"
:class="['spec-list-tag',{'spec-list-tag-active': Object.values(currentGoods.selected_spec).includes(specItem)}]"
@click="buyFlowChangeSpec(item.attr_name, specItem)"
>
{{ specItem || '' }}
</view>
</view>
</view>
</view>
<!--数量变更-->
<view class="bottom-content" v-if="(currentGoods.selected.stock || 0) > 0">
<!--操作按钮-->
<view class="num-change">
<text class="iconfont icon-shangpinshuliang-jian" @click="buyFlowChangeNum('reduce', currentGoods.selected)"></text>
<input
:value="specInputValue"
class="num-input"
type='number'
@input="buyFlowInputBuyNum($event, currentGoods.selected, currentGoods)"
/>
<text class="iconfont icon-shangpinshuliang-jia" @click="buyFlowChangeNum('add', currentGoods.selected)"></text>
</view>
<!--单位-->
<view v-if="(batch_list[currentGoods.product_id] || 0) == 1" class="unit">
{{ currentGoods.batch_unit }} 共{{ (specInputValue) * (buyList[currentGoods.product_id].batch_num || 1) }}{{ currentGoods.unit_name }}
</view>
<view v-else class="unit">{{ currentGoods.unit_name }}</view>
</view>
</view>
</uni-popup>
<!-- 品牌选择器 -->
<uni-popup ref="brandPopup" type="bottom">
<view class="screen-popup-content">
<view class="close-btn" @click="brandSelectShowOrHide(false)">关闭</view>
<picker-view @change="changeSearch($event, 'brand')" class="picker-view">
<picker-view-column>
<view class="item" v-for="(item,index) in brand_list" :key="index">{{ item.brand_id == 0 ? '全部' : item.brand_name }}</view>
</picker-view-column>
</picker-view>
</view>
</uni-popup>
<!-- 分类选择器 -->
<uni-popup ref="catePopup" type="bottom">
<view class="screen-popup-content">
<view class="close-btn" @click="cateSelectShowOrHide(false)">关闭</view>
<picker-view @change="changeSearch($event, 'cate')" :value="[cate_one_index, cate_two_index, cate_three_index]" class="picker-view">
<picker-view-column>
<view class="item" v-for="(item,index) in cate_list[0]" :key="index">{{ item.cate_name }}</view>
</picker-view-column>
<picker-view-column>
<view class="item" v-for="(item,index) in cate_list[1]" :key="index">{{ item.cate_name }}</view>
</picker-view-column>
<picker-view-column>
<view class="item" v-for="(item,index) in cate_list[2]" :key="index">{{ item.cate_name }}</view>
</picker-view-column>
</picker-view>
</view>
</uni-popup>
<!-- 酒道馆选择器 -->
<uni-popup ref="merPopup" type="bottom">
<view class="screen-popup-content">
<view class="close-btn" @click="merSelectShowOrHide(false)">关闭</view>
<picker-view @change="changeSearch($event, 'mer')" class="picker-view">
<picker-view-column>
<view class="item">全部</view>
<view class="item" v-for="(item,index) in mer_list" :key="index">{{ item.mer_name }}</view>
</picker-view-column>
</picker-view>
</view>
</uni-popup>
</view>
</template>
<script>
import { mapGetters } from "vuex";
import authorize from '@/components/Authorize';
import {wineGoodsList, wineWithGoodsCartAdd, wineWithGoodsCartDel, wineWithGoodsCartIds, wineWithGoodsCartList, wineList} from "@/api/wine";
import { getUserInfo } from '@/api/user.js';
import {getBrandlist, getProductCate} from "@/api/store";
export default {
name: 'business',
components: {
authorize,
},
computed: {
specInputValue(){
let selected = this.currentGoods.selected || {};
let productId = selected.product_id || 0;
let unique = selected.unique || '';
let good = this.buyList[productId] || {};
let specs = good.specs || {};
let spec = specs[unique] || {};
return spec.cart_num || 0;
},
...mapGetters(['isLogin', 'uid', 'userInfo', 'viewColor', 'shopIsLogin', 'shopMerId'])
},
data() {
return {
// 登录相关
isAuto: false, //没有授权的不会自动授权
isShowAuth: false,//是否隐藏授权
// 定位
lat: '',
lng: '',
// 商品列表相关
list: [],
total_page: 0,
search:{
page: 1,
limit: 20,
store_name: '',
brand_id: '',
store_category_id: '',
mer_id: '',
},
// 筛选 - 品牌
brand_list: {},
brand_name: '',
// 筛选 - 商品分类
cate_list:{},
cate_name: '',
cate_one_index: 0,
cate_two_index: 0,
cate_three_index: 0,
// 筛选 - 酒道馆
mer_list: {},
mer_name: '',
// 购买选中商品相关
totalNum: 0,
totalPrice: 0.00,
buyList: {},
batch_list: {},
currentGoods: {},
// 用户相关
userInfoNow: {},
available: 0,
surplus_available: 0,
wine_available: 0,
surplus_wine_available: 0,
// 惠民积分
quota_type: 1,// 类型1=酒道馆2=小酒馆
}
},
onLoad(options) {
this.quota_type = options.quota_type || 1;
// 判断:是否登录
if (!this.isLogin) {
this.isAuto = true;
this.isShowAuth = true;// 未登录 授权登录
}
else this.init();// 已登录 获取信息
},
watch: {
// 多规格 选中规格改变
'currentGoods.selected_spec': {
handler() {
let good = Object.assign({}, this.currentGoods)
if(good.selected_spec){
let defaultName = Object.values(good.selected_spec).join(',');
// 赋值
this.$set(this.currentGoods, 'selected', good.attrValue[defaultName] || {});
}else{
this.$set(this.currentGoods, 'selected', {});
}
},
deep: true
},
// 购买信息列表变更
'buyList': {
handler() {
this.BuyFlowComputeTotal();
},
deep: true
},
// 购买类型列表信息变更
'batch_list':{
handler() {
this.BuyFlowComputeTotal();
},
deep: true
},
// 筛选 - 一级分类改变
cate_one_index:{
handler() {
let cateList = Object.assign({}, this.cate_list);
let info = cateList[0][this.cate_one_index] || {};
this.cate_two_index = this.cate_three_index = 0;
this.cateSelected(info);
},
deep: true
},
// 筛选 - 二级分类改变
cate_two_index:{
handler() {
let cateList = Object.assign({}, this.cate_list);
let info = cateList[1][this.cate_two_index] || {};
this.cate_three_index = 0;
this.cateSelected(info);
},
deep: true
},
// 筛选 - 三级分类改变
cate_three_index:{
handler() {
let cateList = Object.assign({}, this.cate_list);
let info = cateList[2][this.cate_three_index] || {};
this.cateSelected(info);
},
deep: true
}
},
methods: {
// 授权回调
onLoadFun(e) {
if(this.isLogin){
this.isShowAuth = false;
this.init();
}
},
// 授权关闭
authClose(e) {
this.isShowAuth = e
},
// 授权成功 初始化
init () {
let _this = this;
_this.lat = uni.getStorageSync('user_latitude') || '';
_this.lng = uni.getStorageSync('user_longitude') || '';
if(_this.lat && _this.lng){
_this.getInfo();
}else{
_this.getLocation();
}
},
// 获取用户定位信息
getLocation(){
let _this = this;
// 获取定位
uni.getLocation({
type: 'gcj02',
success: (res) => {
uni.setStorageSync('user_latitude', res.latitude);
uni.setStorageSync('user_longitude', res.longitude);
_this.lat = res.latitude;
_this.lng = res.longitude;
},
fail: (err) => {},
complete: (res) => {
_this.getInfo();
}
});
},
// 信息获取
getInfo(){
this.getUserInfo();
this.getBrandList();
this.getAllCategory(0);
this.getMerWineList();
this.getGoodsList();
this.cartGetList();
},
// 获取用户信息
getUserInfo(){
let _this = this;
getUserInfo().then(res => {
_this.$set(_this, 'userInfoNow', res.data);
_this.$set(_this, 'available', res.data.available_quota)
_this.$set(_this, 'surplus_available', res.data.available_quota)
_this.$set(_this, 'wine_available', res.data.wine_available_quota)
_this.$set(_this, 'surplus_wine_available', res.data.wine_available_quota)
});
},
// 商品列表
getGoodsList(page = 0) {
let _this = this;
let params = _this.search;
if(Number(page) > 0) params.page = page;
params.lat = _this.lat;
params.lng = _this.lng;
params.merchant_sub_type = _this.quota_type || 1;
// 数据查询
wineGoodsList(params).then(res => {
let oldList = Object.assign({}, _this.list);
// 判断:如果是第一页 则数据重置
if(params.page == 1) oldList = [];
// 数据合并
let list = res.data.list || {};
if (Object.values(list).length > 0) {
_this.total_page = Math.ceil(res.data.count / _this.search.limit);
oldList = _this.$util.SplitArray(list, oldList);
_this.search.page++;
}
_this.$set(_this, 'list', oldList);
}).catch(err => {
this.$util.tips({ content: err });
});
},
// 输入购买数量
buyFlowInputBuyNum(event, spec, currentGoods){
// 指定数量
spec.input_num = Number(event.detail.value || event.target.value);
this.currentGoods = currentGoods;
this.buyFlowChangeNum('input', spec);
},
// 购买流程 - 添加购买数量
buyFlowAddBuyNum(type, item){
let isMoreSpecs = Object.values(item.attrValue).length || 0;
let good = Object.assign({}, item);
good.is_batch = this.batch_list[good.product_id] || 0;
if(Number(isMoreSpecs) > 1){
// 多规格 初始化选中项
let selected_spec = {};
Object.values(good.attr).forEach((val,index) => {
selected_spec[val.attr_name] = (val.attr_values ? val.attr_values[0] : '');
})
// 赋值
good.selected_spec = selected_spec;
this.currentGoods = Object.assign({}, good);
this.$refs.moreSpecsSelect.open('bottom');
}
else if(['add', 'reduce', 'input'].includes(type)){
// 单规格
good.selected_spec = {};
this.currentGoods = Object.assign({}, good);
let spec = item.attrValue[0];
this.buyFlowChangeNum(type, spec)
}
},
// 购买流程 - 数量改变(添加 || 减少)
buyFlowChangeNum(type, spec){
// 数据处理
let isBatch = this.batch_list[spec.product_id] || 0;// 0=单个购买1=批量购买
let currentProduct = Object.assign({}, this.buyList[spec.product_id] || {});
if(Object.values(currentProduct).length > 0){
// 商品已经存在
let currentSpec = currentProduct.specs[spec.unique] || {};
if(Object.values(currentSpec).length <= 0) {
if(type === 'reduce') return false;
spec.cart_num = 0;
currentSpec = spec;
}
// 记录变更前数量
let oldNum = currentSpec.cart_num || 0;
// 数量变更
if(type === 'add') currentSpec.cart_num += 1;
else if(type === 'reduce') currentSpec.cart_num -= 1;
else if(type === 'input') currentSpec.cart_num = spec.input_num || 0;
// 判断:存在起购 并且低于起购数量则等于起购数量
let onceMinCount = this.currentGoods.once_min_count || 0;
if(onceMinCount > 0 && currentSpec.cart_num < onceMinCount) {
// 判断如果是减少后数量低于起购数量则直接归0否则等于起购数量
if(type === 'reduce') currentSpec.cart_num = 0;
else currentSpec.cart_num = onceMinCount;
}
// 判断:是否超出库存
let stock = currentSpec.stock || 0;
if(isBatch == 1) stock = Math.floor(stock / (this.currentGoods.batch_num || ''));//批量购买时 库存需要除以每批数量
if(Number(stock) < Number(currentSpec.cart_num)) currentSpec.cart_num = stock;
// 计算变更数量
let currentNum = currentSpec.cart_num || 0;
let changeNum = Number(oldNum) - Number(currentNum);
// 判断:额度 是否充足
if(type !== 'reduce' && this.quotaIsAdequate(changeNum, currentSpec.price)) return false;
// 判断购买数量是否已经为0 是则删除
if(currentSpec.cart_num <= 0) {
this.cartDel(currentSpec);
delete currentProduct.specs[spec.unique];
} else {
currentProduct.specs[spec.unique] = currentSpec;
// 增加购物车信息 存在即修改
currentSpec.batch_num = this.currentGoods.batch_num || '';
currentSpec.is_batch = this.currentGoods.is_batch || 0;
this.cartSubmitEdit(currentSpec);
}
// 判断:当前商品不存在任何购买规格
if(Object.values(currentProduct.specs).length <= 0){
this.$set(this.buyList, spec.product_id, {});
delete this.buyList[spec.product_id];
}else{
currentProduct.total_num -= changeNum;
this.$set(this.buyList, spec.product_id, currentProduct);
}
}
else{
// 商品不存在
if(type === 'add') spec.cart_num = 1;
else if(type === 'reduce') return false;
else if(type === 'input') spec.cart_num = spec.input_num || 0;
// 判断:存在起购 并且低于起购数量则等于起购数量
let onceMinCount = this.currentGoods.once_min_count || 0;
if(onceMinCount > 0 && spec.cart_num < onceMinCount) spec.cart_num = onceMinCount;
// 判断:是否超出库存
let stock = spec.stock || 0;
if(isBatch == 1) stock = Math.floor(stock / (this.currentGoods.batch_num || ''));//批量购买时 库存需要除以每批数量
if(Number(stock) < Number(spec.cart_num)) spec.cart_num = stock;
// 判断:额度 是否充足
if(this.quotaIsAdequate(spec.cart_num, spec.price)) return false;
// 初始化
this.$set(this.buyList, spec.product_id, {
// 购买单位类型
is_batch: this.currentGoods.is_batch,// 是否支持按照批次购买
batch_num: this.currentGoods.batch_num,// 一批等于多少件
batch_unit: this.currentGoods.batch_unit,// 一批次的单位
// 其他信息
product_id: spec.product_id,
total_num: spec.cart_num,
store_name: this.currentGoods.store_name,
wine_type: this.currentGoods.wine_type || 0,
specs: {
[spec.unique]: spec,
},
});
// 增加购物车信息
spec.batch_num = this.currentGoods.batch_num || '';
spec.is_batch = this.currentGoods.is_batch || 0;
this.cartSubmitEdit(spec);
}
this.$forceUpdate();
},
// 购买流程 - 判断对应的额度是否充足
quotaIsAdequate(num, price){
// 判断:如果当前是小酒馆兑换则无需判断额度是否充足 如果是酒道馆则需要判断额度是否充足
if(Number(this.quota_type) === 2 ) return false;
// 酒类型0=未知1=瓶装酒2=封坛酒
let wineType = this.currentGoods.wine_type || 0;
let surplus_available = 0;
let tips = '额度不足!';
if(Number(wineType) === 1) {
surplus_available = this.surplus_available || 0;
tips = '瓶装酒额度不足!'
}
else if(Number(wineType) === 2) {
surplus_available = this.surplus_wine_available || 0;
tips = '封坛酒额度不足!'
}
// 判断是否超出
if(Number(surplus_available) < (Math.abs(Number(num)) * Number(price))){
this.$util.tips({ content: tips });
this.cartGetList();
return true;
}
return false;
},
// 购买流程 - 多规格弹框关闭
closeMoreSpecsSelect(){
this.$refs.moreSpecsSelect.close();
},
// 购买流程 - 多规格切换
buyFlowChangeSpec(attrName, specItem){
this.currentGoods.selected_spec[attrName] = specItem;
},
// 购买流程 - 切换购买单位
changeBatchType(productId){
// 获取切换后购买单位
let currentBatchType = this.batch_list[productId] || 0;
let negation = currentBatchType == 0 ? 1 : 0;
// 切换商品购买数量
let currentProduct = Object.assign({}, this.buyList[productId] || {});
this.$set(this.batch_list, productId, negation);
if(Object.values(currentProduct).length > 0){
let specs = currentProduct.specs || {};
let totalNum = 0;
Object.values(specs).forEach(item => {
let stock = item.stock || 0;
let cartNum = 0;
if(negation == 1){
// 批量购买 当前购买数量除以每批的数量
cartNum = Math.floor(item.cart_num / currentProduct.batch_num);
stock = Math.floor(stock / currentProduct.batch_num);
}else{
// 单个购买 当前购买数量乘以每批的数量
cartNum = Math.floor(item.cart_num * currentProduct.batch_num);
}
// 判断:是否超出库存
cartNum = cartNum <= 0 ? 1 : cartNum;
if(stock < cartNum) cartNum = stock;
totalNum += cartNum;
currentProduct.specs[item.unique].cart_num = cartNum || 1;
// 修改购物车信息
let spec = currentProduct.specs[item.unique] || {};
spec.batch_num = currentProduct.batch_num || '';
spec.is_batch = negation || 0;
this.cartSubmitEdit(spec);
})
currentProduct.total_num = totalNum;
this.$set(this.buyList, productId, currentProduct);
}
// 赋值
this.$forceUpdate();
},
// 购买流程 - 计算总价值和总数量
BuyFlowComputeTotal(){
// 初始化信息
let totalNum = 0;// 总数量
let totalPrice = 0.00;// 总价值
let needAvailable = 0;// 需要的瓶装酒额度
let needWindAvailable = 0;// 需要的封坛酒额度
// 循环处理
Object.values(this.buyList).forEach(item => {
totalNum += item.total_num;
Object.values(item.specs).forEach(value => {
let price = value.price * value.cart_num;
let currentBatchType = this.batch_list[value.product_id] || 0;
// 判断:如果是批量购买 当前价格需要乘以每批的数量
if(currentBatchType == 1) price = price * item.batch_num;
// 根据商品酒类型增加对应的额度酒类型0=未知1=瓶装酒2=封坛酒
if(Number(item.wine_type) === 1) needAvailable += price;
else if(Number(item.wine_type) === 2) needWindAvailable += price;
totalPrice += price;
})
})
// 赋值
this.totalNum = totalNum.toFixed(0);
this.totalPrice = totalPrice.toFixed(2);
// 计算剩余瓶装酒额度
let surplusAvailable = this.available || 0;
surplusAvailable = (Number(surplusAvailable) - Number(needAvailable)).toFixed(2);
this.$set(this, 'surplus_available', surplusAvailable);
// 计算剩余封坛酒额度
let surplusWineAvailable = this.wine_available || 0;
surplusWineAvailable = (Number(surplusWineAvailable) - Number(needWindAvailable)).toFixed(2);
this.$set(this, 'surplus_wine_available', surplusWineAvailable);
this.$forceUpdate();
},
// 购物车 - 获取已存在列表
cartGetList(){
let _this = this;
// 数据查询
wineWithGoodsCartList({ merchant_sub_type: _this.quota_type }).then(res => {
if(res.status == 200){
let data = res.data || {};
let buyList = {};
let batchList = {};
Object.values(data).forEach( item => {
// 获取规格信息
let spec = item.productAttr || {};
spec.cart_num = item.cart_num || 0;
// 赋值
let good = buyList[item.product_id] || {};
if(Object.values(good).length > 0){
// 商品已经存在
buyList[item.product_id].specs[item.product_attr_unique] = spec;
buyList[item.product_id].total_num += item.cart_num;
}else{
// 商品不存在
buyList[item.product_id] = {
// 购买单位类型
is_batch: item.is_batch,// 是否支持按照批次购买
batch_num: item.batch_num,// 一批等于多少件
unit_name: item.product.unit_name,// 单件单位
batch_unit: item.product.batch_unit,// 一批次的单位
// 其他信息
product_id: item.product_id,
total_num: item.cart_num,
store_name: item.product.store_name,
wine_type: item.product.wine_type || 0,
specs: {
[item.product_attr_unique]: spec,
},
};
}
// 购买类型
batchList[item.product_id] = item.is_batch || 0;
});
_this.buyList = Object.assign({}, buyList);
_this.batch_list = Object.assign({}, batchList);
_this.$forceUpdate();
}
}).catch(err => {
_this.$util.tips({ content: err});
});
},
// 购物车 - 提交购物车
cartSubmitEdit(spec){
let _this = this;
let params = {
cart_num: spec.cart_num,
product_attr_unique: spec.unique,
product_id: spec.product_id,
// 购买单位类型
is_batch: 0,// 0=单个购买1=批量购买
batch_num: spec.batch_num || '',// 一批等于多少件
};
// 数据查询
wineWithGoodsCartAdd(params).then(res => {
// console.log(res)
}).catch(err => {
_this.cartGetList();
_this.$util.tips({ content: err});
});
},
// 购物车 - 删除购物车商品信息
cartDel(spec){
let _this = this;
let params = {
product_attr_unique: spec.unique,
product_id: spec.product_id,
};
// 数据查询
wineWithGoodsCartDel(params).then(res => {
// console.log(res)
}).catch(err => {
_this.cartGetList();
_this.$util.tips({ content: err});
});
},
// 立即结算
settlementCart(){
let _this = this;
// 数据查询
wineWithGoodsCartIds({ merchant_sub_type: _this.quota_type }).then(res => {
if(res.status == 200){
let data = res.data || {};
if(Object.values(data).length <= 0){
_this.$util.tips({ content: '请选择商品!'});
return false;
}
// 去结算
uni.navigateTo({
url: '/pages/users/order_confirm/index?cartId=' + data.join(',')
});
}
}).catch(err => {
_this.$util.tips({ content: err});
});
},
// 搜索 - 获取品牌列表
getBrandList() {
let _this = this;
getBrandlist().then(res => {
_this.brand_list = res.data.list || {};
})
},
// 搜索 - 选择品牌
brandSelectShowOrHide(type = true){
if(type) this.$refs.brandPopup.open("bottom");
else this.$refs.brandPopup.close();
},
// 搜索 - 获取分类
getAllCategory(pid = 0) {
let _this = this;
getProductCate({ pid: pid }).then(res => {
// 列表赋值
let list = res.data || {};
let info = list[0] || {};
let lv = info.level || 0;
_this.$set(_this.cate_list, lv, list || {});
_this.cateSelected(info);
})
},
// 搜索 - 选择分类
cateSelectShowOrHide(type = true){
if(type) this.$refs.catePopup.open("bottom");
else this.$refs.catePopup.close();
},
// 搜索 - 分类选中
cateSelected(info){
// 判断:不为初始化 赋值
this.cate_name = info.cate_name || '';
this.search.store_category_id = info.store_category_id || 0;
// 判断:根据等级 进行对应的操作
if(Number(info.store_category_id) > 0){
if(info.level < 2) this.getAllCategory(info.store_category_id)
else this.getGoodsList( 1);
}else{
this.$set(this.cate_list, 1, {});
this.$set(this.cate_list, 2, {});
this.getGoodsList( 1);
}
},
// 搜索 - 获取酒道馆列表
getMerWineList() {
let _this = this;
wineList({ merchant_sub_type: _this.quota_type}).then(res => {
_this.mer_list = res.data || {};
})
},
// 搜索 - 选择酒道馆
merSelectShowOrHide(type = true){
if(type) this.$refs.merPopup.open("bottom");
else this.$refs.merPopup.close();
},
// 搜索 - 内容改变
changeSearch(event, type){
// 当前选中内容下标
let indexArr = event.detail.value || event.target.value;
let oneIndex = indexArr[0] || 0;
let twoIndex = indexArr[1] || 0;
let threeIndex = indexArr[2] || 0;
// 根据类型 进行对应的操作
switch (type){
case 'brand':
let brand = Object.assign({}, this.brand_list[oneIndex]);
this.search.brand_id = brand.brand_id || '';
this.brand_name = brand.brand_name || '';
this.getGoodsList( 1);
break;
case 'cate':
this.cate_one_index = oneIndex;
this.cate_two_index = twoIndex;
this.cate_three_index = threeIndex;
break;
case 'mer':
if(oneIndex <= 0){
this.search.mer_id = '';
this.mer_name = '';
}else{
let mer = Object.assign({}, this.mer_list[(oneIndex - 1)]);
this.search.mer_id = mer.mer_id || '';
this.mer_name = mer.mer_name || '';
}
this.getGoodsList( 1);
break;
}
},
},
// 滚动到底部
onReachBottom() {
if(this.total_page > this.search.page) this.getGoodsList();
},
}
</script>
<style scoped lang="scss">
.page-content{
width: 100vw;
min-height: 100vh;
background-color: #f6f6f6;
// 主要内容
.main-content{
padding-bottom: 200rpx;
// 搜索
.search-content{
background: #F9F0DA;
.search-main{
display: inline-flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: space-between;
align-items: center;
width: 100%;
padding: 20rpx;
.search-input{
border-top-left-radius: 10rpx;
border-bottom-left-radius: 10rpx;
width: calc(100% - 110rpx);
padding: 0 20rpx;
height: 60rpx;
line-height: 60rpx;
border: 4rpx solid #c5464a;
background: transparent;
outline: none;
}
.search-btn{
background: #c5464a;
border-top-right-radius: 10rpx;
border-bottom-right-radius: 10rpx;
width: 110rpx;
height: calc(60rpx + (4rpx * 2));
line-height: calc(60rpx + (4rpx * 2));
font-size: 26rpx;
color: #F9F0DA;
text-align: center;
}
}
}
// 筛选
.screen{
background: #F9F0DA;
color: #813d40;
width: 100%;
height: 80rpx;
display: inline-flex;
flex-direction: row;
flex-wrap: nowrap;
align-items: center;
justify-content: space-around;
.block{
width: calc(100% / 3);
height: 80rpx;
display: inline-flex;
flex-direction: row;
flex-wrap: nowrap;
align-items: center;
justify-content: center;
.title{
font-size: 30rpx;
}
.iconfont{
font-size: 30rpx;
margin-left: 10rpx;
}
}
}
// 商品列表
.list{
--item-padding-: 20rpx;
.item:not(:last-child){
margin-bottom: var(--item-padding-);
}
.item{
padding: var(--item-padding-);
background: #FFFFFF;
.goods{
width: 100%;
padding-bottom: var(--item-padding-);
display: inline-flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: flex-start;
align-items: center;
.image{
width: 120rpx;
height: 120rpx;
.goods-image{
width: 100%;
height: 100%;
}
}
.info{
width: calc(100% - 120rpx);
height: 120rpx;
padding-left: 20rpx;
display: inline-flex;
flex-direction: column;
flex-wrap: nowrap;
justify-content: space-evenly;
align-items: flex-start;
.top{
height: 60rpx;
width: 100%;
display: inline-flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: space-between;
align-items: center;
.title{
width: calc(100% - 150rpx);
font-size: 32rpx;
font-weight: bold;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.distance{
font-size: 26rpx;
width: 150rpx;
color: #828282;
text-align: right;
}
}
.price-info{
height: 30rpx;
display: inline-flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: space-between;
align-items: flex-end;
.integral{
font-size: 30rpx;
color: #d84b40;
font-weight: bold;
}
.price{
font-size: 24rpx;
color: #828282;
text-decoration: line-through;
margin-left: 15rpx;
}
}
.other-info{
height: 30rpx;
width: 100%;
font-size: 24rpx;
color: #828282;
display: inline-flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: flex-start;
align-items: center;
.once_min_count{
margin-left: 30rpx;
}
}
}
}
.buy{
padding-top: var(--item-padding-);
border-top: 2rpx solid #F6F6F6;
width: 100%;
height: 75rpx;
display: inline-flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: space-between;
align-items: center;
.left{
.left-text{}
.wine-type-one{
color: #409eff;
}
.wine-type-two{
color: #e6a23c;
}
}
.right{
.icon-gengduozhankai1{
font-size: 42rpx;
}
.buy-num{
--border-color-: #f2f2f2;
display: inline-flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: flex-start;
align-items: center;
.num-change{
border: 2rpx solid var(--border-color-);
display: inline-flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: flex-start;
align-items: center;
border-radius: 100rpx;
padding: 0 15rpx;
height: 45rpx;
.iconfont{
text-align: center;
font-size: 30rpx;
}
.icon-shangpinshuliang-jian{
padding-right: 15rpx;
}
.icon-shangpinshuliang-jia{
padding-left: 15rpx;
}
.num-input{
border-left: 2rpx solid var(--border-color-);
border-right: 2rpx solid var(--border-color-);
width: 100rpx;
text-align: center;
z-index: 1;
}
}
.unit{
font-size: 26rpx;
margin-left: 10rpx;
}
}
.lack_available{
font-size: 26rpx;
color: #828282;
text-align: right;
}
}
}
}
}
// 结算按钮
.settlement{
position: fixed;
bottom: 0;
left: 0;
width: 100%;
background: #FFFFFF;
padding: 20rpx 20rpx 50rpx 20rpx;
box-shadow: 0 0 10px 0 #f3f3f3;
z-index: 9;
.top{
width: 100%;
display: inline-flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: space-between;
align-items: center;
.left{
display: inline-flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: flex-start;
align-items: center;
.icon-gouwuche-mendian{
font-size: 30rpx;
margin-right: 20rpx;
border: 2rpx solid #000000;
border-radius: 50%;
padding: 15rpx;
position: relative;
.total-num{
position: absolute;
top: -5px;
right: -5px;
font-size: 20rpx;
background: #ef2c1c;
color: #ffffff;
border-radius: 50%;
width: 35rpx;
height: 35rpx;
text-align: center;
line-height: 35rpx;
}
}
.total{
font-size: 30rpx;
.total-price{
font-weight: bold;
color: #ef2c1c;
}
}
}
.right{
.available{
font-size: 24rpx;
color: #828282;
height: 40rpx;
line-height: 50rpx;
}
.settlement-btn{
background: #ef2c1c;
color: #FFFFFF;
height: 55rpx;
line-height: 55rpx;
width: 200rpx;
text-align: center;
border-radius: 100rpx;
}
.not-btn{
background-color: #909399!important;
border-color: #909399!important;
color: #fff!important;
}
}
}
.quota-info{
width: 100%;
display: inline-flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: space-between;
align-items: center;
.available-line{
font-size: 24rpx;
color: #828282;
height: 40rpx;
line-height: 50rpx;
}
}
}
}
// 多规格选择弹框
.more-spec-content{
height: 80vh;
width: 100vw;
border-top-left-radius: 30rpx;
border-top-right-radius: 30rpx;
background: #f6f6f6;
padding: 20rpx;
.goods-info{
width: 100%;
padding-bottom: 20rpx;
display: inline-flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: flex-start;
align-items: center;
position: relative;
.image{
width: 120rpx;
height: 120rpx;
.goods-image{
width: 100% !important;
height: 100% !important;
}
}
.info{
width: calc(100% - (120rpx + 60rpx));
padding-left: 15rpx;
.title{
font-size: 32rpx;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
height: 50rpx;
line-height: 50rpx;
}
.price-info{
height: 30rpx;
display: inline-flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: space-between;
align-items: flex-end;
.integral{
color: #d14e42;
font-size: 28rpx;
font-weight: bold;
}
.price{
font-size: 24rpx;
color: #828282;
text-decoration: line-through;
margin-left: 15rpx;
.price-icon{
font-size: 24rpx;
}
}
}
.stock{
color: #a8a8a8;
font-size: 22rpx;
}
}
.close-btn{
width: 60rpx;
text-align: right;
position: absolute;
top: 0;
right: 0;
font-size: 50rpx;
}
}
.goods-spec{
max-height: calc(100% - 70rpx - 30rpx - 120rpx - 20rpx);
overflow: auto;
.spec-block{
.spec-title{
width: 100%;
height: 50rpx;
line-height: 50rpx;
color: #a8a8a8;
font-size: 30rpx;
font-weight: bold;
}
.spec-list{
display: inline-flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: flex-start;
align-items: center;
.spec-list-tag{
border: 2rpx solid #a6a6a6;
height: 45rpx;
line-height: 45rpx;
padding: 0 15rpx;
font-size: 26rpx;
margin-right: 15rpx;
margin-bottom: 15rpx;
}
.spec-list-tag-active{
background: #e93423;
color: #f3f3f3;
border-color: #e93423;
}
}
}
}
.bottom-content{
--border-color-: #000000;
width: 100%;
display: inline-flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: flex-end;
align-items: center;
margin-top: 30rpx;
.num-change{
border: 2rpx solid var(--border-color-);
display: inline-flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: flex-start;
align-items: center;
border-radius: 100rpx;
padding: 0 15rpx;
height: 70rpx;
float: right;
.iconfont{
text-align: center;
font-size: 30rpx;
width: 70rpx;
}
.icon-shangpinshuliang-jian{
padding-right: 15rpx;
}
.icon-shangpinshuliang-jia{
padding-left: 15rpx;
}
.num-input{
border-left: 2rpx solid var(--border-color-);
border-right: 2rpx solid var(--border-color-);
width: 150rpx;
height: 70rpx;
text-align: center;
}
}
.unit{
font-size: 26rpx;
margin-left: 10rpx;
}
}
}
// 选择弹框
.screen-popup-content{
height: 80vh;
width: 100vw;
border-top-left-radius: 30rpx;
border-top-right-radius: 30rpx;
background: #f6f6f6;
position: relative;
.close-btn{
position: absolute;
top: 0;
right: 0;
z-index: 10;
font-size: 30rpx;
width: 120rpx;
text-align: center;
height: 60rpx;
line-height: 60rpx;
}
.picker-view {
width: 100vw!important;
height: 80vh!important;
border-top-left-radius: 30rpx;
border-top-right-radius: 30rpx;
.item {
text-align: center;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
line-height: 34px!important;
}
}
}
}
</style>