Commit a1f45177 authored by Andy-bubu's avatar Andy-bubu

chore: sync develop changes

parent 152a3358
......@@ -17,9 +17,15 @@
`@heroui-pro/react@1.0.0-beta.8` 由官方 `hpsetup` 安装到本项目,`package.json` 使用正式版本范围,锁文件解析到 registry 包。本项目不得再使用跨项目 `file:`、绝对路径、相邻 `node_modules`、符号链接或 Webpack symlink 兼容配置。
## 品牌与图表 Token
- 本应用的 HeroUI Primary 入口为 `--accent: #DA241A`,并提供固定 `--primary`/`--color-primary-*` 品牌色阶别名;`--focus` 同值,品牌 Hover 为 `#C91F17`。不得在页面或组件中另设 primary 色或让默认蓝紫主题覆盖。
- 图表必须通过 `XinyuanEChart` 与 `chartPalette.js` 使用 `--xinyuan-chart-*`。色板顺序固定为品牌红深浅、暖棕、灰紫、灰蓝,禁止绿色、荧光色和彩虹式相邻配色;单系列使用品牌红。
- 图表 Token 在浅色/深色主题中保持相同具体颜色,ECharts 入参必须是可绘制的具体颜色,不能把嵌套 CSS `var(...)` 原样传入 Canvas。
## 样式所有权
`src/design-system/theme.css` 与 `tokens.css` 直接同步审计项目管理当前版本;`shell.css`、`tailwind.css` 与 `global.less` 使用同一共享结构规则,并保留当前项目的 Sidebar 状态、固定列和 Autocomplete 受控值扩展。项目不再加载 `portable.css`,页面没有私有 CSS 外观层。
`src/design-system/theme.css` 与 `tokens.css` 保持审计项目管理的变量结构,仅在本项目的品牌与图表专项中覆盖 `--accent`/`--focus` 和 `--xinyuan-chart-*`;`shell.css`、`tailwind.css` 与 `global.less` 使用同一共享结构规则,并保留当前项目的 Sidebar 状态、固定列和 Autocomplete 受控值扩展。项目不再加载 `portable.css`,页面没有私有 CSS 外观层。
本地浏览器验收产物目录 `.playwright-cli/` 与 `test-results/` 必须保持在 `.gitignore` 中。Tailwind CSS v4 会自动探测未忽略的项目文件;若验收日志进入扫描范围,CSS HMR 日志写入会反向触发持续编译,造成样式表和字体反复重载。
......
......@@ -14,6 +14,7 @@
- [x] Shell:Sidebar/Navbar/退出/应用切换/offcanvas(审计项目管理结构)
- [x] 应用切换:同步审计项目管理 Modal 几何、动态分组/计数、其他/全部回退、两列 Card 与 identity well(代码结构)
- [x] 驾驶舱:Pro KPI、统一 `XinyuanEChart`/ECharts;环形扇区间隙/10px 扇区圆角/外部引导线、柱图 8px 末端圆角与 24px 分析模块圆角(代码结构)
- [x] 品牌与图表专项:HeroUI `--accent`/`--focus` 固定为 `#DA241A`,品牌 Hover 为 `#C91F17`;图表 16 色切换为低饱和品牌红、暖棕、灰紫、灰蓝体系,移除绿色/荧光色与彩虹式相邻配色;KPI 图标同步使用同一协调色系
- [x] 案例管理:Tabs、筛选工具栏、DataGrid、Pagination、ActionBar、EmptyState(代码结构)
- [x] 弹窗:新建、查看/编辑、批量修改、导入、删除确认(代码结构)
- [x] 清除 Catalyst/Headless/旧图表调用/原生可见控件与页面私有视觉 CSS
......@@ -57,4 +58,6 @@
- [x] HeroUI/React Aria 依赖树唯一
- [x] HeroUI Pro 必需子路径通过 ESM 实际导入
本次品牌与图表专项额外执行:`npm run build`、`git diff --check`、颜色 token 扫描及 Playwright computed token/canvas/viewport 检查。结果:构建通过、差异检查通过、图表与 KPI 未使用绿色/荧光色;1440x900/1280x720 viewport 溢出为 0,移动端宽表保留既有内部横向滚动。
应用切换与数据表目标页打开态已在历史真实会话中验收;本次主题同步后的受鉴权复核仍需有效验证码,不得使用伪造 token、网络数据或测试数字替代。
# 鑫元设计系统
本项目直接采用 HeroUI/HeroUI Pro 与鑫元权威主题。“审计项目管理”应用是当前 Shell、列表、弹窗与应用切换的结构、尺寸、间距、组件层级与交互基准。
本项目直接采用 HeroUI/HeroUI Pro 与鑫元权威主题。“审计项目管理”应用是当前 Shell、列表、弹窗与应用切换的结构、尺寸、间距、组件层级与交互基准。本项目的鑫元基金品牌主色固定为 `#DA241A`。HeroUI v3 的真实主按钮入口为 `--accent`,同时维护 `--primary`、`--primary-50` 至 `--primary-950` 及对应 `--color-primary-*` Tailwind 映射;`--focus` 与品牌 Hover 固定使用品牌红体系,不允许默认蓝紫主题覆盖。
## 依赖与样式
- 基础控件直接从 `@heroui/react` 导入。
- Sidebar、Navbar、DataGrid、ActionBar、EmptyState、DropZone 与 KPI 从 `@heroui-pro/react` 对应子路径直接导入;业务图表统一通过共享 `XinyuanEChart` 使用 ECharts。
- 样式顺序固定为 Tailwind、HeroUI、HeroUI Pro、`theme.css`、`tokens.css`、批准的共享布局层。
- 本轮 `theme.css` 与 `tokens.css` 必须与审计项目管理当前版本逐字节一致;页面不得覆盖 HeroUI 外观、slot、BEM 类或交互状态。
- `theme.css` 保留 HeroUI 官方变量结构;本项目允许的品牌覆盖仅为鑫元基金品牌主色 `#DA241A`、品牌 Hover `#C91F17`、固定 primary 色阶和对应图表/指标 Token。页面不得覆盖 HeroUI 外观、slot、BEM 类或交互状态。
- 页面 `className` 只承担 flex、grid、宽度、间距、对齐和响应式布局。
## 页面规则
......@@ -19,7 +19,7 @@
- 页容量选择使用现有 HeroUI Autocomplete 的受控 value 合同;切换容量只重置列表页码并复用既有查询回调,不改变筛选、排序或服务请求协议。
- 详情和内容型表单使用鑫元 4xl(1088px)Modal:HeroUI `Modal.Container size="lg"` 保留官方交互与响应式结构,`Modal.Dialog` 通过共享布局类限制为 `bg-background p-7 sm:max-w-[68rem]`,使详情背景与页面画布一致;查看态不添加灰色嵌套 Surface,编辑态直接放置 `secondary` 控件。
- 指标必须使用 HeroUI Pro KPI compound API;所有业务图表统一使用共享 `XinyuanEChart` ECharts 渲染器,图表主题、Tooltip、坐标轴和颜色由鑫元 Token 统一注入。
- 图表业务序列只使用 `--rc-chart-*` Token,不使用 UI 状态色或页面硬编码颜色。
- 图表业务序列只使用 `--rc-chart-*` Token,不使用 UI 状态色或页面硬编码颜色。色板按“品牌红深浅 -> 暖棕 -> 灰紫 -> 灰蓝”协调排序,禁止绿色、荧光色和彩虹式相邻对撞;单系列统一为 `#DA241A`,同一指标状态使用同色相深浅变化。当前 16 色顺序为 `#DA241A`、`#B83A32`、`#C95A52`、`#D47A70`、`#A65A45`、`#B87958`、`#C99772`、`#8A6F63`、`#9A8174`、`#6F6674`、`#807783`、`#938B96`、`#4F6380`、`#61758F`、`#74879A`、`#8798A8`。
- 环形图通过共享 `--xinyuan-chart-sector-gap`、`--xinyuan-chart-sector-radius` 呈现扇区间隙与 10px 扇区圆角;柱图通过共享图表几何统一使用 8px 末端圆角。分析卡片沿用 `.rc-dashboard-card` 的 24px 外圆角。
## 跨应用能力
......
# 鑫元 UI 审计
审计日期:2026-09-01。目标仓库为 Umi 4 / React 19,部署基路径为 `/risk_case_library/`。本轮 Shell、列表、弹窗和应用切换的唯一实现基准为“审计项目管理”。
审计日期:2026-09-02。目标仓库为 Umi 4 / React 19,部署基路径为 `/risk_case_library/`。本轮 Shell、列表、弹窗和应用切换的唯一实现基准为“审计项目管理”;品牌与图表专项以鑫元基金品牌红 `#DA241A` 为唯一 Primary 基准。
## 安装与运行基线
- 官方安装命令已在项目根目录执行成功,`@heroui-pro/react` 解析为本项目 `node_modules` 内的 `1.0.0-beta.8`,不是符号链接或跨项目 `file:` 依赖。
- 项目使用 npm,保留 `package-lock.json`;旧 `pnpm-lock.yaml` 已删除。
- 当前迁移实例运行于 `http://localhost:8003/risk_case_library/`。
- 当前迁移实例运行于 `http://localhost:8006/risk_case_library/`。
- “审计项目管理”源代码基准位于 `/Users/liuchenlong/Desktop/job/audit_project_manager`。
## 业务契约
......@@ -19,16 +19,24 @@
## 全局审计结果
### 图表配色与品牌专项
- HeroUI `--accent` 与 `--focus` 已固定为 `#DA241A`,品牌 Hover 为 `#C91F17`;Button、Tabs、Chip、选中态和焦点态不再使用 HeroUI 默认蓝色。
- `--xinyuan-chart-1..16` 已替换为低饱和、低冲突的品牌红/暖棕/灰紫/灰蓝顺序,完整色板不含绿色或荧光色;同一图表的序列由共享分配器按协调顺序分配。
- 单序列柱图、横向排名图首项、风险重点和主要趋势使用 `--rc-chart-primary`(`#DA241A`);同一指标状态使用品牌红深浅,比较序列使用灰紫/灰蓝,不使用 UI `success` 或绿色 Token。
- KPI 图标表面已改为同一低饱和品牌/中性体系;布局、数据、接口、统计口径、交互回调和业务状态未改变。
- HeroUI v3 真实主色入口为 `--accent: #DA241A`;同时提供 `--primary`、`--primary-50..950` 与 `--color-primary-*` 映射。`--accent-hover` 固定为 `#C91F17`,`--focus` 固定为 `#DA241A`。Success 语义改为低饱和蓝灰,避免绿色出现在后台界面。
| 范围 | 当前结果 | 迁移要求 |
| --- | --- | --- |
| Login | HeroUI;结构、尺寸、字段节奏与审计项目管理一致;可访问性告警已消除 | 固定浅色 Shell;本次复核受服务端验证码阻塞 |
| Login | HeroUI;结构、尺寸、字段节奏与审计项目管理一致;可访问性告警已消除 | 固定浅色 Shell;登录页品牌色已通过浏览器复核 |
| Shell | HeroUI Pro Sidebar/Navbar,offcanvas、主题、用户退出与应用切换保留既有业务回调 | 代码与共享基准一致;登录后浏览器状态待真实凭证 |
| 应用切换 | HeroUI Modal compound API;46rem/42rem/28px 几何;读取 `/info -> site.group` 动态分组、真实计数与未分组回退;两列 Card、Surface + Avatar identity、唯一当前态 | 与审计项目管理的两列/移动端单列结构一致 |
| 驾驶舱 | HeroUI Pro KPI;统一 `XinyuanEChart`/ECharts 渲染器 | 环形图使用共享扇区间隙、10px 扇区圆角和外部引导线;两类柱图使用 8px 末端圆角;外层分析 Card 为 24px。真实图表 Tooltip 待登录验收 |
| 驾驶舱 | HeroUI Pro KPI;统一 `XinyuanEChart`/ECharts 渲染器 | 环形图使用共享扇区间隙、10px 扇区圆角和外部引导线;两类柱图使用 8px 末端圆角;外层分析 Card 为 24px;真实 Tooltip 已打开验证 |
| 案例管理 | HeroUI Surface/Tabs/TextField/Autocomplete、Pro DataGrid/ActionBar/EmptyState | 默认 20、20/50/100 分页口径已保护;交互待登录验收 |
| 弹窗 | HeroUI Modal/Alert/DropZone,Container 使用官方 `lg`、Dialog 映射鑫元 4xl/1088px,详情 Dialog 使用 `bg-background` 并取消查看态灰色嵌套 Surface | 真实打开态已确认 Dialog 与页面画布同色 |
| 旧组件 | Catalyst、Headless、旧 Select/Date/Table 兼容层已移除 | 活动源码无旧 UI 导入;所有业务图表统一使用 `XinyuanEChart` + ECharts,未保留 HeroUI Pro Recharts 图表调用 |
| 样式 | `theme.css`、`tokens.css` 已与审计项目管理逐字节一致;`shell.css` 保留当前项目所需的 Sidebar 状态、固定列和 Autocomplete 交互扩展 | `portable.css` 与页面私有视觉 CSS 已移除 |
| 样式 | `theme.css`、`tokens.css` 沿用审计项目管理的结构与 Token 层级,并按本项目品牌规范固定 `#DA241A`;`shell.css` 保留当前项目所需的 Sidebar 状态、固定列和 Autocomplete 交互扩展 | `portable.css` 与页面私有视觉 CSS 已移除 |
## 四项功能审计
......@@ -62,3 +70,10 @@ View 配置审计确认本次没有实现权限功能:活动代码不读取 `v
- 审计项目管理基准的应用切换在 1440x900 实测为 736px Dialog、两列 332px 卡片;目标同一会话得到相同 46rem 两列结构。目标移动端 768x1024/390x844 的 Sidebar 是 500px/312px HeroUI offcanvas Dialog,均无 viewport 级横向溢出。
- 页容量选择器在真实列表中从 20 条/页切换到 50 条/页,页面回到第一页并保持原查询数据;1280x720、768x1024 视口均满足 `body.scrollWidth === innerWidth`。本轮控制台检查为 0 error、0 warning。
- 本次以审计项目管理为唯一基准同步主题后,`--background`、`--field-background` 和 `--accent` 已在目标登录页与基准登录页计算为相同值。目标服务端连续返回“验证码错误”,故没有伪造会话来重新打开受鉴权页面;登录失败产生的 3 条请求错误不计入 UI 控制台验收。
## 2026-09-02 品牌与图表专项复核
- 通过 `playwright-cli` 在已存在的真实登录会话中打开 `/risk_case_library/resource/stat`,未注入 token、业务数据或测试记录。
- 1440x900 下驾驶舱渲染 4 个 ECharts Canvas;抽样 Canvas 像素包含 `#DA241A`、`#B83A32`、`#C95A52`、`#D47A70`、`#A65A45`,未发现绿色系像素。
- 环形图和横向排行图 Tooltip 可正常打开,Tooltip 使用共享背景、边框和阴影 Token;390x844 下 `body.scrollWidth === innerWidth`,无视口横向溢出。
- 轻色与临时 `data-theme="dark"` 运行时检查均保持 `--accent`、`--primary`、`--focus` 和 `--xinyuan-chart-1` 为 `#DA241A`;登录页主按钮计算背景为 `rgb(218, 36, 26)`、前景为白色。
......@@ -34,7 +34,10 @@ export function getXinyuanChartGeometry() {
return {
barRadius: 8,
sectorGap: readToken('--xinyuan-chart-sector-gap', '#ffffff'),
sectorGap: resolveXinyuanChartColor(
readToken('--xinyuan-chart-sector-gap', '#ffffff'),
'#ffffff',
),
sectorRadius: Number.parseFloat(
readToken('--xinyuan-chart-sector-radius', '10'),
) || 10,
......@@ -51,9 +54,29 @@ function readRootToken(tokenName, fallback = '') {
.trim() || fallback;
}
function resolveCssColor(value, fallback = '') {
if (!value || typeof document === 'undefined') {
return value || fallback;
}
const probe = document.createElement('span');
probe.style.color = value;
if (!probe.style.color) {
return fallback;
}
probe.style.position = 'absolute';
probe.style.pointerEvents = 'none';
document.body?.appendChild(probe);
const resolved = window.getComputedStyle(probe).color || fallback;
probe.remove();
return resolved;
}
export function resolveXinyuanChartColor(color, fallback = '') {
const match = String(color || '').trim().match(/^var\((--[^)]+)\)$/);
return match ? readRootToken(match[1], fallback) : String(color || fallback);
return match
? resolveCssColor(`var(${match[1]})`, fallback)
: resolveCssColor(String(color || fallback), fallback);
}
export function createResolvedXinyuanChartColorMap(keys = [], options = {}) {
......@@ -71,16 +94,16 @@ export function getXinyuanEChartsTheme() {
: window.getComputedStyle(document.body).fontFamily;
return {
axis: readRootToken('--xinyuan-chart-axis', '#737373'),
axis: resolveXinyuanChartColor(readRootToken('--xinyuan-chart-axis', '#737373')),
fontFamily: documentFont || 'Inter, sans-serif',
foreground: readRootToken('--xinyuan-chart-tooltip-foreground', '#222222'),
grid: readRootToken('--xinyuan-chart-grid', '#e8e8e8'),
label: readRootToken('--xinyuan-chart-label', '#737373'),
foreground: resolveXinyuanChartColor(readRootToken('--xinyuan-chart-tooltip-foreground', '#222222')),
grid: resolveXinyuanChartColor(readRootToken('--xinyuan-chart-grid', '#e8e8e8')),
label: resolveXinyuanChartColor(readRootToken('--xinyuan-chart-label', '#737373')),
palette: Array.from({ length: 16 }, (_, index) => (
readRootToken(`--xinyuan-chart-${index + 1}`, '#667085')
resolveXinyuanChartColor(readRootToken(`--xinyuan-chart-${index + 1}`, '#667085'))
)),
tooltipBackground: readRootToken('--xinyuan-chart-tooltip-background', '#ffffff'),
tooltipBorder: readRootToken('--xinyuan-chart-tooltip-border', '#dedede'),
tooltipBackground: resolveXinyuanChartColor(readRootToken('--xinyuan-chart-tooltip-background', '#ffffff')),
tooltipBorder: resolveXinyuanChartColor(readRootToken('--xinyuan-chart-tooltip-border', '#dedede')),
tooltipShadow: readRootToken(
'--xinyuan-chart-tooltip-shadow',
'0 16px 40px rgb(15 23 42 / 14%)',
......@@ -124,9 +147,10 @@ export function createXinyuanChartColorMap(keys = [], options = {}) {
const usedIndexes = new Set();
stableKeys.forEach((key, keyIndex) => {
const preferredIndex = order.length > 0
? keyIndex % XINYUAN_CHART_PALETTE.length
: hashChartKey(key) % XINYUAN_CHART_PALETTE.length;
// Use the coordinated palette in order instead of a hue-random hash.
// Explicit order keeps ranked/category charts visually intentional;
// without it, lexical ordering keeps the same key set deterministic.
const preferredIndex = keyIndex % XINYUAN_CHART_PALETTE.length;
let paletteIndex = preferredIndex;
if (keyIndex < XINYUAN_CHART_PALETTE.length) {
......
......@@ -11,8 +11,38 @@
[data-theme="light"],
[data-theme="default"] {
/* Theme Colors (Light Mode) */
--accent: oklch(57.14% 0.2156 29.20);
--accent-foreground: oklch(99.11% 0 0);
/* Fixed Xinyuan brand scale. HeroUI v3 consumes --accent; the primary aliases
* keep the brand scale available to utility/theme integrations without allowing
* an automatic blue or purple primary to take over. */
--primary-50: #FEF2F1;
--primary-100: #FDE3E1;
--primary-200: #FBC8C5;
--primary-300: #F49A94;
--primary-400: #EA645B;
--primary-500: #DA241A;
--primary-600: #C91F17;
--primary-700: #B51B14;
--primary-800: #8F1711;
--primary-900: #67100D;
--primary-950: #3D0907;
--primary: var(--primary-500);
--primary-foreground: #FFFFFF;
--color-primary: var(--primary);
--color-primary-foreground: var(--primary-foreground);
--color-primary-50: var(--primary-50);
--color-primary-100: var(--primary-100);
--color-primary-200: var(--primary-200);
--color-primary-300: var(--primary-300);
--color-primary-400: var(--primary-400);
--color-primary-500: var(--primary-500);
--color-primary-600: var(--primary-600);
--color-primary-700: var(--primary-700);
--color-primary-800: var(--primary-800);
--color-primary-900: var(--primary-900);
--color-primary-950: var(--primary-950);
--accent: #DA241A;
--accent-foreground: #FFFFFF;
--accent-hover: #C91F17;
--background: oklch(97.02% 0.0000 29.20);
--border: oklch(90.00% 0.0000 29.20);
--danger: oklch(45.32% 0.1661 27.03);
......@@ -23,7 +53,7 @@
--field-border: transparent;
--field-foreground: oklch(21.03% 0.0000 29.20);
--field-placeholder: oklch(55.17% 0.0000 29.20);
--focus: oklch(57.14% 0.2156 29.20);
--focus: #DA241A;
--foreground: oklch(21.03% 0.0000 29.20);
--muted: oklch(55.17% 0.0000 29.20);
--overlay: oklch(100.00% 0.0000 29.20);
......@@ -32,8 +62,8 @@
--segment: oklch(100.00% 0.0000 29.20);
--segment-foreground: oklch(21.03% 0.0000 29.20);
--separator: oklch(92.00% 0.0000 29.20);
--success: oklch(73.29% 0.1935 123.85);
--success-foreground: oklch(21.03% 0.0059 123.85);
--success: #61758F;
--success-foreground: #FFFFFF;
--surface: oklch(100.00% 0.0000 29.20);
--surface-foreground: oklch(21.03% 0.0000 29.20);
--surface-secondary: oklch(95.24% 0.0000 29.20);
......@@ -63,31 +93,30 @@
--xinyuan-sidebar-item-hover: oklch(22% 0.026 255);
--xinyuan-sidebar-item-selected: oklch(28% 0.016 255);
--xinyuan-sidebar-item-selected-foreground: oklch(99% 0.002 255);
--xinyuan-sidebar-focus: oklch(78% 0.105 29.20);
--xinyuan-sidebar-focus: #DA241A;
/*
* ECharts is the required chart renderer for Xinyuan applications.
* Ant Design remains the icon source. Resolve these CSS variables to
* concrete colors before assigning them to an ECharts option object.
*/
/* First pass: red -> pink -> orange -> yellow -> blue -> purple -> cyan -> neutral. */
--xinyuan-chart-1: #991b1b;
--xinyuan-chart-2: #db2777;
--xinyuan-chart-3: #ea580c;
--xinyuan-chart-4: #eab308;
--xinyuan-chart-5: #1d4ed8;
--xinyuan-chart-6: #7e22ce;
--xinyuan-chart-7: #0891b2;
--xinyuan-chart-8: #475569;
/* Second pass: stronger/lighter companions for charts with more series. */
--xinyuan-chart-9: #dc2626;
--xinyuan-chart-10: #ec4899;
--xinyuan-chart-11: #f97316;
--xinyuan-chart-12: #facc15;
--xinyuan-chart-13: #60a5fa;
--xinyuan-chart-14: #a855f7;
--xinyuan-chart-15: #06b6d4;
--xinyuan-chart-16: #1e293b;
/* Low-conflict financial visualization palette: brand red, warm neutrals, cool slate. */
--xinyuan-chart-1: #DA241A;
--xinyuan-chart-2: #B83A32;
--xinyuan-chart-3: #C95A52;
--xinyuan-chart-4: #D47A70;
--xinyuan-chart-5: #A65A45;
--xinyuan-chart-6: #B87958;
--xinyuan-chart-7: #C99772;
--xinyuan-chart-8: #8A6F63;
--xinyuan-chart-9: #9A8174;
--xinyuan-chart-10: #6F6674;
--xinyuan-chart-11: #807783;
--xinyuan-chart-12: #938B96;
--xinyuan-chart-13: #4F6380;
--xinyuan-chart-14: #61758F;
--xinyuan-chart-15: #74879A;
--xinyuan-chart-16: #8798A8;
--xinyuan-chart-sector-gap: var(--surface);
--xinyuan-chart-sector-radius: 10px;
--xinyuan-chart-grid: #e8e8e8;
......@@ -105,8 +134,36 @@
[data-theme="dark"] {
color-scheme: dark;
/* Theme Colors (Dark Mode) */
--accent: oklch(57.14% 0.2156 29.20);
--accent-foreground: oklch(99.11% 0 0);
/* Keep brand identity stable across the fixed light canvas and dark mode. */
--primary-50: #FEF2F1;
--primary-100: #FDE3E1;
--primary-200: #FBC8C5;
--primary-300: #F49A94;
--primary-400: #EA645B;
--primary-500: #DA241A;
--primary-600: #C91F17;
--primary-700: #B51B14;
--primary-800: #8F1711;
--primary-900: #67100D;
--primary-950: #3D0907;
--primary: var(--primary-500);
--primary-foreground: #FFFFFF;
--color-primary: var(--primary);
--color-primary-foreground: var(--primary-foreground);
--color-primary-50: var(--primary-50);
--color-primary-100: var(--primary-100);
--color-primary-200: var(--primary-200);
--color-primary-300: var(--primary-300);
--color-primary-400: var(--primary-400);
--color-primary-500: var(--primary-500);
--color-primary-600: var(--primary-600);
--color-primary-700: var(--primary-700);
--color-primary-800: var(--primary-800);
--color-primary-900: var(--primary-900);
--color-primary-950: var(--primary-950);
--accent: #DA241A;
--accent-foreground: #FFFFFF;
--accent-hover: #C91F17;
--background: oklch(12.00% 0.0000 29.20);
--border: oklch(28.00% 0.0000 29.20);
--danger: oklch(62% 0.16 27.03);
......@@ -117,7 +174,7 @@
--field-border: transparent;
--field-foreground: oklch(99.11% 0.0000 29.20);
--field-placeholder: oklch(70.50% 0.0000 29.20);
--focus: oklch(57.14% 0.2156 29.20);
--focus: #DA241A;
--foreground: oklch(99.11% 0.0000 29.20);
--muted: oklch(70.50% 0.0000 29.20);
--overlay: oklch(21.03% 0.0000 29.20);
......@@ -126,8 +183,8 @@
--segment: oklch(39.64% 0.0000 29.20);
--segment-foreground: oklch(99.11% 0.0000 29.20);
--separator: oklch(25.00% 0.0000 29.20);
--success: oklch(73.29% 0.1935 123.85);
--success-foreground: oklch(21.03% 0.0059 123.85);
--success: #74879A;
--success-foreground: #FFFFFF;
--surface: oklch(21.03% 0.0000 29.20);
--surface-foreground: oklch(99.11% 0.0000 29.20);
--surface-secondary: oklch(25.70% 0.0000 29.20);
......
......@@ -92,14 +92,14 @@
0 4px 12px rgb(15 23 42 / 2%);
/* KPI icon surfaces. Card bodies remain neutral; only the icon well carries tone. */
--rc-metric-tone-info: oklch(55% 0.14 255);
--rc-metric-tone-success: oklch(54% 0.13 145);
--rc-metric-tone-teal: oklch(55% 0.1 205);
--rc-metric-tone-danger: oklch(52% 0.17 25);
--rc-metric-tone-warning: oklch(62% 0.12 75);
--rc-metric-tone-violet: oklch(56% 0.12 300);
--rc-metric-tone-indigo: oklch(53% 0.13 275);
--rc-metric-tone-coral: oklch(60% 0.12 48);
--rc-metric-tone-info: #6F6674;
--rc-metric-tone-success: #B83A32;
--rc-metric-tone-teal: #61758F;
--rc-metric-tone-danger: #DA241A;
--rc-metric-tone-warning: #B87958;
--rc-metric-tone-violet: #807783;
--rc-metric-tone-indigo: #4F6380;
--rc-metric-tone-coral: #C95A52;
--rc-metric-tone-neutral: var(--muted);
--rc-metric-tone-info-soft: color-mix(
in oklab,
......@@ -167,9 +167,9 @@
--rc-chart-primary: var(--rc-chart-1);
--rc-chart-risk: var(--rc-chart-1);
--rc-chart-warning: var(--rc-chart-3);
--rc-chart-positive: var(--rc-chart-7);
--rc-chart-comparison: var(--rc-chart-5);
--rc-chart-neutral: var(--rc-chart-8);
--rc-chart-positive: var(--rc-chart-4);
--rc-chart-comparison: var(--rc-chart-13);
--rc-chart-neutral: var(--rc-chart-10);
--rc-chart-legend-font-size: var(--xinyuan-chart-legend-font-size);
--rc-chart-legend-line-height: var(--xinyuan-chart-legend-line-height);
}
:root {
--pm-brand: var(--rc-brand-primary, #9e1b1b);
--pm-brand: var(--rc-brand-primary, #DA241A);
--pm-brand-strong: var(--rc-brand-dark, #7e1515);
--pm-surface: var(--rc-bg-surface, #ffffff);
--pm-bg: var(--rc-bg-canvas, #f5f5f5);
......
......@@ -206,10 +206,6 @@ function HorizontalBarChart({ groups }) {
function SourceComposedChart({ groups }) {
const data = normalizeChartData(groups);
const colorMap = createResolvedXinyuanChartColorMap(
data.map((item) => item.name),
{ order: data.map((item) => item.name) },
);
const geometry = getXinyuanChartGeometry();
const option = useMemo(() => ({
grid: { containLabel: true, left: 8, right: 16, top: 24, bottom: 12 },
......@@ -220,13 +216,13 @@ function SourceComposedChart({ groups }) {
barMaxWidth: 28,
data: data.map((item) => ({
...item,
itemStyle: { color: colorMap.get(String(item.name ?? '').trim()) },
itemStyle: { color: resolveXinyuanChartColor(XINYUAN_CHART_SEMANTIC.primary) },
})),
itemStyle: { borderRadius: [geometry.barRadius, geometry.barRadius, 0, 0] },
name: '数量',
type: 'bar',
}],
}), [colorMap, data, geometry.barRadius]);
}), [data, geometry.barRadius]);
return <XinyuanEChart ariaLabel="案例来源分布图" option={option} />;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment