Files
TakeoutSaaS.C-Side-Mini-Pro…/src/components/spec-popup/index.vue

154 lines
4.8 KiB
Vue

<template>
<view v-if="props.visible" class="overlay" @click="emit('close')" />
<view v-if="props.visible" class="spec-popup">
<view class="spec-popup__handle" />
<scroll-view scroll-y class="spec-popup__scroll">
<view class="spec-popup__header">
<image
class="spec-popup__img"
:src="props.product.coverImageUrl"
mode="aspectFill"
/>
<view class="spec-popup__info">
<text class="spec-popup__name">{{ props.product.name }}</text>
<text class="spec-popup__desc">
{{ props.product.subtitle || props.product.description }}
</text>
<view class="spec-popup__tags">
<text
v-for="tag in props.product.tagTexts"
:key="tag"
class="spec-popup__tag"
:class="tagClass(tag)"
>
{{ tag }}
</text>
</view>
<view class="spec-popup__price-row">
<text class="spec-popup__price-unit">¥</text>
<text class="spec-popup__price-current">{{ props.displayUnitPrice }}</text>
<text
v-if="props.product.originalPriceText"
class="spec-popup__price-origin"
>
¥{{ props.product.originalPriceText }}
</text>
</view>
</view>
<view class="spec-popup__close" @click="emit('close')">
<text></text>
</view>
</view>
<view
v-for="group in props.product.optionGroups"
:key="group.id"
class="spec-popup__group"
>
<view class="spec-popup__group-header">
<text class="spec-popup__group-title">{{ group.name }}</text>
<text
v-if="group.required"
class="spec-popup__group-tag spec-popup__group-tag--required"
>
必选
</text>
<text
v-else-if="group.selectionType === 'multiple'"
class="spec-popup__group-tag spec-popup__group-tag--multi"
>
可多选
</text>
</view>
<view class="spec-popup__pills">
<view
v-for="option in group.options"
:key="option.id"
class="spec-popup__pill"
:class="{
'spec-popup__pill--selected': props.isSelected(group.id, option.id),
'spec-popup__pill--disabled': option.soldOut
}"
@click="emit('toggleOption', group, option)"
>
<text>{{ option.name }}</text>
<text v-if="option.extraPrice" class="spec-popup__pill-extra">
+¥{{ option.extraPriceText }}
</text>
</view>
</view>
</view>
<view class="spec-popup__stepper-row">
<text class="spec-popup__stepper-label">数量</text>
<view class="spec-popup__stepper">
<view
class="spec-popup__stepper-btn"
:class="{ 'spec-popup__stepper-btn--disabled': props.quantity <= 1 }"
@click="emit('changeQty', -1)"
>
<text>-</text>
</view>
<text class="spec-popup__stepper-value">{{ props.quantity }}</text>
<view class="spec-popup__stepper-btn" @click="emit('changeQty', 1)">
<text>+</text>
</view>
</view>
</view>
</scroll-view>
<view class="spec-popup__footer">
<view class="spec-popup__footer-price">
<text class="spec-popup__footer-label">合计</text>
<view class="spec-popup__footer-total">
<text class="spec-popup__footer-unit">¥</text>
<text class="spec-popup__footer-value">{{ props.totalPriceText }}</text>
</view>
<text class="spec-popup__footer-summary">{{ props.summaryText }}</text>
</view>
<view
class="spec-popup__footer-btn"
:class="{ 'spec-popup__footer-btn--disabled': !props.canAdd }"
@click="props.canAdd && emit('addToCart')"
>
<text>{{ props.canAdd ? '加入购物车' : props.disabledText }}</text>
</view>
</view>
</view>
</template>
<script setup lang="ts">
import type {
MiniProductDetail,
MiniProductOption,
MiniProductOptionGroup
} from '@/shared'
import { useSpecPopup } from './useSpecPopup'
const props = defineProps<{
visible: boolean
product: MiniProductDetail
quantity: number
displayUnitPrice: number
totalPriceText: string
summaryText: string
canAdd: boolean
disabledText: string
isSelected: (groupId: string, optionId: string) => boolean
}>()
const emit = defineEmits<{
close: []
addToCart: []
toggleOption: [group: MiniProductOptionGroup, option: MiniProductOption]
changeQty: [delta: number]
}>()
const { tagClass } = useSpecPopup()
</script>
<style lang="scss">
@use './styles/index.scss';
</style>