Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
R
risk_case_library
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
David Yang
risk_case_library
Commits
a1f45177
Commit
a1f45177
authored
Sep 02, 2026
by
Andy-bubu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
chore: sync develop changes
parent
152a3358
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
169 additions
and
68 deletions
+169
-68
ui-architecture.md
docs/ui-architecture.md
+7
-1
ui-migration-checklist.md
docs/ui-migration-checklist.md
+3
-0
xinyuan-design-system.md
docs/xinyuan-design-system.md
+3
-3
xinyuan-ui-audit.md
docs/xinyuan-ui-audit.md
+20
-5
chartPalette.js
src/design-system/chartPalette.js
+36
-12
theme.css
src/design-system/theme.css
+86
-29
tokens.css
src/design-system/tokens.css
+11
-11
global.less
src/global.less
+1
-1
index.jsx
src/pages/project_manager_xy/resource-stat/index.jsx
+2
-6
No files found.
docs/ui-architecture.md
View file @
a1f45177
...
...
@@ -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 日志写入会反向触发持续编译,造成样式表和字体反复重载。
...
...
docs/ui-migration-checklist.md
View file @
a1f45177
...
...
@@ -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、网络数据或测试数字替代。
docs/xinyuan-design-system.md
View file @
a1f45177
# 鑫元设计系统
本项目直接采用 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 外圆角。
## 跨应用能力
...
...
docs/xinyuan-ui-audit.md
View file @
a1f45177
# 鑫元 UI 审计
审计日期:2026-09-0
1。目标仓库为 Umi 4 / React 19,部署基路径为
`/risk_case_library/`
。本轮 Shell、列表、弹窗和应用切换的唯一实现基准为“审计项目管理”
。
审计日期:2026-09-0
2。目标仓库为 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:800
3
/risk_case_library/`
。
-
当前迁移实例运行于
`http://localhost:800
6
/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)`
、前景为白色。
src/design-system/chartPalette.js
View file @
a1f45177
...
...
@@ -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
:
re
adRootToken
(
'--xinyuan-chart-axis'
,
'#737373'
),
axis
:
re
solveXinyuanChartColor
(
readRootToken
(
'--xinyuan-chart-axis'
,
'#737373'
)
),
fontFamily
:
documentFont
||
'Inter, sans-serif'
,
foreground
:
re
adRootToken
(
'--xinyuan-chart-tooltip-foreground'
,
'#222222'
),
grid
:
re
adRootToken
(
'--xinyuan-chart-grid'
,
'#e8e8e8'
),
label
:
re
adRootToken
(
'--xinyuan-chart-label'
,
'#737373'
),
foreground
:
re
solveXinyuanChartColor
(
readRootToken
(
'--xinyuan-chart-tooltip-foreground'
,
'#222222'
)
),
grid
:
re
solveXinyuanChartColor
(
readRootToken
(
'--xinyuan-chart-grid'
,
'#e8e8e8'
)
),
label
:
re
solveXinyuanChartColor
(
readRootToken
(
'--xinyuan-chart-label'
,
'#737373'
)
),
palette
:
Array
.
from
({
length
:
16
},
(
_
,
index
)
=>
(
re
adRootToken
(
`--xinyuan-chart-
${
index
+
1
}
`
,
'#667085'
)
re
solveXinyuanChartColor
(
readRootToken
(
`--xinyuan-chart-
${
index
+
1
}
`
,
'#667085'
)
)
)),
tooltipBackground
:
re
adRootToken
(
'--xinyuan-chart-tooltip-background'
,
'#ffffff'
),
tooltipBorder
:
re
adRootToken
(
'--xinyuan-chart-tooltip-border'
,
'#dedede'
),
tooltipBackground
:
re
solveXinyuanChartColor
(
readRootToken
(
'--xinyuan-chart-tooltip-background'
,
'#ffffff'
)
),
tooltipBorder
:
re
solveXinyuanChartColor
(
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
)
{
...
...
src/design-system/theme.css
View file @
a1f45177
...
...
@@ -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
);
...
...
src/design-system/tokens.css
View file @
a1f45177
...
...
@@ -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
);
}
src/global.less
View file @
a1f45177
: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);
...
...
src/pages/project_manager_xy/resource-stat/index.jsx
View file @
a1f45177
...
...
@@ -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
}
/>;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment