import React, { useState, useEffect, useCallback } from 'react';
|
import { Card, Row, Col, Descriptions, Button, Tag, Avatar, Space, Spin, message } from 'antd';
|
import { useNavigate, useParams } from 'react-router-dom';
|
import { UserOutlined, ArrowLeftOutlined } from '@ant-design/icons';
|
import dayjs from 'dayjs';
|
import { activityUserAPI } from '../../services/api';
|
|
const RegistrationDetail = () => {
|
const navigate = useNavigate();
|
const { id } = useParams();
|
const [registrationDetail, setRegistrationDetail] = useState(null);
|
const [loading, setLoading] = useState(false);
|
|
// 获取报名详情数据
|
const fetchRegistrationDetail = useCallback(async () => {
|
try {
|
setLoading(true);
|
const response = await activityUserAPI.getRegistrationById(id);
|
if (response.code === 0) {
|
const data = response.data;
|
// 转换数据格式以适配前端显示
|
const transformedData = {
|
id: data.id,
|
volunteerName: data.userName, // userName -> volunteerName
|
phone: data.userPhone, // userPhone -> phone
|
registerTime: data.createTime ? dayjs(data.createTime).format('YYYY-MM-DD HH:mm') : '', // 格式化报名时间
|
checkInLocation: data.checkinLocation || '', // checkinLocation -> checkInLocation
|
checkInTime: data.checkinTime ? dayjs(data.checkinTime).format('YYYY-MM-DD HH:mm') : '', // 格式化签到时间
|
checkOutLocation: data.checkoutLocation || '', // checkoutLocation -> checkOutLocation
|
checkOutTime: data.checkoutTime ? dayjs(data.checkoutTime).format('YYYY-MM-DD HH:mm') : '', // 格式化签退时间
|
status: (data.status === 1 || data.status === '1') ? '1' : (data.status === 2 || data.status === '2') ? '2' : (data.status === 3 || data.status === '3') ? '3' : '未知', // 状态映射
|
serviceHours: data.serviceHours || 0, // 服务时长
|
earnedPoints: data.earnedPoints || 0, // 获得积分
|
activityTitle: data.volActivities?.title || '', // 活动名称
|
activityCategory: data.volActivities?.categoryDesc || '', // 活动分类
|
activityStartTime: data.volActivities?.startTime ? dayjs(data.volActivities.startTime).format('YYYY-MM-DD HH:mm') : '', // 活动开始时间
|
activityEndTime: data.volActivities?.endTime ? dayjs(data.volActivities.endTime).format('YYYY-MM-DD HH:mm') : '', // 活动结束时间
|
activityLocation: data.volActivities?.location || '', // 活动地点
|
activityPoints: data.volActivities?.points || 0, // 活动积分
|
originalData: data,
|
};
|
setRegistrationDetail(transformedData);
|
} else {
|
message.error('获取报名详情失败');
|
navigate(-1);
|
}
|
} catch (error) {
|
console.error('获取报名详情失败:', error);
|
message.error('获取报名详情失败');
|
navigate(-1);
|
} finally {
|
setLoading(false);
|
}
|
}, [id, navigate]);
|
|
// 页面初始化加载数据
|
useEffect(() => {
|
if (id) {
|
fetchRegistrationDetail();
|
}
|
}, [id, fetchRegistrationDetail]);
|
|
const getStatusColor = (status) => {
|
const colorMap = {
|
'1': 'blue',
|
'2': 'green',
|
'3': 'purple',
|
'未知': 'default',
|
};
|
return colorMap[status] || 'default';
|
};
|
|
const getStatusText = (status) => {
|
const statusMap = {
|
'1': '已报名',
|
'2': '已签到',
|
'3': '已签退',
|
'未知': '未知',
|
};
|
return statusMap[status] || status;
|
};
|
|
const handleBack = () => {
|
navigate(-1);
|
};
|
|
if (loading) {
|
return (
|
<div style={{ textAlign: 'center', padding: '50px' }}>
|
<Spin size="large" />
|
<div style={{ marginTop: '16px' }}>加载中...</div>
|
</div>
|
);
|
}
|
|
if (!registrationDetail) {
|
return (
|
<div style={{ textAlign: 'center', padding: '50px' }}>
|
<div>报名详情不存在</div>
|
<Button type="primary" onClick={() => navigate(-1)} style={{ marginTop: '16px' }}>
|
返回
|
</Button>
|
</div>
|
);
|
}
|
|
return (
|
<div>
|
<div className="page-header">
|
<Button
|
icon={<ArrowLeftOutlined />}
|
onClick={handleBack}
|
style={{ marginBottom: '16px' }}
|
>
|
返回
|
</Button>
|
<h1 className="page-title">报名详情</h1>
|
<p className="page-description">查看志愿者报名详细信息,管理服务时长和积分</p>
|
</div>
|
|
<Row gutter={[24, 24]}>
|
{/* 基本信息 */}
|
<Col xs={24} lg={12}>
|
<Card title="基本信息" className="detail-card">
|
<Descriptions column={1} size="small">
|
<Descriptions.Item label="志愿者姓名">
|
<Space>
|
<Avatar icon={<UserOutlined />} />
|
{registrationDetail.volunteerName}
|
</Space>
|
</Descriptions.Item>
|
<Descriptions.Item label="联系电话">
|
{registrationDetail.phone}
|
</Descriptions.Item>
|
<Descriptions.Item label="报名时间">
|
{dayjs(registrationDetail.registerTime).format('YYYY-MM-DD HH:mm:ss')}
|
</Descriptions.Item>
|
<Descriptions.Item label="报名状态">
|
<Tag color={getStatusColor(registrationDetail.status)}>
|
{getStatusText(registrationDetail.status)}
|
</Tag>
|
</Descriptions.Item>
|
</Descriptions>
|
</Card>
|
</Col>
|
|
{/* 活动信息 */}
|
<Col xs={24} lg={12}>
|
<Card title="活动信息" className="detail-card">
|
<Descriptions column={1} size="small">
|
<Descriptions.Item label="活动名称">
|
{registrationDetail.activityTitle}
|
</Descriptions.Item>
|
<Descriptions.Item label="活动分类">
|
<Tag color="blue">{registrationDetail.activityCategory}</Tag>
|
</Descriptions.Item>
|
<Descriptions.Item label="活动时间">
|
{dayjs(registrationDetail.activityStartTime).format('MM-DD HH:mm')} - {dayjs(registrationDetail.activityEndTime).format('MM-DD HH:mm')}
|
</Descriptions.Item>
|
<Descriptions.Item label="活动地点">
|
{registrationDetail.activityLocation}
|
</Descriptions.Item>
|
<Descriptions.Item label="活动积分">
|
<span style={{ color: '#52c41a', fontWeight: 'bold' }}>
|
+{registrationDetail.activityPoints}
|
</span>
|
</Descriptions.Item>
|
</Descriptions>
|
</Card>
|
</Col>
|
|
{/* 签到签退信息 */}
|
<Col xs={24}>
|
<Card title="签到签退信息" className="detail-card">
|
<Row gutter={[24, 16]}>
|
<Col xs={24} md={12}>
|
<Descriptions title="签到信息" column={1} size="small">
|
<Descriptions.Item label="签到地点">
|
{registrationDetail.checkInLocation || '未签到'}
|
</Descriptions.Item>
|
<Descriptions.Item label="签到时间">
|
{registrationDetail.checkInTime ? dayjs(registrationDetail.checkInTime).format('YYYY-MM-DD HH:mm:ss') : '未签到'}
|
</Descriptions.Item>
|
</Descriptions>
|
</Col>
|
<Col xs={24} md={12}>
|
<Descriptions title="签退信息" column={1} size="small">
|
<Descriptions.Item label="签退地点">
|
{registrationDetail.checkOutLocation || '未签退'}
|
</Descriptions.Item>
|
<Descriptions.Item label="签退时间">
|
{registrationDetail.checkOutTime ? dayjs(registrationDetail.checkOutTime).format('YYYY-MM-DD HH:mm:ss') : '未签退'}
|
</Descriptions.Item>
|
</Descriptions>
|
</Col>
|
</Row>
|
</Card>
|
</Col>
|
|
{/* 服务时长和积分管理 */}
|
<Col xs={24}>
|
<Card title="服务时长和积分管理" className="detail-card">
|
<Row gutter={[24, 16]}>
|
<Col xs={24} md={12}>
|
<Descriptions column={1} size="small">
|
<Descriptions.Item label="服务时长">
|
<span style={{ fontSize: '16px', fontWeight: 'bold', color: '#1890ff' }}>
|
{registrationDetail.serviceHours} 小时
|
</span>
|
</Descriptions.Item>
|
</Descriptions>
|
</Col>
|
<Col xs={24} md={12}>
|
<Descriptions column={1} size="small">
|
<Descriptions.Item label="获取积分">
|
<span style={{ fontSize: '16px', fontWeight: 'bold', color: '#52c41a' }}>
|
+{registrationDetail.earnedPoints} 分
|
</span>
|
</Descriptions.Item>
|
</Descriptions>
|
</Col>
|
</Row>
|
</Card>
|
</Col>
|
</Row>
|
</div>
|
);
|
};
|
|
export default RegistrationDetail;
|