fix(code): 修正代码错误及不严谨的地方

This commit is contained in:
2025-12-23 16:59:14 +08:00
parent 68ecdd6e3c
commit 5588165f2c
91 changed files with 8364 additions and 8996 deletions

View File

@@ -1,638 +0,0 @@
<template>
<view class="order-container" :class="{ 'safe-area': isIphoneX }">
<!-- #ifdef MP-WEIXIN -->
<view class="payment-navbar" :style="{ 'padding-top': menuButtonBounding.top + 'px', height: menuButtonBounding.height + 'px' }">
<view class="nav-wrap">
<text class="iconfont icon-back_light" @click="back"></text>
<view class="navbar-title">确认订单</view>
</view>
</view>
<view class="payment-navbar-block" :style="{ height: menuButtonBounding.bottom + 'px' }"></view>
<!-- #endif -->
<scroll-view scroll-y="true" class="order-scroll-container">
<view class="payment-navbar-block"></view>
<template v-if="paymentData">
<template v-if="paymentData.is_virtual">
<!-- 虚拟商品联系方式 -->
<view class="mobile-wrap">
<view class="tips color-base-text">
<text class="iconfont icongantanhao"></text>
购买虚拟类商品需填写手机号方便商家与您联系
</view>
<view class="form-group">
<text class="icon">
<image :src="$util.img('public/uniapp/order/icon-mobile.png')" mode="widthFix"></image>
</text>
<text class="text">手机号码</text>
<input type="number" maxlength="11" placeholder="请输入您的手机号码" placeholder-class="color-tip placeholder" class="input" v-model="orderCreateData.member_address.mobile" />
</view>
</view>
</template>
<template v-else>
<!-- 配送方式 -->
<view class="delivery-mode" v-if="goodsData.delivery.express_type.length > 1">
<view class="action">
<view :class="{ active: item.name == orderCreateData.delivery.delivery_type }" v-for="(item, index) in goodsData.delivery.express_type" :key="index" @click="selectDeliveryType(item)">
{{ item.title }}
<!-- 外圆角 -->
<view class="out-radio"></view>
</view>
</view>
</view>
<view class="address-box" :class="{ 'not-delivery-type': goodsData.delivery.express_type.length <= 1 }" v-if="orderCreateData.delivery.delivery_type == 'express'">
<view class="info-wrap" v-if="memberAddress" @click="selectAddress">
<view class="content">
<text class="name">{{ memberAddress.name ? memberAddress.name : '' }}</text>
<text class="mobile">{{ memberAddress.mobile ? memberAddress.mobile : '' }}</text>
<view class="desc-wrap">
{{ memberAddress.full_address ? memberAddress.full_address : '' }}
{{ memberAddress.address ? memberAddress.address : '' }}
</view>
</view>
<text class="cell-more iconfont icon-right"></text>
</view>
<view class="empty-wrap" v-else @click="selectAddress">
<view class="info">请设置收货地址</view>
<view class="cell-more">
<view class="iconfont icon-right"></view>
</view>
</view>
<image class="address-line" :src="$util.img('public/uniapp/order/address-line.png')"></image>
</view>
<view class="address-box" :class="{ 'not-delivery-type': goodsData.delivery.express_type.length <= 1 }" v-if="orderCreateData.delivery.delivery_type == 'local'">
<view v-if="localMemberAddress">
<block v-if="storeList && Object.keys(storeList).length > 1">
<view class="local-delivery-store" v-if="storeInfo" @click="openPopup('deliveryPopup')">
<view class="info">
<text class="store-name">{{ storeInfo.store_name }}</text>
提供配送
</view>
<view class="cell-more">
<text>点击切换</text>
<text class="iconfont icon-right"></text>
</view>
</view>
<view v-else class="local-delivery-store">
<view class="info">
<text class="store-name">您的附近没有可配送的门店请选择其他配送方式</text>
</view>
</view>
</block>
<view class="info-wrap local" @click="selectAddress">
<view class="content">
<text class="name">{{ localMemberAddress.name ? localMemberAddress.name : '' }}
</text>
<text class="mobile">{{ localMemberAddress.mobile ? localMemberAddress.mobile : '' }}
</text>
<view class="desc-wrap">
{{ localMemberAddress.full_address ? localMemberAddress.full_address : '' }}
{{ localMemberAddress.address ? localMemberAddress.address : '' }}
</view>
</view>
<text class="cell-more iconfont icon-right"></text>
</view>
<view class="local-box" v-if="calculateGoodsData.config.local && calculateGoodsData.delivery.local.info.time_is_open == 1">
<view class="pick-block" @click="localtime('')">
<view class="title font-size-base">送达时间</view>
<view class="time-picker">
<text :class="{ 'color-tip': !deliveryTime }">{{ deliveryTime ? deliveryTime : '请选择送达时间' }}</text>
<text class="iconfont icon-right cell-more"></text>
</view>
</view>
</view>
</view>
<view class="empty-wrap" v-else @click="selectAddress">
<view class="info">请设置收货地址</view>
<view class="cell-more">
<view class="iconfont icon-right"></view>
</view>
</view>
<image class="address-line" :src="$util.img('public/uniapp/order/address-line.png')"></image>
</view>
<!-- 门店信息 -->
<view class="store-box" :class="{ 'not-delivery-type': goodsData.delivery.express_type.length <= 1 }" v-if="orderCreateData.delivery.delivery_type == 'store'">
<block v-if="storeInfo">
<view @click="openPopup('deliveryPopup')" class="store-info">
<view class="store-address-info">
<view class="info-wrap">
<view class="title">
<text>{{ storeInfo.store_name }}</text>
</view>
<view class="store-detail">
<view v-if="storeInfo.open_date">营业时间{{ storeInfo.open_date }}</view>
<view class="address">{{ storeInfo.full_address }} {{ storeInfo.address }}
</view>
</view>
</view>
<view class="cell-more iconfont icon-right" v-if="storeList && Object.keys(storeList).length > 1"></view>
</view>
</view>
<view class="mobile-wrap store-mobile" v-if="orderCreateData.member_address">
<view class="form-group">
<text class="text">姓名</text>
<input type="text" placeholder-class="color-tip placeholder" class="input" disabled v-model="orderCreateData.member_address.name" />
</view>
</view>
<view class="mobile-wrap store-mobile" v-if="orderCreateData.member_address">
<view class="form-group">
<text class="text">预留手机</text>
<input type="number" maxlength="11" placeholder="请输入您的手机号码" placeholder-class="color-tip placeholder" class="input" v-model="orderCreateData.member_address.mobile" />
</view>
</view>
<view class="store-time" @click="storetime('')">
<view class="left">提货时间</view>
<view class="right">
{{ deliveryTime }}
<text class="iconfont icon-right"></text>
</view>
</view>
</block>
<view v-else class="empty">当前无自提门店请选择其它配送方式</view>
<image class="address-line" :src="$util.img('public/uniapp/order/address-line.png')"></image>
</view>
</template>
<!-- 店铺 -->
<view class="site-wrap order-goods" v-if="calculateGoodsData">
<view class="site-header">
<view class="iconfont icon-dianpu"></view>
<text class="site-name">门店</text>
</view>
<view class="site-body">
<!-- 商品 -->
<view class="goods-item" v-for="(goodsItem, goodsIndex) in calculateGoodsData.goods_list" :key="goodsIndex">
<view class="goods-wrap">
<view class="goods-img" @click="$util.redirectTo('/pages/goods/detail', { goods_id: goodsItem.goods_id })">
<image :src="$util.img(goodsItem.sku_image, { size: 'mid' })" @error="imageError(goodsIndex)" mode="aspectFill"/>
</view>
<view class="goods-info">
<view class="top-wrap">
<view @click="$util.redirectTo('/pages/goods/detail', { goods_id: goodsItem.goods_id })" class="goods-name">{{ goodsItem.sku_name }}</view>
<view class="sku" v-if="goodsItem.sku_spec_format">
<view class="goods-spec">
<block v-for="(x, i) in goodsItem.sku_spec_format" :key="i">
<view>{{ x.spec_value_name }}</view>
</block>
</view>
</view>
<block v-if="goodsItem.is_virtual == 0">
<view class="error-tips" v-if="orderCreateData.delivery &&
orderCreateData.delivery.delivery_type &&
goodsItem.support_trade_type &&
goodsItem.support_trade_type.indexOf(orderCreateData.delivery.delivery_type) == -1
">
<text class="iconfont icon-gantanhao"></text>
<text>该商品不支持{{ orderCreateData.delivery.delivery_type_name }}</text>
</view>
</block>
<view class="error-tips" v-if="goodsItem.error && goodsItem.error.message">
<text class="iconfont icon-gantanhao"></text>
<text>{{ goodsItem.error.message }}</text>
</view>
</view>
<view class="goods-sub-section">
<view class="color-base-text">
<text class="unit price-style small">{{ $lang('common.currencySymbol') }}</text>
<text class="goods-price price-style large">{{ parseFloat(goodsItem.price).toFixed(2).split('.')[0] }}</text>
<text class="unit price-style small">.{{ parseFloat(goodsItem.price).toFixed(2).split('.')[1] }}</text>
</view>
<view>
<text class="font-size-tag">x</text>
<text class="font-size-base">{{ goodsItem.num }}</text>
</view>
</view>
</view>
</view>
<view class="member-goods-card order-cell" v-if="calculateGoodsData.goods_list[goodsIndex].member_card_list" @click="selectMemberGoodsCard(goodsIndex)">
<text class="tit">次卡抵扣</text>
<view class="box text-overflow">
<block v-if="calculateGoodsData.goods_list[goodsIndex].card_promotion_money">
<text class="text">次卡抵扣{{ calculateGoodsData.goods_list[goodsIndex].card_use_num }}张/{{ calculateGoodsData.goods_list[goodsIndex].card_use_num }}次</text>
<text class="price-font">-¥{{ calculateGoodsData.goods_list[goodsIndex].card_promotion_money | moneyFormat }}</text>
</block>
<text class="color-tip" v-else>请选择次卡</text>
</view>
<text class="iconfont icon-right"></text>
</view>
<view class="goods-form" v-if="goodsData.goods_list[goodsIndex].goods_form" @click="editForm(goodsIndex)">
<ns-form :data="goodsData.goods_list[goodsIndex].goods_form.json_data" ref="goodsForm" :custom-attr="{ sku_id: goodsItem.sku_id, form_id: goodsData.goods_list[goodsIndex].goods_form.id }"/>
<text class="cell-more iconfont icon-right"></text>
<view class="shade"></view>
</view>
</view>
</view>
</view>
<view class="site-wrap buyer-message">
<view class="order-cell">
<text class="tit">买家留言</text>
<view class="box text-overflow " @click="openPopup('buyerMessagePopup')">
<text v-if="orderCreateData.buyer_message">{{ orderCreateData.buyer_message }}</text>
<text class="color-sub" v-else>无留言</text>
</view>
<text class="iconfont icon-right"></text>
</view>
</view>
<view v-if="paymentData.system_form" class="system-form-wrap">
<view class="order-cell">
<text class="tit">{{ paymentData.system_form.form_name }}</text>
</view>
<ns-form :data="paymentData.system_form.json_data" ref="form"/>
</view>
<view class="site-wrap" v-if="calculateGoodsData || promotionInfo || (calculateGoodsData && calculateGoodsData.max_usable_point > 0) || goodsData.invoice">
<view class="site-footer">
<view class="order-cell coupon" v-if="modules.indexOf('coupon') != -1">
<text class="tit">优惠券</text>
<view class="box text-overflow" @click="openPopup('couponPopup')">
<template v-if="orderCreateData.coupon && orderCreateData.coupon.coupon_id">
<text>已使用优惠券,优惠</text>
<text class="unit price-font">{{ $lang('common.currencySymbol') }}</text>
<text class="money price-font">{{ (calculateData && calculateData.coupon_money ? calculateData.coupon_money : 0) | moneyFormat }}</text>
</template>
<text v-else>不使用优惠券</text>
</view>
<text class="iconfont icon-right"></text>
</view>
<view class="order-cell" v-if="promotionInfo">
<text class="tit">活动优惠</text>
<view class="box text-overflow" @click="openPopup('promotionPopup')">
<text>{{ promotionInfo.title }}</text>
</view>
<text class="iconfont icon-right"></text>
</view>
<view class="order-cell point" v-if="calculateGoodsData && calculateGoodsData.max_usable_point > 0">
<text class="tit">
<text>使用{{ parseInt(calculateGoodsData.max_usable_point) }}积分可抵扣</text>
<text class="unit price-font">{{ $lang('common.currencySymbol') }}</text>
<text class="money price-font">{{ calculateData.point_money | moneyFormat }}</text>
</text>
<view class="box"></view>
<ns-switch class="balance-switch" @change="usePoint" :checked="orderCreateData.is_point == 1"/>
</view>
<view class="order-cell order-invoice-cell" v-if="goodsData.invoice.invoice_status == 1">
<text class="tit">发票</text>
<view class="box text-overflow" @click="openPopup('invoicePopup')">
<text v-if="orderCreateData.is_invoice == 1">{{ orderCreateData.invoice_type == 1 ? '纸质' : '电子' }}发票({{ orderCreateData.invoice_content }})</text>
<text v-else>无需发票</text>
</view>
<text class="iconfont icon-right"></text>
</view>
</view>
</view>
<view class="site-wrap box member-card-wrap" v-if="paymentData.recommend_member_card && Object.keys(paymentData.recommend_member_card).length > 0">
<view class="head" @click="selectMemberCard">
<text class="iconfont icon-huiyuan"></text>
<view class="info">
开通{{ paymentData.recommend_member_card.level_name }}
<text>本单预计可省</text>
<text class="price-color">{{ paymentData.recommend_member_card.discount_money | moneyFormat }}</text>
<text>元</text>
</view>
<text class="iconfont" :class="orderCreateData.is_open_card == 1 ? 'icon-yuan_checked color-base-text' : 'icon-yuan_checkbox'"></text>
</view>
<view class="body" v-if="orderCreateData.is_open_card">
<view class="item" :class="{ 'active color-base-border': item.key == orderCreateData.member_card_unit }" v-for="(item, index) in cardChargeType" :key="index" @click="selectMembercardUnit(item.key)">
<view class="title">{{ item.title }}</view>
<view class="price price-font">{{ $lang('common.currencySymbol') }}{{ parseFloat(item.value) }}/{{ item.unit }}</view>
<text class="iconfont icon-icon color-base-text price-font identify" v-if="item.key == orderCreateData.member_card_unit"></text>
</view>
</view>
</view>
<!-- 订单金额 -->
<template v-if="calculateData">
<view class="order-money">
<view class="order-cell">
<text class="tit">商品金额</text>
<view class="box">
<text class="unit color-title price-font">{{ $lang('common.currencySymbol') }}</text>
<text class="money color-title price-font">{{ calculateData.goods_money | moneyFormat }}</text>
</view>
</view>
<view class="order-cell" v-if="calculateData.is_virtual == 0 && calculateData.delivery_money > 0">
<text class="tit">运费</text>
<view class="box color-base-text">
<text class="operator">+</text>
<text class="unit price-font">{{ $lang('common.currencySymbol') }}</text>
<text class="money price-font">{{ calculateData.delivery_money | moneyFormat }}</text>
</view>
</view>
<view class="order-cell" v-if="orderCreateData.is_invoice && calculateData.invoice_money > 0">
<text class="tit">
<text>税费</text>
<text class="color-base-text font-bold price-font">({{ goodsData.invoice.invoice_rate }}%)</text>
</text>
<view class="box color-base-text">
<text class="operator">+</text>
<text class="unit price-font">{{ $lang('common.currencySymbol') }}</text>
<text class="money price-font">{{ calculateData.invoice_money | moneyFormat }}</text>
</view>
</view>
<view class="order-cell" v-if="orderCreateData.is_invoice && calculateData.invoice_delivery_money > 0">
<text class="tit">发票邮寄费</text>
<view class="box color-base-text">
<text class="operator">+</text>
<text class="unit price-font">{{ $lang('common.currencySymbol') }}</text>
<text class="money price-font">{{ calculateData.invoice_delivery_money | moneyFormat }}</text>
</view>
</view>
<view class="order-cell" v-if="calculateData.promotion_money > 0">
<text class="tit">优惠</text>
<view class="box color-base-text">
<text class="operator">-</text>
<text class="unit price-font">{{ $lang('common.currencySymbol') }}</text>
<text class="money price-font">{{ calculateData.promotion_money | moneyFormat }}</text>
</view>
</view>
<view class="order-cell" v-if="calculateData.coupon_money">
<text class="tit">优惠券</text>
<view class="box color-base-text">
<text class="operator">-</text>
<text class="unit price-font">{{ $lang('common.currencySymbol') }}</text>
<text class="money price-font">{{ calculateData.coupon_money | moneyFormat }}</text>
</view>
</view>
<view class="order-cell" v-if="calculateData.point_money > 0">
<text class="tit">积分抵扣</text>
<view class="box color-base-text">
<text class="operator">-</text>
<text class="unit price-font">{{ $lang('common.currencySymbol') }}</text>
<text class="money price-font">{{ calculateData.point_money | moneyFormat }}</text>
</view>
</view>
<view class="order-cell" v-if="calculateData.member_card_money > 0">
<text class="tit">会员卡</text>
<view class="box color-base-text">
<text class="operator">+</text>
<text class="unit price-font">{{ $lang('common.currencySymbol') }}</text>
<text class="money price-font">{{ calculateData.member_card_money | moneyFormat }}
</text>
</view>
</view>
</view>
<view v-if="transactionAgreement.title && transactionAgreement.content" class="agreement">购买前请先阅读<text @click="$refs.agreementPopup.open()">《{{ transactionAgreement.title }}》</text>,下单即代表同意该协议</view>
<view class="order-submit bottom-safe-area">
<view class="order-settlement-info">
<text class="font-size-base color-tip margin-right">共{{ calculateData.goods_num }}件</text>
<text class="font-size-base">合计:</text>
<text class=" unit price-font">{{ $lang('common.currencySymbol') }}</text>
<text class=" money price-font">{{ parseFloat(calculateData.pay_money).toFixed(2).split('.')[0] }}</text>
<text class=" unit price-font">.{{ parseFloat(calculateData.pay_money).toFixed(2).split('.')[1] }}</text>
</view>
<view class="submit-btn">
<button type="primary" class="mini" size="mini" @click="create()" v-if="!surplusStartMoney()">提交订单</button>
<button v-else class="no-submit mini" size="mini">差{{ surplusStartMoney() | moneyFormat }}起送</button>
</view>
</view>
<view class="order-submit-block"></view>
<payment ref="choosePaymentPopup" @close="payClose" v-if="calculateData"></payment>
</template>
<!-- 活动优惠弹窗 -->
<uni-popup ref="promotionPopup" type="bottom" v-if="promotionInfo">
<view class="promotion-popup popup">
<view class="popup-header">
<text class="tit">活动优惠</text>
<text class="iconfont icon-close" @click="closePopup('promotionPopup')"></text>
</view>
<scroll-view scroll-y="true" class="popup-body" :class="{ 'safe-area': isIphoneX }">
<view class="order-cell" style="align-items: baseline;">
<view class="tit">
<text class="promotion-mark ns-gradient-promotionpages-payment">{{ promotionInfo.title }}
</text>
</view>
<view class="promotion-content">
<view class="tit tit-content" style="white-space: pre-line;" v-html="promotionInfo.content"></view>
</view>
</view>
</scroll-view>
<view class="popup-footer" :class="{ 'bottom-safe-area': isIphoneX }">
<view class="confirm-btn color-base-bg" @click="closePopup('promotionPopup')">确定</view>
</view>
</view>
</uni-popup>
<!-- 门店列表弹窗 -->
<uni-popup ref="deliveryPopup" type="bottom">
<view class="delivery-popup popup">
<view class="popup-header">
<text class="tit">已为您甄选出附近所有相关门店</text>
<text class="iconfont icon-close" @click="closePopup('deliveryPopup')"></text>
</view>
<view class="popup-body store-popup" :class="{ 'safe-area': isIphoneX }">
<mescroll-uni @getData="getStore" ref="mescroll" top="50px">
<block slot="list">
<view class="delivery-content">
<block v-if="storeData">
<view class="item-wrap" v-for="(item, index) in storeData" :key="index" @click="selectPickupPoint(item)">
<view class="detail">
<view class="name" :class="item.store_id == orderCreateData.delivery.store_id ? 'color-base-text' : ''">
<text>{{ item.store_name }}</text>
<text v-if="item.distance">({{ item.distance }}km)</text>
</view>
<view class="info">
<view :class="item.store_id == orderCreateData.delivery.store_id ? 'color-base-text' : ''" class="font-size-goods-tag">营业时间:{{ item.open_date }}</view>
<view :class="item.store_id == orderCreateData.delivery.store_id ? 'color-base-text' : ''" class="font-size-goods-tag">地址:{{ item.full_address }}{{ item.address }}</view>
</view>
</view>
<view class="icon" v-if="item.store_id == orderCreateData.delivery.store_id">
<text class="iconfont icon-yuan_checked color-base-text"></text>
</view>
</view>
</block>
<view v-else class="empty-wrap">
<ns-empty text="所选择收货地址附近没有可以自提的门店" :isIndex="false"></ns-empty>
</view>
</view>
</block>
</mescroll-uni>
</view>
</view>
</uni-popup>
<!-- 留言弹窗 -->
<uni-popup ref="buyerMessagePopup" type="bottom">
<view style="height: auto;" class="buyermessag-popup popup" @touchmove.prevent.stop>
<view class="popup-header">
<text class="tit">买家留言</text>
<text class="iconfont icon-close" @click="closePopup('buyerMessagePopup')"></text>
</view>
<scroll-view scroll-y="true" class="popup-body" :class="{ 'safe-area': isIphoneX }">
<view>
<view class="buyermessag-cell">
<view class="buyermessag-form-group">
<textarea type="text" maxlength="100" placeholder="留言前建议先与商家协调一致" placeholder-class="color-tip" v-model="orderCreateData.buyer_message"/>
</view>
</view>
</view>
</scroll-view>
<view class="popup-footer" @click="saveBuyerMessage" :class="{ 'bottom-safe-area': isIphoneX }">
<view class="confirm-btn color-base-bg">确定</view>
</view>
</view>
</uni-popup>
<!-- 优惠券弹窗 -->
<uni-popup ref="couponPopup" type="bottom" v-if="calculateGoodsData" :mask-click="false">
<view class="coupon-popup popup" @touchmove.prevent.stop>
<view class="popup-header">
<text class="tit">优惠券</text>
<text class="iconfont icon-close" @click="closePopup('couponPopup')"></text>
</view>
<scroll-view scroll-y="true" class="popup-body" :class="{ 'safe-area': isIphoneX }">
<view v-if="coupon_list.length > 0">
<view class="coupon-item" v-for="(couponItem, couponIndex) in coupon_list" :key="couponIndex" @click="selectCoupon(couponItem)">
<view class="coupon-info" :style="{ backgroundColor: 'var(--main-color-shallow)' }">
<view class="info-wrap">
<image class="coupon-line" mode="heightFix" :src="$util.img('public/uniapp/coupon/coupon_line.png')"/>
<view class="coupon-money">
<template v-if="couponItem.type == 'divideticket'">
<text class="unit">{{ $lang('common.currencySymbol') }}</text>
<text class="money">{{ parseFloat(couponItem.money) }}</text>
</template>
<template v-else-if="couponItem.type == 'reward'">
<text class="unit">{{ $lang('common.currencySymbol') }}</text>
<text class="money">{{ parseFloat(couponItem.money) }}</text>
</template>
<template v-else-if="couponItem.type == 'discount'">
<text class="money">{{ parseFloat(couponItem.discount) }}</text>
<text class="unit">折</text>
</template>
<view class="at-least">
<template v-if="couponItem.at_least > 0">
满{{ couponItem.at_least }}可用
</template>
<template v-else>
无门槛
</template>
</view>
</view>
</view>
<view class="desc-wrap">
<view class="coupon-name">{{ couponItem.coupon_name }}</view>
<view v-if="couponItem.type == 'discount' && couponItem.discount_limit > 0" class="limit">最多可抵¥{{ couponItem.discount_limit }}</view>
<view class="time font-size-goods-tag">有效期:{{ couponItem.end_time ? $util.timeStampTurnTime(couponItem.end_time) : '长期有效' }}</view>
</view>
<view class="iconfont" :class="orderCreateData.coupon.coupon_id == couponItem.coupon_id ? 'icon-yuan_checked color-base-text' : 'icon-yuan_checkbox'"></view>
</view>
</view>
</view>
<view v-else class="coupon-empty">暂无可用的优惠券</view>
</scroll-view>
<view class="popup-footer" :class="{ 'bottom-safe-area': isIphoneX }">
<view class="confirm-btn color-base-bg" @click="useCpopon">确定</view>
</view>
</view>
</uni-popup>
<!-- 交易协议 -->
<view @touchmove.prevent>
<uni-popup ref="agreementPopup" type="center" :maskClick="false">
<view class="agreement-conten-box">
<view class="close">
<text class="iconfont icon-close" @click="$refs.agreementPopup.close()"></text>
</view>
<view class="title">{{ transactionAgreement.title }}</view>
<view class="con">
<scroll-view scroll-y="true" class="con">
<rich-text :nodes="transactionAgreement.content"></rich-text>
</scroll-view>
</view>
</view>
</uni-popup>
</view>
<!-- 表单修改弹窗 -->
<uni-popup ref="editFormPopup" type="bottom">
<view style="height: auto;" class="form-popup popup" @touchmove.prevent.stop>
<view class="popup-header">
<text class="tit">买家信息</text>
<text class="iconfont icon-close" @click="$refs.editFormPopup.close()"></text>
</view>
<scroll-view scroll-y="true" class="popup-body" :class="{ 'safe-area': isIphoneX }">
<ns-form v-if="tempFormData" :data="tempFormData.json_data" ref="tempForm"></ns-form>
</scroll-view>
<view class="popup-footer" @click="saveForm" :class="{ 'bottom-safe-area': isIphoneX }">
<view class="confirm-btn color-base-bg">确定</view>
</view>
</view>
</uni-popup>
<uni-popup ref="memberGoodsCardPopup" type="bottom">
<view class="member-card-popup popup" @touchmove.prevent.stop>
<view class="popup-header">
<text class="tit">选择次卡</text>
<text class="iconfont icon-close" @click="$refs.memberGoodsCardPopup.close()"></text>
</view>
<scroll-view scroll-y="true" class="popup-body" :class="{ 'safe-area': isIphoneX }">
<view v-for="(item, index) in selectGoodsCard.cardList" class="card-item" @click="selectGoodsCard.click(item.item_id)">
<view class="content">
<view class="title">{{ item.goods_name }}</view>
<view class="info">
<text v-if="item.card_type == 'timecard'">不限次数</text>
<text v-if="item.card_type == 'oncecard'">剩余{{ item.num - item.use_num }}次</text>
<text v-if="item.card_type == 'commoncard'">剩余{{ item.total_num - item.total_use_num }}次</text>
<text>|</text>
<text>{{ item.end_time ? $util.timeStampTurnTime(item.end_time) : '长期有效' }}</text>
</view>
</view>
<view class="iconfont" :class="selectGoodsCard.itemId == item.item_id ? 'icon-yuan_checked color-base-text' : 'icon-yuan_checkbox'"></view>
</view>
</scroll-view>
<view class="popup-footer" @click="saveMemberGoodsCard" :class="{ 'bottom-safe-area': isIphoneX }">
<view class="confirm-btn color-base-bg">确定</view>
</view>
</view>
</uni-popup>
</template>
</scroll-view>
<!-- 门店自提时间 -->
<ns-select-time @selectTime="selectPickupTime" ref="timePopup"></ns-select-time>
<ns-login ref="login"></ns-login>
<loading-cover ref="loadingCover"></loading-cover>
</view>
</template>
<script>
import payment from './payment.js';
export default {
name: 'common-payment',
data() {
return {};
},
props: {
api: Object,
createDataKey: String
},
mixins: [payment]
};
</script>
<style lang="scss">
@import '@/common/css/order_parment.scss';
.order-cell .promotion-content {
flex: 1;
}
</style>

View File

@@ -603,7 +603,7 @@
<text class="iconfont icon-close" @click="$refs.memberGoodsCardPopup.close()"></text> <text class="iconfont icon-close" @click="$refs.memberGoodsCardPopup.close()"></text>
</view> </view>
<scroll-view scroll-y="true" class="popup-body" :class="{ 'safe-area': isIphoneX }"> <scroll-view scroll-y="true" class="popup-body" :class="{ 'safe-area': isIphoneX }">
<view v-for="(item, index) in selectGoodsCard.cardList" class="card-item" @click="selectGoodsCard.click(item.item_id)"> <view v-for="(item, index) in selectGoodsCard.cardList" :key="item.item_id || index" class="card-item" @click="selectGoodsCard.click(item.item_id)">
<view class="content"> <view class="content">
<view class="title">{{ item.goods_name }}</view> <view class="title">{{ item.goods_name }}</view>
<view class="info"> <view class="info">

View File

@@ -11,7 +11,7 @@
:interval="swiperConfig.interval || 3000" :interval="swiperConfig.interval || 3000"
:duration="swiperConfig.duration || 500" :duration="swiperConfig.duration || 500"
:display-multiple-items="swiperConfig.displayMultipleItems || 3"> :display-multiple-items="swiperConfig.displayMultipleItems || 3">
<swiper-item v-for="(item, index) in list" :key="index" @click="toDetail(item)"> <swiper-item v-for="(item, index) in list" :key="item.article_id || index" @click="toDetail(item)">
<view class="swiper-item-content"> <view class="swiper-item-content">
<view :class="['item', value.ornament.type]" :style="itemCss"> <view :class="['item', value.ornament.type]" :style="itemCss">
<view class="article-img"> <view class="article-img">

View File

