From 50ba594ad1603c26e1174dbd137f42cc1c57f745 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E8=87=AA=E8=BE=BE?= <980324341@qq.com> Date: Sat, 5 Sep 2026 20:48:57 +0800 Subject: [PATCH] =?UTF-8?q?task-242(admin.html=E8=A7=82=E6=84=9F=E5=AF=B9?= =?UTF-8?q?=E9=BD=90):=20Element=20Plus=20=E8=AF=AD=E4=B9=89=E8=89=B2/?= =?UTF-8?q?=E5=9C=86=E8=A7=92=E5=AF=B9=E9=BD=90=E8=93=9D=E7=99=BD=E6=B5=85?= =?UTF-8?q?=E8=89=B2=EF=BC=88ep-overrides=20=E5=8D=95=E6=BA=90=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- admin-frontend-vue/src/styles/ep-overrides.ts | 35 +++++++++ admin-frontend-vue/src/styles/main.css | 11 ++- admin-frontend-vue/tests/task-242.test.ts | 72 +++++++++++++++++++ 3 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 admin-frontend-vue/src/styles/ep-overrides.ts create mode 100644 admin-frontend-vue/tests/task-242.test.ts diff --git a/admin-frontend-vue/src/styles/ep-overrides.ts b/admin-frontend-vue/src/styles/ep-overrides.ts new file mode 100644 index 00000000..a9dc3980 --- /dev/null +++ b/admin-frontend-vue/src/styles/ep-overrides.ts @@ -0,0 +1,35 @@ +/** + * Element Plus 主题对齐映射(module 13 task 242):把 Element 默认语义色/圆角 + * 对齐 admin.html 蓝白浅色皮肤。main.css 用 elCssVars() 的结果承载 --el-* 变量; + * tests 用本模块校验值正确且已落盘,防止 Element 默认红绿黄(#f56c6c/#67c23a/#e6a23c)回潮。 + */ +export const EP_ALIGN = { + primary: '#4f78a5', + success: '#4e806d', + warning: '#a8793e', + danger: '#b35f6a', + borderColor: '#d8e3ee', + borderRadiusBase: '9px', +} as const + +export type EpAlignKey = keyof typeof EP_ALIGN + +export function elCssVarName(key: EpAlignKey): string { + if (key === 'borderColor') return '--el-border-color' + if (key === 'borderRadiusBase') return '--el-border-radius-base' + return `--el-color-${key}` +} + +/** 需要落盘到 main.css 的 --el-* 变量(key -> CSS 值)。 */ +export function elCssVars(): Record { + const out: Record = {} + for (const key of Object.keys(EP_ALIGN) as EpAlignKey[]) { + out[elCssVarName(key)] = EP_ALIGN[key] + } + // danger/success/warning 的 light 家族 Element 不会自动从 base 推导覆盖, + // 显式对齐成浅色调(供标签/提示等底色使用),避免仍偏默认色。 + out['--el-color-success-light-9'] = '#eef5f0' + out['--el-color-warning-light-9'] = '#fbf4ea' + out['--el-color-danger-light-9'] = '#faf0f1' + return out +} diff --git a/admin-frontend-vue/src/styles/main.css b/admin-frontend-vue/src/styles/main.css index de7e9c83..582c76d7 100644 --- a/admin-frontend-vue/src/styles/main.css +++ b/admin-frontend-vue/src/styles/main.css @@ -16,7 +16,16 @@ --el-color-primary-light-8: #e1e9f0; --el-color-primary-light-9: #f0f4f8; --el-color-primary-dark-2: #3f628a; - --el-border-radius-base: 6px; + /* 语义色/边框/圆角对齐 admin.html 蓝白浅色皮肤(EP_ALIGN 单源,勿单独改) */ + --el-color-success: #4e806d; + --el-color-warning: #a8793e; + --el-color-danger: #b35f6a; + --el-color-success-light-9: #eef5f0; + --el-color-warning-light-9: #fbf4ea; + --el-color-danger-light-9: #faf0f1; + --el-border-color: #d8e3ee; + --el-border-color-base: #d8e3ee; + --el-border-radius-base: 9px; } * { box-sizing: border-box; } diff --git a/admin-frontend-vue/tests/task-242.test.ts b/admin-frontend-vue/tests/task-242.test.ts new file mode 100644 index 00000000..1968c24f --- /dev/null +++ b/admin-frontend-vue/tests/task-242.test.ts @@ -0,0 +1,72 @@ +import test from 'node:test' +import assert from 'node:assert/strict' +import { readSource } from './helpers.ts' +import { contrastRatio } from '../src/styles/theme.ts' +import { EP_ALIGN, elCssVarName, elCssVars } from '../src/styles/ep-overrides.ts' + +// module 13 task 242:Element Plus 全局语义色/圆角对齐 admin.html 蓝白浅色皮肤, +// 避免页面仍用 Element 默认红/绿/黄与默认边框。 + +test('test_task_242_ep_align_normal_primary_path', () => { + // 正常主路径:语义色命中 admin.html 蓝白基线。 + assert.equal(EP_ALIGN.primary, '#4f78a5') + assert.equal(EP_ALIGN.success, '#4e806d') + assert.equal(EP_ALIGN.warning, '#a8793e') + assert.equal(EP_ALIGN.danger, '#b35f6a') + assert.equal(EP_ALIGN.borderColor, '#d8e3ee') +}) + +test('test_task_242_ep_align_normal_variant_input', () => { + // 正常变体:CSS 变量名生成规则符合 --el-color-。 + assert.equal(elCssVarName('danger'), '--el-color-danger') + assert.equal(elCssVarName('success'), '--el-color-success') + assert.equal(elCssVarName('warning'), '--el-color-warning') +}) + +test('test_task_242_ep_align_normal_repeated_operation_is_idempotent', () => { + // 正常重复:变量映射幂等、可安全合并多次。 + const a = elCssVars() + const b = elCssVars() + assert.deepEqual(a, b) + assert.ok(Object.keys(a).length >= 5, '至少覆盖主色/成功/警告/危险/边框') +}) + +test('test_task_242_ep_align_boundary_empty_input', () => { + // 边界:全部 hex 合法、值与 Element 默认值不同(确认不是漏改的默认色)。 + for (const v of [EP_ALIGN.primary, EP_ALIGN.success, EP_ALIGN.warning, EP_ALIGN.danger, EP_ALIGN.borderColor]) { + assert.match(v, /^#[0-9a-fA-F]{6}$/) + } + assert.notEqual(EP_ALIGN.danger, '#f56c6c', 'danger 不应停留在 Element 默认红') + assert.notEqual(EP_ALIGN.success, '#67c23a', 'success 不应停留在 Element 默认绿') + assert.notEqual(EP_ALIGN.warning, '#e6a23c', 'warning 不应停留在 Element 默认黄') +}) + +test('test_task_242_ep_align_boundary_single_item', () => { + // 边界单元素:danger/success 在浅色内容底上满足按钮文本对比。 + const bg = '#ffffff' + assert.ok(contrastRatio('#ffffff', EP_ALIGN.danger) >= 3, '白字/危险渐变按钮需 ≥3') + assert.ok(contrastRatio(EP_ALIGN.success, bg) >= 3, '成功色可读') +}) + +test('test_task_242_ep_align_boundary_limit_or_missing_field', () => { + // 边界上限:圆角 token 有值;映射含边框变量。 + assert.ok(typeof EP_ALIGN.borderRadiusBase === 'string' && EP_ALIGN.borderRadiusBase.trim().length > 0) + assert.ok('--el-border-color' in elCssVars() || '--el-border-color-base' in elCssVars()) +}) + +test('test_task_242_ep_align_invalid_input_rejected', () => { + // 异常:main.css 必须落盘对齐后的语义色与圆角(readSource 交叉校验)。 + const css = readSource('src/styles/main.css') + for (const [name, value] of Object.entries(elCssVars())) { + assert.ok(css.includes(`${name}: ${value}`), `main.css 缺 ${name}: ${value}`) + } + assert.ok(css.includes('--el-border-radius-base: 9px'), '圆角应对齐 admin 9px') + assert.equal(/@import/.test(css), false) +}) + +test('test_task_242_ep_align_dependency_failure_returns_actionable_message', () => { + // 依赖失败:按钮/输入框等关键组件仍依赖 --el-* 变量(防硬编码 Element 默认色绕过主题)。 + const css = readSource('src/styles/main.css') + assert.ok(css.includes('--el-color-primary'), '主色变量需存在') + assert.ok(!/#f56c6c|#67c23a|#e6a23c/.test(css), 'main.css 不得残留 Element 默认红绿黄') +})