/**
|
* @author 韩天尊
|
* @time 2024-01-15
|
* @version 1.0.0
|
* @description 管理端志愿者审核页面,展示待审核的志愿者注册申请
|
*/
|
import React, { useState, useEffect } from 'react';
|
import { useNavigate } from 'react-router-dom';
|
import { useAppContext } from '../context/AppContext';
|
import PageHeader from '../components/PageHeader';
|
import { adminAPI } from '../services/api';
|
import { AdminVolunteerReviewRecord } from '../types';
|
|
const AdminVolunteerReviewPage: React.FC = () => {
|
const navigate = useNavigate();
|
const { state } = useAppContext();
|
const [activeTab, setActiveTab] = useState('all');
|
const [selectedRecords, setSelectedRecords] = useState<number[]>([]);
|
const [volunteerReviewRecords, setVolunteerReviewRecords] = useState<AdminVolunteerReviewRecord[]>([]);
|
const [loading, setLoading] = useState(true);
|
const [pagination, setPagination] = useState({
|
page: 1,
|
size: 10,
|
total: 0
|
});
|
|
// 获取志愿者审核列表数据
|
const fetchVolunteerReviewRecords = async (status?: string) => {
|
try {
|
setLoading(true);
|
const response = await adminAPI.getVolunteerReviewList({
|
page: pagination.page,
|
size: pagination.size,
|
status: status
|
});
|
|
if (response.code === 0) {
|
setVolunteerReviewRecords(response.data.list || []);
|
setPagination(prev => ({
|
...prev,
|
total: response.data.total || 0
|
}));
|
}
|
} catch (error) {
|
console.error('获取志愿者审核列表失败:', error);
|
} finally {
|
setLoading(false);
|
}
|
};
|
|
// 初始化数据
|
useEffect(() => {
|
fetchVolunteerReviewRecords();
|
}, [pagination.page]);
|
|
// 切换Tab时重新获取数据
|
useEffect(() => {
|
const statusMap: { [key: string]: string } = {
|
'all': '',
|
'pending': '0',
|
'reviewed': '1,2' // 已审核包括通过和拒绝
|
};
|
fetchVolunteerReviewRecords(statusMap[activeTab]);
|
}, [activeTab]);
|
|
// 获取筛选后的记录
|
const getFilteredRecords = () => {
|
return volunteerReviewRecords;
|
};
|
|
// Tab切换处理
|
const handleTabSwitch = (tab: string) => {
|
setActiveTab(tab);
|
setSelectedRecords([]);
|
};
|
|
// 复选框选择处理
|
const handleRecordSelect = (recordId: number) => {
|
setSelectedRecords(prev => {
|
if (prev.includes(recordId)) {
|
return prev.filter(id => id !== recordId);
|
} else {
|
return [...prev, recordId];
|
}
|
});
|
};
|
|
// 全选/取消全选
|
const handleSelectAll = () => {
|
const filteredRecords = getFilteredRecords();
|
const pendingRecords = filteredRecords.filter(record => record.status === 'pending');
|
|
if (selectedRecords.length === pendingRecords.length && pendingRecords.length > 0) {
|
setSelectedRecords([]);
|
} else {
|
setSelectedRecords(pendingRecords.map(record => record.id));
|
}
|
};
|
|
// 批量审核处理
|
const handleBatchReview = async (action: 'approve' | 'reject') => {
|
if (selectedRecords.length === 0) {
|
alert('请选择要审核的记录');
|
return;
|
}
|
|
try {
|
const response = await adminAPI.batchReviewVolunteerApplication({
|
applicationIds: selectedRecords,
|
action: action === 'approve' ? '1' : '2',
|
comment: action === 'approve' ? '审核通过' : '审核拒绝'
|
});
|
|
if (response.code === 0) {
|
setSelectedRecords([]);
|
alert(`已${action === 'approve' ? '通过' : '拒绝'}选中的志愿者申请`);
|
// 重新获取数据
|
fetchVolunteerReviewRecords();
|
}
|
} catch (error) {
|
console.error('批量审核失败:', error);
|
alert('审核失败,请重试');
|
}
|
};
|
|
// 跳转到审核详情页面
|
const handleReviewDetail = (recordId: number) => {
|
navigate(`/admin-volunteer-review-detail/${recordId}`);
|
};
|
|
// 获取状态文本
|
const getStatusText = (status: string) => {
|
const statusMap: { [key: string]: string } = {
|
'0': '待审核',
|
'1': '已通过',
|
'2': '已拒绝',
|
'pending': '待审核',
|
'approved': '已通过',
|
'rejected': '已拒绝'
|
};
|
return statusMap[status] || status;
|
};
|
|
// 格式化时间为 yyyy-MM-dd HH:mm 格式
|
const formatDateTime = (dateTime: string) => {
|
if (!dateTime) return '';
|
const date = new Date(dateTime);
|
const year = date.getFullYear();
|
const month = String(date.getMonth() + 1).padStart(2, '0');
|
const day = String(date.getDate()).padStart(2, '0');
|
const hours = String(date.getHours()).padStart(2, '0');
|
const minutes = String(date.getMinutes()).padStart(2, '0');
|
return `${year}-${month}-${day} ${hours}:${minutes}`;
|
};
|
|
const filteredRecords = getFilteredRecords();
|
const pendingRecords = filteredRecords.filter(record => record.status === '0');
|
|
return (
|
<div className="page admin-volunteer-review-page">
|
<PageHeader title="志愿者审核" showBack={true} />
|
|
{/* Tab切换 */}
|
<div className="declaration-tabs">
|
<button
|
className={`declaration-tab ${activeTab === 'all' ? 'active' : ''}`}
|
onClick={() => handleTabSwitch('all')}
|
>
|
全部
|
</button>
|
<button
|
className={`declaration-tab ${activeTab === 'pending' ? 'active' : ''}`}
|
onClick={() => handleTabSwitch('pending')}
|
>
|
待审核
|
</button>
|
<button
|
className={`declaration-tab ${activeTab === 'reviewed' ? 'active' : ''}`}
|
onClick={() => handleTabSwitch('reviewed')}
|
>
|
已审核
|
</button>
|
</div>
|
|
{/* 批量操作区域 */}
|
{activeTab === 'pending' && pendingRecords.length > 0 && (
|
<div className="batch-actions">
|
<div className="batch-select">
|
<label className="checkbox-label">
|
<input
|
type="checkbox"
|
checked={selectedRecords.length === pendingRecords.length && pendingRecords.length > 0}
|
onChange={handleSelectAll}
|
/>
|
<span className="checkmark"></span>
|
全选 ({selectedRecords.length}/{pendingRecords.length})
|
</label>
|
</div>
|
<div className="batch-buttons">
|
<button
|
className="batch-btn approve"
|
onClick={() => handleBatchReview('approve')}
|
disabled={selectedRecords.length === 0}
|
>
|
<i className="fas fa-check"></i>
|
批量通过
|
</button>
|
<button
|
className="batch-btn reject"
|
onClick={() => handleBatchReview('reject')}
|
disabled={selectedRecords.length === 0}
|
>
|
<i className="fas fa-times"></i>
|
批量拒绝
|
</button>
|
</div>
|
</div>
|
)}
|
|
{/* 志愿者审核记录列表 */}
|
<div className="volunteer-review-list">
|
{loading ? (
|
<div className="loading">
|
<i className="fas fa-spinner fa-spin"></i>
|
<p>加载中...</p>
|
</div>
|
) : filteredRecords.length === 0 ? (
|
<div className="empty-state">
|
<i className="fas fa-user-check"></i>
|
<p>暂无志愿者审核记录</p>
|
</div>
|
) : (
|
filteredRecords.map((record) => (
|
<div key={record.id} className="volunteer-review-item">
|
{record.status === '0' && (
|
<div className="review-checkbox">
|
<label className="checkbox-label">
|
<input
|
type="checkbox"
|
checked={selectedRecords.includes(record.id)}
|
onChange={() => handleRecordSelect(record.id)}
|
/>
|
<span className="checkmark"></span>
|
</label>
|
</div>
|
)}
|
<div
|
className="volunteer-review-content"
|
onClick={() => handleReviewDetail(record.id)}
|
>
|
<div className="volunteer-review-header">
|
<div className="volunteer-name">{record.name}</div>
|
<div className={`volunteer-status ${record.status}`}>
|
{getStatusText(record.status)}
|
</div>
|
</div>
|
<div className="volunteer-info">
|
<div className="volunteer-phone">{record.phone}</div>
|
<div className="volunteer-id">身份证:{record.idCard}</div>
|
</div>
|
<div className="volunteer-time">提交时间:{formatDateTime(record.createTime)}</div>
|
</div>
|
</div>
|
))
|
)}
|
</div>
|
</div>
|
);
|
};
|
|
export default AdminVolunteerReviewPage;
|