@@ -206,7 +206,7 @@
}; };
</script> </script>
<style scoped> <style lang="scss" scoped>
.fui-audio { .fui-audio {
width: 100%; width: 100%;

View File

@@ -17,7 +17,7 @@
<!-- 商品列表 --> <!-- 商品列表 -->
<template v-if="value.template == 'row1-of1'"> <template v-if="value.template == 'row1-of1'">
<view class="item" v-for="(item, index) in list" :key="index" @click="toDetail(item)" :class="[value.ornament.type]" :style="goodsItemCss"> <view class="item" v-for="(item, index) in list" :key="item.bargain_id || index" @click="toDetail(item)" :class="[value.ornament.type]" :style="goodsItemCss">
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"> <view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }" :src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix" @error="imageError(index)"/> <image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }" :src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix" @error="imageError(index)"/>
</view> </view>
@@ -67,7 +67,7 @@
<template v-if="value.template == 'horizontal-slide'"> <template v-if="value.template == 'horizontal-slide'">
<scroll-view v-if="value.slideMode == 'scroll'" class="scroll" :scroll-x="true" :show-scrollbar="false"> <scroll-view v-if="value.slideMode == 'scroll'" class="scroll" :scroll-x="true" :show-scrollbar="false">
<view class="item" v-for="(item, index) in list" :key="index" @click="toDetail(item)" :class="[value.ornament.type]" :style="goodsItemCss"> <view class="item" v-for="(item, index) in list" :key="item.bargain_id || index" @click="toDetail(item)" :class="[value.ornament.type]" :style="goodsItemCss">
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"> <view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }" :src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix" @error="imageError(index)" :lazy-load="true"/> <image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }" :src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix" @error="imageError(index)" :lazy-load="true"/>
<image class="bg" v-if="value.saleStyle.control && value.template == 'horizontal-slide' && value.style != 'style-2'" :src="$util.img('public/uniapp/bargain/bg.png')" mode="widthFix"/> <image class="bg" v-if="value.saleStyle.control && value.template == 'horizontal-slide' && value.style != 'style-2'" :src="$util.img('public/uniapp/bargain/bg.png')" mode="widthFix"/>

View File

@@ -68,7 +68,7 @@
<block v-if="categoryTree.length"> <block v-if="categoryTree.length">
<scroll-view scroll-y="true" class="tree-wrap"> <scroll-view scroll-y="true" class="tree-wrap">
<view class="category-item-wrap"> <view class="category-item-wrap">
<view class="category-item" v-for="(item, index) in categoryTree" :key="index" :class="[ <view class="category-item" v-for="(item, index) in categoryTree" :key="item.category_id || index" :class="[
{ select: select == index }, { select: select == index },
{ 'border-bottom': value.template == 4 && select + 1 === index }, { 'border-bottom': value.template == 4 && select + 1 === index },
{ 'border-top': value.template == 4 && select - 1 === index } { 'border-top': value.template == 4 && select - 1 === index }
@@ -84,7 +84,7 @@
@scroll="listenScroll" @touchstart="touchStart" :refresher-enabled="true" @scroll="listenScroll" @touchstart="touchStart" :refresher-enabled="true"
refresher-default-style="none" :refresher-triggered="triggered" @refresherrefresh="onRefresh" refresher-default-style="none" :refresher-triggered="triggered" @refresherrefresh="onRefresh"
@refresherrestore="onRestore"> @refresherrestore="onRestore">
<view class="child-category" v-for="(item, index) in categoryTree" :key="index" :id="'category-' + index"> <view class="child-category" v-for="(item, index) in categoryTree" :key="item.category_id || index" :id="'category-' + index">
<diy-category-item :category="item" :value="value" ref="categoryItem" :index="index" <diy-category-item :category="item" :value="value" ref="categoryItem" :index="index"
:select="select" :oneCategorySelect="oneCategorySelect" :isList="isList" @tologin="toLogin" :select="select" :oneCategorySelect="oneCategorySelect" :isList="isList" @tologin="toLogin"
@selectsku="selectSku($event, index)" @addCart="addCartPoint" @selectsku="selectSku($event, index)" @addCart="addCartPoint"
@@ -95,7 +95,7 @@
<view class="content-wrap" <view class="content-wrap"
v-if="(value.template == 2 || value.template == 3 || value.template == 4) && loadType == 'part'"> v-if="(value.template == 2 || value.template == 3 || value.template == 4) && loadType == 'part'">
<view class="child-category-wrap" v-for="(item, index) in categoryTree" :key="index" <view class="child-category-wrap" v-for="(item, index) in categoryTree" :key="item.category_id || index"
:id="'category-' + index" :style="{ display: select == index ? 'block' : 'none' }"> :id="'category-' + index" :style="{ display: select == index ? 'block' : 'none' }">
<diy-category-item :category="item" :value="value" ref="categoryItem" :index="index" <diy-category-item :category="item" :value="value" ref="categoryItem" :index="index"
:last="index == categoryTree.length - 1 ? true : false" :select="select" :last="index == categoryTree.length - 1 ? true : false" :select="select"

View File

@@ -20,4 +20,4 @@ export default {
}; };
</script> </script>
<style></style> <style lang="scss"></style>

View File

@@ -9,7 +9,7 @@
<swiper class="coupon-style-one" circular> <swiper class="coupon-style-one" circular>
<swiper-item v-for="(numItem, numIndex) in Math.ceil(computedCouponList.length / 3)" :key="numIndex" class="coupon-item-box"> <swiper-item v-for="(numItem, numIndex) in Math.ceil(computedCouponList.length / 3)" :key="numIndex" class="coupon-item-box">
<view v-for="(item, index) in computedCouponList" class="coupon-item" <view v-for="(item, index) in computedCouponList" class="coupon-item" :key="item.coupon_id || index"
v-if="index >= [numIndex * 3] && index < [(numIndex + 1) * 3]" :style="{ v-if="index >= [numIndex * 3] && index < [(numIndex + 1) * 3]" :style="{
color: value.moneyColor, color: value.moneyColor,
backgroundImage: 'url(' + $util.img('public/uniapp/coupon/style1-bg.png') + ')', backgroundImage: 'url(' + $util.img('public/uniapp/coupon/style1-bg.png') + ')',
@@ -43,7 +43,7 @@
<template v-if="value.style == '2'"> <template v-if="value.style == '2'">
<swiper class="coupon-style-two" circular> <swiper class="coupon-style-two" circular>
<swiper-item v-for="(numItem, numIndex) in Math.ceil(computedCouponList.length / 3)" :key="numIndex" class="coupon-item-box"> <swiper-item v-for="(numItem, numIndex) in Math.ceil(computedCouponList.length / 3)" :key="numIndex" class="coupon-item-box">
<view class="coupon-item" v-for="(item, index) in computedCouponList" :key="index" <view class="coupon-item" v-for="(item, index) in computedCouponList" :key="item.coupon_id || index"
v-if="index >= [numIndex * 3] && index < [(numIndex + 1) * 3]" :style="{ v-if="index >= [numIndex * 3] && index < [(numIndex + 1) * 3]" :style="{
color: value.moneyColor, color: value.moneyColor,
backgroundImage: 'url(' + $util.img('public/uniapp/coupon/coupon_bg1.png') + ')', backgroundImage: 'url(' + $util.img('public/uniapp/coupon/coupon_bg1.png') + ')',
@@ -76,7 +76,7 @@
<template v-if="value.style == '3'"> <template v-if="value.style == '3'">
<swiper class="coupon-style-three" circular> <swiper class="coupon-style-three" circular>
<swiper-item v-for="(numItem, numIndex) in Math.ceil(computedCouponList.length / 3)" :key="numIndex" class="coupon-item-box"> <swiper-item v-for="(numItem, numIndex) in Math.ceil(computedCouponList.length / 3)" :key="numIndex" class="coupon-item-box">
<view class="coupon-item" v-for="(item, index) in computedCouponList" :key="index" <view class="coupon-item" v-for="(item, index) in computedCouponList" :key="item.coupon_id || index"
v-if="index >= [numIndex * 3] && index < [(numIndex + 1) * 3]" :style="{ v-if="index >= [numIndex * 3] && index < [(numIndex + 1) * 3]" :style="{
color: value.moneyColor, color: value.moneyColor,
backgroundImage: 'url(' + $util.img('public/uniapp/coupon/coupon_shu.png') + ')', backgroundImage: 'url(' + $util.img('public/uniapp/coupon/coupon_shu.png') + ')',
@@ -110,7 +110,7 @@
<template v-if="value.style == '4'"> <template v-if="value.style == '4'">
<swiper class="coupon-style-four" circular> <swiper class="coupon-style-four" circular>
<swiper-item v-for="(numItem, numIndex) in Math.ceil(computedCouponList.length / 3)" :key="numIndex" class="coupon-item-box"> <swiper-item v-for="(numItem, numIndex) in Math.ceil(computedCouponList.length / 3)" :key="numIndex" class="coupon-item-box">
<view class="coupon-item" v-for="(item, index) in computedCouponList" :key="index" <view class="coupon-item" v-for="(item, index) in computedCouponList" :key="item.coupon_id || index"
v-if="index >= [numIndex * 3] && index < [(numIndex + 1) * 3]" :style="{ v-if="index >= [numIndex * 3] && index < [(numIndex + 1) * 3]" :style="{
color: value.moneyColor, color: value.moneyColor,
backgroundImage: 'url(' + $util.img('public/uniapp/coupon/style4_bg.png') + ')', backgroundImage: 'url(' + $util.img('public/uniapp/coupon/style4_bg.png') + ')',
@@ -143,7 +143,7 @@
<view class="coupon-style-five"> <view class="coupon-style-five">
<view class="coupon-all"> <view class="coupon-all">
<view class="coupon-box"> <view class="coupon-box">
<view class="coupon-list" v-for="(item, index) in computedCouponList" :key="index" @click="couponAction(item, index)"> <view class="coupon-list" v-for="(item, index) in computedCouponList" :key="item.coupon_id || index" @click="couponAction(item, index)">
<image :src="$util.img('public/uniapp/coupon/style5_bg.png')"></image> <image :src="$util.img('public/uniapp/coupon/style5_bg.png')"></image>
<view class="coupon"> <view class="coupon">
<view class="coupon-info"> <view class="coupon-info">
@@ -176,7 +176,7 @@
<template v-if="value.style == '6'"> <template v-if="value.style == '6'">
<swiper class="coupon-style-six" circular> <swiper class="coupon-style-six" circular>
<swiper-item class="style-six-wrap" v-for="(numItem, numIndex) in Math.ceil(computedCouponList.length / 3)" :key="numIndex"> <swiper-item class="style-six-wrap" v-for="(numItem, numIndex) in Math.ceil(computedCouponList.length / 3)" :key="numIndex">
<view class="coupon" v-for="(item, index) in computedCouponList" :key="index" <view class="coupon" v-for="(item, index) in computedCouponList" :key="item.coupon_id || index"
v-if="index >= [numIndex * 3] && index < [(numIndex + 1) * 3]" :style="{ v-if="index >= [numIndex * 3] && index < [(numIndex + 1) * 3]" :style="{
color: value.moneyColor, color: value.moneyColor,
backgroundImage: 'url(' + $util.img('public/uniapp/coupon/style6-bg-1.png') + ')', backgroundImage: 'url(' + $util.img('public/uniapp/coupon/style6-bg-1.png') + ')',
@@ -230,7 +230,7 @@
<template v-if="value.style == '7'"> <template v-if="value.style == '7'">
<scroll-view class="coupon-style-seven" scroll-x="true"> <scroll-view class="coupon-style-seven" scroll-x="true">
<view class="wrap"> <view class="wrap">
<view class="coupon-list" v-for="(item, index) in computedCouponList" :key="index" @click="couponAction(item, index)"> <view class="coupon-list" v-for="(item, index) in computedCouponList" :key="item.coupon_id || index" @click="couponAction(item, index)">
<image :src="$util.img('public/uniapp/coupon/style7_bg.png')"></image> <image :src="$util.img('public/uniapp/coupon/style7_bg.png')"></image>
<view class="coupon"> <view class="coupon">
<view class="coupon-info"> <view class="coupon-info">
@@ -1067,7 +1067,7 @@
background: transparent; background: transparent;
} }
</style> </style>
<style scoped> <style lang="scss" scoped>
.coupon-all>>>.uni-scroll-view::-webkit-scrollbar { .coupon-all>>>.uni-scroll-view::-webkit-scrollbar {
display: none; display: none;
} }

View File

@@ -1,6 +1,6 @@
<template> <template>
<view data-component-name="diy-fenxiao-goods-list" class="diy-fenxiao" v-if="list.length" :class="['goods-list', value.template, value.style]" :style="goodsListWarpCss"> <view data-component-name="diy-fenxiao-goods-list" class="diy-fenxiao" v-if="list.length" :class="['goods-list', value.template, value.style]" :style="goodsListWarpCss">
<view class="goods-item" v-for="(item, index) in list" :key="index" @click="toDetail(item)" :class="[value.ornament.type]" :style="goodsItemCss"> <view class="goods-item" v-for="(item, index) in list" :key="item.goods_id || index" @click="toDetail(item)" :class="[value.ornament.type]" :style="goodsItemCss">
<view class="goods-img" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"> <view class="goods-img" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }" :src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix" @error="imgError(index)"/> <image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }" :src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix" @error="imgError(index)"/>
</view> </view>

View File

@@ -26,4 +26,4 @@
}; };
</script> </script>
<style></style> <style lang="scss"></style>

View File

@@ -5,7 +5,7 @@
<view class="title-wrap" v-show="value.title" :style="{ color: value.textColor, fontWeight: value.fontWeight ? 'bold' : '' }">{{ value.title }} <view class="title-wrap" v-show="value.title" :style="{ color: value.textColor, fontWeight: value.fontWeight ? 'bold' : '' }">{{ value.title }}
</view> </view>
<view class="ul-wrap"> <view class="ul-wrap">
<view class="li-item" v-for="(item, index) in list" :key="index"> <view class="li-item" v-for="(item, index) in list" :key="item.brand_id || index">
<image class="brand-pic" :src="$util.img(item.image_url)" mode="aspectFit" @click="handlerClick(item)" @tap="handlerClick(item)" @error="imgError(index)" :style="itemCss"/> <image class="brand-pic" :src="$util.img(item.image_url)" mode="aspectFit" @click="handlerClick(item)" @tap="handlerClick(item)" @error="imgError(index)" :style="itemCss"/>
</view> </view>
</view> </view>

View File

@@ -9,13 +9,13 @@
:key="index" :key="index"
v-if="index >= [(numItem) * (value.pageCount * value.rowCount)] && index < [(numItem+1) * (value.pageCount * value.rowCount)]" v-if="index >= [(numItem) * (value.pageCount * value.rowCount)] && index < [(numItem+1) * (value.pageCount * value.rowCount)]"
:style="{ width: 100 / value.rowCount + '%' }" @click="redirectTo(item.link)"> :style="{ width: 100 / value.rowCount + '%' }" @click="redirectTo(item.link)">
<!-- #endif --> <!-- #endif -->
<!-- #ifdef H5 --> <!-- #ifdef H5 -->
<view class="graphic-nav-item" :class="[value.mode]" v-for="(item, index) in value.list" <view class="graphic-nav-item" :class="[value.mode]" v-for="(item, index) in value.list"
:key="index" :key="index"
v-if="index >= [(numItem - 1) * (value.pageCount * value.rowCount)] && index < [numItem * (value.pageCount * value.rowCount)]" v-if="index >= [(numItem - 1) * (value.pageCount * value.rowCount)] && index < [numItem * (value.pageCount * value.rowCount)]"
:style="{ width: 100 / value.rowCount + '%' }" @click="redirectTo(item.link)"> :style="{ width: 100 / value.rowCount + '%' }" @click="redirectTo(item.link)">
<!-- #endif --> <!-- #endif -->
<view class="graphic-img" v-if="value.mode != 'text'" <view class="graphic-img" v-if="value.mode != 'text'"
:style="{ fontSize: value.imageSize * 2 + 'rpx', width: value.imageSize * 2 + 'rpx', height: value.imageSize * 2 + 'rpx' }"> :style="{ fontSize: value.imageSize * 2 + 'rpx', width: value.imageSize * 2 + 'rpx', height: value.imageSize * 2 + 'rpx' }">
<image v-if="item.iconType == 'img'" <image v-if="item.iconType == 'img'"
@@ -37,7 +37,12 @@
:style="{ fontSize: value.font.size * 2 + 'rpx', fontWeight: value.font.weight, color: value.font.color }"> :style="{ fontSize: value.font.size * 2 + 'rpx', fontWeight: value.font.weight, color: value.font.color }">
{{ item.title }} {{ item.title }}
</text> </text>
</view> <!-- #ifdef H5 -->
</view>
<!-- #endif -->
<!-- #ifdef MP -->
</view>
<!-- #endif -->
</swiper-item> </swiper-item>
</swiper> </swiper>
@@ -159,7 +164,7 @@
} }
}; };
</script> </script>
<style> <style lang="scss">
/* 固定显示 */ /* 固定显示 */
.graphic-nav.fixed-layout>>>.uni-scroll-view-content { .graphic-nav.fixed-layout>>>.uni-scroll-view-content {
display: flex; display: flex;

View File

@@ -37,4 +37,4 @@ export default {
}; };
</script> </script>
<style></style> <style lang="scss"></style>

View File

@@ -22,4 +22,4 @@ export default {
}; };
</script> </script>
<style></style> <style lang="scss"></style>

View File

@@ -242,7 +242,7 @@
} }
} }
</style> </style>
<style scoped> <style lang="scss" scoped>
.coupon-all>>>.uni-scroll-view::-webkit-scrollbar { .coupon-all>>>.uni-scroll-view::-webkit-scrollbar {
display: none; display: none;
} }

View File

@@ -1457,7 +1457,7 @@
} }
} }
</style> </style>
<style scoped> <style lang="scss" scoped>
.member-complete-info-popup /deep/ .uni-popup__wrapper.bottom, .member-complete-info-popup /deep/ .uni-popup__wrapper.bottom,
.member-complete-info-popup /deep/ .uni-popup__wrapper.bottom .uni-popup__wrapper-box { .member-complete-info-popup /deep/ .uni-popup__wrapper.bottom .uni-popup__wrapper-box {
border-top-left-radius: 30rpx !important; border-top-left-radius: 30rpx !important;

View File

@@ -179,7 +179,7 @@
} }
}; };
</script> </script>
<style> <style lang="scss">
/* 单行滑动 */ /* 单行滑动 */
.merch-nav.singleSlide>>>.uni-scroll-view-content { .merch-nav.singleSlide>>>.uni-scroll-view-content {
display: flex; display: flex;

View File

@@ -7,7 +7,7 @@
</view> </view>
<scroll-view class="diy-notes-box" scroll-x="true" show-scrollbar="true"> <scroll-view class="diy-notes-box" scroll-x="true" show-scrollbar="true">
<view class="notes-box-item" v-for="(item, i) in dataList" :key="i" @click="handlerClick(item)" @tap="handlerClick(item)" <view class="notes-box-item" v-for="(item, i) in dataList" :key="item.note_id || i" @click="handlerClick(item)" @tap="handlerClick(item)"
:style="notesItemStyle"> :style="notesItemStyle">
<view class="notes-item" v-if="item.status == 1"> <view class="notes-item" v-if="item.status == 1">
<view class="notes-item-con"> <view class="notes-item-con">

View File

@@ -79,7 +79,7 @@
} }
}; };
</script> </script>
<style> <style lang="scss">
.quick-nav >>> .uni-scroll-view-content { .quick-nav >>> .uni-scroll-view-content {
display: flex; display: flex;
} }

View File

@@ -27,7 +27,7 @@
<view class="content-wrap"> <view class="content-wrap">
<template v-if="value.template == 'row1-of1'"> <template v-if="value.template == 'row1-of1'">
<view class="item" v-for="(item, index) in dataList" :key="index" @click="toDetail(item.id)" :class="[value.ornament.type]" :style="goodsItemCss"> <view class="item" v-for="(item, index) in dataList" :key="item.goods_id || index" @click="toDetail(item.id)" :class="[value.ornament.type]" :style="goodsItemCss">
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"> <view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }" :src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix" @error="imageError(index)"/> <image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }" :src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix" @error="imageError(index)"/>
</view> </view>
@@ -82,7 +82,7 @@
</template> </template>
<template v-if="value.template == 'row1-of2'"> <template v-if="value.template == 'row1-of2'">
<view class="item" v-for="(item, index) in dataList" :key="index" @click="toDetail(item.id)" :class="[value.ornament.type]" :style="goodsItemCss"> <view class="item" v-for="(item, index) in dataList" :key="item.goods_id || index" @click="toDetail(item.id)" :class="[value.ornament.type]" :style="goodsItemCss">
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"> <view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }" :src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix" @error="imageError(index)"/> <image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }" :src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix" @error="imageError(index)"/>
</view> </view>
@@ -119,7 +119,7 @@
<template v-if="value.template == 'horizontal-slide'"> <template v-if="value.template == 'horizontal-slide'">
<scroll-view v-if="value.slideMode == 'scroll'" class="scroll" :scroll-x="true" :show-scrollbar="false"> <scroll-view v-if="value.slideMode == 'scroll'" class="scroll" :scroll-x="true" :show-scrollbar="false">
<view class="item" v-for="(item, index) in dataList" :key="index" @click="toDetail(item.id)" :class="[value.ornament.type]" :style="goodsItemCss"> <view class="item" v-for="(item, index) in dataList" :key="item.goods_id || index" @click="toDetail(item.id)" :class="[value.ornament.type]" :style="goodsItemCss">
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"> <view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }" :src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix" @error="imageError(index)"/> <image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }" :src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix" @error="imageError(index)"/>
</view> </view>
@@ -147,7 +147,7 @@
</scroll-view> </scroll-view>
<swiper v-if="value.slideMode == 'slide'" :autoplay="false" class="swiper" :style="{ height: swiperHeight }"> <swiper v-if="value.slideMode == 'slide'" :autoplay="false" class="swiper" :style="{ height: swiperHeight }">
<swiper-item v-for="(pageItem, pageIndex) in page" :key="pageIndex" :class="['swiper-item', dataList[pageIndex] && [dataList[pageIndex].length / 3].length >= 1 && 'flex-between']"> <swiper-item v-for="(pageItem, pageIndex) in page" :key="pageIndex" :class="['swiper-item', dataList[pageIndex] && [dataList[pageIndex].length / 3].length >= 1 && 'flex-between']">
<view class="item" v-for="(item, dataIndex) in dataList[pageIndex]" :key="dataIndex" @click="toDetail(item.id)" :class="[value.ornament.type]" :style="goodsItemCss"> <view class="item" v-for="(item, dataIndex) in dataList[pageIndex]" :key="item.goods_id || dataIndex" @click="toDetail(item.id)" :class="[value.ornament.type]" :style="goodsItemCss">
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"> <view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }" :src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix" @error="imageError(dataIndex, pageIndex)"/> <image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }" :src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix" @error="imageError(dataIndex, pageIndex)"/>
</view> </view>

View File

@@ -3,7 +3,7 @@
<view class="diy-store-label"> <view class="diy-store-label">
<block v-if="businessConfig.store_business == 'store'"> <block v-if="businessConfig.store_business == 'store'">
<scroll-view scroll-x="true" :class="[value.contentStyle, { between: list.length == 3 }]" :style="storeLabelWrapCss" :enable-flex="true"> <scroll-view scroll-x="true" :class="[value.contentStyle, { between: list.length == 3 }]" :style="storeLabelWrapCss" :enable-flex="true">
<view v-for="(item, index) in storeLabel" :class="['item']"> <view v-for="(item, index) in storeLabel" :key="item.label_id || index" :class="['item']">
<diy-icon v-if="value.icon" class="icon-box" :icon="value.icon" :value="value.style ? value.style : 'null'"></diy-icon> <diy-icon v-if="value.icon" class="icon-box" :icon="value.icon" :value="value.style ? value.style : 'null'"></diy-icon>
<text class="label-name" :style="{ color: value.textColor, fontSize: value.fontSize * 2 + 'rpx', fontWeight: value.fontWeight }">{{ item }}</text> <text class="label-name" :style="{ color: value.textColor, fontSize: value.fontSize * 2 + 'rpx', fontWeight: value.fontWeight }">{{ item }}</text>
</view> </view>

View File

@@ -43,7 +43,7 @@
}; };
</script> </script>
<style scoped> <style lang="scss" scoped>
video { video {
width: 100%; width: 100%;
} }

View File

@@ -452,4 +452,4 @@
<style lang="scss"> <style lang="scss">
@import '@/common/css/goods_detail.scss'; @import '@/common/css/goods_detail.scss';
</style> </style>
<style scoped></style> <style lang="scss" scoped></style>

View File

@@ -1,52 +1,52 @@
<!-- 下拉刷新区域 --> <!-- 下拉刷新区域 -->
<template> <template>
<view v-if="mOption.use" class="mescroll-downwarp"> <view v-if="mOption.use" class="mescroll-downwarp">
<view class="downwarp-content"> <view class="downwarp-content">
<view class="downwarp-progress" :class="{ 'mescroll-rotate': isDownLoading }" :style="{ transform: downRotate }"></view> <view class="downwarp-progress" :class="{ 'mescroll-rotate': isDownLoading }" :style="{ transform: downRotate }"></view>
<view class="downwarp-tip">{{ downText }}</view> <view class="downwarp-tip">{{ downText }}</view>
</view> </view>
</view> </view>
</template> </template>
<script> <script>
export default { export default {
props: { props: {
option: Object, // down的配置项 option: Object, // down的配置项
type: Number, // 下拉状态inOffset1 outOffset2 showLoading3 endDownScroll4 type: Number, // 下拉状态inOffset1 outOffset2 showLoading3 endDownScroll4
rate: Number // 下拉比率 (inOffset: rate<1; outOffset: rate>=1) rate: Number // 下拉比率 (inOffset: rate<1; outOffset: rate>=1)
}, },
computed: { computed: {
// 支付宝小程序需写成计算属性,prop定义default仍报错 // 支付宝小程序需写成计算属性,prop定义default仍报错
mOption() { mOption() {
return this.option || {}; return this.option || {};
}, },
// 是否在加载中 // 是否在加载中
isDownLoading() { isDownLoading() {
return this.type === 3; return this.type === 3;
}, },
// 旋转的角度 // 旋转的角度
downRotate() { downRotate() {
return 'rotate(' + 360 * this.rate + 'deg)'; return 'rotate(' + 360 * this.rate + 'deg)';
}, },
// 文本提示 // 文本提示
downText() { downText() {
switch (this.type) { switch (this.type) {
case 1: case 1:
return this.mOption.textInOffset; return this.mOption.textInOffset;
case 2: case 2:
return this.mOption.textOutOffset; return this.mOption.textOutOffset;
case 3: case 3:
return this.mOption.textLoading; return this.mOption.textLoading;
case 4: case 4:
return this.mOption.textLoading; return this.mOption.textLoading;
default: default:
return this.mOption.textInOffset; return this.mOption.textInOffset;
} }
} }
} }
}; };
</script> </script>
<style> <style lang="scss">
@import './mescroll-down.css'; @import './mescroll-down.css';
</style> </style>

View File

@@ -1,90 +1,90 @@
<!--空布局 <!--空布局
可作为独立的组件, 不使用mescroll的页面也能单独引入, 以便APP全局统一管理: 可作为独立的组件, 不使用mescroll的页面也能单独引入, 以便APP全局统一管理:
import MescrollEmpty from '@/components/mescroll-uni/components/mescroll-empty.vue'; import MescrollEmpty from '@/components/mescroll-uni/components/mescroll-empty.vue';
<mescroll-empty v-if="isShowEmpty" :option="optEmpty" @emptyclick="emptyClick"></mescroll-empty> <mescroll-empty v-if="isShowEmpty" :option="optEmpty" @emptyclick="emptyClick"></mescroll-empty>
--> -->
<template> <template>
<view class="mescroll-empty" :class="{ 'empty-fixed': option.fixed }" :style="{ 'z-index': option.zIndex, top: option.top }"> <view class="mescroll-empty" :class="{ 'empty-fixed': option.fixed }" :style="{ 'z-index': option.zIndex, top: option.top }">
<image v-if="icon" class="empty-icon" :src="icon" mode="widthFix" /> <image v-if="icon" class="empty-icon" :src="icon" mode="widthFix" />
<view v-if="tip" class="empty-tip">{{ tip }}</view> <view v-if="tip" class="empty-tip">{{ tip }}</view>
<view v-if="option.btnText" class="empty-btn" @click="emptyClick">{{ option.btnText }}</view> <view v-if="option.btnText" class="empty-btn" @click="emptyClick">{{ option.btnText }}</view>
</view> </view>
</template> </template>
<script> <script>
// 引入全局配置 // 引入全局配置
import GlobalOption from './../mescroll-uni-option.js'; import GlobalOption from './../mescroll-uni-option.js';
export default { export default {
props: { props: {
// empty的配置项: 默认为GlobalOption.up.empty // empty的配置项: 默认为GlobalOption.up.empty
option: { option: {
type: Object, type: Object,
default() { default() {
return {}; return {};
} }
} }
}, },
// 使用computed获取配置,用于支持option的动态配置 // 使用computed获取配置,用于支持option的动态配置
computed: { computed: {
// 图标 // 图标
icon() { icon() {
return this.option.icon == null ? GlobalOption.up.empty.icon : this.option.icon; // 此处不使用短路求值, 用于支持传空串不显示图标 return this.option.icon == null ? GlobalOption.up.empty.icon : this.option.icon; // 此处不使用短路求值, 用于支持传空串不显示图标
}, },
// 文本提示 // 文本提示
tip() { tip() {
return this.option.tip == null ? GlobalOption.up.empty.tip : this.option.tip; // 此处不使用短路求值, 用于支持传空串不显示文本提示 return this.option.tip == null ? GlobalOption.up.empty.tip : this.option.tip; // 此处不使用短路求值, 用于支持传空串不显示文本提示
} }
}, },
methods: { methods: {
// 点击按钮 // 点击按钮
emptyClick() { emptyClick() {
this.$emit('emptyclick'); this.$emit('emptyclick');
} }
} }
}; };
</script> </script>
<style> <style lang="scss">
/* 无任何数据的空布局 */ /* 无任何数据的空布局 */
.mescroll-empty { .mescroll-empty {
box-sizing: border-box; box-sizing: border-box;
width: 100%; width: 100%;
padding: 100rpx 50rpx; padding: 100rpx 50rpx;
text-align: center; text-align: center;
} }
.mescroll-empty.empty-fixed { .mescroll-empty.empty-fixed {
z-index: 99; z-index: 99;
position: absolute; /*transform会使fixed失效,最终会降级为absolute */ position: absolute; /*transform会使fixed失效,最终会降级为absolute */
top: 100rpx; top: 100rpx;
left: 0; left: 0;
} }
.mescroll-empty .empty-icon { .mescroll-empty .empty-icon {
width: 280rpx; width: 280rpx;
height: 280rpx; height: 280rpx;
} }
.mescroll-empty .empty-tip { .mescroll-empty .empty-tip {
margin-top: 20rpx; margin-top: 20rpx;
font-size: $font-size-tag; font-size: $font-size-tag;
color: gray; color: gray;
} }
.mescroll-empty .empty-btn { .mescroll-empty .empty-btn {
display: inline-block; display: inline-block;
margin-top: 40rpx; margin-top: 40rpx;
min-width: 200rpx; min-width: 200rpx;
padding: 18rpx; padding: 18rpx;
font-size: $font-size-base; font-size: $font-size-base;
border: 1rpx solid #e04b28; border: 1rpx solid #e04b28;
border-radius: 60rpx; border-radius: 60rpx;
color: #e04b28; color: #e04b28;
} }
.mescroll-empty .empty-btn:active { .mescroll-empty .empty-btn:active {
opacity: 0.75; opacity: 0.75;
} }
</style> </style>

View File

@@ -1,81 +1,81 @@
<!-- 回到顶部的按钮 --> <!-- 回到顶部的按钮 -->
<template> <template>
<image <image
v-if="mOption.src" v-if="mOption.src"
class="mescroll-totop" class="mescroll-totop"
:class="[value ? 'mescroll-totop-in' : 'mescroll-totop-out', { 'mescroll-safe-bottom': mOption.safearea }]" :class="[value ? 'mescroll-totop-in' : 'mescroll-totop-out', { 'mescroll-safe-bottom': mOption.safearea }]"
:style="{ 'z-index': mOption.zIndex, left: left, right: right, bottom: addUnit(mOption.bottom), width: addUnit(mOption.width), 'border-radius': addUnit(mOption.radius) }" :style="{ 'z-index': mOption.zIndex, left: left, right: right, bottom: addUnit(mOption.bottom), width: addUnit(mOption.width), 'border-radius': addUnit(mOption.radius) }"
:src="mOption.src" :src="mOption.src"
mode="widthFix" mode="widthFix"
@click="toTopClick" @click="toTopClick"
/> />
</template> </template>
<script> <script>
export default { export default {
props: { props: {
// up.toTop的配置项 // up.toTop的配置项
option: Object, option: Object,
// 是否显示 // 是否显示
value: false value: false
}, },
computed: { computed: {
// 支付宝小程序需写成计算属性,prop定义default仍报错 // 支付宝小程序需写成计算属性,prop定义default仍报错
mOption() { mOption() {
return this.option || {}; return this.option || {};
}, },
// 优先显示左边 // 优先显示左边
left() { left() {
return this.mOption.left ? this.addUnit(this.mOption.left) : 'auto'; return this.mOption.left ? this.addUnit(this.mOption.left) : 'auto';
}, },
// 右边距离 (优先显示左边) // 右边距离 (优先显示左边)
right() { right() {
return this.mOption.left ? 'auto' : this.addUnit(this.mOption.right); return this.mOption.left ? 'auto' : this.addUnit(this.mOption.right);
} }
}, },
methods: { methods: {
addUnit(num) { addUnit(num) {
if (!num) return 0; if (!num) return 0;
if (typeof num === 'number') return num + 'rpx'; if (typeof num === 'number') return num + 'rpx';
return num; return num;
}, },
toTopClick() { toTopClick() {
this.$emit('input', false); // 使v-model生效 this.$emit('input', false); // 使v-model生效
this.$emit('click'); // 派发点击事件 this.$emit('click'); // 派发点击事件
} }
} }
}; };
</script> </script>
<style> <style lang="scss">
/* 回到顶部的按钮 */ /* 回到顶部的按钮 */
.mescroll-totop { .mescroll-totop {
z-index: 99; z-index: 99;
position: fixed !important; /* 加上important避免编译到H5,在多mescroll中定位失效 */ position: fixed !important; /* 加上important避免编译到H5,在多mescroll中定位失效 */
right: 46rpx !important; right: 46rpx !important;
bottom: 272rpx !important; bottom: 272rpx !important;
width: 72rpx; width: 72rpx;
height: auto; height: auto;
border-radius: 50%; border-radius: 50%;
opacity: 0; opacity: 0;
transition: opacity 0.5s; /* 过渡 */ transition: opacity 0.5s; /* 过渡 */
margin-bottom: var(--window-bottom); /* css变量 */ margin-bottom: var(--window-bottom); /* css变量 */
} }
/* 适配 iPhoneX */ /* 适配 iPhoneX */
.mescroll-safe-bottom { .mescroll-safe-bottom {
margin-bottom: calc(var(--window-bottom) + constant(safe-area-inset-bottom)); /* window-bottom + 适配 iPhoneX */ margin-bottom: calc(var(--window-bottom) + constant(safe-area-inset-bottom)); /* window-bottom + 适配 iPhoneX */
margin-bottom: calc(var(--window-bottom) + env(safe-area-inset-bottom)); margin-bottom: calc(var(--window-bottom) + env(safe-area-inset-bottom));
} }
/* 显示 -- 淡入 */ /* 显示 -- 淡入 */
.mescroll-totop-in { .mescroll-totop-in {
opacity: 1; opacity: 1;
} }
/* 隐藏 -- 淡出且不接收事件*/ /* 隐藏 -- 淡出且不接收事件*/
.mescroll-totop-out { .mescroll-totop-out {
opacity: 0; opacity: 0;
pointer-events: none; pointer-events: none;
} }
</style> </style>

View File

@@ -1,39 +1,39 @@
<!-- 上拉加载区域 --> <!-- 上拉加载区域 -->
<template> <template>
<view class="mescroll-upwarp"> <view class="mescroll-upwarp">
<!-- 加载中 (此处不能用v-if,否则android小程序快速上拉可能会不断触发上拉回调) --> <!-- 加载中 (此处不能用v-if,否则android小程序快速上拉可能会不断触发上拉回调) -->
<view v-show="isUpLoading"> <view v-show="isUpLoading">
<view class="upwarp-progress mescroll-rotate"></view> <view class="upwarp-progress mescroll-rotate"></view>
<view class="upwarp-tip">{{ mOption.textLoading }}</view> <view class="upwarp-tip">{{ mOption.textLoading }}</view>
</view> </view>
<!-- 无数据 --> <!-- 无数据 -->
<view v-if="isUpNoMore" class="upwarp-nodata">{{ mOption.textNoMore }}</view> <view v-if="isUpNoMore" class="upwarp-nodata">{{ mOption.textNoMore }}</view>
</view> </view>
</template> </template>
<script> <script>
export default { export default {
props: { props: {
option: Object, // up的配置项 option: Object, // up的配置项
type: Number // 上拉加载的状态0loading前1loading中2没有更多了 type: Number // 上拉加载的状态0loading前1loading中2没有更多了
}, },
computed: { computed: {
// 支付宝小程序需写成计算属性,prop定义default仍报错 // 支付宝小程序需写成计算属性,prop定义default仍报错
mOption() { mOption() {
return this.option || {}; return this.option || {};
}, },
// 加载中 // 加载中
isUpLoading() { isUpLoading() {
return this.type === 1; return this.type === 1;
}, },
// 没有更多了 // 没有更多了
isUpNoMore() { isUpNoMore() {
return this.type === 2; return this.type === 2;
} }
} }
}; };
</script> </script>
<style> <style lang="scss">
@import './mescroll-up.css'; @import './mescroll-up.css';
</style> </style>

View File

