admin_new P0+P1 全批次合并 (84 commits) #2

Merged
direv merged 85 commits from develop into main 2026-08-07 11:27:17 +08:00
11 changed files with 125 additions and 69 deletions
Showing only changes of commit ee52bed129 - Show all commits

View File

@ -356,7 +356,7 @@ onMounted(loadBadges)
.rr-layout { .rr-layout {
display: flex; display: flex;
height: 100vh; height: 100vh;
background: var(--rr-page-bg, #F1F5F9); background: var(--bg-soft);
transition: background 0.3s; transition: background 0.3s;
&.collapsed .rr-sidebar { width: 64px; } &.collapsed .rr-sidebar { width: 64px; }
} }
@ -457,7 +457,7 @@ onMounted(loadBadges)
transition: all 0.12s; transition: all 0.12s;
white-space: nowrap; white-space: nowrap;
&:hover { background: var(--rr-page-bg, #F1F5F9); color: var(--ink); } &:hover { background: var(--bg-soft); color: var(--ink); }
&.active { &.active {
background: var(--brand-soft); background: var(--brand-soft);
color: var(--brand); color: var(--brand);
@ -475,7 +475,7 @@ onMounted(loadBadges)
font-weight: 600; font-weight: 600;
padding: 1px 7px; padding: 1px 7px;
border-radius: 10px; border-radius: 10px;
background: var(--rr-page-bg, #F1F5F9); background: var(--bg-soft);
color: var(--ink-3); color: var(--ink-3);
.rr-sidebar-item.active & { background: rgba(255,255,255,0.18); color: var(--brand); } .rr-sidebar-item.active & { background: rgba(255,255,255,0.18); color: var(--brand); }
@ -501,7 +501,7 @@ onMounted(loadBadges)
margin-bottom: 1px; margin-bottom: 1px;
white-space: nowrap; white-space: nowrap;
&:hover { background: var(--rr-page-bg, #F1F5F9); color: var(--ink); } &:hover { background: var(--bg-soft); color: var(--ink); }
&.active { &.active {
background: var(--brand-soft); background: var(--brand-soft);
color: var(--brand); color: var(--brand);
@ -602,7 +602,7 @@ onMounted(loadBadges)
justify-content: center; justify-content: center;
cursor: pointer; cursor: pointer;
color: var(--ink-2); color: var(--ink-2);
&:hover { background: var(--rr-page-bg, #F1F5F9); color: var(--brand); } &:hover { background: var(--bg-soft); color: var(--brand); }
} }
.rr-topbar-breadcrumb { font-size: 13px; } .rr-topbar-breadcrumb { font-size: 13px; }
@ -627,7 +627,7 @@ onMounted(loadBadges)
padding: 4px 8px; padding: 4px 8px;
border-radius: 16px; border-radius: 16px;
cursor: pointer; cursor: pointer;
&:hover { background: var(--rr-page-bg, #F1F5F9); } &:hover { background: var(--bg-soft); }
} }
.rr-topbar-avatar { .rr-topbar-avatar {
width: 26px; width: 26px;
@ -652,7 +652,7 @@ onMounted(loadBadges)
flex: 1; flex: 1;
overflow: auto; overflow: auto;
padding: 24px 28px; padding: 24px 28px;
background: var(--rr-page-bg, #F1F5F9); background: var(--bg-soft);
} }
/* ===== W5.x v2 Design Language 新增样式 ===== */ /* ===== W5.x v2 Design Language 新增样式 ===== */
@ -662,7 +662,7 @@ onMounted(loadBadges)
width: 28px; width: 28px;
height: 28px; height: 28px;
border-radius: 6px; border-radius: 6px;
background: var(--rr-page-bg, #F1F5F9); background: var(--bg-soft);
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
@ -691,7 +691,7 @@ img.rr-sidebar-logo {
transition: all 0.2s var(--ease); transition: all 0.2s var(--ease);
} }
.rr-topbar-notification:hover { .rr-topbar-notification:hover {
background: var(--rr-page-bg, #F1F5F9); background: var(--bg-soft);
color: var(--brand); color: var(--brand);
} }
.rr-topbar-notification-icon { .rr-topbar-notification-icon {
@ -733,7 +733,7 @@ img.rr-sidebar-logo {
width: 28px; width: 28px;
height: 28px; height: 28px;
border-radius: 6px; border-radius: 6px;
background: var(--rr-page-bg, #F1F5F9); background: var(--bg-soft);
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
@ -762,7 +762,7 @@ img.rr-sidebar-logo {
transition: all 0.2s var(--ease); transition: all 0.2s var(--ease);
} }
.rr-topbar-notification:hover { .rr-topbar-notification:hover {
background: var(--rr-page-bg, #F1F5F9); background: var(--bg-soft);
color: var(--brand); color: var(--brand);
} }
.rr-topbar-notification-icon { .rr-topbar-notification-icon {

View File

@ -143,12 +143,12 @@ watch(() => props.columns, () => autoFillTable(), { flush: 'post' })
row-class-name="rr-clickable-row" row-class-name="rr-clickable-row"
:header-row-style="{ height: '48px' }" :header-row-style="{ height: '48px' }"
:header-cell-style="{ :header-cell-style="{
background: 'var(--rr-table-header-bg, #F8FAFC)', background: 'var(--surface-2)',
color: 'var(--rr-text-secondary, #64748B)', color: 'var(--ink-3)',
fontWeight: '600', fontWeight: '600',
fontSize: '12px', fontSize: '12px',
padding: '14px 16px', padding: '14px 16px',
borderBottom: '1px solid var(--rr-border-color, #E2E8F0)', borderBottom: '1px solid var(--border)',
textTransform: 'uppercase', textTransform: 'uppercase',
letterSpacing: '0.04em', letterSpacing: '0.04em',
whiteSpace: 'nowrap', whiteSpace: 'nowrap',
@ -157,8 +157,8 @@ watch(() => props.columns, () => autoFillTable(), { flush: 'post' })
}" }"
:cell-style="{ :cell-style="{
padding: '10px 16px', padding: '10px 16px',
borderBottom: '1px solid var(--rr-border-color, #E2E8F0)', borderBottom: '1px solid var(--border)',
color: 'var(--rr-text-secondary, #334155)', color: 'var(--ink-2)',
fontSize: '13px', fontSize: '13px',
textAlign: 'left', textAlign: 'left',
verticalAlign: 'middle' verticalAlign: 'middle'
@ -228,8 +228,8 @@ watch(() => props.columns, () => autoFillTable(), { flush: 'post' })
<style scoped lang="scss"> <style scoped lang="scss">
.rr-data-table { .rr-data-table {
width: 100%; width: 100%;
background: var(--rr-bg-card, #FFFFFF); background: var(--surface);
border: 1px solid var(--rr-border-color, #E2E8F0); border: 1px solid var(--border);
border-radius: 10px; border-radius: 10px;
overflow: hidden; overflow: hidden;
box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04); box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
@ -238,7 +238,7 @@ watch(() => props.columns, () => autoFillTable(), { flush: 'post' })
transition: background 0.15s; transition: background 0.15s;
} }
:deep(.el-table__row:hover > td.el-table__cell) { :deep(.el-table__row:hover > td.el-table__cell) {
background-color: var(--rr-row-hover, #F8FAFC) !important; background-color: var(--bg-soft) !important;
} }
// 表格本体圆角配合容器 // 表格本体圆角配合容器
:deep(.el-table) { :deep(.el-table) {
@ -286,10 +286,10 @@ watch(() => props.columns, () => autoFillTable(), { flush: 'post' })
justify-content: space-between; justify-content: space-between;
padding: 12px 20px; padding: 12px 20px;
font-size: 13px; /* W17.3.6 跟内容行一致 (13px) */ font-size: 13px; /* W17.3.6 跟内容行一致 (13px) */
color: var(--ink-3, #94A3B8); color: var(--ink-3);
background: var(--rr-bg-card, #FFFFFF); background: var(--surface);
border-top: 1px solid var(--rr-border-color, #F1F5F9); border-top: 1px solid var(--border);
&__info { color: var(--ink-3, #94A3B8); } &__info { color: var(--ink-3); }
:deep(.el-pagination) { :deep(.el-pagination) {
--el-pagination-bg-color: transparent; --el-pagination-bg-color: transparent;
--el-pagination-font-size: 13px; /* W17.3.6 跟内容行 cell 字号一致 (13px) */ --el-pagination-font-size: 13px; /* W17.3.6 跟内容行 cell 字号一致 (13px) */

View File

@ -50,7 +50,7 @@ function onClick(key: string) {
align-items: center; align-items: center;
gap: 0; gap: 0;
margin-bottom: 14px; margin-bottom: 14px;
border-bottom: 1px solid var(--border, #E2E8F0); border-bottom: 1px solid var(--border);
} }
.rr-list-tab { .rr-list-tab {
padding: 10px 18px; padding: 10px 18px;
@ -77,8 +77,8 @@ function onClick(key: string) {
&__count { &__count {
font-size: 11px; font-size: 11px;
background: var(--surface-2, #F1F5F9); background: var(--surface-2);
color: var(--ink-4, #94A3B8); color: var(--ink-3);
padding: 0 6px; padding: 0 6px;
border-radius: 999px; border-radius: 999px;
font-weight: 500; font-weight: 500;

View File

@ -108,7 +108,7 @@ const activeChips = computed(() => {
v-model="localFilters[f.key]" v-model="localFilters[f.key]"
:placeholder="f.placeholder || `请输入${f.label}`" :placeholder="f.placeholder || `请输入${f.label}`"
:clearable="f.clearable !== false" :clearable="f.clearable !== false"
:style="{ width: f.width || 180 }" :style="{ width: (typeof f.width === 'number' ? f.width + 'px' : (f.width || '180px')) }"
@keyup.enter="onEnter" @keyup.enter="onEnter"
/> />
<el-select <el-select
@ -116,7 +116,7 @@ const activeChips = computed(() => {
v-model="localFilters[f.key]" v-model="localFilters[f.key]"
:placeholder="f.placeholder || `请选择${f.label}`" :placeholder="f.placeholder || `请选择${f.label}`"
:clearable="f.clearable !== false" :clearable="f.clearable !== false"
:style="{ width: f.width || 160 }" :style="{ width: (typeof f.width === 'number' ? f.width + 'px' : (f.width || '160px')) }"
> >
<el-option <el-option
v-for="opt in f.options || []" v-for="opt in f.options || []"
@ -130,7 +130,7 @@ const activeChips = computed(() => {
v-model="localFilters[f.key]" v-model="localFilters[f.key]"
type="date" type="date"
:placeholder="f.placeholder || `请选择${f.label}`" :placeholder="f.placeholder || `请选择${f.label}`"
:style="{ width: f.width || 180 }" :style="{ width: (typeof f.width === 'number' ? f.width + 'px' : (f.width || '180px')) }"
value-format="YYYY-MM-DD" value-format="YYYY-MM-DD"
/> />
<el-date-picker <el-date-picker
@ -140,14 +140,14 @@ const activeChips = computed(() => {
range-separator="~" range-separator="~"
:start-placeholder="f.placeholder || '开始日期'" :start-placeholder="f.placeholder || '开始日期'"
:end-placeholder="'结束日期'" :end-placeholder="'结束日期'"
:style="{ width: f.width || 260 }" :style="{ width: (typeof f.width === 'number' ? f.width + 'px' : (f.width || '260px')) }"
value-format="YYYY-MM-DD" value-format="YYYY-MM-DD"
/> />
<el-input-number <el-input-number
v-else-if="f.type === 'number'" v-else-if="f.type === 'number'"
v-model="localFilters[f.key]" v-model="localFilters[f.key]"
:placeholder="f.placeholder || `请输入${f.label}`" :placeholder="f.placeholder || `请输入${f.label}`"
:style="{ width: f.width || 180 }" :style="{ width: (typeof f.width === 'number' ? f.width + 'px' : (f.width || '180px')) }"
/> />
</div> </div>
<div class="rr-search-bar__chips" v-if="showChips && activeChips.length"> <div class="rr-search-bar__chips" v-if="showChips && activeChips.length">
@ -169,28 +169,63 @@ const activeChips = computed(() => {
</template> </template>
<style scoped lang="scss"> <style scoped lang="scss">
/* === 统一 input/select 圆角 (按 ui-preview-v2.html 模板) === */
:deep(.el-input__wrapper),
:deep(.el-select__wrapper) {
border-radius: var(--radius, 8px);
box-shadow: 0 0 0 1px var(--border) inset;
transition: box-shadow 0.15s, border-color 0.15s;
min-height: 34px;
}
:deep(.el-input__wrapper:hover),
:deep(.el-select__wrapper:hover) {
box-shadow: 0 0 0 1px var(--ink-3, #94A3B8) inset;
}
:deep(.el-input__wrapper.is-focus),
:deep(.el-select__wrapper.is-focused) {
box-shadow: 0 0 0 1px var(--brand, #2563EB) inset, 0 0 0 3px var(--brand-glow, rgba(37, 99, 235, 0.18));
}
/* === el-select 宽度兜底 (Vue :style 没生效时也保证最小宽度) === */
:deep(.el-select) {
min-width: 140px;
width: auto !important;
}
:deep(.el-select .el-select__wrapper) {
min-width: 140px;
}
:deep(.el-select .el-select__wrapper .el-select__selection) {
min-width: 100px;
}
/* === 下拉弹层圆角 (跟 input 一致) === */
:deep(.el-select-dropdown),
:deep(.el-select__popper),
:deep(.el-popper.is-light) {
border-radius: var(--radius, 8px) !important;
overflow: hidden;
}
:deep(.el-select-dropdown__item) {
border-radius: var(--radius-sm, 6px);
margin: 2px 4px;
padding: 0 12px;
height: 32px;
line-height: 32px;
font-size: 13px;
}
:deep(.el-select-dropdown__item.is-hovering) {
background: var(--brand-soft, rgba(37, 99, 235, 0.08));
color: var(--brand, #2563EB);
}
:deep(.el-select-dropdown__item.is-selected) {
font-weight: 600;
color: var(--brand, #2563EB);
}
// 统一 input/select 高度
:deep(.el-input__wrapper),
:deep(.el-select__wrapper) {
border-radius: var(--radius, 6px);
box-shadow: 0 0 0 1px var(--rr-border-color, #E2E8F0) inset;
transition: box-shadow 0.15s;
}
:deep(.el-input__wrapper:hover),
:deep(.el-select__wrapper:hover) {
box-shadow: 0 0 0 1px var(--rr-text-secondary, #94A3B8) inset;
}
:deep(.el-input__wrapper.is-focus),
:deep(.el-select__wrapper.is-focused) {
box-shadow: 0 0 0 2px var(--brand, #2563EB) inset;
}
.rr-search-bar { .rr-search-bar {
margin-bottom: 16px; margin-bottom: 16px;
&__row { &__row {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 12px; gap: 10px;
flex-wrap: wrap; flex-wrap: wrap;
} }
&__field { &__field {
@ -214,7 +249,7 @@ const activeChips = computed(() => {
padding: 4px 10px; padding: 4px 10px;
background: var(--brand-soft, rgba(37, 99, 235, 0.08)); background: var(--brand-soft, rgba(37, 99, 235, 0.08));
color: var(--brand, #2563EB); color: var(--brand, #2563EB);
border-radius: 999px; border-radius: var(--radius-pill, 9999px);
font-size: 12px; font-size: 12px;
font-weight: 500; font-weight: 500;
&-close { &-close {
@ -230,9 +265,9 @@ const activeChips = computed(() => {
gap: 8px; gap: 8px;
margin-left: auto; margin-left: auto;
:deep(.el-button) { :deep(.el-button) {
padding: 8px 16px; padding: 7px 16px;
font-weight: 500; font-weight: 500;
border-radius: var(--radius, 6px); border-radius: var(--radius, 8px);
} }
} }
} }

View File

@ -201,8 +201,8 @@ onMounted(() => { load() })
height: 21.25px; height: 21.25px;
box-sizing: border-box; box-sizing: border-box;
} }
.rr-badge-pending { background: #FEF3C7; color: #D97706; } .rr-badge-pending { background: var(--amber-soft); color: var(--amber); }
.rr-badge-quoting { background: #DBEAFE; color: #2563EB; } .rr-badge-quoting { background: var(--brand-soft); color: var(--brand); }
.rr-badge-done { background: #D1FAE5; color: #059669; } .rr-badge-done { background: var(--green-soft); color: var(--green); }
.rr-badge-cancelled { background: #FEE2E2; color: #DC2626; } .rr-badge-cancelled { background: var(--red-soft); color: var(--red); }
</style> </style>

View File

@ -231,7 +231,7 @@ function notifyContact() {
:loading="loadingCustomers" :loading="loadingCustomers"
:row-style="{ height: '36px' }" :row-style="{ height: '36px' }"
:cell-style="{ padding: '4px 8px', fontSize: '12.5px' }" :cell-style="{ padding: '4px 8px', fontSize: '12.5px' }"
:header-cell-style="{ padding: '6px 8px', fontSize: '12px', height: '32px', background: '#F8FAFC' }" :header-cell-style="{ padding: '6px 8px', fontSize: '12px', height: '32px', background: 'var(--surface-2)' }"
@selection-change="onSelectionChange" @selection-change="onSelectionChange"
> >
<el-table-column type="selection" header-align="center" align="center" width="40" /> <el-table-column type="selection" header-align="center" align="center" width="40" />

View File

@ -580,10 +580,10 @@ onMounted(() => { load(); loadCustomers() })
font-size: 11.5px; font-weight: 500; line-height: 17.25px; height: 21.25px; font-size: 11.5px; font-weight: 500; line-height: 17.25px; height: 21.25px;
box-sizing: border-box; box-sizing: border-box;
} }
.rr-badge-0 { background: #FEF3C7; color: #D97706; } /* 待激活 amber */ .rr-badge-0 { background: var(--amber-soft); color: var(--amber); } /* 待激活 amber */
.rr-badge-1 { background: #D1FAE5; color: #059669; } /* 已激活 green */ .rr-badge-1 { background: var(--green-soft); color: var(--green); } /* 已激活 green */
.rr-badge-2 { background: #DBEAFE; color: #2563EB; } /* 已撤销 blue */ .rr-badge-2 { background: var(--brand-soft); color: var(--brand); } /* 已撤销 blue */
.rr-badge-3 { background: #E2E8F0; color: #64748B; } /* 已过期 gray */ .rr-badge-3 { background: var(--surface-2); color: var(--ink-3); } /* 已过期 gray */
/* 危险文字按钮(撤销/删除 - 老 vue 用 style color: #ff4d4f) */ /* 危险文字按钮(撤销/删除 - 老 vue 用 style color: #ff4d4f) */
:deep(.rr-danger-text) { :deep(.rr-danger-text) {
@ -606,7 +606,7 @@ onMounted(() => { load(); loadCustomers() })
:deep(.el-input__inner), :deep(.el-input__inner),
:deep(.el-select__wrapper) { :deep(.el-select__wrapper) {
border-radius: 8px !important; border-radius: 8px !important;
background: #F8FAFC; background: var(--surface-2);
} }
/* 弹窗圆角 12px + 紧凑(套设计规范 §7.1 + §17 v3) */ /* 弹窗圆角 12px + 紧凑(套设计规范 §7.1 + §17 v3) */

View File

@ -211,10 +211,10 @@ onMounted(load)
font-weight: 600; font-weight: 600;
font-family: 'SF Mono', Menlo, Monaco, Consolas, monospace; font-family: 'SF Mono', Menlo, Monaco, Consolas, monospace;
} }
.rr-method-get { background: #DBEAFE; color: #2563EB; } .rr-method-get { background: var(--brand-soft); color: var(--brand); }
.rr-method-post { background: #D1FAE5; color: #059669; } .rr-method-post { background: var(--green-soft); color: var(--green); }
.rr-method-put { background: #FEF3C7; color: #D97706; } .rr-method-put { background: var(--amber-soft); color: var(--amber); }
.rr-method-delete { background: #FEE2E2; color: #DC2626; } .rr-method-delete { background: var(--red-soft); color: var(--red); }
.rr-error-detail { display: grid; grid-template-columns: 1fr 1fr; gap: 14px 20px; } .rr-error-detail { display: grid; grid-template-columns: 1fr 1fr; gap: 14px 20px; }
.rr-detail-row { display: flex; flex-direction: column; gap: 4px; } .rr-detail-row { display: flex; flex-direction: column; gap: 4px; }
.rr-detail-full { grid-column: 1 / -1; } .rr-detail-full { grid-column: 1 / -1; }

View File

@ -189,8 +189,8 @@ onMounted(load)
font-weight: 600; font-weight: 600;
font-family: 'SF Mono', Menlo, Monaco, Consolas, monospace; font-family: 'SF Mono', Menlo, Monaco, Consolas, monospace;
} }
.rr-method-get { background: #DBEAFE; color: #2563EB; } .rr-method-get { background: var(--brand-soft); color: var(--brand); }
.rr-method-post { background: #D1FAE5; color: #059669; } .rr-method-post { background: var(--green-soft); color: var(--green); }
.rr-method-put { background: #FEF3C7; color: #D97706; } .rr-method-put { background: var(--amber-soft); color: var(--amber); }
.rr-method-delete { background: #FEE2E2; color: #DC2626; } .rr-method-delete { background: var(--red-soft); color: var(--red); }
</style> </style>

View File

@ -191,4 +191,17 @@
--el-color-primary-light-8: var(--brand-soft); --el-color-primary-light-8: var(--brand-soft);
--el-color-primary-light-9: var(--brand-soft); --el-color-primary-light-9: var(--brand-soft);
--el-color-primary-dark-2: var(--brand-hover); --el-color-primary-dark-2: var(--brand-hover);
// W18 dark 主题适配:EP 内部 SCSS 常量重写
// :root 块里 --el-color-white 解析为 var(--surface), 但解析时 surface 还未被 dark 块重写
// 这里用 dark 主题的实际值硬编码, 不依赖 var() 链
--el-color-white: #1E293B; /* surface */
--el-color-black: #F8FAFC; /* ink */
--el-fill-color-blank: #1E293B; /* surface */
--el-fill-color-light: #0F172A; /* bg-soft (row hover) */
--el-table-tr-bg-color: #1E293B; /* surface */
--el-table-bg-color: #1E293B; /* surface */
--el-table-expanded-cell-bg-color: #1E293B;
--el-table-header-bg-color: #283449; /* surface-2 (表头略亮区分) */
--el-table-row-hover-bg-color: #0F172A; /* bg-soft */
} }

View File

@ -13,7 +13,7 @@
:root { :root {
// ===== 圆角(沿用 v1.3) ===== // ===== 圆角(沿用 v1.3) =====
--radius-sm: 6px; --radius-sm: 6px;
--radius: 6px; --radius: 8px;
--radius-lg: 10px; --radius-lg: 10px;
--radius-xl: 16px; --radius-xl: 16px;
--radius-pill: 9999px; --radius-pill: 9999px;
@ -120,4 +120,12 @@
// ===== v2 新增:主按钮渐变(从主题 brand 自动组合) ===== // ===== v2 新增:主按钮渐变(从主题 brand 自动组合) =====
--brand-gradient: linear-gradient(135deg, var(--brand), var(--brand-2)); --brand-gradient: linear-gradient(135deg, var(--brand), var(--brand-2));
// ===== W18 暗主题适配:补齐 EP 缺失 token (dark 下表格背景/边框自适应) =====
// EP 内部用 --el-color-white / black, 未重定向, dark 下仍是 #FFFFFF
--el-color-white: var(--surface);
--el-color-black: var(--ink);
// el-table 表格体/展开行背景
--el-table-tr-bg-color: var(--surface);
--el-table-expanded-cell-bg-color: var(--surface);
} }