buddhism/pages/pray/pray.vue
2025-08-05 14:41:40 +08:00

465 lines
11 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="page">
<view class="navbar-container">
<custom-navbar title="在线祈福" />
</view>
<view class="background-container">
<image class="background-image" :src="CommonEnum.BUDDHA_BACKGROUND" mode="aspectFit" />
</view>
<view class="header">
<!-- 香炉图标 -->
<view class="censer-container">
<image class="censer-icon" :src="CommonEnum.CENSER" mode="aspectFit" />
</view>
<!-- 祈福信息表单 -->
<view class="prayer-form-background">
<view class="prayer-form">
<view class="form-title">
<text class="title-text">祈福信息</text>
</view>
<!-- 祈福人姓名 -->
<view class="form-item">
<text class="label">祈福人姓名</text>
<input class="input-field" placeholder="请输入姓名" v-model="formData.name" />
</view>
<!-- 祈福类型 -->
<view class="form-item">
<text class="label">祈福类型</text>
<view class="select-field" @click="showPrayerTypePicker">
<text class="select-text">{{ selectedPrayerType }}</text>
<text class="arrow">></text>
</view>
</view>
<!-- 为他人祈福 -->
<view class="form-item">
<text class="label">为他人祈福</text>
<view class="radio-group">
<view class="radio-item" @click="formData.forOthers = 1">
<text class="radio-text">是</text>
<view class="radio-button" :class="{ 'checked': formData.forOthers === 1 }">
<text v-if="formData.forOthers === 1" class="checkmark">✓</text>
</view>
</view>
<view class="radio-item" @click="formData.forOthers = 2">
<text class="radio-text">否</text>
<view class="radio-button" :class="{ 'checked': formData.forOthers === 2 }">
<text v-if="formData.forOthers === 2" class="checkmark">✓</text>
</view>
</view>
</view>
</view>
<!-- 心愿内容 -->
<view class="form-item">
<text class="label">心愿内容</text>
<view class="textarea-container">
<textarea
class="textarea-field"
placeholder="请填写心愿内容"
v-model="formData.wish"
maxlength="50"
:show-confirm-bar="false"
/>
<text class="char-counter">{{ formData.wish.length }}/50</text>
</view>
</view>
</view>
</view>
<!-- 敬香按钮 -->
<bottom-button
title="敬香"
type="primary"
@click="submitPrayer"
/>
</view>
</view>
</template>
<script>
import CommonEnum from "../../enum/common";
import CustomNavbar from "../../components/custom-navbar/custom-navbar.vue";
import BottomButton from "../../components/bottom-button/bottom-button.vue";
import { submitPrayer } from "@/api/pray/pray";
export default {
components: {
CustomNavbar,
BottomButton,
},
data() {
return {
CommonEnum,
loading: false,
formData: {
name: '',
prayerType: '1', // 默认祈福类型
forOthers: 2, // 默认不为他人祈福
wish: ''
},
prayerTypes: [
{ label: '学业', value: 1 },
{ label: '健康', value: 2 },
{ label: '姻缘', value: 3 },
{ label: '财运', value: 4 },
{ label: '消灾', value: 5 }
],
selectedPrayerType: '学业',
selectedPrayerTypeValue: 1,
showPicker: false
}
},
onLoad() {
// 页面加载时获取数据
this.loadPageData()
},
methods: {
// 加载页面数据
async loadPageData() {
this.loading = true
try {
// TODO: 调用页面数据API
// const response = await getPageData()
// 模拟加载
setTimeout(() => {
this.loading = false
}, 1000)
} catch (error) {
console.error('获取页面数据失败:', error)
this.loading = false
}
},
// 提交祈福
submitPrayer() {
// 表单验证
if (!this.validateForm()) {
return;
}
// 显示确认信息
this.showConfirmation();
},
// 表单验证
validateForm() {
if (!this.formData.name?.trim()) {
uni.showToast({ title: '请输入祈福人姓名', icon: 'none' });
return false;
}
if (!this.selectedPrayerTypeValue) {
uni.showToast({ title: '请选择祈福类型', icon: 'none' });
return false;
}
if (!this.formData.wish?.trim()) {
uni.showToast({ title: '请填写心愿内容', icon: 'none' });
return false;
}
return true;
},
// 显示确认信息
showConfirmation() {
uni.showModal({
title: '确认祈福信息',
content: `祈福人:${this.formData.name}\n祈福类型${this.selectedPrayerType}\n为他人祈福${this.formData.forOthers === 1 ? '是' : '否'}\n心愿内容${this.formData.wish}`,
confirmText: '确认敬香',
cancelText: '修改信息',
success: (res) => {
if (res.confirm) {
this.performPrayer();
}
}
});
},
// 执行祈福
async performPrayer() {
uni.showLoading({ title: '正在敬香...' });
try {
const response = await submitPrayer({
name: this.formData.name.trim(),
type: this.selectedPrayerTypeValue,
isOthers: this.formData.forOthers,
content: this.formData.wish.trim()
});
uni.hideLoading();
if (response.code === 200) {
uni.showToast({ title: '祈福成功!', icon: 'success' });
this.resetForm();
} else {
uni.showToast({ title: response.msg || '祈福失败,请重试', icon: 'none' });
}
} catch (error) {
console.error('祈福请求失败:', error);
uni.hideLoading();
uni.showToast({ title: '网络错误,请重试', icon: 'none' });
}
},
// 重置表单
resetForm() {
this.formData = {
name: '',
prayerType: '1',
forOthers: 2,
wish: ''
}
this.selectedPrayerType = '学业'
this.selectedPrayerTypeValue = 1
},
// 显示祈福类型选择器
showPrayerTypePicker() {
uni.showActionSheet({
itemList: this.prayerTypes.map(item => item.label),
success: (res) => {
if (res.tapIndex !== undefined && res.tapIndex >= 0 && res.tapIndex < this.prayerTypes.length) {
const selectedType = this.prayerTypes[res.tapIndex];
// 更新选中的祈福类型
this.selectedPrayerType = selectedType.label;
this.selectedPrayerTypeValue = selectedType.value;
// 同步更新表单数据
this.formData.prayerType = selectedType.value;
}
},
fail: (res) => {
console.log('用户取消选择或选择失败:', res);
}
});
}
}
}
</script>
<style lang="scss" scoped>
page {
background: #FFFBF5;
}
.page {
position: relative;
width: 100%;
min-height: 100vh;
}
.navbar-container {
background-color: #FAF8F3;
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 10;
padding-top: env(safe-area-inset-top);
}
.background-container {
position: fixed;
top: -600rpx;
left: 0;
width: 100%;
height: calc(100vh + 432rpx);
z-index: -1;
overflow: hidden;
.background-image {
width: 100%;
height: 100%;
object-fit: cover;
}
}
.header {
position: relative;
width: 100%;
min-height: 100vh;
display: flex;
align-items: flex-start;
flex-direction: column;
padding: 0 15rpx;
padding-top: 120rpx;
padding-bottom: 160rpx;
z-index: 1;
}
.censer-container {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
margin-top: 128rpx;
margin-bottom: 60rpx;
z-index: 3;
.censer-icon {
width: 648rpx;
height: 648rpx;
opacity: 0.8;
}
}
.prayer-form-background {
position: fixed;
left: 50%;
transform: translateX(-50%);
width: 100%;
background-color: #FDFCF5;
display: flex;
padding: 0 50rpx 300rpx 50rpx;
margin-top: 625rpx;
z-index: 2;
.prayer-form {
margin-top: 30rpx;
padding: 30rpx 60rpx 0 60rpx;
width: 650rpx;
display: flex;
flex-direction: column;
justify-content: center;
border: 2rpx solid #c0a4ae;
border-radius: 20rpx;
}
}
.form-title {
display: flex;
align-items: center;
.title-text {
width: 126rpx;
height: 44rpx;
font-weight: 400;
color: #695347;
font-size: 32rpx;
line-height: normal;
}
}
.form-item {
margin: 15rpx 0 15rpx 0 ;
display: flex;
border-bottom: #C7A26D 1px solid;
padding: 25rpx 0 25rpx 0;
.label {
font-size: 28rpx;
color: #666;
font-weight: 500;
white-space: nowrap;
}
.input-field{
padding-left: 40rpx;
}
}
.form-item:last-child {
border-bottom: none;
}
.select-field {
display: flex;
align-items: center;
justify-content: space-between;
padding:0 30rpx 0 66rpx;
width: 100%;
.select-text {
font-size: 28rpx;
color: #333;
}
.arrow {
font-size: 24rpx;
color: #999;
}
}
.radio-group {
display: flex;
align-items: center;
//border: #C7A26D 1px solid;
margin-left: 40rpx;
.radio-item {
display: flex;
align-items: center;
margin-right: 60rpx;
&:last-child {
margin-right: 0;
}
.radio-button {
width: 32rpx;
height: 32rpx;
border: 2rpx solid #DDD;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
margin-right: 12rpx;
box-sizing: border-box;
transition: all 0.3s ease;
&.checked {
border-color: #8B2E2E;
background-color: #8B2E2E;
}
}
.checkmark {
font-size: 20rpx;
color: #FFFFFF;
font-weight: bold;
}
.radio-text {
font-size: 28rpx;
color: #333;
padding-right: 12rpx;
}
}
}
.textarea-container {
position: relative;
.textarea-field {
width: 400rpx;
height: 140rpx;
//border: 1rpx solid #e10c0c;
border-radius: 12rpx;
padding: 0 20rpx 0 66rpx;
font-size: 28rpx;
color: #333;
box-sizing: border-box;
resize: none;
}
.char-counter {
position: absolute;
bottom: 0;
right: 0;
font-size: 22rpx;
color: #999;
}
}
</style>