buddhism/pages/memorial/compositons/offeringModal.vue
2025-09-18 15:16:28 +08:00

308 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 v-if="visible" class="offering-modal" @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.id"
:class="{ selected: selectedDuration === option.id }"
class="duration-option"
@click="selectDuration(option.id)"
>
<text class="duration-text">{{ option.name }}</text>
<text class="duration-price">¥{{ option.amount }}</text>
</view>
</view>
</view>
<!-- 供奉人信息 -->
<view class="offerer-section">
<view class="section-label">供奉人</view>
<input
v-model="offererName"
class="offerer-input"
maxlength="20"
placeholder="请填写供奉人姓名"
/>
</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>
import { object } from "../../../uni_modules/uv-ui-tools/libs/function/test";
export default {
name: "OfferingModal",
props: {
visible: {
type: Boolean,
default: false,
},
durationOptions: {
type: object(),
default: {},
},
},
data() {
return {
selectedDuration: null, // 默认选择3天
offererName: "",
};
},
computed: {
totalPrice() {
// 未选择或options为空时返回0
if (!this.selectedDuration || !this.durationOptions.length) return 0;
const selectedOption = this.durationOptions.find(
(option) => option.id === this.selectedDuration,
);
// 当未找到选项时返回空值
return selectedOption?.amount ?? null;
},
},
methods: {
// 关闭弹窗
handleClose() {
this.$emit("close");
},
// 选择供奉时长
selectDuration(value) {
this.selectedDuration = value;
},
// 确认供奉
handleConfirm() {
// 验证供奉人姓名
if (!this.offererName.trim()) {
uni.showToast({
title: "请填写供奉人姓名",
icon: "none",
});
return;
}
console.log("this.durationOptions", this.durationOptions);
// 获取选中的时长选项
const selectedOption = this.durationOptions.find(
(option) => option.id === this.selectedDuration,
);
console.log("selectedOption", selectedOption);
// 触发确认事件
this.$emit("confirm", {
thaliId: this.selectedDuration,
// durationLabel: selectedOption.name,
payAmount: selectedOption.amount,
worName: 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;
display: flex;
flex-direction: column;
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 51rpx;
width: 100%;
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>