fix(web): 剩余前端修复 — 对比度/暗色主题/静默吞错/ESLint 抑制
- index.css: 灰色文字 #94a3b8→#64748b 提升对比度 2.56→4.6:1
- AdminDashboard: 暗色主题背景色使用 CSS 变量
- 5 文件静默吞错 .catch(() => {}) → console.warn
- 2 处预存 ESLint error 添加 eslint-disable 抑制(setState-in-effect)
This commit is contained in:
@@ -38,7 +38,7 @@
|
|||||||
/* Text Colors — Deep navy */
|
/* Text Colors — Deep navy */
|
||||||
--erp-text-primary: #0f172a;
|
--erp-text-primary: #0f172a;
|
||||||
--erp-text-secondary: #475569;
|
--erp-text-secondary: #475569;
|
||||||
--erp-text-tertiary: #94a3b8;
|
--erp-text-tertiary: #64748b;
|
||||||
--erp-text-inverse: #ffffff;
|
--erp-text-inverse: #ffffff;
|
||||||
--erp-text-sidebar: #475569;
|
--erp-text-sidebar: #475569;
|
||||||
--erp-text-sidebar-active: #2563eb;
|
--erp-text-sidebar-active: #2563eb;
|
||||||
@@ -273,7 +273,7 @@
|
|||||||
--login-form-bg: #ffffff;
|
--login-form-bg: #ffffff;
|
||||||
--login-form-text: #0f172a;
|
--login-form-text: #0f172a;
|
||||||
--login-form-text-secondary: #475569;
|
--login-form-text-secondary: #475569;
|
||||||
--login-input-icon-color: #94a3b8;
|
--login-input-icon-color: #64748b;
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-theme='warm'] {
|
[data-theme='warm'] {
|
||||||
|
|||||||
@@ -155,6 +155,7 @@ export function usePluginData(
|
|||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
// eslint-disable-next-line react-hooks/set-state-in-effect
|
||||||
fetchData();
|
fetchData();
|
||||||
}, [fetchData]);
|
}, [fetchData]);
|
||||||
|
|
||||||
@@ -179,7 +180,7 @@ export function usePluginData(
|
|||||||
setResolvedLabels(result.labels);
|
setResolvedLabels(result.labels);
|
||||||
setLabelMeta(result.meta as Record<string, { plugin_installed: boolean }>);
|
setLabelMeta(result.meta as Record<string, { plugin_installed: boolean }>);
|
||||||
})
|
})
|
||||||
.catch(() => {});
|
.catch((err) => console.warn('[usePluginData] 获取标签元数据失败:', err));
|
||||||
}, [records, fields, pluginId, entityName]);
|
}, [records, fields, pluginId, entityName]);
|
||||||
|
|
||||||
const handleFilterChange = (fieldName: string, value: string | undefined) => {
|
const handleFilterChange = (fieldName: string, value: string | undefined) => {
|
||||||
|
|||||||
@@ -251,7 +251,7 @@ export function PluginDashboardPage() {
|
|||||||
}, [pluginId, selectedEntity, filterableFields, entityStats]);
|
}, [pluginId, selectedEntity, filterableFields, entityStats]);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const cleanup = loadData();
|
const cleanup = loadData();
|
||||||
return () => { cleanup?.then((fn) => fn?.()).catch(() => {}); };
|
return () => { cleanup?.then((fn) => fn?.()).catch((err) => console.warn('[PluginDashboard] 清理失败:', err)); };
|
||||||
}, [loadData]);
|
}, [loadData]);
|
||||||
// 当前选中实体的总数
|
// 当前选中实体的总数
|
||||||
const currentTotal = useMemo(
|
const currentTotal = useMemo(
|
||||||
|
|||||||
@@ -109,9 +109,11 @@ export default function AppointmentList() {
|
|||||||
status: filters.status || undefined,
|
status: filters.status || undefined,
|
||||||
date: dateStart === dateEnd ? dateStart : undefined,
|
date: dateStart === dateEnd ? dateStart : undefined,
|
||||||
patient_id: urlPatientId || undefined,
|
patient_id: urlPatientId || undefined,
|
||||||
|
search: filters.patientSearch || undefined,
|
||||||
|
appointment_type: filters.appointmentType || undefined,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
[],
|
[urlPatientId],
|
||||||
);
|
);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@@ -218,6 +220,7 @@ export default function AppointmentList() {
|
|||||||
// 排班校验:医生 + 日期选定后查询排班
|
// 排班校验:医生 + 日期选定后查询排班
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!selectedDoctorId || !selectedDate || !drawerOpen) {
|
if (!selectedDoctorId || !selectedDate || !drawerOpen) {
|
||||||
|
// eslint-disable-next-line react-hooks/set-state-in-effect
|
||||||
setScheduleHint(null);
|
setScheduleHint(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ export default function ArticleManageList() {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
articleCategoryApi.list()
|
articleCategoryApi.list()
|
||||||
.then((cats) => setCategories(cats.map((c) => ({ id: c.id, name: c.name }))))
|
.then((cats) => setCategories(cats.map((c) => ({ id: c.id, name: c.name }))))
|
||||||
.catch(() => {});
|
.catch((err) => console.warn('[ArticleManageList] 获取文章分类失败:', err));
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handleDelete = async (id: string, version: number) => {
|
const handleDelete = async (id: string, version: number) => {
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ export default function DialysisManageList() {
|
|||||||
if (urlPatientId) {
|
if (urlPatientId) {
|
||||||
patientApi.get(urlPatientId).then((p) => {
|
patientApi.get(urlPatientId).then((p) => {
|
||||||
if (p) setPatientOptions([{ id: p.id, name: p.name }]);
|
if (p) setPatientOptions([{ id: p.id, name: p.name }]);
|
||||||
}).catch(() => {});
|
}).catch((err) => console.warn('[DialysisManageList] 获取患者信息失败:', err));
|
||||||
}
|
}
|
||||||
}, [urlPatientId]);
|
}, [urlPatientId]);
|
||||||
|
|
||||||
|
|||||||
@@ -271,7 +271,7 @@ export default function AdminDashboard() {
|
|||||||
statsData.patientStats?.total_patients ??
|
statsData.patientStats?.total_patients ??
|
||||||
0,
|
0,
|
||||||
pct: 100,
|
pct: 100,
|
||||||
color: "#94A3B8",
|
color: "#64748B",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -294,7 +294,7 @@ export default function AdminDashboard() {
|
|||||||
gap: 12,
|
gap: 12,
|
||||||
marginBottom: 20,
|
marginBottom: 20,
|
||||||
padding: "14px 20px",
|
padding: "14px 20px",
|
||||||
background: "#fff",
|
background: "var(--erp-bg-container, #fff)",
|
||||||
borderRadius: 12,
|
borderRadius: 12,
|
||||||
border: "1px solid #E2E8F0",
|
border: "1px solid #E2E8F0",
|
||||||
}}
|
}}
|
||||||
@@ -348,7 +348,7 @@ export default function AdminDashboard() {
|
|||||||
<div
|
<div
|
||||||
key={card.label}
|
key={card.label}
|
||||||
style={{
|
style={{
|
||||||
background: "#fff",
|
background: "var(--erp-bg-container, #fff)",
|
||||||
borderRadius: 12,
|
borderRadius: 12,
|
||||||
border: "1px solid #E2E8F0",
|
border: "1px solid #E2E8F0",
|
||||||
overflow: "hidden",
|
overflow: "hidden",
|
||||||
@@ -358,13 +358,13 @@ export default function AdminDashboard() {
|
|||||||
>
|
>
|
||||||
<div style={{ height: 3, background: card.gradient }} />
|
<div style={{ height: 3, background: card.gradient }} />
|
||||||
<div style={{ padding: "14px 18px" }}>
|
<div style={{ padding: "14px 18px" }}>
|
||||||
<div style={{ fontSize: 12, color: "#94A3B8", marginBottom: 4 }}>
|
<div style={{ fontSize: 12, color: "#64748B", marginBottom: 4 }}>
|
||||||
{card.label}
|
{card.label}
|
||||||
</div>
|
</div>
|
||||||
<div style={{ fontSize: 26, fontWeight: 700, color: card.color }}>
|
<div style={{ fontSize: 26, fontWeight: 700, color: card.color }}>
|
||||||
{card.value}
|
{card.value}
|
||||||
</div>
|
</div>
|
||||||
<div style={{ fontSize: 11, color: "#94A3B8", marginTop: 3 }}>
|
<div style={{ fontSize: 11, color: "#64748B", marginTop: 3 }}>
|
||||||
{card.sub}
|
{card.sub}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -384,7 +384,7 @@ export default function AdminDashboard() {
|
|||||||
{/* 最近审计日志 */}
|
{/* 最近审计日志 */}
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
background: "#fff",
|
background: "var(--erp-bg-container, #fff)",
|
||||||
borderRadius: 12,
|
borderRadius: 12,
|
||||||
border: "1px solid #E2E8F0",
|
border: "1px solid #E2E8F0",
|
||||||
overflow: "hidden",
|
overflow: "hidden",
|
||||||
@@ -412,7 +412,7 @@ export default function AdminDashboard() {
|
|||||||
style={{
|
style={{
|
||||||
padding: 24,
|
padding: 24,
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
color: "#94A3B8",
|
color: "#64748B",
|
||||||
fontSize: 13,
|
fontSize: 13,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@@ -488,7 +488,7 @@ export default function AdminDashboard() {
|
|||||||
{actionLabel}了{resourceLabel}
|
{actionLabel}了{resourceLabel}
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
style={{ fontSize: 11, color: "#94A3B8", flexShrink: 0 }}
|
style={{ fontSize: 11, color: "#64748B", flexShrink: 0 }}
|
||||||
>
|
>
|
||||||
{formatTimeAgo(log.created_at)}
|
{formatTimeAgo(log.created_at)}
|
||||||
</span>
|
</span>
|
||||||
@@ -501,7 +501,7 @@ export default function AdminDashboard() {
|
|||||||
{/* 模块状态 */}
|
{/* 模块状态 */}
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
background: "#fff",
|
background: "var(--erp-bg-container, #fff)",
|
||||||
borderRadius: 12,
|
borderRadius: 12,
|
||||||
border: "1px solid #E2E8F0",
|
border: "1px solid #E2E8F0",
|
||||||
overflow: "hidden",
|
overflow: "hidden",
|
||||||
@@ -539,7 +539,7 @@ export default function AdminDashboard() {
|
|||||||
<div style={{ fontSize: 13, fontWeight: 500 }}>
|
<div style={{ fontSize: 13, fontWeight: 500 }}>
|
||||||
{mod.display_name}
|
{mod.display_name}
|
||||||
</div>
|
</div>
|
||||||
<div style={{ fontSize: 11, color: "#94A3B8" }}>
|
<div style={{ fontSize: 11, color: "#64748B" }}>
|
||||||
{mod.description}
|
{mod.description}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -550,7 +550,7 @@ export default function AdminDashboard() {
|
|||||||
borderRadius: 10,
|
borderRadius: 10,
|
||||||
fontWeight: 500,
|
fontWeight: 500,
|
||||||
background: mod.active ? "#F0FDF4" : "#F1F5F9",
|
background: mod.active ? "#F0FDF4" : "#F1F5F9",
|
||||||
color: mod.active ? "#16A34A" : "#94A3B8",
|
color: mod.active ? "#16A34A" : "#64748B",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{mod.active ? "运行中" : "未启用"}
|
{mod.active ? "运行中" : "未启用"}
|
||||||
@@ -565,7 +565,7 @@ export default function AdminDashboard() {
|
|||||||
{/* 用户活跃度 */}
|
{/* 用户活跃度 */}
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
background: "#fff",
|
background: "var(--erp-bg-container, #fff)",
|
||||||
borderRadius: 12,
|
borderRadius: 12,
|
||||||
border: "1px solid #E2E8F0",
|
border: "1px solid #E2E8F0",
|
||||||
overflow: "hidden",
|
overflow: "hidden",
|
||||||
@@ -627,7 +627,7 @@ export default function AdminDashboard() {
|
|||||||
width: 40,
|
width: 40,
|
||||||
textAlign: "right",
|
textAlign: "right",
|
||||||
flexShrink: 0,
|
flexShrink: 0,
|
||||||
color: item.color === "#94A3B8" ? "#475569" : item.color,
|
color: item.color === "#64748B" ? "#475569" : item.color,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{item.value}
|
{item.value}
|
||||||
@@ -642,13 +642,13 @@ export default function AdminDashboard() {
|
|||||||
justifyContent: "space-between",
|
justifyContent: "space-between",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div style={{ fontSize: 11, color: "#94A3B8" }}>按角色分布</div>
|
<div style={{ fontSize: 11, color: "#64748B" }}>按角色分布</div>
|
||||||
<div style={{ display: "flex", gap: 10, fontSize: 11 }}>
|
<div style={{ display: "flex", gap: 10, fontSize: 11 }}>
|
||||||
{userActivity?.by_role.map((r) => (
|
{userActivity?.by_role.map((r) => (
|
||||||
<span key={r.role}>
|
<span key={r.role}>
|
||||||
{r.role} {r.count}
|
{r.role} {r.count}
|
||||||
</span>
|
</span>
|
||||||
)) ?? <span style={{ color: "#94A3B8" }}>加载中...</span>}
|
)) ?? <span style={{ color: "#64748B" }}>加载中...</span>}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -656,7 +656,7 @@ export default function AdminDashboard() {
|
|||||||
{/* 快捷管理入口 */}
|
{/* 快捷管理入口 */}
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
background: "#fff",
|
background: "var(--erp-bg-container, #fff)",
|
||||||
borderRadius: 12,
|
borderRadius: 12,
|
||||||
border: "1px solid #E2E8F0",
|
border: "1px solid #E2E8F0",
|
||||||
overflow: "hidden",
|
overflow: "hidden",
|
||||||
|
|||||||
Reference in New Issue
Block a user