fix: QA 全量测试发现 5 个 bug 修复
- [P0] 登录失败无反馈: client.ts 响应拦截器跳过 /auth/login 的 401 处理,让错误传播到 Login 组件 - [P0] 统计仪表盘 400: 前端用独立 try/catch 替代 Promise.all 提高容错性;后端 stats_service 白名单补充 ultrafiltration_volume/dialysis_duration - [P1] 随访负责人显示 UUID: 批量解析 assigned_to 用户名 - [P2] 消息中心时间未格式化: 添加 formatDateTime 函数 - [P2] 首页显示 login_failed: 过滤审计日志中的 login_failed 动作
This commit is contained in:
@@ -16,6 +16,7 @@ import type { ColumnsType, TablePaginationConfig } from 'antd/es/table';
|
||||
import dayjs from 'dayjs';
|
||||
import { followUpApi, type FollowUpTask, type CreateFollowUpTaskReq, type UpdateFollowUpTaskReq } from '../../api/health/followUp';
|
||||
import { patientApi } from '../../api/health/patients';
|
||||
import { getUser } from '../../api/users';
|
||||
import { StatusTag } from './components/StatusTag';
|
||||
import { PatientSelect } from './components/PatientSelect';
|
||||
import { DoctorSelect } from './components/DoctorSelect';
|
||||
@@ -120,6 +121,21 @@ export default function FollowUpTaskList() {
|
||||
if (Object.keys(newLabels).length > 0) {
|
||||
setPatientLabels((prev) => ({ ...prev, ...newLabels }));
|
||||
}
|
||||
|
||||
// Batch resolve assignee names
|
||||
const assigneeIds = [...new Set(result.data.map((t: FollowUpTask) => t.assigned_to).filter(Boolean))];
|
||||
const newDoctorLabels: Record<string, string> = {};
|
||||
await Promise.allSettled(
|
||||
assigneeIds.map(async (id: string) => {
|
||||
try {
|
||||
const u = await getUser(id);
|
||||
newDoctorLabels[id] = u.display_name || u.username;
|
||||
} catch { /* skip */ }
|
||||
}),
|
||||
);
|
||||
if (Object.keys(newDoctorLabels).length > 0) {
|
||||
setDoctorLabels((prev) => ({ ...prev, ...newDoctorLabels }));
|
||||
}
|
||||
} catch {
|
||||
message.error('加载随访任务失败');
|
||||
} finally {
|
||||
|
||||
@@ -92,25 +92,33 @@ export default function StatisticsDashboard() {
|
||||
const fetchAllStats = useCallback(async () => {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
try {
|
||||
const [patients, consultations, followUps, points, healthData] = await Promise.all([
|
||||
pointsApi.getPatientStats(),
|
||||
pointsApi.getConsultationStats(),
|
||||
pointsApi.getFollowUpStats(),
|
||||
pointsApi.getStatistics(),
|
||||
pointsApi.getHealthDataStats(),
|
||||
]);
|
||||
setPatientStats(patients);
|
||||
setConsultationStats(consultations);
|
||||
setFollowUpStats(followUps);
|
||||
setPointsStats(points);
|
||||
setHealthDataStats(healthData);
|
||||
} catch (err: unknown) {
|
||||
const message = err instanceof Error ? err.message : '加载统计数据失败';
|
||||
setError(message);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
|
||||
let hasAnyError = false;
|
||||
const errors: string[] = [];
|
||||
|
||||
const tryFetch = async <T,>(fn: () => Promise<T>, setter: (v: T) => void, label: string) => {
|
||||
try {
|
||||
const data = await fn();
|
||||
setter(data);
|
||||
} catch {
|
||||
hasAnyError = true;
|
||||
errors.push(label);
|
||||
}
|
||||
};
|
||||
|
||||
await Promise.all([
|
||||
tryFetch(pointsApi.getPatientStats, setPatientStats, '患者'),
|
||||
tryFetch(pointsApi.getConsultationStats, setConsultationStats, '咨询'),
|
||||
tryFetch(pointsApi.getFollowUpStats, setFollowUpStats, '随访'),
|
||||
tryFetch(pointsApi.getStatistics, setPointsStats, '积分'),
|
||||
tryFetch(pointsApi.getHealthDataStats, setHealthDataStats, '健康数据'),
|
||||
]);
|
||||
|
||||
if (hasAnyError && errors.length === 5) {
|
||||
setError('加载统计数据失败');
|
||||
}
|
||||
|
||||
setLoading(false);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
Reference in New Issue
Block a user