From 0d3e45300ff5c70b77b2875e0fc1f0d9356ec8c3 Mon Sep 17 00:00:00 2001 From: iven Date: Sun, 3 May 2026 19:59:12 +0800 Subject: [PATCH] =?UTF-8?q?refactor(web):=20=E5=89=8D=E7=AB=AF=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E5=A4=84=E7=90=86=E7=BB=9F=E4=B8=80=E5=8C=96=20?= =?UTF-8?q?=E2=80=94=209=20=E4=B8=AA=E6=96=87=E4=BB=B6=2013=20=E5=A4=84?= =?UTF-8?q?=E6=9B=BF=E6=8D=A2=20handleApiError?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 统一使用 api/client.ts 的 handleApiError() 替代内联错误提取: - Login/Users/Roles/Organizations/Settings 操作失败提示 - ArticleEditor/ArticleTagManage/ArticleCategoryManage 表单错误 - FamilyMembersTab 家庭成员操作 零 response?.data?.message 内联模式残留 --- apps/web/src/pages/Login.tsx | 6 ++---- apps/web/src/pages/Organizations.tsx | 21 ++++++------------- apps/web/src/pages/Roles.tsx | 5 ++--- apps/web/src/pages/Users.tsx | 5 ++--- .../pages/health/ArticleCategoryManage.tsx | 6 ++---- apps/web/src/pages/health/ArticleEditor.tsx | 12 +++-------- .../web/src/pages/health/ArticleTagManage.tsx | 6 ++---- .../health/components/FamilyMembersTab.tsx | 4 ++-- .../web/src/pages/settings/SystemSettings.tsx | 5 ++--- 9 files changed, 23 insertions(+), 47 deletions(-) diff --git a/apps/web/src/pages/Login.tsx b/apps/web/src/pages/Login.tsx index 517ebe9..a54c221 100644 --- a/apps/web/src/pages/Login.tsx +++ b/apps/web/src/pages/Login.tsx @@ -3,6 +3,7 @@ import { useNavigate } from 'react-router-dom'; import { Form, Input, Button, message, Divider } from 'antd'; import { UserOutlined, LockOutlined, SafetyCertificateOutlined } from '@ant-design/icons'; import { useAuthStore } from '../stores/auth'; +import { handleApiError } from '../api/client'; import ThemeSwitcher from '../components/ThemeSwitcher'; import { getPublicBrand, type BrandConfig } from '../api/themes'; @@ -23,10 +24,7 @@ export default function Login() { messageApi.success('登录成功'); navigate('/'); } catch (err: unknown) { - const errorMsg = - (err as { response?: { data?: { message?: string } } })?.response?.data?.message || - '登录失败,请检查用户名和密码'; - messageApi.error(errorMsg); + handleApiError(err, '登录失败,请检查用户名和密码'); } }; diff --git a/apps/web/src/pages/Organizations.tsx b/apps/web/src/pages/Organizations.tsx index 32a0e68..ace8a91 100644 --- a/apps/web/src/pages/Organizations.tsx +++ b/apps/web/src/pages/Organizations.tsx @@ -21,6 +21,7 @@ import { } from '@ant-design/icons'; import type { DataNode } from 'antd/es/tree'; import { useThemeMode } from '../hooks/useThemeMode'; +import { handleApiError } from '../api/client'; import { listOrgTree, createOrg, @@ -158,9 +159,7 @@ export default function Organizations() { orgForm.resetFields(); fetchOrgTree(); } catch (err: unknown) { - const errorMsg = - (err as { response?: { data?: { message?: string } } })?.response?.data?.message || '操作失败'; - message.error(errorMsg); + handleApiError(err, '操作失败'); } }; @@ -173,9 +172,7 @@ export default function Organizations() { setPositions([]); fetchOrgTree(); } catch (err: unknown) { - const errorMsg = - (err as { response?: { data?: { message?: string } } })?.response?.data?.message || '删除失败'; - message.error(errorMsg); + handleApiError(err, '删除失败'); } }; @@ -198,9 +195,7 @@ export default function Organizations() { deptForm.resetFields(); fetchDeptTree(); } catch (err: unknown) { - const errorMsg = - (err as { response?: { data?: { message?: string } } })?.response?.data?.message || '操作失败'; - message.error(errorMsg); + handleApiError(err, '操作失败'); } }; @@ -212,9 +207,7 @@ export default function Organizations() { setPositions([]); fetchDeptTree(); } catch (err: unknown) { - const errorMsg = - (err as { response?: { data?: { message?: string } } })?.response?.data?.message || '删除失败'; - message.error(errorMsg); + handleApiError(err, '删除失败'); } }; @@ -238,9 +231,7 @@ export default function Organizations() { positionForm.resetFields(); fetchPositions(); } catch (err: unknown) { - const errorMsg = - (err as { response?: { data?: { message?: string } } })?.response?.data?.message || '操作失败'; - message.error(errorMsg); + handleApiError(err, '操作失败'); } }; diff --git a/apps/web/src/pages/Roles.tsx b/apps/web/src/pages/Roles.tsx index 2baf3b0..3732acb 100644 --- a/apps/web/src/pages/Roles.tsx +++ b/apps/web/src/pages/Roles.tsx @@ -23,6 +23,7 @@ import { type RoleInfo, type PermissionInfo, } from '../api/roles'; +import { handleApiError } from '../api/client'; import { useThemeMode } from '../hooks/useThemeMode'; export default function Roles() { @@ -79,9 +80,7 @@ export default function Roles() { form.resetFields(); fetchRoles(); } catch (err: unknown) { - const errorMsg = - (err as { response?: { data?: { message?: string } } })?.response?.data?.message || '操作失败'; - message.error(errorMsg); + handleApiError(err, '操作失败'); } }; diff --git a/apps/web/src/pages/Users.tsx b/apps/web/src/pages/Users.tsx index 5d6f1f5..be68d06 100644 --- a/apps/web/src/pages/Users.tsx +++ b/apps/web/src/pages/Users.tsx @@ -32,6 +32,7 @@ import { } from '../api/users'; import { listRoles, type RoleInfo } from '../api/roles'; import type { UserInfo } from '../api/auth'; +import { handleApiError } from '../api/client'; import { useThemeMode } from '../hooks/useThemeMode'; const STATUS_COLOR_MAP: Record = { @@ -135,9 +136,7 @@ export default function Users() { form.resetFields(); fetchUsers(); } catch (err: unknown) { - const errorMsg = - (err as { response?: { data?: { message?: string } } })?.response?.data?.message || '操作失败'; - message.error(errorMsg); + handleApiError(err, '操作失败'); } }; diff --git a/apps/web/src/pages/health/ArticleCategoryManage.tsx b/apps/web/src/pages/health/ArticleCategoryManage.tsx index 0f4399e..f800a94 100644 --- a/apps/web/src/pages/health/ArticleCategoryManage.tsx +++ b/apps/web/src/pages/health/ArticleCategoryManage.tsx @@ -22,6 +22,7 @@ import { type CreateCategoryReq, type UpdateCategoryReq, } from '../../api/health/articles'; +import { handleApiError } from '../../api/client'; import { useThemeMode } from '../../hooks/useThemeMode'; import { AuthButton } from '../../components/AuthButton'; @@ -106,10 +107,7 @@ export default function ArticleCategoryManage() { closeModal(); fetchCategories(); } catch (err: unknown) { - const errorMsg = - (err as { response?: { data?: { message?: string } } })?.response?.data?.message || - '操作失败'; - message.error(errorMsg); + handleApiError(err, '操作失败'); } }; diff --git a/apps/web/src/pages/health/ArticleEditor.tsx b/apps/web/src/pages/health/ArticleEditor.tsx index 70831f8..c178d67 100644 --- a/apps/web/src/pages/health/ArticleEditor.tsx +++ b/apps/web/src/pages/health/ArticleEditor.tsx @@ -13,7 +13,7 @@ import { } from '../../api/health/articles'; import { useThemeMode } from '../../hooks/useThemeMode'; import { AuthButton } from '../../components/AuthButton'; -import client from '../../api/client'; +import client, { handleApiError } from '../../api/client'; import '@wangeditor/editor/dist/css/style.css'; export default function ArticleEditor() { @@ -175,10 +175,7 @@ export default function ArticleEditor() { navigate('/health/articles'); } } catch (err: unknown) { - const errorMsg = - (err as { response?: { data?: { message?: string } } })?.response?.data?.message || - '保存失败'; - message.error(errorMsg); + handleApiError(err, '保存失败'); } finally { setSaving(false); } @@ -236,10 +233,7 @@ export default function ArticleEditor() { message.success('已提交审核'); navigate('/health/articles'); } catch (err: unknown) { - const errorMsg = - (err as { response?: { data?: { message?: string } } })?.response?.data?.message || - '提交审核失败'; - message.error(errorMsg); + handleApiError(err, '提交审核失败'); } finally { setSaving(false); } diff --git a/apps/web/src/pages/health/ArticleTagManage.tsx b/apps/web/src/pages/health/ArticleTagManage.tsx index 4486797..66342d0 100644 --- a/apps/web/src/pages/health/ArticleTagManage.tsx +++ b/apps/web/src/pages/health/ArticleTagManage.tsx @@ -15,6 +15,7 @@ import { type ArticleTagItem, type CreateTagReq, } from '../../api/health/articles'; +import { handleApiError } from '../../api/client'; import { useThemeMode } from '../../hooks/useThemeMode'; import { AuthButton } from '../../components/AuthButton'; @@ -77,10 +78,7 @@ export default function ArticleTagManage() { closeModal(); fetchTags(); } catch (err: unknown) { - const errorMsg = - (err as { response?: { data?: { message?: string } } })?.response?.data?.message || - (editing ? '更新失败' : '创建失败'); - message.error(errorMsg); + handleApiError(err, editing ? '更新失败' : '创建失败'); } }; diff --git a/apps/web/src/pages/health/components/FamilyMembersTab.tsx b/apps/web/src/pages/health/components/FamilyMembersTab.tsx index 6042b43..08fd3e7 100644 --- a/apps/web/src/pages/health/components/FamilyMembersTab.tsx +++ b/apps/web/src/pages/health/components/FamilyMembersTab.tsx @@ -2,6 +2,7 @@ import { useCallback, useEffect, useState } from 'react'; import { Table, Button, Form, Input, Select, Drawer, message, Popconfirm, Space } from 'antd'; import { PlusOutlined } from '@ant-design/icons'; import { patientApi, type FamilyMember, type CreateFamilyMemberReq } from '../../../api/health/patients'; +import { handleApiError } from '../../../api/client'; import { AuthButton } from '../../../components/AuthButton'; import { useDictionary } from '../../../hooks/useDictionary'; @@ -52,8 +53,7 @@ export function FamilyMembersTab({ patientId }: Props) { form.resetFields(); fetchMembers(); } catch (err: unknown) { - const msg = (err as { response?: { data?: { message?: string } } })?.response?.data?.message || '操作失败'; - message.error(msg); + handleApiError(err, '操作失败'); } }; diff --git a/apps/web/src/pages/settings/SystemSettings.tsx b/apps/web/src/pages/settings/SystemSettings.tsx index b4548cc..76fe343 100644 --- a/apps/web/src/pages/settings/SystemSettings.tsx +++ b/apps/web/src/pages/settings/SystemSettings.tsx @@ -16,6 +16,7 @@ import { updateSetting, deleteSetting, } from '../../api/settings'; +import { handleApiError } from '../../api/client'; import { useThemeMode } from '../../hooks/useThemeMode'; interface SettingEntry { @@ -93,9 +94,7 @@ export default function SystemSettings() { message.success('设置已保存'); closeModal(); } catch (err: unknown) { - const errorMsg = - (err as { response?: { data?: { message?: string } } })?.response?.data?.message || '保存失败'; - message.error(errorMsg); + handleApiError(err, '保存失败'); } };