@@ -1,298 +1,298 @@
<template> <template>
<view <view
class="mescroll-body" class="mescroll-body"
:style="{ minHeight: minHeight, 'padding-top': padTop, 'padding-bottom': padBottom, 'padding-bottom': padBottomConstant, 'padding-bottom': padBottomEnv }" :style="{ minHeight: minHeight, 'padding-top': padTop, 'padding-bottom': padBottom, 'padding-bottom': padBottomConstant, 'padding-bottom': padBottomEnv }"
@touchstart="touchstartEvent" @touchstart="touchstartEvent"
@touchmove="touchmoveEvent" @touchmove="touchmoveEvent"
@touchend="touchendEvent" @touchend="touchendEvent"
@touchcancel="touchendEvent" @touchcancel="touchendEvent"
> >
<view class="mescroll-body-content mescroll-touch" :style="{ transform: translateY, transition: transition }"> <view class="mescroll-body-content mescroll-touch" :style="{ transform: translateY, transition: transition }">
<!-- 下拉加载区域 (支付宝小程序子组件传参给子子组件仍报单项数据流的异常,暂时不通过mescroll-down组件实现)--> <!-- 下拉加载区域 (支付宝小程序子组件传参给子子组件仍报单项数据流的异常,暂时不通过mescroll-down组件实现)-->
<!-- <mescroll-down :option="mescroll.optDown" :type="downLoadType" :rate="downRate"></mescroll-down> --> <!-- <mescroll-down :option="mescroll.optDown" :type="downLoadType" :rate="downRate"></mescroll-down> -->
<view v-if="mescroll.optDown.use" class="mescroll-downwarp"> <view v-if="mescroll.optDown.use" class="mescroll-downwarp">
<view class="downwarp-content"> <view class="downwarp-content">
<view class="downwarp-progress" :class="{ 'mescroll-rotate': isDownLoading }" :style="{ transform: downRotate }"></view> <view class="downwarp-progress" :class="{ 'mescroll-rotate': isDownLoading }" :style="{ transform: downRotate }"></view>
<view class="downwarp-tip">{{ downText }}</view> <view class="downwarp-tip">{{ downText }}</view>
</view> </view>
</view> </view>
<!-- 列表内容 --> <!-- 列表内容 -->
<slot></slot> <slot></slot>
<!-- 空布局 --> <!-- 空布局 -->
<!-- <mescroll-empty v-if="isShowEmpty" :option="mescroll.optUp.empty" @emptyclick="emptyClick"></mescroll-empty> --> <!-- <mescroll-empty v-if="isShowEmpty" :option="mescroll.optUp.empty" @emptyclick="emptyClick"></mescroll-empty> -->
<!-- 上拉加载区域 (下拉刷新时不显示, 支付宝小程序子组件传参给子子组件仍报单项数据流的异常,暂时不通过mescroll-up组件实现)--> <!-- 上拉加载区域 (下拉刷新时不显示, 支付宝小程序子组件传参给子子组件仍报单项数据流的异常,暂时不通过mescroll-up组件实现)-->
<!-- <mescroll-up v-if="mescroll.optUp.use && !isDownLoading" :option="mescroll.optUp" :type="upLoadType"></mescroll-up> --> <!-- <mescroll-up v-if="mescroll.optUp.use && !isDownLoading" :option="mescroll.optUp" :type="upLoadType"></mescroll-up> -->
<view v-if="mescroll.optUp.use && !isDownLoading" class="mescroll-upwarp"> <view v-if="mescroll.optUp.use && !isDownLoading" class="mescroll-upwarp">
<!-- 加载中 (此处不能用v-if,否则android小程序快速上拉可能会不断触发上拉回调) --> <!-- 加载中 (此处不能用v-if,否则android小程序快速上拉可能会不断触发上拉回调) -->
<view v-show="upLoadType === 1"> <view v-show="upLoadType === 1">
<view class="upwarp-progress mescroll-rotate"></view> <view class="upwarp-progress mescroll-rotate"></view>
<view class="upwarp-tip">{{ mescroll.optUp.textLoading }}</view> <view class="upwarp-tip">{{ mescroll.optUp.textLoading }}</view>
</view> </view>
<!-- 无数据 --> <!-- 无数据 -->
<view v-if="upLoadType === 2" class="upwarp-nodata">{{ mescroll.optUp.textNoMore }}</view> <view v-if="upLoadType === 2" class="upwarp-nodata">{{ mescroll.optUp.textNoMore }}</view>
</view> </view>
</view> </view>
<!-- 回到顶部按钮 (fixed元素需写在transform外面,防止降级为absolute)--> <!-- 回到顶部按钮 (fixed元素需写在transform外面,防止降级为absolute)-->
<mescroll-top v-model="isShowToTop" :option="mescroll.optUp.toTop" @click="toTopClick" v-if="showTop"></mescroll-top> <mescroll-top v-model="isShowToTop" :option="mescroll.optUp.toTop" @click="toTopClick" v-if="showTop"></mescroll-top>
</view> </view>
</template> </template>
<script> <script>
// 引入mescroll-uni.js,处理核心逻辑 // 引入mescroll-uni.js,处理核心逻辑
import MeScroll from './mescroll-uni.js'; import MeScroll from './mescroll-uni.js';
// 引入全局配置 // 引入全局配置
import GlobalOption from './mescroll-uni-option.js'; import GlobalOption from './mescroll-uni-option.js';
// 引入空布局组件 // 引入空布局组件
import MescrollEmpty from './components/mescroll-empty.vue'; import MescrollEmpty from './components/mescroll-empty.vue';
// 引入回到顶部组件 // 引入回到顶部组件
import MescrollTop from './components/mescroll-top.vue'; import MescrollTop from './components/mescroll-top.vue';
export default { export default {
components: { components: {
MescrollEmpty, MescrollEmpty,
MescrollTop MescrollTop
}, },
data() { data() {
return { return {
mescroll: { optDown: {}, optUp: {} }, // mescroll实例 mescroll: { optDown: {}, optUp: {} }, // mescroll实例
downHight: 0, //下拉刷新: 容器高度 downHight: 0, //下拉刷新: 容器高度
downRate: 0, // 下拉比率(inOffset: rate<1; outOffset: rate>=1) downRate: 0, // 下拉比率(inOffset: rate<1; outOffset: rate>=1)
downLoadType: 4, // 下拉刷新状态 inOffset1 outOffset2 showLoading3 endDownScroll4 downLoadType: 4, // 下拉刷新状态 inOffset1 outOffset2 showLoading3 endDownScroll4
upLoadType: 0, // 上拉加载状态0loading前1loading中2没有更多了 upLoadType: 0, // 上拉加载状态0loading前1loading中2没有更多了
isShowEmpty: false, // 是否显示空布局 isShowEmpty: false, // 是否显示空布局
isShowToTop: false, // 是否显示回到顶部按钮 isShowToTop: false, // 是否显示回到顶部按钮
windowHeight: 0, // 可使用窗口的高度 windowHeight: 0, // 可使用窗口的高度
statusBarHeight: 0 // 状态栏高度 statusBarHeight: 0 // 状态栏高度
}; };
}, },
props: { props: {
down: Object, // 下拉刷新的参数配置 down: Object, // 下拉刷新的参数配置
up: Object, // 上拉加载的参数配置 up: Object, // 上拉加载的参数配置
top: [String, Number], // 下拉布局往下的偏移量 (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx, 百分比则相对于windowHeight) top: [String, Number], // 下拉布局往下的偏移量 (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx, 百分比则相对于windowHeight)
topbar: Boolean, // top的偏移量是否加上状态栏高度, 默认false (使用场景:取消原生导航栏时,配置此项可自动加上状态栏高度的偏移量) topbar: Boolean, // top的偏移量是否加上状态栏高度, 默认false (使用场景:取消原生导航栏时,配置此项可自动加上状态栏高度的偏移量)
bottom: [String, Number], // 上拉布局往上的偏移量 (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx, 百分比则相对于windowHeight) bottom: [String, Number], // 上拉布局往上的偏移量 (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx, 百分比则相对于windowHeight)
safearea: Boolean, // bottom的偏移量是否加上底部安全区的距离, 默认false (需要适配iPhoneX时使用) safearea: Boolean, // bottom的偏移量是否加上底部安全区的距离, 默认false (需要适配iPhoneX时使用)
height: [String, Number], // 指定mescroll最小高度,默认windowHeight,使列表不满屏仍可下拉 height: [String, Number], // 指定mescroll最小高度,默认windowHeight,使列表不满屏仍可下拉
showTop: { showTop: {
type: Boolean, type: Boolean,
default: true default: true
} }
}, },
computed: { computed: {
// mescroll最小高度,默认windowHeight,使列表不满屏仍可下拉 // mescroll最小高度,默认windowHeight,使列表不满屏仍可下拉
minHeight() { minHeight() {
return this.toPx(this.height || '100%') + 'px'; return this.toPx(this.height || '100%') + 'px';
}, },
// 下拉布局往下偏移的距离 (px) // 下拉布局往下偏移的距离 (px)
numTop() { numTop() {
return this.toPx(this.top) + (this.topbar ? this.statusBarHeight : 0); return this.toPx(this.top) + (this.topbar ? this.statusBarHeight : 0);
}, },
padTop() { padTop() {
return this.numTop + 'px'; return this.numTop + 'px';
}, },
// 上拉布局往上偏移 (px) // 上拉布局往上偏移 (px)
numBottom() { numBottom() {
return this.toPx(this.bottom); return this.toPx(this.bottom);
}, },
padBottom() { padBottom() {
return this.numBottom + 'px'; return this.numBottom + 'px';
}, },
padBottomConstant() { padBottomConstant() {
return this.safearea ? 'calc(' + this.padBottom + ' + constant(safe-area-inset-bottom))' : this.padBottom; return this.safearea ? 'calc(' + this.padBottom + ' + constant(safe-area-inset-bottom))' : this.padBottom;
}, },
padBottomEnv() { padBottomEnv() {
return this.safearea ? 'calc(' + this.padBottom + ' + env(safe-area-inset-bottom))' : this.padBottom; return this.safearea ? 'calc(' + this.padBottom + ' + env(safe-area-inset-bottom))' : this.padBottom;
}, },
// 是否为重置下拉的状态 // 是否为重置下拉的状态
isDownReset() { isDownReset() {
return this.downLoadType === 3 || this.downLoadType === 4; return this.downLoadType === 3 || this.downLoadType === 4;
}, },
// 过渡 // 过渡
transition() { transition() {
return this.isDownReset ? 'transform 300ms' : ''; return this.isDownReset ? 'transform 300ms' : '';
}, },
translateY() { translateY() {
return this.downHight > 0 ? 'translateY(' + this.downHight + 'px)' : ''; // transform会使fixed失效,需注意把fixed元素写在mescroll之外 return this.downHight > 0 ? 'translateY(' + this.downHight + 'px)' : ''; // transform会使fixed失效,需注意把fixed元素写在mescroll之外
}, },
// 是否在加载中 // 是否在加载中
isDownLoading() { isDownLoading() {
return this.downLoadType === 3; return this.downLoadType === 3;
}, },
// 旋转的角度 // 旋转的角度
downRotate() { downRotate() {
return 'rotate(' + 360 * this.downRate + 'deg)'; return 'rotate(' + 360 * this.downRate + 'deg)';
}, },
// 文本提示 // 文本提示
downText() { downText() {
switch (this.downLoadType) { switch (this.downLoadType) {
case 1: case 1:
return this.mescroll.optDown.textInOffset; return this.mescroll.optDown.textInOffset;
case 2: case 2:
return this.mescroll.optDown.textOutOffset; return this.mescroll.optDown.textOutOffset;
case 3: case 3:
return this.mescroll.optDown.textLoading; return this.mescroll.optDown.textLoading;
case 4: case 4:
return this.mescroll.optDown.textLoading; return this.mescroll.optDown.textLoading;
default: default:
return this.mescroll.optDown.textInOffset; return this.mescroll.optDown.textInOffset;
} }
} }
}, },
methods: { methods: {
//number,rpx,upx,px,% --> px的数值 //number,rpx,upx,px,% --> px的数值
toPx(num) { toPx(num) {
if (typeof num === 'string') { if (typeof num === 'string') {
if (num.indexOf('px') !== -1) { if (num.indexOf('px') !== -1) {
if (num.indexOf('rpx') !== -1) { if (num.indexOf('rpx') !== -1) {
// "10rpx" // "10rpx"
num = num.replace('rpx', ''); num = num.replace('rpx', '');
} else if (num.indexOf('upx') !== -1) { } else if (num.indexOf('upx') !== -1) {
// "10upx" // "10upx"
num = num.replace('upx', ''); num = num.replace('upx', '');
} else { } else {
// "10px" // "10px"
return Number(num.replace('px', '')); return Number(num.replace('px', ''));
} }
} else if (num.indexOf('%') !== -1) { } else if (num.indexOf('%') !== -1) {
// 传百分比,则相对于windowHeight,传"10%"则等于windowHeight的10% // 传百分比,则相对于windowHeight,传"10%"则等于windowHeight的10%
let rate = Number(num.replace('%', '')) / 100; let rate = Number(num.replace('%', '')) / 100;
return this.windowHeight * rate; return this.windowHeight * rate;
} }
} }
return num ? uni.upx2px(Number(num)) : 0; return num ? uni.upx2px(Number(num)) : 0;
}, },
//注册列表touchstart事件,用于下拉刷新 //注册列表touchstart事件,用于下拉刷新
touchstartEvent(e) { touchstartEvent(e) {
this.mescroll.touchstartEvent(e); this.mescroll.touchstartEvent(e);
}, },
//注册列表touchmove事件,用于下拉刷新 //注册列表touchmove事件,用于下拉刷新
touchmoveEvent(e) { touchmoveEvent(e) {
this.mescroll.touchmoveEvent(e); this.mescroll.touchmoveEvent(e);
}, },
//注册列表touchend事件,用于下拉刷新 //注册列表touchend事件,用于下拉刷新
touchendEvent(e) { touchendEvent(e) {
this.mescroll.touchendEvent(e); this.mescroll.touchendEvent(e);
}, },
// 点击空布局的按钮回调 // 点击空布局的按钮回调
emptyClick() { emptyClick() {
this.$emit('emptyclick', this.mescroll); this.$emit('emptyclick', this.mescroll);
}, },
// 点击回到顶部的按钮回调 // 点击回到顶部的按钮回调
toTopClick() { toTopClick() {
this.mescroll.scrollTo(0, this.mescroll.optUp.toTop.duration); // 执行回到顶部 this.mescroll.scrollTo(0, this.mescroll.optUp.toTop.duration); // 执行回到顶部
this.$emit('topclick', this.mescroll); // 派发点击回到顶部按钮的回调 this.$emit('topclick', this.mescroll); // 派发点击回到顶部按钮的回调
} }
}, },
// 使用created初始化mescroll对象; 如果用mounted部分css样式编译到H5会失效 // 使用created初始化mescroll对象; 如果用mounted部分css样式编译到H5会失效
created() { created() {
let vm = this; let vm = this;
let diyOption = { let diyOption = {
// 下拉刷新的配置 // 下拉刷新的配置
down: { down: {
inOffset(mescroll) { inOffset(mescroll) {
vm.downLoadType = 1; // 下拉的距离进入offset范围内那一刻的回调 (自定义mescroll组件时,此行不可删) vm.downLoadType = 1; // 下拉的距离进入offset范围内那一刻的回调 (自定义mescroll组件时,此行不可删)
}, },
outOffset(mescroll) { outOffset(mescroll) {
vm.downLoadType = 2; // 下拉的距离大于offset那一刻的回调 (自定义mescroll组件时,此行不可删) vm.downLoadType = 2; // 下拉的距离大于offset那一刻的回调 (自定义mescroll组件时,此行不可删)
}, },
onMoving(mescroll, rate, downHight) { onMoving(mescroll, rate, downHight) {
// 下拉过程中的回调,滑动过程一直在执行; // 下拉过程中的回调,滑动过程一直在执行;
vm.downHight = downHight; // 设置下拉区域的高度 (自定义mescroll组件时,此行不可删) vm.downHight = downHight; // 设置下拉区域的高度 (自定义mescroll组件时,此行不可删)
vm.downRate = rate; //下拉比率 (inOffset: rate<1; outOffset: rate>=1) vm.downRate = rate; //下拉比率 (inOffset: rate<1; outOffset: rate>=1)
}, },
showLoading(mescroll, downHight) { showLoading(mescroll, downHight) {
vm.downLoadType = 3; // 显示下拉刷新进度的回调 (自定义mescroll组件时,此行不可删) vm.downLoadType = 3; // 显示下拉刷新进度的回调 (自定义mescroll组件时,此行不可删)
vm.downHight = downHight; // 设置下拉区域的高度 (自定义mescroll组件时,此行不可删) vm.downHight = downHight; // 设置下拉区域的高度 (自定义mescroll组件时,此行不可删)
}, },
endDownScroll(mescroll) { endDownScroll(mescroll) {
vm.downLoadType = 4; // 结束下拉 (自定义mescroll组件时,此行不可删) vm.downLoadType = 4; // 结束下拉 (自定义mescroll组件时,此行不可删)
vm.downHight = 0; // 设置下拉区域的高度 (自定义mescroll组件时,此行不可删) vm.downHight = 0; // 设置下拉区域的高度 (自定义mescroll组件时,此行不可删)
}, },
// 派发下拉刷新的回调 // 派发下拉刷新的回调
callback: function(mescroll) { callback: function(mescroll) {
vm.$emit('down', mescroll); vm.$emit('down', mescroll);
} }
}, },
// 上拉加载的配置 // 上拉加载的配置
up: { up: {
// 显示加载中的回调 // 显示加载中的回调
showLoading() { showLoading() {
vm.upLoadType = 1; vm.upLoadType = 1;
}, },
// 显示无更多数据的回调 // 显示无更多数据的回调
showNoMore() { showNoMore() {
vm.upLoadType = 2; vm.upLoadType = 2;
}, },
// 隐藏上拉加载的回调 // 隐藏上拉加载的回调
hideUpScroll() { hideUpScroll() {
vm.upLoadType = 0; vm.upLoadType = 0;
}, },
// 空布局 // 空布局
empty: { empty: {
onShow(isShow) { onShow(isShow) {
// 显示隐藏的回调 // 显示隐藏的回调
vm.isShowEmpty = isShow; vm.isShowEmpty = isShow;
} }
}, },
// 回到顶部 // 回到顶部
toTop: { toTop: {
onShow(isShow) { onShow(isShow) {
// 显示隐藏的回调 // 显示隐藏的回调
vm.isShowToTop = isShow; vm.isShowToTop = isShow;
} }
}, },
// 派发上拉加载的回调 // 派发上拉加载的回调
callback: function(mescroll) { callback: function(mescroll) {
vm.$emit('up', mescroll); vm.$emit('up', mescroll);
} }
} }
}; };
MeScroll.extend(diyOption, GlobalOption); // 混入全局的配置 MeScroll.extend(diyOption, GlobalOption); // 混入全局的配置
let myOption = JSON.parse( let myOption = JSON.parse(
JSON.stringify({ JSON.stringify({
down: vm.down, down: vm.down,
up: vm.up up: vm.up
}) })
); // 深拷贝,避免对props的影响 ); // 深拷贝,避免对props的影响
MeScroll.extend(myOption, diyOption); // 混入具体界面的配置 MeScroll.extend(myOption, diyOption); // 混入具体界面的配置
// 初始化MeScroll对象 // 初始化MeScroll对象
vm.mescroll = new MeScroll(myOption, true); // 传入true,标记body为滚动区域 vm.mescroll = new MeScroll(myOption, true); // 传入true,标记body为滚动区域
// init回调mescroll对象 // init回调mescroll对象
vm.$emit('init', vm.mescroll); vm.$emit('init', vm.mescroll);
// 设置高度 // 设置高度
const sys = uni.getSystemInfoSync(); const sys = uni.getSystemInfoSync();
if (sys.windowHeight) vm.windowHeight = sys.windowHeight; if (sys.windowHeight) vm.windowHeight = sys.windowHeight;
if (sys.statusBarHeight) vm.statusBarHeight = sys.statusBarHeight; if (sys.statusBarHeight) vm.statusBarHeight = sys.statusBarHeight;
// 使down的bottomOffset生效 // 使down的bottomOffset生效
vm.mescroll.setBodyHeight(sys.windowHeight); vm.mescroll.setBodyHeight(sys.windowHeight);
// 因为使用的是page的scroll,这里需自定义scrollTo // 因为使用的是page的scroll,这里需自定义scrollTo
vm.mescroll.resetScrollTo((y, t) => { vm.mescroll.resetScrollTo((y, t) => {
uni.pageScrollTo({ uni.pageScrollTo({
scrollTop: y, scrollTop: y,
duration: t duration: t
}); });
}); });
// 具体的界面如果不配置up.toTop.safearea,则取本vue的safearea值 // 具体的界面如果不配置up.toTop.safearea,则取本vue的safearea值
if (vm.up && vm.up.toTop && vm.up.toTop.safearea != null) { if (vm.up && vm.up.toTop && vm.up.toTop.safearea != null) {
} else { } else {
vm.mescroll.optUp.toTop.safearea = vm.safearea; vm.mescroll.optUp.toTop.safearea = vm.safearea;
} }
} }
}; };
</script> </script>
<style> <style lang="scss">
@import './mescroll-body.css'; @import './mescroll-body.css';
@import './components/mescroll-down.css'; @import './components/mescroll-down.css';
@import './components/mescroll-up.css'; @import './components/mescroll-up.css';
</style> </style>

View File

@@ -1,429 +1,429 @@
<template> <template>
<view class="mescroll-uni-warp"> <view class="mescroll-uni-warp">
<scroll-view :id="viewId" class="mescroll-uni" :class="{ 'mescroll-uni-fixed': isFixed }" :style="{ <scroll-view :id="viewId" class="mescroll-uni" :class="{ 'mescroll-uni-fixed': isFixed }" :style="{
height: scrollHeight, height: scrollHeight,
'padding-top': padTop, 'padding-top': padTop,
'padding-bottom': padBottom, 'padding-bottom': padBottom,
'padding-bottom': padBottomConstant, 'padding-bottom': padBottomConstant,
'padding-bottom': padBottomEnv, 'padding-bottom': padBottomEnv,
top: fixedTop, top: fixedTop,
bottom: fixedBottom, bottom: fixedBottom,
bottom: fixedBottomConstant, bottom: fixedBottomConstant,
bottom: fixedBottomEnv, bottom: fixedBottomEnv,
background: background, background: background,
'padding-left': paddingBoth, 'padding-left': paddingBoth,
'padding-right': paddingBoth 'padding-right': paddingBoth
}" :scroll-top="scrollTop" :scroll-with-animation="scrollAnim" @scroll="scroll" @touchstart="touchstartEvent" }" :scroll-top="scrollTop" :scroll-with-animation="scrollAnim" @scroll="scroll" @touchstart="touchstartEvent"
@touchmove="touchmoveEvent" @touchend="touchendEvent" @touchcancel="touchendEvent" :scroll-y="isDownReset" @touchmove="touchmoveEvent" @touchend="touchendEvent" @touchcancel="touchendEvent" :scroll-y="isDownReset"
:enable-back-to-top="true"> :enable-back-to-top="true">
<view class="mescroll-uni-content" :style="{ transform: translateY, transition: transition }"> <view class="mescroll-uni-content" :style="{ transform: translateY, transition: transition }">
<!-- 下拉加载区域 (支付宝小程序子组件传参给子子组件仍报单项数据流的异常,暂时不通过mescroll-down组件实现)--> <!-- 下拉加载区域 (支付宝小程序子组件传参给子子组件仍报单项数据流的异常,暂时不通过mescroll-down组件实现)-->
<!-- <mescroll-down :option="mescroll.optDown" :type="downLoadType" :rate="downRate"></mescroll-down> --> <!-- <mescroll-down :option="mescroll.optDown" :type="downLoadType" :rate="downRate"></mescroll-down> -->
<view v-if="mescroll.optDown.use" class="mescroll-downwarp"> <view v-if="mescroll.optDown.use" class="mescroll-downwarp">
<view class="downwarp-content"> <view class="downwarp-content">
<!-- <view class="downwarp-progress" :class="{'mescroll-rotate': isDownLoading}" :style="{'transform': downRotate}"></view> --> <!-- <view class="downwarp-progress" :class="{'mescroll-rotate': isDownLoading}" :style="{'transform': downRotate}"></view> -->
<view class="downwarp-tip">{{ downText }}</view> <view class="downwarp-tip">{{ downText }}</view>
</view> </view>
</view> </view>
<!-- 列表内容 --> <!-- 列表内容 -->
<slot></slot> <slot></slot>
<!-- 空布局 --> <!-- 空布局 -->
<!-- <mescroll-empty v-if="isShowEmpty" :option="mescroll.optUp.empty" @emptyclick="emptyClick"></mescroll-empty> --> <!-- <mescroll-empty v-if="isShowEmpty" :option="mescroll.optUp.empty" @emptyclick="emptyClick"></mescroll-empty> -->
<!-- 上拉加载区域 (下拉刷新时不显示, 支付宝小程序子组件传参给子子组件仍报单项数据流的异常,暂时不通过mescroll-up组件实现)--> <!-- 上拉加载区域 (下拉刷新时不显示, 支付宝小程序子组件传参给子子组件仍报单项数据流的异常,暂时不通过mescroll-up组件实现)-->
<!-- <mescroll-up v-if="mescroll.optUp.use && !isDownLoading" :option="mescroll.optUp" :type="upLoadType"></mescroll-up> --> <!-- <mescroll-up v-if="mescroll.optUp.use && !isDownLoading" :option="mescroll.optUp" :type="upLoadType"></mescroll-up> -->
<view v-if="mescroll.optUp.use && !isDownLoading" class="mescroll-upwarp"> <view v-if="mescroll.optUp.use && !isDownLoading" class="mescroll-upwarp">
<!-- 加载中 (此处不能用v-if,否则android小程序快速上拉可能会不断触发上拉回调) --> <!-- 加载中 (此处不能用v-if,否则android小程序快速上拉可能会不断触发上拉回调) -->
<view v-show="upLoadType === 1"> <view v-show="upLoadType === 1">
<!-- <view class="upwarp-progress mescroll-rotate"></view> <!-- <view class="upwarp-progress mescroll-rotate"></view>
<view class="upwarp-tip">{{ mescroll.optUp.textLoading }}</view> --> <view class="upwarp-tip">{{ mescroll.optUp.textLoading }}</view> -->
<ns-loading></ns-loading> <ns-loading></ns-loading>
</view> </view>
<!-- 无数据 --> <!-- 无数据 -->
<view v-if="upLoadType === 2" class="upwarp-nodata">{{ mescroll.optUp.textNoMore }}</view> <view v-if="upLoadType === 2" class="upwarp-nodata">{{ mescroll.optUp.textNoMore }}</view>
</view> </view>
</view> </view>
</scroll-view> </scroll-view>
<!-- 回到顶部按钮 (fixed元素,需写在scroll-view外面,防止滚动的时候抖动)--> <!-- 回到顶部按钮 (fixed元素,需写在scroll-view外面,防止滚动的时候抖动)-->
<mescroll-top v-if="showTop" v-model="isShowToTop" :option="mescroll.optUp.toTop" @click="toTopClick"></mescroll-top> <mescroll-top v-if="showTop" v-model="isShowToTop" :option="mescroll.optUp.toTop" @click="toTopClick"></mescroll-top>
</view> </view>
</template> </template>
<script> <script>
// 引入mescroll-uni.js,处理核心逻辑 // 引入mescroll-uni.js,处理核心逻辑
import MeScroll from './mescroll-uni.js'; import MeScroll from './mescroll-uni.js';
// 引入全局配置 // 引入全局配置
import GlobalOption from './mescroll-uni-option.js'; import GlobalOption from './mescroll-uni-option.js';
// 引入空布局组件 // 引入空布局组件
import MescrollEmpty from './components/mescroll-empty.vue'; import MescrollEmpty from './components/mescroll-empty.vue';
// 引入回到顶部组件 // 引入回到顶部组件
import MescrollTop from './components/mescroll-top.vue'; import MescrollTop from './components/mescroll-top.vue';
import nsLoading from '@/components/ns-loading/ns-loading.vue'; import nsLoading from '@/components/ns-loading/ns-loading.vue';
export default { export default {
name: 'mescroll-uni', name: 'mescroll-uni',
components: { components: {
MescrollEmpty, MescrollEmpty,
MescrollTop MescrollTop
}, },
props: { props: {
down: Object, // 下拉刷新的参数配置 down: Object, // 下拉刷新的参数配置
up: Object, // 上拉加载的参数配置 up: Object, // 上拉加载的参数配置
top: [String, Number], // 下拉布局往下的偏移量 (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx, 百分比则相对于windowHeight) top: [String, Number], // 下拉布局往下的偏移量 (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx, 百分比则相对于windowHeight)
topbar: Boolean, // top的偏移量是否加上状态栏高度, 默认false (使用场景:取消原生导航栏时,配置此项可自动加上状态栏高度的偏移量) topbar: Boolean, // top的偏移量是否加上状态栏高度, 默认false (使用场景:取消原生导航栏时,配置此项可自动加上状态栏高度的偏移量)
bottom: [String, Number], // 上拉布局往上的偏移量 (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx, 百分比则相对于windowHeight) bottom: [String, Number], // 上拉布局往上的偏移量 (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx, 百分比则相对于windowHeight)
safearea: Boolean, // bottom的偏移量是否加上底部安全区的距离, 默认false (需要适配iPhoneX时使用) safearea: Boolean, // bottom的偏移量是否加上底部安全区的距离, 默认false (需要适配iPhoneX时使用)
fixed: { fixed: {
// 是否通过fixed固定mescroll的高度, 默认true // 是否通过fixed固定mescroll的高度, 默认true
type: Boolean, type: Boolean,
default () { default () {
return true; return true;
} }
}, },
height: [String, height: [String,
Number Number
], // 指定mescroll的高度, 此项有值,则不使用fixed. (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx, 百分比则相对于windowHeight) ], // 指定mescroll的高度, 此项有值,则不使用fixed. (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx, 百分比则相对于windowHeight)
showTop: { showTop: {
//是否需要展示返回顶部按钮 //是否需要展示返回顶部按钮
type: Boolean, type: Boolean,
default () { default () {
return true; return true;
} }
}, },
background: String, background: String,
paddingBoth: { paddingBoth: {
type: [String, Number], type: [String, Number],
default () { default () {
return 0; return 0;
} }
} }
}, },
data() { data() {
return { return {
mescroll: { mescroll: {
optDown: {}, optDown: {},
optUp: {} optUp: {}
}, // mescroll实例 }, // mescroll实例
viewId: 'id_' + viewId: 'id_' +
Math.random() Math.random()
.toString(36) .toString(36)
.substr(2), // 随机生成mescroll的id(不能数字开头,否则找不到元素) .substr(2), // 随机生成mescroll的id(不能数字开头,否则找不到元素)
downHight: 0, //下拉刷新: 容器高度 downHight: 0, //下拉刷新: 容器高度
downRate: 0, // 下拉比率(inOffset: rate<1; outOffset: rate>=1) downRate: 0, // 下拉比率(inOffset: rate<1; outOffset: rate>=1)
downLoadType: 4, // 下拉刷新状态 inOffset1 outOffset2 showLoading3 endDownScroll4 downLoadType: 4, // 下拉刷新状态 inOffset1 outOffset2 showLoading3 endDownScroll4
upLoadType: 0, // 上拉加载状态0loading前1loading中2没有更多了 upLoadType: 0, // 上拉加载状态0loading前1loading中2没有更多了
isShowEmpty: false, // 是否显示空布局 isShowEmpty: false, // 是否显示空布局
isShowToTop: false, // 是否显示回到顶部按钮 isShowToTop: false, // 是否显示回到顶部按钮
scrollTop: 0, // 滚动条的位置 scrollTop: 0, // 滚动条的位置
scrollAnim: false, // 是否开启滚动动画 scrollAnim: false, // 是否开启滚动动画
windowTop: 0, // 可使用窗口的顶部位置 windowTop: 0, // 可使用窗口的顶部位置
windowBottom: 0, // 可使用窗口的底部位置 windowBottom: 0, // 可使用窗口的底部位置
windowHeight: 0, // 可使用窗口的高度 windowHeight: 0, // 可使用窗口的高度
statusBarHeight: 0 // 状态栏高度 statusBarHeight: 0 // 状态栏高度
}; };
}, },
computed: { computed: {
// 是否使用fixed定位 (当height有值,则不使用) // 是否使用fixed定位 (当height有值,则不使用)
isFixed() { isFixed() {
return !this.height && this.fixed; return !this.height && this.fixed;
}, },
// mescroll的高度 // mescroll的高度
scrollHeight() { scrollHeight() {
if (this.isFixed) { if (this.isFixed) {
return 'auto'; return 'auto';
} else if (this.height) { } else if (this.height) {
return this.toPx(this.height) + 'px'; return this.toPx(this.height) + 'px';
} else { } else {
return '100%'; return '100%';
} }
}, },
// 下拉布局往下偏移的距离 (px) // 下拉布局往下偏移的距离 (px)
numTop() { numTop() {
// #ifdef H5 // #ifdef H5
return this.toPx(this.top) + (this.topbar ? this.statusBarHeight : 0); return this.toPx(this.top) + (this.topbar ? this.statusBarHeight : 0);
// #endif // #endif
// #ifdef MP // #ifdef MP
return this.toPx(this.top) + (this.topbar ? 44 + this.statusBarHeight : 0); return this.toPx(this.top) + (this.topbar ? 44 + this.statusBarHeight : 0);
// #endif // #endif
}, },
fixedTop() { fixedTop() {
return this.isFixed ? this.numTop + this.windowTop + 'px' : 0; return this.isFixed ? this.numTop + this.windowTop + 'px' : 0;
}, },
padTop() { padTop() {
return !this.isFixed ? this.numTop + 'px' : 0; return !this.isFixed ? this.numTop + 'px' : 0;
}, },
// 上拉布局往上偏移 (px) // 上拉布局往上偏移 (px)
numBottom() { numBottom() {
return this.toPx(this.bottom); return this.toPx(this.bottom);
}, },
fixedBottom() { fixedBottom() {
return this.isFixed ? this.numBottom + this.windowBottom + 'px' : 0; return this.isFixed ? this.numBottom + this.windowBottom + 'px' : 0;
}, },
fixedBottomConstant() { fixedBottomConstant() {
return this.safearea ? 'calc(' + this.fixedBottom + ' + constant(safe-area-inset-bottom))' : this return this.safearea ? 'calc(' + this.fixedBottom + ' + constant(safe-area-inset-bottom))' : this
.fixedBottom; .fixedBottom;
}, },
fixedBottomEnv() { fixedBottomEnv() {
return this.safearea ? 'calc(' + this.fixedBottom + ' + env(safe-area-inset-bottom))' : this.fixedBottom; return this.safearea ? 'calc(' + this.fixedBottom + ' + env(safe-area-inset-bottom))' : this.fixedBottom;
}, },
padBottom() { padBottom() {
return !this.isFixed ? this.numBottom + 'px' : 0; return !this.isFixed ? this.numBottom + 'px' : 0;
}, },
padBottomConstant() { padBottomConstant() {
return this.safearea ? 'calc(' + this.padBottom + ' + constant(safe-area-inset-bottom))' : this.padBottom; return this.safearea ? 'calc(' + this.padBottom + ' + constant(safe-area-inset-bottom))' : this.padBottom;
}, },
padBottomEnv() { padBottomEnv() {
return this.safearea ? 'calc(' + this.padBottom + ' + env(safe-area-inset-bottom))' : this.padBottom; return this.safearea ? 'calc(' + this.padBottom + ' + env(safe-area-inset-bottom))' : this.padBottom;
}, },
// 是否为重置下拉的状态 // 是否为重置下拉的状态
isDownReset() { isDownReset() {
return this.downLoadType === 3 || this.downLoadType === 4; return this.downLoadType === 3 || this.downLoadType === 4;
}, },
// 过渡 // 过渡
transition() { transition() {
return this.isDownReset ? 'transform 300ms' : ''; return this.isDownReset ? 'transform 300ms' : '';
}, },
translateY() { translateY() {
return this.downHight > 0 ? 'translateY(' + this.downHight + 'px)' : return this.downHight > 0 ? 'translateY(' + this.downHight + 'px)' :
''; // transform会使fixed失效,需注意把fixed元素写在mescroll之外 ''; // transform会使fixed失效,需注意把fixed元素写在mescroll之外
}, },
// 是否在加载中 // 是否在加载中
isDownLoading() { isDownLoading() {
return this.downLoadType === 3; return this.downLoadType === 3;
}, },
// 旋转的角度 // 旋转的角度
downRotate() { downRotate() {
return 'rotate(' + 360 * this.downRate + 'deg)'; return 'rotate(' + 360 * this.downRate + 'deg)';
}, },
// 文本提示 // 文本提示
downText() { downText() {
switch (this.downLoadType) { switch (this.downLoadType) {
case 1: case 1:
return this.mescroll.optDown.textInOffset; return this.mescroll.optDown.textInOffset;
case 2: case 2:
return this.mescroll.optDown.textOutOffset; return this.mescroll.optDown.textOutOffset;
case 3: case 3:
return this.mescroll.optDown.textLoading; return this.mescroll.optDown.textLoading;
case 4: case 4:
return this.mescroll.optDown.textLoading; return this.mescroll.optDown.textLoading;
default: default:
return this.mescroll.optDown.textInOffset; return this.mescroll.optDown.textInOffset;
} }
} }
}, },
methods: { methods: {
//number,rpx,upx,px,% --> px的数值 //number,rpx,upx,px,% --> px的数值
toPx(num) { toPx(num) {
if (typeof num === 'string') { if (typeof num === 'string') {
if (num.indexOf('px') !== -1) { if (num.indexOf('px') !== -1) {
if (num.indexOf('rpx') !== -1) { if (num.indexOf('rpx') !== -1) {
// "10rpx" // "10rpx"
num = num.replace('rpx', ''); num = num.replace('rpx', '');
} else if (num.indexOf('upx') !== -1) { } else if (num.indexOf('upx') !== -1) {
// "10upx" // "10upx"
num = num.replace('upx', ''); num = num.replace('upx', '');
} else { } else {
// "10px" // "10px"
return Number(num.replace('px', '')); return Number(num.replace('px', ''));
} }
} else if (num.indexOf('%') !== -1) { } else if (num.indexOf('%') !== -1) {
// 传百分比,则相对于windowHeight,传"10%"则等于windowHeight的10% // 传百分比,则相对于windowHeight,传"10%"则等于windowHeight的10%
let rate = Number(num.replace('%', '')) / 100; let rate = Number(num.replace('%', '')) / 100;
return this.windowHeight * rate; return this.windowHeight * rate;
} }
} }
return num ? uni.upx2px(Number(num)) : 0; return num ? uni.upx2px(Number(num)) : 0;
}, },
//注册列表滚动事件,用于下拉刷新和上拉加载 //注册列表滚动事件,用于下拉刷新和上拉加载
scroll(e) { scroll(e) {
this.mescroll.scroll(e.detail, () => { this.mescroll.scroll(e.detail, () => {
this.$emit('scroll', this this.$emit('scroll', this
.mescroll); // 此时可直接通过 this.mescroll.scrollTop获取滚动条位置; this.mescroll.isScrollUp获取是否向上滑动 .mescroll); // 此时可直接通过 this.mescroll.scrollTop获取滚动条位置; this.mescroll.isScrollUp获取是否向上滑动
}); });
}, },
//注册列表touchstart事件,用于下拉刷新 //注册列表touchstart事件,用于下拉刷新
touchstartEvent(e) { touchstartEvent(e) {
this.mescroll.touchstartEvent(e); this.mescroll.touchstartEvent(e);
}, },
//注册列表touchmove事件,用于下拉刷新 //注册列表touchmove事件,用于下拉刷新
touchmoveEvent(e) { touchmoveEvent(e) {
this.mescroll.touchmoveEvent(e); this.mescroll.touchmoveEvent(e);
}, },
//注册列表touchend事件,用于下拉刷新 //注册列表touchend事件,用于下拉刷新
touchendEvent(e) { touchendEvent(e) {
this.mescroll.touchendEvent(e); this.mescroll.touchendEvent(e);
}, },
// 点击空布局的按钮回调 // 点击空布局的按钮回调
emptyClick() { emptyClick() {
this.$emit('emptyclick', this.mescroll); this.$emit('emptyclick', this.mescroll);
}, },
// 点击回到顶部的按钮回调 // 点击回到顶部的按钮回调
toTopClick() { toTopClick() {
this.mescroll.scrollTo(0, this.mescroll.optUp.toTop.duration); // 执行回到顶部 this.mescroll.scrollTo(0, this.mescroll.optUp.toTop.duration); // 执行回到顶部
this.$emit('topclick', this.mescroll); // 派发点击回到顶部按钮的回调 this.$emit('topclick', this.mescroll); // 派发点击回到顶部按钮的回调
}, },
// 更新滚动区域的高度 (使内容不满屏和到底,都可继续翻页) // 更新滚动区域的高度 (使内容不满屏和到底,都可继续翻页)
setClientHeight() { setClientHeight() {
if (this.mescroll.getClientHeight(true) === 0 && !this.isExec) { if (this.mescroll.getClientHeight(true) === 0 && !this.isExec) {
this.isExec = true; // 避免多次获取 this.isExec = true; // 避免多次获取
this.$nextTick(() => { this.$nextTick(() => {
// 确保dom已渲染 // 确保dom已渲染
try { try {
let view = uni let view = uni
.createSelectorQuery() .createSelectorQuery()
.in(this) .in(this)
.select('#' + this.viewId); .select('#' + this.viewId);
view.boundingClientRect(data => { view.boundingClientRect(data => {
this.isExec = false; this.isExec = false;
if (data) { if (data) {
this.mescroll.setClientHeight(data.height); this.mescroll.setClientHeight(data.height);
} else if (this.clientNum != 3) { } else if (this.clientNum != 3) {
// 极少部分情况,可能dom还未渲染完毕,递归获取,最多重试3次 // 极少部分情况,可能dom还未渲染完毕,递归获取,最多重试3次
this.clientNum = this.clientNum == null ? 1 : this.clientNum + 1; this.clientNum = this.clientNum == null ? 1 : this.clientNum + 1;
setTimeout(() => { setTimeout(() => {
this.setClientHeight(); this.setClientHeight();
}, this.clientNum * 100); }, this.clientNum * 100);
} }
}).exec(); }).exec();
} catch (e) {} } catch (e) {}
}); });
} }
} }
}, },
// 使用created初始化mescroll对象; 如果用mounted部分css样式编译到H5会失效 // 使用created初始化mescroll对象; 如果用mounted部分css样式编译到H5会失效
created() { created() {
let vm = this; let vm = this;
let diyOption = { let diyOption = {
// 下拉刷新的配置 // 下拉刷新的配置
down: { down: {
inOffset(mescroll) { inOffset(mescroll) {
vm.downLoadType = 1; // 下拉的距离进入offset范围内那一刻的回调 (自定义mescroll组件时,此行不可删) vm.downLoadType = 1; // 下拉的距离进入offset范围内那一刻的回调 (自定义mescroll组件时,此行不可删)
}, },
outOffset(mescroll) { outOffset(mescroll) {
vm.downLoadType = 2; // 下拉的距离大于offset那一刻的回调 (自定义mescroll组件时,此行不可删) vm.downLoadType = 2; // 下拉的距离大于offset那一刻的回调 (自定义mescroll组件时,此行不可删)
}, },
onMoving(mescroll, rate, downHight) { onMoving(mescroll, rate, downHight) {
// 下拉过程中的回调,滑动过程一直在执行; // 下拉过程中的回调,滑动过程一直在执行;
vm.downHight = downHight; // 设置下拉区域的高度 (自定义mescroll组件时,此行不可删) vm.downHight = downHight; // 设置下拉区域的高度 (自定义mescroll组件时,此行不可删)
vm.downRate = rate; //下拉比率 (inOffset: rate<1; outOffset: rate>=1) vm.downRate = rate; //下拉比率 (inOffset: rate<1; outOffset: rate>=1)
}, },
showLoading(mescroll, downHight) { showLoading(mescroll, downHight) {
vm.downLoadType = 3; // 显示下拉刷新进度的回调 (自定义mescroll组件时,此行不可删) vm.downLoadType = 3; // 显示下拉刷新进度的回调 (自定义mescroll组件时,此行不可删)
vm.downHight = downHight; // 设置下拉区域的高度 (自定义mescroll组件时,此行不可删) vm.downHight = downHight; // 设置下拉区域的高度 (自定义mescroll组件时,此行不可删)
}, },
endDownScroll(mescroll) { endDownScroll(mescroll) {
vm.downLoadType = 4; // 结束下拉 (自定义mescroll组件时,此行不可删) vm.downLoadType = 4; // 结束下拉 (自定义mescroll组件时,此行不可删)
vm.downHight = 0; // 设置下拉区域的高度 (自定义mescroll组件时,此行不可删) vm.downHight = 0; // 设置下拉区域的高度 (自定义mescroll组件时,此行不可删)
}, },
// 派发下拉刷新的回调 // 派发下拉刷新的回调
callback: function(mescroll) { callback: function(mescroll) {
vm.$emit('down', mescroll); vm.$emit('down', mescroll);
} }
}, },
// 上拉加载的配置 // 上拉加载的配置
up: { up: {
// 显示加载中的回调 // 显示加载中的回调
showLoading() { showLoading() {
vm.upLoadType = 1; vm.upLoadType = 1;
}, },
// 显示无更多数据的回调 // 显示无更多数据的回调
showNoMore() { showNoMore() {
vm.upLoadType = 2; vm.upLoadType = 2;
}, },
// 隐藏上拉加载的回调 // 隐藏上拉加载的回调
hideUpScroll() { hideUpScroll() {
vm.upLoadType = 0; vm.upLoadType = 0;
}, },
// 空布局 // 空布局
empty: { empty: {
onShow(isShow) { onShow(isShow) {
// 显示隐藏的回调 // 显示隐藏的回调
vm.isShowEmpty = isShow; vm.isShowEmpty = isShow;
} }
}, },
// 回到顶部 // 回到顶部
toTop: { toTop: {
onShow(isShow) { onShow(isShow) {
// 显示隐藏的回调 // 显示隐藏的回调
vm.isShowToTop = isShow; vm.isShowToTop = isShow;
} }
}, },
// 派发上拉加载的回调 // 派发上拉加载的回调
callback: function(mescroll) { callback: function(mescroll) {
vm.$emit('up', mescroll); vm.$emit('up', mescroll);
// 更新容器的高度 (多mescroll的情况) // 更新容器的高度 (多mescroll的情况)
vm.setClientHeight(); vm.setClientHeight();
} }
} }
}; };
MeScroll.extend(diyOption, GlobalOption); // 混入全局的配置 MeScroll.extend(diyOption, GlobalOption); // 混入全局的配置
let myOption = JSON.parse( let myOption = JSON.parse(
JSON.stringify({ JSON.stringify({
down: vm.down, down: vm.down,
up: vm.up up: vm.up
}) })
); // 深拷贝,避免对props的影响 ); // 深拷贝,避免对props的影响
MeScroll.extend(myOption, diyOption); // 混入具体界面的配置 MeScroll.extend(myOption, diyOption); // 混入具体界面的配置
// 初始化MeScroll对象 // 初始化MeScroll对象
vm.mescroll = new MeScroll(myOption); vm.mescroll = new MeScroll(myOption);
vm.mescroll.viewId = vm.viewId; // 附带id vm.mescroll.viewId = vm.viewId; // 附带id
// init回调mescroll对象 // init回调mescroll对象
vm.$emit('init', vm.mescroll); vm.$emit('init', vm.mescroll);
// 设置高度 // 设置高度
const sys = uni.getSystemInfoSync(); const sys = uni.getSystemInfoSync();
if (sys.windowTop) vm.windowTop = sys.windowTop; if (sys.windowTop) vm.windowTop = sys.windowTop;
if (sys.windowBottom) vm.windowBottom = sys.windowBottom; if (sys.windowBottom) vm.windowBottom = sys.windowBottom;
if (sys.windowHeight) vm.windowHeight = sys.windowHeight; if (sys.windowHeight) vm.windowHeight = sys.windowHeight;
if (sys.statusBarHeight) vm.statusBarHeight = sys.statusBarHeight; if (sys.statusBarHeight) vm.statusBarHeight = sys.statusBarHeight;
// 使down的bottomOffset生效 // 使down的bottomOffset生效
vm.mescroll.setBodyHeight(sys.windowHeight); vm.mescroll.setBodyHeight(sys.windowHeight);
// 因为使用的是scrollview,这里需自定义scrollTo // 因为使用的是scrollview,这里需自定义scrollTo
vm.mescroll.resetScrollTo((y, t) => { vm.mescroll.resetScrollTo((y, t) => {
let curY = vm.mescroll.getScrollTop(); let curY = vm.mescroll.getScrollTop();
vm.scrollAnim = t !== 0; // t为0,则不使用动画过渡 vm.scrollAnim = t !== 0; // t为0,则不使用动画过渡
if (t === 0 || t === 300) { if (t === 0 || t === 300) {
// 当t使用默认配置的300时,则使用系统自带的动画过渡 // 当t使用默认配置的300时,则使用系统自带的动画过渡
vm.scrollTop = curY; vm.scrollTop = curY;
vm.$nextTick(function() { vm.$nextTick(function() {
vm.scrollTop = y; vm.scrollTop = y;
}); });
} else { } else {
vm.mescroll.getStep( vm.mescroll.getStep(
curY, curY,
y, y,
step => { step => {
// 此写法可支持配置t // 此写法可支持配置t
vm.scrollTop = step; vm.scrollTop = step;
}, },
t t
); );
} }
}); });
// 具体的界面如果不配置up.toTop.safearea,则取本vue的safearea值 // 具体的界面如果不配置up.toTop.safearea,则取本vue的safearea值
if (vm.up && vm.up.toTop && vm.up.toTop.safearea != null) {} else { if (vm.up && vm.up.toTop && vm.up.toTop.safearea != null) {} else {
vm.mescroll.optUp.toTop.safearea = vm.safearea; vm.mescroll.optUp.toTop.safearea = vm.safearea;
} }
}, },
mounted() { mounted() {
// 设置容器的高度 // 设置容器的高度
this.setClientHeight(); this.setClientHeight();
} }
}; };
</script> </script>
<style> <style lang="scss">
@import './mescroll-uni.css'; @import './mescroll-uni.css';
@import './components/mescroll-down.css'; @import './components/mescroll-down.css';
@import './components/mescroll-up.css'; @import './components/mescroll-up.css';
</style> </style>

View File

@@ -164,7 +164,7 @@
} }
}; };
</script> </script>
<style scoped> <style lang="scss" scoped>
.register-box /deep/ .uni-scroll-view { .register-box /deep/ .uni-scroll-view {
background: unset !important; background: unset !important;
} }

View File

@@ -1,33 +1,33 @@
<template> <template>
<view class="ns-goods-action bottom-safe-area" :class="{ 'bottom-safe-area': safeArea }"><slot></slot></view> <view class="ns-goods-action bottom-safe-area" :class="{ 'bottom-safe-area': safeArea }"><slot></slot></view>
</template> </template>
<script> <script>
export default { export default {
name: 'ns-goods-action', name: 'ns-goods-action',
props: { props: {
safeArea: { safeArea: {
type: Boolean, type: Boolean,
default: false default: false
} }
} }
}; };
</script> </script>
<style> <style lang="scss">
.ns-goods-action { .ns-goods-action {
position: fixed; position: fixed;
right: 0; right: 0;
bottom: 0; bottom: 0;
left: 0; left: 0;
display: flex; display: flex;
align-items: center; align-items: center;
background-color: #fff; background-color: #fff;
z-index: 9; z-index: 9;
} }
.ns-goods-action.bottom-safe-area { .ns-goods-action.bottom-safe-area {
padding-bottom: 0; padding-bottom: 0;
padding-bottom: constant(safe-area-inset-bottom); padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom); padding-bottom: env(safe-area-inset-bottom);
} }
</style> </style>

