buddhism/pages/memorial/compositons/offeringModal.vue
WindowBird e6b33e9d7e 点灯
2025-11-24 17:25:29 +08:00

308 lines
6.0 KiB
Vue
Raw Permalink 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>