feat(admin): refine theme settings UI

This commit is contained in:
kate522 committed 2026-08-19 13:11:04 +08:00
1 parent 2e442e20ec
commit 8a738c7998
27 files changed
+425 -337

No files matched your search

+1
View File
@@ -20,6 +20,7 @@
!/tests/widget-system/toast-contract.test.cjs !/tests/widget-system/toast-contract.test.cjs
!/tests/widget-system/page-display-contract.test.cjs !/tests/widget-system/page-display-contract.test.cjs
!/tests/widget-system/page-display-save-harness.php !/tests/widget-system/page-display-save-harness.php
!/tests/widget-system/admin-ui-contract.test.cjs
!/tests/visual/docker-compose.zibll.yml !/tests/visual/docker-compose.zibll.yml
!/tests/visual/zibll-Caddyfile !/tests/visual/zibll-Caddyfile
!/tests/visual/README.md !/tests/visual/README.md
+109 -93
View File
@@ -1,22 +1,18 @@
<template> <template>
<n-config-provider :style-mount-target="styleMountTarget"> <n-config-provider
:style-mount-target="styleMountTarget"
:theme-overrides="adminThemeOverrides"
>
<n-message-provider> <n-message-provider>
<n-dialog-provider> <n-dialog-provider>
<n-notification-provider> <n-notification-provider>
<div v-if="!isMobile" class="aksrt-csf-shell"> <n-layout v-if="!isMobile" class="aksrt-admin-layout" has-sider>
<header class="aksrt-csf-header">
<div>
<h1>AKSRT主题设置 <small>页面与功能配置</small></h1>
<p>欢迎使用 AKSRT 主题</p>
</div>
<span class="aksrt-csf-version">V{{ themeVersion }}</span>
</header>
<n-layout class="aksrt-admin-layout" has-sider>
<n-layout-sider <n-layout-sider
class="aksrt-admin-sider"
bordered bordered
collapse-mode="width" collapse-mode="width"
:collapsed-width="64" :collapsed-width="64"
:width="240" :width="232"
show-collapse-trigger show-collapse-trigger
:collapsed="collapsed" :collapsed="collapsed"
:native-scrollbar="false" :native-scrollbar="false"
@@ -25,10 +21,14 @@
> >
<div class="aksrt-logo"> <div class="aksrt-logo">
<span class="logo-icon">AK</span> <span class="logo-icon">AK</span>
<span v-if="!collapsed" class="logo-text">AKSRT</span> <span v-if="!collapsed" class="aksrt-logo__copy">
<span class="logo-text">AKSRT</span>
<span class="aksrt-logo__version">v{{ themeVersion }}</span>
</span>
</div> </div>
<n-menu <n-menu
class="aksrt-admin-menu"
:value="activeMenuKey" :value="activeMenuKey"
:collapsed="collapsed" :collapsed="collapsed"
:collapsed-width="64" :collapsed-width="64"
@@ -55,7 +55,6 @@
</div> </div>
</n-layout> </n-layout>
</n-layout> </n-layout>
</div>
<div v-else class="aksrt-admin-mobile"> <div v-else class="aksrt-admin-mobile">
<MobileTopBar :title="currentPageTitle" @toggle="drawerActive = true" /> <MobileTopBar :title="currentPageTitle" @toggle="drawerActive = true" />
@@ -64,9 +63,13 @@
<n-drawer-content :native-scrollbar="false" body-content-style="padding:0;"> <n-drawer-content :native-scrollbar="false" body-content-style="padding:0;">
<div class="aksrt-logo aksrt-logo--drawer"> <div class="aksrt-logo aksrt-logo--drawer">
<span class="logo-icon">AK</span> <span class="logo-icon">AK</span>
<span class="logo-text">AKSRT</span> <span class="aksrt-logo__copy">
<span class="logo-text">AKSRT</span>
<span class="aksrt-logo__version">v{{ themeVersion }}</span>
</span>
</div> </div>
<n-menu <n-menu
class="aksrt-admin-menu"
:value="activeMenuKey" :value="activeMenuKey"
:options="menuOptions" :options="menuOptions"
@update:value="handleMenuClick" @update:value="handleMenuClick"
@@ -110,10 +113,63 @@ const collapsed = ref(false)
const pageError = ref(null) const pageError = ref(null)
const isMobile = ref(false) const isMobile = ref(false)
const drawerActive = ref(false) const drawerActive = ref(false)
const themeVersion = window.aksrtAdminData?.version || '9.0' const themeVersion = window.aksrtAdminData?.themeVersion || window.aksrtAdminData?.version || '9.0'
const MOBILE_BREAKPOINT = 960
const adminThemeOverrides = {
common: {
primaryColor: '#18A058',
primaryColorHover: '#36AD6A',
primaryColorPressed: '#0C7A43',
primaryColorSuppl: '#36AD6A',
bodyColor: '#F5F7F6',
cardColor: '#FFFFFF',
modalColor: '#FFFFFF',
popoverColor: '#FFFFFF',
textColorBase: '#1F2923',
textColor1: '#1F2923',
textColor2: '#465149',
textColor3: '#6F7A72',
borderColor: '#E2E8E3',
dividerColor: '#E2E8E3',
borderRadius: '8px',
borderRadiusSmall: '6px',
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif',
},
Button: {
borderRadiusMedium: '8px',
heightMedium: '36px',
fontWeight: '600',
},
Card: {
borderRadius: '12px',
borderColor: '#E2E8E3',
},
DataTable: {
thColor: '#F7F9F7',
thTextColor: '#465149',
tdColorHover: '#F7FBF8',
borderColor: '#E2E8E3',
},
Input: {
borderRadius: '8px',
heightMedium: '36px',
},
Menu: {
itemColorActive: '#EAF7EF',
itemColorActiveHover: '#EAF7EF',
itemColorHover: '#F2F8F4',
itemTextColorActive: '#168A4B',
itemTextColorActiveHover: '#168A4B',
itemTextColorHover: '#168A4B',
},
Switch: {
railColorActive: '#18A058',
},
}
function checkMobile() { function checkMobile() {
isMobile.value = window.innerWidth < 768 isMobile.value = window.innerWidth < MOBILE_BREAKPOINT
} }
onMounted(() => { onMounted(() => {
@@ -214,15 +270,15 @@ function handleMenuClick(key) {
.aksrt-logo { .aksrt-logo {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: flex-start;
height: 72px; height: 64px;
gap: 10px; gap: 11px;
border-bottom: 1px solid var(--n-border-color, #efeff5); padding: 0 18px;
border-bottom: 1px solid var(--aksrt-color-border);
} }
.aksrt-logo--drawer { .aksrt-logo--drawer {
justify-content: flex-start; height: 64px;
padding: 0 18px;
} }
.logo-icon { .logo-icon {
@@ -231,91 +287,45 @@ function handleMenuClick(key) {
justify-content: center; justify-content: center;
width: 28px; width: 28px;
height: 28px; height: 28px;
border-radius: 8px; flex: 0 0 28px;
background: linear-gradient(135deg, #65bff7 10%, #0d67b9 100%); border-radius: 7px;
background: var(--aksrt-color-primary);
color: #fff; color: #fff;
font-size: 12px; font-size: 12px;
font-weight: 700; font-weight: 700;
letter-spacing: 0.08em; letter-spacing: 0.08em;
} }
.aksrt-logo__copy {
display: flex;
align-items: baseline;
gap: 7px;
min-width: 0;
}
.logo-text { .logo-text {
font-size: 18px; font-size: 17px;
font-weight: 700; font-weight: 700;
color: #1a1a2e; color: var(--aksrt-color-text);
letter-spacing: 1px; letter-spacing: .08em;
}
.aksrt-logo__version {
color: var(--aksrt-color-muted);
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
font-size: 10px;
letter-spacing: .02em;
} }
.aksrt-admin-content__inner { .aksrt-admin-content__inner {
padding: 30px; width: 100%;
} max-width: 1236px;
margin: 0 auto;
.aksrt-csf-shell { padding: 26px 28px 42px;
max-width: 1380px;
margin: 20px auto;
overflow: hidden;
border-radius: 8px;
box-shadow: 0 0 20px rgba(82, 82, 82, .1);
}
.aksrt-csf-header {
position: relative;
display: flex;
min-height: 108px;
align-items: center;
justify-content: space-between;
overflow: hidden;
padding: 22px 34px;
color: #fff;
background: linear-gradient(135deg, #f97794 10%, #623aa2 100%);
}
.aksrt-csf-header::before {
position: absolute;
left: 10%;
bottom: -25px;
content: 'AKSRT';
color: rgba(255, 255, 255, .05);
font-size: 100px;
font-weight: 800;
font-style: oblique;
transform: rotate(-5deg) scaleX(1.5);
}
.aksrt-csf-header h1,
.aksrt-csf-header p {
position: relative;
z-index: 1;
margin: 0;
color: #fff;
}
.aksrt-csf-header h1 {
font-size: 26px;
}
.aksrt-csf-header h1 small {
margin-left: 8px;
font-size: 13px;
font-weight: 400;
}
.aksrt-csf-header p {
margin-top: 7px;
opacity: .78;
}
.aksrt-csf-version {
position: relative;
z-index: 1;
padding: 5px 12px;
border: 1px solid rgba(255, 255, 255, .3);
border-radius: 20px;
background: rgba(255, 255, 255, .1);
} }
.aksrt-admin-mobile { .aksrt-admin-mobile {
background: #f5f7fb; background: var(--aksrt-color-canvas);
min-height: 100vh; min-height: 100vh;
} }
@@ -343,4 +353,10 @@ function handleMenuClick(key) {
font-size: 13px; font-size: 13px;
color: #777; color: #777;
} }
@media (max-width: 1100px) {
.aksrt-admin-content__inner {
padding: 22px 20px 38px;
}
}
</style> </style>
+6 -6
View File
@@ -89,7 +89,7 @@ const resolvedFeatures = computed(() => {
} }
.aksrt-deferred-page__icon { .aksrt-deferred-page__icon {
color: #c0c4cc; color: var(--aksrt-color-border-strong);
margin-bottom: 20px; margin-bottom: 20px;
} }
@@ -97,13 +97,13 @@ const resolvedFeatures = computed(() => {
margin: 0 0 10px; margin: 0 0 10px;
font-size: 20px; font-size: 20px;
font-weight: 600; font-weight: 600;
color: #1a1a2e; color: var(--aksrt-color-text);
} }
.aksrt-deferred-page__desc { .aksrt-deferred-page__desc {
margin: 0 0 20px; margin: 0 0 20px;
font-size: 14px; font-size: 14px;
color: #8a909c; color: var(--aksrt-color-muted);
max-width: 400px; max-width: 400px;
line-height: 1.6; line-height: 1.6;
} }
@@ -126,7 +126,7 @@ const resolvedFeatures = computed(() => {
margin-bottom: 8px; margin-bottom: 8px;
font-size: 12px; font-size: 12px;
font-weight: 600; font-weight: 600;
color: #4b5563; color: var(--aksrt-color-text-secondary);
} }
.aksrt-deferred-page__depends-list { .aksrt-deferred-page__depends-list {
@@ -137,7 +137,7 @@ const resolvedFeatures = computed(() => {
.aksrt-deferred-page__reason p { .aksrt-deferred-page__reason p {
margin: 0; margin: 0;
color: #666; color: var(--aksrt-color-muted);
line-height: 1.7; line-height: 1.7;
} }
@@ -153,7 +153,7 @@ const resolvedFeatures = computed(() => {
align-items: center; align-items: center;
gap: 8px; gap: 8px;
font-size: 13px; font-size: 13px;
color: #666; color: var(--aksrt-color-muted);
} }
.aksrt-deferred-page__feature :deep(i) { .aksrt-deferred-page__feature :deep(i) {
+3 -3
View File
@@ -28,20 +28,20 @@ defineProps({
.aksrt-empty-state__icon { .aksrt-empty-state__icon {
margin-bottom: 20px; margin-bottom: 20px;
color: #c0c4cc; color: var(--aksrt-color-border-strong);
} }
.aksrt-empty-state__title { .aksrt-empty-state__title {
margin: 0 0 8px; margin: 0 0 8px;
font-size: 18px; font-size: 18px;
font-weight: 600; font-weight: 600;
color: #1a1a2e; color: var(--aksrt-color-text);
} }
.aksrt-empty-state__desc { .aksrt-empty-state__desc {
margin: 0; margin: 0;
font-size: 13px; font-size: 13px;
color: #7a7f8a; color: var(--aksrt-color-muted);
max-width: 360px; max-width: 360px;
line-height: 1.65; line-height: 1.65;
} }
+6 -6
View File
@@ -34,8 +34,8 @@ defineEmits(['toggle'])
gap: 10px; gap: 10px;
height: 48px; height: 48px;
padding: 0 14px; padding: 0 14px;
background: #fff; background: var(--aksrt-color-surface);
border-bottom: 1px solid #eceff5; border-bottom: 1px solid var(--aksrt-color-border);
position: sticky; position: sticky;
top: 0; top: 0;
z-index: 50; z-index: 50;
@@ -50,20 +50,20 @@ defineEmits(['toggle'])
border: none; border: none;
border-radius: 8px; border-radius: 8px;
background: transparent; background: transparent;
color: #1a1a2e; color: var(--aksrt-color-text);
cursor: pointer; cursor: pointer;
margin-left: -6px; margin-left: -6px;
} }
.aksrt-mobile-topbar__menu:hover { .aksrt-mobile-topbar__menu:hover {
background: #f3f5f9; background: var(--aksrt-color-primary-soft);
} }
.aksrt-mobile-topbar__title { .aksrt-mobile-topbar__title {
flex: 1 1 auto; flex: 1 1 auto;
font-size: 15px; font-size: 15px;
font-weight: 600; font-weight: 600;
color: #1a1a2e; color: var(--aksrt-color-text);
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
@@ -77,7 +77,7 @@ defineEmits(['toggle'])
width: 28px; width: 28px;
height: 28px; height: 28px;
border-radius: 8px; border-radius: 8px;
background: #18a058; background: var(--aksrt-color-primary);
color: #fff; color: #fff;
font-size: 11px; font-size: 11px;
font-weight: 700; font-weight: 700;
@@ -105,7 +105,7 @@ const callbackUrl = computed(() => {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
background: #f7f8fa; background: var(--aksrt-color-canvas);
border-radius: 12px; border-radius: 12px;
} }
@@ -118,19 +118,19 @@ const callbackUrl = computed(() => {
.oauth-platform-text { .oauth-platform-text {
font-size: 20px; font-size: 20px;
font-weight: 700; font-weight: 700;
color: #666; color: var(--aksrt-color-muted);
} }
.oauth-platform-info h4 { .oauth-platform-info h4 {
font-size: 16px; font-size: 16px;
font-weight: 600; font-weight: 600;
color: #1a1a2e; color: var(--aksrt-color-text);
margin-bottom: 2px; margin-bottom: 2px;
} }
.oauth-doc-link { .oauth-doc-link {
font-size: 12px; font-size: 12px;
color: #1565c0; color: var(--aksrt-color-primary);
text-decoration: none; text-decoration: none;
} }
.oauth-doc-link:hover { .oauth-doc-link:hover {
@@ -145,7 +145,7 @@ const callbackUrl = computed(() => {
/* 表单体 */ /* 表单体 */
.oauth-form-body { .oauth-form-body {
padding-top: 8px; padding-top: 8px;
border-top: 1px solid #f0f0f5; border-top: 1px solid var(--aksrt-color-border);
} }
.oauth-form-grid :deep(.n-form-item) { .oauth-form-grid :deep(.n-form-item) {
@@ -159,6 +159,6 @@ const callbackUrl = computed(() => {
} }
.oauth-disabled-hint p { .oauth-disabled-hint p {
font-size: 13px; font-size: 13px;
color: #bbb; color: var(--aksrt-color-border-strong);
} }
</style> </style>
+2 -2
View File
@@ -39,7 +39,7 @@ defineProps({
.aksrt-page-header__title { .aksrt-page-header__title {
margin: 0 0 6px; margin: 0 0 6px;
color: #1a1a2e; color: var(--aksrt-color-text);
font-size: 22px; font-size: 22px;
font-weight: 700; font-weight: 700;
letter-spacing: -0.02em; letter-spacing: -0.02em;
@@ -48,7 +48,7 @@ defineProps({
.aksrt-page-header__desc { .aksrt-page-header__desc {
margin: 0; margin: 0;
color: #7a7f8a; color: var(--aksrt-color-muted);
font-size: 13px; font-size: 13px;
line-height: 1.65; line-height: 1.65;
} }
+37 -37
View File
@@ -1019,7 +1019,7 @@ function confirmRepeaterModal() {
.aksrt-field__label { .aksrt-field__label {
font-size: 13px; font-size: 13px;
font-weight: 500; font-weight: 500;
color: #555; color: var(--aksrt-color-text-secondary);
} }
.aksrt-field__required { .aksrt-field__required {
@@ -1028,19 +1028,19 @@ function confirmRepeaterModal() {
} }
.aksrt-field__help-icon { .aksrt-field__help-icon {
color: #c0c4cc; color: var(--aksrt-color-border-strong);
cursor: help; cursor: help;
transition: color 0.15s; transition: color 0.15s;
} }
.aksrt-field__help-icon:hover { .aksrt-field__help-icon:hover {
color: #1890ff; color: var(--aksrt-color-primary);
} }
.aksrt-field__desc { .aksrt-field__desc {
margin: -2px 0 8px; margin: -2px 0 8px;
font-size: 12px; font-size: 12px;
color: #8a909c; color: var(--aksrt-color-muted);
line-height: 1.5; line-height: 1.5;
} }
@@ -1063,7 +1063,7 @@ function confirmRepeaterModal() {
} }
.aksrt-field__dimensions-sep { .aksrt-field__dimensions-sep {
color: #c0c4cc; color: var(--aksrt-color-border-strong);
font-size: 14px; font-size: 14px;
} }
@@ -1077,7 +1077,7 @@ function confirmRepeaterModal() {
.aksrt-field__spacing-label { .aksrt-field__spacing-label {
font-size: 12px; font-size: 12px;
color: #8a909c; color: var(--aksrt-color-muted);
text-align: center; text-align: center;
} }
@@ -1096,7 +1096,7 @@ function confirmRepeaterModal() {
.aksrt-field__sublabel { .aksrt-field__sublabel {
font-size: 12px; font-size: 12px;
color: #8a909c; color: var(--aksrt-color-muted);
min-width: 70px; min-width: 70px;
} }
@@ -1113,7 +1113,7 @@ function confirmRepeaterModal() {
align-items: center; align-items: center;
gap: 6px; gap: 6px;
padding: 8px; padding: 8px;
border: 2px solid #eef1f6; border: 2px solid var(--aksrt-color-border);
border-radius: 8px; border-radius: 8px;
cursor: pointer; cursor: pointer;
transition: all 0.2s; transition: all 0.2s;
@@ -1121,12 +1121,12 @@ function confirmRepeaterModal() {
} }
.aksrt-field__image-select-item:hover { .aksrt-field__image-select-item:hover {
border-color: #1890ff; border-color: var(--aksrt-color-primary);
} }
.aksrt-field__image-select-item--active { .aksrt-field__image-select-item--active {
border-color: #1890ff; border-color: var(--aksrt-color-primary);
background: #e6f7ff; background: var(--aksrt-color-primary-soft);
} }
.aksrt-field__image-select-img { .aksrt-field__image-select-img {
@@ -1142,14 +1142,14 @@ function confirmRepeaterModal() {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
background: #f5f7fb; background: var(--aksrt-color-canvas);
border-radius: 4px; border-radius: 4px;
color: #c0c4cc; color: var(--aksrt-color-border-strong);
} }
.aksrt-field__image-select-label { .aksrt-field__image-select-label {
font-size: 11px; font-size: 11px;
color: #555; color: var(--aksrt-color-text-secondary);
text-align: center; text-align: center;
} }
@@ -1165,12 +1165,12 @@ function confirmRepeaterModal() {
padding: 0; padding: 0;
border: 3px solid #fff; border: 3px solid #fff;
border-radius: 3px; border-radius: 3px;
box-shadow: 0 0 0 1px #d8d8d8; box-shadow: 0 0 0 1px var(--aksrt-color-border-strong);
cursor: pointer; cursor: pointer;
} }
.aksrt-field__palette-item.is-active { .aksrt-field__palette-item.is-active {
box-shadow: 0 0 0 2px #2f8fce; box-shadow: 0 0 0 2px var(--aksrt-color-primary);
} }
.aksrt-field__link { .aksrt-field__link {
@@ -1195,14 +1195,14 @@ function confirmRepeaterModal() {
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
padding: 5px 9px; padding: 5px 9px;
border: 1px solid #e6e8eb; border: 1px solid var(--aksrt-color-border);
border-radius: 3px; border-radius: 3px;
background: #fafafa; background: var(--aksrt-color-canvas);
} }
.aksrt-field__sortable-item { .aksrt-field__sortable-item {
border: 1px solid #e5e5e5; border: 1px solid var(--aksrt-color-border);
background: #fff; background: var(--aksrt-color-surface);
} }
.aksrt-field__sortable-head { .aksrt-field__sortable-head {
@@ -1210,7 +1210,7 @@ function confirmRepeaterModal() {
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
padding: 10px 12px; padding: 10px 12px;
background: #f7f7f7; background: var(--aksrt-color-canvas);
cursor: move; cursor: move;
} }
@@ -1224,9 +1224,9 @@ function confirmRepeaterModal() {
/* Repeater */ /* Repeater */
.aksrt-field__fieldset { .aksrt-field__fieldset {
padding: 14px; padding: 14px;
border: 1px solid #eef1f6; border: 1px solid var(--aksrt-color-border);
border-radius: 8px; border-radius: 8px;
background: #fafbfc; background: var(--aksrt-color-canvas);
} }
.aksrt-field__repeater { .aksrt-field__repeater {
@@ -1236,10 +1236,10 @@ function confirmRepeaterModal() {
} }
.aksrt-field__repeater-item { .aksrt-field__repeater-item {
border: 1px solid #eef1f6; border: 1px solid var(--aksrt-color-border);
border-radius: 8px; border-radius: 8px;
padding: 12px; padding: 12px;
background: #fafbfc; background: var(--aksrt-color-canvas);
} }
.aksrt-field__repeater-header { .aksrt-field__repeater-header {
@@ -1252,7 +1252,7 @@ function confirmRepeaterModal() {
.aksrt-field__repeater-index { .aksrt-field__repeater-index {
font-size: 12px; font-size: 12px;
font-weight: 600; font-weight: 600;
color: #1890ff; color: var(--aksrt-color-primary);
} }
.aksrt-field__repeater-fields { .aksrt-field__repeater-fields {
@@ -1264,7 +1264,7 @@ function confirmRepeaterModal() {
/* Content field */ /* Content field */
.aksrt-field__content { .aksrt-field__content {
font-size: 13px; font-size: 13px;
color: #555; color: var(--aksrt-color-text-secondary);
line-height: 1.6; line-height: 1.6;
} }
@@ -1307,9 +1307,9 @@ function confirmRepeaterModal() {
align-items: center; align-items: center;
gap: 12px; gap: 12px;
padding: 10px 12px; padding: 10px 12px;
border: 1px solid #eef1f6; border: 1px solid var(--aksrt-color-border);
border-radius: 8px; border-radius: 8px;
background: #fafbfc; background: var(--aksrt-color-canvas);
} }
.aksrt-field__repeater-list-actions { .aksrt-field__repeater-list-actions {
@@ -1335,8 +1335,8 @@ function confirmRepeaterModal() {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
background: #eef3ff; background: var(--aksrt-color-primary-soft);
color: #3b82f6; color: var(--aksrt-color-primary);
flex-shrink: 0; flex-shrink: 0;
overflow: hidden; overflow: hidden;
font-size: 16px; font-size: 16px;
@@ -1365,7 +1365,7 @@ function confirmRepeaterModal() {
.aksrt-field__repeater-list-title { .aksrt-field__repeater-list-title {
font-size: 13px; font-size: 13px;
font-weight: 600; font-weight: 600;
color: #1f2329; color: var(--aksrt-color-text);
line-height: 1.35; line-height: 1.35;
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
@@ -1375,7 +1375,7 @@ function confirmRepeaterModal() {
.aksrt-field__repeater-list-desc { .aksrt-field__repeater-list-desc {
margin-top: 2px; margin-top: 2px;
font-size: 12px; font-size: 12px;
color: #8a909c; color: var(--aksrt-color-muted);
line-height: 1.4; line-height: 1.4;
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
@@ -1388,11 +1388,11 @@ function confirmRepeaterModal() {
align-items: center; align-items: center;
gap: 8px; gap: 8px;
padding: 22px 12px; padding: 22px 12px;
color: #c0c4cc; color: var(--aksrt-color-border-strong);
font-size: 13px; font-size: 13px;
border: 1px dashed #e5e7eb; border: 1px dashed var(--aksrt-color-border);
border-radius: 8px; border-radius: 8px;
background: #fcfcfd; background: var(--aksrt-color-canvas);
} }
.aksrt-field__repeater-modal-fields { .aksrt-field__repeater-modal-fields {
@@ -1410,7 +1410,7 @@ function confirmRepeaterModal() {
gap: 8px; gap: 8px;
margin-top: 16px; margin-top: 16px;
padding-top: 12px; padding-top: 12px;
border-top: 1px solid #eef1f6; border-top: 1px solid var(--aksrt-color-border);
} }
</style> </style>
@@ -72,9 +72,10 @@ function toggleCollapse() {
<style scoped> <style scoped>
.aksrt-field-group { .aksrt-field-group {
margin-bottom: 20px; margin-bottom: 20px;
border: 1px solid #eef1f6; border: 1px solid var(--aksrt-color-border);
border-radius: 12px; border-radius: 12px;
background: #fff; background: var(--aksrt-color-surface);
box-shadow: var(--aksrt-shadow-card);
overflow: hidden; overflow: hidden;
} }
@@ -92,7 +93,7 @@ function toggleCollapse() {
} }
.aksrt-field-group__header.is-clickable:hover .aksrt-field-group__title { .aksrt-field-group__header.is-clickable:hover .aksrt-field-group__title {
color: #1890ff; color: var(--aksrt-color-primary);
} }
.aksrt-field-group.is-collapsed .aksrt-field-group__header { .aksrt-field-group.is-collapsed .aksrt-field-group__header {
@@ -114,7 +115,7 @@ function toggleCollapse() {
} }
.aksrt-field-group__icon { .aksrt-field-group__icon {
color: #1890ff; color: var(--aksrt-color-primary);
margin-top: 2px; margin-top: 2px;
} }
@@ -122,14 +123,14 @@ function toggleCollapse() {
margin: 0; margin: 0;
font-size: 15px; font-size: 15px;
font-weight: 600; font-weight: 600;
color: #1a1a2e; color: var(--aksrt-color-text);
transition: color 0.15s; transition: color 0.15s;
} }
.aksrt-field-group__desc { .aksrt-field-group__desc {
margin: 4px 0 0; margin: 4px 0 0;
font-size: 12px; font-size: 12px;
color: #8a909c; color: var(--aksrt-color-muted);
line-height: 1.5; line-height: 1.5;
} }
@@ -143,9 +144,9 @@ function toggleCollapse() {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
gap: 6px; gap: 6px;
border: 1px solid #e8ecf2; border: 1px solid var(--aksrt-color-border);
background: #f7f9fc; background: var(--aksrt-color-canvas);
color: #5c6370; color: var(--aksrt-color-text-secondary);
border-radius: 999px; border-radius: 999px;
padding: 4px 10px; padding: 4px 10px;
font-size: 12px; font-size: 12px;
@@ -154,9 +155,9 @@ function toggleCollapse() {
} }
.aksrt-field-group__collapse-btn:hover { .aksrt-field-group__collapse-btn:hover {
color: #1890ff; color: var(--aksrt-color-primary);
border-color: #91caff; border-color: var(--aksrt-color-primary);
background: #f0f7ff; background: var(--aksrt-color-primary-soft);
} }
.aksrt-field-group__body { .aksrt-field-group__body {
@@ -292,7 +292,7 @@ const filteredSchema = computed(() => {
} }
.aksrt-form-renderer__header-icon { .aksrt-form-renderer__header-icon {
color: #1890ff; color: var(--aksrt-color-primary);
margin-top: 4px; margin-top: 4px;
} }
@@ -300,14 +300,14 @@ const filteredSchema = computed(() => {
margin: 0; margin: 0;
font-size: 22px; font-size: 22px;
font-weight: 700; font-weight: 700;
color: #1a1a2e; color: var(--aksrt-color-text);
letter-spacing: -0.02em; letter-spacing: -0.02em;
} }
.aksrt-form-renderer__desc { .aksrt-form-renderer__desc {
margin: 4px 0 0; margin: 4px 0 0;
font-size: 13px; font-size: 13px;
color: #7a7f8a; color: var(--aksrt-color-muted);
line-height: 1.6; line-height: 1.6;
} }
@@ -322,7 +322,7 @@ const filteredSchema = computed(() => {
align-items: center; align-items: center;
gap: 12px; gap: 12px;
padding: 60px 0; padding: 60px 0;
color: #8a909c; color: var(--aksrt-color-muted);
font-size: 14px; font-size: 14px;
} }
@@ -332,7 +332,7 @@ const filteredSchema = computed(() => {
align-items: center; align-items: center;
gap: 12px; gap: 12px;
padding: 60px 0; padding: 60px 0;
color: #c0c4cc; color: var(--aksrt-color-border-strong);
} }
.aksrt-form-renderer__empty p { .aksrt-form-renderer__empty p {
@@ -347,9 +347,9 @@ const filteredSchema = computed(() => {
left: 0; left: 0;
right: 0; right: 0;
z-index: 1000; z-index: 1000;
background: #fff; background: var(--aksrt-color-surface);
border-top: 1px solid #eef1f6; border-top: 1px solid var(--aksrt-color-border);
box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.06); box-shadow: var(--aksrt-shadow-floating);
animation: slideUp 0.2s ease; animation: slideUp 0.2s ease;
} }
@@ -99,7 +99,7 @@ function clearMedia() {
position: relative; position: relative;
border-radius: 8px; border-radius: 8px;
overflow: hidden; overflow: hidden;
border: 1px solid #eef1f6; border: 1px solid var(--aksrt-color-border);
margin-bottom: 8px; margin-bottom: 8px;
} }
@@ -115,12 +115,12 @@ function clearMedia() {
align-items: center; align-items: center;
gap: 8px; gap: 8px;
padding: 16px; padding: 16px;
background: #f8fafc; background: var(--aksrt-color-canvas);
} }
.aksrt-media-field__filename { .aksrt-media-field__filename {
font-size: 13px; font-size: 13px;
color: #555; color: var(--aksrt-color-text-secondary);
word-break: break-all; word-break: break-all;
} }
@@ -146,19 +146,19 @@ function clearMedia() {
justify-content: center; justify-content: center;
gap: 8px; gap: 8px;
padding: 32px; padding: 32px;
border: 2px dashed #d9dce3; border: 2px dashed var(--aksrt-color-border-strong);
border-radius: 8px; border-radius: 8px;
cursor: pointer; cursor: pointer;
color: #8a909c; color: var(--aksrt-color-muted);
font-size: 13px; font-size: 13px;
transition: all 0.2s; transition: all 0.2s;
margin-bottom: 8px; margin-bottom: 8px;
} }
.aksrt-media-field__empty:hover { .aksrt-media-field__empty:hover {
border-color: #1890ff; border-color: var(--aksrt-color-primary);
color: #1890ff; color: var(--aksrt-color-primary);
background: #f0f7ff; background: var(--aksrt-color-primary-soft);
} }
.aksrt-media-field__url { .aksrt-media-field__url {
@@ -136,10 +136,10 @@ function updateField(index, key, value) {
} }
.aksrt-repeater__item { .aksrt-repeater__item {
border: 1px solid #eef1f6; border: 1px solid var(--aksrt-color-border);
border-radius: 8px; border-radius: 8px;
padding: 12px; padding: 12px;
background: #fafbfc; background: var(--aksrt-color-canvas);
} }
.aksrt-repeater__item-header { .aksrt-repeater__item-header {
@@ -152,8 +152,8 @@ function updateField(index, key, value) {
.aksrt-repeater__item-index { .aksrt-repeater__item-index {
font-size: 12px; font-size: 12px;
font-weight: 600; font-weight: 600;
color: #1890ff; color: var(--aksrt-color-primary);
background: #e6f4ff; background: var(--aksrt-color-primary-soft);
padding: 2px 8px; padding: 2px 8px;
border-radius: 4px; border-radius: 4px;
} }
@@ -175,7 +175,7 @@ function updateField(index, key, value) {
align-items: center; align-items: center;
gap: 8px; gap: 8px;
padding: 24px; padding: 24px;
color: #c0c4cc; color: var(--aksrt-color-border-strong);
font-size: 13px; font-size: 13px;
} }
@@ -193,17 +193,17 @@ function selectIcon(icon) {
border-radius: 6px; border-radius: 6px;
cursor: pointer; cursor: pointer;
font-size: 16px; font-size: 16px;
color: #555; color: var(--aksrt-color-text-secondary);
transition: all 0.15s; transition: all 0.15s;
} }
.aksrt-icon-picker__item:hover { .aksrt-icon-picker__item:hover {
background: #f0f5ff; background: var(--aksrt-color-primary-soft);
color: #1890ff; color: var(--aksrt-color-primary);
} }
.aksrt-icon-picker__item.is-active { .aksrt-icon-picker__item.is-active {
background: #1890ff; background: var(--aksrt-color-primary);
color: #fff; color: #fff;
} }
@@ -211,7 +211,7 @@ function selectIcon(icon) {
grid-column: 1 / -1; grid-column: 1 / -1;
text-align: center; text-align: center;
padding: 20px; padding: 20px;
color: #999; color: var(--aksrt-color-muted);
font-size: 13px; font-size: 13px;
} }
</style> </style>
+2 -2
View File
@@ -80,7 +80,7 @@
<n-spin /> <n-spin />
<p style="margin-top:10px;color:#999;">加载中...</p> <p style="margin-top:10px;color:#999;">加载中...</p>
</div> </div>
<div v-if="testResult && !testLoading" :style="{color: testResult.success ? '#18a058' : '#d03050', textAlign:'center', padding:'20px'}"> <div v-if="testResult && !testLoading" :style="{color: testResult.success ? 'var(--aksrt-color-primary)' : '#d03050', textAlign:'center', padding:'20px'}">
<p style="font-size:16px;margin:0;">{{ testResult.message }}</p> <p style="font-size:16px;margin:0;">{{ testResult.message }}</p>
</div> </div>
<div v-if="!testLoading && !testResult" id="captcha-test-box" style="min-height:150px;"></div> <div v-if="!testLoading && !testResult" id="captcha-test-box" style="min-height:150px;"></div>
@@ -462,7 +462,7 @@ onBeforeUnmount(() => {
.aksrt-schema-page__field-hint { .aksrt-schema-page__field-hint {
margin: 8px 0 0; margin: 8px 0 0;
font-size: 12px; font-size: 12px;
color: #8a909c; color: var(--aksrt-color-muted);
} }
.captcha-test-overlay { .captcha-test-overlay {
@@ -733,7 +733,7 @@ onMounted(loadSettings)
align-items: center; align-items: center;
justify-content: center; justify-content: center;
background: rgba(24, 160, 88, 0.12); background: rgba(24, 160, 88, 0.12);
color: #18a058; color: var(--aksrt-color-primary);
font-size: 18px; font-size: 18px;
flex: 0 0 auto; flex: 0 0 auto;
} }
+7 -7
View File
@@ -95,7 +95,7 @@ const themeVersion = ref(window.aksrtAdminData?.themeVersion || '3.4.0-dev')
const dbSchemaVersion = ref('—') const dbSchemaVersion = ref('—')
const docs = ref([ const docs = ref([
{ key: 'admin-ia-map', title: '后台 IA 蓝图', description: '完整的后台信息架构映射,12 个顶级分区及子页面清单。', icon: 'fa fas fa-sitemap', color: '#1890ff', file: 'admin-ia-map.md' }, { key: 'admin-ia-map', title: '后台 IA 蓝图', description: '完整的后台信息架构映射,12 个顶级分区及子页面清单。', icon: 'fa fas fa-sitemap', color: 'var(--aksrt-color-primary)', file: 'admin-ia-map.md' },
{ key: 'zibll-gap-matrix', title: '对标差异矩阵', description: 'AKSRT 当前 → Zibll 参考 → AKSRT 目标三层对照表。', icon: 'fa fas fa-columns', color: '#722ed1', file: 'zibll-gap-matrix.md' }, { key: 'zibll-gap-matrix', title: '对标差异矩阵', description: 'AKSRT 当前 → Zibll 参考 → AKSRT 目标三层对照表。', icon: 'fa fas fa-columns', color: '#722ed1', file: 'zibll-gap-matrix.md' },
{ key: 'frontend-page-matrix', title: '前端页面矩阵', description: '前端模板、CSS、JS 资产映射与覆盖范围。', icon: 'fa fas fa-desktop', color: '#13c2c2', file: 'frontend-page-matrix.md' }, { key: 'frontend-page-matrix', title: '前端页面矩阵', description: '前端模板、CSS、JS 资产映射与覆盖范围。', icon: 'fa fas fa-desktop', color: '#13c2c2', file: 'frontend-page-matrix.md' },
{ key: 'manual-acceptance-baseline', title: '验收基线', description: '每个 Phase 的人工验收标准和检查清单。', icon: 'fa fas fa-clipboard', color: '#52c41a', file: 'manual-acceptance-baseline.md' }, { key: 'manual-acceptance-baseline', title: '验收基线', description: '每个 Phase 的人工验收标准和检查清单。', icon: 'fa fas fa-clipboard', color: '#52c41a', file: 'manual-acceptance-baseline.md' },
@@ -164,13 +164,13 @@ function openDoc(doc) {
margin: 0 0 2px; margin: 0 0 2px;
font-size: 14px; font-size: 14px;
font-weight: 600; font-weight: 600;
color: #1a1a2e; color: var(--aksrt-color-text);
} }
.aksrt-docs__card-desc { .aksrt-docs__card-desc {
margin: 0; margin: 0;
font-size: 12px; font-size: 12px;
color: #8a909c; color: var(--aksrt-color-muted);
line-height: 1.5; line-height: 1.5;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
@@ -196,26 +196,26 @@ function openDoc(doc) {
} }
.aksrt-docs__action i { .aksrt-docs__action i {
color: #1890ff; color: var(--aksrt-color-primary);
margin-top: 2px; margin-top: 2px;
} }
.aksrt-docs__action strong { .aksrt-docs__action strong {
display: block; display: block;
font-size: 14px; font-size: 14px;
color: #1a1a2e; color: var(--aksrt-color-text);
margin-bottom: 2px; margin-bottom: 2px;
} }
.aksrt-docs__action p { .aksrt-docs__action p {
margin: 0 0 4px; margin: 0 0 4px;
font-size: 12px; font-size: 12px;
color: #8a909c; color: var(--aksrt-color-muted);
} }
.aksrt-docs__action a { .aksrt-docs__action a {
font-size: 12px; font-size: 12px;
color: #1890ff; color: var(--aksrt-color-primary);
text-decoration: none; text-decoration: none;
} }
@@ -276,7 +276,7 @@ export default {
.aksrt-ai__status-icon--warn { background: #fff3cd; color: #856404; } .aksrt-ai__status-icon--warn { background: #fff3cd; color: #856404; }
.aksrt-ai__status-icon--off { background: #f8d7da; color: #721c24; } .aksrt-ai__status-icon--off { background: #f8d7da; color: #721c24; }
.aksrt-ai__status-icon--info { background: #d1ecf1; color: #0c5460; } .aksrt-ai__status-icon--info { background: #d1ecf1; color: #0c5460; }
.aksrt-ai__status-value { font-size: 18px; font-weight: 600; color: #1a1a2e; } .aksrt-ai__status-value { font-size: 18px; font-weight: 600; color: var(--aksrt-color-text); }
.aksrt-ai__status-label { font-size: 12px; color: #888; } .aksrt-ai__status-label { font-size: 12px; color: #888; }
.aksrt-ai__form-card { .aksrt-ai__form-card {
background: #fff; background: #fff;
@@ -85,20 +85,20 @@ const router = useRouter()
const message = useMessage() const message = useMessage()
const healthItems = ref([ const healthItems = ref([
{ key: 'php', icon: 'fa fas fa-code', color: '#1890ff', value: '—', label: 'PHP 版本', status: 'ok' }, { key: 'php', icon: 'fa fas fa-code', color: 'var(--aksrt-color-primary)', value: '—', label: 'PHP 版本', status: 'ok' },
{ key: 'wp', icon: 'fa fab fa-wordpress', color: '#722ed1', value: '—', label: 'WordPress', status: 'ok' }, { key: 'wp', icon: 'fa fab fa-wordpress', color: '#722ed1', value: '—', label: 'WordPress', status: 'ok' },
{ key: 'db', icon: 'fa fas fa-database', color: '#52c41a', value: '—', label: '数据库', status: 'ok' }, { key: 'db', icon: 'fa fas fa-database', color: '#52c41a', value: '—', label: '数据库', status: 'ok' },
{ key: 'uploads', icon: 'fa fas fa-folder-open', color: '#fa8c16', value: '—', label: '上传目录', status: 'ok' }, { key: 'uploads', icon: 'fa fas fa-folder-open', color: '#fa8c16', value: '—', label: '上传目录', status: 'ok' },
]) ])
const tools = ref([ const tools = ref([
{ key: 'import-export', icon: 'fa fas fa-exchange-alt', bg: '#1890ff', title: '导入导出', desc: '设置导入、导出和重置', route: '/tools/import-export' }, { key: 'import-export', icon: 'fa fas fa-exchange-alt', bg: 'var(--aksrt-color-primary)', title: '导入导出', desc: '设置导入、导出和重置', route: '/tools/import-export' },
{ key: 'health', icon: 'fa fas fa-heartbeat', bg: '#52c41a', title: '健康检查', desc: '系统状态检测和诊断', route: '/tools/health' }, { key: 'health', icon: 'fa fas fa-heartbeat', bg: '#52c41a', title: '健康检查', desc: '系统状态检测和诊断', route: '/tools/health' },
{ key: 'email-rollback', icon: 'fa fas fa-undo', bg: '#fa8c16', title: '邮箱回滚', desc: '邮箱变更 14 天内回滚', route: '/tools/email-rollback' }, { key: 'email-rollback', icon: 'fa fas fa-undo', bg: '#fa8c16', title: '邮箱回滚', desc: '邮箱变更 14 天内回滚', route: '/tools/email-rollback' },
]) ])
const services = ref([ const services = ref([
{ key: 'sms', icon: 'fa fas fa-comment', color: '#1890ff', name: '短信服务', description: '验证码和通知短信', available: false }, { key: 'sms', icon: 'fa fas fa-comment', color: 'var(--aksrt-color-primary)', name: '短信服务', description: '验证码和通知短信', available: false },
{ key: 'wechat', icon: 'fa fab fa-weixin', color: '#52c41a', name: '微信通知', description: '微信模板消息和订阅通知', available: false }, { key: 'wechat', icon: 'fa fab fa-weixin', color: '#52c41a', name: '微信通知', description: '微信模板消息和订阅通知', available: false },
{ key: 'captcha', icon: 'fa fas fa-shield-alt', color: '#722ed1', name: '验证码服务', description: '人机验证(极验/腾讯/阿里云)', available: false }, { key: 'captcha', icon: 'fa fas fa-shield-alt', color: '#722ed1', name: '验证码服务', description: '人机验证(极验/腾讯/阿里云)', available: false },
{ key: 'push', icon: 'fa fas fa-paper-plane', color: '#fa8c16', name: '搜索引擎推送', description: '百度/Google 主动推送', available: false }, { key: 'push', icon: 'fa fas fa-paper-plane', color: '#fa8c16', name: '搜索引擎推送', description: '百度/Google 主动推送', available: false },
@@ -210,13 +210,13 @@ async function handleRebuildIndex() {
.aksrt-tools__health-card strong { .aksrt-tools__health-card strong {
display: block; display: block;
font-size: 14px; font-size: 14px;
color: #1a1a2e; color: var(--aksrt-color-text);
} }
.aksrt-tools__health-card p { .aksrt-tools__health-card p {
margin: 2px 0 0; margin: 2px 0 0;
font-size: 12px; font-size: 12px;
color: #8a909c; color: var(--aksrt-color-muted);
} }
.aksrt-tools__health-card--warn { .aksrt-tools__health-card--warn {
@@ -237,7 +237,7 @@ async function handleRebuildIndex() {
} }
.aksrt-tools__tool-card:hover { .aksrt-tools__tool-card:hover {
border-color: #1890ff; border-color: var(--aksrt-color-primary);
box-shadow: 0 2px 8px rgba(24, 144, 255, 0.1); box-shadow: 0 2px 8px rgba(24, 144, 255, 0.1);
} }
@@ -259,12 +259,12 @@ async function handleRebuildIndex() {
.aksrt-tools__tool-body strong { .aksrt-tools__tool-body strong {
display: block; display: block;
font-size: 14px; font-size: 14px;
color: #1a1a2e; color: var(--aksrt-color-text);
} }
.aksrt-tools__tool-body p { .aksrt-tools__tool-body p {
margin: 2px 0 0; margin: 2px 0 0;
font-size: 12px; font-size: 12px;
color: #8a909c; color: var(--aksrt-color-muted);
} }
</style> </style>
@@ -101,25 +101,25 @@ onMounted(async () => {
align-items: center; align-items: center;
justify-content: center; justify-content: center;
background: var(--surface-3, #f0f0f0); background: var(--surface-3, #f0f0f0);
color: var(--color-ink-4, #8a909c); color: var(--aksrt-color-muted);
font-size: 16px; font-size: 16px;
} }
.aksrt-gateway__icon--active { .aksrt-gateway__icon--active {
background: var(--color-primary-soft, #f0f5ff); background: var(--color-primary-soft, #f0f5ff);
color: var(--color-primary, #1890ff); color: var(--aksrt-color-primary);
} }
.aksrt-gateway__card strong { .aksrt-gateway__card strong {
display: block; display: block;
font-size: 14px; font-size: 14px;
color: var(--color-ink, #1a1a2e); color: var(--aksrt-color-text);
} }
.aksrt-gateway__card p { .aksrt-gateway__card p {
margin: 2px 0 0; margin: 2px 0 0;
font-size: 12px; font-size: 12px;
color: var(--color-ink-4, #8a909c); color: var(--aksrt-color-muted);
} }
.aksrt-gateway__help { .aksrt-gateway__help {
@@ -209,13 +209,13 @@ onMounted(loadRevenue)
display: block; display: block;
font-size: 24px; font-size: 24px;
font-weight: 600; font-weight: 600;
color: var(--color-ink, #1a1a2e); color: var(--aksrt-color-text);
} }
.aksrt-revenue__stat p { .aksrt-revenue__stat p {
margin: 4px 0 0; margin: 4px 0 0;
font-size: 12px; font-size: 12px;
color: var(--color-ink-4, #8a909c); color: var(--aksrt-color-muted);
} }
.aksrt-revenue__charts { .aksrt-revenue__charts {
@@ -229,7 +229,7 @@ onMounted(loadRevenue)
.aksrt-revenue__chart h4 { .aksrt-revenue__chart h4 {
margin: 0 0 10px; margin: 0 0 10px;
color: var(--color-ink, #1a1a2e); color: var(--aksrt-color-text);
} }
.aksrt-revenue__chart-bars { .aksrt-revenue__chart-bars {
@@ -267,7 +267,7 @@ onMounted(loadRevenue)
.aksrt-revenue__chart-label { .aksrt-revenue__chart-label {
font-size: 10px; font-size: 10px;
color: var(--color-ink-4, #8a909c); color: var(--aksrt-color-muted);
margin-top: 4px; margin-top: 4px;
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
@@ -285,7 +285,7 @@ onMounted(loadRevenue)
} }
.aksrt-revenue__chart-summary strong { .aksrt-revenue__chart-summary strong {
color: var(--color-ink, #1a1a2e); color: var(--aksrt-color-text);
font-weight: 600; font-weight: 600;
} }
</style> </style>
@@ -20,7 +20,7 @@
<n-grid :cols="3" :x-gap="12" :y-gap="12"> <n-grid :cols="3" :x-gap="12" :y-gap="12">
<n-grid-item v-for="item in summaryItems" :key="item.key"> <n-grid-item v-for="item in summaryItems" :key="item.key">
<div class="aksrt-attach__summary"> <div class="aksrt-attach__summary">
<FaIcon :icon="item.icon" :size="16" :color="item.enabled ? '#52c41a' : '#8a909c'" /> <FaIcon :icon="item.icon" :size="16" :color="item.enabled ? '#52c41a' : 'var(--aksrt-color-muted)'" />
<div> <div>
<strong>{{ item.label }}</strong> <strong>{{ item.label }}</strong>
<p>{{ item.enabled ? '已启用' : '已关闭' }}</p> <p>{{ item.enabled ? '已启用' : '已关闭' }}</p>
@@ -163,12 +163,12 @@ onMounted(load)
.aksrt-attach__summary strong { .aksrt-attach__summary strong {
display: block; display: block;
font-size: 13px; font-size: 13px;
color: #1a1a2e; color: var(--aksrt-color-text);
} }
.aksrt-attach__summary p { .aksrt-attach__summary p {
margin: 2px 0 0; margin: 2px 0 0;
font-size: 12px; font-size: 12px;
color: #8a909c; color: var(--aksrt-color-muted);
} }
</style> </style>
@@ -224,7 +224,7 @@ async function handleSave() {
.aksrt-cap-matrix__desc { .aksrt-cap-matrix__desc {
margin: 4px 0 0; margin: 4px 0 0;
font-size: 12px; font-size: 12px;
color: #8a909c; color: var(--aksrt-color-muted);
} }
.aksrt-cap-matrix__cap { .aksrt-cap-matrix__cap {
@@ -26,7 +26,7 @@
<p style="margin: 6px 0 0; color: #4b5565;"> <p style="margin: 6px 0 0; color: #4b5565;">
{{ item.current_email }} → {{ item.previous_email }} {{ item.current_email }} → {{ item.previous_email }}
</p> </p>
<p style="margin: 6px 0 0; color: #7a7f8a; font-size: 12px;"> <p style="margin: 6px 0 0; color: var(--aksrt-color-muted); font-size: 12px;">
剩余窗口:{{ Math.max(0, Math.floor((item.expires_in || 0) / 3600)) }} 小时 剩余窗口:{{ Math.max(0, Math.floor((item.expires_in || 0) / 3600)) }} 小时
</p> </p>
</div> </div>
+2 -2
View File
@@ -179,7 +179,7 @@ async function handleDismiss() {
flex-direction: column; flex-direction: column;
gap: 4px; gap: 4px;
padding: 14px; padding: 14px;
border: 1px solid #eef1f6; border: 1px solid var(--aksrt-color-border);
border-radius: 12px; border-radius: 12px;
text-decoration: none; text-decoration: none;
color: inherit; color: inherit;
@@ -187,7 +187,7 @@ async function handleDismiss() {
} }
.aksrt-update__guide:hover { .aksrt-update__guide:hover {
border-color: #1890ff; border-color: var(--aksrt-color-primary);
background: #f5faff; background: #f5faff;
} }
@@ -231,7 +231,7 @@ export default {
.aksrt-wechat__status-value { .aksrt-wechat__status-value {
font-size: 18px; font-size: 18px;
font-weight: 600; font-weight: 600;
color: #1a1a2e; color: var(--aksrt-color-text);
} }
.aksrt-wechat__status-label { .aksrt-wechat__status-label {
font-size: 12px; font-size: 12px;
+116 -110
View File
@@ -4,9 +4,23 @@
} }
#aksrt-admin-app { #aksrt-admin-app {
--aksrt-color-primary: #18A058;
--aksrt-color-primary-hover: #36AD6A;
--aksrt-color-primary-pressed: #0C7A43;
--aksrt-color-primary-soft: #EAF7EF;
--aksrt-color-canvas: #F5F7F6;
--aksrt-color-surface: #FFFFFF;
--aksrt-color-text: #1F2923;
--aksrt-color-text-secondary: #465149;
--aksrt-color-muted: #6F7A72;
--aksrt-color-border: #E2E8E3;
--aksrt-color-border-strong: #CCD7CE;
--aksrt-shadow-card: 0 1px 2px rgba(31, 41, 35, .04);
--aksrt-shadow-floating: 0 12px 32px rgba(31, 41, 35, .12);
min-height: 100%; min-height: 100%;
color: #333; color: var(--aksrt-color-text);
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans SC", sans-serif; background: var(--aksrt-color-canvas);
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;
font-size: 14px; font-size: 14px;
line-height: 1.6; line-height: 1.6;
} }
@@ -37,125 +51,100 @@
#aksrt-admin-app .aksrt-admin-layout { #aksrt-admin-app .aksrt-admin-layout {
min-height: 100vh; min-height: 100vh;
background: rgb(249, 250, 252); background: var(--aksrt-color-canvas);
} }
#aksrt-admin-app .aksrt-csf-shell .n-layout-sider { #aksrt-admin-app .aksrt-admin-sider {
background: #fff; background: var(--aksrt-color-surface);
border-right: 1px solid #f2f2f2; border-right: 1px solid var(--aksrt-color-border);
} }
#aksrt-admin-app .aksrt-csf-shell .n-menu-item-content { #aksrt-admin-app .aksrt-admin-sider .n-layout-toggle-button {
border-bottom: 1px solid #f4f4f4; border: 1px solid var(--aksrt-color-border);
border-radius: 0; background: var(--aksrt-color-surface);
color: var(--aksrt-color-muted);
box-shadow: var(--aksrt-shadow-card);
} }
#aksrt-admin-app .aksrt-csf-shell .n-menu-item-content--selected, #aksrt-admin-app .aksrt-admin-sider .n-layout-toggle-button:hover {
#aksrt-admin-app .aksrt-csf-shell .n-menu-item-content:hover { border-color: var(--aksrt-color-primary);
color: #0997f5; color: var(--aksrt-color-primary);
background: rgb(249, 250, 252);
} }
#aksrt-admin-app .aksrt-schema-page { #aksrt-admin-app .aksrt-admin-menu {
max-width: none; padding: 10px 8px 18px;
} }
#aksrt-admin-app .aksrt-form-renderer__header { #aksrt-admin-app .aksrt-admin-menu .n-menu-item-content {
margin: -30px -30px 0; position: relative;
padding: 18px 30px; border-radius: 8px;
border-bottom: 1px solid #eee; transition: color .16s ease, background-color .16s ease;
background: #fff;
} }
#aksrt-admin-app .aksrt-form-renderer__title { #aksrt-admin-app .aksrt-admin-menu .n-menu-item-content--selected::after {
color: #0991f5; position: absolute;
font-size: 19px; top: 9px;
bottom: 9px;
left: 0;
width: 3px;
border-radius: 0 3px 3px 0;
background: var(--aksrt-color-primary);
content: '';
} }
#aksrt-admin-app .aksrt-field-group { #aksrt-admin-app .aksrt-admin-menu .n-submenu-children {
margin: 0 -30px; margin: 2px 0 6px;
border: 0;
border-radius: 0;
background: transparent;
} }
#aksrt-admin-app .aksrt-field-group__body { #aksrt-admin-app .aksrt-admin-menu .n-menu-item-content-header {
padding: 0; font-weight: 500;
} }
#aksrt-admin-app .aksrt-field { #aksrt-admin-app .aksrt-menu-item--secondary .n-menu-item-content-header {
display: grid; color: var(--aksrt-color-muted);
grid-template-columns: minmax(150px, 22%) minmax(0, 1fr); font-size: 12px;
column-gap: 24px;
align-items: start;
margin: 0;
padding: 20px 30px;
border-bottom: 1px solid #eee;
} }
#aksrt-admin-app .aksrt-field > :not(.aksrt-field__label-row):not(.aksrt-field__desc):not(.aksrt-field__error) { #aksrt-admin-app .aksrt-admin-content {
grid-column: 2; background: var(--aksrt-color-canvas);
} }
#aksrt-admin-app .aksrt-field__label-row { #aksrt-admin-app .aksrt-schema-page,
grid-column: 1; #aksrt-admin-app .aksrt-page-container,
grid-row: 1; #aksrt-admin-app .content-page {
margin: 4px 0 0; width: 100%;
} max-width: 1180px;
margin: 0 auto;
#aksrt-admin-app .aksrt-field__label {
color: #0991f5;
font-weight: 600;
}
#aksrt-admin-app .aksrt-field__desc {
grid-column: 1;
margin: 26px 0 0;
}
#aksrt-admin-app .aksrt-field--notice {
display: block;
padding-top: 14px;
padding-bottom: 14px;
background: #fff8e5;
}
#aksrt-admin-app .aksrt-field__fieldset .aksrt-field,
#aksrt-admin-app .aksrt-field__repeater .aksrt-field,
#aksrt-admin-app .aksrt-field__sortable .aksrt-field {
padding: 12px 0;
border-bottom-color: #eee;
}
#aksrt-admin-app .aksrt-field__repeater-item,
#aksrt-admin-app .aksrt-field__fieldset {
border-radius: 2px;
background: #fff;
} }
#aksrt-admin-app .aksrt-form-renderer__save-bar { #aksrt-admin-app .aksrt-form-renderer__save-bar {
right: 28px;
left: auto; left: auto;
right: 0; width: min(1180px, calc(100vw - 448px));
bottom: 0; border: 1px solid var(--aksrt-color-border);
border-top: 1px solid #f2f2f2; border-bottom: 0;
border-radius: 12px 12px 0 0;
background: rgba(255, 255, 255, .96); background: rgba(255, 255, 255, .96);
box-shadow: var(--aksrt-shadow-floating);
backdrop-filter: blur(12px);
}
#aksrt-admin-app .aksrt-form-renderer__save-bar__inner {
max-width: 1180px;
} }
#aksrt-admin-app .aksrt-form-renderer__save-bar .n-button--primary-type { #aksrt-admin-app .aksrt-form-renderer__save-bar .n-button--primary-type {
border-radius: 30px; box-shadow: 0 4px 12px rgba(24, 160, 88, .18);
background-image: linear-gradient(135deg, #65bff7 10%, #0d67b9 100%);
box-shadow: -1px 2px 10px rgba(1, 65, 139, .3);
} }
#aksrt-admin-app .aksrt-page-container, #aksrt-admin-app :where(a, button, input, textarea, select, [tabindex]):focus-visible {
#aksrt-admin-app .content-page { outline: 2px solid var(--aksrt-color-primary);
max-width: 1100px; outline-offset: 2px;
margin: 0 auto;
} }
#aksrt-admin-app .aksrt-page-title { #aksrt-admin-app .aksrt-page-title {
margin: 0 0 12px; margin: 0 0 12px;
color: #1a1a2e; color: var(--aksrt-color-text);
font-size: 22px; font-size: 22px;
font-weight: 700; font-weight: 700;
letter-spacing: -0.02em; letter-spacing: -0.02em;
@@ -163,7 +152,7 @@
#aksrt-admin-app .aksrt-page-desc { #aksrt-admin-app .aksrt-page-desc {
margin: 0 0 24px; margin: 0 0 24px;
color: #7a7f8a; color: var(--aksrt-color-muted);
font-size: 13px; font-size: 13px;
line-height: 1.7; line-height: 1.7;
} }
@@ -171,8 +160,9 @@
#aksrt-admin-app .aksrt-section-card { #aksrt-admin-app .aksrt-section-card {
margin-bottom: 18px; margin-bottom: 18px;
border-radius: 12px !important; border-radius: 12px !important;
border: 1px solid #eceff5 !important; border: 1px solid var(--aksrt-color-border) !important;
box-shadow: 0 1px 3px rgba(15, 23, 42, 0.04); background: var(--aksrt-color-surface);
box-shadow: var(--aksrt-shadow-card);
} }
#aksrt-admin-app .aksrt-section-card .n-card__content { #aksrt-admin-app .aksrt-section-card .n-card__content {
@@ -192,7 +182,7 @@
#aksrt-admin-app .aksrt-section-header h3 { #aksrt-admin-app .aksrt-section-header h3 {
margin: 0; margin: 0;
color: #1a1a2e; color: var(--aksrt-color-text);
font-size: 15px; font-size: 15px;
font-weight: 600; font-weight: 600;
} }
@@ -207,7 +197,7 @@
#aksrt-admin-app .section-desc, #aksrt-admin-app .section-desc,
#aksrt-admin-app .aksrt-hint-text { #aksrt-admin-app .aksrt-hint-text {
color: #8a909c; color: var(--aksrt-color-muted);
font-size: 12px; font-size: 12px;
line-height: 1.6; line-height: 1.6;
} }
@@ -225,7 +215,7 @@
} }
#aksrt-admin-app .aksrt-form .n-form-item-label { #aksrt-admin-app .aksrt-form .n-form-item-label {
color: #555 !important; color: var(--aksrt-color-text-secondary) !important;
font-size: 13px; font-size: 13px;
font-weight: 500; font-weight: 500;
} }
@@ -233,8 +223,8 @@
#aksrt-admin-app .aksrt-form .n-input, #aksrt-admin-app .aksrt-form .n-input,
#aksrt-admin-app .aksrt-form .n-select .n-base-selection, #aksrt-admin-app .aksrt-form .n-select .n-base-selection,
#aksrt-admin-app .aksrt-form .n-input-number { #aksrt-admin-app .aksrt-form .n-input-number {
min-height: 38px; min-height: 36px;
--n-height: 38px !important; --n-height: 36px !important;
} }
#aksrt-admin-app .aksrt-form .n-input--textarea textarea { #aksrt-admin-app .aksrt-form .n-input--textarea textarea {
@@ -253,7 +243,7 @@
gap: 12px; gap: 12px;
padding: 24px 0 8px; padding: 24px 0 8px;
margin-top: 28px; margin-top: 28px;
border-top: 1px solid #eef1f6; border-top: 1px solid var(--aksrt-color-border);
} }
#aksrt-admin-app .aksrt-form-actions .n-button { #aksrt-admin-app .aksrt-form-actions .n-button {
@@ -278,7 +268,7 @@
} }
#aksrt-admin-app .n-data-table .n-data-table-th { #aksrt-admin-app .n-data-table .n-data-table-th {
background: #f8fafc; background: #f7f9f7;
} }
#aksrt-admin-app .n-empty { #aksrt-admin-app .n-empty {
@@ -326,7 +316,7 @@
margin: 0; margin: 0;
font-size: 15px; font-size: 15px;
font-weight: 600; font-weight: 600;
color: #1a1a2e; color: var(--aksrt-color-text);
} }
/* ==================== 过渡 ==================== */ /* ==================== 过渡 ==================== */
@@ -351,6 +341,25 @@
max-width: 520px; max-width: 520px;
} }
@media (max-width: 960px) {
#aksrt-admin-app .aksrt-form-renderer__save-bar {
right: 0;
left: 0;
width: auto;
border-right: 0;
border-left: 0;
border-radius: 0;
}
#aksrt-admin-app .aksrt-page-wrapper {
width: 100%;
}
#aksrt-admin-app .aksrt-admin-menu {
padding-top: 8px;
}
}
/* ==================== 移动端适配 ==================== */ /* ==================== 移动端适配 ==================== */
@media (max-width: 768px) { @media (max-width: 768px) {
/* 容器 */ /* 容器 */
@@ -360,20 +369,6 @@
padding: 0; padding: 0;
} }
#aksrt-admin-app .aksrt-form-renderer__header {
margin: -14px -12px 0;
padding: 14px 16px;
}
#aksrt-admin-app .aksrt-field-group {
margin: 0 -12px;
}
#aksrt-admin-app .aksrt-field {
display: block;
padding: 16px;
}
#aksrt-admin-app .aksrt-field__desc { #aksrt-admin-app .aksrt-field__desc {
margin: 2px 0 8px; margin: 2px 0 8px;
} }
@@ -527,3 +522,14 @@
padding: 12px 12px 0 !important; padding: 12px 12px 0 !important;
} }
} }
@media (prefers-reduced-motion: reduce) {
#aksrt-admin-app *,
#aksrt-admin-app *::before,
#aksrt-admin-app *::after {
scroll-behavior: auto !important;
animation-duration: .01ms !important;
animation-iteration-count: 1 !important;
transition-duration: .01ms !important;
}
}
@@ -0,0 +1,64 @@
const test = require('node:test')
const assert = require('node:assert/strict')
const fs = require('node:fs')
const path = require('node:path')
const root = path.resolve(__dirname, '../..')
const read = file => fs.readFileSync(path.join(root, file), 'utf8')
const app = read('assets/admin/src/App.vue')
const styles = read('assets/admin/src/style.css')
const field = read('assets/admin/src/components/form/AksField.vue')
const fieldGroup = read('assets/admin/src/components/form/AksFieldGroup.vue')
const formRenderer = read('assets/admin/src/components/form/AksFormRenderer.vue')
test('admin theme exposes the approved white, grey, and green tokens', () => {
const requiredTokens = {
'--aksrt-color-primary': '#18A058',
'--aksrt-color-primary-soft': '#EAF7EF',
'--aksrt-color-canvas': '#F5F7F6',
'--aksrt-color-surface': '#FFFFFF',
'--aksrt-color-text': '#1F2923',
'--aksrt-color-muted': '#6F7A72',
'--aksrt-color-border': '#E2E8E3',
}
for (const [token, value] of Object.entries(requiredTokens)) {
assert.match(styles, new RegExp(`${token}:\\s*${value}`, 'i'), `missing ${token}`)
}
})
test('app uses Naive UI overrides and the compact responsive shell', () => {
assert.match(app, /:theme-overrides="adminThemeOverrides"/)
assert.match(app, /const adminThemeOverrides = \{/)
assert.match(app, /:width="232"/)
assert.match(app, /const MOBILE_BREAKPOINT = 960/)
assert.match(app, /aksrt-logo__version/)
assert.doesNotMatch(app, /aksrt-csf-(?:shell|header|version)/)
})
test('rejected gradient banner and split-row form overrides do not return', () => {
const source = `${app}\n${styles}`
assert.doesNotMatch(source, /#f97794|#623aa2|#0991f5|#0997f5/i)
assert.doesNotMatch(source, /linear-gradient/i)
assert.doesNotMatch(styles, /\.aksrt-field\s*>\s*:not/)
assert.doesNotMatch(styles, /\.aksrt-field__label-row\s*\{[^}]*grid-column/s)
})
test('shared forms use card surfaces and design tokens', () => {
assert.match(fieldGroup, /border:\s*1px solid var\(--aksrt-color-border\)/)
assert.match(fieldGroup, /border-radius:\s*12px/)
assert.match(fieldGroup, /box-shadow:\s*var\(--aksrt-shadow-card\)/)
assert.match(field, /color:\s*var\(--aksrt-color-primary\)/)
assert.match(field, /background:\s*var\(--aksrt-color-primary-soft\)/)
assert.match(formRenderer, /background:\s*var\(--aksrt-color-surface\)/)
})
test('navigation, focus, responsive layout, and reduced motion are contracted', () => {
assert.match(styles, /\.n-menu-item-content--selected::after/)
assert.match(styles, /:focus-visible/)
assert.match(styles, /@media \(max-width:\s*960px\)/)
assert.match(styles, /@media \(max-width:\s*768px\)/)
assert.match(styles, /@media \(max-width:\s*480px\)/)
assert.match(styles, /@media \(prefers-reduced-motion:\s*reduce\)/)
})