View File

@@ -768,7 +768,7 @@
} }
} }
</style> </style>
<style scoped> <style lang="scss" scoped>
/deep/ .reward-popup .uni-popup__wrapper-box { /deep/ .reward-popup .uni-popup__wrapper-box {
background: none !important; background: none !important;
max-width: unset !important; max-width: unset !important;

View File

@@ -171,7 +171,7 @@
}; };
</script> </script>
<style scoped> <style lang="scss" scoped>
/deep/ .newgift-content uni-image { /deep/ .newgift-content uni-image {
width: 113rpx !important; width: 113rpx !important;
height: 24rpx !important; height: 24rpx !important;

View File

@@ -1,69 +1,69 @@
<template> <template>
<view> <view>
<view class="weui-switch" :class="{ 'weui-switch-on': checked, 'color-base-border': checked }" @click="change()"> <view class="weui-switch" :class="{ 'weui-switch-on': checked, 'color-base-border': checked }" @click="change()">
<view class="bgview" :class="{ 'color-base-bg': checked }"></view> <view class="bgview" :class="{ 'color-base-bg': checked }"></view>
<view class="spotview"></view> <view class="spotview"></view>
</view> </view>
</view> </view>
</template> </template>
<script> <script>
export default { export default {
name: 'nsSwitch', name: 'nsSwitch',
props: { props: {
checked: { checked: {
type: Boolean, type: Boolean,
default: false default: false
} }
}, },
methods: { methods: {
change() { change() {
this.$emit('change'); this.$emit('change');
} }
} }
}; };
</script> </script>
<style> <style lang="scss">
.weui-switch { .weui-switch {
display: block; display: block;
position: relative; position: relative;
width: 94rpx; width: 94rpx;
height: 45rpx; height: 45rpx;
outline: 0; outline: 0;
border-radius: 30rpx; border-radius: 30rpx;
border: 2rpx solid; border: 2rpx solid;
border-color: #dfdfdf; border-color: #dfdfdf;
transition: background-color 0.1s, border 0.1s; transition: background-color 0.1s, border 0.1s;
} }
.weui-switch .bgview { .weui-switch .bgview {
content: ' '; content: ' ';
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; left: 0;
width: 94rpx; width: 94rpx;
height: 45rpx; height: 45rpx;
border-radius: 30rpx; border-radius: 30rpx;
transition: transform 0.35s cubic-bezier(0.45, 1, 0.4, 1); transition: transform 0.35s cubic-bezier(0.45, 1, 0.4, 1);
} }
.weui-switch .spotview { .weui-switch .spotview {
content: ' '; content: ' ';
position: absolute; position: absolute;
top: 2rpx; top: 2rpx;
left: 4rpx; left: 4rpx;
width: 40rpx; width: 40rpx;
height: 40rpx; height: 40rpx;
border-radius: 50%; border-radius: 50%;
background-color: #ffffff; background-color: #ffffff;
box-shadow: 0 2rpx 6rpx rgba(0, 0, 0, 0.4); box-shadow: 0 2rpx 6rpx rgba(0, 0, 0, 0.4);
transition: transform 0.35s cubic-bezier(0.4, 0.4, 0.25, 1.35); transition: transform 0.35s cubic-bezier(0.4, 0.4, 0.25, 1.35);
} }
.weui-switch-on { .weui-switch-on {
border-color: #6f6f6f; border-color: #6f6f6f;
} }
.weui-switch-on .bgview { .weui-switch-on .bgview {
border-color: #1aad19; border-color: #1aad19;
} }
.weui-switch-on .spotview { .weui-switch-on .spotview {
transform: translateX(48rpx); transform: translateX(48rpx);
} }
</style> </style>

View File

@@ -150,7 +150,7 @@
} }
}; };
</script> </script>
<style scoped> <style lang="scss" scoped>
.register-box /deep/ .uni-scroll-view { .register-box /deep/ .uni-scroll-view {
background: unset !important; background: unset !important;
} }

View File

@@ -1,58 +1,58 @@
<!-- 回到顶部的按钮 --> <!-- 回到顶部的按钮 -->
<template> <template>
<image <image
class="mescroll-totop" class="mescroll-totop"
:class="[value ? 'mescroll-totop-in' : 'mescroll-totop-out']" :class="[value ? 'mescroll-totop-in' : 'mescroll-totop-out']"
:src="$util.img('public/uniapp/common/mescroll-totop.png')" :src="$util.img('public/uniapp/common/mescroll-totop.png')"
mode="widthFix" mode="widthFix"
@click="toTopClick" @click="toTopClick"
/> />
</template> </template>
<script> <script>
export default { export default {
data() { data() {
return { return {
value: true value: true
}; };
}, },
methods: { methods: {
toTopClick() { toTopClick() {
this.$emit('toTop'); // 派发点击事件 this.$emit('toTop'); // 派发点击事件
} }
} }
}; };
</script> </script>
<style> <style lang="scss">
/* 回到顶部的按钮 */ /* 回到顶部的按钮 */
.mescroll-totop { .mescroll-totop {
z-index: 99; z-index: 99;
position: fixed !important; /* 加上important避免编译到H5,在多mescroll中定位失效 */ position: fixed !important; /* 加上important避免编译到H5,在多mescroll中定位失效 */
right: 46rpx !important; right: 46rpx !important;
bottom: 272rpx !important; bottom: 272rpx !important;
width: 72rpx; width: 72rpx;
height: 72rpx; height: 72rpx;
border-radius: 50%; border-radius: 50%;
opacity: 0; opacity: 0;
transition: opacity 0.5s; /* 过渡 */ transition: opacity 0.5s; /* 过渡 */
margin-bottom: var(--window-bottom); /* css变量 */ margin-bottom: var(--window-bottom); /* css变量 */
} }
/* 适配 iPhoneX */ /* 适配 iPhoneX */
.mescroll-safe-bottom { .mescroll-safe-bottom {
margin-bottom: calc(var(--window-bottom) + constant(safe-area-inset-bottom)); /* window-bottom + 适配 iPhoneX */ margin-bottom: calc(var(--window-bottom) + constant(safe-area-inset-bottom)); /* window-bottom + 适配 iPhoneX */
margin-bottom: calc(var(--window-bottom) + env(safe-area-inset-bottom)); margin-bottom: calc(var(--window-bottom) + env(safe-area-inset-bottom));
} }
/* 显示 -- 淡入 */ /* 显示 -- 淡入 */
.mescroll-totop-in { .mescroll-totop-in {
opacity: 1; opacity: 1;
} }
/* 隐藏 -- 淡出且不接收事件*/ /* 隐藏 -- 淡出且不接收事件*/
.mescroll-totop-out { .mescroll-totop-out {
opacity: 0; opacity: 0;
pointer-events: none; pointer-events: none;
} }
</style> </style>

View File

@@ -1,105 +1,105 @@
<template> <template>
<text <text
v-if="text" v-if="text"
:class="inverted ? 'uni-badge-' + type + ' uni-badge--' + size + ' uni-badge-inverted' : 'uni-badge-' + type + ' uni-badge--' + size" :class="inverted ? 'uni-badge-' + type + ' uni-badge--' + size + ' uni-badge-inverted' : 'uni-badge-' + type + ' uni-badge--' + size"
class="uni-badge" class="uni-badge"
@click="onClick()" @click="onClick()"
> >
{{ text }} {{ text }}
</text> </text>
</template> </template>
<script> <script>
export default { export default {
name: 'UniBadge', name: 'UniBadge',
props: { props: {
type: { type: {
type: String, type: String,
default: 'default' default: 'default'
}, },
inverted: { inverted: {
type: Boolean, type: Boolean,
default: false default: false
}, },
text: { text: {
type: String, type: String,
default: '' default: ''
}, },
size: { size: {
// small.normal // small.normal
type: String, type: String,
default: 'normal' default: 'normal'
} }
}, },
methods: { methods: {
onClick() { onClick() {
this.$emit('click'); this.$emit('click');
} }
} }
}; };
</script> </script>
<style> <style lang="scss">
.uni-badge { .uni-badge {
font-family: 'Helvetica Neue', Helvetica, sans-serif; font-family: 'Helvetica Neue', Helvetica, sans-serif;
box-sizing: border-box; box-sizing: border-box;
font-size: 24rpx; font-size: 24rpx;
line-height: 1; line-height: 1;
display: inline-block; display: inline-block;
padding: 6rpx 12rpx; padding: 6rpx 12rpx;
color: #333; color: #333;
border-radius: 200rpx; border-radius: 200rpx;
background-color: #e5e5e5; background-color: #e5e5e5;
} }
.uni-badge.uni-badge-inverted { .uni-badge.uni-badge-inverted {
padding: 0 10rpx 0 0; padding: 0 10rpx 0 0;
color: #999; color: #999;
background-color: transparent; background-color: transparent;
} }
.uni-badge-primary { .uni-badge-primary {
color: #fff; color: #fff;
background-color: #007aff; background-color: #007aff;
} }
.uni-badge-primary.uni-badge-inverted { .uni-badge-primary.uni-badge-inverted {
color: #007aff; color: #007aff;
background-color: transparent; background-color: transparent;
} }
.uni-badge-success { .uni-badge-success {
color: #fff; color: #fff;
background-color: #4cd964; background-color: #4cd964;
} }
.uni-badge-success.uni-badge-inverted { .uni-badge-success.uni-badge-inverted {
color: #4cd964; color: #4cd964;
background-color: transparent; background-color: transparent;
} }
.uni-badge-warning { .uni-badge-warning {
color: #fff; color: #fff;
background-color: #f0ad4e; background-color: #f0ad4e;
} }
.uni-badge-warning.uni-badge-inverted { .uni-badge-warning.uni-badge-inverted {
color: #f0ad4e; color: #f0ad4e;
background-color: transparent; background-color: transparent;
} }
.uni-badge-error { .uni-badge-error {
color: #fff; color: #fff;
background-color: #dd524d; background-color: #dd524d;
} }
.uni-badge-error.uni-badge-inverted { .uni-badge-error.uni-badge-inverted {
color: #dd524d; color: #dd524d;
background-color: transparent; background-color: transparent;
} }
.uni-badge--small { .uni-badge--small {
transform: scale(0.8); transform: scale(0.8);
transform-origin: center center; transform-origin: center center;
} }
</style> </style>

View File

@@ -1,146 +1,146 @@
<template> <template>
<view v-if="visibleSync" :class="{ 'uni-drawer--visible': showDrawer, 'uni-drawer--right': rightMode }" class="uni-drawer" @touchmove.stop.prevent="moveHandle"> <view v-if="visibleSync" :class="{ 'uni-drawer--visible': showDrawer, 'uni-drawer--right': rightMode }" class="uni-drawer" @touchmove.stop.prevent="moveHandle">
<view class="uni-drawer__mask" @tap="close" ></view> <view class="uni-drawer__mask" @tap="close" ></view>
<view class="uni-drawer__content" :class="{ 'safe-area': isIphoneX }"><slot /></view> <view class="uni-drawer__content" :class="{ 'safe-area': isIphoneX }"><slot /></view>
</view> </view>
</template> </template>
<script> <script>
export default { export default {
name: 'UniDrawer', name: 'UniDrawer',
props: { props: {
/** /**
* 显示状态 * 显示状态
*/ */
visible: { visible: {
type: Boolean, type: Boolean,
default: false default: false
}, },
/** /**
* 显示模式(左、右),只在初始化生效 * 显示模式(左、右),只在初始化生效
*/ */
mode: { mode: {
type: String, type: String,
default: '' default: ''
}, },
/** /**
* 蒙层显示状态 * 蒙层显示状态
*/ */
mask: { mask: {
type: Boolean, type: Boolean,
default: true default: true
} }
}, },
data() { data() {
return { return {
visibleSync: false, visibleSync: false,
showDrawer: false, showDrawer: false,
rightMode: false, rightMode: false,
closeTimer: null, closeTimer: null,
watchTimer: null, watchTimer: null,
isIphoneX: false isIphoneX: false
}; };
}, },
watch: { watch: {
visible(val) { visible(val) {
clearTimeout(this.watchTimer); clearTimeout(this.watchTimer);
setTimeout(() => { setTimeout(() => {
this.showDrawer = val; this.showDrawer = val;
}, 100); }, 100);
if (this.visibleSync) { if (this.visibleSync) {
clearTimeout(this.closeTimer); clearTimeout(this.closeTimer);
} }
if (val) { if (val) {
this.visibleSync = val; this.visibleSync = val;
} else { } else {
this.watchTimer = setTimeout(() => { this.watchTimer = setTimeout(() => {
this.visibleSync = val; this.visibleSync = val;
}, 300); }, 300);
} }
} }
}, },
created() { created() {
this.isIphoneX = this.$util.uniappIsIPhoneX(); this.isIphoneX = this.$util.uniappIsIPhoneX();
this.visibleSync = this.visible; this.visibleSync = this.visible;
setTimeout(() => { setTimeout(() => {
this.showDrawer = this.visible; this.showDrawer = this.visible;
}, 100); }, 100);
this.rightMode = this.mode === 'right'; this.rightMode = this.mode === 'right';
}, },
methods: { methods: {
close() { close() {
this.showDrawer = false; this.showDrawer = false;
this.closeTimer = setTimeout(() => { this.closeTimer = setTimeout(() => {
this.visibleSync = false; this.visibleSync = false;
this.$emit('close'); this.$emit('close');
}, 200); }, 200);
}, },
moveHandle() {} moveHandle() {}
} }
}; };
</script> </script>
<style> <style lang="scss">
.uni-drawer { .uni-drawer {
display: block; display: block;
position: fixed; position: fixed;
top: 0; top: 0;
left: 0; left: 0;
right: 0; right: 0;
bottom: 0; bottom: 0;
overflow: hidden; overflow: hidden;
visibility: hidden; visibility: hidden;
z-index: 999; z-index: 999;
height: 100%; height: 100%;
} }
.uni-drawer.uni-drawer--right .uni-drawer__content { .uni-drawer.uni-drawer--right .uni-drawer__content {
left: auto; left: auto;
right: 0; right: 0;
transform: translatex(100%); transform: translatex(100%);
} }
.uni-drawer.uni-drawer--visible { .uni-drawer.uni-drawer--visible {
visibility: visible; visibility: visible;
} }
.uni-drawer.uni-drawer--visible .uni-drawer__content { .uni-drawer.uni-drawer--visible .uni-drawer__content {
transform: translatex(0); transform: translatex(0);
} }
.uni-drawer.uni-drawer--visible .uni-drawer__mask { .uni-drawer.uni-drawer--visible .uni-drawer__mask {
display: block; display: block;
opacity: 1; opacity: 1;
} }
.uni-drawer__mask { .uni-drawer__mask {
display: block; display: block;
opacity: 0; opacity: 0;
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; left: 0;
width: 100%; width: 100%;
height: 100%; height: 100%;
background: rgba(0, 0, 0, 0.4); background: rgba(0, 0, 0, 0.4);
transition: opacity 0.3s; transition: opacity 0.3s;
} }
.uni-drawer__content { .uni-drawer__content {
display: block; display: block;
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; left: 0;
width: 61.8%; width: 61.8%;
height: 100%; height: 100%;
background: #fff; background: #fff;
transition: all 0.3s ease-out; transition: all 0.3s ease-out;
transform: translatex(-100%); transform: translatex(-100%);
} }
.safe-area { .safe-area {
padding-bottom: 68rpx; padding-bottom: 68rpx;
padding-top: 44rpx; padding-top: 44rpx;
box-sizing: border-box; box-sizing: border-box;
} }
</style> </style>

View File

