306 lines
7.0 KiB
Vue
Raw Normal View History

2025-08-06 13:22:26 +08:00
<template>
<view class="jc-bm-page">
<!-- 报名信息头部 - 固定部分 -->
<view class="selection-header">
<view class="header-content">
<!-- 学生选择部分 -->
<XsPicker :is-bar="true" />
</view>
</view>
<!-- 可滚动的内容区域 -->
<view class="scrollable-content">
2025-08-06 20:29:45 +08:00
<!-- 就餐标准选择器 -->
2025-08-08 20:38:11 +08:00
<view class="form-section" v-if="jcBzList.length > 0">
2025-08-06 20:29:45 +08:00
<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="已选择的就餐标准"
2025-08-08 20:38:11 +08:00
:show-detail-btn="false"
2025-08-06 20:29:45 +08:00
:show-summary="false"
/>
2025-08-06 13:22:26 +08:00
</view>
<!-- 底部操作区域 -->
<view class="bottom-action">
<view class="selected-info">
2025-08-06 20:29:45 +08:00
<text class="total-price">缴费金额¥{{ totalPrice }}</text>
2025-08-06 13:22:26 +08:00
</view>
<view class="action-buttons">
<view class="cancel-btn" @click="goBack">取消</view>
2025-08-06 20:29:45 +08:00
<view class="confirm-btn" @click="confirmBm" :class="{ disabled: !selectedJcBzId }">确认报名</view>
2025-08-06 13:22:26 +08:00
</view>
</view>
</view>
</template>
<script setup lang="ts">
import XsPicker from "@/pages/base/components/XsPicker/index.vue"
2025-08-06 20:29:45 +08:00
import JcBzPicker from "@/pages/base/components/JcBzPicker/index.vue"
import JcBzDetailCard from "@/pages/base/components/JcBzDetailCard/index.vue"
2025-08-06 13:22:26 +08:00
import { useUserStore } from "@/store/modules/user";
import { useDataStore } from "@/store/modules/data";
2025-08-06 20:29:45 +08:00
import { jcBmJcBzApi, jcGetJcBzListApi } from "@/api/base/jcApi";
2025-08-06 13:22:26 +08:00
const { getCurXs, getUser } = useUserStore();
const { getData, setData } = useDataStore();
const curXs = computed(() => getCurXs);
2025-08-06 20:29:45 +08:00
// 选中的就餐标准ID
const selectedJcBzId = ref<string>('');
// 选中的就餐标准详情
const selectedJcBz = ref<any>(null);
2025-08-08 20:38:11 +08:00
// 就餐标准列表
const jcBzList = ref<any[]>([]);
2025-08-06 13:22:26 +08:00
2025-08-06 20:29:45 +08:00
// 缴费金额
2025-08-06 13:22:26 +08:00
const totalPrice = computed(() => {
2025-08-08 20:38:11 +08:00
return selectedJcBz.value?.bzJe || 0;
2025-08-06 13:22:26 +08:00
});
2025-08-08 20:38:11 +08:00
// 获取就餐标准列表
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);
}
};
2025-08-06 13:22:26 +08:00
// 就餐标准选择变更
2025-08-06 20:29:45 +08:00
const onJcBzChange = (id: string) => {
selectedJcBzId.value = id;
// 根据选中的ID获取对应的就餐标准详情
updateSelectedJcBz(id);
2025-08-06 13:22:26 +08:00
};
2025-08-06 20:29:45 +08:00
// 更新选中的就餐标准详情
const updateSelectedJcBz = async (id: string) => {
if (!id) {
selectedJcBz.value = null;
return;
}
2025-08-08 20:38:11 +08:00
// 从本地列表中查找
selectedJcBz.value = jcBzList.value.find((jcBz: any) =>
jcBz.id === id
) || null;
2025-08-06 13:22:26 +08:00
};
// 返回上一页
const goBack = () => {
uni.navigateBack();
};
// 确认报名
const confirmBm = async () => {
2025-08-06 20:29:45 +08:00
if (!selectedJcBzId.value) {
2025-08-06 13:22:26 +08:00
uni.showToast({
title: "请选择就餐标准",
icon: "none",
});
return;
}
try {
2025-08-08 20:38:11 +08:00
const params = {
2025-08-06 13:22:26 +08:00
xsId: curXs.value.id,
2025-08-06 20:29:45 +08:00
bzId: selectedJcBzId.value,
2025-08-06 13:22:26 +08:00
jzId: getUser.jzId,
2025-08-13 20:04:51 +08:00
bjId: curXs.value.bjId,
bjmc: curXs.value.bjmc,
2025-08-06 20:29:45 +08:00
njId: curXs.value.njId,
njmcId: curXs.value.njmcId,
njmc: curXs.value.njmc,
2025-08-13 20:04:51 +08:00
njbc: curXs.value.njbc,
xm: curXs.value.xm,
2025-08-08 20:38:11 +08:00
}
const res = await jcBmJcBzApi(params);
2025-08-06 13:22:26 +08:00
if (res.resultCode === 1) {
uni.showToast({
title: "报名成功",
icon: "success",
});
// 保存报名数据到store
setData({
2025-08-08 20:38:11 +08:00
...params,
2025-08-06 13:22:26 +08:00
xsId: curXs.value.id,
2025-08-08 20:38:11 +08:00
bzId: selectedJcBzId.value,
jcBz: selectedJcBz.value,
2025-08-06 13:22:26 +08:00
totalJe: totalPrice.value,
});
// 跳转到支付页面
uni.redirectTo({
url: '/pages/base/jc/pay/index'
});
} else {
2025-08-06 20:29:45 +08:00
// 检查是否已经报名
if (res.result?.message && res.result.message.includes('已报名')) {
uni.showModal({
title: '提示',
content: '您已经报名了该就餐标准,是否查看报名详情?',
success: (modalRes) => {
2025-08-07 10:12:04 +08:00
if (modalRes.confirm) {
// 跳转到已选择页面
uni.redirectTo({
url: '/pages/base/jc/index'
});
} else {
// 返回上一页
uni.navigateBack();
}
2025-08-06 20:29:45 +08:00
}
});
} else {
uni.showToast({
title: res.result?.message || "报名失败",
icon: "none",
});
}
2025-08-06 13:22:26 +08:00
}
} catch (error) {
console.error('报名失败:', error);
uni.showToast({
title: "报名失败,请重试",
icon: "none",
});
}
};
// 页面卸载前清除定时器
onBeforeUnmount(() => {
});
2025-08-08 20:38:11 +08:00
// 页面加载时获取就餐标准列表
onMounted(() => {
getJcBzList();
});
2025-08-06 13:22:26 +08:00
</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滚动体验
}
2025-08-06 20:29:45 +08:00
.form-section {
padding: 15px;
background-color: #fff;
margin: 15px;
border-radius: 8px;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
}
2025-08-06 13:22:26 +08:00
.bottom-action {
background-color: #fff;
padding: 15px;
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.05);
.selected-info {
display: flex;
2025-08-06 20:29:45 +08:00
justify-content: center;
2025-08-06 13:22:26 +08:00
align-items: center;
margin-bottom: 15px;
font-size: 14px;
color: #666;
.total-price {
color: #ff6b00;
font-weight: bold;
2025-08-06 20:29:45 +08:00
font-size: 18px;
2025-08-06 13:22:26 +08:00
}
}
.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>