2025-08-13 20:04:51 +08:00

306 lines
7.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="jc-bm-page">
<!-- 报名信息头部 - 固定部分 -->
<view class="selection-header">
<view class="header-content">
<!-- 学生选择部分 -->
<XsPicker :is-bar="true" />
</view>
</view>
<!-- 可滚动的内容区域 -->
<view class="scrollable-content">
<!-- 就餐标准选择器 -->
<view class="form-section" v-if="jcBzList.length > 0">
<JcBzPicker
:xs-id="curXs.id"
label="就餐标准"
placeholder="请选择就餐标准"
:multiple="false"
:required="true"
v-model="selectedJcBzId"
@change="onJcBzChange"
/>
</view>
<!-- 选中标准的详情展示 -->
<JcBzDetailCard
v-if="selectedJcBz"
:jc-bz-list="[selectedJcBz]"
title="已选择的就餐标准"
:show-detail-btn="false"
:show-summary="false"
/>
</view>
<!-- 底部操作区域 -->
<view class="bottom-action">
<view class="selected-info">
<text class="total-price">缴费金额¥{{ totalPrice }}</text>
</view>
<view class="action-buttons">
<view class="cancel-btn" @click="goBack">取消</view>
<view class="confirm-btn" @click="confirmBm" :class="{ disabled: !selectedJcBzId }">确认报名</view>
</view>
</view>
</view>
</template>
<script setup lang="ts">
import XsPicker from "@/pages/base/components/XsPicker/index.vue"
import JcBzPicker from "@/pages/base/components/JcBzPicker/index.vue"
import JcBzDetailCard from "@/pages/base/components/JcBzDetailCard/index.vue"
import { useUserStore } from "@/store/modules/user";
import { useDataStore } from "@/store/modules/data";
import { jcBmJcBzApi, jcGetJcBzListApi } from "@/api/base/jcApi";
const { getCurXs, getUser } = useUserStore();
const { getData, setData } = useDataStore();
const curXs = computed(() => getCurXs);
// 选中的就餐标准ID
const selectedJcBzId = ref<string>('');
// 选中的就餐标准详情
const selectedJcBz = ref<any>(null);
// 就餐标准列表
const jcBzList = ref<any[]>([]);
// 缴费金额
const totalPrice = computed(() => {
return selectedJcBz.value?.bzJe || 0;
});
// 获取就餐标准列表
const getJcBzList = async () => {
try {
const res = await jcGetJcBzListApi({
xsId: curXs.value.id
});
if (res.resultCode === 1) {
const result = res.result;
jcBzList.value = result && result.jcBzList ? result.jcBzList : [];
// 如果只有一个标准,自动选中
if (jcBzList.value.length === 1) {
const singleJcBz = jcBzList.value[0];
selectedJcBzId.value = singleJcBz.id;
selectedJcBz.value = singleJcBz;
}
}
} catch (error) {
console.error('获取就餐标准列表失败:', error);
}
};
// 就餐标准选择变更
const onJcBzChange = (id: string) => {
selectedJcBzId.value = id;
// 根据选中的ID获取对应的就餐标准详情
updateSelectedJcBz(id);
};
// 更新选中的就餐标准详情
const updateSelectedJcBz = async (id: string) => {
if (!id) {
selectedJcBz.value = null;
return;
}
// 从本地列表中查找
selectedJcBz.value = jcBzList.value.find((jcBz: any) =>
jcBz.id === id
) || null;
};
// 返回上一页
const goBack = () => {
uni.navigateBack();
};
// 确认报名
const confirmBm = async () => {
if (!selectedJcBzId.value) {
uni.showToast({
title: "请选择就餐标准",
icon: "none",
});
return;
}
try {
const params = {
xsId: curXs.value.id,
bzId: selectedJcBzId.value,
jzId: getUser.jzId,
bjId: curXs.value.bjId,
bjmc: curXs.value.bjmc,
njId: curXs.value.njId,
njmcId: curXs.value.njmcId,
njmc: curXs.value.njmc,
njbc: curXs.value.njbc,
xm: curXs.value.xm,
}
const res = await jcBmJcBzApi(params);
if (res.resultCode === 1) {
uni.showToast({
title: "报名成功",
icon: "success",
});
// 保存报名数据到store
setData({
...params,
xsId: curXs.value.id,
bzId: selectedJcBzId.value,
jcBz: selectedJcBz.value,
totalJe: totalPrice.value,
});
// 跳转到支付页面
uni.redirectTo({
url: '/pages/base/jc/pay/index'
});
} else {
// 检查是否已经报名
if (res.result?.message && res.result.message.includes('已报名')) {
uni.showModal({
title: '提示',
content: '您已经报名了该就餐标准,是否查看报名详情?',
success: (modalRes) => {
if (modalRes.confirm) {
// 跳转到已选择页面
uni.redirectTo({
url: '/pages/base/jc/index'
});
} else {
// 返回上一页
uni.navigateBack();
}
}
});
} else {
uni.showToast({
title: res.result?.message || "报名失败",
icon: "none",
});
}
}
} catch (error) {
console.error('报名失败:', error);
uni.showToast({
title: "报名失败,请重试",
icon: "none",
});
}
};
// 页面卸载前清除定时器
onBeforeUnmount(() => {
});
// 页面加载时获取就餐标准列表
onMounted(() => {
getJcBzList();
});
</script>
<style lang="scss" scoped>
.jc-bm-page {
min-height: 100%;
background-color: #f5f7fa;
display: flex;
flex-direction: column;
height: 100%;
overflow: hidden;
}
.selection-header {
background: linear-gradient(135deg, #4a90e2, #2879ff);
padding: 20px 15px;
color: #fff;
border-radius: 0 0 15px 15px;
box-shadow: 0 4px 12px rgba(40, 121, 255, 0.2);
position: sticky;
top: 0;
left: 0;
right: 0;
z-index: 10;
.header-content {
display: flex;
flex-direction: column;
gap: 15px;
}
}
// 可滚动内容区域样式
.scrollable-content {
flex: 1;
overflow-y: auto;
-webkit-overflow-scrolling: touch; // 增强iOS滚动体验
}
.form-section {
padding: 15px;
background-color: #fff;
margin: 15px;
border-radius: 8px;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
}
.bottom-action {
background-color: #fff;
padding: 15px;
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.05);
.selected-info {
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 15px;
font-size: 14px;
color: #666;
.total-price {
color: #ff6b00;
font-weight: bold;
font-size: 18px;
}
}
.action-buttons {
display: flex;
justify-content: space-between;
.cancel-btn,
.confirm-btn {
width: 48%;
height: 44px;
line-height: 44px;
text-align: center;
border-radius: 22px;
font-size: 16px;
}
.cancel-btn {
background-color: #fff;
color: #333;
border: 1px solid #ddd;
}
.confirm-btn {
background-color: #2879ff;
color: #fff;
&.disabled {
background-color: #ccc;
color: #999;
}
}
}
}
</style>