@@ -1,223 +1,223 @@
<template> <template>
<view v-if="width" :style="{ width: width }" class="uni-grid-item"> <view v-if="width" :style="{ width: width }" class="uni-grid-item">
<view <view
:class="{ border: showBorder, 'uni-grid-item__box-square': square, 'border-top': showBorder && index < column, 'uni-highlight': highlight }" :class="{ border: showBorder, 'uni-grid-item__box-square': square, 'border-top': showBorder && index < column, 'uni-highlight': highlight }"
:style="{ 'border-color': borderColor }" :style="{ 'border-color': borderColor }"
class="uni-grid-item__box" class="uni-grid-item__box"
@click="_onClick" @click="_onClick"
> >
<view v-if="marker === 'dot'" :style="{ left: top * 2 + 'rpx', top: left * 2 + 'rpx' }" class="uni-grid-item__box-dot" /> <view v-if="marker === 'dot'" :style="{ left: top * 2 + 'rpx', top: left * 2 + 'rpx' }" class="uni-grid-item__box-dot" />
<view v-if="marker === 'badge'" :style="{ left: top * 2 + 'rpx', top: left * 2 + 'rpx' }" class="uni-grid-item__box-badge"> <view v-if="marker === 'badge'" :style="{ left: top * 2 + 'rpx', top: left * 2 + 'rpx' }" class="uni-grid-item__box-badge">
<uni-badge :text="text" :type="type" :size="size" :inverted="inverted" /> <uni-badge :text="text" :type="type" :size="size" :inverted="inverted" />
</view> </view>
<view v-if="marker === 'image'" :style="{ left: top * 2 + 'rpx', top: left * 2 + 'rpx' }" class="uni-grid-item__box-image"> <view v-if="marker === 'image'" :style="{ left: top * 2 + 'rpx', top: left * 2 + 'rpx' }" class="uni-grid-item__box-image">
<image :style="{ width: imgWidth * 2 + 'rpx' }" :src="src" class="box-image" mode="widthFix" /> <image :style="{ width: imgWidth * 2 + 'rpx' }" :src="src" class="box-image" mode="widthFix" />
</view> </view>
<view class="uni-grid-item__box-item"><slot /></view> <view class="uni-grid-item__box-item"><slot /></view>
</view> </view>
</view> </view>
</template> </template>
<script> <script>
import uniBadge from '@/components/uni-badge/uni-badge.vue'; import uniBadge from '@/components/uni-badge/uni-badge.vue';
export default { export default {
name: 'UniGridItem', name: 'UniGridItem',
components: { components: {
uniBadge uniBadge
}, },
props: { props: {
// 类型可选值dot圆点badge角标image图片 // 类型可选值dot圆点badge角标image图片
marker: { marker: {
type: String, type: String,
default: '' default: ''
}, },
// 水平方向 // 水平方向
hor: { hor: {
type: Number, type: Number,
default: 0 default: 0
}, },
// 垂直方向 // 垂直方向
ver: { ver: {
type: Number, type: Number,
default: 0 default: 0
}, },
// badge 下颜色类型可选值default灰色、primary蓝色、success绿色、warning(黄色)、error(红色) // badge 下颜色类型可选值default灰色、primary蓝色、success绿色、warning(黄色)、error(红色)
type: { type: {
type: String, type: String,
default: '' default: ''
}, },
// badge 下显示内容汉字最多为1个 // badge 下显示内容汉字最多为1个
text: { text: {
type: String, type: String,
default: '' default: ''
}, },
// badge 下 Badge 大小 // badge 下 Badge 大小
size: { size: {
type: String, type: String,
default: 'normal' default: 'normal'
}, },
// badge 下 是否无需背景颜色 // badge 下 是否无需背景颜色
inverted: { inverted: {
type: Boolean, type: Boolean,
default: false default: false
}, },
// image 下图片路径 // image 下图片路径
src: { src: {
type: String, type: String,
default: '' default: ''
}, },
// image 下图片宽度 ,最大 为 100 。 默认为 30 // image 下图片宽度 ,最大 为 100 。 默认为 30
imgWidth: { imgWidth: {
type: Number, type: Number,
default: 30 default: 30
} }
}, },
inject: ['grid'], inject: ['grid'],
data() { data() {
return { return {
column: 0, column: 0,
showBorder: true, showBorder: true,
square: true, square: true,
highlight: true, highlight: true,
left: 0, left: 0,
top: 0, top: 0,
index: 0, index: 0,
openNum: 2, openNum: 2,
width: 0, width: 0,
borderColor: '#e5e5e5' borderColor: '#e5e5e5'
}; };
}, },
created() { created() {
this.column = this.grid.column; this.column = this.grid.column;
this.showBorder = this.grid.showBorder; this.showBorder = this.grid.showBorder;
this.square = this.grid.square; this.square = this.grid.square;
this.highlight = this.grid.highlight; this.highlight = this.grid.highlight;
this.top = this.hor === 0 ? this.grid.hor : this.hor; this.top = this.hor === 0 ? this.grid.hor : this.hor;
this.left = this.ver === 0 ? this.grid.ver : this.ver; this.left = this.ver === 0 ? this.grid.ver : this.ver;
this.borderColor = this.grid.borderColor; this.borderColor = this.grid.borderColor;
this.index = this.grid.index++; this.index = this.grid.index++;
}, },
// #ifdef H5 // #ifdef H5
mounted() { mounted() {
this.grid._getSize(width => { this.grid._getSize(width => {
this.width = width; this.width = width;
}); });
}, },
// #endif // #endif
// #ifndef H5 // #ifndef H5
onReady() { onReady() {
this.grid._getSize(width => { this.grid._getSize(width => {
this.width = width; this.width = width;
}); });
}, },
// #endif // #endif
methods: { methods: {
_onClick() { _onClick() {
this.grid.change({ this.grid.change({
detail: { detail: {
index: this.index index: this.index
} }
}); });
} }
} }
}; };
</script> </script>
<style> <style lang="scss">
.uni-grid-item { .uni-grid-item {
box-sizing: border-box; box-sizing: border-box;
} }
.uni-grid-item__box { .uni-grid-item__box {
position: relative; position: relative;
width: 100%; width: 100%;
} }
.uni-grid-item__box-item { .uni-grid-item__box-item {
display: flex; display: flex;
justify-content: center; justify-content: center;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
width: 100%; width: 100%;
height: 100%; height: 100%;
font-size: 32rpx; font-size: 32rpx;
color: #666; color: #666;
padding: 20rpx 0; padding: 20rpx 0;
box-sizing: border-box; box-sizing: border-box;
} }
.uni-grid-item__box-item .image { .uni-grid-item__box-item .image {
width: 50rpx; width: 50rpx;
height: 50rpx; height: 50rpx;
} }
.uni-grid-item__box-item .text { .uni-grid-item__box-item .text {
font-size: 26rpx; font-size: 26rpx;
margin-top: 10rpx; margin-top: 10rpx;
} }
.uni-grid-item__box.uni-grid-item__box-square { .uni-grid-item__box.uni-grid-item__box-square {
height: 0; height: 0;
padding-top: 100%; padding-top: 100%;
} }
.uni-grid-item__box.uni-grid-item__box-square .uni-grid-item__box-item { .uni-grid-item__box.uni-grid-item__box-square .uni-grid-item__box-item {
position: absolute; position: absolute;
top: 0; top: 0;
} }
.uni-grid-item__box.border { .uni-grid-item__box.border {
position: relative; position: relative;
box-sizing: border-box; box-sizing: border-box;
border-bottom: 2rpx #e5e5e5 solid; border-bottom: 2rpx #e5e5e5 solid;
border-right: 2rpx #e5e5e5 solid; border-right: 2rpx #e5e5e5 solid;
} }
.uni-grid-item__box.border-top { .uni-grid-item__box.border-top {
border-top: 2rpx #e5e5e5 solid; border-top: 2rpx #e5e5e5 solid;
} }
.uni-grid-item__box.uni-highlight:active { .uni-grid-item__box.uni-highlight:active {
background-color: #eee; background-color: #eee;
} }
.uni-grid-item__box-badge, .uni-grid-item__box-badge,
.uni-grid-item__box-dot, .uni-grid-item__box-dot,
.uni-grid-item__box-image { .uni-grid-item__box-image {
position: absolute; position: absolute;
top: 0; top: 0;
right: 0; right: 0;
left: 0; left: 0;
bottom: 0; bottom: 0;
margin: auto; margin: auto;
z-index: 10; z-index: 10;
} }
.uni-grid-item__box-dot { .uni-grid-item__box-dot {
width: 20rpx; width: 20rpx;
height: 20rpx; height: 20rpx;
background: #ff5a5f; background: #ff5a5f;
border-radius: 50%; border-radius: 50%;
} }
.uni-grid-item__box-badge { .uni-grid-item__box-badge {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
width: 0; width: 0;
height: 0; height: 0;
} }
.uni-grid-item__box-image { .uni-grid-item__box-image {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
width: 100rpx; width: 100rpx;
height: 100rpx; height: 100rpx;
overflow: hidden; overflow: hidden;
} }
.uni-grid-item__box-image .box-image { .uni-grid-item__box-image .box-image {
width: 90rpx; width: 90rpx;
} }
</style> </style>

View File

@@ -84,7 +84,7 @@ export default {
}; };
</script> </script>
<style> <style lang="scss">
.uni-grid { .uni-grid {
display: flex; display: flex;

View File

@@ -1,221 +1,221 @@
<template> <template>
<view v-if="showPopup" class="uni-popup"> <view v-if="showPopup" class="uni-popup">
<view :class="[ani, animation ? 'ani' : '', !custom ? 'uni-custom' : '']" class="uni-popup__mask" @click="close(true)" ></view> <view :class="[ani, animation ? 'ani' : '', !custom ? 'uni-custom' : '']" class="uni-popup__mask" @click="close(true)" ></view>
<view :class="[type, ani, animation ? 'ani' : '', !custom ? 'uni-custom' : '']" class="uni-popup__wrapper goodslist-uni-popup safe-area" @click="close(true)" v-if="isIphoneX"> <view :class="[type, ani, animation ? 'ani' : '', !custom ? 'uni-custom' : '']" class="uni-popup__wrapper goodslist-uni-popup safe-area" @click="close(true)" v-if="isIphoneX">
<view class="uni-popup__wrapper-box goodslist-uni-popup-box" @click.stop="clear"><slot /></view> <view class="uni-popup__wrapper-box goodslist-uni-popup-box" @click.stop="clear"><slot /></view>
</view> </view>
<view :class="[type, ani, animation ? 'ani' : '', !custom ? 'uni-custom' : '']" class="uni-popup__wrapper goodslist-uni-popup" @click="close(true)" v-else> <view :class="[type, ani, animation ? 'ani' : '', !custom ? 'uni-custom' : '']" class="uni-popup__wrapper goodslist-uni-popup" @click="close(true)" v-else>
<view class="uni-popup__wrapper-box goodslist-uni-popup-box" @click.stop="clear"><slot /></view> <view class="uni-popup__wrapper-box goodslist-uni-popup-box" @click.stop="clear"><slot /></view>
</view> </view>
</view> </view>
</template> </template>
<script> <script>
export default { export default {
name: 'UniPopup', name: 'UniPopup',
props: { props: {
// 开启动画 // 开启动画
animation: { animation: {
type: Boolean, type: Boolean,
default: true default: true
}, },
// 弹出层类型可选值top: 顶部弹出层bottom底部弹出层center全屏弹出层 // 弹出层类型可选值top: 顶部弹出层bottom底部弹出层center全屏弹出层
type: { type: {
type: String, type: String,
default: 'center' default: 'center'
}, },
// 是否开启自定义 // 是否开启自定义
custom: { custom: {
type: Boolean, type: Boolean,
default: false default: false
}, },
// maskClick // maskClick
maskClick: { maskClick: {
type: Boolean, type: Boolean,
default: true default: true
}, },
show: { show: {
type: Boolean, type: Boolean,
default: true default: true
} }
}, },
data() { data() {
return { return {
ani: '', ani: '',
showPopup: false, showPopup: false,
callback: null, callback: null,
isIphoneX: false isIphoneX: false
}; };
}, },
watch: { watch: {
show(newValue) { show(newValue) {
if (newValue) { if (newValue) {
this.open(); this.open();
} else { } else {
this.close(); this.close();
} }
} }
}, },
created() { created() {
this.isIphoneX = this.$util.uniappIsIPhoneX(); this.isIphoneX = this.$util.uniappIsIPhoneX();
}, },
methods: { methods: {
clear() {}, clear() {},
open(callback) { open(callback) {
if (callback) this.callback = callback; if (callback) this.callback = callback;
this.$emit('change', { this.$emit('change', {
show: true show: true
}); });
this.showPopup = true; this.showPopup = true;
this.$nextTick(() => { this.$nextTick(() => {
setTimeout(() => { setTimeout(() => {
this.ani = 'uni-' + this.type; this.ani = 'uni-' + this.type;
}, 30); }, 30);
}); });
}, },
close(type, callback) { close(type, callback) {
if (!this.maskClick && type) return; if (!this.maskClick && type) return;
this.$emit('change', { this.$emit('change', {
show: false show: false
}); });
this.ani = ''; this.ani = '';
this.$nextTick(() => { this.$nextTick(() => {
setTimeout(() => { setTimeout(() => {
this.showPopup = false; this.showPopup = false;
}, 300); }, 300);
}); });
if (callback) callback(); if (callback) callback();
if (this.callback) this.callback.call(this); if (this.callback) this.callback.call(this);
} }
} }
}; };
</script> </script>
<style> <style lang="scss">
.uni-popup { .uni-popup {
position: fixed; position: fixed;
top: 0; top: 0;
bottom: 0; bottom: 0;
left: 0; left: 0;
right: 0; right: 0;
z-index: 999; z-index: 999;
overflow: hidden; overflow: hidden;
} }
.uni-popup__mask { .uni-popup__mask {
position: absolute; position: absolute;
top: 0; top: 0;
bottom: 0; bottom: 0;
left: 0; left: 0;
right: 0; right: 0;
z-index: 998; z-index: 998;
background: rgba(0, 0, 0, 0.4); background: rgba(0, 0, 0, 0.4);
opacity: 0; opacity: 0;
} }
.uni-popup__mask.ani { .uni-popup__mask.ani {
transition: all 0.3s; transition: all 0.3s;
} }
.uni-popup__mask.uni-bottom, .uni-popup__mask.uni-bottom,
.uni-popup__mask.uni-center, .uni-popup__mask.uni-center,
.uni-popup__mask.uni-right, .uni-popup__mask.uni-right,
.uni-popup__mask.uni-left, .uni-popup__mask.uni-left,
.uni-popup__mask.uni-top { .uni-popup__mask.uni-top {
opacity: 1; opacity: 1;
} }
.uni-popup__wrapper { .uni-popup__wrapper {
position: absolute; position: absolute;
z-index: 999; z-index: 999;
box-sizing: border-box; box-sizing: border-box;
//background: #ffffff; //background: #ffffff;
} }
.uni-popup__wrapper.ani { .uni-popup__wrapper.ani {
transition: all 0.3s; transition: all 0.3s;
} }
.uni-popup__wrapper.top { .uni-popup__wrapper.top {
top: 0; top: 0;
left: 0; left: 0;
width: 100%; width: 100%;
transform: translateY(-100%); transform: translateY(-100%);
} }
.uni-popup__wrapper.bottom { .uni-popup__wrapper.bottom {
bottom: 0; bottom: 0;
left: 0; left: 0;
width: 100%; width: 100%;
transform: translateY(100%); transform: translateY(100%);
} }
.uni-popup__wrapper.right { .uni-popup__wrapper.right {
bottom: 0; bottom: 0;
left: 0; left: 0;
width: 100%; width: 100%;
transform: translateX(100%); transform: translateX(100%);
} }
.uni-popup__wrapper.left { .uni-popup__wrapper.left {
bottom: 0; bottom: 0;
left: 0; left: 0;
width: 100%; width: 100%;
transform: translateX(-100%); transform: translateX(-100%);
} }
.uni-popup__wrapper.center { .uni-popup__wrapper.center {
width: 100%; width: 100%;
height: 100%; height: 100%;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
transform: scale(1.2); transform: scale(1.2);
opacity: 0; opacity: 0;
} }
.uni-popup__wrapper-box { .uni-popup__wrapper-box {
position: relative; position: relative;
box-sizing: border-box; box-sizing: border-box;
} }
.uni-popup__wrapper.uni-custom .uni-popup__wrapper-box { .uni-popup__wrapper.uni-custom .uni-popup__wrapper-box {
//background: #fff; //background: #fff;
} }
.uni-popup__wrapper.uni-custom.center .uni-popup__wrapper-box { .uni-popup__wrapper.uni-custom.center .uni-popup__wrapper-box {
position: relative; position: relative;
max-width: 80%; max-width: 80%;
max-height: 80%; max-height: 80%;
overflow-y: scroll; overflow-y: scroll;
} }
.uni-popup__wrapper.uni-custom.bottom .uni-popup__wrapper-box, .uni-popup__wrapper.uni-custom.bottom .uni-popup__wrapper-box,
.uni-popup__wrapper.uni-custom.top .uni-popup__wrapper-box { .uni-popup__wrapper.uni-custom.top .uni-popup__wrapper-box {
width: 100%; width: 100%;
max-height: 500px; max-height: 500px;
overflow-y: scroll; overflow-y: scroll;
} }
.uni-popup__wrapper.uni-bottom, .uni-popup__wrapper.uni-bottom,
.uni-popup__wrapper.uni-top { .uni-popup__wrapper.uni-top {
transform: translateY(0); transform: translateY(0);
} }
.uni-popup__wrapper.uni-left, .uni-popup__wrapper.uni-left,
.uni-popup__wrapper.uni-right { .uni-popup__wrapper.uni-right {
transform: translateX(0); transform: translateX(0);
} }
.uni-popup__wrapper.uni-center { .uni-popup__wrapper.uni-center {
transform: scale(1); transform: scale(1);
opacity: 1; opacity: 1;
} }
/* isIphoneX系列手机底部安全距离 */ /* isIphoneX系列手机底部安全距离 */
.bottom.safe-area { .bottom.safe-area {
padding-bottom: constant(safe-area-inset-bottom); padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom); padding-bottom: env(safe-area-inset-bottom);
} }
</style> </style>

View File

@@ -1,222 +1,222 @@
<template> <template>
<view v-if="showPopup" class="uni-popup"> <view v-if="showPopup" class="uni-popup">
<view :class="[ani, animation ? 'ani' : '', !custom ? 'uni-custom' : '']" class="uni-popup__mask" @click="close(true)" ></view> <view :class="[ani, animation ? 'ani' : '', !custom ? 'uni-custom' : '']" class="uni-popup__mask" @click="close(true)" ></view>
<view :class="[type, ani, animation ? 'ani' : '', !custom ? 'uni-custom' : '']" class="uni-popup__wrapper safe-area" @click="close(true)" v-if="isIphoneX"> <view :class="[type, ani, animation ? 'ani' : '', !custom ? 'uni-custom' : '']" class="uni-popup__wrapper safe-area" @click="close(true)" v-if="isIphoneX">
<view class="uni-popup__wrapper-box" @click.stop="clear"><slot /></view> <view class="uni-popup__wrapper-box" @click.stop="clear"><slot /></view>
</view> </view>
<view :class="[type, ani, animation ? 'ani' : '', !custom ? 'uni-custom' : '']" class="uni-popup__wrapper" @click="close(true)" v-else> <view :class="[type, ani, animation ? 'ani' : '', !custom ? 'uni-custom' : '']" class="uni-popup__wrapper" @click="close(true)" v-else>
<view class="uni-popup__wrapper-box" @click.stop="clear"><slot /></view> <view class="uni-popup__wrapper-box" @click.stop="clear"><slot /></view>
</view> </view>
</view> </view>
</template> </template>
<script> <script>
export default { export default {
name: 'UniPopup', name: 'UniPopup',
props: { props: {
// 开启动画 // 开启动画
animation: { animation: {
type: Boolean, type: Boolean,
default: true default: true
}, },
// 弹出层类型可选值top: 顶部弹出层bottom底部弹出层center全屏弹出层 // 弹出层类型可选值top: 顶部弹出层bottom底部弹出层center全屏弹出层
type: { type: {
type: String, type: String,
default: 'center' default: 'center'
}, },
// 是否开启自定义 // 是否开启自定义
custom: { custom: {
type: Boolean, type: Boolean,
default: false default: false
}, },
// maskClick // maskClick
maskClick: { maskClick: {
type: Boolean, type: Boolean,
default: true default: true
}, },
show: { show: {
type: Boolean, type: Boolean,
default: true default: true
} }
}, },
data() { data() {
return { return {
ani: '', ani: '',
showPopup: false, showPopup: false,
callback: null, callback: null,
isIphoneX: false isIphoneX: false
}; };
}, },
watch: { watch: {
show(newValue) { show(newValue) {
if (newValue) { if (newValue) {
this.open(); this.open();
} else { } else {
this.close(); this.close();
} }
} }
}, },
created() { created() {
this.isIphoneX = this.$util.uniappIsIPhoneX(); this.isIphoneX = this.$util.uniappIsIPhoneX();
}, },
methods: { methods: {
clear() {}, clear() {},
open(callback) { open(callback) {
if (callback) this.callback = callback; if (callback) this.callback = callback;
this.$emit('change', { this.$emit('change', {
show: true show: true
}); });
this.showPopup = true; this.showPopup = true;
this.$nextTick(() => { this.$nextTick(() => {
setTimeout(() => { setTimeout(() => {
this.ani = 'uni-' + this.type; this.ani = 'uni-' + this.type;
}, 30); }, 30);
}); });
}, },
close(type, callback) { close(type, callback) {
if (!this.maskClick && type) return; if (!this.maskClick && type) return;
this.$emit('change', { this.$emit('change', {
show: false show: false
}); });
this.ani = ''; this.ani = '';
this.$nextTick(() => { this.$nextTick(() => {
setTimeout(() => { setTimeout(() => {
this.showPopup = false; this.showPopup = false;
}, 300); }, 300);
}); });
if (callback) callback(); if (callback) callback();
if (this.callback) this.callback.call(this); if (this.callback) this.callback.call(this);
} }
} }
}; };
</script> </script>
<style> <style lang="scss">
.uni-popup { .uni-popup {
position: fixed; position: fixed;
top: 0; top: 0;
bottom: 0; bottom: 0;
left: 0; left: 0;
right: 0; right: 0;
z-index: 999; z-index: 999;
overflow: hidden; overflow: hidden;
} }
.uni-popup__mask { .uni-popup__mask {
position: absolute; position: absolute;
top: 0; top: 0;
bottom: 0; bottom: 0;
left: 0; left: 0;
right: 0; right: 0;
z-index: 998; z-index: 998;
background: rgba(0, 0, 0, 0.4); background: rgba(0, 0, 0, 0.4);
opacity: 0; opacity: 0;
} }
.uni-popup__mask.ani { .uni-popup__mask.ani {
transition: all 0.3s; transition: all 0.3s;
} }
.uni-popup__mask.uni-bottom, .uni-popup__mask.uni-bottom,
.uni-popup__mask.uni-center, .uni-popup__mask.uni-center,
.uni-popup__mask.uni-right, .uni-popup__mask.uni-right,
.uni-popup__mask.uni-left, .uni-popup__mask.uni-left,
.uni-popup__mask.uni-top { .uni-popup__mask.uni-top {
opacity: 1; opacity: 1;
} }
.uni-popup__wrapper { .uni-popup__wrapper {
position: absolute; position: absolute;
z-index: 999; z-index: 999;
box-sizing: border-box; box-sizing: border-box;
background: #ffffff; background: #ffffff;
} }
.uni-popup__wrapper.ani { .uni-popup__wrapper.ani {
transition: all 0.3s; transition: all 0.3s;
} }
.uni-popup__wrapper.top { .uni-popup__wrapper.top {
top: 0; top: 0;
left: 0; left: 0;
width: 100%; width: 100%;
transform: translateY(-100%); transform: translateY(-100%);
} }
.uni-popup__wrapper.bottom { .uni-popup__wrapper.bottom {
bottom: 0; bottom: 0;
left: 0; left: 0;
width: 100%; width: 100%;
transform: translateY(100%); transform: translateY(100%);
} }
.uni-popup__wrapper.right { .uni-popup__wrapper.right {
bottom: 0; bottom: 0;
left: 0; left: 0;
width: 100%; width: 100%;
transform: translateX(100%); transform: translateX(100%);
} }
.uni-popup__wrapper.left { .uni-popup__wrapper.left {
bottom: 0; bottom: 0;
left: 0; left: 0;
width: 100%; width: 100%;
transform: translateX(-100%); transform: translateX(-100%);
} }
.uni-popup__wrapper.center { .uni-popup__wrapper.center {
width: 100%; width: 100%;
height: 100%; height: 100%;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
transform: scale(1.2); transform: scale(1.2);
opacity: 0; opacity: 0;
} }
.uni-popup__wrapper-box { .uni-popup__wrapper-box {
position: relative; position: relative;
box-sizing: border-box; box-sizing: border-box;
} }
.uni-popup__wrapper.uni-custom .uni-popup__wrapper-box { .uni-popup__wrapper.uni-custom .uni-popup__wrapper-box {
background: #fff; background: #fff;
} }
.uni-popup__wrapper.uni-custom.center .uni-popup__wrapper-box { .uni-popup__wrapper.uni-custom.center .uni-popup__wrapper-box {
position: relative; position: relative;
max-width: 80%; max-width: 80%;
max-height: 80%; max-height: 80%;
overflow-y: scroll; overflow-y: scroll;
} }
.uni-popup__wrapper.uni-custom.bottom .uni-popup__wrapper-box, .uni-popup__wrapper.uni-custom.bottom .uni-popup__wrapper-box,
.uni-popup__wrapper.uni-custom.top .uni-popup__wrapper-box { .uni-popup__wrapper.uni-custom.top .uni-popup__wrapper-box {
width: 100%; width: 100%;
max-height: 500px; max-height: 500px;
overflow-y: scroll; overflow-y: scroll;
} }
.uni-popup__wrapper.uni-bottom, .uni-popup__wrapper.uni-bottom,
.uni-popup__wrapper.uni-top { .uni-popup__wrapper.uni-top {
transform: translateY(0); transform: translateY(0);
} }
.uni-popup__wrapper.uni-left, .uni-popup__wrapper.uni-left,
.uni-popup__wrapper.uni-right { .uni-popup__wrapper.uni-right {
transform: translateX(0); transform: translateX(0);
} }
.uni-popup__wrapper.uni-center { .uni-popup__wrapper.uni-center {
transform: scale(1); transform: scale(1);
opacity: 1; opacity: 1;
} }
/* isIphoneX系列手机底部安全距离 */ /* isIphoneX系列手机底部安全距离 */
.bottom.safe-area { .bottom.safe-area {
padding-bottom: constant(safe-area-inset-bottom); padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom); padding-bottom: env(safe-area-inset-bottom);
} }
</style> </style>

View File

@@ -105,7 +105,7 @@
} }
}; };
</script> </script>
<style> <style lang="scss">
.uni-popup { .uni-popup {
position: fixed; position: fixed;
top: 0; top: 0;

View File

@@ -67,7 +67,7 @@ export default {
}; };
</script> </script>
<style> <style lang="scss">
.uni-tag { .uni-tag {
box-sizing: border-box; box-sizing: border-box;

View File

@@ -210,7 +210,7 @@ export default {
} }
</script> </script>
<style scoped> <style lang="scss" scoped>
.uv-count-num { .uv-count-num {
display: inline-flex; display: inline-flex;
text-align: center; text-align: center;

View File

@@ -35,7 +35,7 @@
</view> </view>
<!-- #endif --> <!-- #endif -->
<view class="view_ul_100" v-for="(item, index) in dataList" style="margin-bottom: 20rpx;"> <view class="view_ul_100" v-for="(item, index) in dataList" :key="item.personnel_id || index" style="margin-bottom: 20rpx;">
<view class="bl clearfix bor bg-white" <view class="bl clearfix bor bg-white"
:style="{ backgroundImage: ' url(' + $util.img(personnel_bg) + ')', backgroundSize: '100% 100%' }"> :style="{ backgroundImage: ' url(' + $util.img(personnel_bg) + ')', backgroundSize: '100% 100%' }">

View File

@@ -562,7 +562,7 @@ export default {
} }
</style> </style>
<style scoped> <style lang="scss" scoped>
/deep/ .action-icon-wrap .iconfont.icon-shouye1 { /deep/ .action-icon-wrap .iconfont.icon-shouye1 {
font-size: 40rpx; font-size: 40rpx;
} }

View File

@@ -306,7 +306,7 @@
<style lang="scss"> <style lang="scss">
@import './public/css/list.scss'; @import './public/css/list.scss';
</style> </style>
<style scoped> <style lang="scss" scoped>
>>>.uni-tag--primary.uni-tag--inverted { >>>.uni-tag--primary.uni-tag--inverted {
background-color: #f5f5f5 !important; background-color: #f5f5f5 !important;
} }

View File

@@ -194,7 +194,7 @@
} }
</style> </style>
<style scoped> <style lang="scss" scoped>
.swiper /deep/ .uni-swiper-dots-horizontal { .swiper /deep/ .uni-swiper-dots-horizontal {
left: 40%; left: 40%;
bottom:40px bottom:40px

View File

@@ -93,7 +93,7 @@
} }
</style> </style>
<style scoped> <style lang="scss" scoped>
.wap-floating>>>.uni-popup__wrapper.uni-custom .uni-popup__wrapper-box { .wap-floating>>>.uni-popup__wrapper.uni-custom .uni-popup__wrapper-box {
background: none !important; background: none !important;
} }

View File

@@ -814,7 +814,7 @@
<style lang="scss"> <style lang="scss">
@import './public/css/detail.scss'; @import './public/css/detail.scss';
</style> </style>
<style scoped> <style lang="scss" scoped>
.pickup-code-info .code img:nth-child(1) { .pickup-code-info .code img:nth-child(1) {
margin-bottom: 30rpx; margin-bottom: 30rpx;
} }

View File

@@ -297,7 +297,7 @@
<style lang="scss"> <style lang="scss">
@import './public/css/detail.scss'; @import './public/css/detail.scss';
</style> </style>
<style scoped> <style lang="scss" scoped>
/deep/ .sku-layer .uni-popup__wrapper.uni-custom .uni-popup__wrapper-box { /deep/ .sku-layer .uni-popup__wrapper.uni-custom .uni-popup__wrapper-box {
max-height: unset !important; max-height: unset !important;
} }

View File

@@ -442,7 +442,7 @@
<style lang="scss"> <style lang="scss">
@import './public/css/list.scss'; @import './public/css/list.scss';
</style> </style>
<style scoped> <style lang="scss" scoped>
/deep/ .uni-page { /deep/ .uni-page {
overflow: hidden; overflow: hidden;
} }

View File

@@ -1,56 +1,56 @@
<template> <template>
<text>{{ temp }}</text> <text>{{ temp }}</text>
</template> </template>
<script> <script>
import _time_ from './time.js'; import _time_ from './time.js';
export default { export default {
name: 'l-time', name: 'l-time',
props: { props: {
//日期字符串 //日期字符串
text: { text: {
type: [String, Number, Date], type: [String, Number, Date],
default: '' default: ''
}, },
//是否显示大于当前时间日期默认false大于显示刚刚 //是否显示大于当前时间日期默认false大于显示刚刚
maxDate: { maxDate: {
type: Boolean, type: Boolean,
default: false default: false
} }
}, },
data() { data() {
return { return {
textVal: this.text textVal: this.text
}; };
}, },
watch: { watch: {
text() { text() {
this.textVal = this.text; this.textVal = this.text;
} }
}, },
computed: { computed: {
temp() { temp() {
return this.getText(); return this.getText();
} }
}, },
methods: { methods: {
getText() { getText() {
let self = this; let self = this;
let timeVal = _time_.getFormatTime(self.textVal, self.maxDate); let timeVal = _time_.getFormatTime(self.textVal, self.maxDate);
if (timeVal && (timeVal.endsWith('刚刚') || timeVal.endsWith('分钟前'))) { if (timeVal && (timeVal.endsWith('刚刚') || timeVal.endsWith('分钟前'))) {
setTimeout(() => { setTimeout(() => {
let temp = self.textVal; let temp = self.textVal;
self.textVal = ''; self.textVal = '';
self.textVal = temp; self.textVal = temp;
}, 60000); }, 60000);
} }
return this.textVal ? timeVal : ''; return this.textVal ? timeVal : '';
}, },
onClick() { onClick() {
this.$emit('on-tap', this.textVal); this.$emit('on-tap', this.textVal);
} }
} }
}; };
</script> </script>
<style></style> <style lang="scss"></style>

File diff suppressed because it is too large Load Diff

View File

@@ -12,6 +12,7 @@
<view <view
class="quick-nav-item" class="quick-nav-item"
v-for="item in categoryList" v-for="item in categoryList"
:key="item.category_id"
:class="{ selected: categoryId == item.category_id }" :class="{ selected: categoryId == item.category_id }"
@click="changeCategory(item.category_id)" @click="changeCategory(item.category_id)"
> >
@@ -140,7 +141,7 @@ export default {
}; };
</script> </script>
<style> <style lang="scss">
.quick-nav >>> .uni-scroll-view-content { .quick-nav >>> .uni-scroll-view-content {
display: flex; display: flex;
} }

View File

