2024-01-03 14:19:05 +08:00

1507 lines
42 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>
<view class="uni-header">
<view class="uni-group hide-on-phone">
<view class="uni-title">{{$t('order.food.title')}}</view>
</view>
</view>
<view class="uni-container food">
<view class="left">
<scroll-view class="sidebar menu-scroll-view" scroll-y scroll-with-animation :scroll-top="scrollTop"
:scroll-into-view="itemId">
<view v-for="(item,index) in category" :key="index"
:class="[current == index ? 'tab-item-active' : '']" @click="swichMenu(index)" class="tab-item">
{{item.name}}
</view>
</scroll-view>
</view>
<view class="right" :style="{width: leftWidth + 'px'}">
<!-- 右侧商品列表 -->
<scroll-view :scroll-top="scrollRightTop" @scroll="rightScroll" scroll-y scroll-with-animation
class="right-box">
<view class="class-item" :id="'item' + index" v-for="(item , index) in category" :key="index">
<view class="title">- {{item.name}} -</view>
<uni-row gutter="20">
<uni-col :xs="12" :sm="12" :md="8" :lg="6" :xl="2" v-for="(item1, index1) in item.goods"
:key="index1">
<view class="item">
<view class="goods-img">
<image :src="item1.image[0].url">
</image>
<view class="number-box">
<uni-number-box :transparent="true" :spec="item1.spec_type == 20"
@minus="minusCount(index,index1)" @plus="addCount(index,index1)"
v-model="category[index].goods[index1].total_num">
</uni-number-box>
</view>
</view>
<view class="goods_name">{{item1.goods_name}}</view>
<view class="sold">
已售:{{item1.goods_sales}}份
<text>
¥{{item1.spec[0].goods_price}}
<text
v-if="item1.spec[0].line_price > 0">¥{{item1.spec[0].line_price}}</text>
</text>
</view>
</view>
</uni-col>
</uni-row>
</view>
</scroll-view>
</view>
<uni-fab @fabClick="$refs.cart.open()" :value="order_total_num" horizontal="right" vertical="bottom">
</uni-fab>
<!-- 多规格选择框 -->
<uni-popup ref="spec" :is-mask-click="false">
<view class="popup-350">
<view class="title">
{{$t('order.food.spec.title')}}
<view @click="close('spec')" class="close">
<uni-icons type="closeempty" color="#999" size="22"></uni-icons>
</view>
</view>
<view class="spec-box">
<view class="goods cf">
<image :src="goods_img"></image>
<view class="detail">
<view class="hm-col-0">{{goods.goods_name}}</view>
<view class="hm-col-9 hm-m-t-10">{{spec_name}}</view>
<view class="hm-col-error hm-m-t-10">
¥{{goods_price}}
<text class="hm-zhx hm-col-9 hm-m-l-5" v-if="line_price>0">¥{{line_price}}</text>
</view>
</view>
</view>
<view v-for="(attr, attr_idx) in specData.spec_attr" :key="attr_idx" class="hm-p-10 cf">
<view class="spec-title" :data-id="attr.group_id">{{attr.group_name}}</view>
<view class="cf">
<view v-for="(item, item_idx) in attr.spec_items" :key="item_idx" class="spec-but"
:class="item.checked?'ok':'no'" @click="specTap(attr_idx,item_idx)">
{{item.spec_value}}
</view>
</view>
</view>
<view>
<view class="spec-title">{{$t('order.food.spec.buy_num')}}</view>
<uni-number-box @minus="minus()" @plus="plus()" v-model="goods.spec[spec_index].sell_num"
background="#ff9900">
</uni-number-box>
<view class="hm-m-t-10 hm-p-lr-33">
<button class="uni-button uni-button-full" type="primary"
@click="close('spec')">{{$t('common.button.confirm')}}</button>
</view>
</view>
</view>
</view>
</uni-popup>
<!-- 购物车 -->
<uni-popup ref="cart" :is-mask-click="false">
<view class="popup-350">
<view class="title">
{{$t('order.food.cart.title')}}
<view @click="close('cart')" class="close hm-m-l-15">
<uni-icons type="closeempty" color="#999" size="22"></uni-icons>
</view>
<view @click="cartCler" class="close">
<uni-icons type="trash-filled" color="#999" size="22"></uni-icons>
</view>
</view>
<view class="hm-p-10">
<view>
<view @click="$refs.user.open()"
:class="user.constructor === Object?'cart-but-ok':'cart-but-no'" class="cart-but">
<view v-if="user.constructor === Object" class="icons">
<uni-icons type="checkbox-filled" color="#2979ff" size="20"></uni-icons>
</view>
<view v-else class="icons">
<uni-icons type="vip" color="#888" size="20"></uni-icons>
</view>
{{$t('order.food.cart.user')}}
</view>
<view @click="$refs.table.open()" v-if="food_mode_tab_value[foodModeIndex] == 10"
:class="table.constructor === Object?'cart-but-ok':'cart-but-no'" class="cart-but">
<view v-if="table.constructor === Object" class="icons">
<uni-icons type="checkbox-filled" color="#2979ff" size="20"></uni-icons>
</view>
<view v-else class="icons">
<uni-icons type="circle" color="#888" size="20"></uni-icons>
</view>
{{$t('order.food.cart.table')}}
</view>
<view @click="$refs.address.open()" v-if="food_mode_tab_value[foodModeIndex] == 20"
:class="address.constructor === Object?'cart-but-ok':'cart-but-no'" class="cart-but">
<view v-if="address.constructor === Object" class="icons">
<uni-icons type="checkbox-filled" color="#2979ff" size="20"></uni-icons>
</view>
<view v-else class="icons">
<uni-icons type="location" color="#888" size="20"></uni-icons>
</view>
{{$t('order.food.cart.address')}}
</view>
<view @click="$refs.arrive.open()" v-if="food_mode_tab_value[foodModeIndex] == 30"
class="cart-but cart-but-ok">
<view class="icons">
<uni-icons type="checkbox-filled" color="#2979ff" size="20"></uni-icons>
</view>
{{$t('order.food.cart.time')}}
</view>
<view class="food-mode">
<uni-segmented-control :current="foodModeIndex" :values="food_mode_tab_text"
@clickItem="setFoodMode" styleType="button" activeColor="#000000">
</uni-segmented-control>
</view>
</view>
<view class="car-list">
<block v-for="(item, index) in goods_list" :key="index">
<view v-if="item.total_num > 0" :class="index > 0 ?'item hm-border-t':'item'">
<image v-if="item.spec_type == 10" :src="item.image[0].url"></image>
<image v-if="item.spec_type == 20"
:src="item.goods_sku.image.url ?item.goods_sku.image.url:item.image[0].url">
</image>
<view class="goods-name">
{{item.goods_name}}
<text class="hm-m-l-5 hm-col-9">{{item.goods_sku.goods_attr}}</text>
<text class="fr hm-col-9">{{index+1}}#</text>
</view>
<view class="hm-font-14 hm-col-error hm-m-t-5">
¥{{item.goods_sku.goods_price}}
<text class="hm-zhx hm-col-9 hm-m-l-5"
v-if="item.goods_sku.line_price>0">¥{{item.goods_sku.line_price}}</text>
</view>
<view class="cart-list-but">
<uni-number-box @minus="cartDown(item.goods_id,item.goods_sku_id)"
@plus="cartUp(item.goods_id,item.goods_sku_id)" v-model="item.total_num"
background="#ff9900">
</uni-number-box>
</view>
</view>
</block>
</view>
<view class="uni-button-group hm-p-lr-33">
<button class="uni-button uni-button-full" type="primary"
@click="settlement">{{$t('order.food.cart.button')}}</button>
</view>
</view>
</view>
</uni-popup>
<!-- 查找会员选择框 -->
<uni-popup ref="user" :is-mask-click="false">
<view class="popup-350">
<view class="title">
{{$t('order.food.user.title')}}
<view @click="$refs.user.close()" class="close">
<uni-icons type="closeempty" color="#999" size="22"></uni-icons>
</view>
</view>
<view class="form">
<uni-forms :border="true" ref="formUser" v-model="formDataUser" :rules="rulesUser">
<uni-forms-item :label="$t('order.food.user.text')" name="phone" labelWidth="35">
<uni-easyinput @confirm="getVip" type="number" v-model="formDataUser.phone"
:placeholder="$t('order.food.user.placeholder')">
</uni-easyinput>
</uni-forms-item>
<view class="uni-button-group hm-p-lr-33">
<button class="uni-button uni-button-full" type="primary"
@click="getVip">{{$t('common.button.submit')}}</button>
</view>
</uni-forms>
</view>
</view>
</uni-popup>
<!-- 选择餐桌框 -->
<uni-popup ref="table" :is-mask-click="false">
<view class="popup-350">
<view class="title">
{{$t('order.food.table.title')}}
<view @click="$refs.table.close()" class="close">
<uni-icons type="closeempty" color="#999" size="22"></uni-icons>
</view>
</view>
<view class="table-list">
<view @click="chooseTable(table_index)" v-for="(table_item, table_index) in tableList"
:key="table_index" :class="'table-item table-item-' + table_item.status.value">
<view v-if="table.table_id == table_item.table_id" class="icons">
<uni-icons type="checkmarkempty" color="#e43d33"></uni-icons>
</view>
<view>{{table_item.status.text}}</view>
<view>{{table_item.table_name}}</view>
</view>
</view>
</view>
</uni-popup>
<!-- 设置收货地址 -->
<uni-popup ref="address" :is-mask-click="false">
<view class="popup-350">
<view class="title">
{{$t('order.food.address.title')}}
<view @click="$refs.address.close()" class="close">
<uni-icons type="closeempty" color="#999" size="22"></uni-icons>
</view>
</view>
<view class="form">
<uni-forms :border="true" ref="formAddress" v-model="formDataAddress" :rules="rulesAddress">
<uni-forms-item :label="$t('order.food.address.field.name')" name="name" labelWidth="35">
<uni-easyinput @confirm="setAddress" v-model="formDataAddress.name"
:placeholder="$t('order.food.address.placeholder.name')">
</uni-easyinput>
</uni-forms-item>
<uni-forms-item :label="$t('order.food.address.field.phone')" name="phone" labelWidth="35">
<uni-easyinput @confirm="setAddress" type="number" v-model="formDataAddress.phone"
:placeholder="$t('order.food.address.placeholder.phone')">
</uni-easyinput>
</uni-forms-item>
<uni-forms-item :label="$t('order.food.address.field.detail')" name="detail" labelWidth="35">
<uni-easyinput type="textarea" v-model="formDataAddress.detail"
:placeholder="$t('order.food.address.placeholder.detail')" />
</uni-forms-item>
<view class="uni-button-group hm-p-lr-33">
<button class="uni-button uni-button-full" type="primary"
@click="setAddress">{{$t('common.button.confirm')}}</button>
</view>
</uni-forms>
</view>
</view>
</uni-popup>
<!-- 设置取餐时间 -->
<uni-popup ref="arrive" :is-mask-click="false">
<view class="popup-350">
<view class="title">
{{$t('order.food.arrive.title')}}
<view @click="$refs.arrive.close()" class="close">
<uni-icons type="closeempty" color="#999" size="22"></uni-icons>
</view>
</view>
<view class="arrive">
<uni-data-select v-model="arrive_time" :localdata="arrive" @change="setArrive">
</uni-data-select>
<view class="uni-button-group hm-p-lr-33">
<button class="uni-button uni-button-full" type="primary"
@click="$refs.arrive.close()">{{$t('common.button.confirm')}}</button>
</view>
</view>
</view>
</uni-popup>
<!-- 结算框 -->
<uni-popup ref="settlement" :is-mask-click="false">
<view class="popup-350">
<view class="title">
{{$t('order.food.settlement.title')}}
<view @click="close('settlement')" class="close">
<uni-icons type="closeempty" color="#999" size="22"></uni-icons>
</view>
</view>
<view class="settlement">
<view class="money">
{{$t('order.food.settlement.money')}}<text>¥{{order_pay_price}}</text>
</view>
<uni-section titleColor="#444" :title="$t('order.food.settlement.price.title')" type="line" titleFontSize="14">
</uni-section>
<view class="price">
{{$t('order.food.settlement.price.goods')}}<text>+¥{{order_total_price}}</text>
</view>
<view v-if="food_mode_tab_value[foodModeIndex] > 10 && pack_price > 0" class="price hm-border-t">
{{$t('order.food.settlement.price.pack')}}<text>+¥{{pack_price}}</text>
</view>
<view v-if="food_mode_tab_value[foodModeIndex] == 20 && express_price > 0" class="price hm-border-t">
{{$t('order.food.settlement.price.express')}}<text>+¥{{express_price}}</text>
</view>
<view class="price hm-border-t">
{{$t('order.food.settlement.price.activity')}}<text>-¥{{activity_price}}</text>
</view>
<view class="discount hm-border-t">
<view class="item">
{{$t('order.food.settlement.price.discount')}}
<view class="input">
<uni-easyinput @change="setDiscount" v-model="discount"
:styles="{color:'#ff0000',textAlign:'center',height:'28px'}" maxlength="3"
type="number" :clearable="false" />
</view>
</view>
<view class="item">
{{$t('order.food.settlement.price.direct')}}
<view class="input">
<uni-easyinput @change="setDirect" v-model="direct"
:styles="{color:'#ff0000',textAlign:'center',height:'28px'}" maxlength="3"
type="number" :clearable="false" />
</view>
</view>
<view class="item">
<uni-data-checkbox mode="button" multiple @change="setWipe" :localdata="wipe" />
</view>
</view>
<uni-section titleColor="#444" :title="$t('order.food.settlement.payment.title')" type="line" titleFontSize="25">
</uni-section>
<view class="payment">
<view class="item" @click="setPayMode(0)" :class="pay_mode == 0?'item-ok':'item-no'">
<view class="icons">
<uni-icons type="weixin" :color="pay_mode == 0?'#fff':'#999'" size="25"></uni-icons>
</view>
{{$t('order.food.settlement.payment.wechat')}}
</view>
<view class="item" @click="setPayMode(1)" v-if="user.constructor === Object"
:class="pay_mode == 1?'item-ok':'item-no'">
<view class="icons">
<uni-icons type="wallet-filled" :color="pay_mode == 1?'#fff':'#999'" size="25">
</uni-icons>
</view>
{{$t('order.food.settlement.payment.wallet')}}
</view>
<view class="item" @click="setPayMode(2)" :class="pay_mode == 2?'item-ok':'item-no'">
<view class="icons">
<uni-icons type="download-filled" :color="pay_mode == 2?'#fff':'#999'" size="25">
</uni-icons>
</view>
{{$t('order.food.settlement.payment.offline')}}
</view>
<view class="item" @click="setPayMode(3)" :class="pay_mode == 3?'item-ok':'item-no'">
<view class="icons">
<uni-icons type="calendar-filled" :color="pay_mode == 3?'#fff':'#999'" size="25">
</uni-icons>
</view>
{{$t('order.food.settlement.payment.after')}}
</view>
</view>
<view v-if="pay_mode == 0" class="wx-id">
<uni-easyinput v-model="wx_id" :placeholder="$t('order.food.settlement.payment.placeholder')" focus />
</view>
<view class="uni-button-group hm-p-lr-25">
<button class="uni-button uni-button-full" type="primary" @click="payCart" :disabled="disabled" :loading="disabled">{{$t('order.food.settlement.button')}}</button>
</view>
</view>
</view>
</uni-popup>
</view>
<!-- #ifndef H5 -->
<fix-window />
<!-- #endif -->
</view>
</template>
<script>
let App = getApp();
export default {
data() {
return {
leftWidth: 740,
//购物车数据
category: {}, //分类+商品列表
goods_list: {}, //购物车商品列表
order_total_num: 0, //购物车商品总数
order_total_price: 0, //购物车商品总价
order_pay_price:0,//实付金额
min_price: 0, //起送价
pack_price:0,//包装费
express_price:0,//配送费
activity_price:0,//优惠金额
scrollTop: 0, //tab标题的滚动条位置
oldScrollTop: 0,
current: 0, // 预设当前项的值
menuHeight: 0, // 左边菜单的高度
menuItemHeight: 0, // 左边菜单item的高度
itemId: '', // 栏目右边scroll-view用于滚动的id
arr: [],
scrollRightTop: 0, // 右边栏目scroll-view的滚动条高度
//多规格商品数据
show: false, //是否显示
goods: {}, //商品详情
spec_name: '',
goods_price: '',
line_price: '',
goods_img: '',
goods_sku_id: '',
goods_spec_arr: [],
specData: {}, //商品规格
spec_index: 0,
//点单模式
foodModeIndex: 0,
food_mode_tab_text: [],
food_mode_tab_value: [],
formDataUser: {
phone: ''
},
rulesUser: {
phone: {
rules: [{
required: true,
errorMessage: '请输入会员手机号',
},
{
minLength: 11,
maxLength: 11,
errorMessage: '长度必须是11位的手机号',
}
]
}
},
user: [], //用户信息
tableList: {}, //餐桌列表
message:'',//备注
table: [], //餐桌信息
address: [], //地址信息
formDataAddress: {
name: '',
phone: '',
detail: ''
},
rulesAddress: {
phone: {
rules: [{
required: true,
errorMessage: '请输入收货人电话',
},
{
minLength: 11,
maxLength: 11,
errorMessage: '长度必须是11位的手机号',
}
]
},
detail: {
rules: [{
required: true,
errorMessage: '请输入详细地址',
}]
}
},
arrive_time: 1, //约定时间
arrive: [{
value: 1,
text: "立即取餐"
},
{
value: 30,
text: "30分钟后"
},
{
value: 60,
text: "1小时后"
},
{
value: 90,
text: "1.5小时后"
}, {
value: 120,
text: "2小时后"
},
{
value: 150,
text: "2.5小时后"
}, {
value: 180,
text: "3小时后"
},
{
value: 210,
text: "3.5小时后"
}, {
value: 240,
text: "4小时后"
}
],
wipe: [{
text: '抹零',
value: 1
}],
wipe_price: 0, //抹零金额
discount: 100, //折扣
direct: 0, //直减金额
pay_mode: 0, //支付方式
wx_id:'',//微信支付单号
order_no:'',//订单编号,微信支付有返回
interval_id: '', //循环定时器ID
disabled: false,
}
},
onLoad(opts) {
let _this = this;
_this.getSystem();
_this.getGoods();
_this.getFoodModeTab();
_this.getTableList();
if(opts.table_id != undefined){
_this.getTableDetail(opts.table_id);
}
},
onResize() {
let _this = this;
_this.getSystem();
},
methods: {
/**
* 下单成功
*/
payCartOk(){
let _this = this;
_this.close('settlement');//关闭结算中心弹窗
_this.close('cart');//关闭购物车
},
/**
* 关闭窗口
*/
close(type) {
let _this = this;
if (type == 'cart') {
_this.foodModeIndex = 0;
_this.formDataUser.phone = '';
_this.user = [];
_this.table = [];
_this.address = [];
_this.message = '';//备注
_this.formDataAddress = {
name: '',
phone: '',
detail: ''
};
_this.arrive_time = 1;
_this.$refs.cart.close();
}
if (type == 'spec') {
_this.$refs.spec.close();
}
if (type == 'settlement') {
_this.order_no = '';
_this.wipe_price = 0;
_this.discount = 100; //折扣
_this.direct = 0; //直减金额
_this.pay_mode = 0; //支付方式
_this.wx_id = '';
_this.$refs.settlement.close();
}
_this.getGoods();
},
/**
* 购物车结算
*/
payCart(){
let _this = this;
//如果是微信支付
if (_this.pay_mode == 0 && _this.wx_id.length != 18) {
App.showError('微信付款码必须为18位');
return false;
}
// 订单创建成功后回调--微信支付
let callback = function(result) {
if (result.code === -10) {
App.showError(result.msg);
return false;
}
//判断微信支付是否需要输入密码验证
if (_this.pay_mode == 0 && result.data.pay_status == 10) {
_this.order_no = result.data.order_no;
//开启5秒定时查询
_this.interval_id = setInterval(() => {
_this.checkPayStatus(); //检测订单微信支付状态
}, 5000);
} else {
_this.payCartOk(); //下单成功
}
};
_this.disabled = true; // 按钮禁用, 防止二次提交
App._post_form('order/cart', {
order_mode: _this.food_mode_tab_value[_this.foodModeIndex],
table_id: _this.table.table_id || 0,
pay_mode: _this.pay_mode,
wx_id: _this.wx_id,
activity_price: _this.activity_price,
arrive_time: _this.arrive_time,
address: JSON.stringify(_this.address),
message: _this.message,
user_id: _this.user.user_id || 0
}, function(result) {
callback(result);
}, function(result) {
// fail
}, function() {
_this.disabled = false; // 解除按钮禁用
});
},
/**
* 检测订单微信支付状态
*/
checkPayStatus: function() {
let _this = this;
// 购物车结算
App._get('order/checkPayStatus', {
order_no: _this.order_no
}, function(result) {
//继续等待
if (result.data.order_status == 'USERPAYING' || result.data.order_status == 'ACCEPT') {
return true;
}
clearInterval(_this.interval_id) //停止循环
//支付成功
if (result.data.order_status == 'SUCCESS') {
_this.payCartOk(); //下单成功
return true;
}
App.showError('微信支付失败');
return false;
});
},
/**
* 结算中心
*/
settlement(){
let _this = this;
//如果是外卖,验证收货信息
if(_this.food_mode_tab_value[_this.foodModeIndex] == 20){
if(_this.formDataAddress.phone == ''){
App.showError('收货人电话不可为空');
return false;
}
if(_this.formDataAddress.detail == ''){
App.showError('收货人地址不可为空');
return false;
}
}
App._get('order/cart', {
order_mode: _this.food_mode_tab_value[_this.foodModeIndex],
table_id: _this.table.table_id || 0
}, function(result) {
_this.order = result.data;
_this.goods_list = result.data.goods_list;
_this.order_total_num = result.data.order_total_num;
_this.order_total_price = result.data.order_total_price;
_this.order_pay_price = result.data.order_pay_price;
_this.min_price = result.data.min_price;
_this.pack_price = result.data.pack_price;
_this.express_price = result.data.express_price;
_this.activity_price = result.data.activity_price;
_this.$refs.settlement.open();
});
},
/**
* 设置折扣
*/
setDiscount(){
let _this = this,
order_pay_price = _this.order_pay_price,
activity_price = _this.activity_price,
discount_price = Math.floor((Number(order_pay_price) * _this.discount / 100) * 100) / 100;
activity_price = Math.floor((Number(activity_price) + Number(order_pay_price) - discount_price) * 100) / 100;
_this.order_pay_price = _this.decimal(discount_price);
_this.activity_price = _this.decimal(activity_price);
},
/**
* 设置直减
*/
setDirect(){
let _this = this,
order_pay_price = _this.order_pay_price,
activity_price = _this.activity_price,
direct_price = Math.floor((Number(order_pay_price) - _this.direct) * 100) / 100;
activity_price = Math.floor((Number(activity_price) + Number(order_pay_price) - direct_price) * 100) / 100;
_this.order_pay_price = _this.decimal(direct_price);
_this.activity_price = _this.decimal(activity_price);
},
/**
* 设置支付方式
*/
setPayMode(n) {
let _this = this;
_this.pay_mode = n;
},
/**
* 抹零操作
*/
setWipe(e) {
let _this = this,
order_pay_price = _this.order_pay_price,
activity_price = _this.activity_price;
if (e.detail.value.length == 0) {
//取消抹零
let price = Number(_this.order_pay_price) + _this.wipe_price;
activity_price = Math.floor((Number(activity_price) - _this.wipe_price) * 100) / 100;
_this.order_pay_price = _this.decimal(price);
_this.activity_price = _this.decimal(activity_price);
_this.wipe_price = 0
} else {
//进行抹零
let price = Math.trunc(_this.order_pay_price);
_this.wipe_price = Math.floor((Number(_this.order_pay_price) - price) * 100) / 100;
activity_price = Math.floor((Number(activity_price) + _this.wipe_price) * 100) / 100;
_this.order_pay_price = _this.decimal(price);
_this.activity_price = _this.decimal(activity_price);
}
},
/**
* 保留两位小数
*/
decimal(number){
let str = String(number);
let arr = str.split('.');
if(arr.length == 1){
return arr[0] + '.00';
}
if(arr[1].length == 1){
return arr[0] + '.' + arr[1] + '0';
}
return arr[0] + '.' + arr[1];
},
/**
* 设置取餐时间
*/
setArrive(e) {
let _this = this;
console.log(e);
_this.arrive_time = e;
},
/**
* 设置地址信息
*/
setAddress() {
let _this = this;
_this.$refs.formAddress.validate().then(result => {
//数据验证没有问题
if (_this.address.constructor === Object) {
_this.address.name = result.name;
_this.address.phone = result.phone;
_this.address.detail = result.detail;
} else {
_this.address = result;
}
_this.$refs.address.close();
}).catch(err => {
console.log('表单提交错误');
});
},
/**
* 选择餐桌
*/
chooseTable(index) {
let _this = this,
table = _this.tableList[index];
if (table.status.value != 10) {
uni.showModal({
title: "提示",
content: "确定要为《"+table.table_name+"》加单?",
success: function(o) {
if (!o.confirm) {
return false;
}
}
});
}
_this.table = table;
_this.$refs.table.close();
},
/**
* 获取餐桌列表
*/
getTableList() {
let _this = this;
App._get('table/lists', {}, function(result) {
_this.tableList = result.data.list;
});
},
/**
* 获取餐桌详情
*/
getTableDetail(table_id) {
let _this = this;
App._get('table/detail', {
table_id: table_id
}, function(result) {
_this.table = result.data.detail;
console.log(_this.table);
});
},
/**
* 获取会员信息
*/
getVip() {
let _this = this;
_this.$refs.formUser.validate().then(result => {
//数据验证没有问题
App._post_form('user/phone', result, result => {
_this.user = result.data;
if (result.data.addressDefault) {
_this.formDataAddress.province = result.data.addressDefault.province;
_this.formDataAddress.city = result.data.addressDefault.city;
_this.formDataAddress.district = result.data.addressDefault.district;
_this.formDataAddress.detail = result.data.addressDefault.detail;
_this.formDataAddress.location = result.data.addressDefault.location;
_this.formDataAddress.name = result.data.addressDefault.name;
_this.formDataAddress.phone = result.data.addressDefault.phone;
_this.formDataAddress.user_id = result.data.addressDefault.user_id;
_this.address = _this.formDataAddress;
}
_this.$refs.user.close();
}, false, () => {});
}).catch(err => {
console.log('表单提交错误');
});
},
/**
* 购物车 - 清空
*/
cartCler: function() {
let _this = this;
uni.showModal({
title: "提示",
content: "确定要清空购物车?",
success: function(o) {
if (o.confirm) {
App._get('cart/clearAll', {}, function(result) {
_this.close('cart');
});
}
}
});
},
/**
* 购物车 - 递增
*/
cartUp: function(goods_id, goods_sku_id) {
let _this = this; // 后端同步更新
App._post_form('cart/add', {
goods_id: goods_id,
goods_num: 1,
goods_sku_id: goods_sku_id
}, () => {});
},
/**
* 购物车 - 递减
*/
cartDown: function(goods_id, goods_sku_id) {
let _this = this; // 后端同步更新
App._post_form('cart/sub', {
goods_id: goods_id,
goods_sku_id: goods_sku_id
}, () => {});
},
/**
* 设置点餐模式
*/
setFoodMode(e) {
let _this = this;
if (_this.foodModeIndex != e.currentIndex) {
_this.foodModeIndex = e.currentIndex;
}
},
/**
* 获取门店点餐模式
*/
getFoodModeTab() {
let _this = this,
user = App.getUser(),
tab = user.shop.food_mode.tab,
m = 0;
for (let n = 0; n < tab.length; n++) {
if (tab[n].status == 1) {
_this.food_mode_tab_text[m] = tab[n].text;
_this.food_mode_tab_value[m] = tab[n].value;
m++;
}
}
},
/**
* 递增 - 多规格
*/
plus: function() {
let _this = this,
spec_index = _this.spec_index,
goods = _this.goods; // 后端同步更新
App._post_form('cart/add', {
goods_id: goods.goods_id,
goods_num: 1,
goods_sku_id: goods.spec[spec_index].spec_sku_id
}, function(result) {
//goods.spec[spec_index].sell_num++;
//_this.goods = goods;
});
},
/**
* 递减 - 多规格
*/
minus: function() {
let _this = this,
spec_index = _this.spec_index,
goods = _this.goods;
if (goods.spec[spec_index].sell_num > 0) {
// 后端同步更新
App._post_form('cart/sub', {
goods_id: goods.goods_id,
goods_sku_id: goods.spec[spec_index].spec_sku_id
}, function(result) {
//goods.spec[spec_index].sell_num--;
//_this.goods = goods;
});
}
if (goods.spec[spec_index].sell_num == 0) {
// 后端同步更新
App._post_form('cart/delete', {
goods_id: goods.goods_id,
goods_sku_id: goods.spec[spec_index].spec_sku_id
}, function(result) {
//goods.spec[spec_index].sell_num--;
//_this.goods = goods;
});
}
},
/**
* 点击切换不同规格
*/
specTap: function(attrIdx, itemIdx) {
let _this = this,
specData = this.specData;
for (let i in specData.spec_attr) {
for (let j in specData.spec_attr[i].spec_items) {
if (attrIdx == i) {
specData.spec_attr[i].spec_items[j].checked = false;
if (itemIdx == j) {
specData.spec_attr[i].spec_items[itemIdx].checked = true;
_this.goods_spec_arr[i] = specData.spec_attr[i].spec_items[itemIdx].item_id;
}
}
}
}
_this.specData = specData; // 更新商品规格信息
_this.updateSpecGoods();
},
/**
* 更新商品规格信息
*/
updateSpecGoods: function() {
let _this = this,
spec_sku_id = _this.goods_spec_arr.join('_'),
spec_list = _this.specData.spec_list,
spec_index = 0,
goods_img = '',
skuItem;
for (let i = 0; i < spec_list.length; i++) {
if (spec_list[i].spec_sku_id == spec_sku_id) {
skuItem = spec_list[i];
spec_index = i;
break;
}
}
//规格图片
if (skuItem.form.image_url == '') {
goods_img = _this.goods.image[0].url;
} else {
goods_img = skuItem.form.image_url;
}
// 记录goods_sku_id
// 更新商品价格、划线价、库存
if (typeof skuItem === 'object') {
_this.spec_name = skuItem.spec_name;
_this.goods_sku_id = skuItem.spec_sku_id;
_this.goods_price = skuItem.form.goods_price;
_this.line_price = skuItem.form.line_price;
_this.spec_index = spec_index;
_this.goods_img = goods_img;
}
},
//显示多规格操作框
specShow: function(goods) {
let _this = this,
specData = null;
for (let i = 0; i < goods.specData.spec_attr.length; i++) {
for (let j = 0; j < goods.specData.spec_attr[i].spec_items.length; j++) {
if (j == 0) {
goods.specData.spec_attr[i].spec_items[0].checked = true;
_this.goods_spec_arr[i] = goods.specData.spec_attr[i].spec_items[0].item_id;
} else {
goods.specData.spec_attr[i].spec_items[j].checked = false;
}
}
}
specData = goods.specData;
console.log(specData.spec_list[0]);
let spec_list = specData.spec_list[0];
_this.goods = goods;
_this.specData = specData;
_this.spec_name = spec_list.spec_name;
_this.goods_sku_id = spec_list.goods_spec_id;
_this.goods_price = spec_list.form.goods_price;
_this.line_price = spec_list.form.line_price;
_this.goods_img = spec_list.form.image_url;
_this.$refs.spec.open()
},
/**
* 递增指定的商品数量
*/
addCount: function(index, index1) {
let _this = this,
goods = _this.category[index].goods[index1]; // 后端同步更新
//判断是否为多规格
if (goods.spec_type == 20) {
_this.specShow(goods);
return true;
}
App._post_form('cart/add', {
goods_id: goods.goods_id,
goods_num: 1,
goods_sku_id: goods.spec[0].spec_sku_id
}, function(result) {
_this.getGoods();
});
},
/**
* 递减指定的商品数量
*/
minusCount: function(index, index1) {
let _this = this,
goods = _this.category[index].goods[index1]; // 后端同步更新
//判断是否为多规格
if (goods.spec_type == 20) {
_this.specShow(goods);
return true;
}
if (goods.total_num > 0) {
// 后端同步更新
App._post_form('cart/sub', {
goods_id: goods.goods_id,
goods_sku_id: goods.spec[0].spec_sku_id
}, function(result) {
_this.getGoods();
});
}
if (goods.total_num == 0) {
// 后端同步更新
App._post_form('cart/delete', {
goods_id: goods.goods_id,
goods_sku_id: goods.spec[0].spec_sku_id
}, function(result) {
_this.getGoods();
});
}
},
/**
* 获取列表
*/
getGoods() {
let _this = this;
App._get('goods/food', {}, function(result) {
_this.goods_list = result.data.goods_list;
_this.category = result.data.category;
_this.order_total_num = result.data.order_total_num;
_this.order_total_price = result.data.order_total_price;
_this.min_price = result.data.min_price;
}, false, function(result) {});
},
// 点击左边的栏目切换
async swichMenu(index) {
let _this = this;
if (_this.arr.length == 0) {
await _this.getMenuItemTop();
}
if (index == _this.current) return;
_this.scrollRightTop = _this.oldScrollTop;
_this.$nextTick(function() {
_this.scrollRightTop = _this.arr[index];
_this.current = index;
_this.leftMenuStatus(index);
})
},
// 观测元素相交状态
async observer() {
this.tabbar.map((val, index) => {
let observer = uni.createIntersectionObserver(this);
// 检测右边scroll-view的id为itemxx的元素与right-box的相交状态
// 如果跟.right-box底部相交就动态设置左边栏目的活动状态
observer.relativeTo('.right-box', {
top: 0
}).observe('#item' + index, res => {
if (res.intersectionRatio > 0) {
let id = res.id.substring(4);
this.leftMenuStatus(id);
}
})
})
},
// 设置左边菜单的滚动状态
async leftMenuStatus(index) {
this.current = index;
// 如果为0意味着尚未初始化
if (this.menuHeight == 0 || this.menuItemHeight == 0) {
await this.getElRect('menu-scroll-view', 'menuHeight');
await this.getElRect('tab-item', 'menuItemHeight');
}
// 将菜单活动item垂直居中
this.scrollTop = index * this.menuItemHeight + this.menuItemHeight / 2 - this.menuHeight / 2;
},
// 右边菜单滚动
async rightScroll(e) {
let _this = this;
_this.oldScrollTop = e.detail.scrollTop;
if (this.arr.length == 0) {
await this.getMenuItemTop();
}
if (!this.menuHeight) {
await this.getElRect('menu-scroll-view', 'menuHeight');
}
setTimeout(() => { // 节流
// scrollHeight为右边菜单垂直中点位置
let scrollHeight = e.detail.scrollTop + this.menuHeight / 2;
for (let i = 0; i < this.arr.length; i++) {
let height1 = this.arr[i];
let height2 = this.arr[i + 1];
// 如果不存在height2意味着数据循环已经到了最后一个设置左边菜单为最后一项即可
if (!height2 || scrollHeight >= height1 && scrollHeight < height2) {
this.leftMenuStatus(i);
return;
}
}
}, 10)
},
// 获取右边菜单每个item到顶部的距离
getMenuItemTop() {
new Promise(resolve => {
let selectorQuery = uni.createSelectorQuery();
selectorQuery.selectAll('.class-item').boundingClientRect((rects) => {
// 如果节点尚未生成rects值为[](因为用selectAll所以返回的是数组),循环调用执行
if (!rects.length) {
setTimeout(() => {
this.getMenuItemTop();
}, 10);
return;
}
rects.forEach((item) => {
// 这里减去rects[0].top是因为第一项顶部可能不是贴到导航栏(比如有个搜索框的情况)
this.arr.push(item.top - rects[0].top);
resolve();
})
}).exec()
})
},
// 获取一个目标元素的高度
getElRect(elClass, dataVal) {
new Promise((resolve, reject) => {
const query = uni.createSelectorQuery().in(this);
query.select('.' + elClass).fields({
size: true
}, res => {
// 如果节点尚未生成res值为null循环调用执行
if (!res) {
setTimeout(() => {
this.getElRect(elClass);
}, 10);
return;
}
this[dataVal] = res.height;
resolve();
}).exec();
})
},
/**
* 获取系统信息
*/
getSystem() {
let _this = this,
system = uni.getSystemInfoSync();
if (system.windowWidth < 768) {
_this.leftWidth = system.windowWidth - 140 - 30;
} else {
_this.leftWidth = system.windowWidth - 140 - 200;
}
}
}
}
</script>
<style lang="scss">
.popup-350 {
.settlement {
padding: 10px;
.payment {
padding-bottom: 10px;
.item {
display: inline-block;
font-size: 16px;
margin-right: 5px;
padding: 5px 10px 3px 5px;
border-radius: 5px;
line-height: 25px;
.icons {
display: inline-block;
float: left;
}
}
.item-ok {
background-color: #18bc37;
color: #fff;
}
.item-no {
border: 1px solid #999;
color: #999;
}
}
.money {
text-align: center;
font-weight: bold;
color: #000;
padding-bottom: 10px;
border-bottom: 1px solid #f0f0f0;
text {
font-size: 30px;
color: #e43d33;
}
}
.price {
padding: 5px 10px;
color: #888;
text {
color: #e43d33;
}
}
.discount {
color: #888;
padding: 10px 0px;
.item {
display: inline-block;
margin-right: 10px;
.input {
display: inline-block;
width: 60px;
}
}
}
}
.table-list {
padding-bottom: 10px;
.table-item {
text-align: center;
border-radius: 5px;
display: inline-block;
margin: 10px 0 0 10px;
padding: 10px 5px;
width: 92px;
.icons {
display: inline-block;
float: right;
}
}
.table-item-10 {
border: 1px sold #18bc37;
color: #18bc37;
background-color: #d1f2d7;
}
.table-item-20 {
border: 1px sold #e43d33;
color: #e43d33;
background-color: #fad8d6;
}
.table-item-30 {
border: 1px sold #f3a73f;
color: #f3a73f;
background-color: #fdedd9;
}
}
.arrive {
padding: 15px 5px;
}
.form {
padding: 15px;
font-size: 18px;
}
.cart-but {
margin-top: 5px;
font-size: 14px;
display: inline-block;
padding: 2px 5px;
margin-left: 5px;
border-radius: 5px;
.icons {
display: inline-block;
float: left;
}
}
.cart-but-ok {
border: 1px solid #2979ff;
background-color: #d4e4ff;
color: #2979ff;
}
.cart-but-no {
border: 1px solid #888;
background-color: #f0f0f0;
color: #888;
}
.food-mode {
display: inline-block;
float: right;
width: 150px;
}
.car-list {
margin-top: 10px;
border: 1px solid #f0f0f0;
.item {
padding: 5px;
height: 50px;
font-size: 15px;
image {
float: left;
width: 50px;
height: 50px;
margin-right: 5px;
}
.cart-list-but {
display: inline-block;
float: right;
margin-top: -20px;
}
}
}
}
.food {
.left {
display: inline-block;
text-align: center;
background-color: #f7f7f7;
height: calc(100vh - 120px - (var(--top-window-height)));
width: 120px;
margin-right: 20px;
float: left;
overflow: hidden;
.sidebar {
width: 100%;
}
.sidebar::-webkit-scrollbar {
display: none;
}
.tab-item {
padding: 8px 0;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
border-bottom: 1px solid #fff;
}
.tab-item-active {
position: relative;
background: #fff;
}
.tab-item-active::before {
content: "";
position: absolute;
border-left: 4px solid #ff9900;
height: 25px;
left: 0;
top: 6px;
}
}
.right {
display: inline-block;
float: left;
height: calc(100vh - 120px - (var(--top-window-height)));
overflow: hidden;
.right-box {
width: 100%;
height: 100%;
}
.class-item {
width: 100%;
.title {
background-color: #f7f7f7;
text-align: center;
font-weight: 700;
padding: 5px 0;
}
.item {
width: 100%;
text-align: center;
padding: 10px 5px;
.goods-img {
position: relative;
image {
width: 90%;
height: 200px;
z-index: 0;
}
.number-box {
position: absolute;
bottom: 10px;
right: 20px;
}
}
.goods_name {
font-size: 16px;
text-align: left;
padding: 0 10px;
}
.sold {
font-size: 13px;
padding: 0 10px;
text-align: left;
color: #999;
text {
color: #e43d33;
float: right;
text {
color: #999;
margin-left: 5px;
text-decoration: line-through;
}
}
}
}
}
}
}
</style>