123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563 |
- <template>
- <uni-popup type="bottom" class="uni-popup" ref="popup" @change="handleChange">
- <view class="close iconfont icon-iconfontguanbi" @click="handleClose"></view>
- <view class="popup-content" v-if="currentSku">
- <view class="goods-info">
- <image class="cover" :src="product.mainImage"></image>
- <!-- 普通价格,阶梯价格,拼团价格,限时特价 -->
- <view class="info">
- <view class="price row">
- <text class="label">单价:</text>
- <text class="amount" v-text="price"></text>
- </view>
- <view class="row tags">
- <!-- 券后价 -->
- <template v-if="couponPriceFlag">
- <view class="tag-qh">券后价¥{{ couponPrice }}</view>
- </template>
- <template v-if="activityType === 'group'">
- <view class="tag-pt">{{ collageInfo.memberNum }}人拼团</view>
- </template>
- <template v-if="activityType === 'activity'">
- <view class="tag-hd">活动价</view>
- <view class="tag-text">查看活动价</view>
- </template>
- <template v-if="activityType === 'time-limit'">
- <view class="tag-xs">限时特价</view>
- </template>
- </view>
- </view>
- </view>
- <!-- 产品规格 -->
- <view class="buy-unit">
- <view class="label">规格:</view>
- <scroll-view scroll-y="true" class="unit-wrapper">
- <view class="unit-list">
- <template v-for="item in skusList">
- <view
- class="unit"
- :class="{
- disabled: item.stock === 0,
- active: item.skuId === currentSkuId && item.stock !== 0
- }"
- :key="item.skuId"
- v-text="item.unit"
- @click="handleChooseUtil(item)"
- ></view>
- </template>
- </view>
- </scroll-view>
- </view>
- <!-- 购买数量 -->
- <view class="buy-number">
- <view class="label">购买数量:</view>
- <cm-number-box v-model.lazy="count" :max="limitedNum"></cm-number-box>
- </view>
- <!-- 优惠券 -->
- <view class="coupon-tip">
- <template v-if="couponTipFlag">
- <text>当前商品可使用</text>
- <text class="active" v-text="couponTip">满300减200元</text>
- <text>优惠券</text>
- </template>
- </view>
- <!-- 操作 -->
- <view class="control" :class="{ disabled: disabled }">
- <!-- 加入购物车 -->
- <template v-if="useType === 'cart'">
- <view class="btn btn-confirm" @click="handleClick('cart')">确定</view>
- </template>
- <!-- 加入购物车 / 立即购买区域 -->
- <template v-if="useType === 'buy'">
- <template v-if="groupPriceFlag">
- <template v-if="couponPriceFlag">
- <view class="btn btn-confirm" @click="handleClick('buy')">领券购买</view>
- </template>
- <template v-else>
- <view class="btn btn-confirm" @click="handleClick('buy')">立即购买</view>
- </template>
- </template>
- <template v-else>
- <template v-if="buttonType === 'left'">
- <view class="btn btn-confirm" @click="handleClick('cart')">确定</view>
- </template>
- <template v-else>
- <template v-if="couponPriceFlag">
- <view class="btn btn-confirm" @click="handleClick('buy')">领券购买</view>
- </template>
- <template v-else>
- <view class="btn btn-confirm" @click="handleClick('buy')">确定</view>
- </template>
- </template>
- </template>
- </template>
- <!-- 点击规格区域 -->
- <template v-if="useType === 'unit'">
- <template v-if="groupPriceFlag">
- <view class="btn btn-cart" @click="handleClick('buy')">
- <text class="tip">{{ leftButton[0] }}</text>
- <text class="amount">{{ leftButton[1] }}</text>
- </view>
- <view class="btn btn-buy" @click="handleClick('buy')">
- <text class="tip">{{ rightButton[0] }}</text>
- <text class="amount">{{ rightButton[1] }}</text>
- </view>
- </template>
- <template v-else>
- <view class="btn btn-cart" @click="handleClick('cart')">{{ leftButton[0] }}</view>
- <view class="btn btn-buy" @click="handleClick('buy')">
- <template v-if="rightButton[1]">
- <text class="tip">{{ rightButton[0] }}</text>
- <text class="amount">{{ rightButton[1] }}</text>
- </template>
- <template v-else>
- {{ rightButton[0] }}
- </template>
- </view>
- </template>
- </template>
- </view>
- </view>
- </uni-popup>
- </template>
- <script>
- import { generateNavbarButtonText } from '@/common/goods.helper.js'
- import { mapGetters } from 'vuex'
- export default {
- name: 'cm-goods-buy-popup',
- props: {
- value: {
- type: Boolean,
- default: false
- },
- product: {
- type: Object,
- default: () => {}
- },
- couponList: {
- type: Array,
- default: () => []
- },
- // 组件使用位置
- useType: {
- type: String,
- default: 'buy'
- },
- // 按钮类型 left 左侧按钮点击 right 右侧按钮点击
- buttonType: {
- type: String,
- default: 'left'
- }
- },
- computed: {
- // sku列表
- skusList() {
- return this.product.skus || []
- },
- // 选中的sku
- currentSku() {
- return this.skusList.find(sku => sku.skuId === this.currentSkuId) || {}
- },
- // 展示价格
- price() {
- return this.generatePrice()
- },
- // 活动类型
- activityType() {
- return this.currentSku.activityType
- },
- // 价格类型
- priceType() {
- return this.currentSku.priceType
- },
- // 券后价标识
- couponPriceFlag() {
- return ['groupWithCoupon', 'activityWithCoupon', 'normalWithCoupon'].includes(this.currentSku.priceType)
- },
- // 拼团价标识
- groupPriceFlag() {
- return ['groupWithCoupon', 'group'].includes(this.currentSku.priceType)
- },
- // 券后价
- couponPrice() {
- return this.buttonType === 'left' ? this.currentSku.normalCouponPrice : this.currentSku.couponPrice
- },
- // 优惠券提示标识
- couponTipFlag() {
- return this.currentSku.couponStatus > 0 && this.currentSku.couponId
- },
- // 优惠券提示
- couponTip() {
- if (this.currentSku.couponId) {
- const currentCoupon = this.couponList.find(coupon => this.currentSku.couponId === coupon.couponId)
- return currentCoupon.couponTitle
- }
- if (this.currentSku.couponInfo) {
- return this.currentSku.couponInfo.split('|')[1]
- }
- return ''
- },
- // 商品拼团信息
- collageInfo() {
- return this.currentSku.collageProduct
- },
- limitedNum() {
- return this.currentSku.stock === null ? 100 : this.currentSku.stock
- },
- disabled() {
- return this.currentSku.stock === 0
- }
- },
- data() {
- return {
- count: 1,
- currentSkuId: 0,
- leftButton: {},
- rightButton: {}
- }
- },
- watch: {
- value: {
- handler: function(val) {
- if (val) {
- this.currentSkuId = this.product.skuId
- this.initNavbarButton()
- this.handleOpen()
- } else {
- this.handleClose()
- }
- },
- immediate: true
- }
- },
- mounted() {
- console.log('product', this.product)
- },
- methods: {
- // 导航按钮点击事件
- handleClick(type) {
- if (this.disabled) {
- return
- }
- this.$emit('confirm', {
- type: type,
- sku: this.currentSku,
- count: this.count
- })
- },
- // 初始化导航按钮文案
- initNavbarButton() {
- const navbarButton = generateNavbarButtonText(this.currentSku)
- this.leftButton = navbarButton.left
- this.rightButton = navbarButton.right
- },
- // 设置价格
- generatePrice() {
- // 拼团价
- if (this.groupPriceFlag) {
- // 单独购买价格
- if (this.buttonType === 'left') {
- return this.currentSku.normalPrice
- }
- }
- // 非阶梯价
- if (this.currentSku.activeStatus <= 0) {
- return this.currentSku.price
- }
- // 阶梯价列表为空
- if (!this.currentSku.ladderList) {
- return this.currentSku.price
- }
- // 阶梯价
- const lastItem = this.currentSku.ladderList
- .sort((a, b) => b.buyNum - a.buyNum)
- .find(item => this.count >= item.buyNum)
- return lastItem ? lastItem.buyPrice : this.currentSku.price
- },
- // 关闭
- handleClose() {
- this.$nextTick(() => {
- this.$refs.popup.close()
- })
- },
- // 关闭/打开
- handleChange(e) {
- this.$emit('input', e.show)
- },
- // 打开
- handleOpen() {
- this.$nextTick(() => {
- this.$refs.popup.open()
- })
- },
- handleChooseUtil(item) {
- this.currentSkuId = item.skuId
- this.$emit('utilChange', item)
- }
- }
- }
- </script>
- <style lang="scss" scoped>
- .uni-popup {
- position: relative;
- z-index: 99999;
- .close {
- position: absolute;
- right: 24rpx;
- top: 24rpx;
- color: #999;
- font-size: 32rpx;
- }
- }
- .popup-content {
- padding: 40rpx 32rpx;
- background-color: #fff;
- border-radius: 16rpx 16rpx 0 0;
- &::after {
- position: absolute;
- content: '';
- width: 100%;
- height: 80rpx;
- bottom: -80rpx;
- left: 0;
- background-color: #fff;
- }
- .goods-info {
- display: flex;
- .cover {
- flex-shrink: 0;
- width: 180rpx;
- height: 180rpx;
- border: 1px solid #e1e1e1;
- }
- .info {
- margin-left: 24rpx;
- margin-top: 24rpx;
- .price {
- display: flex;
- align-items: center;
- .label {
- font-size: 26rpx;
- color: #666666;
- }
- .amount {
- font-size: 26rpx;
- color: #ff457b;
- font-weight: bold;
- &::before {
- content: '¥';
- }
- }
- }
- .tags {
- display: flex;
- align-items: center;
- flex-wrap: wrap;
- margin-top: 24rpx;
- gap: 16rpx 24rpx;
- .tag-text {
- font-size: 22rpx;
- color: #ff457b;
- }
- .tag-qh {
- line-height: 40rpx;
- height: 40rpx;
- background: #ff457b;
- border-radius: 25rpx;
- padding: 0 15rpx;
- font-size: 24rpx;
- font-weight: bold;
- color: #ffffff;
- }
- .tag-pt {
- height: 32rpx;
- line-height: 32rpx;
- padding: 0 8rpx;
- background: linear-gradient(90deg, #6431f2 0%, #b03bb8 49%, #ff457b 100%);
- border-radius: 4rpx;
- font-size: 22rpx;
- color: #fff;
- }
- .tag-hd,
- .tag-xs {
- height: 30rpx;
- padding: 0 8rpx;
- line-height: 28rpx;
- background: #fff3f7;
- border: 1rpx solid #ff457b;
- border-radius: 4rpx;
- font-size: 22rpx;
- color: #ff457b;
- }
- }
- }
- }
- .buy-unit {
- margin-top: 32rpx;
- .label {
- margin-bottom: 24rpx;
- }
- .unit-wrapper {
- max-height: 300rpx;
- .unit-list {
- display: flex;
- flex-wrap: wrap;
- gap: 24rpx 16rpx;
- padding-top: 24rpx;
- .unit {
- position: relative;
- height: 48rpx;
- line-height: 46rpx;
- padding: 0 28rpx;
- background: #f5f5f5;
- color: #666666;
- font-size: 24rpx;
- box-sizing: border-box;
- border: 1rpx solid #f5f5f5;
- border-radius: 24rpx;
- &.active {
- color: #ff457b;
- border-color: #ff457b;
- background: #fff8fd;
- }
- &.disabled::after {
- content: '缺货';
- position: absolute;
- height: 32rpx;
- line-height: 32rpx;
- background: #cccccc;
- color: #fff;
- padding: 0 10rpx;
- right: 0;
- top: 0;
- transform: translate(30%, -50%);
- font-size: 22rpx;
- border-radius: 17rpx;
- border: 2rpx solid #fff;
- }
- }
- }
- }
- }
- .buy-number,
- .buy-unit {
- .label {
- font-weight: bold;
- color: #333333;
- font-size: 28rpx;
- }
- }
- .buy-number {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-top: 60rpx;
- }
- .coupon-tip {
- margin: 70rpx 0 24rpx;
- font-size: 0;
- text-align: center;
- text {
- font-size: 24rpx;
- color: #666;
- }
- .active {
- color: #ff457b;
- }
- }
- .control {
- display: flex;
- align-items: center;
- justify-content: space-evenly;
- &.disabled {
- .btn {
- background: #ddd !important;
- color: #fff !important;
- }
- }
- .btn {
- height: 90rpx;
- font-size: 30rpx;
- border-radius: 45rpx;
- display: flex;
- justify-content: center;
- align-items: center;
- flex-direction: column;
- position: relative;
- overflow: hidden;
- &:active::after {
- content: '';
- position: absolute;
- width: 100%;
- height: 100%;
- left: 0;
- top: 0;
- background: #999;
- opacity: 0.1;
- }
- &.btn-confirm {
- width: 100%;
- }
- &.btn-confirm,
- &.btn-buy {
- color: #fff;
- background: linear-gradient(90deg, #fc32b4 0%, #f83c6c 100%);
- }
- &.btn-cart {
- color: #ff457b;
- background: #ffeff4;
- }
- &.btn-buy,
- &.btn-cart {
- width: 280rpx;
- }
- .tip {
- font-size: 22rpx;
- margin-bottom: 4rpx;
- line-height: 24rpx;
- }
- .amount {
- font-size: 30rpx;
- font-weight: 600;
- line-height: 36rpx;
- }
- }
- }
- }
- </style>
|