|
|
@@ -0,0 +1,1504 @@
|
|
|
+<template>
|
|
|
+ <view class="u-wrap">
|
|
|
+ <login ref="login" @signIn="signIn"></login>
|
|
|
+ <view class="u-search-box">
|
|
|
+ <view class="nav" >
|
|
|
+ <view class="header">
|
|
|
+ <view class="left overflow-hidden">
|
|
|
+ <view class="flex align-center overflow-hidden" v-if="takeType == takeTypeGlobal.delivery">
|
|
|
+ <image src="/pagesD/static/icon/location1.png" style="width: 30rpx; height: 30rpx;"
|
|
|
+ class="margin-right-10">
|
|
|
+ </image>
|
|
|
+ <text v-if="$isEmpty(vuex_userId)" @tap="showLogin">去登录</text>
|
|
|
+ <view class="" v-else @click="$jump('/pagesD/pages/address/address')">
|
|
|
+ <text v-if="$isEmpty(address)">请完善地址信息</text>
|
|
|
+ <view style="margin-right: 20rpx;" v-else >
|
|
|
+ <text class="text-cut-1">{{address.address}}</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="flex align-center overflow-hidden" v-else>
|
|
|
+ <image src="/pagesD/static/icon/shop2.png" style="width: 30rpx; height: 30rpx;"
|
|
|
+ class="margin-right-10">
|
|
|
+ </image>
|
|
|
+ <text style="font-size: 36rpx;font-weight: 800;">杨国福麻辣烫</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view @click="modalCheckedShow" class="cu-btn round bg-red sm" style="font-size: 24rpx;">
|
|
|
+ <text class="center">{{takeType.substring(2,4)}}</text>
|
|
|
+ <text class="cuIcon-order center text-bold" style="transform: rotate(90deg);margin-left: 6rpx;"></text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="bg-white">
|
|
|
+ <u-notice-bar mode="horizontal" :list="appProperties.shopNotice"></u-notice-bar>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="u-menu-wrap">
|
|
|
+ <scroll-view scroll-y scroll-with-animation class="u-tab-view menu-scroll-view" :scroll-top="scrollTop"
|
|
|
+ :scroll-into-view="itemId">
|
|
|
+ <view v-for="(item,index) in goods" :key="index" class="u-tab-item"
|
|
|
+ :class="[current == index ? 'u-tab-item-active' : '']" @tap.stop="swichMenu(index)">
|
|
|
+ <text class="u-line-1">{{item.goodsCategoryName}}</text>
|
|
|
+ </view>
|
|
|
+ </scroll-view>
|
|
|
+ <scroll-view :scroll-top="scrollRightTop" scroll-y scroll-with-animation class="right-box"
|
|
|
+ @scroll="rightScroll">
|
|
|
+ <view class="page-view">
|
|
|
+ <view class="class-item" :id="'item' + index" v-for="(item , index) in goods" :key="index">
|
|
|
+ <view class="item-title" >
|
|
|
+ <text>{{item.goodsCategoryName}}</text>
|
|
|
+ </view>
|
|
|
+ <view class="item-container" >
|
|
|
+ <view class="thumb-box" v-for="(goods, index1) in item.goodsList" :key="index1">
|
|
|
+ <image class="item-menu-image" :src="goods.image" mode=""></image>
|
|
|
+ <view class="item-content" >
|
|
|
+ <view class="name">{{goods.name}}</view>
|
|
|
+ <view class="tips">
|
|
|
+ {{ goods.description && goods.description != '' ? goods.description : goods.name }}
|
|
|
+ </view>
|
|
|
+ <view class="price_and_action">
|
|
|
+ <text class="price">¥{{ goods.defaultPrice / 100 }}</text>
|
|
|
+ <!-- 商品没有下架 -->
|
|
|
+ <view v-if="goods.isSell">
|
|
|
+ <!-- 要选商品规格详细信息 -->
|
|
|
+ <view class="btn-group"
|
|
|
+ v-if="goods.goodsPropertyVos && goods.goodsPropertyVos.length">
|
|
|
+ <button type="primary" class="btn property_btn" hover-class="none"
|
|
|
+ size="mini" @tap="showGoodDetailModal(goods)">
|
|
|
+ 选规格
|
|
|
+ </button>
|
|
|
+ <view class="dot" v-show="goodsCartNum(goods.id)">
|
|
|
+ {{ goodsCartNum(goods.id) }}
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <!-- 可以直接添加,不用选择商品属性 -->
|
|
|
+ <view class="btn-group" v-else>
|
|
|
+ <button type="default" v-show="goodsCartNum(goods.id)" plain
|
|
|
+ class="btn reduce_btn" size="mini" hover-class="none"
|
|
|
+ @tap="handleReduceFromCart(goods)">
|
|
|
+ <view class="iconfont iconsami-select"></view>
|
|
|
+ </button>
|
|
|
+ <view class="number" v-show="goodsCartNum(goods.id)">
|
|
|
+ {{ goodsCartNum(goods.id) }}
|
|
|
+ </view>
|
|
|
+ <button type="primary" class="btn add_btn" size="min" hover-class="none"
|
|
|
+ @tap="handleAddToCart(goods)">
|
|
|
+ <view class="iconfont iconadd-select"></view>
|
|
|
+ </button>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <!-- 已经下架了 -->
|
|
|
+ <view v-else>
|
|
|
+ <view class="btn-group">
|
|
|
+ <button type="primary" disabled class="btn property_btn"
|
|
|
+ style="text-decoration: line-through;background-color: rgba(255, 148, 71,.6);" size="mini">
|
|
|
+ 已售空
|
|
|
+ </button>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </scroll-view>
|
|
|
+
|
|
|
+
|
|
|
+ <view class="">
|
|
|
+ <!-- 购物车栏 begin -->
|
|
|
+ <view class="cart-box" v-if="cart && cart.length">
|
|
|
+ <view class="mark" @tap="cartPopupVisible = !cartPopupVisible">
|
|
|
+ <image src="/pagesD/static/icon/cart1.png" class="cart-img"></image>
|
|
|
+ <view class="tag">{{ getCartGoodsNumber }}</view>
|
|
|
+ </view>
|
|
|
+ <view class="price" @tap="cartPopupVisible = !cartPopupVisible">¥{{ getCartGoodsPrice / 100 }}</view>
|
|
|
+ <view v-if="!appProperties.shopStatus"><button type="primary" class="pay-btn" disabled>商家休息中</button>
|
|
|
+ </view>
|
|
|
+ <view v-else-if="isBusinessTime">
|
|
|
+ <button :style="!disabledPay?'background-color: #FF9447;':''" type="primary" class="pay-btn" @tap="toPay()"
|
|
|
+ :disabled="disabledPay">{{ disabledPay ? `差${spread / 100}元起送` : '去结算' }}</button>
|
|
|
+ </view>
|
|
|
+ <view v-else><button type="primary" class="pay-btn" disabled>未在营业时段</button></view>
|
|
|
+ </view>
|
|
|
+ <!-- 购物车栏 end -->
|
|
|
+
|
|
|
+ <!-- 商品详情模态框 begin -->
|
|
|
+ <modal :show="goodDetailModalVisible" class="good-detail-modal" color="#5A5B5C" width="90%" custom
|
|
|
+ padding="0rpx" radius="12rpx">
|
|
|
+ <view class="cover">
|
|
|
+ <image v-if="currentGoods.image" :src="currentGoods.image" class="image"></image>
|
|
|
+ <view class="btn-group">
|
|
|
+ <image src="/pagesD/static/icon/close.png" @tap="closeGoodDetailModal"></image>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <scroll-view class="detail" scroll-y style="padding-bottom: 100px;">
|
|
|
+ <view class="wrapper">
|
|
|
+ <view class="basic">
|
|
|
+ <view class="name">{{ currentGoods.name }}</view>
|
|
|
+ <view class="tips">{{ currentGoods.description }}</view>
|
|
|
+ </view>
|
|
|
+ <!-- 商品的额外属性 -->
|
|
|
+ <view class="properties"
|
|
|
+ v-if="currentGoods.goodsPropertyVos && currentGoods.goodsPropertyVos.length">
|
|
|
+ <view class="property" v-for="(goodsPropertyVo, index) in currentGoods.goodsPropertyVos"
|
|
|
+ :key="index">
|
|
|
+ <view class="title">
|
|
|
+ <text class="name">
|
|
|
+ <text v-if="goodsPropertyVo.required" style="color: red">*</text>
|
|
|
+ {{ goodsPropertyVo.category }}
|
|
|
+ </text>
|
|
|
+ </view>
|
|
|
+ <view class="values">
|
|
|
+ <view class="value" v-for="(property, index2) in goodsPropertyVo.propertyList"
|
|
|
+ :key="index2" :class="{ default: property.isDefault }"
|
|
|
+ @tap="changePropertyDefault(index, index2)">
|
|
|
+ {{ property.propertyOption }}
|
|
|
+ {{ property.rebasePrice && property.rebasePrice >=0 ? '¥' + property.rebasePrice / 100 : property.extraPrice / 100 ? '¥' + property.extraPrice / 100 : '' }}
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </scroll-view>
|
|
|
+ <view class="action">
|
|
|
+ <!-- 价格和属性 -->
|
|
|
+ <view class="left">
|
|
|
+ <view class="price">¥{{ currentGoods.realPrice / 100 }}</view>
|
|
|
+ <view class="props" v-if="getGoodSelectedProps(currentGoods)">
|
|
|
+ {{ getGoodSelectedProps(currentGoods) }}
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <!-- 模态窗里面增减商品 -->
|
|
|
+ <view class="btn-group">
|
|
|
+ <button type="default" plain class="btn" size="mini" hover-class="none"
|
|
|
+ @tap="changeCurrentGoodsNumber(-1)">
|
|
|
+ <view class="iconfont iconsami-select"></view>
|
|
|
+ </button>
|
|
|
+ <view class="number">{{ currentGoods.number }}</view>
|
|
|
+ <button type="primary" class="btn" size="min" hover-class="none" @tap="changeCurrentGoodsNumber(1)">
|
|
|
+ <view class="iconfont iconadd-select"></view>
|
|
|
+ </button>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="add-to-cart-btn" @tap="addCurrentGoodsToCart()">
|
|
|
+ <view>确认</view>
|
|
|
+ </view>
|
|
|
+ </modal>
|
|
|
+ <!-- 商品详情模态框 end -->
|
|
|
+
|
|
|
+ <!-- 购物车详情popup -->
|
|
|
+
|
|
|
+ <u-popup z-index="99" v-model="cartPopupVisible" mode="bottom">
|
|
|
+ <view class="cart-popup">
|
|
|
+ <view class="top"><text @tap="handleCartClear">清空</text></view>
|
|
|
+ <scroll-view class="cart-list" scroll-y>
|
|
|
+ <view class="wrapper">
|
|
|
+ <view class="item" v-for="(goods, index) in cart" :key="index">
|
|
|
+ <view class="left">
|
|
|
+ <view class="name">{{ goods.name }}</view>
|
|
|
+ <view class="props">{{ getGoodSelectedProps(goods) }}</view>
|
|
|
+ </view>
|
|
|
+ <view class="center">
|
|
|
+ <text>¥{{ goods.realPrice / 100 }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="right">
|
|
|
+ <!-- 购物车里添加数量 -->
|
|
|
+ <button type="default" plain size="mini" class="btn" hover-class="none"
|
|
|
+ @tap="handleCartItemReduce(index)">
|
|
|
+ <view class="iconfont iconsami-select"></view>
|
|
|
+ </button>
|
|
|
+ <view class="number">{{ goods.number }}</view>
|
|
|
+ <!-- 购物车里减少数量 -->
|
|
|
+ <button type="primary" class="btn" size="min" hover-class="none"
|
|
|
+ @tap="handleCartItemAdd(index)">
|
|
|
+ <view class="iconfont iconadd-select"></view>
|
|
|
+ </button>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="item" v-if="takeType == takeTypeGlobal.package">
|
|
|
+ <view class="left">
|
|
|
+ <view class="name">包装费</view>
|
|
|
+ </view>
|
|
|
+ <view class="center">
|
|
|
+ <text>¥{{ appProperties.packingPrice / 100 }}</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="item" v-if="takeType == takeTypeGlobal.delivery">
|
|
|
+ <view class="left">
|
|
|
+ <view class="name">包装费</view>
|
|
|
+ </view>
|
|
|
+ <view class="center">
|
|
|
+ <text>¥{{ appProperties.packingPrice / 100 }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="left">
|
|
|
+ <view class="name">配送费</view>
|
|
|
+ </view>
|
|
|
+ <view class="center">
|
|
|
+ <text>¥{{ appProperties.sendingPrice / 100 }}</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </scroll-view>
|
|
|
+ </view>
|
|
|
+ </u-popup>
|
|
|
+ <!-- 购物车详情popup -->
|
|
|
+
|
|
|
+ <modal-checked @confirm="modalConfirm" ref="modalChecked" :list="checkList"></modal-checked>
|
|
|
+ <login ref="login" @signIn="signIn"></login>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+</template>
|
|
|
+<script>
|
|
|
+ import login from "../../comps/login.vue"
|
|
|
+ import modal from '../../comps/modal/modal.vue';
|
|
|
+ import modalChecked from "../../comps/modal-checked.vue"
|
|
|
+ import popupLayer from '../../comps/popup-layer/popup-layer.vue';
|
|
|
+ import global from "@/assets/http/global.js"
|
|
|
+ let _this = this
|
|
|
+ export default {
|
|
|
+ components: {
|
|
|
+ modal,
|
|
|
+ popupLayer,
|
|
|
+ login,
|
|
|
+ modalChecked
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ shopId:'',
|
|
|
+ address: {},
|
|
|
+ cart: [],
|
|
|
+ takeType: "店内堂食",
|
|
|
+ takeTypeGlobal:global.takeType,
|
|
|
+ appProperties: {
|
|
|
+ "shopName": "杨国福麻辣烫",
|
|
|
+ "sendingPrice": 100, // 商家配送费
|
|
|
+ "packingPrice": 100, // 包装费
|
|
|
+ "sendingNeedLeastPrice": 2000, // 起送需要的最低价格
|
|
|
+ "businessStartTime": '09:00:00', // 营业开始时间, 开始的点必须在结束之前
|
|
|
+ "businessEndTime": '22:00:00', // 营业结束时间
|
|
|
+ "shopStatus": true, // 商家营业状态
|
|
|
+ "shopNotice": ['10点到22点可以送餐~'], // 公告
|
|
|
+ },
|
|
|
+ goods: {},
|
|
|
+ currentCategoryName: '', // 默认分类
|
|
|
+ goodDetailModalVisible: false, //是否饮品详情模态框
|
|
|
+ currentGoods: {}, // 当前商品
|
|
|
+ selectedPropertyList: [], // 当前商品的属性
|
|
|
+ cartPopupVisible: false,
|
|
|
+
|
|
|
+ /**
|
|
|
+ * uview菜单begin
|
|
|
+ */
|
|
|
+ scrollTop: 0, //tab标题的滚动条位置
|
|
|
+ oldScrollTop: 0,
|
|
|
+ current: 0, // 预设当前项的值
|
|
|
+ menuHeight: 0, // 左边菜单的高度
|
|
|
+ menuItemHeight: 0, // 左边菜单item的高度
|
|
|
+ itemId: '', // 栏目右边scroll-view用于滚动的id
|
|
|
+ goods: [],
|
|
|
+ menuItemPos: [],
|
|
|
+ arr: [],
|
|
|
+ scrollRightTop: 0, // 右边栏目scroll-view的滚动条高度
|
|
|
+ timer: null, // 定时器
|
|
|
+ /**
|
|
|
+ * u-view菜单end
|
|
|
+ */
|
|
|
+ checkList:[
|
|
|
+ {
|
|
|
+ name:global.takeType.dine_in,
|
|
|
+ icon:"/pagesD/static/icon/order.png",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name:global.takeType.package,
|
|
|
+ icon:"/pagesD/static/icon/pickup.png",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name:global.takeType.delivery,
|
|
|
+ icon:"/pagesD/static/icon/delivery2.png",
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ },
|
|
|
+ onLoad(options) {
|
|
|
+ _this = this
|
|
|
+ if (!options.shopId) {
|
|
|
+ this.$dialog.showModalAndBack('系统错误')
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.shopId=options.shopId
|
|
|
+ this.init()
|
|
|
+
|
|
|
+ },
|
|
|
+ onShow() {
|
|
|
+ this.address = this.$util.getBackParams('addressData')
|
|
|
+ if (this.$isEmpty(this.address)) {
|
|
|
+ this.fetchAddress()
|
|
|
+ }
|
|
|
+ },
|
|
|
+ onReady() {
|
|
|
+ this.getMenuItemTop()
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ isBusinessTime:{
|
|
|
+ get(){
|
|
|
+ return this.timeRange(this.appProperties.businessStartTime,this.appProperties.businessEndTime)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 计算单个饮品添加到购物车的数量
|
|
|
+ goodsCartNum() {
|
|
|
+ return id =>
|
|
|
+ this.cart.reduce((acc, cur) => {
|
|
|
+ if (cur.id === id) {
|
|
|
+ return (acc += cur.number);
|
|
|
+ }
|
|
|
+ return acc;
|
|
|
+ }, 0);
|
|
|
+ },
|
|
|
+ // 计算该类商品的购买总数
|
|
|
+ menuCartNum() {
|
|
|
+ return goodsCategoryName =>
|
|
|
+ this.cart.reduce((acc, cur) => {
|
|
|
+ if (cur.goodsCategoryName === goodsCategoryName) {
|
|
|
+ return (acc += cur.number);
|
|
|
+ }
|
|
|
+ return acc;
|
|
|
+ }, 0);
|
|
|
+ },
|
|
|
+ // 计算购物车总数
|
|
|
+ getCartGoodsNumber() {
|
|
|
+ return this.cart.reduce((acc, cur) => acc + cur.number, 0);
|
|
|
+ },
|
|
|
+ // 计算购物车总价,
|
|
|
+ getCartGoodsPrice() {
|
|
|
+ let totalPrice = 0;
|
|
|
+ this.cart.forEach(goods => {
|
|
|
+ totalPrice += goods.realPrice * goods.number;
|
|
|
+ });
|
|
|
+ //如果是到店自取,要计算包装费
|
|
|
+ if (this.takeType == this.takeTypeGlobal.package) {
|
|
|
+ totalPrice += this.appProperties.packingPrice
|
|
|
+ }
|
|
|
+ //如果是商家配送,要计算配送费和包装费
|
|
|
+ if (this.takeType == this.takeTypeGlobal.delivery) {
|
|
|
+ totalPrice += this.appProperties.packingPrice + this.appProperties.sendingPrice;
|
|
|
+ }
|
|
|
+ return totalPrice;
|
|
|
+ }, // 是否达到起送价
|
|
|
+ disabledPay() {
|
|
|
+ return this.takeType == this.takeTypeGlobal.delivery && this.getCartGoodsPrice < this.appProperties
|
|
|
+ .sendingNeedLeastPrice ? true : false;
|
|
|
+ }, // 差多少元起送
|
|
|
+ spread() {
|
|
|
+ if (this.takeType != this.takeTypeGlobal.delivery) return;
|
|
|
+ return this.appProperties.sendingNeedLeastPrice - this.getCartGoodsPrice;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ cart: {
|
|
|
+ handler: (newV, oldV) => {
|
|
|
+ _this.putCart()
|
|
|
+ },
|
|
|
+ deep: true,
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ modalCheckedShow(){
|
|
|
+ this.$refs.modalChecked.showModal()
|
|
|
+ },
|
|
|
+ timeRange(beginTime, endTime) {//判断是否在缴费查询时间
|
|
|
+ var strb = beginTime.split (":");
|
|
|
+ if (strb.length != 3) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ var stre = endTime.split (":");
|
|
|
+ if (stre.length != 3) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ var b = new Date ();
|
|
|
+ var e = new Date ();
|
|
|
+ var n = new Date ();
|
|
|
+
|
|
|
+ if (parseInt(strb[0])>=parseInt(stre[0])) {
|
|
|
+ b.setDate(b.getDate() - 1)
|
|
|
+ }
|
|
|
+
|
|
|
+ console.log(b,",,,");
|
|
|
+ console.log(e,",,,");
|
|
|
+ console.log(n,",,,");
|
|
|
+
|
|
|
+ b.setHours (strb[0]);
|
|
|
+ b.setMinutes (strb[1]);
|
|
|
+ b.setSeconds(strb[2]);
|
|
|
+ e.setHours (stre[0]);
|
|
|
+ e.setMinutes (stre[1]);
|
|
|
+ e.setSeconds(stre[2]);
|
|
|
+
|
|
|
+ if (n.getTime () - b.getTime () > 0 && n.getTime () - e.getTime () < 0) {
|
|
|
+ return true;
|
|
|
+ } else {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ //页面初始化
|
|
|
+ async init() {
|
|
|
+ this.initMenu()
|
|
|
+ this.initCart()
|
|
|
+ },
|
|
|
+ initMenu(){
|
|
|
+ this.$api.goods.menu({
|
|
|
+ shopId: this.shopId
|
|
|
+ }).then(res => {
|
|
|
+ this.goods = res.data;
|
|
|
+ })
|
|
|
+ },
|
|
|
+ //初始化购物车
|
|
|
+ initCart() {
|
|
|
+ this.cartKey = this.$global.cart_prefix + this.shopId
|
|
|
+
|
|
|
+ if (!this.$isEmpty(this.$cache.get(this.cartKey))) {
|
|
|
+ this.cart = this.$cache.get(this.cartKey)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ putCart() {
|
|
|
+ this.$cache.put(this.cartKey, this.cart)
|
|
|
+ },
|
|
|
+ modalConfirm(index){
|
|
|
+ this.takeType=this.checkList[index].name
|
|
|
+ if (this.takeType==this.takeTypeGlobal.delivery) {
|
|
|
+ this.takeout()
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 选择商家配送的方式下单
|
|
|
+ takeout() {
|
|
|
+ if (this.$isEmpty(this.vuex_userId)) {
|
|
|
+ this.showLogin()
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (this.$isEmpty(this.address) && this.$isNotEmpty(this.vuex_userId)) {
|
|
|
+ uni.navigateTo({
|
|
|
+ url:"../address/address"
|
|
|
+ })
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 显示当前商品的详情信息
|
|
|
+ showGoodDetailModal(currentGoods) {
|
|
|
+ currentGoods.number = 1;
|
|
|
+ currentGoods.realPrice = this.getGoodsRealPrice(currentGoods);
|
|
|
+ currentGoods.propertyStr = this.getGoodSelectedProps(currentGoods);
|
|
|
+ this.currentGoods = JSON.parse(JSON.stringify(currentGoods)); // 深拷贝
|
|
|
+
|
|
|
+ this.goodDetailModalVisible = true;
|
|
|
+ this.selectedPropertyList = [];
|
|
|
+ console.log('显示当前商品的详情信息', this.currentGoods);
|
|
|
+ },
|
|
|
+ // 获取商品具体价格,如大杯商品,小杯商品价格不同
|
|
|
+ getGoodsRealPrice(goods) {
|
|
|
+ console.log(goods);
|
|
|
+ let realPrice = goods.realPrice;
|
|
|
+ if (goods.goodsPropertyVos && goods.goodsPropertyVos.length) {
|
|
|
+ let vos = goods.goodsPropertyVos;
|
|
|
+ for (let i = 0; i < vos.length; i++) {
|
|
|
+ let propertyList = vos[i].propertyList;
|
|
|
+ for (let j = 0; j < propertyList.length; j++) {
|
|
|
+ if (propertyList[j].isDefault && propertyList[j].realPrice) {
|
|
|
+ realPrice = propertyList[j].realPrice;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return realPrice;
|
|
|
+ },
|
|
|
+ // 显示当前商品的详情信息
|
|
|
+ showGoodDetailModal(currentGoods) {
|
|
|
+ currentGoods.number = 1;
|
|
|
+ currentGoods.realPrice = this.getGoodsRealPrice(currentGoods);
|
|
|
+ currentGoods.propertyStr = this.getGoodSelectedProps(currentGoods);
|
|
|
+ this.currentGoods = JSON.parse(JSON.stringify(currentGoods)); // 深拷贝
|
|
|
+
|
|
|
+ this.goodDetailModalVisible = true;
|
|
|
+ this.selectedPropertyList = [];
|
|
|
+ console.log('显示当前商品的详情信息', this.currentGoods);
|
|
|
+ },
|
|
|
+ closeGoodDetailModal() {
|
|
|
+ // 关闭饮品详情模态框
|
|
|
+ this.goodDetailModalVisible = false;
|
|
|
+ },
|
|
|
+ // 改变商品的某个默认属性值 要区分必选和多选的属性
|
|
|
+ changePropertyDefault(categoryIndex, propertyIndex) {
|
|
|
+ let propertyCategory = this.currentGoods.goodsPropertyVos[categoryIndex].category;
|
|
|
+ let propertyList = this.currentGoods.goodsPropertyVos[categoryIndex].propertyList;
|
|
|
+ if (propertyCategory != '加料') {
|
|
|
+ // 必须选一个
|
|
|
+ propertyList.forEach(property => (property.isDefault = false)); // 重置所有默认选择状态重新选择
|
|
|
+ propertyList[propertyIndex].isDefault = true;
|
|
|
+ if (propertyCategory == '大小') {
|
|
|
+ this.currentGoods.realPrice = this.currentGoods.realPrice - this.currentGoods.defaultPrice +
|
|
|
+ propertyList[propertyIndex].rebasePrice;
|
|
|
+ this.currentGoods.defaultPrice = propertyList[propertyIndex].rebasePrice;
|
|
|
+ this.currentGoods.number = 1;
|
|
|
+ this.currentGoods.propertyStr = this.getGoodSelectedProps(this.currentGoods);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 可选项 加料或减料
|
|
|
+ if (propertyList[propertyIndex].isDefault) {
|
|
|
+ this.currentGoods.realPrice -= propertyList[propertyIndex].extraPrice;
|
|
|
+ propertyList[propertyIndex].isDefault = false;
|
|
|
+ } else {
|
|
|
+ this.currentGoods.realPrice += propertyList[propertyIndex].extraPrice;
|
|
|
+ propertyList[propertyIndex].isDefault = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 计算当前饮品所选属性,空格隔开
|
|
|
+ getGoodSelectedProps(goods) {
|
|
|
+ if (goods.goodsPropertyVos) {
|
|
|
+ let propertyStr = '';
|
|
|
+ goods.goodsPropertyVos.forEach(goodsPropertyVo => {
|
|
|
+ goodsPropertyVo.propertyList.forEach(property => {
|
|
|
+ if (property.isDefault) {
|
|
|
+ propertyStr += property.propertyOption + ' ';
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+ return propertyStr;
|
|
|
+ }
|
|
|
+ return '';
|
|
|
+ },
|
|
|
+ // 改变当前商品数量
|
|
|
+ changeCurrentGoodsNumber(number) {
|
|
|
+ this.currentGoods.number += number;
|
|
|
+ if (this.currentGoods.number < 0) {
|
|
|
+ this.currentGoods.number = 0;
|
|
|
+ } else if (this.currentGoods.number >= 100) {
|
|
|
+ this.currentGoods.number = 100;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 将当前商品加入到购物车
|
|
|
+ addCurrentGoodsToCart() {
|
|
|
+ if (this.currentGoods && this.currentGoods.number) {
|
|
|
+ this.handleAddToCart(this.currentGoods);
|
|
|
+ }
|
|
|
+ this.closeGoodDetailModal();
|
|
|
+ },
|
|
|
+ // 减少购物车里的商品数量, goodsId和propertyStr去比较
|
|
|
+ handleReduceFromCart(goods) {
|
|
|
+ let propertyStr = this.getGoodSelectedProps(goods);
|
|
|
+ let cart = this.cart;
|
|
|
+ for (let i = cart.length - 1; i >= 0; i--) {
|
|
|
+ if (cart[i].id == goods.id && cart[i].propertyStr == propertyStr) {
|
|
|
+ if (cart[i].number <= 1) cart.splice(i, 1);
|
|
|
+ else cart[i].number -= 1;
|
|
|
+
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 添加到购物车
|
|
|
+ handleAddToCart(goods) {
|
|
|
+ let propertyStr = this.getGoodSelectedProps(goods);
|
|
|
+ goods.propertyStr = propertyStr;
|
|
|
+ let cart = this.cart;
|
|
|
+ for (let i = cart.length - 1; i >= 0; i--) {
|
|
|
+ if (cart[i].id == goods.id && cart[i].propertyStr == propertyStr) {
|
|
|
+ cart[i].number++;
|
|
|
+
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 购物车里不存在
|
|
|
+ if (!goods.number) goods.number = 1;
|
|
|
+ this.cart.push(JSON.parse(JSON.stringify(goods)));
|
|
|
+ },
|
|
|
+ // 清空购物车
|
|
|
+ handleCartClear() {
|
|
|
+ let that = this;
|
|
|
+ uni.showModal({
|
|
|
+ title: '提示',
|
|
|
+ content: '确定清空购物车么',
|
|
|
+ success: ({
|
|
|
+ confirm
|
|
|
+ }) => {
|
|
|
+ if (confirm) {
|
|
|
+ that.cartPopupVisible = false;
|
|
|
+ this.cart = []
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ // 在购物车里操作商品数量
|
|
|
+ handleCartItemAdd(index) {
|
|
|
+ this.cart[index].number += 1;
|
|
|
+
|
|
|
+ },
|
|
|
+ handleCartItemReduce(index) {
|
|
|
+ if (this.cart[index].number === 1) {
|
|
|
+ this.cart.splice(index, 1);
|
|
|
+ } else {
|
|
|
+ this.cart[index].number -= 1;
|
|
|
+ }
|
|
|
+ if (!this.cart.length) {
|
|
|
+ this.cartPopupVisible = false;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ toPay() {
|
|
|
+ this.cartPopupVisible = false;
|
|
|
+ if (this.$isEmpty(this.vuex_userId)) {
|
|
|
+ this.showLogin()
|
|
|
+ return
|
|
|
+ }
|
|
|
+ let orderInfo={
|
|
|
+ shopId:this.shopId,
|
|
|
+ cart:this.cart,
|
|
|
+ cartKey:this.cartKey,
|
|
|
+ takeType:this.takeType,
|
|
|
+ address:this.address,
|
|
|
+ store:this.appProperties,
|
|
|
+ address:this.address
|
|
|
+ }
|
|
|
+ this.$u.vuex('vuex_orderInfo',orderInfo)
|
|
|
+ uni.navigateTo({
|
|
|
+ url: '../pay/pay'
|
|
|
+ })
|
|
|
+ },
|
|
|
+ fetchAddress(){
|
|
|
+ if (this.$isEmpty(this.vuex_userId)) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ let params={
|
|
|
+ userId:this.vuex_userId,
|
|
|
+ isDefault:true
|
|
|
+ }
|
|
|
+ this.$api.address.list(params).then(res=>{
|
|
|
+ this.address=res.data.records[0]
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // 登录 begin
|
|
|
+ showLogin(){
|
|
|
+ this.$refs.login.show()
|
|
|
+ },
|
|
|
+ showPhoneModal(){
|
|
|
+ this.$refs.login.showPhoneModal()
|
|
|
+ },
|
|
|
+ signIn(resp){
|
|
|
+ //获取手机号
|
|
|
+ if (this.$isEmpty(this.vuex_phone)) {
|
|
|
+ this.showPhoneModal()
|
|
|
+ }
|
|
|
+ this.$u.toast('登录成功')
|
|
|
+
|
|
|
+ this.fetchAddress()
|
|
|
+ },
|
|
|
+ async login(e){
|
|
|
+ if (this.$isEmpty(this.vuex_userId)) {
|
|
|
+ this.showLogin()
|
|
|
+ return
|
|
|
+ }else{
|
|
|
+ this.userInfo=this.$cache.get('userInfo')
|
|
|
+ }
|
|
|
+
|
|
|
+ //获取手机号
|
|
|
+ if (this.$isEmpty(this.vuex_phone)) {
|
|
|
+ this.showPhoneModal()
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 登录 end
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * u-view 菜单栏 begin
|
|
|
+ *
|
|
|
+ */
|
|
|
+ async swichMenu(index) {
|
|
|
+ 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);
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // 获取一个目标元素的高度
|
|
|
+ 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();
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // 观测元素相交状态
|
|
|
+ async observer() {
|
|
|
+ this.goods.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('u-tab-item', 'menuItemHeight');
|
|
|
+ }
|
|
|
+ // 将菜单活动item垂直居中
|
|
|
+ this.scrollTop = index * this.menuItemHeight + this.menuItemHeight / 2 - this.menuHeight / 2;
|
|
|
+ },
|
|
|
+ // 获取右边菜单每个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((rect) => {
|
|
|
+ // 这里减去rects[0].top,是因为第一项顶部可能不是贴到导航栏(比如有个搜索框的情况)
|
|
|
+ this.arr.push(rect.top - rects[0].top);
|
|
|
+ resolve();
|
|
|
+ })
|
|
|
+ }).exec()
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // 右边菜单滚动
|
|
|
+ async rightScroll(e) {
|
|
|
+ this.oldScrollTop = e.detail.scrollTop;
|
|
|
+ if (this.arr.length == 0) {
|
|
|
+ await this.getMenuItemTop();
|
|
|
+ }
|
|
|
+ if (this.timer) return;
|
|
|
+ if (!this.menuHeight) {
|
|
|
+ await this.getElRect('menu-scroll-view', 'menuHeight');
|
|
|
+ }
|
|
|
+ setTimeout(() => { // 节流
|
|
|
+ this.timer = null;
|
|
|
+ // 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)
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * u-view 菜单栏 end
|
|
|
+ */
|
|
|
+ }
|
|
|
+ }
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+ .nav {
|
|
|
+ width: 100%;
|
|
|
+ flex-shrink: 0;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+
|
|
|
+ .header {
|
|
|
+ width: 100%;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ padding: 20rpx;
|
|
|
+ background-color: #ffffff;
|
|
|
+ height: 100rpx;
|
|
|
+
|
|
|
+ .left {
|
|
|
+ flex: 1;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+
|
|
|
+ .store-name {
|
|
|
+ display: flex;
|
|
|
+ justify-content: flex-start;
|
|
|
+ align-items: center;
|
|
|
+ font-size: $font-size-lg;
|
|
|
+ margin-bottom: 10rpx;
|
|
|
+
|
|
|
+ .iconfont {
|
|
|
+ margin-left: 10rpx;
|
|
|
+ line-height: 100%;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .store-location {
|
|
|
+ display: flex;
|
|
|
+ justify-content: flex-start;
|
|
|
+ align-items: center;
|
|
|
+ color: $text-color-assist;
|
|
|
+ font-size: $font-size-sm;
|
|
|
+
|
|
|
+ .iconfont {
|
|
|
+ vertical-align: middle;
|
|
|
+ display: table-cell;
|
|
|
+ color: $color-primary;
|
|
|
+ line-height: 100%;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .right {
|
|
|
+ background-color: $bg-color-grey;
|
|
|
+ border-radius: 38rpx;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ font-size: $font-size-sm;
|
|
|
+ padding: 0 38rpx;
|
|
|
+ color: $text-color-assist;
|
|
|
+
|
|
|
+ .dinein,
|
|
|
+ .takeout {
|
|
|
+ position: relative;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ &.active {
|
|
|
+ padding: 14rpx 38rpx;
|
|
|
+ color: #ffffff;
|
|
|
+ background-color: $color-primary;
|
|
|
+ border-radius: 38rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .takeout {
|
|
|
+ margin-left: 20rpx;
|
|
|
+ height: 100%;
|
|
|
+ flex: 1;
|
|
|
+ padding: 14rpx 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .dinein.active {
|
|
|
+ margin-left: -38rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .takeout.active {
|
|
|
+ margin-right: -38rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .coupon {
|
|
|
+ flex: 1;
|
|
|
+ width: 100%;
|
|
|
+ font-size: $font-size-base;
|
|
|
+ color: $color-primary;
|
|
|
+ padding: 0 20rpx;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ overflow: hidden;
|
|
|
+
|
|
|
+ .title {
|
|
|
+ flex: 1;
|
|
|
+ margin-left: 10rpx;
|
|
|
+ overflow: hidden;
|
|
|
+ white-space: nowrap;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ }
|
|
|
+
|
|
|
+ .iconfont {
|
|
|
+ line-height: 100%;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .item-container {
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: wrap;
|
|
|
+
|
|
|
+ .thumb-box {
|
|
|
+ width: 100%;
|
|
|
+ display: flex;
|
|
|
+ padding: 20rpx 0;
|
|
|
+ border-bottom: 1rpx solid #EEEEEE;
|
|
|
+
|
|
|
+ .item-menu-image {
|
|
|
+ width: 160rpx;
|
|
|
+ height: 160rpx;
|
|
|
+ margin-right: 20rpx;
|
|
|
+ border-radius: 8rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .item-content{
|
|
|
+ width: calc(100% - 180rpx);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ .name {
|
|
|
+ font-size: $font-size-base;
|
|
|
+ margin-bottom: 10rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .tips {
|
|
|
+ width: 100%;
|
|
|
+ height: 40rpx;
|
|
|
+ line-height: 40rpx;
|
|
|
+ overflow: hidden;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ white-space: nowrap;
|
|
|
+ font-size: $font-size-sm;
|
|
|
+ color: $text-color-assist;
|
|
|
+ margin-bottom: 10rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .price_and_action {
|
|
|
+ width: 100%;
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ margin-top: 30rpx;
|
|
|
+
|
|
|
+ .price {
|
|
|
+ font-size: $font-size-base;
|
|
|
+ font-weight: 600;
|
|
|
+ }
|
|
|
+
|
|
|
+ .btn-group {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ position: relative;
|
|
|
+
|
|
|
+ .btn {
|
|
|
+ background-color: $base-color;
|
|
|
+ padding: 0 20rpx;
|
|
|
+ box-sizing: border-box;
|
|
|
+ font-size: $font-size-sm;
|
|
|
+ height: 44rpx;
|
|
|
+ line-height: 44rpx;
|
|
|
+
|
|
|
+ &.property_btn {
|
|
|
+ border-radius: 24rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ &.add_btn,
|
|
|
+ &.reduce_btn {
|
|
|
+ color: #FFFFFF;
|
|
|
+ border: $base-color;
|
|
|
+ padding: 0;
|
|
|
+ width: 44rpx;
|
|
|
+ border-radius: 44rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .dot {
|
|
|
+ position: absolute;
|
|
|
+ background-color: #ffffff;
|
|
|
+ border: 1px solid $color-primary;
|
|
|
+ color: $color-primary;
|
|
|
+ font-size: $font-size-sm;
|
|
|
+ width: 36rpx;
|
|
|
+ height: 36rpx;
|
|
|
+ line-height: 36rpx;
|
|
|
+ text-align: center;
|
|
|
+ border-radius: 100%;
|
|
|
+ right: -12rpx;
|
|
|
+ top: -10rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .number {
|
|
|
+ width: 44rpx;
|
|
|
+ height: 44rpx;
|
|
|
+ line-height: 44rpx;
|
|
|
+ text-align: center;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .thumb-box:last-child {
|
|
|
+ border: none;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .good-detail-modal {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+
|
|
|
+ .cover {
|
|
|
+ height: 320rpx;
|
|
|
+ padding: 30rpx 0;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ position: relative;
|
|
|
+
|
|
|
+ .image {
|
|
|
+ width: 260rpx;
|
|
|
+ height: 260rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .btn-group {
|
|
|
+ position: absolute;
|
|
|
+ right: 10rpx;
|
|
|
+ top: 30rpx;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-around;
|
|
|
+
|
|
|
+ image {
|
|
|
+ width: 80rpx;
|
|
|
+ height: 80rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .detail {
|
|
|
+ width: 100%;
|
|
|
+ min-height: 1vh;
|
|
|
+ max-height: calc(90vh - 320rpx - 80rpx - 330rpx);
|
|
|
+
|
|
|
+ .wrapper {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ overflow: hidden;
|
|
|
+
|
|
|
+ .basic {
|
|
|
+ padding: 0 20rpx 30rpx;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+
|
|
|
+ .name {
|
|
|
+ font-size: $font-size-base;
|
|
|
+ color: $text-color-base;
|
|
|
+ margin-bottom: 10rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .tips {
|
|
|
+ font-size: $font-size-sm;
|
|
|
+ color: $text-color-grey;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .properties {
|
|
|
+ width: 100%;
|
|
|
+ border-top: 2rpx solid $bg-color-grey;
|
|
|
+ padding: 10rpx 30rpx 0;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+
|
|
|
+ .property {
|
|
|
+ width: 100%;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ margin-bottom: 20rpx;
|
|
|
+ padding-bottom: -16rpx;
|
|
|
+
|
|
|
+ .title {
|
|
|
+ width: 100%;
|
|
|
+ display: flex;
|
|
|
+ justify-content: flex-start;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 20rpx;
|
|
|
+
|
|
|
+ .name {
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: $text-color-base;
|
|
|
+ margin-right: 20rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .desc {
|
|
|
+ flex: 1;
|
|
|
+ font-size: $font-size-sm;
|
|
|
+ color: $color-primary;
|
|
|
+ overflow: hidden;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ white-space: nowrap;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .values {
|
|
|
+ width: 100%;
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: wrap;
|
|
|
+
|
|
|
+ .value {
|
|
|
+ border-radius: 8rpx;
|
|
|
+ background-color: $bg-color-grey;
|
|
|
+ padding: 16rpx 30rpx;
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: $text-color-assist;
|
|
|
+ margin-right: 16rpx;
|
|
|
+ margin-bottom: 16rpx;
|
|
|
+
|
|
|
+ &.default {
|
|
|
+ background-color: $color-primary;
|
|
|
+ color: $text-color-white;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .action {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ background-color: $bg-color-grey;
|
|
|
+ height: 120rpx;
|
|
|
+ padding: 0 26rpx;
|
|
|
+
|
|
|
+ .left {
|
|
|
+ flex: 1;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ justify-content: center;
|
|
|
+ margin-right: 20rpx;
|
|
|
+ overflow: hidden;
|
|
|
+
|
|
|
+ .price {
|
|
|
+ font-size: $font-size-lg;
|
|
|
+ color: $text-color-base;
|
|
|
+ }
|
|
|
+
|
|
|
+ .props {
|
|
|
+ color: $text-color-assist;
|
|
|
+ font-size: 24rpx;
|
|
|
+ width: 100%;
|
|
|
+ overflow: hidden;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ white-space: nowrap;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .btn-group {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-around;
|
|
|
+
|
|
|
+ .number {
|
|
|
+ font-size: $font-size-base;
|
|
|
+ width: 44rpx;
|
|
|
+ height: 44rpx;
|
|
|
+ line-height: 44rpx;
|
|
|
+ text-align: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ .btn {
|
|
|
+ padding: 0;
|
|
|
+ font-size: $font-size-base;
|
|
|
+ width: 44rpx;
|
|
|
+ height: 44rpx;
|
|
|
+ line-height: 44rpx;
|
|
|
+ border-radius: 100%;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .add-to-cart-btn {
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ background-color: $color-primary;
|
|
|
+ color: $text-color-white;
|
|
|
+ font-size: $font-size-base;
|
|
|
+ height: 80rpx;
|
|
|
+ border-radius: 0 0 12rpx 12rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .cart-popup {
|
|
|
+ .top {
|
|
|
+ background-color: #f3ede3;
|
|
|
+ color: #ff9447;
|
|
|
+ padding: 10rpx 30rpx;
|
|
|
+ font-size: 24rpx;
|
|
|
+ text-align: right;
|
|
|
+ }
|
|
|
+
|
|
|
+ .cart-list {
|
|
|
+ background-color: #FFFFFF;
|
|
|
+ width: 100%;
|
|
|
+ overflow: hidden;
|
|
|
+ min-height: 30vh;
|
|
|
+ max-height: 70vh;
|
|
|
+ margin-bottom: 30rpx;
|
|
|
+
|
|
|
+ .wrapper {
|
|
|
+ height: 100%;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ padding: 0 30rpx;
|
|
|
+ margin-bottom: 156rpx;
|
|
|
+
|
|
|
+ .item {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ padding: 30rpx 0;
|
|
|
+ position: relative;
|
|
|
+
|
|
|
+ &::after {
|
|
|
+ content: ' ';
|
|
|
+ position: absolute;
|
|
|
+ bottom: 0;
|
|
|
+ left: 0;
|
|
|
+ width: 100%;
|
|
|
+ background-color: $border-color;
|
|
|
+ height: 2rpx;
|
|
|
+ transform: scaleY(.6);
|
|
|
+ }
|
|
|
+
|
|
|
+ .left {
|
|
|
+ flex: 1;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ overflow: hidden;
|
|
|
+ margin-right: 30rpx;
|
|
|
+
|
|
|
+ .name {
|
|
|
+ font-size: $font-size-sm;
|
|
|
+ color: $text-color-base;
|
|
|
+ }
|
|
|
+
|
|
|
+ .props {
|
|
|
+ color: $text-color-assist;
|
|
|
+ font-size: 24rpx;
|
|
|
+ overflow: hidden;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ white-space: nowrap;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .center {
|
|
|
+ margin-right: 120rpx;
|
|
|
+ font-size: $font-size-base;
|
|
|
+ }
|
|
|
+
|
|
|
+ .right {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+
|
|
|
+ .btn {
|
|
|
+ width: 46rpx;
|
|
|
+ height: 46rpx;
|
|
|
+ border-radius: 100%;
|
|
|
+ padding: 0;
|
|
|
+ text-align: center;
|
|
|
+ line-height: 46rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .number {
|
|
|
+ font-size: $font-size-base;
|
|
|
+ width: 46rpx;
|
|
|
+ height: 46rpx;
|
|
|
+ text-align: center;
|
|
|
+ line-height: 46rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ .cart-box {
|
|
|
+ position: fixed;
|
|
|
+ bottom: 30rpx;
|
|
|
+ left: 30rpx;
|
|
|
+ right: 30rpx;
|
|
|
+ height: 96rpx;
|
|
|
+ border-radius: 48rpx;
|
|
|
+ box-shadow: 0 0 20rpx rgba(0, 0, 0, 0.2);
|
|
|
+ background-color: #FFFFFF;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ z-index: 999;
|
|
|
+
|
|
|
+ .cart-img {
|
|
|
+ width: 96rpx;
|
|
|
+ height: 96rpx;
|
|
|
+ position: relative;
|
|
|
+ margin-top: -48rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .pay-btn {
|
|
|
+ height: 100%;
|
|
|
+ padding: 0 30rpx;
|
|
|
+ color: #FFFFFF;
|
|
|
+ border-radius: 0 50rpx 50rpx 0;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ background-color: rgba(255, 148, 71,.6);
|
|
|
+ font-size: $font-size-base;
|
|
|
+ }
|
|
|
+
|
|
|
+ .mark {
|
|
|
+ padding-left: 46rpx;
|
|
|
+ margin-right: 30rpx;
|
|
|
+ position: relative;
|
|
|
+
|
|
|
+ .tag {
|
|
|
+ background-color: #FFFFFF;
|
|
|
+ color: $base-color;
|
|
|
+ border: 1rpx solid $base-color;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ font-size: $font-size-sm;
|
|
|
+ position: absolute;
|
|
|
+ right: -10rpx;
|
|
|
+ top: -50rpx;
|
|
|
+ border-radius: 100%;
|
|
|
+ padding: 4rpx;
|
|
|
+ width: 40rpx;
|
|
|
+ height: 40rpx;
|
|
|
+ opacity: .9;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .price {
|
|
|
+ flex: 1;
|
|
|
+ color: $text-color-base;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ .u-wrap {
|
|
|
+ height: calc(100vh);
|
|
|
+ /* #ifdef H5 */
|
|
|
+ height: calc(100vh - var(--window-top));
|
|
|
+ /* #endif */
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ width: 100%;
|
|
|
+ }
|
|
|
+
|
|
|
+ .u-search-box {
|
|
|
+ background-color: #FFFFFF;
|
|
|
+ }
|
|
|
+
|
|
|
+ .u-menu-wrap {
|
|
|
+ width: 100%;
|
|
|
+ flex: 1;
|
|
|
+ display: flex;
|
|
|
+ overflow: hidden;
|
|
|
+ }
|
|
|
+
|
|
|
+ .u-search-inner {
|
|
|
+ background-color: rgb(234, 234, 234);
|
|
|
+ border-radius: 100rpx;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ padding: 10rpx 16rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .u-search-text {
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: $u-tips-color;
|
|
|
+ margin-left: 10rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .u-tab-view {
|
|
|
+ width: 200rpx;
|
|
|
+ height: 100%;
|
|
|
+ }
|
|
|
+
|
|
|
+ .u-tab-item {
|
|
|
+ height: 110rpx;
|
|
|
+ background: #f6f6f6;
|
|
|
+ box-sizing: border-box;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: #444;
|
|
|
+ font-weight: 400;
|
|
|
+ line-height: 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ .u-tab-item-active {
|
|
|
+ position: relative;
|
|
|
+ color: #000;
|
|
|
+ font-size: 30rpx;
|
|
|
+ font-weight: 600;
|
|
|
+ background: #fff;
|
|
|
+ }
|
|
|
+
|
|
|
+ .u-tab-item-active::before {
|
|
|
+ content: "";
|
|
|
+ position: absolute;
|
|
|
+ border-left: 4px solid $base-color;
|
|
|
+ height: 32rpx;
|
|
|
+ left: 0;
|
|
|
+ top: 39rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .u-tab-view {
|
|
|
+ height: 100%;
|
|
|
+ }
|
|
|
+
|
|
|
+ .right-box {
|
|
|
+ background-color: rgb(250, 250, 250);
|
|
|
+ }
|
|
|
+
|
|
|
+ .page-view {
|
|
|
+ margin-bottom: 150rpx;
|
|
|
+ background-color: #FFFFFF;
|
|
|
+ padding: 16rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .class-item {
|
|
|
+ margin-bottom: 30rpx;
|
|
|
+ background-color: #fff;
|
|
|
+ border-radius: 8rpx;
|
|
|
+ }
|
|
|
+ .class-item:first-child{
|
|
|
+ margin-bottom: 0rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .class-item:last-child {
|
|
|
+ min-height: 100vh;
|
|
|
+ }
|
|
|
+
|
|
|
+ .item-title {
|
|
|
+ padding: 20rpx;
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: $u-main-color;
|
|
|
+ font-weight: bold;
|
|
|
+ }
|
|
|
+</style>
|