@@ -1,323 +1,323 @@
<template> <template>
<page-meta :page-style="themeColor"></page-meta> <page-meta :page-style="themeColor"></page-meta>
<view class="content"> <view class="content">
<view class="head-wrap"> <view class="head-wrap">
<!-- 搜索区域 --> <!-- 搜索区域 -->
<view class="search-wrap uni-flex uni-row" style="margin-bottom: 20rpx;"> <view class="search-wrap uni-flex uni-row" style="margin-bottom: 20rpx;">
<!-- <view class="flex-item input-wrap"> <!-- <view class="flex-item input-wrap">
<input class="uni-input" maxlength="50" v-model="keyword" @confirm="search()" placeholder="请输入您要搜索的商品" /> <input class="uni-input" maxlength="50" v-model="keyword" @confirm="search()" placeholder="请输入您要搜索的商品" />
<text class="iconfont icon-sousuo3" @click.stop="search()"></text> <text class="iconfont icon-sousuo3" @click.stop="search()"></text>
</view> </view>
<view class="iconfont" :class="{ 'icon-apps': isList, 'icon-list': !isList }" @click="changeListStyle()"></view> --> <view class="iconfont" :class="{ 'icon-apps': isList, 'icon-list': !isList }" @click="changeListStyle()"></view> -->
<view style="width: 100rpx;height: 100rpx;"> <view style="width: 100rpx;height: 100rpx;">
<image :src="$util.img(merch.merch_image)" mode="widthFix" style="width: 100rpx;height: 100rpx;" /> <image :src="$util.img(merch.merch_image)" mode="widthFix" style="width: 100rpx;height: 100rpx;" />
</view> </view>
<view style="margin-left: 20rpx;padding-top: 22rpx;"> <view style="margin-left: 20rpx;padding-top: 22rpx;">
<view style="line-height: 1;font-size: 32rpx;font-weight: 600;">{{merch.merch_name}}</view> <view style="line-height: 1;font-size: 32rpx;font-weight: 600;">{{merch.merch_name}}</view>
<view style="color:rgb(255 202 40)"> <view style="color:rgb(255 202 40)">
<text class="icox icox-xing"></text> <text class="icox icox-xing"></text>
<text class="icox icox-xing"></text> <text class="icox icox-xing"></text>
<text class="icox icox-xing"></text> <text class="icox icox-xing"></text>
<text class="icox icox-xing"></text> <text class="icox icox-xing"></text>
<text class="icox icox-xing"></text> <text class="icox icox-xing"></text>
</view> </view>
</view> </view>
</view> </view>
<!-- 排序 --> <!-- 排序 -->
<view class="sort-wrap"> <view class="sort-wrap">
<view class="comprehensive-wrap" :class="{ 'color-base-text': orderType === '' }" @click="sortTabClick('')"> <view class="comprehensive-wrap" :class="{ 'color-base-text': orderType === '' }" @click="sortTabClick('')">
<text :class="{ 'color-base-text': orderType === '' }">综合</text> <text :class="{ 'color-base-text': orderType === '' }">综合</text>
</view> </view>
<view :class="{ 'color-base-text': orderType === 'sale_num' }" @click="sortTabClick('sale_num')">销量 <view :class="{ 'color-base-text': orderType === 'sale_num' }" @click="sortTabClick('sale_num')">销量
</view> </view>
<view class="price-wrap" @click="sortTabClick('discount_price')"> <view class="price-wrap" @click="sortTabClick('discount_price')">
<text :class="{ 'color-base-text': orderType === 'discount_price' }">价格</text> <text :class="{ 'color-base-text': orderType === 'discount_price' }">价格</text>
<view class="iconfont-wrap"> <view class="iconfont-wrap">
<view class="iconfont icon-iconangledown-copy asc" :class="{ 'color-base-text': priceOrder === 'asc' && orderType === 'discount_price' }"></view> <view class="iconfont icon-iconangledown-copy asc" :class="{ 'color-base-text': priceOrder === 'asc' && orderType === 'discount_price' }"></view>
<view class="iconfont icon-iconangledown desc" :class="{ 'color-base-text': priceOrder === 'desc' && orderType === 'discount_price' }"></view> <view class="iconfont icon-iconangledown desc" :class="{ 'color-base-text': priceOrder === 'desc' && orderType === 'discount_price' }"></view>
</view> </view>
</view> </view>
<!-- <view :class="{ 'color-base-text': orderType === 'screen' }" class="screen-wrap"> <!-- <view :class="{ 'color-base-text': orderType === 'screen' }" class="screen-wrap">
<text @click="sortTabClick('screen')">筛选</text> <text @click="sortTabClick('screen')">筛选</text>
<view @click="sortTabClick('screen')" class="iconfont-wrap"> <view @click="sortTabClick('screen')" class="iconfont-wrap">
<view class="iconfont icon-shaixuan color-tip"></view> <view class="iconfont icon-shaixuan color-tip"></view>
</view> </view>
</view> --> </view> -->
</view> </view>
</view> </view>
<mescroll-uni top="240" ref="mescroll" @getData="getGoodsList"> <mescroll-uni top="240" ref="mescroll" @getData="getGoodsList">
<block slot="list"> <block slot="list">
<view class="goods-list single-column" :class="{ show: isList }"> <view class="goods-list single-column" :class="{ show: isList }">
<view class="goods-item margin-bottom" v-for="(item, index) in goodsList" :key="index" @click="toDetail(item)"> <view class="goods-item margin-bottom" v-for="(item, index) in goodsList" :key="index" @click="toDetail(item)">
<view class="goods-img"> <view class="goods-img">
<image :src="goodsImg(item.goods_image)" mode="widthFix" @error="imgError(index)"></image> <image :src="goodsImg(item.goods_image)" mode="widthFix" @error="imgError(index)"></image>
<view class="color-base-bg goods-tag" v-if="goodsTag(item) != ''">{{ goodsTag(item) }}</view> <view class="color-base-bg goods-tag" v-if="goodsTag(item) != ''">{{ goodsTag(item) }}</view>
<view class="sell-out" v-if="item.stock <= 0"> <view class="sell-out" v-if="item.stock <= 0">
<text class="iconfont icon-shuqing"></text> <text class="iconfont icon-shuqing"></text>
</view> </view>
</view> </view>
<view class="info-wrap"> <view class="info-wrap">
<view class="name-wrap"> <view class="name-wrap">
<view class="goods-name" :class="[{ 'using-hidden': config.nameLineMode == 'single' }, { 'multi-hidden': config.nameLineMode == 'multiple' }]"> <view class="goods-name" :class="[{ 'using-hidden': config.nameLineMode == 'single' }, { 'multi-hidden': config.nameLineMode == 'multiple' }]">
{{ item.goods_name }} {{ item.goods_name }}
</view> </view>
</view> </view>
<view class="lineheight-clear"> <view class="lineheight-clear">
<view class="discount-price" v-if="item.isinformation == 0"> <view class="discount-price" v-if="item.isinformation == 0">
<text class="unit price-style small">{{ $lang('common.currencySymbol') }}</text> <text class="unit price-style small">{{ $lang('common.currencySymbol') }}</text>
<text class="price price-style large">{{ parseFloat(showPrice(item)).toFixed(2).split('.')[0] }}</text> <text class="price price-style large">{{ parseFloat(showPrice(item)).toFixed(2).split('.')[0] }}</text>
<text class="unit price-style small">.{{ parseFloat(showPrice(item)).toFixed(2).split('.')[1] }}</text> <text class="unit price-style small">.{{ parseFloat(showPrice(item)).toFixed(2).split('.')[1] }}</text>
</view> </view>
<view class="discount-price" v-else> <view class="discount-price" v-else>
<text class="price price-style large">咨询</text> <text class="price price-style large">咨询</text>
</view> </view>
<view class="member-price-tag" v-if="item.member_price && item.member_price == showPrice(item)"> <view class="member-price-tag" v-if="item.member_price && item.member_price == showPrice(item)">
<image :src="$util.img('public/uniapp/index/VIP.png')" mode="widthFix"></image> <image :src="$util.img('public/uniapp/index/VIP.png')" mode="widthFix"></image>
</view> </view>
<view class="member-price-tag" v-else-if="item.promotion_type == 1"> <view class="member-price-tag" v-else-if="item.promotion_type == 1">
<image :src="$util.img('public/uniapp/index/discount.png')" mode="widthFix"></image> <image :src="$util.img('public/uniapp/index/discount.png')" mode="widthFix"></image>
</view> </view>
</view> </view>
<view class="pro-info" v-if="item.isinformation == 0"> <view class="pro-info" v-if="item.isinformation == 0">
<view class="delete-price color-tip price-font" v-if="showMarketPrice(item)"> <view class="delete-price color-tip price-font" v-if="showMarketPrice(item)">
<text class="unit">{{ $lang('common.currencySymbol') }}</text> <text class="unit">{{ $lang('common.currencySymbol') }}</text>
<text>{{ showMarketPrice(item) }}</text> <text>{{ showMarketPrice(item) }}</text>
</view> </view>
<view class="block-wrap"> <view class="block-wrap">
<view class="sale color-tip" v-if="item.sale_show">已售{{ item.sale_num }}{{ item.unit ? item.unit : '' }}</view> <view class="sale color-tip" v-if="item.sale_show">已售{{ item.sale_num }}{{ item.unit ? item.unit : '' }}</view>
</view> </view>
<view class="cart-action-wrap" v-if="config.control && item.is_virtual == 0"> <view class="cart-action-wrap" v-if="config.control && item.is_virtual == 0">
<!-- 购物车图标 --> <!-- 购物车图标 -->
<view v-if="config.style == 'icon-cart'" :style="{ <view v-if="config.style == 'icon-cart'" :style="{
color: config.theme == 'diy' ? config.textColor : '', color: config.theme == 'diy' ? config.textColor : '',
borderColor: config.theme == 'diy' ? config.textColor : '' borderColor: config.theme == 'diy' ? config.textColor : ''
}" class="cart shopping-cart-btn iconfont icon-gouwuche click-wrap" :id="'goods-' + item.id" }" class="cart shopping-cart-btn iconfont icon-gouwuche click-wrap" :id="'goods-' + item.id"
@click.stop="$refs.goodsSkuIndex.addCart(config.cartEvent, item, $event)"> @click.stop="$refs.goodsSkuIndex.addCart(config.cartEvent, item, $event)">
<view class="click-event"></view> <view class="click-event"></view>
</view> </view>
<!--加号图标 --> <!--加号图标 -->
<view v-else-if="config.style == 'icon-add'" :style="{ <view v-else-if="config.style == 'icon-add'" :style="{
color: config.theme == 'diy' ? config.textColor : '', color: config.theme == 'diy' ? config.textColor : '',
borderColor: config.theme == 'diy' ? config.textColor : '' borderColor: config.theme == 'diy' ? config.textColor : ''
}" class="cart plus-sign-btn iconfont icon-add1 click-wrap" :id="'goods-' + item.id" }" class="cart plus-sign-btn iconfont icon-add1 click-wrap" :id="'goods-' + item.id"
@click.stop="$refs.goodsSkuIndex.addCart(config.cartEvent, item, $event)"> @click.stop="$refs.goodsSkuIndex.addCart(config.cartEvent, item, $event)">
<view class="click-event"></view> <view class="click-event"></view>
</view> </view>
<!-- 按钮 --> <!-- 按钮 -->
<view v-else-if="config.style == 'button'" :style="{ <view v-else-if="config.style == 'button'" :style="{
backgroundColor: config.theme == 'diy' ? config.bgColor : '', backgroundColor: config.theme == 'diy' ? config.bgColor : '',
color: config.theme == 'diy' ? config.textColor : '', color: config.theme == 'diy' ? config.textColor : '',
fontWeight: config.theme == 'diy' ? (config.fontWeight ? 'bold' : 'normal') : '', fontWeight: config.theme == 'diy' ? (config.fontWeight ? 'bold' : 'normal') : '',
padding: config.theme == 'diy' ? '12rpx ' + config.padding * 2 + 'rpx' : '' padding: config.theme == 'diy' ? '12rpx ' + config.padding * 2 + 'rpx' : ''
}" class="cart buy-btn click-wrap" :id="'goods-' + item.id" }" class="cart buy-btn click-wrap" :id="'goods-' + item.id"
@click.stop="$refs.goodsSkuIndex.addCart(config.cartEvent, item, $event)"> @click.stop="$refs.goodsSkuIndex.addCart(config.cartEvent, item, $event)">
{{ config.text }} {{ config.text }}
<view class="click-event"></view> <view class="click-event"></view>
</view> </view>
<!--自定义图标 --> <!--自定义图标 -->
<view v-else-if="config.style == 'icon-diy'" :style="{ <view v-else-if="config.style == 'icon-diy'" :style="{
color: config.theme == 'diy' ? config.textColor : '' color: config.theme == 'diy' ? config.textColor : ''
}" class="icon-diy click-wrap" :id="'goods-' + item.id" }" class="icon-diy click-wrap" :id="'goods-' + item.id"
@click.stop="$refs.goodsSkuIndex.addCart(config.cartEvent, item, $event)"> @click.stop="$refs.goodsSkuIndex.addCart(config.cartEvent, item, $event)">
<view class="click-event"></view> <view class="click-event"></view>
<diy-icon :icon="config.iconDiy.icon" :value="config.iconDiy.style ? config.iconDiy.style : null"></diy-icon> <diy-icon :icon="config.iconDiy.icon" :value="config.iconDiy.style ? config.iconDiy.style : null"></diy-icon>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
<view class="goods-list double-column" :class="{ show: !isList }"> <view class="goods-list double-column" :class="{ show: !isList }">
<view class="goods-item margin-bottom" v-for="(item, index) in goodsList" :key="index" <view class="goods-item margin-bottom" v-for="(item, index) in goodsList" :key="index"
@click="toDetail(item)" :style="{ left: listPosition[index] ? listPosition[index].left : '', top: listPosition[index] ? listPosition[index].top : '' }"> @click="toDetail(item)" :style="{ left: listPosition[index] ? listPosition[index].left : '', top: listPosition[index] ? listPosition[index].top : '' }">
<view class="goods-img"> <view class="goods-img">
<image :src="goodsImg(item.goods_image)" mode="widthFix" @error="imgError(index)"></image> <image :src="goodsImg(item.goods_image)" mode="widthFix" @error="imgError(index)"></image>
<view class="color-base-bg goods-tag" v-if="goodsTag(item) != ''">{{ goodsTag(item) }}</view> <view class="color-base-bg goods-tag" v-if="goodsTag(item) != ''">{{ goodsTag(item) }}</view>
<view class="sell-out" v-if="item.stock <= 0"> <view class="sell-out" v-if="item.stock <= 0">
<text class="iconfont icon-shuqing"></text> <text class="iconfont icon-shuqing"></text>
</view> </view>
</view> </view>
<view class="info-wrap"> <view class="info-wrap">
<view class="goods-name" :class="[{ 'using-hidden': config.nameLineMode == 'single' }, { 'multi-hidden': config.nameLineMode == 'multiple' }]"> <view class="goods-name" :class="[{ 'using-hidden': config.nameLineMode == 'single' }, { 'multi-hidden': config.nameLineMode == 'multiple' }]">
{{ item.goods_name }} {{ item.goods_name }}
</view> </view>
<view class="lineheight-clear"> <view class="lineheight-clear">
<view class="discount-price" v-if="item.isinformation == 0"> <view class="discount-price" v-if="item.isinformation == 0">
<text class="unit price-style small">{{ $lang('common.currencySymbol') }}</text> <text class="unit price-style small">{{ $lang('common.currencySymbol') }}</text>
<text class="price price-style large">{{ parseFloat(showPrice(item)).toFixed(2).split('.')[0] }}</text> <text class="price price-style large">{{ parseFloat(showPrice(item)).toFixed(2).split('.')[0] }}</text>
<text class="unit price-style small">.{{ parseFloat(showPrice(item)).toFixed(2).split('.')[1] }}</text> <text class="unit price-style small">.{{ parseFloat(showPrice(item)).toFixed(2).split('.')[1] }}</text>
</view> </view>
<view class="discount-price" v-else> <view class="discount-price" v-else>
<text class="price price-style large">咨询</text> <text class="price price-style large">咨询</text>
</view> </view>
<view class="member-price-tag" v-if="item.member_price && item.member_price == showPrice(item)"> <view class="member-price-tag" v-if="item.member_price && item.member_price == showPrice(item)">
<image :src="$util.img('public/uniapp/index/VIP.png')" mode="widthFix"></image> <image :src="$util.img('public/uniapp/index/VIP.png')" mode="widthFix"></image>
</view> </view>
<view class="member-price-tag" v-else-if="item.promotion_type == 1"> <view class="member-price-tag" v-else-if="item.promotion_type == 1">
<image :src="$util.img('public/uniapp/index/discount.png')" mode="widthFix"></image> <image :src="$util.img('public/uniapp/index/discount.png')" mode="widthFix"></image>
</view> </view>
<view class="delete-price color-tip price-font" v-if="showMarketPrice(item)"> <view class="delete-price color-tip price-font" v-if="showMarketPrice(item)">
<text class="unit">{{ $lang('common.currencySymbol') }}</text> <text class="unit">{{ $lang('common.currencySymbol') }}</text>
<text>{{ showMarketPrice(item) }}</text> <text>{{ showMarketPrice(item) }}</text>
</view> </view>
</view> </view>
<view class="pro-info" v-if="item.isinformation == 0"> <view class="pro-info" v-if="item.isinformation == 0">
<view class="block-wrap" > <view class="block-wrap" >
<view class="sale color-tip" v-if="item.sale_show">已售{{ item.sale_num }}{{ item.unit ? item.unit : '' }}</view> <view class="sale color-tip" v-if="item.sale_show">已售{{ item.sale_num }}{{ item.unit ? item.unit : '' }}</view>
</view> </view>
<view class="cart-action-wrap" v-if="config.control && item.is_virtual == 0"> <view class="cart-action-wrap" v-if="config.control && item.is_virtual == 0">
<!-- 购物车图标 --> <!-- 购物车图标 -->
<view v-if="config.style == 'icon-cart'" :style="{ <view v-if="config.style == 'icon-cart'" :style="{
color: config.theme == 'diy' ? config.textColor : '', color: config.theme == 'diy' ? config.textColor : '',
borderColor: config.theme == 'diy' ? config.textColor : '' borderColor: config.theme == 'diy' ? config.textColor : ''
}" class="cart shopping-cart-btn iconfont icon-gouwuche click-wrap" :id="'goods-' + item.id" }" class="cart shopping-cart-btn iconfont icon-gouwuche click-wrap" :id="'goods-' + item.id"
@click.stop="$refs.goodsSkuIndex.addCart(config.cartEvent, item, $event)"> @click.stop="$refs.goodsSkuIndex.addCart(config.cartEvent, item, $event)">
<view class="click-event"></view> <view class="click-event"></view>
</view> </view>
<!--加号图标 --> <!--加号图标 -->
<view v-else-if="config.style == 'icon-add'" :style="{ <view v-else-if="config.style == 'icon-add'" :style="{
color: config.theme == 'diy' ? config.textColor : '', color: config.theme == 'diy' ? config.textColor : '',
borderColor: config.theme == 'diy' ? config.textColor : '' borderColor: config.theme == 'diy' ? config.textColor : ''
}" class="cart plus-sign-btn iconfont icon-add1 click-wrap" :id="'goods-' + item.id" }" class="cart plus-sign-btn iconfont icon-add1 click-wrap" :id="'goods-' + item.id"
@click.stop="$refs.goodsSkuIndex.addCart(config.cartEvent, item, $event)"> @click.stop="$refs.goodsSkuIndex.addCart(config.cartEvent, item, $event)">
<view class="click-event"></view> <view class="click-event"></view>
</view> </view>
<!-- 按钮 --> <!-- 按钮 -->
<view v-else-if="config.style == 'button'" :style="{ <view v-else-if="config.style == 'button'" :style="{
backgroundColor: config.theme == 'diy' ? config.bgColor : '', backgroundColor: config.theme == 'diy' ? config.bgColor : '',
color: config.theme == 'diy' ? config.textColor : '', color: config.theme == 'diy' ? config.textColor : '',
fontWeight: config.theme == 'diy' ? (config.fontWeight ? 'bold' : 'normal') : '', fontWeight: config.theme == 'diy' ? (config.fontWeight ? 'bold' : 'normal') : '',
padding: config.theme == 'diy' ? '12rpx ' + config.padding * 2 + 'rpx' : '' padding: config.theme == 'diy' ? '12rpx ' + config.padding * 2 + 'rpx' : ''
}" class="cart buy-btn click-wrap" :id="'goods-' + item.id" }" class="cart buy-btn click-wrap" :id="'goods-' + item.id"
@click.stop="$refs.goodsSkuIndex.addCart(config.cartEvent, item, $event)"> @click.stop="$refs.goodsSkuIndex.addCart(config.cartEvent, item, $event)">
{{ config.text }} {{ config.text }}
<view class="click-event"></view> <view class="click-event"></view>
</view> </view>
<!--自定义图标 --> <!--自定义图标 -->
<view v-else-if="config.style == 'icon-diy'" :style="{ <view v-else-if="config.style == 'icon-diy'" :style="{
color: config.theme == 'diy' ? config.textColor : '' color: config.theme == 'diy' ? config.textColor : ''
}" class="icon-diy click-wrap" :id="'goods-' + item.id" }" class="icon-diy click-wrap" :id="'goods-' + item.id"
@click.stop="$refs.goodsSkuIndex.addCart(config.cartEvent, item, $event)"> @click.stop="$refs.goodsSkuIndex.addCart(config.cartEvent, item, $event)">
<view class="click-event"></view> <view class="click-event"></view>
<diy-icon :icon="config.iconDiy.icon" :value="config.iconDiy.style ? config.iconDiy.style : null"></diy-icon> <diy-icon :icon="config.iconDiy.icon" :value="config.iconDiy.style ? config.iconDiy.style : null"></diy-icon>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
<view v-if="goodsList.length == 0 && emptyShow"><ns-empty text="暂无商品"></ns-empty></view> <view v-if="goodsList.length == 0 && emptyShow"><ns-empty text="暂无商品"></ns-empty></view>
</block> </block>
</mescroll-uni> </mescroll-uni>
<ns-goods-sku-index ref="goodsSkuIndex" @addCart="addCart"></ns-goods-sku-index> <ns-goods-sku-index ref="goodsSkuIndex" @addCart="addCart"></ns-goods-sku-index>
<!-- 筛选弹出框 --> <!-- 筛选弹出框 -->
<uni-drawer :visible="showScreen" mode="right" @close="showScreen = false" class="screen-wrap"> <uni-drawer :visible="showScreen" mode="right" @close="showScreen = false" class="screen-wrap">
<view class="title color-tip">筛选</view> <view class="title color-tip">筛选</view>
<scroll-view scroll-y> <scroll-view scroll-y>
<!-- 包邮 --> <!-- 包邮 -->
<!-- <view class="item-wrap"> <!-- <view class="item-wrap">
<view class="label"><text>是否包邮</text></view> <view class="label"><text>是否包邮</text></view>
<view class="list"> <view class="list">
<uni-tag :inverted="true" text="包邮" :type="isFreeShipping ? 'primary' : 'default'" @click="isFreeShipping = !isFreeShipping" /> <uni-tag :inverted="true" text="包邮" :type="isFreeShipping ? 'primary' : 'default'" @click="isFreeShipping = !isFreeShipping" />
</view> </view>
</view> --> </view> -->
<!-- 价格筛选项 --> <!-- 价格筛选项 -->
<!-- <view class="item-wrap"> <!-- <view class="item-wrap">
<view class="label"><text>价格区间()</text></view> <view class="label"><text>价格区间()</text></view>
<view class="price-wrap"> <view class="price-wrap">
<input class="uni-input" type="digit" v-model="minPrice" placeholder="最低价" /> <input class="uni-input" type="digit" v-model="minPrice" placeholder="最低价" />
<view class="h-line"></view> <view class="h-line"></view>
<input class="uni-input" type="digit" v-model="maxPrice" placeholder="最高价" /> <input class="uni-input" type="digit" v-model="maxPrice" placeholder="最高价" />
</view> </view>
</view> --> </view> -->
<!-- 品牌筛选项 --> <!-- 品牌筛选项 -->
<!-- <view class="item-wrap" v-if="brandList.length > 0"> <!-- <view class="item-wrap" v-if="brandList.length > 0">
<view class="label"><text>品牌</text></view> <view class="label"><text>品牌</text></view>
<view class="list"> <view class="list">
<view v-for="(item, index) in brandList" :key="index"> <view v-for="(item, index) in brandList" :key="index">
<uni-tag :inverted="true" :text="item.brand_name" :type="item.brand_id == brandId ? 'primary' : 'default'" @click="brandId == item.brand_id ? (brandId = 0) : (brandId = item.brand_id)" /> <uni-tag :inverted="true" :text="item.brand_name" :type="item.brand_id == brandId ? 'primary' : 'default'" @click="brandId == item.brand_id ? (brandId = 0) : (brandId = item.brand_id)" />
</view> </view>
</view> </view>
</view> --> </view> -->
<!-- 分类筛选项 --> <!-- 分类筛选项 -->
<view class="category-list-wrap"> <view class="category-list-wrap">
<text class="first">全部分类</text> <text class="first">全部分类</text>
<view class="class-box"> <view class="class-box">
<view @click="selectedCategory('')" class="list-wrap"> <view @click="selectedCategory('')" class="list-wrap">
<text :class="{ selected: !categoryId, 'color-base-text': !categoryId }">全部</text> <text :class="{ selected: !categoryId, 'color-base-text': !categoryId }">全部</text>
</view> </view>
<view @click="selectedCategory(item.category_id)" v-for="(item, index) in categoryList" :key="index" class="list-wrap"> <view @click="selectedCategory(item.category_id)" v-for="(item, index) in categoryList" :key="index" class="list-wrap">
<text :class="{ selected: item.category_id == categoryId, 'color-base-text': item.category_id == categoryId }">{{ item.category_name }}</text> <text :class="{ selected: item.category_id == categoryId, 'color-base-text': item.category_id == categoryId }">{{ item.category_name }}</text>
</view> </view>
</view> </view>
</view> </view>
</scroll-view> </scroll-view>
<view class="footer" :class="{ 'safe-area': isIphoneX }"> <view class="footer" :class="{ 'safe-area': isIphoneX }">
<button type="default" class="footer-box" @click="resetData">重置</button> <button type="default" class="footer-box" @click="resetData">重置</button>
<button type="primary" class="footer-box1" @click="screenData">确定</button> <button type="primary" class="footer-box1" @click="screenData">确定</button>
</view> </view>
</uni-drawer> </uni-drawer>
<loading-cover ref="loadingCover"></loading-cover> <loading-cover ref="loadingCover"></loading-cover>
<!-- #ifdef MP-WEIXIN --> <!-- #ifdef MP-WEIXIN -->
<!-- 小程序隐私协议 --> <!-- 小程序隐私协议 -->
<privacy-popup ref="privacyPopup"></privacy-popup> <privacy-popup ref="privacyPopup"></privacy-popup>
<!-- #endif --> <!-- #endif -->
</view> </view>
</template> </template>
<script> <script>
import uniDrawer from '@/components/uni-drawer/uni-drawer.vue'; import uniDrawer from '@/components/uni-drawer/uni-drawer.vue';
import uniTag from '@/components/uni-tag/uni-tag.vue'; import uniTag from '@/components/uni-tag/uni-tag.vue';
import nsGoodsSkuIndex from '@/components/ns-goods-sku/ns-goods-sku-index.vue'; import nsGoodsSkuIndex from '@/components/ns-goods-sku/ns-goods-sku-index.vue';
import list from './public/js/list.js'; import list from './public/js/list.js';
export default { export default {
components: { components: {
uniDrawer, uniDrawer,
uniTag, uniTag,
nsGoodsSkuIndex nsGoodsSkuIndex
}, },
data() { data() {
return {}; return {};
}, },
mixins: [list] mixins: [list]
}; };
</script> </script>
<style lang="scss"> <style lang="scss">
@import './public/css/list.scss'; @import './public/css/list.scss';
</style> </style>
<style scoped> <style lang="scss" scoped>
>>>.uni-tag--primary.uni-tag--inverted { >>>.uni-tag--primary.uni-tag--inverted {
background-color: #f5f5f5 !important; background-color: #f5f5f5 !important;
} }
/deep/ .sku-layer .uni-popup__wrapper.uni-custom .uni-popup__wrapper-box { /deep/ .sku-layer .uni-popup__wrapper.uni-custom .uni-popup__wrapper-box {
max-height: unset !important; max-height: unset !important;
} }
</style> </style>

View File

