fix(web,plugin): 前端审计修复 — 401 消除 + 统计卡片 crash + 销售漏斗 500 + antd 6 废弃 API

- API client: proactive token refresh(请求前 30s 检查过期,提前刷新避免 401)
- Plugin store: fetchPlugins promise 去重,防止 StrictMode 并发重复请求
- Home stats: 简化 useEffect 加载逻辑,修复 tagColor undefined crash
- PluginGraphPage: valueStyle → styles.content, Spin tip → description(antd 6)
- DashboardWidgets: trailColor → railColor(antd 6)
- data_service: build_scope_sql 参数索引修复(硬编码 $100 → 动态 values.len()+1)
- erp-core error: Internal 错误添加 tracing::error 日志输出
This commit is contained in:
iven
2026-04-18 20:31:49 +08:00
parent 790991f77c
commit 5ba11f985f
12 changed files with 308 additions and 100 deletions

View File

@@ -11,7 +11,7 @@ import {
type DashboardWidget,
} from '../api/plugins';
import type { EntityStat, FieldBreakdown, WidgetData } from './dashboard/dashboardTypes';
import { ENTITY_PALETTE, DEFAULT_PALETTE, ENTITY_ICONS, getDelayClass } from './dashboard/dashboardConstants';
import { getEntityPalette, getEntityIcon, getDelayClass } from './dashboard/dashboardConstants';
import {
StatCard,
SkeletonStatCard,
@@ -89,27 +89,28 @@ export function PluginDashboardPage() {
const abortController = new AbortController();
async function loadAllCounts() {
const results: EntityStat[] = [];
for (const entity of entities) {
for (let i = 0; i < entities.length; i++) {
const entity = entities[i];
if (abortController.signal.aborted) return;
const palette = getEntityPalette(entity.name, i);
const icon = getEntityIcon(entity.name);
try {
const count = await countPluginData(pluginId!, entity.name);
if (abortController.signal.aborted) return;
const palette = ENTITY_PALETTE[entity.name] || DEFAULT_PALETTE;
results.push({
name: entity.name,
displayName: entity.display_name || entity.name,
count,
icon: ENTITY_ICONS[entity.name] || <DashboardOutlined />,
icon,
gradient: palette.gradient,
iconBg: palette.iconBg,
});
} catch {
const palette = ENTITY_PALETTE[entity.name] || DEFAULT_PALETTE;
results.push({
name: entity.name,
displayName: entity.display_name || entity.name,
count: 0,
icon: ENTITY_ICONS[entity.name] || <DashboardOutlined />,
icon,
gradient: palette.gradient,
iconBg: palette.iconBg,
});
@@ -206,8 +207,8 @@ export function PluginDashboardPage() {
);
// 当前实体的色板
const currentPalette = useMemo(
() => ENTITY_PALETTE[selectedEntity] || DEFAULT_PALETTE,
[selectedEntity],
() => getEntityPalette(selectedEntity, entities.findIndex((e) => e.name === selectedEntity)),
[selectedEntity, entities],
);
// ── 渲染 ──
if (schemaLoading) {
@@ -257,7 +258,7 @@ export function PluginDashboardPage() {
margin: 0,
}}
>
CRM
{pluginId ? `${pluginId.toUpperCase()} 数据统计` : '数据统计'}
</p>
</div>
<Select