buddhism/pages/memorial/compositons/offeringModal.vue
2025-08-11 16:02:00 +08:00

298 lines
6.0 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="offering-modal" v-if="visible" @click="handleClose">
<view class="modal-overlay" @click="handleClose"></view>
<view class="modal-content" @click.stop>
<!-- 关闭按钮 -->
<view class="close-btn" @click="handleClose">
<text class="close-icon">×</text>
</view>
<!-- 标题 -->
<view class="modal-title">牌位供奉</view>
<!-- 供奉时长选择 -->
<view class="duration-section">
<view class="duration-grid">
<view
v-for="option in durationOptions"
:key="option.value"
class="duration-option"
:class="{ 'selected': selectedDuration === option.value }"
@click="selectDuration(option.value)"
>
<text class="duration-text">{{ option.label }}</text>
<text class="duration-price">¥{{ option.price }}</text>
</view>
</view>
</view>
<!-- 供奉人信息 -->
<view class="offerer-section">
<view class="section-label">供奉人</view>
<input
class="offerer-input"
placeholder="请填写供奉人姓名"
v-model="offererName"
maxlength="20"
/>
</view>
<view class="input-tip">将在供奉名单上展现供奉人的姓名,此为必填</view>
<!-- 确认按钮 -->
<view class="confirm-section">
<view class="price-info">
<text class="total-price">¥{{ totalPrice }}</text>
</view>
<view class="confirm-btn" @click="handleConfirm">
<text class="btn-text">立即供奉</text>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
name: 'OfferingModal',
props: {
visible: {
type: Boolean,
default: false
}
},
data() {
return {
selectedDuration: '3', // 默认选择3天
offererName: '',
durationOptions: [
{ label: '供奉3天', value: '3', price: '99.9' },
{ label: '供奉1周', value: '7', price: '129.9' },
{ label: '供奉1月', value: '30', price: '299.9' },
{ label: '供奉1年', value: '365', price: '499.9' }
]
}
},
computed: {
totalPrice() {
const selectedOption = this.durationOptions.find(option => option.value === this.selectedDuration)
if (!selectedOption) return '99.9'
// 根据设计图,显示的价格可能需要调整
// 这里可以根据实际需求调整价格计算逻辑
return selectedOption.price
}
},
methods: {
// 关闭弹窗
handleClose() {
this.$emit('close')
},
// 选择供奉时长
selectDuration(value) {
this.selectedDuration = value
},
// 确认供奉
handleConfirm() {
// 验证供奉人姓名
if (!this.offererName.trim()) {
uni.showToast({
title: '请填写供奉人姓名',
icon: 'none'
})
return
}
// 获取选中的时长选项
const selectedOption = this.durationOptions.find(option => option.value === this.selectedDuration)
// 触发确认事件
this.$emit('confirm', {
duration: this.selectedDuration,
durationLabel: selectedOption.label,
price: selectedOption.price,
offererName: this.offererName.trim()
})
}
}
}
</script>
<style lang="scss" scoped>
.offering-modal {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1000;
display: flex;
align-items: flex-end;
}
.modal-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
}
.modal-content {
position: relative;
width: 100%;
background: #FFFBF5;
border-radius: 24rpx 24rpx 0 0;
padding: 40rpx 32rpx 60rpx 32rpx;
box-sizing: border-box;
max-height: 80vh;
overflow-y: auto;
}
.close-btn {
position: absolute;
top: 20rpx;
right: 20rpx;
width: 60rpx;
height: 60rpx;
display: flex;
align-items: center;
justify-content: center;
z-index: 10;
}
.close-icon {
font-size: 40rpx;
color: #999;
font-weight: bold;
}
.modal-title {
color: #695347;
text-align: left;
margin-bottom: 40rpx;
padding-top: 20rpx;
font-weight: 400;
font-size: 32rpx;
line-height: 44rpx;
}
.duration-section {
margin-bottom: 40rpx;
}
.duration-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20rpx;
}
.duration-option {
background: #FFF1DD;
border-radius: 12rpx;
padding: 24rpx 20rpx;
text-align: center;
border: 2rpx solid transparent;
transition: all 0.3s ease;
cursor: pointer;
&.selected {
background: #A24242;
border-color: #A24242;
.duration-text,
.duration-price {
color: #fff;
}
}
}
.duration-text {
display: block;
font-size: 28rpx;
color: #C7A26D;
margin-bottom: 8rpx;
font-weight: 500;
}
.duration-price {
display: block;
font-size: 32rpx;
color: #C7A26D;
font-weight: 600;
}
.offerer-section {
display: flex;
margin-bottom: 40rpx;
align-items: center;
width: 686rpx;
height: 112rpx;
border-radius: 16rpx 16rpx 16rpx 16rpx;
border: 2rpx solid #A24242;
}
.section-label {
font-size: 32rpx;
color: #522510;
font-weight: 500;
margin:34rpx 70rpx 34rpx 54rpx;
width: 196rpx;
}
.offerer-input {
width: 100%;
height: 80rpx;
border-radius: 8rpx;
font-size: 28rpx;
color: #ACACAC;
box-sizing: border-box;
margin:34rpx 0 34rpx 0;
}
.input-tip {
font-weight: 400;
font-size: 28rpx;
color: #695347;
line-height: 38rpx;
text-align: center;
margin-bottom: 30rpx;
}
.confirm-section {
display: flex;
align-items: center;
padding: 24rpx 32rpx;
width: 648rpx;
height: 90rpx;
background: #A24242;
border-radius: 45rpx 45rpx 45rpx 45rpx;
gap: 20rpx;
}
.price-info {
flex: 1;
text-align: right;
}
.total-price {
font-size: 36rpx;
color: #fff;
font-weight: 600;
}
.confirm-btn {
flex: 1;
text-align: left;
}
.btn-text {
font-size: 32rpx;
color: #fff;
font-weight: 500;
}
</style>