@@ -13,7 +13,7 @@
<block v-if="categoryTree.length"> <block v-if="categoryTree.length">
<scroll-view scroll-y="true" class="tree-wrap"> <scroll-view scroll-y="true" class="tree-wrap">
<view class="category-item-wrap"> <view class="category-item-wrap">
<view class="category-item" v-for="(item, index) in categoryTree" :key="index" :class="[ <view class="category-item" v-for="(item, index) in categoryTree" :key="item.category_id || index" :class="[
{ select: select == index }, { select: select == index },
]" @click="switchOneCategory(index)"> ]" @click="switchOneCategory(index)">
<view class="">{{ item.category_name }}</view> <view class="">{{ item.category_name }}</view>
@@ -26,7 +26,7 @@
@scroll="listenScroll" @touchstart="touchStart" :refresher-enabled="true" @scroll="listenScroll" @touchstart="touchStart" :refresher-enabled="true"
refresher-default-style="none" :refresher-triggered="triggered" @refresherrefresh="onRefresh" refresher-default-style="none" :refresher-triggered="triggered" @refresherrefresh="onRefresh"
@refresherrestore="onRestore"> @refresherrestore="onRestore">
<view class="child-category" v-for="(item, index) in categoryTree" :id="'category-' + index" v-if="item.child_list.length > 0"> <view class="child-category" v-for="(item, index) in categoryTree" :key="item.category_id || index" :id="'category-' + index" v-if="item.child_list.length > 0">
<!----> <!---->
<view class="item-wrap category"> <view class="item-wrap category">
<view class="category-title">{{ item.category_name }}</view> <view class="category-title">{{ item.category_name }}</view>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -586,7 +586,7 @@
<style lang="scss"> <style lang="scss">
@import './public/css/list.scss'; @import './public/css/list.scss';
</style> </style>
<style> <style lang="scss">
.ns-adv>>>image { .ns-adv>>>image {
width: 100%; width: 100%;
border-radius: 0; border-radius: 0;

View File

@@ -1,309 +1,309 @@
<template> <template>
<page-meta :page-style="themeColor"></page-meta> <page-meta :page-style="themeColor"></page-meta>
<view class="order-container" :class="{ 'safe-area': isIphoneX }"> <view class="order-container" :class="{ 'safe-area': isIphoneX }">
<!-- #ifdef MP-WEIXIN --> <!-- #ifdef MP-WEIXIN -->
<view class="payment-navbar" :style="{ <view class="payment-navbar" :style="{
'padding-top': menuButtonBounding.top + 'px', 'padding-top': menuButtonBounding.top + 'px',
height: menuButtonBounding.height + 'px' height: menuButtonBounding.height + 'px'
}"> }">
<view class="nav-wrap"> <view class="nav-wrap">
<text class="iconfont icon-back_light" @click="back"></text> <text class="iconfont icon-back_light" @click="back"></text>
<view class="navbar-title">确认订单</view> <view class="navbar-title">确认订单</view>
</view> </view>
</view> </view>
<view class="payment-navbar-block" :style="{ height: menuButtonBounding.bottom + 'px' }"></view> <view class="payment-navbar-block" :style="{ height: menuButtonBounding.bottom + 'px' }"></view>
<!-- #endif --> <!-- #endif -->
<scroll-view scroll-y="true" class="order-scroll-container"> <scroll-view scroll-y="true" class="order-scroll-container">
<view class="payment-navbar-block"></view> <view class="payment-navbar-block"></view>
<!-- 选择地址 --> <!-- 选择地址 -->
<template v-if="orderPaymentData.exchange_info.type == 1 && orderPaymentData.is_virtual == 0"> <template v-if="orderPaymentData.exchange_info.type == 1 && orderPaymentData.is_virtual == 0">
<!-- 配送方式 --> <!-- 配送方式 -->
<view class="delivery-mode" v-if="orderCreateData.delivery &&orderPaymentData.delivery.express_type.length > 1"> <view class="delivery-mode" v-if="orderCreateData.delivery &&orderPaymentData.delivery.express_type.length > 1">
<view class="action"> <view class="action">
<view v-for="(deliveryItem, deliveryIndex) in orderPaymentData.delivery.express_type" <view v-for="(deliveryItem, deliveryIndex) in orderPaymentData.delivery.express_type"
:key="deliveryIndex" :key="deliveryIndex"
:class="{active: deliveryItem.name == orderCreateData.delivery.delivery_type}" :class="{active: deliveryItem.name == orderCreateData.delivery.delivery_type}"
@click="selectDeliveryType(deliveryItem)"> @click="selectDeliveryType(deliveryItem)">
{{ deliveryItem.title }} {{ deliveryItem.title }}
<!-- 外圆角 --> <!-- 外圆角 -->
<view class="out-radio"></view> <view class="out-radio"></view>
</view> </view>
</view> </view>
</view> </view>
<view class="address-box" :class="{'not-delivery-type': orderPaymentData.delivery.express_type.length <= 1}" <view class="address-box" :class="{'not-delivery-type': orderPaymentData.delivery.express_type.length <= 1}"
v-if="orderPaymentData.delivery.delivery_type != 'store'"> v-if="orderPaymentData.delivery.delivery_type != 'store'">
<block v-if="storeInfo.storeList.length > 1 && orderPaymentData.delivery.delivery_type == 'local'"> <block v-if="storeInfo.storeList.length > 1 && orderPaymentData.delivery.delivery_type == 'local'">
<view class="local-delivery-store" v-if="Object.keys(storeInfo.currStore).length" @click="$refs.deliveryPopup.open()"> <view class="local-delivery-store" v-if="Object.keys(storeInfo.currStore).length" @click="$refs.deliveryPopup.open()">
<view class="info"> <view class="info">
<text class="store-name">{{ storeInfo.currStore.store_name }}</text> 提供配送 <text class="store-name">{{ storeInfo.currStore.store_name }}</text> 提供配送
</view> </view>
<view class="cell-more"> <view class="cell-more">
<text>点击切换</text> <text>点击切换</text>
<text class="iconfont icon-right"></text> <text class="iconfont icon-right"></text>
</view> </view>
</view> </view>
<view v-else class="local-delivery-store"> <view v-else class="local-delivery-store">
<view class="info"> <view class="info">
<text class="store-name">您的附近没有可配送的门店请选择其他配送方式</text> <text class="store-name">您的附近没有可配送的门店请选择其他配送方式</text>
</view> </view>
</view> </view>
</block> </block>
<view class="info-wrap" :class="{'local': orderPaymentData.delivery.delivery_type == 'local'}" v-if="orderCreateData.member_address" @click="selectAddress"> <view class="info-wrap" :class="{'local': orderPaymentData.delivery.delivery_type == 'local'}" v-if="orderCreateData.member_address" @click="selectAddress">
<view class="content"> <view class="content">
<text class="name font-size-base">{{ orderCreateData.member_address.name ? orderCreateData.member_address.name : '' }}</text> <text class="name font-size-base">{{ orderCreateData.member_address.name ? orderCreateData.member_address.name : '' }}</text>
<text class="font-size-base mobile">{{ orderCreateData.member_address.mobile ? orderCreateData.member_address.mobile : '' }}</text> <text class="font-size-base mobile">{{ orderCreateData.member_address.mobile ? orderCreateData.member_address.mobile : '' }}</text>
<text class="cell-more iconfont icon-right"></text> <text class="cell-more iconfont icon-right"></text>
<view class="desc-wrap"> <view class="desc-wrap">
{{ orderCreateData.member_address.full_address ? orderCreateData.member_address.full_address : '' }} {{ orderCreateData.member_address.full_address ? orderCreateData.member_address.full_address : '' }}
{{ orderCreateData.member_address.address ? orderCreateData.member_address.address : '' }} {{ orderCreateData.member_address.address ? orderCreateData.member_address.address : '' }}
</view> </view>
</view> </view>
</view> </view>
<view class="empty-wrap" v-else @click="selectAddress"> <view class="empty-wrap" v-else @click="selectAddress">
<view class="info">请设置收货地址</view> <view class="info">请设置收货地址</view>
<view class="cell-more"> <view class="cell-more">
<view class="iconfont icon-right"></view> <view class="iconfont icon-right"></view>
</view> </view>
</view> </view>
<!-- 外卖配送 --> <!-- 外卖配送 -->
<block v-if="orderPaymentData.delivery.delivery_type == 'local'"> <block v-if="orderPaymentData.delivery.delivery_type == 'local'">
<view class="local-box" v-if="orderPaymentData.config.local.is_use && orderPaymentData.delivery.local.info && orderPaymentData.delivery.local.info.time_is_open == 1"> <view class="local-box" v-if="orderPaymentData.config.local.is_use && orderPaymentData.delivery.local.info && orderPaymentData.delivery.local.info.time_is_open == 1">
<view class="pick-block" @click="localtime"> <view class="pick-block" @click="localtime">
<view class="font-size-base">送达时间</view> <view class="font-size-base">送达时间</view>
<view class="time-picker"> <view class="time-picker">
<text :class="{'color-tip': !orderCreateData.buyer_ask_delivery_title}">{{ orderCreateData.buyer_ask_delivery_title ? orderCreateData.buyer_ask_delivery_title : '请选择送达时间' }}</text> <text :class="{'color-tip': !orderCreateData.buyer_ask_delivery_title}">{{ orderCreateData.buyer_ask_delivery_title ? orderCreateData.buyer_ask_delivery_title : '请选择送达时间' }}</text>
<text class="iconfont icon-right cell-more"></text> <text class="iconfont icon-right cell-more"></text>
</view> </view>
</view> </view>
</view> </view>
</block> </block>
<image class="address-line" :src="$util.img('public/uniapp/order/address-line.png')"></image> <image class="address-line" :src="$util.img('public/uniapp/order/address-line.png')"></image>
</view> </view>
<view class="store-box" :class="{'not-delivery-type': orderPaymentData.delivery.express_type.length <= 1}" v-if="orderPaymentData.delivery.delivery_type == 'store' && storeInfo.currStore"> <view class="store-box" :class="{'not-delivery-type': orderPaymentData.delivery.express_type.length <= 1}" v-if="orderPaymentData.delivery.delivery_type == 'store' && storeInfo.currStore">
<block v-if="storeInfo.currStore"> <block v-if="storeInfo.currStore">
<view @click="openSiteDelivery" class="store-info"> <view @click="openSiteDelivery" class="store-info">
<view class="store-address-info"> <view class="store-address-info">
<view class="info-wrap"> <view class="info-wrap">
<view class="title"> <view class="title">
<text>{{ storeInfo.currStore.store_name }}</text> <text>{{ storeInfo.currStore.store_name }}</text>
<view class="cell-more iconfont icon-right"></view> <view class="cell-more iconfont icon-right"></view>
</view> </view>
<view class="store-detail"> <view class="store-detail">
<view v-if="storeInfo.currStore.open_date"> <view v-if="storeInfo.currStore.open_date">
营业时间{{ storeInfo.currStore.open_date }}</view> 营业时间{{ storeInfo.currStore.open_date }}</view>
<view>地址{{ storeInfo.currStore.full_address }} <view>地址{{ storeInfo.currStore.full_address }}
{{ storeInfo.currStore.address }} {{ storeInfo.currStore.address }}
</view> </view>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
<view class="mobile-wrap store-mobile"> <view class="mobile-wrap store-mobile">
<view class="form-group"> <view class="form-group">
<text class="text">姓名</text> <text class="text">姓名</text>
<input type="text" placeholder-class="color-tip placeholder" class="input" v-model="member_address.name" disabled /> <input type="text" placeholder-class="color-tip placeholder" class="input" v-model="member_address.name" disabled />
</view> </view>
</view> </view>
<view class="mobile-wrap store-mobile"> <view class="mobile-wrap store-mobile">
<view class="form-group"> <view class="form-group">
<text class="text">预留手机</text> <text class="text">预留手机</text>
<input type="number" maxlength="11" placeholder="请输入您的手机号码" <input type="number" maxlength="11" placeholder="请输入您的手机号码"
placeholder-class="color-tip placeholder" class="input" v-model="member_address.mobile" /> placeholder-class="color-tip placeholder" class="input" v-model="member_address.mobile" />
</view> </view>
</view> </view>
<view class="store-time"> <view class="store-time">
<view class="left">自提时间</view> <view class="left">自提时间</view>
<view class="right" @click="storetime"> <view class="right" @click="storetime">
{{orderCreateData.buyer_ask_delivery_title}} {{orderCreateData.buyer_ask_delivery_title}}
<text class="iconfont icon-right"></text> <text class="iconfont icon-right"></text>
</view> </view>
</view> </view>
</block> </block>
<view v-else class="empty">当前无自提门店请选择其它配送方式</view> <view v-else class="empty">当前无自提门店请选择其它配送方式</view>
<image class="address-line" :src="$util.img('public/uniapp/order/address-line.png')"></image> <image class="address-line" :src="$util.img('public/uniapp/order/address-line.png')"></image>
</view> </view>
</template> </template>
<!-- 虚拟商品展示手机号 --> <!-- 虚拟商品展示手机号 -->
<view class="mobile-wrap" v-if="orderPaymentData.is_virtual == 1 && orderCreateData.member_address"> <view class="mobile-wrap" v-if="orderPaymentData.is_virtual == 1 && orderCreateData.member_address">
<view class="tips color-base-text"> <view class="tips color-base-text">
<text class="iconfont icon-gantanhao"></text> <text class="iconfont icon-gantanhao"></text>
购买虚拟类商品需填写手机号方便商家与您联系 购买虚拟类商品需填写手机号方便商家与您联系
</view> </view>
<view class="form-group"> <view class="form-group">
<text class="iconfont icon-dianhua2"></text> <text class="iconfont icon-dianhua2"></text>
<text class="text">手机号码</text> <text class="text">手机号码</text>
<input type="number" maxlength="11" placeholder="请输入您的手机号码" placeholder-class="color-tip placeholder" class="input" v-model="orderCreateData.member_address.mobile" /> <input type="number" maxlength="11" placeholder="请输入您的手机号码" placeholder-class="color-tip placeholder" class="input" v-model="orderCreateData.member_address.mobile" />
</view> </view>
</view> </view>
<!-- 店铺 --> <!-- 店铺 -->
<view class="site-wrap" :class="orderPaymentData.exchange_info.type == 2 || orderPaymentData.exchange_info.type == 3 ? 'margin-top' : ''"> <view class="site-wrap" :class="orderPaymentData.exchange_info.type == 2 || orderPaymentData.exchange_info.type == 3 ? 'margin-top' : ''">
<view class="site-body"> <view class="site-body">
<view class="goods-wrap"> <view class="goods-wrap">
<block v-if="orderPaymentData.exchange_info.type == 2"> <block v-if="orderPaymentData.exchange_info.type == 2">
<view class="goods-img"> <view class="goods-img">
<image :src="orderPaymentData.exchange_info.image ? $util.img(orderPaymentData.exchange_info.image) : $util.img('public/uniapp/point/coupon.png')" @error="imageError()" mode="aspectFill"/> <image :src="orderPaymentData.exchange_info.image ? $util.img(orderPaymentData.exchange_info.image) : $util.img('public/uniapp/point/coupon.png')" @error="imageError()" mode="aspectFill"/>
</view> </view>
</block> </block>
<block v-else-if="orderPaymentData.exchange_info.type == 3"> <block v-else-if="orderPaymentData.exchange_info.type == 3">
<view class="goods-img"> <view class="goods-img">
<image :src="orderPaymentData.exchange_info.image ? $util.img(orderPaymentData.exchange_info.image) : $util.img('public/uniapp/point/hongbao.png')" @error="imageError()" mode="aspectFill"/> <image :src="orderPaymentData.exchange_info.image ? $util.img(orderPaymentData.exchange_info.image) : $util.img('public/uniapp/point/hongbao.png')" @error="imageError()" mode="aspectFill"/>
</view> </view>
</block> </block>
<block v-else> <block v-else>
<view class="goods-img"> <view class="goods-img">
<image :src="$util.img(orderPaymentData.exchange_info.image)" @error="imageError()" mode="aspectFill"/> <image :src="$util.img(orderPaymentData.exchange_info.image)" @error="imageError()" mode="aspectFill"/>
</view> </view>
</block> </block>
<view class="goods-info"> <view class="goods-info">
<view class="goods-name">{{ orderPaymentData.exchange_info.name }}</view> <view class="goods-name">{{ orderPaymentData.exchange_info.name }}</view>
<view class="goods-sub-section"> <view class="goods-sub-section">
<view v-if="orderPaymentData.exchange_info.pay_type == 1" class="color-base-text"> <view v-if="orderPaymentData.exchange_info.pay_type == 1" class="color-base-text">
<text class="goods-price">{{ orderPaymentData.exchange_info.point }}</text> <text class="goods-price">{{ orderPaymentData.exchange_info.point }}</text>
<text class="unit">积分</text> <text class="unit">积分</text>
<template v-if="orderPaymentData.exchange_info.price != '0.00'"> <template v-if="orderPaymentData.exchange_info.price != '0.00'">
<text class="unit">+{{ $lang('common.currencySymbol') }}</text> <text class="unit">+{{ $lang('common.currencySymbol') }}</text>
<text class="goods-price">{{ orderPaymentData.exchange_info.price }}</text> <text class="goods-price">{{ orderPaymentData.exchange_info.price }}</text>
</template> </template>
</view> </view>
<view> <view>
<text class="font-size-tag">x</text> <text class="font-size-tag">x</text>
<text class="font-size-base">{{ orderPaymentData.goods_num }}</text> <text class="font-size-base">{{ orderPaymentData.goods_num }}</text>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
<view class="site-footer"> <view class="site-footer">
<view class="order-cell"> <view class="order-cell">
<text class="tit">买家留言</text> <text class="tit">买家留言</text>
<view class="box"><input type="text" placeholder="留言前建议先与商家协调一致" placeholder-class="color-tip" v-model="orderCreateData.buyer_message" /></view> <view class="box"><input type="text" placeholder="留言前建议先与商家协调一致" placeholder-class="color-tip" v-model="orderCreateData.buyer_message" /></view>
</view> </view>
</view> </view>
</view> </view>
<!-- 金额 --> <!-- 金额 -->
<view class="order-money"> <view class="order-money">
<view class="order-cell"> <view class="order-cell">
<text class="tit">所需积分</text> <text class="tit">所需积分</text>
<view class="box"> <view class="box">
<text class="money">{{ orderPaymentData.point }}</text> <text class="money">{{ orderPaymentData.point }}</text>
<text class="unit">积分</text> <text class="unit">积分</text>
</view> </view>
</view> </view>
<view class="order-cell" v-if="orderPaymentData.exchange_info.type == 1 && orderPaymentData.delivery_money > 0"> <view class="order-cell" v-if="orderPaymentData.exchange_info.type == 1 && orderPaymentData.delivery_money > 0">
<text class="tit">运费</text> <text class="tit">运费</text>
<view class="box"> <view class="box">
<text class="unit">{{ $lang('common.currencySymbol') }}</text> <text class="unit">{{ $lang('common.currencySymbol') }}</text>
<text class="money">{{ orderPaymentData.delivery_money | moneyFormat }}</text> <text class="money">{{ orderPaymentData.delivery_money | moneyFormat }}</text>
</view> </view>
</view> </view>
</view> </view>
<view class="error-message" v-if="orderPaymentData.delivery && orderPaymentData.delivery.delivery_type == 'local' && orderPaymentData.delivery && orderPaymentData.delivery.error && orderPaymentData.delivery.error !== ''"> <view class="error-message" v-if="orderPaymentData.delivery && orderPaymentData.delivery.delivery_type == 'local' && orderPaymentData.delivery && orderPaymentData.delivery.error && orderPaymentData.delivery.error !== ''">
{{orderPaymentData.delivery.error_msg}} {{orderPaymentData.delivery.error_msg}}
</view> </view>
<view class="order-submit" :class="{ 'bottom-safe-area': isIphoneX }"> <view class="order-submit" :class="{ 'bottom-safe-area': isIphoneX }">
<view class="order-settlement-info"> <view class="order-settlement-info">
<text class="font-size-base color-tip margin-right">{{ orderPaymentData.goods_num }}</text> <text class="font-size-base color-tip margin-right">{{ orderPaymentData.goods_num }}</text>
<text class="font-size-base">合计</text> <text class="font-size-base">合计</text>
<text class="color-base-text money">{{ orderPaymentData.point }}</text> <text class="color-base-text money">{{ orderPaymentData.point }}</text>
<text class="color-base-text unit">积分</text> <text class="color-base-text unit">积分</text>
<template v-if="orderPaymentData.exchange_info.type == 1 && orderPaymentData.order_money > 0"> <template v-if="orderPaymentData.exchange_info.type == 1 && orderPaymentData.order_money > 0">
<text class="color-base-text unit">+{{ $lang('common.currencySymbol') }}</text> <text class="color-base-text unit">+{{ $lang('common.currencySymbol') }}</text>
<text class="color-base-text money">{{ orderPaymentData.order_money | moneyFormat }}</text> <text class="color-base-text money">{{ orderPaymentData.order_money | moneyFormat }}</text>
</template> </template>
</view> </view>
<view class="submit-btn"> <view class="submit-btn">
<button v-if="createBtn()" type="primary" class="mini" size="mini" @click="openChoosePayment()">提交订单</button> <button v-if="createBtn()" type="primary" class="mini" size="mini" @click="openChoosePayment()">提交订单</button>
<button v-else class="no-submit mini" size="mini"> <button v-else class="no-submit mini" size="mini">
<block v-if="orderPaymentData.delivery && orderPaymentData.delivery.delivery_type == 'local' && orderPaymentData.delivery && orderPaymentData.delivery.error && orderPaymentData.delivery.start_money > orderPaymentData.price"> <block v-if="orderPaymentData.delivery && orderPaymentData.delivery.delivery_type == 'local' && orderPaymentData.delivery && orderPaymentData.delivery.error && orderPaymentData.delivery.start_money > orderPaymentData.price">
{{ orderPaymentData.delivery.start_money-orderPaymentData.price | moneyFormat }}起送 {{ orderPaymentData.delivery.start_money-orderPaymentData.price | moneyFormat }}起送
</block> </block>
<block v-else >提交订单</block> <block v-else >提交订单</block>
</button> </button>
</view> </view>
</view> </view>
<div class="order-submit-block"></div> <div class="order-submit-block"></div>
<!-- 门店列表弹窗 --> <!-- 门店列表弹窗 -->
<uni-popup ref="deliveryPopup" type="bottom"> <uni-popup ref="deliveryPopup" type="bottom">
<view class="delivery-popup popup"> <view class="delivery-popup popup">
<view class="popup-header"> <view class="popup-header">
<text class="tit">已为您甄选出附近所有相关门店</text> <text class="tit">已为您甄选出附近所有相关门店</text>
<text class="iconfont icon-close" @click="closePopup('deliveryPopup')"></text> <text class="iconfont icon-close" @click="closePopup('deliveryPopup')"></text>
</view> </view>
<view class="popup-body store-popup" :class="{ 'safe-area': isIphoneX }"> <view class="popup-body store-popup" :class="{ 'safe-area': isIphoneX }">
<view class="delivery-content"> <view class="delivery-content">
<view class="item-wrap" v-for="(item, index) in storeInfo.storeList" :key="index" @click="selectPickupPoint(item)"> <view class="item-wrap" v-for="(item, index) in storeInfo.storeList" :key="index" @click="selectPickupPoint(item)">
<view class="detail"> <view class="detail">
<view class="name" :class="item.store_id == orderPaymentData.delivery.store_id ? 'color-base-text' : ''"> <view class="name" :class="item.store_id == orderPaymentData.delivery.store_id ? 'color-base-text' : ''">
<text>{{ item.store_name }}</text> <text>{{ item.store_name }}</text>
<text v-if="item.distance">({{ item.distance }}km)</text> <text v-if="item.distance">({{ item.distance }}km)</text>
</view> </view>
<view class="info"> <view class="info">
<view :class="item.store_id == orderPaymentData.delivery.store_id ? 'color-base-text' : ''" class="font-size-goods-tag"> <view :class="item.store_id == orderPaymentData.delivery.store_id ? 'color-base-text' : ''" class="font-size-goods-tag">
营业时间{{ item.open_date }} 营业时间{{ item.open_date }}
</view> </view>
<view :class="item.store_id == orderPaymentData.delivery.store_id ? 'color-base-text' : ''" class="font-size-goods-tag"> <view :class="item.store_id == orderPaymentData.delivery.store_id ? 'color-base-text' : ''" class="font-size-goods-tag">
地址{{ item.full_address }}{{ item.address }} 地址{{ item.full_address }}{{ item.address }}
</view> </view>
</view> </view>
</view> </view>
<view class="icon" v-if="item.store_id == orderPaymentData.delivery.store_id"><text class="iconfont icon-yuan_checked color-base-text"></text></view> <view class="icon" v-if="item.store_id == orderPaymentData.delivery.store_id"><text class="iconfont icon-yuan_checked color-base-text"></text></view>
</view> </view>
<view v-if="!storeInfo.storeList" class="empty">所选择收货地址附近没有可以自提的门店</view> <view v-if="!storeInfo.storeList" class="empty">所选择收货地址附近没有可以自提的门店</view>
</view> </view>
</view> </view>
</view> </view>
</uni-popup> </uni-popup>
</scroll-view> </scroll-view>
<!-- 选择支付方式弹窗 --> <!-- 选择支付方式弹窗 -->
<ns-payment ref="choosePaymentPopup" :payMoney="orderPaymentData.order_money" @confirm="orderCreate"></ns-payment> <ns-payment ref="choosePaymentPopup" :payMoney="orderPaymentData.order_money" @confirm="orderCreate"></ns-payment>
<loading-cover ref="loadingCover"></loading-cover> <loading-cover ref="loadingCover"></loading-cover>
<!-- 门店自提同城配送时间选择 --> <!-- 门店自提同城配送时间选择 -->
<ns-select-time @selectTime='selectTime' ref="TimePopup"></ns-select-time> <ns-select-time @selectTime='selectTime' ref="TimePopup"></ns-select-time>
</view> </view>
</template> </template>
<script> <script>
import payment from './public/js/payment.js'; import payment from './public/js/payment.js';
import uniPopup from '@/components/uni-popup/uni-popup.vue'; import uniPopup from '@/components/uni-popup/uni-popup.vue';
export default { export default {
components: { components: {
uniPopup, uniPopup,
}, },
mixins: [payment] mixins: [payment]
}; };
</script> </script>
<style lang="scss"> <style lang="scss">
@import "@/common/css/order_parment.scss"; @import "@/common/css/order_parment.scss";
</style> </style>
<style scoped> <style lang="scss" scoped>
/deep/ .uni-popup__wrapper.uni-custom .uni-popup__wrapper-box { /deep/ .uni-popup__wrapper.uni-custom .uni-popup__wrapper-box {
background: none; background: none;
max-height: unset !important; max-height: unset !important;
overflow-y: hidden !important; overflow-y: hidden !important;
} }
>>>.uni-popup__wrapper { >>>.uni-popup__wrapper {
border-radius: 20rpx 20rpx 0 0; border-radius: 20rpx 20rpx 0 0;
} }
>>>.uni-popup { >>>.uni-popup {
z-index: 8; z-index: 8;
} }
</style> </style>

View File

@@ -3,7 +3,7 @@
<view class="about w100"> <view class="about w100">
<view class="list_cotact padding-top"> <view class="list_cotact padding-top">
<view class="container"> <view class="container">
<block v-for="(item, index) in dataList" :key="index"> <block v-for="(item, index) in dataList" :key="item.case_id || index">
<view class="view_ul_100" style="margin-bottom:30rpx;"> <view class="view_ul_100" style="margin-bottom:30rpx;">
<view class="bl clearfix bor bg-white"> <view class="bl clearfix bor bg-white">
<block v-if="item.$orig.case_type === 0"> <block v-if="item.$orig.case_type === 0">
@@ -312,7 +312,7 @@ export default {
}; };
</script> </script>
<style scoped> <style lang="scss" scoped>
.item { .item {
display: flex; display: flex;
padding: 30rpx 0; padding: 30rpx 0;

View File

@@ -1360,7 +1360,7 @@ export default {
}; };
</script> </script>
<style> <style lang="scss">
.my-canvas { .my-canvas {
display: flex; display: flex;
position: fixed !important; position: fixed !important;

View File

@@ -108,7 +108,7 @@ export default {
}; };
</script> </script>
<style scoped> <style lang="scss" scoped>
@keyframes twinkling { @keyframes twinkling {
0% { 0% {
opacity: 0.2; opacity: 0.2;

View File

@@ -1,218 +1,218 @@
<template> <template>
<view class="rate-box" :class="[{ animation }, containerClass]" @touchmove="ontouchmove" @touchend="touchMoving = false"> <view class="rate-box" :class="[{ animation }, containerClass]" @touchmove="ontouchmove" @touchend="touchMoving = false">
<view <view
v-for="(val, i) in list" v-for="(val, i) in list"
:key="val" :key="val"
class="rate" class="rate"
:style="{ fontSize, paddingLeft: i !== 0 ? rateMargin : 0, paddingRight: i < list.length - 1 ? rateMargin : 0 }" :style="{ fontSize, paddingLeft: i !== 0 ? rateMargin : 0, paddingRight: i < list.length - 1 ? rateMargin : 0 }"
:class="[ :class="[
{ scale: !disabled && val <= rateValue && animation && touchMoving, 'color-base-text': val <= rateValue, defaultColor: val > rateValue }, { scale: !disabled && val <= rateValue && animation && touchMoving, 'color-base-text': val <= rateValue, defaultColor: val > rateValue },
`rate-${i}`, `rate-${i}`,
rateClass rateClass
]" ]"
:data-val="val" :data-val="val"
@click="onItemClick" @click="onItemClick"
> >
<text class="iconfont icon-star"></text> <text class="iconfont icon-star"></text>
</view> </view>
</view> </view>
</template> </template>
<script> <script>
import { getClientRect } from './common'; import { getClientRect } from './common';
export default { export default {
name: 'sx-rate', name: 'sx-rate',
props: { props: {
// 当前值 // 当前值
value: { value: {
type: [Number, String] type: [Number, String]
}, },
// 最大星星数量 // 最大星星数量
max: { max: {
type: Number, type: Number,
default: 5 default: 5
}, },
// 禁用 // 禁用
disabled: { disabled: {
type: Boolean, type: Boolean,
default: false default: false
}, },
// 动画效果 // 动画效果
animation: { animation: {
type: Boolean, type: Boolean,
default: true default: true
}, },
// 默认星星颜色 // 默认星星颜色
defaultColor: { defaultColor: {
type: String, type: String,
default: '#ccc' default: '#ccc'
}, },
// 滑选后星星颜色 // 滑选后星星颜色
activeColor: { activeColor: {
type: String type: String
// default: '#FFB700' // default: '#FFB700'
}, },
// 星星大小 // 星星大小
fontSize: { fontSize: {
type: String, type: String,
default: 'inherit' default: 'inherit'
}, },
// 星星间距 // 星星间距
margin: { margin: {
type: String, type: String,
default: '' default: ''
}, },
// 自定义类名-容器 // 自定义类名-容器
containerClass: { containerClass: {
type: String, type: String,
default: '' default: ''
}, },
// 自定义类名-星星 // 自定义类名-星星
rateClass: { rateClass: {
type: String, type: String,
default: '' default: ''
}, },
index: { index: {
// 如果页面中存在多个该组件,通过该属性区分 // 如果页面中存在多个该组件,通过该属性区分
type: [Number, String] type: [Number, String]
} }
}, },
data() { data() {
return { return {
rateValue: 0, rateValue: 0,
touchMoving: false, touchMoving: false,
startX: [], startX: [],
startW: 30 startW: 30
}; };
}, },
computed: { computed: {
list() { list() {
return [...new Array(this.max)].map((_, i) => i + 1); return [...new Array(this.max)].map((_, i) => i + 1);
}, },
rateMargin() { rateMargin() {
let margin = this.margin; let margin = this.margin;
if (!margin) return 0; if (!margin) return 0;
switch (typeof margin) { switch (typeof margin) {
case 'number': case 'number':
margin = margin * 2 + 'rpx'; margin = margin * 2 + 'rpx';
case 'string': case 'string':
break; break;
default: default:
return 0; return 0;
} }
let reg = /^(\d+)([^\d]*)/; let reg = /^(\d+)([^\d]*)/;
let result = reg.exec(margin); let result = reg.exec(margin);
if (!result) return 0; if (!result) return 0;
let [_, num, unit] = result; let [_, num, unit] = result;
return num / 2 + unit; return num / 2 + unit;
} }
}, },
watch: { watch: {
value: { value: {
handler(val) { handler(val) {
this.rateValue = val; this.rateValue = val;
}, },
immediate: true immediate: true
} }
}, },
methods: { methods: {
// 计算星星位置 // 计算星星位置
async initStartX() { async initStartX() {
let { max } = this; let { max } = this;
this.startX = []; this.startX = [];
for (let i = 0; i < max; i++) { for (let i = 0; i < max; i++) {
let selector = `.rate-${i}`; let selector = `.rate-${i}`;
let { left, width } = await getClientRect(selector, this); let { left, width } = await getClientRect(selector, this);
this.startX.push(left); this.startX.push(left);
this.startW = width; this.startW = width;
} }
}, },
/** /**
* 手指滑动事件回调 * 手指滑动事件回调
* https://github.com/sunxi1997/uni-app-sx-rate/pull/1 * https://github.com/sunxi1997/uni-app-sx-rate/pull/1
* 原本的触摸处理在自定了样式后可能会出现bug, 已解决 * 原本的触摸处理在自定了样式后可能会出现bug, 已解决
*/ */
async ontouchmove(e) { async ontouchmove(e) {
if (!this.touchMoving) { if (!this.touchMoving) {
this.touchMoving = true; this.touchMoving = true;
// 开始手指滑动时重新计算星星位置,防止星星位置意外变化 // 开始手指滑动时重新计算星星位置,防止星星位置意外变化
await this.initStartX(); await this.initStartX();
} }
let { startX, startW, max } = this; let { startX, startW, max } = this;
let { touches } = e; let { touches } = e;
// 触摸焦点停留的位置 // 触摸焦点停留的位置
let { pageX } = touches[touches.length - 1]; let { pageX } = touches[touches.length - 1];
// 超出最左边, 0 星 // 超出最左边, 0 星
if (pageX <= startX[0]) return this.toggle(0); if (pageX <= startX[0]) return this.toggle(0);
// 刚好在第一颗星 // 刚好在第一颗星
else if (pageX <= startX[0] + startW) return this.toggle(1); else if (pageX <= startX[0] + startW) return this.toggle(1);
// 超出最右边, 最大星 // 超出最右边, 最大星
else if (pageX >= startX[max - 1]) return this.toggle(max); else if (pageX >= startX[max - 1]) return this.toggle(max);
//计算星星停留的位置 //计算星星停留的位置
let startXHash = startX.concat(pageX).sort((a, b) => a - b); let startXHash = startX.concat(pageX).sort((a, b) => a - b);
this.toggle(startXHash.indexOf(pageX)); this.toggle(startXHash.indexOf(pageX));
}, },
// 点击回调 // 点击回调
onItemClick(e) { onItemClick(e) {
let { val } = e.currentTarget.dataset; let { val } = e.currentTarget.dataset;
this.toggle(val); this.toggle(val);
}, },
// 修改值 // 修改值
toggle(val) { toggle(val) {
let { disabled } = this; let { disabled } = this;
if (disabled) return; if (disabled) return;
if (this.rateValue !== val) { if (this.rateValue !== val) {
this.rateValue = val; this.rateValue = val;
this.$emit('update:value', val); this.$emit('update:value', val);
let data = { let data = {
index: this.index, index: this.index,
value: val value: val
}; };
this.$emit('change', data); this.$emit('change', data);
} }
} }
}, },
mounted() {} mounted() {}
}; };
</script> </script>
<style scoped> <style lang="scss" scoped>
@import './sx-rate/iconfont.css'; @import './sx-rate/iconfont.css';
</style> </style>
<style lang="scss"> <style lang="scss">
.rate-box { .rate-box {
min-height: 1.4em; min-height: 1.4em;
display: flex; display: flex;
align-items: center; align-items: center;
} }
.rate { .rate {
display: inline-flex; display: inline-flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
width: 1.2em; width: 1.2em;
transition: all 0.15s linear; transition: all 0.15s linear;
} }
.rate.scale { .rate.scale {
transform: scale(1.1); transform: scale(1.1);
} }
.defaultColor { .defaultColor {
color: #ccc !important; color: #ccc !important;
} }
.activeColor { .activeColor {
} }
</style> </style>

View File

@@ -183,7 +183,7 @@
} }
</script> </script>
<style scoped> <style lang="scss" scoped>
.search-wrap { .search-wrap {
flex: 0.5; flex: 0.5;
padding: 30rpx 30rpx 0; padding: 30rpx 30rpx 0;

View File

@@ -2,9 +2,9 @@
<page-meta :page-style="themeColor"></page-meta> <page-meta :page-style="themeColor"></page-meta>
<view class="help"> <view class="help">
<block v-if="dataList.length"> <block v-if="dataList.length">
<view class="help-item" v-for="(item, index) in dataList" :key="index"> <view class="help-item" v-for="(item, index) in dataList" :key="item.class_id || index">
<view :class="['item-title', item.child_list.length == 0 ? 'empty' : '']">{{ item.class_name }}</view> <view :class="['item-title', item.child_list.length == 0 ? 'empty' : '']">{{ item.class_name }}</view>
<view class="item-content" v-for="(s_item, s_index) in item.child_list" :key="s_index" @click="helpDetail(s_item)">{{ s_item.title }}</view> <view class="item-content" v-for="(s_item, s_index) in item.child_list" :key="s_item.id || s_index" @click="helpDetail(s_item)">{{ s_item.title }}</view>
</view> </view>
</block> </block>
<block v-else><ns-empty text="暂无帮助信息" :isIndex="false"></ns-empty></block> <block v-else><ns-empty text="暂无帮助信息" :isIndex="false"></ns-empty></block>

View File

@@ -1,95 +1,95 @@
<template> <template>
<page-meta :page-style="themeColor"></page-meta> <page-meta :page-style="themeColor"></page-meta>
<view :style="{ backgroundColor: bgColor, minHeight: openBottomNav ? 'calc(100vh - 55px)' : '' }" class="page-img"> <view :style="{ backgroundColor: bgColor, minHeight: openBottomNav ? 'calc(100vh - 55px)' : '' }" class="page-img">
<view class="page-header" v-if="diyData.global && diyData.global.navBarSwitch" :style="{ backgroundImage: bgImg }"> <view class="page-header" v-if="diyData.global && diyData.global.navBarSwitch" :style="{ backgroundImage: bgImg }">
<ns-navbar :title-color="textNavColor" :data="diyData.global" :scrollTop="scrollTop" :isBack="true"/> <ns-navbar :title-color="textNavColor" :data="diyData.global" :scrollTop="scrollTop" :isBack="true"/>
</view> </view>
<diy-index-page v-if="topIndexValue" ref="indexPage" :value="topIndexValue" :bgUrl="bgUrl" :scrollTop="scrollTop" :diyGlobal="diyData.global" class="diy-index-page"> <diy-index-page v-if="topIndexValue" ref="indexPage" :value="topIndexValue" :bgUrl="bgUrl" :scrollTop="scrollTop" :diyGlobal="diyData.global" class="diy-index-page">
<diy-group ref="diyGroup" v-if="diyData.value" :diyData="diyData" :scrollTop="scrollTop" :haveTopCategory="true"/> <diy-group ref="diyGroup" v-if="diyData.value" :diyData="diyData" :scrollTop="scrollTop" :haveTopCategory="true"/>
<ns-copyright v-show="isShowCopyRight"/> <ns-copyright v-show="isShowCopyRight"/>
</diy-index-page> </diy-index-page>
<view v-else class="bg-index" :style="{ backgroundImage: backgroundUrl, paddingTop: paddingTop, marginTop: marginTop }"> <view v-else class="bg-index" :style="{ backgroundImage: backgroundUrl, paddingTop: paddingTop, marginTop: marginTop }">
<diy-group ref="diyGroup" v-if="diyData.value" :diyData="diyData" :scrollTop="scrollTop"/> <diy-group ref="diyGroup" v-if="diyData.value" :diyData="diyData" :scrollTop="scrollTop"/>
<ns-copyright v-show="isShowCopyRight"/> <ns-copyright v-show="isShowCopyRight"/>
</view> </view>
<template v-if="diyData.global && diyData.global.popWindow && diyData.global.popWindow.count != -1 && diyData.global.popWindow.imageUrl"> <template v-if="diyData.global && diyData.global.popWindow && diyData.global.popWindow.count != -1 && diyData.global.popWindow.imageUrl">
<view @touchmove.prevent.stop> <view @touchmove.prevent.stop>
<uni-popup ref="uniPopupWindow" type="center" class="wap-floating" :maskClick="false"> <uni-popup ref="uniPopupWindow" type="center" class="wap-floating" :maskClick="false">
<view class="image-wrap"> <view class="image-wrap">
<image :src="$util.img(diyData.global.popWindow.imageUrl)" :style="popWindowStyle" @click="uniPopupWindowFn()" mode="aspectFit"/> <image :src="$util.img(diyData.global.popWindow.imageUrl)" :style="popWindowStyle" @click="uniPopupWindowFn()" mode="aspectFit"/>
</view> </view>
<text class="iconfont icon-round-close" @click="closePopupWindow"></text> <text class="iconfont icon-round-close" @click="closePopupWindow"></text>
</uni-popup> </uni-popup>
</view> </view>
</template> </template>
<!-- 底部tabBar --> <!-- 底部tabBar -->
<view class="page-bottom" v-if="openBottomNav"> <view class="page-bottom" v-if="openBottomNav">
<diy-bottom-nav @callback="callback" :name="name"/> <diy-bottom-nav @callback="callback" :name="name"/>
</view> </view>
<!-- 收藏 --> <!-- 收藏 -->
<uni-popup ref="collectPopupWindow" type="top" class="wap-floating wap-floating-collect"> <uni-popup ref="collectPopupWindow" type="top" class="wap-floating wap-floating-collect">
<view v-if="showTip" class="collectPopupWindow" :style="{ marginTop: (collectTop + statusBarHeight) * 2 + 'rpx' }"> <view v-if="showTip" class="collectPopupWindow" :style="{ marginTop: (collectTop + statusBarHeight) * 2 + 'rpx' }">
<image :src="$util.img('public/uniapp/index/collect2.png')" mode="aspectFit"/> <image :src="$util.img('public/uniapp/index/collect2.png')" mode="aspectFit"/>
<text @click="closeCollectPopupWindow">我知道了</text> <text @click="closeCollectPopupWindow">我知道了</text>
</view> </view>
</uni-popup> </uni-popup>
<!-- #ifdef MP-WEIXIN --> <!-- #ifdef MP-WEIXIN -->
<!-- 小程序隐私协议 --> <!-- 小程序隐私协议 -->
<privacy-popup ref="privacyPopup"></privacy-popup> <privacy-popup ref="privacyPopup"></privacy-popup>
<!-- #endif --> <!-- #endif -->
</view> </view>
</template> </template>
<script> <script>
import uniPopup from '@/components/uni-popup/uni-popup.vue'; import uniPopup from '@/components/uni-popup/uni-popup.vue';
import nsNavbar from '@/components/ns-navbar/ns-navbar.vue'; import nsNavbar from '@/components/ns-navbar/ns-navbar.vue';
import diyJs from '@/common/js/diy.js'; import diyJs from '@/common/js/diy.js';
import microPageJs from './public/js/diy.js'; import microPageJs from './public/js/diy.js';
export default { export default {
components: { components: {
uniPopup, uniPopup,
nsNavbar nsNavbar
}, },
mixins: [diyJs, microPageJs] mixins: [diyJs, microPageJs]
}; };
</script> </script>
<style lang="scss"> <style lang="scss">
@import '@/common/css/diy.scss'; @import '@/common/css/diy.scss';
</style> </style>
<style scoped> <style lang="scss" scoped>
.wap-floating>>>.uni-popup__wrapper.uni-custom .uni-popup__wrapper-box { .wap-floating>>>.uni-popup__wrapper.uni-custom .uni-popup__wrapper-box {
background: none !important; background: none !important;
} }
/deep/.diy-index-page .uni-popup .uni-popup__wrapper-box { /deep/.diy-index-page .uni-popup .uni-popup__wrapper-box {
border-radius: 0; border-radius: 0;
} }
.choose-store>>>.goodslist-uni-popup-box { .choose-store>>>.goodslist-uni-popup-box {
width: 80%; width: 80%;
} }
/deep/ .placeholder { /deep/ .placeholder {
height: 0; height: 0;
} }
/deep/::-webkit-scrollbar { /deep/::-webkit-scrollbar {
width: 0; width: 0;
height: 0; height: 0;
background-color: transparent; background-color: transparent;
display: none; display: none;
} }
/deep/ .sku-layer .uni-popup__wrapper.uni-custom .uni-popup__wrapper-box { /deep/ .sku-layer .uni-popup__wrapper.uni-custom .uni-popup__wrapper-box {
max-height: unset !important; max-height: unset !important;
} }
</style> </style>

View File

@@ -470,7 +470,7 @@
} }
</style> </style>
<style scoped> <style lang="scss" scoped>
/deep/ .reward-popup .uni-popup__wrapper-box { /deep/ .reward-popup .uni-popup__wrapper-box {
background: none !important; background: none !important;
max-width: unset !important; max-width: unset !important;

View File

@@ -12,7 +12,7 @@
</view> </view>
</view> </view>
<block v-if="dataList.length > 0"> <block v-if="dataList.length > 0">
<view class="list-item" v-for="(item, index) in dataList" :key="index"> <view class="list-item" v-for="(item, index) in dataList" :key="item.withdraw_type_id || index">
<view class="item-top"> <view class="item-top">
<view class="item-left"> <view class="item-left">
<view class="title-text">{{ item.withdraw_type_name }}</view> <view class="title-text">{{ item.withdraw_type_name }}</view>
@@ -425,12 +425,12 @@
} }
} }
</style> </style>
<style> <style lang="scss">
/deep/ .mescroll-upwarp { /deep/ .mescroll-upwarp {
padding-bottom: 150rpx; padding-bottom: 150rpx;
} }
</style> </style>
<style> <style lang="scss">
.item-bottom>>>.uni-switch-wrapper .uni-switch-input { .item-bottom>>>.uni-switch-wrapper .uni-switch-input {
height: 48rpx !important; height: 48rpx !important;
width: 88rpx !important; width: 88rpx !important;

View File

@@ -580,7 +580,7 @@
height: calc(100vh - 260rpx); height: calc(100vh - 260rpx);
} }
</style> </style>
<style> <style lang="scss">
.address-item>>>.uni-switch-wrapper .uni-switch-input { .address-item>>>.uni-switch-wrapper .uni-switch-input {
height: 48rpx !important; height: 48rpx !important;
width: 88rpx !important; width: 88rpx !important;

View File

@@ -27,7 +27,7 @@
<!-- 明细列表 --> <!-- 明细列表 -->
<block v-if="dataList.length > 0"> <block v-if="dataList.length > 0">
<view class="detailed-wrap"> <view class="detailed-wrap">
<view class="balances" v-for="(item, index) in dataList" :key="index"> <view class="balances" v-for="(item, index) in dataList" :key="item.balance_id || index">
<image :src="$util.img('public/uniapp/balance/recharge.png')" class="balances-img" v-if="item.account_data > 0"></image> <image :src="$util.img('public/uniapp/balance/recharge.png')" class="balances-img" v-if="item.account_data > 0"></image>
<image v-else :src="$util.img('public/uniapp/balance/shopping.png')" mode="widthFix"></image> <image v-else :src="$util.img('public/uniapp/balance/shopping.png')" mode="widthFix"></image>
<view class="balances-info" @click="toFromDetail(item)"> <view class="balances-info" @click="toFromDetail(item)">

View File

@@ -222,7 +222,7 @@
} }
</style> </style>
<style scoped> <style lang="scss" scoped>
/deep/ .sku-layer .uni-popup__wrapper.uni-custom .uni-popup__wrapper-box { /deep/ .sku-layer .uni-popup__wrapper.uni-custom .uni-popup__wrapper-box {
max-height: unset !important; max-height: unset !important;
} }

View File

@@ -79,7 +79,7 @@
@import './public/css/collection.scss'; @import './public/css/collection.scss';
</style> </style>
<style scoped> <style lang="scss" scoped>
/deep/ .sku-layer .uni-popup__wrapper.uni-custom .uni-popup__wrapper-box { /deep/ .sku-layer .uni-popup__wrapper.uni-custom .uni-popup__wrapper-box {
max-height: unset !important; max-height: unset !important;
} }

View File

@@ -22,7 +22,7 @@
<block v-if="inviteList.length > 0"> <block v-if="inviteList.length > 0">
<view class="invitelist_block"> <view class="invitelist_block">
<view class="invitelist"> <view class="invitelist">
<view class="list-item" v-for="(item, index) in inviteList"> <view class="list-item" v-for="(item, index) in inviteList" :key="item.invite_id || index">
<view class="img color-base-border"> <view class="img color-base-border">
<image mode="aspectFit" :src="item.headimg == '' ? $util.img($util.getDefaultImage().head) : $util.img(item.headimg)"/> <image mode="aspectFit" :src="item.headimg == '' ? $util.img($util.getDefaultImage().head) : $util.img(item.headimg)"/>
</view> </view>
@@ -265,7 +265,7 @@
<style lang="scss"> <style lang="scss">
@import './public/css/invite_friends.scss'; @import './public/css/invite_friends.scss';
</style> </style>
<style scoped> <style lang="scss" scoped>
/deep/ .uni-popup__wrapper.bottom { /deep/ .uni-popup__wrapper.bottom {
border-radius: 24rpx 24rpx 0 0; border-radius: 24rpx 24rpx 0 0;
} }

View File

@@ -23,7 +23,7 @@
<block v-if="dataList.length"> <block v-if="dataList.length">
<view class="detailed-wrap"> <view class="detailed-wrap">
<view class="cont"> <view class="cont">
<view class="detailed-item" v-for="(item, index) in dataList" :key="index"> <view class="detailed-item" v-for="(item, index) in dataList" :key="item.point_id || index">
<view class="info" @click="toFromDetail(item)"> <view class="info" @click="toFromDetail(item)">
<view class="event">{{ item.type_name }}</view> <view class="event">{{ item.type_name }}</view>
<view class="time-box"> <view class="time-box">

View File

@@ -6,7 +6,7 @@
<block v-if="dataList.length"> <block v-if="dataList.length">
<view class="detailed-wrap"> <view class="detailed-wrap">
<view class="cont"> <view class="cont">
<view class="detailed-item" v-for="(item, index) in dataList" :key="index" @click="toDetail(item.id)"> <view class="detailed-item" v-for="(item, index) in dataList" :key="item.withdraw_type_id || index" @click="toDetail(item.id)">
<view class="info"> <view class="info">
<view class="event">{{ item.transfer_type_name }}</view> <view class="event">{{ item.transfer_type_name }}</view>
<view> <view>

View File

@@ -4,7 +4,7 @@
<mescroll-uni @getData="getData" ref="mescroll"> <mescroll-uni @getData="getData" ref="mescroll">
<block slot="list"> <block slot="list">
<view class="notice-list" v-if="dataList.length"> <view class="notice-list" v-if="dataList.length">
<view class="notice-item" @click="jumpDetail(item.id)" v-for="(item, index) in dataList" :key="index"> <view class="notice-item" @click="jumpDetail(item.id)" v-for="(item, index) in dataList" :key="item.notice_id || index">
<view class="title-info"> <view class="title-info">
<view class="title"> <view class="title">
<text v-if="item.is_top == 1" class="color-base-bg tag">置顶</text> <text v-if="item.is_top == 1" class="color-base-bg tag">置顶</text>

View File

@@ -291,7 +291,7 @@ export default {
<style lang="scss"> <style lang="scss">
@import './public/css/refund.scss'; @import './public/css/refund.scss';
</style> </style>
<style scoped> <style lang="scss" scoped>
/deep/ .uni-popup__wrapper.uni-custom .uni-popup__wrapper-box { /deep/ .uni-popup__wrapper.uni-custom .uni-popup__wrapper-box {
background: none; background: none;
max-height: unset !important; max-height: unset !important;

View File

@@ -293,7 +293,7 @@ export default {
<style lang="scss"> <style lang="scss">
@import './public/css/refund.scss'; @import './public/css/refund.scss';
</style> </style>
<style scoped> <style lang="scss" scoped>
/deep/ .uni-popup__wrapper.uni-custom .uni-popup__wrapper-box { /deep/ .uni-popup__wrapper.uni-custom .uni-popup__wrapper-box {
background: none; background: none;
max-height: unset !important; max-height: unset !important;

View File

@@ -99,7 +99,7 @@
<style lang="scss"> <style lang="scss">
@import './public/css/refund.scss'; @import './public/css/refund.scss';
</style> </style>
<style scoped> <style lang="scss" scoped>
/deep/ .uni-popup__wrapper.uni-custom .uni-popup__wrapper-box { /deep/ .uni-popup__wrapper.uni-custom .uni-popup__wrapper-box {
background: none; background: none;
max-height: unset !important; max-height: unset !important;

View File

@@ -337,7 +337,7 @@
} }
</style> </style>
<style scoped> <style lang="scss" scoped>
/deep/ .sku-layer .uni-popup__wrapper.uni-custom .uni-popup__wrapper-box { /deep/ .sku-layer .uni-popup__wrapper.uni-custom .uni-popup__wrapper-box {
max-height: unset !important; max-height: unset !important;
} }

View File

@@ -125,7 +125,7 @@ export default {
}; };
</script> </script>
<style scoped> <style lang="scss" scoped>
.content { .content {
padding: 20rpx; padding: 20rpx;
} }

View File

@@ -162,7 +162,7 @@ export default {
}; };
</script> </script>
<style scoped> <style lang="scss" scoped>
.content { .content {
padding: 20rpx; padding: 20rpx;
background-color: #f8f8f8; background-color: #f8f8f8;

View File

@@ -76,7 +76,7 @@ export default {
}; };
</script> </script>
<style scoped> <style lang="scss" scoped>
.picker-container { .picker-container {
padding: 20rpx; padding: 20rpx;
display: flex; display: flex;

View File

@@ -40,7 +40,7 @@
} }
</script> </script>
<style> <style lang="scss">
.error-msg{ .error-msg{
text-align: center; text-align: center;
padding-top: 10vh; padding-top: 10vh;

View File

@@ -1,498 +1,498 @@
<template> <template>
<view id="_root" :class="(selectable?'_select ':'')+'_root'" :style="containerStyle"> <view id="_root" :class="(selectable?'_select ':'')+'_root'" :style="containerStyle">
<slot v-if="!nodes[0]" /> <slot v-if="!nodes[0]" />
<!-- #ifndef APP-PLUS-NVUE --> <!-- #ifndef APP-PLUS-NVUE -->
<node v-else :childs="nodes" :opts="[lazyLoad,loadingImg,errorImg,showImgMenu,selectable]" name="span" /> <node v-else :childs="nodes" :opts="[lazyLoad,loadingImg,errorImg,showImgMenu,selectable]" name="span" />
<!-- #endif --> <!-- #endif -->
<!-- #ifdef APP-PLUS-NVUE --> <!-- #ifdef APP-PLUS-NVUE -->
<web-view ref="web" src="/uni_modules/mp-html/static/app-plus/mp-html/local.html" :style="'margin-top:-2px;height:' + height + 'px'" @onPostMessage="_onMessage" /> <web-view ref="web" src="/uni_modules/mp-html/static/app-plus/mp-html/local.html" :style="'margin-top:-2px;height:' + height + 'px'" @onPostMessage="_onMessage" />
<!-- #endif --> <!-- #endif -->
</view> </view>
</template> </template>
<script> <script>
/** /**
* mp-html v2.5.0 * mp-html v2.5.0
* @description 富文本组件 * @description 富文本组件
* @tutorial https://github.com/jin-yufeng/mp-html * @tutorial https://github.com/jin-yufeng/mp-html
* @property {String} container-style 容器的样式 * @property {String} container-style 容器的样式
* @property {String} content 用于渲染的 html 字符串 * @property {String} content 用于渲染的 html 字符串
* @property {Boolean} copy-link 是否允许外部链接被点击时自动复制 * @property {Boolean} copy-link 是否允许外部链接被点击时自动复制
* @property {String} domain 主域名,用于拼接链接 * @property {String} domain 主域名,用于拼接链接
* @property {String} error-img 图片出错时的占位图链接 * @property {String} error-img 图片出错时的占位图链接
* @property {Boolean} lazy-load 是否开启图片懒加载 * @property {Boolean} lazy-load 是否开启图片懒加载
* @property {string} loading-img 图片加载过程中的占位图链接 * @property {string} loading-img 图片加载过程中的占位图链接
* @property {Boolean} pause-video 是否在播放一个视频时自动暂停其他视频 * @property {Boolean} pause-video 是否在播放一个视频时自动暂停其他视频
* @property {Boolean} preview-img 是否允许图片被点击时自动预览 * @property {Boolean} preview-img 是否允许图片被点击时自动预览
* @property {Boolean} scroll-table 是否给每个表格添加一个滚动层使其能单独横向滚动 * @property {Boolean} scroll-table 是否给每个表格添加一个滚动层使其能单独横向滚动
* @property {Boolean | String} selectable 是否开启长按复制 * @property {Boolean | String} selectable 是否开启长按复制
* @property {Boolean} set-title 是否将 title 标签的内容设置到页面标题 * @property {Boolean} set-title 是否将 title 标签的内容设置到页面标题
* @property {Boolean} show-img-menu 是否允许图片被长按时显示菜单 * @property {Boolean} show-img-menu 是否允许图片被长按时显示菜单
* @property {Object} tag-style 标签的默认样式 * @property {Object} tag-style 标签的默认样式
* @property {Boolean | Number} use-anchor 是否使用锚点链接 * @property {Boolean | Number} use-anchor 是否使用锚点链接
* @event {Function} load dom 结构加载完毕时触发 * @event {Function} load dom 结构加载完毕时触发
* @event {Function} ready 所有图片加载完毕时触发 * @event {Function} ready 所有图片加载完毕时触发
* @event {Function} imgtap 图片被点击时触发 * @event {Function} imgtap 图片被点击时触发
* @event {Function} linktap 链接被点击时触发 * @event {Function} linktap 链接被点击时触发
* @event {Function} play 音视频播放时触发 * @event {Function} play 音视频播放时触发
* @event {Function} error 媒体加载出错时触发 * @event {Function} error 媒体加载出错时触发
*/ */
// #ifndef APP-PLUS-NVUE // #ifndef APP-PLUS-NVUE
import node from './node/node' import node from './node/node'
// #endif // #endif
import Parser from './parser' import Parser from './parser'
const plugins=[] const plugins=[]
// #ifdef APP-PLUS-NVUE // #ifdef APP-PLUS-NVUE
const dom = weex.requireModule('dom') const dom = weex.requireModule('dom')
// #endif // #endif
export default { export default {
name: 'mp-html', name: 'mp-html',
data () { data () {
return { return {
nodes: [], nodes: [],
// #ifdef APP-PLUS-NVUE // #ifdef APP-PLUS-NVUE
height: 3 height: 3
// #endif // #endif
} }
}, },
props: { props: {
containerStyle: { containerStyle: {
type: String, type: String,
default: '' default: ''
}, },
content: { content: {
type: String, type: String,
default: '' default: ''
}, },
copyLink: { copyLink: {
type: [Boolean, String], type: [Boolean, String],
default: true default: true
}, },
domain: String, domain: String,
errorImg: { errorImg: {
type: String, type: String,
default: '' default: ''
}, },
lazyLoad: { lazyLoad: {
type: [Boolean, String], type: [Boolean, String],
default: false default: false
}, },
loadingImg: { loadingImg: {
type: String, type: String,
default: '' default: ''
}, },
pauseVideo: { pauseVideo: {
type: [Boolean, String], type: [Boolean, String],
default: true default: true
}, },
previewImg: { previewImg: {
type: [Boolean, String], type: [Boolean, String],
default: true default: true
}, },
scrollTable: [Boolean, String], scrollTable: [Boolean, String],
selectable: [Boolean, String], selectable: [Boolean, String],
setTitle: { setTitle: {
type: [Boolean, String], type: [Boolean, String],
default: true default: true
}, },
showImgMenu: { showImgMenu: {
type: [Boolean, String], type: [Boolean, String],
default: true default: true
}, },
tagStyle: Object, tagStyle: Object,
useAnchor: [Boolean, Number] useAnchor: [Boolean, Number]
}, },
// #ifdef VUE3 // #ifdef VUE3
emits: ['load', 'ready', 'imgtap', 'linktap', 'play', 'error'], emits: ['load', 'ready', 'imgtap', 'linktap', 'play', 'error'],
// #endif // #endif
// #ifndef APP-PLUS-NVUE // #ifndef APP-PLUS-NVUE
components: { components: {
node node
}, },
// #endif // #endif
watch: { watch: {
content (content) { content (content) {
this.setContent(content) this.setContent(content)
} }
}, },
created () { created () {
this.plugins = [] this.plugins = []
for (let i = plugins.length; i--;) { for (let i = plugins.length; i--;) {
this.plugins.push(new plugins[i](this)) this.plugins.push(new plugins[i](this))
} }
}, },
mounted () { mounted () {
if (this.content && !this.nodes.length) { if (this.content && !this.nodes.length) {
this.setContent(this.content) this.setContent(this.content)
} }
}, },
beforeDestroy () { beforeDestroy () {
this._hook('onDetached') this._hook('onDetached')
}, },
methods: { methods: {
/** /**
* @description 将锚点跳转的范围限定在一个 scroll-view 内 * @description 将锚点跳转的范围限定在一个 scroll-view 内
* @param {Object} page scroll-view 所在页面的示例 * @param {Object} page scroll-view 所在页面的示例
* @param {String} selector scroll-view 的选择器 * @param {String} selector scroll-view 的选择器
* @param {String} scrollTop scroll-view scroll-top 属性绑定的变量名 * @param {String} scrollTop scroll-view scroll-top 属性绑定的变量名
*/ */
in (page, selector, scrollTop) { in (page, selector, scrollTop) {
// #ifndef APP-PLUS-NVUE // #ifndef APP-PLUS-NVUE
if (page && selector && scrollTop) { if (page && selector && scrollTop) {
this._in = { this._in = {
page, page,
selector, selector,
scrollTop scrollTop
} }
} }
// #endif // #endif
}, },
/** /**
* @description 锚点跳转 * @description 锚点跳转
* @param {String} id 要跳转的锚点 id * @param {String} id 要跳转的锚点 id
* @param {Number} offset 跳转位置的偏移量 * @param {Number} offset 跳转位置的偏移量
* @returns {Promise} * @returns {Promise}
*/ */
navigateTo (id, offset) { navigateTo (id, offset) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (!this.useAnchor) { if (!this.useAnchor) {
reject(Error('Anchor is disabled')) reject(Error('Anchor is disabled'))
return return
} }
offset = offset || parseInt(this.useAnchor) || 0 offset = offset || parseInt(this.useAnchor) || 0
// #ifdef APP-PLUS-NVUE // #ifdef APP-PLUS-NVUE
if (!id) { if (!id) {
dom.scrollToElement(this.$refs.web, { dom.scrollToElement(this.$refs.web, {
offset offset
}) })
resolve() resolve()
} else { } else {
this._navigateTo = { this._navigateTo = {
resolve, resolve,
reject, reject,
offset offset
} }
this.$refs.web.evalJs('uni.postMessage({data:{action:"getOffset",offset:(document.getElementById(' + id + ')||{}).offsetTop}})') this.$refs.web.evalJs('uni.postMessage({data:{action:"getOffset",offset:(document.getElementById(' + id + ')||{}).offsetTop}})')
} }
// #endif // #endif
// #ifndef APP-PLUS-NVUE // #ifndef APP-PLUS-NVUE
let deep = ' ' let deep = ' '
// #ifdef MP-WEIXIN || MP-QQ || MP-TOUTIAO // #ifdef MP-WEIXIN || MP-QQ || MP-TOUTIAO
deep = '>>>' deep = '>>>'
// #endif // #endif
const selector = uni.createSelectorQuery() const selector = uni.createSelectorQuery()
// #ifndef MP-ALIPAY // #ifndef MP-ALIPAY
.in(this._in ? this._in.page : this) .in(this._in ? this._in.page : this)
// #endif // #endif
.select((this._in ? this._in.selector : '._root') + (id ? `${deep}#${id}` : '')).boundingClientRect() .select((this._in ? this._in.selector : '._root') + (id ? `${deep}#${id}` : '')).boundingClientRect()
if (this._in) { if (this._in) {
selector.select(this._in.selector).scrollOffset() selector.select(this._in.selector).scrollOffset()
.select(this._in.selector).boundingClientRect() .select(this._in.selector).boundingClientRect()
} else { } else {
// 获取 scroll-view 的位置和滚动距离 // 获取 scroll-view 的位置和滚动距离
selector.selectViewport().scrollOffset() // 获取窗口的滚动距离 selector.selectViewport().scrollOffset() // 获取窗口的滚动距离
} }
selector.exec(res => { selector.exec(res => {
if (!res[0]) { if (!res[0]) {
reject(Error('Label not found')) reject(Error('Label not found'))
return return
} }
const scrollTop = res[1].scrollTop + res[0].top - (res[2] ? res[2].top : 0) + offset const scrollTop = res[1].scrollTop + res[0].top - (res[2] ? res[2].top : 0) + offset
if (this._in) { if (this._in) {
// scroll-view 跳转 // scroll-view 跳转
this._in.page[this._in.scrollTop] = scrollTop this._in.page[this._in.scrollTop] = scrollTop
} else { } else {
// 页面跳转 // 页面跳转
uni.pageScrollTo({ uni.pageScrollTo({
scrollTop, scrollTop,
duration: 300 duration: 300
}) })
} }
resolve() resolve()
}) })
// #endif // #endif
}) })
}, },
/** /**
* @description 获取文本内容 * @description 获取文本内容
* @return {String} * @return {String}
*/ */
getText (nodes) { getText (nodes) {
let text = ''; let text = '';
(function traversal (nodes) { (function traversal (nodes) {
for (let i = 0; i < nodes.length; i++) { for (let i = 0; i < nodes.length; i++) {
const node = nodes[i] const node = nodes[i]
if (node.type === 'text') { if (node.type === 'text') {
text += node.text.replace(/&amp;/g, '&') text += node.text.replace(/&amp;/g, '&')
} else if (node.name === 'br') { } else if (node.name === 'br') {
text += '\n' text += '\n'
} else { } else {
// 块级标签前后加换行 // 块级标签前后加换行
const isBlock = node.name === 'p' || node.name === 'div' || node.name === 'tr' || node.name === 'li' || (node.name[0] === 'h' && node.name[1] > '0' && node.name[1] < '7') const isBlock = node.name === 'p' || node.name === 'div' || node.name === 'tr' || node.name === 'li' || (node.name[0] === 'h' && node.name[1] > '0' && node.name[1] < '7')
if (isBlock && text && text[text.length - 1] !== '\n') { if (isBlock && text && text[text.length - 1] !== '\n') {
text += '\n' text += '\n'
} }
// 递归获取子节点的文本 // 递归获取子节点的文本
if (node.children) { if (node.children) {
traversal(node.children) traversal(node.children)
} }
if (isBlock && text[text.length - 1] !== '\n') { if (isBlock && text[text.length - 1] !== '\n') {
text += '\n' text += '\n'
} else if (node.name === 'td' || node.name === 'th') { } else if (node.name === 'td' || node.name === 'th') {
text += '\t' text += '\t'
} }
} }
} }
})(nodes || this.nodes) })(nodes || this.nodes)
return text return text
}, },
/** /**
* @description 获取内容大小和位置 * @description 获取内容大小和位置
* @return {Promise} * @return {Promise}
*/ */
getRect () { getRect () {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
uni.createSelectorQuery() uni.createSelectorQuery()
// #ifndef MP-ALIPAY // #ifndef MP-ALIPAY
.in(this) .in(this)
// #endif // #endif
.select('#_root').boundingClientRect().exec(res => res[0] ? resolve(res[0]) : reject(Error('Root label not found'))) .select('#_root').boundingClientRect().exec(res => res[0] ? resolve(res[0]) : reject(Error('Root label not found')))
}) })
}, },
/** /**
* @description 暂停播放媒体 * @description 暂停播放媒体
*/ */
pauseMedia () { pauseMedia () {
for (let i = (this._videos || []).length; i--;) { for (let i = (this._videos || []).length; i--;) {
this._videos[i].pause() this._videos[i].pause()
} }
// #ifdef APP-PLUS // #ifdef APP-PLUS
const command = 'for(var e=document.getElementsByTagName("video"),i=e.length;i--;)e[i].pause()' const command = 'for(var e=document.getElementsByTagName("video"),i=e.length;i--;)e[i].pause()'
// #ifndef APP-PLUS-NVUE // #ifndef APP-PLUS-NVUE
let page = this.$parent let page = this.$parent
while (!page.$scope) page = page.$parent while (!page.$scope) page = page.$parent
page.$scope.$getAppWebview().evalJS(command) page.$scope.$getAppWebview().evalJS(command)
// #endif // #endif
// #ifdef APP-PLUS-NVUE // #ifdef APP-PLUS-NVUE
this.$refs.web.evalJs(command) this.$refs.web.evalJs(command)
// #endif // #endif
// #endif // #endif
}, },
/** /**
* @description 设置媒体播放速率 * @description 设置媒体播放速率
* @param {Number} rate 播放速率 * @param {Number} rate 播放速率
*/ */
setPlaybackRate (rate) { setPlaybackRate (rate) {
this.playbackRate = rate this.playbackRate = rate
for (let i = (this._videos || []).length; i--;) { for (let i = (this._videos || []).length; i--;) {
this._videos[i].playbackRate(rate) this._videos[i].playbackRate(rate)
} }
// #ifdef APP-PLUS // #ifdef APP-PLUS
const command = 'for(var e=document.getElementsByTagName("video"),i=e.length;i--;)e[i].playbackRate=' + rate const command = 'for(var e=document.getElementsByTagName("video"),i=e.length;i--;)e[i].playbackRate=' + rate
// #ifndef APP-PLUS-NVUE // #ifndef APP-PLUS-NVUE
let page = this.$parent let page = this.$parent
while (!page.$scope) page = page.$parent while (!page.$scope) page = page.$parent
page.$scope.$getAppWebview().evalJS(command) page.$scope.$getAppWebview().evalJS(command)
// #endif // #endif
// #ifdef APP-PLUS-NVUE // #ifdef APP-PLUS-NVUE
this.$refs.web.evalJs(command) this.$refs.web.evalJs(command)
// #endif // #endif
// #endif // #endif
}, },
/** /**
* @description 设置内容 * @description 设置内容
* @param {String} content html 内容 * @param {String} content html 内容
* @param {Boolean} append 是否在尾部追加 * @param {Boolean} append 是否在尾部追加
*/ */
setContent (content, append) { setContent (content, append) {
if (!append || !this.imgList) { if (!append || !this.imgList) {
this.imgList = [] this.imgList = []
} }
const nodes = new Parser(this).parse(content) const nodes = new Parser(this).parse(content)
// #ifdef APP-PLUS-NVUE // #ifdef APP-PLUS-NVUE
if (this._ready) { if (this._ready) {
this._set(nodes, append) this._set(nodes, append)
} }
// #endif // #endif
this.$set(this, 'nodes', append ? (this.nodes || []).concat(nodes) : nodes) this.$set(this, 'nodes', append ? (this.nodes || []).concat(nodes) : nodes)
// #ifndef APP-PLUS-NVUE // #ifndef APP-PLUS-NVUE
this._videos = [] this._videos = []
this.$nextTick(() => { this.$nextTick(() => {
this._hook('onLoad') this._hook('onLoad')
this.$emit('load') this.$emit('load')
}) })
if (this.lazyLoad || this.imgList._unloadimgs < this.imgList.length / 2) { if (this.lazyLoad || this.imgList._unloadimgs < this.imgList.length / 2) {
// 设置懒加载,每 350ms 获取高度,不变则认为加载完毕 // 设置懒加载,每 350ms 获取高度,不变则认为加载完毕
let height = 0 let height = 0
const callback = rect => { const callback = rect => {
if (!rect || !rect.height) rect = {} if (!rect || !rect.height) rect = {}
// 350ms 总高度无变化就触发 ready 事件 // 350ms 总高度无变化就触发 ready 事件
if (rect.height === height) { if (rect.height === height) {
this.$emit('ready', rect) this.$emit('ready', rect)
} else { } else {
height = rect.height height = rect.height
setTimeout(() => { setTimeout(() => {
this.getRect().then(callback).catch(callback) this.getRect().then(callback).catch(callback)
}, 350) }, 350)
} }
} }
this.getRect().then(callback).catch(callback) this.getRect().then(callback).catch(callback)
} else { } else {
// 未设置懒加载,等待所有图片加载完毕 // 未设置懒加载,等待所有图片加载完毕
if (!this.imgList._unloadimgs) { if (!this.imgList._unloadimgs) {
this.getRect().then(rect => { this.getRect().then(rect => {
this.$emit('ready', rect) this.$emit('ready', rect)
}).catch(() => { }).catch(() => {
this.$emit('ready', {}) this.$emit('ready', {})
}) })
} }
} }
// #endif // #endif
}, },
/** /**
* @description 调用插件钩子函数 * @description 调用插件钩子函数
*/ */
_hook (name) { _hook (name) {
for (let i = plugins.length; i--;) { for (let i = plugins.length; i--;) {
if (this.plugins[i][name]) { if (this.plugins[i][name]) {
this.plugins[i][name]() this.plugins[i][name]()
} }
} }
}, },
// #ifdef APP-PLUS-NVUE // #ifdef APP-PLUS-NVUE
/** /**
* @description 设置内容 * @description 设置内容
*/ */
_set (nodes, append) { _set (nodes, append) {
this.$refs.web.evalJs('setContent(' + JSON.stringify(nodes).replace(/%22/g, '') + ',' + JSON.stringify([this.containerStyle.replace(/(?:margin|padding)[^;]+/g, ''), this.errorImg, this.loadingImg, this.pauseVideo, this.scrollTable, this.selectable]) + ',' + append + ')') this.$refs.web.evalJs('setContent(' + JSON.stringify(nodes).replace(/%22/g, '') + ',' + JSON.stringify([this.containerStyle.replace(/(?:margin|padding)[^;]+/g, ''), this.errorImg, this.loadingImg, this.pauseVideo, this.scrollTable, this.selectable]) + ',' + append + ')')
}, },
/** /**
* @description 接收到 web-view 消息 * @description 接收到 web-view 消息
*/ */
_onMessage (e) { _onMessage (e) {
const message = e.detail.data[0] const message = e.detail.data[0]
switch (message.action) { switch (message.action) {
// web-view 初始化完毕 // web-view 初始化完毕
case 'onJSBridgeReady': case 'onJSBridgeReady':
this._ready = true this._ready = true
if (this.nodes) { if (this.nodes) {
this._set(this.nodes) this._set(this.nodes)
} }
break break
// 内容 dom 加载完毕 // 内容 dom 加载完毕
case 'onLoad': case 'onLoad':
this.height = message.height this.height = message.height
this._hook('onLoad') this._hook('onLoad')
this.$emit('load') this.$emit('load')
break break
// 所有图片加载完毕 // 所有图片加载完毕
case 'onReady': case 'onReady':
this.getRect().then(res => { this.getRect().then(res => {
this.$emit('ready', res) this.$emit('ready', res)
}).catch(() => { }).catch(() => {
this.$emit('ready', {}) this.$emit('ready', {})
}) })
break break
// 总高度发生变化 // 总高度发生变化
case 'onHeightChange': case 'onHeightChange':
this.height = message.height this.height = message.height
break break
// 图片点击 // 图片点击
case 'onImgTap': case 'onImgTap':
this.$emit('imgtap', message.attrs) this.$emit('imgtap', message.attrs)
if (this.previewImg) { if (this.previewImg) {
uni.previewImage({ uni.previewImage({
current: parseInt(message.attrs.i), current: parseInt(message.attrs.i),
urls: this.imgList urls: this.imgList
}) })
} }
break break
// 链接点击 // 链接点击
case 'onLinkTap': { case 'onLinkTap': {
const href = message.attrs.href const href = message.attrs.href
this.$emit('linktap', message.attrs) this.$emit('linktap', message.attrs)
if (href) { if (href) {
// 锚点跳转 // 锚点跳转
if (href[0] === '#') { if (href[0] === '#') {
if (this.useAnchor) { if (this.useAnchor) {
dom.scrollToElement(this.$refs.web, { dom.scrollToElement(this.$refs.web, {
offset: message.offset offset: message.offset
}) })
} }
} else if (href.includes('://')) { } else if (href.includes('://')) {
// 打开外链 // 打开外链
if (this.copyLink) { if (this.copyLink) {
plus.runtime.openWeb(href) plus.runtime.openWeb(href)
} }
} else { } else {
uni.navigateTo({ uni.navigateTo({
url: href, url: href,
fail () { fail () {
uni.switchTab({ uni.switchTab({
url: href url: href
}) })
} }
}) })
} }
} }
break break
} }
case 'onPlay': case 'onPlay':
this.$emit('play') this.$emit('play')
break break
// 获取到锚点的偏移量 // 获取到锚点的偏移量
case 'getOffset': case 'getOffset':
if (typeof message.offset === 'number') { if (typeof message.offset === 'number') {
dom.scrollToElement(this.$refs.web, { dom.scrollToElement(this.$refs.web, {
offset: message.offset + this._navigateTo.offset offset: message.offset + this._navigateTo.offset
}) })
this._navigateTo.resolve() this._navigateTo.resolve()
} else { } else {
this._navigateTo.reject(Error('Label not found')) this._navigateTo.reject(Error('Label not found'))
} }
break break
// 点击 // 点击
case 'onClick': case 'onClick':
this.$emit('tap') this.$emit('tap')
this.$emit('click') this.$emit('click')
break break
// 出错 // 出错
case 'onError': case 'onError':
this.$emit('error', { this.$emit('error', {
source: message.source, source: message.source,
attrs: message.attrs attrs: message.attrs
}) })
} }
} }
// #endif // #endif
} }
} }
</script> </script>
<style> <style lang="scss">
/* #ifndef APP-PLUS-NVUE */ /* #ifndef APP-PLUS-NVUE */
/* 根节点样式 */ /* 根节点样式 */
._root { ._root {
padding: 1px 0; padding: 1px 0;
overflow-x: auto; overflow-x: auto;
overflow-y: hidden; overflow-y: hidden;
-webkit-overflow-scrolling: touch; -webkit-overflow-scrolling: touch;
} }
/* 长按复制 */ /* 长按复制 */
._select { ._select {
user-select: text; user-select: text;
} }
/* #endif */ /* #endif */
</style> </style>

File diff suppressed because it is too large Load Diff