feat(Company): 优化主题系统,添加颜色工具函数和 ESLint 规则
- 新增 colorUtils.ts:提供 alpha()、hex()、fui.* 语义化颜色 API - 新增 chartTheme:统一图表主题配置(坐标轴、tooltip、渐变等) - 扩展 FUI_COLORS.line:完整的透明度级别(0.03-0.8) - 新增 ESLint 规则:检测硬编码金色值(rgba/hex),warning 级别 - 迁移 chartOptions.ts:~15 处硬编码值改用工具函数 - 迁移 shared/styles.ts:~8 处硬编码值改用工具函数 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
10
.eslintrc.js
10
.eslintrc.js
@@ -79,6 +79,16 @@ module.exports = {
|
||||
'no-unused-vars': 'off', // 使用 TS 版本的规则
|
||||
},
|
||||
},
|
||||
// Company 视图主题硬编码检测
|
||||
{
|
||||
files: ['src/views/Company/**/*.{ts,tsx,js,jsx}'],
|
||||
excludedFiles: ['**/theme/**', '**/*.test.*', '**/*.spec.*'],
|
||||
plugins: ['local-rules'],
|
||||
rules: {
|
||||
// warning 级别:提醒开发者但不阻塞构建
|
||||
'local-rules/no-hardcoded-fui-colors': 'warn',
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
/* 忽略文件(与 .eslintignore 等效)*/
|
||||
|
||||
10
eslint-rules/index.js
Normal file
10
eslint-rules/index.js
Normal file
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* 本地 ESLint 规则插件
|
||||
*
|
||||
* 在 .eslintrc.js 中通过 eslint-plugin-local-rules 使用
|
||||
*/
|
||||
module.exports = {
|
||||
rules: {
|
||||
'no-hardcoded-fui-colors': require('./no-hardcoded-fui-colors'),
|
||||
},
|
||||
};
|
||||
86
eslint-rules/no-hardcoded-fui-colors.js
Normal file
86
eslint-rules/no-hardcoded-fui-colors.js
Normal file
@@ -0,0 +1,86 @@
|
||||
/**
|
||||
* ESLint 规则:禁止在 Company 目录使用硬编码颜色
|
||||
*
|
||||
* 检测模式:
|
||||
* - #D4AF37 (金色十六进制)
|
||||
* - rgba(212, 175, 55, x) (金色 RGBA)
|
||||
*
|
||||
* 使用方式:
|
||||
* 在 .eslintrc.js 中添加规则配置
|
||||
*/
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: 'suggestion',
|
||||
docs: {
|
||||
description: '禁止在 FUI 主题组件中使用硬编码颜色值',
|
||||
category: 'Best Practices',
|
||||
recommended: true,
|
||||
},
|
||||
messages: {
|
||||
noHardcodedGoldRgba:
|
||||
'避免硬编码金色 RGBA 值 "{{value}}"。请使用 alpha("gold", {{opacity}}) 或 fui.border() 等语义化 API。',
|
||||
noHardcodedGoldHex:
|
||||
'避免硬编码金色十六进制值 "{{value}}"。请使用 fui.gold 或 FUI_COLORS.gold[400]。',
|
||||
},
|
||||
schema: [],
|
||||
},
|
||||
|
||||
create(context) {
|
||||
const filename = context.getFilename();
|
||||
|
||||
// 仅在 src/views/Company 目录下生效
|
||||
if (!filename.includes('src/views/Company')) {
|
||||
return {};
|
||||
}
|
||||
|
||||
// 排除主题定义文件
|
||||
if (
|
||||
filename.includes('/theme/') ||
|
||||
filename.includes('/utils/colorUtils')
|
||||
) {
|
||||
return {};
|
||||
}
|
||||
|
||||
// 金色 RGBA 正则 - 匹配 rgba(212, 175, 55, x)
|
||||
const goldRgbaPattern =
|
||||
/rgba\(\s*212\s*,\s*175\s*,\s*55\s*,\s*([\d.]+)\s*\)/i;
|
||||
|
||||
// 金色十六进制 - 匹配 #D4AF37(不区分大小写)
|
||||
const goldHexPattern = /#D4AF37/i;
|
||||
|
||||
function checkValue(node, value) {
|
||||
if (typeof value !== 'string') return;
|
||||
|
||||
// 检测金色十六进制
|
||||
if (goldHexPattern.test(value)) {
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'noHardcodedGoldHex',
|
||||
data: { value },
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 检测金色 RGBA
|
||||
const rgbaMatch = value.match(goldRgbaPattern);
|
||||
if (rgbaMatch) {
|
||||
const opacity = rgbaMatch[1];
|
||||
context.report({
|
||||
node,
|
||||
messageId: 'noHardcodedGoldRgba',
|
||||
data: { value, opacity },
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
Literal(node) {
|
||||
checkValue(node, node.value);
|
||||
},
|
||||
|
||||
TemplateElement(node) {
|
||||
checkValue(node, node.value.raw);
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -98,6 +98,7 @@
|
||||
"cos-nodejs-sdk-v5": "^2.15.4",
|
||||
"env-cmd": "^11.0.0",
|
||||
"eslint-config-prettier": "8.3.0",
|
||||
"eslint-plugin-local-rules": "^3.0.2",
|
||||
"eslint-plugin-prettier": "3.4.0",
|
||||
"gulp": "4.0.2",
|
||||
"gulp-append-prepend": "1.0.9",
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
*/
|
||||
|
||||
import { formatUtils } from '@services/financialService';
|
||||
import { alpha, fui, chartTheme } from '@views/Company/theme';
|
||||
|
||||
interface ChartDataItem {
|
||||
period: string;
|
||||
@@ -106,22 +107,22 @@ export const getComparisonChartOption = (
|
||||
text: '营收与利润趋势',
|
||||
left: 'center',
|
||||
textStyle: {
|
||||
color: '#D4AF37',
|
||||
color: fui.gold,
|
||||
fontSize: 16,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
backgroundColor: 'rgba(26, 32, 44, 0.95)',
|
||||
borderColor: 'rgba(212, 175, 55, 0.3)',
|
||||
backgroundColor: chartTheme.tooltip.bg,
|
||||
borderColor: chartTheme.tooltip.border,
|
||||
textStyle: {
|
||||
color: '#E2E8F0',
|
||||
},
|
||||
axisPointer: {
|
||||
type: 'cross',
|
||||
crossStyle: {
|
||||
color: 'rgba(212, 175, 55, 0.5)',
|
||||
color: alpha('gold', 0.5),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -144,7 +145,7 @@ export const getComparisonChartOption = (
|
||||
data: revenueData.map((d) => d.period),
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: 'rgba(212, 175, 55, 0.3)',
|
||||
color: chartTheme.axisLine,
|
||||
},
|
||||
},
|
||||
axisLabel: {
|
||||
@@ -161,7 +162,7 @@ export const getComparisonChartOption = (
|
||||
},
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: 'rgba(212, 175, 55, 0.3)',
|
||||
color: chartTheme.axisLine,
|
||||
},
|
||||
},
|
||||
axisLabel: {
|
||||
@@ -169,7 +170,7 @@ export const getComparisonChartOption = (
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: 'rgba(212, 175, 55, 0.1)',
|
||||
color: chartTheme.splitLine,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -182,7 +183,7 @@ export const getComparisonChartOption = (
|
||||
},
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: 'rgba(212, 175, 55, 0.3)',
|
||||
color: chartTheme.axisLine,
|
||||
},
|
||||
},
|
||||
axisLabel: {
|
||||
@@ -201,7 +202,7 @@ export const getComparisonChartOption = (
|
||||
itemStyle: {
|
||||
color: (params: { dataIndex: number; value: number }) => {
|
||||
const idx = params.dataIndex;
|
||||
if (idx === 0) return '#D4AF37'; // 金色作为基准
|
||||
if (idx === 0) return fui.gold; // 金色作为基准
|
||||
const prevValue = revenueData[idx - 1].value;
|
||||
const currValue = params.value;
|
||||
// 红涨绿跌
|
||||
@@ -215,37 +216,18 @@ export const getComparisonChartOption = (
|
||||
yAxisIndex: 1,
|
||||
data: profitData.map((d) => d.value?.toFixed(2)),
|
||||
smooth: true,
|
||||
itemStyle: { color: '#D4AF37' },
|
||||
lineStyle: { width: 2, color: '#D4AF37' },
|
||||
itemStyle: { color: fui.gold },
|
||||
lineStyle: { width: 2, color: fui.gold },
|
||||
areaStyle: {
|
||||
color: {
|
||||
type: 'linear',
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [
|
||||
{ offset: 0, color: 'rgba(212, 175, 55, 0.3)' },
|
||||
{ offset: 1, color: 'rgba(212, 175, 55, 0.05)' },
|
||||
],
|
||||
},
|
||||
color: chartTheme.goldGradient(0.3, 0.05),
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
};
|
||||
|
||||
// 黑金主题饼图配色
|
||||
const BLACK_GOLD_PIE_COLORS = [
|
||||
'#D4AF37', // 金色
|
||||
'#B8860B', // 深金色
|
||||
'#FFD700', // 亮金色
|
||||
'#DAA520', // 金菊色
|
||||
'#CD853F', // 秘鲁色
|
||||
'#F4A460', // 沙褐色
|
||||
'#DEB887', // 实木色
|
||||
'#D2691E', // 巧克力色
|
||||
];
|
||||
// 黑金主题饼图配色(使用 chartTheme 统一定义)
|
||||
const BLACK_GOLD_PIE_COLORS = chartTheme.goldSeries;
|
||||
|
||||
/**
|
||||
* 生成主营业务饼图配置 - 黑金主题
|
||||
@@ -265,7 +247,7 @@ export const getMainBusinessPieOption = (
|
||||
subtext: subtitle,
|
||||
left: 'center',
|
||||
textStyle: {
|
||||
color: '#D4AF37',
|
||||
color: fui.gold,
|
||||
fontSize: 14,
|
||||
},
|
||||
subtextStyle: {
|
||||
@@ -275,8 +257,8 @@ export const getMainBusinessPieOption = (
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
backgroundColor: 'rgba(26, 32, 44, 0.95)',
|
||||
borderColor: 'rgba(212, 175, 55, 0.3)',
|
||||
backgroundColor: chartTheme.tooltip.bg,
|
||||
borderColor: chartTheme.tooltip.border,
|
||||
textStyle: {
|
||||
color: '#E2E8F0',
|
||||
},
|
||||
@@ -310,14 +292,14 @@ export const getMainBusinessPieOption = (
|
||||
},
|
||||
labelLine: {
|
||||
lineStyle: {
|
||||
color: 'rgba(212, 175, 55, 0.5)',
|
||||
color: alpha('gold', 0.5),
|
||||
},
|
||||
},
|
||||
emphasis: {
|
||||
itemStyle: {
|
||||
shadowBlur: 10,
|
||||
shadowOffsetX: 0,
|
||||
shadowColor: 'rgba(212, 175, 55, 0.5)',
|
||||
shadowColor: alpha('gold', 0.5),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// 共享样式常量
|
||||
|
||||
import { darkGoldTheme } from '../../constants';
|
||||
import { alpha, fui } from '@views/Company/theme';
|
||||
import type { SystemStyleObject } from '@chakra-ui/react';
|
||||
|
||||
/**
|
||||
@@ -21,7 +22,7 @@ export const darkGoldCardStyle: SystemStyleObject = {
|
||||
*/
|
||||
export const darkGoldCardHoverStyle: SystemStyleObject = {
|
||||
borderColor: darkGoldTheme.borderHover,
|
||||
boxShadow: '0 8px 30px rgba(212, 175, 55, 0.15)',
|
||||
boxShadow: `0 8px 30px ${alpha('gold', 0.15)}`,
|
||||
transform: 'translateY(-2px)',
|
||||
};
|
||||
|
||||
@@ -47,7 +48,7 @@ export const dataRowStyle: SystemStyleObject = {
|
||||
* 表格行悬停样式
|
||||
*/
|
||||
export const tableRowHoverStyle: SystemStyleObject = {
|
||||
bg: 'rgba(212, 175, 55, 0.08)',
|
||||
bg: alpha('gold', 0.08),
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -55,7 +56,7 @@ export const tableRowHoverStyle: SystemStyleObject = {
|
||||
*/
|
||||
export const tableBorderStyle: SystemStyleObject = {
|
||||
borderBottom: '1px solid',
|
||||
borderColor: 'rgba(212, 175, 55, 0.1)',
|
||||
borderColor: fui.border('subtle'),
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -63,14 +64,14 @@ export const tableBorderStyle: SystemStyleObject = {
|
||||
*/
|
||||
export const financingRowStyle: SystemStyleObject = {
|
||||
p: 3,
|
||||
bg: 'rgba(212, 175, 55, 0.08)',
|
||||
bg: alpha('gold', 0.08),
|
||||
borderRadius: 'md',
|
||||
border: '1px solid',
|
||||
borderColor: 'rgba(212, 175, 55, 0.15)',
|
||||
borderColor: alpha('gold', 0.15),
|
||||
transition: 'all 0.2s',
|
||||
_hover: {
|
||||
bg: 'rgba(212, 175, 55, 0.12)',
|
||||
borderColor: 'rgba(212, 175, 55, 0.3)',
|
||||
bg: alpha('gold', 0.12),
|
||||
borderColor: alpha('gold', 0.3),
|
||||
},
|
||||
};
|
||||
|
||||
@@ -127,8 +128,8 @@ export const sellRowStyle: SystemStyleObject = {
|
||||
*/
|
||||
export const dayCardStyle: SystemStyleObject = {
|
||||
p: 4,
|
||||
bg: 'rgba(212, 175, 55, 0.05)',
|
||||
bg: alpha('gold', 0.05),
|
||||
borderRadius: 'lg',
|
||||
border: '1px solid',
|
||||
borderColor: 'rgba(212, 175, 55, 0.15)',
|
||||
borderColor: alpha('gold', 0.15),
|
||||
};
|
||||
|
||||
@@ -50,6 +50,20 @@ export const FUI_COLORS = {
|
||||
default: 'rgba(212, 175, 55, 0.2)',
|
||||
emphasis: 'rgba(212, 175, 55, 0.4)',
|
||||
glow: 'rgba(212, 175, 55, 0.6)',
|
||||
// 完整透明度等级(用于替换硬编码)
|
||||
opacity03: 'rgba(212, 175, 55, 0.03)',
|
||||
opacity05: 'rgba(212, 175, 55, 0.05)',
|
||||
opacity08: 'rgba(212, 175, 55, 0.08)',
|
||||
opacity10: 'rgba(212, 175, 55, 0.1)',
|
||||
opacity12: 'rgba(212, 175, 55, 0.12)',
|
||||
opacity15: 'rgba(212, 175, 55, 0.15)',
|
||||
opacity20: 'rgba(212, 175, 55, 0.2)',
|
||||
opacity30: 'rgba(212, 175, 55, 0.3)',
|
||||
opacity40: 'rgba(212, 175, 55, 0.4)',
|
||||
opacity50: 'rgba(212, 175, 55, 0.5)',
|
||||
opacity60: 'rgba(212, 175, 55, 0.6)',
|
||||
opacity70: 'rgba(212, 175, 55, 0.7)',
|
||||
opacity80: 'rgba(212, 175, 55, 0.8)',
|
||||
},
|
||||
|
||||
// 文字
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
* 使用方式:
|
||||
* import { COLORS, GLOW, GLASS } from '@views/Company/theme';
|
||||
* import { FUI_COLORS, FUI_THEME } from '@views/Company/theme';
|
||||
* import { alpha, fui, chartTheme } from '@views/Company/theme';
|
||||
*/
|
||||
|
||||
// 完整主题对象
|
||||
@@ -20,6 +21,22 @@ export {
|
||||
// 主题组件
|
||||
export * from './components';
|
||||
|
||||
// ============================================
|
||||
// 工具函数导出(推荐使用)
|
||||
// ============================================
|
||||
|
||||
export {
|
||||
// 核心工具
|
||||
alpha,
|
||||
hex,
|
||||
fui,
|
||||
BASE_COLORS,
|
||||
OPACITY,
|
||||
chartTheme,
|
||||
// 类型
|
||||
type ColorName,
|
||||
} from './utils';
|
||||
|
||||
// ============================================
|
||||
// 便捷常量导出(推荐使用)
|
||||
// ============================================
|
||||
|
||||
251
src/views/Company/theme/utils/colorUtils.ts
Normal file
251
src/views/Company/theme/utils/colorUtils.ts
Normal file
@@ -0,0 +1,251 @@
|
||||
/**
|
||||
* FUI 颜色工具函数
|
||||
*
|
||||
* 提供便捷的颜色+透明度生成能力,用于替换硬编码的 rgba 值
|
||||
*
|
||||
* @example
|
||||
* // 替换 'rgba(212, 175, 55, 0.2)' 为:
|
||||
* alpha('gold', 0.2)
|
||||
*
|
||||
* // 或使用语义化 API:
|
||||
* fui.border() // => 'rgba(212, 175, 55, 0.2)'
|
||||
* fui.border('hover') // => 'rgba(212, 175, 55, 0.4)'
|
||||
*/
|
||||
|
||||
// ============================================
|
||||
// 基础色值(单一数据源)
|
||||
// ============================================
|
||||
|
||||
export const BASE_COLORS = {
|
||||
gold: { r: 212, g: 175, b: 55 }, // #D4AF37
|
||||
white: { r: 255, g: 255, b: 255 },
|
||||
black: { r: 0, g: 0, b: 0 },
|
||||
bgPrimary: { r: 15, g: 15, b: 26 }, // #0F0F1A
|
||||
bgElevated: { r: 26, g: 26, b: 46 }, // #1A1A2E
|
||||
positive: { r: 239, g: 68, b: 68 }, // #EF4444 涨
|
||||
negative: { r: 34, g: 197, b: 94 }, // #22C55E 跌
|
||||
warning: { r: 245, g: 158, b: 11 }, // #F59E0B
|
||||
info: { r: 59, g: 130, b: 246 }, // #3B82F6
|
||||
} as const;
|
||||
|
||||
export type ColorName = keyof typeof BASE_COLORS;
|
||||
|
||||
// ============================================
|
||||
// 核心工具函数
|
||||
// ============================================
|
||||
|
||||
/**
|
||||
* 生成带透明度的颜色值
|
||||
* @param color - 颜色名称
|
||||
* @param opacity - 透明度 (0-1)
|
||||
* @returns rgba 字符串
|
||||
*
|
||||
* @example
|
||||
* alpha('gold', 0.2) => 'rgba(212, 175, 55, 0.2)'
|
||||
* alpha('white', 0.5) => 'rgba(255, 255, 255, 0.5)'
|
||||
*/
|
||||
export function alpha(color: ColorName, opacity: number): string {
|
||||
const { r, g, b } = BASE_COLORS[color];
|
||||
return `rgba(${r}, ${g}, ${b}, ${opacity})`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取十六进制颜色值
|
||||
* @param color - 颜色名称
|
||||
* @returns hex 字符串
|
||||
*
|
||||
* @example
|
||||
* hex('gold') => '#D4AF37'
|
||||
*/
|
||||
export function hex(color: ColorName): string {
|
||||
const { r, g, b } = BASE_COLORS[color];
|
||||
const toHex = (n: number) => n.toString(16).padStart(2, '0').toUpperCase();
|
||||
return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// 预设透明度级别
|
||||
// ============================================
|
||||
|
||||
export const OPACITY = {
|
||||
/** 0.05 - 极淡背景 */
|
||||
ghost: 0.05,
|
||||
/** 0.08 - 微弱背景 */
|
||||
faint: 0.08,
|
||||
/** 0.1 - 淡背景/边框 */
|
||||
subtle: 0.1,
|
||||
/** 0.15 - 轻背景 */
|
||||
light: 0.15,
|
||||
/** 0.2 - 默认边框 */
|
||||
muted: 0.2,
|
||||
/** 0.3 - 标签边框 */
|
||||
soft: 0.3,
|
||||
/** 0.4 - 悬停边框 */
|
||||
medium: 0.4,
|
||||
/** 0.5 - 半透明 */
|
||||
half: 0.5,
|
||||
/** 0.6 - 发光边框 */
|
||||
emphasis: 0.6,
|
||||
/** 0.7 - 次要文字 */
|
||||
secondary: 0.7,
|
||||
/** 0.8 - 高可见 */
|
||||
high: 0.8,
|
||||
/** 0.95 - 主文字 */
|
||||
primary: 0.95,
|
||||
} as const;
|
||||
|
||||
// ============================================
|
||||
// 语义化颜色生成器
|
||||
// ============================================
|
||||
|
||||
type BorderVariant = 'subtle' | 'default' | 'hover' | 'emphasis';
|
||||
type BgVariant = 'ghost' | 'subtle' | 'light' | 'medium';
|
||||
type TextVariant = 'primary' | 'secondary' | 'muted' | 'dim';
|
||||
type GlowSize = 'sm' | 'md' | 'lg' | 'pulse';
|
||||
|
||||
/**
|
||||
* FUI 语义化颜色 API
|
||||
* 提供直观的颜色获取方式
|
||||
*/
|
||||
export const fui = {
|
||||
/**
|
||||
* 边框颜色
|
||||
* @example
|
||||
* fui.border() => 'rgba(212, 175, 55, 0.2)'
|
||||
* fui.border('hover') => 'rgba(212, 175, 55, 0.4)'
|
||||
*/
|
||||
border: (variant: BorderVariant = 'default'): string => {
|
||||
const opacityMap: Record<BorderVariant, number> = {
|
||||
subtle: 0.1,
|
||||
default: 0.2,
|
||||
hover: 0.4,
|
||||
emphasis: 0.6,
|
||||
};
|
||||
return alpha('gold', opacityMap[variant]);
|
||||
},
|
||||
|
||||
/**
|
||||
* 背景颜色(金色系)
|
||||
* @example
|
||||
* fui.bg() => 'rgba(212, 175, 55, 0.1)'
|
||||
* fui.bg('ghost') => 'rgba(212, 175, 55, 0.05)'
|
||||
*/
|
||||
bg: (variant: BgVariant = 'subtle'): string => {
|
||||
const opacityMap: Record<BgVariant, number> = {
|
||||
ghost: 0.05,
|
||||
subtle: 0.1,
|
||||
light: 0.15,
|
||||
medium: 0.2,
|
||||
};
|
||||
return alpha('gold', opacityMap[variant]);
|
||||
},
|
||||
|
||||
/**
|
||||
* 文字颜色(白色系)
|
||||
* @example
|
||||
* fui.text() => 'rgba(255, 255, 255, 0.95)'
|
||||
* fui.text('secondary') => 'rgba(255, 255, 255, 0.7)'
|
||||
*/
|
||||
text: (variant: TextVariant = 'primary'): string => {
|
||||
const opacityMap: Record<TextVariant, number> = {
|
||||
primary: 0.95,
|
||||
secondary: 0.7,
|
||||
muted: 0.5,
|
||||
dim: 0.3,
|
||||
};
|
||||
return alpha('white', opacityMap[variant]);
|
||||
},
|
||||
|
||||
/**
|
||||
* 发光效果(box-shadow 值)
|
||||
* @example
|
||||
* fui.glow() => '0 0 16px rgba(212, 175, 55, 0.4)'
|
||||
* fui.glow('lg') => '0 0 32px rgba(212, 175, 55, 0.5)'
|
||||
*/
|
||||
glow: (size: GlowSize = 'md'): string => {
|
||||
const sizeMap: Record<GlowSize, string> = {
|
||||
sm: `0 0 8px ${alpha('gold', 0.3)}`,
|
||||
md: `0 0 16px ${alpha('gold', 0.4)}`,
|
||||
lg: `0 0 32px ${alpha('gold', 0.5)}`,
|
||||
pulse: `0 0 20px ${alpha('gold', 0.6)}, 0 0 40px ${alpha('gold', 0.3)}`,
|
||||
};
|
||||
return sizeMap[size];
|
||||
},
|
||||
|
||||
/**
|
||||
* 玻璃态边框(完整 border 属性)
|
||||
* @example
|
||||
* fui.glassBorder() => '1px solid rgba(212, 175, 55, 0.2)'
|
||||
*/
|
||||
glassBorder: (variant: BorderVariant = 'default'): string => {
|
||||
return `1px solid ${fui.border(variant)}`;
|
||||
},
|
||||
|
||||
/**
|
||||
* 状态颜色
|
||||
*/
|
||||
status: {
|
||||
positive: hex('positive'), // #EF4444
|
||||
negative: hex('negative'), // #22C55E
|
||||
warning: hex('warning'), // #F59E0B
|
||||
info: hex('info'), // #3B82F6
|
||||
positiveBg: alpha('positive', 0.15),
|
||||
negativeBg: alpha('negative', 0.15),
|
||||
},
|
||||
|
||||
/**
|
||||
* 金色(主色调)
|
||||
*/
|
||||
gold: hex('gold'), // #D4AF37
|
||||
} as const;
|
||||
|
||||
// ============================================
|
||||
// 图表主题配置
|
||||
// ============================================
|
||||
|
||||
/**
|
||||
* ECharts 图表主题配置
|
||||
*/
|
||||
export const chartTheme = {
|
||||
// 轴线和网格线
|
||||
axisLine: alpha('gold', 0.3),
|
||||
splitLine: alpha('gold', 0.1),
|
||||
|
||||
// Tooltip
|
||||
tooltip: {
|
||||
bg: alpha('bgElevated', 0.95),
|
||||
border: alpha('gold', 0.3),
|
||||
text: alpha('white', 0.9),
|
||||
},
|
||||
|
||||
// 标题
|
||||
title: {
|
||||
color: hex('gold'),
|
||||
subtextColor: alpha('white', 0.6),
|
||||
},
|
||||
|
||||
// 金色系列配色
|
||||
goldSeries: [
|
||||
'#D4AF37',
|
||||
'#B8860B',
|
||||
'#FFD700',
|
||||
'#DAA520',
|
||||
'#CD853F',
|
||||
'#F4A460',
|
||||
'#DEB887',
|
||||
'#D2691E',
|
||||
],
|
||||
|
||||
// 渐变生成器
|
||||
goldGradient: (startOpacity = 0.3, endOpacity = 0.05) => ({
|
||||
type: 'linear' as const,
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [
|
||||
{ offset: 0, color: alpha('gold', startOpacity) },
|
||||
{ offset: 1, color: alpha('gold', endOpacity) },
|
||||
],
|
||||
}),
|
||||
} as const;
|
||||
15
src/views/Company/theme/utils/index.ts
Normal file
15
src/views/Company/theme/utils/index.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* FUI 主题工具函数导出
|
||||
*/
|
||||
|
||||
export {
|
||||
// 核心工具
|
||||
alpha,
|
||||
hex,
|
||||
fui,
|
||||
BASE_COLORS,
|
||||
OPACITY,
|
||||
chartTheme,
|
||||
// 类型
|
||||
type ColorName,
|
||||
} from './colorUtils';
|
||||
Reference in New Issue
Block a user